summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root@linux.site>2008-04-28 10:46:29 +0800
committerroot <root@linux.site>2008-04-28 10:46:29 +0800
commitf9f7b2a7457744f9abc99626ee992a6886a6fbe5 (patch)
tree07ce9357cb2965e24d03b888fac25c9582f5168f
parent0b28672591001e1448cfc65f928d0b5f0ec79138 (diff)
XGI:Add support for XG21/27
-rw-r--r--src/init.c2105
-rw-r--r--src/init.h1
-rw-r--r--src/vb_def.h18
-rw-r--r--src/vb_ext.c19
-rw-r--r--src/vb_ext.h27
-rw-r--r--src/vb_init.c6702
-rw-r--r--src/vb_init.h3
-rw-r--r--src/vb_setmode.c17902
-rw-r--r--src/vb_setmode.h18
-rw-r--r--src/vb_struct.h1073
-rw-r--r--src/vb_table.h205
-rw-r--r--src/vgatypes.h20
-rw-r--r--src/xgi.h1794
-rw-r--r--src/xgi_accel.c1729
-rw-r--r--src/xgi_accel.h48
-rw-r--r--src/xgi_cursor.c89
-rw-r--r--src/xgi_cursor.h23
-rw-r--r--src/xgi_dac.c45
-rw-r--r--src/xgi_dri.c6
-rw-r--r--src/xgi_driver.c12494
-rw-r--r--src/xgi_driver.h86
-rw-r--r--src/xgi_opt.c2
-rw-r--r--src/xgi_pci.h70
-rw-r--r--src/xgi_setup.c1107
-rw-r--r--src/xgi_vga.c539
-rw-r--r--xgi-xg20-21-27.patch46676
26 files changed, 71740 insertions, 21061 deletions
diff --git a/src/init.c b/src/init.c
index cc12b4f..12f3c80 100644
--- a/src/init.c
+++ b/src/init.c
@@ -1,1032 +1,1073 @@
-/*
- * Mode initializing code (CRT1 section)
- * (Universal module for Linux kernel framebuffer and XFree86 4.x)
- *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
- *
- * If distributed as part of the Linux kernel, the following license terms
- * apply:
- *
- * * This program is free software; you can redistribute it and/or modify
- * * it under the terms of the GNU General Public License as published by
- * * the Free Software Foundation; either version 2 of the named License,
- * * or any later version.
- * *
- * * This program is distributed in the hope that it will be useful,
- * * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * * GNU General Public License for more details.
- * *
- * * You should have received a copy of the GNU General Public License
- * * along with this program; if not, write to the Free Software
- * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
- *
- * Otherwise, the following license terms apply:
- *
- * * Redistribution and use in source and binary forms, with or without
- * * modification, are permitted provided that the following conditions
- * * are met:
- * * 1) Redistributions of source code must retain the above copyright
- * * notice, this list of conditions and the following disclaimer.
- * * 2) Redistributions in binary form must reproduce the above copyright
- * * notice, this list of conditions and the following disclaimer in the
- * * documentation and/or other materials provided with the distribution.
- * * 3) The name of the author may not be used to endorse or promote products
- * * derived from this software without specific prior written permission.
- * *
- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
- * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
- *
- * Formerly based on non-functional code-fragements for 300 series by XGI, Inc.
- * Used by permission.
- *
- * TW says: This code looks awful, I know. But please don't do anything about
- * this otherwise debugging will be hell.
- * The code is extremely fragile as regards the different chipsets, different
- * video bridges and combinations thereof. If anything is changed, extreme
- * care has to be taken that that change doesn't break it for other chipsets,
- * bridges or combinations thereof.
- * All comments in this file are by me, regardless if they are marked TW or not.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "init.h"
-#include "vgatypes.h"
-#include "vb_def.h"
-#include "vb_setmode.h"
-
-/*********************************************/
-/* HELPER: Get ModeID */
-/*********************************************/
-
-USHORT
-XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
- int Depth, int LCDwidth, int LCDheight)
-{
- USHORT ModeIndex = 0;
-
- switch(HDisplay)
- {
- case 320:
- if(VDisplay == 200)
- ModeIndex = ModeIndex_320x200[Depth];
- else if(VDisplay == 240)
- ModeIndex = ModeIndex_320x240[Depth];
-
- break;
- case 400:
- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
- break;
- case 512:
- if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
- break;
- case 640:
- if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
- else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
- break;
- case 720:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
- else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
- }
- break;
- case 768:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
- }
- break;
- case 800:
- if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
- else if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
- }
- break;
- case 848:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
- }
- break;
- case 856:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
- }
- break;
- case 1024:
- if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
- else if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
- }
- break;
- case 1152:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
- }
- break;
- case 1280:
- if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
- else if(VDisplay == 720) {
- if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
- ModeIndex = ModeIndex_1280x720[Depth];
- } else if(!(VBFlags & CRT1_LCDA)) {
- ModeIndex = ModeIndex_1280x720[Depth];
- }
- } else if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
- else if(VDisplay == 768) {
- ModeIndex = ModeIndex_310_1280x768[Depth];
- }
- }
- break;
- case 1360:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
- }
- break;
- case 1400:
- break;
- case 1600:
- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
- break;
- case 1680:
- break;
- case 1920:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
- }
- break;
- case 2048:
- if(!(VBFlags & CRT1_LCDA)) {
- if(VDisplay == 1536) {
- ModeIndex = ModeIndex_310_2048x1536[Depth];
- }
- }
- break;
- }
-
- return(ModeIndex);
-}
-
-/*********************************************/
-/* HELPER: SetReg, GetReg */
-/*********************************************/
-
-void
-XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data)
-{
- outb(port,index);
- outb(port + 1,data);
-}
-
-void
-XGI_SetRegByte(XGIIOADDRESS port, USHORT data)
-{
- outb(port,data);
-}
-
-void
-XGI_SetRegShort(XGIIOADDRESS port, USHORT data)
-{
- outw(port,data);
-}
-
-void
-XGI_SetRegLong(XGIIOADDRESS port, ULONG data)
-{
- outl(port,data);
-}
-
-UCHAR
-XGI_GetReg(XGIIOADDRESS port, USHORT index)
-{
- outb(port,index);
- return inb(port + 1);
-}
-
-UCHAR
-XGI_GetRegByte(XGIIOADDRESS port)
-{
- return inb(port);
-}
-
-USHORT
-XGI_GetRegShort(XGIIOADDRESS port)
-{
- return inw(port);
-}
-
-ULONG
-XGI_GetRegLong(XGIIOADDRESS port)
-{
- return inl(port);
-}
-
-void
-XGI_SetRegANDOR(XGIIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
-{
- USHORT temp;
-
- temp = XGI_GetReg(Port,Index);
- temp = (temp & (DataAND)) | DataOR;
- XGI_SetReg(Port,Index,temp);
-}
-
-void
-XGI_SetRegAND(XGIIOADDRESS Port,USHORT Index,USHORT DataAND)
-{
- USHORT temp;
-
- temp = XGI_GetReg(Port,Index);
- temp &= DataAND;
- XGI_SetReg(Port,Index,temp);
-}
-
-void
-XGI_SetRegOR(XGIIOADDRESS Port,USHORT Index,USHORT DataOR)
-{
- USHORT temp;
-
- temp = XGI_GetReg(Port,Index);
- temp |= DataOR;
- XGI_SetReg(Port,Index,temp);
-}
-
-/*********************************************/
-/* HELPER: DisplayOn, DisplayOff */
-/*********************************************/
-
-void
-XGI_New_DisplayOn(VB_DEVICE_INFO *XGI_Pr)
-{
- XGI_SetRegAND(XGI_Pr->P3c4,0x01,0xDF);
-}
-
-void
-XGI_New_DisplayOff(VB_DEVICE_INFO *XGI_Pr)
-{
- XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x20);
-}
-
-/*********************************************/
-/* HELPER: Init PCI & Engines */
-/*********************************************/
-
-static void
-XGIInitPCIetc(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
-{
- switch(HwInfo->jChipType) {
- case XG40:
- case XG42:
- case XG20:
- XGI_SetReg(XGI_Pr->P3c4,0x20,0xa1);
- /* - Enable 2D (0x40)
- * - Enable 3D (0x02)
- * - Enable 3D vertex command fetch (0x10)
- * - Enable 3D command parser (0x08)
- * - Enable 3D G/L transformation engine (0x80)
- */
- XGI_SetRegOR(XGI_Pr->P3c4, 0x1E,
- SR1E_ENABLE_3D_TRANSFORM_ENGINE
- | SR1E_ENABLE_2D
- | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
- | SR1E_ENABLE_3D_COMMAND_PARSER
- | SR1E_ENABLE_3D);
- break;
- }
-}
-
-/*********************************************/
-/* HELPER: GetVBType */
-/*********************************************/
-
-void
-XGI_New_GetVBType(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
-{
- USHORT flag=0, rev=0, nolcd=0;
-
- XGI_Pr->VBType = 0;
-
- flag = XGI_GetReg(XGI_Pr->Part4Port,0x00);
-PDEBUG(ErrorF("GetVBType: part4_0: %x \n",flag)); //yilin
- if(flag > 3) return;
-
- rev = XGI_GetReg(XGI_Pr->Part4Port,0x01);
-PDEBUG(ErrorF("GetVBType: part4_1: %x \n",rev)); //yilin
-
- if(flag >= 2) {
- XGI_Pr->VBType = VB_XGI302B;
- } else if(flag == 1) {
- if(rev >= 0xC0) {
- XGI_Pr->VBType = VB_XGI301C;
- } else if(rev >= 0xB0) {
- XGI_Pr->VBType = VB_XGI301B;
- /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
- nolcd = XGI_GetReg(XGI_Pr->Part4Port,0x23);
- if(!(nolcd & 0x02)) XGI_Pr->VBType |= VB_NoLCD;
- } else {
- XGI_Pr->VBType = VB_XGI301;
- }
- }
- if(XGI_Pr->VBType & (VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
- if(rev >= 0xE0) {
- flag = XGI_GetReg(XGI_Pr->Part4Port,0x39);
- if(flag == 0xff) XGI_Pr->VBType = VB_XGI302LV;
- else XGI_Pr->VBType = VB_XGI302ELV;
- } else if(rev >= 0xD0) {
- XGI_Pr->VBType = VB_XGI301LV;
- }
- }
-PDEBUG(ErrorF("GetVBType: XGI_Pr->VBType=%x \n",XGI_Pr->VBType)); //yilin
-}
-
-/*********************************************/
-/* HELPER: SearchModeID */
-/*********************************************/
-
-BOOLEAN
-XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
- const XGI_ExtStruct *EModeIDTable,
- unsigned char VGAINFO, USHORT *ModeNo, USHORT *ModeIdIndex)
-{
- if (*ModeNo <= 0x13) {
- if ((*ModeNo) <= 0x05)
- (*ModeNo) |= 0x01;
-
- for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
- if (SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo))
- break;
-
- if (SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
- return FALSE;
- }
-
- if (*ModeNo == 0x07) {
- if (VGAINFO & 0x10)
- (*ModeIdIndex)++; /* 400 lines */
- /* else 350 lines */
- }
-
- if (*ModeNo <= 0x03) {
- if (!(VGAINFO & 0x80))
- (*ModeIdIndex)++;
-
- if (VGAINFO & 0x10)
- (*ModeIdIndex)++; /* 400 lines */
- /* else 350 lines */
- }
- /* else 200 lines */
- }
- else {
-
- for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
- if (EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo))
- break;
-
- if (EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-/*********************************************/
-/* HELPER: GetModePtr */
-/*********************************************/
-
-UCHAR
-XGI_GetModePtr(const XGI_StStruct *SModeIDTable, unsigned ModeType,
- USHORT ModeNo, USHORT ModeIdIndex)
-{
- return (ModeNo <= 0x13)
- ? SModeIDTable[ModeIdIndex].St_StTableIndex
- : ((ModeType <= 0x02) ? 0x1B /* 02 -> ModeEGA */ : 0x0F);
-}
-
-
-/*********************************************/
-/* HELPER: LowModeTests */
-/*********************************************/
-
-static BOOLEAN
-XGI_DoLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
-{
- USHORT temp,temp1,temp2;
-
- if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
- return(1);
- temp = XGI_GetReg(XGI_Pr->P3d4,0x11);
- XGI_SetRegOR(XGI_Pr->P3d4,0x11,0x80);
- temp1 = XGI_GetReg(XGI_Pr->P3d4,0x00);
- XGI_SetReg(XGI_Pr->P3d4,0x00,0x55);
- temp2 = XGI_GetReg(XGI_Pr->P3d4,0x00);
- XGI_SetReg(XGI_Pr->P3d4,0x00,temp1);
- XGI_SetReg(XGI_Pr->P3d4,0x11,temp);
- if (temp2 == 0x55)
- return(0);
- else
- return(1);
-}
-
-static void
-XGI_SetLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
-{
- if(XGI_DoLowModeTest(XGI_Pr, ModeNo, HwInfo)) {
- XGI_Pr->SetFlag |= LowModeTests;
- }
-}
-
-static void
-XGI_HandleCRT1(VB_DEVICE_INFO *XGI_Pr)
-{
- XGI_SetRegAND(XGI_Pr->P3d4, 0x53, 0xbf);
-}
-
-/*********************************************/
-/* HELPER: GetOffset */
-/*********************************************/
-
-USHORT
-XGI_New_GetOffset(VB_DEVICE_INFO *XGI_Pr,USHORT ModeNo,USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwInfo)
-{
- USHORT xres, temp, colordepth, infoflag;
-
- infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- xres = XGI_Pr->RefIndex[RefreshRateTableIndex].XRes;
-
- colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, XGI_Pr);
-
- temp = xres / 16;
- if(infoflag & InterlaceMode) temp <<= 1;
- temp *= colordepth;
- if(xres % 16) {
- colordepth >>= 1;
- temp += colordepth;
- }
-
- return(temp);
-}
-
-/*********************************************/
-/* RESET VCLK */
-/*********************************************/
-
-static void
-XGI_ResetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
-{
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xCF,0x20);
- XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[1].SR2B);
- XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[1].SR2C);
- XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xcf,0x10);
- XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[0].SR2B);
- XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[0].SR2C);
- XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
-}
-
-/*********************************************/
-/* CRTC/2 */
-/*********************************************/
-
-static void
-XGI_New_SetCRT1CRTC(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwInfo)
-{
- UCHAR index;
- USHORT temp,i,j,modeflag;
-
- XGI_SetRegAND(XGI_Pr->P3d4,0x11,0x7f); /* unlock cr0-7 */
-
- if(ModeNo <= 0x13) {
- modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-
- for(i=0,j=0;i<=7;i++,j++) {
- XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
- }
- for(j=0x10;i<=10;i++,j++) {
- XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
- }
- for(j=0x15;i<=12;i++,j++) {
- XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
- }
- for(j=0x0A;i<=15;i++,j++) {
- XGI_SetReg(XGI_Pr->P3c4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
- }
-
- temp = XGI_Pr->XGINEWUB_CRT1Table[index].CR[16] & 0xE0;
- XGI_SetReg(XGI_Pr->P3c4,0x0E,temp);
-
- temp = ((XGI_Pr->XGINEWUB_CRT1Table[index].CR[16]) & 0x01) << 5;
- if(modeflag & DoubleScanMode) temp |= 0x80;
- XGI_SetRegANDOR(XGI_Pr->P3d4,0x09,0x5F,temp);
-
- if(XGI_Pr->ModeType > ModeVGA) XGI_SetReg(XGI_Pr->P3d4,0x14,0x4F);
-}
-
-/*********************************************/
-/* OFFSET & PITCH */
-/*********************************************/
-/* (partly overruled by SetPitch() in XF86) */
-/*********************************************/
-
-static void
-XGI_New_SetCRT1Offset(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwInfo)
-{
- USHORT temp, DisplayUnit, infoflag;
-
- infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-
- DisplayUnit = XGI_New_GetOffset(XGI_Pr,ModeNo,ModeIdIndex,
- RefreshRateTableIndex,HwInfo);
-
- temp = (DisplayUnit >> 8) & 0x0f;
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,temp);
-
- temp = DisplayUnit & 0xFF;
- XGI_SetReg(XGI_Pr->P3d4,0x13,temp);
-
- if(infoflag & InterlaceMode) DisplayUnit >>= 1;
-
- DisplayUnit <<= 5;
- temp = (DisplayUnit & 0xff00) >> 8;
- if(DisplayUnit & 0xff) temp++;
- temp++;
- XGI_SetReg(XGI_Pr->P3c4,0x10,temp);
-}
-
-/*********************************************/
-/* VCLK */
-/*********************************************/
-
-static void
-XGI_New_SetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwInfo, USHORT RefreshRateTableIndex)
-{
- USHORT index=0, clka, clkb;
-
- if((XGI_Pr->VBType & VB_XGI301BLV302BLV) && (XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
- clka = XGI_Pr->VBVCLKData[index].Part4_A;
- clkb = XGI_Pr->VBVCLKData[index].Part4_B;
- } else {
- clka = XGI_Pr->VCLKData[index].SR2B;
- clkb = XGI_Pr->VCLKData[index].SR2C;
- }
-
- XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xCF);
- XGI_SetReg(XGI_Pr->P3c4,0x2B,clka);
- XGI_SetReg(XGI_Pr->P3c4,0x2C,clkb);
- XGI_SetReg(XGI_Pr->P3c4,0x2D,0x01);
-}
-
-/*********************************************/
-/* MODE REGISTERS */
-/*********************************************/
-
-static void
-XGI_New_SetVCLKState(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
- USHORT ModeNo, USHORT RefreshRateTableIndex,
- USHORT ModeIdIndex)
-{
- USHORT data=0, VCLK=0, index=0;
-
- if(ModeNo > 0x13) {
- VCLK = XGI_Pr->VCLKData[index].CLOCK;
- }
-
- if(VCLK >= 166)
- data |= 0x0c;
-
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x32,0xf3,data);
-
- if(VCLK >= 166) {
- XGI_SetRegAND(XGI_Pr->P3c4,0x1f,0xe7);
- }
-
- /* DAC speed */
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x07,0xE8,0x10);
-}
-
-static void
-XGI_New_SetCRT1ModeRegs(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
- USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
-{
- USHORT data,infoflag=0,modeflag;
- USHORT resindex = 0,xres;
-
- if(ModeNo > 0x13) {
- modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- xres = XGI_Pr->ModeResInfo[resindex].HTotal;
- } else {
- modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
- xres = XGI_Pr->StResInfo[resindex].HTotal;
- }
-
- /* Disable DPMS */
- XGI_SetRegAND(XGI_Pr->P3c4,0x1F,0x3F);
-
- data = 0;
- if(ModeNo > 0x13) {
- if(XGI_Pr->ModeType > 0x02) {
- data |= 0x02;
- data |= ((XGI_Pr->ModeType - ModeVGA) << 2);
- }
- if(infoflag & InterlaceMode) data |= 0x20;
- }
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x06,0xC0,data);
-
- data = 0;
- if(infoflag & InterlaceMode) {
- if(xres <= 800) data = 0x0020;
- else if(xres <= 1024) data = 0x0035;
- else data = 0x0048;
- }
- XGI_SetReg(XGI_Pr->P3d4,0x19,(data & 0xFF));
- XGI_SetRegANDOR(XGI_Pr->P3d4,0x1a,0xFC,(data >> 8));
-
- if(modeflag & HalfDCLK) {
- XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x08);
- }
-
- data = 0;
- if(modeflag & LineCompareOff) data = 0x08;
-
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0F,0xB7,data);
- if(XGI_Pr->ModeType == ModeEGA) {
- if(ModeNo > 0x13) {
- XGI_SetRegOR(XGI_Pr->P3c4,0x0F,0x40);
- }
- }
-
- XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xfb);
-
- data = 0x60;
- if(XGI_Pr->ModeType != ModeText) {
- data ^= 0x60;
- if(XGI_Pr->ModeType != ModeEGA) {
- data ^= 0xA0;
- }
- }
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x21,0x1F,data);
-
- XGI_New_SetVCLKState(XGI_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
-}
-
-/*********************************************/
-/* LOAD DAC */
-/*********************************************/
-
-extern const uint8_t XGI_MDA_DAC[];
-extern const uint8_t XGI_CGA_DAC[];
-extern const uint8_t XGI_EGA_DAC[];
-extern const uint8_t XGI_VGA_DAC[];
-
-void
-XGI_New_LoadDAC(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
-{
- USHORT data,data2;
- USHORT time,i,j,k,m,n,o;
- USHORT si,di,bx,dl,al,ah,dh;
- USHORT shiftflag;
- XGIIOADDRESS DACAddr, DACData;
- const uint8_t *table = NULL;
-
- if(ModeNo <= 0x13) {
- data = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
- } else {
- data = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- data &= DACInfoFlag;
- time = 64;
- if(data == 0x00) table = XGI_MDA_DAC;
- if(data == 0x08) table = XGI_CGA_DAC;
- if(data == 0x10) table = XGI_EGA_DAC;
- if(data == 0x18) {
- time = 256;
- table = XGI_VGA_DAC;
- }
- if(time == 256) j = 16;
- else j = time;
-
- if( ( (XGI_Pr->VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
- (XGI_Pr->VBType & VB_NoLCD) ) ||
- (XGI_Pr->VBInfo & SetCRT2ToLCDA) || /* LCDA */
- (!(XGI_Pr->SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
- DACAddr = XGI_Pr->P3c8;
- DACData = XGI_Pr->P3c9;
- shiftflag = 0;
- XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
- } else {
- shiftflag = 1;
- DACAddr = XGI_Pr->Part5Port;
- DACData = XGI_Pr->Part5Port + 1;
- }
-
- XGI_SetRegByte(DACAddr,0x00);
-
- for(i=0; i<j; i++) {
- data = table[i];
- for(k=0; k<3; k++) {
- data2 = 0;
- if(data & 0x01) data2 = 0x2A;
- if(data & 0x02) data2 += 0x15;
- if(shiftflag) data2 <<= 2;
- XGI_SetRegByte(DACData, data2);
- data >>= 2;
- }
- }
-
- if(time == 256) {
- for(i = 16; i < 32; i++) {
- data = table[i];
- if(shiftflag) data <<= 2;
- for(k = 0; k < 3; k++) XGI_SetRegByte(DACData, data);
- }
- si = 32;
- for(m = 0; m < 9; m++) {
- di = si;
- bx = si + 4;
- dl = 0;
- for(n = 0; n < 3; n++) {
- for(o = 0; o < 5; o++) {
- dh = table[si];
- ah = table[di];
- al = table[bx];
- si++;
- XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
- }
- si -= 2;
- for(o = 0; o < 3; o++) {
- dh = table[bx];
- ah = table[di];
- al = table[si];
- si--;
- XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
- }
- dl++;
- } /* for n < 3 */
- si += 5;
- } /* for m < 9 */
- }
-}
-
-/*********************************************/
-/* SET CRT1 REGISTER GROUP */
-/*********************************************/
-
-static void
-XGI_New_SetCRT1Group(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
- USHORT ModeNo, USHORT ModeIdIndex)
-{
- const USHORT StandTableIndex = XGI_GetModePtr(XGI_Pr->SModeIDTable,
- XGI_Pr->ModeType,
- ModeNo, ModeIdIndex);
- USHORT RefreshRateTableIndex = 0;
-
-
-/*
- if(XGI_Pr->SetFlag & LowModeTests) {
- if(XGI_Pr->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
- XGI_New_DisableBridge(XGI_Pr, HwInfo);
- }
- }
-*/
- XGI_SetSeqRegs(StandTableIndex, XGI_Pr);
- XGI_SetMiscRegs(StandTableIndex, XGI_Pr);
- XGI_SetCRTCRegs(StandTableIndex, XGI_Pr);
- XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, XGI_Pr);
- XGI_SetGRCRegs(StandTableIndex, XGI_Pr);
- XGI_ClearExt1Regs(ModeNo, XGI_Pr);
- XGI_ResetCRT1VCLK(XGI_Pr, HwInfo);
-
- XGI_Pr->SetFlag &= (~ProgrammingCRT2);
-
-#ifdef LINUX_XF86
- xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
- XGI_Pr->VBType, XGI_Pr->VBInfo);
-#endif
-
- if(XGI_Pr->VBInfo & SetSimuScanMode) {
- if(XGI_Pr->VBInfo & SetInSlaveMode) {
- XGI_Pr->SetFlag |= ProgrammingCRT2;
- }
- }
-
- if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
- XGI_Pr->SetFlag |= ProgrammingCRT2;
- }
-
- if(!(XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
- XGI_Pr->SetFlag &= ~ProgrammingCRT2;
- }
-
- if(RefreshRateTableIndex != 0xFFFF) {
- XGI_SetSync(RefreshRateTableIndex, XGI_Pr);
- XGI_New_SetCRT1CRTC(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- XGI_New_SetCRT1Offset(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
- XGI_New_SetCRT1VCLK(XGI_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
- }
-
- XGI_New_SetCRT1ModeRegs(XGI_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
-
- XGI_New_LoadDAC(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
-}
-
-
-/*********************************************/
-/* XFree86: SET SCREEN PITCH */
-/*********************************************/
-
-#ifdef LINUX_XF86
-static void
-XGI_SetPitchCRT1(VB_DEVICE_INFO *XGI_Pr, ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- UShort HDisplay = pXGI->scrnPitch >> 3;
-
- XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
-}
-#endif
-
-/*********************************************/
-/* XFree86: XGIBIOSSetMode() */
-/* for non-Dual-Head mode */
-/*********************************************/
-
-#ifdef LINUX_XF86
-BOOLEAN
-XGIBIOSSetMode(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
- ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- UShort ModeNo=0;
- BOOLEAN SetModeRet = FALSE ;
- UShort HDisplay = pXGI->scrnOffset >> 3 ;
-
- ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
- if(!ModeNo) return FALSE;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
-
-#if XGI_USING_BIOS_SETMODE
- PDEBUG(ErrorF("XGI_USING_BIOS_SETMODE \n"));
- if ((pXGI->pVbe != NULL) && (pXGI->pVbe->pInt10 != NULL)) {
- xf86Int10InfoPtr pInt = pXGI->pVbe->pInt10;
-
- if (xf86LoadSubModule(pScrn, "int10")) {
- pInt->num = 0x10;
- pInt->ax = 0x80 | ModeNo;
-
- /* ah = 0, set mode */
- xf86ExecX86int10(pInt);
- SetModeRet = ((pInt->ax & 0x7f) == ModeNo);
- }
- }
- else
-#endif
- {
- PDEBUG(ErrorF("XGI_USING_C_code_SETMODE \n"));
- SetModeRet = XGISetModeNew(HwInfo, XGI_Pr, ModeNo);
- PDEBUG(ErrorF("out_of_C_code_SETMODE \n"));
- }
-
-
- /* SetPitch: Adapt to virtual size & position */
- if (ModeNo > 0x13) {
- XGI_SetReg(XGI_Pr->Part1Port, 0x2f, 1); //yilin for crt2pitch it shoude modify if not colone mode
- XGI_SetReg(XGI_Pr->Part1Port, 0x07, (HDisplay & 0xFF));
- XGI_SetRegANDOR(XGI_Pr->Part1Port, 0x09, 0xF0, (HDisplay>>8));
-
- XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
- }
-
- return SetModeRet;
-}
-
-/*********************************************/
-/* XFree86: XGIBIOSSetModeCRT1() */
-/* for Dual-Head modes */
-/*********************************************/
-
-BOOLEAN
-XGIBIOSSetModeCRT1(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
- ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- USHORT ModeIdIndex, ModeNo=0;
- UCHAR backupreg=0;
- unsigned vga_info;
- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
- UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
-
-
- ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
- if(!ModeNo) return FALSE;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "Setting standard mode 0x%x on CRT1\n", ModeNo);
-
-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
- vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-#else
- vga_info = 0x11;
-#endif
- XGIInitPCIetc(XGI_Pr, HwInfo);
-
- XGI_SetReg(XGI_Pr->P3c4,0x05,0x86);
-
- if (!XGI_SearchModeID(XGI_Pr->SModeIDTable, XGI_Pr->EModeIDTable,
- vga_info, &ModeNo, &ModeIdIndex)) {
- return FALSE;
- }
-
- /* Determine VBType */
- XGI_New_GetVBType(XGI_Pr, HwInfo);
-
- if (XGI_Pr->VBType & VB_XGI301BLV302BLV) {
- backupreg = XGI_GetReg(XGI_Pr->P3d4,0x38);
- }
-
- /* Get VB information (connectors, connected devices) */
- /* (We don't care if the current mode is a CRT2 mode) */
- XGI_SetLowModeTest(XGI_Pr, ModeNo, HwInfo);
-
- /* Set mode on CRT1 */
- XGI_New_SetCRT1Group(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
- /* SetPitch: Adapt to virtual size & position */
- XGI_SetPitchCRT1(XGI_Pr, pScrn);
-
-
- /* Reset CRT2 if changing mode on CRT1 */
- if(IS_DUAL_HEAD(pXGI)) {
- if(pXGIEnt->CRT2ModeNo != -1) {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "(Re-)Setting mode for CRT2\n");
- backupcr30 = XGI_GetReg(XGI_Pr->P3d4,0x30);
- backupcr31 = XGI_GetReg(XGI_Pr->P3d4,0x31);
- backupcr35 = XGI_GetReg(XGI_Pr->P3d4,0x35);
- backupcr38 = XGI_GetReg(XGI_Pr->P3d4,0x38);
- if(XGI_Pr->VBType & VB_XGIVB) {
- /* Backup LUT-enable */
- if(pXGIEnt->CRT2ModeSet) {
- backupp40d = XGI_GetReg(XGI_Pr->Part4Port,0x0d) & 0x08;
- }
- }
- if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
- XGI_SetReg(XGI_Pr->P3d4,0x30,pXGIEnt->CRT2CR30);
- XGI_SetReg(XGI_Pr->P3d4,0x31,pXGIEnt->CRT2CR31);
- XGI_SetReg(XGI_Pr->P3d4,0x35,pXGIEnt->CRT2CR35);
- XGI_SetReg(XGI_Pr->P3d4,0x38,pXGIEnt->CRT2CR38);
- }
-
- XGI_SetReg(XGI_Pr->P3d4,0x30,backupcr30);
- XGI_SetReg(XGI_Pr->P3d4,0x31,backupcr31);
- XGI_SetReg(XGI_Pr->P3d4,0x35,backupcr35);
- XGI_SetReg(XGI_Pr->P3d4,0x38,backupcr38);
- if(XGI_Pr->VBType & VB_XGIVB) {
- XGI_SetRegANDOR(XGI_Pr->Part4Port,0x0d, ~0x08, backupp40d);
- }
- }
- }
-
- /* Warning: From here, the custom mode entries in XGI_Pr are
- * possibly overwritten
- */
-
- XGI_HandleCRT1(XGI_Pr);
-
- XGI_New_DisplayOn(XGI_Pr);
- XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
-
- /* Backup/Set ModeNo in BIOS scratch area */
- XGI_GetSetModeID(pScrn,ModeNo);
-
- return TRUE;
-}
-#endif /* Linux_XF86 */
+/*
+ * Mode initializing code (CRT1 section)
+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+ *
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the Linux kernel, the following license terms
+ * apply:
+ *
+ * * This program is free software; you can redistribute it and/or modify
+ * * it under the terms of the GNU General Public License as published by
+ * * the Free Software Foundation; either version 2 of the named License,
+ * * or any later version.
+ * *
+ * * This program is distributed in the hope that it will be useful,
+ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * * GNU General Public License for more details.
+ * *
+ * * You should have received a copy of the GNU General Public License
+ * * along with this program; if not, write to the Free Software
+ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Otherwise, the following license terms apply:
+ *
+ * * Redistribution and use in source and binary forms, with or without
+ * * modification, are permitted provided that the following conditions
+ * * are met:
+ * * 1) Redistributions of source code must retain the above copyright
+ * * notice, this list of conditions and the following disclaimer.
+ * * 2) Redistributions in binary form must reproduce the above copyright
+ * * notice, this list of conditions and the following disclaimer in the
+ * * documentation and/or other materials provided with the distribution.
+ * * 3) The name of the author may not be used to endorse or promote products
+ * * derived from this software without specific prior written permission.
+ * *
+ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Formerly based on non-functional code-fragements for 300 series by XGI, Inc.
+ * Used by permission.
+ *
+ * TW says: This code looks awful, I know. But please don't do anything about
+ * this otherwise debugging will be hell.
+ * The code is extremely fragile as regards the different chipsets, different
+ * video bridges and combinations thereof. If anything is changed, extreme
+ * care has to be taken that that change doesn't break it for other chipsets,
+ * bridges or combinations thereof.
+ * All comments in this file are by me, regardless if they are marked TW or not.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "init.h"
+#include "vgatypes.h"
+#include "vb_def.h"
+#include "vb_setmode.h"
+
+/*********************************************/
+/* HELPER: Get ModeID */
+/*********************************************/
+/* Jong 09/18/2007; patch to GIT */
+/* VGAEngine is not used; FSTN is always FALSE */
+USHORT
+XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
+ int Depth, int LCDwidth, int LCDheight)
+{
+ USHORT ModeIndex = 0;
+
+ switch(HDisplay)
+ {
+ case 320:
+ if(VDisplay == 200)
+ ModeIndex = ModeIndex_320x200[Depth];
+ else if(VDisplay == 240)
+ {
+ ModeIndex = ModeIndex_320x240[Depth];
+ }
+ break;
+ case 400:
+ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+ break;
+ case 512:
+ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+ break;
+ case 640:
+ if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
+ else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+ break;
+ case 720:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+ else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+ }
+ break;
+ case 768:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+ }
+ break;
+ case 800:
+ if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+ else if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+ }
+ break;
+ case 848:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+ }
+ break;
+ case 856:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+ }
+ break;
+ case 1024:
+ if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+ else if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+ }
+ break;
+ case 1152:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+ }
+ break;
+ case 1280:
+ if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+ else if(VDisplay == 720) {
+ if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
+ ModeIndex = ModeIndex_1280x720[Depth];
+ } else if(!(VBFlags & CRT1_LCDA)) {
+ ModeIndex = ModeIndex_1280x720[Depth];
+ }
+ } else if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
+ else if(VDisplay == 768) {
+ ModeIndex = ModeIndex_310_1280x768[Depth];
+ }
+ }
+ break;
+ case 1360:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+ }
+ break;
+ case 1400:
+ break;
+ case 1600:
+ if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+ break;
+ case 1680:
+ break;
+ case 1920:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+ }
+ break;
+ case 2048:
+ if(!(VBFlags & CRT1_LCDA)) {
+ if(VDisplay == 1536) {
+ ModeIndex = ModeIndex_310_2048x1536[Depth];
+ }
+ }
+ break;
+ }
+
+ return(ModeIndex);
+}
+
+/*********************************************/
+/* HELPER: SetReg, GetReg */
+/*********************************************/
+
+void
+XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data)
+{
+ outb(port,index);
+ outb(port + 1,data);
+}
+
+void
+XGI_SetRegByte(XGIIOADDRESS port, USHORT data)
+{
+ outb(port,data);
+}
+
+void
+XGI_SetRegShort(XGIIOADDRESS port, USHORT data)
+{
+ outw(port,data);
+}
+
+void
+XGI_SetRegLong(XGIIOADDRESS port, ULONG data)
+{
+ outl(port,data);
+}
+
+UCHAR
+XGI_GetReg(XGIIOADDRESS port, USHORT index)
+{
+ outb(port,index);
+ return inb(port + 1);
+}
+
+UCHAR
+XGI_GetRegByte(XGIIOADDRESS port)
+{
+ return inb(port);
+}
+
+USHORT
+XGI_GetRegShort(XGIIOADDRESS port)
+{
+ return inw(port);
+}
+
+ULONG
+XGI_GetRegLong(XGIIOADDRESS port)
+{
+ return inl(port);
+}
+
+void
+XGI_SetRegANDOR(XGIIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+{
+ USHORT temp;
+
+ temp = XGI_GetReg(Port,Index);
+ temp = (temp & (DataAND)) | DataOR;
+ XGI_SetReg(Port,Index,temp);
+}
+
+void
+XGI_SetRegAND(XGIIOADDRESS Port,USHORT Index,USHORT DataAND)
+{
+ USHORT temp;
+
+ temp = XGI_GetReg(Port,Index);
+ temp &= DataAND;
+ XGI_SetReg(Port,Index,temp);
+}
+
+void
+XGI_SetRegOR(XGIIOADDRESS Port,USHORT Index,USHORT DataOR)
+{
+ USHORT temp;
+
+ temp = XGI_GetReg(Port,Index);
+ temp |= DataOR;
+ XGI_SetReg(Port,Index,temp);
+}
+
+/*********************************************/
+/* HELPER: DisplayOn, DisplayOff */
+/*********************************************/
+
+void
+XGI_New_DisplayOn(VB_DEVICE_INFO *XGI_Pr)
+{
+ XGI_SetRegAND(XGI_Pr->P3c4,0x01,0xDF);
+}
+
+void
+XGI_New_DisplayOff(VB_DEVICE_INFO *XGI_Pr)
+{
+ XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x20);
+}
+
+/*********************************************/
+/* HELPER: Init PCI & Engines */
+/*********************************************/
+
+static void
+XGIInitPCIetc(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
+{
+ CARD8 bForce=0x00; /* Jong 01/07/2008; force to disable 2D */
+
+ switch(HwInfo->jChipType) {
+ case XG40:
+ case XG42:
+ case XG20:
+ case XG21:
+ XGI_SetReg(XGI_Pr->P3c4,0x20,0xa1);
+ /* - Enable 2D (0x40)
+ * - Enable 3D (0x02)
+ * - Enable 3D vertex command fetch (0x10)
+ * - Enable 3D command parser (0x08)
+ * - Enable 3D G/L transformation engine (0x80)
+ */
+ XGI_SetRegOR(XGI_Pr->P3c4, 0x1E,
+ SR1E_ENABLE_3D_TRANSFORM_ENGINE
+ | SR1E_ENABLE_2D
+ | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
+ | SR1E_ENABLE_3D_COMMAND_PARSER
+ | SR1E_ENABLE_3D);
+
+ /* Jong 01/07/2008; support forcing to disable 2D engine */
+ if(HwInfo->jChipType == XG21)
+ {
+ inXGIIDXREG(XGI_Pr->P3c4, 0x3A, bForce) ;
+ bForce &= 0x40;
+
+ if(bForce != 0x00)
+ XGI_SetRegAND(XGI_Pr->P3c4,0x1E,0xBF);
+ }
+
+ break;
+ }
+}
+
+/*********************************************/
+/* HELPER: GetVBType */
+/*********************************************/
+
+void
+XGI_New_GetVBType(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
+{
+ USHORT flag=0, rev=0, nolcd=0;
+
+ XGI_Pr->VBType = 0;
+
+ flag = XGI_GetReg(XGI_Pr->Part4Port,0x00);
+PDEBUG(ErrorF("GetVBType: part4_0: %x \n",flag)); //yilin
+ if(flag > 3) return;
+
+ rev = XGI_GetReg(XGI_Pr->Part4Port,0x01);
+PDEBUG(ErrorF("GetVBType: part4_1: %x \n",rev)); //yilin
+
+ if(flag >= 2) {
+ XGI_Pr->VBType = VB_XGI302B;
+ } else if(flag == 1) {
+ if(rev >= 0xC0) {
+ XGI_Pr->VBType = VB_XGI301C;
+ } else if(rev >= 0xB0) {
+ XGI_Pr->VBType = VB_XGI301B;
+ /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
+ nolcd = XGI_GetReg(XGI_Pr->Part4Port,0x23);
+ if(!(nolcd & 0x02)) XGI_Pr->VBType |= VB_NoLCD;
+ } else {
+ XGI_Pr->VBType = VB_XGI301;
+ }
+ }
+ if(XGI_Pr->VBType & (VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
+ if(rev >= 0xE0) {
+ flag = XGI_GetReg(XGI_Pr->Part4Port,0x39);
+ if(flag == 0xff) XGI_Pr->VBType = VB_XGI302LV;
+ else XGI_Pr->VBType = VB_XGI302ELV;
+ } else if(rev >= 0xD0) {
+ XGI_Pr->VBType = VB_XGI301LV;
+ }
+ }
+PDEBUG(ErrorF("GetVBType: XGI_Pr->VBType=%x \n",XGI_Pr->VBType)); //yilin
+}
+
+/*********************************************/
+/* HELPER: SearchModeID */
+/*********************************************/
+
+BOOLEAN
+XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
+ const XGI_ExtStruct *EModeIDTable,
+ unsigned char VGAINFO, USHORT *ModeNo, USHORT *ModeIdIndex)
+{
+ if (*ModeNo <= 0x13) {
+ if ((*ModeNo) <= 0x05)
+ (*ModeNo) |= 0x01;
+
+ for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
+ if (SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo))
+ break;
+
+ if (SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
+ return FALSE;
+ }
+
+ if (*ModeNo == 0x07) {
+ if (VGAINFO & 0x10)
+ (*ModeIdIndex)++; /* 400 lines */
+ /* else 350 lines */
+ }
+
+ if (*ModeNo <= 0x03) {
+ if (!(VGAINFO & 0x80))
+ (*ModeIdIndex)++;
+
+ if (VGAINFO & 0x10)
+ (*ModeIdIndex)++; /* 400 lines */
+ /* else 350 lines */
+ }
+ /* else 200 lines */
+ }
+ else {
+
+ for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
+ if (EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo))
+ break;
+
+ if (EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/*********************************************/
+/* HELPER: GetModePtr */
+/*********************************************/
+
+UCHAR
+XGI_GetModePtr(const XGI_StStruct *SModeIDTable, unsigned ModeType,
+ USHORT ModeNo, USHORT ModeIdIndex)
+{
+ return (ModeNo <= 0x13)
+ ? SModeIDTable[ModeIdIndex].St_StTableIndex
+ : ((ModeType <= 0x02) ? 0x1B /* 02 -> ModeEGA */ : 0x0F);
+}
+
+
+/*********************************************/
+/* HELPER: LowModeTests */
+/*********************************************/
+
+static BOOLEAN
+XGI_DoLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
+{
+ USHORT temp,temp1,temp2;
+
+ if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+ return(1);
+ temp = XGI_GetReg(XGI_Pr->P3d4,0x11);
+ XGI_SetRegOR(XGI_Pr->P3d4,0x11,0x80);
+ temp1 = XGI_GetReg(XGI_Pr->P3d4,0x00);
+ XGI_SetReg(XGI_Pr->P3d4,0x00,0x55);
+ temp2 = XGI_GetReg(XGI_Pr->P3d4,0x00);
+ XGI_SetReg(XGI_Pr->P3d4,0x00,temp1);
+ XGI_SetReg(XGI_Pr->P3d4,0x11,temp);
+ if (temp2 == 0x55)
+ return(0);
+ else
+ return(1);
+}
+
+static void
+XGI_SetLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
+{
+ if(XGI_DoLowModeTest(XGI_Pr, ModeNo, HwInfo)) {
+ XGI_Pr->SetFlag |= LowModeTests;
+ }
+}
+
+static void
+XGI_HandleCRT1(VB_DEVICE_INFO *XGI_Pr)
+{
+ XGI_SetRegAND(XGI_Pr->P3d4, 0x53, 0xbf);
+}
+
+/*********************************************/
+/* HELPER: GetOffset */
+/*********************************************/
+
+USHORT
+XGI_New_GetOffset(VB_DEVICE_INFO *XGI_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwInfo)
+{
+ USHORT xres, temp, colordepth, infoflag;
+
+ infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ xres = XGI_Pr->RefIndex[RefreshRateTableIndex].XRes;
+
+ colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, XGI_Pr);
+
+ temp = xres / 16;
+ if(infoflag & InterlaceMode) temp <<= 1;
+ temp *= colordepth;
+ if(xres % 16) {
+ colordepth >>= 1;
+ temp += colordepth;
+ }
+
+ return(temp);
+}
+
+/*********************************************/
+/* RESET VCLK */
+/*********************************************/
+
+static void
+XGI_ResetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
+{
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xCF,0x20);
+ XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[1].SR2B);
+ XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[1].SR2C);
+ XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xcf,0x10);
+ XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[0].SR2B);
+ XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[0].SR2C);
+ XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
+}
+
+/*********************************************/
+/* CRTC/2 */
+/*********************************************/
+
+static void
+XGI_New_SetCRT1CRTC(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwInfo)
+{
+ UCHAR index;
+ USHORT temp,i,j,modeflag;
+
+ XGI_SetRegAND(XGI_Pr->P3d4,0x11,0x7f); /* unlock cr0-7 */
+
+ if(ModeNo <= 0x13) {
+ modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+ for(i=0,j=0;i<=7;i++,j++) {
+ XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+ }
+ for(j=0x10;i<=10;i++,j++) {
+ XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+ }
+ for(j=0x15;i<=12;i++,j++) {
+ XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+ }
+ for(j=0x0A;i<=15;i++,j++) {
+ XGI_SetReg(XGI_Pr->P3c4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+ }
+
+ temp = XGI_Pr->XGINEWUB_CRT1Table[index].CR[16] & 0xE0;
+ XGI_SetReg(XGI_Pr->P3c4,0x0E,temp);
+
+ temp = ((XGI_Pr->XGINEWUB_CRT1Table[index].CR[16]) & 0x01) << 5;
+ if(modeflag & DoubleScanMode) temp |= 0x80;
+ XGI_SetRegANDOR(XGI_Pr->P3d4,0x09,0x5F,temp);
+
+ if(XGI_Pr->ModeType > ModeVGA) XGI_SetReg(XGI_Pr->P3d4,0x14,0x4F);
+}
+
+/*********************************************/
+/* OFFSET & PITCH */
+/*********************************************/
+/* (partly overruled by SetPitch() in XF86) */
+/*********************************************/
+
+static void
+XGI_New_SetCRT1Offset(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwInfo)
+{
+ USHORT temp, DisplayUnit, infoflag;
+
+ infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ DisplayUnit = XGI_New_GetOffset(XGI_Pr,ModeNo,ModeIdIndex,
+ RefreshRateTableIndex,HwInfo);
+
+ temp = (DisplayUnit >> 8) & 0x0f;
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,temp);
+
+ temp = DisplayUnit & 0xFF;
+ XGI_SetReg(XGI_Pr->P3d4,0x13,temp);
+
+ if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+
+ DisplayUnit <<= 5;
+ temp = (DisplayUnit & 0xff00) >> 8;
+ if(DisplayUnit & 0xff) temp++;
+ temp++;
+ XGI_SetReg(XGI_Pr->P3c4,0x10,temp);
+}
+
+/*********************************************/
+/* VCLK */
+/*********************************************/
+
+static void
+XGI_New_SetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwInfo, USHORT RefreshRateTableIndex)
+{
+ USHORT index=0, clka, clkb;
+
+ if((XGI_Pr->VBType & VB_XGI301BLV302BLV) && (XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
+ clka = XGI_Pr->VBVCLKData[index].Part4_A;
+ clkb = XGI_Pr->VBVCLKData[index].Part4_B;
+ } else {
+ clka = XGI_Pr->VCLKData[index].SR2B;
+ clkb = XGI_Pr->VCLKData[index].SR2C;
+ }
+
+ XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xCF);
+ XGI_SetReg(XGI_Pr->P3c4,0x2B,clka);
+ XGI_SetReg(XGI_Pr->P3c4,0x2C,clkb);
+ XGI_SetReg(XGI_Pr->P3c4,0x2D,0x01);
+}
+
+/*********************************************/
+/* MODE REGISTERS */
+/*********************************************/
+
+static void
+XGI_New_SetVCLKState(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+ USHORT ModeNo, USHORT RefreshRateTableIndex,
+ USHORT ModeIdIndex)
+{
+ USHORT data=0, VCLK=0, index=0;
+
+ if(ModeNo > 0x13) {
+ VCLK = XGI_Pr->VCLKData[index].CLOCK;
+ }
+
+ if(VCLK >= 166)
+ data |= 0x0c;
+
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x32,0xf3,data);
+
+ if(VCLK >= 166) {
+ XGI_SetRegAND(XGI_Pr->P3c4,0x1f,0xe7);
+ }
+
+ /* DAC speed */
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x07,0xE8,0x10);
+}
+
+static void
+XGI_New_SetCRT1ModeRegs(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+ USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+{
+ USHORT data,infoflag=0,modeflag;
+ USHORT resindex = 0,xres;
+
+ if(ModeNo > 0x13) {
+ modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ xres = XGI_Pr->ModeResInfo[resindex].HTotal;
+ } else {
+ modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ xres = XGI_Pr->StResInfo[resindex].HTotal;
+ }
+
+ /* Disable DPMS */
+ XGI_SetRegAND(XGI_Pr->P3c4,0x1F,0x3F);
+
+ data = 0;
+ if(ModeNo > 0x13) {
+ if(XGI_Pr->ModeType > 0x02) {
+ data |= 0x02;
+ data |= ((XGI_Pr->ModeType - ModeVGA) << 2);
+ }
+ if(infoflag & InterlaceMode) data |= 0x20;
+ }
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x06,0xC0,data);
+
+ data = 0;
+ if(infoflag & InterlaceMode) {
+ if(xres <= 800) data = 0x0020;
+ else if(xres <= 1024) data = 0x0035;
+ else data = 0x0048;
+ }
+ XGI_SetReg(XGI_Pr->P3d4,0x19,(data & 0xFF));
+ XGI_SetRegANDOR(XGI_Pr->P3d4,0x1a,0xFC,(data >> 8));
+
+ if(modeflag & HalfDCLK) {
+ XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x08);
+ }
+
+ data = 0;
+ if(modeflag & LineCompareOff) data = 0x08;
+
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0F,0xB7,data);
+ if(XGI_Pr->ModeType == ModeEGA) {
+ if(ModeNo > 0x13) {
+ XGI_SetRegOR(XGI_Pr->P3c4,0x0F,0x40);
+ }
+ }
+
+ XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xfb);
+
+ data = 0x60;
+ if(XGI_Pr->ModeType != ModeText) {
+ data ^= 0x60;
+ if(XGI_Pr->ModeType != ModeEGA) {
+ data ^= 0xA0;
+ }
+ }
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x21,0x1F,data);
+
+ XGI_New_SetVCLKState(XGI_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
+}
+
+/*********************************************/
+/* LOAD DAC */
+/*********************************************/
+
+extern const uint8_t XGI_MDA_DAC[];
+extern const uint8_t XGI_CGA_DAC[];
+extern const uint8_t XGI_EGA_DAC[];
+extern const uint8_t XGI_VGA_DAC[];
+
+void
+XGI_New_LoadDAC(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+ USHORT ModeNo, USHORT ModeIdIndex)
+{
+ USHORT data,data2;
+ USHORT time,i,j,k,m,n,o;
+ USHORT si,di,bx,dl,al,ah,dh;
+ USHORT shiftflag;
+ XGIIOADDRESS DACAddr, DACData;
+ const uint8_t *table = NULL;
+
+ if(ModeNo <= 0x13) {
+ data = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ } else {
+ data = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ data &= DACInfoFlag;
+ time = 64;
+ if(data == 0x00) table = XGI_MDA_DAC;
+ if(data == 0x08) table = XGI_CGA_DAC;
+ if(data == 0x10) table = XGI_EGA_DAC;
+ if(data == 0x18) {
+ time = 256;
+ table = XGI_VGA_DAC;
+ }
+ if(time == 256) j = 16;
+ else j = time;
+
+ if( ( (XGI_Pr->VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
+ (XGI_Pr->VBType & VB_NoLCD) ) ||
+ (XGI_Pr->VBInfo & SetCRT2ToLCDA) || /* LCDA */
+ (!(XGI_Pr->SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
+ DACAddr = XGI_Pr->P3c8;
+ DACData = XGI_Pr->P3c9;
+ shiftflag = 0;
+ XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
+ } else {
+ shiftflag = 1;
+ DACAddr = XGI_Pr->Part5Port;
+ DACData = XGI_Pr->Part5Port + 1;
+ }
+
+ XGI_SetRegByte(DACAddr,0x00);
+
+ for(i=0; i<j; i++) {
+ data = table[i];
+ for(k=0; k<3; k++) {
+ data2 = 0;
+ if(data & 0x01) data2 = 0x2A;
+ if(data & 0x02) data2 += 0x15;
+ if(shiftflag) data2 <<= 2;
+ XGI_SetRegByte(DACData, data2);
+ data >>= 2;
+ }
+ }
+
+ if(time == 256) {
+ for(i = 16; i < 32; i++) {
+ data = table[i];
+ if(shiftflag) data <<= 2;
+ for(k = 0; k < 3; k++) XGI_SetRegByte(DACData, data);
+ }
+ si = 32;
+ for(m = 0; m < 9; m++) {
+ di = si;
+ bx = si + 4;
+ dl = 0;
+ for(n = 0; n < 3; n++) {
+ for(o = 0; o < 5; o++) {
+ dh = table[si];
+ ah = table[di];
+ al = table[bx];
+ si++;
+ XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
+ }
+ si -= 2;
+ for(o = 0; o < 3; o++) {
+ dh = table[bx];
+ ah = table[di];
+ al = table[si];
+ si--;
+ XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
+ }
+ dl++;
+ } /* for n < 3 */
+ si += 5;
+ } /* for m < 9 */
+ }
+}
+
+/*********************************************/
+/* SET CRT1 REGISTER GROUP */
+/*********************************************/
+
+static void
+XGI_New_SetCRT1Group(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+ USHORT ModeNo, USHORT ModeIdIndex)
+{
+ const USHORT StandTableIndex = XGI_GetModePtr(XGI_Pr->SModeIDTable,
+ XGI_Pr->ModeType,
+ ModeNo, ModeIdIndex);
+ USHORT RefreshRateTableIndex = 0;
+
+
+/*
+ if(XGI_Pr->SetFlag & LowModeTests) {
+ if(XGI_Pr->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+ XGI_New_DisableBridge(XGI_Pr, HwInfo);
+ }
+ }
+*/
+ XGI_SetSeqRegs(StandTableIndex, XGI_Pr);
+ XGI_SetMiscRegs(StandTableIndex, XGI_Pr);
+ XGI_SetCRTCRegs(StandTableIndex, XGI_Pr);
+ XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, XGI_Pr);
+ XGI_SetGRCRegs(StandTableIndex, XGI_Pr);
+ XGI_ClearExt1Regs(ModeNo, XGI_Pr);
+ XGI_ResetCRT1VCLK(XGI_Pr, HwInfo);
+
+ XGI_Pr->SetFlag &= (~ProgrammingCRT2);
+
+#ifdef LINUX_XF86
+ xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+ XGI_Pr->VBType, XGI_Pr->VBInfo);
+#endif
+
+ if(XGI_Pr->VBInfo & SetSimuScanMode) {
+ if(XGI_Pr->VBInfo & SetInSlaveMode) {
+ XGI_Pr->SetFlag |= ProgrammingCRT2;
+ }
+ }
+
+ if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
+ XGI_Pr->SetFlag |= ProgrammingCRT2;
+ }
+
+ if(!(XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
+ XGI_Pr->SetFlag &= ~ProgrammingCRT2;
+ }
+
+ if(RefreshRateTableIndex != 0xFFFF) {
+ XGI_SetSync(RefreshRateTableIndex, XGI_Pr);
+ XGI_New_SetCRT1CRTC(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ XGI_New_SetCRT1Offset(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+ XGI_New_SetCRT1VCLK(XGI_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+ }
+
+ XGI_New_SetCRT1ModeRegs(XGI_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+
+ XGI_New_LoadDAC(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
+}
+
+
+/*********************************************/
+/* XFree86: SET SCREEN PITCH */
+/*********************************************/
+
+#ifdef LINUX_XF86
+static void
+XGI_SetPitchCRT1(VB_DEVICE_INFO *XGI_Pr, ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ UShort HDisplay = pXGI->scrnPitch >> 3;
+
+ XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
+}
+#endif
+
+/*********************************************/
+/* XFree86: XGIBIOSSetMode() */
+/* for non-Dual-Head mode */
+/*********************************************/
+
+#ifdef LINUX_XF86
+BOOLEAN
+XGIBIOSSetMode(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+ ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ UShort ModeNo=0;
+ BOOLEAN SetModeRet = FALSE ;
+ UShort HDisplay = pXGI->scrnOffset >> 3 ;
+
+ ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
+ if(!ModeNo) return FALSE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+
+#if XGI_USING_BIOS_SETMODE
+ PDEBUG(ErrorF("XGI_USING_BIOS_SETMODE \n"));
+ if ((pXGI->pVbe != NULL) && (pXGI->pVbe->pInt10 != NULL)) {
+ xf86Int10InfoPtr pInt = pXGI->pVbe->pInt10;
+
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ pInt->num = 0x10;
+ pInt->ax = 0x80 | ModeNo;
+
+ /* ah = 0, set mode */
+ xf86ExecX86int10(pInt);
+ SetModeRet = ((pInt->ax & 0x7f) == ModeNo);
+ }
+ }
+ else
+#endif
+ {
+ PDEBUG(ErrorF("XGI_USING_C_code_SETMODE \n"));
+ /* Jong 08/21/2007; support external modeline in X configuration file */
+ /* ------------------------------------------------------------------ */
+ HwInfo->BPP = pScrn->bitsPerPixel;
+ HwInfo->Frequency = mode->VRefresh;
+ HwInfo->Horizontal_ACTIVE = mode->HDisplay;
+ HwInfo->Vertical_ACTIVE = mode->VDisplay;
+ HwInfo->Interlace=FALSE;
+
+ if(mode->type == M_T_USERDEF) /* custom mode */
+ {
+ HwInfo->SpecifyTiming = TRUE;
+ HwInfo->Horizontal_FP = mode->HSyncStart - mode->HDisplay; /* HSyncStart - HDisplay */
+ HwInfo->Horizontal_BP = mode->HTotal - mode->HSyncEnd; /* HTotal - HSyncEnd */
+ HwInfo->Horizontal_SYNC = mode->HSyncEnd - mode->HSyncStart; /* HSyncEnd - HSyncStart */
+ HwInfo->Vertical_FP = mode->VSyncStart - mode->VDisplay;
+ HwInfo->Vertical_BP = mode->VTotal - mode->VSyncEnd;
+ HwInfo->Vertical_SYNC = mode->VSyncEnd - mode->VSyncStart;
+ HwInfo->DCLK = mode->Clock;
+ }
+ else
+ {
+ HwInfo->SpecifyTiming = FALSE;
+ }
+ /* ------------------------------------------------------------------ */
+
+ SetModeRet = XGISetModeNew(HwInfo, XGI_Pr, ModeNo);
+ PDEBUG(ErrorF("out_of_C_code_SETMODE \n"));
+ }
+
+
+ /* SetPitch: Adapt to virtual size & position */
+ if (ModeNo > 0x13) {
+ XGI_SetReg(XGI_Pr->Part1Port, 0x2f, 1); //yilin for crt2pitch it shoude modify if not colone mode
+ XGI_SetReg(XGI_Pr->Part1Port, 0x07, (HDisplay & 0xFF));
+ XGI_SetRegANDOR(XGI_Pr->Part1Port, 0x09, 0xF0, (HDisplay>>8));
+
+ XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
+ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
+ }
+
+ return SetModeRet;
+}
+
+/*********************************************/
+/* XFree86: XGIBIOSSetModeCRT1() */
+/* for Dual-Head modes */
+/*********************************************/
+
+BOOLEAN
+XGIBIOSSetModeCRT1(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+ ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ USHORT ModeIdIndex, ModeNo=0;
+ UCHAR backupreg=0;
+ unsigned vga_info;
+ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+ UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
+
+
+ ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
+ if(!ModeNo) return FALSE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "Setting standard mode 0x%x on CRT1\n", ModeNo);
+
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+ vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+#else
+ vga_info = 0x11;
+#endif
+ XGIInitPCIetc(XGI_Pr, HwInfo);
+
+ XGI_SetReg(XGI_Pr->P3c4,0x05,0x86);
+
+ if (!XGI_SearchModeID(XGI_Pr->SModeIDTable, XGI_Pr->EModeIDTable,
+ vga_info, &ModeNo, &ModeIdIndex)) {
+ return FALSE;
+ }
+
+ /* Determine VBType */
+ XGI_New_GetVBType(XGI_Pr, HwInfo);
+
+ if (XGI_Pr->VBType & VB_XGI301BLV302BLV) {
+ backupreg = XGI_GetReg(XGI_Pr->P3d4,0x38);
+ }
+
+ /* Get VB information (connectors, connected devices) */
+ /* (We don't care if the current mode is a CRT2 mode) */
+ XGI_SetLowModeTest(XGI_Pr, ModeNo, HwInfo);
+
+ /* Set mode on CRT1 */
+ XGI_New_SetCRT1Group(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
+ /* SetPitch: Adapt to virtual size & position */
+ XGI_SetPitchCRT1(XGI_Pr, pScrn);
+
+
+ /* Reset CRT2 if changing mode on CRT1 */
+ if(IS_DUAL_HEAD(pXGI)) {
+ if(pXGIEnt->CRT2ModeNo != -1) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "(Re-)Setting mode for CRT2\n");
+ backupcr30 = XGI_GetReg(XGI_Pr->P3d4,0x30);
+ backupcr31 = XGI_GetReg(XGI_Pr->P3d4,0x31);
+ backupcr35 = XGI_GetReg(XGI_Pr->P3d4,0x35);
+ backupcr38 = XGI_GetReg(XGI_Pr->P3d4,0x38);
+ if(XGI_Pr->VBType & VB_XGIVB) {
+ /* Backup LUT-enable */
+ if(pXGIEnt->CRT2ModeSet) {
+ backupp40d = XGI_GetReg(XGI_Pr->Part4Port,0x0d) & 0x08;
+ }
+ }
+ if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
+ XGI_SetReg(XGI_Pr->P3d4,0x30,pXGIEnt->CRT2CR30);
+ XGI_SetReg(XGI_Pr->P3d4,0x31,pXGIEnt->CRT2CR31);
+ XGI_SetReg(XGI_Pr->P3d4,0x35,pXGIEnt->CRT2CR35);
+ XGI_SetReg(XGI_Pr->P3d4,0x38,pXGIEnt->CRT2CR38);
+ }
+
+ XGI_SetReg(XGI_Pr->P3d4,0x30,backupcr30);
+ XGI_SetReg(XGI_Pr->P3d4,0x31,backupcr31);
+ XGI_SetReg(XGI_Pr->P3d4,0x35,backupcr35);
+ XGI_SetReg(XGI_Pr->P3d4,0x38,backupcr38);
+ if(XGI_Pr->VBType & VB_XGIVB) {
+ XGI_SetRegANDOR(XGI_Pr->Part4Port,0x0d, ~0x08, backupp40d);
+ }
+ }
+ }
+
+ /* Warning: From here, the custom mode entries in XGI_Pr are
+ * possibly overwritten
+ */
+
+ XGI_HandleCRT1(XGI_Pr);
+
+ XGI_New_DisplayOn(XGI_Pr);
+ XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
+
+ /* Backup/Set ModeNo in BIOS scratch area */
+ XGI_GetSetModeID(pScrn,ModeNo);
+
+ return TRUE;
+}
+#endif /* Linux_XF86 */
diff --git a/src/init.h b/src/init.h
index 5e668dc..32f61ee 100644
--- a/src/init.h
+++ b/src/init.h
@@ -84,6 +84,7 @@
/* Mode numbers */
static const USHORT ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
static const USHORT ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
+static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
static const USHORT ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
static const USHORT ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
static const USHORT ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
diff --git a/src/vb_def.h b/src/vb_def.h
index ff7d15d..5f43dd5 100644
--- a/src/vb_def.h
+++ b/src/vb_def.h
@@ -456,6 +456,11 @@
#define VB_XGI301LV 0x0008
#define VB_XGI302LV 0x0010
#define VB_LVDS_NS 0x0001 /* 3rd party chip */
+
+/* Jong 10/04/2007; merge code */
+#define VB_CH7017 0x0002
+#define VB_CH7007 0x0080 /* [Billy] 07/05/03 */
+
/* #define VB_LVDS_SI 0x0004 */
#define ModeInfoFlag 0x0007
@@ -973,6 +978,19 @@
#define CHTVVCLK26_2 0x57
#define CHTVVCLK39 0x58
#define CHTVVCLK36 0x59
+
+/* Jong 10/04/2007; merge code */
+#define CH7007TVVCLK30_2 0x00 /* [Billy] 2007/05/18 For CH7007 */
+#define CH7007TVVCLK28_1 0x01
+#define CH7007TVVCLK43_6 0x02
+#define CH7007TVVCLK26_4 0x03
+#define CH7007TVVCLK24_6 0x04
+#define CH7007TVVCLK47_8 0x05
+#define CH7007TVVCLK31_5 0x06
+#define CH7007TVVCLK26_2 0x07
+#define CH7007TVVCLK39 0x08
+#define CH7007TVVCLK36 0x09
+
#define RES320x200 0x00
#define RES320x240 0x01
#define RES400x300 0x02
diff --git a/src/vb_ext.c b/src/vb_ext.c
index fa2a4f3..e8a16ce 100644
--- a/src/vb_ext.c
+++ b/src/vb_ext.c
@@ -76,6 +76,25 @@ static int XGINew_Is301B(PVB_DEVICE_INFO pVBInfo)
return !(XGI_GetReg((XGIIOADDRESS)pVBInfo->Part4Port, 0x01) > 0x0B0);
}
+/* --------------------------------------------------------------------- */
+/* Function : XGI_Is301C */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN XGI_Is301C( PVB_DEVICE_INFO pVBInfo )
+{
+ if ( ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->Part4Port , 0x01 ) & 0xF0 ) == 0xC0 )
+ return( 1 ) ;
+
+ if ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
+ {
+ if ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->Part4Port , 0x39 ) == 0xE0 )
+ return( 1 ) ;
+ }
+
+ return( 0 ) ;
+}
/* --------------------------------------------------------------------- */
/* Function : XGINew_Sense */
diff --git a/src/vb_ext.h b/src/vb_ext.h
index 3477fce..9aaf447 100644
--- a/src/vb_ext.h
+++ b/src/vb_ext.h
@@ -27,7 +27,34 @@
#ifndef _VBEXT_
#define _VBEXT_
+/* Jong 10/04/2007; merge code */
+struct DWORDREGS {
+ ULONG Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
+};
+
+/* Jong 10/04/2007; merge code */
+struct WORDREGS {
+ USHORT ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si, hi_si, di ,hi_di, bp, hi_bp;
+};
+
+/* Jong 10/04/2007; merge code */
+struct BYTEREGS {
+ UCHAR al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch, hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
+};
+
+/* Jong 10/04/2007; merge code */
+typedef union _X86_REGS {
+ struct DWORDREGS e;
+ struct WORDREGS x;
+ struct BYTEREGS h;
+} X86_REGS, *PX86_REGS;
+
extern void XGI_GetSenseStatus(PXGI_HW_DEVICE_INFO HwDeviceExtension,
PVB_DEVICE_INFO pVBInfo);
+/* Jong 10/04/2007; merge code */
+extern void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
+extern void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
+extern USHORT XGINew_SenseLCD(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo);
+
#endif
diff --git a/src/vb_init.c b/src/vb_init.c
index 9ba85bb..7e4ba77 100644
--- a/src/vb_init.c
+++ b/src/vb_init.c
@@ -1,2960 +1,3742 @@
-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "osdef.h"
-#include "vgatypes.h"
-
-
-#ifdef LINUX_KERNEL
-#include <linux/version.h>
-#include <linux/types.h>
-#include <linux/delay.h> /* udelay */
-#include "XGIfb.h"
-#endif
-
-#include "vb_def.h"
-#include "vb_struct.h"
-#include "vb_setmode.h"
-#include "vb_init.h"
-#include "vb_ext.h"
-
-#ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86PciInfo.h"
-#include "xgi.h"
-#include "xgi_regs.h"
-#endif
-
-#ifdef LINUX_KERNEL
-#include <asm/io.h>
-#include <linux/types.h>
-#endif
-
-
-
-
-static UCHAR XGINew_ChannelAB;
-static UCHAR XGINew_DataBusWidth;
-
-USHORT XGINew_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
- {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
- {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
- {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
- {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
- {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
- {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
- {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
- {0x09,0x08,0x01,0x01,0x00}};
-
-static const USHORT XGINew_SDRDRAM_TYPE[13][5]=
-{
- { 2,12, 9,64,0x35},
- { 1,13, 9,64,0x44},
- { 2,12, 8,32,0x31},
- { 2,11, 9,32,0x25},
- { 1,12, 9,32,0x34},
- { 1,13, 8,32,0x40},
- { 2,11, 8,16,0x21},
- { 1,12, 8,16,0x30},
- { 1,11, 9,16,0x24},
- { 1,11, 8, 8,0x20},
- { 2, 9, 8, 4,0x01},
- { 1,10, 8, 4,0x10},
- { 1, 9, 8, 2,0x00}
-};
-
-static const USHORT XGINew_DDRDRAM_TYPE[4][5]=
-{
- { 2,12, 9,64,0x35},
- { 2,12, 8,32,0x31},
- { 2,11, 8,16,0x21},
- { 2, 9, 8, 4,0x01}
-};
-
-static const USHORT XGINew_DDRDRAM_TYPE340[4][5]=
-{
- { 2,13, 9,64,0x45},
- { 2,12, 9,32,0x35},
- { 2,12, 8,16,0x31},
- { 2,11, 8, 8,0x21}
-};
-
-static void XGINew_SetDRAMSize_340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static void XGINew_SetDRAMSize_XG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static void XGINew_SetMemoryClock(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static void XGINew_SetDRAMDefaultRegister340(PXGI_HW_DEVICE_INFO, USHORT,
- PVB_DEVICE_INFO);
-static void XGINew_SetDRAMDefaultRegisterXG45(PXGI_HW_DEVICE_INFO, USHORT,
- PVB_DEVICE_INFO);
-static UCHAR XGINew_Get340DRAMType(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-
-static int XGINew_SetDDRChannel(int index, UCHAR ChannelNo,
- UCHAR XGINew_ChannelAB, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo);
-
-static void XGINew_SetDRAMSizingType(int index ,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-static USHORT XGINew_SetDRAMSizeReg(int index,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-
-static int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-
-static int XGINew_CheckRanks(int RankNo, int index,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-static int XGINew_CheckRank(int RankNo, int index,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-static int XGINew_CheckDDRRank(int RankNo, int index,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-static int XGINew_CheckDDRRanks(int RankNo, int index,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
-
-static int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo);
-static int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo);
-
-static int XGINew_DDRSizing340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static int XGINew_DDRSizingXG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static int XGINew_SDRSizing(PVB_DEVICE_INFO);
-static int XGINew_DDRSizing(PVB_DEVICE_INFO);
-
-static void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo);
-static void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo);
-static void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
-static void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
-static void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
-static void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT Port, PVB_DEVICE_INFO pVBInfo);
-static void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT Port, PVB_DEVICE_INFO pVBInfo);
-static void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT Port, PVB_DEVICE_INFO pVBInfo);
-
-static void XGINew_DisableChannelInterleaving(int index,
- const USHORT XGINew_DDRDRAM_TYPE[][5], PVB_DEVICE_INFO pVBInfo);
-
-static void DualChipInit(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-
-static void XGINew_DisableRefresh(PXGI_HW_DEVICE_INFO ,PVB_DEVICE_INFO);
-static void XGINew_EnableRefresh(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-
-static void XGINew_Delay15us(ULONG);
-static void SetPowerConsume(PXGI_HW_DEVICE_INFO, USHORT);
-static void XGINew_DDR1x_MRS_XG20(USHORT, PVB_DEVICE_INFO);
-static void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-static void XGINew_ChkSenseStatus(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
-
-static int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
- PVB_DEVICE_INFO pVBInfo);
-static int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
- PVB_DEVICE_INFO pVBInfo);
-static UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo);
-static void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-
-static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
-static ULONG UNIROM; /* UNIROM */
-
-
-#ifdef LINUX_KERNEL
-void DelayUS(ULONG MicroSeconds)
-{
- udelay(MicroSeconds);
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-/* Function : XGIInitNew */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN XGIInitNew(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
-#ifndef LINUX_XF86
- USHORT Mclockdata[ 30 ] , Eclockdata[ 30 ] ;
- UCHAR j , SR11 , SR17 = 0 , SR18 = 0 , SR19 = 0 ;
- UCHAR CR37 = 0 , CR38 = 0 , CR79 = 0 , CR7A = 0 ,
- CR7B = 0 , CR36 = 0 , CR78 = 0 , CR3C = 0 ,
- CR3D = 0 , CR3E = 0 , CR3F = 0 , CR35 = 0 ;
-#endif
- UCHAR i , temp = 0 , temp1 ,
- VBIOSVersion[ 5 ] ;
- ULONG base,ChipsetID,VendorID,GraphicVendorID;
- PUCHAR volatile pVideoMemory;
-
- /* ULONG j, k ; */
-
- PXGI_DSReg pSR ;
-
- ULONG Temp ;
-
-
- XGINew_InitVBIOSData(HwDeviceExtension, pVBInfo);
-
- pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr;
-
-
- Newdebugcode( 0x99 ) ;
-
- /* if ( pVBInfo->ROMAddr == 0 ) */
- /* return( FALSE ) ; */
-
- if ( pVBInfo->FBAddr == 0 )
- return( FALSE ) ;
-
- if ( pVBInfo->BaseAddr == 0 )
- return( FALSE ) ;
-
- XGI_SetRegByte((XGIIOADDRESS) ( USHORT )( pVBInfo->BaseAddr + 0x12 ) , 0x67 ) ; /* 3c2 <- 67 ,ynlai */
-
-
- if ( !HwDeviceExtension->bIntegratedMMEnabled )
- return( FALSE ) ; /* alan */
-
-
-
- XGI_MemoryCopy( VBIOSVersion , HwDeviceExtension->szVBIOSVer , 4 ) ;
-
- VBIOSVersion[ 4 ] = 0x0 ;
-
-
- /* ReadVBIOSData */
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- /* 1.Openkey */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x05 , 0x86 ) ;
-
-
-
- /* 2.Reset Extended register */
-
- for( i = 0x06 ; i < 0x20 ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
-
- for( i = 0x21 ; i <= 0x27 ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
-
- /* for( i = 0x06 ; i <= 0x27 ; i++ ) */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ; */
-
-
- if(( HwDeviceExtension->jChipType == XG20 ) || ( HwDeviceExtension->jChipType >= XG40))
- {
- for( i = 0x31 ; i <= 0x3B ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
- }
- else
- {
- for( i = 0x31 ; i <= 0x3D ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
- }
-
- if ( HwDeviceExtension->jChipType == XG42 ) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B , 0xC0 ) ;
-
- /* for( i = 0x30 ; i <= 0x3F ; i++ ) */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; */
-
- for( i = 0x79 ; i <= 0x7C ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; /* shampoo 0208 */
-
-
-
- if ( HwDeviceExtension->jChipType == XG20 )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x97, pVBInfo->CR97);
-
- /* 3.SetMemoryClock */
- if (!(pVBInfo->SoftSetting & SoftDRAMType)) {
- if ( HwDeviceExtension->jChipType == XG20 )
- {
- temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
- }
- else if (HwDeviceExtension->jChipType == XG45)
- {
- temp = 0x02 ;
- }
- else
- {
- temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
- }
- }
-
-
- if ( HwDeviceExtension->jChipType == XG20 )
- XGINew_RAMType = temp & 0x01 ;
- else
- {
- XGINew_RAMType = temp & 0x03 ; /* alan */
- }
-
- /* Get DRAM type */
- if ( HwDeviceExtension->jChipType == XG45 )
- { }
- else if ( HwDeviceExtension->jChipType >= XG40 )
- XGINew_RAMType = ( int )XGINew_Get340DRAMType( HwDeviceExtension , pVBInfo) ;
-
- if ( UNIROM == 1 ) XGINew_RAMType = 0;
-
-
- if ( HwDeviceExtension->jChipType < XG40 )
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- /* 4.SetDefExt1Regs begin */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, pVBInfo->SR07);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x11, 0x0F);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, pVBInfo->SR1F);
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0x20); */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
-
-
- /* SR11 = 0x0F ; */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x11 , SR11 ) ; */
-
-
- if ( (HwDeviceExtension->jChipType != XG20) || (HwDeviceExtension->jChipType != XG45) ) /* kuku 2004/06/25 */
- {
- /* Set AGP Rate */
- temp1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B ) ;
- temp1 &= 0x02 ;
- if ( temp1 == 0x02 )
- {
- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
- ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8000002C ) ;
- VendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
- VendorID &= 0x0000FFFF ;
- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8001002C ) ;
- GraphicVendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
- GraphicVendorID &= 0x0000FFFF;
-
- if ( ChipsetID == 0x7301039 )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x09 ) ;
-
- ChipsetID &= 0x0000FFFF ;
-
- if ( ( ChipsetID == 0x700E ) || ( ChipsetID == 0x1022 ) || ( ChipsetID == 0x1106 ) || ( ChipsetID == 0x10DE ) )
- {
- if ( ChipsetID == 0x1106 )
- {
- if ( ( VendorID == 0x1019 ) && ( GraphicVendorID == 0x1019 ) )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0D ) ;
- else
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
- }
- else
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
- }
- }
-
- if ( HwDeviceExtension->jChipType >= XG40 )
- {
- /* Set AGP customize registers (in SetDefAGPRegs) Start */
- for( i = 0x47 ; i <= 0x4C ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ i - 0x47 ] ) ;
-
- for( i = 0x70 ; i <= 0x71 ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 6 + i - 0x70 ] ) ;
-
- for( i = 0x74 ; i <= 0x77 ; i++ )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 8 + i - 0x74 ] ) ;
- /* Set AGP customize registers (in SetDefAGPRegs) End */
- /*[Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
- ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
- if ( ChipsetID == 0x25308086 )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x77 , 0xF0 ) ;
-
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x50 , 0 , &Temp ) ; /* Get */
- Temp >>= 20 ;
- Temp &= 0xF ;
-
- if ( Temp == 1 )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , 0x20 ) ; /* CR48 */
- }
-
- if ( HwDeviceExtension->jChipType < XG40 )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x49 , pVBInfo->CR49[ 0 ] ) ;
- } /* != XG20 */
-
- /* Set PCI */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x23, pVBInfo->SR23);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x24, pVBInfo->SR24);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
-
- if ( HwDeviceExtension->jChipType != XG20 ) /* kuku 2004/06/25 */
- {
- /* Set VB */
- XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ; /* alan, disable VideoCapture */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , 0x00 ) ;
- temp1 = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7B ) ; /* chk if BCLK>=100MHz */
- temp = ( UCHAR )( ( temp1 >> 4 ) & 0x0F ) ;
-
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02,
- pVBInfo->CRT2Data_1_2);
-
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x2E , 0x08 ) ; /* use VB */
- } /* != XG20 */
-
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x27 , 0x1F ) ;
-
- /* Not DDR */
- if ((HwDeviceExtension->jChipType == XG42)
- && XGINew_Get340DRAMType(HwDeviceExtension, pVBInfo) != 0) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, (pVBInfo->SR31 & 0x3F) | 0x40);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, (pVBInfo->SR32 & 0xFC) | 0x01);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, pVBInfo->SR31);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, pVBInfo->SR32);
- }
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x33, pVBInfo->SR33);
-
-
-
- if ( HwDeviceExtension->jChipType >= XG40 )
- SetPowerConsume ( HwDeviceExtension , pVBInfo->P3c4);
-
- if ( HwDeviceExtension->jChipType != XG20 ) /* kuku 2004/06/25 */
- {
- if ( XGI_BridgeIsOn( pVBInfo ) == 1 )
- {
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0x1C);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, pVBInfo->CRT2Data_4_D);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, pVBInfo->CRT2Data_4_E);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, pVBInfo->CRT2Data_4_10);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0F, 0x3F);
- }
-
- XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
- }
- } /* != XG20 */
-
- if ( HwDeviceExtension->jChipType < XG40 )
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x83 , 0x00 ) ;
-
-
-
- if ( HwDeviceExtension->jChipType >= XG40 )
- {
- if (HwDeviceExtension->jChipType == XG45)
- XGINew_SetDRAMDefaultRegisterXG45( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
- else
- XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
-
- if ( HwDeviceExtension->bSkipDramSizing == TRUE )
- {
- pSR = HwDeviceExtension->pSR ;
- if ( pSR!=NULL )
- {
- while( pSR->jIdx != 0xFF )
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , pSR->jIdx , pSR->jVal ) ;
- pSR++ ;
- }
- }
- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
- } /* SkipDramSizing */
- else
- {
-/* if ( HwDeviceExtension->jChipType == XG20 )
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , pVBInfo->SR15[0][XGINew_RAMType] ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , pVBInfo->SR15[1][XGINew_RAMType] ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x20 , 0x20 ) ;
- }
- else*/
- if ( HwDeviceExtension->jChipType == XG45 )
- XGINew_SetDRAMSize_XG45( HwDeviceExtension , pVBInfo) ;
- else
- XGINew_SetDRAMSize_340( HwDeviceExtension , pVBInfo) ;
- }
- } /* XG40 */
-
-
-
-
- /* SetDefExt2Regs begin */
-/*
- AGP = 1 ;
- temp =( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
- temp &= 0x30 ;
- if ( temp == 0x30 )
- AGP = 0 ;
-
- if ( AGP == 0 )
- pVBInfo->SR21 &= 0xEF ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , pVBInfo->SR21 ) ;
- if ( AGP == 1 )
- pVBInfo->SR22 &= 0x20;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x22 , pVBInfo->SR22 ) ;
-*/
-
- base = 0x80000000;
- XGI_SetRegLong(0xcf8, base);
- Temp = (XGI_GetRegLong(0xcfc) & 0x0000FFFF);
- if (Temp == 0x1039) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22 & 0xFE);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22);
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21, pVBInfo->SR21);
-
- if ( HwDeviceExtension->jChipType == XG40 ) /* Initialize seconary chip */
- {
- if ( CheckDualChip(pVBInfo) )
- DualChipInit( HwDeviceExtension , pVBInfo) ;
- /* SetDefExt2Regs end */
- }
-
- if ( HwDeviceExtension->bSkipSense == FALSE )
- {
- XGI_SenseCRT1(pVBInfo) ;
- /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
- XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
- }
-
- XGINew_ChkSenseStatus ( HwDeviceExtension , pVBInfo ) ;
- XGINew_SetModeScratch ( HwDeviceExtension , pVBInfo ) ;
-
- Newdebugcode( 0x88 ) ;
-
- /* Johnson@062403. To save time for power management. */
- /* DelayMS(1000); */
- /* ~Johnson@062403. */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , 0x28 ) ; //0207 temp */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x36 , 0x02 ) ; //0207 temp */
-
- return( TRUE ) ;
-} /* end of init */
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : DualChipInit */
-/* Input : */
-/* Output : */
-/* Description : Initialize the secondary chip. */
-/* --------------------------------------------------------------------- */
-void DualChipInit( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
-{
-#ifdef LINUX_XF86
- USHORT BaseAddr2nd = (USHORT)(ULONG)HwDeviceExtension->pj2ndIOAddress ;
-#else
- USHORT BaseAddr2nd = (USHORT)HwDeviceExtension->pj2ndIOAddress ;
-#endif
- USHORT XGINew_P3C3 = pVBInfo->BaseAddr + VIDEO_SUBSYSTEM_ENABLE_PORT ;
- USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT ;
- USHORT XGINew_2ndP3C3 = BaseAddr2nd + VIDEO_SUBSYSTEM_ENABLE_PORT ;
- USHORT XGINew_2ndP3D4 = BaseAddr2nd + CRTC_ADDRESS_PORT_COLOR ;
- USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT ;
- USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT ;
- ULONG Temp ;
- UCHAR tempal , i ;
-
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->BaseAddr = (USHORT)HwDeviceExtension->pjIOAddress ;
- /* Programming Congiguration Space in Secondary Chip */
- /* set CRA1 D[6] = 1 */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0xBF , 0x40 ) ;
-
- /* Write 2nd Chip Configuration Info into Configuration Space */
- /* Command CNFG04 */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND , 0 , &Temp ) ; /* Get */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND + 0x80 , 1 , &Temp ) ; /* Set */
- /* Latency Timer CNFG0C */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c , 0 , &Temp ) ; /* Get */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c + 0x80 , 1 , &Temp ) ; /* Set */
- /* Linear space */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 , 0 , &Temp ) ; /* Get */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 + 0x80 , 1 , &Temp ) ; /* Set */
- /* MMIO space */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 , 0 , &Temp ) ; /* Get */
- Temp += 0x40000;
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 + 0x80 , 1 , &Temp ) ; /* Set */
- /* Relocated IO space */
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 , 0 , &Temp ) ; /* Get */
- Temp += 0x80;
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 + 0x80 , 1 , &Temp ) ; /* Set */
- /* Miscellaneous reg(input port 3cch,output port 3c2h) */
- tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC ) ; /* 3cc */
- XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2 , tempal ) ;
- /* VGA enable reg(port 3C3h) */
- tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3C3 ) ; /* 3c3 */
- XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C3 , tempal ) ;
- SetPowerConsume ( HwDeviceExtension , XGINew_2ndP3D4);
- /* ----- CRA0=42, CRA1=81, CRA2=60, CRA3=20, CRA4=50, CRA5=40, CRA8=88 -----// */
- /* ----- CRA9=10, CRAA=80, CRAB=01, CRAC=F1, CRAE=80, CRAF=45, CRB7=24 -----// */
- /* primary chip */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA0 , 0x72 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0x81 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA2 , 0x60 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA3 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA4 , 0x50 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA5 , 0x40 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA8 , 0x88 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA9 , 0x10 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAA , 0x80 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAB , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAC , 0xF1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAE , 0x80 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAF , 0x45 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xB7 , 0x24 ) ;
-
- /* secondary chip */
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA0 , 0x72 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA1 , 0x81 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA2 , 0x60 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA3 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA4 , 0x50 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA5 , 0x40 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA8 , 0x88 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA9 , 0x10 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAA , 0x80 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAB , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAC , 0xF1 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAE , 0x80 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAF , 0x45 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xB7 , 0x24 ) ;
-
- /* 06/20/2003 [christine] CRT threshold setting request */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x78 , 0x40 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x79 , 0x0C ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7A , 0x34 ) ;
-
- /* OpenKey in 2nd chip */
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x86 ) ;
-
- /* Set PCI registers */
- tempal = (UCHAR)XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x06 ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x06 , tempal ) ;
-
- for( i = 0x20 ; i <= 0x25 ; i++ )
- {
- tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
- }
- for(i = 0x31; i <= 0x32; i++ )
- {
- tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
- }
- XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , XGINew_2ndP3D4 , pVBInfo) ;
-
- for(i = 0x13; i <= 0x14; i++ )
- {
- tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
- }
-
- /* Close key in 2nd chip */
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x00 ) ;
-}
-
-
-
-
-/* ============== alan ====================== */
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_Get340DRAMType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-UCHAR XGINew_Get340DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR data ;
-
- if ( HwDeviceExtension->jChipType != XG20 )
- {
- if (pVBInfo->SoftSetting & SoftDRAMType) {
- return (pVBInfo->SoftSetting & 0x07);
- }
- else
- {
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ;
-
- if ( data == 0 )
- data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) & 0x02 ) >> 1 ;
-
- return( data ) ;
- }
- }
- else
- {
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) & 0x01 ;
-
- if ( data == 1 )
- data ++ ;
-
- return( data );
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_Delay15us */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-/*
-void XGINew_Delay15us(ULONG ulMicrsoSec)
-{
-}
-*/
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SDR_MRS */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ;
- data &= 0x3F ; /* SR16 D7=0,D6=0 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) low */
- /* XGINew_Delay15us( 0x100 ) ; */
- data |= 0x80 ; /* SR16 D7=1,D6=0 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) high */
- /* XGINew_Delay15us( 0x100 ) ; */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR1x_MRS_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
- PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
- if ( HwDeviceExtension->jChipType == XG42 ) /* XG42 BA0 & BA1 layout change */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
- else
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
-
- /* Samsung F Die */
- if (pVBInfo->DRAMTypeDefinition != 0x0C) {
- DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
- if ( HwDeviceExtension->jChipType == XG42 )
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
- else
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- }
-
- DelayUS( 60 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
-
- if (HwDeviceExtension->jChipType == XG45)
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ; /*TSop DRAM DLL pin jump to A9*/
- else
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
-
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
- DelayUS( 1000 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
- DelayUS( 500 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2x_MRS_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
- PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
- if ( HwDeviceExtension->jChipType == XG42 ) /*XG42 BA0 & BA1 layout change*/
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
- else
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
-
- /* Samsung F Die */
- if (pVBInfo->DRAMTypeDefinition != 0x0C) {
- DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
- if ( HwDeviceExtension->jChipType == XG42 )
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
- else
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- }
-
- DelayUS( 60 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
- DelayUS( 1000 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
- DelayUS( 500 ) ;
- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2_MRS_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT P3d4 = P3c4 + 0x10 ;
- UCHAR data ;
-
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , 0x64 ) ; /* SR28 */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , 0x63 ) ; /* SR29 */
- DelayUS( 200 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 2 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
-
- if( P3c4 != pVBInfo->P3c4 )
- {
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , data ) ; /* SR28 */
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , data ) ; /* SR29 */
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2A , data ) ; /* SR2A */
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2e , data ) ; /* SR2E */
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2f , data ) ; /* SR2F */
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x30 , data ) ; /* SR30 */
- }
- else
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- DelayUS( 1000 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 1 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
- DelayUS( 5) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
- DelayUS( 5 ) ;
- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x72 ) ; */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x06 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
- DelayUS( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR1x_DefaultRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT Port, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-#ifndef LINUX_XF86
- UCHAR data ;
-#endif
- if ( HwDeviceExtension->jChipType == XG20 )
- {
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
-
- XGINew_DDR1x_MRS_XG20( P3c4 , pVBInfo) ;
- }
- else
- {
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- switch( HwDeviceExtension->jChipType )
- {
- case XG41:
- case XG42:
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
- break ;
- default:
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- break ;
- }
- if (HwDeviceExtension->jChipType != XG45)
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
- XGINew_DDR1x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2x_DefaultRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT Port, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
-#ifndef LINUX_XF86
- UCHAR data ;
-#endif
-
- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
-
- /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
- switch( HwDeviceExtension->jChipType )
- {
- case XG41:
- case XG42:
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
- break ;
- default:
- /* keep following setting sequence, each setting in the same reg insert idle */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
- }
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ;
- if ( HwDeviceExtension->jChipType == XG42 )
- {
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
- }
- else
- {
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
- }
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
-
- XGINew_DDR2x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR2_DefaultRegister */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT Port, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- /* keep following setting sequence, each setting in the same reg insert idle */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
- XGINew_DDR2_MRS_340( HwDeviceExtension , P3c4, pVBInfo ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMDefaultRegister340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR temp , temp1 , temp2 , temp3 ,
- i , j , k ;
-
- USHORT P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
-
- temp2 = 0 ;
- for( i = 0 ; i < 4 ; i++ )
- {
- temp = pVBInfo->CR6B[ XGINew_RAMType ][ i ] ; /* CR6B DQS fine tune delay */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp2 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6B ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
- }
-
- temp2 = 0 ;
- for( i = 0 ; i < 4 ; i++ )
- {
- temp = pVBInfo->CR6E[ XGINew_RAMType ][ i ] ; /* CR6E DQM fine tune delay */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , temp2 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6E ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
- }
-
- temp3 = 0 ;
- for( k = 0 ; k < 4 ; k++ )
- {
- XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x6E , 0xFC , temp3 ) ; /* CR6E_D[1:0] select channel */
- temp2 = 0 ;
- for( i = 0 ; i < 8 ; i++ )
- {
- temp = pVBInfo->CR6F[ XGINew_RAMType ][ 8 * k + i ] ; /* CR6F DQ fine tune delay */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , temp2 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6F ) ; /* Insert read command for delay */
- temp2 &= 0xF8 ;
- temp2 += 0x08 ;
- }
- }
- temp3 += 0x01 ;
- }
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
-
- temp2 = 0x80 ;
- temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
-
- temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
- temp1 = temp & 0x03 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
-
- temp = pVBInfo->CR40[ 3 ][ XGINew_RAMType ] ;
- temp1 = temp & 0x0F ;
- temp2 = ( temp >> 4 ) & 0x07 ;
- temp3 = temp & 0x80 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , temp1 ) ; /* CR45 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , temp2 ) ; /* CR99 */
- XGI_SetRegOR((XGIIOADDRESS) P3d4 , 0x40 , temp3 ) ; /* CR40_D[7] */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , pVBInfo->CR40[ 0 ][ XGINew_RAMType ] ) ; /* CR41 */
-
- for( j = 0 ; j <= 6 ; j++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
-
- for( j = 0 ; j <= 2 ; j++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
-
- for( j = 0 ; j < 2 ; j++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
-
- if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
-
- XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
- XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
- XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
- XGI_SetReg((XGIIOADDRESS) P3c4, 0x1A, 0x87); /* SR1A */
-
- temp = XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) ;
- if( temp == 0 )
- XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
- else if ( temp == 0x02 )
- XGINew_DDR2x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
- else
- XGINew_DDR2_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
-
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMDefaultRegisterXG45 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMDefaultRegisterXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR temp , temp1 , temp2 ,
- i , j , k ;
-
- USHORT P3d4 = Port ,
- P3c4 = Port - 0x10 ;
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , pVBInfo->XG45CR6E[ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , pVBInfo->XG45CR6F[ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
-
- temp = 0x00 ;
- for ( j = 0 ; j < 24 ; j ++ )
- {
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp );
- temp += 0x08 ;
- }
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
-
- temp2 = 0x80 ;
- temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
- for( j = 0 ; j < 4 ; j++ )
- {
- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
- temp2 &= 0xF0 ;
- temp2 += 0x10 ;
- }
-
- temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
- temp1 = temp & 0x03 ;
- temp2 |= temp1 ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
-
- temp = 0x00 ;
- for ( j = 0 ; j < 3 ; j ++ )
- {
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x40 , temp );
- temp += 0x40 ;
- }
-
- temp = 0x00 ;
- for ( j = 0 ; j < 24 ; j ++ )
- {
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , temp );
- temp += 0x08 ;
- }
-
- temp = 0x00 ;
- for ( j = 0 ; j < 24 ; j ++ )
- {
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x42 , temp );
- temp += 0x08 ;
- }
-
- for ( k = 0 ; k < 2 ; k ++ )
- {
- XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x04 , k * 0x04 );
-
- for ( i = 0 ; i < 3 ; i ++ )
- {
-
- XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x03 , i * 0x01 );
-
- for ( j = 0 ; j < 32 ; j ++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x44 , j * 0x08 );
- }
- }
-
- for ( j = 0 ; j < 3 ; j ++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , j * 0x08 ) ; /* CR45 */
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x84 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , 0x22 ) ;
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
-
- for( j = 0 ; j <= 6 ; j++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
-
- for( j = 0 ; j <= 2 ; j++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0xC8 , 0x04 ) ;
-
- for( j = 0 ; j < 2 ; j++ )
- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
-
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x40 ) ;
-
- if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
-
- XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
- XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
- XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
- XGI_SetReg((XGIIOADDRESS) P3d4, 0x8D, 0x87); /* CR8D */
-
- XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
-
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1A , 0x87 ) ; /* SR1A */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR_MRS */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
- PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
-
- /* SR16 <- 1F,DF,2F,AF */
- /* yriver modified SR16 <- 0F,DF,0F,AF */
- /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
- data = pVideoMemory[ 0xFB ] ;
- /* data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ; */
-
- data &= 0x0F ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0xC0 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data &= 0x0F ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0x80 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data &= 0x0F ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0xD0 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data &= 0x0F ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
- data |= 0xA0 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
-/*
- else {
- data &= 0x0F;
- data |= 0x10;
- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
-
- if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
- {
- data &= 0x0F;
- }
-
- data |= 0xC0;
- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
-
-
- data &= 0x0F;
- data |= 0x20;
- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
- if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
- {
- data &= 0x0F;
- }
-
- data |= 0x80;
- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
- }
-*/
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSize_340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /* disable read cache */
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
- data |= 0x20 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; /* Turn OFF Display */
-
- XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
-
- data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /* enable read cache */
-}
-
-
-/*--------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSize_XG45 */
-/*Input : */
-/*Output : */
-/*Description : */
-/*--------------------------------------------------------------------- */
-void XGINew_SetDRAMSize_XG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /*disable read cache*/
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
- data |= 0x20 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; /*Turn OFF Display*/
-
- XGINew_DDRSizingXG45( HwDeviceExtension, pVBInfo ) ;
-
- data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /*enable read cache*/
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMModeRegister340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-
-void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR data ;
-
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- if (HwDeviceExtension->jChipType == XG45)
- XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
- else
- {
- if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
- {
- data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ) >> 1 ;
- if ( data == 0x01 )
- XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
- else
- XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
- }
- else
- XGINew_DDR2_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DisableRefresh */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B ) ;
- data &= 0xF8 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , data ) ;
-
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_EnableRefresh */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
-{
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
-
-
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DisableChannelInterleaving */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DisableChannelInterleaving(int index,
- const USHORT XGINew_DDRDRAM_TYPE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
- data &= 0x1F ;
-
- switch( XGINew_DDRDRAM_TYPE[ index ][ 3 ] )
- {
- case 64:
- data |= 0 ;
- break ;
- case 32:
- data |= 0x20 ;
- break ;
- case 16:
- data |= 0x40 ;
- break ;
- case 4:
- data |= 0x60 ;
- break ;
- default:
- break ;
- }
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSizingType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMSizingType(int index , const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
-
- data = DRAMTYPE_TABLE[ index ][ 4 ] ;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
- /* should delay 50 ns */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetRank */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
- int RankSize ;
-
- if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
- return 0 ;
-
- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] / 2 * XGINew_DataBusWidth / 32 ;
-
- if ( ( RankNo * RankSize ) <= 128 )
- {
- data = 0 ;
-
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
- data |= ( RankNo - 1 ) << 2 ;
- data |= ( XGINew_DataBusWidth / 64 ) & 2 ;
- data |= XGINew_ChannelAB ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
- /* should delay */
- XGINew_SDR_MRS( pVBInfo ) ;
- return( 1 ) ;
- }
- else
- return( 0 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDDRChannel */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_SetDDRChannel(int index, UCHAR ChannelNo, UCHAR XGINew_ChannelAB,
- const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data ;
- int RankSize ;
-
- RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
- /* RankSize = DRAMTYPE_TABLE[ index ][ 3 ] ; */
- if ( ChannelNo * RankSize <= 128 )
- {
- data = 0 ;
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
-
- if ( ChannelNo == 2 )
- data |= 0x0C ;
-
- data |= ( XGINew_DataBusWidth / 32 ) & 2 ;
- data |= XGINew_ChannelAB ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
- /* should delay */
- XGINew_DDR_MRS( pVBInfo ) ;
- return( 1 ) ;
- }
- else
- return( 0 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckColumn */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- ULONG Increment , Position ;
-
- /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
- Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
- Position += Increment ;
- }
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
- Position += Increment ;
- }
- return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckBanks */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- ULONG Increment , Position ;
-
- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
-
- for( i = 0 , Position = 0 ; i < 4 ; i++ )
- {
- /* pVBInfo->FBAddr[ Position ] = Position ; */
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
- Position += Increment ;
- }
-
- for( i = 0 , Position = 0 ; i < 4 ; i++ )
- {
- /* if (pVBInfo->FBAddr[ Position ] != Position ) */
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
- Position += Increment ;
- }
- return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckRank */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckRank(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- ULONG Increment , Position ;
-
- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
- DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- /* pVBInfo->FBAddr[ Position ] = Position ; */
- /* *( ( PULONG )( pVBInfo->FBAddr ) ) = Position ; */
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
- Position += Increment ;
- }
-
- for( i = 0 , Position = 0 ; i < 2 ; i++ )
- {
- /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
- /* if ( ( *( PULONG )( pVBInfo->FBAddr ) ) != Position ) */
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
- Position += Increment ;
- }
- return( 1 );
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckDDRRank */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckDDRRank(int RankNo, int index,
- const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- ULONG Increment , Position ;
- USHORT data ;
-
- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
- DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
-
- Increment += Increment / 2 ;
-
- Position = 0;
- *( ( PULONG )( pVBInfo->FBAddr + Position + 0 ) ) = 0x01234567 ;
- *( ( PULONG )( pVBInfo->FBAddr + Position + 1 ) ) = 0x456789AB ;
- *( ( PULONG )( pVBInfo->FBAddr + Position + 2 ) ) = 0x55555555 ;
- *( ( PULONG )( pVBInfo->FBAddr + Position + 3 ) ) = 0x55555555 ;
- *( ( PULONG )( pVBInfo->FBAddr + Position + 4 ) ) = 0xAAAAAAAA ;
- *( ( PULONG )( pVBInfo->FBAddr + Position + 5 ) ) = 0xAAAAAAAA ;
-
- if ( ( *( PULONG )( pVBInfo->FBAddr + 1 ) ) == 0x456789AB )
- return( 1 ) ;
-
- if ( ( *( PULONG )( pVBInfo->FBAddr + 0 ) ) == 0x01234567 )
- return( 0 ) ;
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) ;
- data &= 0xF3 ;
- data |= 0x0E ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
- data += 0x20 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
-
- return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckRanks */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckRanks(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- int r ;
-
- for( r = RankNo ; r >= 1 ; r-- )
- {
- if ( !XGINew_CheckRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
- }
-
- if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
-
- if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
-
- return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckDDRRanks */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_CheckDDRRanks(int RankNo, int index,
- const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- int r ;
-
- for( r = RankNo ; r >= 1 ; r-- )
- {
- if ( !XGINew_CheckDDRRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
- }
-
- if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
-
- if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
- return( 0 ) ;
-
- return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- UCHAR j ;
-
- for( i = 0 ; i < 13 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_SDRDRAM_TYPE , pVBInfo) ;
-
- for( j = 2 ; j > 0 ; j-- )
- {
- if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_SDRDRAM_TYPE , pVBInfo) )
- continue ;
- else
- {
- if ( XGINew_CheckRanks( j , i , XGINew_SDRDRAM_TYPE, pVBInfo) )
- return( 1 ) ;
- }
- }
- }
- return( 0 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMSizeReg */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT XGINew_SetDRAMSizeReg(int index, const USHORT DRAMTYPE_TABLE[][5],
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data = 0 , memsize = 0 ;
- int RankSize ;
- UCHAR ChannelNo ;
-
- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 ) ;
- data &= 0x80 ;
-
- if ( data == 0x80 )
- RankSize *= 2 ;
-
- data = 0 ;
-
- if( XGINew_ChannelAB == 3 )
- ChannelNo = 4 ;
- else
- ChannelNo = XGINew_ChannelAB ;
-
- if ( ChannelNo * RankSize <= 256 )
- {
- while( ( RankSize >>= 1 ) > 0 )
- {
- data += 0x10 ;
- }
-
- memsize = data >> 4 ;
-
- /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
-
- /* data |= XGINew_ChannelAB << 2 ; */
- /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ; */
-
- /* should delay */
- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
- }
- return( memsize ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_ReadWriteRest */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
- PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- ULONG Position = 0 ;
-
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
-
- for( i = StartAddr ; i <= StopAddr ; i++ )
- {
- Position = 1 << i ;
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
- }
-
- DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
-
- Position = 0 ;
-
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
-
- for( i = StartAddr ; i <= StopAddr ; i++ )
- {
- Position = 1 << i ;
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
- }
- return( 1 ) ;
-}
-
-
-/*--------------------------------------------------------------------- */
-/* Function : XGI45New_ReadWriteRest */
-/* Input : */
-/* Output : */
-/* Description : return 0 : fail, 1 : pass */
-/*--------------------------------------------------------------------- */
-int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
- PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- ULONG Position = 0 ;
-
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
-
- for( i = StartAddr ; i <= StopAddr ; i++ )
- {
- Position = 1 << i ;
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
- }
-
- if ( XGINew_ChannelAB == 4 )
- {
- Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
- }
-
- DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
-
- Position = 0 ;
-
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
-
- for( i = StartAddr ; i <= StopAddr ; i++ )
- {
- Position = 1 << i ;
- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
- return( 0 ) ;
- }
-
- if ( XGINew_ChannelAB == 4 )
- {
- Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
- if( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position );
- return( 0 ) ;
- }
- return( 1 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckFrequence */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR data ;
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
-
- if ( ( data & 0x10 ) == 0 )
- {
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) ;
- data = ( data & 0x02 ) >> 1 ;
- return( data ) ;
- }
- else
- return( data & 0x01 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_CheckChannel */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR i, data ;
-
- switch( HwDeviceExtension->jChipType )
- {
- case XG20:
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
- data = data & 0x01;
- XGINew_ChannelAB = 1 ; /* XG20 "JUST" one channel */
-
- if ( data == 0 ) /* Single_32_16 */
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 32bit */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* 22bit + 1 rank + 32bit */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_DataBusWidth = 16 ; /* 16 bits */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 16bit */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
- else
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
-
- }
- else /* Dual_16_8 */
- {
- XGINew_DataBusWidth = 16 ; /* 16 bits */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x31 ) ;
-
- if ( XGINew_ReadWriteRest( 22 , 22 , pVBInfo ) == 1 )
- return ;
-
- XGINew_DataBusWidth = 8 ; /* 8 bits */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
-
- if ( XGINew_ReadWriteRest( 22 , 21 , pVBInfo ) == 1 )
- return ;
- else
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
- }
- break ;
-
- case XG41:
- if ( XGINew_CheckFrequence(pVBInfo) == 1 )
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_ChannelAB = 3 ; /* Quad Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* Dual channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x49 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 3 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
-
- if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
- return ;
- else
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x39 ) ;
- }
- else
- { /* DDR */
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 2 ; /* Dual channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* Single channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x53 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* Dual channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* Single channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
-
- if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
- return ;
- else
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x43 ) ;
- }
-
- break ;
-
- case XG42:
-/*
- XG42 SR14 D[3] Reserve
- D[2] = 1, Dual Channel
- = 0, Single Channel
-
- It's Different from Other XG40 Series.
-*/
- if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII, DDR2x */
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_ChannelAB = 2 ; /* 2 Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x44 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x34 ) ;
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* Single Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x40 ) ;
-
- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
- else
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
- }
- }
- else
- { /* DDR */
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 1 ; /* 1 channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
- else
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
- }
- }
-
- break ;
-
- case XG45:
-
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 4 ; /* 3+1 Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
-
- if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 3 ; /* 3 Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
-
- if ( XGI45New_ReadWriteRest( 26 , 24 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* 2 Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
-
- if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* 1 Channel */
- for ( i = 0; i <= 2; i++)
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
-
- if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
- }
-
- XGINew_ChannelAB = 3 ; /* 3 Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
-
- if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* 2 Channel */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
-
- if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 1 ; /* 1 Channel */
- for ( i = 0; i <= 2; i++)
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
-
- if ( XGI45New_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
- return ;
- }
- break ;
-
- default: /* XG40 */
-
- if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII */
- {
- XGINew_DataBusWidth = 32 ; /* 32 bits */
- XGINew_ChannelAB = 3 ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGINew_ChannelAB = 2 ; /* 2 channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- return ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
-
- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
- XGINew_ChannelAB = 3 ; /* 4 channels */
- else
- {
- XGINew_ChannelAB = 2 ; /* 2 channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
- }
- }
- else
- { /* DDR */
- XGINew_DataBusWidth = 64 ; /* 64 bits */
- XGINew_ChannelAB = 2 ; /* 2 channels */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
-
- if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
- return ;
- else
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
- }
- }
- break ;
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDRSizing340 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- USHORT memsize , addr ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
- XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
-
- for( i = 0 ; i < 4 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
- memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
- if ( memsize == 0 )
- continue ;
-
- addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
- if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
- continue ;
-
- if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
- return( 1 ) ;
- }
- return( 0 ) ;
-}
-
-
-/*--------------------------------------------------------------------- */
-/* Function : XGINew_DDRSizingXG45 */
-/* Input : */
-/* Output : */
-/* Description : */
-/*--------------------------------------------------------------------- */
-int XGINew_DDRSizingXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- USHORT memsize , addr ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
- XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
-
- for( i = 0 ; i < 4 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
- memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
- if ( memsize == 0 )
- continue ;
-
- addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
- if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
- continue ;
-
- if ( XGI45New_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
- return( 1 ) ;
- }
- return( 0 ) ;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDRSizing */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
-{
- int i ;
- UCHAR j ;
-
- for( i = 0 ; i < 4 ; i++ )
- {
- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE, pVBInfo ) ;
- XGINew_DisableChannelInterleaving( i , XGINew_DDRDRAM_TYPE , pVBInfo) ;
- for( j = 2 ; j > 0 ; j-- )
- {
- XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
- if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE, pVBInfo ) )
- continue ;
- else
- {
- if ( XGINew_CheckDDRRanks( j , i , XGINew_DDRDRAM_TYPE, pVBInfo ) )
- return( 1 ) ;
- }
- }
- }
- return( 0 ) ;
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetMemoryClock */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
-#ifndef LINUX_XF86
- UCHAR tempal ;
-#endif
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 , pVBInfo->MCLKData[ XGINew_RAMType ].SR28 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 , pVBInfo->MCLKData[ XGINew_RAMType ].SR29 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A , pVBInfo->MCLKData[ XGINew_RAMType ].SR2A ) ;
-
-
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , pVBInfo->ECLKData[ XGINew_RAMType ].SR2E ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , pVBInfo->ECLKData[ XGINew_RAMType ].SR2F ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , pVBInfo->ECLKData[ XGINew_RAMType ].SR30 ) ;
-
- /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
- /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
- if ( HwDeviceExtension->jChipType == XG42 )
- {
- if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
- && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
- || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
- {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 , ( ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 ) & 0xFC ) | 0x02 ) ;
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* input : dx ,valid value : CR or second chip's CR */
-/* */
-/* SetPowerConsume : */
-/* Description: reduce 40/43 power consumption in first chip or */
-/* in second chip, assume CR A1 D[6]="1" in this case */
-/* output : none */
-/* --------------------------------------------------------------------- */
-void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT XGI_P3d4Port )
-{
- ULONG lTemp ;
- UCHAR bTemp;
-
- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
- if ((lTemp&0xFF)==0)
- {
- /* set CR58 D[5]=0 D[3]=0 */
- XGI_SetRegAND((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 ) ;
- bTemp = (UCHAR) XGI_GetReg((XGIIOADDRESS) XGI_P3d4Port , 0xCB ) ;
- if (bTemp&0x20)
- {
- if (!(bTemp&0x10))
- {
- XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x20 ) ; /* CR58 D[5]=1 D[3]=0 */
- }
- else
- {
- XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x08 ) ; /* CR58 D[5]=0 D[3]=1 */
- }
-
- }
-
- }
-}
-
-
-void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
-
- /* ULONG ROMAddr = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
- pVBInfo->BaseAddr = ( USHORT )HwDeviceExtension->pjIOAddress ;
- pVBInfo->RelIO = HwDeviceExtension->pjIOAddress - 0x30;
- pVBInfo->ISXPDOS = 0 ;
-
- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
-
- pVBInfo->IF_DEF_LCDA = 1 ;
- pVBInfo->IF_DEF_VideoCapture = 0 ;
- pVBInfo->IF_DEF_ScaleLCD = 0 ;
- pVBInfo->IF_DEF_OEMUtil = 0 ;
- pVBInfo->IF_DEF_PWD = 0 ;
-
- if ( HwDeviceExtension->jChipType == XG20 ) /* kuku 2004/06/25 */
- {
- pVBInfo->IF_DEF_YPbPr = 0 ;
- pVBInfo->IF_DEF_HiVision = 0 ;
- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
- }
- else if ( HwDeviceExtension->jChipType >= XG40 )
- {
- pVBInfo->IF_DEF_YPbPr = 1 ;
- pVBInfo->IF_DEF_HiVision = 1 ;
- pVBInfo->IF_DEF_CRT2Monitor = 1 ;
- }
- else
- {
- pVBInfo->IF_DEF_YPbPr = 1 ;
- pVBInfo->IF_DEF_HiVision = 1 ;
- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
- }
-
- if (HwDeviceExtension->jChipType != XG20) {
- /* alan, disable VideoCapture */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
- }
-
- XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : ReadVBIOSTablData */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
-{
-#ifndef LINUX_XF86
- ULONG ulOffset ;
- UCHAR temp , index , l ;
-#endif
- PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
- ULONG i ;
- UCHAR j , k ;
- ULONG ii , jj ;
-
- i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ; /* UniROM */
- if ( i != 0 )
- UNIROM = 1 ;
-
- ii = 0x90 ;
- for( jj = 0x00 ; jj < 0x08 ; jj++ )
- {
- pVBInfo->MCLKData[ jj ].SR28 = pVideoMemory[ ii ] ;
- pVBInfo->MCLKData[ jj ].SR29 = pVideoMemory[ ii + 1] ;
- pVBInfo->MCLKData[ jj ].SR2A = pVideoMemory[ ii + 2] ;
- pVBInfo->MCLKData[ jj ].CLOCK = pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
- ii += 0x05 ;
- }
-
- ii = 0xB8 ;
- for( jj = 0x00 ; jj < 0x08 ; jj++ )
- {
- pVBInfo->ECLKData[ jj ].SR2E = pVideoMemory[ ii ] ;
- pVBInfo->ECLKData[ jj ].SR2F=pVideoMemory[ ii + 1 ] ;
- pVBInfo->ECLKData[ jj ].SR30= pVideoMemory[ ii + 2 ] ;
- pVBInfo->ECLKData[ jj ].CLOCK= pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
- ii += 0x05 ;
- }
-
- /* Volari customize data area start */
- /* if ( ChipType == XG40 ) */
- if ( ChipType >= XG40 )
- {
- ii = 0xE0 ;
- for( jj = 0x00 ; jj < 0x03 ; jj++ )
- {
- pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR13, SR14, and SR18 */
- pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
- pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
- pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
- pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
- pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
- pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
- pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
- ii += 0x08 ;
- }
- ii = 0x110 ;
- jj = 0x03 ;
- pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR1B */
- pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
- pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
- pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
- pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
- pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
- pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
- pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
-
- pVBInfo->SR07 = pVideoMemory[0x74];
- pVBInfo->SR1F = pVideoMemory[0x75];
- pVBInfo->SR21 = pVideoMemory[0x76];
- pVBInfo->SR22 = pVideoMemory[0x77];
- pVBInfo->SR23 = pVideoMemory[0x78];
- pVBInfo->SR24 = pVideoMemory[0x79];
- pVBInfo->SR25[0] = pVideoMemory[0x7A];
- pVBInfo->SR31 = pVideoMemory[0x7B];
- pVBInfo->SR32 = pVideoMemory[0x7C];
- pVBInfo->SR33 = pVideoMemory[0x7D];
- ii = 0xF8 ;
-
- for( jj = 0 ; jj < 3 ; jj++ )
- {
- pVBInfo->CR40[ jj ][ 0 ] = pVideoMemory[ ii ] ;
- pVBInfo->CR40[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
- pVBInfo->CR40[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
- pVBInfo->CR40[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
- pVBInfo->CR40[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
- pVBInfo->CR40[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
- pVBInfo->CR40[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
- pVBInfo->CR40[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
- ii += 0x08 ;
- }
-
- ii = 0x118 ;
- for( j = 3 ; j < 24 ; j++ )
- {
- pVBInfo->CR40[ j ][ 0 ] = pVideoMemory[ ii ] ;
- pVBInfo->CR40[ j ][ 1 ] = pVideoMemory[ ii + 1 ] ;
- pVBInfo->CR40[ j ][ 2 ] = pVideoMemory[ ii + 2 ] ;
- pVBInfo->CR40[ j ][ 3 ] = pVideoMemory[ ii + 3 ] ;
- pVBInfo->CR40[ j ][ 4 ] = pVideoMemory[ ii + 4 ] ;
- pVBInfo->CR40[ j ][ 5 ] = pVideoMemory[ ii + 5 ] ;
- pVBInfo->CR40[ j ][ 6 ] = pVideoMemory[ ii + 6 ] ;
- pVBInfo->CR40[ j ][ 7 ] = pVideoMemory[ ii + 7 ] ;
- ii += 0x08 ;
- }
-
- i = pVideoMemory[ 0x1C0 ] | ( pVideoMemory[ 0x1C1 ] << 8 ) ;
-
- for( j = 0 ; j < 8 ; j++ )
- {
- for( k = 0 ; k < 4 ; k++ )
- pVBInfo->CR6B[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
- }
-
- i = pVideoMemory[ 0x1C2 ] | ( pVideoMemory[ 0x1C3 ] << 8 ) ;
-
- if (ChipType == XG45)
- {
- for( j = 0 ; j < 8 ; j++ )
- {
- pVBInfo->XG45CR6E[ j ] = pVideoMemory[i] ;
- }
- }
- else
- {
- for( j = 0 ; j < 8 ; j++ )
- {
- for( k = 0 ; k < 4 ; k++ )
- pVBInfo->CR6E[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
- }
- }
-
- i = pVideoMemory[ 0x1C4 ] | ( pVideoMemory[ 0x1C5 ] << 8 ) ;
- if (ChipType == XG45)
- {
- for( j = 0 ; j < 8 ; j++ )
- {
- pVBInfo->XG45CR6F[ j ] = pVideoMemory[i] ;
- }
- }
- else
- {
- for( j = 0 ; j < 8 ; j++ )
- {
- for( k = 0 ; k < 32 ; k++ )
- pVBInfo->CR6F[ j ][ k ] = pVideoMemory[ i + 32 * j + k ] ;
- }
- }
-
- i = pVideoMemory[ 0x1C6 ] | ( pVideoMemory[ 0x1C7 ] << 8 ) ;
-
- for( j = 0 ; j < 8 ; j++ )
- {
- for( k = 0 ; k < 2 ; k++ )
- pVBInfo->CR89[ j ][ k ] = pVideoMemory[ i + 2 * j + k ] ;
- }
-
- i = pVideoMemory[ 0x1C8 ] | ( pVideoMemory[ 0x1C9 ] << 8 ) ;
- for( j = 0 ; j < 12 ; j++ )
- pVBInfo->AGPReg[ j ] = pVideoMemory[ i + j ] ;
-
- i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;
- for( j = 0 ; j < 4 ; j++ )
- pVBInfo->SR16[ j ] = pVideoMemory[ i + j ] ;
-
- pVBInfo->CRCF = pVideoMemory[0x1CA];
- pVBInfo->DRAMTypeDefinition = pVideoMemory[0x1CB];
- pVBInfo->I2CDefinition = pVideoMemory[0x1D1];
- if ( ChipType == XG20 )
- pVBInfo->CR97 = pVideoMemory[0x1D2];
- }
- /* Volari customize data area end */
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_DDR1x_MRS_XG20 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_DDR1x_MRS_XG20( USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
-{
-
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 60 ) ;
-
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
- DelayUS( 60 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
- DelayUS( 1000 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
- DelayUS( 500 ) ;
- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_SetDRAMModeRegister_XG20 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
-#ifndef LINUX_XF86
- UCHAR data ;
-#endif
-
- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
-
- if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
- XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
- else
- XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
-}
-
-/* -------------------------------------------------------- */
-/* Function : XGINew_ChkSenseStatus */
-/* Input : */
-/* Output : */
-/* Description : */
-/* -------------------------------------------------------- */
-void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx=0 , temp , tempcx , CR3CData;
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 ) ;
-
- if ( temp & Monitor1Sense )
- tempbx |= ActiveCRT1 ;
- if ( temp & LCDSense )
- tempbx |= ActiveLCD ;
- if ( temp & Monitor2Sense )
- tempbx |= ActiveCRT2 ;
- if ( temp & TVSense )
- {
- tempbx |= ActiveTV ;
- if ( temp & AVIDEOSense )
- tempbx |= ( ActiveAVideo << 8 );
- if ( temp & SVIDEOSense )
- tempbx |= ( ActiveSVideo << 8 );
- if ( temp & SCARTSense )
- tempbx |= ( ActiveSCART << 8 );
- if ( temp & HiTVSense )
- tempbx |= ( ActiveHiTV << 8 );
- if ( temp & YPbPrSense )
- tempbx |= ( ActiveYPbPr << 8 );
- }
-
- tempcx = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
- tempcx |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ) ;
-
- if ( tempbx & tempcx )
- {
- CR3CData = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3c ) ;
- if ( !( CR3CData & DisplayDeviceFromCMOS ) )
- {
- tempcx = 0x1FF0 ;
- if (pVBInfo->SoftSetting & ModeSoftSetting) {
- tempbx = 0x1FF0 ;
- }
- }
- }
- else
- {
- tempcx = 0x1FF0 ;
- if (pVBInfo->SoftSetting & ModeSoftSetting) {
- tempbx = 0x1FF0 ;
- }
- }
-
- tempbx &= tempcx ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d , ( tempbx & 0x00FF ) ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e , ( ( tempbx & 0xFF00 ) >> 8 )) ;
-}
-/* -------------------------------------------------------- */
-/* Function : XGINew_SetModeScratch */
-/* Input : */
-/* Output : */
-/* Description : */
-/* -------------------------------------------------------- */
-void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
-{
- USHORT temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
- temp |= XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ;
- temp |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) & ( DriverMode >> 8) ) << 8 ;
-
- if ( pVBInfo->IF_DEF_CRT2Monitor == 1)
- {
- if ( temp & ActiveCRT2 )
- tempcl = SetCRT2ToRAMDAC ;
- }
-
- if ( temp & ActiveLCD )
- {
- tempcl |= SetCRT2ToLCD ;
- if ( temp & DriverMode )
- {
- if ( temp & ActiveTV )
- {
- tempch = SetToLCDA | EnableDualEdge ;
- temp ^= SetCRT2ToLCD ;
-
- if ( ( temp >> 8 ) & ActiveAVideo )
- tempcl |= SetCRT2ToAVIDEO ;
- if ( ( temp >> 8 ) & ActiveSVideo )
- tempcl |= SetCRT2ToSVIDEO ;
- if ( ( temp >> 8 ) & ActiveSCART )
- tempcl |= SetCRT2ToSCART ;
-
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- if ( ( temp >> 8 ) & ActiveHiTV )
- tempcl |= SetCRT2ToHiVisionTV ;
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( ( temp >> 8 ) & ActiveYPbPr )
- tempch |= SetYPbPr ;
- }
- }
- }
- }
- else
- {
- if ( ( temp >> 8 ) & ActiveAVideo )
- tempcl |= SetCRT2ToAVIDEO ;
- if ( ( temp >> 8 ) & ActiveSVideo )
- tempcl |= SetCRT2ToSVIDEO ;
- if ( ( temp >> 8 ) & ActiveSCART )
- tempcl |= SetCRT2ToSCART ;
-
- if ( pVBInfo->IF_DEF_HiVision == 1 )
- {
- if ( ( temp >> 8 ) & ActiveHiTV )
- tempcl |= SetCRT2ToHiVisionTV ;
- }
-
- if ( pVBInfo->IF_DEF_YPbPr == 1 )
- {
- if ( ( temp >> 8 ) & ActiveYPbPr )
- tempch |= SetYPbPr ;
- }
- }
-
-
- tempcl |= SetSimuScanMode ;
- if ( (!( temp & ActiveCRT1 )) && ( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
- tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
- if ( ( temp & ActiveLCD ) && ( temp & ActiveTV ) )
- tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30 , tempcl ) ;
-
- CR31Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) ;
- CR31Data &= ~( SetNotSimuMode >> 8 ) ;
- if ( !( temp & ActiveCRT1 ) )
- CR31Data |= ( SetNotSimuMode >> 8 ) ;
- CR31Data &= ~( DisableCRT2Display >> 8 ) ;
- if (!( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
- CR31Data |= ( DisableCRT2Display >> 8 ) ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31 , CR31Data ) ;
-
- CR38Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
- CR38Data &= ~SetYPbPr ;
- CR38Data |= tempch ;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38 , CR38Data ) ;
-
-}
+/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "osdef.h"
+#include "vgatypes.h"
+
+
+#ifdef LINUX_KERNEL
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/delay.h> /* udelay */
+#include "XGIfb.h"
+#endif
+
+#include "vb_def.h"
+#include "vb_struct.h"
+#include "vb_setmode.h"
+#include "vb_init.h"
+#include "vb_ext.h"
+
+#ifdef LINUX_XF86
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "xgi.h"
+#include "xgi_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
+#include <asm/io.h>
+#include <linux/types.h>
+#endif
+
+
+
+
+static UCHAR XGINew_ChannelAB;
+static UCHAR XGINew_DataBusWidth;
+
+USHORT XGINew_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
+ {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
+ {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
+ {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
+ {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
+ {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
+ {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
+ {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
+ {0x09,0x08,0x01,0x01,0x00}};
+
+static const USHORT XGINew_SDRDRAM_TYPE[13][5]=
+{
+ { 2,12, 9,64,0x35},
+ { 1,13, 9,64,0x44},
+ { 2,12, 8,32,0x31},
+ { 2,11, 9,32,0x25},
+ { 1,12, 9,32,0x34},
+ { 1,13, 8,32,0x40},
+ { 2,11, 8,16,0x21},
+ { 1,12, 8,16,0x30},
+ { 1,11, 9,16,0x24},
+ { 1,11, 8, 8,0x20},
+ { 2, 9, 8, 4,0x01},
+ { 1,10, 8, 4,0x10},
+ { 1, 9, 8, 2,0x00}
+};
+
+static const USHORT XGINew_DDRDRAM_TYPE[4][5]=
+{
+ { 2,12, 9,64,0x35},
+ { 2,12, 8,32,0x31},
+ { 2,11, 8,16,0x21},
+ { 2, 9, 8, 4,0x01}
+};
+
+static const USHORT XGINew_DDRDRAM_TYPE340[4][5]=
+{
+ { 2,13, 9,64,0x45},
+ { 2,12, 9,32,0x35},
+ { 2,12, 8,16,0x31},
+ { 2,11, 8, 8,0x21}
+};
+
+/* Jong 10/05/2007; merge code */
+USHORT XGINew_DDRDRAM_TYPE20[12][5]=
+{
+{ 2,14,11,128,0x5D},
+{ 2,14,10,64,0x59},
+{ 2,13,11,64,0x4D},
+{ 2,14, 9,32,0x55},
+{ 2,13,10,32,0x49},
+{ 2,12,11,32,0x3D},
+{ 2,14, 8,16,0x51},
+{ 2,13, 9,16,0x45},
+{ 2,12,10,16,0x39},
+{ 2,13, 8, 8,0x41},
+{ 2,12, 9, 8,0x35},
+{ 2,12, 8, 4,0x31}
+};
+
+static void XGINew_SetDRAMSize_340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static void XGINew_SetDRAMSize_XG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static void XGINew_SetMemoryClock(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static void XGINew_SetDRAMDefaultRegister340(PXGI_HW_DEVICE_INFO, USHORT,
+ PVB_DEVICE_INFO);
+static void XGINew_SetDRAMDefaultRegisterXG45(PXGI_HW_DEVICE_INFO, USHORT,
+ PVB_DEVICE_INFO);
+static UCHAR XGINew_Get340DRAMType(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+
+static int XGINew_SetDDRChannel(int index, UCHAR ChannelNo,
+ UCHAR XGINew_ChannelAB, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo);
+
+static void XGINew_SetDRAMSizingType(int index ,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+static USHORT XGINew_SetDRAMSizeReg(int index,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+
+static int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+
+static int XGINew_CheckRanks(int RankNo, int index,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+static int XGINew_CheckRank(int RankNo, int index,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+static int XGINew_CheckDDRRank(int RankNo, int index,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+static int XGINew_CheckDDRRanks(int RankNo, int index,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+
+static int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo);
+static int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo);
+
+static int XGINew_DDRSizing340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static int XGINew_DDRSizingXG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static int XGINew_SDRSizing(PVB_DEVICE_INFO);
+static int XGINew_DDRSizing(PVB_DEVICE_INFO);
+
+/* Jong 10/05/2007; merge code */
+static void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
+static UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
+static void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
+static UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
+
+static void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo);
+static void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo);
+static void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
+static void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
+static void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
+static void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT Port, PVB_DEVICE_INFO pVBInfo);
+static void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT Port, PVB_DEVICE_INFO pVBInfo);
+static void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT Port, PVB_DEVICE_INFO pVBInfo);
+
+static void XGINew_DisableChannelInterleaving(int index,
+ const USHORT XGINew_DDRDRAM_TYPE[][5], PVB_DEVICE_INFO pVBInfo);
+
+static void DualChipInit(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+
+static void XGINew_DisableRefresh(PXGI_HW_DEVICE_INFO ,PVB_DEVICE_INFO);
+static void XGINew_EnableRefresh(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+
+static void XGINew_Delay15us(ULONG);
+static void SetPowerConsume(PXGI_HW_DEVICE_INFO, USHORT);
+static void XGINew_DDR1x_MRS_XG20(USHORT, PVB_DEVICE_INFO);
+static void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+static void XGINew_ChkSenseStatus(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+
+static int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
+ PVB_DEVICE_INFO pVBInfo);
+static int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
+ PVB_DEVICE_INFO pVBInfo);
+static UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo);
+static void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+
+static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
+static ULONG UNIROM; /* UNIROM */
+
+
+#ifdef LINUX_KERNEL
+void DelayUS(ULONG MicroSeconds)
+{
+ udelay(MicroSeconds);
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+/* Function : XGIInitNew */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN XGIInitNew(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+#ifndef LINUX_XF86
+ USHORT Mclockdata[ 30 ] , Eclockdata[ 30 ] ;
+ UCHAR j , SR11 , SR17 = 0 , SR18 = 0 , SR19 = 0 ;
+ UCHAR CR37 = 0 , CR38 = 0 , CR79 = 0 , CR7A = 0 ,
+ CR7B = 0 , CR36 = 0 , CR78 = 0 , CR3C = 0 ,
+ CR3D = 0 , CR3E = 0 , CR3F = 0 , CR35 = 0 ;
+#endif
+ UCHAR i , temp = 0 , temp1 ,
+ VBIOSVersion[ 5 ] ;
+ ULONG base,ChipsetID,VendorID,GraphicVendorID;
+ PUCHAR volatile pVideoMemory;
+
+ /* ULONG j, k ; */
+
+ PXGI_DSReg pSR ;
+
+ ULONG Temp ;
+
+
+ XGINew_InitVBIOSData(HwDeviceExtension, pVBInfo);
+
+ pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr;
+
+
+ Newdebugcode( 0x99 ) ;
+
+ /* if ( pVBInfo->ROMAddr == 0 ) */
+ /* return( FALSE ) ; */
+
+ if ( pVBInfo->FBAddr == 0 )
+ return( FALSE ) ;
+
+ if ( pVBInfo->BaseAddr == 0 )
+ return( FALSE ) ;
+
+ XGI_SetRegByte((XGIIOADDRESS) ( USHORT )( pVBInfo->BaseAddr + 0x12 ) , 0x67 ) ; /* 3c2 <- 67 ,ynlai */
+
+
+ if ( !HwDeviceExtension->bIntegratedMMEnabled )
+ return( FALSE ) ; /* alan */
+
+
+
+ XGI_MemoryCopy( VBIOSVersion , HwDeviceExtension->szVBIOSVer , 4 ) ;
+
+ VBIOSVersion[ 4 ] = 0x0 ;
+
+
+ /* ReadVBIOSData */
+ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+
+ /* 1.Openkey */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x05 , 0x86 ) ;
+
+
+
+ /* 2.Reset Extended register */
+
+ for( i = 0x06 ; i < 0x20 ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+
+ for( i = 0x21 ; i <= 0x27 ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+
+ /* for( i = 0x06 ; i <= 0x27 ; i++ ) */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ; */
+
+
+ if(( HwDeviceExtension->jChipType == XG20 ) || ( HwDeviceExtension->jChipType >= XG40))
+ {
+ for( i = 0x31 ; i <= 0x3B ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+ }
+ else
+ {
+ for( i = 0x31 ; i <= 0x3D ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+ }
+
+ if ( HwDeviceExtension->jChipType == XG42 ) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B , 0xC0 ) ;
+
+ /* for( i = 0x30 ; i <= 0x3F ; i++ ) */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; */
+
+ for( i = 0x79 ; i <= 0x7C ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; /* shampoo 0208 */
+
+ /* Jong 10/01/2007; SetDefPCIRegs */ /* alan 12/07/2006 */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ for( i = 0xD0 ; i <= 0xDB ; i++ )
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->pCRD0[i-0xd0] ) ;
+ for( i = 0xDE ; i <= 0xDF ; i++ )
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->pCRDE[i-0xdE] ) ;
+ }
+
+
+ if ( HwDeviceExtension->jChipType >= XG20 )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x97, pVBInfo->CR97);
+
+ /* 3.SetMemoryClock */
+ if (!(pVBInfo->SoftSetting & SoftDRAMType)) {
+ if (( HwDeviceExtension->jChipType == XG20 )||( HwDeviceExtension->jChipType == XG21 )||( HwDeviceExtension->jChipType == XG27 ))
+ {
+ temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
+ }
+ else if (HwDeviceExtension->jChipType == XG45)
+ {
+ temp = 0x02 ;
+ }
+ else
+ {
+ temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
+ }
+ }
+
+
+ if ( HwDeviceExtension->jChipType == XG20 )
+ XGINew_RAMType = temp & 0x01 ;
+ else
+ {
+ XGINew_RAMType = temp & 0x03 ; /* alan */
+ }
+
+ /* Get DRAM type */
+ if ( HwDeviceExtension->jChipType == XG45 )
+ { }
+ else if ( HwDeviceExtension->jChipType >= XG40 )
+ XGINew_RAMType = ( int )XGINew_Get340DRAMType( HwDeviceExtension , pVBInfo) ;
+
+ if ( UNIROM == 1 ) XGINew_RAMType = 0;
+
+ if ( HwDeviceExtension->jChipType < XG40 )
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ /* 4.SetDefExt1Regs begin */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, pVBInfo->SR07);
+
+ /* Jong 10/01/2007; add for ??? */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x40 , *pVBInfo->pSR40 ) ;
+ XGI_SetReg( (XGIIOADDRESS)pVBInfo->P3c4 , 0x41 , *pVBInfo->pSR41 ) ;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x11, 0x0F);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, pVBInfo->SR1F);
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0x20); */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
+
+ /* Jong 10/01/2007; added for ??? */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x36 , 0x70 ) ; /* Hsuan, 2006/01/01 H/W request for slow corner chip */
+ if ( HwDeviceExtension->jChipType == XG27 ) /* Alan 12/07/2006 */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x36 , *pVBInfo->pSR36 ) ;
+
+ /* SR11 = 0x0F ; */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x11 , SR11 ) ; */
+
+
+ if ( (HwDeviceExtension->jChipType != XG20)
+ &&(HwDeviceExtension->jChipType != XG21)
+ &&(HwDeviceExtension->jChipType != XG27)
+ &&(HwDeviceExtension->jChipType != XG45) ) /* kuku 2004/06/25 */
+ {
+ /* Set AGP Rate */
+ temp1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B ) ;
+ temp1 &= 0x02 ;
+ if ( temp1 == 0x02 )
+ {
+ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
+ ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8000002C ) ;
+ VendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+ VendorID &= 0x0000FFFF ;
+ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8001002C ) ;
+ GraphicVendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+ GraphicVendorID &= 0x0000FFFF;
+
+ if ( ChipsetID == 0x7301039 )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x09 ) ;
+
+ ChipsetID &= 0x0000FFFF ;
+
+ if ( ( ChipsetID == 0x700E ) || ( ChipsetID == 0x1022 ) || ( ChipsetID == 0x1106 ) || ( ChipsetID == 0x10DE ) )
+ {
+ if ( ChipsetID == 0x1106 )
+ {
+ if ( ( VendorID == 0x1019 ) && ( GraphicVendorID == 0x1019 ) )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0D ) ;
+ else
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
+ }
+ else
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
+ }
+ }
+
+ if ( HwDeviceExtension->jChipType >= XG40 )
+ {
+ /* Set AGP customize registers (in SetDefAGPRegs) Start */
+ for( i = 0x47 ; i <= 0x4C ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ i - 0x47 ] ) ;
+
+ for( i = 0x70 ; i <= 0x71 ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 6 + i - 0x70 ] ) ;
+
+ for( i = 0x74 ; i <= 0x77 ; i++ )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 8 + i - 0x74 ] ) ;
+ /* Set AGP customize registers (in SetDefAGPRegs) End */
+ /*[Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
+ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
+ ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+ if ( ChipsetID == 0x25308086 )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x77 , 0xF0 ) ;
+
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x50 , 0 , &Temp ) ; /* Get */
+ Temp >>= 20 ;
+ Temp &= 0xF ;
+
+ if ( Temp == 1 )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , 0x20 ) ; /* CR48 */
+ }
+
+ if ( HwDeviceExtension->jChipType < XG40 )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x49 , pVBInfo->CR49[ 0 ] ) ;
+ } /* != XG20 */
+
+ /* Set PCI */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x23, pVBInfo->SR23);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x24, pVBInfo->SR24);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
+
+ if ( (HwDeviceExtension->jChipType != XG20) &&
+ (HwDeviceExtension->jChipType != XG21) &&
+ (HwDeviceExtension->jChipType != XG27) ) /* kuku 2004/06/25 */
+ {
+ /* Set VB */
+ XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ; /* alan, disable VideoCapture */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , 0x00 ) ;
+ temp1 = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7B ) ; /* chk if BCLK>=100MHz */
+ temp = ( UCHAR )( ( temp1 >> 4 ) & 0x0F ) ;
+
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02,
+ pVBInfo->CRT2Data_1_2);
+
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x2E , 0x08 ) ; /* use VB */
+ } /* != XG20 */
+
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x27 , 0x1F ) ;
+
+ /* Not DDR */
+ if ((HwDeviceExtension->jChipType == XG42)
+ && XGINew_Get340DRAMType(HwDeviceExtension, pVBInfo) != 0) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, (pVBInfo->SR31 & 0x3F) | 0x40);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, (pVBInfo->SR32 & 0xFC) | 0x01);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, pVBInfo->SR31);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, pVBInfo->SR32);
+ }
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x33, pVBInfo->SR33);
+
+
+
+ if ( HwDeviceExtension->jChipType >= XG40 )
+ SetPowerConsume ( HwDeviceExtension , pVBInfo->P3c4);
+
+ if ( (HwDeviceExtension->jChipType != XG20) &&
+ (HwDeviceExtension->jChipType != XG21) &&
+ (HwDeviceExtension->jChipType != XG27) ) /* kuku 2004/06/25 */
+ {
+ if ( XGI_BridgeIsOn( pVBInfo ) == 1 )
+ {
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0x1C);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, pVBInfo->CRT2Data_4_D);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, pVBInfo->CRT2Data_4_E);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, pVBInfo->CRT2Data_4_10);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0F, 0x3F);
+ }
+
+ XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
+ }
+ } /* != XG20 */
+
+ if ( HwDeviceExtension->jChipType < XG40 )
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x83 , 0x00 ) ;
+
+
+ /* Jong 10/01/2007; added for ??? */
+ if ( HwDeviceExtension->bSkipSense == FALSE )
+ {
+ XGI_SenseCRT1(pVBInfo) ;
+ /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
+ if ( ( HwDeviceExtension->jChipType == XG21 ) && (pVBInfo->IF_DEF_CH7007) )
+ {
+ XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
+ }
+ if ( HwDeviceExtension->jChipType == XG21 )
+ {
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
+ temp = GetXG21FPBits( pVBInfo ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 , ~0x01, temp ) ;
+ }
+ if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
+ temp = GetXG27FPBits( pVBInfo ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 , ~0x03, temp ) ;
+ }
+ }
+
+ if ( HwDeviceExtension->jChipType >= XG40 )
+ {
+ if (HwDeviceExtension->jChipType == XG45)
+ XGINew_SetDRAMDefaultRegisterXG45( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
+ else
+ XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
+
+ if ( HwDeviceExtension->bSkipDramSizing == TRUE )
+ {
+ pSR = HwDeviceExtension->pSR ;
+ if ( pSR!=NULL )
+ {
+ while( pSR->jIdx != 0xFF )
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , pSR->jIdx , pSR->jVal ) ;
+ pSR++ ;
+ }
+ }
+ /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
+ } /* SkipDramSizing */
+ else
+ {
+/* if ( HwDeviceExtension->jChipType == XG20 )
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , pVBInfo->SR15[0][XGINew_RAMType] ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , pVBInfo->SR15[1][XGINew_RAMType] ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x20 , 0x20 ) ;
+ }
+ else*/
+ if ( HwDeviceExtension->jChipType == XG45 )
+ XGINew_SetDRAMSize_XG45( HwDeviceExtension , pVBInfo) ;
+ else
+ XGINew_SetDRAMSize_340( HwDeviceExtension , pVBInfo) ;
+ }
+ } /* XG40 */
+
+
+
+
+ /* SetDefExt2Regs begin */
+/*
+ AGP = 1 ;
+ temp =( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
+ temp &= 0x30 ;
+ if ( temp == 0x30 )
+ AGP = 0 ;
+
+ if ( AGP == 0 )
+ pVBInfo->SR21 &= 0xEF ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , pVBInfo->SR21 ) ;
+ if ( AGP == 1 )
+ pVBInfo->SR22 &= 0x20;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x22 , pVBInfo->SR22 ) ;
+*/
+
+ base = 0x80000000;
+ XGI_SetRegLong(0xcf8, base);
+ Temp = (XGI_GetRegLong(0xcfc) & 0x0000FFFF);
+ if (Temp == 0x1039) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22 & 0xFE);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22);
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21, pVBInfo->SR21);
+
+ if ( HwDeviceExtension->jChipType == XG40 ) /* Initialize seconary chip */
+ {
+ if ( CheckDualChip(pVBInfo) )
+ DualChipInit( HwDeviceExtension , pVBInfo) ;
+ /* SetDefExt2Regs end */
+ }
+
+ /* Jong 10/01/2007; be removed and recoded */
+#if 0
+ if ( HwDeviceExtension->bSkipSense == FALSE )
+ {
+ XGI_SenseCRT1(pVBInfo) ;
+ /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
+ XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
+ }
+#endif
+
+ XGINew_ChkSenseStatus ( HwDeviceExtension , pVBInfo ) ;
+ XGINew_SetModeScratch ( HwDeviceExtension , pVBInfo ) ;
+
+ Newdebugcode( 0x88 ) ;
+
+ /* Johnson@062403. To save time for power management. */
+ /* DelayMS(1000); */
+ /* ~Johnson@062403. */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , 0x28 ) ; //0207 temp */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x36 , 0x02 ) ; //0207 temp */
+
+ return( TRUE ) ;
+} /* end of init */
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : DualChipInit */
+/* Input : */
+/* Output : */
+/* Description : Initialize the secondary chip. */
+/* --------------------------------------------------------------------- */
+void DualChipInit( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
+{
+#ifdef LINUX_XF86
+ USHORT BaseAddr2nd = (USHORT)(ULONG)HwDeviceExtension->pj2ndIOAddress ;
+#else
+ USHORT BaseAddr2nd = (USHORT)HwDeviceExtension->pj2ndIOAddress ;
+#endif
+ USHORT XGINew_P3C3 = pVBInfo->BaseAddr + VIDEO_SUBSYSTEM_ENABLE_PORT ;
+ USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT ;
+ USHORT XGINew_2ndP3C3 = BaseAddr2nd + VIDEO_SUBSYSTEM_ENABLE_PORT ;
+ USHORT XGINew_2ndP3D4 = BaseAddr2nd + CRTC_ADDRESS_PORT_COLOR ;
+ USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT ;
+ USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT ;
+ ULONG Temp ;
+ UCHAR tempal , i ;
+
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+ pVBInfo->BaseAddr = (USHORT)HwDeviceExtension->pjIOAddress ;
+ /* Programming Congiguration Space in Secondary Chip */
+ /* set CRA1 D[6] = 1 */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0xBF , 0x40 ) ;
+
+ /* Write 2nd Chip Configuration Info into Configuration Space */
+ /* Command CNFG04 */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND , 0 , &Temp ) ; /* Get */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND + 0x80 , 1 , &Temp ) ; /* Set */
+ /* Latency Timer CNFG0C */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c , 0 , &Temp ) ; /* Get */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c + 0x80 , 1 , &Temp ) ; /* Set */
+ /* Linear space */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 , 0 , &Temp ) ; /* Get */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 + 0x80 , 1 , &Temp ) ; /* Set */
+ /* MMIO space */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 , 0 , &Temp ) ; /* Get */
+ Temp += 0x40000;
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 + 0x80 , 1 , &Temp ) ; /* Set */
+ /* Relocated IO space */
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 , 0 , &Temp ) ; /* Get */
+ Temp += 0x80;
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 + 0x80 , 1 , &Temp ) ; /* Set */
+ /* Miscellaneous reg(input port 3cch,output port 3c2h) */
+ tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC ) ; /* 3cc */
+ XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2 , tempal ) ;
+ /* VGA enable reg(port 3C3h) */
+ tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3C3 ) ; /* 3c3 */
+ XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C3 , tempal ) ;
+ SetPowerConsume ( HwDeviceExtension , XGINew_2ndP3D4);
+ /* ----- CRA0=42, CRA1=81, CRA2=60, CRA3=20, CRA4=50, CRA5=40, CRA8=88 -----// */
+ /* ----- CRA9=10, CRAA=80, CRAB=01, CRAC=F1, CRAE=80, CRAF=45, CRB7=24 -----// */
+ /* primary chip */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA0 , 0x72 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0x81 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA2 , 0x60 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA3 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA4 , 0x50 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA5 , 0x40 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA8 , 0x88 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA9 , 0x10 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAA , 0x80 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAB , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAC , 0xF1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAE , 0x80 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAF , 0x45 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xB7 , 0x24 ) ;
+
+ /* secondary chip */
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA0 , 0x72 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA1 , 0x81 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA2 , 0x60 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA3 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA4 , 0x50 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA5 , 0x40 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA8 , 0x88 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA9 , 0x10 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAA , 0x80 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAB , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAC , 0xF1 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAE , 0x80 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAF , 0x45 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xB7 , 0x24 ) ;
+
+ /* 06/20/2003 [christine] CRT threshold setting request */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x78 , 0x40 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x79 , 0x0C ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7A , 0x34 ) ;
+
+ /* OpenKey in 2nd chip */
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x86 ) ;
+
+ /* Set PCI registers */
+ tempal = (UCHAR)XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x06 ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x06 , tempal ) ;
+
+ for( i = 0x20 ; i <= 0x25 ; i++ )
+ {
+ tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
+ }
+ for(i = 0x31; i <= 0x32; i++ )
+ {
+ tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
+ }
+ XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , XGINew_2ndP3D4 , pVBInfo) ;
+
+ for(i = 0x13; i <= 0x14; i++ )
+ {
+ tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
+ }
+
+ /* Close key in 2nd chip */
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x00 ) ;
+}
+
+
+
+
+/* ============== alan ====================== */
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_Get340DRAMType */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+UCHAR XGINew_Get340DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR data, temp ; /* Jong 10/05/2007; merge code */
+
+ if ( HwDeviceExtension->jChipType < XG20 )
+ {
+ if (pVBInfo->SoftSetting & SoftDRAMType) {
+ return (pVBInfo->SoftSetting & 0x07);
+ }
+ else
+ {
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ;
+
+ if ( data == 0 )
+ data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) & 0x02 ) >> 1 ;
+
+ return( data ) ;
+ }
+ }
+ else if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ if ( pVBInfo->SoftSetting & SoftDRAMType )
+ {
+ data = pVBInfo->SoftSetting & 0x07 ;
+ return( data ) ;
+ }
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3B ) ;
+
+ if (( temp & 0x88 )==0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+ data = 0 ; /*DDR*/
+ else
+ data = 1 ; /*DDRII*/
+ return( data ) ;
+ }
+ else if ( HwDeviceExtension->jChipType == XG21 )
+ {
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , ~0x02 ) ; /* Independent GPIO control */
+ DelayUS(800);
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , 0x80 ) ; /* Enable GPIOH read */
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ; /* GPIOF 0:DVI 1:DVO */
+
+ /* HOTPLUG_SUPPORT */
+ /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
+ if ( temp & 0x01 ) /* DVI read GPIOH */
+ data = 1 ; /*DDRII*/
+ else
+ data = 0 ; /*DDR*/
+
+ /*~HOTPLUG_SUPPORT */
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , 0x02 ) ;
+ return( data ) ;
+ }
+ else
+ {
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) & 0x01 ;
+
+ if ( data == 1 )
+ data ++ ;
+
+ return( data );
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_Delay15us */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+/*
+void XGINew_Delay15us(ULONG ulMicrsoSec)
+{
+}
+*/
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SDR_MRS */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ;
+ data &= 0x3F ; /* SR16 D7=0,D6=0 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) low */
+ /* XGINew_Delay15us( 0x100 ) ; */
+ data |= 0x80 ; /* SR16 D7=1,D6=0 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) high */
+ /* XGINew_Delay15us( 0x100 ) ; */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR1x_MRS_340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
+ if ( HwDeviceExtension->jChipType == XG42 ) /* XG42 BA0 & BA1 layout change */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ else
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ /* Samsung F Die */
+ if (pVBInfo->DRAMTypeDefinition != 0x0C) {
+ DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+ if ( HwDeviceExtension->jChipType == XG42 )
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ else
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ }
+
+ DelayUS( 60 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+
+ if (HwDeviceExtension->jChipType == XG45)
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ; /*TSop DRAM DLL pin jump to A9*/
+ else
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
+
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
+ DelayUS( 1000 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
+ DelayUS( 500 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR2x_MRS_340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+ if ( HwDeviceExtension->jChipType == XG42 ) /*XG42 BA0 & BA1 layout change*/
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ else
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ /* Samsung F Die */
+ if (pVBInfo->DRAMTypeDefinition != 0x0C) {
+ DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+ if ( HwDeviceExtension->jChipType == XG42 )
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ else
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ }
+
+ DelayUS( 60 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
+ DelayUS( 1000 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
+ DelayUS( 500 ) ;
+ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR2_MRS_340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = P3c4 + 0x10 ;
+ UCHAR data ;
+
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , 0x64 ) ; /* SR28 */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , 0x63 ) ; /* SR29 */
+ DelayUS( 200 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ DelayUS( 2 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
+
+ if( P3c4 != pVBInfo->P3c4 )
+ {
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , data ) ; /* SR28 */
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , data ) ; /* SR29 */
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2A , data ) ; /* SR2A */
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2e , data ) ; /* SR2E */
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2f , data ) ; /* SR2F */
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x30 , data ) ; /* SR30 */
+ }
+ else
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ DelayUS( 1000 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ DelayUS( 1 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
+ DelayUS( 5) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
+ DelayUS( 5 ) ;
+ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x72 ) ; */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x06 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+ DelayUS( 1 ) ;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDRII_Bootup_XG27 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDRII_Bootup_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = P3c4 + 0x10 ;
+ UCHAR data ;
+ XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ /* Set Double Frequency */
+ /* XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; */ /* CR97 */
+ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x97 , pVBInfo->CR97 ) ; /* CR97 */
+
+ DelayUS( 200 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS2*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x80 ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS3*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0xC0 ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
+ DelayUS( 15) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS1*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ /*MRS, DLL Enable*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x0A ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ; /* Set SR16 */
+ /* DelayUS( 15 ) ; */
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* Set SR1B */
+ DelayUS( 60 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* Set SR1B */
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ /*MRS, DLL Reset*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x08 ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
+
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x80 ) ; /* Set SR18 */ /*MRS, ODT*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x46 ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
+ DelayUS( 15 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* Set SR1B refresh control 000:close; 010:open */
+ DelayUS( 200 ) ;
+}
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR2_MRS_XG20 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR2_MRS_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = P3c4 + 0x10 ;
+ UCHAR data ;
+
+ XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
+
+ DelayUS( 200 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x80 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0xC0 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+
+ /* XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ;*/ /* MRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+
+ DelayUS( 15 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
+ DelayUS( 100 ) ;
+
+ /*XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ;*/ /* MRS2 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+
+ DelayUS( 200 ) ;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR2_MRS_XG27 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR2_MRS_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = P3c4 + 0x10 ;
+ UCHAR data ;
+
+ XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
+ DelayUS( 200 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x80 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x10 ) ;
+ DelayUS( 15 ) ; /* 06/11/23 XG27 A0 for CKE enable*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x90 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0xC0 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ DelayUS( 15 ) ; /*06/11/22 XG27 A0*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ DelayUS( 15 ) ; /*06/11/22 XG27 A0 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x06 ) ; /*[Billy]06/11/22 DLL Reset for XG27 Hynix DRAM*/
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ DelayUS( 15 ) ; /*06/11/23 XG27 A0*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ DelayUS( 30 ) ; /*06/11/23 XG27 A0 Start Auto-PreCharge*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
+ DelayUS( 60 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
+
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x04 ) ; /* DLL without Reset for XG27 Hynix DRAM*/
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x80 ); /*XG27 OCD ON */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x46 );
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 );
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 );
+
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ DelayUS( 30 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+
+ DelayUS( 15 ) ; /*Start Auto-PreCharge*/
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
+ DelayUS( 200 ) ;
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ; /* SR1B */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR1x_DefaultRegister */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT Port, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = Port ,
+ P3c4 = Port - 0x10 ;
+#ifndef LINUX_XF86
+ UCHAR data ;
+#endif
+ if ( HwDeviceExtension->jChipType >= XG20 )
+ {
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+
+ XGINew_DDR1x_MRS_XG20( P3c4 , pVBInfo) ;
+ }
+ else
+ {
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ switch( HwDeviceExtension->jChipType )
+ {
+ case XG41:
+ case XG42:
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+ break ;
+ default:
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+ break ;
+ }
+ if (HwDeviceExtension->jChipType != XG45)
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+ XGINew_DDR1x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR2x_DefaultRegister */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT Port, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = Port ,
+ P3c4 = Port - 0x10 ;
+
+#ifndef LINUX_XF86
+ UCHAR data ;
+#endif
+
+ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+
+ /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
+ switch( HwDeviceExtension->jChipType )
+ {
+ case XG41:
+ case XG42:
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+ break ;
+ default:
+ /* keep following setting sequence, each setting in the same reg insert idle */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+ }
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ;
+ if ( HwDeviceExtension->jChipType == XG42 )
+ {
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+ }
+ else
+ {
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
+ }
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+
+ XGINew_DDR2x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR2_DefaultRegister */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT Port, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT P3d4 = Port ,
+ P3c4 = Port - 0x10 ;
+
+ /* keep following setting sequence, each setting in the same reg insert idle */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+
+ /* Jong 10/01/2007 */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ XGINew_DDRII_Bootup_XG27( HwDeviceExtension , P3c4 , pVBInfo) ;
+ else if ( HwDeviceExtension->jChipType >= XG20 )
+ XGINew_DDR2_MRS_XG20( HwDeviceExtension , P3c4, pVBInfo ) ;
+ else
+ XGINew_DDR2_MRS_340( HwDeviceExtension , P3c4, pVBInfo ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMDefaultRegister340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR temp , temp1 , temp2 , temp3 ,
+ i , j , k ;
+
+ USHORT P3d4 = Port ,
+ P3c4 = Port - 0x10 ;
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
+
+ temp2 = 0 ;
+ for( i = 0 ; i < 4 ; i++ )
+ {
+ temp = pVBInfo->CR6B[ XGINew_RAMType ][ i ] ; /* CR6B DQS fine tune delay */
+ for( j = 0 ; j < 4 ; j++ )
+ {
+ temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp2 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6B ) ; /* Insert read command for delay */
+ temp2 &= 0xF0 ;
+ temp2 += 0x10 ;
+ }
+ }
+
+ temp2 = 0 ;
+ for( i = 0 ; i < 4 ; i++ )
+ {
+ temp = pVBInfo->CR6E[ XGINew_RAMType ][ i ] ; /* CR6E DQM fine tune delay */
+ for( j = 0 ; j < 4 ; j++ )
+ {
+ temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , temp2 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6E ) ; /* Insert read command for delay */
+ temp2 &= 0xF0 ;
+ temp2 += 0x10 ;
+ }
+ }
+
+ temp3 = 0 ;
+ for( k = 0 ; k < 4 ; k++ )
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x6E , 0xFC , temp3 ) ; /* CR6E_D[1:0] select channel */
+ temp2 = 0 ;
+ for( i = 0 ; i < 8 ; i++ )
+ {
+ temp = pVBInfo->CR6F[ XGINew_RAMType ][ 8 * k + i ] ; /* CR6F DQ fine tune delay */
+ for( j = 0 ; j < 4 ; j++ )
+ {
+ temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , temp2 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6F ) ; /* Insert read command for delay */
+ temp2 &= 0xF8 ;
+ temp2 += 0x08 ;
+ }
+ }
+ temp3 += 0x01 ;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
+
+ temp2 = 0x80 ;
+ temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
+ for( j = 0 ; j < 4 ; j++ )
+ {
+ temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
+ temp2 &= 0xF0 ;
+ temp2 += 0x10 ;
+ }
+
+ temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
+ temp1 = temp & 0x03 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+
+ temp = pVBInfo->CR40[ 3 ][ XGINew_RAMType ] ;
+ temp1 = temp & 0x0F ;
+ temp2 = ( temp >> 4 ) & 0x07 ;
+ temp3 = temp & 0x80 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , temp1 ) ; /* CR45 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , temp2 ) ; /* CR99 */
+ XGI_SetRegOR((XGIIOADDRESS) P3d4 , 0x40 , temp3 ) ; /* CR40_D[7] */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , pVBInfo->CR40[ 0 ][ XGINew_RAMType ] ) ; /* CR41 */
+
+ /* Jong 10/01/2007; */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x8F , *pVBInfo->pCR8F ) ; /* CR8F */
+
+ for( j = 0 ; j <= 6 ; j++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
+
+ for( j = 0 ; j <= 2 ; j++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
+
+ for( j = 0 ; j < 2 ; j++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
+
+ if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
+
+ /* Jong 10/01/2007 */
+ if ( XGINew_RAMType )
+ {
+ /*XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0xC0 ) ;*/ /* SR17 DDRII */
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0x80 ) ; /* SR17 DDRII */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0x02 ) ; /* SR17 DDRII */
+
+ }
+ else
+ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0x00 ) ; /* SR17 DDR */
+
+ XGI_SetReg((XGIIOADDRESS) P3c4, 0x1A, 0x87); /* SR1A */
+
+ temp = XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) ;
+ if( temp == 0 )
+ XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+ else if ( temp == 0x02 )
+ XGINew_DDR2x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+ else
+ XGINew_DDR2_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMDefaultRegisterXG45 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SetDRAMDefaultRegisterXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR temp , temp1 , temp2 ,
+ i , j , k ;
+
+ USHORT P3d4 = Port ,
+ P3c4 = Port - 0x10 ;
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , pVBInfo->XG45CR6E[ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , pVBInfo->XG45CR6F[ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
+
+ temp = 0x00 ;
+ for ( j = 0 ; j < 24 ; j ++ )
+ {
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp );
+ temp += 0x08 ;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
+
+ temp2 = 0x80 ;
+ temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
+ for( j = 0 ; j < 4 ; j++ )
+ {
+ temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
+ temp2 &= 0xF0 ;
+ temp2 += 0x10 ;
+ }
+
+ temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
+ temp1 = temp & 0x03 ;
+ temp2 |= temp1 ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+
+ temp = 0x00 ;
+ for ( j = 0 ; j < 3 ; j ++ )
+ {
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x40 , temp );
+ temp += 0x40 ;
+ }
+
+ temp = 0x00 ;
+ for ( j = 0 ; j < 24 ; j ++ )
+ {
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , temp );
+ temp += 0x08 ;
+ }
+
+ temp = 0x00 ;
+ for ( j = 0 ; j < 24 ; j ++ )
+ {
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x42 , temp );
+ temp += 0x08 ;
+ }
+
+ for ( k = 0 ; k < 2 ; k ++ )
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x04 , k * 0x04 );
+
+ for ( i = 0 ; i < 3 ; i ++ )
+ {
+
+ XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x03 , i * 0x01 );
+
+ for ( j = 0 ; j < 32 ; j ++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x44 , j * 0x08 );
+ }
+ }
+
+ for ( j = 0 ; j < 3 ; j ++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , j * 0x08 ) ; /* CR45 */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x84 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , 0x22 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+
+ for( j = 0 ; j <= 6 ; j++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
+
+ for( j = 0 ; j <= 2 ; j++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0xC8 , 0x04 ) ;
+
+ for( j = 0 ; j < 2 ; j++ )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
+
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x40 ) ;
+
+ if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
+ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
+
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
+ XGI_SetReg((XGIIOADDRESS) P3d4, 0x8D, 0x87); /* CR8D */
+
+ XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1A , 0x87 ) ; /* SR1A */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR_MRS */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+
+ /* SR16 <- 1F,DF,2F,AF */
+ /* yriver modified SR16 <- 0F,DF,0F,AF */
+ /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
+ data = pVideoMemory[ 0xFB ] ;
+ /* data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ; */
+
+ data &= 0x0F ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data |= 0xC0 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data &= 0x0F ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data |= 0x80 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data &= 0x0F ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data |= 0xD0 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data &= 0x0F ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+ data |= 0xA0 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+/*
+ else {
+ data &= 0x0F;
+ data |= 0x10;
+ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+
+ if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
+ {
+ data &= 0x0F;
+ }
+
+ data |= 0xC0;
+ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+
+
+ data &= 0x0F;
+ data |= 0x20;
+ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+ if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
+ {
+ data &= 0x0F;
+ }
+
+ data |= 0x80;
+ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+ }
+*/
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMSize_340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /* disable read cache */
+
+ /* Jong 10/03/2007; add support for DVO, XG27, ...*/
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo );
+ /* data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
+ data |= 0x20 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; */ /* Turn OFF Display */
+
+ XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
+
+ data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /* enable read cache */
+}
+
+
+/*--------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMSize_XG45 */
+/*Input : */
+/*Output : */
+/*Description : */
+/*--------------------------------------------------------------------- */
+void XGINew_SetDRAMSize_XG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /*disable read cache*/
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
+ data |= 0x20 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; /*Turn OFF Display*/
+
+ XGINew_DDRSizingXG45( HwDeviceExtension, pVBInfo ) ;
+
+ data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /*enable read cache*/
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMModeRegister340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+
+void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR data ;
+
+ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+
+ if (HwDeviceExtension->jChipType == XG45)
+ XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+ else
+ {
+ if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
+ {
+ data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ) >> 1 ;
+ if ( data == 0x01 )
+ XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+ else
+ XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+ }
+ else
+ XGINew_DDR2_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DisableRefresh */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B ) ;
+ data &= 0xF8 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , data ) ;
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_EnableRefresh */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+{
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DisableChannelInterleaving */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DisableChannelInterleaving(int index,
+ const USHORT XGINew_DDRDRAM_TYPE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
+ data &= 0x1F ;
+
+ switch( XGINew_DDRDRAM_TYPE[ index ][ 3 ] )
+ {
+ case 64:
+ data |= 0 ;
+ break ;
+ case 32:
+ data |= 0x20 ;
+ break ;
+ case 16:
+ data |= 0x40 ;
+ break ;
+ case 4:
+ data |= 0x60 ;
+ break ;
+ default:
+ break ;
+ }
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMSizingType */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SetDRAMSizingType(int index , const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+
+ data = DRAMTYPE_TABLE[ index ][ 4 ] ;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
+ /* should delay 50 ns */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetRank */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
+ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+ int RankSize ;
+
+ if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
+ return 0 ;
+
+ RankSize = DRAMTYPE_TABLE[ index ][ 3 ] / 2 * XGINew_DataBusWidth / 32 ;
+
+ if ( ( RankNo * RankSize ) <= 128 )
+ {
+ data = 0 ;
+
+ while( ( RankSize >>= 1 ) > 0 )
+ {
+ data += 0x10 ;
+ }
+ data |= ( RankNo - 1 ) << 2 ;
+ data |= ( XGINew_DataBusWidth / 64 ) & 2 ;
+ data |= XGINew_ChannelAB ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
+ /* should delay */
+ XGINew_SDR_MRS( pVBInfo ) ;
+ return( 1 ) ;
+ }
+ else
+ return( 0 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDDRChannel */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_SetDDRChannel(int index, UCHAR ChannelNo, UCHAR XGINew_ChannelAB,
+ const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data ;
+ int RankSize ;
+
+ RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
+ /* RankSize = DRAMTYPE_TABLE[ index ][ 3 ] ; */
+ if ( ChannelNo * RankSize <= 128 )
+ {
+ data = 0 ;
+ while( ( RankSize >>= 1 ) > 0 )
+ {
+ data += 0x10 ;
+ }
+
+ if ( ChannelNo == 2 )
+ data |= 0x0C ;
+
+ data |= ( XGINew_DataBusWidth / 32 ) & 2 ;
+ data |= XGINew_ChannelAB ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
+ /* should delay */
+ XGINew_DDR_MRS( pVBInfo ) ;
+ return( 1 ) ;
+ }
+ else
+ return( 0 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckColumn */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ ULONG Increment , Position ;
+
+ /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
+ Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
+
+ for( i = 0 , Position = 0 ; i < 2 ; i++ )
+ {
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+ Position += Increment ;
+ }
+
+ for( i = 0 , Position = 0 ; i < 2 ; i++ )
+ {
+ /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+ Position += Increment ;
+ }
+ return( 1 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckBanks */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ ULONG Increment , Position ;
+
+ Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
+
+ for( i = 0 , Position = 0 ; i < 4 ; i++ )
+ {
+ /* pVBInfo->FBAddr[ Position ] = Position ; */
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+ Position += Increment ;
+ }
+
+ for( i = 0 , Position = 0 ; i < 4 ; i++ )
+ {
+ /* if (pVBInfo->FBAddr[ Position ] != Position ) */
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+ Position += Increment ;
+ }
+ return( 1 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckRank */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_CheckRank(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ ULONG Increment , Position ;
+
+ Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
+ DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
+
+ for( i = 0 , Position = 0 ; i < 2 ; i++ )
+ {
+ /* pVBInfo->FBAddr[ Position ] = Position ; */
+ /* *( ( PULONG )( pVBInfo->FBAddr ) ) = Position ; */
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+ Position += Increment ;
+ }
+
+ for( i = 0 , Position = 0 ; i < 2 ; i++ )
+ {
+ /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
+ /* if ( ( *( PULONG )( pVBInfo->FBAddr ) ) != Position ) */
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+ Position += Increment ;
+ }
+ return( 1 );
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckDDRRank */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_CheckDDRRank(int RankNo, int index,
+ const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ ULONG Increment , Position ;
+ USHORT data ;
+
+ Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
+ DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
+
+ Increment += Increment / 2 ;
+
+ Position = 0;
+ *( ( PULONG )( pVBInfo->FBAddr + Position + 0 ) ) = 0x01234567 ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position + 1 ) ) = 0x456789AB ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position + 2 ) ) = 0x55555555 ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position + 3 ) ) = 0x55555555 ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position + 4 ) ) = 0xAAAAAAAA ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position + 5 ) ) = 0xAAAAAAAA ;
+
+ if ( ( *( PULONG )( pVBInfo->FBAddr + 1 ) ) == 0x456789AB )
+ return( 1 ) ;
+
+ if ( ( *( PULONG )( pVBInfo->FBAddr + 0 ) ) == 0x01234567 )
+ return( 0 ) ;
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) ;
+ data &= 0xF3 ;
+ data |= 0x0E ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
+ data += 0x20 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
+
+ return( 1 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckRanks */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_CheckRanks(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int r ;
+
+ for( r = RankNo ; r >= 1 ; r-- )
+ {
+ if ( !XGINew_CheckRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
+ return( 0 ) ;
+ }
+
+ if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
+ return( 0 ) ;
+
+ if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
+ return( 0 ) ;
+
+ return( 1 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckDDRRanks */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_CheckDDRRanks(int RankNo, int index,
+ const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int r ;
+
+ for( r = RankNo ; r >= 1 ; r-- )
+ {
+ if ( !XGINew_CheckDDRRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
+ return( 0 ) ;
+ }
+
+ if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
+ return( 0 ) ;
+
+ if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
+ return( 0 ) ;
+
+ return( 1 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ UCHAR j ;
+
+ for( i = 0 ; i < 13 ; i++ )
+ {
+ XGINew_SetDRAMSizingType( i , XGINew_SDRDRAM_TYPE , pVBInfo) ;
+
+ for( j = 2 ; j > 0 ; j-- )
+ {
+ if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_SDRDRAM_TYPE , pVBInfo) )
+ continue ;
+ else
+ {
+ if ( XGINew_CheckRanks( j , i , XGINew_SDRDRAM_TYPE, pVBInfo) )
+ return( 1 ) ;
+ }
+ }
+ }
+ return( 0 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMSizeReg */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT XGINew_SetDRAMSizeReg(int index, const USHORT DRAMTYPE_TABLE[][5],
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data = 0 , memsize = 0 ;
+ int RankSize ;
+ UCHAR ChannelNo ;
+
+ RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 ) ;
+ data &= 0x80 ;
+
+ if ( data == 0x80 )
+ RankSize *= 2 ;
+
+ data = 0 ;
+
+ if( XGINew_ChannelAB == 3 )
+ ChannelNo = 4 ;
+ else
+ ChannelNo = XGINew_ChannelAB ;
+
+ if ( ChannelNo * RankSize <= 256 )
+ {
+ while( ( RankSize >>= 1 ) > 0 )
+ {
+ data += 0x10 ;
+ }
+
+ memsize = data >> 4 ;
+
+ /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
+
+ /* data |= XGINew_ChannelAB << 2 ; */
+ /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ; */
+
+ /* should delay */
+ /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
+ }
+ return( memsize ) ;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMSize20Reg */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT XGINew_SetDRAMSize20Reg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data = 0 , memsize = 0 ;
+ int RankSize ;
+ UCHAR ChannelNo ;
+
+ RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 8 ;
+ data = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x13 ) ;
+ data &= 0x80 ;
+
+ if ( data == 0x80 )
+ RankSize *= 2 ;
+
+ data = 0 ;
+
+ if( XGINew_ChannelAB == 3 )
+ ChannelNo = 4 ;
+ else
+ ChannelNo = XGINew_ChannelAB ;
+
+ if ( ChannelNo * RankSize <= 256 )
+ {
+ while( ( RankSize >>= 1 ) > 0 )
+ {
+ data += 0x10 ;
+ }
+
+ memsize = data >> 4 ;
+
+ /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
+ DelayUS( 15 ) ;
+
+ /* data |= XGINew_ChannelAB << 2 ; */
+ /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
+ /* XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ; */
+
+ /* should delay */
+ /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
+ }
+ return( memsize ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_ReadWriteRest */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ ULONG Position = 0 ;
+
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+
+ for( i = StartAddr ; i <= StopAddr ; i++ )
+ {
+ Position = 1 << i ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+ }
+
+ DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+
+ Position = 0 ;
+
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+
+ for( i = StartAddr ; i <= StopAddr ; i++ )
+ {
+ Position = 1 << i ;
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+ }
+ return( 1 ) ;
+}
+
+
+/*--------------------------------------------------------------------- */
+/* Function : XGI45New_ReadWriteRest */
+/* Input : */
+/* Output : */
+/* Description : return 0 : fail, 1 : pass */
+/*--------------------------------------------------------------------- */
+int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ ULONG Position = 0 ;
+
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+
+ for( i = StartAddr ; i <= StopAddr ; i++ )
+ {
+ Position = 1 << i ;
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+ }
+
+ if ( XGINew_ChannelAB == 4 )
+ {
+ Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
+ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+ }
+
+ DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+
+ Position = 0 ;
+
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+
+ for( i = StartAddr ; i <= StopAddr ; i++ )
+ {
+ Position = 1 << i ;
+ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+ return( 0 ) ;
+ }
+
+ if ( XGINew_ChannelAB == 4 )
+ {
+ Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
+ if( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position );
+ return( 0 ) ;
+ }
+ return( 1 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckFrequence */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR data ;
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
+
+ if ( ( data & 0x10 ) == 0 )
+ {
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) ;
+ data = ( data & 0x02 ) >> 1 ;
+ return( data ) ;
+ }
+ else
+ return( data & 0x01 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_CheckChannel */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR i, data ;
+
+ switch( HwDeviceExtension->jChipType )
+ {
+ case XG20:
+ case XG21:
+ data = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
+ data = data & 0x01;
+ XGINew_ChannelAB = 1 ; /* XG20 "JUST" one channel */
+
+ if ( data == 0 ) /* Single_32_16 */
+ {
+ /* Jong 10/03/2007 */
+ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x1000000)
+ {
+
+ XGINew_DataBusWidth = 32 ; /* 32 bits */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 32bit */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
+ DelayUS( 15 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ /* Jong 10/03/2007 */
+ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* 22bit + 1 rank + 32bit */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
+ DelayUS( 15 ) ;
+
+ if ( XGINew_ReadWriteRest( 23 , 23 , pVBInfo ) == 1 )
+ return ;
+ }
+ }
+
+ /* Jong 10/03/2007 */
+ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
+ {
+ XGINew_DataBusWidth = 16 ; /* 16 bits */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 16bit */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
+ DelayUS( 15 ) ;
+
+ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+ return ;
+ else
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
+
+ DelayUS( 15 ) ;
+ }
+ }
+ else /* Dual_16_8 */
+ {
+ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
+ {
+
+ XGINew_DataBusWidth = 16 ; /* 16 bits */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
+ DelayUS( 15 ) ;
+
+ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+ return ;
+
+ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
+ {
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x31 ) ;
+ DelayUS( 15 ) ;
+
+ if ( XGINew_ReadWriteRest( 22 , 22 , pVBInfo ) == 1 )
+ return ;
+ }
+ }
+
+
+ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
+ {
+ XGINew_DataBusWidth = 8 ; /* 8 bits */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
+ DelayUS( 15 ) ;
+
+ if ( XGINew_ReadWriteRest( 22 , 21 , pVBInfo ) == 1 )
+ return ;
+ else
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
+ DelayUS( 15 ) ;
+ }
+ }
+ break ;
+
+ case XG27:
+ XGINew_DataBusWidth = 16 ; /* 16 bits */
+ XGINew_ChannelAB = 1 ; /* Single channel */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x51 ) ; /* 32Mx16 bit*/
+ break ;
+
+ case XG41:
+ if ( XGINew_CheckFrequence(pVBInfo) == 1 )
+ {
+ XGINew_DataBusWidth = 32 ; /* 32 bits */
+ XGINew_ChannelAB = 3 ; /* Quad Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
+
+ if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 2 ; /* Dual channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x49 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 3 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
+
+ if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
+ return ;
+ else
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x39 ) ;
+ }
+ else
+ { /* DDR */
+ XGINew_DataBusWidth = 64 ; /* 64 bits */
+ XGINew_ChannelAB = 2 ; /* Dual channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
+
+ if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 1 ; /* Single channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x53 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 2 ; /* Dual channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 1 ; /* Single channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
+
+ if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
+ return ;
+ else
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x43 ) ;
+ }
+
+ break ;
+
+ case XG42:
+/*
+ XG42 SR14 D[3] Reserve
+ D[2] = 1, Dual Channel
+ = 0, Single Channel
+
+ It's Different from Other XG40 Series.
+*/
+ if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII, DDR2x */
+ {
+ XGINew_DataBusWidth = 32 ; /* 32 bits */
+ XGINew_ChannelAB = 2 ; /* 2 Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x44 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x34 ) ;
+ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 1 ; /* Single Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x40 ) ;
+
+ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+ return ;
+ else
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
+ }
+ }
+ else
+ { /* DDR */
+ XGINew_DataBusWidth = 64 ; /* 64 bits */
+ XGINew_ChannelAB = 1 ; /* 1 channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+ else
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
+ }
+ }
+
+ break ;
+
+ case XG45:
+
+ XGINew_DataBusWidth = 64 ; /* 64 bits */
+ XGINew_ChannelAB = 4 ; /* 3+1 Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
+
+ if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 3 ; /* 3 Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
+
+ if ( XGI45New_ReadWriteRest( 26 , 24 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 2 ; /* 2 Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
+
+ if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 1 ; /* 1 Channel */
+ for ( i = 0; i <= 2; i++)
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
+
+ if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+ }
+
+ XGINew_ChannelAB = 3 ; /* 3 Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
+
+ if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 2 ; /* 2 Channel */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
+
+ if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 1 ; /* 1 Channel */
+ for ( i = 0; i <= 2; i++)
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
+
+ if ( XGI45New_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+ return ;
+ }
+ break ;
+
+ default: /* XG40 */
+
+ if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII */
+ {
+ XGINew_DataBusWidth = 32 ; /* 32 bits */
+ XGINew_ChannelAB = 3 ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
+
+ if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGINew_ChannelAB = 2 ; /* 2 channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ return ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
+
+ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+ XGINew_ChannelAB = 3 ; /* 4 channels */
+ else
+ {
+ XGINew_ChannelAB = 2 ; /* 2 channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
+ }
+ }
+ else
+ { /* DDR */
+ XGINew_DataBusWidth = 64 ; /* 64 bits */
+ XGINew_ChannelAB = 2 ; /* 2 channels */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
+
+ if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+ return ;
+ else
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
+ }
+ }
+ break ;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDRSizing340 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ USHORT memsize , addr ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
+ XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
+
+ /* Jong 10/03/2007 */
+ if ( HwDeviceExtension->jChipType >= XG20 )
+ {
+ for( i = 0 ; i < 12 ; i++ )
+ {
+ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
+ memsize = XGINew_SetDRAMSize20Reg( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
+ if ( memsize == 0 )
+ continue ;
+
+ addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
+ if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+ continue ;
+
+ if ( XGINew_ReadWriteRest( addr , 5, pVBInfo ) == 1 )
+ return( 1 ) ;
+ }
+ }
+ else
+ {
+ for( i = 0 ; i < 4 ; i++ )
+ {
+ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+ memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+ if ( memsize == 0 )
+ continue ;
+
+ addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
+ if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+ continue ;
+
+ if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
+ return( 1 ) ;
+ }
+ }
+ return( 0 ) ;
+}
+
+
+/*--------------------------------------------------------------------- */
+/* Function : XGINew_DDRSizingXG45 */
+/* Input : */
+/* Output : */
+/* Description : */
+/*--------------------------------------------------------------------- */
+int XGINew_DDRSizingXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ USHORT memsize , addr ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
+ XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
+
+ for( i = 0 ; i < 4 ; i++ )
+ {
+ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+ memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+ if ( memsize == 0 )
+ continue ;
+
+ addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
+ if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+ continue ;
+
+ if ( XGI45New_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
+ return( 1 ) ;
+ }
+ return( 0 ) ;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDRSizing */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
+{
+ int i ;
+ UCHAR j ;
+
+ for( i = 0 ; i < 4 ; i++ )
+ {
+ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE, pVBInfo ) ;
+ XGINew_DisableChannelInterleaving( i , XGINew_DDRDRAM_TYPE , pVBInfo) ;
+ for( j = 2 ; j > 0 ; j-- )
+ {
+ XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
+ if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE, pVBInfo ) )
+ continue ;
+ else
+ {
+ if ( XGINew_CheckDDRRanks( j , i , XGINew_DDRDRAM_TYPE, pVBInfo ) )
+ return( 1 ) ;
+ }
+ }
+ }
+ return( 0 ) ;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetMemoryClock */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+#ifndef LINUX_XF86
+ UCHAR tempal ;
+#endif
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 , pVBInfo->MCLKData[ XGINew_RAMType ].SR28 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 , pVBInfo->MCLKData[ XGINew_RAMType ].SR29 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A , pVBInfo->MCLKData[ XGINew_RAMType ].SR2A ) ;
+
+
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , pVBInfo->ECLKData[ XGINew_RAMType ].SR2E ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , pVBInfo->ECLKData[ XGINew_RAMType ].SR2F ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , pVBInfo->ECLKData[ XGINew_RAMType ].SR30 ) ;
+
+ /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
+ /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
+ if ( HwDeviceExtension->jChipType == XG42 )
+ {
+ if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
+ && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
+ || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 , ( ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 ) & 0xFC ) | 0x02 ) ;
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* input : dx ,valid value : CR or second chip's CR */
+/* */
+/* SetPowerConsume : */
+/* Description: reduce 40/43 power consumption in first chip or */
+/* in second chip, assume CR A1 D[6]="1" in this case */
+/* output : none */
+/* --------------------------------------------------------------------- */
+void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT XGI_P3d4Port )
+{
+ ULONG lTemp ;
+ UCHAR bTemp;
+
+ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
+ if ((lTemp&0xFF)==0)
+ {
+ /* set CR58 D[5]=0 D[3]=0 */
+ XGI_SetRegAND((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 ) ;
+ bTemp = (UCHAR) XGI_GetReg((XGIIOADDRESS) XGI_P3d4Port , 0xCB ) ;
+ if (bTemp&0x20)
+ {
+ if (!(bTemp&0x10))
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x20 ) ; /* CR58 D[5]=1 D[3]=0 */
+ }
+ else
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x08 ) ; /* CR58 D[5]=0 D[3]=1 */
+ }
+
+ }
+
+ }
+}
+
+
+void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+
+ /* ULONG ROMAddr = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ pVBInfo->BaseAddr = ( USHORT )HwDeviceExtension->pjIOAddress ;
+ pVBInfo->RelIO = HwDeviceExtension->pjIOAddress - 0x30;
+ pVBInfo->ISXPDOS = 0 ;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
+
+ pVBInfo->IF_DEF_LCDA = 1 ;
+ pVBInfo->IF_DEF_VideoCapture = 0 ;
+ pVBInfo->IF_DEF_ScaleLCD = 0 ;
+ pVBInfo->IF_DEF_OEMUtil = 0 ;
+ pVBInfo->IF_DEF_PWD = 0 ;
+
+ if ( HwDeviceExtension->jChipType >= XG20 ) /* kuku 2004/06/25 */
+ {
+ pVBInfo->IF_DEF_YPbPr = 0 ;
+ pVBInfo->IF_DEF_HiVision = 0 ;
+ pVBInfo->IF_DEF_CRT2Monitor = 0 ;
+ }
+ else if ( HwDeviceExtension->jChipType >= XG40 )
+ {
+ pVBInfo->IF_DEF_YPbPr = 1 ;
+ pVBInfo->IF_DEF_HiVision = 1 ;
+ pVBInfo->IF_DEF_CRT2Monitor = 1 ;
+ }
+ else
+ {
+ pVBInfo->IF_DEF_YPbPr = 1 ;
+ pVBInfo->IF_DEF_HiVision = 1 ;
+ pVBInfo->IF_DEF_CRT2Monitor = 0 ;
+ }
+
+ if ( (HwDeviceExtension->jChipType != XG20) &&
+ (HwDeviceExtension->jChipType != XG21) &&
+ (HwDeviceExtension->jChipType != XG27)) {
+ /* alan, disable VideoCapture */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
+ }
+
+ XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
+ InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : ReadVBIOSTablData */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
+{
+#ifndef LINUX_XF86
+ ULONG ulOffset ;
+ UCHAR temp , index , l ;
+#endif
+ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+ ULONG i ;
+ UCHAR j , k ;
+ ULONG ii , jj ;
+
+ i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ; /* UniROM */
+ if ( i != 0 )
+ UNIROM = 1 ;
+
+ ii = 0x90 ;
+ for( jj = 0x00 ; jj < 0x08 ; jj++ )
+ {
+ pVBInfo->MCLKData[ jj ].SR28 = pVideoMemory[ ii ] ;
+ pVBInfo->MCLKData[ jj ].SR29 = pVideoMemory[ ii + 1] ;
+ pVBInfo->MCLKData[ jj ].SR2A = pVideoMemory[ ii + 2] ;
+ pVBInfo->MCLKData[ jj ].CLOCK = pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
+ ii += 0x05 ;
+ }
+
+ ii = 0xB8 ;
+ for( jj = 0x00 ; jj < 0x08 ; jj++ )
+ {
+ pVBInfo->ECLKData[ jj ].SR2E = pVideoMemory[ ii ] ;
+ pVBInfo->ECLKData[ jj ].SR2F=pVideoMemory[ ii + 1 ] ;
+ pVBInfo->ECLKData[ jj ].SR30= pVideoMemory[ ii + 2 ] ;
+ pVBInfo->ECLKData[ jj ].CLOCK= pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
+ ii += 0x05 ;
+ }
+
+ /* Volari customize data area start */
+ /* if ( ChipType == XG40 ) */
+ if ( ChipType >= XG40 )
+ {
+ ii = 0xE0 ;
+ for( jj = 0x00 ; jj < 0x03 ; jj++ )
+ {
+ pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR13, SR14, and SR18 */
+ pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+ pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+ pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+ pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+ pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+ pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+ pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+ ii += 0x08 ;
+ }
+ ii = 0x110 ;
+ jj = 0x03 ;
+ pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR1B */
+ pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+ pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+ pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+ pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+ pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+ pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+ pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+
+ pVBInfo->SR07 = pVideoMemory[0x74];
+ pVBInfo->SR1F = pVideoMemory[0x75];
+ pVBInfo->SR21 = pVideoMemory[0x76];
+ pVBInfo->SR22 = pVideoMemory[0x77];
+ pVBInfo->SR23 = pVideoMemory[0x78];
+ pVBInfo->SR24 = pVideoMemory[0x79];
+ pVBInfo->SR25[0] = pVideoMemory[0x7A];
+ pVBInfo->SR31 = pVideoMemory[0x7B];
+ pVBInfo->SR32 = pVideoMemory[0x7C];
+ pVBInfo->SR33 = pVideoMemory[0x7D];
+ ii = 0xF8 ;
+
+ for( jj = 0 ; jj < 3 ; jj++ )
+ {
+ pVBInfo->CR40[ jj ][ 0 ] = pVideoMemory[ ii ] ;
+ pVBInfo->CR40[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+ pVBInfo->CR40[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+ pVBInfo->CR40[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+ pVBInfo->CR40[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+ pVBInfo->CR40[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+ pVBInfo->CR40[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+ pVBInfo->CR40[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+ ii += 0x08 ;
+ }
+
+ ii = 0x118 ;
+ for( j = 3 ; j < 24 ; j++ )
+ {
+ pVBInfo->CR40[ j ][ 0 ] = pVideoMemory[ ii ] ;
+ pVBInfo->CR40[ j ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+ pVBInfo->CR40[ j ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+ pVBInfo->CR40[ j ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+ pVBInfo->CR40[ j ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+ pVBInfo->CR40[ j ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+ pVBInfo->CR40[ j ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+ pVBInfo->CR40[ j ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+ ii += 0x08 ;
+ }
+
+ i = pVideoMemory[ 0x1C0 ] | ( pVideoMemory[ 0x1C1 ] << 8 ) ;
+
+ for( j = 0 ; j < 8 ; j++ )
+ {
+ for( k = 0 ; k < 4 ; k++ )
+ pVBInfo->CR6B[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
+ }
+
+ i = pVideoMemory[ 0x1C2 ] | ( pVideoMemory[ 0x1C3 ] << 8 ) ;
+
+ if (ChipType == XG45)
+ {
+ for( j = 0 ; j < 8 ; j++ )
+ {
+ pVBInfo->XG45CR6E[ j ] = pVideoMemory[i] ;
+ }
+ }
+ else
+ {
+ for( j = 0 ; j < 8 ; j++ )
+ {
+ for( k = 0 ; k < 4 ; k++ )
+ pVBInfo->CR6E[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
+ }
+ }
+
+ i = pVideoMemory[ 0x1C4 ] | ( pVideoMemory[ 0x1C5 ] << 8 ) ;
+ if (ChipType == XG45)
+ {
+ for( j = 0 ; j < 8 ; j++ )
+ {
+ pVBInfo->XG45CR6F[ j ] = pVideoMemory[i] ;
+ }
+ }
+ else
+ {
+ for( j = 0 ; j < 8 ; j++ )
+ {
+ for( k = 0 ; k < 32 ; k++ )
+ pVBInfo->CR6F[ j ][ k ] = pVideoMemory[ i + 32 * j + k ] ;
+ }
+ }
+
+ i = pVideoMemory[ 0x1C6 ] | ( pVideoMemory[ 0x1C7 ] << 8 ) ;
+
+ for( j = 0 ; j < 8 ; j++ )
+ {
+ for( k = 0 ; k < 2 ; k++ )
+ pVBInfo->CR89[ j ][ k ] = pVideoMemory[ i + 2 * j + k ] ;
+ }
+
+ i = pVideoMemory[ 0x1C8 ] | ( pVideoMemory[ 0x1C9 ] << 8 ) ;
+ for( j = 0 ; j < 12 ; j++ )
+ pVBInfo->AGPReg[ j ] = pVideoMemory[ i + j ] ;
+
+ i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;
+ for( j = 0 ; j < 4 ; j++ )
+ pVBInfo->SR16[ j ] = pVideoMemory[ i + j ] ;
+
+ /* Jong 10/03/2007 */
+ /*
+ pVBInfo->CRCF = pVideoMemory[0x1CA];
+ pVBInfo->DRAMTypeDefinition = pVideoMemory[0x1CB];
+ pVBInfo->I2CDefinition = pVideoMemory[0x1D1];
+ if ( ChipType == XG20 )
+ pVBInfo->CR97 = pVideoMemory[0x1D2]; */
+ if ( ChipType == XG21 )
+ {
+ if (pVideoMemory[ 0x67 ] & 0x80)
+ {
+ *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
+ }
+ if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
+ {
+ *pVBInfo->pCR2E = pVideoMemory[ i + 4 ] ;
+ *pVBInfo->pCR2F = pVideoMemory[ i + 5 ] ;
+ *pVBInfo->pCR46 = pVideoMemory[ i + 6 ] ;
+ *pVBInfo->pCR47 = pVideoMemory[ i + 7 ] ;
+ }
+ }
+
+ if ( ChipType == XG27 )
+ {
+ jj = i+j;
+ for( i = 0 ; i <= 0xB ; i++,jj++ )
+ pVBInfo->pCRD0[i] = pVideoMemory[ jj ] ;
+ for( i = 0x0 ; i <= 0x1 ; i++,jj++ )
+ pVBInfo->pCRDE[i] = pVideoMemory[ jj ] ;
+
+ *pVBInfo->pSR40 = pVideoMemory[ jj ] ;
+ jj++;
+ *pVBInfo->pSR41 = pVideoMemory[ jj ] ;
+
+ if (pVideoMemory[ 0x67 ] & 0x80)
+ {
+ *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
+ }
+ if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
+ {
+ jj++;
+ *pVBInfo->pCR2E = pVideoMemory[ jj ] ;
+ *pVBInfo->pCR2F = pVideoMemory[ jj + 1 ] ;
+ *pVBInfo->pCR46 = pVideoMemory[ jj + 2 ] ;
+ *pVBInfo->pCR47 = pVideoMemory[ jj + 3 ] ;
+ }
+
+ }
+
+ pVBInfo->CRCF = pVideoMemory[ 0x1CA ] ;
+ pVBInfo->DRAMTypeDefinition = pVideoMemory[ 0x1CB ] ;
+ pVBInfo->I2CDefinition = pVideoMemory[ 0x1D1 ] ;
+ if ( ChipType >= XG20 )
+ {
+ pVBInfo->CR97 = pVideoMemory[ 0x1D2 ] ;
+ if ( ChipType == XG27 )
+ {
+ *pVBInfo->pSR36 = pVideoMemory[ 0x1D3 ] ;
+ *pVBInfo->pCR8F = pVideoMemory[ 0x1D5 ] ;
+ }
+ }
+ }
+ /* Volari customize data area end */
+
+ if ( ChipType == XG21 )
+ {
+ pVBInfo->IF_DEF_LVDS = 0 ;
+ if (pVideoMemory[ 0x65 ] & 0x1)
+ {
+ pVBInfo->IF_DEF_LVDS = 1 ;
+ i = pVideoMemory[ 0x316 ] | ( pVideoMemory[ 0x317 ] << 8 );
+ j = pVideoMemory[ i-1 ] ;
+ if ( j != 0xff )
+ {
+ k = 0;
+ do
+ {
+ pVBInfo->XG21_LVDSCapList[k].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
+ pVBInfo->XG21_LVDSCapList[k].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].VCLKData1 = pVideoMemory[ i + 18 ] ;
+ pVBInfo->XG21_LVDSCapList[k].VCLKData2 = pVideoMemory[ i + 19 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S1 = pVideoMemory[ i + 20 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S2 = pVideoMemory[ i + 21 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S3 = pVideoMemory[ i + 22 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S4 = pVideoMemory[ i + 23 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S5 = pVideoMemory[ i + 24 ] ;
+ i += 25;
+ j--;
+ k++;
+ } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
+ }
+ else
+ {
+ pVBInfo->XG21_LVDSCapList[0].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
+ pVBInfo->XG21_LVDSCapList[0].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].VCLKData1 = pVideoMemory[ i + 18 ] ;
+ pVBInfo->XG21_LVDSCapList[0].VCLKData2 = pVideoMemory[ i + 19 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S1 = pVideoMemory[ i + 20 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S2 = pVideoMemory[ i + 21 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S3 = pVideoMemory[ i + 22 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S4 = pVideoMemory[ i + 23 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S5 = pVideoMemory[ i + 24 ] ;
+ }
+ }
+ pVBInfo->IF_DEF_CH7007 = 0 ;
+ if ( ( pVideoMemory[ 0x65 ] & 0x02 ) ) /* For XG21 CH7007 */
+ {
+ /* VideoDebugPrint((0, "ReadVBIOSTablData: pVideoMemory[ 0x65 ] =%x\n",pVideoMemory[ 0x65 ])); */
+ pVBInfo->IF_DEF_CH7007 = 1 ; /* [Billy] 07/05/03 */
+ }
+ }
+
+ if ( ChipType == XG27 )
+ {
+ if (pVideoMemory[ 0x65 ] & 0x1)
+ {
+ i = pVideoMemory[ 0x316 ] | ( pVideoMemory[ 0x317 ] << 8 );
+ j = pVideoMemory[ i-1 ] ;
+ if ( j != 0xff )
+ {
+ k = 0;
+ do
+ {
+ pVBInfo->XG21_LVDSCapList[k].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
+ pVBInfo->XG21_LVDSCapList[k].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[k].VCLKData1 = pVideoMemory[ i + 18 ] ;
+ pVBInfo->XG21_LVDSCapList[k].VCLKData2 = pVideoMemory[ i + 19 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S1 = pVideoMemory[ i + 20 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S2 = pVideoMemory[ i + 21 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S3 = pVideoMemory[ i + 22 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S4 = pVideoMemory[ i + 23 ] ;
+ pVBInfo->XG21_LVDSCapList[k].PSC_S5 = pVideoMemory[ i + 24 ] ;
+ i += 25;
+ j--;
+ k++;
+ } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
+ }
+ else
+ {
+ pVBInfo->XG21_LVDSCapList[0].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
+ pVBInfo->XG21_LVDSCapList[0].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
+ pVBInfo->XG21_LVDSCapList[0].VCLKData1 = pVideoMemory[ i + 18 ] ;
+ pVBInfo->XG21_LVDSCapList[0].VCLKData2 = pVideoMemory[ i + 19 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S1 = pVideoMemory[ i + 20 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S2 = pVideoMemory[ i + 21 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S3 = pVideoMemory[ i + 22 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S4 = pVideoMemory[ i + 23 ] ;
+ pVBInfo->XG21_LVDSCapList[0].PSC_S5 = pVideoMemory[ i + 24 ] ;
+ }
+ }
+ }
+
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_DDR1x_MRS_XG20 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_DDR1x_MRS_XG20( USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
+{
+
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ DelayUS( 60 ) ;
+
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+ DelayUS( 60 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
+ DelayUS( 1000 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
+ DelayUS( 500 ) ;
+ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
+ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_SetDRAMModeRegister_XG20 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+#ifndef LINUX_XF86
+ UCHAR data ;
+#endif
+
+ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+
+ if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
+ XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
+ else
+ XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+}
+
+void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
+{
+#ifndef LINUX_XF86
+ UCHAR data ;
+#endif
+ VB_DEVICE_INFO VBINF;
+ PVB_DEVICE_INFO pVBInfo = &VBINF;
+ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+ pVBInfo->BaseAddr = ( USHORT )HwDeviceExtension->pjIOAddress ;
+ pVBInfo->ISXPDOS = 0 ;
+
+ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
+ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
+ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
+ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
+ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
+ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
+ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
+ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
+ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
+ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
+ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
+ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
+ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
+ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
+ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
+ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
+ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
+
+ InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
+
+ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+
+ if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
+ XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
+ else
+ /*XGINew_DDR2_MRS_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;*/
+ XGINew_DDRII_Bootup_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo) ;
+
+ /*XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;*/
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+
+}
+
+/* -------------------------------------------------------- */
+/* Function : XGINew_ChkSenseStatus */
+/* Input : */
+/* Output : */
+/* Description : */
+/* -------------------------------------------------------- */
+void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx=0 , temp , tempcx , CR3CData;
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 ) ;
+
+ if ( temp & Monitor1Sense )
+ tempbx |= ActiveCRT1 ;
+ if ( temp & LCDSense )
+ tempbx |= ActiveLCD ;
+ if ( temp & Monitor2Sense )
+ tempbx |= ActiveCRT2 ;
+ if ( temp & TVSense )
+ {
+ tempbx |= ActiveTV ;
+ if ( temp & AVIDEOSense )
+ tempbx |= ( ActiveAVideo << 8 );
+ if ( temp & SVIDEOSense )
+ tempbx |= ( ActiveSVideo << 8 );
+ if ( temp & SCARTSense )
+ tempbx |= ( ActiveSCART << 8 );
+ if ( temp & HiTVSense )
+ tempbx |= ( ActiveHiTV << 8 );
+ if ( temp & YPbPrSense )
+ tempbx |= ( ActiveYPbPr << 8 );
+ }
+
+ tempcx = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
+ tempcx |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ) ;
+
+ if ( tempbx & tempcx )
+ {
+ CR3CData = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3c ) ;
+ if ( !( CR3CData & DisplayDeviceFromCMOS ) )
+ {
+ tempcx = 0x1FF0 ;
+ if (pVBInfo->SoftSetting & ModeSoftSetting) {
+ tempbx = 0x1FF0 ;
+ }
+ }
+ }
+ else
+ {
+ tempcx = 0x1FF0 ;
+ if (pVBInfo->SoftSetting & ModeSoftSetting) {
+ tempbx = 0x1FF0 ;
+ }
+ }
+
+ tempbx &= tempcx ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d , ( tempbx & 0x00FF ) ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e , ( ( tempbx & 0xFF00 ) >> 8 )) ;
+}
+/* -------------------------------------------------------- */
+/* Function : XGINew_SetModeScratch */
+/* Input : */
+/* Output : */
+/* Description : */
+/* -------------------------------------------------------- */
+void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
+{
+ USHORT temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
+ temp |= XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ;
+ temp |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) & ( DriverMode >> 8) ) << 8 ;
+
+ if ( pVBInfo->IF_DEF_CRT2Monitor == 1)
+ {
+ if ( temp & ActiveCRT2 )
+ tempcl = SetCRT2ToRAMDAC ;
+ }
+
+ if ( temp & ActiveLCD )
+ {
+ tempcl |= SetCRT2ToLCD ;
+ if ( temp & DriverMode )
+ {
+ if ( temp & ActiveTV )
+ {
+ tempch = SetToLCDA | EnableDualEdge ;
+ temp ^= SetCRT2ToLCD ;
+
+ if ( ( temp >> 8 ) & ActiveAVideo )
+ tempcl |= SetCRT2ToAVIDEO ;
+ if ( ( temp >> 8 ) & ActiveSVideo )
+ tempcl |= SetCRT2ToSVIDEO ;
+ if ( ( temp >> 8 ) & ActiveSCART )
+ tempcl |= SetCRT2ToSCART ;
+
+ if ( pVBInfo->IF_DEF_HiVision == 1 )
+ {
+ if ( ( temp >> 8 ) & ActiveHiTV )
+ tempcl |= SetCRT2ToHiVisionTV ;
+ }
+
+ if ( pVBInfo->IF_DEF_YPbPr == 1 )
+ {
+ if ( ( temp >> 8 ) & ActiveYPbPr )
+ tempch |= SetYPbPr ;
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( ( temp >> 8 ) & ActiveAVideo )
+ tempcl |= SetCRT2ToAVIDEO ;
+ if ( ( temp >> 8 ) & ActiveSVideo )
+ tempcl |= SetCRT2ToSVIDEO ;
+ if ( ( temp >> 8 ) & ActiveSCART )
+ tempcl |= SetCRT2ToSCART ;
+
+ if ( pVBInfo->IF_DEF_HiVision == 1 )
+ {
+ if ( ( temp >> 8 ) & ActiveHiTV )
+ tempcl |= SetCRT2ToHiVisionTV ;
+ }
+
+ if ( pVBInfo->IF_DEF_YPbPr == 1 )
+ {
+ if ( ( temp >> 8 ) & ActiveYPbPr )
+ tempch |= SetYPbPr ;
+ }
+ }
+
+ tempcl |= SetSimuScanMode ;
+ if ( (!( temp & ActiveCRT1 )) && ( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
+ tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
+ if ( ( temp & ActiveLCD ) && ( temp & ActiveTV ) )
+ tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30 , tempcl ) ;
+
+ CR31Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) ;
+ CR31Data &= ~( SetNotSimuMode >> 8 ) ;
+ if ( !( temp & ActiveCRT1 ) )
+ CR31Data |= ( SetNotSimuMode >> 8 ) ;
+ CR31Data &= ~( DisableCRT2Display >> 8 ) ;
+ if (!( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
+ CR31Data |= ( DisableCRT2Display >> 8 ) ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31 , CR31Data ) ;
+
+ CR38Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
+ CR38Data &= ~SetYPbPr ;
+ CR38Data |= tempch ;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38 , CR38Data ) ;
+
+}
+
+/* -------------------------------------------------------- */
+/* Function : XGINew_GetXG21Sense */
+/* Input : */
+/* Output : */
+/* Description : */
+/* -------------------------------------------------------- */
+void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR Temp;
+ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+
+ pVBInfo->IF_DEF_LVDS = 0 ;
+
+ if ( ( pVideoMemory[ 0x65 ] & 0x01 ) ) /* For XG21 LVDS */
+ {
+ pVBInfo->IF_DEF_LVDS = 1 ;
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , LCDSense ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS on chip */
+ }
+ else
+ {
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* Enable GPIOA/B read */
+ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) & 0xC0;
+ if ( Temp == 0xC0 )
+ { /* DVI & DVO GPIOA/B pull high */
+ XGINew_SenseLCD( HwDeviceExtension, pVBInfo ) ;
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , LCDSense ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x20 , 0x20 ) ; /* Enable read GPIOF */
+ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) & 0x04 ;
+ if ( !Temp )
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0x80 ) ; /* TMDS on chip */
+ else
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* Only DVO on chip */
+
+ XGI_SetRegAND( (XGIIOADDRESS)pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Disable read GPIOF */
+ }
+ }
+}
+
+/* -------------------------------------------------------- */
+/* Function : XGINew_GetXG27Sense */
+/* Input : */
+/* Output : */
+/* Description : */
+/* -------------------------------------------------------- */
+void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR Temp,bCR4A;
+ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+
+ pVBInfo->IF_DEF_LVDS = 0 ;
+ bCR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x07 , 0x07 ) ; /* Enable GPIOA/B/C read */
+ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) & 0x07;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x4A , bCR4A ) ;
+
+ if ( Temp <= 0x02 )
+ {
+ pVBInfo->IF_DEF_LVDS = 1 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS setting */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x30 , 0x21 ) ;
+ }
+ else
+ {
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* TMDS/DVO setting */
+ }
+
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , LCDSense ) ;
+}
+
+UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CR38,CR4A,temp;
+
+ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x10 , 0x10 ) ; /* enable GPIOE read */
+ CR38 = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
+ temp =0;
+ if ( ( CR38 & 0xE0 ) > 0x80 )
+ {
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
+ temp &= 0x08;
+ temp >>= 3;
+ }
+
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x4A , CR4A ) ;
+
+ return temp;
+}
+
+UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CR38,CR4A,temp;
+
+ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* enable GPIOA/B/C read */
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
+ if ( temp <= 2 )
+ {
+ temp &= 0x03;
+ }
+ else
+ {
+ temp = ((temp&0x04)>>1) || ((~temp)&0x01);
+ }
+
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x4A , CR4A ) ;
+
+ return temp;
+}
+
diff --git a/src/vb_init.h b/src/vb_init.h
index 0ee7f4e..7412a6e 100644
--- a/src/vb_init.h
+++ b/src/vb_init.h
@@ -33,5 +33,8 @@ extern void XGINew_SetModeScratch(PXGI_HW_DEVICE_INFO HwDeviceExtension,
PVB_DEVICE_INFO pVBInfo);
extern void ReadVBIOSTablData(UCHAR ChipType, PVB_DEVICE_INFO pVBInfo);
+
+extern XGI21_LVDSCapStruct XGI21_LCDCapList;
+
#endif
diff --git a/src/vb_setmode.c b/src/vb_setmode.c
index 11431ce..cd1afc7 100644
--- a/src/vb_setmode.c
+++ b/src/vb_setmode.c
@@ -1,8012 +1,9890 @@
-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "osdef.h"
-
-#ifdef LINUX_XF86
-#include "xf86.h"
-#include "xf86PciInfo.h"
-#include "xgi.h"
-#include "xgi_regs.h"
-#endif
-
-#ifdef LINUX_KERNEL
-#include <asm/io.h>
-#include <linux/types.h>
-#include <linux/version.h>
-#include "XGIfb.h"
-#endif
-
-#include "vb_def.h"
-#include "vgatypes.h"
-#include "vb_struct.h"
-#include "vb_table.h"
-#include "vb_setmode.h"
-
-#define IndexMask 0xff
-#ifndef XGI_MASK_DUAL_CHIP
-#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */
-#endif
-
-
-BOOLEAN CheckDualChip(PVB_DEVICE_INFO pVBInfo);
-static BOOLEAN XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo);
-
-BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, USHORT * i,
- PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-BOOLEAN XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo);
-USHORT XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-USHORT XGI_GetRatePtrCRT2(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-static USHORT XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-USHORT XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo);
-static unsigned XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo);
-void XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo);
-void XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-static const void *XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-static const void *XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo);
-void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
-void XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo);
-void XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo);
-void XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo);
-void SetDualChipRegs(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void XGI_DisplayOn(PVB_DEVICE_INFO pVBInfo);
-void XGI_DisplayOff(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-static void XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo);
-void XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo);
-
-void XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
- PXGI_HW_DEVICE_INFO HwDeviceExtension);
-void XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
- PXGI_HW_DEVICE_INFO HwDeviceExtension);
-void XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-
-void XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_GetVBType(PVB_DEVICE_INFO pVBInfo);
-void XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void InitTo330Pointer(UCHAR, PVB_DEVICE_INFO pVBInfo);
-void XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
-void XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
-void SetSpectrum(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
- PVB_DEVICE_INFO pVBInfo);
-USHORT XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PVB_DEVICE_INFO pVBInfo);
-void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void XGI_LockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
-void XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo);
-void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo);
-void XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo);
-static void XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo);
-static unsigned XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
-static void XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di,
- PVB_DEVICE_INFO pVBInfo);
-USHORT XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo);
-USHORT XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo);
-static const XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(USHORT tempcx,
- PVB_DEVICE_INFO pVBInfo);
-
-
-const uint8_t XGI_MDA_DAC[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
-};
-
-const uint8_t XGI_CGA_DAC[] = {
- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
-};
-
-const uint8_t XGI_EGA_DAC[] = {
- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
- 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
- 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
- 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
- 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
- 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
- 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
-};
-
-const uint8_t XGI_VGA_DAC[] = {
- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
- 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
- 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
- 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
- 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
- 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
- 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
- 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
- 0x0B, 0x0C, 0x0D, 0x0F, 0x10
-};
-
-
-/* --------------------------------------------------------------------- */
-/* Function : InitTo330Pointer */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-InitTo330Pointer(UCHAR ChipType, PVB_DEVICE_INFO pVBInfo)
-{
- pVBInfo->SModeIDTable = XGI330_SModeIDTable;
- pVBInfo->StandTable = XGI330_StandTable;
- pVBInfo->EModeIDTable = XGI330_EModeIDTable;
- pVBInfo->RefIndex = XGI330_RefIndex;
- pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table;
-
- /* add for new UNIVGABIOS */
- /* XGINew_UBLCDDataTable = (XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
- /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
-
-
- if (ChipType >= XG40) {
- (void) memcpy(pVBInfo->MCLKData, XGI340New_MCLKData, sizeof(XGI340New_MCLKData));
- (void) memcpy(pVBInfo->ECLKData, XGI340_ECLKData, sizeof(XGI340_ECLKData));
- }
- else {
- (void) memcpy(pVBInfo->MCLKData, XGI330New_MCLKData, sizeof(XGI330New_MCLKData));
- (void) memcpy(pVBInfo->ECLKData, XGI330_ECLKData, sizeof(XGI330_ECLKData));
- }
-
- pVBInfo->VCLKData = XGI_VCLKData;
- pVBInfo->VBVCLKData = XGI_VBVCLKData;
- pVBInfo->ScreenOffset = XGI330_ScreenOffset;
- pVBInfo->StResInfo = XGI330_StResInfo;
- pVBInfo->ModeResInfo = XGI330_ModeResInfo;
-
- pVBInfo->OutputSelect = XGI330_OutputSelect;
- pVBInfo->SoftSetting = XGI330_SoftSetting;
- pVBInfo->SR07 = XGI330_SR07;
- pVBInfo->LCDResInfo = 0;
- pVBInfo->LCDTypeInfo = 0;
- pVBInfo->LCDInfo = 0;
- pVBInfo->VBInfo = 0;
- pVBInfo->TVInfo = 0;
-
-
- (void) memcpy(pVBInfo->SR15, XGI340_SR13, sizeof(XGI340_SR13));
- (void) memcpy(pVBInfo->CR40, XGI340_CR41, sizeof(XGI340_CR41));
- (void) memcpy(pVBInfo->SR25, XGI330_SR25, sizeof(XGI330_SR25));
- pVBInfo->SR31 = XGI330_SR31;
- pVBInfo->SR32 = XGI330_SR32;
- (void) memcpy(pVBInfo->CR6B, XGI340_CR6B, sizeof(XGI340_CR6B));
- if (ChipType == XG45) {
- (void) memcpy(pVBInfo->XG45CR6E, XGI45_CR6E, sizeof(XGI45_CR6E));
- (void) memcpy(pVBInfo->XG45CR6F, XGI45_CR6F, sizeof(XGI45_CR6F));
- }
- else {
- (void) memcpy(pVBInfo->CR6E, XGI340_CR6E, sizeof(XGI340_CR6E));
- (void) memcpy(pVBInfo->CR6F, XGI340_CR6F, sizeof(XGI340_CR6F));
- }
- (void) memcpy(pVBInfo->CR89, XGI340_CR89, sizeof(XGI340_CR89));
- (void) memcpy(pVBInfo->AGPReg, XGI340_AGPReg, sizeof(XGI340_AGPReg));
- (void) memcpy(pVBInfo->SR16, XGI340_SR16, sizeof(XGI340_SR16));
- pVBInfo->CRCF = XG40_CRCF;
- pVBInfo->DRAMTypeDefinition = XG40_DRAMTypeDefinition;
-
-
- (void) memcpy(pVBInfo->CR49, XGI330_CR49, sizeof(XGI330_CR49));
- pVBInfo->SR1F = XGI330_SR1F;
- pVBInfo->SR21 = XGI330_SR21;
- pVBInfo->SR22 = XGI330_SR22;
- pVBInfo->SR23 = XGI330_SR23;
- pVBInfo->SR24 = XGI330_SR24;
- pVBInfo->SR33 = XGI330_SR33;
-
-
-
- pVBInfo->CRT2Data_1_2 = XGI330_CRT2Data_1_2;
- pVBInfo->CRT2Data_4_D = XGI330_CRT2Data_4_D;
- pVBInfo->CRT2Data_4_E = XGI330_CRT2Data_4_E;
- pVBInfo->CRT2Data_4_10 = XGI330_CRT2Data_4_10;
- pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
- pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
- pVBInfo->pYCSenseData = &XGI330_YCSenseData;
- pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
- pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
- pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
-
- pVBInfo->NTSCTiming = XGI330_NTSCTiming;
- pVBInfo->PALTiming = XGI330_PALTiming;
- pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
- pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
- pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
- pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
- pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
- pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
- pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
- pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
- pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
- pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
- pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
- pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
-
-
- (void) memcpy(& pVBInfo->TimingH, XGI_TimingH, sizeof(XGI_TimingH));
- (void) memcpy(& pVBInfo->TimingV, XGI_TimingV, sizeof(XGI_TimingV));
-
- pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC;
- pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC;
- pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL;
- pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL;
-
- /* 310 customization related */
- if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
- pVBInfo->LCDCapList = XGI_LCDDLCapList;
- else
- pVBInfo->LCDCapList = XGI_LCDCapList;
-
- pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
- pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
-
-
- pVBInfo->I2CDefinition = XG40_I2CDefinition;
-
- if (ChipType == XG20)
- pVBInfo->CR97 = XG20_CR97;
-}
-
-
-
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGISetModeNew */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo,
- USHORT ModeNo)
-{
-#ifndef LINUX_XF86
- ULONG temp;
- USHORT KeepLockReg;
-#endif
- USHORT ModeIdIndex;
- /* PUCHAR pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
- USHORT temp_mode_no;
-
- pVBInfo->IF_DEF_VideoCapture = 1;
- pVBInfo->IF_DEF_ScaleLCD = 1;
-
-
- if (ModeNo & 0x80) {
- ModeNo = ModeNo & 0x7F;
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
-
- if (HwDeviceExtension->jChipType != XG20) /* kuku 2004/06/25 1.Openkey */
- XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
-
- temp_mode_no = ModeNo;
- XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11,
- &temp_mode_no, &ModeIdIndex);
-
- if (HwDeviceExtension->jChipType != XG20) { /* kuku 2004/06/25 */
- PDEBUG(ErrorF("XGI_GetVBInfo \n"));
- XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
- PDEBUG(ErrorF("XGI_GetTVInfo \n"));
- XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
- PDEBUG(ErrorF("XGI_GetLCDInfo \n"));
- XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
- PDEBUG(ErrorF("XGI_DisableBridge \n"));
- XGI_DisableBridge(HwDeviceExtension, pVBInfo);
-
-
- if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
- XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
-
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
- pVBInfo);
- }
- }
- else {
- if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
- XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
- pVBInfo);
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
- pVBInfo);
- }
- }
- }
-
- PDEBUG(ErrorF(" vb_setmode 474\n")); // yilin
- if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
- switch (HwDeviceExtension->ujVBChipID) {
- case VB_CHIP_301:
- PDEBUG(ErrorF(" vb_setmode 301\n")); //yilin
- XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
- break;
-
- case VB_CHIP_302:
- XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
- break;
-
- default:
- break;
- }
- }
- ErrorF("492 Part2 0 = %x ",
- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
- XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
- XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212 */
- XGI_EnableBridge(HwDeviceExtension, pVBInfo);
- ErrorF("497 Part2 0 = %x ",
- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
- } /* !XG20 */
- else {
- if (ModeNo <= 0x13) {
- pVBInfo->ModeType =
- pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag & ModeInfoFlag;
- }
- else {
- pVBInfo->ModeType =
- pVBInfo->EModeIDTable[ModeIdIndex].
- Ext_ModeFlag & ModeInfoFlag;
- }
- pVBInfo->SetFlag = 0;
- pVBInfo->VBInfo = DisableCRT2Display;
- XGI_DisplayOff(pVBInfo);
- XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
- XGI_DisplayOn(pVBInfo);
- }
-
-/*
- if ( ModeNo <= 0x13 )
- {
- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
- }
- else
- {
- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
- }
- pVBInfo->ModeType = modeflag&ModeInfoFlag ;
- pVBInfo->SetFlag = 0x00 ;
- pVBInfo->VBInfo = DisableCRT2Display ;
- temp = XGINew_CheckMemorySize( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
-
- if ( temp == 0 )
- return( 0 ) ;
-
- XGI_DisplayOff( pVBInfo) ;
- XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
- XGI_DisplayOn( pVBInfo) ;
-*/
- ErrorF("Part2 0 = %x ",
- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
- XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
-
- if (HwDeviceExtension->jChipType != XG20) /* kuku 2004/06/25 */
- XGI_LockCRT2(HwDeviceExtension, pVBInfo);
-
- return (TRUE);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Group */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
- pVBInfo->ModeType,
- ModeNo, ModeIdIndex);
- USHORT RefreshRateTableIndex;
- USHORT b3CC;
- USHORT temp;
-
- USHORT XGINew_P3cc = pVBInfo->P3cc;
-#ifndef LINUX_XF86
- USHORT XGINew_P3c2 = pVBInfo->P3c2;
-#endif
-
- /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
- XGI_SetSeqRegs(StandTableIndex, pVBInfo);
- XGI_SetMiscRegs(StandTableIndex, pVBInfo);
- XGI_SetCRTCRegs(StandTableIndex, pVBInfo);
- XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
- XGI_SetGRCRegs(StandTableIndex, pVBInfo);
- XGI_ClearExt1Regs(ModeNo, pVBInfo);
-
- temp = ~ProgrammingCRT2;
- pVBInfo->SetFlag &= temp;
- pVBInfo->SelectCRT2Rate = 0;
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (pVBInfo->
- VBInfo & (SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode)) {
- pVBInfo->SetFlag |= ProgrammingCRT2;
- }
- }
-
- RefreshRateTableIndex = XGI_GetRatePtrCRT2(ModeNo, ModeIdIndex, pVBInfo);
-
- if (RefreshRateTableIndex != 0xFFFF) {
- XGI_SetSync(RefreshRateTableIndex, pVBInfo);
- XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo,
- HwDeviceExtension);
- XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
- XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwDeviceExtension, pVBInfo);
- XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
- RefreshRateTableIndex, pVBInfo);
- }
-
- if (HwDeviceExtension->jChipType == XG20) {
- if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x4E);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE9);
- b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
- XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
- }
- else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE3);
- b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
- XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
- }
- }
-
- pVBInfo->SetFlag &= (~ProgrammingCRT2);
- XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
- XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
-
- if (HwDeviceExtension->jChipType == XG40) { /* Copy reg settings to 2nd chip */
- if (CheckDualChip(pVBInfo))
- SetDualChipRegs(HwDeviceExtension, pVBInfo);
- }
-
- /* XGI_LoadCharacter(); //dif ifdef TVFont */
-
- XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetSeqRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetSeqRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
-{
- unsigned SRdata;
- unsigned i;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
- SRdata = pVBInfo->StandTable[StandTableIndex].SR[0];
-
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- SRdata |= 0x01;
- }
- else {
- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
- if (pVBInfo->VBInfo & SetInSlaveMode)
- SRdata |= 0x01;
- }
- }
-
- SRdata |= 0x20; /* screen off */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SRdata); /* Set SR1 */
-
- /* Get SR2, SR3, and SR4 from table and set in hardware.
- */
- for (i = 2; i <= 4; i++) {
- SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, SRdata);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetMiscRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetMiscRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
-{
- UCHAR Miscdata;
-
- Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
-/*
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- {
- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
- {
- Miscdata |= 0x0C ;
- }
- }
-*/
-
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRTCRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRTCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
-{
- unsigned i;
-
- /* Unlock CRTC */
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x7f);
-
- for (i = 0; i <= 0x18; i++) {
- /* Get CRTC from file */
- const unsigned CRTCdata =
- pVBInfo->StandTable[StandTableIndex].CRTC[i];
-
- /* Set CRTC( 3d4 ) */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, i, CRTCdata);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetATTRegs(unsigned ModeNo, unsigned StandTableIndex, unsigned ModeIdIndex,
- const VB_DEVICE_INFO *pVBInfo)
-{
- unsigned i;
- const unsigned modeflag = (ModeNo <= 0x13)
- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
- for (i = 0; i <= 0x13; i++) {
- UCHAR ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
-
- if (modeflag & Charx8Dot) { /* ifndef Dot9 */
- if (i == 0x13) {
- /* Pixel shift. If screen on LCD or TV is shifted left or
- * right, this might be the cause.
- */
- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
- ARdata = 0;
- else {
- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
- if (pVBInfo->VBInfo & SetInSlaveMode)
- ARdata = 0;
- }
- }
- }
- }
-
- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, i); /* set index */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, ARdata); /* set data */
- }
-
- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x14); /* set index */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x00); /* set data */
-
- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* Enable Attribute */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x20);
- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGRCRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetGRCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
-{
- unsigned i;
-
- for (i = 0; i <= 8; i++) {
- /* Get GR from file and set GR (3ce)
- */
- const unsigned GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3ce, i, GRdata);
- }
-
- if (pVBInfo->ModeType > ModeVGA) {
- /* 256 color disable */
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_ClearExt1Regs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_ClearExt1Regs(unsigned ModeNo, const VB_DEVICE_INFO *pVBInfo)
-{
- unsigned i;
-
- /* Clear SR0A-SR0E */
- for (i = 0x0A; i <= 0x0E; i++) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, 0x00);
- }
-
- /* This code came from the old XGI_New_ClearExt1Regs in init.c. Since
- * it wasn't included in the newer code drop from XGI, I'm not sure if
- * it's necessary on the Volari chips. I've included it here, ifdefed
- * out, for future reference.
- * - idr
- */
-#if 0
- XGI_SetRegAND(pVBInfo->P3c4, 0x37, 0xFE);
- if ((ModeNo == 0x06) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
- XGI_SetReg(pVBInfo->P3c4, 0x0e, 0x20);
- }
-#else
- (void) ModeNo;
-#endif
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetRatePtrCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetRatePtrCRT2(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 }
- , LCDARefreshIndex[] = {
- 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01};
-
- USHORT RefreshRateTableIndex, i, modeflag, index, temp;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- if (ModeNo < 0x14)
- return (0xFFFF);
-
- index = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
- index = index >> pVBInfo->SelectCRT2Rate;
- index &= 0x0F;
-
- if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD))
- index = 0;
-
- if (index > 0)
- index--;
-
- if (pVBInfo->SetFlag & ProgrammingCRT2) {
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
- | VB_XGI301C))
- temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x0F]; /* 301b */
- else
- temp = LCDRefreshIndex[pVBInfo->LCDResInfo & 0x0F];
-
- if (index > temp) {
- index = temp;
- }
- }
- }
-
- RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
- ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
- i = 0;
-
- do {
- if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
- break;
- temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
- temp &= ModeInfoFlag;
- if (temp < pVBInfo->ModeType)
- break;
-
- i++;
- index--;
-
- } while (index != 0xFFFF);
-
- if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- temp =
- pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
- if (temp & InterlaceMode) {
- i++;
- }
- }
- }
-
- i--;
- if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
- temp =
- XGI_AjustCRT2Rate(ModeNo, ModeIdIndex, RefreshRateTableIndex, &i,
- pVBInfo);
- }
- return (RefreshRateTableIndex + i); /*return(0x01|(temp1<<1)); */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_AjustCRT2Rate */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, USHORT * i,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, tempbx, resinfo, modeflag, infoflag;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
- tempax = 0;
-
- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempax |= SupportRAMDAC2;
-
- if (pVBInfo->VBType & VB_XGI301C)
- tempax |= SupportCRT2in301C;
- }
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
- tempax |= SupportLCD;
-
- if (pVBInfo->LCDResInfo != Panel1280x1024) {
- if (pVBInfo->LCDResInfo != Panel1280x960) {
- if (pVBInfo->LCDInfo & LCDNonExpanding) {
- if (resinfo >= 9) {
- tempax = 0;
- return (0);
- }
- }
- }
- }
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
- if ((pVBInfo->VBType & VB_XGI301LV)
- && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
- tempax |= SupportYPbPr;
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (resinfo == 4)
- return (0);
-
- if (resinfo == 3)
- return (0);
-
- if (resinfo > 7)
- return (0);
- }
- }
- else {
- tempax |= SupportHiVisionTV;
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (resinfo == 4)
- return (0);
-
- if (resinfo == 3) {
- if (pVBInfo->SetFlag & TVSimuMode)
- return (0);
- }
-
- if (resinfo > 7)
- return (0);
- }
- }
- }
- else {
- if (pVBInfo->
- VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
- SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
- tempax |= SupportTV;
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
- | VB_XGI301C)) {
- tempax |= SupportTV1024;
- }
-
- if (!(pVBInfo->VBInfo & SetPALTV)) {
- if (modeflag & NoSupportSimuTV) {
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (!(pVBInfo->VBInfo & SetNotSimuMode)) {
- return (0);
- }
- }
- }
- }
- }
- }
-
- for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx;
- (*i)--) {
- infoflag =
- pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
- if (infoflag & tempax) {
- return (1);
- }
- if ((*i) == 0)
- break;
- }
-
- for ((*i) = 0;; (*i)++) {
- infoflag =
- pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
- if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
- return (0);
- }
-
- if (infoflag & tempax) {
- return (1);
- }
- }
- return (1);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetSync */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetSync(unsigned RefreshRateTableIndex, const VB_DEVICE_INFO *pVBInfo)
-{
- const unsigned sync =
- (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8) & 0xC0;
-
- /* Set Misc(3c2) */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, sync | 0x2F);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1CRTC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
- PXGI_HW_DEVICE_INFO HwDeviceExtension)
-{
- UCHAR index, data;
-#ifndef LINUX_XF86
- USHORT temp, tempah, j, modeflag, ResInfo, DisplayType;
-#endif
- USHORT i;
-
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
- index = index & IndexMask;
-
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
- data &= 0x7F;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
-
- for (i = 0; i < 8; i++)
- pVBInfo->TimingH.data[i] =
- pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
-
- for (i = 0; i < 7; i++)
- pVBInfo->TimingV.data[i] =
- pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
-
- XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
-
-
-
- XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
-
-
- if (pVBInfo->ModeType > 0x03)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0x4F);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Timing_H */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
- PXGI_HW_DEVICE_INFO HwDeviceExtension)
-{
- UCHAR data, data1, pushax;
- USHORT i, j;
-
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
- /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
-
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
- data &= 0x7F;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data);
-
- data = pVBInfo->TimingH.data[0];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0, data);
-
- for (i = 0x01; i <= 0x04; i++) {
- data = pVBInfo->TimingH.data[i];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 1), data);
- }
-
- for (i = 0x05; i <= 0x06; i++) {
- data = pVBInfo->TimingH.data[i];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i + 6), data);
- }
-
- j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
- j &= 0x1F;
- data = pVBInfo->TimingH.data[7];
- data &= 0xE0;
- data |= j;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, data);
-
- if (HwDeviceExtension->jChipType == XG20) {
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04);
- data = data - 1;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04, data);
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05);
- data1 = data;
- data1 &= 0xE0;
- data &= 0x1F;
- if (data == 0) {
- pushax = data;
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c);
- data &= 0xFB;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c, data);
- data = pushax;
- }
- data = data - 1;
- data |= data1;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05, data);
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
- data = data >> 5;
- data = data + 3;
- if (data > 7)
- data = data - 7;
- data = data << 5;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, ~0xE0, data);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Timing_V */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
- PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR data;
- USHORT i, j;
-
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
- /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , 0x7f , 0x00 ) ; */
-
- for (i = 0x00; i <= 0x01; i++) {
- data = pVBInfo->TimingV.data[i];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 6), data);
- }
-
- for (i = 0x02; i <= 0x03; i++) {
- data = pVBInfo->TimingV.data[i];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x0e), data);
- }
-
- for (i = 0x04; i <= 0x05; i++) {
- data = pVBInfo->TimingV.data[i];
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x11), data);
- }
-
- j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a);
- j &= 0xC0;
- data = pVBInfo->TimingV.data[6];
- data &= 0x3F;
- data |= j;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a, data);
-
- data = pVBInfo->TimingV.data[6];
- data &= 0x80;
- data = data >> 2;
-
- if (ModeNo <= 0x13)
- i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- else
- i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
- i &= DoubleScanMode;
- if (i)
- data |= 0x80;
-
- j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09);
- j &= 0x5F;
- data |= j;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09, data);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1DE */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, tempbx, tempcx, temp, modeflag;
- UCHAR data;
- const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
-
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- tempax = pVBInfo->StResInfo[resindex].HTotal;
- tempbx = pVBInfo->StResInfo[resindex].VTotal;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempax = pVBInfo->ModeResInfo[resindex].HTotal;
- tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
- }
-
- if (modeflag & HalfDCLK)
- tempax = tempax >> 1;
-
- if (ModeNo > 0x13) {
- if (modeflag & HalfDCLK)
- tempax = tempax << 1;
-
- temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-
- if (temp & InterlaceMode)
- tempbx = tempbx >> 1;
-
- if (modeflag & DoubleScanMode)
- tempbx = tempbx << 1;
- }
-
- tempcx = 8;
-
- /* if ( !( modeflag & Charx8Dot ) ) */
- /* tempcx = 9 ; */
-
- tempax /= tempcx;
- tempax -= 1;
- tempbx -= 1;
- tempcx = tempax;
- temp = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
- data &= 0x7F;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x01, (USHORT) (tempcx & 0xff));
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0b, ~0x0c,
- (USHORT) ((tempcx & 0x0ff00) >> 10));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x12, (USHORT) (tempbx & 0xff));
- tempax = 0;
- tempbx = tempbx >> 8;
-
- if (tempbx & 0x01)
- tempax |= 0x02;
-
- if (tempbx & 0x02)
- tempax |= 0x40;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, ~0x42, tempax);
- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x07);
- data &= 0xFF;
- tempax = 0;
-
- if (tempbx & 0x04)
- tempax |= 0x02;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0a, ~0x02, tempax);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, temp);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetResInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- return (ModeNo <= 0x13)
- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo
- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-}
-
-
-static void
-get_mode_xres_yres(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo,
- unsigned *width, unsigned *height)
-{
- const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
- unsigned xres;
- unsigned yres;
-
-
- if (ModeNo <= 0x13) {
- xres = pVBInfo->StResInfo[resindex].HTotal;
- yres = pVBInfo->StResInfo[resindex].VTotal;
- }
- else {
- const unsigned modeflag =
- pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
- xres = pVBInfo->ModeResInfo[resindex].HTotal;
- yres = pVBInfo->ModeResInfo[resindex].VTotal;
-
- if (modeflag & HalfDCLK)
- xres *= 2;
-
- if (modeflag & DoubleScanMode)
- yres *= 2;
- }
-
- *width = xres;
- *height = yres;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1Offset */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp, ah, al, temp2, i, DisplayUnit;
-
- /* GetOffset */
- temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
- temp = temp >> 8;
- temp = pVBInfo->ScreenOffset[temp];
-
- temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- temp2 &= InterlaceMode;
-
- if (temp2)
- temp = temp << 1;
-
- temp2 = pVBInfo->ModeType - ModeEGA;
-
- switch (temp2) {
- case 0:
- temp2 = 1;
- break;
- case 1:
- temp2 = 2;
- break;
- case 2:
- temp2 = 4;
- break;
- case 3:
- temp2 = 4;
- break;
- case 4:
- temp2 = 6;
- break;
- case 5:
- temp2 = 8;
- break;
- default:
- break;
- }
-
- if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
- temp = temp * temp2 + temp2 / 2;
- else
- temp *= temp2;
-
- /* SetOffset */
- DisplayUnit = temp;
- temp2 = temp;
- temp = temp >> 8; /* ah */
- temp &= 0x0F;
- i = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E);
- i &= 0xF0;
- i |= temp;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E, i);
-
- temp = (UCHAR) temp2;
- temp &= 0xFF; /* al */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x13, temp);
-
- /* SetDisplayUnit */
- temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- temp2 &= InterlaceMode;
- if (temp2)
- DisplayUnit >>= 1;
-
- DisplayUnit = DisplayUnit << 5;
- ah = (DisplayUnit & 0xff00) >> 8;
- al = DisplayUnit & 0x00ff;
- if (al == 0)
- ah += 1;
- else
- ah += 2;
-
- if (HwDeviceExtension->jChipType == XG20)
- if ((ModeNo == 0x4A) | (ModeNo == 0x49))
- ah -= 1;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, ah);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1VCLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- unsigned index;
- unsigned clka;
- unsigned clkb;
-
- if ((pVBInfo->VBType & VB_XGI301BLV302BLV)
- && (pVBInfo->VBInfo & SetCRT2ToLCDA)) {
- index = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- pVBInfo);
-
- clka = pVBInfo->VBVCLKData[index].Part4_A;
- clkb = pVBInfo->VBVCLKData[index].Part4_B;
- }
- else {
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-
- clka = pVBInfo->VCLKData[index].SR2B;
- clkb = pVBInfo->VCLKData[index].SR2C;
- }
-
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0xCF);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, clka);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, clkb);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2D, 0x01);
-
- if ((HwDeviceExtension->jChipType == XG20)
- && (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK)) {
- UCHAR data;
-
- /* FIXME: Does this actually serve any purpose? This register is
- * FIXME: already written above.
- */
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, data);
-
- /* FIXME: The logic here seems wrong. It looks like its possible
- * FIXME: for the (data << 1) to cause a bit to creep into the index
- * FIXME: part. THere's no documentation for this register, so I have
- * FIXME: no way of knowing. :(
- */
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C);
- index = data;
- index &= 0xE0;
- data &= 0x1F;
- data = data << 1;
- data += 1;
- data |= index;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, data);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1FIFO */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data;
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
- data &= 0xfe;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
-
- if (ModeNo > 0x13) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0x34);
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
- data &= 0xF0;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
- data |= 0x01;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0xAE);
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
- data &= 0xF0;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT1ModeRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data, data2, data3, infoflag = 0, modeflag, resindex, xres;
-
- if (ModeNo > 0x13) {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
- }
- else
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
-
- if (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31) & 0x01)
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
-
- if (ModeNo > 0x13)
- data = infoflag;
- else
- data = 0;
-
- data2 = 0;
-
- if (ModeNo > 0x13) {
- if (pVBInfo->ModeType > 0x02) {
- data2 |= 0x02;
- data3 = pVBInfo->ModeType - ModeVGA;
- data3 = data3 << 2;
- data2 |= data3;
- }
- }
-
- data &= InterlaceMode;
-
- if (data)
- data2 |= 0x20;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, ~0x3F, data2);
- /* XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x06,data2); */
- resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
- if (ModeNo <= 0x13)
- xres = pVBInfo->StResInfo[resindex].HTotal;
- else
- xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
-
- data = 0x0000;
- if (infoflag & InterlaceMode) {
- if (xres == 1024)
- data = 0x0035;
- else if (xres == 1280)
- data = 0x0048;
- }
-
- data2 = data & 0x00FF;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFF, data2);
- data2 = (data & 0xFF00) >> 8;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFC, data2);
-
- if (modeflag & HalfDCLK)
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xF7, 0x08);
-
- data2 = 0;
-
- if (modeflag & LineCompareOff)
- data2 |= 0x08;
-
- if (ModeNo > 0x13) {
- if (pVBInfo->ModeType == ModeEGA)
- data2 |= 0x40;
- }
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0F, ~0x48, data2);
- data = 0x60;
- if (pVBInfo->ModeType != ModeText) {
- data = data ^ 0x60;
- if (pVBInfo->ModeType != ModeEGA) {
- data = data ^ 0xA0;
- }
- }
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x21, 0x1F, data);
-
- XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
- pVBInfo);
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
-
- if (HwDeviceExtension->jChipType == XG20) {
- if (data & 0x40)
- data = 0x33;
- else
- data = 0x73;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x51, 0x02);
- }
- else {
- if (data & 0x40)
- data = 0x2c;
- else
- data = 0x6c;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
- }
-
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetVCLKState */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data, data2 = 0;
- SHORT VCLK;
-
- UCHAR index;
-
- if (ModeNo <= 0x13)
- VCLK = 0;
- else {
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
- index &= IndexMask;
- VCLK = pVBInfo->VCLKData[index].CLOCK;
- }
-
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
- data &= 0xf3;
- if (VCLK >= 200)
- data |= 0x0c; /* VCLK > 200 */
-
- if (HwDeviceExtension->jChipType == XG20)
- data &= ~0x04; /* 2 pixel mode */
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, data);
-
- if (HwDeviceExtension->jChipType != XG20) {
- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
- data &= 0xE7;
- if (VCLK < 200)
- data |= 0x10;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, data);
- }
-
- if ((VCLK >= 0) && (VCLK < 135))
- data2 = 0x03;
- else if ((VCLK >= 135) && (VCLK < 160))
- data2 = 0x02;
- else if ((VCLK >= 160) && (VCLK < 260))
- data2 = 0x01;
- else if (VCLK > 260)
- data2 = 0x00;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x07, 0xFC, data2);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_LoadDAC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, ah, dh;
- const uint8_t *table = NULL;
-
- if (ModeNo <= 0x13)
- data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- else
- data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
- data &= DACInfoFlag;
- time = 64;
-
- if (data == 0x00)
- table = XGI_MDA_DAC;
- else if (data == 0x08)
- table = XGI_CGA_DAC;
- else if (data == 0x10)
- table = XGI_EGA_DAC;
- else if (data == 0x18) {
- time = 256;
- table = XGI_VGA_DAC;
- }
-
- if (time == 256)
- j = 16;
- else
- j = time;
-
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c6, 0xFF);
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
-
- for (i = 0; i < j; i++) {
- data = table[i];
-
- for (k = 0; k < 3; k++) {
- data2 = 0;
-
- if (data & 0x01)
- data2 = 0x2A;
-
- if (data & 0x02)
- data2 += 0x15;
-
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data2);
- data = data >> 2;
- }
- }
-
- if (time == 256) {
- for (i = 16; i < 32; i++) {
- data = table[i];
-
- for (k = 0; k < 3; k++)
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data);
- }
-
- si = 32;
-
- for (m = 0; m < 9; m++) {
- di = si;
- bx = si + 0x04;
- dl = 0;
-
- for (n = 0; n < 3; n++) {
- for (o = 0; o < 5; o++) {
- dh = table[si];
- ah = table[di];
- al = table[bx];
- si++;
- XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
- ah, al, dh);
- }
-
- si -= 2;
-
- for (o = 0; o < 3; o++) {
- dh = table[bx];
- ah = table[di];
- al = table[si];
- si--;
- XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
- ah, al, dh);
- }
-
- dl++;
- }
-
- si += 5;
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_WriteDAC */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift, unsigned ordering,
- uint8_t ah, uint8_t al, uint8_t dh)
-{
- USHORT temp, bh, bl;
-
- if (shift) {
- ah <<= 2;
- al <<= 2;
- dh <<= 2;
- }
-
- bh = ah;
- bl = al;
-
- if (ordering != 0) {
- temp = bh;
- bh = dh;
- dh = temp;
- if (ordering == 1) {
- temp = bl;
- bl = dh;
- dh = temp;
- }
- else {
- temp = bl;
- bl = bh;
- bh = temp;
- }
- }
- XGI_SetRegByte(dac_data, dh);
- XGI_SetRegByte(dac_data, bh);
- XGI_SetRegByte(dac_data, bl);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDAGroup */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT RefreshRateTableIndex;
- /* USHORT temp ; */
-
- /* pVBInfo->SelectCRT2Rate = 0 ; */
-
- pVBInfo->SetFlag |= ProgrammingCRT2;
- RefreshRateTableIndex = XGI_GetRatePtrCRT2(ModeNo, ModeIdIndex, pVBInfo);
- XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
- XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwDeviceExtension, pVBInfo);
- XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-}
-
-
-/**
- * Get LVDS resolution information.
- */
-void
-XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- unsigned xres;
- unsigned yres;
-
-
- get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
-
- if (xres == 720)
- xres = 640;
-
- pVBInfo->VGAHDE = xres;
- pVBInfo->HDE = xres;
- pVBInfo->VGAVDE = yres;
- pVBInfo->VDE = yres;
-}
-
-
-static void
-get_HDE_VDE(PVB_DEVICE_INFO pVBInfo, USHORT *HDE, USHORT *VDE)
-{
- switch (pVBInfo->LCDResInfo) {
- case Panel1024x768:
- case Panel1024x768x75:
- *HDE = 1024;
- *VDE = 768;
- break;
-
- case Panel1280x1024:
- case Panel1280x1024x75:
- *HDE = 1280;
- *VDE = 1024;
- break;
-
- case Panel1400x1050:
- *HDE = 1400;
- *VDE = 1050;
- break;
-
- default:
- *HDE = 1600;
- *VDE = 1200;
- break;
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLVDSData */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx;
- XGI330_LVDSDataStruct *LCDPtr = NULL;
-
- tempbx = 2;
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- LCDPtr =
- (XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
- ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- pVBInfo->VGAHT = LCDPtr->VGAHT;
- pVBInfo->VGAVT = LCDPtr->VGAVT;
- pVBInfo->HT = LCDPtr->LCDHT;
- pVBInfo->VT = LCDPtr->LCDVT;
- }
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))) {
- get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_ModCRT1Regs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR index;
- USHORT tempbx, i;
- XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
- XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
- /* XGI330_CHTVDataStruct *TVPtr = NULL ; */
-
- if (ModeNo <= 0x13)
- index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- else
- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
- index = index & IndexMask;
-
- if ((pVBInfo->IF_DEF_ScaleLCD == 0)
- || ((pVBInfo->IF_DEF_ScaleLCD == 1)
- && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
- tempbx = 0;
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- LCDPtr =
- (XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
- ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
-
- for (i = 0; i < 8; i++)
- pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
- }
-
- XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
-
- tempbx = 1;
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- LCDPtr1 =
- (XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
- ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- for (i = 0; i < 7; i++)
- pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
- }
-
- XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
- }
-}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLVDSRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
- unsigned long temp, temp1, temp2, temp3, push3;
- XGI330_LCDDataDesStruct *LCDPtr = NULL;
- XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
-
- if (ModeNo > 0x13)
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- else
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
-
- if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
- if (pVBInfo->IF_DEF_OEMUtil == 1) {
- tempbx = 8;
- LCDPtr =
- (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
- ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- }
-
- if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == 0)) {
- tempbx = 3;
- if (pVBInfo->LCDInfo & EnableScalingLCD)
- LCDPtr1 =
- (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(tempbx, ModeNo,
- ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- else
- LCDPtr =
- (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
- ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- }
-
- XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
- push1 = tempbx;
- push2 = tempax;
-
- /* GetLCDResInfo */
- if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
- get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
-
- pVBInfo->VGAHDE = pVBInfo->HDE;
- pVBInfo->VGAVDE = pVBInfo->VDE;
- }
-
- tempax = pVBInfo->HT;
-
- tempbx = (pVBInfo->LCDInfo & EnableScalingLCD)
- ? LCDPtr1->LCDHDES : LCDPtr->LCDHDES;
-
- tempcx = pVBInfo->HDE;
- tempbx = tempbx & 0x0fff;
- tempcx += tempbx;
-
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
-
- tempcx = tempcx >> 3;
- tempbx = tempbx >> 3;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16,
- (USHORT) (tempbx & 0xff));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17,
- (USHORT) (tempcx & 0xff));
-
- tempax = pVBInfo->HT;
-
- if (pVBInfo->LCDInfo & EnableScalingLCD)
- tempbx = LCDPtr1->LCDHRS;
- else
- tempbx = LCDPtr->LCDHRS;
-
- tempcx = push2;
-
- if (pVBInfo->LCDInfo & EnableScalingLCD)
- tempcx = LCDPtr1->LCDHSync;
-
- tempcx += tempbx;
-
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- /* FIXME: Won't this *always* set tempax to zero? */
- tempax = tempbx & 0x07;
- tempax = tempax >> 5;
- tempcx = tempcx >> 3;
- tempbx = tempbx >> 3;
-
- tempcx &= 0x1f;
- tempax |= tempcx;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x15, tempax);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x14,
- (USHORT) (tempbx & 0xff));
-
- tempax = pVBInfo->VT;
- if (pVBInfo->LCDInfo & EnableScalingLCD)
- tempbx = LCDPtr1->LCDVDES;
- else
- tempbx = LCDPtr->LCDVDES;
- tempcx = pVBInfo->VDE;
-
- tempbx = tempbx & 0x0fff;
- tempcx += tempbx;
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1b,
- (USHORT) (tempbx & 0xff));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1c,
- (USHORT) (tempcx & 0xff));
-
- tempbx = (tempbx >> 8) & 0x07;
- tempcx = (tempcx >> 8) & 0x07;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1d,
- (USHORT) ((tempcx << 3) | tempbx));
-
- tempax = pVBInfo->VT;
- if (pVBInfo->LCDInfo & EnableScalingLCD)
- tempbx = LCDPtr1->LCDVRS;
- else
- tempbx = LCDPtr->LCDVRS;
-
- /* tempbx = tempbx >> 4 ; */
- tempcx = push1;
-
- if (pVBInfo->LCDInfo & EnableScalingLCD)
- tempcx = LCDPtr1->LCDVSync;
-
- tempcx += tempbx;
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18,
- (USHORT) (tempbx & 0xff));
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, ~0x0f,
- (USHORT) (tempcx & 0x0f));
-
- tempax = ((tempbx >> 8) & 0x07) << 3;
-
- tempbx = pVBInfo->VGAVDE;
- if (tempbx != pVBInfo->VDE)
- tempax |= 0x40;
-
- if (pVBInfo->LCDInfo & EnableLVDSDDA)
- tempax |= 0x40;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1a, 0x07,
- tempax);
-
- tempcx = pVBInfo->VGAVT;
- tempbx = pVBInfo->VDE;
- tempax = pVBInfo->VGAVDE;
- tempcx -= tempax;
-
- temp = tempax; /* 0430 ylshieh */
- temp1 = (temp << 18) / tempbx;
-
- tempdx = (USHORT) ((temp << 18) % tempbx);
-
- if (tempdx != 0)
- temp1 += 1;
-
- temp2 = temp1;
- push3 = temp2;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x37,
- (USHORT) (temp2 & 0xff));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x36,
- (USHORT) ((temp2 >> 8) & 0xff));
-
- tempbx = (USHORT) (temp2 >> 16);
- tempax = tempbx & 0x03;
-
- tempbx = pVBInfo->VGAVDE;
- if (tempbx == pVBInfo->VDE)
- tempax |= 0x04;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x35, tempax);
-
- if (pVBInfo->VBType & VB_XGI301C) {
- temp2 = push3;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3c,
- (USHORT) (temp2 & 0xff));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3b,
- (USHORT) ((temp2 >> 8) & 0xff));
- tempbx = (USHORT) (temp2 >> 16);
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x3a, ~0xc0,
- (USHORT) ((tempbx & 0xff) << 6));
-
- tempcx = pVBInfo->VGAVDE;
- if (tempcx == pVBInfo->VDE)
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
- ~0x0c, 0x00);
- else
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
- ~0x0c, 0x08);
- }
-
- tempcx = pVBInfo->VGAHDE;
- tempbx = pVBInfo->HDE;
-
- temp1 = tempcx << 16;
-
- tempax = (USHORT) (temp1 / tempbx);
-
- if ((tempbx & 0xffff) == (tempcx & 0xffff))
- tempax = 65535;
-
- temp3 = tempax;
- temp1 = pVBInfo->VGAHDE << 16;
-
- temp1 /= temp3;
- temp3 = temp3 << 16;
- temp1 -= 1;
-
- temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
-
- tempax = (USHORT) (temp3 & 0xff);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1f, tempax);
-
- temp1 = pVBInfo->VGAVDE << 18;
- temp1 = temp1 / push3;
- tempbx = (USHORT) (temp1 & 0xffff);
-
- if (pVBInfo->LCDResInfo == Panel1024x768)
- tempbx -= 1;
-
- tempax = ((tempbx >> 8) & 0xff) << 3;
- tempax |= (USHORT) ((temp3 >> 8) & 0x07);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x20,
- (USHORT) (tempax & 0xff));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x21,
- (USHORT) (tempbx & 0xff));
-
- temp3 = temp3 >> 16;
-
- if (modeflag & HalfDCLK)
- temp3 = temp3 >> 1;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x22,
- (USHORT) ((temp3 >> 8) & 0xff));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x23,
- (USHORT) (temp3 & 0xff));
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2ECLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR di[2];
- int i;
- const unsigned vclkindex =
- XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
-
- XGI_GetVCLKLen(vclkindex, di, pVBInfo);
- XGI_GetLCDVCLKPtr(di, pVBInfo);
-
- for (i = 0; i < 4; i++) {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, ~0x30,
- (USHORT) (0x10 * i));
- if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
- && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, di[0]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, di[1]);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2b, di[0]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2c, di[1]);
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_UpdateModeInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempcl, tempch, temp, tempbl, tempax;
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- tempcl = 0;
- tempch = 0;
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
-
- if (!(temp & 0x20)) {
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
- if (temp & 0x80) {
- if ((HwDeviceExtension->jChipType == XG20)
- || (HwDeviceExtension->jChipType >= XG40))
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53);
- else
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
-
- if (!(temp & 0x40))
- tempcl |= ActiveCRT1;
- }
- }
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e);
- temp &= 0x0f;
-
- if (!(temp == 0x08)) {
- tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
- if (tempax & 0x04)
- tempcl = tempcl | ActiveLCD;
-
- temp &= 0x05;
-
- if (!(tempcl & ActiveLCD))
- if (temp == 0x01)
- tempcl |= ActiveCRT2;
-
- if (temp == 0x04)
- tempcl |= ActiveLCD;
-
- if (temp == 0x05) {
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00);
-
- if (!(temp & 0x08))
- tempch |= ActiveAVideo;
-
- if (!(temp & 0x04))
- tempch |= ActiveSVideo;
-
- if (temp & 0x02)
- tempch |= ActiveSCART;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (temp & 0x01)
- tempch |= ActiveHiTV;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
- temp =
- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d);
-
- if (temp & 0x10)
- tempch |= ActiveYPbPr;
- }
-
- if (tempch != 0)
- tempcl |= ActiveTV;
- }
- }
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d);
- if (tempcl & ActiveLCD) {
- if ((pVBInfo->SetFlag & ReserveTVOption)) {
- if (temp & ActiveTV)
- tempcl |= ActiveTV;
- }
- }
- temp = tempcl;
- tempbl = ~ModeSwitchStatus;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x3d, tempbl, temp);
-
- if (!(pVBInfo->SetFlag & ReserveTVOption))
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e, tempch);
- }
- else {
- return;
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVBType */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetVBType(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT flag, tempbx, tempah;
-
- tempbx = VB_XGI302B;
- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
- if (flag != 0x02) {
- tempbx = VB_XGI301;
- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x01);
- if (flag >= 0xB0) {
- tempbx = VB_XGI301B;
- if (flag >= 0xC0) {
- tempbx = VB_XGI301C;
- if (flag >= 0xD0) {
- tempbx = VB_XGI301LV;
- if (flag >= 0xE0) {
- tempbx = VB_XGI302LV;
- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port,
- 0x39);
- if (tempah != 0xFF)
- tempbx = VB_XGI301C;
- }
- }
- }
-
- if (tempbx & (VB_XGI301B | VB_XGI302B)) {
- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x23);
-
- if (!(flag & 0x02))
- tempbx = tempbx | VB_NoLCD;
- }
- }
- }
-
- pVBInfo->VBType = tempbx;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVBInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, push, tempbx, temp, modeflag;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- pVBInfo->SetFlag = 0;
- pVBInfo->ModeType = modeflag & ModeInfoFlag;
- tempbx = 0;
-
- if (pVBInfo->VBType & 0xFFFF) {
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30); /* Check Display Device */
- tempbx = tempbx | temp;
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
- push = temp;
- push = push << 8;
- tempax = temp << 8;
- tempbx = tempbx | tempax;
- temp =
- (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA |
- SetInSlaveMode | DisableCRT2Display);
- temp = 0xFFFF ^ temp;
- tempbx &= temp;
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38);
-
- if (pVBInfo->IF_DEF_LCDA == 1) {
- /* if ( ( pVBInfo->VBType & VB_XGI302B ) || ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) */
- if (pVBInfo->
- VBType & (VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (temp & EnableDualEdge) {
- tempbx |= SetCRT2ToDualEdge;
-
- if (temp & SetToLCDA)
- tempbx |= SetCRT2ToLCDA;
- }
- }
- }
-
- if (pVBInfo->IF_DEF_YPbPr == 1) {
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV)
- || (pVBInfo->VBType & VB_XGI301C)) {
- if (temp & SetYPbPr) { /* temp = CR38 */
- if (pVBInfo->IF_DEF_HiVision == 1) {
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35); /* shampoo add for new scratch */
- temp &= YPbPrMode;
- tempbx |= SetCRT2ToHiVisionTV;
-
- if (temp != YPbPrMode1080i) {
- tempbx &= (~SetCRT2ToHiVisionTV);
- tempbx |= SetCRT2ToYPbPr;
- }
- }
-
- /* tempbx |= SetCRT2ToYPbPr ; */
- }
- }
- }
-
- tempax = push; /* restore CR31 */
-
- if (pVBInfo->IF_DEF_YPbPr == 1) {
- if (pVBInfo->IF_DEF_HiVision == 1)
- temp = 0x09FC;
- else
- temp = 0x097C;
- }
- else {
- if (pVBInfo->IF_DEF_HiVision == 1)
- temp = 0x01FC;
- else
- temp = 0x017C;
- }
-
-
- if (!(tempbx & temp)) {
- tempax |= DisableCRT2Display;
- tempbx = 0;
- }
-
- if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
- if (!(pVBInfo->VBType & VB_NoLCD)) {
- if (tempbx & SetCRT2ToLCDA) {
- if (tempbx & SetSimuScanMode)
- tempbx &=
- (~
- (SetCRT2ToLCD | SetCRT2ToRAMDAC | SwitchToCRT2));
- else
- tempbx &=
- (~
- (SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV |
- SwitchToCRT2));
- }
- }
- }
-
- /* shampoo add */
- if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
- if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
- if (tempbx & SetCRT2ToRAMDAC) {
- tempbx &=
- (0xFF00 | SetCRT2ToRAMDAC | SwitchToCRT2 |
- SetSimuScanMode);
- tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
- }
- }
- else
- tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV));
- }
-
- if (!(pVBInfo->VBType & VB_NoLCD)) {
- if (tempbx & SetCRT2ToLCD) {
- tempbx &=
- (0xFF00 | SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode);
- tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
- }
- }
-
- if (tempbx & SetCRT2ToSCART) {
- tempbx &=
- (0xFF00 | SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode);
- tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
- }
-
- if (pVBInfo->IF_DEF_YPbPr == 1) {
- if (tempbx & SetCRT2ToYPbPr)
- tempbx &= (0xFF00 | SwitchToCRT2 | SetSimuScanMode);
- }
-
- if (pVBInfo->IF_DEF_HiVision == 1) {
- if (tempbx & SetCRT2ToHiVisionTV)
- tempbx &=
- (0xFF00 | SetCRT2ToHiVisionTV | SwitchToCRT2 |
- SetSimuScanMode);
- }
-
- if (tempax & DisableCRT2Display) { /* Set Display Device Info */
- if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
- tempbx = DisableCRT2Display;
- }
-
- if (!(tempbx & DisableCRT2Display)) {
- if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
- if (pVBInfo->IF_DEF_LCDA == 1) {
- if (!(tempbx & SetCRT2ToLCDA))
- tempbx |= (SetInSlaveMode | SetSimuScanMode);
- }
-
- if (pVBInfo->IF_DEF_VideoCapture == 1) {
- if ((HwDeviceExtension->jChipType >= XG40)
- && (HwDeviceExtension->jChipType <= XG45)) {
- if (ModeNo <= 13) {
- /* CRT2 not need to support */
- if (!(tempbx & SetCRT2ToRAMDAC)) {
- tempbx &= (0x00FF | (~SetInSlaveMode));
- pVBInfo->SetFlag |= EnableVCMode;
- }
- }
- }
- }
- }
-
- /*LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
- if ((tempbx & SetInSlaveMode) && (tempbx & SetCRT2ToLCDA)) {
- tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToDualEdge);
- pVBInfo->SetFlag |= ReserveTVOption;
- }
- }
- }
-
- pVBInfo->VBInfo = tempbx;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp, tempbx = 0, resinfo = 0, modeflag, index1;
-
- tempbx = 0;
- resinfo = 0;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
- tempbx = temp;
- if (tempbx & SetPALTV) {
- tempbx &=
- (SetCHTVOverScan | SetPALMTV | SetPALNTV | SetPALTV);
- if (tempbx & SetPALMTV)
- tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
- }
- else
- tempbx &= (SetCHTVOverScan | SetNTSCJ | SetPALTV);
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToSCART)
- tempbx |= SetPALTV;
-
- if (pVBInfo->IF_DEF_YPbPr == 1) {
- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
- index1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
- index1 &= YPbPrMode;
-
- if (index1 == YPbPrMode525i)
- tempbx |= SetYPbPrMode525i;
-
- if (index1 == YPbPrMode525p)
- tempbx = tempbx | SetYPbPrMode525p;
- if (index1 == YPbPrMode750p)
- tempbx = tempbx | SetYPbPrMode750p;
- }
- }
-
- if (pVBInfo->IF_DEF_HiVision == 1) {
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
- }
- }
-
- if ((pVBInfo->VBInfo & SetInSlaveMode)
- && (!(pVBInfo->VBInfo & SetNotSimuMode)))
- tempbx |= TVSimuMode;
-
- if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo == 8)) /* NTSC 1024x768, */
- tempbx |= NTSC1024x768;
-
- tempbx |= RPLLDIV2XO;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (pVBInfo->VBInfo & SetInSlaveMode)
- tempbx &= (~RPLLDIV2XO);
- }
- else {
- if (tempbx & (SetYPbPrMode525p | SetYPbPrMode750p))
- tempbx &= (~RPLLDIV2XO);
- else if (!
- (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV |
- VB_XGI302LV | VB_XGI301C))) {
- if (tempbx & TVSimuMode)
- tempbx &= (~RPLLDIV2XO);
- }
- }
- }
- pVBInfo->TVInfo = tempbx;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
-
- pVBInfo->LCDResInfo = 0;
- pVBInfo->LCDTypeInfo = 0;
- pVBInfo->LCDInfo = 0;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo// */
- }
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
- tempbx = temp & 0x0F;
-
- if (tempbx == 0)
- tempbx = Panel1024x768; /* default */
-
- /* LCD75 [2003/8/22] Vicent */
- if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
- if (pVBInfo->VBInfo & DriverMode) {
- tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
- tempax &= 0x0F;
- else
- tempax = tempax >> 4;
-
- if ((resinfo == 6) || (resinfo == 9)) {
- if (tempax >= 3)
- tempbx |= PanelRef75Hz;
- }
- else if ((resinfo == 7) || (resinfo == 8)) {
- if (tempax >= 4)
- tempbx |= PanelRef75Hz;
- }
- }
- }
-
- pVBInfo->LCDResInfo = tempbx;
-
- /* End of LCD75 */
-
- if (pVBInfo->IF_DEF_OEMUtil == 1) {
- pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
- }
-
- if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
- return 0;
- }
-
- tempbx = 0;
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
-
- temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
-
- if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
- temp &= ~EnableScalingLCD;
-
- tempbx |= temp;
-
- LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
-
- tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
-
- if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C))
- && (tempax & LCDDualLink)) {
- tempbx |= SetLCDDualLink;
- }
-
- if ((pVBInfo->LCDResInfo == Panel1400x1050)
- && (pVBInfo->VBInfo & SetCRT2ToLCD) && (ModeNo > 0x13)
- && (resinfo == 9) && (!(tempbx & EnableScalingLCD)))
- tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
-
-/*
- if ( tempax & LCDBToA )
- {
- tempbx |= SetLCDBToA ;
- }
-*/
-
- if (pVBInfo->IF_DEF_ExpLink == 1) {
- if (modeflag & HalfDCLK) {
- /* if ( !( pVBInfo->LCDInfo&LCDNonExpanding ) ) */
- if (!(tempbx & SetLCDtoNonExpanding)) {
- tempbx |= EnableLVDSDDA;
- }
- else {
- if (ModeNo > 0x13) {
- if (pVBInfo->LCDResInfo == Panel1024x768) {
- if (resinfo == 4) { /* 512x384 */
- tempbx |= EnableLVDSDDA;
- }
- }
- }
- }
- }
- }
-
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (pVBInfo->VBInfo & SetNotSimuMode) {
- tempbx |= LCDVESATiming;
- }
- }
- else {
- tempbx |= LCDVESATiming;
- }
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x39);
- if (temp & ReduceTiming) {
- tempbx |= EnableReduceTiming;
- }
-
- pVBInfo->LCDInfo = tempbx;
-
- if (pVBInfo->IF_DEF_PWD == 1) {
- if (pVBInfo->LCDInfo & SetPWDEnable) {
- if ((pVBInfo->VBType & VB_XGI302LV)
- || (pVBInfo->VBType & VB_XGI301C)) {
- if (!(tempax & PWDEnable)) {
- pVBInfo->LCDInfo &= ~SetPWDEnable;
- }
- }
- }
- }
-
- {
- if (tempax & (LockLCDBToA | StLCDBToA)) {
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (!(tempax & LockLCDBToA)) {
- if (ModeNo <= 0x13) {
- pVBInfo->VBInfo &=
- ~(SetSimuScanMode | SetInSlaveMode |
- SetCRT2ToLCD);
- pVBInfo->VBInfo |= SetCRT2ToLCDA | SetCRT2ToDualEdge;
- }
- }
- }
- }
- }
-
- return (1);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT memorysize, modeflag, temp, temp1, tmp;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- /* ModeType = modeflag&ModeInfoFlag ; // Get mode type */
-
- memorysize = modeflag & MemoryInfoFlag;
- memorysize = memorysize > MemorySizeShift;
- memorysize++; /* Get memory size */
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x14); /* Get DRAM Size */
- tmp = temp;
-
- if (HwDeviceExtension->jChipType == XG40) {
- temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
- if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
- temp <<= 2;
- }
- else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
- temp <<= 1;
- }
- }
- else if (HwDeviceExtension->jChipType == XG42) {
- temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
- if ((tmp & 0x04) == 0x04) { /* Dual channels */
- temp <<= 1;
- }
- }
- else if (HwDeviceExtension->jChipType == XG45) {
- temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
- if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
- temp <<= 2;
- }
- else if ((tmp & 0x0c) == 0x08) { /* triple channels */
- temp1 = temp;
- temp <<= 1;
- temp += temp1;
- }
- else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
- temp <<= 1;
- }
- }
- if (temp < memorysize)
- return (FALSE);
- else
- return (TRUE);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisplayOn */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_DisplayOn(PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x00);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisplayOff */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_DisplayOff(PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x20);
-}
-
-
-/**
- * Wait for vertical or horizontal blanking period.
- */
-void
-XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo)
-{
- while ((XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
- break;
-
- while (!(XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
- break;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SenseCRT1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-
-void
-XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
- 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7,
- 0x04, 0x00, 0x00, 0x05, 0x00
- };
-
- UCHAR SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
-
- UCHAR CR17, CR63, SR31;
- USHORT temp;
- UCHAR DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
-
- int i;
-#ifndef LINUX_XF86
- int j;
-#endif
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
-
- /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x57, 0x4A);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
- (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) |
- 0x02));
-
- SR31 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31);
- CR63 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
- SR01 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, (UCHAR) (SR01 & 0xDF));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, (UCHAR) (CR63 & 0xBF));
-
- CR17 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17, (UCHAR) (CR17 | 0x80));
-
- SR1F = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, (UCHAR) (SR1F | 0x04));
-
- SR07 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, (UCHAR) (SR07 & 0xFB));
- SR06 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06, (UCHAR) (SR06 & 0xC3));
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x00);
-
- for (i = 0; i < 8; i++)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) i, CRTCData[i]);
-
- for (i = 8; i < 11; i++)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 8),
- CRTCData[i]);
-
- for (i = 11; i < 13; i++)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 4),
- CRTCData[i]);
-
- for (i = 13; i < 16; i++)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i - 3),
- CRTCData[i]);
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E,
- (UCHAR) (CRTCData[16] & 0xE0));
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0x00);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE1);
-
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
- for (i = 0; i < 256; i++) {
- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
- (UCHAR) DAC_TEST_PARMS[0]);
- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
- (UCHAR) DAC_TEST_PARMS[1]);
- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
- (UCHAR) DAC_TEST_PARMS[2]);
- }
-
- XGI_VBLongWait(pVBInfo);
- XGI_VBLongWait(pVBInfo);
- XGI_VBLongWait(pVBInfo);
-
- XGINew_LCD_Wait_Time(0x01, pVBInfo);
- XGI_WaitDisplay(pVBInfo);
-
- temp = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3c2);
- if (temp & 0x10) {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x20);
- }
- else {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x00);
- }
-
- /* alan, avoid display something, set BLACK DAC if not restore DAC */
- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
-
- for (i = 0; i < 256; i++) {
- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SR01);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, CR63);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, SR31);
-
- /* [2004/05/11] Vicent */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
- (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) &
- 0xFD));
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-CheckDualChip(PVB_DEVICE_INFO pVBInfo)
-{
- /* Check H/W trap that 2nd chip is present or not. */
- return ((BOOLEAN)
- (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3A) &
- XGI_MASK_DUAL_CHIP));
-}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : SetDualChipRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-SetDualChipRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
-
-#ifdef LINUX_XF86
- USHORT BaseAddr2nd = (USHORT) (ULONG) HwDeviceExtension->pj2ndIOAddress;
-#else
- USHORT BaseAddr2nd = (USHORT) HwDeviceExtension->pj2ndIOAddress;
-#endif
- USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT;
- USHORT XGINew_2ndP3CE = BaseAddr2nd + GRAPH_ADDRESS_PORT;
- USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT;
- USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT;
- UCHAR tempal, i;
- pVBInfo->BaseAddr = (USHORT) HwDeviceExtension->pjIOAddress;
- for (i = 0x00; i <= 0x04; i++) { /* SR0 - SR4 */
- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, i);
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, i, tempal);
- }
- for (i = 0x00; i <= 0x08; i++) { /* GR0 - GR8 */
- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3ce, i);
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3CE, i, tempal);
- }
- /* OpenKey in 2nd chip */
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x86);
-
- /* Copy SR06 to 2nd chip */
- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x06, tempal);
-
- /* Copy SR21 to 2nd chip */
- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21);
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x21, tempal);
-
- /* Miscellaneous reg(input port 3cch,output port 3c2h) */
- tempal = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC); /* 3cc */
- XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2, tempal);
-
- /* Close key in 2nd chip */
- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x00);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2Group301 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, ModeIdIndex, RefreshRateTableIndex;
- USHORT temp_mode_no;
-
- tempbx = pVBInfo->VBInfo;
- pVBInfo->SetFlag |= ProgrammingCRT2;
-
- temp_mode_no = ModeNo;
- XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11,
- &temp_mode_no, &ModeIdIndex);
-
-
- pVBInfo->SelectCRT2Rate = 4;
- RefreshRateTableIndex = XGI_GetRatePtrCRT2(ModeNo, ModeIdIndex, pVBInfo);
- XGI_SaveCRT2Info(ModeNo, pVBInfo);
- XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
- XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
- RefreshRateTableIndex, pVBInfo);
- XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
- RefreshRateTableIndex, pVBInfo);
- XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
- RefreshRateTableIndex, pVBInfo);
- XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwDeviceExtension, pVBInfo);
- XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
- RefreshRateTableIndex, pVBInfo);
- XGI_SetTap4Regs(pVBInfo);
- XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
- XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwDeviceExtension, pVBInfo);
- XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
- XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
- XGI_AutoThreshold(pVBInfo);
- return 1;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_AutoThreshold */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo)
-{
- if (!(pVBInfo->SetFlag & Win9xDOSMode))
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x40);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SaveCRT2Info */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp1, temp2;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
- temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
- temp2 = ~(SetInSlaveMode >> 8);
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, temp2, temp1);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetCRT2ResInfo */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- unsigned xres;
- unsigned yres;
-
-
- get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
-
- if ((pVBInfo->VBInfo & SetCRT2ToLCD)
- && !(pVBInfo->LCDInfo & (EnableScalingLCD | LCDNonExpanding))) {
- switch (pVBInfo->LCDResInfo) {
- case Panel1600x1200:
- if (!(pVBInfo->LCDInfo & LCDVESATiming) && (yres == 1024)) {
- yres = 1056;
- }
- break;
-
-
- case Panel1280x1024:
- if (yres == 400)
- yres = 405;
- else if (yres == 350)
- yres = 360;
- else if ((pVBInfo->LCDInfo & LCDVESATiming) && (yres == 360)) {
- yres = 375;
- }
- break;
-
-
- case Panel1024x768:
- if (!(pVBInfo->LCDInfo & (LCDVESATiming | LCDNonExpanding))) {
- if (yres == 350) {
- yres = 357;
- }
- else if (yres == 400) {
- yres = 420;
- }
- else if (yres == 480) {
- yres = 525;
- }
- }
-
- break;
- }
-
- if (xres == 720)
- xres = 640;
- }
-
- pVBInfo->VGAHDE = xres;
- pVBInfo->HDE = xres;
- pVBInfo->VGAVDE = yres;
- pVBInfo->VDE = yres;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_IsLCDDualLink */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo)
-{
- return (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) != 0)
- && ((pVBInfo->LCDInfo & SetLCDDualLink) != 0));
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetCRT2Data */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax = 0, tempbx, modeflag, resinfo;
-#ifndef LINUX_XF86
- USHORT CRT2Index, ResIndex;
-#endif
-
- XGI_LCDDataStruct *LCDPtr = NULL;
- XGI_TVDataStruct *TVPtr = NULL;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
-
- pVBInfo->NewFlickerMode = 0;
- pVBInfo->RVBHRS = 50;
-
- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- pVBInfo);
- return;
- }
-
- tempbx = 4;
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- LCDPtr =
- (XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
-
- PDEBUG(ErrorF
- ("C code setmode: ModeNo: 0x%08lX VGAHT:0x%081X \n", ModeNo,
- LCDPtr->VGAHT));
- pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
- pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
- pVBInfo->VGAHT = LCDPtr->VGAHT;
- pVBInfo->VGAVT = LCDPtr->VGAVT;
- pVBInfo->HT = LCDPtr->LCDHT;
- pVBInfo->VT = LCDPtr->LCDVT;
-
- if (pVBInfo->LCDResInfo == Panel1024x768) {
- tempax = 1024;
- tempbx = 768;
-
- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
- if (pVBInfo->VGAVDE == 357)
- tempbx = 527;
- else if (pVBInfo->VGAVDE == 420)
- tempbx = 620;
- else if (pVBInfo->VGAVDE == 525)
- tempbx = 775;
- else if (pVBInfo->VGAVDE == 600)
- tempbx = 775;
- /* else if(pVBInfo->VGAVDE==350) tempbx=560; */
- /* else if(pVBInfo->VGAVDE==400) tempbx=640; */
- else
- tempbx = 768;
- }
- else
- tempbx = 768;
- }
- else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
- tempax = 1024;
- tempbx = 768;
- }
- else if (pVBInfo->LCDResInfo == Panel1280x1024) {
- tempax = 1280;
- if (pVBInfo->VGAVDE == 360)
- tempbx = 768;
- else if (pVBInfo->VGAVDE == 375)
- tempbx = 800;
- else if (pVBInfo->VGAVDE == 405)
- tempbx = 864;
- else
- tempbx = 1024;
- }
- else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
- tempax = 1280;
- tempbx = 1024;
- }
- else if (pVBInfo->LCDResInfo == Panel1280x960) {
- tempax = 1280;
- if (pVBInfo->VGAVDE == 350)
- tempbx = 700;
- else if (pVBInfo->VGAVDE == 400)
- tempbx = 800;
- else if (pVBInfo->VGAVDE == 1024)
- tempbx = 960;
- else
- tempbx = 960;
- }
- else if (pVBInfo->LCDResInfo == Panel1400x1050) {
- tempax = 1400;
- tempbx = 1050;
-
- if (pVBInfo->VGAVDE == 1024) {
- tempax = 1280;
- tempbx = 1024;
- }
- }
- else if (pVBInfo->LCDResInfo == Panel1600x1200) {
- tempax = 1600;
- tempbx = 1200; /* alan 10/14/2003 */
- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
- if (pVBInfo->VGAVDE == 350)
- tempbx = 875;
- else if (pVBInfo->VGAVDE == 400)
- tempbx = 1000;
- }
- }
-
- if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD)) {
- tempax = pVBInfo->VGAHDE;
- tempbx = pVBInfo->VGAVDE;
- }
-
- pVBInfo->HDE = tempax;
- pVBInfo->VDE = tempbx;
- return;
- }
-
- if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
- tempbx = 4;
- TVPtr =
- (XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex,
- RefreshRateTableIndex, pVBInfo);
- pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
- pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
- pVBInfo->VGAHT = TVPtr->VGAHT;
- pVBInfo->VGAVT = TVPtr->VGAVT;
- pVBInfo->HDE = TVPtr->TVHDE;
- pVBInfo->VDE = TVPtr->TVVDE;
- pVBInfo->RVBHRS = TVPtr->RVBHRS;
- pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (resinfo == 0x08)
- pVBInfo->NewFlickerMode = 0x40;
- else if (resinfo == 0x09)
- pVBInfo->NewFlickerMode = 0x40;
- else if (resinfo == 0x12)
- pVBInfo->NewFlickerMode = 0x40;
-
- if (pVBInfo->VGAVDE == 350)
- pVBInfo->TVInfo |= TVSimuMode;
-
- tempax = ExtHiTVHT;
- tempbx = ExtHiTVVT;
-
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (pVBInfo->TVInfo & TVSimuMode) {
- tempax = StHiTVHT;
- tempbx = StHiTVVT;
-
- if (!(modeflag & Charx8Dot)) {
- tempax = StHiTextTVHT;
- tempbx = StHiTextTVVT;
- }
- }
- }
- }
- else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
- if (pVBInfo->TVInfo & SetYPbPrMode750p) {
- tempax = YPbPrTV750pHT; /* Ext750pTVHT */
- tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
- }
-
- if (pVBInfo->TVInfo & SetYPbPrMode525p) {
- tempax = YPbPrTV525pHT; /* Ext525pTVHT */
- tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
- }
- else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
- tempax = YPbPrTV525iHT; /* Ext525iTVHT */
- tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
- if (pVBInfo->TVInfo & NTSC1024x768)
- tempax = NTSC1024x768HT;
- }
- }
- else {
- tempax = PALHT;
- tempbx = PALVT;
- if (!(pVBInfo->TVInfo & SetPALTV)) {
- tempax = NTSCHT;
- tempbx = NTSCVT;
- if (pVBInfo->TVInfo & NTSC1024x768)
- tempax = NTSC1024x768HT;
- }
- }
-
- pVBInfo->HT = tempax;
- pVBInfo->VT = tempbx;
- return;
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2VCLK */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR di[2];
- const unsigned vclkindex =
- XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
-
- XGI_GetVCLKLen(vclkindex, di, pVBInfo);
- XGI_GetLCDVCLKPtr(di, pVBInfo);
-
- if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 *//* 301 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x10);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
- }
- else { /* 301b/302b/301lv/302lv */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
- }
-
- if ((pVBInfo->LCDInfo & EnableReduceTiming)
- && (pVBInfo->LCDResInfo == Panel1600x1200)) {
- if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0A) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x5A);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, 0x24);
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00, 0x12);
-
- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x28);
- else
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x08);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GETLCDVCLKPtr */
-/* Input : */
-/* Output : al -> VCLK Index */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo)
-{
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if ((pVBInfo->IF_DEF_ScaleLCD != 1)
- || !(pVBInfo->LCDInfo & EnableScalingLCD)) {
- const unsigned index = XGI_GetLCDCapPtr1(pVBInfo);
-
- if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
- di[0] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
- di[1] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
- }
- else { /* LCDA */
- di[0] = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
- di[1] = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
- }
- }
- }
-
- return;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVCLKPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-unsigned
-XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- unsigned vclk;
- const unsigned modeflag = (ModeNo <= 0x13)
- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-
- if ((pVBInfo->SetFlag & ProgrammingCRT2)
- && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
- const unsigned index = XGI_GetLCDCapPtr(pVBInfo);
- vclk = pVBInfo->LCDCapList[index].LCD_VCLK;
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
- return vclk;
-
- /* {TV} */
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (pVBInfo->TVInfo & TVSimuMode) {
- vclk = (modeflag & Charx8Dot)
- ? HiTVSimuVCLK : HiTVTextVCLK;
- }
- else {
- vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
- ? HiTVVCLKDIV2 : HiTVVCLK;
- }
-
- return vclk;
- }
- else if (pVBInfo->TVInfo & SetYPbPrMode750p) {
- return YPbPr750pVCLK;
- }
- else if (pVBInfo->TVInfo & SetYPbPrMode525p) {
- return YPbPr525pVCLK;
- }
-
- vclk = NTSC1024VCLK;
-
- if (!(pVBInfo->TVInfo & NTSC1024x768)) {
- vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
- ? TVVCLKDIV2 : TVVCLK;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToTV)
- return vclk;
- }
- } /* {End of VB} */
-
- vclk = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
- vclk = (vclk >> 2) & 0x03;
-
- /* for Dot8 Scaling LCD */
- if ((pVBInfo->LCDInfo & EnableScalingLCD)
- && (modeflag & Charx8Dot)
- && ((pVBInfo->IF_DEF_VideoCapture) == 1)) {
- vclk = VCLK25_175; /* ; set to VCLK25MHz always */
- }
-
- if (ModeNo <= 0x13)
- return vclk;
-
- return pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVCLKLen */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di, PVB_DEVICE_INFO pVBInfo)
-{
- if (pVBInfo->
- VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV |
- VB_XGI302LV | VB_XGI301C)) {
- if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
- && (pVBInfo->SetFlag & ProgrammingCRT2)) {
- di[0] = XGI_VBVCLKData[vclkindex].SR2B;
- di[1] = XGI_VBVCLKData[vclkindex].SR2C;
- }
- }
- else {
- di[0] = XGI_VCLKData[vclkindex].SR2B;
- di[1] = XGI_VCLKData[vclkindex].SR2C;
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2Offset */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT2Offset(USHORT ModeNo,
- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT offset;
- UCHAR temp;
-
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- return;
- }
-
- offset =
- XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwDeviceExtension, pVBInfo);
- temp = (UCHAR) (offset & 0xFF);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp);
- temp = (UCHAR) ((offset & 0xFF00) >> 8);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, temp);
- temp = (UCHAR) (((offset >> 3) & 0xFF) + 1);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetOffset */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp,
- colordepth,
- modeinfo, index, infoflag;
-
- modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
- if (ModeNo <= 0x14)
- infoflag = 0;
- else
- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-
-
- index = (modeinfo >> 8) & 0xFF;
-
- temp = pVBInfo->ScreenOffset[index];
-
- if (infoflag & InterlaceMode) {
- temp = temp << 1;
- }
-
- colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
-
- if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
- return (temp * colordepth + (colordepth >> 1));
- }
- else
- return (temp * colordepth);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2FIFO */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT2FIFO(PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_PreSetGroup1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempcx = 0, CRT1Index = 0, resinfo = 0;
-#ifndef LINUX_XF86
- USHORT temp = 0, tempax = 0, tempbx = 0, pushbx = 0, modeflag;
-#endif
-
- if (ModeNo > 0x13) {
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- CRT1Index &= IndexMask;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
-
- XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
- HwDeviceExtension, pVBInfo);
- XGI_SetCRT2FIFO(pVBInfo);
- /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
-
- for (tempcx = 4; tempcx < 7; tempcx++) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, tempcx, 0x0);
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp = 0,
- tempax = 0,
- tempbx = 0,
- tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
-
- if (ModeNo > 0x13) {
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- CRT1Index &= IndexMask;
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- }
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- /* bainy change table name */
- if (modeflag & HalfDCLK) {
- temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
- temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
- temp);
- temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
- tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
- pushbx = pVBInfo->VGAHDE / 2 + 16;
- tempcx = tempcx >> 1;
- tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
- tempcx += tempbx;
-
- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
- tempbx |=
- ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
- tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
- tempcx &= 0x1F;
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
- temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
- tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
- }
-
- tempbx += 4;
- tempcx += 4;
-
- if (tempcx > (pVBInfo->VGAHT / 2))
- tempcx = pVBInfo->VGAHT / 2;
-
- temp = tempbx & 0x00FF;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
- }
- else {
- temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
- temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
- temp);
- temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
- tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
- pushbx = pVBInfo->VGAHDE + 16;
- tempcx = tempcx >> 1;
- tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
- tempcx += tempbx;
-
- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
- tempbx |=
- ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5] & 0xC0) << 2);
- tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
- tempcx &= 0x1F;
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
- temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
- tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
- tempbx += 16;
- tempcx += 16;
- }
-
- if (tempcx > pVBInfo->VGAHT)
- tempcx = pVBInfo->VGAHT;
-
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
- }
-
- tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
- tempbx = pushbx;
- tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
- tempax |= (tempbx & 0xFF00);
- temp = (tempax & 0xFF00) >> 8;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp);
- tempcx = (pVBInfo->VGAVT - 1);
- temp = tempcx & 0x00FF;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
- tempbx = pVBInfo->VGAVDE - 1;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, temp);
- temp = ((tempbx & 0xFF00) << 3) >> 8;
- temp |= ((tempcx & 0xFF00) >> 8);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, temp);
-
- tempax = pVBInfo->VGAVDE;
- tempbx = pVBInfo->VGAVDE;
- tempcx = pVBInfo->VGAVT;
- tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
- tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
-
- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
-
- if (temp & 0x04)
- tempbx |= 0x0100;
-
- if (temp & 0x080)
- tempbx |= 0x0200;
-
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
-
- if (temp & 0x08)
- tempbx |= 0x0400;
-
- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
- tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
- }
-
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
- temp = ((tempbx & 0xFF00) >> 8) << 4;
- temp = ((tempcx & 0x000F) | (temp));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, temp);
- tempax = 0;
-
- if (modeflag & DoubleScanMode)
- tempax |= 0x80;
-
- if (modeflag & HalfDCLK)
- tempax |= 0x40;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLockRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT push1,
- push2, tempax, tempbx = 0, tempcx, temp, resinfo, modeflag, CRT1Index;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- CRT1Index &= IndexMask;
- }
-
- if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
- return;
- }
-
- temp = 0xFF; /* set MAX HT */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
- /* if ( modeflag & Charx8Dot ) tempcx = 0x08 ; */
- /* else */
- tempcx = 0x08;
-
- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
- modeflag |= Charx8Dot;
-
- tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
-
- if (modeflag & HalfDCLK)
- tempax = tempax >> 1;
-
- tempax = (tempax / tempcx) - 1;
- tempbx |= ((tempax & 0x00FF) << 8);
- temp = tempax & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x04, temp);
-
- temp = (tempbx & 0xFF00) >> 8;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (!
- (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)))
- temp += 2;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (pVBInfo->VBType & VB_XGI301LV) {
- if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
- if (resinfo == 7)
- temp -= 2;
- }
- }
- else if (resinfo == 7)
- temp -= 2;
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
-
- if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
- if (pVBInfo->VBInfo & SetCRT2ToTV)
- tempax = pVBInfo->VGAHT;
- else
- tempax = XGI_GetVGAHT2(pVBInfo);
- }
-
- if (tempax >= pVBInfo->VGAHT) {
- tempax = pVBInfo->VGAHT;
- }
-
- if (modeflag & HalfDCLK) {
- tempax = tempax >> 1;
- }
-
- tempax = (tempax / tempcx) - 5;
- tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- temp = (tempbx & 0x00FF) - 1;
- if (!(modeflag & HalfDCLK)) {
- temp -= 6;
- if (pVBInfo->TVInfo & TVSimuMode) {
- temp -= 4;
- if (ModeNo > 0x13)
- temp -= 10;
- }
- }
- }
- else {
- /* tempcx = tempbx & 0x00FF ; */
- tempbx = (tempbx & 0xFF00) >> 8;
- tempcx = (tempcx + tempbx) >> 1;
- temp = (tempcx & 0x00FF) + 2;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- temp -= 1;
- if (!(modeflag & HalfDCLK)) {
- if ((modeflag & Charx8Dot)) {
- temp += 4;
- if (pVBInfo->VGAHDE >= 800) {
- temp -= 6;
- }
- }
- }
- }
- else {
- if (!(modeflag & HalfDCLK)) {
- temp -= 4;
- if (pVBInfo->LCDResInfo != Panel1280x960) {
- if (pVBInfo->VGAHDE >= 800) {
- temp -= 7;
- if (pVBInfo->ModeType == ModeEGA) {
- if (pVBInfo->VGAVDE == 1024) {
- temp += 15;
- if (pVBInfo->LCDResInfo != Panel1280x1024) {
- temp += 7;
- }
- }
- }
-
- if (pVBInfo->VGAHDE >= 1280) {
- if (pVBInfo->LCDResInfo != Panel1280x960) {
- if (!
- (pVBInfo->
- LCDInfo & (LCDNonExpanding |
- EnableScalingLCD))) {
- temp += 28;
- }
- }
- }
- }
- }
- }
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (pVBInfo->TVInfo & TVSimuMode) {
- if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11)
- || (ModeNo == 0x13) || (ModeNo == 0x0F)) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x5b);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
- }
-
- if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
- if (pVBInfo->TVInfo & SetNTSCTV) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x61);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x41);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
- }
- }
-
- if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)) {
- if (pVBInfo->TVInfo & SetNTSCTV) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x54);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x55);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
- }
- }
-
- if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D)
- || (ModeNo == 0x50)) {
- if (pVBInfo->TVInfo & SetNTSCTV) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x30);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2f);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x02);
- }
- }
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
-
- tempbx = pVBInfo->VGAVT;
- push1 = tempbx;
- tempcx = 0x121;
- tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
-
- if (tempbx == 357)
- tempbx = 350;
- if (tempbx == 360)
- tempbx = 350;
- if (tempbx == 375)
- tempbx = 350;
- if (tempbx == 405)
- tempbx = 400;
- if (tempbx == 525)
- tempbx = 480;
-
- push2 = tempbx;
-
- if (pVBInfo->VBInfo & SetCRT2ToLCD) {
- if (pVBInfo->LCDResInfo == Panel1024x768) {
- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
- if (tempbx == 350)
- tempbx += 5;
- if (tempbx == 480)
- tempbx += 5;
- }
- }
- }
- tempbx--;
- temp = tempbx & 0x00FF;
- tempbx--;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
- tempbx = push2;
- tempbx--;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
-
- if (tempbx & 0x0100) {
- tempcx |= 0x0002;
- }
-
- tempax = 0x000B;
-
- if (modeflag & DoubleScanMode) {
- tempax |= 0x08000;
- }
-
- if (tempbx & 0x0200) {
- tempcx |= 0x0040;
- }
-
- temp = (tempax & 0xFF00) >> 8;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
-
- if (tempbx & 0x0400) {
- tempcx |= 0x0600;
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
-
- tempax = push1;
- tempax -= tempbx; /* 0x0C Vertical Retrace Start */
- tempax = tempax >> 2;
- push1 = tempax; /* push ax */
-
- if (resinfo != 0x09) {
- tempax = tempax << 1;
- tempbx += tempax;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (pVBInfo->VBType & VB_XGI301LV) {
- if (pVBInfo->TVInfo & SetYPbPrMode1080i)
- tempbx -= 10;
- else {
- if (pVBInfo->TVInfo & TVSimuMode) {
- if (pVBInfo->TVInfo & SetPALTV) {
- if (pVBInfo->VBType & VB_XGI301LV) {
- if (!
- (pVBInfo->
- TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p
- | SetYPbPrMode1080i)))
- tempbx += 40;
- }
- else
- tempbx += 40;
- }
- }
- }
- }
- else
- tempbx -= 10;
- }
- else {
- if (pVBInfo->TVInfo & TVSimuMode) {
- if (pVBInfo->TVInfo & SetPALTV) {
- if (pVBInfo->VBType & VB_XGI301LV) {
- if (!
- (pVBInfo->
- TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p |
- SetYPbPrMode1080i)))
- tempbx += 40;
- }
- else
- tempbx += 40;
- }
- }
- }
- tempax = push1;
- tempax = tempax >> 2;
- tempax++;
- tempax += tempbx;
- push1 = tempax; /* push ax */
-
- if ((pVBInfo->TVInfo & SetPALTV)) {
- if (tempbx <= 513) {
- if (tempax >= 513) {
- tempbx = 513;
- }
- }
- }
-
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
- tempbx--;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
-
- if (tempbx & 0x0100) {
- tempcx |= 0x0008;
- }
-
- if (tempbx & 0x0200) {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
- }
-
- tempbx++;
-
- if (tempbx & 0x0100) {
- tempcx |= 0x0004;
- }
-
- if (tempbx & 0x0200) {
- tempcx |= 0x0080;
- }
-
- if (tempbx & 0x0400) {
- tempcx |= 0x0C00;
- }
-
- tempbx = push1; /* pop ax */
- temp = tempbx & 0x00FF;
- temp &= 0x0F;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
-
- if (tempbx & 0x0010) {
- tempcx |= 0x2000;
- }
-
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
- temp = (tempcx & 0x0FF00) >> 8;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
- tempax = modeflag;
- temp = (tempax & 0xFF00) >> 8;
-
- temp = (temp >> 1) & 0x09;
-
- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
- temp |= 0x01;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
-
- if (pVBInfo->LCDInfo & LCDRGB18Bit)
- temp = 0x80;
- else
- temp = 0x00;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
-
- return;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT i,
- j,
- tempax,
- tempbx, tempcx, temp, push1, push2, modeflag, resinfo, crt2crtc;
-#ifndef LINUX_XF86
- USHORT temp1, temp3, resindex, xres;
-#endif
-/* XGINew_RY1COE = 0 ,
- XGINew_RY2COE = 0 ,
- XGINew_RY3COE = 0 ,
- XGINew_RY4COE = 0 ,
- XGINew_RY5COE = 0 ,
- XGINew_RY6COE = 0 ,
- XGINew_RY7COE = 0 ;
-*/
-
-#ifndef LINUX_XF86
- UCHAR *PhasePoint;
-#endif
- const UCHAR *TimingPoint;
-
- ULONG longtemp, tempeax, tempebx, temp2, tempecx;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
- crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- tempax = 0;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
- tempax |= 0x0800;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
- tempax |= 0x0400;
-
- if (pVBInfo->VBInfo & SetCRT2ToSCART)
- tempax |= 0x0200;
-
- if (!(pVBInfo->TVInfo & SetPALTV))
- tempax |= 0x1000;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
- tempax |= 0x0100;
-
- if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
- tempax &= 0xfe00;
-
- ErrorF("Part2 0 = %x ",
- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
- ErrorF(" pVBInfo->VBInfo =%x", pVBInfo->VBInfo);
-
- tempax = (tempax & 0xff00) >> 8;
- ErrorF("tempax = %x ", tempax);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0, tempax);
- TimingPoint = pVBInfo->NTSCTiming;
-
- if (pVBInfo->TVInfo & SetPALTV) {
- TimingPoint = pVBInfo->PALTiming;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- TimingPoint = pVBInfo->HiTVExtTiming;
-
- if (pVBInfo->VBInfo & SetInSlaveMode)
- TimingPoint = pVBInfo->HiTVSt2Timing;
-
- if (pVBInfo->SetFlag & TVSimuMode)
- TimingPoint = pVBInfo->HiTVSt1Timing;
-
- if (!(modeflag & Charx8Dot))
- TimingPoint = pVBInfo->HiTVTextTiming;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
- if (pVBInfo->TVInfo & SetYPbPrMode525i)
- TimingPoint = pVBInfo->YPbPr525iTiming;
-
- if (pVBInfo->TVInfo & SetYPbPrMode525p)
- TimingPoint = pVBInfo->YPbPr525pTiming;
-
- if (pVBInfo->TVInfo & SetYPbPrMode750p)
- TimingPoint = pVBInfo->YPbPr750pTiming;
- }
-
- for (i = 0x01, j = 0; i <= 0x2D; i++, j++) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]);
- }
-
- for (i = 0x39; i <= 0x45; i++, j++) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
- }
-
- temp = pVBInfo->NewFlickerMode;
- temp &= 0x80;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xFF, temp);
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
- tempax = 950;
-
- if (pVBInfo->TVInfo & SetPALTV)
- tempax = 520;
- else
- tempax = 440;
-
- if (pVBInfo->VDE <= tempax) {
- tempax -= pVBInfo->VDE;
- tempax = tempax >> 2;
- tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
- push1 = tempax;
- temp = (tempax & 0xFF00) >> 8;
- temp += (USHORT) TimingPoint[0];
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (pVBInfo->
- VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
- SetCRT2ToYPbPr)) {
- tempcx = pVBInfo->VGAHDE;
- if (tempcx >= 1024) {
- temp = 0x17; /* NTSC */
- if (pVBInfo->TVInfo & SetPALTV)
- temp = 0x19; /* PAL */
- }
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
- tempax = push1;
- temp = (tempax & 0xFF00) >> 8;
- temp += TimingPoint[1];
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if ((pVBInfo->
- VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART
- | SetCRT2ToYPbPr))) {
- tempcx = pVBInfo->VGAHDE;
- if (tempcx >= 1024) {
- temp = 0x1D; /* NTSC */
- if (pVBInfo->TVInfo & SetPALTV)
- temp = 0x52; /* PAL */
- }
- }
- }
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, temp);
- }
-
- /* 301b */
- tempcx = pVBInfo->HT;
-
- if (XGI_IsLCDDualLink(pVBInfo))
- tempcx = tempcx >> 1;
-
- tempcx -= 2;
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1B, temp);
-
- temp = (tempcx & 0xFF00) >> 8;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
-
- tempcx = pVBInfo->HT >> 1;
- push1 = tempcx; /* push cx */
- tempcx += 7;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- tempcx -= 4;
- }
-
- temp = tempcx & 0x00FF;
- temp = temp << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x22, 0x0F, temp);
-
- tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
- tempbx += tempcx;
- push2 = tempbx;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x24, temp);
- temp = (tempbx & 0xFF00) >> 8;
- temp = temp << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, 0x0F, temp);
-
- tempbx = push2;
- tempbx = tempbx + 8;
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- tempbx = tempbx - 4;
- tempcx = tempbx;
- }
-
- temp = (tempbx & 0x00FF) << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x29, 0x0F, temp);
-
- j += 2;
- tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x27, temp);
- temp = ((tempcx & 0xFF00) >> 8) << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x28, 0x0F, temp);
-
- tempcx += 8;
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- tempcx -= 4;
- }
-
- temp = tempcx & 0xFF;
- temp = temp << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2A, 0x0F, temp);
-
- tempcx = push1; /* pop cx */
- j += 2;
- temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
- tempcx -= temp;
- temp = tempcx & 0x00FF;
- temp = temp << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2D, 0x0F, temp);
-
- tempcx -= 11;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
- tempax = XGI_GetVGAHT2(pVBInfo);
- tempcx = tempax - 1;
- }
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2E, temp);
-
- tempbx = pVBInfo->VDE;
-
- if (pVBInfo->VGAVDE == 360)
- tempbx = 746;
- if (pVBInfo->VGAVDE == 375)
- tempbx = 746;
- if (pVBInfo->VGAVDE == 405)
- tempbx = 853;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
- if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
- tempbx = tempbx >> 1;
- }
- else
- tempbx = tempbx >> 1;
- }
-
- tempbx -= 2;
- temp = tempbx & 0x00FF;
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (pVBInfo->VBType & VB_XGI301LV) {
- if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (ModeNo == 0x2f)
- temp += 1;
- }
- }
- }
- else {
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (ModeNo == 0x2f)
- temp += 1;
- }
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2F, temp);
-
- temp = (tempcx & 0xFF00) >> 8;
- temp |= ((tempbx & 0xFF00) >> 8) << 6;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
- if (pVBInfo->VBType & VB_XGI301LV) {
- if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
- temp |= 0x10;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
- temp |= 0x20;
- }
- }
- else {
- temp |= 0x10;
- if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
- temp |= 0x20;
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, temp);
-
- if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
- tempbx = pVBInfo->VDE;
- tempcx = tempbx - 2;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
- tempbx = tempbx >> 1;
- }
-
- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
- temp = 0;
- if (tempcx & 0x0400)
- temp |= 0x20;
-
- if (tempbx & 0x0400)
- temp |= 0x40;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, temp);
- }
-
- temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, temp);
- temp = (tempbx - 3) & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x47, temp);
- }
-
- tempbx = tempbx & 0x00FF;
-
- if (!(modeflag & HalfDCLK)) {
- tempcx = pVBInfo->VGAHDE;
- if (tempcx >= pVBInfo->HDE) {
- tempbx |= 0x2000;
- tempax &= 0x00FF;
- }
- }
-
- tempcx = 0x0101;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b */
- if (pVBInfo->VGAHDE >= 1024) {
- tempcx = 0x1920;
- if (pVBInfo->VGAHDE >= 1280) {
- tempcx = 0x1420;
- tempbx = tempbx & 0xDFFF;
- }
- }
- }
-
- if (!(tempbx & 0x2000)) {
- if (modeflag & HalfDCLK) {
- tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
- }
-
- push1 = tempbx;
- tempeax = pVBInfo->VGAHDE;
- tempebx = (tempcx & 0xFF00) >> 8;
- longtemp = tempeax * tempebx;
- tempecx = tempcx & 0x00FF;
- longtemp = longtemp / tempecx;
-
- /* 301b */
- tempecx = 8 * 1024;
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- tempecx = tempecx * 8;
- }
-
- longtemp = longtemp * tempecx;
- tempecx = pVBInfo->HDE;
- temp2 = longtemp % tempecx;
- tempeax = longtemp / tempecx;
- if (temp2 != 0) {
- tempeax += 1;
- }
-
- tempax = (USHORT) tempeax;
-
- /* 301b */
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- tempcx = ((tempax & 0xFF00) >> 5) >> 8;
- }
- /* end 301b */
-
- tempbx = push1;
- tempbx =
- (USHORT) (((tempeax & 0x0000FF00) & 0x1F00) | (tempbx & 0x00FF));
- tempax = (USHORT) (((tempeax & 0x000000FF) << 8) | (tempax & 0x00FF));
- temp = (tempax & 0xFF00) >> 8;
- }
- else {
- temp = (tempax & 0x00FF) >> 8;
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x44, temp);
- temp = (tempbx & 0xFF00) >> 8;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x45, ~0x03F, temp);
- temp = tempcx & 0x00FF;
-
- if (tempbx & 0x2000)
- temp = 0;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
- temp |= 0x18;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, ~0x1F, temp);
- if (pVBInfo->TVInfo & SetPALTV) {
- tempbx = 0x0382;
- tempcx = 0x007e;
- }
- else {
- tempbx = 0x0369;
- tempcx = 0x0061;
- }
-
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4b, temp);
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4c, temp);
-
- temp = ((tempcx & 0xFF00) >> 8) & 0x03;
- temp = temp << 2;
- temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
-
- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
- temp |= 0x10;
-
- if (pVBInfo->TVInfo & SetYPbPrMode525p)
- temp |= 0x20;
-
- if (pVBInfo->TVInfo & SetYPbPrMode750p)
- temp |= 0x60;
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d, temp);
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43); /* 301b change */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, (USHORT) (temp - 3));
-
- if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
- if (pVBInfo->TVInfo & NTSC1024x768) {
- TimingPoint = XGI_NTSC1024AdjTime;
- for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
- TimingPoint[j]);
- }
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, 0x72);
- }
- }
-
- /* [ycchen] 01/14/03 Modify for 301C PALM Support */
- if (pVBInfo->VBType & VB_XGI301C) {
- if (pVBInfo->TVInfo & SetPALMTV)
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x08, 0x08); /* PALM Mode */
- }
-
- if (pVBInfo->TVInfo & SetPALMTV) {
- tempax = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01);
- tempax--;
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, tempax);
-
- /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xEF);
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, 0x00);
- }
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- return;
- }
- ErrorF("5935 Part2 0 = %x ",
- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDRegs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT push1,
- push2,
- pushbx,
- tempax,
- tempbx,
- tempcx, temp, tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
-
- XGI_LCDDesStruct *LCDBDesPtr = NULL;
- XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
-
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- CRT1Index &= IndexMask;
- }
-
- if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
- return;
- }
-
- tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
-
- if (XGI_IsLCDDualLink(pVBInfo))
- tempbx = tempbx >> 1;
-
- tempbx -= 1;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2C, temp);
- temp = (tempbx & 0xFF00) >> 8;
- temp = temp << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2B, 0x0F, temp);
- temp = 0x01;
-
- if (pVBInfo->LCDResInfo == Panel1280x1024) {
- if (pVBInfo->ModeType == ModeEGA) {
- if (pVBInfo->VGAHDE >= 1024) {
- temp = 0x02;
- if (pVBInfo->LCDInfo & LCDVESATiming)
- temp = 0x01;
- }
- }
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, temp);
- tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
- push1 = tempbx;
- tempbx--;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x03, temp);
- temp = ((tempbx & 0xFF00) >> 8) & 0x07;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0C, ~0x07, temp);
-
- tempcx = pVBInfo->VT - 1;
- push2 = tempcx + 1;
- temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x19, temp);
- temp = (tempcx & 0xFF00) >> 8;
- temp = temp << 5;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, temp);
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
-
- /* Customized LCDB Des no add */
- LCDBDesPtr = (XGI_LCDDesStruct *) XGI_GetLcdPtr(5, ModeNo, ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
-
- if (pVBInfo->LCDInfo & EnableScalingLCD) {
- tempbx = pVBInfo->HDE;
- tempcx = pVBInfo->VDE;
- }
- else {
- get_HDE_VDE(pVBInfo, & tempbx, & tempcx);
- }
-
- pushbx = tempbx;
- tempax = pVBInfo->VT;
- pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
- pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
- pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
- pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
- tempbx = pVBInfo->LCDVDES;
- tempcx += tempbx;
-
- if (tempcx >= tempax)
- tempcx -= tempax; /* lcdvdes */
-
- temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x05, temp);
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x06, temp);
- tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
- tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
- tempah = tempch;
- tempah = tempah << 3;
- tempah |= tempbh;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, tempah);
-
- /* getlcdsync() */
- XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
- if (pVBInfo->LCDInfo & EnableScalingLCD) {
- LCDPtr1 =
- (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- tempbx = LCDPtr1->LCDVSync;
- }
- tempcx = tempbx;
- tempax = pVBInfo->VT;
- tempbx = pVBInfo->LCDVRS;
-
- /* if ( SetLCD_Info & EnableScalingLCD ) */
- tempcx += tempbx;
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x04, temp);
- temp = (tempbx & 0xFF00) >> 8;
- temp = temp << 4;
- temp |= (tempcx & 0x000F);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
- tempcx = pushbx;
- tempax = pVBInfo->HT;
- tempbx = pVBInfo->LCDHDES;
- tempbx &= 0x0FFF;
-
- if (XGI_IsLCDDualLink(pVBInfo)) {
- tempax = tempax >> 1;
- tempbx = tempbx >> 1;
- tempcx = tempcx >> 1;
- }
-
- if (pVBInfo->VBType & VB_XGI302LV)
- tempbx += 1;
-
- if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
- tempbx += 1;
-
- tempcx += tempbx;
-
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
- temp = ((tempbx & 0xFF00) >> 8) << 4;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x20, temp);
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
- temp = (tempcx & 0xFF00) >> 8;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, temp);
-
- /* getlcdsync() */
- XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
- if (pVBInfo->LCDInfo & EnableScalingLCD) {
- LCDPtr1 =
- (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
- RefreshRateTableIndex,
- pVBInfo);
- tempax = LCDPtr1->LCDHSync;
- }
- tempcx = tempax;
- tempax = pVBInfo->HT;
- tempbx = pVBInfo->LCDHRS;
- /* if ( SetLCD_Info & EnableScalingLCD) */
- if (XGI_IsLCDDualLink(pVBInfo)) {
- tempax = tempax >> 1;
- tempbx = tempbx >> 1;
- tempcx = tempcx >> 1;
- }
-
- if (pVBInfo->VBType & VB_XGI302LV)
- tempbx += 1;
-
- tempcx += tempbx;
-
- if (tempcx >= tempax)
- tempcx -= tempax;
-
- temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1C, temp);
-
- temp = (tempbx & 0xFF00) >> 8;
- temp = temp << 4;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
- temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x21, temp);
-
- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
- if (pVBInfo->VGAVDE == 525) {
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
- | VB_XGI301C)) {
- temp = 0xC6;
- }
- else
- temp = 0xC4;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, 0xB3);
- }
-
- if (pVBInfo->VGAVDE == 420) {
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
- | VB_XGI301C)) {
- temp = 0x4F;
- }
- else
- temp = 0x4E;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTap4Ptr */
-/* Input : */
-/* Output : di -> Tap4 Reg. Setting Pointer */
-/* Description : */
-/* --------------------------------------------------------------------- */
-const XGI301C_Tap4TimingStruct *
-XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, tempbx, i;
-
- const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
-
- if (tempcx == 0) {
- tempax = pVBInfo->VGAHDE;
- tempbx = pVBInfo->HDE;
- }
- else {
- tempax = pVBInfo->VGAVDE;
- tempbx = pVBInfo->VDE;
- }
-
- if (tempax < tempbx)
- return &EnlargeTap4Timing[0];
- else if (tempax == tempbx)
- return &NoScaleTap4Timing[0]; /* 1:1 */
- else
- Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
-
- if (pVBInfo->TVInfo & SetPALTV)
- Tap4TimingPtr = PALTap4Timing;
-
-
- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
- if (pVBInfo->TVInfo & SetYPbPrMode525i)
- Tap4TimingPtr = YPbPr525iTap4Timing;
- if (pVBInfo->TVInfo & SetYPbPrMode525p)
- Tap4TimingPtr = YPbPr525pTap4Timing;
- if (pVBInfo->TVInfo & SetYPbPrMode750p)
- Tap4TimingPtr = YPbPr750pTap4Timing;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
- Tap4TimingPtr = HiTVTap4Timing;
-
- i = 0;
- while (Tap4TimingPtr[i].DE != 0xFFFF) {
- if (Tap4TimingPtr[i].DE == tempax)
- break;
- i++;
- }
- return &Tap4TimingPtr[i];
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetTap4Regs */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo)
-{
-
-#ifndef LINUX_XF86
- USHORT tempcx;
-#endif
- USHORT i, j;
-
- const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
-
- if (!(pVBInfo->VBType & VB_XGI301C))
- return;
-
-#ifndef Tap4
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
-#else /* Tap4 Setting */
-
- Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
- for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
- Tap4TimingPtr->Reg[j]);
-
- if ((pVBInfo->VBInfo & SetCRT2ToTV)
- && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
- Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
- for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
- Tap4TimingPtr->Reg[j]);
- }
-
- if ((pVBInfo->VBInfo & SetCRT2ToTV)
- && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
- else
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
-#endif
-}
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup3 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT i;
- const UCHAR *tempdi;
- USHORT modeflag;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- }
-
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x00, 0x00);
- if (pVBInfo->TVInfo & SetPALTV) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xF5);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xB7);
- }
-
- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
- return;
- }
-
- if (pVBInfo->TVInfo & SetPALMTV) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x3D, 0xA8);
- }
-
- if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
- || (pVBInfo->VBInfo & SetCRT2ToYPbPr)) {
- if (pVBInfo->TVInfo & SetYPbPrMode525i) {
- return;
- }
- tempdi = pVBInfo->HiTVGroup3Data;
- if (pVBInfo->SetFlag & TVSimuMode) {
- tempdi = pVBInfo->HiTVGroup3Simu;
- if (!(modeflag & Charx8Dot)) {
- tempdi = pVBInfo->HiTVGroup3Text;
- }
- }
-
- if (pVBInfo->TVInfo & SetYPbPrMode525p) {
- tempdi = pVBInfo->Ren525pGroup3;
- }
- if (pVBInfo->TVInfo & SetYPbPrMode750p) {
- tempdi = pVBInfo->Ren750pGroup3;
- }
-
- for (i = 0; i <= 0x3E; i++) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, i, tempdi[i]);
- }
- if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
- if (pVBInfo->TVInfo & SetYPbPrMode525p) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x28, 0x3f);
- }
- }
- }
- return;
-} /* {end of XGI_SetGroup3} */
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup4 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, tempcx, tempbx, modeflag, temp, temp2;
-#ifndef LINUX_XF86
- USHORT push1;
-#endif
-
- ULONG tempebx, tempeax, templong;
-
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
- }
-
- temp = pVBInfo->RVBHCFACT;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x13, temp);
-
- tempbx = pVBInfo->RVBHCMAX;
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x14, temp);
- temp2 = ((tempbx & 0xFF00) >> 8) << 7;
- tempcx = pVBInfo->VGAHT - 1;
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x16, temp);
-
- temp = ((tempcx & 0xFF00) >> 8) << 3;
- temp2 |= temp;
-
- tempcx = pVBInfo->VGAVT - 1;
- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
- tempcx -= 5;
- }
-
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x17, temp);
- temp = temp2 | ((tempcx & 0xFF00) >> 8);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x15, temp);
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, 0x08);
- tempcx = pVBInfo->VBInfo;
- tempbx = pVBInfo->VGAHDE;
-
- if (modeflag & HalfDCLK) {
- tempbx = tempbx >> 1;
- }
-
- if (XGI_IsLCDDualLink(pVBInfo))
- tempbx = tempbx >> 1;
-
- if (tempcx & SetCRT2ToHiVisionTV) {
- temp = 0;
- if (tempbx <= 1024)
- temp = 0xA0;
- if (tempbx == 1280)
- temp = 0xC0;
- }
- else if (tempcx & SetCRT2ToTV) {
- temp = 0xA0;
- if (tempbx <= 800)
- temp = 0x80;
- }
- else {
- temp = 0x80;
- if (pVBInfo->VBInfo & SetCRT2ToLCD) {
- temp = 0;
- if (tempbx > 800)
- temp = 0x60;
- }
- }
-
- if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
- temp = 0x00;
- if (pVBInfo->VGAHDE == 1280)
- temp = 0x40;
- if (pVBInfo->VGAHDE == 1024)
- temp = 0x20;
- }
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
-
- tempebx = pVBInfo->VDE;
-
- if (tempcx & SetCRT2ToHiVisionTV) {
- if (!(temp & 0xE000))
- tempbx = tempbx >> 1;
- }
-
- tempcx = pVBInfo->RVBHRS;
- temp = tempcx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x18, temp);
-
- tempeax = pVBInfo->VGAVDE;
- tempcx |= 0x04000;
-
-
- if (tempeax <= tempebx) {
- tempcx = (tempcx & (~0x4000));
- tempeax = pVBInfo->VGAVDE;
- }
- else {
- tempeax -= tempebx;
- }
-
-
- templong = (tempeax * 256 * 1024) % tempebx;
- tempeax = (tempeax * 256 * 1024) / tempebx;
- tempebx = tempeax;
-
- if (templong != 0) {
- tempebx++;
- }
-
-
- temp = (USHORT) (tempebx & 0x000000FF);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1B, temp);
-
- temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1A, temp);
- tempbx = (USHORT) (tempebx >> 16);
- temp = tempbx & 0x00FF;
- temp = temp << 4;
- temp |= ((tempcx & 0xFF00) >> 8);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x19, temp);
-
- /* 301b */
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- temp = 0x0028;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1C, temp);
- tempax = pVBInfo->VGAHDE;
- if (modeflag & HalfDCLK) {
- tempax = tempax >> 1;
- }
-
- if (XGI_IsLCDDualLink(pVBInfo))
- tempax = tempax >> 1;
-
- /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
- if (pVBInfo->VBInfo & SetCRT2ToLCD) {
- if (tempax > 800)
- tempax -= 800;
- }
- else {
- if (pVBInfo->VGAHDE > 800) {
- if (pVBInfo->VGAHDE == 1024)
- tempax = (tempax * 25 / 32) - 1;
- else
- tempax = (tempax * 20 / 32) - 1;
- }
- }
- tempax -= 1;
-
-/*
- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
- {
- if ( pVBInfo->VBType & VB_XGI301LV )
- {
- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
- {
- if ( pVBInfo->VGAHDE > 800 )
- {
- if ( pVBInfo->VGAHDE == 1024 )
- tempax = ( tempax * 25 / 32 ) - 1 ;
- else
- tempax = ( tempax * 20 / 32 ) - 1 ;
- }
- }
- }
- else
- {
- if ( pVBInfo->VGAHDE > 800 )
- {
- if ( pVBInfo->VGAHDE == 1024 )
- tempax = ( tempax * 25 / 32 ) - 1 ;
- else
- tempax = ( tempax * 20 / 32 ) - 1 ;
- }
- }
- }
-*/
-
- temp = (tempax & 0xFF00) >> 8;
- temp = ((temp & 0x0003) << 4);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, temp);
- temp = (tempax & 0x00FF);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1D, temp);
-
- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
- if (pVBInfo->VGAHDE > 800) {
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, 0x08);
- }
- }
- temp = 0x0036;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (!
- (pVBInfo->
- TVInfo & (NTSC1024x768 | SetYPbPrMode525p | SetYPbPrMode750p
- | SetYPbPrMode1080i))) {
- temp |= 0x0001;
- if ((pVBInfo->VBInfo & SetInSlaveMode)
- && (!(pVBInfo->TVInfo & TVSimuMode)))
- temp &= (~0x0001);
- }
- }
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, 0x00C0,
- temp);
- tempbx = pVBInfo->HT;
- if (XGI_IsLCDDualLink(pVBInfo))
- tempbx = tempbx >> 1;
- tempbx = (tempbx >> 1) - 2;
- temp = ((tempbx & 0x0700) >> 8) << 3;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, 0x00C0,
- temp);
- temp = tempbx & 0x00FF;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x22, temp);
- }
- /* end 301b */
-
- if (pVBInfo->ISXPDOS == 0)
- XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetGroup5 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT Pindex, Pdata;
-
- Pindex = pVBInfo->Part5Port;
- Pdata = pVBInfo->Part5Port + 1;
- if (pVBInfo->ModeType == ModeVGA) {
- if (!
- (pVBInfo->
- VBInfo & (SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag))) {
- XGINew_EnableCRT2(pVBInfo);
- /* LoadDAC2(pVBInfo->Part5Port,ModeNo,ModeIdIndex); */
- }
- }
- return;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLcdPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-const void *
-XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT i, tempdx, tempcx, tempbx, tempal, modeflag, table;
-
- const XGI330_LCDDataTablStruct *tempdi = 0;
-
-
- tempbx = BX;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
- if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x14) {
- tempal = 0x0A;
- }
- else if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0F) {
- tempal = 0x0B;
- }
- }
-
- tempal = tempal & 0x0f;
-
- if (tempbx <= 1) { /* ExpLink */
- if (ModeNo <= 0x13) {
- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
- }
- else {
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- if (ModeNo <= 0x13)
- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
- else
- tempal =
- pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
- }
-
- if (tempbx & 0x01)
- tempal = (tempal >> 4);
-
- tempal = (tempal & 0x0f);
- }
-
- tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
-
- if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
- if ((tempbx == 5) || (tempbx) == 7)
- tempcx = LCDDesDataLen2;
- else if ((tempbx == 3) || (tempbx == 8))
- tempcx = LVDSDesDataLen2;
- }
- /* mov di, word ptr cs:LCDDataList[bx] */
- /* tempdi=pVideoMemory[LCDDataList+tempbx*2]|(pVideoMemory[LCDDataList+tempbx*2+1]<<8); */
-
- switch (tempbx) {
- case 0:
- tempdi = XGI_EPLLCDCRT1Ptr_H;
- break;
- case 1:
- tempdi = XGI_EPLLCDCRT1Ptr_V;
- break;
- case 2:
- tempdi = XGI_EPLLCDDataPtr;
- break;
- case 3:
- tempdi = XGI_EPLLCDDesDataPtr;
- break;
- case 4:
- tempdi = XGI_LCDDataTable;
- break;
- case 5:
- tempdi = XGI_LCDDesDataTable;
- break;
- case 6:
- tempdi = XGI_EPLCHLCDRegPtr;
- break;
- case 7:
- case 8:
- case 9:
- tempdi = 0;
- break;
- default:
- break;
- }
-
- if (tempdi == 0x00) /* OEMUtil */
- return 0;
-
- table = tempbx;
- i = 0;
-
- while (tempdi[i].PANELID != 0xff) {
- tempdx = pVBInfo->LCDResInfo;
- if (tempbx & 0x0080) { /* OEMUtil */
- tempbx &= (~0x0080);
- tempdx = pVBInfo->LCDTypeInfo;
- }
-
- if (pVBInfo->LCDInfo & EnableScalingLCD) {
- if ((pVBInfo->LCDInfo & EnableReduceTiming)
- && (pVBInfo->LCDResInfo == Panel1600x1200)) {
- tempdx = Panel1600x1200_1;
- }
- else {
- tempdx &= (~PanelResInfo);
- }
- }
- if (tempdi[i].PANELID == tempdx) {
- tempbx = tempdi[i].MASK;
- tempdx = pVBInfo->LCDInfo;
-
- if (ModeNo <= 0x13) /* alan 09/10/2003 */
- tempdx |= SetLCDStdMode;
-
- if (modeflag & HalfDCLK)
- tempdx |= SetLCDLowResolution;
-
- tempbx &= tempdx;
- if (tempbx == tempdi[i].CAP)
- break;
- }
- i++;
- }
-
- if (table == 0) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDSCRT11024x768_1_H[tempal];
- break;
- case 1:
- return &XGI_LVDSCRT11024x768_2_H[tempal];
- break;
- case 2:
- return &XGI_LVDSCRT11280x1024_1_H[tempal];
- break;
- case 3:
- return &XGI_LVDSCRT11280x1024_2_H[tempal];
- break;
- case 4:
- return &XGI_LVDSCRT11400x1050_1_H[tempal];
- break;
- case 5:
- return &XGI_LVDSCRT11400x1050_2_H[tempal];
- break;
- case 6:
- return &XGI_LVDSCRT11600x1200_1_H[tempal];
- break;
- case 7:
- return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
- break;
- case 8:
- return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
- break;
- case 9:
- return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
- break;
- case 10:
- return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 1) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDSCRT11024x768_1_V[tempal];
- break;
- case 1:
- return &XGI_LVDSCRT11024x768_2_V[tempal];
- break;
- case 2:
- return &XGI_LVDSCRT11280x1024_1_V[tempal];
- break;
- case 3:
- return &XGI_LVDSCRT11280x1024_2_V[tempal];
- break;
- case 4:
- return &XGI_LVDSCRT11400x1050_1_V[tempal];
- break;
- case 5:
- return &XGI_LVDSCRT11400x1050_2_V[tempal];
- break;
- case 6:
- return &XGI_LVDSCRT11600x1200_1_V[tempal];
- break;
- case 7:
- return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
- break;
- case 8:
- return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
- break;
- case 9:
- return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
- break;
- case 10:
- return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 2) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDS1024x768Data_1[tempal];
- break;
- case 1:
- return &XGI_LVDS1024x768Data_2[tempal];
- break;
- case 2:
- return &XGI_LVDS1280x1024Data_1[tempal];
- break;
- case 3:
- return &XGI_LVDS1280x1024Data_2[tempal];
- break;
- case 4:
- return &XGI_LVDS1400x1050Data_1[tempal];
- break;
- case 5:
- return &XGI_LVDS1400x1050Data_2[tempal];
- break;
- case 6:
- return &XGI_LVDS1600x1200Data_1[tempal];
- break;
- case 7:
- return &XGI_LVDSNoScalingData[tempal];
- break;
- case 8:
- return &XGI_LVDS1024x768Data_1x75[tempal];
- break;
- case 9:
- return &XGI_LVDS1024x768Data_2x75[tempal];
- break;
- case 10:
- return &XGI_LVDS1280x1024Data_1x75[tempal];
- break;
- case 11:
- return &XGI_LVDS1280x1024Data_2x75[tempal];
- break;
- case 12:
- return &XGI_LVDSNoScalingDatax75[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 3) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_LVDS1024x768Des_1[tempal];
- break;
- case 1:
- return &XGI_LVDS1024x768Des_3[tempal];
- break;
- case 2:
- return &XGI_LVDS1024x768Des_2[tempal];
- break;
- case 3:
- return &XGI_LVDS1280x1024Des_1[tempal];
- break;
- case 4:
- return &XGI_LVDS1280x1024Des_2[tempal];
- break;
- case 5:
- return &XGI_LVDS1400x1050Des_1[tempal];
- break;
- case 6:
- return &XGI_LVDS1400x1050Des_2[tempal];
- break;
- case 7:
- return &XGI_LVDS1600x1200Des_1[tempal];
- break;
- case 8:
- return &XGI_LVDSNoScalingDesData[tempal];
- break;
- case 9:
- return &XGI_LVDS1024x768Des_1x75[tempal];
- break;
- case 10:
- return &XGI_LVDS1024x768Des_3x75[tempal];
- break;
- case 11:
- return &XGI_LVDS1024x768Des_2x75[tempal];
- break;
- case 12:
- return &XGI_LVDS1280x1024Des_1x75[tempal];
- break;
- case 13:
- return &XGI_LVDS1280x1024Des_2x75[tempal];
- break;
- case 14:
- return &XGI_LVDSNoScalingDesDatax75[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 4) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_ExtLCD1024x768Data[tempal];
- break;
- case 1:
- return &XGI_StLCD1024x768Data[tempal];
- break;
- case 2:
- return &XGI_CetLCD1024x768Data[tempal];
- break;
- case 3:
- return &XGI_ExtLCD1280x1024Data[tempal];
- break;
- case 4:
- return &XGI_StLCD1280x1024Data[tempal];
- break;
- case 5:
- return &XGI_CetLCD1280x1024Data[tempal];
- break;
- case 6:
- return &XGI_ExtLCD1400x1050Data[tempal];
- break;
- case 7:
- return &XGI_StLCD1400x1050Data[tempal];
- break;
- case 8:
- return &XGI_CetLCD1400x1050Data[tempal];
- break;
- case 9:
- return &XGI_ExtLCD1600x1200Data[tempal];
- break;
- case 10:
- return &XGI_StLCD1600x1200Data[tempal];
- break;
- case 11:
- return &XGI_NoScalingData[tempal];
- break;
- case 12:
- return &XGI_ExtLCD1024x768x75Data[tempal];
- break;
- case 13:
- return &XGI_ExtLCD1024x768x75Data[tempal];
- break;
- case 14:
- return &XGI_CetLCD1024x768x75Data[tempal];
- break;
- case 15:
- return &XGI_ExtLCD1280x1024x75Data[tempal];
- break;
- case 16:
- return &XGI_StLCD1280x1024x75Data[tempal];
- break;
- case 17:
- return &XGI_CetLCD1280x1024x75Data[tempal];
- break;
- case 18:
- return &XGI_NoScalingDatax75[tempal];
- break;
- case 19:
- return &XGI_NoScalingData_1[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 5) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_ExtLCDDes1024x768Data[tempal];
- break;
- case 1:
- return &XGI_StLCDDes1024x768Data[tempal];
- break;
- case 2:
- return &XGI_CetLCDDes1024x768Data[tempal];
- break;
- case 3:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_ExtLCDDLDes1280x1024Data[tempal];
- else
- return &XGI_ExtLCDDes1280x1024Data[tempal];
- break;
- case 4:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_StLCDDLDes1280x1024Data[tempal];
- else
- return &XGI_StLCDDes1280x1024Data[tempal];
- break;
- case 5:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_CetLCDDLDes1280x1024Data[tempal];
- else
- return &XGI_CetLCDDes1280x1024Data[tempal];
- break;
- case 6:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_ExtLCDDLDes1400x1050Data[tempal];
- else
- return &XGI_ExtLCDDes1400x1050Data[tempal];
- break;
- case 7:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_StLCDDLDes1400x1050Data[tempal];
- else
- return &XGI_StLCDDes1400x1050Data[tempal];
- break;
- case 8:
- return &XGI_CetLCDDes1400x1050Data[tempal];
- break;
- case 9:
- return &XGI_CetLCDDes1400x1050Data2[tempal];
- break;
- case 10:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_ExtLCDDLDes1600x1200Data[tempal];
- else
- return &XGI_ExtLCDDes1600x1200Data[tempal];
- break;
- case 11:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_StLCDDLDes1600x1200Data[tempal];
- else
- return &XGI_StLCDDes1600x1200Data[tempal];
- break;
- case 12:
- return &XGI_NoScalingDesData[tempal];
- break;
- case 13:
- return &XGI_ExtLCDDes1024x768x75Data[tempal];
- break;
- case 14:
- return &XGI_StLCDDes1024x768x75Data[tempal];
- break;
- case 15:
- return &XGI_CetLCDDes1024x768x75Data[tempal];
- break;
- case 16:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
- else
- return &XGI_ExtLCDDes1280x1024x75Data[tempal];
- break;
- case 17:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_StLCDDLDes1280x1024x75Data[tempal];
- else
- return &XGI_StLCDDes1280x1024x75Data[tempal];
- break;
- case 18:
- if ((pVBInfo->VBType & VB_XGI301LV)
- || (pVBInfo->VBType & VB_XGI302LV))
- return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
- else
- return &XGI_CetLCDDes1280x1024x75Data[tempal];
- break;
- case 19:
- return &XGI_NoScalingDesDatax75[tempal];
- break;
- case 20:
- return &XGI_NoScalingDesData_1[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 6) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_CH7017LV1024x768[tempal];
- break;
- case 1:
- return &XGI_CH7017LV1400x1050[tempal];
- break;
- default:
- break;
- }
- }
- return 0;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-const void *
-XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT i, tempdx, tempbx, tempal, modeflag, table;
- const XGI330_TVDataTablStruct *tempdi = NULL;
-
- tempbx = BX;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
- }
-
- tempal = tempal & 0x3f;
- table = tempbx;
-
- switch (tempbx) {
- case 0:
- tempdi = 0; /*EPLCHTVCRT1Ptr_H; */
- break;
- case 1:
- tempdi = 0; /*EPLCHTVCRT1Ptr_V; */
- break;
- case 2:
- tempdi = XGI_EPLCHTVDataPtr;
- break;
- case 3:
- tempdi = 0;
- break;
- case 4:
- tempdi = XGI_TVDataTable;
- break;
- case 5:
- tempdi = 0;
- break;
- case 6:
- tempdi = XGI_EPLCHTVRegPtr;
- break;
- default:
- break;
- }
-
- if (tempdi == 0x00) /* OEMUtil */
- return (0);
-
- tempdx = pVBInfo->TVInfo;
-
- if (pVBInfo->VBInfo & SetInSlaveMode)
- tempdx = tempdx | SetTVLockMode;
-
- if (modeflag & HalfDCLK)
- tempdx = tempdx | SetTVLowResolution;
-
- i = 0;
-
- while (tempdi[i].MASK != 0xffff) {
- if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
- break;
- i++;
- }
-
- if (table == 0x04) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_ExtPALData[tempal];
- break;
- case 1:
- return &XGI_ExtNTSCData[tempal];
- break;
- case 2:
- return &XGI_StPALData[tempal];
- break;
- case 3:
- return &XGI_StNTSCData[tempal];
- break;
- case 4:
- return &XGI_ExtHiTVData[tempal];
- break;
- case 5:
- return &XGI_St2HiTVData[tempal];
- break;
- case 6:
- return &XGI_ExtYPbPr525iData[tempal];
- break;
- case 7:
- return &XGI_ExtYPbPr525pData[tempal];
- break;
- case 8:
- return &XGI_ExtYPbPr750pData[tempal];
- break;
- case 9:
- return &XGI_StYPbPr525iData[tempal];
- break;
- case 10:
- return &XGI_StYPbPr525pData[tempal];
- break;
- case 11:
- return &XGI_StYPbPr750pData[tempal];
- break;
- case 12: /* avoid system hang */
- return &XGI_ExtNTSCData[tempal];
- break;
- case 13:
- return &XGI_St1HiTVData[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 0x02) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_CHTVUNTSCData[tempal];
- break;
- case 1:
- return &XGI_CHTVONTSCData[tempal];
- break;
- case 2:
- return &XGI_CHTVUPALData[tempal];
- break;
- case 3:
- return &XGI_CHTVOPALData[tempal];
- break;
- default:
- break;
- }
- }
- else if (table == 0x06) {
- switch (tempdi[i].DATAPTR) {
- case 0:
- return &XGI_CHTVRegUNTSC[tempal];
- break;
- case 1:
- return &XGI_CHTVRegONTSC[tempal];
- break;
- case 2:
- return &XGI_CHTVRegUPAL[tempal];
- break;
- case 3:
- return &XGI_CHTVRegOPAL[tempal];
- break;
- default:
- break;
- }
- }
- return (0);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_BacklightByDrv */
-/* Input : */
-/* Output : TRUE -> Skip backlight control */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR tempah;
-
- tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3A);
- if (tempah & BacklightControlBit)
- return TRUE;
- else
- return FALSE;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_FirePWDDisable */
-/* Input : */
-/* Output : */
-/* Description : Turn off VDD & Backlight : Fire disable procedure */
-/* --------------------------------------------------------------------- */
-/*
-void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
-{
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
-}
-*/
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_FirePWDEnable */
-/* Input : */
-/* Output : */
-/* Description : Turn on VDD & Backlight : Fire enable procedure */
-/* --------------------------------------------------------------------- */
-void
-XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x26, 0x03, 0xFC);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnableGatingCRT */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x40);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisableGatingCRT */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x00);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetPanelDelay */
-/* Input : */
-/* Output : */
-/* Description : */
-/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
-/* : bl : 2 ; T2 : the duration signal on and Vdd on */
-/* : bl : 3 ; T3 : the duration between CPL off and signal off */
-/* : bl : 4 ; T4 : the duration signal off and Vdd off */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT index;
-#ifndef LINUX_XF86
- USHORT temp;
-#endif
-
- index = XGI_GetLCDCapPtr(pVBInfo);
-
- if (tempbl == 1)
- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S1, pVBInfo);
-
- if (tempbl == 2)
- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S2, pVBInfo);
-
- if (tempbl == 3)
- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S3, pVBInfo);
-
- if (tempbl == 4)
- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S4, pVBInfo);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetPanelPower */
-/* Input : */
-/* Output : */
-/* Description : */
-/* I/O : ah = 0011b = 03h ; Backlight on, Power on */
-/* = 0111b = 07h ; Backlight on, Power off */
-/* = 1011b = 0Bh ; Backlight off, Power on */
-/* = 1111b = 0Fh ; Backlight off, Power off */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
-{
- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x26, tempbl,
- tempah);
- else
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x11, tempbl, tempah);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_IsLCDON */
-/* Input : */
-/* Output : FALSE : Skip PSC Control */
-/* TRUE: Disable PSC */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax;
-
- tempax = pVBInfo->VBInfo;
- if (tempax & SetCRT2ToDualEdge)
- return FALSE;
- else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
- return TRUE;
-
- return FALSE;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnablePWD */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT index, temp;
-
- index = XGI_GetLCDCapPtr(pVBInfo);
- temp = pVBInfo->LCDCapList[index].PWD_2B;
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2B, temp);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2C,
- pVBInfo->LCDCapList[index].PWD_2C);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2D,
- pVBInfo->LCDCapList[index].PWD_2D);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2E,
- pVBInfo->LCDCapList[index].PWD_2E);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2F,
- pVBInfo->LCDCapList[index].PWD_2F);
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisablePWD */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisableChISLCD */
-/* Input : */
-/* Output : FALSE -> Not LCD Mode */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, tempah;
-
- tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
- tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
-
- if (tempbx & (EnableChA | DisableChA)) {
- if (!(tempah & 0x08)) /* Chk LCDA Mode */
- return FALSE;
- }
-
- if (!(tempbx & (EnableChB | DisableChB)))
- return FALSE;
-
- if (tempah & 0x01) /* Chk LCDB Mode */
- return TRUE;
-
- return FALSE;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnableChISLCD */
-/* Input : */
-/* Output : 0 -> Not LCD mode */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, tempah;
-
-
- tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
- tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
-
- if (tempbx & (EnableChA | DisableChA)) {
- if (!(tempah & 0x08)) /* Chk LCDA Mode */
- return FALSE;
- }
-
- if (!(tempbx & (EnableChB | DisableChB)))
- return FALSE;
-
- if (tempah & 0x01) /* Chk LCDB Mode */
- return TRUE;
-
- return FALSE;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDCapPtr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo)
-{
- UCHAR tempal, tempah, tempbl, i;
-
- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36);
- tempal = tempah & 0x0F;
- tempah = tempah & 0xF0;
- i = 0;
- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
-
- while (tempbl != 0xFF) {
- if (tempbl & 0x80) { /* OEMUtil */
- tempal = tempah;
- tempbl = tempbl & ~(0x80);
- }
-
- if (tempal == tempbl)
- break;
-
- i++;
-
- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
- }
-
- return i;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDCapPtr1 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempah, tempal, tempbl, i;
-
- tempal = pVBInfo->LCDResInfo;
- tempah = pVBInfo->LCDTypeInfo;
-
- i = 0;
- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
-
- while (tempbl != 0xFF) {
- if ((tempbl & 0x80) && (tempbl != 0x80)) {
- tempal = tempah;
- tempbl &= ~0x80;
- }
-
- if (tempal == tempbl)
- break;
-
- i++;
- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
- }
-
- if (tempbl == 0xFF) {
- pVBInfo->LCDResInfo = Panel1024x768;
- pVBInfo->LCDTypeInfo = 0;
- i = 0;
- }
-
- return i;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetLCDSync */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT Index;
-
- Index = XGI_GetLCDCapPtr(pVBInfo);
- *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
- *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
-
- return;
-}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_EnableBridge */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
-#ifndef LINUX_XF86
- USHORT tempax;
-#endif
- USHORT tempbl, tempah;
-
- if (pVBInfo->SetFlag == Win9xDOSMode) {
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- XGI_DisplayOn(pVBInfo);
- return;
- }
- else /* LVDS or CH7017 */
- return;
- }
-
-
- if (HwDeviceExtension->jChipType < XG40) {
- if (!XGI_DisableChISLCD(pVBInfo)) {
- if ((XGI_EnableChISLCD(pVBInfo))
- || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
- if (pVBInfo->LCDInfo & SetPWDEnable) {
- XGI_EnablePWD(pVBInfo);
- }
- else {
- pVBInfo->LCDInfo &= (~SetPWDEnable);
- if (pVBInfo->
- VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
- tempbl = 0xFD;
- tempah = 0x02;
- }
- else {
- tempbl = 0xFB;
- tempah = 0x00;
- }
-
- XGI_SetPanelPower(tempah, tempbl, pVBInfo);
- XGI_SetPanelDelay(1, pVBInfo);
- }
- }
- }
- } /* Not 340 */
-
-
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (!(pVBInfo->SetFlag & DisableChA)) {
- if (pVBInfo->SetFlag & EnableChA) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
- }
- else {
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
- }
- }
- }
-
- if (!(pVBInfo->SetFlag & DisableChB)) {
- if ((pVBInfo->SetFlag & EnableChB)
- || (pVBInfo->
- VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC)))
- {
- tempah =
- (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
- tempah &= 0xDF;
- if (pVBInfo->VBInfo & SetInSlaveMode) {
- if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
- tempah |= 0x20;
- }
- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, tempah);
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E,
- SR1E_ENABLE_CRT2);
-
-
- tempah =
- (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port,
- 0x2E);
-
- if (!(tempah & 0x80))
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
-
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
- }
- }
-
- if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
- || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, ~0xE0, 0x20); /* shampoo 0129 */
- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
- if (!XGI_DisableChISLCD(pVBInfo)) {
- if (XGI_EnableChISLCD(pVBInfo)
- || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x2A, 0x7F); /* LVDS PLL power on */
- }
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
- }
- }
-
- tempah = 0x00;
-
- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
- tempah = 0xc0;
-
- if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
- tempah = tempah & 0x40;
- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
- tempah = tempah ^ 0xC0;
-
- if (pVBInfo->SetFlag & DisableChB)
- tempah &= 0xBF;
-
- if (pVBInfo->SetFlag & DisableChA)
- tempah &= 0x7F;
-
- if (pVBInfo->SetFlag & EnableChB)
- tempah |= 0x40;
-
- if (pVBInfo->SetFlag & EnableChA)
- tempah |= 0x80;
- }
- }
- }
- }
-
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
-
- if (pVBInfo->SetFlag & Win9xDOSMode) {
- XGI_DisplayOn(pVBInfo);
- return;
- }
-
- if (!(pVBInfo->SetFlag & DisableChA)) {
- XGI_VBLongWait(pVBInfo);
- if (!(pVBInfo->SetFlag & GatingCRT)) {
- XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
- XGI_DisplayOn(pVBInfo);
- XGI_VBLongWait(pVBInfo);
- }
- }
- } /* 301 */
- else { /* LVDS */
-
- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA))
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
-
-
-
- tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E);
- if (!(tempah & 0x80))
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
-
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F);
- XGI_DisplayOn(pVBInfo);
- } /* End of VB */
-
-
- if (HwDeviceExtension->jChipType < XG40) {
- if (!XGI_EnableChISLCD(pVBInfo)) {
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- if (XGI_BacklightByDrv(pVBInfo))
- return;
- }
- else
- return;
- }
-
- if (pVBInfo->LCDInfo & SetPWDEnable) {
- XGI_FirePWDEnable(pVBInfo);
- return;
- }
-
- XGI_SetPanelDelay(2, pVBInfo);
-
- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
- tempah = 0x01;
- tempbl = 0xFE; /* turn on backlght */
- }
- else {
- tempbl = 0xF7;
- tempah = 0x00;
- }
- XGI_SetPanelPower(tempah, tempbl, pVBInfo);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_DisableBridge */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, tempbx, tempah = 0, tempbl = 0;
-
- if (pVBInfo->SetFlag == Win9xDOSMode)
- return;
-
-
- if (HwDeviceExtension->jChipType < XG40) {
- if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
- || (XGI_DisableChISLCD(pVBInfo))) {
- if (!XGI_IsLCDON(pVBInfo)) {
- if (pVBInfo->LCDInfo & SetPWDEnable)
- XGI_EnablePWD(pVBInfo);
- else {
- pVBInfo->LCDInfo &= ~SetPWDEnable;
- XGI_DisablePWD(pVBInfo);
- if (pVBInfo->
- VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
- tempbx = 0xFE; /* not 01h */
- tempax = 0;
- }
- else {
- tempbx = 0xF7; /* not 08h */
- tempax = 0x08;
- }
- XGI_SetPanelPower(tempax, tempbx, pVBInfo);
- XGI_SetPanelDelay(3, pVBInfo);
- }
- } /* end if(!XGI_IsLCDON(pVBInfo)) */
- }
- }
-
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- tempah = 0x3F;
- if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
- tempah = 0x7F; /* Disable Channel A */
- if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
- tempah = 0xBF; /* Disable Channel B */
-
- if (pVBInfo->SetFlag & DisableChB)
- tempah &= 0xBF; /* force to disable Cahnnel */
-
- if (pVBInfo->SetFlag & DisableChA)
- tempah &= 0x7F; /* Force to disable Channel B */
- }
- }
- }
-
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
-
- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
- if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
- || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo)))
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
- }
-
- if ((pVBInfo->SetFlag & DisableChA)
- || (pVBInfo->
- VBInfo & (DisableCRT2Display | SetCRT2ToLCDA |
- SetSimuScanMode))) {
- if (pVBInfo->SetFlag & GatingCRT)
- XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
- XGI_DisplayOff(pVBInfo);
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- if ((pVBInfo->SetFlag & DisableChA)
- || (pVBInfo->VBInfo & SetCRT2ToLCDA))
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
- }
-
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
-
- if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xdf);
-
- if ((pVBInfo->SetFlag & DisableChB)
- || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
- || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
- && (pVBInfo->
- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
-
- if ((pVBInfo->SetFlag & DisableChB)
- || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
- || (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
- || (pVBInfo->
- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
- }
- }
- else { /* {301} */
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
- }
-
- if (pVBInfo->
- VBInfo & (DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode))
- XGI_DisplayOff(pVBInfo);
- }
-
-
-
-
- if (HwDeviceExtension->jChipType < XG40) {
- if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
- || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) {
- if (pVBInfo->LCDInfo & SetPWDEnable) {
- if (pVBInfo->LCDInfo & SetPWDEnable)
- XGI_BacklightByDrv(pVBInfo);
- else {
- XGI_SetPanelDelay(4, pVBInfo);
- if (pVBInfo->VBType & VB_XGI301LV) {
- tempbl = 0xFD;
- tempah = 0x00;
- }
- else {
- tempbl = 0xFB;
- tempah = 0x04;
- }
- }
- }
- XGI_SetPanelPower(tempah, tempbl, pVBInfo);
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVPtrIndex */
-/* Input : */
-/* Output : */
-/* Description : bx 0 : ExtNTSC */
-/* 1 : StNTSC */
-/* 2 : ExtPAL */
-/* 3 : StPAL */
-/* 4 : ExtHiTV */
-/* 5 : StHiTV */
-/* 6 : Ext525i */
-/* 7 : St525i */
-/* 8 : Ext525p */
-/* 9 : St525p */
-/* A : Ext750p */
-/* B : St750p */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx = 0;
-
- if (pVBInfo->TVInfo & SetPALTV)
- tempbx = 2;
- if (pVBInfo->TVInfo & SetYPbPrMode1080i)
- tempbx = 4;
- if (pVBInfo->TVInfo & SetYPbPrMode525i)
- tempbx = 6;
- if (pVBInfo->TVInfo & SetYPbPrMode525p)
- tempbx = 8;
- if (pVBInfo->TVInfo & SetYPbPrMode750p)
- tempbx = 10;
- if (pVBInfo->TVInfo & TVSimuMode)
- tempbx++;
-
- return tempbx;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_OEM310Setting */
-/* Input : */
-/* Output : */
-/* Description : Customized Param. for 301 */
-/* --------------------------------------------------------------------- */
-void
-XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- if (pVBInfo->SetFlag & Win9xDOSMode)
- return;
-
- /* GetPart1IO(); */
- XGI_SetDelayComp(pVBInfo);
-
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
- XGI_SetLCDCap(pVBInfo);
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- /* GetPart2IO() */
- XGI_SetPhaseIncr(pVBInfo);
- XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
- XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
-
- if (pVBInfo->VBType & VB_XGI301)
- XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetDelayComp */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT index;
-
- UCHAR tempah, tempbl, tempbh;
-#ifndef LINUX_XF86
- UCHAR temp;
-#endif
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (pVBInfo->
- VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV |
- SetCRT2ToRAMDAC)) {
- tempbl = 0;
- tempbh = 0;
-
- index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
- tempbl = pVBInfo->XGI_TVDelayList[index];
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
- | VB_XGI301C))
- tempbl = pVBInfo->XGI_TVDelayList2[index];
-
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
- tempbl = tempbl >> 4;
-/*
- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
- tempbl = CRT2Delay1 ; // Get CRT2 Delay
-
- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
- tempbl = CRT2Delay2 ;
-*/
- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
- index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
- tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
- tempbl = tempbh;
- }
-
- tempbl &= 0x0F;
- tempbh &= 0xF0;
- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D);
-
- if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)) { /* Channel B */
- tempah &= 0xF0;
- tempah |= tempbl;
- }
-
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
- tempah &= 0x0F;
- tempah |= tempbh;
- }
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D, tempah);
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDCap */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempcx;
-
- tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
- /* Set 301LV Capability */
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x24,
- (UCHAR) (tempcx & 0x1F));
- }
- /* VB Driving */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D,
- ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
- (USHORT) ((tempcx &
- (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >>
- 8));
- }
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if (pVBInfo->VBInfo & SetCRT2ToLCD)
- XGI_SetLCDCap_B(tempcx, pVBInfo);
- else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
- XGI_SetLCDCap_A(tempcx, pVBInfo);
-
- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
- if (tempcx & EnableSpectrum)
- SetSpectrum(pVBInfo);
- }
- }
- else /* LVDS,CH7017 */
- XGI_SetLCDCap_A(tempcx, pVBInfo);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDCap_A */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT temp;
-
- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
-
- if (temp & LCDRGB18Bit) {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F, (USHORT) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
- }
- else {
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F,
- (USHORT) (0x30 | (tempcx & 0x00C0)));
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
- }
-
-/*
- if ( tempcx & EnableLCD24bpp ) // 24bits
- {
- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x30|(tempcx&0x00C0)) );
- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x00);
- }
- else
- {
- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x20|(tempcx&0x00C0)) );//Enable Dither
- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x80);
- }
-*/
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetLCDCap_B */
-/* Input : cx -> LCD Capability */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
-{
- if (tempcx & EnableLCD24bpp) /* 24bits */
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0,
- (USHORT) (((tempcx & 0x00ff) >> 6) | 0x0c));
- else
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0, (USHORT) (((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : SetSpectrum */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-SetSpectrum(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT index;
-
- index = XGI_GetLCDCapPtr(pVBInfo);
-
- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
- XGI_WaitEndRetrace(pVBInfo->RelIO);
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
- XGI_WaitEndRetrace(pVBInfo->RelIO);
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x31,
- pVBInfo->LCDCapList[index].Spectrum_31);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x32,
- pVBInfo->LCDCapList[index].Spectrum_32);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x33,
- pVBInfo->LCDCapList[index].Spectrum_33);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x34,
- pVBInfo->LCDCapList[index].Spectrum_34);
- XGI_WaitEndRetrace(pVBInfo->RelIO);
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetAntiFlicker */
-/* Input : */
-/* Output : */
-/* Description : Set TV Customized Param. */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, index;
-
- UCHAR tempah;
-
- if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
- return;
-
- tempbx = XGI_GetTVPtrIndex(pVBInfo);
- tempbx &= 0xFE;
-
- if (ModeNo <= 0x13) {
- index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
- }
- else {
- index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
- }
-
- tempbx += index;
- tempah = TVAntiFlickList[tempbx];
- tempah = tempah << 4;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetEdgeEnhance */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, index;
-
- UCHAR tempah;
-
-
- tempbx = XGI_GetTVPtrIndex(pVBInfo);
- tempbx &= 0xFE;
-
- if (ModeNo <= 0x13) {
- index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
- }
- else {
- index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
- }
-
- tempbx += index;
- tempah = TVEdgeList[tempbx];
- tempah = tempah << 5;
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetPhaseIncr */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx;
-
- UCHAR tempcl, tempch;
-
- ULONG tempData;
-
- XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
- tempData = TVPhaseList[tempbx];
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x31,
- (USHORT) (tempData & 0x000000FF));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x32,
- (USHORT) ((tempData & 0x0000FF00) >> 8));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x33,
- (USHORT) ((tempData & 0x00FF0000) >> 16));
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x34,
- (USHORT) ((tempData & 0xFF000000) >> 24));
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetYFilter */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempbx, index;
-
- UCHAR tempcl, tempch, tempal;
- const UCHAR *filterPtr;
-
- XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
-
- switch (tempbx) {
- case 0x00:
- case 0x04:
- filterPtr = NTSCYFilter1;
- break;
-
- case 0x01:
- filterPtr = PALYFilter1;
- break;
-
- case 0x02:
- case 0x05:
- case 0x0D:
- filterPtr = PALMYFilter1;
- break;
-
- case 0x03:
- filterPtr = PALNYFilter1;
- break;
-
- case 0x08:
- case 0x0C:
- filterPtr = NTSCYFilter2;
- break;
-
- case 0x0A:
- filterPtr = PALMYFilter2;
- break;
-
- case 0x0B:
- filterPtr = PALNYFilter2;
- break;
-
- case 0x09:
- filterPtr = PALYFilter2;
- break;
-
- default:
- return;
- }
-
- if (ModeNo <= 0x13)
- tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
- else
- tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
-
- if (tempcl == 0)
- index = tempal * 4;
- else
- index = tempal * 7;
-
- if ((tempcl == 0) && (tempch == 1)) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35, 0);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36, 0);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37, 0);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
- filterPtr[index++]);
- }
- else {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35,
- filterPtr[index++]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36,
- filterPtr[index++]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37,
- filterPtr[index++]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
- filterPtr[index++]);
- }
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x48,
- filterPtr[index++]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x49,
- filterPtr[index++]);
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4A,
- filterPtr[index++]);
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetTVPtrIndex2 */
-/* Input : */
-/* Output : bx 0 : NTSC */
-/* 1 : PAL */
-/* 2 : PALM */
-/* 3 : PALN */
-/* 4 : NTSC1024x768 */
-/* 5 : PAL-M 1024x768 */
-/* 6-7: reserved */
-/* cl 0 : YFilter1 */
-/* 1 : YFilter2 */
-/* ch 0 : 301A */
-/* 1 : 301B/302B/301LV/302LV */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
- PVB_DEVICE_INFO pVBInfo)
-{
- *tempbx = 0;
- *tempcl = 0;
- *tempch = 0;
-
- if (pVBInfo->TVInfo & SetPALTV)
- *tempbx = 1;
-
- if (pVBInfo->TVInfo & SetPALMTV)
- *tempbx = 2;
-
- if (pVBInfo->TVInfo & SetPALNTV)
- *tempbx = 3;
-
- if (pVBInfo->TVInfo & NTSC1024x768) {
- *tempbx = 4;
- if (pVBInfo->TVInfo & SetPALMTV)
- *tempbx = 5;
- }
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- if ((!(pVBInfo->VBInfo & SetInSlaveMode))
- || (pVBInfo->TVInfo & TVSimuMode)) {
- *tempbx += 8;
- *tempcl += 1;
- }
- }
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C))
- *tempch++;
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_SetCRT2ModeRegs */
-/* Input : */
-/* Output : */
-/* Description : Origin code for crt2group */
-/* --------------------------------------------------------------------- */
-void
-XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
- PVB_DEVICE_INFO pVBInfo)
-{
-#ifndef LINUX_XF86
- USHORT i, j;
-#endif
- USHORT tempbl;
- SHORT tempcl;
-
- UCHAR tempah;
-
- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
- tempah = 0;
- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00);
- tempah &= ~0x10; /* BTRAMDAC */
- tempah |= 0x40; /* BTRAM */
-
- if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
- tempah = 0x40; /* BTDRAM */
- if (ModeNo > 0x13) {
- tempcl = pVBInfo->ModeType;
- tempcl -= ModeVGA;
- if (tempcl >= 0) {
- tempah = (0x008 >> tempcl); /* BT Color */
- if (tempah == 0)
- tempah = 1;
- tempah |= 0x040;
- }
- }
- if (pVBInfo->VBInfo & SetInSlaveMode)
- tempah ^= 0x50; /* BTDAC */
- }
- }
-
-/* 0210 shampoo
- if ( pVBInfo->VBInfo & DisableCRT2Display )
- {
- tempah = 0 ;
- }
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , tempah ) ;
- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
- {
- tempcl = pVBInfo->ModeType ;
- if ( ModeNo > 0x13 )
- {
- tempcl -= ModeVGA ;
- if ( ( tempcl > 0 ) || ( tempcl == 0 ) )
- {
- tempah=(0x008>>tempcl) ;
- if ( tempah == 0 )
- tempah = 1 ;
- tempah |= 0x040;
- }
- }
- else
- {
- tempah = 0x040 ;
- }
-
- if ( pVBInfo->VBInfo & SetInSlaveMode )
- {
- tempah = ( tempah ^ 0x050 ) ;
- }
- }
-*/
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah);
- tempah = 0x08;
- tempbl = 0xf0;
-
- if (pVBInfo->VBInfo & DisableCRT2Display)
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
- tempah);
- else {
- tempah = 0x00;
- tempbl = 0xff;
-
- if (pVBInfo->
- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
- SetCRT2ToLCDA)) {
- if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
- && (!(pVBInfo->VBInfo & SetSimuScanMode))) {
- tempbl &= 0xf7;
- tempah |= 0x01;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
- tempbl, tempah);
- }
- else {
- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
- tempbl &= 0xf7;
- tempah |= 0x01;
- }
-
- if (pVBInfo->
- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
- tempbl &= 0xf8;
- tempah = 0x01;
-
- if (!(pVBInfo->VBInfo & SetInSlaveMode))
- tempah |= 0x02;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
- tempah = tempah ^ 0x05;
- if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
- tempah = tempah ^ 0x01;
- }
-
- if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
- tempah |= 0x08;
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
- tempbl, tempah);
- }
- else
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
- tempbl, tempah);
- }
- }
- else
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
- tempah);
- }
-
- if (pVBInfo->
- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
- SetCRT2ToLCDA)) {
- tempah &= (~0x08);
- if ((pVBInfo->ModeType == ModeVGA)
- && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
- tempah |= 0x010;
- }
- tempah |= 0x080;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- /* if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) */
- /* { */
- tempah |= 0x020;
- if (ModeNo > 0x13) {
- if (pVBInfo->VBInfo & DriverMode)
- tempah = tempah ^ 0x20;
- }
- /* } */
- }
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, ~0x0BF,
- tempah);
- tempah = 0;
-
- if (pVBInfo->LCDInfo & SetLCDDualLink)
- tempah |= 0x40;
-
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- /* if ( ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) && ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) ) */
- /* { */
- if (pVBInfo->TVInfo & RPLLDIV2XO)
- tempah |= 0x40;
- /* } */
- }
-
- if ((pVBInfo->LCDResInfo == Panel1280x1024)
- || (pVBInfo->LCDResInfo == Panel1280x1024x75))
- tempah |= 0x80;
-
- if (pVBInfo->LCDResInfo == Panel1280x960)
- tempah |= 0x80;
-
- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0C, tempah);
- }
-
- if (pVBInfo->
- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
- VB_XGI301C)) {
- tempah = 0;
- tempbl = 0xfb;
-
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
- tempbl = 0xff;
- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
- tempah |= 0x04; /* shampoo 0129 */
- }
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x13, tempbl,
- tempah);
- tempah = 0x00;
- tempbl = 0xcf;
- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
- tempah |= 0x30;
- }
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2c, tempbl,
- tempah);
- tempah = 0;
- tempbl = 0x3f;
-
- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
- if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
- tempah |= 0xc0;
- }
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, tempbl,
- tempah);
- }
-
- tempah = 0;
- tempbl = 0x7f;
- if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
- tempbl = 0xff;
- if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
- tempah |= 0x80;
- }
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x23, tempbl, tempah);
-
- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
- if (pVBInfo->LCDInfo & SetLCDDualLink) {
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x20);
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x34, 0x10);
- }
- }
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetRAMDAC2DATA */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, CRT1Index;
-#ifndef LINUX_XF86
- USHORT temp, ResInfo, DisplayType;
-#endif
-
- pVBInfo->RVBHCMAX = 1;
- pVBInfo->RVBHCFACT = 1;
-
- if (ModeNo <= 0x13) {
- const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
- pVBInfo->ModeType,
- ModeNo, ModeIdIndex);
-
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
- tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
- temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
- CRT1Index &= IndexMask;
- temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
- temp2 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
- tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
- tempbx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
- tempcx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
- tempcx &= 0x0100;
- tempcx = tempcx << 2;
- tempbx |= tempcx;
- temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
- }
-
- if (temp1 & 0x01)
- tempbx |= 0x0100;
-
- if (temp1 & 0x20)
- tempbx |= 0x0200;
- tempax += 5;
-
- if (modeflag & Charx8Dot)
- tempax *= 8;
- else
- tempax *= 9;
-
- pVBInfo->VGAHT = tempax;
- pVBInfo->HT = tempax;
- tempbx++;
- pVBInfo->VGAVT = tempbx;
- pVBInfo->VT = tempbx;
-}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetColorDepth */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetColorDepth(USHORT ModeNo, USHORT ModeIdIndex,
- const VB_DEVICE_INFO *pVBInfo)
-{
- USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
- SHORT index;
- USHORT modeflag;
-
- if (ModeNo <= 0x13) {
- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
- }
- else {
- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- }
-
- index = (modeflag & ModeInfoFlag) - ModeEGA;
-
- if (index < 0)
- index = 0;
-
- return (ColorDepth[index]);
-}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_UnLockCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
-
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
-
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_LockCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_LockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGINew_EnableCRT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo)
-{
- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E, SR1E_ENABLE_CRT2);
-}
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
-{
- USHORT i, j;
-
- ULONG temp, flag;
-
- flag = 0;
-
- for (i = 0; i < DelayTime; i++) {
- for (j = 0; j < 66; j++) {
- temp = XGI_GetRegLong((XGIIOADDRESS) 0x61);
- temp &= 0x10;
-
- if (temp == flag)
- continue;
-
- flag = temp;
- }
- }
-}
-
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_BridgeIsOn */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-BOOLEAN
-XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT flag;
-
- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
- if ((flag == 1) || (flag == 2))
- return (1); /* 301b */
- else
- return (0);
-}
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_VBLongWait */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-void
-XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo)
-{
- USHORT tempal, temp, i, j;
-
- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
- temp = 0;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 100; j++) {
- tempal = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
- if (temp & 0x01) { /* VBWaitMode2 */
- if ((tempal & 0x08)) {
- continue;
- }
-
- if (!(tempal & 0x08)) {
- break;
- }
- }
- else { /* VBWaitMode1 */
- if (!(tempal & 0x08)) {
- continue;
- }
-
- if ((tempal & 0x08)) {
- break;
- }
- }
- }
- temp = temp ^ 0x01;
- }
- }
- else {
- XGI_WaitEndRetrace(pVBInfo->RelIO);
- }
- return;
-}
-
-
-
-
-/* --------------------------------------------------------------------- */
-/* Function : XGI_GetVGAHT2 */
-/* Input : */
-/* Output : */
-/* Description : */
-/* --------------------------------------------------------------------- */
-USHORT
-XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo)
-{
- ULONG tempax, tempbx;
-
- tempbx =
- ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) & 0xFFFF;
- tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
- tempax = (tempax * pVBInfo->HT) / tempbx;
-
- return ((USHORT) tempax);
-}
-
-
-/**
- * Get magic index into clock table.
- *
- * \bugs
- * I'm pretty sure the first if-statement is wrong. It will \b always
- * evaluate to true.
- */
-unsigned
-XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
- USHORT RefreshRateTableIndex,
- PVB_DEVICE_INFO pVBInfo)
-{
- unsigned VCLKIndex;
- const unsigned modeflag = (ModeNo <= 0x13)
- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-
-
- if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b */
- VCLKIndex = (pVBInfo->LCDResInfo != Panel1024x768)
- ? (VCLK108_2 + 5) : (VCLK65 + 2);
- }
- else { /* for TV */
- if (pVBInfo->VBInfo & SetCRT2ToTV) {
- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
- VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
- ? HiTVVCLKDIV2 : HiTVVCLK;
-
- VCLKIndex += 25;
-
- if (pVBInfo->SetFlag & TVSimuMode) {
- VCLKIndex = (modeflag & Charx8Dot)
- ? HiTVSimuVCLK : HiTVTextVCLK;
-
- VCLKIndex += 25;
- }
-
- if (pVBInfo->VBType & VB_XGI301LV) {
- switch (pVBInfo->VBExtInfo) {
- case VB_YPbPr1080i:
- /* VCLKIndex already set to correct value? */
- break;
- case VB_YPbPr750p:
- VCLKIndex = YPbPr750pVCLK;
- break;
- case VB_YPbPr525p:
- VCLKIndex = YPbPr525pVCLK;
- break;
- case VB_YPbPr525i:
- VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
- ? YPbPr525iVCLK_2 : YPbPr525iVCLK;
- break;
- }
- }
- }
- else {
- VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
- ? TVVCLKDIV2 : TVVCLK;
-
- VCLKIndex += 25;
- }
- }
- else { /* for CRT2 */
- VCLKIndex = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
- if (ModeNo > 0x13) {
- VCLKIndex =
- (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK
- & IndexMask);
- }
- }
- }
-
- return VCLKIndex;
-}
+/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "osdef.h"
+
+#ifdef LINUX_XF86
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "xgi.h"
+#include "xgi_regs.h"
+#endif
+
+#ifdef LINUX_KERNEL
+#include <asm/io.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include "XGIfb.h"
+#endif
+
+#include "vb_def.h"
+#include "vgatypes.h"
+#include "vb_struct.h"
+#include "vb_table.h"
+#include "vb_setmode.h"
+
+#define IndexMask 0xff
+#ifndef XGI_MASK_DUAL_CHIP
+#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */
+#endif
+
+
+BOOLEAN CheckDualChip(PVB_DEVICE_INFO pVBInfo);
+static BOOLEAN XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo);
+
+BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, USHORT * i,
+ PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetRatePtrCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo);
+static unsigned XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo);
+void XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo);
+void XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+static const void *XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+static const void *XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo);
+void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+void XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo);
+void XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo);
+void XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo);
+void SetDualChipRegs(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
+void XGI_DisplayOn(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
+void XGI_DisplayOff(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+/* Jong 10/03/2007 */
+void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
+void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
+void XGI_UpdateXG21CRTC(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo, USHORT RefreshRateTableIndex);
+
+static void XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo);
+void XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo);
+
+void XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension);
+void XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension);
+void XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+
+void XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_GetVBType(PVB_DEVICE_INFO pVBInfo);
+void XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void InitTo330Pointer(UCHAR, PVB_DEVICE_INFO pVBInfo);
+void XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+void XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
+void SetSpectrum(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
+ PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PVB_DEVICE_INFO pVBInfo);
+void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
+void XGI_LockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
+void XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo);
+void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo);
+void XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+static void XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo);
+static unsigned XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
+ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+static void XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di,
+ PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo);
+USHORT XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo);
+static const XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
+
+/* Jong 10/03/2007 */
+void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
+void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
+UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo);
+UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo);
+void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
+void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
+void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
+UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo );
+
+const uint8_t XGI_MDA_DAC[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
+};
+
+const uint8_t XGI_CGA_DAC[] = {
+ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
+};
+
+const uint8_t XGI_EGA_DAC[] = {
+ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
+ 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
+ 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
+ 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
+ 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
+ 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
+ 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
+ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
+};
+
+const uint8_t XGI_VGA_DAC[] = {
+ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+ 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
+ 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
+ 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
+ 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
+ 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
+ 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
+ 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
+ 0x0B, 0x0C, 0x0D, 0x0F, 0x10
+};
+
+
+/* --------------------------------------------------------------------- */
+/* Function : InitTo330Pointer */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+InitTo330Pointer(UCHAR ChipType, PVB_DEVICE_INFO pVBInfo)
+{
+ pVBInfo->SModeIDTable = XGI330_SModeIDTable;
+ pVBInfo->StandTable = XGI330_StandTable;
+ pVBInfo->EModeIDTable = XGI330_EModeIDTable;
+ pVBInfo->RefIndex = XGI330_RefIndex;
+ pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table;
+
+ /* add for new UNIVGABIOS */
+ /* XGINew_UBLCDDataTable = (XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
+ /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
+
+
+ if (ChipType >= XG40) {
+ (void) memcpy(pVBInfo->MCLKData, XGI340New_MCLKData, sizeof(XGI340New_MCLKData));
+ (void) memcpy(pVBInfo->ECLKData, XGI340_ECLKData, sizeof(XGI340_ECLKData));
+ }
+ else {
+ (void) memcpy(pVBInfo->MCLKData, XGI330New_MCLKData, sizeof(XGI330New_MCLKData));
+ (void) memcpy(pVBInfo->ECLKData, XGI330_ECLKData, sizeof(XGI330_ECLKData));
+ }
+
+ pVBInfo->VCLKData = XGI_VCLKData;
+ pVBInfo->VBVCLKData = XGI_VBVCLKData;
+ pVBInfo->ScreenOffset = XGI330_ScreenOffset;
+ pVBInfo->StResInfo = XGI330_StResInfo;
+ pVBInfo->ModeResInfo = XGI330_ModeResInfo;
+
+ pVBInfo->OutputSelect = XGI330_OutputSelect;
+ pVBInfo->SoftSetting = XGI330_SoftSetting;
+ pVBInfo->SR07 = XGI330_SR07;
+ pVBInfo->LCDResInfo = 0;
+ pVBInfo->LCDTypeInfo = 0;
+ pVBInfo->LCDInfo = 0;
+ pVBInfo->VBInfo = 0;
+ pVBInfo->TVInfo = 0;
+
+
+ (void) memcpy(pVBInfo->SR15, XGI340_SR13, sizeof(XGI340_SR13));
+ (void) memcpy(pVBInfo->CR40, XGI340_CR41, sizeof(XGI340_CR41));
+ (void) memcpy(pVBInfo->SR25, XGI330_SR25, sizeof(XGI330_SR25));
+ pVBInfo->SR31 = XGI330_SR31;
+ pVBInfo->SR32 = XGI330_SR32;
+ (void) memcpy(pVBInfo->CR6B, XGI340_CR6B, sizeof(XGI340_CR6B));
+ if (ChipType == XG45) {
+ (void) memcpy(pVBInfo->XG45CR6E, XGI45_CR6E, sizeof(XGI45_CR6E));
+ (void) memcpy(pVBInfo->XG45CR6F, XGI45_CR6F, sizeof(XGI45_CR6F));
+ }
+ else {
+ (void) memcpy(pVBInfo->CR6E, XGI340_CR6E, sizeof(XGI340_CR6E));
+ (void) memcpy(pVBInfo->CR6F, XGI340_CR6F, sizeof(XGI340_CR6F));
+ }
+ (void) memcpy(pVBInfo->CR89, XGI340_CR89, sizeof(XGI340_CR89));
+ (void) memcpy(pVBInfo->AGPReg, XGI340_AGPReg, sizeof(XGI340_AGPReg));
+ (void) memcpy(pVBInfo->SR16, XGI340_SR16, sizeof(XGI340_SR16));
+ pVBInfo->CRCF = XG40_CRCF;
+ pVBInfo->DRAMTypeDefinition = XG40_DRAMTypeDefinition;
+
+
+ (void) memcpy(pVBInfo->CR49, XGI330_CR49, sizeof(XGI330_CR49));
+ pVBInfo->SR1F = XGI330_SR1F;
+ pVBInfo->SR21 = XGI330_SR21;
+ pVBInfo->SR22 = XGI330_SR22;
+ pVBInfo->SR23 = XGI330_SR23;
+ pVBInfo->SR24 = XGI330_SR24;
+ pVBInfo->SR33 = XGI330_SR33;
+
+
+
+ pVBInfo->CRT2Data_1_2 = XGI330_CRT2Data_1_2;
+ pVBInfo->CRT2Data_4_D = XGI330_CRT2Data_4_D;
+ pVBInfo->CRT2Data_4_E = XGI330_CRT2Data_4_E;
+ pVBInfo->CRT2Data_4_10 = XGI330_CRT2Data_4_10;
+ pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
+ pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
+ pVBInfo->pYCSenseData = &XGI330_YCSenseData;
+ pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
+ pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
+ pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
+
+ pVBInfo->NTSCTiming = XGI330_NTSCTiming;
+ pVBInfo->PALTiming = XGI330_PALTiming;
+ pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
+ pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
+ pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
+ pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
+ pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
+ pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
+ pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
+ pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
+ pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
+ pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
+ pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
+ pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
+
+
+ (void) memcpy(& pVBInfo->TimingH, XGI_TimingH, sizeof(XGI_TimingH));
+ (void) memcpy(& pVBInfo->TimingV, XGI_TimingV, sizeof(XGI_TimingV));
+
+ /* Jong 10/17/2007; merge code */
+ pVBInfo->UpdateCRT1 = (XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table ;
+
+ pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC;
+ pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC;
+ pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL;
+ pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL;
+
+ /* 310 customization related */
+ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
+ pVBInfo->LCDCapList = XGI_LCDDLCapList;
+ else
+ pVBInfo->LCDCapList = XGI_LCDCapList;
+
+ /* Jong 10/03/2007 */
+ if ( ( ChipType == XG21 ) || ( ChipType == XG27 ) )
+ pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList ;
+
+ pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
+ pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
+
+
+ pVBInfo->I2CDefinition = XG40_I2CDefinition;
+
+ /* Jong 10/03/2007 */
+ if (ChipType >= XG20)
+ pVBInfo->CR97 = XG20_CR97;
+
+
+ /* Jong 10/03/2007 */
+ if ( ChipType == XG27 )
+ {
+ /* pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI27New_MCLKData ; */
+ (void) memcpy(pVBInfo->MCLKData, XGI27New_MCLKData, sizeof(XGI27New_MCLKData));
+
+ /* pVBInfo->CR40 = XGI27_cr41 ; */
+ (void) memcpy(pVBInfo->CR40, XGI27_cr41, sizeof(XGI27_cr41));
+
+ pVBInfo->CR97 = XG27_CR97 ;
+ pVBInfo->pSR36 = &XG27_SR36 ;
+ pVBInfo->pCR8F = &XG27_CR8F ;
+ pVBInfo->pCRD0 = XG27_CRD0 ;
+ pVBInfo->pCRDE = XG27_CRDE ;
+ pVBInfo->pSR40 = &XG27_SR40 ;
+ pVBInfo->pSR41 = &XG27_SR41 ;
+ }
+
+ if ( ChipType >= XG20 )
+ {
+ pVBInfo->pDVOSetting = &XG21_DVOSetting ;
+ pVBInfo->pCR2E = &XG21_CR2E ;
+ pVBInfo->pCR2F = &XG21_CR2F ;
+ pVBInfo->pCR46 = &XG21_CR46 ;
+ pVBInfo->pCR47 = &XG21_CR47 ;
+ }
+
+}
+
+
+
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGISetModeNew */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo,
+ USHORT ModeNo)
+{
+#ifndef LINUX_XF86
+ ULONG temp;
+ USHORT KeepLockReg;
+#endif
+ USHORT ModeIdIndex;
+ /* PUCHAR pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
+ USHORT temp_mode_no;
+
+ pVBInfo->IF_DEF_LVDS = 0 ;
+ pVBInfo->IF_DEF_VideoCapture = 1;
+ pVBInfo->IF_DEF_ScaleLCD = 1;
+
+ unsigned vga_info; /* Jong 11/28/2007 */
+
+ /* Jong 10/03/2007 */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ if ( ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
+ {
+ if ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x30 ) & 0x20 )
+ {
+ pVBInfo->IF_DEF_LVDS = 1 ;
+ }
+ }
+ }
+
+ /* Jong 10/03/20007 */
+ if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
+ XGI_GetVBType( pVBInfo ) ;
+
+ /* Jong 10/17/2007; merge code */
+ InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
+
+ if (ModeNo & 0x80) {
+ ModeNo = ModeNo & 0x7F;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
+
+ /* Jong 10/03/2007 */
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
+ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
+
+ /* Jong 10/03/2007 */
+ HwDeviceExtension->SpecialMode = FALSE;
+
+/* Jong 11/27/2007 */
+#if 0 /* can't get pScrn */
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+ vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+#else
+ vga_info = 0x11; /* set default mode 3 */
+#endif
+#endif
+
+ /* Jong 11/28/2007; pVBInfo field is not matching VGAINFO argument */
+ /* if ( !XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, pVBInfo , &ModeNo , &ModeIdIndex) ) */
+ if ( !XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11, &ModeNo , &ModeIdIndex) )
+ {
+ switch (HwDeviceExtension->BPP)
+ {
+ case 8: ModeNo = 0x2E;
+ HwDeviceExtension->SpecialMode = TRUE;
+ break;
+ case 15: ModeNo = 0x43;
+ HwDeviceExtension->SpecialMode = TRUE;
+ break;
+ case 16: ModeNo = 0x44;
+ HwDeviceExtension->SpecialMode = TRUE;
+ break;
+ case 32: ModeNo = 0x62;
+ HwDeviceExtension->SpecialMode = TRUE;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+
+ /* Jong 10/03/2007 */
+ if (HwDeviceExtension->SpecialMode)
+ {
+
+ /* Jong 11/28/2007; pVBInfo field is not matching VGAINFO argument */
+ /* XGI_SearchModeID( pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, pVBInfo, &ModeNo , &ModeIdIndex ) ; */
+ XGI_SearchModeID( pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11, &ModeNo , &ModeIdIndex ) ;
+ if ( !(HwDeviceExtension->SpecifyTiming) )
+ {
+ int i = 0;
+ while ( SpecialModeTiming[i].Horizontal_ACTIVE != 0 )
+ {
+ if ( ( SpecialModeTiming[i].Horizontal_ACTIVE==HwDeviceExtension->Horizontal_ACTIVE ) &&
+ ( (SpecialModeTiming[i].Vertical_ACTIVE<<(SpecialModeTiming[i].Interlace&0x1))==HwDeviceExtension->Vertical_ACTIVE ) )
+ {
+ if ( ( ( SpecialModeTiming[i].FrameRate-HwDeviceExtension->Frequency ) < 2.0 ) ||
+ ( ( SpecialModeTiming[i].FrameRate-HwDeviceExtension->Frequency ) > -2.0 ) )
+ {
+ HwDeviceExtension->Horizontal_FP = SpecialModeTiming[i].Horizontal_FP;
+ HwDeviceExtension->Horizontal_SYNC = SpecialModeTiming[i].Horizontal_SYNC;
+ HwDeviceExtension->Horizontal_BP = SpecialModeTiming[i].Horizontal_BP;
+ HwDeviceExtension->Vertical_FP = SpecialModeTiming[i].Vertical_FP;
+ HwDeviceExtension->Vertical_SYNC = SpecialModeTiming[i].Vertical_SYNC;
+ HwDeviceExtension->Vertical_BP = SpecialModeTiming[i].Vertical_BP;
+ HwDeviceExtension->DCLK = SpecialModeTiming[i].DCLK;
+ HwDeviceExtension->Interlace = SpecialModeTiming[i].Interlace & 0x1;
+ break;
+ }
+ }
+ i++;
+ }
+ if ( SpecialModeTiming[i].Horizontal_ACTIVE == 0 )
+ {
+ return FALSE; /* currently not support */
+ }
+ }
+ }
+ }
+
+ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
+ PDEBUG(ErrorF("XGI_GetVBInfo \n"));
+ XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
+ PDEBUG(ErrorF("XGI_GetTVInfo \n"));
+ XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
+ PDEBUG(ErrorF("XGI_GetLCDInfo \n"));
+ XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
+ PDEBUG(ErrorF("XGI_DisableBridge \n"));
+
+ /* Jong 10/17/2007; merge code */
+ if ( pVBInfo->VBInfo & ( SetSimuScanMode | SwitchToCRT2 ) )
+ {
+ if (HwDeviceExtension->SpecialMode)
+ {
+ return FALSE;
+ }
+ }
+
+ XGI_DisableBridge(HwDeviceExtension, pVBInfo);
+
+
+ if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
+ pVBInfo);
+ }
+ }
+ else {
+ if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
+ pVBInfo);
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
+ pVBInfo);
+ }
+ }
+ }
+
+ PDEBUG(ErrorF(" vb_setmode 474\n")); // yilin
+ if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+ switch (HwDeviceExtension->ujVBChipID) {
+ case VB_CHIP_301:
+ PDEBUG(ErrorF(" vb_setmode 301\n")); //yilin
+ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
+ break;
+
+ case VB_CHIP_302:
+ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
+ break;
+
+ default:
+ break;
+ }
+ }
+ ErrorF("492 Part2 0 = %x ",
+ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+ XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
+ XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212 */
+ XGI_EnableBridge(HwDeviceExtension, pVBInfo);
+ ErrorF("497 Part2 0 = %x ",
+ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+ } /* !XG20 */
+ else
+ {
+ /* Jong 10/04/2007 */
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ if ( !XGI_XG21CheckLVDSMode(ModeNo , ModeIdIndex, pVBInfo) )
+ {
+ return FALSE;
+ }
+ }
+
+ if (ModeNo <= 0x13) {
+ pVBInfo->ModeType =
+ pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag & ModeInfoFlag;
+ }
+ else {
+ pVBInfo->ModeType =
+ pVBInfo->EModeIDTable[ModeIdIndex].
+ Ext_ModeFlag & ModeInfoFlag;
+ }
+
+ pVBInfo->SetFlag = 0;
+ if ( pVBInfo->IF_DEF_CH7007 != 1 )
+ {
+ pVBInfo->VBInfo = DisableCRT2Display;
+ }
+
+ XGI_DisplayOff(HwDeviceExtension,pVBInfo);
+ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ }
+
+/*
+ if ( ModeNo <= 0x13 )
+ {
+ modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
+ }
+ else
+ {
+ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
+ }
+ pVBInfo->ModeType = modeflag&ModeInfoFlag ;
+ pVBInfo->SetFlag = 0x00 ;
+ pVBInfo->VBInfo = DisableCRT2Display ;
+ temp = XGINew_CheckMemorySize( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
+
+ if ( temp == 0 )
+ return( 0 ) ;
+
+ XGI_DisplayOff( HwDeviceExtension,pVBInfo) ;
+ XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
+ XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
+*/
+ ErrorF("Part2 0 = %x ",
+ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+ XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
+
+ /* Jong 10/04/2007 */
+ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
+ XGI_LockCRT2(HwDeviceExtension, pVBInfo);
+
+ return (TRUE);
+}
+
+/* Jong 10/17/2007; merge code */
+void XGI_SetCRTVCLK(PVB_DEVICE_INFO pVBInfo, double dwPixelClock)
+{
+struct factor
+{
+ int sr2b7;
+ int sr2c7;
+ int sr2c6;
+ int sr2c5;
+ int dividend ;
+ int divisor ;
+};
+
+struct factor kind[16]=
+{
+ {0,0,0,0,1,1},
+ {0,0,0,1,1,2},
+ {0,0,1,0,1,3},
+ {0,0,1,1,1,4},
+ {1,0,0,0,2,1},
+ {1,0,0,1,2,2},
+ {1,0,1,0,2,3},
+ {1,0,1,1,2,4},
+ {0,1,0,0,1,1},
+ {0,1,0,1,1,4},
+ {0,1,1,0,1,6},
+ {0,1,1,1,1,8},
+ {1,1,0,0,2,1},
+ {1,1,0,1,2,4},
+ {1,1,1,0,2,6},
+ {1,1,1,1,2,8}
+};
+ int ii,jj,kk,ll,sr2b,sr2c,Numerator,DeNumerator;
+ double factor1,tempclock,vclk,temp1,min,clock;
+
+
+ vclk=(double)dwPixelClock;
+ min=99.0;
+ for(ii=2;ii<=31;ii++) /* (DeNumerator1)It's value must >=2 */
+ {
+ for(jj=0;jj<=127;jj++) /* (Numerator1) */
+ {
+
+ for(kk=0;kk<=15;kk++)
+ {
+ tempclock=14.318*kind[kk].dividend*(jj+1)/(ii+1);
+ if ( (tempclock >= 150 ) && ( tempclock <= 380) )
+ {
+ tempclock = tempclock / kind[kk].divisor ;
+ temp1=fabs(vclk-tempclock);
+ if(temp1<min)
+ {
+ clock=tempclock;
+ DeNumerator=ii;
+ Numerator=jj;
+ min=temp1;
+ factor1=(double) (kind[kk].dividend / kind[kk].divisor);
+ ll=kk;
+ }
+ }
+ }
+ }
+ }
+ sr2b=128*kind[ll].sr2b7+Numerator;
+ sr2c=128*kind[ll].sr2c7+64*kind[ll].sr2c6+32*kind[ll].sr2c5+DeNumerator;
+
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , (unsigned char) sr2b) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , (unsigned char) sr2c) ;
+}
+
+/* Jong 10/17/2007; merge code */
+void XGI_SetCRTTiming(
+ PXGI_HW_DEVICE_INFO pXGIHWDE,
+ PVB_DEVICE_INFO pVBInfo
+ )
+{
+ int HT, VT, HDE, VDE, HRS, VRS, HRE, VRE, VGAHDE, VGAVDE, VGAHT, VGAVT;
+ int HorizontalActivePixel, HorizontalFrontPorch, HorizontalSyncWidth, HorizontalBackPorch;
+ int VerticalActivePixel, VerticalFrontPorch, VerticalSyncWidth, VerticalBackPorch;
+ int temp1;
+ UCHAR temp;
+
+ HorizontalActivePixel = pXGIHWDE->Horizontal_ACTIVE;
+ HorizontalFrontPorch = pXGIHWDE->Horizontal_FP;
+ HorizontalSyncWidth = pXGIHWDE->Horizontal_SYNC;
+ HorizontalBackPorch = pXGIHWDE->Horizontal_BP;
+ VerticalActivePixel = pXGIHWDE->Vertical_ACTIVE >> (pXGIHWDE->Interlace & 0x1);
+ VerticalFrontPorch = pXGIHWDE->Vertical_FP;
+ VerticalSyncWidth = pXGIHWDE->Vertical_SYNC;
+ VerticalBackPorch = pXGIHWDE->Vertical_BP;
+
+ HT = HorizontalActivePixel + HorizontalFrontPorch + HorizontalSyncWidth + HorizontalBackPorch;
+ HDE = HorizontalActivePixel;
+ HRS = HorizontalActivePixel + HorizontalFrontPorch;
+ HRE = HorizontalActivePixel + HorizontalFrontPorch + HorizontalSyncWidth;
+ HT = HT / 8;
+ HDE = HDE / 8;
+ HRS = HRS / 8;
+ HRE = HRE / 8;
+ VGAHT = HT - 5;
+ VGAHDE = HDE - 1;
+ HDE = HDE - 1;
+ HT = HT - 1;
+ HRS = HRS + 3;
+ HRE = HRE + 3;
+
+ /*
+ HRS = HRS + 2;
+ HRE = HRE + 2;
+ */
+
+ VT = VerticalActivePixel + VerticalFrontPorch + VerticalSyncWidth + VerticalBackPorch;
+ VDE = VerticalActivePixel;
+ VRS = VerticalActivePixel + VerticalFrontPorch;
+ VRE = VerticalActivePixel + VerticalFrontPorch + VerticalSyncWidth;
+ VGAVT = VT - 2;
+ VGAVDE = VDE - 1;
+ VRS = VRS - 1;
+ VRE = VRE - 1;
+ VDE = VDE - 1;
+ VT = VT - 1;
+
+
+ temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x06 ) ;
+ temp = ((temp & 0x1c ) >> 2) * 8;
+ if (temp == 0)
+ temp = 8;
+ temp1 = HorizontalActivePixel * temp / 8;
+ temp1 = temp1 / 8;
+ temp = temp1 / 8 + 1;
+
+ if (pXGIHWDE->Interlace)
+ {
+ temp1 = temp1 << 1;
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x00, 0x86);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x7f, 0x00);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x00, 0x00, (VGAHT & 0xff)); /* HT */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x01, 0x00, (VGAHDE & 0xff)); /* HDEE */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x02, 0x00, (HDE & 0xff)); /* HBS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x03, 0xe0, (HT & 0x1f)); /* HBE */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x04, 0x00, (HRS & 0xff)); /* HRS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x05, 0x60, (((HT & 0x20) << 2) | (HRE & 0x1f))); /* HRE */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x06, 0x00, (VGAVT & 0xff)); /* VT */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, 0x00, (((VRS & 0x0200) >> 2) | ((VDE & 0x0200) >> 3) | ((VGAVT & 0x0200) >> 4)| ((VGAVDE & 0x0100) >> 5) | ((VRS & 0x0100) >> 6) | ((VDE & 0x0100) >> 7) | ((VGAVT & 0x0100) >> 8)));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x09, 0xdf, ((VGAVDE & 0x0200) >> 4));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x10, 0x00, (VRS & 0xff)); /* VRS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0xf0, (VRE & 0x0f)); /* VRE */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x12, 0x00, (VDE & 0xff)); /* VDEE */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x13, 0x00, (temp1 & 0xff));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x15, 0x00, (VGAVDE & 0xff)); /* VBS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x16, 0x00, (VT & 0xff)); /* VBE */
+
+ if ( pXGIHWDE->jChipType == XG21 )
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, 0x00, ((HRS-1) & 0xff)); /* HRS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, 0x00, (((HRE-1) & 0x3f)<<2) | (((HRS-1) & 0x0300) >> 8)); /* HRS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x33, 0xFE, (((VRS) & 0x01))); /* VRS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x34, 0x00, (((VRS) & 0x01FE)>>1)); /* VRS */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x3F, 0x00, (((VRS) & 0x0600)>>9) | (((VRE) & 0x003F)<<2 )); /* VRS */
+
+ }
+ if ( pXGIHWDE->jChipType == XG27 )
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, 0x00, ((HRS-1) & 0xff)); /* HRS SR2E[7:0] */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, 0x00, (((HRE-1) & 0x3f)<<2) | (((HRS-1) & 0x0300) >> 8)); /* HRE SR2F[7:2] HRS SR2F[1:0] */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x34, 0x00, ((VRS) & 0x0FF) ); /* VRS SR34[7:0] */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x35, 0xF8, (((VRS) & 0x0700)>>8)); /* VRS SR35[2:0] */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x3F, 0xFC, (((VRE) & 0x003F)<<2 )); /* VRE SR3F[7:2] */
+
+ }
+ if (VerticalActivePixel > 1024)
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0f, 0xf7, 0x08);
+ }
+ else
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, 0xef, ((VGAVDE & 0x0100) >> 4));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x09, 0xbf, ((VGAVDE & 0x0200) >> 3));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x18, 0x00, (VGAVDE & 0x0ff));
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0xff, 0x80);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0a, 0xc0, (((VRE & 0x10) << 1) | ((VT & 0x0100) >> 4) | ((VRS & 0x0400) >> 7) | ((VGAVDE & 0x0400) >> 8) | ((VDE & 0x0400) >> 9) | ((VGAVT & 0x0400) >> 10)));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0b, 0x00, (((VGAHT & 0xff00) >> 8) | ((VGAHDE & 0xff00) >> 6) | ((HDE & 0xff00) >> 4) | ((HRS & 0xff00) >> 2)));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0c, 0xf8, (((HRE & 0x20) >> 3) | ((HT & 0xc0) >> 6)));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, 0xf0, ((temp1 & 0xff00) >> 8));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x10, 0x00, temp);
+
+
+
+ XGI_SetCRTVCLK (pVBInfo, pXGIHWDE->DCLK);
+
+ if (pXGIHWDE->BPP==0x20)
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0xE0, 0x0f);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF, 0x0);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, 0xE3, 0x10);
+ temp = ((pXGIHWDE->Horizontal_ACTIVE / 8 * pXGIHWDE->BPP) / 64) + 1;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, temp);
+ }
+ if (pXGIHWDE->BPP==0x10)
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0xE0, 0x0f);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF, 0x0);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, 0xE3, 0x08);
+ temp = ((pXGIHWDE->Horizontal_ACTIVE / 8 * pXGIHWDE->BPP) / 64) + 1;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, temp);
+ }
+ if (pXGIHWDE->BPP==0x8)
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, 0xE3, 0x00);
+ temp = ((pXGIHWDE->Horizontal_ACTIVE / 8 * pXGIHWDE->BPP) / 64) + 1;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, temp);
+ }
+
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1Group */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
+ pVBInfo->ModeType,
+ ModeNo, ModeIdIndex);
+ USHORT RefreshRateTableIndex;
+ USHORT b3CC;
+ USHORT temp;
+
+ USHORT XGINew_P3cc = pVBInfo->P3cc;
+#ifndef LINUX_XF86
+ USHORT XGINew_P3c2 = pVBInfo->P3c2;
+#endif
+
+ /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
+ XGI_SetSeqRegs(StandTableIndex, pVBInfo);
+ XGI_SetMiscRegs(StandTableIndex, pVBInfo);
+ XGI_SetCRTCRegs(StandTableIndex, pVBInfo);
+ XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
+ XGI_SetGRCRegs(StandTableIndex, pVBInfo);
+ XGI_ClearExt1Regs(ModeNo, pVBInfo);
+
+ /* Jong 10/19/2007; merge code */
+ /* Jong 04/23/2008; All XG20,21,27 should do this */
+ /* if ( HwDeviceExtension->jChipType == XG27 ) */
+ if ( HwDeviceExtension->jChipType >= XG20 )
+ {
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ XGI_SetDefaultVCLK( pVBInfo ) ;
+ }
+ }
+
+ temp = ~ProgrammingCRT2;
+ pVBInfo->SetFlag &= temp;
+ pVBInfo->SelectCRT2Rate = 0;
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->
+ VBInfo & (SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode)) {
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ }
+ }
+
+ /* Jong 10/05/2007; merge code */
+ /* RefreshRateTableIndex = XGI_GetRatePtrCRT2( ModeNo, ModeIdIndex, pVBInfo); */
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+
+ if (RefreshRateTableIndex != 0xFFFF) {
+ XGI_SetSync(RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo,
+ HwDeviceExtension);
+ XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ }
+
+ /* Jong 10/04/2007; merge code */
+ /* if (HwDeviceExtension->jChipType == XG20) { */
+ if ( ( HwDeviceExtension->jChipType >= XG20 ) &&
+ ( HwDeviceExtension->jChipType < XG27 ) ) /* fix H/W DCLK/2 bug */
+ {
+ if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x4E);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE9);
+ b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
+ XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
+ }
+ else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE3);
+ b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
+ XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
+ }
+ }
+
+ /* Jong 10/04/2007; merge code */
+ if ( HwDeviceExtension->jChipType >= XG21 )
+ {
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
+ if ( temp & 0xA0 )
+ {
+
+ /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ;*/ /* Enable write GPIOF */
+ /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x48 , ~0x20 ) ;*/ /* P. DWN */
+ /* XG21 CRT1 Timing */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ XGI_SetXG27CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
+ else
+ XGI_SetXG21CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
+
+ XGI_UpdateXG21CRTC( ModeNo , pVBInfo , RefreshRateTableIndex) ;
+
+ if ( HwDeviceExtension->jChipType == XG27 )
+ XGI_SetXG27LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
+ else
+ XGI_SetXG21LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
+
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ if ( HwDeviceExtension->jChipType == XG27 )
+ XGI_SetXG27LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
+ else
+ XGI_SetXG21LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
+ }
+ /*XGINew_SetRegOR( pVBInfo->P3d4 , 0x48 , 0x20 ) ;*/ /* P. ON */
+ }
+ }
+
+ /* Jong 10/04/2007; merge code */
+ if ( HwDeviceExtension->SpecialMode )
+ {
+ XGI_SetCRTTiming( HwDeviceExtension, pVBInfo );
+ }
+
+ pVBInfo->SetFlag &= (~ProgrammingCRT2);
+ XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
+ XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+
+ if (HwDeviceExtension->jChipType == XG40) { /* Copy reg settings to 2nd chip */
+ if (CheckDualChip(pVBInfo))
+ SetDualChipRegs(HwDeviceExtension, pVBInfo);
+ }
+
+ /* XGI_LoadCharacter(); //dif ifdef TVFont */
+
+ XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetSeqRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetSeqRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+{
+ unsigned SRdata;
+ unsigned i;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
+ SRdata = pVBInfo->StandTable[StandTableIndex].SR[0];
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ SRdata |= 0x01;
+ }
+ else {
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ SRdata |= 0x01;
+ }
+ }
+
+ SRdata |= 0x20; /* screen off */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SRdata); /* Set SR1 */
+
+ /* Get SR2, SR3, and SR4 from table and set in hardware.
+ */
+ for (i = 2; i <= 4; i++) {
+ SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, SRdata);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetMiscRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetMiscRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+{
+ UCHAR Miscdata;
+
+ Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
+/*
+ if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
+ {
+ if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
+ {
+ Miscdata |= 0x0C ;
+ }
+ }
+*/
+
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRTCRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRTCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+{
+ unsigned i;
+
+ /* Unlock CRTC */
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x7f);
+
+ for (i = 0; i <= 0x18; i++) {
+ /* Get CRTC from file */
+ const unsigned CRTCdata =
+ pVBInfo->StandTable[StandTableIndex].CRTC[i];
+
+ /* Set CRTC( 3d4 ) */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, i, CRTCdata);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetATTRegs(unsigned ModeNo, unsigned StandTableIndex, unsigned ModeIdIndex,
+ const VB_DEVICE_INFO *pVBInfo)
+{
+ unsigned i;
+ const unsigned modeflag = (ModeNo <= 0x13)
+ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ for (i = 0; i <= 0x13; i++) {
+ UCHAR ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
+
+ if (modeflag & Charx8Dot) { /* ifndef Dot9 */
+ if (i == 0x13) {
+ /* Pixel shift. If screen on LCD or TV is shifted left or
+ * right, this might be the cause.
+ */
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ ARdata = 0;
+ else {
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ ARdata = 0;
+ }
+ }
+ }
+ }
+
+ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, i); /* set index */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, ARdata); /* set data */
+ }
+
+ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x14); /* set index */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x00); /* set data */
+
+ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* Enable Attribute */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x20);
+ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetGRCRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetGRCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+{
+ unsigned i;
+
+ for (i = 0; i <= 8; i++) {
+ /* Get GR from file and set GR (3ce)
+ */
+ const unsigned GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3ce, i, GRdata);
+ }
+
+ if (pVBInfo->ModeType > ModeVGA) {
+ /* 256 color disable */
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_ClearExt1Regs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_ClearExt1Regs(unsigned ModeNo, const VB_DEVICE_INFO *pVBInfo)
+{
+ unsigned i;
+
+ /* Clear SR0A-SR0E */
+ for (i = 0x0A; i <= 0x0E; i++) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, 0x00);
+ }
+
+ /* This code came from the old XGI_New_ClearExt1Regs in init.c. Since
+ * it wasn't included in the newer code drop from XGI, I'm not sure if
+ * it's necessary on the Volari chips. I've included it here, ifdefed
+ * out, for future reference.
+ * - idr
+ */
+#if 0
+ XGI_SetRegAND(pVBInfo->P3c4, 0x37, 0xFE);
+ if ((ModeNo == 0x06) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
+ XGI_SetReg(pVBInfo->P3c4, 0x0e, 0x20);
+ }
+#else
+ (void) ModeNo;
+#endif
+}
+
+/* Jong 10/17/2007; merge code */
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetDefaultVCLK */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo )
+{
+ /* Jong 04/22/2008; XGINew_ -> XGI_*/
+ /* Jong 04/23/2008; coding error: VCLKData[0]-> 0x10:25MHz; VCLKData[1]-> 0x20:28MHz */
+ /* XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ; */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x10 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 0 ].SR2B ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 0 ].SR2C ) ;
+
+ /* XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x10 ) ; */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 1 ].SR2B ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 1 ].SR2C ) ;
+
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 ) ;
+ return( 0 ) ;
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetRatePtrCRT2 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetRatePtrCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 }
+ , LCDARefreshIndex[] = {
+ 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01};
+
+ USHORT RefreshRateTableIndex, i, modeflag, index, temp;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ if (ModeNo < 0x14)
+ return (0xFFFF);
+
+ index = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
+ index = index >> pVBInfo->SelectCRT2Rate;
+ index &= 0x0F;
+
+ if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD))
+ index = 0;
+
+ if (index > 0)
+ index--;
+
+ if (pVBInfo->SetFlag & ProgrammingCRT2) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+
+ /* Jong 10/03/2007; merge code */
+ if( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C))
+ temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x0F]; /* 301b */
+ else
+ temp = LCDRefreshIndex[pVBInfo->LCDResInfo & 0x0F];
+
+ if (index > temp) {
+ index = temp;
+ }
+ }
+ else
+ {
+ index = 0 ;
+ }
+ }
+ }
+
+ RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
+ ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
+
+ /* Jong 10/03/2007; merge code */
+ /* Do the similiar adjustment like XGISearchCRT1Rate() */
+ if ( HwDeviceExtension->jChipType >= XG20 ) /* for XG20, XG21, XG27 */
+ {
+ /*
+ if ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag & XG2xNotSupport )
+ {
+ index++;
+ }
+ */
+
+ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 800 ) &&
+ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 600 ) )
+ {
+ index++;
+ }
+ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1024 ) &&
+ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 768 ) )
+ {
+ index++;
+ }
+ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1280 ) &&
+ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 1024 ) )
+ {
+ index++;
+ }
+
+ /* Jong 11/29/2007; fix bugs of 1600x1200; set limitation to 60Hz */
+ /* It should need to check refresh rate supporting of output device */
+ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1600 ) &&
+ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 1200 ) )
+ {
+ index=0;
+ }
+ }
+
+ /* Jong 11/29/2007; according to CR33(index) to update refresh table index */
+ i = 0 ;
+ do
+ {
+ if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
+ break;
+ temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+ temp &= ModeInfoFlag;
+ if (temp < pVBInfo->ModeType)
+ break;
+
+ i++;
+ index--;
+
+ } while (index != 0xFFFF);
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ temp =
+ pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+ if (temp & InterlaceMode) {
+ i++;
+ }
+ }
+ }
+
+ i--;
+ if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
+ temp =
+ XGI_AjustCRT2Rate(ModeNo, ModeIdIndex, RefreshRateTableIndex, &i,
+ pVBInfo);
+ }
+
+ return (RefreshRateTableIndex + i); /*return(0x01|(temp1<<1)); */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_AjustCRT2Rate */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, USHORT * i,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, tempbx, resinfo, modeflag, infoflag;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+ tempax = 0;
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempax |= SupportRAMDAC2;
+
+ if (pVBInfo->VBType & VB_XGI301C)
+ tempax |= SupportCRT2in301C;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
+ tempax |= SupportLCD;
+
+ if (pVBInfo->LCDResInfo != Panel1280x1024) {
+ if (pVBInfo->LCDResInfo != Panel1280x960) {
+ if (pVBInfo->LCDInfo & LCDNonExpanding) {
+ if (resinfo >= 9) {
+ tempax = 0;
+ return (0);
+ }
+ }
+ }
+ }
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
+ tempax |= SupportYPbPr;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (resinfo == 4)
+ return (0);
+
+ if (resinfo == 3)
+ return (0);
+
+ if (resinfo > 7)
+ return (0);
+ }
+ }
+ else {
+ tempax |= SupportHiVisionTV;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (resinfo == 4)
+ return (0);
+
+ if (resinfo == 3) {
+ if (pVBInfo->SetFlag & TVSimuMode)
+ return (0);
+ }
+
+ if (resinfo > 7)
+ return (0);
+ }
+ }
+ }
+ else {
+ if (pVBInfo->
+ VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
+ SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
+ tempax |= SupportTV;
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C)) {
+ tempax |= SupportTV1024;
+ }
+
+ if (!(pVBInfo->VBInfo & SetPALTV)) {
+ if (modeflag & NoSupportSimuTV) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!(pVBInfo->VBInfo & SetNotSimuMode)) {
+ return (0);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else /* for LVDS */
+ {
+ if ( pVBInfo->VBInfo & SetCRT2ToLCD )
+ {
+ tempax |= SupportLCD ;
+
+ if ( resinfo > 0x08 )
+ return( 0 ) ; /* 1024x768 */
+
+ if ( pVBInfo->LCDResInfo < Panel1024x768 )
+ {
+ if ( resinfo > 0x07 )
+ return( 0 ) ; /* 800x600 */
+
+ if ( resinfo == 0x04 )
+ return( 0 ) ; /* 512x384 */
+ }
+ }
+ }
+
+ for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx;
+ (*i)--) {
+ infoflag =
+ pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+ if (infoflag & tempax) {
+ return (1);
+ }
+ if ((*i) == 0)
+ break;
+ }
+
+ for ((*i) = 0;; (*i)++) {
+ infoflag =
+ pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+ if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+ return (0);
+ }
+
+ if (infoflag & tempax) {
+ return (1);
+ }
+ }
+ return (1);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetSync */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetSync(unsigned RefreshRateTableIndex, const VB_DEVICE_INFO *pVBInfo)
+{
+ const unsigned sync =
+ (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8) & 0xC0;
+
+ /* Set Misc(3c2) */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, sync | 0x2F);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1CRTC */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR index, data;
+#ifndef LINUX_XF86
+ USHORT temp, tempah, j, modeflag, ResInfo, DisplayType;
+#endif
+ USHORT i;
+
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
+ index = index & IndexMask;
+
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH.data[i] =
+ pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
+
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV.data[i] =
+ pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
+
+ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+
+
+
+ XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+
+
+ if (pVBInfo->ModeType > 0x03)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0x4F);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1Timing_H */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension)
+{
+ UCHAR data, data1, pushax;
+ USHORT i, j;
+
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
+ /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
+
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
+ data &= 0x7F;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data);
+
+ data = pVBInfo->TimingH.data[0];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0, data);
+
+ for (i = 0x01; i <= 0x04; i++) {
+ data = pVBInfo->TimingH.data[i];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 1), data);
+ }
+
+ for (i = 0x05; i <= 0x06; i++) {
+ data = pVBInfo->TimingH.data[i];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i + 6), data);
+ }
+
+ j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
+ j &= 0x1F;
+ data = pVBInfo->TimingH.data[7];
+ data &= 0xE0;
+ data |= j;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, data);
+
+ /* Jong 10/04/2007; merge code */
+ if (HwDeviceExtension->jChipType >= XG20) {
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04);
+ data = data - 1;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04, data);
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05);
+ data1 = data;
+ data1 &= 0xE0;
+ data &= 0x1F;
+ if (data == 0) {
+ pushax = data;
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c);
+ data &= 0xFB;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c, data);
+ data = pushax;
+ }
+ data = data - 1;
+ data |= data1;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05, data);
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
+ data = data >> 5;
+ data = data + 3;
+ if (data > 7)
+ data = data - 7;
+ data = data << 5;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, ~0xE0, data);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1Timing_V */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR data;
+ USHORT i, j;
+
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
+ /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , 0x7f , 0x00 ) ; */
+
+ for (i = 0x00; i <= 0x01; i++) {
+ data = pVBInfo->TimingV.data[i];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 6), data);
+ }
+
+ for (i = 0x02; i <= 0x03; i++) {
+ data = pVBInfo->TimingV.data[i];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x0e), data);
+ }
+
+ for (i = 0x04; i <= 0x05; i++) {
+ data = pVBInfo->TimingV.data[i];
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x11), data);
+ }
+
+ j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a);
+ j &= 0xC0;
+ data = pVBInfo->TimingV.data[6];
+ data &= 0x3F;
+ data |= j;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a, data);
+
+ data = pVBInfo->TimingV.data[6];
+ data &= 0x80;
+ data = data >> 2;
+
+ if (ModeNo <= 0x13)
+ i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ i &= DoubleScanMode;
+ if (i)
+ data |= 0x80;
+
+ j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09);
+ j &= 0x5F;
+ data |= j;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09, data);
+}
+
+/* Jong 10/04/2007; merge code */
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetXG21CRTC */
+/* Input : Stand or enhance CRTC table */
+/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
+/* Description : Set LCD timing */
+/* --------------------------------------------------------------------- */
+void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
+ USHORT Temp1, Temp2, Temp3 ;
+
+ if ( ModeNo <= 0x13 )
+ {
+ StandTableIndex = XGI_GetModePtr( pVBInfo->SModeIDTable,
+ pVBInfo->ModeType,
+ ModeNo, ModeIdIndex);
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
+ Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
+ Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
+ Tempcx = Tempax ;
+ Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
+ Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
+ if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
+ Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
+ Tempdx <<= 2 ; /* Tempdx << 2 */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
+
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR16 VRS */
+ Tempbx = Tempax ; /* Tempbx=Tempax */
+ Tempax &= 0x01 ; /* Tempax: VRS[0] */
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS */
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax: CR7 VRS */
+ Tempdx = Tempbx >> 1 ; /* Tempdx: VRS[7:1] */
+ Tempcx = Tempax & 0x04 ; /* Tempcx: CR7[2] */
+ Tempcx <<= 5 ; /* Tempcx[7]: VRS[8] */
+ Tempdx |= Tempcx ; /* Tempdx: VRS[8:1] */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempdx ) ; /* SR34[7:0]: VRS[8:1] */
+
+ Temp1 = Tempcx << 1 ; /* Temp1[8]: VRS[8] UCHAR -> USHORT */
+ Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
+ Tempax &= 0x80 ; /* Tempax[7]: CR7[7] */
+ Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
+ Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
+
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR16 VRE */
+ Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
+ Temp2 = Temp1 & 0x3F0 ; /* Temp2[9:4]: VRS[9:4] */
+ Temp2 |= Tempax ; /* Temp2[9:0]: VRE[9:0] */
+ Temp3 = Temp1 & 0x0F ; /* Temp3[3:0]: VRS[3:0] */
+ if ( Tempax < Temp3 ) /* VRE[3:0]<VRS[3:0] */
+ Temp2 |= 0x10 ; /* Temp2: VRE + 0x10 */
+ Temp2 &= 0xFF ; /* Temp2[7:0]: VRE[7:0] */
+ Tempax = (UCHAR)Temp2 ; /* Tempax[7:0]: VRE[7:0] */
+ Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
+ Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
+ Temp1 >>= 9 ; /* [10:9]->[1:0] */
+ Tempbx = (UCHAR)Temp1 ; /* Tempbx[1:0]: VRS[10:9] */
+ Tempax |= Tempbx ; /* VRE[5:0]VRS[10:9] */
+ Tempax &= 0x7F ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
+ }
+ else
+ {
+ index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
+ Tempcx = Tempax ; /* Tempcx: HRS */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
+
+ Tempdx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SRB */
+ Tempdx &= 0xC0 ; /* Tempdx[7:6]: SRB[7:6] */
+ Temp1 = Tempdx ; /* Temp1[7:6]: HRS[9:8] */
+ Temp1 <<= 2 ; /* Temp1[9:8]: HRS[9:8] */
+ Temp1 |= Tempax ; /* Temp1[9:0]: HRS[9:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
+ Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
+
+ Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
+ Tempbx &= 0x04 ; /* Tempbx[2]: HRE[5] */
+ Tempbx <<= 3 ; /* Tempbx[5]: HRE[5] */
+ Tempax |= Tempbx ; /* Tempax[5:0]: HRE[5:0] */
+
+ Temp2 = Temp1 & 0x3C0 ; /* Temp2[9:6]: HRS[9:6] */
+ Temp2 |= Tempax ; /* Temp2[9:0]: HRE[9:0] */
+
+ Tempcx &= 0x3F ; /* Tempcx[5:0]: HRS[5:0] */
+ if( Tempax < Tempcx ) /* HRE < HRS */
+ Temp2 |= 0x40 ; /* Temp2 + 0x40 */
+
+ Temp2 &= 0xFF ;
+ Tempax = (UCHAR)Temp2 ; /* Tempax: HRE[7:0] */
+ Tempax <<= 2 ; /* Tempax[7:2]: HRE[5:0] */
+ Tempdx >>= 6 ; /* Tempdx[7:6]->[1:0] HRS[9:8] */
+ Tempax |= Tempdx ; /* HRE[5:0]HRS[9:8] */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F D[7:2]->HRE, D[1:0]->HRS */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
+ Tempbx = Tempax ; /* Tempbx: VRS */
+ Tempax &= 0x01 ; /* Tempax[0]: VRS[0] */
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS[0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[2][7] VRE */
+ Tempcx = Tempbx >> 1 ; /* Tempcx[6:0]: VRS[7:1] */
+ Tempdx = Tempax & 0x04 ; /* Tempdx[2]: CR7[2] */
+ Tempdx <<= 5 ; /* Tempdx[7]: VRS[8] */
+ Tempcx |= Tempdx ; /* Tempcx[7:0]: VRS[8:1] */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempcx ) ; /* SR34[8:1]->VRS */
+
+ Temp1 = Tempdx ; /* Temp1[7]: Tempdx[7] */
+ Temp1 <<= 1 ; /* Temp1[8]: VRS[8] */
+ Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
+ Tempax &= 0x80 ;
+ Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
+ Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SRA */
+ Tempax &= 0x08 ; /* Tempax[3]: VRS[3] */
+ Temp2 = Tempax ;
+ Temp2 <<= 7 ; /* Temp2[10]: VRS[10] */
+ Temp1 |= Temp2 ; /* Temp1[10:0]: VRS[10:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
+ Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
+ Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SRA */
+ Tempbx &= 0x20 ; /* Tempbx[5]: VRE[5] */
+ Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
+ Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
+ Temp2 = Temp1 & 0x7E0 ; /* Temp2[10:5]: VRS[10:5] */
+ Temp2 |= Tempax ; /* Temp2[10:5]: VRE[10:5] */
+
+ Temp3 = Temp1 & 0x1F ; /* Temp3[4:0]: VRS[4:0] */
+ if ( Tempax < Temp3 ) /* VRE < VRS */
+ Temp2 |= 0x20 ; /* VRE + 0x20 */
+
+ Temp2 &= 0xFF ;
+ Tempax = (UCHAR)Temp2 ; /* Tempax: VRE[7:0] */
+ Tempax <<= 2 ; /* Tempax[7:0]; VRE[5:0]00 */
+ Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
+ Temp1 >>= 9 ; /* Temp1[1:0]: VRS[10:9] */
+ Tempbx = (UCHAR)Temp1 ;
+ Tempax |= Tempbx ; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
+ Tempax &= 0x7F ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
+ }
+}
+
+/* Jong 10/04/2007; merge code */
+void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
+
+ if ( ModeNo <= 0x13 )
+ {
+ /* Jong 10/05/2007; merge code */
+ /* StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ; */
+ StandTableIndex = XGI_GetModePtr( pVBInfo->SModeIDTable,
+ pVBInfo->ModeType,
+ ModeNo, ModeIdIndex);
+
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
+ Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
+ Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
+ Tempcx = Tempax ;
+ Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
+ Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
+ if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
+ Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
+ Tempdx <<= 2 ; /* Tempdx << 2 */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
+
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR10 VRS */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS */
+ Tempcx = Tempax ; /* Tempcx=Tempax=VRS[7:0] */
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
+ Tempbx = Tempax ; /* Tempbx=CR07 */
+ Tempax &= 0x04 ; /* Tempax[2]: CR07[2] VRS[8] */
+ Tempax >>= 2;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x01, Tempax ) ; /* SR35 D[0]->VRS D[8] */
+ Tempcx |= (Tempax << 8) ; /* Tempcx[8] |= VRS[8] */
+ Tempcx |= (Tempbx & 0x80)<<2; /* Tempcx[9] |= VRS[9] */
+
+
+ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR11 VRE */
+ Tempax &= 0x0F ; /* Tempax: VRE[3:0] */
+ Tempbx = Tempcx ; /* Tempbx=Tempcx=VRS[9:0] */
+ Tempbx &= 0x3F0 ; /* Tempbx[9:4]: VRS[9:4] */
+ Tempbx |= Tempax ; /* Tempbx[9:0]: VRE[9:0] */
+ if ( Tempax <= (Tempcx & 0x0F) ) /* VRE[3:0]<=VRS[3:0] */
+ Tempbx |= 0x10 ; /* Tempbx: VRE + 0x10 */
+ Tempax = (UCHAR)Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
+ Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
+ Tempcx = (Tempcx&0x600)>>8; /* Tempcx VRS[10:9] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC, Tempax ) ; /* SR3F D[7:2]->VRE D[5:0] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x06, Tempcx ) ; /* SR35 D[2:1]->VRS[10:9] */
+ }
+ else
+ {
+ index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
+ Tempbx = Tempax ; /* Tempbx: HRS[7:0] */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
+ Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+ Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
+ Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
+ Tempcx = Tempax ; /* Tempcx: HRE[4:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
+ Tempax &= 0x04 ; /* Tempax[2]: HRE[5] */
+ Tempax <<= 3 ; /* Tempax[5]: HRE[5] */
+ Tempcx |= Tempax ; /* Tempcx[5:0]: HRE[5:0] */
+
+ Tempbx = Tempbx & 0x3C0 ; /* Tempbx[9:6]: HRS[9:6] */
+ Tempbx |= Tempcx ; /* Tempbx: HRS[9:6]HRE[5:0] */
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
+ Tempax &= 0x3F ; /* Tempax: HRS[5:0] */
+ if( Tempcx <= Tempax ) /* HRE[5:0] < HRS[5:0] */
+ Tempbx += 0x40 ; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
+ Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
+ Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
+ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS[7:0] */
+
+ Tempcx = Tempax ; /* Tempcx <= VRS[7:0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[7][2] VRS[9][8] */
+ Tempbx = Tempax ; /* Tempbx <= CR07[7:0] */
+ Tempax = Tempax & 0x04 ; /* Tempax[2]: CR7[2]: VRS[8] */
+ Tempax >>= 2 ; /* Tempax[0]: VRS[8] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x01 , Tempax ) ; /* SR35[0]: VRS[8] */
+ Tempcx |= (Tempax<<8) ; /* Tempcx <= VRS[8:0] */
+ Tempcx |= ((Tempbx&0x80)<<2) ; /* Tempcx <= VRS[9:0] */
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SR0A */
+ Tempax &= 0x08; /* SR0A[3] VRS[10] */
+ Tempcx |= (Tempax<<7) ; /* Tempcx <= VRS[10:0] */
+
+
+ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
+ Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
+ Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SR0A */
+ Tempbx &= 0x20 ; /* Tempbx[5]: SR0A[5]: VRE[4] */
+ Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
+ Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
+ Tempbx = Tempcx ; /* Tempbx: VRS[10:0] */
+ Tempbx &= 0x7E0 ; /* Tempbx[10:5]: VRS[10:5] */
+ Tempbx |= Tempax ; /* Tempbx: VRS[10:5]VRE[4:0] */
+
+ if ( Tempbx <= Tempcx ) /* VRE <= VRS */
+ Tempbx |= 0x20 ; /* VRE + 0x20 */
+
+ Tempax = (Tempbx<<2) & 0xFF ; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC , Tempax ) ; /* SR3F[7:2]:VRE[5:0] */
+ Tempax = Tempcx >> 8;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x07 , Tempax ) ; /* SR35[2:0]:VRS[10:8] */
+ }
+}
+
+
+/* Jong 10/04/2007; merge code */
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetXG21LCD */
+/* Input : */
+/* Output : FCLK duty cycle, FCLK delay compensation */
+/* Description : All values set zero */
+/* --------------------------------------------------------------------- */
+void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
+{
+ USHORT Data , Temp , b3CC ;
+ USHORT XGI_P3cc ;
+
+ if ( ModeNo > 0x13 )
+ Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
+ XGI_P3cc = pVBInfo->P3cc ;
+
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , 0x00 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , 0x00 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , 0x00 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , 0x00 ) ;
+ if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
+ {
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
+ }
+
+ Temp = XGI_GetReg( pVBInfo->P3d4 , 0x37 ) ;
+
+ if ( Temp & 0x01 )
+ {
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x06 , 0x40 ) ; /* 18 bits FP */
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , 0x40 ) ;
+ }
+
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
+
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 ) ;
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 ) ;
+
+ if ( ModeNo <= 0x13 )
+ {
+ b3CC = (UCHAR) XGI_GetRegByte( (XGIIOADDRESS) XGI_P3cc ) ;
+ if ( b3CC & 0x40 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
+ if ( b3CC & 0x80 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
+ }
+ else
+ {
+ if ( Data & 0x4000 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
+ if ( Data & 0x8000 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
+ }
+}
+
+/* Jong 10/04/2007; merge code */
+void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
+{
+ USHORT Data , Temp , b3CC ;
+ USHORT XGI_P3cc ;
+
+ if ( ModeNo > 0x13 )
+ Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
+ XGI_P3cc = pVBInfo->P3cc ;
+
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , 0x00 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , 0x00 ) ;
+ XGI_SetReg( pVBInfo->P3d4 , 0x46 , 0x00 ) ;
+ XGI_SetReg( pVBInfo->P3d4 , 0x47 , 0x00 ) ;
+
+ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 ) ;
+ if ( ( Temp & 0x03 ) == 0 ) /* dual 12 */
+ {
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , 0x13 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , 0x13 ) ;
+ }
+
+ if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
+ {
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
+ }
+
+ XGI_SetXG27FPBits(pVBInfo);
+
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
+
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 ) ; /* Hsync polarity */
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 ) ; /* Vsync polarity */
+
+ if ( ModeNo <= 0x13 )
+ {
+ b3CC = (UCHAR) XGI_GetRegByte( (XGIIOADDRESS) XGI_P3cc ) ;
+ if ( b3CC & 0x40 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
+ if ( b3CC & 0x80 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
+ }
+ else
+ {
+ if ( Data & 0x4000 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
+ if ( Data & 0x8000 )
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
+ }
+}
+
+/* Jong 10/04/2007; merge code */
+/* --------------------------------------------------------------------- */
+/* Function : XGI_UpdateXG21CRTC */
+/* Input : */
+/* Output : CRT1 CRTC */
+/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
+/* --------------------------------------------------------------------- */
+void XGI_UpdateXG21CRTC( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo , USHORT RefreshRateTableIndex )
+{
+ int i , index = -1;
+
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , 0x7F ) ; /* Unlock CR0~7 */
+ if ( ModeNo <= 0x13 )
+ {
+ for( i = 0 ; i < 12 ; i++ )
+ {
+ if ( ModeNo == pVBInfo->UpdateCRT1[ i ].ModeID )
+ index = i ;
+ }
+ }
+ else
+ {
+ if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x60 ) )
+ index = 12 ;
+ else if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x72 ) )
+ index = 13 ;
+ else if ( ModeNo == 0x2F )
+ index = 14 ;
+ else if ( ModeNo == 0x50 )
+ index = 15 ;
+ else if ( ModeNo == 0x59 )
+ index = 16 ;
+ }
+
+ if( index != -1 )
+ {
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x02 , pVBInfo->UpdateCRT1[ index ].CR02 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x03 , pVBInfo->UpdateCRT1[ index ].CR03 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x15 , pVBInfo->UpdateCRT1[ index ].CR15 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x16 , pVBInfo->UpdateCRT1[ index ].CR16 ) ;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1DE */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, tempbx, tempcx, temp, modeflag;
+ UCHAR data;
+ const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempax = pVBInfo->StResInfo[resindex].HTotal;
+ tempbx = pVBInfo->StResInfo[resindex].VTotal;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempax = pVBInfo->ModeResInfo[resindex].HTotal;
+ tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
+ }
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ if (ModeNo > 0x13) {
+ if (modeflag & HalfDCLK)
+ tempax = tempax << 1;
+
+ temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+ if (temp & InterlaceMode)
+ tempbx = tempbx >> 1;
+
+ if (modeflag & DoubleScanMode)
+ tempbx = tempbx << 1;
+ }
+
+ tempcx = 8;
+
+ /* if ( !( modeflag & Charx8Dot ) ) */
+ /* tempcx = 9 ; */
+
+ tempax /= tempcx;
+ tempax -= 1;
+ tempbx -= 1;
+ tempcx = tempax;
+ temp = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
+ data &= 0x7F;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x01, (USHORT) (tempcx & 0xff));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0b, ~0x0c,
+ (USHORT) ((tempcx & 0x0ff00) >> 10));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x12, (USHORT) (tempbx & 0xff));
+ tempax = 0;
+ tempbx = tempbx >> 8;
+
+ if (tempbx & 0x01)
+ tempax |= 0x02;
+
+ if (tempbx & 0x02)
+ tempax |= 0x40;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, ~0x42, tempax);
+ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x07);
+ data &= 0xFF;
+ tempax = 0;
+
+ if (tempbx & 0x04)
+ tempax |= 0x02;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0a, ~0x02, tempax);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, temp);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetResInfo */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ return (ModeNo <= 0x13)
+ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo
+ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+}
+
+
+static void
+get_mode_xres_yres(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo,
+ unsigned *width, unsigned *height)
+{
+ const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ unsigned xres;
+ unsigned yres;
+
+
+ if (ModeNo <= 0x13) {
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ yres = pVBInfo->StResInfo[resindex].VTotal;
+ }
+ else {
+ const unsigned modeflag =
+ pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ xres = pVBInfo->ModeResInfo[resindex].HTotal;
+ yres = pVBInfo->ModeResInfo[resindex].VTotal;
+
+ if (modeflag & HalfDCLK)
+ xres *= 2;
+
+ if (modeflag & DoubleScanMode)
+ yres *= 2;
+ }
+
+ *width = xres;
+ *height = yres;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1Offset */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp, ah, al, temp2, i, DisplayUnit;
+
+ /* GetOffset */
+ temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ temp = temp >> 8;
+ temp = pVBInfo->ScreenOffset[temp];
+
+ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 &= InterlaceMode;
+
+ if (temp2)
+ temp = temp << 1;
+
+ temp2 = pVBInfo->ModeType - ModeEGA;
+
+ switch (temp2) {
+ case 0:
+ temp2 = 1;
+ break;
+ case 1:
+ temp2 = 2;
+ break;
+ case 2:
+ temp2 = 4;
+ break;
+ case 3:
+ temp2 = 4;
+ break;
+ case 4:
+ temp2 = 6;
+ break;
+ case 5:
+ temp2 = 8;
+ break;
+ default:
+ break;
+ }
+
+ if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
+ temp = temp * temp2 + temp2 / 2;
+ else
+ temp *= temp2;
+
+ /* SetOffset */
+ DisplayUnit = temp;
+ temp2 = temp;
+ temp = temp >> 8; /* ah */
+ temp &= 0x0F;
+ i = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E);
+ i &= 0xF0;
+ i |= temp;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E, i);
+
+ temp = (UCHAR) temp2;
+ temp &= 0xFF; /* al */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x13, temp);
+
+ /* SetDisplayUnit */
+ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ temp2 &= InterlaceMode;
+ if (temp2)
+ DisplayUnit >>= 1;
+
+ DisplayUnit = DisplayUnit << 5;
+ ah = (DisplayUnit & 0xff00) >> 8;
+ al = DisplayUnit & 0x00ff;
+ if (al == 0)
+ ah += 1;
+ else
+ ah += 2;
+
+ /* Jong 10/04/2007; merge code */
+ if (HwDeviceExtension->jChipType >= XG20)
+ if ((ModeNo == 0x4A) | (ModeNo == 0x49))
+ ah -= 1;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, ah);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1VCLK */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ unsigned index;
+ unsigned clka;
+ unsigned clkb;
+ unsigned data; /* Jong 10/04/2007; merge code */
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
+ clka = pVBInfo->VCLKData[ index ].SR2B;
+ clkb = pVBInfo->VCLKData[ index ].SR2C;
+ }
+ else if ((pVBInfo->VBType & VB_XGI301BLV302BLV)
+ && (pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+ index = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+
+ clka = pVBInfo->VBVCLKData[index].Part4_A;
+ clkb = pVBInfo->VBVCLKData[index].Part4_B;
+ }
+ else {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+
+ clka = pVBInfo->VCLKData[index].SR2B;
+ clkb = pVBInfo->VCLKData[index].SR2C;
+ }
+
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0xCF);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, clka);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, clkb);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2D, 0x01);
+
+ /* Jong 10/04/2007; merge code */
+ if ((HwDeviceExtension->jChipType >= XG20)
+ && (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK)) {
+ UCHAR data;
+
+ /* FIXME: Does this actually serve any purpose? This register is
+ * FIXME: already written above.
+ */
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, data);
+
+ /* FIXME: The logic here seems wrong. It looks like its possible
+ * FIXME: for the (data << 1) to cause a bit to creep into the index
+ * FIXME: part. THere's no documentation for this register, so I have
+ * FIXME: no way of knowing. :(
+ */
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C);
+ index = data;
+ index &= 0xE0;
+ data &= 0x1F;
+ data = data << 1;
+ data += 1;
+ data |= index;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, data);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1FIFO */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data;
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
+ data &= 0xfe;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
+
+ if (ModeNo > 0x13) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0x34);
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
+ data &= 0xF0;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
+ data |= 0x01;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data);
+ }
+ else {
+ if (HwDeviceExtension->jChipType == XG27)
+ {
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x08 , 0x0E ) ;
+ data = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 ) ;
+ data &= 0xC0 ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , data | 0x20 ) ;
+ }
+ else
+ {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0xAE);
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
+ data &= 0xF0;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
+ }
+ }
+
+ /* Jong 10/17/2007; merge code */
+ if (HwDeviceExtension->jChipType == XG21)
+ {
+ XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
+ }
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT1ModeRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data, data2, data3, infoflag = 0, modeflag, resindex, xres;
+
+ if (ModeNo > 0x13) {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+ }
+ else
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+
+ if (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31) & 0x01)
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
+
+ if (ModeNo > 0x13)
+ data = infoflag;
+ else
+ data = 0;
+
+ data2 = 0;
+
+ if (ModeNo > 0x13) {
+ if (pVBInfo->ModeType > 0x02) {
+ data2 |= 0x02;
+ data3 = pVBInfo->ModeType - ModeVGA;
+ data3 = data3 << 2;
+ data2 |= data3;
+ }
+ }
+
+ data &= InterlaceMode;
+
+ if (data)
+ data2 |= 0x20;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, ~0x3F, data2);
+ /* XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x06,data2); */
+ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ if (ModeNo <= 0x13)
+ xres = pVBInfo->StResInfo[resindex].HTotal;
+ else
+ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+
+ data = 0x0000;
+ if (infoflag & InterlaceMode) {
+ if (xres == 1024)
+ data = 0x0035;
+ else if (xres == 1280)
+ data = 0x0048;
+ }
+
+ data2 = data & 0x00FF;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFF, data2);
+ data2 = (data & 0xFF00) >> 8;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFC, data2);
+
+ if (modeflag & HalfDCLK)
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xF7, 0x08);
+
+ data2 = 0;
+
+ if (modeflag & LineCompareOff)
+ data2 |= 0x08;
+
+ if (ModeNo > 0x13) {
+ if (pVBInfo->ModeType == ModeEGA)
+ data2 |= 0x40;
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0F, ~0x48, data2);
+ data = 0x60;
+ if (pVBInfo->ModeType != ModeText) {
+ data = data ^ 0x60;
+ if (pVBInfo->ModeType != ModeEGA) {
+ data = data ^ 0xA0;
+ }
+ }
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x21, 0x1F, data);
+
+ XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
+ pVBInfo);
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
+
+ /* Jong 10/04/2007; merge code */
+ if (HwDeviceExtension->jChipType == XG27 )
+ {
+ if ( data & 0x40 )
+ data = 0x2c ;
+ else
+ data = 0x6c ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x52 , data ) ;
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0x10 ) ;
+ }
+ else if (HwDeviceExtension->jChipType >= XG20)
+ {
+ if (data & 0x40)
+ data = 0x33;
+ else
+ data = 0x73;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x51, 0x02);
+ }
+ else {
+ if (data & 0x40)
+ data = 0x2c;
+ else
+ data = 0x6c;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
+ }
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetVCLKState */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data, data2 = 0;
+ SHORT VCLK;
+
+ UCHAR index;
+
+ if (ModeNo <= 0x13)
+ VCLK = 0;
+ else {
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+ index &= IndexMask;
+ VCLK = pVBInfo->VCLKData[index].CLOCK;
+ }
+
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
+ data &= 0xf3;
+ if (VCLK >= 200)
+ data |= 0x0c; /* VCLK > 200 */
+
+ /* Jong 10/04/2007; merge code */
+ if (HwDeviceExtension->jChipType >= XG20)
+ data &= ~0x04; /* 2 pixel mode */
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, data);
+
+ /* Jong 10/04/2007; merge code */
+ if (HwDeviceExtension->jChipType < XG20) {
+ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
+ data &= 0xE7;
+ if (VCLK < 200)
+ data |= 0x10;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, data);
+ }
+
+ /* Jong for Adavantech LCD ripple issue
+ if ((VCLK >= 0) && (VCLK < 135))
+ data2 = 0x03;
+ else if ((VCLK >= 135) && (VCLK < 160))
+ data2 = 0x02;
+ else if ((VCLK >= 160) && (VCLK < 260))
+ data2 = 0x01;
+ else if (VCLK > 260)
+ data2 = 0x00; */
+
+ data2 = 0x00 ;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x07, 0xFC, data2);
+
+ /* Jong 10/04/2007; merge code */
+ if (HwDeviceExtension->jChipType >= XG27 )
+ {
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x40 , 0xFC , data2&0x03 ) ;
+ }
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_LoadDAC */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, ah, dh;
+ const uint8_t *table = NULL;
+
+ if (ModeNo <= 0x13)
+ data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ else
+ data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ data &= DACInfoFlag;
+ time = 64;
+
+ if (data == 0x00)
+ table = XGI_MDA_DAC;
+ else if (data == 0x08)
+ table = XGI_CGA_DAC;
+ else if (data == 0x10)
+ table = XGI_EGA_DAC;
+ else if (data == 0x18) {
+ time = 256;
+ table = XGI_VGA_DAC;
+ }
+
+ if (time == 256)
+ j = 16;
+ else
+ j = time;
+
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c6, 0xFF);
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
+
+ for (i = 0; i < j; i++) {
+ data = table[i];
+
+ for (k = 0; k < 3; k++) {
+ data2 = 0;
+
+ if (data & 0x01)
+ data2 = 0x2A;
+
+ if (data & 0x02)
+ data2 += 0x15;
+
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data2);
+ data = data >> 2;
+ }
+ }
+
+ if (time == 256) {
+ for (i = 16; i < 32; i++) {
+ data = table[i];
+
+ for (k = 0; k < 3; k++)
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data);
+ }
+
+ si = 32;
+
+ for (m = 0; m < 9; m++) {
+ di = si;
+ bx = si + 0x04;
+ dl = 0;
+
+ for (n = 0; n < 3; n++) {
+ for (o = 0; o < 5; o++) {
+ dh = table[si];
+ ah = table[di];
+ al = table[bx];
+ si++;
+ XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
+ ah, al, dh);
+ }
+
+ si -= 2;
+
+ for (o = 0; o < 3; o++) {
+ dh = table[bx];
+ ah = table[di];
+ al = table[si];
+ si--;
+ XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
+ ah, al, dh);
+ }
+
+ dl++;
+ }
+
+ si += 5;
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_WriteDAC */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift, unsigned ordering,
+ uint8_t ah, uint8_t al, uint8_t dh)
+{
+ USHORT temp, bh, bl;
+
+ if (shift) {
+ ah <<= 2;
+ al <<= 2;
+ dh <<= 2;
+ }
+
+ bh = ah;
+ bl = al;
+
+ if (ordering != 0) {
+ temp = bh;
+ bh = dh;
+ dh = temp;
+ if (ordering == 1) {
+ temp = bl;
+ bl = dh;
+ dh = temp;
+ }
+ else {
+ temp = bl;
+ bl = bh;
+ bh = temp;
+ }
+ }
+ XGI_SetRegByte(dac_data, dh);
+ XGI_SetRegByte(dac_data, bh);
+ XGI_SetRegByte(dac_data, bl);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDAGroup */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT RefreshRateTableIndex;
+ /* USHORT temp ; */
+
+ /* pVBInfo->SelectCRT2Rate = 0 ; */
+
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+}
+
+
+/**
+ * Get LVDS resolution information.
+ */
+void
+XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ unsigned xres;
+ unsigned yres;
+
+
+ get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
+
+ if (xres == 720)
+ xres = 640;
+
+ pVBInfo->VGAHDE = xres;
+ pVBInfo->HDE = xres;
+ pVBInfo->VGAVDE = yres;
+ pVBInfo->VDE = yres;
+}
+
+
+static void
+get_HDE_VDE(PVB_DEVICE_INFO pVBInfo, USHORT *HDE, USHORT *VDE)
+{
+ switch (pVBInfo->LCDResInfo) {
+ case Panel1024x768:
+ case Panel1024x768x75:
+ *HDE = 1024;
+ *VDE = 768;
+ break;
+
+ case Panel1280x1024:
+ case Panel1280x1024x75:
+ *HDE = 1280;
+ *VDE = 1024;
+ break;
+
+ case Panel1400x1050:
+ *HDE = 1400;
+ *VDE = 1050;
+ break;
+
+ default:
+ *HDE = 1600;
+ *VDE = 1200;
+ break;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetLVDSData */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx;
+ XGI330_LVDSDataStruct *LCDPtr = NULL;
+
+ tempbx = 2;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr =
+ (XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))) {
+ get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_ModCRT1Regs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR index;
+ USHORT tempbx, i;
+ XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
+ XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
+ /* XGI330_CHTVDataStruct *TVPtr = NULL ; */
+
+ if (ModeNo <= 0x13)
+ index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ else
+ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+
+ index = index & IndexMask;
+
+ if ((pVBInfo->IF_DEF_ScaleLCD == 0)
+ || ((pVBInfo->IF_DEF_ScaleLCD == 1)
+ && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
+ tempbx = 0;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr =
+ (XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+
+ for (i = 0; i < 8; i++)
+ pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
+ }
+
+ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+
+ tempbx = 1;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr1 =
+ (XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ for (i = 0; i < 7; i++)
+ pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
+ }
+
+ XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+ }
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLVDSRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
+ unsigned long temp, temp1, temp2, temp3, push3;
+ XGI330_LCDDataDesStruct *LCDPtr = NULL;
+ XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
+
+ if (ModeNo > 0x13)
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ else
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+
+ if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
+ if (pVBInfo->IF_DEF_OEMUtil == 1) {
+ tempbx = 8;
+ LCDPtr =
+ (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ }
+
+ if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == 0)) {
+ tempbx = 3;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ LCDPtr1 =
+ (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ else
+ LCDPtr =
+ (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+ ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ }
+
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ push1 = tempbx;
+ push2 = tempax;
+
+ /* GetLCDResInfo */
+ if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
+ get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
+
+ pVBInfo->VGAHDE = pVBInfo->HDE;
+ pVBInfo->VGAVDE = pVBInfo->VDE;
+ }
+
+ tempax = pVBInfo->HT;
+
+ tempbx = (pVBInfo->LCDInfo & EnableScalingLCD)
+ ? LCDPtr1->LCDHDES : LCDPtr->LCDHDES;
+
+ tempcx = pVBInfo->HDE;
+ tempbx = tempbx & 0x0fff;
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
+
+ tempcx = tempcx >> 3;
+ tempbx = tempbx >> 3;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16,
+ (USHORT) (tempbx & 0xff));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17,
+ (USHORT) (tempcx & 0xff));
+
+ tempax = pVBInfo->HT;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDHRS;
+ else
+ tempbx = LCDPtr->LCDHRS;
+
+ tempcx = push2;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempcx = LCDPtr1->LCDHSync;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ /* FIXME: Won't this *always* set tempax to zero? */
+ tempax = tempbx & 0x07;
+ tempax = tempax >> 5;
+ tempcx = tempcx >> 3;
+ tempbx = tempbx >> 3;
+
+ tempcx &= 0x1f;
+ tempax |= tempcx;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x15, tempax);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x14,
+ (USHORT) (tempbx & 0xff));
+
+ tempax = pVBInfo->VT;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDVDES;
+ else
+ tempbx = LCDPtr->LCDVDES;
+ tempcx = pVBInfo->VDE;
+
+ tempbx = tempbx & 0x0fff;
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1b,
+ (USHORT) (tempbx & 0xff));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1c,
+ (USHORT) (tempcx & 0xff));
+
+ tempbx = (tempbx >> 8) & 0x07;
+ tempcx = (tempcx >> 8) & 0x07;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1d,
+ (USHORT) ((tempcx << 3) | tempbx));
+
+ tempax = pVBInfo->VT;
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempbx = LCDPtr1->LCDVRS;
+ else
+ tempbx = LCDPtr->LCDVRS;
+
+ /* tempbx = tempbx >> 4 ; */
+ tempcx = push1;
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD)
+ tempcx = LCDPtr1->LCDVSync;
+
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18,
+ (USHORT) (tempbx & 0xff));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, ~0x0f,
+ (USHORT) (tempcx & 0x0f));
+
+ tempax = ((tempbx >> 8) & 0x07) << 3;
+
+ tempbx = pVBInfo->VGAVDE;
+ if (tempbx != pVBInfo->VDE)
+ tempax |= 0x40;
+
+ if (pVBInfo->LCDInfo & EnableLVDSDDA)
+ tempax |= 0x40;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1a, 0x07,
+ tempax);
+
+ tempcx = pVBInfo->VGAVT;
+ tempbx = pVBInfo->VDE;
+ tempax = pVBInfo->VGAVDE;
+ tempcx -= tempax;
+
+ temp = tempax; /* 0430 ylshieh */
+ temp1 = (temp << 18) / tempbx;
+
+ tempdx = (USHORT) ((temp << 18) % tempbx);
+
+ if (tempdx != 0)
+ temp1 += 1;
+
+ temp2 = temp1;
+ push3 = temp2;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x37,
+ (USHORT) (temp2 & 0xff));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x36,
+ (USHORT) ((temp2 >> 8) & 0xff));
+
+ tempbx = (USHORT) (temp2 >> 16);
+ tempax = tempbx & 0x03;
+
+ tempbx = pVBInfo->VGAVDE;
+ if (tempbx == pVBInfo->VDE)
+ tempax |= 0x04;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x35, tempax);
+
+ if (pVBInfo->VBType & VB_XGI301C) {
+ temp2 = push3;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3c,
+ (USHORT) (temp2 & 0xff));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3b,
+ (USHORT) ((temp2 >> 8) & 0xff));
+ tempbx = (USHORT) (temp2 >> 16);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x3a, ~0xc0,
+ (USHORT) ((tempbx & 0xff) << 6));
+
+ tempcx = pVBInfo->VGAVDE;
+ if (tempcx == pVBInfo->VDE)
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
+ ~0x0c, 0x00);
+ else
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
+ ~0x0c, 0x08);
+ }
+
+ tempcx = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->HDE;
+
+ temp1 = tempcx << 16;
+
+ tempax = (USHORT) (temp1 / tempbx);
+
+ if ((tempbx & 0xffff) == (tempcx & 0xffff))
+ tempax = 65535;
+
+ temp3 = tempax;
+ temp1 = pVBInfo->VGAHDE << 16;
+
+ temp1 /= temp3;
+ temp3 = temp3 << 16;
+ temp1 -= 1;
+
+ temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
+
+ tempax = (USHORT) (temp3 & 0xff);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1f, tempax);
+
+ temp1 = pVBInfo->VGAVDE << 18;
+ temp1 = temp1 / push3;
+ tempbx = (USHORT) (temp1 & 0xffff);
+
+ if (pVBInfo->LCDResInfo == Panel1024x768)
+ tempbx -= 1;
+
+ tempax = ((tempbx >> 8) & 0xff) << 3;
+ tempax |= (USHORT) ((temp3 >> 8) & 0x07);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x20,
+ (USHORT) (tempax & 0xff));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x21,
+ (USHORT) (tempbx & 0xff));
+
+ temp3 = temp3 >> 16;
+
+ if (modeflag & HalfDCLK)
+ temp3 = temp3 >> 1;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x22,
+ (USHORT) ((temp3 >> 8) & 0xff));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x23,
+ (USHORT) (temp3 & 0xff));
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2ECLK */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR di[2];
+ int i;
+ const unsigned vclkindex =
+ XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
+
+ XGI_GetVCLKLen(vclkindex, di, pVBInfo);
+ XGI_GetLCDVCLKPtr(di, pVBInfo);
+
+ for (i = 0; i < 4; i++) {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, ~0x30,
+ (USHORT) (0x10 * i));
+ if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, di[0]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, di[1]);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2b, di[0]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2c, di[1]);
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_UpdateModeInfo */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempcl, tempch, temp, tempbl, tempax;
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ tempcl = 0;
+ tempch = 0;
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
+
+ if (!(temp & 0x20)) {
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
+ if (temp & 0x80) {
+ /* Jong 10/04/2007; merge code */
+ if ((HwDeviceExtension->jChipType >= XG20)
+ || (HwDeviceExtension->jChipType >= XG40))
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53);
+ else
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
+
+ if (!(temp & 0x40))
+ tempcl |= ActiveCRT1;
+ }
+ }
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e);
+ temp &= 0x0f;
+
+ if (!(temp == 0x08)) {
+ tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
+ if (tempax & 0x04)
+ tempcl = tempcl | ActiveLCD;
+
+ temp &= 0x05;
+
+ if (!(tempcl & ActiveLCD))
+ if (temp == 0x01)
+ tempcl |= ActiveCRT2;
+
+ if (temp == 0x04)
+ tempcl |= ActiveLCD;
+
+ if (temp == 0x05) {
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00);
+
+ if (!(temp & 0x08))
+ tempch |= ActiveAVideo;
+
+ if (!(temp & 0x04))
+ tempch |= ActiveSVideo;
+
+ if (temp & 0x02)
+ tempch |= ActiveSCART;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (temp & 0x01)
+ tempch |= ActiveHiTV;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ temp =
+ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d);
+
+ if (temp & 0x10)
+ tempch |= ActiveYPbPr;
+ }
+
+ if (tempch != 0)
+ tempcl |= ActiveTV;
+ }
+ }
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d);
+ if (tempcl & ActiveLCD) {
+ if ((pVBInfo->SetFlag & ReserveTVOption)) {
+ if (temp & ActiveTV)
+ tempcl |= ActiveTV;
+ }
+ }
+ temp = tempcl;
+ tempbl = ~ModeSwitchStatus;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x3d, tempbl, temp);
+
+ if (!(pVBInfo->SetFlag & ReserveTVOption))
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e, tempch);
+ }
+ else {
+ return;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetVBType */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetVBType(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT flag, tempbx, tempah;
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ tempbx = VB_XGI302B;
+ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
+ if (flag != 0x02) {
+ tempbx = VB_XGI301;
+ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x01);
+ if (flag >= 0xB0) {
+ tempbx = VB_XGI301B;
+ if (flag >= 0xC0) {
+ tempbx = VB_XGI301C;
+ if (flag >= 0xD0) {
+ tempbx = VB_XGI301LV;
+ if (flag >= 0xE0) {
+ tempbx = VB_XGI302LV;
+ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port,
+ 0x39);
+ if (tempah != 0xFF)
+ tempbx = VB_XGI301C;
+ }
+ }
+ }
+
+ if (tempbx & (VB_XGI301B | VB_XGI302B)) {
+ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x23);
+
+ if (!(flag & 0x02))
+ tempbx = tempbx | VB_NoLCD;
+ }
+ }
+ }
+
+ pVBInfo->VBType = tempbx;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetVBInfo */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, push, tempbx, temp, modeflag;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ pVBInfo->SetFlag = 0;
+ pVBInfo->ModeType = modeflag & ModeInfoFlag;
+ tempbx = 0;
+
+ if (pVBInfo->VBType & 0xFFFF) {
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30); /* Check Display Device */
+ tempbx = tempbx | temp;
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
+ push = temp;
+ push = push << 8;
+ tempax = temp << 8;
+ tempbx = tempbx | tempax;
+ temp =
+ (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA |
+ SetInSlaveMode | DisableCRT2Display);
+ temp = 0xFFFF ^ temp;
+ tempbx &= temp;
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38);
+
+ if (pVBInfo->IF_DEF_LCDA == 1) {
+ /* if ( ( pVBInfo->VBType & VB_XGI302B ) || ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) */
+ if (pVBInfo->
+ VBType & (VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (temp & EnableDualEdge) {
+ tempbx |= SetCRT2ToDualEdge;
+
+ if (temp & SetToLCDA)
+ tempbx |= SetCRT2ToLCDA;
+ }
+ }
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV)
+ || (pVBInfo->VBType & VB_XGI301C)) {
+ if (temp & SetYPbPr) { /* temp = CR38 */
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35); /* shampoo add for new scratch */
+ temp &= YPbPrMode;
+ tempbx |= SetCRT2ToHiVisionTV;
+
+ if (temp != YPbPrMode1080i) {
+ tempbx &= (~SetCRT2ToHiVisionTV);
+ tempbx |= SetCRT2ToYPbPr;
+ }
+ }
+
+ /* tempbx |= SetCRT2ToYPbPr ; */
+ }
+ }
+ }
+
+ tempax = push; /* restore CR31 */
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (pVBInfo->IF_DEF_HiVision == 1)
+ temp = 0x09FC;
+ else
+ temp = 0x097C;
+ }
+ else {
+ if (pVBInfo->IF_DEF_HiVision == 1)
+ temp = 0x01FC;
+ else
+ temp = 0x017C;
+ }
+ }
+ else /* 3nd party chip */
+ {
+ if ( pVBInfo->IF_DEF_CH7017 == 1 )
+ temp = ( SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) ;
+ else if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 07/05/03 */
+ {
+ temp = SetCRT2ToTV ;
+ }
+ else
+ temp = SetCRT2ToLCD ;
+ }
+
+
+ if (!(tempbx & temp)) {
+ tempax |= DisableCRT2Display;
+ tempbx = 0;
+ }
+
+ if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
+ if (!(pVBInfo->VBType & VB_NoLCD)) {
+ if (tempbx & SetCRT2ToLCDA) {
+ if (tempbx & SetSimuScanMode)
+ tempbx &=
+ (~
+ (SetCRT2ToLCD | SetCRT2ToRAMDAC | SwitchToCRT2));
+ else
+ tempbx &=
+ (~
+ (SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV |
+ SwitchToCRT2));
+ }
+ }
+ }
+
+ /* shampoo add */
+ if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
+ if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+ if (tempbx & SetCRT2ToRAMDAC) {
+ tempbx &=
+ (0xFF00 | SetCRT2ToRAMDAC | SwitchToCRT2 |
+ SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+ }
+ }
+ else
+ tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV));
+ }
+
+ if (!(pVBInfo->VBType & VB_NoLCD)) {
+ if (tempbx & SetCRT2ToLCD) {
+ tempbx &=
+ (0xFF00 | SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+ }
+ }
+
+ if (tempbx & SetCRT2ToSCART) {
+ tempbx &=
+ (0xFF00 | SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode);
+ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (tempbx & SetCRT2ToYPbPr)
+ tempbx &= (0xFF00 | SwitchToCRT2 | SetSimuScanMode);
+ }
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if (tempbx & SetCRT2ToHiVisionTV)
+ tempbx &=
+ (0xFF00 | SetCRT2ToHiVisionTV | SwitchToCRT2 |
+ SetSimuScanMode);
+ }
+
+ if (tempax & DisableCRT2Display) { /* Set Display Device Info */
+ if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
+ tempbx = DisableCRT2Display;
+ }
+
+ if (!(tempbx & DisableCRT2Display)) {
+ if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
+ if (pVBInfo->IF_DEF_LCDA == 1) {
+ if (!(tempbx & SetCRT2ToLCDA))
+ tempbx |= (SetInSlaveMode | SetSimuScanMode);
+ }
+
+ if (pVBInfo->IF_DEF_VideoCapture == 1) {
+ if ((HwDeviceExtension->jChipType >= XG40)
+ && (HwDeviceExtension->jChipType <= XG45)) {
+ if (ModeNo <= 13) {
+ /* CRT2 not need to support */
+ if (!(tempbx & SetCRT2ToRAMDAC)) {
+ tempbx &= (0x00FF | (~SetInSlaveMode));
+ pVBInfo->SetFlag |= EnableVCMode;
+ }
+ }
+ }
+ }
+ }
+
+ /*LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
+ if ((tempbx & SetInSlaveMode) && (tempbx & SetCRT2ToLCDA)) {
+ tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToDualEdge);
+ pVBInfo->SetFlag |= ReserveTVOption;
+ }
+ }
+ }
+
+ pVBInfo->VBInfo = tempbx;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVInfo */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp, tempbx = 0, resinfo = 0, modeflag, index1;
+
+ tempbx = 0;
+ resinfo = 0;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
+ tempbx = temp;
+ if (tempbx & SetPALTV) {
+ tempbx &=
+ (SetCHTVOverScan | SetPALMTV | SetPALNTV | SetPALTV);
+ if (tempbx & SetPALMTV)
+ tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
+ }
+ else
+ tempbx &= (SetCHTVOverScan | SetNTSCJ | SetPALTV);
+ }
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ if (pVBInfo->VBInfo & SetCRT2ToSCART)
+ tempbx |= SetPALTV;
+ }
+
+ if (pVBInfo->IF_DEF_YPbPr == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ index1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
+ index1 &= YPbPrMode;
+
+ if (index1 == YPbPrMode525i)
+ tempbx |= SetYPbPrMode525i;
+
+ if (index1 == YPbPrMode525p)
+ tempbx = tempbx | SetYPbPrMode525p;
+ if (index1 == YPbPrMode750p)
+ tempbx = tempbx | SetYPbPrMode750p;
+ }
+ }
+
+ if (pVBInfo->IF_DEF_HiVision == 1) {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
+ }
+ }
+
+ /* Jong 10/17/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ if ((pVBInfo->VBInfo & SetInSlaveMode)
+ && (!(pVBInfo->VBInfo & SetNotSimuMode)))
+ tempbx |= TVSimuMode;
+
+ if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo == 8)) /* NTSC 1024x768, */
+ tempbx |= NTSC1024x768;
+
+ tempbx |= RPLLDIV2XO;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempbx &= (~RPLLDIV2XO);
+ }
+ else {
+ if (tempbx & (SetYPbPrMode525p | SetYPbPrMode750p))
+ tempbx &= (~RPLLDIV2XO);
+ else if (!
+ (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV |
+ VB_XGI302LV | VB_XGI301C))) {
+ if (tempbx & TVSimuMode)
+ tempbx &= (~RPLLDIV2XO);
+ }
+ }
+ }
+ }
+ pVBInfo->TVInfo = tempbx;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetLCDInfo */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
+
+ pVBInfo->LCDResInfo = 0;
+ pVBInfo->LCDTypeInfo = 0;
+ pVBInfo->LCDInfo = 0;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo// */
+ }
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
+ tempbx = temp & 0x0F;
+
+ if (tempbx == 0)
+ tempbx = Panel1024x768; /* default */
+
+ /* LCD75 [2003/8/22] Vicent */
+ if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
+ if (pVBInfo->VBInfo & DriverMode) {
+ tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ tempax &= 0x0F;
+ else
+ tempax = tempax >> 4;
+
+ if ((resinfo == 6) || (resinfo == 9)) {
+ if (tempax >= 3)
+ tempbx |= PanelRef75Hz;
+ }
+ else if ((resinfo == 7) || (resinfo == 8)) {
+ if (tempax >= 4)
+ tempbx |= PanelRef75Hz;
+ }
+ }
+ }
+
+ pVBInfo->LCDResInfo = tempbx;
+
+ /* End of LCD75 */
+
+ if (pVBInfo->IF_DEF_OEMUtil == 1) {
+ pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
+ }
+
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+ return 0;
+ }
+
+ tempbx = 0;
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
+
+ temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
+
+ if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
+ temp &= ~EnableScalingLCD;
+
+ tempbx |= temp;
+
+ LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
+
+ tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
+
+ /* Jong 10/17/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 ) /* shampoo */
+ {
+ if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C))
+ && (tempax & LCDDualLink)) {
+ tempbx |= SetLCDDualLink;
+ }
+ }
+
+ /* Jong 10/17/1007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ if ((pVBInfo->LCDResInfo == Panel1400x1050)
+ && (pVBInfo->VBInfo & SetCRT2ToLCD) && (ModeNo > 0x13)
+ && (resinfo == 9) && (!(tempbx & EnableScalingLCD)))
+ tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
+ }
+
+/*
+ if ( tempax & LCDBToA )
+ {
+ tempbx |= SetLCDBToA ;
+ }
+*/
+
+ if (pVBInfo->IF_DEF_ExpLink == 1) {
+ if (modeflag & HalfDCLK) {
+ /* if ( !( pVBInfo->LCDInfo&LCDNonExpanding ) ) */
+ if (!(tempbx & SetLCDtoNonExpanding)) {
+ tempbx |= EnableLVDSDDA;
+ }
+ else {
+ if (ModeNo > 0x13) {
+ if (pVBInfo->LCDResInfo == Panel1024x768) {
+ if (resinfo == 4) { /* 512x384 */
+ tempbx |= EnableLVDSDDA;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->VBInfo & SetNotSimuMode) {
+ tempbx |= LCDVESATiming;
+ }
+ }
+ else {
+ tempbx |= LCDVESATiming;
+ }
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x39);
+ if (temp & ReduceTiming) {
+ tempbx |= EnableReduceTiming;
+ }
+
+ pVBInfo->LCDInfo = tempbx;
+
+ if (pVBInfo->IF_DEF_PWD == 1) {
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ if ((pVBInfo->VBType & VB_XGI302LV)
+ || (pVBInfo->VBType & VB_XGI301C)) {
+ if (!(tempax & PWDEnable)) {
+ pVBInfo->LCDInfo &= ~SetPWDEnable;
+ }
+ }
+ }
+ }
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ if (tempax & (LockLCDBToA | StLCDBToA)) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!(tempax & LockLCDBToA)) {
+ if (ModeNo <= 0x13) {
+ pVBInfo->VBInfo &=
+ ~(SetSimuScanMode | SetInSlaveMode |
+ SetCRT2ToLCD);
+ pVBInfo->VBInfo |= SetCRT2ToLCDA | SetCRT2ToDualEdge;
+ }
+ }
+ }
+ }
+ }
+
+ return (1);
+}
+
+/* Jong 10/04/2007; defined in init.c */
+/* Function : XGI_SearchModeID */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+
+/* --------------------------------------------------------------------- */
+/* Function : */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT memorysize, modeflag, temp, temp1, tmp;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ /* ModeType = modeflag&ModeInfoFlag ; // Get mode type */
+
+ memorysize = modeflag & MemoryInfoFlag;
+ memorysize = memorysize > MemorySizeShift;
+ memorysize++; /* Get memory size */
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x14); /* Get DRAM Size */
+ tmp = temp;
+
+ if (HwDeviceExtension->jChipType == XG40) {
+ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+ if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+ temp <<= 2;
+ }
+ else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
+ temp <<= 1;
+ }
+ }
+ else if (HwDeviceExtension->jChipType == XG42) {
+ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+ if ((tmp & 0x04) == 0x04) { /* Dual channels */
+ temp <<= 1;
+ }
+ }
+ else if (HwDeviceExtension->jChipType == XG45) {
+ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+ if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+ temp <<= 2;
+ }
+ else if ((tmp & 0x0c) == 0x08) { /* triple channels */
+ temp1 = temp;
+ temp <<= 1;
+ temp += temp1;
+ }
+ else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
+ temp <<= 1;
+ }
+ }
+ if (temp < memorysize)
+ return (FALSE);
+ else
+ return (TRUE);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_DisplayOn */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_DisplayOn(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x00);
+
+ /* Jong 10/04/2007; merge code */
+ if ( HwDeviceExtension->jChipType == XG21 )
+ {
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ if (!(XGI_XG21GetPSCValue( pVBInfo )&0x1))
+ {
+ XGI_XG21BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
+ XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
+ }
+ if (!(XGI_XG21GetPSCValue( pVBInfo )&0x20))
+ {
+ XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
+ }
+ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
+ XGI_XG21BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
+ }
+ else
+ {
+ XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
+ }
+
+ }
+
+ /* Jong 10/04/2007; merge code */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ if (!(XGI_XG27GetPSCValue( pVBInfo )&0x1))
+ {
+ XGI_XG27BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
+ XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
+ }
+ if (!(XGI_XG27GetPSCValue( pVBInfo )&0x20))
+ {
+ XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
+ }
+ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
+ XGI_XG27BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
+ }
+ else
+ {
+ XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
+ }
+ }
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_DisplayOff */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_DisplayOff(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ /* Jong 10/04/2007; merge code */
+ if ( HwDeviceExtension->jChipType == XG21 )
+ {
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ XGI_XG21BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
+ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
+ }
+ else
+ {
+ XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
+ }
+ }
+
+ /* Jong 10/04/2007; merge code */
+ if ( HwDeviceExtension->jChipType == XG27 )
+ {
+ if ((XGI_XG27GetPSCValue( pVBInfo )&0x2))
+ {
+ XGI_XG27BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
+ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
+ }
+
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
+ }
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x20);
+}
+
+
+/**
+ * Wait for vertical or horizontal blanking period.
+ */
+void
+XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo)
+{
+ while ((XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
+ break;
+
+ while (!(XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
+ break;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SenseCRT1 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+
+void
+XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
+ 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7,
+ 0x04, 0x00, 0x00, 0x05, 0x00
+ };
+
+ UCHAR SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
+
+ UCHAR CR17, CR63, SR31;
+ USHORT temp;
+ UCHAR DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
+
+ int i;
+#ifndef LINUX_XF86
+ int j;
+#endif
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
+
+ /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x57, 0x4A);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
+ (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) |
+ 0x02));
+
+ SR31 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31);
+ CR63 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
+ SR01 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, (UCHAR) (SR01 & 0xDF));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, (UCHAR) (CR63 & 0xBF));
+
+ CR17 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17, (UCHAR) (CR17 | 0x80));
+
+ SR1F = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, (UCHAR) (SR1F | 0x04));
+
+ SR07 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, (UCHAR) (SR07 & 0xFB));
+ SR06 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06, (UCHAR) (SR06 & 0xC3));
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x00);
+
+ for (i = 0; i < 8; i++)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) i, CRTCData[i]);
+
+ for (i = 8; i < 11; i++)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 8),
+ CRTCData[i]);
+
+ for (i = 11; i < 13; i++)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 4),
+ CRTCData[i]);
+
+ for (i = 13; i < 16; i++)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i - 3),
+ CRTCData[i]);
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E,
+ (UCHAR) (CRTCData[16] & 0xE0));
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0x00);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE1);
+
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
+ for (i = 0; i < 256; i++) {
+ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
+ (UCHAR) DAC_TEST_PARMS[0]);
+ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
+ (UCHAR) DAC_TEST_PARMS[1]);
+ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
+ (UCHAR) DAC_TEST_PARMS[2]);
+ }
+
+ XGI_VBLongWait(pVBInfo);
+ XGI_VBLongWait(pVBInfo);
+ XGI_VBLongWait(pVBInfo);
+
+ XGINew_LCD_Wait_Time(0x01, pVBInfo);
+ XGI_WaitDisplay(pVBInfo);
+
+ temp = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3c2);
+ if (temp & 0x10) {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x20);
+ }
+ else {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x00);
+ }
+
+ /* alan, avoid display something, set BLACK DAC if not restore DAC */
+ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
+
+ for (i = 0; i < 256; i++) {
+ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
+ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
+ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SR01);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, CR63);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, SR31);
+
+ /* [2004/05/11] Vicent */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
+ (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) &
+ 0xFD));
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+CheckDualChip(PVB_DEVICE_INFO pVBInfo)
+{
+ /* Check H/W trap that 2nd chip is present or not. */
+ return ((BOOLEAN)
+ (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3A) &
+ XGI_MASK_DUAL_CHIP));
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : SetDualChipRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+SetDualChipRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+
+#ifdef LINUX_XF86
+ USHORT BaseAddr2nd = (USHORT) (ULONG) HwDeviceExtension->pj2ndIOAddress;
+#else
+ USHORT BaseAddr2nd = (USHORT) HwDeviceExtension->pj2ndIOAddress;
+#endif
+ USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT;
+ USHORT XGINew_2ndP3CE = BaseAddr2nd + GRAPH_ADDRESS_PORT;
+ USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT;
+ USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT;
+ UCHAR tempal, i;
+ pVBInfo->BaseAddr = (USHORT) HwDeviceExtension->pjIOAddress;
+ for (i = 0x00; i <= 0x04; i++) { /* SR0 - SR4 */
+ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, i);
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, i, tempal);
+ }
+ for (i = 0x00; i <= 0x08; i++) { /* GR0 - GR8 */
+ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3ce, i);
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3CE, i, tempal);
+ }
+ /* OpenKey in 2nd chip */
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x86);
+
+ /* Copy SR06 to 2nd chip */
+ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x06, tempal);
+
+ /* Copy SR21 to 2nd chip */
+ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21);
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x21, tempal);
+
+ /* Miscellaneous reg(input port 3cch,output port 3c2h) */
+ tempal = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC); /* 3cc */
+ XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2, tempal);
+
+ /* Close key in 2nd chip */
+ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x00);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2Group301 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, ModeIdIndex, RefreshRateTableIndex;
+ USHORT temp_mode_no;
+
+ tempbx = pVBInfo->VBInfo;
+ pVBInfo->SetFlag |= ProgrammingCRT2;
+
+ temp_mode_no = ModeNo;
+ XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11,
+ &temp_mode_no, &ModeIdIndex);
+
+
+ pVBInfo->SelectCRT2Rate = 4;
+ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SaveCRT2Info(ModeNo, pVBInfo);
+ XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+ RefreshRateTableIndex, pVBInfo);
+ XGI_SetTap4Regs(pVBInfo);
+ XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+ XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_AutoThreshold(pVBInfo);
+ return 1;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_AutoThreshold */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo)
+{
+ if (!(pVBInfo->SetFlag & Win9xDOSMode))
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x40);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SaveCRT2Info */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp1, temp2;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
+ temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
+ temp2 = ~(SetInSlaveMode >> 8);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, temp2, temp1);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetCRT2ResInfo */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ unsigned xres;
+ unsigned yres;
+
+
+ get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
+
+ if ((pVBInfo->VBInfo & SetCRT2ToLCD)
+ && !(pVBInfo->LCDInfo & (EnableScalingLCD | LCDNonExpanding))) {
+ switch (pVBInfo->LCDResInfo) {
+ case Panel1600x1200:
+ if (!(pVBInfo->LCDInfo & LCDVESATiming) && (yres == 1024)) {
+ yres = 1056;
+ }
+ break;
+
+
+ case Panel1280x1024:
+ if (yres == 400)
+ yres = 405;
+ else if (yres == 350)
+ yres = 360;
+ else if ((pVBInfo->LCDInfo & LCDVESATiming) && (yres == 360)) {
+ yres = 375;
+ }
+ break;
+
+
+ case Panel1024x768:
+ if (!(pVBInfo->LCDInfo & (LCDVESATiming | LCDNonExpanding))) {
+ if (yres == 350) {
+ yres = 357;
+ }
+ else if (yres == 400) {
+ yres = 420;
+ }
+ else if (yres == 480) {
+ yres = 525;
+ }
+ }
+
+ break;
+ }
+
+ if (xres == 720)
+ xres = 640;
+ }
+
+ pVBInfo->VGAHDE = xres;
+ pVBInfo->HDE = xres;
+ pVBInfo->VGAVDE = yres;
+ pVBInfo->VDE = yres;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_IsLCDDualLink */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo)
+{
+ return (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) != 0)
+ && ((pVBInfo->LCDInfo & SetLCDDualLink) != 0));
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetCRT2Data */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax = 0, tempbx, modeflag, resinfo;
+#ifndef LINUX_XF86
+ USHORT CRT2Index, ResIndex;
+#endif
+
+ XGI_LCDDataStruct *LCDPtr = NULL;
+ XGI_TVDataStruct *TVPtr = NULL;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ pVBInfo->NewFlickerMode = 0;
+ pVBInfo->RVBHRS = 50;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ pVBInfo);
+ return;
+ }
+
+ tempbx = 4;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ LCDPtr =
+ (XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+
+ PDEBUG(ErrorF
+ ("C code setmode: ModeNo: 0x%08lX VGAHT:0x%081X \n", ModeNo,
+ LCDPtr->VGAHT));
+ pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
+ pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
+ pVBInfo->VGAHT = LCDPtr->VGAHT;
+ pVBInfo->VGAVT = LCDPtr->VGAVT;
+ pVBInfo->HT = LCDPtr->LCDHT;
+ pVBInfo->VT = LCDPtr->LCDVT;
+
+ if (pVBInfo->LCDResInfo == Panel1024x768) {
+ tempax = 1024;
+ tempbx = 768;
+
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 357)
+ tempbx = 527;
+ else if (pVBInfo->VGAVDE == 420)
+ tempbx = 620;
+ else if (pVBInfo->VGAVDE == 525)
+ tempbx = 775;
+ else if (pVBInfo->VGAVDE == 600)
+ tempbx = 775;
+ /* else if(pVBInfo->VGAVDE==350) tempbx=560; */
+ /* else if(pVBInfo->VGAVDE==400) tempbx=640; */
+ else
+ tempbx = 768;
+ }
+ else
+ tempbx = 768;
+ }
+ else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
+ tempax = 1024;
+ tempbx = 768;
+ }
+ else if (pVBInfo->LCDResInfo == Panel1280x1024) {
+ tempax = 1280;
+ if (pVBInfo->VGAVDE == 360)
+ tempbx = 768;
+ else if (pVBInfo->VGAVDE == 375)
+ tempbx = 800;
+ else if (pVBInfo->VGAVDE == 405)
+ tempbx = 864;
+ else
+ tempbx = 1024;
+ }
+ else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
+ tempax = 1280;
+ tempbx = 1024;
+ }
+ else if (pVBInfo->LCDResInfo == Panel1280x960) {
+ tempax = 1280;
+ if (pVBInfo->VGAVDE == 350)
+ tempbx = 700;
+ else if (pVBInfo->VGAVDE == 400)
+ tempbx = 800;
+ else if (pVBInfo->VGAVDE == 1024)
+ tempbx = 960;
+ else
+ tempbx = 960;
+ }
+ else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+ tempax = 1400;
+ tempbx = 1050;
+
+ if (pVBInfo->VGAVDE == 1024) {
+ tempax = 1280;
+ tempbx = 1024;
+ }
+ }
+ else if (pVBInfo->LCDResInfo == Panel1600x1200) {
+ tempax = 1600;
+ tempbx = 1200; /* alan 10/14/2003 */
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 350)
+ tempbx = 875;
+ else if (pVBInfo->VGAVDE == 400)
+ tempbx = 1000;
+ }
+ }
+
+ if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD)) {
+ tempax = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->VGAVDE;
+ }
+
+ pVBInfo->HDE = tempax;
+ pVBInfo->VDE = tempbx;
+ return;
+ }
+
+ if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
+ tempbx = 4;
+ TVPtr =
+ (XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex, pVBInfo);
+ pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
+ pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
+ pVBInfo->VGAHT = TVPtr->VGAHT;
+ pVBInfo->VGAVT = TVPtr->VGAVT;
+ pVBInfo->HDE = TVPtr->TVHDE;
+ pVBInfo->VDE = TVPtr->TVVDE;
+ pVBInfo->RVBHRS = TVPtr->RVBHRS;
+ pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (resinfo == 0x08)
+ pVBInfo->NewFlickerMode = 0x40;
+ else if (resinfo == 0x09)
+ pVBInfo->NewFlickerMode = 0x40;
+ else if (resinfo == 0x12)
+ pVBInfo->NewFlickerMode = 0x40;
+
+ if (pVBInfo->VGAVDE == 350)
+ pVBInfo->TVInfo |= TVSimuMode;
+
+ tempax = ExtHiTVHT;
+ tempbx = ExtHiTVVT;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ tempax = StHiTVHT;
+ tempbx = StHiTVVT;
+
+ if (!(modeflag & Charx8Dot)) {
+ tempax = StHiTextTVHT;
+ tempbx = StHiTextTVVT;
+ }
+ }
+ }
+ }
+ else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+ tempax = YPbPrTV750pHT; /* Ext750pTVHT */
+ tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
+ }
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+ tempax = YPbPrTV525pHT; /* Ext525pTVHT */
+ tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
+ }
+ else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+ tempax = YPbPrTV525iHT; /* Ext525iTVHT */
+ tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
+ if (pVBInfo->TVInfo & NTSC1024x768)
+ tempax = NTSC1024x768HT;
+ }
+ }
+ else {
+ tempax = PALHT;
+ tempbx = PALVT;
+ if (!(pVBInfo->TVInfo & SetPALTV)) {
+ tempax = NTSCHT;
+ tempbx = NTSCVT;
+ if (pVBInfo->TVInfo & NTSC1024x768)
+ tempax = NTSC1024x768HT;
+ }
+ }
+
+ pVBInfo->HT = tempax;
+ pVBInfo->VT = tempbx;
+ return;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2VCLK */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR di[2];
+ const unsigned vclkindex =
+ XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
+
+ XGI_GetVCLKLen(vclkindex, di, pVBInfo);
+ XGI_GetLCDVCLKPtr(di, pVBInfo);
+
+ if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 *//* 301 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x10);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
+ }
+ else { /* 301b/302b/301lv/302lv */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
+ }
+
+ if ((pVBInfo->LCDInfo & EnableReduceTiming)
+ && (pVBInfo->LCDResInfo == Panel1600x1200)) {
+ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0A) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x5A);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, 0x24);
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00, 0x12);
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x28);
+ else
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x08);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GETLCDVCLKPtr */
+/* Input : */
+/* Output : al -> VCLK Index */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo)
+{
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if ((pVBInfo->IF_DEF_ScaleLCD != 1)
+ || !(pVBInfo->LCDInfo & EnableScalingLCD)) {
+ const unsigned index = XGI_GetLCDCapPtr1(pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
+ di[0] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
+ di[1] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
+ }
+ else { /* LCDA */
+ di[0] = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
+ di[1] = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
+ }
+ }
+ }
+
+ return;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetVCLKPtr */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+unsigned
+XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
+ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ unsigned vclk;
+ const unsigned modeflag = (ModeNo <= 0x13)
+ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+
+ if ((pVBInfo->SetFlag & ProgrammingCRT2)
+ && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
+ const unsigned index = XGI_GetLCDCapPtr(pVBInfo);
+ vclk = pVBInfo->LCDCapList[index].LCD_VCLK;
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+ return vclk;
+
+ /* {TV} */
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ vclk = (modeflag & Charx8Dot)
+ ? HiTVSimuVCLK : HiTVTextVCLK;
+ }
+ else {
+ vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
+ ? HiTVVCLKDIV2 : HiTVVCLK;
+ }
+
+ return vclk;
+ }
+ else if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+ return YPbPr750pVCLK;
+ }
+ else if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+ return YPbPr525pVCLK;
+ }
+
+ vclk = NTSC1024VCLK;
+
+ if (!(pVBInfo->TVInfo & NTSC1024x768)) {
+ vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
+ ? TVVCLKDIV2 : TVVCLK;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ return vclk;
+ }
+ } /* {End of VB} */
+
+ vclk = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
+ vclk = (vclk >> 2) & 0x03;
+
+ /* for Dot8 Scaling LCD */
+ if ((pVBInfo->LCDInfo & EnableScalingLCD)
+ && (modeflag & Charx8Dot)
+ && ((pVBInfo->IF_DEF_VideoCapture) == 1)) {
+ vclk = VCLK25_175; /* ; set to VCLK25MHz always */
+ }
+
+ if (ModeNo <= 0x13)
+ return vclk;
+
+ return pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetVCLKLen */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di, PVB_DEVICE_INFO pVBInfo)
+{
+ if (pVBInfo->
+ VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV |
+ VB_XGI302LV | VB_XGI301C)) {
+ if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ && (pVBInfo->SetFlag & ProgrammingCRT2)) {
+ di[0] = XGI_VBVCLKData[vclkindex].SR2B;
+ di[1] = XGI_VBVCLKData[vclkindex].SR2C;
+ }
+ }
+ else {
+ di[0] = XGI_VCLKData[vclkindex].SR2B;
+ di[1] = XGI_VCLKData[vclkindex].SR2C;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2Offset */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT2Offset(USHORT ModeNo,
+ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT offset;
+ UCHAR temp;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ return;
+ }
+
+ offset =
+ XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ temp = (UCHAR) (offset & 0xFF);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp);
+ temp = (UCHAR) ((offset & 0xFF00) >> 8);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, temp);
+ temp = (UCHAR) (((offset >> 3) & 0xFF) + 1);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetOffset */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp,
+ colordepth,
+ modeinfo, index, infoflag,
+ ColorDepth[] = { 0x01 , 0x02 , 0x04 } ;
+
+ modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+ if (ModeNo <= 0x14)
+ infoflag = 0;
+ else
+ infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+
+
+ index = (modeinfo >> 8) & 0xFF;
+
+ temp = pVBInfo->ScreenOffset[index];
+
+ if (infoflag & InterlaceMode) {
+ temp = temp << 1;
+ }
+
+ colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
+
+ /* Jong 10/04/2007; merge code */
+ if ( ( ModeNo >= 0x7C ) && ( ModeNo <= 0x7E ) )
+ {
+ temp = ModeNo - 0x7C ;
+ colordepth = ColorDepth[ temp ] ;
+ temp = 0x6B ;
+ if ( infoflag & InterlaceMode )
+ {
+ temp = temp << 1 ;
+ }
+ return( temp * colordepth ) ;
+ }
+ else
+ return( temp * colordepth ) ;
+
+ /*
+ if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
+ return (temp * colordepth + (colordepth >> 1));
+ }
+ else
+ return (temp * colordepth); */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2FIFO */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT2FIFO(PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_PreSetGroup1 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempcx = 0, CRT1Index = 0, resinfo = 0;
+#ifndef LINUX_XF86
+ USHORT temp = 0, tempax = 0, tempbx = 0, pushbx = 0, modeflag;
+#endif
+
+ if (ModeNo > 0x13) {
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+ HwDeviceExtension, pVBInfo);
+ XGI_SetCRT2FIFO(pVBInfo);
+ /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
+
+ for (tempcx = 4; tempcx < 7; tempcx++) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, tempcx, 0x0);
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetGroup1 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp = 0,
+ tempax = 0,
+ tempbx = 0,
+ tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
+
+ if (ModeNo > 0x13) {
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ }
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ /* bainy change table name */
+ if (modeflag & HalfDCLK) {
+ temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
+ temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
+ temp);
+ temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
+ tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
+ pushbx = pVBInfo->VGAHDE / 2 + 16;
+ tempcx = tempcx >> 1;
+ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx += tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+ tempbx |=
+ ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+ tempcx &= 0x1F;
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
+ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ }
+
+ tempbx += 4;
+ tempcx += 4;
+
+ if (tempcx > (pVBInfo->VGAHT / 2))
+ tempcx = pVBInfo->VGAHT / 2;
+
+ temp = tempbx & 0x00FF;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
+ }
+ else {
+ temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
+ temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
+ temp);
+ temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
+ tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
+ pushbx = pVBInfo->VGAHDE + 16;
+ tempcx = tempcx >> 1;
+ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+ tempcx += tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
+ tempbx |=
+ ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5] & 0xC0) << 2);
+ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+ tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+ tempcx &= 0x1F;
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
+ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+ tempbx += 16;
+ tempcx += 16;
+ }
+
+ if (tempcx > pVBInfo->VGAHT)
+ tempcx = pVBInfo->VGAHT;
+
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
+ }
+
+ tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
+ tempbx = pushbx;
+ tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+ tempax |= (tempbx & 0xFF00);
+ temp = (tempax & 0xFF00) >> 8;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp);
+ tempcx = (pVBInfo->VGAVT - 1);
+ temp = tempcx & 0x00FF;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
+ tempbx = pVBInfo->VGAVDE - 1;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, temp);
+ temp = ((tempbx & 0xFF00) << 3) >> 8;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, temp);
+
+ tempax = pVBInfo->VGAVDE;
+ tempbx = pVBInfo->VGAVDE;
+ tempcx = pVBInfo->VGAVT;
+ tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+ tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+
+ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+
+ if (temp & 0x04)
+ tempbx |= 0x0100;
+
+ if (temp & 0x080)
+ tempbx |= 0x0200;
+
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
+
+ if (temp & 0x08)
+ tempbx |= 0x0400;
+
+ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
+ tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+ }
+
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ temp = ((tempcx & 0x000F) | (temp));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, temp);
+ tempax = 0;
+
+ if (modeflag & DoubleScanMode)
+ tempax |= 0x80;
+
+ if (modeflag & HalfDCLK)
+ tempax |= 0x40;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLockRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT push1,
+ push2, tempax, tempbx = 0, tempcx, temp, resinfo, modeflag, CRT1Index;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ }
+
+ if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
+ return;
+ }
+
+ temp = 0xFF; /* set MAX HT */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
+ /* if ( modeflag & Charx8Dot ) tempcx = 0x08 ; */
+ /* else */
+ tempcx = 0x08;
+
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ modeflag |= Charx8Dot;
+
+ tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
+
+ if (modeflag & HalfDCLK)
+ tempax = tempax >> 1;
+
+ tempax = (tempax / tempcx) - 1;
+ tempbx |= ((tempax & 0x00FF) << 8);
+ temp = tempax & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x04, temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!
+ (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)))
+ temp += 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
+ if (resinfo == 7)
+ temp -= 2;
+ }
+ }
+ else if (resinfo == 7)
+ temp -= 2;
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
+ if (pVBInfo->VBInfo & SetCRT2ToTV)
+ tempax = pVBInfo->VGAHT;
+ else
+ tempax = XGI_GetVGAHT2(pVBInfo);
+ }
+
+ if (tempax >= pVBInfo->VGAHT) {
+ tempax = pVBInfo->VGAHT;
+ }
+
+ if (modeflag & HalfDCLK) {
+ tempax = tempax >> 1;
+ }
+
+ tempax = (tempax / tempcx) - 5;
+ tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ temp = (tempbx & 0x00FF) - 1;
+ if (!(modeflag & HalfDCLK)) {
+ temp -= 6;
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ temp -= 4;
+ if (ModeNo > 0x13)
+ temp -= 10;
+ }
+ }
+ }
+ else {
+ /* tempcx = tempbx & 0x00FF ; */
+ tempbx = (tempbx & 0xFF00) >> 8;
+ tempcx = (tempcx + tempbx) >> 1;
+ temp = (tempcx & 0x00FF) + 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ temp -= 1;
+ if (!(modeflag & HalfDCLK)) {
+ if ((modeflag & Charx8Dot)) {
+ temp += 4;
+ if (pVBInfo->VGAHDE >= 800) {
+ temp -= 6;
+ }
+ }
+ }
+ }
+ else {
+ if (!(modeflag & HalfDCLK)) {
+ temp -= 4;
+ if (pVBInfo->LCDResInfo != Panel1280x960) {
+ if (pVBInfo->VGAHDE >= 800) {
+ temp -= 7;
+ if (pVBInfo->ModeType == ModeEGA) {
+ if (pVBInfo->VGAVDE == 1024) {
+ temp += 15;
+ if (pVBInfo->LCDResInfo != Panel1280x1024) {
+ temp += 7;
+ }
+ }
+ }
+
+ if (pVBInfo->VGAHDE >= 1280) {
+ if (pVBInfo->LCDResInfo != Panel1280x960) {
+ if (!
+ (pVBInfo->
+ LCDInfo & (LCDNonExpanding |
+ EnableScalingLCD))) {
+ temp += 28;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11)
+ || (ModeNo == 0x13) || (ModeNo == 0x0F)) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x5b);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
+ }
+
+ if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
+ if (pVBInfo->TVInfo & SetNTSCTV) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x61);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x41);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
+ }
+ }
+
+ if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)) {
+ if (pVBInfo->TVInfo & SetNTSCTV) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x54);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x55);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
+ }
+ }
+
+ if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D)
+ || (ModeNo == 0x50)) {
+ if (pVBInfo->TVInfo & SetNTSCTV) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x30);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2f);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x02);
+ }
+ }
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
+
+ tempbx = pVBInfo->VGAVT;
+ push1 = tempbx;
+ tempcx = 0x121;
+ tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
+
+ if (tempbx == 357)
+ tempbx = 350;
+ if (tempbx == 360)
+ tempbx = 350;
+ if (tempbx == 375)
+ tempbx = 350;
+ if (tempbx == 405)
+ tempbx = 400;
+ if (tempbx == 525)
+ tempbx = 480;
+
+ push2 = tempbx;
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (pVBInfo->LCDResInfo == Panel1024x768) {
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (tempbx == 350)
+ tempbx += 5;
+ if (tempbx == 480)
+ tempbx += 5;
+ }
+ }
+ }
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
+ tempbx = push2;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
+
+ if (tempbx & 0x0100) {
+ tempcx |= 0x0002;
+ }
+
+ tempax = 0x000B;
+
+ if (modeflag & DoubleScanMode) {
+ tempax |= 0x08000;
+ }
+
+ if (tempbx & 0x0200) {
+ tempcx |= 0x0040;
+ }
+
+ temp = (tempax & 0xFF00) >> 8;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
+
+ if (tempbx & 0x0400) {
+ tempcx |= 0x0600;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
+
+ tempax = push1;
+ tempax -= tempbx; /* 0x0C Vertical Retrace Start */
+ tempax = tempax >> 2;
+ push1 = tempax; /* push ax */
+
+ if (resinfo != 0x09) {
+ tempax = tempax << 1;
+ tempbx += tempax;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+ tempbx -= 10;
+ else {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if (pVBInfo->TVInfo & SetPALTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (!
+ (pVBInfo->
+ TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p
+ | SetYPbPrMode1080i)))
+ tempbx += 40;
+ }
+ else
+ tempbx += 40;
+ }
+ }
+ }
+ }
+ else
+ tempbx -= 10;
+ }
+ else {
+ if (pVBInfo->TVInfo & TVSimuMode) {
+ if (pVBInfo->TVInfo & SetPALTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (!
+ (pVBInfo->
+ TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p |
+ SetYPbPrMode1080i)))
+ tempbx += 40;
+ }
+ else
+ tempbx += 40;
+ }
+ }
+ }
+ tempax = push1;
+ tempax = tempax >> 2;
+ tempax++;
+ tempax += tempbx;
+ push1 = tempax; /* push ax */
+
+ if ((pVBInfo->TVInfo & SetPALTV)) {
+ if (tempbx <= 513) {
+ if (tempax >= 513) {
+ tempbx = 513;
+ }
+ }
+ }
+
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
+
+ if (tempbx & 0x0100) {
+ tempcx |= 0x0008;
+ }
+
+ if (tempbx & 0x0200) {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
+ }
+
+ tempbx++;
+
+ if (tempbx & 0x0100) {
+ tempcx |= 0x0004;
+ }
+
+ if (tempbx & 0x0200) {
+ tempcx |= 0x0080;
+ }
+
+ if (tempbx & 0x0400) {
+ tempcx |= 0x0C00;
+ }
+
+ tempbx = push1; /* pop ax */
+ temp = tempbx & 0x00FF;
+ temp &= 0x0F;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
+
+ if (tempbx & 0x0010) {
+ tempcx |= 0x2000;
+ }
+
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
+ temp = (tempcx & 0x0FF00) >> 8;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
+ tempax = modeflag;
+ temp = (tempax & 0xFF00) >> 8;
+
+ temp = (temp >> 1) & 0x09;
+
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ temp |= 0x01;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
+
+ if (pVBInfo->LCDInfo & LCDRGB18Bit)
+ temp = 0x80;
+ else
+ temp = 0x00;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
+
+ return;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetGroup2 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT i,
+ j,
+ tempax,
+ tempbx, tempcx, temp, push1, push2, modeflag, resinfo, crt2crtc;
+#ifndef LINUX_XF86
+ USHORT temp1, temp3, resindex, xres;
+#endif
+/* XGINew_RY1COE = 0 ,
+ XGINew_RY2COE = 0 ,
+ XGINew_RY3COE = 0 ,
+ XGINew_RY4COE = 0 ,
+ XGINew_RY5COE = 0 ,
+ XGINew_RY6COE = 0 ,
+ XGINew_RY7COE = 0 ;
+*/
+
+#ifndef LINUX_XF86
+ UCHAR *PhasePoint;
+#endif
+ const UCHAR *TimingPoint;
+
+ ULONG longtemp, tempeax, tempebx, temp2, tempecx;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempax = 0;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
+ tempax |= 0x0800;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ tempax |= 0x0400;
+
+ if (pVBInfo->VBInfo & SetCRT2ToSCART)
+ tempax |= 0x0200;
+
+ if (!(pVBInfo->TVInfo & SetPALTV))
+ tempax |= 0x1000;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempax |= 0x0100;
+
+ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+ tempax &= 0xfe00;
+
+ ErrorF("Part2 0 = %x ",
+ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+ ErrorF(" pVBInfo->VBInfo =%x", pVBInfo->VBInfo);
+
+ tempax = (tempax & 0xff00) >> 8;
+ ErrorF("tempax = %x ", tempax);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0, tempax);
+ TimingPoint = pVBInfo->NTSCTiming;
+
+ if (pVBInfo->TVInfo & SetPALTV) {
+ TimingPoint = pVBInfo->PALTiming;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ TimingPoint = pVBInfo->HiTVExtTiming;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ TimingPoint = pVBInfo->HiTVSt2Timing;
+
+ if (pVBInfo->SetFlag & TVSimuMode)
+ TimingPoint = pVBInfo->HiTVSt1Timing;
+
+ if (!(modeflag & Charx8Dot))
+ TimingPoint = pVBInfo->HiTVTextTiming;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ TimingPoint = pVBInfo->YPbPr525iTiming;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ TimingPoint = pVBInfo->YPbPr525pTiming;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ TimingPoint = pVBInfo->YPbPr750pTiming;
+ }
+
+ for (i = 0x01, j = 0; i <= 0x2D; i++, j++) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]);
+ }
+
+ for (i = 0x39; i <= 0x45; i++, j++) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
+ }
+
+ temp = pVBInfo->NewFlickerMode;
+ temp &= 0x80;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xFF, temp);
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ tempax = 950;
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ tempax = 520;
+ else
+ tempax = 440;
+
+ if (pVBInfo->VDE <= tempax) {
+ tempax -= pVBInfo->VDE;
+ tempax = tempax >> 2;
+ tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+ push1 = tempax;
+ temp = (tempax & 0xFF00) >> 8;
+ temp += (USHORT) TimingPoint[0];
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->
+ VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
+ SetCRT2ToYPbPr)) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= 1024) {
+ temp = 0x17; /* NTSC */
+ if (pVBInfo->TVInfo & SetPALTV)
+ temp = 0x19; /* PAL */
+ }
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
+ tempax = push1;
+ temp = (tempax & 0xFF00) >> 8;
+ temp += TimingPoint[1];
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if ((pVBInfo->
+ VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART
+ | SetCRT2ToYPbPr))) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= 1024) {
+ temp = 0x1D; /* NTSC */
+ if (pVBInfo->TVInfo & SetPALTV)
+ temp = 0x52; /* PAL */
+ }
+ }
+ }
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, temp);
+ }
+
+ /* 301b */
+ tempcx = pVBInfo->HT;
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempcx = tempcx >> 1;
+
+ tempcx -= 2;
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1B, temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
+
+ tempcx = pVBInfo->HT >> 1;
+ push1 = tempcx; /* push cx */
+ tempcx += 7;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ tempcx -= 4;
+ }
+
+ temp = tempcx & 0x00FF;
+ temp = temp << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x22, 0x0F, temp);
+
+ tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+ tempbx += tempcx;
+ push2 = tempbx;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x24, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, 0x0F, temp);
+
+ tempbx = push2;
+ tempbx = tempbx + 8;
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ tempbx = tempbx - 4;
+ tempcx = tempbx;
+ }
+
+ temp = (tempbx & 0x00FF) << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x29, 0x0F, temp);
+
+ j += 2;
+ tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x27, temp);
+ temp = ((tempcx & 0xFF00) >> 8) << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x28, 0x0F, temp);
+
+ tempcx += 8;
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ tempcx -= 4;
+ }
+
+ temp = tempcx & 0xFF;
+ temp = temp << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2A, 0x0F, temp);
+
+ tempcx = push1; /* pop cx */
+ j += 2;
+ temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+ tempcx -= temp;
+ temp = tempcx & 0x00FF;
+ temp = temp << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2D, 0x0F, temp);
+
+ tempcx -= 11;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ tempax = XGI_GetVGAHT2(pVBInfo);
+ tempcx = tempax - 1;
+ }
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2E, temp);
+
+ tempbx = pVBInfo->VDE;
+
+ if (pVBInfo->VGAVDE == 360)
+ tempbx = 746;
+ if (pVBInfo->VGAVDE == 375)
+ tempbx = 746;
+ if (pVBInfo->VGAVDE == 405)
+ tempbx = 853;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
+ tempbx = tempbx >> 1;
+ }
+ else
+ tempbx = tempbx >> 1;
+ }
+
+ tempbx -= 2;
+ temp = tempbx & 0x00FF;
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (ModeNo == 0x2f)
+ temp += 1;
+ }
+ }
+ }
+ else {
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (ModeNo == 0x2f)
+ temp += 1;
+ }
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2F, temp);
+
+ temp = (tempcx & 0xFF00) >> 8;
+ temp |= ((tempbx & 0xFF00) >> 8) << 6;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+ temp |= 0x10;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ temp |= 0x20;
+ }
+ }
+ else {
+ temp |= 0x10;
+ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+ temp |= 0x20;
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, temp);
+
+ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
+ tempbx = pVBInfo->VDE;
+ tempcx = tempbx - 2;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
+ tempbx = tempbx >> 1;
+ }
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ temp = 0;
+ if (tempcx & 0x0400)
+ temp |= 0x20;
+
+ if (tempbx & 0x0400)
+ temp |= 0x40;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, temp);
+ }
+
+ temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, temp);
+ temp = (tempbx - 3) & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x47, temp);
+ }
+
+ tempbx = tempbx & 0x00FF;
+
+ if (!(modeflag & HalfDCLK)) {
+ tempcx = pVBInfo->VGAHDE;
+ if (tempcx >= pVBInfo->HDE) {
+ tempbx |= 0x2000;
+ tempax &= 0x00FF;
+ }
+ }
+
+ tempcx = 0x0101;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b */
+ if (pVBInfo->VGAHDE >= 1024) {
+ tempcx = 0x1920;
+ if (pVBInfo->VGAHDE >= 1280) {
+ tempcx = 0x1420;
+ tempbx = tempbx & 0xDFFF;
+ }
+ }
+ }
+
+ if (!(tempbx & 0x2000)) {
+ if (modeflag & HalfDCLK) {
+ tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
+ }
+
+ push1 = tempbx;
+ tempeax = pVBInfo->VGAHDE;
+ tempebx = (tempcx & 0xFF00) >> 8;
+ longtemp = tempeax * tempebx;
+ tempecx = tempcx & 0x00FF;
+ longtemp = longtemp / tempecx;
+
+ /* 301b */
+ tempecx = 8 * 1024;
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ tempecx = tempecx * 8;
+ }
+
+ longtemp = longtemp * tempecx;
+ tempecx = pVBInfo->HDE;
+ temp2 = longtemp % tempecx;
+ tempeax = longtemp / tempecx;
+ if (temp2 != 0) {
+ tempeax += 1;
+ }
+
+ tempax = (USHORT) tempeax;
+
+ /* 301b */
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+ }
+ /* end 301b */
+
+ tempbx = push1;
+ tempbx =
+ (USHORT) (((tempeax & 0x0000FF00) & 0x1F00) | (tempbx & 0x00FF));
+ tempax = (USHORT) (((tempeax & 0x000000FF) << 8) | (tempax & 0x00FF));
+ temp = (tempax & 0xFF00) >> 8;
+ }
+ else {
+ temp = (tempax & 0x00FF) >> 8;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x44, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x45, ~0x03F, temp);
+ temp = tempcx & 0x00FF;
+
+ if (tempbx & 0x2000)
+ temp = 0;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ temp |= 0x18;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, ~0x1F, temp);
+ if (pVBInfo->TVInfo & SetPALTV) {
+ tempbx = 0x0382;
+ tempcx = 0x007e;
+ }
+ else {
+ tempbx = 0x0369;
+ tempcx = 0x0061;
+ }
+
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4b, temp);
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4c, temp);
+
+ temp = ((tempcx & 0xFF00) >> 8) & 0x03;
+ temp = temp << 2;
+ temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ temp |= 0x10;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ temp |= 0x20;
+
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ temp |= 0x60;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d, temp);
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43); /* 301b change */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, (USHORT) (temp - 3));
+
+ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
+ if (pVBInfo->TVInfo & NTSC1024x768) {
+ TimingPoint = XGI_NTSC1024AdjTime;
+ for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
+ TimingPoint[j]);
+ }
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, 0x72);
+ }
+ }
+
+ /* [ycchen] 01/14/03 Modify for 301C PALM Support */
+ if (pVBInfo->VBType & VB_XGI301C) {
+ if (pVBInfo->TVInfo & SetPALMTV)
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x08, 0x08); /* PALM Mode */
+ }
+
+ if (pVBInfo->TVInfo & SetPALMTV) {
+ tempax = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01);
+ tempax--;
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, tempax);
+
+ /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xEF);
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+ if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, 0x00);
+ }
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ return;
+ }
+ ErrorF("5935 Part2 0 = %x ",
+ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDRegs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT push1,
+ push2,
+ pushbx,
+ tempax,
+ tempbx,
+ tempcx, temp, tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
+
+ XGI_LCDDesStruct *LCDBDesPtr = NULL;
+ XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
+
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ }
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
+ return;
+ }
+
+ tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+
+ tempbx -= 1;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2C, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2B, 0x0F, temp);
+ temp = 0x01;
+
+ if (pVBInfo->LCDResInfo == Panel1280x1024) {
+ if (pVBInfo->ModeType == ModeEGA) {
+ if (pVBInfo->VGAHDE >= 1024) {
+ temp = 0x02;
+ if (pVBInfo->LCDInfo & LCDVESATiming)
+ temp = 0x01;
+ }
+ }
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, temp);
+ tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
+ push1 = tempbx;
+ tempbx--;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x03, temp);
+ temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0C, ~0x07, temp);
+
+ tempcx = pVBInfo->VT - 1;
+ push2 = tempcx + 1;
+ temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x19, temp);
+ temp = (tempcx & 0xFF00) >> 8;
+ temp = temp << 5;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, temp);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
+
+ /* Customized LCDB Des no add */
+ LCDBDesPtr = (XGI_LCDDesStruct *) XGI_GetLcdPtr(5, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) {
+ tempbx = pVBInfo->HDE;
+ tempcx = pVBInfo->VDE;
+ }
+ else {
+ get_HDE_VDE(pVBInfo, & tempbx, & tempcx);
+ }
+
+ pushbx = tempbx;
+ tempax = pVBInfo->VT;
+ pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
+ pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
+ pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
+ pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
+ tempbx = pVBInfo->LCDVDES;
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax; /* lcdvdes */
+
+ temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x05, temp);
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x06, temp);
+ tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
+ tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
+ tempah = tempch;
+ tempah = tempah << 3;
+ tempah |= tempbh;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, tempah);
+
+ /* getlcdsync() */
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ if (pVBInfo->LCDInfo & EnableScalingLCD) {
+ LCDPtr1 =
+ (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ tempbx = LCDPtr1->LCDVSync;
+ }
+ tempcx = tempbx;
+ tempax = pVBInfo->VT;
+ tempbx = pVBInfo->LCDVRS;
+
+ /* if ( SetLCD_Info & EnableScalingLCD ) */
+ tempcx += tempbx;
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x04, temp);
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ temp |= (tempcx & 0x000F);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
+ tempcx = pushbx;
+ tempax = pVBInfo->HT;
+ tempbx = pVBInfo->LCDHDES;
+ tempbx &= 0x0FFF;
+
+ if (XGI_IsLCDDualLink(pVBInfo)) {
+ tempax = tempax >> 1;
+ tempbx = tempbx >> 1;
+ tempcx = tempcx >> 1;
+ }
+
+ if (pVBInfo->VBType & VB_XGI302LV)
+ tempbx += 1;
+
+ if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
+ tempbx += 1;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
+ temp = ((tempbx & 0xFF00) >> 8) << 4;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x20, temp);
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
+ temp = (tempcx & 0xFF00) >> 8;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, temp);
+
+ /* getlcdsync() */
+ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+ if (pVBInfo->LCDInfo & EnableScalingLCD) {
+ LCDPtr1 =
+ (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
+ RefreshRateTableIndex,
+ pVBInfo);
+ tempax = LCDPtr1->LCDHSync;
+ }
+ tempcx = tempax;
+ tempax = pVBInfo->HT;
+ tempbx = pVBInfo->LCDHRS;
+ /* if ( SetLCD_Info & EnableScalingLCD) */
+ if (XGI_IsLCDDualLink(pVBInfo)) {
+ tempax = tempax >> 1;
+ tempbx = tempbx >> 1;
+ tempcx = tempcx >> 1;
+ }
+
+ if (pVBInfo->VBType & VB_XGI302LV)
+ tempbx += 1;
+
+ tempcx += tempbx;
+
+ if (tempcx >= tempax)
+ tempcx -= tempax;
+
+ temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1C, temp);
+
+ temp = (tempbx & 0xFF00) >> 8;
+ temp = temp << 4;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
+ temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x21, temp);
+
+ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+ if (pVBInfo->VGAVDE == 525) {
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C)) {
+ temp = 0xC6;
+ }
+ else
+ temp = 0xC4;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, 0xB3);
+ }
+
+ if (pVBInfo->VGAVDE == 420) {
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C)) {
+ temp = 0x4F;
+ }
+ else
+ temp = 0x4E;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTap4Ptr */
+/* Input : */
+/* Output : di -> Tap4 Reg. Setting Pointer */
+/* Description : */
+/* --------------------------------------------------------------------- */
+const XGI301C_Tap4TimingStruct *
+XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, tempbx, i;
+
+ const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+
+ if (tempcx == 0) {
+ tempax = pVBInfo->VGAHDE;
+ tempbx = pVBInfo->HDE;
+ }
+ else {
+ tempax = pVBInfo->VGAVDE;
+ tempbx = pVBInfo->VDE;
+ }
+
+ if (tempax < tempbx)
+ return &EnlargeTap4Timing[0];
+ else if (tempax == tempbx)
+ return &NoScaleTap4Timing[0]; /* 1:1 */
+ else
+ Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ Tap4TimingPtr = PALTap4Timing;
+
+
+ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ Tap4TimingPtr = YPbPr525iTap4Timing;
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ Tap4TimingPtr = YPbPr525pTap4Timing;
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ Tap4TimingPtr = YPbPr750pTap4Timing;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ Tap4TimingPtr = HiTVTap4Timing;
+
+ i = 0;
+ while (Tap4TimingPtr[i].DE != 0xFFFF) {
+ if (Tap4TimingPtr[i].DE == tempax)
+ break;
+ i++;
+ }
+ return &Tap4TimingPtr[i];
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetTap4Regs */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo)
+{
+
+#ifndef LINUX_XF86
+ USHORT tempcx;
+#endif
+ USHORT i, j;
+
+ const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+
+ if (!(pVBInfo->VBType & VB_XGI301C))
+ return;
+
+#ifndef Tap4
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
+#else /* Tap4 Setting */
+
+ Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
+ for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
+ Tap4TimingPtr->Reg[j]);
+
+ if ((pVBInfo->VBInfo & SetCRT2ToTV)
+ && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
+ Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
+ for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
+ Tap4TimingPtr->Reg[j]);
+ }
+
+ if ((pVBInfo->VBInfo & SetCRT2ToTV)
+ && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
+ else
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
+#endif
+}
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetGroup3 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT i;
+ const UCHAR *tempdi;
+ USHORT modeflag;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ }
+
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x00, 0x00);
+ if (pVBInfo->TVInfo & SetPALTV) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xF5);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xB7);
+ }
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ return;
+ }
+
+ if (pVBInfo->TVInfo & SetPALMTV) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x3D, 0xA8);
+ }
+
+ if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ || (pVBInfo->VBInfo & SetCRT2ToYPbPr)) {
+ if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+ return;
+ }
+ tempdi = pVBInfo->HiTVGroup3Data;
+ if (pVBInfo->SetFlag & TVSimuMode) {
+ tempdi = pVBInfo->HiTVGroup3Simu;
+ if (!(modeflag & Charx8Dot)) {
+ tempdi = pVBInfo->HiTVGroup3Text;
+ }
+ }
+
+ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+ tempdi = pVBInfo->Ren525pGroup3;
+ }
+ if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+ tempdi = pVBInfo->Ren750pGroup3;
+ }
+
+ for (i = 0; i <= 0x3E; i++) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, i, tempdi[i]);
+ }
+ if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
+ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x28, 0x3f);
+ }
+ }
+ }
+ return;
+} /* {end of XGI_SetGroup3} */
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetGroup4 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, tempcx, tempbx, modeflag, temp, temp2;
+#ifndef LINUX_XF86
+ USHORT push1;
+#endif
+
+ ULONG tempebx, tempeax, templong;
+
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+ }
+
+ temp = pVBInfo->RVBHCFACT;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x13, temp);
+
+ tempbx = pVBInfo->RVBHCMAX;
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x14, temp);
+ temp2 = ((tempbx & 0xFF00) >> 8) << 7;
+ tempcx = pVBInfo->VGAHT - 1;
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x16, temp);
+
+ temp = ((tempcx & 0xFF00) >> 8) << 3;
+ temp2 |= temp;
+
+ tempcx = pVBInfo->VGAVT - 1;
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ tempcx -= 5;
+ }
+
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x17, temp);
+ temp = temp2 | ((tempcx & 0xFF00) >> 8);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x15, temp);
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, 0x08);
+ tempcx = pVBInfo->VBInfo;
+ tempbx = pVBInfo->VGAHDE;
+
+ if (modeflag & HalfDCLK) {
+ tempbx = tempbx >> 1;
+ }
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+
+ if (tempcx & SetCRT2ToHiVisionTV) {
+ temp = 0;
+ if (tempbx <= 1024)
+ temp = 0xA0;
+ if (tempbx == 1280)
+ temp = 0xC0;
+ }
+ else if (tempcx & SetCRT2ToTV) {
+ temp = 0xA0;
+ if (tempbx <= 800)
+ temp = 0x80;
+ }
+ else {
+ temp = 0x80;
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ temp = 0;
+ if (tempbx > 800)
+ temp = 0x60;
+ }
+ }
+
+ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
+ temp = 0x00;
+ if (pVBInfo->VGAHDE == 1280)
+ temp = 0x40;
+ if (pVBInfo->VGAHDE == 1024)
+ temp = 0x20;
+ }
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
+
+ tempebx = pVBInfo->VDE;
+
+ if (tempcx & SetCRT2ToHiVisionTV) {
+ if (!(temp & 0xE000))
+ tempbx = tempbx >> 1;
+ }
+
+ tempcx = pVBInfo->RVBHRS;
+ temp = tempcx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x18, temp);
+
+ tempeax = pVBInfo->VGAVDE;
+ tempcx |= 0x04000;
+
+
+ if (tempeax <= tempebx) {
+ tempcx = (tempcx & (~0x4000));
+ tempeax = pVBInfo->VGAVDE;
+ }
+ else {
+ tempeax -= tempebx;
+ }
+
+
+ templong = (tempeax * 256 * 1024) % tempebx;
+ tempeax = (tempeax * 256 * 1024) / tempebx;
+ tempebx = tempeax;
+
+ if (templong != 0) {
+ tempebx++;
+ }
+
+
+ temp = (USHORT) (tempebx & 0x000000FF);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1B, temp);
+
+ temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1A, temp);
+ tempbx = (USHORT) (tempebx >> 16);
+ temp = tempbx & 0x00FF;
+ temp = temp << 4;
+ temp |= ((tempcx & 0xFF00) >> 8);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x19, temp);
+
+ /* 301b */
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ temp = 0x0028;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1C, temp);
+ tempax = pVBInfo->VGAHDE;
+ if (modeflag & HalfDCLK) {
+ tempax = tempax >> 1;
+ }
+
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempax = tempax >> 1;
+
+ /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
+ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+ if (tempax > 800)
+ tempax -= 800;
+ }
+ else {
+ if (pVBInfo->VGAHDE > 800) {
+ if (pVBInfo->VGAHDE == 1024)
+ tempax = (tempax * 25 / 32) - 1;
+ else
+ tempax = (tempax * 20 / 32) - 1;
+ }
+ }
+ tempax -= 1;
+
+/*
+ if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
+ {
+ if ( pVBInfo->VBType & VB_XGI301LV )
+ {
+ if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
+ {
+ if ( pVBInfo->VGAHDE > 800 )
+ {
+ if ( pVBInfo->VGAHDE == 1024 )
+ tempax = ( tempax * 25 / 32 ) - 1 ;
+ else
+ tempax = ( tempax * 20 / 32 ) - 1 ;
+ }
+ }
+ }
+ else
+ {
+ if ( pVBInfo->VGAHDE > 800 )
+ {
+ if ( pVBInfo->VGAHDE == 1024 )
+ tempax = ( tempax * 25 / 32 ) - 1 ;
+ else
+ tempax = ( tempax * 20 / 32 ) - 1 ;
+ }
+ }
+ }
+*/
+
+ temp = (tempax & 0xFF00) >> 8;
+ temp = ((temp & 0x0003) << 4);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, temp);
+ temp = (tempax & 0x00FF);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1D, temp);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+ if (pVBInfo->VGAHDE > 800) {
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, 0x08);
+ }
+ }
+ temp = 0x0036;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ if (!
+ (pVBInfo->
+ TVInfo & (NTSC1024x768 | SetYPbPrMode525p | SetYPbPrMode750p
+ | SetYPbPrMode1080i))) {
+ temp |= 0x0001;
+ if ((pVBInfo->VBInfo & SetInSlaveMode)
+ && (!(pVBInfo->TVInfo & TVSimuMode)))
+ temp &= (~0x0001);
+ }
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, 0x00C0,
+ temp);
+ tempbx = pVBInfo->HT;
+ if (XGI_IsLCDDualLink(pVBInfo))
+ tempbx = tempbx >> 1;
+ tempbx = (tempbx >> 1) - 2;
+ temp = ((tempbx & 0x0700) >> 8) << 3;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, 0x00C0,
+ temp);
+ temp = tempbx & 0x00FF;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x22, temp);
+ }
+ /* end 301b */
+
+ if (pVBInfo->ISXPDOS == 0)
+ XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetGroup5 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT Pindex, Pdata;
+
+ Pindex = pVBInfo->Part5Port;
+ Pdata = pVBInfo->Part5Port + 1;
+ if (pVBInfo->ModeType == ModeVGA) {
+ if (!
+ (pVBInfo->
+ VBInfo & (SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag))) {
+ XGINew_EnableCRT2(pVBInfo);
+ /* LoadDAC2(pVBInfo->Part5Port,ModeNo,ModeIdIndex); */
+ }
+ }
+ return;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetLcdPtr */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+const void *
+XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT i, tempdx, tempcx, tempbx, tempal, modeflag, table;
+
+ const XGI330_LCDDataTablStruct *tempdi = 0;
+
+
+ tempbx = BX;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
+ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x14) {
+ tempal = 0x0A;
+ }
+ else if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0F) {
+ tempal = 0x0B;
+ }
+ }
+
+ tempal = tempal & 0x0f;
+
+ if (tempbx <= 1) { /* ExpLink */
+ if (ModeNo <= 0x13) {
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
+ }
+ else {
+ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if (ModeNo <= 0x13)
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
+ else
+ tempal =
+ pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
+ }
+
+ if (tempbx & 0x01)
+ tempal = (tempal >> 4);
+
+ tempal = (tempal & 0x0f);
+ }
+
+ tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
+ if ((tempbx == 5) || (tempbx) == 7)
+ tempcx = LCDDesDataLen2;
+ else if ((tempbx == 3) || (tempbx == 8))
+ tempcx = LVDSDesDataLen2;
+ }
+ /* mov di, word ptr cs:LCDDataList[bx] */
+ /* tempdi=pVideoMemory[LCDDataList+tempbx*2]|(pVideoMemory[LCDDataList+tempbx*2+1]<<8); */
+
+ switch (tempbx) {
+ case 0:
+ tempdi = XGI_EPLLCDCRT1Ptr_H;
+ break;
+ case 1:
+ tempdi = XGI_EPLLCDCRT1Ptr_V;
+ break;
+ case 2:
+ tempdi = XGI_EPLLCDDataPtr;
+ break;
+ case 3:
+ tempdi = XGI_EPLLCDDesDataPtr;
+ break;
+ case 4:
+ tempdi = XGI_LCDDataTable;
+ break;
+ case 5:
+ tempdi = XGI_LCDDesDataTable;
+ break;
+ case 6:
+ tempdi = XGI_EPLCHLCDRegPtr;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ tempdi = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (tempdi == 0x00) /* OEMUtil */
+ return 0;
+
+ table = tempbx;
+ i = 0;
+
+ while (tempdi[i].PANELID != 0xff) {
+ tempdx = pVBInfo->LCDResInfo;
+ if (tempbx & 0x0080) { /* OEMUtil */
+ tempbx &= (~0x0080);
+ tempdx = pVBInfo->LCDTypeInfo;
+ }
+
+ if (pVBInfo->LCDInfo & EnableScalingLCD) {
+ if ((pVBInfo->LCDInfo & EnableReduceTiming)
+ && (pVBInfo->LCDResInfo == Panel1600x1200)) {
+ tempdx = Panel1600x1200_1;
+ }
+ else {
+ tempdx &= (~PanelResInfo);
+ }
+ }
+ if (tempdi[i].PANELID == tempdx) {
+ tempbx = tempdi[i].MASK;
+ tempdx = pVBInfo->LCDInfo;
+
+ if (ModeNo <= 0x13) /* alan 09/10/2003 */
+ tempdx |= SetLCDStdMode;
+
+ if (modeflag & HalfDCLK)
+ tempdx |= SetLCDLowResolution;
+
+ tempbx &= tempdx;
+ if (tempbx == tempdi[i].CAP)
+ break;
+ }
+ i++;
+ }
+
+ if (table == 0) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDSCRT11024x768_1_H[tempal];
+ break;
+ case 1:
+ return &XGI_LVDSCRT11024x768_2_H[tempal];
+ break;
+ case 2:
+ return &XGI_LVDSCRT11280x1024_1_H[tempal];
+ break;
+ case 3:
+ return &XGI_LVDSCRT11280x1024_2_H[tempal];
+ break;
+ case 4:
+ return &XGI_LVDSCRT11400x1050_1_H[tempal];
+ break;
+ case 5:
+ return &XGI_LVDSCRT11400x1050_2_H[tempal];
+ break;
+ case 6:
+ return &XGI_LVDSCRT11600x1200_1_H[tempal];
+ break;
+ case 7:
+ return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
+ break;
+ case 8:
+ return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
+ break;
+ case 9:
+ return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 1) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDSCRT11024x768_1_V[tempal];
+ break;
+ case 1:
+ return &XGI_LVDSCRT11024x768_2_V[tempal];
+ break;
+ case 2:
+ return &XGI_LVDSCRT11280x1024_1_V[tempal];
+ break;
+ case 3:
+ return &XGI_LVDSCRT11280x1024_2_V[tempal];
+ break;
+ case 4:
+ return &XGI_LVDSCRT11400x1050_1_V[tempal];
+ break;
+ case 5:
+ return &XGI_LVDSCRT11400x1050_2_V[tempal];
+ break;
+ case 6:
+ return &XGI_LVDSCRT11600x1200_1_V[tempal];
+ break;
+ case 7:
+ return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
+ break;
+ case 8:
+ return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
+ break;
+ case 9:
+ return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 2) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDS1024x768Data_1[tempal];
+ break;
+ case 1:
+ return &XGI_LVDS1024x768Data_2[tempal];
+ break;
+ case 2:
+ return &XGI_LVDS1280x1024Data_1[tempal];
+ break;
+ case 3:
+ return &XGI_LVDS1280x1024Data_2[tempal];
+ break;
+ case 4:
+ return &XGI_LVDS1400x1050Data_1[tempal];
+ break;
+ case 5:
+ return &XGI_LVDS1400x1050Data_2[tempal];
+ break;
+ case 6:
+ return &XGI_LVDS1600x1200Data_1[tempal];
+ break;
+ case 7:
+ return &XGI_LVDSNoScalingData[tempal];
+ break;
+ case 8:
+ return &XGI_LVDS1024x768Data_1x75[tempal];
+ break;
+ case 9:
+ return &XGI_LVDS1024x768Data_2x75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDS1280x1024Data_1x75[tempal];
+ break;
+ case 11:
+ return &XGI_LVDS1280x1024Data_2x75[tempal];
+ break;
+ case 12:
+ return &XGI_LVDSNoScalingDatax75[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 3) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_LVDS1024x768Des_1[tempal];
+ break;
+ case 1:
+ return &XGI_LVDS1024x768Des_3[tempal];
+ break;
+ case 2:
+ return &XGI_LVDS1024x768Des_2[tempal];
+ break;
+ case 3:
+ return &XGI_LVDS1280x1024Des_1[tempal];
+ break;
+ case 4:
+ return &XGI_LVDS1280x1024Des_2[tempal];
+ break;
+ case 5:
+ return &XGI_LVDS1400x1050Des_1[tempal];
+ break;
+ case 6:
+ return &XGI_LVDS1400x1050Des_2[tempal];
+ break;
+ case 7:
+ return &XGI_LVDS1600x1200Des_1[tempal];
+ break;
+ case 8:
+ return &XGI_LVDSNoScalingDesData[tempal];
+ break;
+ case 9:
+ return &XGI_LVDS1024x768Des_1x75[tempal];
+ break;
+ case 10:
+ return &XGI_LVDS1024x768Des_3x75[tempal];
+ break;
+ case 11:
+ return &XGI_LVDS1024x768Des_2x75[tempal];
+ break;
+ case 12:
+ return &XGI_LVDS1280x1024Des_1x75[tempal];
+ break;
+ case 13:
+ return &XGI_LVDS1280x1024Des_2x75[tempal];
+ break;
+ case 14:
+ return &XGI_LVDSNoScalingDesDatax75[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 4) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_ExtLCD1024x768Data[tempal];
+ break;
+ case 1:
+ return &XGI_StLCD1024x768Data[tempal];
+ break;
+ case 2:
+ return &XGI_CetLCD1024x768Data[tempal];
+ break;
+ case 3:
+ return &XGI_ExtLCD1280x1024Data[tempal];
+ break;
+ case 4:
+ return &XGI_StLCD1280x1024Data[tempal];
+ break;
+ case 5:
+ return &XGI_CetLCD1280x1024Data[tempal];
+ break;
+ case 6:
+ return &XGI_ExtLCD1400x1050Data[tempal];
+ break;
+ case 7:
+ return &XGI_StLCD1400x1050Data[tempal];
+ break;
+ case 8:
+ return &XGI_CetLCD1400x1050Data[tempal];
+ break;
+ case 9:
+ return &XGI_ExtLCD1600x1200Data[tempal];
+ break;
+ case 10:
+ return &XGI_StLCD1600x1200Data[tempal];
+ break;
+ case 11:
+ return &XGI_NoScalingData[tempal];
+ break;
+ case 12:
+ return &XGI_ExtLCD1024x768x75Data[tempal];
+ break;
+ case 13:
+ return &XGI_ExtLCD1024x768x75Data[tempal];
+ break;
+ case 14:
+ return &XGI_CetLCD1024x768x75Data[tempal];
+ break;
+ case 15:
+ return &XGI_ExtLCD1280x1024x75Data[tempal];
+ break;
+ case 16:
+ return &XGI_StLCD1280x1024x75Data[tempal];
+ break;
+ case 17:
+ return &XGI_CetLCD1280x1024x75Data[tempal];
+ break;
+ case 18:
+ return &XGI_NoScalingDatax75[tempal];
+ break;
+ case 19:
+ return &XGI_NoScalingData_1[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 5) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_ExtLCDDes1024x768Data[tempal];
+ break;
+ case 1:
+ return &XGI_StLCDDes1024x768Data[tempal];
+ break;
+ case 2:
+ return &XGI_CetLCDDes1024x768Data[tempal];
+ break;
+ case 3:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1280x1024Data[tempal];
+ else
+ return &XGI_ExtLCDDes1280x1024Data[tempal];
+ break;
+ case 4:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_StLCDDLDes1280x1024Data[tempal];
+ else
+ return &XGI_StLCDDes1280x1024Data[tempal];
+ break;
+ case 5:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_CetLCDDLDes1280x1024Data[tempal];
+ else
+ return &XGI_CetLCDDes1280x1024Data[tempal];
+ break;
+ case 6:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1400x1050Data[tempal];
+ else
+ return &XGI_ExtLCDDes1400x1050Data[tempal];
+ break;
+ case 7:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_StLCDDLDes1400x1050Data[tempal];
+ else
+ return &XGI_StLCDDes1400x1050Data[tempal];
+ break;
+ case 8:
+ return &XGI_CetLCDDes1400x1050Data[tempal];
+ break;
+ case 9:
+ return &XGI_CetLCDDes1400x1050Data2[tempal];
+ break;
+ case 10:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1600x1200Data[tempal];
+ else
+ return &XGI_ExtLCDDes1600x1200Data[tempal];
+ break;
+ case 11:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_StLCDDLDes1600x1200Data[tempal];
+ else
+ return &XGI_StLCDDes1600x1200Data[tempal];
+ break;
+ case 12:
+ return &XGI_NoScalingDesData[tempal];
+ break;
+ case 13:
+ return &XGI_ExtLCDDes1024x768x75Data[tempal];
+ break;
+ case 14:
+ return &XGI_StLCDDes1024x768x75Data[tempal];
+ break;
+ case 15:
+ return &XGI_CetLCDDes1024x768x75Data[tempal];
+ break;
+ case 16:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
+ else
+ return &XGI_ExtLCDDes1280x1024x75Data[tempal];
+ break;
+ case 17:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_StLCDDLDes1280x1024x75Data[tempal];
+ else
+ return &XGI_StLCDDes1280x1024x75Data[tempal];
+ break;
+ case 18:
+ if ((pVBInfo->VBType & VB_XGI301LV)
+ || (pVBInfo->VBType & VB_XGI302LV))
+ return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
+ else
+ return &XGI_CetLCDDes1280x1024x75Data[tempal];
+ break;
+ case 19:
+ return &XGI_NoScalingDesDatax75[tempal];
+ break;
+ case 20:
+ return &XGI_NoScalingDesData_1[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 6) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_CH7017LV1024x768[tempal];
+ break;
+ case 1:
+ return &XGI_CH7017LV1400x1050[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtr */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+const void *
+XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT i, tempdx, tempbx, tempal, modeflag, table;
+ const XGI330_TVDataTablStruct *tempdi = NULL;
+
+ tempbx = BX;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+ }
+
+ tempal = tempal & 0x3f;
+ table = tempbx;
+
+ switch (tempbx) {
+ case 0:
+ tempdi = 0; /*EPLCHTVCRT1Ptr_H; */
+ break;
+ case 1:
+ tempdi = 0; /*EPLCHTVCRT1Ptr_V; */
+ break;
+ case 2:
+ tempdi = XGI_EPLCHTVDataPtr;
+ break;
+ case 3:
+ tempdi = 0;
+ break;
+ case 4:
+ tempdi = XGI_TVDataTable;
+ break;
+ case 5:
+ tempdi = 0;
+ break;
+ case 6:
+ tempdi = XGI_EPLCHTVRegPtr;
+ break;
+ default:
+ break;
+ }
+
+ if (tempdi == 0x00) /* OEMUtil */
+ return (0);
+
+ tempdx = pVBInfo->TVInfo;
+
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempdx = tempdx | SetTVLockMode;
+
+ if (modeflag & HalfDCLK)
+ tempdx = tempdx | SetTVLowResolution;
+
+ i = 0;
+
+ while (tempdi[i].MASK != 0xffff) {
+ if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
+ break;
+ i++;
+ }
+
+ if (table == 0x04) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_ExtPALData[tempal];
+ break;
+ case 1:
+ return &XGI_ExtNTSCData[tempal];
+ break;
+ case 2:
+ return &XGI_StPALData[tempal];
+ break;
+ case 3:
+ return &XGI_StNTSCData[tempal];
+ break;
+ case 4:
+ return &XGI_ExtHiTVData[tempal];
+ break;
+ case 5:
+ return &XGI_St2HiTVData[tempal];
+ break;
+ case 6:
+ return &XGI_ExtYPbPr525iData[tempal];
+ break;
+ case 7:
+ return &XGI_ExtYPbPr525pData[tempal];
+ break;
+ case 8:
+ return &XGI_ExtYPbPr750pData[tempal];
+ break;
+ case 9:
+ return &XGI_StYPbPr525iData[tempal];
+ break;
+ case 10:
+ return &XGI_StYPbPr525pData[tempal];
+ break;
+ case 11:
+ return &XGI_StYPbPr750pData[tempal];
+ break;
+ case 12: /* avoid system hang */
+ return &XGI_ExtNTSCData[tempal];
+ break;
+ case 13:
+ return &XGI_St1HiTVData[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 0x02) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_CHTVUNTSCData[tempal];
+ break;
+ case 1:
+ return &XGI_CHTVONTSCData[tempal];
+ break;
+ case 2:
+ return &XGI_CHTVUPALData[tempal];
+ break;
+ case 3:
+ return &XGI_CHTVOPALData[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ else if (table == 0x06) {
+ switch (tempdi[i].DATAPTR) {
+ case 0:
+ return &XGI_CHTVRegUNTSC[tempal];
+ break;
+ case 1:
+ return &XGI_CHTVRegONTSC[tempal];
+ break;
+ case 2:
+ return &XGI_CHTVRegUPAL[tempal];
+ break;
+ case 3:
+ return &XGI_CHTVRegOPAL[tempal];
+ break;
+ default:
+ break;
+ }
+ }
+ return (0);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_BacklightByDrv */
+/* Input : */
+/* Output : TRUE -> Skip backlight control */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR tempah;
+
+ tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3A);
+ if (tempah & BacklightControlBit)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_FirePWDDisable */
+/* Input : */
+/* Output : */
+/* Description : Turn off VDD & Backlight : Fire disable procedure */
+/* --------------------------------------------------------------------- */
+/*
+void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
+{
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
+}
+*/
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_FirePWDEnable */
+/* Input : */
+/* Output : */
+/* Description : Turn on VDD & Backlight : Fire enable procedure */
+/* --------------------------------------------------------------------- */
+void
+XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x26, 0x03, 0xFC);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_EnableGatingCRT */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x40);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_DisableGatingCRT */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x00);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetPanelDelay */
+/* Input : */
+/* Output : */
+/* Description : */
+/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
+/* : bl : 2 ; T2 : the duration signal on and Vdd on */
+/* : bl : 3 ; T3 : the duration between CPL off and signal off */
+/* : bl : 4 ; T4 : the duration signal off and Vdd off */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT index;
+#ifndef LINUX_XF86
+ USHORT temp;
+#endif
+
+ index = XGI_GetLCDCapPtr(pVBInfo);
+
+ if (tempbl == 1)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S1, pVBInfo);
+
+ if (tempbl == 2)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S2, pVBInfo);
+
+ if (tempbl == 3)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S3, pVBInfo);
+
+ if (tempbl == 4)
+ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S4, pVBInfo);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetPanelPower */
+/* Input : */
+/* Output : */
+/* Description : */
+/* I/O : ah = 0011b = 03h ; Backlight on, Power on */
+/* = 0111b = 07h ; Backlight on, Power off */
+/* = 1011b = 0Bh ; Backlight off, Power on */
+/* = 1111b = 0Fh ; Backlight off, Power off */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+{
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x26, tempbl,
+ tempah);
+ else
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x11, tempbl, tempah);
+}
+
+/* Jong 10/04/2007; merge code */
+UCHAR XG21GPIODataTransfer(UCHAR ujDate)
+{
+ UCHAR ujRet = 0;
+ UCHAR i = 0;
+
+ for (i=0; i<8; i++)
+ {
+ ujRet = ujRet << 1;
+ /* ujRet |= GETBITS(ujDate >> i, 0:0); */
+ ujRet |= (ujDate >> i) & 1;
+ }
+
+ return ujRet;
+}
+
+/* Jong 10/04/2007; merge code */
+/*----------------------------------------------------------------------------*/
+/* output */
+/* bl[5] : LVDS signal */
+/* bl[1] : LVDS backlight */
+/* bl[0] : LVDS VDD */
+/*----------------------------------------------------------------------------*/
+UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CR4A,temp;
+
+ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x23 ) ; /* enable GPIO write */
+
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
+
+ temp = XG21GPIODataTransfer(temp);
+ temp &= 0x23;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , CR4A ) ;
+ return temp;
+}
+
+/* Jong 10/04/2007; merge code */
+/*----------------------------------------------------------------------------*/
+/* output */
+/* bl[5] : LVDS signal */
+/* bl[1] : LVDS backlight */
+/* bl[0] : LVDS VDD */
+/*----------------------------------------------------------------------------*/
+UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CR4A,CRB4,temp;
+
+ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x0C ) ; /* enable GPIO write */
+
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
+
+ temp &= 0x0C;
+ temp >>= 2;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , CR4A ) ;
+ CRB4 = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 ) ;
+ temp |= ((CRB4&0x04)<<3);
+ return temp;
+}
+
+/* Jong 10/04/2007; merge code */
+/*----------------------------------------------------------------------------*/
+/* input */
+/* bl[5] : 1;LVDS signal on */
+/* bl[1] : 1;LVDS backlight on */
+/* bl[0] : 1:LVDS VDD on */
+/* bh: 100000b : clear bit 5, to set bit5 */
+/* 000010b : clear bit 1, to set bit1 */
+/* 000001b : clear bit 0, to set bit0 */
+/*----------------------------------------------------------------------------*/
+void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CR4A,temp;
+
+ CR4A = XGI_GetReg( (XGIIOADDRESS)pVBInfo->P3d4 , 0x4A ) ;
+ tempbh &= 0x23;
+ tempbl &= 0x23;
+ XGI_SetRegAND( (XGIIOADDRESS)pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
+
+ if (tempbh&0x20)
+ {
+ temp = (tempbl>>4)&0x02;
+
+ XGI_SetRegANDOR( (XGIIOADDRESS)pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
+
+ }
+
+ temp = XGI_GetReg( (XGIIOADDRESS)pVBInfo->P3d4 , 0x48 ) ;
+
+ temp = XG21GPIODataTransfer(temp);
+
+ temp &= ~tempbh;
+ temp |= tempbl;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , temp ) ;
+}
+
+/* Jong 10/04/2007; merge code */
+void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR CR4A,temp;
+ USHORT tempbh0,tempbl0;
+
+ tempbh0 = tempbh;
+ tempbl0 = tempbl;
+ tempbh0 &= 0x20;
+ tempbl0 &= 0x20;
+ tempbh0 >>= 3;
+ tempbl0 >>= 3;
+
+ if (tempbh&0x20)
+ {
+ temp = (tempbl>>4)&0x02;
+
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
+
+ }
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , ~tempbh0 , tempbl0 ) ;
+
+ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
+ tempbh &= 0x03;
+ tempbl &= 0x03;
+ tempbh <<= 2;
+ tempbl <<= 2; /* GPIOC,GPIOD */
+ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , ~tempbh , tempbl ) ;
+}
+
+/* Jong 10/04/2007; merge code */
+/* --------------------------------------------------------------------- */
+USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT index ;
+
+ index = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x36 ) ;
+ if (index<sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct))
+ {
+ return index;
+ }
+ return 0;
+}
+
+/* Jong 10/04/2007; merge code */
+/* --------------------------------------------------------------------- */
+/* Function : XGI_XG21SetPanelDelay */
+/* Input : */
+/* Output : */
+/* Description : */
+/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
+/* : bl : 2 ; T2 : the duration signal on and Vdd on */
+/* : bl : 3 ; T3 : the duration between CPL off and signal off */
+/* : bl : 4 ; T4 : the duration signal off and Vdd off */
+/* --------------------------------------------------------------------- */
+void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT index ;
+
+ index = XGI_GetLVDSOEMTableIndex( pVBInfo );
+ if ( tempbl == 1 )
+ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S1, pVBInfo ) ;
+
+ if ( tempbl == 2 )
+ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S2, pVBInfo ) ;
+
+ if ( tempbl == 3 )
+ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S3, pVBInfo ) ;
+
+ if ( tempbl == 4 )
+ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S4, pVBInfo ) ;
+}
+
+/* Jong 10/04/2007; merge code */
+BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+{
+ USHORT xres ,
+ yres ,
+ colordepth ,
+ modeflag ,
+ resindex ,
+ lvdstableindex;
+
+ resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
+ if ( ModeNo <= 0x13 )
+ {
+ xres = pVBInfo->StResInfo[ resindex ].HTotal ;
+ yres = pVBInfo->StResInfo[ resindex ].VTotal ;
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ }
+ else
+ {
+ xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
+ }
+
+ if ( !( modeflag & Charx8Dot ) )
+ {
+ xres /= 9;
+ xres *= 8;
+ }
+
+ if ( ModeNo > 0x13 )
+ {
+ if ( ( ModeNo>0x13 ) && ( modeflag & HalfDCLK ) )
+ {
+ xres *= 2 ;
+ }
+ if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
+ {
+ yres *= 2 ;
+ }
+ }
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
+ if ( xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) )
+ return FALSE;
+
+ if ( yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE) )
+ return FALSE;
+
+ if ( ModeNo > 0x13 )
+ {
+ if ( ( xres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) ) ||
+ ( yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE)) )
+ {
+ colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
+ if ( colordepth > 2 )
+ {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+/* Jong 10/04/2007; merge code */
+void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR temp;
+
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 ) ; /* D[0] 1: 18bit */
+ temp = ( temp & 1 ) << 6;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x06 , ~0x40 , temp ) ; /* SR06[6] 18bit Dither */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
+
+}
+
+/* Jong 10/04/2007; merge code */
+void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR temp;
+
+ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 ) ; /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
+ temp = ( temp & 3 ) << 6;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x06 , ~0xc0 , temp & 0x80 ) ; /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
+
+}
+
+/* Jong 10/04/2007; merge code */
+void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+{
+ UCHAR temp,Miscdata;
+ USHORT xres ,
+ yres ,
+ colordepth ,
+ modeflag ,
+ resindex ,
+ lvdstableindex ;
+ USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
+ USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
+ USHORT value;
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
+
+ temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
+ temp &= LCDPolarity;
+ Miscdata =(UCHAR) XGI_GetRegByte(pVBInfo->P3cc) ;
+
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
+
+ temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
+
+ XGI_SetXG21FPBits(pVBInfo);
+ resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
+ if ( ModeNo <= 0x13 )
+ {
+ xres = pVBInfo->StResInfo[ resindex ].HTotal ;
+ yres = pVBInfo->StResInfo[ resindex ].VTotal ;
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ }
+ else
+ {
+ xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
+ }
+
+ if (!( modeflag & Charx8Dot ))
+ xres = xres * 8 / 9;
+
+ LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
+
+ LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
+ if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
+ {
+ LVDSHBS -= xres/4 ;
+ }
+ if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
+
+ LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
+ if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
+
+ LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
+ if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
+
+ LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
+
+ LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
+
+ LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
+ if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
+ {
+ LVDSVBS += yres/2 ;
+ }
+ if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
+
+ LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
+ if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
+
+ LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
+ if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
+
+ LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
+
+ temp = ( UCHAR )XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
+
+ if (!( modeflag & Charx8Dot ))
+ {
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1 , 0x1 ) ;
+ }
+
+ /* HT SR0B[1:0] CR00 */
+ value = ( LVDSHT >> 3 ) - 5;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
+
+ /* HBS SR0B[5:4] CR02 */
+ value = ( LVDSHBS >> 3 ) - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
+
+ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
+ value = ( LVDSHBE >> 3 ) - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
+
+ /* HRS SR0B[7:6] CR04 */
+ value = ( LVDSHRS >> 3 ) + 2;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
+
+ /* Panel HRS SR2F[1:0] SR2E[7:0] */
+ value--;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
+
+ /* HRE SR0C[2] CR05[4:0] */
+ value = ( LVDSHRE >> 3 ) + 2;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
+
+ /* Panel HRE SR2F[7:2] */
+ value--;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
+
+ /* VT SR0A[0] CR07[5][0] CR06 */
+ value = LVDSVT - 2 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
+
+ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
+ value = LVDSVBS - 1 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
+
+ /* VBE SR0A[4] CR16 */
+ value = LVDSVBE - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
+
+ /* VRS SR0A[3] CR7[7][2] CR10 */
+ value = LVDSVRS - 1 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
+
+ /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0x03 , ( value & 0x600 ) >> 9 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , (value >> 1) & 0xFF ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x33 , ~0x01 , value & 0x01 ) ;
+
+ /* VRE SR0A[5] CR11[3:0] */
+ value = LVDSVRE - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
+
+ /* Panel VRE SR3F[7:2] */ /* SR3F[7] has to be 0, h/w bug */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0x7C ) ;
+
+ for ( temp=0, value = 0; temp < 3; temp++)
+ {
+
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
+ value += 0x10;
+ }
+
+ if (!( modeflag & Charx8Dot ))
+ {
+ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x13 ) ; /* set index */
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
+
+ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* Enable Attribute */
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x20 ) ;
+
+ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
+ }
+
+
+}
+
+/* Jong 10/04/2007; merge code */
+/* no shadow case */
+void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
+{
+ UCHAR temp,Miscdata;
+ USHORT xres ,
+ yres ,
+ colordepth ,
+ modeflag ,
+ resindex ,
+ lvdstableindex ;
+ USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
+ USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
+ USHORT value;
+
+ lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
+ temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
+ temp &= LCDPolarity;
+ Miscdata =(UCHAR) XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3cc) ;
+
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
+
+ temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
+
+ XGI_SetXG27FPBits(pVBInfo);
+ resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
+ if ( ModeNo <= 0x13 )
+ {
+ xres = pVBInfo->StResInfo[ resindex ].HTotal ;
+ yres = pVBInfo->StResInfo[ resindex ].VTotal ;
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+ }
+ else
+ {
+ xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
+ yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
+ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
+ }
+
+ if (!( modeflag & Charx8Dot ))
+ xres = xres * 8 / 9;
+
+ LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
+
+ LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
+ if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
+ {
+ LVDSHBS -= xres/4 ;
+ }
+ if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
+
+ LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
+ if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
+
+ LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
+ if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
+
+ LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
+
+ LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
+
+ LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
+ if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
+ {
+ LVDSVBS += yres/2 ;
+ }
+ if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
+
+ LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
+ if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
+
+ LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
+ if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
+
+ LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
+
+ temp = ( UCHAR )XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
+
+ if (!( modeflag & Charx8Dot ))
+ {
+ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1 , 0x1 ) ;
+ }
+
+ /* HT SR0B[1:0] CR00 */
+ value = ( LVDSHT >> 3 ) - 5;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
+
+ /* HBS SR0B[5:4] CR02 */
+ value = ( LVDSHBS >> 3 ) - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
+
+ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
+ value = ( LVDSHBE >> 3 ) - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
+
+ /* HRS SR0B[7:6] CR04 */
+ value = ( LVDSHRS >> 3 ) + 2;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
+
+ /* Panel HRS SR2F[1:0] SR2E[7:0] */
+ value--;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
+
+ /* HRE SR0C[2] CR05[4:0] */
+ value = ( LVDSHRE >> 3 ) + 2;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
+
+ /* Panel HRE SR2F[7:2] */
+ value--;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
+
+ /* VT SR0A[0] CR07[5][0] CR06 */
+ value = LVDSVT - 2 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
+
+ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
+ value = LVDSVBS - 1 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
+
+ /* VBE SR0A[4] CR16 */
+ value = LVDSVBE - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
+
+ /* VRS SR0A[3] CR7[7][2] CR10 */
+ value = LVDSVRS - 1 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
+
+ /* Panel VRS SR35[2:0] SR34[7:0] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x07 , ( value & 0x700 ) >> 8 ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , value & 0xFF ) ;
+
+ /* VRE SR0A[5] CR11[3:0] */
+ value = LVDSVRE - 1;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
+
+ /* Panel VRE SR3F[7:2] */
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0xFC ) ;
+
+ for ( temp=0, value = 0; temp < 3; temp++)
+ {
+
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
+ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
+ value += 0x10;
+ }
+
+ if (!( modeflag & Charx8Dot ))
+ {
+ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x13 ) ; /* set index */
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
+
+ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* Enable Attribute */
+ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x20 ) ;
+
+ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_IsLCDON */
+/* Input : */
+/* Output : FALSE : Skip PSC Control */
+/* TRUE: Disable PSC */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax;
+
+ tempax = pVBInfo->VBInfo;
+ if (tempax & SetCRT2ToDualEdge)
+ return FALSE;
+ else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_EnablePWD */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT index, temp;
+
+ index = XGI_GetLCDCapPtr(pVBInfo);
+ temp = pVBInfo->LCDCapList[index].PWD_2B;
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2B, temp);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2C,
+ pVBInfo->LCDCapList[index].PWD_2C);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2D,
+ pVBInfo->LCDCapList[index].PWD_2D);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2E,
+ pVBInfo->LCDCapList[index].PWD_2E);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2F,
+ pVBInfo->LCDCapList[index].PWD_2F);
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_DisablePWD */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_DisableChISLCD */
+/* Input : */
+/* Output : FALSE -> Not LCD Mode */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, tempah;
+
+ tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
+ tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
+
+ if (tempbx & (EnableChA | DisableChA)) {
+ if (!(tempah & 0x08)) /* Chk LCDA Mode */
+ return FALSE;
+ }
+
+ if (!(tempbx & (EnableChB | DisableChB)))
+ return FALSE;
+
+ if (tempah & 0x01) /* Chk LCDB Mode */
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_EnableChISLCD */
+/* Input : */
+/* Output : 0 -> Not LCD mode */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, tempah;
+
+
+ tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
+ tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
+
+ if (tempbx & (EnableChA | DisableChA)) {
+ if (!(tempah & 0x08)) /* Chk LCDA Mode */
+ return FALSE;
+ }
+
+ if (!(tempbx & (EnableChB | DisableChB)))
+ return FALSE;
+
+ if (tempah & 0x01) /* Chk LCDB Mode */
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetLCDCapPtr */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo)
+{
+ UCHAR tempal, tempah, tempbl, i;
+
+ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36);
+ tempal = tempah & 0x0F;
+ tempah = tempah & 0xF0;
+ i = 0;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+
+ while (tempbl != 0xFF) {
+ if (tempbl & 0x80) { /* OEMUtil */
+ tempal = tempah;
+ tempbl = tempbl & ~(0x80);
+ }
+
+ if (tempal == tempbl)
+ break;
+
+ i++;
+
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+ }
+
+ return i;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetLCDCapPtr1 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempah, tempal, tempbl, i;
+
+ tempal = pVBInfo->LCDResInfo;
+ tempah = pVBInfo->LCDTypeInfo;
+
+ i = 0;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+
+ while (tempbl != 0xFF) {
+ if ((tempbl & 0x80) && (tempbl != 0x80)) {
+ tempal = tempah;
+ tempbl &= ~0x80;
+ }
+
+ if (tempal == tempbl)
+ break;
+
+ i++;
+ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+ }
+
+ if (tempbl == 0xFF) {
+ pVBInfo->LCDResInfo = Panel1024x768;
+ pVBInfo->LCDTypeInfo = 0;
+ i = 0;
+ }
+
+ return i;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetLCDSync */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT Index;
+
+ Index = XGI_GetLCDCapPtr(pVBInfo);
+ *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
+ *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
+
+ return;
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_EnableBridge */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+#ifndef LINUX_XF86
+ USHORT tempax;
+#endif
+ USHORT tempbl, tempah;
+
+ if (pVBInfo->SetFlag == Win9xDOSMode) {
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ return;
+ }
+ else /* LVDS or CH7017 */
+ return;
+ }
+
+
+ if (HwDeviceExtension->jChipType < XG40) {
+ if (!XGI_DisableChISLCD(pVBInfo)) {
+ if ((XGI_EnableChISLCD(pVBInfo))
+ || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ XGI_EnablePWD(pVBInfo);
+ }
+ else {
+ pVBInfo->LCDInfo &= (~SetPWDEnable);
+ if (pVBInfo->
+ VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ tempbl = 0xFD;
+ tempah = 0x02;
+ }
+ else {
+ tempbl = 0xFB;
+ tempah = 0x00;
+ }
+
+ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+ XGI_SetPanelDelay(1, pVBInfo);
+ }
+ }
+ }
+ } /* Not 340 */
+
+
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (!(pVBInfo->SetFlag & DisableChA)) {
+ if (pVBInfo->SetFlag & EnableChA) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+ }
+ else {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+ }
+ }
+ }
+
+ if (!(pVBInfo->SetFlag & DisableChB)) {
+ if ((pVBInfo->SetFlag & EnableChB)
+ || (pVBInfo->
+ VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC)))
+ {
+ tempah =
+ (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
+ tempah &= 0xDF;
+ if (pVBInfo->VBInfo & SetInSlaveMode) {
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
+ tempah |= 0x20;
+ }
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, tempah);
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E,
+ SR1E_ENABLE_CRT2);
+
+
+ tempah =
+ (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port,
+ 0x2E);
+
+ if (!(tempah & 0x80))
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
+ }
+ }
+
+ if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
+ || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, ~0xE0, 0x20); /* shampoo 0129 */
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (!XGI_DisableChISLCD(pVBInfo)) {
+ if (XGI_EnableChISLCD(pVBInfo)
+ || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x2A, 0x7F); /* LVDS PLL power on */
+ }
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
+ }
+ }
+
+ tempah = 0x00;
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ tempah = 0xc0;
+
+ if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempah = tempah & 0x40;
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ tempah = tempah ^ 0xC0;
+
+ if (pVBInfo->SetFlag & DisableChB)
+ tempah &= 0xBF;
+
+ if (pVBInfo->SetFlag & DisableChA)
+ tempah &= 0x7F;
+
+ if (pVBInfo->SetFlag & EnableChB)
+ tempah |= 0x40;
+
+ if (pVBInfo->SetFlag & EnableChA)
+ tempah |= 0x80;
+ }
+ }
+ }
+ }
+
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
+
+ if (pVBInfo->SetFlag & Win9xDOSMode) {
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ return;
+ }
+
+ if (!(pVBInfo->SetFlag & DisableChA)) {
+ XGI_VBLongWait(pVBInfo);
+ if (!(pVBInfo->SetFlag & GatingCRT)) {
+ XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ XGI_VBLongWait(pVBInfo);
+ }
+ }
+ } /* 301 */
+ else { /* LVDS */
+
+ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA))
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
+
+
+
+ tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E);
+ if (!(tempah & 0x80))
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F);
+ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
+ } /* End of VB */
+
+
+ if (HwDeviceExtension->jChipType < XG40) {
+ if (!XGI_EnableChISLCD(pVBInfo)) {
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ if (XGI_BacklightByDrv(pVBInfo))
+ return;
+ }
+ else
+ return;
+ }
+
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ XGI_FirePWDEnable(pVBInfo);
+ return;
+ }
+
+ XGI_SetPanelDelay(2, pVBInfo);
+
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ tempah = 0x01;
+ tempbl = 0xFE; /* turn on backlght */
+ }
+ else {
+ tempbl = 0xF7;
+ tempah = 0x00;
+ }
+ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_DisableBridge */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, tempbx, tempah = 0, tempbl = 0;
+
+ if (pVBInfo->SetFlag == Win9xDOSMode)
+ return;
+
+
+ if (HwDeviceExtension->jChipType < XG40) {
+ if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+ || (XGI_DisableChISLCD(pVBInfo))) {
+ if (!XGI_IsLCDON(pVBInfo)) {
+ if (pVBInfo->LCDInfo & SetPWDEnable)
+ XGI_EnablePWD(pVBInfo);
+ else {
+ pVBInfo->LCDInfo &= ~SetPWDEnable;
+ XGI_DisablePWD(pVBInfo);
+ if (pVBInfo->
+ VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+ tempbx = 0xFE; /* not 01h */
+ tempax = 0;
+ }
+ else {
+ tempbx = 0xF7; /* not 08h */
+ tempax = 0x08;
+ }
+ XGI_SetPanelPower(tempax, tempbx, pVBInfo);
+ XGI_SetPanelDelay(3, pVBInfo);
+ }
+ } /* end if(!XGI_IsLCDON(pVBInfo)) */
+ }
+ }
+
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ tempah = 0x3F;
+ if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempah = 0x7F; /* Disable Channel A */
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ tempah = 0xBF; /* Disable Channel B */
+
+ if (pVBInfo->SetFlag & DisableChB)
+ tempah &= 0xBF; /* force to disable Cahnnel */
+
+ if (pVBInfo->SetFlag & DisableChA)
+ tempah &= 0x7F; /* Force to disable Channel B */
+ }
+ }
+ }
+
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+ || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo)))
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
+ }
+
+ if ((pVBInfo->SetFlag & DisableChA)
+ || (pVBInfo->
+ VBInfo & (DisableCRT2Display | SetCRT2ToLCDA |
+ SetSimuScanMode))) {
+ if (pVBInfo->SetFlag & GatingCRT)
+ XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
+ XGI_DisplayOff(HwDeviceExtension, pVBInfo);
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ if ((pVBInfo->SetFlag & DisableChA)
+ || (pVBInfo->VBInfo & SetCRT2ToLCDA))
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
+ }
+
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
+
+ if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xdf);
+
+ if ((pVBInfo->SetFlag & DisableChB)
+ || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
+ || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ && (pVBInfo->
+ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+
+ if ((pVBInfo->SetFlag & DisableChB)
+ || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
+ || (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ || (pVBInfo->
+ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
+ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
+ }
+ }
+ else { /* {301} */
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
+ }
+
+ if (pVBInfo->
+ VBInfo & (DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode))
+ XGI_DisplayOff(HwDeviceExtension,pVBInfo);
+ }
+
+
+
+
+ if (HwDeviceExtension->jChipType < XG40) {
+ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+ || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) {
+ if (pVBInfo->LCDInfo & SetPWDEnable) {
+ if (pVBInfo->LCDInfo & SetPWDEnable)
+ XGI_BacklightByDrv(pVBInfo);
+ else {
+ XGI_SetPanelDelay(4, pVBInfo);
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ tempbl = 0xFD;
+ tempah = 0x00;
+ }
+ else {
+ tempbl = 0xFB;
+ tempah = 0x04;
+ }
+ }
+ }
+ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtrIndex */
+/* Input : */
+/* Output : */
+/* Description : bx 0 : ExtNTSC */
+/* 1 : StNTSC */
+/* 2 : ExtPAL */
+/* 3 : StPAL */
+/* 4 : ExtHiTV */
+/* 5 : StHiTV */
+/* 6 : Ext525i */
+/* 7 : St525i */
+/* 8 : Ext525p */
+/* 9 : St525p */
+/* A : Ext750p */
+/* B : St750p */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx = 0;
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ tempbx = 2;
+ if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+ tempbx = 4;
+ if (pVBInfo->TVInfo & SetYPbPrMode525i)
+ tempbx = 6;
+ if (pVBInfo->TVInfo & SetYPbPrMode525p)
+ tempbx = 8;
+ if (pVBInfo->TVInfo & SetYPbPrMode750p)
+ tempbx = 10;
+ if (pVBInfo->TVInfo & TVSimuMode)
+ tempbx++;
+
+ return tempbx;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_OEM310Setting */
+/* Input : */
+/* Output : */
+/* Description : Customized Param. for 301 */
+/* --------------------------------------------------------------------- */
+void
+XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ if (pVBInfo->SetFlag & Win9xDOSMode)
+ return;
+
+ /* GetPart1IO(); */
+ XGI_SetDelayComp(pVBInfo);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+ XGI_SetLCDCap(pVBInfo);
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ /* GetPart2IO() */
+ XGI_SetPhaseIncr(pVBInfo);
+ XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
+ XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
+
+ if (pVBInfo->VBType & VB_XGI301)
+ XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetDelayComp */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT index;
+
+ UCHAR tempah, tempbl, tempbh;
+#ifndef LINUX_XF86
+ UCHAR temp;
+#endif
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->
+ VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV |
+ SetCRT2ToRAMDAC)) {
+ tempbl = 0;
+ tempbh = 0;
+
+ index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
+ tempbl = pVBInfo->XGI_TVDelayList[index];
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+ | VB_XGI301C))
+ tempbl = pVBInfo->XGI_TVDelayList2[index];
+
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempbl = tempbl >> 4;
+/*
+ if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
+ tempbl = CRT2Delay1 ; // Get CRT2 Delay
+
+ if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
+ tempbl = CRT2Delay2 ;
+*/
+ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+ index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
+ tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+ tempbl = tempbh;
+ }
+
+ tempbl &= 0x0F;
+ tempbh &= 0xF0;
+ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D);
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)) { /* Channel B */
+ tempah &= 0xF0;
+ tempah |= tempbl;
+ }
+
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
+ tempah &= 0x0F;
+ tempah |= tempbh;
+ }
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D, tempah);
+ }
+ }
+ /* Jong 10/04/2007; merge code */
+ else if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ tempbl = 0;
+ tempbh = 0;
+ if ( pVBInfo->VBInfo & SetCRT2ToLCD )
+ {
+ tempah = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_DelayCompensation ; /* / Get LCD Delay */
+ tempah &= 0x0f ;
+ tempah = tempah << 4 ;
+ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->Part1Port , 0x2D , 0x0f , tempah ) ;
+ }
+ }
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDCap */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempcx;
+
+ tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
+ /* Set 301LV Capability */
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x24,
+ (UCHAR) (tempcx & 0x1F));
+ }
+ /* VB Driving */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D,
+ ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
+ (USHORT) ((tempcx &
+ (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >>
+ 8));
+ }
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if (pVBInfo->VBInfo & SetCRT2ToLCD)
+ XGI_SetLCDCap_B(tempcx, pVBInfo);
+ else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ XGI_SetLCDCap_A(tempcx, pVBInfo);
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (tempcx & EnableSpectrum)
+ SetSpectrum(pVBInfo);
+ }
+ }
+ else /* LVDS,CH7017 */
+ XGI_SetLCDCap_A(tempcx, pVBInfo);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDCap_A */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT temp;
+
+ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
+
+ if (temp & LCDRGB18Bit) {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F, (USHORT) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+ }
+ else {
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F,
+ (USHORT) (0x30 | (tempcx & 0x00C0)));
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+ }
+
+/*
+ if ( tempcx & EnableLCD24bpp ) // 24bits
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x30|(tempcx&0x00C0)) );
+ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x00);
+ }
+ else
+ {
+ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x20|(tempcx&0x00C0)) );//Enable Dither
+ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x80);
+ }
+*/
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetLCDCap_B */
+/* Input : cx -> LCD Capability */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+{
+ if (tempcx & EnableLCD24bpp) /* 24bits */
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0,
+ (USHORT) (((tempcx & 0x00ff) >> 6) | 0x0c));
+ else
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0, (USHORT) (((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : SetSpectrum */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+SetSpectrum(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT index;
+
+ index = XGI_GetLCDCapPtr(pVBInfo);
+
+ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
+ XGI_WaitEndRetrace(pVBInfo->RelIO);
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
+ XGI_WaitEndRetrace(pVBInfo->RelIO);
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x31,
+ pVBInfo->LCDCapList[index].Spectrum_31);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x32,
+ pVBInfo->LCDCapList[index].Spectrum_32);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x33,
+ pVBInfo->LCDCapList[index].Spectrum_33);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x34,
+ pVBInfo->LCDCapList[index].Spectrum_34);
+ XGI_WaitEndRetrace(pVBInfo->RelIO);
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetAntiFlicker */
+/* Input : */
+/* Output : */
+/* Description : Set TV Customized Param. */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, index;
+
+ UCHAR tempah;
+
+ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+ return;
+
+ tempbx = XGI_GetTVPtrIndex(pVBInfo);
+ tempbx &= 0xFE;
+
+ if (ModeNo <= 0x13) {
+ index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+ }
+ else {
+ index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+ }
+
+ tempbx += index;
+ tempah = TVAntiFlickList[tempbx];
+ tempah = tempah << 4;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetEdgeEnhance */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, index;
+
+ UCHAR tempah;
+
+
+ tempbx = XGI_GetTVPtrIndex(pVBInfo);
+ tempbx &= 0xFE;
+
+ if (ModeNo <= 0x13) {
+ index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+ }
+ else {
+ index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
+ }
+
+ tempbx += index;
+ tempah = TVEdgeList[tempbx];
+ tempah = tempah << 5;
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetPhaseIncr */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx;
+
+ UCHAR tempcl, tempch;
+
+ ULONG tempData;
+
+ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+ tempData = TVPhaseList[tempbx];
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x31,
+ (USHORT) (tempData & 0x000000FF));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x32,
+ (USHORT) ((tempData & 0x0000FF00) >> 8));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x33,
+ (USHORT) ((tempData & 0x00FF0000) >> 16));
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x34,
+ (USHORT) ((tempData & 0xFF000000) >> 24));
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetYFilter */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempbx, index;
+
+ UCHAR tempcl, tempch, tempal;
+ const UCHAR *filterPtr;
+
+ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+
+ switch (tempbx) {
+ case 0x00:
+ case 0x04:
+ filterPtr = NTSCYFilter1;
+ break;
+
+ case 0x01:
+ filterPtr = PALYFilter1;
+ break;
+
+ case 0x02:
+ case 0x05:
+ case 0x0D:
+ filterPtr = PALMYFilter1;
+ break;
+
+ case 0x03:
+ filterPtr = PALNYFilter1;
+ break;
+
+ case 0x08:
+ case 0x0C:
+ filterPtr = NTSCYFilter2;
+ break;
+
+ case 0x0A:
+ filterPtr = PALMYFilter2;
+ break;
+
+ case 0x0B:
+ filterPtr = PALNYFilter2;
+ break;
+
+ case 0x09:
+ filterPtr = PALYFilter2;
+ break;
+
+ default:
+ return;
+ }
+
+ if (ModeNo <= 0x13)
+ tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+ else
+ tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+
+ if (tempcl == 0)
+ index = tempal * 4;
+ else
+ index = tempal * 7;
+
+ if ((tempcl == 0) && (tempch == 1)) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35, 0);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36, 0);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37, 0);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
+ filterPtr[index++]);
+ }
+ else {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35,
+ filterPtr[index++]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36,
+ filterPtr[index++]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37,
+ filterPtr[index++]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
+ filterPtr[index++]);
+ }
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x48,
+ filterPtr[index++]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x49,
+ filterPtr[index++]);
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4A,
+ filterPtr[index++]);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetTVPtrIndex2 */
+/* Input : */
+/* Output : bx 0 : NTSC */
+/* 1 : PAL */
+/* 2 : PALM */
+/* 3 : PALN */
+/* 4 : NTSC1024x768 */
+/* 5 : PAL-M 1024x768 */
+/* 6-7: reserved */
+/* cl 0 : YFilter1 */
+/* 1 : YFilter2 */
+/* ch 0 : 301A */
+/* 1 : 301B/302B/301LV/302LV */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ *tempbx = 0;
+ *tempcl = 0;
+ *tempch = 0;
+
+ if (pVBInfo->TVInfo & SetPALTV)
+ *tempbx = 1;
+
+ if (pVBInfo->TVInfo & SetPALMTV)
+ *tempbx = 2;
+
+ if (pVBInfo->TVInfo & SetPALNTV)
+ *tempbx = 3;
+
+ if (pVBInfo->TVInfo & NTSC1024x768) {
+ *tempbx = 4;
+ if (pVBInfo->TVInfo & SetPALMTV)
+ *tempbx = 5;
+ }
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ if ((!(pVBInfo->VBInfo & SetInSlaveMode))
+ || (pVBInfo->TVInfo & TVSimuMode)) {
+ *tempbx += 8;
+ *tempcl += 1;
+ }
+ }
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C))
+ *tempch++;
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_SetCRT2ModeRegs */
+/* Input : */
+/* Output : */
+/* Description : Origin code for crt2group */
+/* --------------------------------------------------------------------- */
+void
+XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo)
+{
+#ifndef LINUX_XF86
+ USHORT i, j;
+#endif
+ USHORT tempbl;
+ SHORT tempcl;
+
+ UCHAR tempah;
+
+ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
+ tempah = 0;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00);
+ tempah &= ~0x10; /* BTRAMDAC */
+ tempah |= 0x40; /* BTRAM */
+
+ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
+ tempah = 0x40; /* BTDRAM */
+ if (ModeNo > 0x13) {
+ tempcl = pVBInfo->ModeType;
+ tempcl -= ModeVGA;
+ if (tempcl >= 0) {
+ tempah = (0x008 >> tempcl); /* BT Color */
+ if (tempah == 0)
+ tempah = 1;
+ tempah |= 0x040;
+ }
+ }
+ if (pVBInfo->VBInfo & SetInSlaveMode)
+ tempah ^= 0x50; /* BTDAC */
+ }
+ }
+
+/* 0210 shampoo
+ if ( pVBInfo->VBInfo & DisableCRT2Display )
+ {
+ tempah = 0 ;
+ }
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , tempah ) ;
+ if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
+ {
+ tempcl = pVBInfo->ModeType ;
+ if ( ModeNo > 0x13 )
+ {
+ tempcl -= ModeVGA ;
+ if ( ( tempcl > 0 ) || ( tempcl == 0 ) )
+ {
+ tempah=(0x008>>tempcl) ;
+ if ( tempah == 0 )
+ tempah = 1 ;
+ tempah |= 0x040;
+ }
+ }
+ else
+ {
+ tempah = 0x040 ;
+ }
+
+ if ( pVBInfo->VBInfo & SetInSlaveMode )
+ {
+ tempah = ( tempah ^ 0x050 ) ;
+ }
+ }
+*/
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah);
+ tempah = 0x08;
+ tempbl = 0xf0;
+
+ if (pVBInfo->VBInfo & DisableCRT2Display)
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
+ tempah);
+ else {
+ tempah = 0x00;
+ tempbl = 0xff;
+
+ if (pVBInfo->
+ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
+ SetCRT2ToLCDA)) {
+ if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
+ && (!(pVBInfo->VBInfo & SetSimuScanMode))) {
+ tempbl &= 0xf7;
+ tempah |= 0x01;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
+ tempbl, tempah);
+ }
+ else {
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+ tempbl &= 0xf7;
+ tempah |= 0x01;
+ }
+
+ if (pVBInfo->
+ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
+ tempbl &= 0xf8;
+ tempah = 0x01;
+
+ if (!(pVBInfo->VBInfo & SetInSlaveMode))
+ tempah |= 0x02;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+ tempah = tempah ^ 0x05;
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+ tempah = tempah ^ 0x01;
+ }
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+ tempah |= 0x08;
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
+ tempbl, tempah);
+ }
+ else
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
+ tempbl, tempah);
+ }
+ }
+ else
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
+ tempah);
+ }
+
+ if (pVBInfo->
+ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
+ SetCRT2ToLCDA)) {
+ tempah &= (~0x08);
+ if ((pVBInfo->ModeType == ModeVGA)
+ && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+ tempah |= 0x010;
+ }
+ tempah |= 0x080;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ /* if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) */
+ /* { */
+ tempah |= 0x020;
+ if (ModeNo > 0x13) {
+ if (pVBInfo->VBInfo & DriverMode)
+ tempah = tempah ^ 0x20;
+ }
+ /* } */
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, ~0x0BF,
+ tempah);
+ tempah = 0;
+
+ if (pVBInfo->LCDInfo & SetLCDDualLink)
+ tempah |= 0x40;
+
+ if (pVBInfo->VBInfo & SetCRT2ToTV) {
+ /* if ( ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) && ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) ) */
+ /* { */
+ if (pVBInfo->TVInfo & RPLLDIV2XO)
+ tempah |= 0x40;
+ /* } */
+ }
+
+ if ((pVBInfo->LCDResInfo == Panel1280x1024)
+ || (pVBInfo->LCDResInfo == Panel1280x1024x75))
+ tempah |= 0x80;
+
+ if (pVBInfo->LCDResInfo == Panel1280x960)
+ tempah |= 0x80;
+
+ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0C, tempah);
+ }
+
+ if (pVBInfo->
+ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+ VB_XGI301C)) {
+ tempah = 0;
+ tempbl = 0xfb;
+
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+ tempbl = 0xff;
+ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+ tempah |= 0x04; /* shampoo 0129 */
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x13, tempbl,
+ tempah);
+ tempah = 0x00;
+ tempbl = 0xcf;
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah |= 0x30;
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2c, tempbl,
+ tempah);
+ tempah = 0;
+ tempbl = 0x3f;
+
+ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+ tempah |= 0xc0;
+ }
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, tempbl,
+ tempah);
+ }
+
+ tempah = 0;
+ tempbl = 0x7f;
+ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+ tempbl = 0xff;
+ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+ tempah |= 0x80;
+ }
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x23, tempbl, tempah);
+
+ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+ if (pVBInfo->LCDInfo & SetLCDDualLink) {
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x20);
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x34, 0x10);
+ }
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetRAMDAC2DATA */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, CRT1Index;
+#ifndef LINUX_XF86
+ USHORT temp, ResInfo, DisplayType;
+#endif
+
+ pVBInfo->RVBHCMAX = 1;
+ pVBInfo->RVBHCFACT = 1;
+
+ if (ModeNo <= 0x13) {
+ const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
+ pVBInfo->ModeType,
+ ModeNo, ModeIdIndex);
+
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
+ tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
+ temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+ CRT1Index &= IndexMask;
+ temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
+ temp2 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+ tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
+ tempbx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
+ tempcx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
+ tempcx &= 0x0100;
+ tempcx = tempcx << 2;
+ tempbx |= tempcx;
+ temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+ }
+
+ if (temp1 & 0x01)
+ tempbx |= 0x0100;
+
+ if (temp1 & 0x20)
+ tempbx |= 0x0200;
+ tempax += 5;
+
+ if (modeflag & Charx8Dot)
+ tempax *= 8;
+ else
+ tempax *= 9;
+
+ pVBInfo->VGAHT = tempax;
+ pVBInfo->HT = tempax;
+ tempbx++;
+ pVBInfo->VGAVT = tempbx;
+ pVBInfo->VT = tempbx;
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetColorDepth */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetColorDepth(USHORT ModeNo, USHORT ModeIdIndex,
+ const VB_DEVICE_INFO *pVBInfo)
+{
+ USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+ SHORT index;
+ USHORT modeflag;
+
+ if (ModeNo <= 0x13) {
+ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+ }
+ else {
+ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+ }
+
+ index = (modeflag & ModeInfoFlag) - ModeEGA;
+
+ if (index < 0)
+ index = 0;
+
+ return (ColorDepth[index]);
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_UnLockCRT2 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
+
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_LockCRT2 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_LockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGINew_EnableCRT2 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo)
+{
+ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E, SR1E_ENABLE_CRT2);
+}
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT i, j;
+
+ ULONG temp, flag;
+
+ flag = 0;
+
+ for (i = 0; i < DelayTime; i++) {
+ for (j = 0; j < 66; j++) {
+ temp = XGI_GetRegLong((XGIIOADDRESS) 0x61);
+ temp &= 0x10;
+
+ if (temp == flag)
+ continue;
+
+ flag = temp;
+ }
+ }
+}
+
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_BridgeIsOn */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+BOOLEAN
+XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT flag;
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 1 )
+ {
+ return( 1 ) ;
+ }
+ else
+ {
+ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
+ if ((flag == 1) || (flag == 2))
+ return (1); /* 301b */
+ else
+ return (0);
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_VBLongWait */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+void
+XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo)
+{
+ USHORT tempal, temp, i, j;
+
+ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+ temp = 0;
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 100; j++) {
+ tempal = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
+ if (temp & 0x01) { /* VBWaitMode2 */
+ if ((tempal & 0x08)) {
+ continue;
+ }
+
+ if (!(tempal & 0x08)) {
+ break;
+ }
+ }
+ else { /* VBWaitMode1 */
+ if (!(tempal & 0x08)) {
+ continue;
+ }
+
+ if ((tempal & 0x08)) {
+ break;
+ }
+ }
+ }
+ temp = temp ^ 0x01;
+ }
+ }
+ else {
+ XGI_WaitEndRetrace(pVBInfo->RelIO);
+ }
+ return;
+}
+
+
+
+
+/* --------------------------------------------------------------------- */
+/* Function : XGI_GetVGAHT2 */
+/* Input : */
+/* Output : */
+/* Description : */
+/* --------------------------------------------------------------------- */
+USHORT
+XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo)
+{
+ ULONG tempax, tempbx;
+
+ tempbx =
+ ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) & 0xFFFF;
+ tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
+ tempax = (tempax * pVBInfo->HT) / tempbx;
+
+ return ((USHORT) tempax);
+}
+
+
+/**
+ * Get magic index into clock table.
+ *
+ * \bugs
+ * I'm pretty sure the first if-statement is wrong. It will \b always
+ * evaluate to true.
+ */
+unsigned
+XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
+ USHORT RefreshRateTableIndex,
+ PVB_DEVICE_INFO pVBInfo)
+{
+ /* Jong 10/08/2007; merge code */
+ USHORT tempbx ;
+ UCHAR *CHTVVCLKPtr = NULL ;
+
+ unsigned VCLKIndex;
+ USHORT CRT2Index;
+
+ /* Jong 10/08/2007; merge code */
+ USHORT LCDXlat1VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
+ USHORT LCDXlat2VCLK[ 4 ] = { VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 } ;
+ USHORT LVDSXlat1VCLK[ 4 ] = { VCLK40 , VCLK40 , VCLK40 , VCLK40 } ;
+ USHORT LVDSXlat2VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
+ USHORT LVDSXlat3VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
+
+ const unsigned modeflag = (ModeNo <= 0x13)
+ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+
+ /* Jong 10/04/2007; merge code */
+ if ( pVBInfo->IF_DEF_LVDS == 0 )
+ {
+ CRT2Index = CRT2Index >> 6 ; /* for LCD */
+
+ if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b */
+ VCLKIndex = (pVBInfo->LCDResInfo != Panel1024x768)
+ ? (VCLK108_2 + 5) : (VCLK65 + 2);
+ }
+ else
+ {
+ if (pVBInfo->VBInfo & SetCRT2ToTV) /* for TV */
+ {
+ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+ {
+ VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
+ ? HiTVVCLKDIV2 : HiTVVCLK;
+
+ VCLKIndex += 25;
+
+ if (pVBInfo->SetFlag & TVSimuMode) {
+ VCLKIndex = (modeflag & Charx8Dot)
+ ? HiTVSimuVCLK : HiTVTextVCLK;
+
+ VCLKIndex += 25;
+ }
+
+ if (pVBInfo->VBType & VB_XGI301LV) {
+ switch (pVBInfo->VBExtInfo) {
+ case VB_YPbPr1080i:
+ /* VCLKIndex already set to correct value? */
+ break;
+ case VB_YPbPr750p:
+ VCLKIndex = YPbPr750pVCLK;
+ break;
+ case VB_YPbPr525p:
+ VCLKIndex = YPbPr525pVCLK;
+ break;
+ case VB_YPbPr525i:
+ VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
+ ? YPbPr525iVCLK_2 : YPbPr525iVCLK;
+ break;
+ }
+ }
+ }
+ else {
+ VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
+ ? TVVCLKDIV2 : TVVCLK;
+
+ VCLKIndex += 25;
+ }
+ }
+ else /* for CRT2 */
+ {
+ VCLKIndex = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
+ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+ if (ModeNo > 0x13) {
+ VCLKIndex =
+ (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK
+ & IndexMask);
+ }
+ }
+ }
+ }
+ else /* Jong 10/04/2007; merge code */
+ { /* LVDS */
+ if ( ModeNo <= 0x13 )
+ VCLKIndex = CRT2Index ;
+ else
+ VCLKIndex = CRT2Index ;
+
+ if ( pVBInfo->IF_DEF_CH7005 == 1 )
+ {
+ if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
+ {
+ VCLKIndex &= 0x1f ;
+ tempbx = 0 ;
+
+ if ( pVBInfo->VBInfo & SetPALTV )
+ tempbx += 2 ;
+
+ if ( pVBInfo->VBInfo & SetCHTVOverScan )
+ tempbx += 1 ;
+
+ switch( tempbx )
+ {
+ case 0:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC ;
+ break ;
+ case 1:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC ;
+ break;
+ case 2:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL ;
+ break ;
+ case 3:
+ CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL ;
+ break ;
+ default:
+ break ;
+ }
+
+ VCLKIndex = CHTVVCLKPtr[ VCLKIndex ] ;
+ }
+ }
+ else
+ {
+ VCLKIndex = VCLKIndex >> 6 ;
+ if ( ( pVBInfo->LCDResInfo == Panel800x600 ) || ( pVBInfo->LCDResInfo == Panel320x480 ) )
+ VCLKIndex = LVDSXlat1VCLK[ VCLKIndex ] ;
+ else if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
+ VCLKIndex = LVDSXlat2VCLK[ VCLKIndex ] ;
+ else
+ VCLKIndex = LVDSXlat3VCLK[ VCLKIndex ] ;
+ }
+ }
+
+ return VCLKIndex;
+}
diff --git a/src/vb_setmode.h b/src/vb_setmode.h
index 558e68d..1b37395 100644
--- a/src/vb_setmode.h
+++ b/src/vb_setmode.h
@@ -34,8 +34,8 @@ extern void XGI_LongWait( PVB_DEVICE_INFO );
extern void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
extern void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
extern void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
-extern void XGI_DisplayOff( PVB_DEVICE_INFO );
-extern void XGI_DisplayOn( PVB_DEVICE_INFO );
+extern void XGI_DisplayOff( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+extern void XGI_DisplayOn( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
extern void XGI_GetVBType(PVB_DEVICE_INFO);
extern void XGI_SenseCRT1(PVB_DEVICE_INFO );
extern void XGI_GetVGAType(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
@@ -44,6 +44,9 @@ extern void XGI_GetTVInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INF
extern void XGI_SetCRT1Offset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
extern void XGI_SetLCDAGroup(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+/* Jong 10/04/2007; merge code */
+extern USHORT XGI_GetResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+
extern BOOLEAN XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension,
PVB_DEVICE_INFO pVBInfo, USHORT ModeNo);
@@ -51,7 +54,7 @@ extern BOOLEAN CheckDualChip(PVB_DEVICE_INFO );
extern BOOLEAN XGI_GetLCDInfo(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO );
extern BOOLEAN XGI_BridgeIsOn( PVB_DEVICE_INFO );
extern BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO);
-extern USHORT XGI_GetRatePtrCRT2( USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
+extern USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
extern USHORT XGI_GetColorDepth(USHORT ModeNo, USHORT ModeIdIndex,
const VB_DEVICE_INFO *pVBInfo);
@@ -73,6 +76,15 @@ extern void XGI_SetGRCRegs(unsigned StandTableIndex,
extern void XGI_ClearExt1Regs(unsigned ModeNo, const VB_DEVICE_INFO *pVBInfo);
+extern void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
+extern void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
+extern void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+extern void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+extern void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+extern BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
+extern void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
+extern USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo);
+
extern void XGI_SetSync(unsigned RefreshRateTableIndex,
const VB_DEVICE_INFO *pVBInfo);
#endif
diff --git a/src/vb_struct.h b/src/vb_struct.h
index 072a024..2ba26cf 100644
--- a/src/vb_struct.h
+++ b/src/vb_struct.h
@@ -1,499 +1,574 @@
-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef _VB_STRUCT_
-#define _VB_STRUCT_
-
-
-typedef struct _XGI_PanelDelayTblStruct
-{
- UCHAR timer[2];
-} XGI_PanelDelayTblStruct;
-
-typedef struct _XGI_LCDDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} XGI_LCDDataStruct;
-
-
-typedef struct _XGI_LVDSCRT1HDataStruct
-{
- UCHAR Reg[8];
-} XGI_LVDSCRT1HDataStruct;
-typedef struct _XGI_LVDSCRT1VDataStruct
-{
- UCHAR Reg[7];
-} XGI_LVDSCRT1VDataStruct;
-
-
-typedef struct _XGI_TVDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT TVHDE;
- USHORT TVVDE;
- USHORT RVBHRS;
- UCHAR FlickerMode;
- USHORT HALFRVBHRS;
- UCHAR RY1COE;
- UCHAR RY2COE;
- UCHAR RY3COE;
- UCHAR RY4COE;
-} XGI_TVDataStruct;
-
-typedef struct _XGI_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} XGI_LVDSDataStruct;
-
-typedef struct _XGI_LVDSDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDVDES;
-} XGI_LVDSDesStruct;
-
-typedef struct _XGI_LVDSCRT1DataStruct
-{
- UCHAR CR[15];
-} XGI_LVDSCRT1DataStruct;
-
-/*add for LCDA*/
-
-
-typedef struct _XGI_StStruct
-{
- UCHAR St_ModeID;
- USHORT St_ModeFlag;
- UCHAR St_StTableIndex;
- UCHAR St_CRT2CRTC;
- UCHAR St_CRT2CRTC2;
- UCHAR St_ResInfo;
- UCHAR VB_StTVFlickerIndex;
- UCHAR VB_StTVEdgeIndex;
- UCHAR VB_StTVYFilterIndex;
-} XGI_StStruct;
-
-typedef struct _XGI_StandTableStruct
-{
- UCHAR CRT_COLS;
- UCHAR ROWS;
- UCHAR CHAR_HEIGHT;
- USHORT CRT_LEN;
- UCHAR SR[4];
- UCHAR MISC;
- UCHAR CRTC[0x19];
- UCHAR ATTR[0x14];
- UCHAR GRC[9];
-} XGI_StandTableStruct;
-
-typedef struct _XGI_ExtStruct
-{
- UCHAR Ext_ModeID;
- USHORT Ext_ModeFlag;
- USHORT Ext_ModeInfo;
- USHORT Ext_Point;
- USHORT Ext_VESAID;
- UCHAR Ext_VESAMEMSize;
- UCHAR Ext_RESINFO;
- UCHAR VB_ExtTVFlickerIndex;
- UCHAR VB_ExtTVEdgeIndex;
- UCHAR VB_ExtTVYFilterIndex;
- UCHAR REFindex;
-} XGI_ExtStruct;
-
-typedef struct _XGI_Ext2Struct
-{
- USHORT Ext_InfoFlag;
- UCHAR Ext_CRT1CRTC;
- UCHAR Ext_CRTVCLK;
- UCHAR Ext_CRT2CRTC;
- UCHAR Ext_CRT2CRTC2;
- UCHAR ModeID;
- USHORT XRes;
- USHORT YRes;
- /* USHORT ROM_OFFSET; */
-} XGI_Ext2Struct;
-
-
-typedef struct _XGI_MCLKDataStruct
-{
- UCHAR SR28,SR29,SR2A;
- USHORT CLOCK;
-} XGI_MCLKDataStruct;
-
-typedef struct _XGI_ECLKDataStruct
-{
- UCHAR SR2E,SR2F,SR30;
- USHORT CLOCK;
-} XGI_ECLKDataStruct;
-
-typedef struct _XGI_VCLKDataStruct
-{
- UCHAR SR2B,SR2C;
- USHORT CLOCK;
-} XGI_VCLKDataStruct;
-
-typedef struct _XGI_VBVCLKDataStruct
-{
- UCHAR Part4_A,Part4_B;
- USHORT CLOCK;
-} XGI_VBVCLKDataStruct;
-
-typedef struct _XGI_StResInfoStruct
-{
- USHORT HTotal;
- USHORT VTotal;
-} XGI_StResInfoStruct;
-
-typedef struct _XGI_ModeResInfoStruct
-{
- USHORT HTotal;
- USHORT VTotal;
- UCHAR XChar;
- UCHAR YChar;
-} XGI_ModeResInfoStruct;
-
-typedef struct _XGI_LCDNBDesStruct
-{
- UCHAR NB[12];
-} XGI_LCDNBDesStruct;
- /*add for new UNIVGABIOS*/
-typedef struct _XGI_LCDDesStruct
-{
- USHORT LCDHDES;
- USHORT LCDHRS;
- USHORT LCDVDES;
- USHORT LCDVRS;
-} XGI_LCDDesStruct;
-
-typedef struct _XGI_LCDDataTablStruct
-{
- UCHAR PANELID;
- USHORT MASK;
- USHORT CAP;
- USHORT DATAPTR;
-} XGI_LCDDataTablStruct;
-
-typedef struct _XGI_TVTablDataStruct
-{
- USHORT MASK;
- USHORT CAP;
- USHORT DATAPTR;
-} XGI_TVDataTablStruct;
-
-typedef struct _XGI330_LCDDesDataStruct
-{
- USHORT LCDHDES;
- USHORT LCDHRS;
- USHORT LCDVDES;
- USHORT LCDVRS;
-} XGI330_LCDDataDesStruct;
-
-
-typedef struct _XGI330_LVDSDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} XGI330_LVDSDataStruct;
-
-typedef struct _XGI330_LCDDesDataStruct2
-{
- USHORT LCDHDES;
- USHORT LCDHRS;
- USHORT LCDVDES;
- USHORT LCDVRS;
- USHORT LCDHSync;
- USHORT LCDVSync;
-} XGI330_LCDDataDesStruct2;
-
-typedef struct _XGI330_LCDDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} XGI330_LCDDataStruct;
-
-
-typedef struct _XGI330_TVDataStruct
-{
- USHORT RVBHCMAX;
- USHORT RVBHCFACT;
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT TVHDE;
- USHORT TVVDE;
- USHORT RVBHRS;
- UCHAR FlickerMode;
- USHORT HALFRVBHRS;
-} XGI330_TVDataStruct;
-
-typedef struct _XGI330_LCDDataTablStruct
-{
- UCHAR PANELID;
- USHORT MASK;
- USHORT CAP;
- USHORT DATAPTR;
-} XGI330_LCDDataTablStruct;
-
-typedef struct _XGI330_TVDataTablStruct
-{
- USHORT MASK;
- USHORT CAP;
- USHORT DATAPTR;
-} XGI330_TVDataTablStruct;
-
-
-typedef struct _XGI330_CHTVDataStruct
-{
- USHORT VGAHT;
- USHORT VGAVT;
- USHORT LCDHT;
- USHORT LCDVT;
-} XGI330_CHTVDataStruct;
-
-typedef struct _XGI_TimingHStruct
-{
- UCHAR data[8];
-} XGI_TimingHStruct;
-
-typedef struct _XGI_TimingVStruct
-{
- UCHAR data[7];
-} XGI_TimingVStruct;
-
-typedef struct _XGI330_CHTVRegDataStruct
-{
- UCHAR Reg[16];
-} XGI330_CHTVRegDataStruct;
-
-typedef struct _XGI330_LCDCapStruct
-{
- UCHAR LCD_ID;
- USHORT LCD_Capability;
- UCHAR LCD_SetFlag;
- UCHAR LCD_DelayCompensation;
- UCHAR LCD_HSyncWidth;
- UCHAR LCD_VSyncWidth;
- UCHAR LCD_VCLK;
- UCHAR LCDA_VCLKData1;
- UCHAR LCDA_VCLKData2;
- UCHAR LCUCHAR_VCLKData1;
- UCHAR LCUCHAR_VCLKData2;
- UCHAR PSC_S1;
- UCHAR PSC_S2;
- UCHAR PSC_S3;
- UCHAR PSC_S4;
- UCHAR PSC_S5;
- UCHAR PWD_2B;
- UCHAR PWD_2C;
- UCHAR PWD_2D;
- UCHAR PWD_2E;
- UCHAR PWD_2F;
- UCHAR Spectrum_31;
- UCHAR Spectrum_32;
- UCHAR Spectrum_33;
- UCHAR Spectrum_34;
-} XGI330_LCDCapStruct;
-
-typedef struct _XGI_CRT1TableStruct
-{
- UCHAR CR[15];
-} XGI_CRT1TableStruct;
-
-
-typedef struct _XGI330_VCLKDataStruct
-{
- UCHAR SR2B,SR2C;
- USHORT CLOCK;
-} XGI330_VCLKDataStruct;
-
-typedef struct _XGI301C_Tap4TimingStruct
-{
- USHORT DE;
- UCHAR Reg[64]; /* C0-FF */
-} XGI301C_Tap4TimingStruct;
-
-typedef struct _XGI_New_StandTableStruct
-{
- UCHAR CRT_COLS;
- UCHAR ROWS;
- UCHAR CHAR_HEIGHT;
- USHORT CRT_LEN;
- UCHAR SR[4];
- UCHAR MISC;
- UCHAR CRTC[0x19];
- UCHAR ATTR[0x14];
- UCHAR GRC[9];
-} XGI_New_StandTableStruct;
-
-typedef UCHAR DRAM8Type[8];
-typedef UCHAR DRAM4Type[4];
-typedef UCHAR DRAM32Type[32];
-typedef UCHAR DRAM2Type[2];
-
-typedef struct _VB_DEVICE_INFO VB_DEVICE_INFO,*PVB_DEVICE_INFO;
-
-#define AGP_REG_SIZE 12
-#define CR40_SIZE 24
-#define CR6B_SIZE 8
-#define CR6E_SIZE 8
-#define CR6F_SIZE 8
-#define CR89_SIZE 8
-#define SR15_SIZE 4
-#define MCLK_SIZE 8
-#define ECLK_SIZE 8
-
-struct _VB_DEVICE_INFO
-{
- BOOLEAN ISXPDOS;
- USHORT P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
- USHORT P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
- USHORT Part0Port,Part1Port,Part2Port;
- USHORT Part3Port,Part4Port,Part5Port;
- USHORT RVBHCFACT,RVBHCMAX,RVBHRS;
- USHORT VGAVT,VGAHT,VGAVDE,VGAHDE;
- USHORT VT,HT,VDE,HDE;
- USHORT LCDHRS,LCDVRS,LCDHDES,LCDVDES;
-
- USHORT ModeType;
- USHORT IF_DEF_TRUMPION,IF_DEF_DSTN;
- USHORT IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
- USHORT IF_DEF_LCDA,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
- USHORT IF_DEF_ExpLink;
- USHORT IF_DEF_HiVision;
- USHORT LCDResInfo,LCDTypeInfo, VBType;/*301b*/
- USHORT VBInfo,TVInfo,LCDInfo;
- USHORT VBExtInfo;/*301lv*/
- USHORT SetFlag;
- USHORT NewFlickerMode;
- USHORT SelectCRT2Rate;
-
- PUCHAR ROMAddr;
- PUCHAR FBAddr;
- USHORT BaseAddr;
- XGIIOADDRESS RelIO;
-
- DRAM4Type CR6B[CR6B_SIZE];
-
- UCHAR XG45CR6E[CR6E_SIZE];
- UCHAR XG45CR6F[CR6F_SIZE];
- DRAM4Type CR6E[CR6E_SIZE];
- DRAM32Type CR6F[CR6F_SIZE];
- DRAM2Type CR89[CR89_SIZE];
-
- DRAM8Type SR15[SR15_SIZE]; /* pointer : point to array */
- DRAM8Type CR40[CR40_SIZE];
- UCHAR SoftSetting;
- UCHAR OutputSelect;
-
- const USHORT *pRGBSenseData;
- const USHORT *pRGBSenseData2; /*301b*/
- const USHORT *pVideoSenseData;
- const USHORT *pVideoSenseData2;
- const USHORT *pYCSenseData;
- const USHORT *pYCSenseData2;
-
- UCHAR SR07;
- UCHAR CR49[2];
- UCHAR SR1F;
- UCHAR AGPReg[AGP_REG_SIZE];
- UCHAR SR16[4];
- UCHAR SR21;
- UCHAR SR22;
- UCHAR SR23;
- UCHAR SR24;
- UCHAR SR25[2];
- UCHAR SR31;
- UCHAR SR32;
- UCHAR SR33;
- UCHAR CRCF;
- UCHAR CRT2Data_1_2;
- UCHAR CRT2Data_4_D;
- UCHAR CRT2Data_4_E;
- UCHAR CRT2Data_4_10;
- XGI_MCLKDataStruct MCLKData[MCLK_SIZE];
- XGI_ECLKDataStruct ECLKData[ECLK_SIZE];
-
- const UCHAR *XGI_TVDelayList;
- const UCHAR *XGI_TVDelayList2;
- const UCHAR *CHTVVCLKUNTSC;
- const UCHAR *CHTVVCLKONTSC;
- const UCHAR *CHTVVCLKUPAL;
- const UCHAR *CHTVVCLKOPAL;
- const UCHAR *NTSCTiming;
- const UCHAR *PALTiming;
- const UCHAR *HiTVExtTiming;
- const UCHAR *HiTVSt1Timing;
- const UCHAR *HiTVSt2Timing;
- const UCHAR *HiTVTextTiming;
- const UCHAR *YPbPr750pTiming;
- const UCHAR *YPbPr525pTiming;
- const UCHAR *YPbPr525iTiming;
- const UCHAR *HiTVGroup3Data;
- const UCHAR *HiTVGroup3Simu;
- const UCHAR *HiTVGroup3Text;
- const UCHAR *Ren525pGroup3;
- const UCHAR *Ren750pGroup3;
- const UCHAR *ScreenOffset;
- UCHAR DRAMTypeDefinition;
- UCHAR I2CDefinition;
- UCHAR CR97;
-
- const XGI330_LCDCapStruct *LCDCapList;
-
- XGI_TimingHStruct TimingH;
- XGI_TimingVStruct TimingV;
-
- const XGI_StStruct *SModeIDTable;
- const XGI_StandTableStruct *StandTable;
- const XGI_ExtStruct *EModeIDTable;
- const XGI_Ext2Struct *RefIndex;
- /* XGINew_CRT1TableStruct *CRT1Table; */
- const XGI_CRT1TableStruct *XGINEWUB_CRT1Table;
- const XGI_VCLKDataStruct *VCLKData;
- const XGI_VBVCLKDataStruct *VBVCLKData;
- const XGI_StResInfoStruct *StResInfo;
- const XGI_ModeResInfoStruct *ModeResInfo;
-}; /* _VB_DEVICE_INFO */
-
-#define _VB_STRUCT_
-#endif /* _VB_STRUCT_ */
+/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _VB_STRUCT_
+#define _VB_STRUCT_
+
+
+typedef struct _XGI_PanelDelayTblStruct
+{
+ UCHAR timer[2];
+} XGI_PanelDelayTblStruct;
+
+typedef struct _XGI_LCDDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} XGI_LCDDataStruct;
+
+
+typedef struct _XGI_LVDSCRT1HDataStruct
+{
+ UCHAR Reg[8];
+} XGI_LVDSCRT1HDataStruct;
+typedef struct _XGI_LVDSCRT1VDataStruct
+{
+ UCHAR Reg[7];
+} XGI_LVDSCRT1VDataStruct;
+
+
+typedef struct _XGI_TVDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT TVHDE;
+ USHORT TVVDE;
+ USHORT RVBHRS;
+ UCHAR FlickerMode;
+ USHORT HALFRVBHRS;
+ UCHAR RY1COE;
+ UCHAR RY2COE;
+ UCHAR RY3COE;
+ UCHAR RY4COE;
+} XGI_TVDataStruct;
+
+typedef struct _XGI_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} XGI_LVDSDataStruct;
+
+typedef struct _XGI_LVDSDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDVDES;
+} XGI_LVDSDesStruct;
+
+typedef struct _XGI_LVDSCRT1DataStruct
+{
+ UCHAR CR[15];
+} XGI_LVDSCRT1DataStruct;
+
+/*add for LCDA*/
+
+
+typedef struct _XGI_StStruct
+{
+ UCHAR St_ModeID;
+ USHORT St_ModeFlag;
+ UCHAR St_StTableIndex;
+ UCHAR St_CRT2CRTC;
+ UCHAR St_CRT2CRTC2;
+ UCHAR St_ResInfo;
+ UCHAR VB_StTVFlickerIndex;
+ UCHAR VB_StTVEdgeIndex;
+ UCHAR VB_StTVYFilterIndex;
+} XGI_StStruct;
+
+typedef struct _XGI_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
+} XGI_StandTableStruct;
+
+typedef struct _XGI_ExtStruct
+{
+ UCHAR Ext_ModeID;
+ USHORT Ext_ModeFlag;
+ USHORT Ext_ModeInfo;
+ USHORT Ext_Point;
+ USHORT Ext_VESAID;
+ UCHAR Ext_VESAMEMSize;
+ UCHAR Ext_RESINFO;
+ UCHAR VB_ExtTVFlickerIndex;
+ UCHAR VB_ExtTVEdgeIndex;
+ UCHAR VB_ExtTVYFilterIndex;
+ UCHAR REFindex;
+} XGI_ExtStruct;
+
+typedef struct _XGI_Ext2Struct
+{
+ USHORT Ext_InfoFlag;
+ UCHAR Ext_CRT1CRTC;
+ UCHAR Ext_CRTVCLK;
+ UCHAR Ext_CRT2CRTC;
+ UCHAR Ext_CRT2CRTC2;
+ UCHAR ModeID;
+ USHORT XRes;
+ USHORT YRes;
+ /* USHORT ROM_OFFSET; */
+} XGI_Ext2Struct;
+
+
+typedef struct _XGI_MCLKDataStruct
+{
+ UCHAR SR28,SR29,SR2A;
+ USHORT CLOCK;
+} XGI_MCLKDataStruct;
+
+typedef struct _XGI_ECLKDataStruct
+{
+ UCHAR SR2E,SR2F,SR30;
+ USHORT CLOCK;
+} XGI_ECLKDataStruct;
+
+typedef struct _XGI_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
+} XGI_VCLKDataStruct;
+
+typedef struct _XGI_VBVCLKDataStruct
+{
+ UCHAR Part4_A,Part4_B;
+ USHORT CLOCK;
+} XGI_VBVCLKDataStruct;
+
+typedef struct _XGI_StResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+} XGI_StResInfoStruct;
+
+typedef struct _XGI_ModeResInfoStruct
+{
+ USHORT HTotal;
+ USHORT VTotal;
+ UCHAR XChar;
+ UCHAR YChar;
+} XGI_ModeResInfoStruct;
+
+typedef struct _XGI_LCDNBDesStruct
+{
+ UCHAR NB[12];
+} XGI_LCDNBDesStruct;
+ /*add for new UNIVGABIOS*/
+typedef struct _XGI_LCDDesStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDHRS;
+ USHORT LCDVDES;
+ USHORT LCDVRS;
+} XGI_LCDDesStruct;
+
+typedef struct _XGI_LCDDataTablStruct
+{
+ UCHAR PANELID;
+ USHORT MASK;
+ USHORT CAP;
+ USHORT DATAPTR;
+} XGI_LCDDataTablStruct;
+
+typedef struct _XGI_TVTablDataStruct
+{
+ USHORT MASK;
+ USHORT CAP;
+ USHORT DATAPTR;
+} XGI_TVDataTablStruct;
+
+typedef struct _XGI330_LCDDesDataStruct
+{
+ USHORT LCDHDES;
+ USHORT LCDHRS;
+ USHORT LCDVDES;
+ USHORT LCDVRS;
+} XGI330_LCDDataDesStruct;
+
+
+typedef struct _XGI330_LVDSDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} XGI330_LVDSDataStruct;
+
+typedef struct _XGI330_LCDDesDataStruct2
+{
+ USHORT LCDHDES;
+ USHORT LCDHRS;
+ USHORT LCDVDES;
+ USHORT LCDVRS;
+ USHORT LCDHSync;
+ USHORT LCDVSync;
+} XGI330_LCDDataDesStruct2;
+
+typedef struct _XGI330_LCDDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} XGI330_LCDDataStruct;
+
+
+typedef struct _XGI330_TVDataStruct
+{
+ USHORT RVBHCMAX;
+ USHORT RVBHCFACT;
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT TVHDE;
+ USHORT TVVDE;
+ USHORT RVBHRS;
+ UCHAR FlickerMode;
+ USHORT HALFRVBHRS;
+} XGI330_TVDataStruct;
+
+typedef struct _XGI330_LCDDataTablStruct
+{
+ UCHAR PANELID;
+ USHORT MASK;
+ USHORT CAP;
+ USHORT DATAPTR;
+} XGI330_LCDDataTablStruct;
+
+typedef struct _XGI330_TVDataTablStruct
+{
+ USHORT MASK;
+ USHORT CAP;
+ USHORT DATAPTR;
+} XGI330_TVDataTablStruct;
+
+
+typedef struct _XGI330_CHTVDataStruct
+{
+ USHORT VGAHT;
+ USHORT VGAVT;
+ USHORT LCDHT;
+ USHORT LCDVT;
+} XGI330_CHTVDataStruct;
+
+typedef struct _XGI_TimingHStruct
+{
+ UCHAR data[8];
+} XGI_TimingHStruct;
+
+typedef struct _XGI_TimingVStruct
+{
+ UCHAR data[7];
+} XGI_TimingVStruct;
+
+/* Jong 10/04/2007; merge code */
+typedef struct _XGI_CH7007TV_TimingHStruct
+{
+ UCHAR data[10];
+} XGI_CH7007TV_TimingHStruct;
+
+/* Jong 10/04/2007; merge code */
+typedef struct _XGI_CH7007TV_TimingVStruct
+{
+ UCHAR data[10];
+} XGI_CH7007TV_TimingVStruct;
+
+/* Jong 10/04/2007; merge code */
+typedef struct _XGI_XG21CRT1Struct
+{
+ UCHAR ModeID,CR02,CR03,CR15,CR16;
+} XGI_XG21CRT1Struct;
+
+typedef struct _XGI330_CHTVRegDataStruct
+{
+ UCHAR Reg[16];
+} XGI330_CHTVRegDataStruct;
+
+typedef struct _XGI330_LCDCapStruct
+{
+ UCHAR LCD_ID;
+ USHORT LCD_Capability;
+ UCHAR LCD_SetFlag;
+ UCHAR LCD_DelayCompensation;
+ UCHAR LCD_HSyncWidth;
+ UCHAR LCD_VSyncWidth;
+ UCHAR LCD_VCLK;
+ UCHAR LCDA_VCLKData1;
+ UCHAR LCDA_VCLKData2;
+ UCHAR LCUCHAR_VCLKData1;
+ UCHAR LCUCHAR_VCLKData2;
+ UCHAR PSC_S1;
+ UCHAR PSC_S2;
+ UCHAR PSC_S3;
+ UCHAR PSC_S4;
+ UCHAR PSC_S5;
+ UCHAR PWD_2B;
+ UCHAR PWD_2C;
+ UCHAR PWD_2D;
+ UCHAR PWD_2E;
+ UCHAR PWD_2F;
+ UCHAR Spectrum_31;
+ UCHAR Spectrum_32;
+ UCHAR Spectrum_33;
+ UCHAR Spectrum_34;
+} XGI330_LCDCapStruct;
+
+/* Jong 10/04/2007; merge code */
+typedef struct _XGI21_LVDSCapStruct
+{
+ USHORT LVDS_Capability;
+ USHORT LVDSHT;
+ USHORT LVDSVT;
+ USHORT LVDSHDE;
+ USHORT LVDSVDE;
+ USHORT LVDSHFP;
+ USHORT LVDSVFP;
+ USHORT LVDSHSYNC;
+ USHORT LVDSVSYNC;
+ UCHAR VCLKData1;
+ UCHAR VCLKData2;
+ UCHAR PSC_S1;
+ UCHAR PSC_S2;
+ UCHAR PSC_S3;
+ UCHAR PSC_S4;
+ UCHAR PSC_S5;
+} XGI21_LVDSCapStruct;
+
+typedef struct _XGI_CRT1TableStruct
+{
+ UCHAR CR[15];
+} XGI_CRT1TableStruct;
+
+
+typedef struct _XGI330_VCLKDataStruct
+{
+ UCHAR SR2B,SR2C;
+ USHORT CLOCK;
+} XGI330_VCLKDataStruct;
+
+typedef struct _XGI301C_Tap4TimingStruct
+{
+ USHORT DE;
+ UCHAR Reg[64]; /* C0-FF */
+} XGI301C_Tap4TimingStruct;
+
+typedef struct _XGI_New_StandTableStruct
+{
+ UCHAR CRT_COLS;
+ UCHAR ROWS;
+ UCHAR CHAR_HEIGHT;
+ USHORT CRT_LEN;
+ UCHAR SR[4];
+ UCHAR MISC;
+ UCHAR CRTC[0x19];
+ UCHAR ATTR[0x14];
+ UCHAR GRC[9];
+} XGI_New_StandTableStruct;
+
+typedef UCHAR DRAM8Type[8];
+typedef UCHAR DRAM4Type[4];
+typedef UCHAR DRAM32Type[32];
+typedef UCHAR DRAM2Type[2];
+
+typedef struct _VB_DEVICE_INFO VB_DEVICE_INFO,*PVB_DEVICE_INFO;
+
+#define AGP_REG_SIZE 12
+#define CR40_SIZE 24
+#define CR6B_SIZE 8
+#define CR6E_SIZE 8
+#define CR6F_SIZE 8
+#define CR89_SIZE 8
+#define SR15_SIZE 4
+#define MCLK_SIZE 8
+#define ECLK_SIZE 8
+
+struct _VB_DEVICE_INFO
+{
+ BOOLEAN ISXPDOS;
+ USHORT P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
+ USHORT P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
+ USHORT Part0Port,Part1Port,Part2Port;
+ USHORT Part3Port,Part4Port,Part5Port;
+ USHORT RVBHCFACT,RVBHCMAX,RVBHRS;
+ USHORT VGAVT,VGAHT,VGAVDE,VGAHDE;
+ USHORT VT,HT,VDE,HDE;
+ USHORT LCDHRS,LCDVRS,LCDHDES,LCDVDES;
+
+ USHORT ModeType;
+ USHORT IF_DEF_TRUMPION,IF_DEF_DSTN;
+ USHORT IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
+ USHORT IF_DEF_CH7017,IF_DEF_LCDA,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
+ USHORT IF_DEF_ExpLink;
+ USHORT IF_DEF_CH7005,IF_DEF_HiVision; /* Jong 10/08/2007; merge code */
+ USHORT IF_DEF_CH7007; /* Jong 10/04/2007; merge code */
+ USHORT LCDResInfo,LCDTypeInfo, VBType;/*301b*/
+ USHORT VBInfo,TVInfo,LCDInfo;
+ USHORT VBExtInfo;/*301lv*/
+ USHORT SetFlag;
+ USHORT NewFlickerMode;
+ USHORT SelectCRT2Rate;
+
+ PUCHAR ROMAddr;
+ PUCHAR FBAddr;
+ USHORT BaseAddr;
+ XGIIOADDRESS RelIO;
+
+ DRAM4Type CR6B[CR6B_SIZE];
+
+ UCHAR XG45CR6E[CR6E_SIZE];
+ UCHAR XG45CR6F[CR6F_SIZE];
+ DRAM4Type CR6E[CR6E_SIZE];
+ DRAM32Type CR6F[CR6F_SIZE];
+ DRAM2Type CR89[CR89_SIZE];
+
+ DRAM8Type SR15[SR15_SIZE]; /* pointer : point to array */
+ DRAM8Type CR40[CR40_SIZE];
+ UCHAR SoftSetting;
+ UCHAR OutputSelect;
+
+ USHORT IF_DEF_LVDS; /* Jong 10/05/2007; merge code */
+
+ const USHORT *pRGBSenseData;
+ const USHORT *pRGBSenseData2; /*301b*/
+ const USHORT *pVideoSenseData;
+ const USHORT *pVideoSenseData2;
+ const USHORT *pYCSenseData;
+ const USHORT *pYCSenseData2;
+
+ UCHAR SR07;
+ UCHAR CR49[2];
+ UCHAR SR1F;
+ UCHAR AGPReg[AGP_REG_SIZE];
+ UCHAR SR16[4];
+ UCHAR SR21;
+ UCHAR SR22;
+ UCHAR SR23;
+ UCHAR SR24;
+ UCHAR SR25[2];
+ UCHAR SR31;
+ UCHAR SR32;
+ UCHAR SR33;
+
+ /* Jong 10/05/2007; merge code */
+ UCHAR *pSR36;
+ UCHAR CRCF;
+ UCHAR *pCRD0;
+ UCHAR *pCRDE;
+ UCHAR *pCR8F;
+ UCHAR *pSR40;
+ UCHAR *pSR41;
+ UCHAR *pDVOSetting;
+ UCHAR *pCR2E;
+ UCHAR *pCR2F;
+ UCHAR *pCR46;
+ UCHAR *pCR47;
+
+ UCHAR CRT2Data_1_2;
+ UCHAR CRT2Data_4_D;
+ UCHAR CRT2Data_4_E;
+ UCHAR CRT2Data_4_10;
+ XGI_MCLKDataStruct MCLKData[MCLK_SIZE];
+ XGI_ECLKDataStruct ECLKData[ECLK_SIZE];
+
+ const UCHAR *XGI_TVDelayList;
+ const UCHAR *XGI_TVDelayList2;
+ const UCHAR *CHTVVCLKUNTSC;
+ const UCHAR *CHTVVCLKONTSC;
+ const UCHAR *CHTVVCLKUPAL;
+ const UCHAR *CHTVVCLKOPAL;
+ const UCHAR *NTSCTiming;
+ const UCHAR *PALTiming;
+ const UCHAR *HiTVExtTiming;
+ const UCHAR *HiTVSt1Timing;
+ const UCHAR *HiTVSt2Timing;
+ const UCHAR *HiTVTextTiming;
+ const UCHAR *YPbPr750pTiming;
+ const UCHAR *YPbPr525pTiming;
+ const UCHAR *YPbPr525iTiming;
+ const UCHAR *HiTVGroup3Data;
+ const UCHAR *HiTVGroup3Simu;
+ const UCHAR *HiTVGroup3Text;
+ const UCHAR *Ren525pGroup3;
+ const UCHAR *Ren750pGroup3;
+ const UCHAR *ScreenOffset;
+ UCHAR DRAMTypeDefinition;
+ UCHAR I2CDefinition;
+ UCHAR CR97;
+
+ const XGI330_LCDCapStruct *LCDCapList;
+ XGI21_LVDSCapStruct *XG21_LVDSCapList; /* Jong 10/05/2007; merge code */
+
+ XGI_TimingHStruct TimingH;
+ XGI_TimingVStruct TimingV;
+
+ const XGI_StStruct *SModeIDTable;
+ const XGI_StandTableStruct *StandTable;
+ const XGI_ExtStruct *EModeIDTable;
+ const XGI_Ext2Struct *RefIndex;
+ /* XGINew_CRT1TableStruct *CRT1Table; */
+ const XGI_CRT1TableStruct *XGINEWUB_CRT1Table;
+ const XGI_VCLKDataStruct *VCLKData;
+ const XGI_VBVCLKDataStruct *VBVCLKData;
+ const XGI_StResInfoStruct *StResInfo;
+ const XGI_ModeResInfoStruct *ModeResInfo;
+ XGI_XG21CRT1Struct *UpdateCRT1; /* Jong 10/05/2007; merge code */
+}; /* _VB_DEVICE_INFO */
+
+/* Jong 10/04/2007; merge code */
+typedef struct
+{
+ USHORT Horizontal_ACTIVE;
+ USHORT Horizontal_FP;
+ USHORT Horizontal_SYNC;
+ USHORT Horizontal_BP;
+ USHORT Vertical_ACTIVE;
+ USHORT Vertical_FP;
+ USHORT Vertical_SYNC;
+ USHORT Vertical_BP;
+ double DCLK;
+ UCHAR FrameRate;
+ UCHAR Interlace;
+ USHORT Margin;
+} TimingInfo;
+
+#define _VB_STRUCT_
+#endif /* _VB_STRUCT_ */
diff --git a/src/vb_table.h b/src/vb_table.h
index 2b31679..b26427c 100644
--- a/src/vb_table.h
+++ b/src/vb_table.h
@@ -84,7 +84,36 @@ static const DRAM8Type XGI340_CR41[CR40_SIZE] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 23 CRC5 */
};
-static const DRAM4Type XGI340_CR6B[CR6B_SIZE]={
+/* Jong 10/04/2007; merge code */
+UCHAR XGI27_cr41[24][8]=
+{
+{0x20,0x60,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
+{0x04,0x44,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
+{0x04,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
+{0xb5,0x03,0xa4,0x00,0x00,0x00,0x00,0x00},/* 3 CR40[7],CR99[2:0],CR45[3:0]*/
+{0xf0,0xf5,0xf0,0x00,0x00,0x00,0x00,0x00},/* 4 CR59 */
+{0xa4,0x1C,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
+{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
+{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
+{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
+{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
+{0x48,0xa8,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
+{0x77,0x88,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
+{0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
+{0x44,0x32,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
+{0x44,0x33,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
+{0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
+{0x44,0x63,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
+{0x0A,0x14,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
+{0x0C,0x0B,0x0C,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
+{0x05,0x22,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
+{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
+{0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
+};
+
+UCHAR XGI340_CR6B[8][4]={
{0xaa, 0xaa, 0xaa, 0xaa},
{0xaa, 0xaa, 0xaa, 0xaa},
{0xaa, 0xaa, 0xaa, 0xaa},
@@ -275,7 +304,32 @@ static const XGI_ExtStruct XGI330_EModeIDTable[]=
{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
};
-static const XGI_StandTableStruct XGI330_StandTable[]=
+/* Jong 10/04/2007; merge code */
+TimingInfo SpecialModeTiming[]=
+{
+ {1280,110, 40,220, 720, 5, 5, 20,
+ 74.18, 60, 0, 0
+ },
+ {1440, 80,152,232, 900, 1, 3, 28,
+ 106.472, 60, 0, 0
+ },
+ {1920, 88, 44,148, 540, 2, 5, 15,
+ 74.11, 60, 1, 0
+ },
+ {1920,120,208,328, 1080, 1, 3, 34,
+ 172.8, 60, 0, 0
+ },
+ {1920,128,208,336, 1200, 1, 3, 38,
+ 193.16, 60, 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0
+ }
+};
+
+
+
+XGI_StandTableStruct XGI330_StandTable[]=
{
/* MD_0_200 */
{
@@ -719,6 +773,27 @@ static const XGI_TimingHStruct XGI_TimingH[]=
static const XGI_TimingVStruct XGI_TimingV[]=
{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
+/* Jong 10/04/2007; merge code */
+XGI_XG21CRT1Struct XGI_UpdateCRT1Table[]=
+{
+ {0x01,0x27,0x91,0x8f,0xc0}, /* 00 */
+ {0x03,0x4f,0x83,0x8f,0xc0}, /* 01 */
+ {0x05,0x27,0x91,0x8f,0xc0}, /* 02 */
+ {0x06,0x4f,0x83,0x8f,0xc0}, /* 03 */
+ {0x07,0x4f,0x83,0x8f,0xc0}, /* 04 */
+ {0x0d,0x27,0x91,0x8f,0xc0}, /* 05 */
+ {0x0e,0x4f,0x83,0x8f,0xc0}, /* 06 */
+ {0x0f,0x4f,0x83,0x5d,0xc0}, /* 07 */
+ {0x10,0x4f,0x83,0x5d,0xc0}, /* 08 */
+ {0x11,0x4f,0x83,0xdf,0x0c}, /* 09 */
+ {0x12,0x4f,0x83,0xdf,0x0c}, /* 10 */
+ {0x13,0x4f,0x83,0x8f,0xc0}, /* 11 */
+ {0x2e,0x4f,0x83,0xdf,0x0c}, /* 12 */
+ {0x2e,0x4f,0x87,0xdf,0xc0}, /* 13 */
+ {0x2f,0x4f,0x83,0x8f,0xc0}, /* 14 */
+ {0x50,0x27,0x91,0xdf,0x0c}, /* 15 */
+ {0x59,0x27,0x91,0x8f,0xc0} /* 16 */
+};
static const XGI_CRT1TableStruct XGI_CRT1Table[]=
{
@@ -2542,6 +2617,74 @@ static const XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[]=
{{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* ; 05 (x1024) */
};
+/* Jong 10/04/2007; merge code */
+XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[]=
+{
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
+ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
+ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
+ {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
+ 0x18,0x84,0xdf,0x57,0x00,0x00,0x01,0x00 }},
+ {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x06,0x01 }}
+};
+
+/* Jong 10/04/2007; merge code */
+XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[]=
+{
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
+ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
+ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
+ {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
+ 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,0x00 }},
+ {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
+ 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,0x01 }}
+};
+
+/* Jong 10/04/2007; merge code */
+XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[]=
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
+ 0x50,0x84,0xdf,0xed,0x00,0x00,0x05,0x00 }},
+ {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
+ 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,0x01 }}
+};
+
+/* Jong 10/04/2007; merge code */
+XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[]=
+{
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
+ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
+ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
+ {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
+ 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,0x00 }},
+ {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
+ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,0x01 }}
+};
+
/*add for new UNIVGABIOS*/
static const XGI330_LCDDataTablStruct XGI_LCDDataTable[]=
{
@@ -2787,7 +2930,37 @@ static const XGI330_LCDCapStruct XGI_LCDCapList[]=
0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
};
-static const XGI_Ext2Struct XGI330_RefIndex[]=
+/* Jong 10/04/2007; merge code */
+XGI21_LVDSCapStruct XGI21_LCDCapList[]=
+{
+ {DisableLCD24bpp + LCDPolarity,
+ 2160,1250,1600,1200, 64, 1, 192, 3,
+ 0x70,0x24,0x20,0x04,0x0A,0x02,0xC8
+ },
+ {DisableLCD24bpp + LCDPolarity,
+ 1688,1066,1280,1024, 48, 1, 112, 3,
+ 0x70,0x44,0x20,0x04,0x0A,0x02,0xC8
+ },
+ {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
+ 1344, 806,1024, 768, 24, 3, 136, 6,
+ 0x6C,0x65,0x20,0x04,0x0A,0x02,0xC8
+ },
+ {DisableLCD24bpp + LCDPolarity,
+ 1056, 628, 800, 600, 40, 1, 128, 4,
+ 0x42,0xE2,0x20,0x14,0x0A,0x02,0x00
+ },
+ {DisableLCD24bpp + LCDPolarity,
+ 928, 525, 800, 480, 40, 13, 48, 3,
+ 0x52,0xC5,0x20,0x14,0x0A,0x02,0x00
+ },
+ {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
+ 800, 525, 640, 480, 16, 10, 96, 2,
+ 0x1B,0xE1,0x20,0x04,0x0A,0x02,0xC8
+ }
+
+};
+
+XGI_Ext2Struct XGI330_RefIndex[]=
{
{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x59, 320, 200},/* 00 */
{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x00, 320, 400},/* 01 */
@@ -2888,6 +3061,18 @@ static const XGI_MCLKDataStruct XGI340New_MCLKData[MCLK_SIZE]=
{ 0x29,0x01,0x81,300}
};
+/* Jong 10/04/2007; merge code */
+static const XGI_MCLKDataStruct XGI27New_MCLKData[]=
+{
+ { 0x5c,0x23,0x01,166},
+ { 0x19,0x02,0x01,124},
+ { 0x7C,0x08,0x80,200},
+ { 0x79,0x06,0x80,250},
+ { 0x29,0x01,0x81,300},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166},
+ { 0x5c,0x23,0x01,166}
+};
static const UCHAR XGI330_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,0x78,0x80,0x2d,0x35,0x57,0x48 };
@@ -2930,6 +3115,20 @@ static const XGI_ModeResInfoStruct XGI330_ModeResInfo[]=
static const UCHAR XGI330_OutputSelect = 0x40;
static const UCHAR XGI330_SoftSetting = 0x30;
static const UCHAR XGI330_SR07 = 0x18;
+static const UCHAR XG21_DVOSetting = 0x00 ;
+static const UCHAR XG21_CR2E = 0x00 ;
+static const UCHAR XG21_CR2F = 0x00 ;
+static const UCHAR XG21_CR46 = 0x00 ;
+static const UCHAR XG21_CR47 = 0x00 ;
+
+UCHAR XG27_CR97 = 0xC1 ;
+UCHAR XG27_SR36 = 0x30 ;
+UCHAR XG27_CR8F = 0x09 ;
+UCHAR XG27_CRD0[] = {0,0,0,0,0,0,0,0x82,0x00,0x66,0x01,0x00} ;
+UCHAR XG27_CRDE[] = {0,0} ;
+UCHAR XG27_SR40 = 0x04 ;
+UCHAR XG27_SR41 = 0x00 ;
+
static const UCHAR XGI330_CR49[2] = { 0xaa, 0x88 };
static const UCHAR XGI330_SR1F = 0x00;
diff --git a/src/vgatypes.h b/src/vgatypes.h
index dda97fe..f26ea57 100644
--- a/src/vgatypes.h
+++ b/src/vgatypes.h
@@ -150,6 +150,7 @@ typedef enum _XGI_CHIP_TYPE {
XG45,
XG20 = 48,
XG21,
+ XG27,
MAX_XGI_CHIP
} XGI_CHIP_TYPE;
#endif
@@ -279,6 +280,25 @@ struct _XGI_HW_DEVICE_INFO
UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH];
+ /* Jong 09/18/2007; patch to GIT */
+ /* Jong 08/17/2007; Alan's code to support custom mode of modeline */
+ /* --------------------------------------------------------------------- */
+ UCHAR BPP;
+ UCHAR Frequency;
+ USHORT Horizontal_ACTIVE;
+ USHORT Vertical_ACTIVE;
+ UCHAR SpecialMode;
+
+ UCHAR SpecifyTiming; /* Set 1 for specifying timing*/
+ USHORT Horizontal_FP; /* Alan 08/10/2007; HSyncStart - HDisplay */
+ USHORT Horizontal_BP; /* Alan 08/10/2007; HTotal - HSyncEnd */
+ USHORT Horizontal_SYNC; /* Alan 08/10/2007; HSyncEnd - HSyncStart */
+ USHORT Vertical_FP;
+ USHORT Vertical_BP;
+ USHORT Vertical_SYNC;
+ double DCLK;
+ UCHAR Interlace; /* Alan 08/10/2007; specify interlace or not */
+ /* --------------------------------------------------------------------- */
};
#endif
diff --git a/src/xgi.h b/src/xgi.h
index 0f016d2..9a89bd7 100644
--- a/src/xgi.h
+++ b/src/xgi.h
@@ -1,890 +1,904 @@
-/*
- * Main global data and definitions
- *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1) Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3) The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Authors: Thomas Winischhofer <thomas@winischhofer.net>
- * others (old code base)
- *
- */
-#ifndef _XGI_H_
-#define _XGI_H_
-
-/***************
-
-#define DEBUG2
-#define DEBUG
-#define DEBUG1
-#define DEBUG3
-#define DEBUG4
-#define DEBUG5
-*****************/
-
-
-#ifdef DEBUG
-#define PDEBUG(p) p
-#else
-#define PDEBUG(p)
-#endif
-
-#ifdef DEBUG1
-#define PDEBUG1(p) p
-#else
-#define PDEBUG1(p)
-#endif
-
-#ifdef DEBUG2
-#define PDEBUG2(p) p
-#else
-#define PDEBUG2(p)
-#endif
-
-#ifdef DEBUG3
-#define PDEBUG3(p) p
-#else
-#define PDEBUG3(p)
-#endif
-
-#ifdef DEBUG4
-#define PDEBUG4(p) p
-#else
-#define PDEBUG4(p)
-#endif
-
-#ifdef DEBUG5
-#define PDEBUG5(p) p
-#else
-#define PDEBUG5(p)
-#endif
-
-/* Always unlock the registers (should be set!) */
-#define UNLOCK_ALWAYS
-
-#undef XGI_CP
-
-#ifdef XSERVER_LIBPCIACCESS
-#include <pciaccess.h>
-#else
-#include "xf86Pci.h"
-#endif
-#include "xf86Cursor.h"
-#include "xf86xv.h"
-#include "compiler.h"
-#include "xaa.h"
-#include "vgaHW.h"
-#include "vbe.h"
-
-#ifdef XORG_VERSION_CURRENT
-#include "xorgVersion.h"
-#endif
-
-#include "xgi_pci.h"
-#include "osdef.h"
-#include "vgatypes.h"
-#include "vb_struct.h"
-
-#ifdef XF86DRI
-#define XGINEWDRI
-#undef XGINEWDRI2
-#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,99,0) /* Adapt this when the time has come */
-#define XGINEWDRI2
-#endif
-#include "xf86drm.h"
-#include "sarea.h"
-#define _XF86DRI_SERVER_
-#include "xf86dri.h"
-#include "dri.h"
-#include "GL/glxint.h"
-#include "xgi_dri.h"
-#endif
-
-#ifdef XSERVER_LIBPCIACCESS
-#define VENDOR_ID(p) (p)->vendor_id
-#define DEVICE_ID(p) (p)->device_id
-#define SUBSYS_ID(p) (p)->subdevice_id
-#define CHIP_REVISION(p) (p)->revision
-#else
-#define VENDOR_ID(p) (p)->vendor
-#define DEVICE_ID(p) (p)->chipType
-#define SUBSYS_ID(p) (p)->subsysCard
-#define CHIP_REVISION(p) (p)->chipRev
-#endif
-
-#if 1
-#define XGIDUALHEAD /* Include Dual Head code */
-#endif
-
-#if 1
-#define XGIMERGED /* Include Merged-FB mode */
-#endif
-
-#ifdef XGIMERGED
-#if 1
-#define XGIXINERAMA /* Include Pseudo-Xinerama for MergedFB mode */
-#define XGI_XINERAMA_MAJOR_VERSION 1
-#define XGI_XINERAMA_MINOR_VERSION 1
-#endif
-#endif
-
-#if 1
-#define XGIGAMMA /* Include code for gamma correction */
-#endif
-
-#if 1 /* Include code for color hardware cursors */
-#define XGI_ARGB_CURSOR
-#endif
-
-#if 0 /* Include YPbPr support on VB */
-#define ENABLE_YPBPR
-#endif
-
-#ifdef XGIMERGED
-#ifdef XGIXINERAMA
-#define NEED_REPLIES /* ? */
-#define EXTENSION_PROC_ARGS void *
-#include "extnsionst.h" /* required */
-#include <X11/extensions/panoramiXproto.h> /* required */
-#endif
-#endif
-
-#if 1
-#define XGIVRAMQ /* Use VRAM queue mode on 315 series */
-#endif
-
-#undef XGI315DRI /* define this if dri is adapted for 315/330 series */
-
-#ifndef PCI_VENDOR_XGI
-#define PCI_VENDOR_XGI 0x18CA
-#endif
-#ifndef PCI_CHIP_XGIXG40
-#define PCI_CHIP_XGIXG40 0x0040
-#endif
-#ifndef PCI_CHIP_XGIXG20
-#define PCI_CHIP_XGIXG20 0x0020
-#endif
-
-#define CONFIG_DRM_XGI
-
-#define XGI_NAME "XGI"
-#define XGI_DRIVER_NAME "xgi"
-#define XGI_CURRENT_VERSION ((PACKAGE_VERSION_MAJOR << 16) | \
- (PACKAGE_VERSION_MINOR << 8) | \
- PACKAGE_VERSION_PATCHLEVEL)
-
-/* pXGI->Flags (old series only) */
-#define SYNCDRAM 0x00000001
-#define RAMFLAG 0x00000002
-#define ESS137xPRESENT 0x00000004
-#define SECRETFLAG 0x00000008
-#define A6326REVAB 0x00000010
-#define MMIOMODE 0x00010000
-#define LFBQMODE 0x00020000
-#define AGPQMODE 0x00040000
-#define UMA 0x80000000
-
-#define BIOS_BASE 0xC0000
-#define BIOS_SIZE 0x10000
-
-#define SR_BUFFER_SIZE 5
-#define CR_BUFFER_SIZE 5
-
-#define XGI_VBFlagsVersion 1
-
-/* VBFlags - if anything is changed here, increase VBFlagsVersion! */
-#define CRT2_DEFAULT 0x00000001
-#define CRT2_LCD 0x00000002 /* Never change the order of the CRT2_XXX entries */
-#define CRT2_TV 0x00000004
-#define CRT2_VGA 0x00000008
-#define TV_NTSC 0x00000010
-#define TV_PAL 0x00000020
-#define TV_HIVISION 0x00000040
-#define TV_YPBPR 0x00000080
-#define TV_AVIDEO 0x00000100
-#define TV_SVIDEO 0x00000200
-#define TV_SCART 0x00000400
-#define VB_CONEXANT 0x00000800 /* 661 series only */
-#define VB_TRUMPION VB_CONEXANT /* 300 series only */
-#define TV_PALM 0x00001000
-#define TV_PALN 0x00002000
-#define TV_NTSCJ 0x00001000
-#define VB_302ELV 0x00004000
-#define TV_CHSCART 0x00008000
-#define TV_CHYPBPR525I 0x00010000
-#define CRT1_VGA 0x00000000
-#define CRT1_LCDA 0x00020000
-#define VGA2_CONNECTED 0x00040000
-#define DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
-
-#define SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
-#define MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
-#define DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
-
-/* Aliases: */
-#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
-#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
-#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR)
-
-/* Only if TV_YPBPR is set: */
-#define TV_YPBPR525I TV_NTSC
-#define TV_YPBPR525P TV_PAL
-#define TV_YPBPR750P TV_PALM
-#define TV_YPBPR1080I TV_PALN
-#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
-
-#define TV_YPBPR43LB TV_CHSCART
-#define TV_YPBPR43 TV_CHYPBPR525I
-#define TV_YPBPR169 (TV_CHSCART | TV_CHYPBPR525I)
-#define TV_YPBPRAR (TV_CHSCART | TV_CHYPBPR525I)
-
-
-#define DISPTYPE_DISP2 CRT2_ENABLE
-#define DISPTYPE_DISP1 DISPTYPE_CRT1
-#define VB_DISPMODE_SINGLE SINGLE_MODE /* alias */
-#define VB_DISPMODE_MIRROR MIRROR_MODE /* alias */
-#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */
-#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
-
-/* PresetMode argument */
-#define XGI_MODE_SIMU 0
-#define XGI_MODE_CRT1 1
-#define XGI_MODE_CRT2 2
-
-/* pXGI->MiscFlags */
-#define MISC_CRT1OVERLAY 0x00000001 /* Current display mode supports overlay */
-#define MISC_PANELLINKSCALER 0x00000002 /* Panel link is currently scaling */
-#define MISC_CRT1OVERLAYGAMMA 0x00000004 /* Current display mode supports overlay gamma corr on CRT1 */
-#define MISC_TVNTSC1024 0x00000008 /* Current display mode is TV NTSC/PALM/YPBPR525I 1024x768 */
-
-
-#define HW_DEVICE_EXTENSION XGI_HW_DEVICE_INFO
-
-#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
-#define GENMASK(mask) BITMASK(1?mask,0?mask)
-
-typedef unsigned long ULong;
-typedef unsigned short UShort;
-typedef unsigned char UChar;
-
-
-/* ChipFlags */
-/* Use only lower 16 bit for chip id! (xgictrl) */
-#define XGICF_LARGEOVERLAY 0x00000001
-#define XGICF_Is651 0x00000002
-#define XGICF_IsM650 0x00000004
-#define XGICF_IsM652 0x00000008
-#define XGICF_IsM653 0x00000010
-#define XGICF_Is652 0x00000020
-#define XGICF_Is65x (XGICF_Is651|XGICF_IsM650|XGICF_IsM652|XGICF_IsM653|XGICF_Is652)
-#define XGICF_IsM661 0x00000100 /* M661FX */
-#define XGICF_IsM741 0x00000200
-#define XGICF_IsM760 0x00000400
-#define XGICF_IsM661M 0x00000800 /* M661MX */
-#define XGICF_IsM66x (XGICF_IsM661 | XGICF_IsM741 | XGICF_IsM760 | XGICF_IsM661M)
-#define XGICF_315Core 0x00010000 /* 3D: Real 315 */
-#define XGICF_Real256ECore 0x00020000 /* 3D: Similar to 315 core, no T&L? (65x, 661, 740, 741) */
-#define XGICF_XabreCore 0x00040000 /* 3D: Real Xabre */
-#define XGICF_Ultra256Core 0x00080000 /* 3D: Similar to Xabre, no T&L?, no P:Shader? (660, 760) */
-#define XGICF_UseLCDA 0x01000000
-#define XGICF_760UMA 0x10000000 /* 760: UMA active */
-#define XGICF_CRT2HWCKaputt 0x20000000 /* CRT2 Mono HWCursor engine buggy */
-#define XGICF_Glamour3 0x40000000
-#define XGICF_Integrated 0x80000000
-
-/* Direct Xv-API */
-#define XGI_SD_IS300SERIES 0x00000001
-#define XGI_SD_IS315SERIES 0x00000002
-#define XGI_SD_IS330SERIES 0x00000004
-#define XGI_SD_SUPPORTPALMN 0x00000008 /* tv chip supports pal-m, pal-n */
-#define XGI_SD_SUPPORT2OVL 0x00000010 /* set = 2 overlays, clear = support SWITCHCRT xv prop */
-#define XGI_SD_SUPPORTTVPOS 0x00000020 /* supports changing tv position */
-#define XGI_SD_ISDUALHEAD 0x00000040 /* Driver is in dual head mode */
-#define XGI_SD_ISMERGEDFB 0x00000080 /* Driver is in merged fb mode */
-#define XGI_SD_ISDHSECONDHEAD 0x00000100 /* Dual head: This is CRT1 (=second head) */
-#define XGI_SD_ISDHXINERAMA 0x00000200 /* Dual head: We are running Xinerama */
-#define XGI_SD_VBHASSCART 0x00000400 /* videobridge has SCART instead of VGA2 */
-#define XGI_SD_ISDEPTH8 0x00000800 /* Depth is 8, no independent gamma correction */
-#define XGI_SD_ENABLED 0x00002000 /* xgictrl is enabled (by option) */
-#define XGI_SD_PSEUDOXINERAMA 0x00004000 /* pseudo xinerama is active */
-#define XGI_SD_SUPPORTLCDA 0x00008000 /* Support LCD Channel A */
-#define XGI_SD_SUPPORTNTSCJ 0x00010000 /* tv chip supports ntsc-j */
-#define XGI_SD_ADDLSUPFLAG 0x00020000 /* 1 = the following flags are valid */
-#define XGI_SD_SUPPORTVGA2 0x00040000 /* CRT2=VGA supported */
-#define XGI_SD_SUPPORTSCART 0x00080000 /* CRT2=SCART supported */
-#define XGI_SD_SUPPORTOVERSCAN 0x00100000 /* Overscan flag supported */
-#define XGI_SD_SUPPORTXVGAMMA1 0x00200000 /* Xv Gamma correction for CRT1 supported */
-#define XGI_SD_SUPPORTTV 0x00400000 /* CRT2=TV supported */
-#define XGI_SD_SUPPORTYPBPR 0x00800000 /* CRT2=YPbPr (525i, 525p, 750p, 1080i) is supported */
-#define XGI_SD_SUPPORTHIVISION 0x01000000 /* CRT2=HiVision is supported */
-#define XGI_SD_SUPPORTYPBPRAR 0x02000000 /* YPbPr aspect ratio is supported */
-#define XGI_SD_SUPPORTSCALE 0x04000000 /* Scaling of LCD panel supported */
-#define XGI_SD_SUPPORTCENTER 0x08000000 /* If scaling supported: Centering of screen [NOT] supported (TMDS only) */
-
-#define XGI_DIRECTKEY 0x03145792
-
-/* XGICtrl: Check mode for CRT2 */
-#define XGI_CF2_LCD 0x01
-#define XGI_CF2_TV 0x02
-#define XGI_CF2_VGA2 0x04
-#define XGI_CF2_TVPAL 0x08
-#define XGI_CF2_TVNTSC 0x10 /* + NTSC-J */
-#define XGI_CF2_TVPALM 0x20
-#define XGI_CF2_TVPALN 0x40
-#define XGI_CF2_CRT1LCDA 0x80
-#define XGI_CF2_TYPEMASK (XGI_CF2_LCD | XGI_CF2_TV | XGI_CF2_VGA2 | XGI_CF2_CRT1LCDA)
-#define XGI_CF2_TVSPECIAL (XGI_CF2_LCD | XGI_CF2_TV)
-#define XGI_CF2_TVSPECMASK (XGI_CF2_TVPAL | XGI_CF2_TVNTSC | XGI_CF2_TVPALM | XGI_CF2_TVPALN)
-#define XGI_CF2_TVHIVISION XGI_CF2_TVPAL
-#define XGI_CF2_TVYPBPR525I XGI_CF2_TVNTSC
-#define XGI_CF2_TVYPBPR525P (XGI_CF2_TVPAL | XGI_CF2_TVNTSC)
-#define XGI_CF2_TVYPBPR750P XGI_CF2_TVPALM
-#define XGI_CF2_TVYPBPR1080I (XGI_CF2_TVPALM | XGI_CF2_TVPAL)
-
-/* AGP stuff for DRI */
-#define AGP_PAGE_SIZE 4096
-#define AGP_PAGES 2048 /* Default: 2048 pages @ 4096 = 8MB */
-/* 300 */
-#define AGP_CMDBUF_PAGES 256
-#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
-/* 315/330 */
-#define AGP_VTXBUF_PAGES 512
-#define AGP_VTXBUF_SIZE (AGP_PAGE_SIZE * AGP_VTXBUF_PAGES)
-
-#define VOLARI_CQSIZE (1024*1024)
-#define VOLARI_CQSIZEXG20 (128*1024)
-#define VOLARI_CURSOR_SHAPE_SIZE (64*64*4)
-
-/* For backup of register contents */
-typedef struct {
- unsigned char xgiRegs3C4[0x50];
- unsigned char xgiRegs3D4[0x90];
- unsigned char xgiRegs3C2;
- unsigned char xgiCapt[0x60];
- unsigned char xgiVid[0x50];
- unsigned char VBPart1[0x50];
- unsigned char VBPart2[0x100];
- unsigned char VBPart3[0x50];
- unsigned char VBPart4[0x50];
- unsigned short ch70xx[64];
- unsigned long xgiMMIO85C0;
- unsigned char xgi6326tv[0x46];
- unsigned long xgiRegsPCI50, xgiRegsPCIA0;
-} XGIRegRec, *XGIRegPtr;
-
-
-/* XGIFBLayout is mainly there because of DGA. It holds the
- * current layout parameters needed for acceleration and other
- * stuff. When switching mode using DGA, these are set up
- * accordingly and not necessarily match pScrn's. Therefore,
- * driver modules should read these values instead of pScrn's.
- */
-typedef struct {
- int bitsPerPixel; /* = pScrn->bitsPerPixel */
- int depth; /* = pScrn->depth */
- int displayWidth; /* = pScrn->displayWidth */
- DisplayModePtr mode; /* = pScrn->currentMode */
-} XGIFBLayout;
-
-/* Dual head private entity structure */
-typedef struct {
- ScrnInfoPtr pScrn_1;
- ScrnInfoPtr pScrn_2;
- unsigned char * BIOS;
- VB_DEVICE_INFO *XGI_Pr;
- int CRT2ModeNo; /* Current display mode for CRT2 */
- Bool CRT2ModeSet; /* CRT2 mode has been set */
- unsigned char CRT2CR30, CRT2CR31, CRT2CR35, CRT2CR38;
- int refCount;
-
- /**
- * Number of entities
- *
- * \bug
- * This field is tested in one place, but it doesn't appear to ever be
- * set or modified.
- */
- int lastInstance;
-
- Bool DisableDual; /* Emergency flag */
- Bool ErrorAfterFirst; /* Emergency flag: Error after first init -> Abort second */
- int maxUsedClock; /* Max used pixelclock on master head */
-
- /**
- * Framebuffer addresses and sizes
- *
- * \bug
- * These 4 fields are set, but the stored values don't appear to be used.
- */
- unsigned long masterFbAddress;
- unsigned long masterFbSize;
- unsigned long slaveFbAddress;
- unsigned long slaveFbSize;
-
- unsigned char * FbBase; /* VRAM linear address */
- unsigned char * IOBase; /* MMIO linear address */
-
- /**
- * Map / unmap queue counter.
- *
- * \bug
- * These vales are tested, set to zero, or decremented. However, I don't
- * see anywhere in the code where they are incremented.
- */
- unsigned short MapCountIOBase;
- unsigned short MapCountFbBase;
-
- Bool forceUnmapIOBase; /* ignore counter and unmap */
- Bool forceUnmapFbBase; /* ignore counter and unmap */
-#ifdef __alpha__
- unsigned char * IOBaseDense; /* MMIO for Alpha platform */
- unsigned short MapCountIOBaseDense;
- Bool forceUnmapIOBaseDense; /* ignore counter and unmap */
-#endif
- BOOLEAN CRT1gamma;
-
- /**
- * \bug This field is tested and set to \c NULL but never used.
- */
- unsigned char *RenderAccelArray;
- unsigned char * FbBase1;
- unsigned long OnScreenSize1;
-
-#ifdef XGI_CP
- XGI_CP_H_ENT
-#endif
-} XGIEntRec, *XGIEntPtr;
-
-#define XGIPTR(p) ((XGIPtr)((p)->driverPrivate))
-#define XAAPTR(p) ((XAAInfoRecPtr)(XGIPTR(p)->AccelInfoPtr))
-
-#define ExtRegSize 0x40
-
-
-/* Relative merge position */
-typedef enum {
- xgiLeftOf,
- xgiRightOf,
- xgiAbove,
- xgiBelow,
- xgiClone
-} XGIScrn2Rel;
-
-typedef struct MonitorRange {
- float loH,hiH,loV,hiV ;
-}MonitorRangeRec,*MonitorRangePtr ;
-
-typedef struct {
- ScrnInfoPtr pScrn; /* -------------- DON'T INSERT ANYTHING HERE --------------- */
-#ifdef XSERVER_LIBPCIACCESS
- struct pci_device * PciInfo;
-#else
- pciVideoPtr PciInfo; /* -------- OTHERWISE xgi_dri.so MUST BE RECOMPILED -------- */
- PCITAG PciTag;
-#endif
- EntityInfoPtr pEnt;
- int Chipset;
- int ChipRev;
- VB_DEVICE_INFO *XGI_Pr; /* For new mode switching code */
- unsigned long FbAddress; /* VRAM physical address (in DHM: for each Fb!) */
- unsigned long realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */
- unsigned char * FbBase; /* VRAM virtual linear address */
- CARD32 IOAddress; /* MMIO physical address */
- unsigned char * IOBase; /* MMIO linear address */
- IOADDRESS IODBase; /* Base of PIO memory area */
-#ifdef __alpha__
- unsigned char * IOBaseDense; /* MMIO for Alpha platform */
-#endif
- XGIIOADDRESS RelIO; /* Relocated IO Ports baseaddress */
- unsigned char * BIOS;
- int MemClock;
- int BusWidth;
- int MinClock;
- int MaxClock;
- int Flags; /* HW config flags */
- long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */
- long availMem; /* Really available Fb mem (minus TQ, HWCursor) */
- unsigned long maxxfbmem; /* limit fb memory X is to use to this (KB) */
- unsigned long xgifbMem; /* heapstart of xgifb (if running) */
- unsigned long dhmOffset; /* Offset to memory for each head (0 or ..) */
- DGAModePtr DGAModes;
- int numDGAModes;
- Bool DGAactive;
- Bool NoAccel;
- Bool NoXvideo;
- Bool TurboQueue;
- int ForceCRT1Type;
- int ForceCRT2Type;
- int OptROMUsage;
- Bool ValidWidth;
- unsigned char myCR63;
- unsigned long VBFlags; /* Video bridge configuration */
- unsigned long VBFlags_backup; /* Backup for SlaveMode-modes */
-
- short scrnOffset; /* Screen pitch (data) */
- short scrnPitch; /* Screen pitch (display; regarding interlace) */
- unsigned long DstColor;
- int xcurrent; /* for temp use in accel */
- int ycurrent; /* for temp use in accel */
- int CommandReg;
-
- Bool HWCursor;
- CARD16 CursorSize; /* Size of HWCursor area (bytes) */
- xf86CursorInfoPtr CursorInfoPtr;
- unsigned CursorOffset;
-
- /**
- * \bug This field is set to \c FALSE but never used.
- */
- Bool DoColorExpand;
-
- XGIRegRec SavedReg;
- XGIRegRec ModeReg;
- XAAInfoRecPtr AccelInfoPtr;
- CloseScreenProcPtr CloseScreen;
- Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode);
- void (*XGISave)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
- void (*XGISave2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
- void (*XGISave3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
- void (*XGIRestore)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
- void (*XGIRestore2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
- void (*XGIRestore3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
- void (*LoadCRT2Palette)(ScrnInfoPtr pScrn, int numColors,
- int *indicies, LOCO *colors, VisualPtr pVisual);
-
- int cmdQueueLen; /* Current cmdQueueLength (for 2D and 3D) */
- unsigned long cmdQueueLenMax;
- unsigned long cmdQueueLenMin;
- unsigned char *cmdQueueBase;
- int *cmdQueueLenPtr; /* Ptr to variable holding the current queue length */
- unsigned int cmdQueueOffset;
- unsigned int cmdQueueSize;
- unsigned long cmdQueueSizeMask;
-
- /**
- * \bug This field is set but never used.
- */
- unsigned int agpWantedPages;
-
-#ifdef XF86DRI
- unsigned long agpHandle;
- unsigned long agpAddr;
- unsigned char *agpBase;
- unsigned int agpSize;
- unsigned long agpVtxBufAddr; /* 315 series */
- unsigned char *agpVtxBufBase;
- unsigned int agpVtxBufSize;
- unsigned int agpVtxBufFree;
- xgiRegion agp;
- Bool irqEnabled;
- int irq;
-#endif
- unsigned long DRIheapstart, DRIheapend;
-
- void (*RenderCallback)(ScrnInfoPtr);
-
- /**
- * \bug This field is tested and set to \c NULL but never used.
- */
- unsigned char *RenderAccelArray;
-
- /**
- * \bug This field is to \c TRUE but never used.
- */
- Bool doRender;
-
- int PerColorExpandBufferSize;
- int ColorExpandBufferNumber;
- unsigned char *ColorExpandBufferAddr[32];
- int ColorExpandBufferScreenOffset[32];
-
- /**
- * \bug This field is read but never initialized.
- */
- int ImageWriteBufferSize;
-
- unsigned char *ImageWriteBufferAddr;
-
- int Rotate;
-
- /* ShadowFB support */
- Bool ShadowFB;
- unsigned char *ShadowPtr;
- int ShadowPitch;
-
- /**
- * \bug This field is set but never used.
- */
- Bool loadDRI;
-
-#ifdef XF86DRI
- Bool directRenderingEnabled;
- DRIInfoPtr pDRIInfo;
- int drmSubFD;
- int numVisualConfigs;
- __GLXvisualConfig* pVisualConfigs;
- XGIConfigPrivPtr pVisualConfigsPriv;
-#endif
-
- HW_DEVICE_EXTENSION xgi_HwDevExt; /* For new mode switching code */
- XF86VideoAdaptorPtr adaptor;
- ScreenBlockHandlerProcPtr BlockHandler;
-
- /**
- * \bug This field is tested and used but never set.
- */
- void (*VideoTimerCallback)(ScrnInfoPtr, Time);
-
- void (*ResetXv)(ScrnInfoPtr);
- void (*ResetXvGamma)(ScrnInfoPtr);
-
- OptionInfoPtr Options;
-
- /**
- * \bug This field is used but never initialized.
- */
- unsigned char LCDon;
- Bool Blank;
- int CRT1off; /* 1=CRT1 off, 0=CRT1 on */
- CARD16 LCDheight; /* Vertical resolution of LCD panel */
- CARD16 LCDwidth; /* Horizontal resolution of LCD panel */
- vbeInfoPtr pVbe; /* For VESA mode switching */
- UCHAR ScratchSet[16];
- MonitorRangeRec CRT1Range,CRT2Range;
-
-#ifdef XGIDUALHEAD
- BOOL DualHeadMode; /* TRUE if we use dual head mode */
- BOOL SecondHead; /* TRUE is this is the second head */
- XGIEntPtr entityPrivate; /* Ptr to private entity (see above) */
-#endif
- XGIFBLayout CurrentLayout; /* Current framebuffer layout */
- BOOL Primary; /* Display adapter is primary */
- xf86Int10InfoPtr pInt; /* Our int10 */
-
- /**
- * Use our own default modes?
- *
- * \bug This field is set but never used.
- */
- Bool noInternalModes;
-
- int ForceTVType, SenseYPbPr;
- int NonDefaultPAL, NonDefaultNTSC;
- unsigned long ForceYPbPrType, ForceYPbPrAR;
- unsigned long lockcalls; /* Count unlock calls for debug */
-
- Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation;
- Atom xvAutopaintColorKey, xvSetDefaults, xvSwitchCRT;
- Atom xvDisableGfx, xvDisableGfxLR, xvTVXPosition, xvTVYPosition;
- Atom xvDisableColorkey, xvUseChromakey, xvChromaMin, xvChromaMax;
- Atom xvInsideChromakey, xvYUVChromakey;
- Atom xvGammaRed, xvGammaGreen, xvGammaBlue;
-#ifdef XGI_CP
- XGI_CP_H
-#endif
- unsigned long ChipFlags;
- unsigned long XGI_SD_Flags;
- int vb;
- BOOLEAN restorebyset;
- BOOLEAN nocrt2ddcdetection;
- BOOLEAN forcecrt2redetection;
- BOOLEAN CRT1gamma, CRT1gammaGiven, CRT2gamma, XvGamma, XvGammaGiven;
- int XvDefCon, XvDefBri, XvDefHue, XvDefSat;
- BOOLEAN XvDefDisableGfx, XvDefDisableGfxLR;
- BOOLEAN XvUseMemcpy;
- int XvGammaRed, XvGammaGreen, XvGammaBlue;
- CARD8 XvGammaRampRed[256], XvGammaRampGreen[256], XvGammaRampBlue[256];
- BOOLEAN disablecolorkeycurrent;
- CARD32 colorKey;
- CARD32 MiscFlags;
- FBLinearPtr AccelLinearScratch;
- float zClearVal;
- unsigned long bClrColor, dwColor;
- int AllowHotkey;
- BOOLEAN enablexgictrl;
- short Video_MaxWidth, Video_MaxHeight;
- short scrnPitch2;
- unsigned long mmioSize;
-#ifdef XGIMERGED
- Bool MergedFB, MergedFBAuto;
- XGIScrn2Rel CRT2Position;
- char * CRT2HSync;
- char * CRT2VRefresh;
- char * MetaModes;
- ScrnInfoPtr CRT2pScrn;
- DisplayModePtr CRT1Modes;
- DisplayModePtr CRT1CurrentMode;
- int CRT1frameX0;
- int CRT1frameY0;
- int CRT1frameX1;
- int CRT1frameY1;
- Bool CheckForCRT2;
- int MergedFBXDPI, MergedFBYDPI;
-#ifdef XGIXINERAMA
- Bool UsexgiXinerama;
- Bool CRT2IsScrn0;
- ExtensionEntry *XineramaExtEntry;
- int xgiXineramaVX, xgiXineramaVY;
- Bool AtLeastOneNonClone;
-#endif
-#endif
-
- /* Added for 3D */
- unsigned long cmdQueue_shareWP_only2D;
- unsigned long *pCQ_shareWritePort;
- void (*SetThreshold)(ScrnInfoPtr pScrn, DisplayModePtr mode,
- unsigned short *Low, unsigned short *High);
-
- XGI_DSReg SRList[ExtRegSize] ;
- XGI_DSReg CRList[ExtRegSize] ;
-
- /**
- * Total number of iterations to wait in \c Volari_Idle.
- */
- unsigned int idle_wait_count;
-
-//:::: for capture
- Bool v4l_videoin;
- int v4l_devnum; /* v4l device number, 0,1,2....*/
-//~::::
-} XGIRec, *XGIPtr;
-
-#ifdef XGIDUALHEAD
-# define IS_DUAL_HEAD(x) ((x)->DualHeadMode)
-# define IS_SECOND_HEAD(x) ((x)->SecondHead)
-# define ENTITY_PRIVATE(x) ((x)->entityPrivate)
-#else
-# define IS_DUAL_HEAD(x) FALSE
-# define IS_SECOND_HEAD(x) FALSE
-# define ENTITY_PRIVATE(x) NULL
-#endif
-
-
-#define SEQ_ADDRESS_PORT 0x0014
-#define MISC_OUTPUT_REG_WRITE_PORT 0x0012
-#define MISC_OUTPUT_REG_READ_PORT 0x001C
-#define GRAPH_ADDRESS_PORT 0x001E
-#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
-#define CRTC_ADDRESS_PORT_COLOR 0x0024
-#define PCI_COMMAND 0x04
-
-#define SDMPTR(x) ((XGIMergedDisplayModePtr)(x->currentMode->Private))
-#define CDMPTR ((XGIMergedDisplayModePtr)(pXGI->CurrentLayout.mode->Private))
-
-#define BOUND(test,low,hi) { \
- if(test < low) test = low; \
- if(test > hi) test = hi; }
-
-#define REBOUND(low,hi,test) { \
- if(test < low) { \
- hi += test-low; \
- low = test; } \
- if(test > hi) { \
- low += test-hi; \
- hi = test; } }
-
-typedef struct _MergedDisplayModeRec {
- DisplayModePtr CRT1;
- DisplayModePtr CRT2;
- XGIScrn2Rel CRT2Position;
-} XGIMergedDisplayModeRec, *XGIMergedDisplayModePtr;
-
-
-typedef struct _region {
- int x0,x1,y0,y1;
-} region;
-
-
-extern void xgiOptions(ScrnInfoPtr pScrn);
-extern const OptionInfoRec * XGIAvailableOptions(int chipid, int busid);
-extern void XGISetup(ScrnInfoPtr pScrn);
-extern void XGIVGAPreInit(ScrnInfoPtr pScrn);
-extern Bool XGIAccelInit(ScreenPtr pScreen);
-extern Bool XGIHWCursorInit(ScreenPtr pScreen);
-extern Bool XGIDGAInit(ScreenPtr pScreen);
-extern void XGIInitVideo(ScreenPtr pScreen);
-
-extern int XGI_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn);
-
-int XG40Mclk(XGIPtr pXGI);
-
-void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
-int compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
- int *out_sbit, int *out_scale);
-
-void XGI_WaitBeginRetrace(XGIIOADDRESS RelIO);
-void XGI_WaitEndRetrace(XGIIOADDRESS RelIO);
-
-/* 2005/11/21 added by jjtseng */
-#define DelayS(sec) usleep((sec)*1000000)
-#define DelayMS(millisec) usleep((millisec)*1000)
-#define DelayUS(microsec) usleep((microsec))
-/*~jjtseng 2005/11/21 */
-
-Bool Volari_AccelInit(ScreenPtr pScreen) ;
-/* void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
-/* void XGI_LockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
-/* void XGI_DisableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
-/* void XGI_EnableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
-#endif
-
-extern USHORT XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
- int Depth, int LCDwith, int LCDheight);
-
-extern BOOLEAN XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
- const XGI_ExtStruct *EModeIDTable, unsigned char VGAINFO,
- USHORT *ModeNo, USHORT *ModeIdIndex);
-
-extern UCHAR XGI_GetModePtr(const XGI_StStruct *SModeIDTable,
- unsigned ModeType, USHORT ModeNo, USHORT ModeIdIndex);
-
-extern void XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data);
-extern void XGI_SetRegByte(XGIIOADDRESS port, USHORT data);
-extern void XGI_SetRegShort(XGIIOADDRESS port, USHORT data);
-extern void XGI_SetRegLong(XGIIOADDRESS port, ULONG data);
-extern UCHAR XGI_GetReg(XGIIOADDRESS port, USHORT index);
-extern UCHAR XGI_GetRegByte(XGIIOADDRESS port);
-extern USHORT XGI_GetRegShort(XGIIOADDRESS port);
-extern ULONG XGI_GetRegLong(XGIIOADDRESS port);
-extern void XGI_SetRegANDOR(XGIIOADDRESS Port, USHORT Index, USHORT DataAND,
- USHORT DataOR);
-extern void XGI_SetRegAND(XGIIOADDRESS Port, USHORT Index, USHORT DataAND);
-extern void XGI_SetRegOR(XGIIOADDRESS Port, USHORT Index, USHORT DataOR);
-
-extern void XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift,
- unsigned ordering, uint8_t red, uint8_t green, uint8_t blue);
-
-#ifdef DEBUG
-void XGIDumpRegs(ScrnInfoPtr pScrn);
-
-/**
- * Write value to the PC's 0x80 debug port.
- *
- * \bug
- * I'm pretty sure the debug 0x80 only exists on PCs. Should this routine
- * be a no-op on non-x86 and non-x86-64 architectures?
- */
-#define Newdebugcode(dbg_code) outb(0x80, dbg_code)
-#else
-#define Newdebugcode(dbg_code)
-#endif
+/*
+ * Main global data and definitions
+ *
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Thomas Winischhofer <thomas@winischhofer.net>
+ * others (old code base)
+ *
+ */
+#ifndef _XGI_H_
+#define _XGI_H_
+
+/***************
+#define DEBUG2
+#define DEBUG
+#define DEBUG1
+#define DEBUG3
+#define DEBUG4
+#define DEBUG5
+*****************/
+
+
+#ifdef DEBUG
+#define PDEBUG(p) p
+#else
+#define PDEBUG(p)
+#endif
+
+#ifdef DEBUG1
+#define PDEBUG1(p) p
+#else
+#define PDEBUG1(p)
+#endif
+
+#ifdef DEBUG2
+#define PDEBUG2(p) p
+#else
+#define PDEBUG2(p)
+#endif
+
+#ifdef DEBUG3
+#define PDEBUG3(p) p
+#else
+#define PDEBUG3(p)
+#endif
+
+#ifdef DEBUG4
+#define PDEBUG4(p) p
+#else
+#define PDEBUG4(p)
+#endif
+
+#ifdef DEBUG5
+#define PDEBUG5(p) p
+#else
+#define PDEBUG5(p)
+#endif
+
+/* Always unlock the registers (should be set!) */
+#define UNLOCK_ALWAYS
+
+#undef XGI_CP
+
+#ifdef XSERVER_LIBPCIACCESS
+#include <pciaccess.h>
+#else
+#include "xf86Pci.h"
+#endif
+#include "xf86Cursor.h"
+#include "xf86xv.h"
+#include "compiler.h"
+#include "xaa.h"
+#include "vgaHW.h"
+#include "vbe.h"
+
+#ifdef XORG_VERSION_CURRENT
+#include "xorgVersion.h"
+#endif
+
+#include "xgi_pci.h"
+#include "osdef.h"
+#include "vgatypes.h"
+#include "vb_struct.h"
+
+#ifdef XF86DRI
+#define XGINEWDRI
+#undef XGINEWDRI2
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,99,0) /* Adapt this when the time has come */
+#define XGINEWDRI2
+#endif
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#include "xgi_dri.h"
+#endif
+
+#ifdef XSERVER_LIBPCIACCESS
+#define VENDOR_ID(p) (p)->vendor_id
+#define DEVICE_ID(p) (p)->device_id
+#define SUBSYS_ID(p) (p)->subdevice_id
+#define CHIP_REVISION(p) (p)->revision
+#else
+#define VENDOR_ID(p) (p)->vendor
+#define DEVICE_ID(p) (p)->chipType
+#define SUBSYS_ID(p) (p)->subsysCard
+#define CHIP_REVISION(p) (p)->chipRev
+#endif
+
+#if 1
+#define XGIDUALHEAD /* Include Dual Head code */
+#endif
+
+#if 1
+#define XGIMERGED /* Include Merged-FB mode */
+#endif
+
+#ifdef XGIMERGED
+#if 1
+#define XGIXINERAMA /* Include Pseudo-Xinerama for MergedFB mode */
+#define XGI_XINERAMA_MAJOR_VERSION 1
+#define XGI_XINERAMA_MINOR_VERSION 1
+#endif
+#endif
+
+#if 1
+#define XGIGAMMA /* Include code for gamma correction */
+#endif
+
+/* Jong 09/28/2007; disable this because it causes cursor drawing incorrectly */
+#if 0 /* Include code for color hardware cursors */
+#define XGI_ARGB_CURSOR
+#endif
+
+#if 0 /* Include YPbPr support on VB */
+#define ENABLE_YPBPR
+#endif
+
+#ifdef XGIMERGED
+#ifdef XGIXINERAMA
+#define NEED_REPLIES /* ? */
+#define EXTENSION_PROC_ARGS void *
+#include "extnsionst.h" /* required */
+#include <X11/extensions/panoramiXproto.h> /* required */
+#endif
+#endif
+
+#if 1
+#define XGIVRAMQ /* Use VRAM queue mode on 315 series */
+#endif
+
+#undef XGI315DRI /* define this if dri is adapted for 315/330 series */
+
+#ifndef PCI_VENDOR_XGI
+#define PCI_VENDOR_XGI 0x18CA
+#endif
+#ifndef PCI_CHIP_XGIXG40
+#define PCI_CHIP_XGIXG40 0x0040
+#endif
+#ifndef PCI_CHIP_XGIXG20
+#define PCI_CHIP_XGIXG20 0x0020
+#endif
+
+/* Jong 09/18/2007; patch to GIT */
+#ifndef PCI_CHIP_XGIXG27
+#define PCI_CHIP_XGIXG27 0x0027
+#endif
+
+/* Jong 01/07/2008; support New XG21 */
+#ifndef PCI_CHIP_XGIXG21
+#define PCI_CHIP_XGIXG21 0x0021
+#endif
+
+#define CONFIG_DRM_XGI
+
+#define XGI_NAME "XGI"
+#define XGI_DRIVER_NAME "xgi"
+#define XGI_CURRENT_VERSION ((PACKAGE_VERSION_MAJOR << 16) | \
+ (PACKAGE_VERSION_MINOR << 8) | \
+ PACKAGE_VERSION_PATCHLEVEL)
+
+/* pXGI->Flags (old series only) */
+#define SYNCDRAM 0x00000001
+#define RAMFLAG 0x00000002
+#define ESS137xPRESENT 0x00000004
+#define SECRETFLAG 0x00000008
+#define A6326REVAB 0x00000010
+#define MMIOMODE 0x00010000
+#define LFBQMODE 0x00020000
+#define AGPQMODE 0x00040000
+#define UMA 0x80000000
+
+#define BIOS_BASE 0xC0000
+#define BIOS_SIZE 0x10000
+
+#define SR_BUFFER_SIZE 5
+#define CR_BUFFER_SIZE 5
+
+#define XGI_VBFlagsVersion 1
+
+/* VBFlags - if anything is changed here, increase VBFlagsVersion! */
+#define CRT2_DEFAULT 0x00000001
+#define CRT2_LCD 0x00000002 /* Never change the order of the CRT2_XXX entries */
+#define CRT2_TV 0x00000004
+#define CRT2_VGA 0x00000008
+#define TV_NTSC 0x00000010
+#define TV_PAL 0x00000020
+#define TV_HIVISION 0x00000040
+#define TV_YPBPR 0x00000080
+#define TV_AVIDEO 0x00000100
+#define TV_SVIDEO 0x00000200
+#define TV_SCART 0x00000400
+#define VB_CONEXANT 0x00000800 /* 661 series only */
+#define VB_TRUMPION VB_CONEXANT /* 300 series only */
+#define TV_PALM 0x00001000
+#define TV_PALN 0x00002000
+#define TV_NTSCJ 0x00001000
+#define VB_302ELV 0x00004000
+#define TV_CHSCART 0x00008000
+#define TV_CHYPBPR525I 0x00010000
+#define CRT1_VGA 0x00000000
+#define CRT1_LCDA 0x00020000
+#define VGA2_CONNECTED 0x00040000
+#define DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
+
+#define SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
+#define MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
+#define DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
+
+/* Aliases: */
+#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
+#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
+#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR)
+
+/* Only if TV_YPBPR is set: */
+#define TV_YPBPR525I TV_NTSC
+#define TV_YPBPR525P TV_PAL
+#define TV_YPBPR750P TV_PALM
+#define TV_YPBPR1080I TV_PALN
+#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
+
+#define TV_YPBPR43LB TV_CHSCART
+#define TV_YPBPR43 TV_CHYPBPR525I
+#define TV_YPBPR169 (TV_CHSCART | TV_CHYPBPR525I)
+#define TV_YPBPRAR (TV_CHSCART | TV_CHYPBPR525I)
+
+
+#define DISPTYPE_DISP2 CRT2_ENABLE
+#define DISPTYPE_DISP1 DISPTYPE_CRT1
+#define VB_DISPMODE_SINGLE SINGLE_MODE /* alias */
+#define VB_DISPMODE_MIRROR MIRROR_MODE /* alias */
+#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */
+#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+
+/* PresetMode argument */
+#define XGI_MODE_SIMU 0
+#define XGI_MODE_CRT1 1
+#define XGI_MODE_CRT2 2
+
+/* pXGI->MiscFlags */
+#define MISC_CRT1OVERLAY 0x00000001 /* Current display mode supports overlay */
+#define MISC_PANELLINKSCALER 0x00000002 /* Panel link is currently scaling */
+#define MISC_CRT1OVERLAYGAMMA 0x00000004 /* Current display mode supports overlay gamma corr on CRT1 */
+#define MISC_TVNTSC1024 0x00000008 /* Current display mode is TV NTSC/PALM/YPBPR525I 1024x768 */
+
+
+#define HW_DEVICE_EXTENSION XGI_HW_DEVICE_INFO
+
+#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
+#define GENMASK(mask) BITMASK(1?mask,0?mask)
+
+typedef unsigned long ULong;
+typedef unsigned short UShort;
+typedef unsigned char UChar;
+
+
+/* ChipFlags */
+/* Use only lower 16 bit for chip id! (xgictrl) */
+#define XGICF_LARGEOVERLAY 0x00000001
+#define XGICF_Is651 0x00000002
+#define XGICF_IsM650 0x00000004
+#define XGICF_IsM652 0x00000008
+#define XGICF_IsM653 0x00000010
+#define XGICF_Is652 0x00000020
+#define XGICF_Is65x (XGICF_Is651|XGICF_IsM650|XGICF_IsM652|XGICF_IsM653|XGICF_Is652)
+#define XGICF_IsM661 0x00000100 /* M661FX */
+#define XGICF_IsM741 0x00000200
+#define XGICF_IsM760 0x00000400
+#define XGICF_IsM661M 0x00000800 /* M661MX */
+#define XGICF_IsM66x (XGICF_IsM661 | XGICF_IsM741 | XGICF_IsM760 | XGICF_IsM661M)
+#define XGICF_315Core 0x00010000 /* 3D: Real 315 */
+#define XGICF_Real256ECore 0x00020000 /* 3D: Similar to 315 core, no T&L? (65x, 661, 740, 741) */
+#define XGICF_XabreCore 0x00040000 /* 3D: Real Xabre */
+#define XGICF_Ultra256Core 0x00080000 /* 3D: Similar to Xabre, no T&L?, no P:Shader? (660, 760) */
+#define XGICF_UseLCDA 0x01000000
+#define XGICF_760UMA 0x10000000 /* 760: UMA active */
+#define XGICF_CRT2HWCKaputt 0x20000000 /* CRT2 Mono HWCursor engine buggy */
+#define XGICF_Glamour3 0x40000000
+#define XGICF_Integrated 0x80000000
+
+/* Direct Xv-API */
+#define XGI_SD_IS300SERIES 0x00000001
+#define XGI_SD_IS315SERIES 0x00000002
+#define XGI_SD_IS330SERIES 0x00000004
+#define XGI_SD_SUPPORTPALMN 0x00000008 /* tv chip supports pal-m, pal-n */
+#define XGI_SD_SUPPORT2OVL 0x00000010 /* set = 2 overlays, clear = support SWITCHCRT xv prop */
+#define XGI_SD_SUPPORTTVPOS 0x00000020 /* supports changing tv position */
+#define XGI_SD_ISDUALHEAD 0x00000040 /* Driver is in dual head mode */
+#define XGI_SD_ISMERGEDFB 0x00000080 /* Driver is in merged fb mode */
+#define XGI_SD_ISDHSECONDHEAD 0x00000100 /* Dual head: This is CRT1 (=second head) */
+#define XGI_SD_ISDHXINERAMA 0x00000200 /* Dual head: We are running Xinerama */
+#define XGI_SD_VBHASSCART 0x00000400 /* videobridge has SCART instead of VGA2 */
+#define XGI_SD_ISDEPTH8 0x00000800 /* Depth is 8, no independent gamma correction */
+#define XGI_SD_ENABLED 0x00002000 /* xgictrl is enabled (by option) */
+#define XGI_SD_PSEUDOXINERAMA 0x00004000 /* pseudo xinerama is active */
+#define XGI_SD_SUPPORTLCDA 0x00008000 /* Support LCD Channel A */
+#define XGI_SD_SUPPORTNTSCJ 0x00010000 /* tv chip supports ntsc-j */
+#define XGI_SD_ADDLSUPFLAG 0x00020000 /* 1 = the following flags are valid */
+#define XGI_SD_SUPPORTVGA2 0x00040000 /* CRT2=VGA supported */
+#define XGI_SD_SUPPORTSCART 0x00080000 /* CRT2=SCART supported */
+#define XGI_SD_SUPPORTOVERSCAN 0x00100000 /* Overscan flag supported */
+#define XGI_SD_SUPPORTXVGAMMA1 0x00200000 /* Xv Gamma correction for CRT1 supported */
+#define XGI_SD_SUPPORTTV 0x00400000 /* CRT2=TV supported */
+#define XGI_SD_SUPPORTYPBPR 0x00800000 /* CRT2=YPbPr (525i, 525p, 750p, 1080i) is supported */
+#define XGI_SD_SUPPORTHIVISION 0x01000000 /* CRT2=HiVision is supported */
+#define XGI_SD_SUPPORTYPBPRAR 0x02000000 /* YPbPr aspect ratio is supported */
+#define XGI_SD_SUPPORTSCALE 0x04000000 /* Scaling of LCD panel supported */
+#define XGI_SD_SUPPORTCENTER 0x08000000 /* If scaling supported: Centering of screen [NOT] supported (TMDS only) */
+
+#define XGI_DIRECTKEY 0x03145792
+
+/* XGICtrl: Check mode for CRT2 */
+#define XGI_CF2_LCD 0x01
+#define XGI_CF2_TV 0x02
+#define XGI_CF2_VGA2 0x04
+#define XGI_CF2_TVPAL 0x08
+#define XGI_CF2_TVNTSC 0x10 /* + NTSC-J */
+#define XGI_CF2_TVPALM 0x20
+#define XGI_CF2_TVPALN 0x40
+#define XGI_CF2_CRT1LCDA 0x80
+#define XGI_CF2_TYPEMASK (XGI_CF2_LCD | XGI_CF2_TV | XGI_CF2_VGA2 | XGI_CF2_CRT1LCDA)
+#define XGI_CF2_TVSPECIAL (XGI_CF2_LCD | XGI_CF2_TV)
+#define XGI_CF2_TVSPECMASK (XGI_CF2_TVPAL | XGI_CF2_TVNTSC | XGI_CF2_TVPALM | XGI_CF2_TVPALN)
+#define XGI_CF2_TVHIVISION XGI_CF2_TVPAL
+#define XGI_CF2_TVYPBPR525I XGI_CF2_TVNTSC
+#define XGI_CF2_TVYPBPR525P (XGI_CF2_TVPAL | XGI_CF2_TVNTSC)
+#define XGI_CF2_TVYPBPR750P XGI_CF2_TVPALM
+#define XGI_CF2_TVYPBPR1080I (XGI_CF2_TVPALM | XGI_CF2_TVPAL)
+
+/* AGP stuff for DRI */
+#define AGP_PAGE_SIZE 4096
+#define AGP_PAGES 2048 /* Default: 2048 pages @ 4096 = 8MB */
+/* 300 */
+#define AGP_CMDBUF_PAGES 256
+#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
+/* 315/330 */
+#define AGP_VTXBUF_PAGES 512
+#define AGP_VTXBUF_SIZE (AGP_PAGE_SIZE * AGP_VTXBUF_PAGES)
+
+#define VOLARI_CQSIZE (1024*1024)
+#define VOLARI_CQSIZEXG20 (128*1024)
+#define VOLARI_CURSOR_SHAPE_SIZE (64*64*4)
+
+/* For backup of register contents */
+typedef struct {
+ unsigned char xgiRegs3C4[0x50];
+ unsigned char xgiRegs3D4[0x90];
+ unsigned char xgiRegs3C2;
+ unsigned char xgiCapt[0x60];
+ unsigned char xgiVid[0x50];
+ unsigned char VBPart1[0x50];
+ unsigned char VBPart2[0x100];
+ unsigned char VBPart3[0x50];
+ unsigned char VBPart4[0x50];
+ unsigned short ch70xx[64];
+ unsigned long xgiMMIO85C0;
+ unsigned char xgi6326tv[0x46];
+ unsigned long xgiRegsPCI50, xgiRegsPCIA0;
+} XGIRegRec, *XGIRegPtr;
+
+
+/* XGIFBLayout is mainly there because of DGA. It holds the
+ * current layout parameters needed for acceleration and other
+ * stuff. When switching mode using DGA, these are set up
+ * accordingly and not necessarily match pScrn's. Therefore,
+ * driver modules should read these values instead of pScrn's.
+ */
+typedef struct {
+ int bitsPerPixel; /* = pScrn->bitsPerPixel */
+ int depth; /* = pScrn->depth */
+ int displayWidth; /* = pScrn->displayWidth */
+ DisplayModePtr mode; /* = pScrn->currentMode */
+} XGIFBLayout;
+
+/* Dual head private entity structure */
+typedef struct {
+ ScrnInfoPtr pScrn_1;
+ ScrnInfoPtr pScrn_2;
+ unsigned char * BIOS;
+ VB_DEVICE_INFO *XGI_Pr;
+ int CRT2ModeNo; /* Current display mode for CRT2 */
+ Bool CRT2ModeSet; /* CRT2 mode has been set */
+ unsigned char CRT2CR30, CRT2CR31, CRT2CR35, CRT2CR38;
+ int refCount;
+
+ /**
+ * Number of entities
+ *
+ * \bug
+ * This field is tested in one place, but it doesn't appear to ever be
+ * set or modified.
+ */
+ int lastInstance;
+
+ Bool DisableDual; /* Emergency flag */
+ Bool ErrorAfterFirst; /* Emergency flag: Error after first init -> Abort second */
+ int maxUsedClock; /* Max used pixelclock on master head */
+
+ /**
+ * Framebuffer addresses and sizes
+ *
+ * \bug
+ * These 4 fields are set, but the stored values don't appear to be used.
+ */
+ unsigned long masterFbAddress;
+ unsigned long masterFbSize;
+ unsigned long slaveFbAddress;
+ unsigned long slaveFbSize;
+
+ unsigned char * FbBase; /* VRAM linear address */
+ unsigned char * IOBase; /* MMIO linear address */
+
+ /**
+ * Map / unmap queue counter.
+ *
+ * \bug
+ * These vales are tested, set to zero, or decremented. However, I don't
+ * see anywhere in the code where they are incremented.
+ */
+ unsigned short MapCountIOBase;
+ unsigned short MapCountFbBase;
+
+ Bool forceUnmapIOBase; /* ignore counter and unmap */
+ Bool forceUnmapFbBase; /* ignore counter and unmap */
+#ifdef __alpha__
+ unsigned char * IOBaseDense; /* MMIO for Alpha platform */
+ unsigned short MapCountIOBaseDense;
+ Bool forceUnmapIOBaseDense; /* ignore counter and unmap */
+#endif
+ BOOLEAN CRT1gamma;
+
+ /**
+ * \bug This field is tested and set to \c NULL but never used.
+ */
+ unsigned char *RenderAccelArray;
+ unsigned char * FbBase1;
+ unsigned long OnScreenSize1;
+
+#ifdef XGI_CP
+ XGI_CP_H_ENT
+#endif
+} XGIEntRec, *XGIEntPtr;
+
+#define XGIPTR(p) ((XGIPtr)((p)->driverPrivate))
+#define XAAPTR(p) ((XAAInfoRecPtr)(XGIPTR(p)->AccelInfoPtr))
+
+#define ExtRegSize 0x40
+
+
+/* Relative merge position */
+typedef enum {
+ xgiLeftOf,
+ xgiRightOf,
+ xgiAbove,
+ xgiBelow,
+ xgiClone
+} XGIScrn2Rel;
+
+typedef struct MonitorRange {
+ float loH,hiH,loV,hiV ;
+}MonitorRangeRec,*MonitorRangePtr ;
+
+typedef struct {
+ ScrnInfoPtr pScrn; /* -------------- DON'T INSERT ANYTHING HERE --------------- */
+#ifdef XSERVER_LIBPCIACCESS
+ struct pci_device * PciInfo;
+#else
+ pciVideoPtr PciInfo; /* -------- OTHERWISE xgi_dri.so MUST BE RECOMPILED -------- */
+ PCITAG PciTag;
+#endif
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int ChipRev;
+ VB_DEVICE_INFO *XGI_Pr; /* For new mode switching code */
+ unsigned long FbAddress; /* VRAM physical address (in DHM: for each Fb!) */
+ unsigned long realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */
+ unsigned char * FbBase; /* VRAM virtual linear address */
+ CARD32 IOAddress; /* MMIO physical address */
+ unsigned char * IOBase; /* MMIO linear address */
+ IOADDRESS IODBase; /* Base of PIO memory area */
+#ifdef __alpha__
+ unsigned char * IOBaseDense; /* MMIO for Alpha platform */
+#endif
+ XGIIOADDRESS RelIO; /* Relocated IO Ports baseaddress */
+ unsigned char * BIOS;
+ int MemClock;
+ int BusWidth;
+ int MinClock;
+ int MaxClock;
+ int Flags; /* HW config flags */
+ long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */
+ long availMem; /* Really available Fb mem (minus TQ, HWCursor) */
+ unsigned long maxxfbmem; /* limit fb memory X is to use to this (KB) */
+ unsigned long xgifbMem; /* heapstart of xgifb (if running) */
+ unsigned long dhmOffset; /* Offset to memory for each head (0 or ..) */
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ Bool NoAccel;
+ Bool NoXvideo;
+ Bool TurboQueue;
+ int ForceCRT1Type;
+ int ForceCRT2Type;
+ int OptROMUsage;
+ Bool ValidWidth;
+ unsigned char myCR63;
+ unsigned long VBFlags; /* Video bridge configuration */
+ unsigned long VBFlags_backup; /* Backup for SlaveMode-modes */
+
+ short scrnOffset; /* Screen pitch (data) */
+ short scrnPitch; /* Screen pitch (display; regarding interlace) */
+ unsigned long DstColor;
+ int xcurrent; /* for temp use in accel */
+ int ycurrent; /* for temp use in accel */
+ int CommandReg;
+
+ Bool HWCursor;
+ CARD16 CursorSize; /* Size of HWCursor area (bytes) */
+ xf86CursorInfoPtr CursorInfoPtr;
+ unsigned CursorOffset;
+
+ /**
+ * \bug This field is set to \c FALSE but never used.
+ */
+ Bool DoColorExpand;
+
+ XGIRegRec SavedReg;
+ XGIRegRec ModeReg;
+ XAAInfoRecPtr AccelInfoPtr;
+ CloseScreenProcPtr CloseScreen;
+ Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode);
+ void (*XGISave)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+ void (*XGISave2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+ void (*XGISave3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+ void (*XGIRestore)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+ void (*XGIRestore2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+ void (*XGIRestore3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+ void (*LoadCRT2Palette)(ScrnInfoPtr pScrn, int numColors,
+ int *indicies, LOCO *colors, VisualPtr pVisual);
+
+ int cmdQueueLen; /* Current cmdQueueLength (for 2D and 3D) */
+ unsigned long cmdQueueLenMax;
+ unsigned long cmdQueueLenMin;
+ unsigned char *cmdQueueBase;
+ int *cmdQueueLenPtr; /* Ptr to variable holding the current queue length */
+ unsigned int cmdQueueOffset;
+ unsigned int cmdQueueSize;
+ unsigned long cmdQueueSizeMask;
+
+ /**
+ * \bug This field is set but never used.
+ */
+ unsigned int agpWantedPages;
+
+#ifdef XF86DRI
+ unsigned long agpHandle;
+ unsigned long agpAddr;
+ unsigned char *agpBase;
+ unsigned int agpSize;
+ unsigned long agpVtxBufAddr; /* 315 series */
+ unsigned char *agpVtxBufBase;
+ unsigned int agpVtxBufSize;
+ unsigned int agpVtxBufFree;
+ xgiRegion agp;
+ Bool irqEnabled;
+ int irq;
+#endif
+ unsigned long DRIheapstart, DRIheapend;
+
+ void (*RenderCallback)(ScrnInfoPtr);
+
+ /**
+ * \bug This field is tested and set to \c NULL but never used.
+ */
+ unsigned char *RenderAccelArray;
+
+ /**
+ * \bug This field is to \c TRUE but never used.
+ */
+ Bool doRender;
+
+ int PerColorExpandBufferSize;
+ int ColorExpandBufferNumber;
+ unsigned char *ColorExpandBufferAddr[32];
+ int ColorExpandBufferScreenOffset[32];
+
+ /**
+ * \bug This field is read but never initialized.
+ */
+ int ImageWriteBufferSize;
+
+ unsigned char *ImageWriteBufferAddr;
+
+ int Rotate;
+
+ /* ShadowFB support */
+ Bool ShadowFB;
+ unsigned char *ShadowPtr;
+ int ShadowPitch;
+
+ /**
+ * \bug This field is set but never used.
+ */
+ Bool loadDRI;
+
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmSubFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ XGIConfigPrivPtr pVisualConfigsPriv;
+#endif
+
+ HW_DEVICE_EXTENSION xgi_HwDevExt; /* For new mode switching code */
+ XF86VideoAdaptorPtr adaptor;
+ ScreenBlockHandlerProcPtr BlockHandler;
+
+ /**
+ * \bug This field is tested and used but never set.
+ */
+ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+
+ void (*ResetXv)(ScrnInfoPtr);
+ void (*ResetXvGamma)(ScrnInfoPtr);
+
+ OptionInfoPtr Options;
+
+ /**
+ * \bug This field is used but never initialized.
+ */
+ unsigned char LCDon;
+ Bool Blank;
+ int CRT1off; /* 1=CRT1 off, 0=CRT1 on */
+ CARD16 LCDheight; /* Vertical resolution of LCD panel */
+ CARD16 LCDwidth; /* Horizontal resolution of LCD panel */
+ vbeInfoPtr pVbe; /* For VESA mode switching */
+ UCHAR ScratchSet[16];
+ MonitorRangeRec CRT1Range,CRT2Range;
+
+#ifdef XGIDUALHEAD
+ BOOL DualHeadMode; /* TRUE if we use dual head mode */
+ BOOL SecondHead; /* TRUE is this is the second head */
+ XGIEntPtr entityPrivate; /* Ptr to private entity (see above) */
+#endif
+ XGIFBLayout CurrentLayout; /* Current framebuffer layout */
+ BOOL Primary; /* Display adapter is primary */
+ xf86Int10InfoPtr pInt; /* Our int10 */
+
+ /**
+ * Use our own default modes?
+ *
+ * \bug This field is set but never used.
+ */
+ Bool noInternalModes;
+
+ int ForceTVType, SenseYPbPr;
+ int NonDefaultPAL, NonDefaultNTSC;
+ unsigned long ForceYPbPrType, ForceYPbPrAR;
+ unsigned long lockcalls; /* Count unlock calls for debug */
+
+ Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation;
+ Atom xvAutopaintColorKey, xvSetDefaults, xvSwitchCRT;
+ Atom xvDisableGfx, xvDisableGfxLR, xvTVXPosition, xvTVYPosition;
+ Atom xvDisableColorkey, xvUseChromakey, xvChromaMin, xvChromaMax;
+ Atom xvInsideChromakey, xvYUVChromakey;
+ Atom xvGammaRed, xvGammaGreen, xvGammaBlue;
+#ifdef XGI_CP
+ XGI_CP_H
+#endif
+ unsigned long ChipFlags;
+ unsigned long XGI_SD_Flags;
+ BOOLEAN UseHWARGBCursor;
+ BOOLEAN HWARGBCursor;
+ int vb;
+ BOOLEAN restorebyset;
+ BOOLEAN nocrt2ddcdetection;
+ BOOLEAN forcecrt2redetection;
+ BOOLEAN CRT1gamma, CRT1gammaGiven, CRT2gamma, XvGamma, XvGammaGiven;
+ int XvDefCon, XvDefBri, XvDefHue, XvDefSat;
+ BOOLEAN XvDefDisableGfx, XvDefDisableGfxLR;
+ BOOLEAN XvUseMemcpy;
+ int XvGammaRed, XvGammaGreen, XvGammaBlue;
+ CARD8 XvGammaRampRed[256], XvGammaRampGreen[256], XvGammaRampBlue[256];
+ BOOLEAN disablecolorkeycurrent;
+ CARD32 colorKey;
+ CARD32 MiscFlags;
+ FBLinearPtr AccelLinearScratch;
+ float zClearVal;
+ unsigned long bClrColor, dwColor;
+ int AllowHotkey;
+ BOOLEAN enablexgictrl;
+ short Video_MaxWidth, Video_MaxHeight;
+ short scrnPitch2;
+ int CurXPreset ;
+ int CurYPreset ;
+ unsigned long mmioSize;
+#ifdef XGIMERGED
+ Bool MergedFB, MergedFBAuto;
+ XGIScrn2Rel CRT2Position;
+ char * CRT2HSync;
+ char * CRT2VRefresh;
+ char * MetaModes;
+ ScrnInfoPtr CRT2pScrn;
+ DisplayModePtr CRT1Modes;
+ DisplayModePtr CRT1CurrentMode;
+ int CRT1frameX0;
+ int CRT1frameY0;
+ int CRT1frameX1;
+ int CRT1frameY1;
+ Bool CheckForCRT2;
+ int MergedFBXDPI, MergedFBYDPI;
+#ifdef XGIXINERAMA
+ Bool UsexgiXinerama;
+ Bool CRT2IsScrn0;
+ ExtensionEntry *XineramaExtEntry;
+ int xgiXineramaVX, xgiXineramaVY;
+ Bool AtLeastOneNonClone;
+#endif
+#endif
+
+ /* Added for 3D */
+ unsigned long cmdQueue_shareWP_only2D;
+ unsigned long *pCQ_shareWritePort;
+ void (*SetThreshold)(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned short *Low, unsigned short *High);
+
+ XGI_DSReg SRList[ExtRegSize] ;
+ XGI_DSReg CRList[ExtRegSize] ;
+
+ /**
+ * Total number of iterations to wait in \c Volari_Idle.
+ */
+ unsigned int idle_wait_count;
+
+//:::: for capture
+ Bool v4l_videoin;
+ int v4l_devnum; /* v4l device number, 0,1,2....*/
+//~::::
+} XGIRec, *XGIPtr;
+
+#ifdef XGIDUALHEAD
+# define IS_DUAL_HEAD(x) ((x)->DualHeadMode)
+# define IS_SECOND_HEAD(x) ((x)->SecondHead)
+# define ENTITY_PRIVATE(x) ((x)->entityPrivate)
+#else
+# define IS_DUAL_HEAD(x) FALSE
+# define IS_SECOND_HEAD(x) FALSE
+# define ENTITY_PRIVATE(x) NULL
+#endif
+
+
+#define SEQ_ADDRESS_PORT 0x0014
+#define MISC_OUTPUT_REG_WRITE_PORT 0x0012
+#define MISC_OUTPUT_REG_READ_PORT 0x001C
+#define GRAPH_ADDRESS_PORT 0x001E
+#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
+#define CRTC_ADDRESS_PORT_COLOR 0x0024
+#define PCI_COMMAND 0x04
+
+#define SDMPTR(x) ((XGIMergedDisplayModePtr)(x->currentMode->Private))
+#define CDMPTR ((XGIMergedDisplayModePtr)(pXGI->CurrentLayout.mode->Private))
+
+#define BOUND(test,low,hi) { \
+ if(test < low) test = low; \
+ if(test > hi) test = hi; }
+
+#define REBOUND(low,hi,test) { \
+ if(test < low) { \
+ hi += test-low; \
+ low = test; } \
+ if(test > hi) { \
+ low += test-hi; \
+ hi = test; } }
+
+typedef struct _MergedDisplayModeRec {
+ DisplayModePtr CRT1;
+ DisplayModePtr CRT2;
+ XGIScrn2Rel CRT2Position;
+} XGIMergedDisplayModeRec, *XGIMergedDisplayModePtr;
+
+
+typedef struct _region {
+ int x0,x1,y0,y1;
+} region;
+
+
+extern void xgiOptions(ScrnInfoPtr pScrn);
+extern const OptionInfoRec * XGIAvailableOptions(int chipid, int busid);
+extern void XGISetup(ScrnInfoPtr pScrn);
+extern void XGIVGAPreInit(ScrnInfoPtr pScrn);
+extern Bool XGIAccelInit(ScreenPtr pScreen);
+extern Bool XGIHWCursorInit(ScreenPtr pScreen);
+extern Bool XGIDGAInit(ScreenPtr pScreen);
+extern void XGIInitVideo(ScreenPtr pScreen);
+
+extern int XGI_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn);
+
+int XG40Mclk(XGIPtr pXGI);
+
+void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
+int compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+ int *out_sbit, int *out_scale);
+
+void XGI_WaitBeginRetrace(XGIIOADDRESS RelIO);
+void XGI_WaitEndRetrace(XGIIOADDRESS RelIO);
+
+/* 2005/11/21 added by jjtseng */
+#define DelayS(sec) usleep((sec)*1000000)
+#define DelayMS(millisec) usleep((millisec)*1000)
+#define DelayUS(microsec) usleep((microsec))
+/*~jjtseng 2005/11/21 */
+
+Bool Volari_AccelInit(ScreenPtr pScreen) ;
+/* void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+/* void XGI_LockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+/* void XGI_DisableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+/* void XGI_EnableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+#endif
+
+extern USHORT XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
+ int Depth, int LCDwith, int LCDheight);
+
+extern BOOLEAN XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
+ const XGI_ExtStruct *EModeIDTable, unsigned char VGAINFO,
+ USHORT *ModeNo, USHORT *ModeIdIndex);
+
+extern UCHAR XGI_GetModePtr(const XGI_StStruct *SModeIDTable,
+ unsigned ModeType, USHORT ModeNo, USHORT ModeIdIndex);
+
+extern void XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data);
+extern void XGI_SetRegByte(XGIIOADDRESS port, USHORT data);
+extern void XGI_SetRegShort(XGIIOADDRESS port, USHORT data);
+extern void XGI_SetRegLong(XGIIOADDRESS port, ULONG data);
+extern UCHAR XGI_GetReg(XGIIOADDRESS port, USHORT index);
+extern UCHAR XGI_GetRegByte(XGIIOADDRESS port);
+extern USHORT XGI_GetRegShort(XGIIOADDRESS port);
+extern ULONG XGI_GetRegLong(XGIIOADDRESS port);
+extern void XGI_SetRegANDOR(XGIIOADDRESS Port, USHORT Index, USHORT DataAND,
+ USHORT DataOR);
+extern void XGI_SetRegAND(XGIIOADDRESS Port, USHORT Index, USHORT DataAND);
+extern void XGI_SetRegOR(XGIIOADDRESS Port, USHORT Index, USHORT DataOR);
+
+extern void XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift,
+ unsigned ordering, uint8_t red, uint8_t green, uint8_t blue);
+
+#ifdef DEBUG
+void XGIDumpRegs(ScrnInfoPtr pScrn);
+
+/**
+ * Write value to the PC's 0x80 debug port.
+ *
+ * \bug
+ * I'm pretty sure the debug 0x80 only exists on PCs. Should this routine
+ * be a no-op on non-x86 and non-x86-64 architectures?
+ */
+#define Newdebugcode(dbg_code) outb(0x80, dbg_code)
+#else
+#define Newdebugcode(dbg_code)
+#endif
diff --git a/src/xgi_accel.c b/src/xgi_accel.c
index 330ed5d..2490348 100644
--- a/src/xgi_accel.c
+++ b/src/xgi_accel.c
@@ -1,850 +1,879 @@
-/*
- *
- * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
- * Parts Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
- *
- * Licensed under the following terms:
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appears in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * and that the name of the copyright holder not be used in advertising
- * or publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holder makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without expressed or implied warranty.
- *
- * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>,
- * Mike Chapman <mike@paranoia.com>,
- * Juanjo Santamarta <santamarta@ctv.es>,
- * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
- * David Thomas <davtom@dream.org.uk>,
- * Thomas Winischhofer <thomas@winischhofer.net>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-
-#include <compiler.h>
-#include <miline.h>
-
-#include "xgi_accel.h"
-#include "xgi_regs.h"
-#include "xgi.h"
-#include "vb_def.h"
-
-#include "xaarop.h"
-#include <xaa.h>
-#include <xaalocal.h>
-#include <xf86fbman.h>
-
-/*************************************************************************/
-
-void Volari_Sync(ScrnInfoPtr pScrn);
-
-static void Volari_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
- int xdir, int ydir, int rop,
- unsigned int planemask, int trans_color);
-static void Volari_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
- int x1, int y1, int x2, int y2,
- int width, int height);
-static void Volari_SetupForSolidFill(ScrnInfoPtr pScrn, int color,
- int rop, unsigned int planemask);
-static void Volari_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
- int x, int y, int w, int h);
-static void Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
- int patx, int paty, int fg, int bg,
- int rop, unsigned int planemask);
-static void Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
- int patx, int paty,
- int x, int y, int w, int h);
-
-void Volari_EnableAccelerator(ScrnInfoPtr pScrn) ;
-static void Volari_InitCmdQueue(ScrnInfoPtr pScrn) ;
-static void Volari_DisableDualPipe(ScrnInfoPtr pScrn) ;
-static void Volari_DisableCmdQueue(ScrnInfoPtr pScrn) ;
-
-extern int FbDevExist;
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-static CARD32 BE_SWAP32 (CARD32 val)
-{
- if (CurrentColorDepth == 8)
- return ((((val) & 0x000000ff) << 24) | \
- (((val) & 0x0000ff00) << 8) | \
- (((val) & 0x00ff0000) >> 8) | \
- (((val) & 0xff000000) >> 24));
- if (CurrentColorDepth == 24)
- return val;
- if (CurrentColorDepth == 16)
- return ((((val) & 0x0000ffff) << 16) | \
- (((val) & 0xffff0000) >> 16));
-}
-#else
-static CARD32 BE_SWAP32 (CARD32 val)
-{
- return val;
-}
-#endif
-
-
-#ifdef DEBUG
-static void dump_cq_read_pointer(unsigned int cqrp)
-{
- static const char *const field_name[8] = {
- "all idle",
- "hardware queues empty",
- "2D idle",
- "3D idle",
- "hardware command queue empty",
- "2D queue empty",
- "3D queue empty",
- "software command queue empty",
- };
- unsigned i;
-
- xf86DrvMsg(0, X_INFO, "IO(0x85CC) = 0x%08x\n", cqrp);
- for (i = 31; i > 23; i--) {
- if ((cqrp & (1U << i)) != 0) {
- xf86DrvMsg(0, X_INFO, " %s\n", field_name[31 - i]);
- }
- }
-}
-#endif /* DEBUG */
-
-
-void Volari_SetDefaultIdleWait(XGIPtr pXGI, unsigned HDisplay,
- unsigned depth)
-{
- static const unsigned wait_table[5][4] = {
- { 1, 1, 1, 1 },
- { 65535, 1, 1000, 3000 },
- { 65535, 160, 1200, 4000 },
- { 65535, 200, 1600, 6000 },
- { 65535, 500, 2000, 8000 }
- };
-
- if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
- unsigned i;
-
- switch (HDisplay) {
- case 640: i = 1; break;
- case 800: i = 2; break;
- case 1024: i = 3; break;
- case 1280: i = 4; break;
- default: i = 0; break;
- }
-
- pXGI->idle_wait_count = wait_table[i][3 & (depth / 8)];
- }
- else {
- pXGI->idle_wait_count = 65535;
- }
-}
-
-void Volari_Idle(XGIPtr pXGI)
-{
- int i;
-#ifdef DEBUG
- unsigned int last_cqrp = 0;
-#endif /* DEBUG */
-
- do {
- int bIdle = 0;
- unsigned int cqrp;
-
- for (i = 0; i < pXGI->idle_wait_count; i++) {
- cqrp = MMIO_IN32(pXGI->IOBase, 0x85CC);
- if (cqrp & IDLE_ALL) {
- bIdle = 1;
- break;
- }
- }
-
- if (bIdle)
- break;
-
-#ifdef DEBUG
- if (last_cqrp != cqrp) {
- dump_cq_read_pointer(cqrp);
- last_cqrp = cqrp;
- }
-
- sleep(1);
-#endif /* DEBUG */
-
- if (pXGI->Chipset == PCI_CHIP_XGIXG20)
- usleep(1);
- } while (1);
-}
-
-
-void
-Volari_EnableAccelerator(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- PDEBUG(ErrorF("Volari_EnableAccelerator()\n")) ;
-
- switch (pXGI->Chipset) {
- case PCI_CHIP_XGIXG40:
- default:
- orXGIIDXREG(XGISR, 0x1E,
- SR1E_ENABLE_3D_TRANSFORM_ENGINE
- | SR1E_ENABLE_2D
- | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
- | SR1E_ENABLE_3D_COMMAND_PARSER
- | SR1E_ENABLE_3D);
- }
-
-
- if( pXGI->TurboQueue )
- {
- Volari_InitCmdQueue(pScrn) ;
- }
-}
-
-static void
-Volari_InitCmdQueue(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned long ulXGITempRP ;
- unsigned long ulCR55 ;
- unsigned long ulSR26 ;
- unsigned long temp ;
- /* unsigned long ulFlag = 0 ; */
-/*
- PDEBUG(ErrorF("Volari_InitCmdQueue()\n"));
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
-*/
- inXGIIDXREG(XGICR, 0x55, ulCR55) ;
- andXGIIDXREG(XGICR, 0x55, 0x33) ;
- orXGIIDXREG(XGISR, 0x26, 1) ; /* reset cmd queue */
-
- w_port = Volari_GetSwWP() ; /* GuardBand() Init */
- r_port = Volari_GetHwRP() ;
-
- if( pXGI->Chipset == PCI_CHIP_XGIXG20 )
- {
- Alignment = 1 ; /* 64 bits */
-
- switch(pXGI->cmdQueueSize)
- {
- case 64*1024:
- ulSR26 = 0x40 + 0x00 ;
- break ;
- case 128*1024:
- ulSR26 = 0x40 + 0x04 ;
- break ;
- default:
- /* reset the command queue information */
-
- pXGI->cmdQueueSize = 128*1024 ; /* reset the command queue */
- pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
- if( FbDevExist )
- {
- if( pScrn->videoRam < 8*1024 )
- {
- pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
- }
- else if( pScrn->videoRam < 16*1024 )
- {
- pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
- }
- else
- {
- pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
- }
- }
- else
- {
- pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
- }
-
- pXGI->cmdQueueLen = 0 ;
- pXGI->cmdQueueLenMin = 0x200 ;
- pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
-
- ulSR26 = 0x40 ;
- break ;
- }
- }
- else
- {
- Alignment = 2 ; /* 128 bits */
-
- switch(pXGI->cmdQueueSize)
- {
- case 512*1024:
- ulSR26 = 0x40 + 0x00 ;
- break ;
- case 1024*1024:
- ulSR26 = 0x40 + 0x04 ;
- break ;
- case 2*1024*1024:
- ulSR26 = 0x40 + 0x08 ;
- break ;
- case 4*1024*1024:
- ulSR26 = 0x40 + 0x0C ;
- break ;
- default:
- /* reset the command queue information */
-
- pXGI->cmdQueueSize = 512*1024 ; /* reset the command queue */
- pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
- if( FbDevExist )
- {
- if( pScrn->videoRam < 8*1024 )
- {
- pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
- }
- else if( pScrn->videoRam < 16*1024 )
- {
- pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
- }
- else
- {
- pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
- }
- }
- else
- {
- pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
- }
-
- pXGI->cmdQueueLen = 0 ;
- pXGI->cmdQueueLenMin = 0x200 ;
- pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
-
- ulSR26 = 0x40 ;
- break ;
- }
- }
-
- pXGI->CursorOffset = pXGI->cmdQueueOffset - VOLARI_CURSOR_SHAPE_SIZE;
-
- temp = (unsigned long)pXGI->FbBase ;
- temp += pXGI->cmdQueueOffset ;
- pXGI->cmdQueueBase = (unsigned char *)temp ;
-/*
- PDEBUG(ErrorF( "pXGI->FbBase = 0x%lX\n", pXGI->FbBase )) ;
- PDEBUG(ErrorF( "pXGI->cmdQueueOffset = 0x%lX\n", pXGI->cmdQueueOffset )) ;
- PDEBUG(ErrorF( "pXGI->cmdQueueBase = 0x%lX\n", pXGI->cmdQueueBase )) ;
-*/
- outXGIIDXREG(XGISR, 0x26, ulSR26) ;
-
- ulXGITempRP=Volari_GetHwRP() ;
-/*
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
-*/
- /* XGI315 */
- pXGI->cmdQueue_shareWP_only2D = ulXGITempRP;
- /* pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D); */
-
- Volari_UpdateHwWP(ulXGITempRP) ;
-
-
-
- MMIO_OUT32(pXGI->IOBase, 0x85C0, pXGI->cmdQueueOffset) ;
-
- outXGIIDXREG(XGICR, 0x55, ulCR55) ;
-
- if(pXGI->Chipset == PCI_CHIP_XGIXG40)
- {
- Volari_Idle(pXGI);
- Volari_DisableDualPipe(pScrn) ;
- Volari_Idle(pXGI);
-
- }
- PDEBUG(ErrorF("Volari_InitCmdQueue() done.\n")) ;
-}
-
-static void
-Volari_DisableDualPipe(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn) ;
- unsigned long ulTemp ;
- unsigned long ulValue = MMIO_IN32(pXGI->IOBase, 0x8240) ;
- ulValue |= 1 << 10 ; /* D[10] = 1, Disable Dual Pipe. */
-
- ulTemp = Volari_GetSwWP() ;
-
- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp) = (CARD32)BE_SWAP32(GR_SKPC_HEADER + 0x8240) ;
- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+4) = (CARD32)BE_SWAP32(ulValue) ;
-
- if( pXGI->Chipset == PCI_CHIP_XGIXG40 )
- {
- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+8) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+12) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
-
- ulTemp += 0x10 ;
- }
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 )
- ulTemp += 0x08 ;
-
- ulTemp &= pXGI->cmdQueueSizeMask ;
- Volari_UpdateHwWP(ulTemp) ;
-}
-
-void
-Volari_DisableAccelerator(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn) ;
-
- PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn)\n")) ;
-
- Volari_Idle(pXGI);
-
- if( pXGI->TurboQueue )
- {
- Volari_DisableCmdQueue(pScrn) ;
- }
-
- andXGIIDXREG(XGISR, 0x1E,
- ~(SR1E_ENABLE_3D_TRANSFORM_ENGINE
- | SR1E_ENABLE_2D
- | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
- | SR1E_ENABLE_3D_COMMAND_PARSER
- | SR1E_ENABLE_3D));
-/* PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn) Done, GBCount = %ld\n",GBCount)) ; */
-}
-
-static void
-Volari_DisableCmdQueue(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn) ;
-
- andXGIIDXREG(XGISR, 0x26, 0x0F) ;
-}
-
-void
-Volari_InitializeAccelerator(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- pXGI->DoColorExpand = FALSE;
-}
-
-Bool
-Volari_AccelInit(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoPtr;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XGIPtr pXGI = XGIPTR(pScrn);
- int reservedFbSize;
- long UsableFbSize;
- unsigned char *AvailBufBase;
- BoxRec Avail;
- int i;
-
-
- Avail.x1 = 0; Avail.y1 = 0; Avail.x2 = 0; Avail.y2 = 0;
-
- PDEBUG1(ErrorF("Volari_AccelInit()\n" )) ;
-
- pXGI->AccelInfoPtr = infoPtr = XAACreateInfoRec();
- if (!infoPtr) return FALSE;
-
- Volari_InitializeAccelerator(pScrn);
-
- infoPtr->Flags = LINEAR_FRAMEBUFFER |
- OFFSCREEN_PIXMAPS |
- PIXMAP_CACHE;
-
- /* sync */
- infoPtr->Sync = Volari_Sync;
-
- if ((pScrn->bitsPerPixel != 8) &&
- (pScrn->bitsPerPixel != 16) &&
- (pScrn->bitsPerPixel != 32))
- {
- return FALSE;
- }
-
-#ifdef XGIG2_SCR2SCRCOPY
- /* BitBlt */
- infoPtr->SetupForScreenToScreenCopy = Volari_SetupForScreenToScreenCopy;
- infoPtr->SubsequentScreenToScreenCopy = Volari_SubsequentScreenToScreenCopy;
- infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
-#endif
-
-#ifdef XGIG2_SOLIDFILL
- /* solid fills */
- infoPtr->SetupForSolidFill = Volari_SetupForSolidFill;
- infoPtr->SubsequentSolidFillRect = Volari_SubsequentSolidFillRect;
- infoPtr->SolidFillFlags = NO_PLANEMASK;
-#endif
-
-#ifdef XGIG2_8X8MONOPATFILL
- /* 8x8 mono pattern fill */
- infoPtr->SetupForMono8x8PatternFill = Volari_SetupForMonoPatternFill;
- infoPtr->SubsequentMono8x8PatternFillRect = Volari_SubsequentMonoPatternFill;
- infoPtr->Mono8x8PatternFillFlags =
- NO_PLANEMASK |
- HARDWARE_PATTERN_SCREEN_ORIGIN |
- HARDWARE_PATTERN_PROGRAMMED_BITS |
- /* 2005/08/15 modified by jjtseng */
- /* NO_TRANSPARENCY | */
- /*~ jjtseng 2005/08/15 */
- BIT_ORDER_IN_BYTE_MSBFIRST ;
-#endif /* XGIG2_8X8MONOPATFILL */
-
- /* init Frame Buffer Manager */
- reservedFbSize = 0;
- if (pXGI->TurboQueue)
- {
- reservedFbSize += pXGI->cmdQueueSize ;
- }
-
- if (pXGI->HWCursor)
- {
- reservedFbSize += VOLARI_CURSOR_SHAPE_SIZE;
- }
-
-#ifdef XGIG2_COLOREXPSCANLN
- reservedFbSize += (pXGI->ColorExpandBufferNumber * pXGI->PerColorExpandBufferSize);
-#endif
-
- UsableFbSize = pXGI->FbMapSize - reservedFbSize;
- AvailBufBase = pXGI->FbBase + UsableFbSize;
-
- for (i = 0; i < pXGI->ColorExpandBufferNumber; i++) {
- const int base = i * pXGI->PerColorExpandBufferSize;
-
- pXGI->ColorExpandBufferAddr[i] = AvailBufBase + base;
- pXGI->ColorExpandBufferScreenOffset[i] = UsableFbSize + base;
- }
-
-#ifdef XGIG2_IMAGEWRITE
- reservedFbSize += pXGI->ImageWriteBufferSize;
- UsableFbSize = pXGI->FbMapSize - reservedFbSize;
- pXGI->ImageWriteBufferAddr = AvailBufBase = pXGI->FbBase + UsableFbSize;
- infoPtr->ImageWriteRange = pXGI->ImageWriteBufferAddr;
-#endif /* XGIG2_IMAGEWRITE */
-
- Avail.x1 = 0;
- Avail.y1 = 0;
-
-/*
- Avail.x2 = pScrn->displayWidth;
-
- ErrorF("FbDevExist=%s\n",FbDevExist?"TRUE":"FALSE");
-
- if (FbDevExist)
- {
- if( UsableFbSize >= 8*1024*1024 )
- {
- UsableFbSize = 8*1024*1024 ;
- }
- else
- {
- UsableFbSize = 4*1024*1024 ;
- }
- }
-
- PDEBUG1(ErrorF( "UsabelFbSize = %08lx\n", UsableFbSize )) ;
- Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
-
- if ((unsigned long)Avail.y2 > 8192)
- {
- Avail.y2 = 8192 ;
- }
-*/
-
- UsableFbSize = pXGI->CursorOffset ;
- Avail.x1 = 0 ;
- Avail.y1 = 0 ;
- Avail.x2 = pScrn->displayWidth;
- Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
-
-
- if ((unsigned long)Avail.y2 > 8192)
- {
- Avail.y2 = 8192 ;
- }
-
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Usable FBSize = %08lx\n", UsableFbSize ) ;
-
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Frame Buffer From (%d,%d) To (%d,%d)\n",
- Avail.x1, Avail.y1, Avail.x2, Avail.y2);
-
- xf86InitFBManager(pScreen, &Avail);
-
- return(XAAInit(pScreen, infoPtr));
-
-}
-
-void
-Volari_Sync(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- PDEBUG1(ErrorF("Volari_Sync()\n"));
- pXGI->DoColorExpand = FALSE;
- Volari_Idle(pXGI);
-}
-
-static int xgiG2_ALUConv[] =
-{
- 0x00, /* dest = 0; 0, GXclear, 0 */
- 0x88, /* dest &= src; DSa, GXand, 0x1 */
- 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
- 0xCC, /* dest = src; S, GXcopy, 0x3 */
- 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
- 0xAA, /* dest = dest; D, GXnoop, 0x5 */
- 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
- 0xEE, /* dest |= src; DSo, GXor, 0x7 */
- 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
- 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
- 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
- 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
- 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
- 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
- 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
- 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
-};
-/* same ROP but with Pattern as Source */
-static int xgiG2_PatALUConv[] =
-{
- 0x00, /* dest = 0; 0, GXclear, 0 */
- 0xA0, /* dest &= src; DPa, GXand, 0x1 */
- 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
- 0xF0, /* dest = src; P, GXcopy, 0x3 */
- 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
- 0xAA, /* dest = dest; D, GXnoop, 0x5 */
- 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
- 0xFA, /* dest |= src; DPo, GXor, 0x7 */
- 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
- 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
- 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
- 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
- 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
- 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
- 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
- 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
-};
-
-static void
-Volari_SetupForScreenToScreenCopy(
- ScrnInfoPtr pScrn,
- int xdir, int ydir, int rop,
- unsigned int planemask, int trans_color)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-#ifdef SHOW_XAAINFO
- XAAInfoRecPtr pXAA = XAAPTR(pScrn);
-/*
- ErrorF("XAAInfoPtr->UsingPixmapCache = %s\n"
- "XAAInfoPtr->CanDoMono8x8 = %s\n"
- "XAAInfoPtr->CanDoColor8x8 = %s\n"
- "XAAInfoPtr->CachePixelGranularity = %d\n"
- "XAAInfoPtr->MaxCacheableTileWidth = %d\n"
- "XAAInfoPtr->MaxCacheableTileHeight = %d\n"
- "XAAInfoPtr->MaxCacheableStippleWidth = %d\n"
- "XAAInfoPtr->MaxCacheableStippleHeight = %d\n"
- "XAAInfoPtr->MonoPatternPitch = %d\n"
- "XAAInfoPtr->CacheWidthMono8x8Pattern = %d\n"
- "XAAInfoPtr->CacheHeightMono8x8Pattern = %d\n"
- "XAAInfoPtr->ColorPatternPitch = %d\n"
- "XAAInfoPtr->CacheWidthColor8x8Pattern = %d\n"
- "XAAInfoPtr->CacheHeightColor8x8Pattern = %d\n"
- "XAAInfoPtr->CacheColorExpandDensity = %d\n"
- "XAAInfoPtr->maxOffPixWidth = %d\n"
- "XAAInfoPtr->maxOffPixHeight= %d\n"
- "XAAInfoPtr->NeedToSync = %s\n"
- "\n",
- pXAA->UsingPixmapCache ? "True" : "False",
- pXAA->CanDoMono8x8 ? "True" : "False",
- pXAA->CanDoColor8x8 ? "True" : "False",
- pXAA->CachePixelGranularity,
- pXAA->MaxCacheableTileWidth,
- pXAA->MaxCacheableTileHeight,
- pXAA->MaxCacheableStippleWidth,
- pXAA->MaxCacheableStippleHeight,
- pXAA->MonoPatternPitch,
- pXAA->CacheWidthMono8x8Pattern,
- pXAA->CacheHeightMono8x8Pattern,
- pXAA->ColorPatternPitch,
- pXAA->CacheWidthColor8x8Pattern,
- pXAA->CacheHeightColor8x8Pattern,
- pXAA->CacheColorExpandDensity,
- pXAA->maxOffPixWidth,
- pXAA->maxOffPixHeight,
- pXAA->NeedToSync ? "True" : "False");
-*/
-#endif
-
- PDEBUG1(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
- xdir, ydir, rop, planemask, trans_color));
-
- Volari_ResetCmd ;
- GuardBand(0x20 * Alignment);
- Volari_SetupDSTColorDepth(pXGI->DstColor);
- Volari_SetupSRCPitch(pXGI->scrnOffset) ;
- Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
- Volari_SetupROP(xgiG2_ALUConv[rop]) ;
-}
-
-static void
-Volari_SubsequentScreenToScreenCopy(
- ScrnInfoPtr pScrn,
- int src_x, int src_y,
- int dst_x, int dst_y,
- int width, int height)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- long srcbase, dstbase;
-/*
- PDEBUG1(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
- src_x, src_y,
- dst_x, dst_y,
- width, height));
-*/
- srcbase=dstbase=0;
- if (src_y >= 2048)
- {
- srcbase=pXGI->scrnOffset*src_y;
- src_y=0;
- }
- if (dst_y >= pScrn->virtualY)
- {
- dstbase=pXGI->scrnOffset*dst_y;
- dst_y=0;
- }
- /*
- PDEBUG1(ErrorF("SrcBase = %08lX DstBase = %08lX\n",srcbase,dstbase)) ;
- PDEBUG1(ErrorF("SrcX = %08lX SrcY = %08lX\n",src_x,src_y)) ;
- PDEBUG1(ErrorF("DstX = %08lX DstY = %08lX\n",dst_x,dst_y)) ;
-*/
- GuardBand(0x30 * Alignment);
- Volari_SetupSRCBase(srcbase);
- Volari_SetupDSTBase(dstbase);
- Volari_SetupSRCXY(src_x,src_y) ;
- Volari_SetupDSTXY(dst_x,dst_y) ;
- Volari_SetupRect(width, height) ;
- Volari_DoCMD ;
-}
-
-static void
-Volari_SetupForSolidFill(ScrnInfoPtr pScrn,
- int color, int rop, unsigned int planemask)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- PDEBUG1(ErrorF("Volari_SetupForSolidFill()\n")) ;
- PDEBUG1(ErrorF("Color = #%08lX ",color)) ;
- PDEBUG1(ErrorF("DstPitch = #%04lX ",(pXGI->scrnOffset))) ;
- PDEBUG1(ErrorF("\n")) ;
-
- Volari_ResetCmd ;
- GuardBand(0x28 * Alignment);
- Volari_SetupPATFG(color) ;
- Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
- Volari_SetupDSTColorDepth(XGIPTR(pScrn)->DstColor) ;
- Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
- Volari_SetupCMDFlag(PATFG | BITBLT) ;
-}
-
-static void
-Volari_SubsequentSolidFillRect(
- ScrnInfoPtr pScrn,
- int x, int y,
- int width, int height)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned long dstbase = 0 ;
-
- PDEBUG1(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
- x, y, width, height));
-
- dstbase=0;
- if (y>=2048)
- {
- dstbase=pXGI->scrnOffset*y;
- y=0;
- }
-
- GuardBand(0x20 * Alignment);
- Volari_SetupDSTBase(dstbase) ;
- Volari_SetupDSTXY(x,y) ;
- Volari_SetupRect(width,height) ;
- Volari_DoCMD ;
-
-}
-
-static void
-Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
- int pat0, int pat1,
- int fg, int bg,
- int rop, unsigned int planemask)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- PDEBUG1(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
- pat0, pat1, fg, bg, rop, planemask));
-
- Volari_ResetCmd ;
- GuardBand(0x40 * Alignment);
- Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
- Volari_SetupMONOPAT0(pat0) ;
- Volari_SetupMONOPAT1(pat1) ;
- Volari_SetupPATFG(fg) ;
- Volari_SetupPATBG(bg) ;
- Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
- Volari_SetupDSTColorDepth(pXGI->DstColor) ;
- Volari_SetupCMDFlag(PATMONO | BITBLT) ;
-}
-
-static void
-Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
- int patx, int paty,
- int x, int y, int w, int h)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- long dstbase;
-
- PDEBUG1(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
- patx, paty, x, y, w, h));
- dstbase=0;
- if (y>=2048)
- {
- dstbase=pXGI->scrnOffset*y;
- y=0;
- }
-
- GuardBand(0x20 * Alignment);
- Volari_SetupDSTBase(dstbase) ;
- Volari_SetupDSTXY(x,y) ;
- Volari_SetupRect(w,h) ;
- Volari_DoCMD ;
- /*Volari_Idle(pXGI)*/;
-}
-
-/************************************************************************/
-
+/*
+ *
+ * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
+ * Parts Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+ *
+ * Licensed under the following terms:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appears in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * and that the name of the copyright holder not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holder makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without expressed or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>,
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
+ * David Thomas <davtom@dream.org.uk>,
+ * Thomas Winischhofer <thomas@winischhofer.net>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include <compiler.h>
+#include <miline.h>
+
+#include "xgi_accel.h"
+#include "xgi_regs.h"
+#include "xgi.h"
+#include "vb_def.h"
+
+#include "xaarop.h"
+#include <xaa.h>
+#include <xaalocal.h>
+#include <xf86fbman.h>
+
+/*************************************************************************/
+
+void Volari_Sync(ScrnInfoPtr pScrn);
+
+static void Volari_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color);
+static void Volari_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int width, int height);
+static void Volari_SetupForSolidFill(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void Volari_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+static void Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask);
+static void Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h);
+
+void Volari_EnableAccelerator(ScrnInfoPtr pScrn) ;
+static void Volari_InitCmdQueue(ScrnInfoPtr pScrn) ;
+static void Volari_DisableDualPipe(ScrnInfoPtr pScrn) ;
+static void Volari_DisableCmdQueue(ScrnInfoPtr pScrn) ;
+
+/* Jong 01/07/2008; force to disable 2D */
+extern Bool ForceToDisable2DEngine(ScrnInfoPtr pScrn);
+
+extern int FbDevExist;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+static CARD32 BE_SWAP32 (CARD32 val)
+{
+ if (CurrentColorDepth == 8)
+ return ((((val) & 0x000000ff) << 24) | \
+ (((val) & 0x0000ff00) << 8) | \
+ (((val) & 0x00ff0000) >> 8) | \
+ (((val) & 0xff000000) >> 24));
+ if (CurrentColorDepth == 24)
+ return val;
+ if (CurrentColorDepth == 16)
+ return ((((val) & 0x0000ffff) << 16) | \
+ (((val) & 0xffff0000) >> 16));
+}
+#else
+static CARD32 BE_SWAP32 (CARD32 val)
+{
+ return val;
+}
+#endif
+
+
+#ifdef DEBUG
+static void dump_cq_read_pointer(unsigned int cqrp)
+{
+ static const char *const field_name[8] = {
+ "all idle",
+ "hardware queues empty",
+ "2D idle",
+ "3D idle",
+ "hardware command queue empty",
+ "2D queue empty",
+ "3D queue empty",
+ "software command queue empty",
+ };
+ unsigned i;
+
+ xf86DrvMsg(0, X_INFO, "IO(0x85CC) = 0x%08x\n", cqrp);
+ for (i = 31; i > 23; i--) {
+ if ((cqrp & (1U << i)) != 0) {
+ xf86DrvMsg(0, X_INFO, " %s\n", field_name[31 - i]);
+ }
+ }
+}
+#endif /* DEBUG */
+
+
+void Volari_SetDefaultIdleWait(XGIPtr pXGI, unsigned HDisplay,
+ unsigned depth)
+{
+ static const unsigned wait_table[5][4] = {
+ { 1, 1, 1, 1 },
+ { 65535, 1, 1000, 3000 },
+ { 65535, 160, 1200, 4000 },
+ { 65535, 200, 1600, 6000 },
+ { 65535, 500, 2000, 8000 }
+ };
+
+ if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
+ unsigned i;
+
+ switch (HDisplay) {
+ case 640: i = 1; break;
+ case 800: i = 2; break;
+ case 1024: i = 3; break;
+ case 1280: i = 4; break;
+ default: i = 0; break;
+ }
+
+ pXGI->idle_wait_count = wait_table[i][3 & (depth / 8)];
+ }
+ else {
+ pXGI->idle_wait_count = 65535;
+ }
+}
+
+void Volari_Idle(XGIPtr pXGI)
+{
+ int i;
+#ifdef DEBUG
+ unsigned int last_cqrp = 0;
+#endif /* DEBUG */
+
+ do {
+ int bIdle = 0;
+ unsigned int cqrp;
+
+ for (i = 0; i < pXGI->idle_wait_count; i++) {
+ cqrp = MMIO_IN32(pXGI->IOBase, 0x85CC);
+ if (cqrp & IDLE_ALL) {
+ bIdle = 1;
+ break;
+ }
+ }
+
+ if (bIdle)
+ break;
+
+#ifdef DEBUG
+ if (last_cqrp != cqrp) {
+ dump_cq_read_pointer(cqrp);
+ last_cqrp = cqrp;
+ }
+
+ sleep(1);
+#endif /* DEBUG */
+
+ if (pXGI->Chipset == PCI_CHIP_XGIXG20)
+ usleep(1);
+ } while (1);
+}
+
+
+void
+Volari_EnableAccelerator(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ PDEBUG(ErrorF("Volari_EnableAccelerator()\n")) ;
+
+ switch (pXGI->Chipset) {
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21: /* Jong 01/07/2008; support new XG21 */
+ case PCI_CHIP_XGIXG27:
+ case PCI_CHIP_XGIXG40:
+ default:
+ orXGIIDXREG(XGISR, 0x1E,
+ SR1E_ENABLE_3D_TRANSFORM_ENGINE
+ | SR1E_ENABLE_2D
+ | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
+ | SR1E_ENABLE_3D_COMMAND_PARSER
+ | SR1E_ENABLE_3D);
+
+ /* Jong 01/07/2008; force to disable 2D */
+ if(pXGI->Chipset == PCI_CHIP_XGIXG21)
+ {
+ if(ForceToDisable2DEngine(pScrn))
+ {
+ andXGIIDXREG(XGISR, 0x1E, 0xBF) ;
+ }
+ }
+
+ break;
+ }
+
+
+ if( pXGI->TurboQueue )
+ {
+ Volari_InitCmdQueue(pScrn) ;
+ }
+}
+
+static void
+Volari_InitCmdQueue(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned long ulXGITempRP ;
+ unsigned long ulCR55 ;
+ unsigned long ulSR26 ;
+ unsigned long temp ;
+ /* unsigned long ulFlag = 0 ; */
+/*
+ PDEBUG(ErrorF("Volari_InitCmdQueue()\n"));
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
+*/
+ inXGIIDXREG(XGICR, 0x55, ulCR55) ;
+ andXGIIDXREG(XGICR, 0x55, 0x33) ;
+ orXGIIDXREG(XGISR, 0x26, 1) ; /* reset cmd queue */
+
+ w_port = Volari_GetSwWP() ; /* GuardBand() Init */
+ r_port = Volari_GetHwRP() ;
+
+ if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 ))
+ {
+ Alignment = 1 ; /* 64 bits */
+
+ switch(pXGI->cmdQueueSize)
+ {
+ case 64*1024:
+ ulSR26 = 0x40 + 0x00 ;
+ break ;
+ case 128*1024:
+ ulSR26 = 0x40 + 0x04 ;
+ break ;
+ default:
+ /* reset the command queue information */
+
+ pXGI->cmdQueueSize = 128*1024 ; /* reset the command queue */
+ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+
+ /* Jong 09/18/2007; bug fixing for ??? */
+ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) )
+ {
+ if( pScrn->videoRam < 8*1024 )
+ {
+ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ else if( pScrn->videoRam < 16*1024 )
+ {
+ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ else
+ {
+ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ }
+ else
+ {
+ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
+ }
+
+ pXGI->cmdQueueLen = 0 ;
+ pXGI->cmdQueueLenMin = 0x200 ;
+ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+
+ ulSR26 = 0x40 ;
+ break ;
+ }
+ }
+ else
+ {
+ Alignment = 2 ; /* 128 bits */
+
+ switch(pXGI->cmdQueueSize)
+ {
+ case 512*1024:
+ ulSR26 = 0x40 + 0x00 ;
+ break ;
+ case 1024*1024:
+ ulSR26 = 0x40 + 0x04 ;
+ break ;
+ case 2*1024*1024:
+ ulSR26 = 0x40 + 0x08 ;
+ break ;
+ case 4*1024*1024:
+ ulSR26 = 0x40 + 0x0C ;
+ break ;
+ default:
+ /* reset the command queue information */
+
+ pXGI->cmdQueueSize = 512*1024 ; /* reset the command queue */
+ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+
+ /* Jong 09/18/2007; bug fixing for ??? */
+ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ))
+ {
+ if( pScrn->videoRam < 8*1024 )
+ {
+ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ else if( pScrn->videoRam < 16*1024 )
+ {
+ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ else
+ {
+ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ }
+ else
+ {
+ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
+ }
+
+ pXGI->cmdQueueLen = 0 ;
+ pXGI->cmdQueueLenMin = 0x200 ;
+ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+
+ ulSR26 = 0x40 ;
+ break ;
+ }
+ }
+
+ pXGI->CursorOffset = pXGI->cmdQueueOffset - VOLARI_CURSOR_SHAPE_SIZE;
+
+ temp = (unsigned long)pXGI->FbBase ;
+ temp += pXGI->cmdQueueOffset ;
+ pXGI->cmdQueueBase = (unsigned char *)temp ;
+/*
+ PDEBUG(ErrorF( "pXGI->FbBase = 0x%lX\n", pXGI->FbBase )) ;
+ PDEBUG(ErrorF( "pXGI->cmdQueueOffset = 0x%lX\n", pXGI->cmdQueueOffset )) ;
+ PDEBUG(ErrorF( "pXGI->cmdQueueBase = 0x%lX\n", pXGI->cmdQueueBase )) ;
+*/
+ outXGIIDXREG(XGISR, 0x26, ulSR26) ;
+
+ ulXGITempRP=Volari_GetHwRP() ;
+/*
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
+ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
+*/
+ /* XGI315 */
+ pXGI->cmdQueue_shareWP_only2D = ulXGITempRP;
+ /* pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D); */
+
+ Volari_UpdateHwWP(ulXGITempRP) ;
+
+
+
+ MMIO_OUT32(pXGI->IOBase, 0x85C0, pXGI->cmdQueueOffset) ;
+
+ outXGIIDXREG(XGICR, 0x55, ulCR55) ;
+
+ if(pXGI->Chipset == PCI_CHIP_XGIXG40)
+ {
+ Volari_Idle(pXGI);
+ Volari_DisableDualPipe(pScrn) ;
+ Volari_Idle(pXGI);
+
+ }
+ PDEBUG(ErrorF("Volari_InitCmdQueue() done.\n")) ;
+}
+
+static void
+Volari_DisableDualPipe(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn) ;
+ unsigned long ulTemp ;
+ unsigned long ulValue = MMIO_IN32(pXGI->IOBase, 0x8240) ;
+ ulValue |= 1 << 10 ; /* D[10] = 1, Disable Dual Pipe. */
+
+ ulTemp = Volari_GetSwWP() ;
+
+ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp) = (CARD32)BE_SWAP32(GR_SKPC_HEADER + 0x8240) ;
+ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+4) = (CARD32)BE_SWAP32(ulValue) ;
+
+ if( pXGI->Chipset == PCI_CHIP_XGIXG40 )
+ {
+ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+8) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
+ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+12) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
+
+ ulTemp += 0x10 ;
+ }
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 ) || ( pXGI->Chipset == PCI_CHIP_XGIXG21 ) || ( pXGI->Chipset == PCI_CHIP_XGIXG27 ))
+ ulTemp += 0x08 ;
+
+ ulTemp &= pXGI->cmdQueueSizeMask ;
+ Volari_UpdateHwWP(ulTemp) ;
+}
+
+void
+Volari_DisableAccelerator(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn) ;
+
+ PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn)\n")) ;
+
+ Volari_Idle(pXGI);
+
+ if( pXGI->TurboQueue )
+ {
+ Volari_DisableCmdQueue(pScrn) ;
+ }
+
+ andXGIIDXREG(XGISR, 0x1E,
+ ~(SR1E_ENABLE_3D_TRANSFORM_ENGINE
+ | SR1E_ENABLE_2D
+ | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
+ | SR1E_ENABLE_3D_COMMAND_PARSER
+ | SR1E_ENABLE_3D));
+/* PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn) Done, GBCount = %ld\n",GBCount)) ; */
+}
+
+static void
+Volari_DisableCmdQueue(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn) ;
+
+ andXGIIDXREG(XGISR, 0x26, 0x0F) ;
+}
+
+void
+Volari_InitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ pXGI->DoColorExpand = FALSE;
+}
+
+Bool
+Volari_AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XGIPtr pXGI = XGIPTR(pScrn);
+ int reservedFbSize;
+ long UsableFbSize;
+ unsigned char *AvailBufBase;
+ BoxRec Avail;
+ int i;
+
+
+ Avail.x1 = 0; Avail.y1 = 0; Avail.x2 = 0; Avail.y2 = 0;
+
+ PDEBUG1(ErrorF("Volari_AccelInit()\n" )) ;
+
+ pXGI->AccelInfoPtr = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ Volari_InitializeAccelerator(pScrn);
+
+ infoPtr->Flags = LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS |
+ PIXMAP_CACHE;
+
+ /* sync */
+ infoPtr->Sync = Volari_Sync;
+
+ if ((pScrn->bitsPerPixel != 8) &&
+ (pScrn->bitsPerPixel != 16) &&
+ (pScrn->bitsPerPixel != 32))
+ {
+ return FALSE;
+ }
+
+ /* Jong 01/07/2008; force to disable 2D based on SR3A[6] for XG21 */
+ if( !((pXGI->Chipset == PCI_CHIP_XGIXG21) && ForceToDisable2DEngine(pScrn)) )
+ {
+#ifdef XGIG2_SCR2SCRCOPY
+ /* BitBlt */
+ /* Jong 08/24/2007; cause an extra rectangle drawing at top-left corner while clicking "Computer" on Suse SP1 (Xorg6.9.0) */
+ if(pScrn->bitsPerPixel != 8)
+ {
+ infoPtr->SetupForScreenToScreenCopy = Volari_SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = Volari_SubsequentScreenToScreenCopy;
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
+ }
+#endif
+
+#ifdef XGIG2_SOLIDFILL
+ /* solid fills */
+ infoPtr->SetupForSolidFill = Volari_SetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = Volari_SubsequentSolidFillRect;
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+#endif
+
+#ifdef XGIG2_8X8MONOPATFILL
+ /* 8x8 mono pattern fill */
+ infoPtr->SetupForMono8x8PatternFill = Volari_SetupForMonoPatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = Volari_SubsequentMonoPatternFill;
+ infoPtr->Mono8x8PatternFillFlags =
+ NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ /* 2005/08/15 modified by jjtseng */
+ /* NO_TRANSPARENCY | */
+ /*~ jjtseng 2005/08/15 */
+ BIT_ORDER_IN_BYTE_MSBFIRST ;
+#endif /* XGIG2_8X8MONOPATFILL */
+ }
+
+ /* init Frame Buffer Manager */
+ reservedFbSize = 0;
+ if (pXGI->TurboQueue)
+ {
+ reservedFbSize += pXGI->cmdQueueSize ;
+ }
+
+ if (pXGI->HWCursor)
+ {
+ reservedFbSize += VOLARI_CURSOR_SHAPE_SIZE;
+ }
+
+#ifdef XGIG2_COLOREXPSCANLN
+ reservedFbSize += (pXGI->ColorExpandBufferNumber * pXGI->PerColorExpandBufferSize);
+#endif
+
+ UsableFbSize = pXGI->FbMapSize - reservedFbSize;
+ AvailBufBase = pXGI->FbBase + UsableFbSize;
+
+ for (i = 0; i < pXGI->ColorExpandBufferNumber; i++) {
+ const int base = i * pXGI->PerColorExpandBufferSize;
+
+ pXGI->ColorExpandBufferAddr[i] = AvailBufBase + base;
+ pXGI->ColorExpandBufferScreenOffset[i] = UsableFbSize + base;
+ }
+
+#ifdef XGIG2_IMAGEWRITE
+ reservedFbSize += pXGI->ImageWriteBufferSize;
+ UsableFbSize = pXGI->FbMapSize - reservedFbSize;
+ pXGI->ImageWriteBufferAddr = AvailBufBase = pXGI->FbBase + UsableFbSize;
+ infoPtr->ImageWriteRange = pXGI->ImageWriteBufferAddr;
+#endif /* XGIG2_IMAGEWRITE */
+
+ Avail.x1 = 0;
+ Avail.y1 = 0;
+
+/*
+ Avail.x2 = pScrn->displayWidth;
+
+ ErrorF("FbDevExist=%s\n",FbDevExist?"TRUE":"FALSE");
+
+ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) )
+ {
+ if( UsableFbSize >= 8*1024*1024 )
+ {
+ UsableFbSize = 8*1024*1024 ;
+ }
+ else
+ {
+ UsableFbSize = 4*1024*1024 ;
+ }
+ }
+
+ PDEBUG1(ErrorF( "UsabelFbSize = %08lx\n", UsableFbSize )) ;
+ Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
+
+ if ((unsigned long)Avail.y2 > 8192)
+ {
+ Avail.y2 = 8192 ;
+ }
+*/
+
+ UsableFbSize = pXGI->CursorOffset ;
+ Avail.x1 = 0 ;
+ Avail.y1 = 0 ;
+ Avail.x2 = pScrn->displayWidth;
+ Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
+
+
+ if ((unsigned long)Avail.y2 > 8192)
+ {
+ Avail.y2 = 8192 ;
+ }
+
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Usable FBSize = %08lx\n", UsableFbSize ) ;
+
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Frame Buffer From (%d,%d) To (%d,%d)\n",
+ Avail.x1, Avail.y1, Avail.x2, Avail.y2);
+
+ xf86InitFBManager(pScreen, &Avail);
+
+ return(XAAInit(pScreen, infoPtr));
+
+}
+
+void
+Volari_Sync(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ PDEBUG1(ErrorF("Volari_Sync()\n"));
+ pXGI->DoColorExpand = FALSE;
+ Volari_Idle(pXGI);
+}
+
+static int xgiG2_ALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+/* same ROP but with Pattern as Source */
+static int xgiG2_PatALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+
+static void
+Volari_SetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+#ifdef SHOW_XAAINFO
+ XAAInfoRecPtr pXAA = XAAPTR(pScrn);
+/*
+ ErrorF("XAAInfoPtr->UsingPixmapCache = %s\n"
+ "XAAInfoPtr->CanDoMono8x8 = %s\n"
+ "XAAInfoPtr->CanDoColor8x8 = %s\n"
+ "XAAInfoPtr->CachePixelGranularity = %d\n"
+ "XAAInfoPtr->MaxCacheableTileWidth = %d\n"
+ "XAAInfoPtr->MaxCacheableTileHeight = %d\n"
+ "XAAInfoPtr->MaxCacheableStippleWidth = %d\n"
+ "XAAInfoPtr->MaxCacheableStippleHeight = %d\n"
+ "XAAInfoPtr->MonoPatternPitch = %d\n"
+ "XAAInfoPtr->CacheWidthMono8x8Pattern = %d\n"
+ "XAAInfoPtr->CacheHeightMono8x8Pattern = %d\n"
+ "XAAInfoPtr->ColorPatternPitch = %d\n"
+ "XAAInfoPtr->CacheWidthColor8x8Pattern = %d\n"
+ "XAAInfoPtr->CacheHeightColor8x8Pattern = %d\n"
+ "XAAInfoPtr->CacheColorExpandDensity = %d\n"
+ "XAAInfoPtr->maxOffPixWidth = %d\n"
+ "XAAInfoPtr->maxOffPixHeight= %d\n"
+ "XAAInfoPtr->NeedToSync = %s\n"
+ "\n",
+ pXAA->UsingPixmapCache ? "True" : "False",
+ pXAA->CanDoMono8x8 ? "True" : "False",
+ pXAA->CanDoColor8x8 ? "True" : "False",
+ pXAA->CachePixelGranularity,
+ pXAA->MaxCacheableTileWidth,
+ pXAA->MaxCacheableTileHeight,
+ pXAA->MaxCacheableStippleWidth,
+ pXAA->MaxCacheableStippleHeight,
+ pXAA->MonoPatternPitch,
+ pXAA->CacheWidthMono8x8Pattern,
+ pXAA->CacheHeightMono8x8Pattern,
+ pXAA->ColorPatternPitch,
+ pXAA->CacheWidthColor8x8Pattern,
+ pXAA->CacheHeightColor8x8Pattern,
+ pXAA->CacheColorExpandDensity,
+ pXAA->maxOffPixWidth,
+ pXAA->maxOffPixHeight,
+ pXAA->NeedToSync ? "True" : "False");
+*/
+#endif
+
+ PDEBUG1(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
+ xdir, ydir, rop, planemask, trans_color));
+
+ Volari_ResetCmd ;
+ GuardBand(0x20 * Alignment);
+ Volari_SetupDSTColorDepth(pXGI->DstColor);
+ Volari_SetupSRCPitch(pXGI->scrnOffset) ;
+ Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
+ Volari_SetupROP(xgiG2_ALUConv[rop]) ;
+}
+
+static void
+Volari_SubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int src_x, int src_y,
+ int dst_x, int dst_y,
+ int width, int height)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ long srcbase, dstbase;
+/*
+ PDEBUG1(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
+ src_x, src_y,
+ dst_x, dst_y,
+ width, height));
+*/
+ srcbase=dstbase=0;
+ if (src_y >= 2048)
+ {
+ srcbase=pXGI->scrnOffset*src_y;
+ src_y=0;
+ }
+ if (dst_y >= pScrn->virtualY)
+ {
+ dstbase=pXGI->scrnOffset*dst_y;
+ dst_y=0;
+ }
+ /*
+ PDEBUG1(ErrorF("SrcBase = %08lX DstBase = %08lX\n",srcbase,dstbase)) ;
+ PDEBUG1(ErrorF("SrcX = %08lX SrcY = %08lX\n",src_x,src_y)) ;
+ PDEBUG1(ErrorF("DstX = %08lX DstY = %08lX\n",dst_x,dst_y)) ;
+*/
+ GuardBand(0x30 * Alignment);
+ Volari_SetupSRCBase(srcbase);
+ Volari_SetupDSTBase(dstbase);
+ Volari_SetupSRCXY(src_x,src_y) ;
+ Volari_SetupDSTXY(dst_x,dst_y) ;
+ Volari_SetupRect(width, height) ;
+ Volari_DoCMD ;
+}
+
+static void
+Volari_SetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ PDEBUG1(ErrorF("Volari_SetupForSolidFill()\n")) ;
+ PDEBUG1(ErrorF("Color = #%08lX ",color)) ;
+ PDEBUG1(ErrorF("DstPitch = #%04lX ",(pXGI->scrnOffset))) ;
+ PDEBUG1(ErrorF("\n")) ;
+
+ Volari_ResetCmd ;
+ GuardBand(0x28 * Alignment);
+ Volari_SetupPATFG(color) ;
+ Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
+ Volari_SetupDSTColorDepth(XGIPTR(pScrn)->DstColor) ;
+ Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
+ Volari_SetupCMDFlag(PATFG | BITBLT) ;
+}
+
+static void
+Volari_SubsequentSolidFillRect(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int width, int height)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned long dstbase = 0 ;
+
+ PDEBUG1(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
+ x, y, width, height));
+
+ dstbase=0;
+ if (y>=2048)
+ {
+ dstbase=pXGI->scrnOffset*y;
+ y=0;
+ }
+
+ GuardBand(0x20 * Alignment);
+ Volari_SetupDSTBase(dstbase) ;
+ Volari_SetupDSTXY(x,y) ;
+ Volari_SetupRect(width,height) ;
+ Volari_DoCMD ;
+
+}
+
+static void
+Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
+ int pat0, int pat1,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ PDEBUG1(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
+ pat0, pat1, fg, bg, rop, planemask));
+
+ Volari_ResetCmd ;
+ GuardBand(0x40 * Alignment);
+ Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
+ Volari_SetupMONOPAT0(pat0) ;
+ Volari_SetupMONOPAT1(pat1) ;
+ Volari_SetupPATFG(fg) ;
+ Volari_SetupPATBG(bg) ;
+ Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
+ Volari_SetupDSTColorDepth(pXGI->DstColor) ;
+ Volari_SetupCMDFlag(PATMONO | BITBLT) ;
+}
+
+static void
+Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ long dstbase;
+
+ PDEBUG1(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
+ patx, paty, x, y, w, h));
+ dstbase=0;
+ if (y>=2048)
+ {
+ dstbase=pXGI->scrnOffset*y;
+ y=0;
+ }
+
+ GuardBand(0x20 * Alignment);
+ Volari_SetupDSTBase(dstbase) ;
+ Volari_SetupDSTXY(x,y) ;
+ Volari_SetupRect(w,h) ;
+ Volari_DoCMD ;
+ /*Volari_Idle(pXGI)*/;
+}
+
+/************************************************************************/
+
diff --git a/src/xgi_accel.h b/src/xgi_accel.h
index 8f5d005..a0fa9f5 100644
--- a/src/xgi_accel.h
+++ b/src/xgi_accel.h
@@ -116,6 +116,8 @@
#define BandSize 0x10
+/* Jong 09/27/2007; recover for compiler error */
+typedef unsigned long ulong ;
/* typedef unsigned long ulong ; */
unsigned long r_port, w_port ;
@@ -248,7 +250,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateHwWP(ulTemp) ;\
@@ -280,7 +282,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -314,7 +316,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -346,7 +348,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -379,7 +381,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -412,7 +414,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -445,7 +447,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -488,7 +490,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -538,7 +540,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -564,7 +566,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -589,7 +591,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -614,7 +616,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -647,7 +649,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -672,7 +674,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -709,7 +711,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -734,7 +736,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -759,7 +761,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -830,7 +832,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -855,7 +857,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -880,7 +882,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -905,7 +907,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -930,7 +932,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
@@ -955,7 +957,7 @@ extern void Volari_Idle(XGIPtr pXGI);
(CARD32)BE_SWAP32(GR_NIL_CMD) ;\
ulTemp += 0x10 ;\
} \
- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
+ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
ulTemp += 0x08 ;\
ulTemp &= pXGI->cmdQueueSizeMask ;\
Volari_UpdateSwWP(ulTemp) ;\
diff --git a/src/xgi_cursor.c b/src/xgi_cursor.c
index a66eed1..2d5d8c6 100644
--- a/src/xgi_cursor.c
+++ b/src/xgi_cursor.c
@@ -67,10 +67,24 @@ Volari_ShowCursor(ScrnInfoPtr pScrn)
/* unsigned long cursor_addr = pXGI->CursorOffset ; */
unsigned long cursor_base = pXGI->CursorOffset/1024 ;
- xgiG2CRT1_EnableHWCursor(cursor_base, 0);
- if (pXGI->VBFlags & CRT2_ENABLE) {
- xgiG2CRT2_EnableHWCursor(cursor_base, 0);
+ /* Jong 09/19/2007; bug fixing for ??? */
+ if( pXGI->HWARGBCursor )
+ {
+ xgiG2CRT1_EnableARGBHWCursor(cursor_base, 0);
+ if (pXGI->VBFlags & CRT2_ENABLE)
+ {
+ xgiG2CRT2_EnableARGBHWCursor(cursor_base, 0);
+ }
}
+ else
+ {
+ xgiG2CRT1_EnableHWCursor(cursor_base, 0);
+ if (pXGI->VBFlags & CRT2_ENABLE)
+ {
+ xgiG2CRT2_EnableHWCursor(cursor_base, 0);
+ }
+ }
+
XGIG1_SetCursorPosition(pScrn, currX, currY) ;
XGI_WaitEndRetrace(pXGI->RelIO);
}
@@ -163,6 +177,66 @@ Volari_UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
return TRUE;
}
+/* Jong 09/19/2007; Is this required? */
+Bool
+Volari_UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DisplayModePtr mode = pScrn->currentMode;
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ if (mode->Flags & V_INTERLACE)
+ {
+ return FALSE;
+ }
+
+ /* DumpDDIName("Volari_UserHWCursorARGB()\n") ; */
+
+ return TRUE ;
+}
+
+/* Jong 09/19/2007; Is this required? */
+static void
+Volari_LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCursor)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned long cursor_addr = pXGI->CursorOffset ;
+ unsigned long cursor_base = pXGI->CursorOffset/1024 ;
+ unsigned char *pCursorShape ;
+ int i , j ; CARD32 *pDest,*pSrc ;
+ CursorBitsPtr pCursorBits = pCursor->bits ;
+
+
+ /* DumpDDIName("Volari_LoadCursorARGB()\n") ; */
+ pXGI->HWARGBCursor = TRUE ;
+ pCursorShape = pXGI->FbBase + cursor_addr ;
+
+ pSrc = pCursorBits->argb ;
+
+ pXGI->CurXPreset = 64-pCursorBits->width ;
+ pXGI->CurYPreset = 64-pCursorBits->height ;
+
+ for( i = 64 - pCursorBits->height ; i< 64 ; i++ )
+ {
+ pDest = (CARD32 *)(pCursorShape + i*64*4 ) ;
+ for( j = 64-pCursorBits->width ; j < 64 ; j++, pSrc++ )
+ {
+ pDest[j] = *pSrc ;
+ }
+ }
+
+ xgiG2CRT1_SetCursorAddressPattern(cursor_base,0) ;
+
+ if (pXGI->VBFlags & CRT2_ENABLE) {
+ xgiG2CRT2_SetCursorAddressPattern(cursor_base,0) ;
+ /* xgiG1CRT2_SetCursorAddress(cursor_base) ; */
+ /* xgiG1CRT2_SetCursorPatternSelect(0) ; */
+ }
+ XGIG1_SetCursorPosition(pScrn, currX, currY) ;
+ PDEBUG4(vWaitCRT1VerticalRetrace(pScrn)) ;
+ PDEBUG4(XGIDumpMMIO(pScrn));
+}
+
Bool
XGIHWCursorInit(ScreenPtr pScreen)
{
@@ -179,6 +253,8 @@ XGIHWCursorInit(ScreenPtr pScreen)
case PCI_CHIP_XGIXG40:
case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21:
+ case PCI_CHIP_XGIXG27:
default:
PDEBUG(ErrorF("--- HWCursorInit() \n"));
infoPtr->MaxWidth = 64;
@@ -192,6 +268,13 @@ XGIHWCursorInit(ScreenPtr pScreen)
infoPtr->LoadCursorImage = Volari_LoadCursorImage;
infoPtr->UseHWCursor = Volari_UseHWCursor;
/* infoPtr->RealizeCursor = XGIRealizeCursorColor ; // */
+
+ /* Jong 09/19/2007; Is this required */
+ #ifdef XGI_ARGB_CURSOR
+ infoPtr->UseHWCursorARGB = Volari_UseHWCursorARGB ;
+ infoPtr->LoadCursorARGB = Volari_LoadCursorARGB ;
+ #endif
+
infoPtr->Flags =
HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_INVERT_MASK |
diff --git a/src/xgi_cursor.h b/src/xgi_cursor.h
index a29e3cb..64bb87f 100644
--- a/src/xgi_cursor.h
+++ b/src/xgi_cursor.h
@@ -190,4 +190,27 @@
XGIMMIOLONG(0x8520) =BE_SWAP32(ulTemp) ;\
}
+/* Jong 09/19/2007; added for ??? */
+#define xgiG2CRT1_EnableARGBHWCursor(cursor_base,pat_id)\
+ {\
+ CARD32 ulTemp ;\
+ ulTemp = XGIMMIOLONG(0x8500) ;\
+ ulTemp &= 0x00FC0000 ;\
+ ulTemp |= 0xE<<28 ;\
+ ulTemp |= (cursor_base) & 0x3FFFF ;\
+ ulTemp |= ((pat_id)&0xF)<<24 ;\
+ XGIMMIOLONG(0x8500) = ulTemp ;\
+ }
+
+#define xgiG2CRT2_EnableARGBHWCursor(cursor_base,pat_id)\
+ {\
+ CARD32 ulTemp ;\
+ ulTemp = XGIMMIOLONG(0x8500) ;\
+ ulTemp &= 0x00FC0000 ;\
+ ulTemp |= 0xE<<28 ;\
+ ulTemp |= (cursor_base) & 0x3FFFF ;\
+ ulTemp |= ((pat_id)&0xF)<<24 ;\
+ XGIMMIOLONG(0x8500) = ulTemp ;\
+ }
+
/*******************************************************************/
diff --git a/src/xgi_dac.c b/src/xgi_dac.c
index b8155e0..9a95001 100644
--- a/src/xgi_dac.c
+++ b/src/xgi_dac.c
@@ -359,7 +359,7 @@ Volari_Restore(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
int vgaIOBase;
int i;
-PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
+ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
"Volari_Restore(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)\n");
@@ -386,8 +386,12 @@ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
| SR1E_ENABLE_3D));
PDEBUG(XGIDumpRegs(pScrn));
#endif
- PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
+
+ PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
+
for (i = 0x19; i < 0x5C; i++) {
+ /* Jong 09/19/2007; added for ??? */
+ if((i!=0x48 && i!=0x4a)|| ((pXGI->Chipset != PCI_CHIP_XGIXG20)&&(pXGI->Chipset != PCI_CHIP_XGIXG21)&&(pXGI->Chipset != PCI_CHIP_XGIXG27)))
outXGIIDXREG(XGICR, i, xgiReg->xgiRegs3D4[i]);
}
@@ -407,7 +411,7 @@ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
}
-// yilin restore the VB register
+ // yilin restore the VB register
outXGIIDXREG(XGIPART1, 0x2f, 0x01);
for (i=0; i<0x50; i++)
{
@@ -432,7 +436,7 @@ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
/* MemClock needs this to take effect */
outw(VGA_SEQ_INDEX, 0x0100); /* Synchronous Reset */
- PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
+ PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
"Volari_Restore(ScrnInfoPtr pScrn, XGIRegPtr xgiReg) Done\n");
@@ -452,7 +456,7 @@ Volari_Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode,
/**
* Calculate available memory bandwidth for an XG40 series chip.
*
- * \sa XG20_MemBandWidth
+ * \sa XG40_MemBandWidth
*/
static int XG40_MemBandWidth(ScrnInfoPtr pScrn)
{
@@ -480,7 +484,7 @@ static int XG40_MemBandWidth(ScrnInfoPtr pScrn)
/**
* Calculate available memory bandwidth for an XG20 series chip.
*
- * \sa XG40_MemBandWidth
+ * \sa XG20_MemBandWidth
*/
static int XG20_MemBandWidth(ScrnInfoPtr pScrn)
{
@@ -491,8 +495,35 @@ static int XG20_MemBandWidth(ScrnInfoPtr pScrn)
const float magic = 1.44;
float total = (mclk * bus) / bpp;
+ /* Jong 09/19/2007; support DDRII and double pixel clock */
+ unsigned long SR39, CR97 ;
+
PDEBUG5(ErrorF("mclk: %d, bus: %d, magic: %f, bpp: %d\n",
mclk, bus, magic, bpp));
+
+ total = mclk*bus/bpp;
+
+ /* Jong 04/26/2007; support DDRII and double pixel clock */
+ /*-------------------------------------------------------*/
+ inXGIIDXREG(XGISR, 0x39, SR39);
+ inXGIIDXREG(XGICR, 0x97, CR97);
+
+ if (CR97 & 0x10)
+ {
+ if (CR97 & 0x01)
+ {
+ total *= 2;
+ }
+ }
+ else
+ {
+ if (SR39 & 0x2)
+ {
+ total *= 2;
+ }
+ }
+ /*-------------------------------------------------------*/
+
PDEBUG5(ErrorF("Total Adapter Bandwidth is %fM\n", total/1000));
return (int)(total / magic);
@@ -606,7 +637,7 @@ PDEBUG(ErrorF("XGIDACPreInit()\n"));
pXGI->XGIRestore = Volari_Restore;
pXGI->SetThreshold = Volari_Threshold;
- pXGI->MaxClock = (pXGI->Chipset == PCI_CHIP_XGIXG20)
+ pXGI->MaxClock = ((pXGI->Chipset == PCI_CHIP_XGIXG20) || (pXGI->Chipset == PCI_CHIP_XGIXG21) || (pXGI->Chipset == PCI_CHIP_XGIXG27))
? XG20_MemBandWidth(pScrn) : XG40_MemBandWidth(pScrn);
}
diff --git a/src/xgi_dri.c b/src/xgi_dri.c
index b76ecbd..08b58e1 100644
--- a/src/xgi_dri.c
+++ b/src/xgi_dri.c
@@ -38,6 +38,12 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+/* Jong 09/27/2007; added for PACKAGE_VERSION_MAJOR,... */
+#define PACKAGE_VERSION_MAJOR 1
+#define PACKAGE_VERSION_MINOR 1
+#define PACKAGE_VERSION_PATCHLEVEL 0
+
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Priv.h"
diff --git a/src/xgi_driver.c b/src/xgi_driver.c
index cb01f9d..a1ef47b 100644
--- a/src/xgi_driver.c
+++ b/src/xgi_driver.c
@@ -1,6036 +1,6458 @@
-/*
- * XGI driver main code
- *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1) Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3) The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
- * - driver entirely rewritten since 2001, only basic structure taken from
- * old code (except xgi_dri.c, xgi_shadow.c, xgi_accel.c and parts of
- * xgi_dga.c; these were mostly taken over; xgi_dri.c was changed for
- * new versions of the DRI layer)
- *
- * This notice covers the entire driver code unless otherwise indicated.
- *
- * Formerly based on code which is
- * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
- * Written by:
- * Alan Hourihane <alanh@fairlite.demon.co.uk>,
- * Mike Chapman <mike@paranoia.com>,
- * Juanjo Santamarta <santamarta@ctv.es>,
- * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
- * David Thomas <davtom@dream.org.uk>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "fb.h"
-#include "mibank.h"
-#include "micmap.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSproc.h"
-#include "xf86Resources.h"
-#include "dixstruct.h"
-#include "xf86Version.h"
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-#include "xf86cmap.h"
-#include "vgaHW.h"
-#include "xf86RAC.h"
-#include "shadowfb.h"
-#include "vbe.h"
-
-#include "mipointer.h"
-#include "mibstore.h"
-
-#include "xgi.h"
-#include "xgi_regs.h"
-#include "xgi_vb.h"
-#include "xgi_dac.h"
-#include "vb_def.h"
-#include "xgi_driver.h"
-#include "valid_mode.h"
-
-#define _XF86DGA_SERVER_
-#include <X11/extensions/xf86dgastr.h>
-
-#include "globals.h"
-
-#define DPMS_SERVER
-#include <X11/extensions/dpms.h>
-
-#if defined(XvExtension)
-#include "xf86xv.h"
-#include <X11/extensions/Xv.h>
-#endif
-
-#ifdef XF86DRI
-#include "dri.h"
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#ifdef XSERVER_LIBPCIACCESS
-static Bool XGIPciProbe(DriverPtr drv, int entity_num,
- struct pci_device *dev, intptr_t match_data);
-#else
-static Bool XGIProbe(DriverPtr drv, int flags);
-#endif
-
-void Volari_EnableAccelerator(ScrnInfoPtr pScrn);
-/* Globals (yes, these ARE really required to be global) */
-
-#ifdef XGIDUALHEAD
-static int XGIEntityIndex = -1;
-#endif
-
-/*
- * This is intentionally screen-independent. It indicates the binding
- * choice made in the first PreInit.
- */
-static int pix24bpp = 0;
-int FbDevExist;
-
-#define FBIOGET_FSCREENINFO 0x4602
-#define FB_ACCEL_XGI_GLAMOUR 41
-
-struct fb_fix_screeninfo
-{
- char id[16]; /* identification string eg "TT Builtin" */
- unsigned long smem_start; /* Start of frame buffer mem */
- /* (physical address) */
- unsigned long smem_len; /* Length of frame buffer mem */
- unsigned long type; /* see FB_TYPE_* */
- unsigned long type_aux; /* Interleave for interleaved Planes */
- unsigned long visual; /* see FB_VISUAL_* */
- unsigned short xpanstep; /* zero if no hardware panning */
- unsigned short ypanstep; /* zero if no hardware panning */
- unsigned short ywrapstep; /* zero if no hardware ywrap */
- unsigned long line_length; /* length of a line in bytes */
- unsigned long mmio_start; /* Start of Memory Mapped I/O */
- /* (physical address) */
- unsigned long mmio_len; /* Length of Memory Mapped I/O */
- unsigned long accel; /* Type of acceleration available */
- unsigned short reserved[3]; /* Reserved for future compatibility */
-};
-
-#ifdef XSERVER_LIBPCIACCESS
-#define XGI_DEVICE_MATCH(d, i) \
- { 0x18ca, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
-
-static const struct pci_id_match xgi_device_match[] = {
- XGI_DEVICE_MATCH(PCI_CHIP_XGIXG40, 0),
- XGI_DEVICE_MATCH(PCI_CHIP_XGIXG20, 1),
-
- { 0, 0, 0 },
-};
-#endif
-
-/*
- * This contains the functions needed by the server after loading the driver
- * module. It must be supplied, and gets passed back by the SetupProc
- * function in the dynamic case. In the static case, a reference to this
- * is compiled in, and this requires that the name of this DriverRec be
- * an upper-case version of the driver name.
- */
-
-DriverRec XGI = {
- XGI_CURRENT_VERSION,
- XGI_DRIVER_NAME,
- XGIIdentify,
-#ifdef XSERVER_LIBPCIACCESS
- NULL,
-#else
- XGIProbe,
-#endif
- XGIAvailableOptions,
- NULL,
- 0,
- NULL,
-
-#ifdef XSERVER_LIBPCIACCESS
- xgi_device_match,
- XGIPciProbe
-#endif
-};
-
-static SymTabRec XGIChipsets[] = {
- {PCI_CHIP_XGIXG40, "Volari V8_V5_V3XT"},
- {PCI_CHIP_XGIXG20, "Volari Z7"},
- {-1, NULL}
-};
-
-static PciChipsets XGIPciChipsets[] = {
- {PCI_CHIP_XGIXG40, PCI_CHIP_XGIXG40, RES_SHARED_VGA},
- {PCI_CHIP_XGIXG20, PCI_CHIP_XGIXG20, RES_SHARED_VGA},
- {-1, -1, RES_UNDEFINED}
-};
-
-static const char *xaaSymbols[] = {
- "XAACopyROP",
- "XAACreateInfoRec",
- "XAADestroyInfoRec",
- "XAAFillMono8x8PatternRects",
- "XAAPatternROP",
- "XAAHelpPatternROP",
- "XAAInit",
- NULL
-};
-
-static const char *vgahwSymbols[] = {
- "vgaHWFreeHWRec",
- "vgaHWGetHWRec",
- "vgaHWGetIOBase",
- "vgaHWGetIndex",
- "vgaHWInit",
- "vgaHWLock",
- "vgaHWMapMem",
- "vgaHWUnmapMem",
- "vgaHWProtect",
- "vgaHWRestore",
- "vgaHWSave",
- "vgaHWSaveScreen",
- "vgaHWUnlock",
- NULL
-};
-
-static const char *fbSymbols[] = {
- "fbPictureInit",
- "fbScreenInit",
- NULL
-};
-
-static const char *shadowSymbols[] = {
- "ShadowFBInit",
- NULL
-};
-
-static const char *ramdacSymbols[] = {
- "xf86CreateCursorInfoRec",
- "xf86DestroyCursorInfoRec",
- "xf86InitCursor",
- NULL
-};
-
-
-static const char *ddcSymbols[] = {
- "xf86PrintEDID",
- "xf86SetDDCproperties",
- "xf86InterpretEDID",
- NULL
-};
-
-
-/* static const char *i2cSymbols[] = {
- "xf86I2CBusInit",
- "xf86CreateI2CBusRec",
- NULL
-}; */
-
-static const char *int10Symbols[] = {
- "xf86FreeInt10",
- "xf86InitInt10",
- "xf86ExecX86int10",
- NULL
-};
-
-static const char *vbeSymbols[] = {
- "VBEExtendedInit",
- "vbeDoEDID",
- "vbeFree",
- "VBEGetVBEInfo",
- "VBEFreeVBEInfo",
- "VBEGetModeInfo",
- "VBEFreeModeInfo",
- "VBESaveRestore",
- "VBESetVBEMode",
- "VBEGetVBEMode",
- "VBESetDisplayStart",
- "VBESetGetLogicalScanlineLength",
- NULL
-};
-
-#ifdef XF86DRI
-static const char *drmSymbols[] = {
- "drmAddMap",
- "drmAgpAcquire",
- "drmAgpAlloc",
- "drmAgpBase",
- "drmAgpBind",
- "drmAgpEnable",
- "drmAgpFree",
- "drmAgpGetMode",
- "drmAgpRelease",
- "drmCtlInstHandler",
- "drmGetInterruptFromBusID",
- "drmXGIAgpInit",
- NULL
-};
-
-static const char *driSymbols[] = {
- "DRICloseScreen",
- "DRICreateInfoRec",
- "DRIDestroyInfoRec",
- "DRIFinishScreenInit",
- "DRIGetSAREAPrivate",
- "DRILock",
- "DRIQueryVersion",
- "DRIScreenInit",
- "DRIUnlock",
-#ifdef XGINEWDRI2
- "GlxSetVisualConfigs",
- "DRICreatePCIBusID",
-#endif
- NULL
-};
-#endif
-
-static MODULESETUPPROTO(xgiSetup);
-
-static XF86ModuleVersionInfo xgiVersRec = {
- XGI_DRIVER_NAME,
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
-#ifdef XORG_VERSION_CURRENT
- XORG_VERSION_CURRENT,
-#else
- XF86_VERSION_CURRENT,
-#endif
- PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
- ABI_CLASS_VIDEODRV, /* This is a video driver */
-#ifdef ABI_VIDEODRV_VERSION
- ABI_VIDEODRV_VERSION,
-#else
- 6,
-#endif
- MOD_CLASS_VIDEODRV,
- {0, 0, 0, 0}
-};
-
-XF86ModuleData xgiModuleData = { &xgiVersRec, xgiSetup, NULL };
-
-/*** static string ***/
-#ifdef XGIMERGED
-static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n";
-static const char *mergednocrt2 =
- "No CRT2 output selected or no bridge detected. %s.\n";
-static const char *mergeddisstr = "MergedFB mode disabled";
-static const char *modesforstr =
- "Modes for CRT%d: *********************************************\n";
-static const char *crtsetupstr =
- "------------------------ CRT%d setup -------------------------\n";
-#endif
-
-typedef struct
-{
- int width, height;
- float VRefresh, HSync, DCLK;
-} ModeTiming;
-
-static const ModeTiming establish_timing[] = {
- {800, 600, 60, 37.9, 40}, /* t1 D[0] */
- {800, 600, 56, 35.1, 36}, /* t1 D[1] */
- {640, 480, 75, 37.5, 31.5}, /* t1 D[2] */
- {640, 480, 72, 37.9, 31.5}, /* t1 D[3] */
- {-1, -1, -1, -1}, /* t1 D[4] 640x480@67Hz, ignore */
- {640, 480, 60, 31.5, 25.175}, /* t1 D[5] */
- {-1, -1, -1, -1}, /* t1 D[6] */
- {-1, -1, -1, -1}, /* t1 D[7] */
- {1280, 1024, 75, 80.0, 135}, /* t2 D[0] */
- {1024, 768, 75, 60.0, 78.75}, /* t2 D[1] */
- {1024, 768, 70, 56.5, 75}, /* t2 D[2] */
- {1024, 768, 60, 48.4, 65}, /* t2 D[3] */
- {-1, -1, -1, -1}, /* t2 D[4] 1024x768@87I, ignore */
- {-1, -1, -1, -1}, /* t2 D[5] 832x624@75Hz, ignore */
- {800, 600, 75, 46.9, 49.5}, /* t2 D[6] */
- {800, 600, 72, 48.1, 50} /* t2 D[7] */
-};
-
-static const ModeTiming StdTiming[] = {
- {640, 480, 60, 31.5, 25.175},
- {640, 480, 72, 37.9, 31.5},
- {640, 480, 75, 37.5, 31.5},
- {640, 480, 85, 43.3, 36.0},
-
- {800, 600, 56, 35.1, 36},
- {800, 600, 60, 37.9, 40},
- {800, 600, 72, 48.1, 50},
- {800, 600, 75, 46.9, 49.5},
- {800, 600, 85, 53.7, 56.25},
-
- {1024, 768, 43, 35.5, 44.9},
- {1024, 768, 60, 48.4, 65},
- {1024, 768, 70, 56.5, 75},
- {1024, 768, 75, 60, 78.75},
- {1024, 768, 85, 68.7, 94.5},
-
- {1152, 864, 75, 67.5, 108},
-
- {1280, 960, 60, 60, 108},
- {1280, 960, 85, 85.9, 148.5},
- {1280, 1024, 60, 64.0, 108},
- {1280, 1024, 75, 80, 135},
- {1280, 1024, 85, 91.1, 157.5},
-
- {1600, 1200, 60, 75, 162.0},
- {1600, 1200, 65, 81.3, 175.5},
- {1600, 1200, 70, 87.5, 189},
- {1600, 1200, 75, 93.8, 202},
- {1600, 1200, 85, 106.3, 229.5},
-
- {1792, 1344, 60, 83.64, 204.75},
- {1792, 1344, 75, 106.27, 261},
-
- {1856, 1392, 60, 86.33, 218.25},
- {1856, 1392, 75, 112.50, 288},
-
- {1920, 1440, 60, 90, 234},
- {1920, 1440, 75, 112.5, 297},
- {-1, -1, -1, -1, -1},
-};
-
-
-static void XGIDumpPalette(ScrnInfoPtr pScrn);
-#ifdef DEBUG
-static void XGIDumpSR(ScrnInfoPtr pScrn);
-static void XGIDumpCR(ScrnInfoPtr pScrn);
-static void XGIDumpGR(ScrnInfoPtr pScrn);
-static void XGIDumpPart1(ScrnInfoPtr pScrn);
-static void XGIDumpPart2(ScrnInfoPtr pScrn);
-static void XGIDumpPart3(ScrnInfoPtr pScrn);
-static void XGIDumpPart4(ScrnInfoPtr pScrn);
-static void XGIDumpMMIO(ScrnInfoPtr pScrn);
-#endif
-
-static int XGICalcVRate(DisplayModePtr mode);
-static unsigned char XGISearchCRT1Rate(ScrnInfoPtr pScrn,
- DisplayModePtr mode);
-static void xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
- unsigned char *reg2);
-static void xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1,
- unsigned char reg2);
-
-
-static pointer
-xgiSetup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- static Bool setupDone = FALSE;
-
- if (!setupDone) {
- setupDone = TRUE;
- xf86AddDriver(&XGI, module, HaveDriverFuncs);
- LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
- shadowSymbols, ramdacSymbols, ddcSymbols,
- vbeSymbols, int10Symbols,
-#ifdef XF86DRI
- drmSymbols, driSymbols,
-#endif
- NULL);
- return (pointer) TRUE;
- }
-
- if (errmaj)
- *errmaj = LDR_ONCEONLY;
- return NULL;
-}
-
-
-static XGIPtr
-XGIGetRec(ScrnInfoPtr pScrn)
-{
- /*
- * Allocate an XGIRec, and hook it into pScrn->driverPrivate.
- * pScrn->driverPrivate is initialised to NULL, so we can check if
- * the allocation has already been done.
- */
- if (pScrn->driverPrivate == NULL) {
- XGIPtr pXGI = xnfcalloc(sizeof(XGIRec), 1);
-
- /* Initialise it to 0 */
- memset(pXGI, 0, sizeof(XGIRec));
-
- pScrn->driverPrivate = pXGI;
- pXGI->pScrn = pScrn;
- }
-
- return (XGIPtr) pScrn->driverPrivate;
-}
-
-static void
-XGIFreeRec(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- XGIEntPtr pXGIEnt = NULL;
-
- /* Just to make sure... */
- if (!pXGI)
- return;
-
- pXGIEnt = ENTITY_PRIVATE(pXGI);
- if (pXGIEnt) {
- if (!IS_SECOND_HEAD(pXGI)) {
- /* Free memory only if we are first head; in case of an error
- * during init of the second head, the server will continue -
- * and we need the BIOS image and VB_DEVICE_INFO for the first
- * head.
- */
- if (pXGIEnt->BIOS)
- xfree(pXGIEnt->BIOS);
- pXGIEnt->BIOS = pXGI->BIOS = NULL;
- if (pXGIEnt->XGI_Pr)
- xfree(pXGIEnt->XGI_Pr);
- pXGIEnt->XGI_Pr = pXGI->XGI_Pr = NULL;
- if (pXGIEnt->RenderAccelArray)
- xfree(pXGIEnt->RenderAccelArray);
- pXGIEnt->RenderAccelArray = pXGI->RenderAccelArray = NULL;
- }
- else {
- pXGI->BIOS = NULL;
- pXGI->XGI_Pr = NULL;
- pXGI->RenderAccelArray = NULL;
- }
- }
- else {
- if (pXGI->BIOS)
- xfree(pXGI->BIOS);
- pXGI->BIOS = NULL;
- if (pXGI->XGI_Pr)
- xfree(pXGI->XGI_Pr);
- pXGI->XGI_Pr = NULL;
- if (pXGI->RenderAccelArray)
- xfree(pXGI->RenderAccelArray);
- pXGI->RenderAccelArray = NULL;
- }
-
-#ifdef XGIMERGED
- if (pXGI->MetaModes)
- xfree(pXGI->MetaModes);
- pXGI->MetaModes = NULL;
-
- if (pXGI->CRT1Modes) {
- if (pXGI->CRT1Modes != pScrn->modes) {
- if (pScrn->modes) {
- pScrn->currentMode = pScrn->modes;
- do {
- DisplayModePtr p = pScrn->currentMode->next;
- if (pScrn->currentMode->Private)
- xfree(pScrn->currentMode->Private);
- xfree(pScrn->currentMode);
- pScrn->currentMode = p;
- } while (pScrn->currentMode != pScrn->modes);
- }
- pScrn->currentMode = pXGI->CRT1CurrentMode;
- pScrn->modes = pXGI->CRT1Modes;
- pXGI->CRT1CurrentMode = NULL;
- pXGI->CRT1Modes = NULL;
- }
- }
-#endif
- if (pXGI->pVbe)
- vbeFree(pXGI->pVbe);
- pXGI->pVbe = NULL;
- if (pScrn->driverPrivate == NULL)
- return;
- xfree(pScrn->driverPrivate);
- pScrn->driverPrivate = NULL;
-}
-
-static void
-XGIDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
- int flags)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- BOOLEAN docrt1 = TRUE, docrt2 = TRUE;
- unsigned char sr1 = 0, cr17 = 0, cr63 = 0, sr11 = 0, pmreg = 0, sr7 = 0;
- unsigned char p1_13 = 0, p2_0 = 0, oldpmreg = 0;
- BOOLEAN backlight = TRUE;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
- "XGIDisplayPowerManagementSet(%d)\n", PowerManagementMode);
-
- if (IS_DUAL_HEAD(pXGI)) {
- if (IS_SECOND_HEAD(pXGI))
- docrt2 = FALSE;
- else
- docrt1 = FALSE;
- }
-
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-#endif
-
- switch (PowerManagementMode) {
-
- case DPMSModeOn: /* HSync: On, VSync: On */
- if (docrt1)
- pXGI->Blank = FALSE;
-
- sr1 = 0x00;
- cr17 = 0x80;
- pmreg = 0x00;
- cr63 = 0x00;
- sr7 = 0x10;
- sr11 = (pXGI->LCDon & 0x0C);
- p2_0 = 0x20;
- p1_13 = 0x00;
- backlight = TRUE;
- break;
-
- case DPMSModeSuspend: /* HSync: On, VSync: Off */
- if (docrt1)
- pXGI->Blank = TRUE;
-
- sr1 = 0x20;
- cr17 = 0x80;
- pmreg = 0x80;
- cr63 = 0x40;
- sr7 = 0x00;
- sr11 = 0x08;
- p2_0 = 0x40;
- p1_13 = 0x80;
- backlight = FALSE;
- break;
-
- case DPMSModeStandby: /* HSync: Off, VSync: On */
- if (docrt1)
- pXGI->Blank = TRUE;
-
- sr1 = 0x20;
- cr17 = 0x80;
- pmreg = 0x40;
- cr63 = 0x40;
- sr7 = 0x00;
- sr11 = 0x08;
- p2_0 = 0x80;
- p1_13 = 0x40;
- backlight = FALSE;
- break;
-
- case DPMSModeOff: /* HSync: Off, VSync: Off */
- if (docrt1)
- pXGI->Blank = TRUE;
-
- sr1 = 0x20;
- cr17 = 0x00;
- pmreg = 0xc0;
- cr63 = 0x40;
- sr7 = 0x00;
- sr11 = 0x08;
- p2_0 = 0xc0;
- p1_13 = 0xc0;
- backlight = FALSE;
- break;
-
- default:
- return;
- }
-
- if (docrt1) {
- /* Set/Clear "Display On" bit
- */
- setXGIIDXREG(XGISR, 0x01, ~0x20, sr1);
-
- if ((!(pXGI->VBFlags & CRT1_LCDA))
- || (pXGI->XGI_Pr->VBType & VB_XGI301C)) {
- inXGIIDXREG(XGISR, 0x1f, oldpmreg);
- if (!pXGI->CRT1off) {
- setXGIIDXREG(XGISR, 0x1f, 0x3f, pmreg);
- }
- }
- oldpmreg &= 0xc0;
- }
-
- if ((docrt1) && (pmreg != oldpmreg)
- && ((!(pXGI->VBFlags & CRT1_LCDA))
- || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
- outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
- usleep(10000);
- outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
- }
-
-}
-
-/* Mandatory */
-static void
-XGIIdentify(int flags)
-{
- xf86PrintChipsets(XGI_NAME, "driver for XGI chipsets", XGIChipsets);
- PDEBUG(ErrorF(" --- XGIIdentify \n"));
-}
-
-static void
-XGIErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
-{
- va_list ap;
- static const char *str =
- "**************************************************\n";
-
- va_start(ap, format);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " ERROR:\n");
- xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
- va_end(ap);
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- " END OF MESSAGE\n");
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
-}
-
-#ifdef XSERVER_LIBPCIACCESS
-static Bool XGIPciProbe(DriverPtr drv, int entity_num,
- struct pci_device *dev, intptr_t match_data)
-{
- ScrnInfoPtr pScrn;
-
-
- pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
- NULL, NULL, NULL, NULL, NULL);
- if (pScrn != NULL) {
- XGIPtr pXGI;
-
- /* Fill in what we can of the ScrnInfoRec */
- pScrn->driverVersion = XGI_CURRENT_VERSION;
- pScrn->driverName = XGI_DRIVER_NAME;
- pScrn->name = XGI_NAME;
- pScrn->Probe = NULL;
- pScrn->PreInit = XGIPreInit;
- pScrn->ScreenInit = XGIScreenInit;
- pScrn->SwitchMode = XGISwitchMode;
- pScrn->AdjustFrame = XGIAdjustFrame;
- pScrn->EnterVT = XGIEnterVT;
- pScrn->LeaveVT = XGILeaveVT;
- pScrn->FreeScreen = XGIFreeScreen;
- pScrn->ValidMode = XGIValidMode;
-
-
- pXGI = XGIGetRec(pScrn);
- if (pXGI == NULL) {
- return FALSE;
- }
-
- pXGI->PciInfo = dev;
- }
-
- return (pScrn != NULL);
-}
-
-#else
-
-/* Mandatory */
-static Bool
-XGIProbe(DriverPtr drv, int flags)
-{
- int i;
- GDevPtr *devSections;
- int *usedChips;
- int numDevSections;
- int numUsed;
- Bool foundScreen = FALSE;
-
- /*
- * The aim here is to find all cards that this driver can handle,
- * and for the ones not already claimed by another driver, claim the
- * slot, and allocate a ScrnInfoRec.
- *
- * This should be a minimal probe, and it should under no circumstances
- * change the state of the hardware. Because a device is found, don't
- * assume that it will be used. Don't do any initialisations other than
- * the required ScrnInfoRec initialisations. Don't allocate any new
- * data structures.
- *
- */
-
- /*
- * Next we check, if there has been a chipset override in the config file.
- * For this we must find out if there is an active device section which
- * is relevant, i.e., which has no driver specified or has THIS driver
- * specified.
- */
-
- if ((numDevSections =
- xf86MatchDevice(XGI_DRIVER_NAME, &devSections)) <= 0) {
- /*
- * There's no matching device section in the config file, so quit
- * now.
- */
- return FALSE;
- }
-
- PDEBUG(ErrorF(" --- XGIProbe \n"));
- /*
- * We need to probe the hardware first. We then need to see how this
- * fits in with what is given in the config file, and allow the config
- * file info to override any contradictions.
- */
-
- /*
- * All of the cards this driver supports are PCI, so the "probing" just
- * amounts to checking the PCI data that the server has already collected.
- */
- if (xf86GetPciVideoInfo() == NULL) {
- /*
- * We won't let anything in the config file override finding no
- * PCI video cards at all. This seems reasonable now, but we'll see.
- */
- return FALSE;
- }
-
- numUsed = xf86MatchPciInstances(XGI_NAME, PCI_VENDOR_XGI,
- XGIChipsets, XGIPciChipsets, devSections,
- numDevSections, drv, &usedChips);
-
- /* Free it since we don't need that list after this */
- xfree(devSections);
- if (numUsed <= 0)
- return FALSE;
-
- if (flags & PROBE_DETECT) {
- foundScreen = TRUE;
- }
- else
- for (i = 0; i < numUsed; i++) {
- ScrnInfoPtr pScrn;
-#ifdef XGIDUALHEAD
- EntityInfoPtr pEnt;
-#endif
-
- /* Allocate a ScrnInfoRec and claim the slot */
- pScrn = NULL;
-
- if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
- XGIPciChipsets, NULL, NULL,
- NULL, NULL, NULL))) {
- /* Fill in what we can of the ScrnInfoRec */
- pScrn->driverVersion = XGI_CURRENT_VERSION;
- pScrn->driverName = XGI_DRIVER_NAME;
- pScrn->name = XGI_NAME;
- pScrn->Probe = XGIProbe;
- pScrn->PreInit = XGIPreInit;
- pScrn->ScreenInit = XGIScreenInit;
- pScrn->SwitchMode = XGISwitchMode;
- pScrn->AdjustFrame = XGIAdjustFrame;
- pScrn->EnterVT = XGIEnterVT;
- pScrn->LeaveVT = XGILeaveVT;
- pScrn->FreeScreen = XGIFreeScreen;
- pScrn->ValidMode = XGIValidMode;
- foundScreen = TRUE;
- }
-#ifdef XGIDUALHEAD
- pEnt = xf86GetEntityInfo(usedChips[i]);
-
-#endif
- }
- xfree(usedChips);
-
- return foundScreen;
-}
-#endif
-
-
-/* Some helper functions for MergedFB mode */
-
-#ifdef XGIMERGED
-
-/* Copy and link two modes form mergedfb mode
- * (Code base taken from mga driver)
- * Copys mode i, links the result to dest, and returns it.
- * Links i and j in Private record.
- * If dest is NULL, return value is copy of i linked to itself.
- * For mergedfb auto-config, we only check the dimension
- * against virtualX/Y, if they were user-provided.
- */
-static DisplayModePtr
-XGICopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
- DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- DisplayModePtr mode;
- int dx = 0, dy = 0;
-
- if (!((mode = xalloc(sizeof(DisplayModeRec)))))
- return dest;
- memcpy(mode, i, sizeof(DisplayModeRec));
- if (!((mode->Private = xalloc(sizeof(XGIMergedDisplayModeRec))))) {
- xfree(mode);
- return dest;
- }
- ((XGIMergedDisplayModePtr) mode->Private)->CRT1 = i;
- ((XGIMergedDisplayModePtr) mode->Private)->CRT2 = j;
- ((XGIMergedDisplayModePtr) mode->Private)->CRT2Position = srel;
- mode->PrivSize = 0;
-
- switch (srel) {
- case xgiLeftOf:
- case xgiRightOf:
- if (!(pScrn->display->virtualX)) {
- dx = i->HDisplay + j->HDisplay;
- }
- else {
- dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
- }
- dx -= mode->HDisplay;
- if (!(pScrn->display->virtualY)) {
- dy = max(i->VDisplay, j->VDisplay);
- }
- else {
- dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
- }
- dy -= mode->VDisplay;
- break;
- case xgiAbove:
- case xgiBelow:
- if (!(pScrn->display->virtualY)) {
- dy = i->VDisplay + j->VDisplay;
- }
- else {
- dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
- }
- dy -= mode->VDisplay;
- if (!(pScrn->display->virtualX)) {
- dx = max(i->HDisplay, j->HDisplay);
- }
- else {
- dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
- }
- dx -= mode->HDisplay;
- break;
- case xgiClone:
- if (!(pScrn->display->virtualX)) {
- dx = max(i->HDisplay, j->HDisplay);
- }
- else {
- dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
- }
- dx -= mode->HDisplay;
- if (!(pScrn->display->virtualY)) {
- dy = max(i->VDisplay, j->VDisplay);
- }
- else {
- dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
- }
- dy -= mode->VDisplay;
- break;
- }
- mode->HDisplay += dx;
- mode->HSyncStart += dx;
- mode->HSyncEnd += dx;
- mode->HTotal += dx;
- mode->VDisplay += dy;
- mode->VSyncStart += dy;
- mode->VSyncEnd += dy;
- mode->VTotal += dy;
- mode->Clock = 0;
-
- if (((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) >
- pXGI->maxxfbmem) || (mode->HDisplay > 4088)
- || (mode->VDisplay > 4096)) {
-
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Skipped %dx%d, not enough video RAM or beyond hardware specs\n",
- mode->HDisplay, mode->VDisplay);
- xfree(mode->Private);
- xfree(mode);
-
- return dest;
- }
-
-#ifdef XGIXINERAMA
- if (srel != xgiClone) {
- pXGI->AtLeastOneNonClone = TRUE;
- }
-#endif
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Merged %dx%d and %dx%d to %dx%d%s\n",
- i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay,
- mode->HDisplay, mode->VDisplay,
- (srel == xgiClone) ? " (Clone)" : "");
-
- mode->next = mode;
- mode->prev = mode;
-
- if (dest) {
- mode->next = dest->next; /* Insert node after "dest" */
- dest->next->prev = mode;
- mode->prev = dest;
- dest->next = mode;
- }
-
- return mode;
-}
-
-/* Helper function to find a mode from a given name
- * (Code base taken from mga driver)
- */
-static DisplayModePtr
-XGIGetModeFromName(char *str, DisplayModePtr i)
-{
- DisplayModePtr c = i;
- if (!i)
- return NULL;
- do {
- if (strcmp(str, c->name) == 0)
- return c;
- c = c->next;
- } while (c != i);
- return NULL;
-}
-
-static DisplayModePtr
-XGIFindWidestTallestMode(DisplayModePtr i, Bool tallest)
-{
- DisplayModePtr c = i, d = NULL;
- int max = 0;
- if (!i)
- return NULL;
- do {
- if (tallest) {
- if (c->VDisplay > max) {
- max = c->VDisplay;
- d = c;
- }
- }
- else {
- if (c->HDisplay > max) {
- max = c->HDisplay;
- d = c;
- }
- }
- c = c->next;
- } while (c != i);
- return d;
-}
-
-static DisplayModePtr
-XGIGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
- DisplayModePtr i, DisplayModePtr j,
- XGIScrn2Rel srel)
-{
-#ifdef XGIXINERAMA
- XGIPtr pXGI = XGIPTR(pScrn);
-#endif
- DisplayModePtr mode1 = NULL;
- DisplayModePtr mode2 = NULL;
- DisplayModePtr result = NULL;
-
-#ifdef XGIXINERAMA
- pXGI->AtLeastOneNonClone = FALSE;
-#endif
-
- switch (srel) {
- case xgiLeftOf:
- case xgiRightOf:
- mode1 = XGIFindWidestTallestMode(i, FALSE);
- mode2 = XGIFindWidestTallestMode(j, FALSE);
- break;
- case xgiAbove:
- case xgiBelow:
- mode1 = XGIFindWidestTallestMode(i, TRUE);
- mode2 = XGIFindWidestTallestMode(j, TRUE);
- break;
- case xgiClone:
- mode1 = i;
- mode2 = j;
- }
-
- if (mode1 && mode2) {
- return (XGICopyModeNLink(pScrn, result, mode1, mode2, srel));
- }
- else {
- return NULL;
- }
-}
-
-/* Generate the merged-fb mode modelist from metamodes
- * (Code base taken from mga driver)
- */
-static DisplayModePtr
-XGIGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char *str,
- DisplayModePtr i, DisplayModePtr j,
- XGIScrn2Rel srel)
-{
-#ifdef XGIXINERAMA
- XGIPtr pXGI = XGIPTR(pScrn);
-#endif
- char *strmode = str;
- char modename[256];
- Bool gotdash = FALSE;
- XGIScrn2Rel sr;
- DisplayModePtr mode1 = NULL;
- DisplayModePtr mode2 = NULL;
- DisplayModePtr result = NULL;
-
-#ifdef XGIXINERAMA
- pXGI->AtLeastOneNonClone = FALSE;
-#endif
-
- do {
- switch (*str) {
- case 0:
- case '-':
- case ' ':
- if ((strmode != str)) {
-
- strncpy(modename, strmode, str - strmode);
- modename[str - strmode] = 0;
-
- if (gotdash) {
- if (mode1 == NULL)
- return NULL;
- mode2 = XGIGetModeFromName(modename, j);
- if (!mode2) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode \"%s\" is not a supported mode for CRT2\n",
- modename);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Skipping metamode \"%s-%s\".\n",
- mode1->name, modename);
- mode1 = NULL;
- }
- }
- else {
- mode1 = XGIGetModeFromName(modename, i);
- if (!mode1) {
- char *tmps = str;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode \"%s\" is not a supported mode for CRT1\n",
- modename);
- gotdash = FALSE;
- while (*tmps == ' ')
- tmps++;
- if (*tmps == '-') { /* skip the next mode */
- tmps++;
- while ((*tmps == ' ') && (*tmps != 0))
- tmps++; /* skip spaces */
- while ((*tmps != ' ') && (*tmps != '-')
- && (*tmps != 0))
- tmps++; /* skip modename */
- strncpy(modename, strmode, tmps - strmode);
- modename[tmps - strmode] = 0;
- str = tmps - 1;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Skipping metamode \"%s\".\n", modename);
- mode1 = NULL;
- }
- }
- gotdash = FALSE;
- }
- strmode = str + 1;
- gotdash |= (*str == '-');
-
- if (*str != 0)
- break;
- /* Fall through otherwise */
-
- default:
- if (!gotdash && mode1) {
- sr = srel;
- if (!mode2) {
- mode2 = XGIGetModeFromName(mode1->name, j);
- sr = xgiClone;
- }
- if (!mode2) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Mode: \"%s\" is not a supported mode for CRT2\n",
- mode1->name);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Skipping metamode \"%s\".\n", modename);
- mode1 = NULL;
- }
- else {
- result =
- XGICopyModeNLink(pScrn, result, mode1, mode2, sr);
- mode1 = NULL;
- mode2 = NULL;
- }
- }
- break;
-
- }
-
- } while (*(str++) != 0);
-
- return result;
-}
-
-static DisplayModePtr
-XGIGenerateModeList(ScrnInfoPtr pScrn, char *str,
- DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
-{
- if (str != NULL) {
- return (XGIGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No MetaModes given, linking %s modes by default\n",
- (srel == xgiClone) ? "first" :
- (((srel == xgiLeftOf)
- || (srel == xgiRightOf)) ? "widest" : "tallest"));
- return (XGIGenerateModeListFromLargestModes(pScrn, i, j, srel));
- }
-}
-
-static void
-XGIRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
-{
- DisplayModePtr mode, bmode;
- int max;
- static const char *str = "MergedFB: Virtual %s %d\n";
-
- if (!(pScrn->display->virtualX)) {
- mode = bmode = pScrn->modes;
- max = 0;
- do {
- if (mode->HDisplay > max)
- max = mode->HDisplay;
- mode = mode->next;
- } while (mode != bmode);
- pScrn->virtualX = max;
- pScrn->displayWidth = max;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
- }
- if (!(pScrn->display->virtualY)) {
- mode = bmode = pScrn->modes;
- max = 0;
- do {
- if (mode->VDisplay > max)
- max = mode->VDisplay;
- mode = mode->next;
- } while (mode != bmode);
- pScrn->virtualY = max;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
- }
-}
-
-static void
-XGIMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, XGIScrn2Rel srel)
-{
- XGIPtr pXGI = XGIPTR(pScrn1);
- MessageType from = X_DEFAULT;
- xf86MonPtr DDC1 = (xf86MonPtr) (pScrn1->monitor->DDC);
- xf86MonPtr DDC2 = (xf86MonPtr) (pScrn2->monitor->DDC);
- int ddcWidthmm = 0, ddcHeightmm = 0;
- const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
-
- /* This sets the DPI for MergedFB mode. The problem is that
- * this can never be exact, because the output devices may
- * have different dimensions. This function tries to compromise
- * through a few assumptions, and it just calculates an average DPI
- * value for both monitors.
- */
-
- /* Given DisplaySize should regard BOTH monitors */
- pScrn1->widthmm = pScrn1->monitor->widthmm;
- pScrn1->heightmm = pScrn1->monitor->heightmm;
-
- /* Get DDC display size; if only either CRT1 or CRT2 provided these,
- * assume equal dimensions for both, otherwise add dimensions
- */
- if ((DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
- (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0))) {
- ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
- ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
- switch (srel) {
- case xgiLeftOf:
- case xgiRightOf:
- ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
- break;
- case xgiAbove:
- case xgiBelow:
- ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
- default:
- break;
- }
- }
- else if (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
- ddcWidthmm = DDC1->features.hsize * 10;
- ddcHeightmm = DDC1->features.vsize * 10;
- switch (srel) {
- case xgiLeftOf:
- case xgiRightOf:
- ddcWidthmm *= 2;
- break;
- case xgiAbove:
- case xgiBelow:
- ddcHeightmm *= 2;
- default:
- break;
- }
- }
- else if (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) {
- ddcWidthmm = DDC2->features.hsize * 10;
- ddcHeightmm = DDC2->features.vsize * 10;
- switch (srel) {
- case xgiLeftOf:
- case xgiRightOf:
- ddcWidthmm *= 2;
- break;
- case xgiAbove:
- case xgiBelow:
- ddcHeightmm *= 2;
- default:
- break;
- }
- }
-
- if (monitorResolution > 0) {
-
- /* Set command line given values (overrules given options) */
- pScrn1->xDpi = monitorResolution;
- pScrn1->yDpi = monitorResolution;
- from = X_CMDLINE;
-
- }
- else if (pXGI->MergedFBXDPI) {
-
- /* Set option-wise given values (overrule DisplaySize) */
- pScrn1->xDpi = pXGI->MergedFBXDPI;
- pScrn1->yDpi = pXGI->MergedFBYDPI;
- from = X_CONFIG;
-
- }
- else if (pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
-
- /* Set values calculated from given DisplaySize */
- from = X_CONFIG;
- if (pScrn1->widthmm > 0) {
- pScrn1->xDpi =
- (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
- }
- if (pScrn1->heightmm > 0) {
- pScrn1->yDpi =
- (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
- }
- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm,
- pScrn1->heightmm);
-
- }
- else if (ddcWidthmm && ddcHeightmm) {
-
- /* Set values from DDC-provided display size */
- from = X_PROBED;
- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
- pScrn1->widthmm = ddcWidthmm;
- pScrn1->heightmm = ddcHeightmm;
- if (pScrn1->widthmm > 0) {
- pScrn1->xDpi =
- (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
- }
- if (pScrn1->heightmm > 0) {
- pScrn1->yDpi =
- (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
- }
-
- }
- else {
-
- pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
-
- }
-
- /* Sanity check */
- if (pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
- pScrn1->yDpi = pScrn1->xDpi;
- if (pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
- pScrn1->xDpi = pScrn1->yDpi;
-
- pScrn2->xDpi = pScrn1->xDpi;
- pScrn2->yDpi = pScrn1->yDpi;
-
- xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
- pScrn1->xDpi, pScrn1->yDpi);
-}
-
-static void
-XGIFreeCRT2Structs(XGIPtr pXGI)
-{
- if (pXGI->CRT2pScrn) {
- if (pXGI->CRT2pScrn->modes) {
- while (pXGI->CRT2pScrn->modes)
- xf86DeleteMode(&pXGI->CRT2pScrn->modes,
- pXGI->CRT2pScrn->modes);
- }
- if (pXGI->CRT2pScrn->monitor) {
- if (pXGI->CRT2pScrn->monitor->Modes) {
- while (pXGI->CRT2pScrn->monitor->Modes)
- xf86DeleteMode(&pXGI->CRT2pScrn->monitor->Modes,
- pXGI->CRT2pScrn->monitor->Modes);
- }
- if (pXGI->CRT2pScrn->monitor->DDC)
- xfree(pXGI->CRT2pScrn->monitor->DDC);
- xfree(pXGI->CRT2pScrn->monitor);
- }
- xfree(pXGI->CRT2pScrn);
- pXGI->CRT2pScrn = NULL;
- }
-}
-
-#endif /* End of MergedFB helpers */
-
-static xf86MonPtr
-XGIInternalDDC(ScrnInfoPtr pScrn, int crtno)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned char buffer[256];
-
- int RealOff;
- unsigned char *page;
-
- xf86MonPtr pMonitor = NULL;
- xf86Int10InfoPtr pInt = NULL; /* Our int10 */
-
- static char *crtno_means_str[] = {
- "CRT1", "DVI", "CRT2"
- };
-
- if (crtno > 2 || crtno < 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "XGIInternalDDC(): Can not get EDID for crtno = %d,abort.\n",
- crtno);
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "XGIInternalDDC(): getting EDID for %s.\n",
- crtno_means_str[crtno]);
- }
-
- if (xf86LoadSubModule(pScrn, "int10")) {
- xf86LoaderReqSymLists(int10Symbols, NULL);
- pInt = xf86InitInt10(pXGI->pEnt->index);
- if (pInt == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "XGIInternalDDC(): Can not initialize pInt, abort.\n");
- return NULL;
- }
-
- page = xf86Int10AllocPages(pInt, 1, &RealOff);
- if (page == NULL) {
- xf86FreeInt10(pInt);
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "XGIInternalDDC(): Can not initialize real mode buffer, abort.\n");
- return NULL;
- }
- }
-
- if (pInt) {
- pInt->ax = 0x4f15; /* VESA DDC supporting */
- pInt->bx = 1; /* get EDID */
- pInt->cx = crtno; /* port 0 or 1 for CRT 1 or 2 */
- pInt->es = SEG_ADDR(RealOff);
- pInt->di = SEG_OFF(RealOff);
- pInt->num = 0x10;
- xf86ExecX86int10(pInt);
-
- PDEBUG3(ErrorF
- ("ax = %04X bx = %04X cx = %04X dx = %04X si = %04X di = %04X es = %04X\n",
- pInt->ax, pInt->bx, pInt->cx, pInt->dx, pInt->si, pInt->di,
- pInt->es));
-
- if ((pInt->ax & 0xff00) == 0) {
- int i;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "XGIInternalDDC(): VESA get DDC success for CRT %d.\n",
- crtno + 1);
-
- for (i = 0; i < 128; i++) {
- buffer[i] = page[i];
- }
-
-#ifdef DEBUG5
- for (i = 0; i < 128; i += 16) {
- unsigned j;
- ErrorF("EDID[%02X]", i);
- for (j = 0; j < 16; j++) {
- ErrorF(" %02X", buffer[i + j]);
- }
- ErrorF("\n");
- }
-#endif /* DEBUG3 */
-
- xf86LoaderReqSymLists(ddcSymbols, NULL);
- pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer);
-
- if (pMonitor == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "CRT%d DDC EDID corrupt\n", crtno + 1);
- return (NULL);
- }
- xf86UnloadSubModule("ddc");
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "XGIInternalDDC(): VESA get DDC fail for CRT %d.\n",
- crtno + 1);
- }
-
- xf86Int10FreePages(pInt, page, 1);
- xf86FreeInt10(pInt);
- }
- return pMonitor;
-}
-
-/* static xf86MonPtr
-XGIDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- if(IS_DUAL_HEAD(pXGI))
- {
- if(IS_SECOND_HEAD(pXGI))
- {
- *crtnum = 1;
- return(XGIInternalDDC(pScrn, 0));
- }
- else
- {
- *crtnum = 2;
- return(XGIInternalDDC(pScrn, 1));
- }
- }
- else if(pXGI->CRT1off)
- {
- *crtnum = 2;
- return(XGIInternalDDC(pScrn, 1));
- }
- else
- {
- *crtnum = 1;
- return(XGIInternalDDC(pScrn, 0));
- }
-} */
-
-
-#ifdef DEBUG5
-static void
-XGIDumpMonitorInfo(xf86MonPtr pMonitor)
-{
- struct detailed_timings *pd_timings;
- Uchar *pserial;
- Uchar *pascii_data;
- Uchar *pname;
- struct monitor_ranges *pranges;
- struct std_timings *pstd_t;
- struct whitePoints *pwp;
- int i, j;
-
- if (pMonitor == NULL) {
- ErrorF("Monitor is NULL");
- return;
- }
-
- ErrorF("pMonitor->scrnIndex = %d\n", pMonitor->scrnIndex);
- ErrorF
- ("vendor = %c%c%c%c, prod_id = %x serial = %d week = %d year = %d\n",
- pMonitor->vendor.name[0], pMonitor->vendor.name[1],
- pMonitor->vendor.name[2], pMonitor->vendor.name[3],
- pMonitor->vendor.prod_id, pMonitor->vendor.serial,
- pMonitor->vendor.week, pMonitor->vendor.year);
-
- ErrorF("ver = %d %d\n", pMonitor->ver.version, pMonitor->ver.revision);
- ErrorF("intput type = %d voltage = %d setup = %d sync = %d\n",
- pMonitor->features.input_type,
- pMonitor->features.input_voltage,
- pMonitor->features.input_setup, pMonitor->features.input_sync);
- ErrorF("hsize = %d vsize = %d gamma=%8.3f\n",
- pMonitor->features.hsize,
- pMonitor->features.vsize, pMonitor->features.gamma);
-
- ErrorF("dpms = %d display_type = %d msc = %d\n",
- pMonitor->features.dpms,
- pMonitor->features.display_type, pMonitor->features.msc);
- ErrorF
- ("redx,redy,greenx,greeny,bluex,bluey,whitex,whitey = %8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f\n",
- pMonitor->features.redx, pMonitor->features.redy,
- pMonitor->features.greenx, pMonitor->features.greeny,
- pMonitor->features.bluex, pMonitor->features.bluey,
- pMonitor->features.whitex, pMonitor->features.whitey);
-
- ErrorF("established_timings = (t1)%d%d%d%d%d%d%d%d",
- (pMonitor->timings1.t1 >> 7) & 1,
- (pMonitor->timings1.t1 >> 6) & 1,
- (pMonitor->timings1.t1 >> 5) & 1,
- (pMonitor->timings1.t1 >> 4) & 1,
- (pMonitor->timings1.t1 >> 3) & 1,
- (pMonitor->timings1.t1 >> 2) & 1,
- (pMonitor->timings1.t1 >> 1) & 1,
- (pMonitor->timings1.t1 >> 0) & 1);
- ErrorF("(t2) %d%d%d%d%d%d%d%d",
- (pMonitor->timings1.t1 >> 7) & 1,
- (pMonitor->timings1.t1 >> 6) & 1,
- (pMonitor->timings1.t1 >> 5) & 1,
- (pMonitor->timings1.t1 >> 4) & 1,
- (pMonitor->timings1.t1 >> 3) & 1,
- (pMonitor->timings1.t1 >> 2) & 1,
- (pMonitor->timings1.t1 >> 1) & 1,
- (pMonitor->timings1.t1 >> 0) & 1);
- ErrorF("(t_manu)%d%d%d%d%d%d%d%d\n",
- (pMonitor->timings1.t_manu >> 7) & 1,
- (pMonitor->timings1.t_manu >> 6) & 1,
- (pMonitor->timings1.t_manu >> 5) & 1,
- (pMonitor->timings1.t_manu >> 4) & 1,
- (pMonitor->timings1.t_manu >> 3) & 1,
- (pMonitor->timings1.t_manu >> 2) & 1,
- (pMonitor->timings1.t_manu >> 1) & 1,
- (pMonitor->timings1.t_manu >> 0) & 1);
-
- for (i = 0; i < 7; i++) {
- ErrorF
- ("std timing %d: hsize = %d, vsize = %d, refresh = %d, id = %d\n",
- i, pMonitor->timings2[i].hsize, pMonitor->timings2[i].vsize,
- pMonitor->timings2[i].refresh, pMonitor->timings2[i].id);
- }
-
- for (i = 0; i < 4; i++) {
- ErrorF("Detail timing section %d\n", i);
- ErrorF("type = %x\n", pMonitor->det_mon[i].type);
- switch (pMonitor->det_mon[i].type) {
- case DS_SERIAL:
- ErrorF("type = %x DS_SERIAL = %x\n", pMonitor->det_mon[i].type,
- DS_SERIAL);
- break;
- case DS_ASCII_STR:
- ErrorF("type = %x DS_ASCII_STR = %x\n", pMonitor->det_mon[i].type,
- DS_ASCII_STR);
- break;
- case DS_NAME:
- ErrorF("type = %x DS_NAME = %x\n", pMonitor->det_mon[i].type,
- DS_NAME);
- break;
- case DS_RANGES:
- ErrorF("type = %x DS_RANGES = %x\n", pMonitor->det_mon[i].type,
- DS_RANGES);
- break;
- case DS_WHITE_P:
- ErrorF("type = %x DS_WHITE_P = %x\n", pMonitor->det_mon[i].type,
- DS_WHITE_P);
- break;
- case DS_STD_TIMINGS:
- ErrorF("type = %x DS_STD_TIMINGS = %x\n",
- pMonitor->det_mon[i].type, DS_STD_TIMINGS);
- break;
- }
- switch (pMonitor->det_mon[i].type) {
- case DS_SERIAL:
- pserial = pMonitor->det_mon[i].section.serial;
- ErrorF("seial: ");
- for (j = 0; j < 13; j++) {
- ErrorF("%02X", pserial[j]);
- }
- ErrorF("\n");
- break;
- case DS_ASCII_STR:
- pascii_data = pMonitor->det_mon[i].section.ascii_data;
- ErrorF("ascii: ");
- for (j = 0; j < 13; j++) {
- ErrorF("%c", pascii_data[j]);
- }
- ErrorF("\n");
- break;
- case DS_NAME:
- pname = pMonitor->det_mon[i].section.name;
- ErrorF("name: ");
- for (j = 0; j < 13; j++) {
- ErrorF("%c", pname[j]);
- }
- ErrorF("\n");
- break;
- case DS_RANGES:
- pranges = &(pMonitor->det_mon[i].section.ranges);
- ErrorF
- ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
- pranges->min_v, pranges->max_v, pranges->min_h,
- pranges->max_h, pranges->max_clock);
- break;
- case DS_WHITE_P:
- pwp = pMonitor->det_mon[i].section.wp;
- for (j = 0; j < 2; j++) {
- ErrorF
- ("wp[%d].index = %d white_x = %8.3f white_y = %8.3f white_gamma = %8.3f\n",
- j, pwp[j].index, pwp[j].white_x, pwp[j].white_y,
- pwp[j].white_gamma);
- }
- break;
- case DS_STD_TIMINGS:
- pstd_t = pMonitor->det_mon[i].section.std_t;
- for (j = 0; j < 5; j++) {
- ErrorF
- ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
- j, pstd_t[j].hsize, pstd_t[j].vsize, pstd_t[j].refresh,
- pstd_t[j].id);
- }
- break;
- case DT:
-
- pd_timings = &pMonitor->det_mon[i].section.d_timings;
- ErrorF("Detail Timing Descriptor\n");
- ErrorF("clock = %d\n", pd_timings->clock);
- ErrorF("h_active = %d\n", pd_timings->h_active);
- ErrorF("h_blanking = %d\n", pd_timings->h_blanking);
- ErrorF("v_active = %d\n", pd_timings->v_active);
- ErrorF("v_blanking = %d\n", pd_timings->v_blanking);
- ErrorF("h_sync_off = %d\n", pd_timings->h_sync_off);
- ErrorF("h_sync_width = %d\n", pd_timings->h_sync_width);
- ErrorF("v_sync_off = %d\n", pd_timings->v_sync_off);
- ErrorF("v_sync_width = %d\n", pd_timings->v_sync_width);
- ErrorF("h_size = %d\n", pd_timings->h_size);
- ErrorF("v_size = %d\n", pd_timings->v_size);
- ErrorF("h_border = %d\n", pd_timings->h_border);
- ErrorF("v_border = %d\n", pd_timings->v_border);
- ErrorF("interlaced = %d stereo = %x sync = %x misc = %x\n",
- pd_timings->interlaced,
- pd_timings->stereo, pd_timings->sync, pd_timings->misc);
- break;
- }
- }
-
- for (i = 0; i < 128; i += 16) {
- ErrorF("rawData[%02X]:", i);
- for (j = 0; j < 16; j++) {
- ErrorF(" %02X", pMonitor->rawData[i + j]);
- }
- ErrorF("\n");
- }
-}
-#endif
-
-static void
-XGIGetMonitorRangeByDDC(MonitorRangePtr range, xf86MonPtr pMonitor)
-{
- int i, j;
- float VF, HF;
- struct detailed_timings *pd_timings;
- struct monitor_ranges *pranges;
- struct std_timings *pstd_t;
-
- if ((range == NULL) || (pMonitor == NULL)) {
- return; /* ignore */
- }
-
- PDEBUG5(ErrorF
- ("establish timing t1 = %02x t2=%02x\n", pMonitor->timings1.t1,
- pMonitor->timings1.t2));
- for (i = 0, j = 0; i < 8; i++, j++) {
- if (establish_timing[j].width == -1) {
- continue;
- }
-
- if (pMonitor->timings1.t1 & (1 << i)) {
- PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
- establish_timing[j].width,
- establish_timing[j].height,
- establish_timing[j].VRefresh,
- establish_timing[j].HSync));
-
- if (range->loH > establish_timing[j].HSync) {
- range->loH = establish_timing[j].HSync;
- }
-
- if (range->hiH < establish_timing[j].HSync) {
- range->hiH = establish_timing[j].HSync;
- }
-
- if (range->loV > establish_timing[j].VRefresh) {
- range->loV = establish_timing[j].VRefresh;
- }
-
- if (range->hiV < establish_timing[j].VRefresh) {
- range->hiV = establish_timing[j].VRefresh;
- }
- }
- }
- PDEBUG5(ErrorF
- ("check establish timing t1:range ( %8.3f %8.3f %8.3f %8.3f )\n",
- range->loH, range->loV, range->hiH, range->hiV));
-
- for (i = 0; i < 8; i++, j++) {
- if (establish_timing[j].width == -1) {
- continue;
- }
-
- if (pMonitor->timings1.t2 & (1 << i)) {
- PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
- establish_timing[j].width,
- establish_timing[j].height,
- establish_timing[j].VRefresh,
- establish_timing[j].HSync));
-
- if (range->loH > establish_timing[j].HSync) {
- range->loH = establish_timing[j].HSync;
- }
-
- if (range->hiH < establish_timing[j].HSync) {
- range->hiH = establish_timing[j].HSync;
- }
-
- if (range->loV > establish_timing[j].VRefresh) {
- range->loV = establish_timing[j].VRefresh;
- }
-
- if (range->hiV < establish_timing[j].VRefresh) {
- range->hiV = establish_timing[j].VRefresh;
- }
- }
- }
- PDEBUG5(ErrorF
- ("check establish timing t2:range ( %8.3f %8.3f %8.3f %8.3f )\n",
- range->loH, range->loV, range->hiH, range->hiV));
-
- for (i = 0; i < 8; i++) {
- for (j = 0; StdTiming[j].width != -1; j++) {
- if ((StdTiming[j].width == pMonitor->timings2[i].hsize) &&
- (StdTiming[j].height == pMonitor->timings2[i].vsize) &&
- (StdTiming[j].VRefresh == pMonitor->timings2[i].refresh)) {
- PDEBUG5(ErrorF("pMonitor->timings2[%d]= %d %d %d %d\n",
- i,
- pMonitor->timings2[i].hsize,
- pMonitor->timings2[i].vsize,
- pMonitor->timings2[i].refresh,
- pMonitor->timings2[i].id));
- HF = StdTiming[j].HSync;
- VF = StdTiming[j].VRefresh;
- if (range->loH > HF)
- range->loH = HF;
- if (range->loV > VF)
- range->loV = VF;
- if (range->hiH < HF)
- range->hiH = HF;
- if (range->hiV < VF)
- range->hiV = VF;
- break;
- }
- }
- }
- PDEBUG5(ErrorF
- ("check standard timing :range ( %8.3f %8.3f %8.3f %8.3f )\n",
- range->loH, range->loV, range->hiH, range->hiV));
-
- for (i = 0; i < 4; i++) {
- switch (pMonitor->det_mon[i].type) {
- case DS_RANGES:
- pranges = &(pMonitor->det_mon[i].section.ranges);
- PDEBUG5(ErrorF
- ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
- pranges->min_v, pranges->max_v, pranges->min_h,
- pranges->max_h, pranges->max_clock));
-
- if (range->loH > pranges->min_h)
- range->loH = pranges->min_h;
- if (range->loV > pranges->min_v)
- range->loV = pranges->min_v;
- if (range->hiH < pranges->max_h)
- range->hiH = pranges->max_h;
- if (range->hiV < pranges->max_v)
- range->hiV = pranges->max_v;
- PDEBUG5(ErrorF
- ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
- range->loV, range->hiH, range->hiV));
- break;
-
- case DS_STD_TIMINGS:
- pstd_t = pMonitor->det_mon[i].section.std_t;
- for (j = 0; j < 5; j++) {
- int k;
- PDEBUG5(ErrorF
- ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
- j, pstd_t[j].hsize, pstd_t[j].vsize,
- pstd_t[j].refresh, pstd_t[j].id));
- for (k = 0; StdTiming[k].width != -1; k++) {
- if ((StdTiming[k].width == pstd_t[j].hsize) &&
- (StdTiming[k].height == pstd_t[j].vsize) &&
- (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
- if (range->loH > StdTiming[k].HSync)
- range->loH = StdTiming[k].HSync;
- if (range->hiH < StdTiming[k].HSync)
- range->hiH = StdTiming[k].HSync;
- if (range->loV > StdTiming[k].VRefresh)
- range->loV = StdTiming[k].VRefresh;
- if (range->hiV < StdTiming[k].VRefresh)
- range->hiV = StdTiming[k].VRefresh;
- break;
- }
-
- }
- }
- break;
-
- case DT:
-
- pd_timings = &pMonitor->det_mon[i].section.d_timings;
-
- HF = pd_timings->clock / (pd_timings->h_active +
- pd_timings->h_blanking);
- VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
- HF /= 1000; /* into KHz Domain */
- if (range->loH > HF)
- range->loH = HF;
- if (range->hiH < HF)
- range->hiH = HF;
- if (range->loV > VF)
- range->loV = VF;
- if (range->hiV < VF)
- range->hiV = VF;
- PDEBUG(ErrorF
- ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
- HF, VF, range->loH, range->loV, range->hiH, range->hiV));
- break;
- }
- }
- PDEBUG5(ErrorF
- ("Done range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, range->loV,
- range->hiH, range->hiV));
-
-}
-
-static void
-XGISyncDDCMonitorRange(MonPtr monitor, MonitorRangePtr range)
-{
- int i;
- if ((monitor == NULL) || (range == NULL)) {
- return;
- }
-
- for (i = 0; i < monitor->nHsync; i++) {
- monitor->hsync[i].lo = range->loH;
- monitor->hsync[i].hi = range->hiH;
- }
-
- for (i = 0; i < monitor->nVrefresh; i++) {
- monitor->vrefresh[i].lo = range->loV;
- monitor->vrefresh[i].hi = range->hiV;
- }
-}
-
-static void
-XGIDDCPreInit(ScrnInfoPtr pScrn)
-{
-
- XGIPtr pXGI = XGIPTR(pScrn);
- xf86MonPtr pMonitor = NULL;
- xf86MonPtr pMonitorDVI = NULL;
- Bool didddc2;
-
- static const char *ddcsstr =
- "CRT%d DDC monitor info: ************************************\n";
- static const char *ddcestr =
- "End of CRT%d DDC monitor info ******************************\n";
-
- /* Now for something completely different: DDC.
- * For 300 and 315/330 series, we provide our
- * own functions (in order to probe CRT2 as well)
- * If these fail, use the VBE.
- * All other chipsets will use VBE. No need to re-invent
- * the wheel there.
- */
-
- pXGI->pVbe = NULL;
- didddc2 = FALSE;
-
- /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */
- if (IS_DUAL_HEAD(pXGI) && (!didddc2) && !IS_SECOND_HEAD(pXGI))
- didddc2 = TRUE;
-
- if (!didddc2) {
- /* If CRT1 is off or LCDA, skip DDC via VBE */
- if ((pXGI->CRT1off) || (pXGI->VBFlags & CRT1_LCDA))
- didddc2 = TRUE;
- }
-
- /* Now (re-)load and initialize the DDC module */
- if (!didddc2) {
-
- if (xf86LoadSubModule(pScrn, "ddc")) {
-
- xf86LoaderReqSymLists(ddcSymbols, NULL);
-
- pMonitor = XGIInternalDDC(pScrn, 0);
- if (pMonitor == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Could not retrieve DDC data\n");
- }
-
- if (pXGI->xgi_HwDevExt.jChipType == XG21) {
- PDEBUG(ErrorF("Getting XG21 DVI EDID...\n"));
- pMonitorDVI = XGIInternalDDC(pScrn, 1);
- if (pMonitorDVI == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Could not retrieve DVI DDC data\n");
- }
-
- if ((pMonitor == NULL) && (pMonitorDVI != NULL)) {
- pMonitor = pMonitorDVI;
- }
- }
-
- }
- }
-
- /* initialize */
-
- if (pMonitor) {
- pXGI->CRT1Range.loH = 1000;
- pXGI->CRT1Range.loV = 1000;
- pXGI->CRT1Range.hiH = 0;
- pXGI->CRT1Range.hiV = 0;
- XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitor);
- }
- else {
- pXGI->CRT1Range.loH = 0;
- pXGI->CRT1Range.loV = 0;
- pXGI->CRT1Range.hiH = 1000;
- pXGI->CRT1Range.hiV = 1000;
- }
-
- if (pMonitorDVI) {
- pXGI->CRT2Range.loV = 1000;
- pXGI->CRT2Range.loH = 1000;
- pXGI->CRT2Range.hiH = 0;
- pXGI->CRT2Range.hiV = 0;
- XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorDVI);
- }
- else {
- pXGI->CRT2Range.loH = 0;
- pXGI->CRT2Range.loV = 0;
- pXGI->CRT2Range.hiH = 1000;
- pXGI->CRT2Range.hiV = 1000;
- }
-
- if (pXGI->xgi_HwDevExt.jChipType == XG21) {
- /* Mode range intersecting */
- if (pXGI->CRT1Range.loH < pXGI->CRT2Range.loH) {
- pXGI->CRT1Range.loH = pXGI->CRT2Range.loH;
- }
- if (pXGI->CRT1Range.loV < pXGI->CRT2Range.loV) {
- pXGI->CRT1Range.loV = pXGI->CRT2Range.loV;
- }
- if (pXGI->CRT1Range.hiH > pXGI->CRT2Range.hiH) {
- pXGI->CRT1Range.hiH = pXGI->CRT2Range.hiH;
- }
- if (pXGI->CRT1Range.hiV > pXGI->CRT2Range.hiV) {
- pXGI->CRT1Range.hiV = pXGI->CRT2Range.hiV;
- }
- }
-
- if (pMonitor) {
- XGISyncDDCMonitorRange(pScrn->monitor, &pXGI->CRT1Range);
- }
-
- if (pScrn->monitor) {
- pScrn->monitor->DDC = pMonitor;
- }
-
- return;
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- pXGI->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
- if (pXGI->CRT2pScrn->monitor) {
- DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
- memcpy(pXGI->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
- pXGI->CRT2pScrn->monitor->DDC = NULL;
- pXGI->CRT2pScrn->monitor->Modes = NULL;
- tempm = pScrn->monitor->Modes;
- while (tempm) {
- if (!(newm = xalloc(sizeof(DisplayModeRec))))
- break;
- memcpy(newm, tempm, sizeof(DisplayModeRec));
- if (!(newm->name = xalloc(strlen(tempm->name) + 1))) {
- xfree(newm);
- break;
- }
- strcpy(newm->name, tempm->name);
- if (!pXGI->CRT2pScrn->monitor->Modes)
- pXGI->CRT2pScrn->monitor->Modes = newm;
- if (currentm) {
- currentm->next = newm;
- newm->prev = currentm;
- }
- currentm = newm;
- tempm = tempm->next;
- }
-
- if ((pMonitor = XGIInternalDDC(pXGI->CRT2pScrn, 1))) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2);
- xf86PrintEDID(pMonitor);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2);
- xf86SetDDCproperties(pXGI->CRT2pScrn, pMonitor);
-
- pXGI->CRT2pScrn->monitor->DDC = pMonitor;
-
- /* use DDC data if no ranges in config file */
- if (!pXGI->CRT2HSync) {
- pXGI->CRT2pScrn->monitor->nHsync = 0;
- }
- if (!pXGI->CRT2VRefresh) {
- pXGI->CRT2pScrn->monitor->nVrefresh = 0;
- }
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Failed to read DDC data for CRT2\n");
- }
- }
- else {
- XGIErrorLog(pScrn,
- "Failed to allocate memory for CRT2 monitor, %s.\n",
- mergeddisstr);
- if (pXGI->CRT2pScrn)
- xfree(pXGI->CRT2pScrn);
- pXGI->CRT2pScrn = NULL;
- pXGI->MergedFB = FALSE;
- }
- }
-#endif
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1);
- }
-#endif
-
- /* end of DDC */
-}
-
-#ifdef DEBUG5
-static void
-XGIDumpModePtr(DisplayModePtr mode)
-{
- if (mode == NULL)
- return;
-
- ErrorF("Dump DisplayModePtr mode\n");
- ErrorF("name = %s\n", mode->name);
- /* ModeStatus status; */
- ErrorF("type = %d\n", mode->type);
- ErrorF("Clock = %d\n", mode->Clock);
- ErrorF("HDisplay = %d\n", mode->HDisplay);
- ErrorF("HSyncStart = %d\n", mode->HSyncStart);
- ErrorF("HSyncEnd = %d\n", mode->HSyncEnd);
- ErrorF("HTotal = %d\n", mode->HTotal);
- ErrorF("HSkew = %d\n", mode->HSkew);
- ErrorF("VDisplay = %d\n", mode->VDisplay);
- ErrorF("VSyncStart = %d\n", mode->VSyncStart);
- ErrorF("VSyncEnd = %d\n", mode->VSyncEnd);
- ErrorF("VTotal = %d\n", mode->VTotal);
- ErrorF("VScan = %d\n", mode->VScan);
- ErrorF("Flags = %d\n", mode->Flags);
-
-
- ErrorF("ClockIndex = %d\n", mode->ClockIndex);
- ErrorF("SynthClock = %d\n", mode->SynthClock);
- ErrorF("CrtcHDisplay = %d\n", mode->CrtcHDisplay);
- ErrorF("CrtcHBlankStart = %d\n", mode->CrtcHBlankStart);
- ErrorF("CrtcHSyncStart = %d\n", mode->CrtcHSyncStart);
- ErrorF("CrtcHSyncEnd = %d\n", mode->CrtcHSyncEnd);
- ErrorF("CrtcHBlankEnd = %d\n", mode->CrtcHBlankEnd);
- ErrorF("CrtcHTotal = %d\n", mode->CrtcHTotal);
- ErrorF("CrtcHSkew = %d\n", mode->CrtcHSkew);
- ErrorF("CrtcVDisplay = %d\n", mode->CrtcVDisplay);
- ErrorF("CrtcVBlankStart = %d\n", mode->CrtcVBlankStart);
- ErrorF("CrtcVSyncStart = %d\n", mode->CrtcVSyncStart);
- ErrorF("CrtcVSyncEnd = %d\n", mode->CrtcVSyncEnd);
- ErrorF("CrtcVBlankEnd = %d\n", mode->CrtcVBlankEnd);
- ErrorF("CrtcVTotal = %d\n", mode->CrtcVTotal);
- ErrorF("CrtcHAdjusted = %s\n", (mode->CrtcHAdjusted) ? "TRUE" : "FALSE");
- ErrorF("CrtcVAdjusted = %s\n", (mode->CrtcVAdjusted) ? "TRUE" : "FALSE");
- ErrorF("PrivSize = %d\n", mode->PrivSize);
- /* INT32 * Private; */
- ErrorF("PrivFlags = %d\n", mode->PrivFlags);
- ErrorF("HSync = %8.3f\n", mode->HSync);
- ErrorF("VRefresh = %8.3f\n", mode->VRefresh);
-}
-#endif
-
-static void
-XGIDumpMonPtr(MonPtr pMonitor)
-{
-#ifdef DEBUG5
- int i;
-# if 0
- DisplayModePtr mode;
-#endif
-
- ErrorF("XGIDumpMonPtr() ... \n");
- if (pMonitor == NULL) {
- ErrorF("pMonitor is NULL\n");
- }
-
- ErrorF("id = %s, vendor = %s model = %s\n",
- pMonitor->id, pMonitor->vendor, pMonitor->model);
- ErrorF("nHsync = %d\n", pMonitor->nHsync);
- ErrorF("nVrefresh = %d\n", pMonitor->nVrefresh);
-
- for (i = 0; i < MAX_HSYNC; i++) {
- ErrorF("hsync[%d] = (%8.3f,%8.3f)\n", i, pMonitor->hsync[i].lo,
- pMonitor->hsync[i].hi);
- }
-
- for (i = 0; i < MAX_VREFRESH; i++) {
- ErrorF("vrefresh[%d] = (%8.3f,%8.3f)\n", i, pMonitor->vrefresh[i].lo,
- pMonitor->vrefresh[i].hi);
- }
-
- ErrorF("widthmm = %d, heightmm = %d\n",
- pMonitor->widthmm, pMonitor->heightmm);
- ErrorF("options = %p, DDC = %p\n", pMonitor->options, pMonitor->DDC);
-# if 0
- mode = pMonitor->Modes;
- while (1) {
- XGIDumpModePtr(mode);
- if (mode == pMonitor->Last) {
- break;
- }
- mode = mode->next;
- }
-# endif
-#endif /* DEBUG5 */
-}
-
-/* Mandatory */
-static Bool
-XGIPreInit(ScrnInfoPtr pScrn, int flags)
-{
- XGIPtr pXGI;
- MessageType from;
- unsigned long int i;
- int temp;
- ClockRangePtr clockRanges;
- int pix24flags;
- int fd;
- struct fb_fix_screeninfo fix;
- XGIEntPtr pXGIEnt = NULL;
- size_t memreq;
-
-#if defined(XGIMERGED) || defined(XGIDUALHEAD)
- DisplayModePtr first, p, n;
-#endif
- unsigned char srlockReg, crlockReg;
- vbeInfoPtr pVbe;
-
- /****************** Code Start ***********************/
-
- ErrorF("XGIPreInit\n");
-
- if (flags & PROBE_DETECT) {
- if (xf86LoadSubModule(pScrn, "vbe")) {
- int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
-
- if ((pVbe = VBEExtendedInit(NULL, index, 0))) {
- ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
- vbeFree(pVbe);
- }
- }
- return TRUE;
- }
-
- /*
- * Note: This function is only called once at server startup, and
- * not at the start of each server generation. This means that
- * only things that are persistent across server generations can
- * be initialised here. xf86Screens[] is the array of all screens,
- * (pScrn is a pointer to one of these). Privates allocated using
- * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
- * for data that must persist across server generations.
- *
- * Per-generation data should be allocated with
- * AllocateScreenPrivateIndex() from the ScreenInit() function.
- */
-
- /* Check the number of entities, and fail if it isn't one. */
- if (pScrn->numEntities != 1) {
- XGIErrorLog(pScrn, "Number of entities is not 1\n");
- return FALSE;
- }
-
- /* The vgahw module should be loaded here when needed */
- if (!xf86LoadSubModule(pScrn, "vgahw")) {
- XGIErrorLog(pScrn, "Could not load vgahw module\n");
- return FALSE;
- }
-
- xf86LoaderReqSymLists(vgahwSymbols, NULL);
-
- /* Due to the liberal license terms this is needed for
- * keeping the copyright notice readable and intact in
- * binary distributions. Removing this is a copyright
- * infringement. Please read the license terms above.
- */
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "XGI driver (%s)\n", XGI_RELEASE_DATE);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n");
-
- /* Allocate a vgaHWRec */
- if (!vgaHWGetHWRec(pScrn)) {
- XGIErrorLog(pScrn, "Could not allocate VGA private\n");
- return FALSE;
- }
-
- /* Allocate the XGIRec driverPrivate */
- pXGI = XGIGetRec(pScrn);
- if (pXGI == NULL) {
- XGIErrorLog(pScrn, "Could not allocate memory for pXGI private\n");
- return FALSE;
- }
-
- pXGI->IODBase = pScrn->domainIOBase;
-
-
- /* Get the entity, and make sure it is PCI. */
- pXGI->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
- if (pXGI->pEnt->location.type != BUS_PCI) {
- XGIErrorLog(pScrn, "Entity's bus type is not PCI\n");
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
-#ifdef XGIDUALHEAD
- /* Allocate an entity private if necessary */
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- pXGIEnt = xf86GetEntityPrivate(pScrn->entityList[0],
- XGIEntityIndex)->ptr;
- pXGI->entityPrivate = pXGIEnt;
-
- /* If something went wrong, quit here */
- if ((pXGIEnt->DisableDual) || (pXGIEnt->ErrorAfterFirst)) {
- XGIErrorLog(pScrn,
- "First head encountered fatal error, can't continue\n");
- XGIFreeRec(pScrn);
- return FALSE;
- }
- }
-#endif
-
- /* Find the PCI info for this screen */
-#ifndef XSERVER_LIBPCIACCESS
- pXGI->PciInfo = xf86GetPciInfoForEntity(pXGI->pEnt->index);
- pXGI->PciTag = pciTag(pXGI->PciInfo->bus, pXGI->PciInfo->device,
- pXGI->PciInfo->func);
-#endif
-
- pXGI->Primary = xf86IsPrimaryPci(pXGI->PciInfo);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "This adapter is %s display adapter\n",
- (pXGI->Primary ? "primary" : "secondary"));
-
- if (pXGI->Primary) {
- VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
- if (!vgaHWMapMem(pScrn)) {
- XGIErrorLog(pScrn, "Could not map VGA memory\n");
- XGIFreeRec(pScrn);
- return FALSE;
- }
- }
- vgaHWGetIOBase(VGAHWPTR(pScrn));
-
- /* We "patch" the PIOOffset inside vgaHW in order to force
- * the vgaHW module to use our relocated i/o ports.
- */
- VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
-#ifdef XSERVER_LIBPCIACCESS
- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
-#else
- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
-#endif
- ;
-
- pXGI->pInt = NULL;
- if (!pXGI->Primary) {
-#if !defined(__alpha__)
-#if !defined(__powerpc__)
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Initializing display adapter through int10\n");
-
- if (xf86LoadSubModule(pScrn, "int10")) {
- xf86LoaderReqSymLists(int10Symbols, NULL);
- pXGI->pInt = xf86InitInt10(pXGI->pEnt->index);
- }
- else {
- XGIErrorLog(pScrn, "Could not load int10 module\n");
- }
-#endif /* !defined(__powerpc__) */
-#endif /* !defined(__alpha__) */
- }
-
- xf86SetOperatingState(resVgaMem, pXGI->pEnt->index, ResUnusedOpr);
-
- /* Operations for which memory access is required */
- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
- /* Operations for which I/O access is required */
- pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
-
- /* The ramdac module should be loaded here when needed */
- if (!xf86LoadSubModule(pScrn, "ramdac")) {
- XGIErrorLog(pScrn, "Could not load ramdac module\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- xf86LoaderReqSymLists(ramdacSymbols, NULL);
-
- /* Set pScrn->monitor */
- pScrn->monitor = pScrn->confScreen->monitor;
-
- /*
- * Set the Chipset and ChipRev, allowing config file entries to
- * override. DANGEROUS!
- */
- if (pXGI->pEnt->device->chipset && *pXGI->pEnt->device->chipset) {
- PDEBUG(ErrorF(" --- Chipset 1 \n"));
- pScrn->chipset = pXGI->pEnt->device->chipset;
- pXGI->Chipset = xf86StringToToken(XGIChipsets, pScrn->chipset);
- from = X_CONFIG;
- }
- else if (pXGI->pEnt->device->chipID >= 0) {
- PDEBUG(ErrorF(" --- Chipset 2 \n"));
- pXGI->Chipset = pXGI->pEnt->device->chipID;
- pScrn->chipset =
- (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
-
- from = X_CONFIG;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
- pXGI->Chipset);
- }
- else {
- PDEBUG(ErrorF(" --- Chipset 3 \n"));
- from = X_PROBED;
- pXGI->Chipset = DEVICE_ID(pXGI->PciInfo);
- pScrn->chipset =
- (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
- }
- if (pXGI->pEnt->device->chipRev >= 0) {
- pXGI->ChipRev = pXGI->pEnt->device->chipRev;
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
- pXGI->ChipRev);
- }
- else {
- pXGI->ChipRev = CHIP_REVISION(pXGI->PciInfo);
- }
- pXGI->xgi_HwDevExt.jChipRevision = pXGI->ChipRev;
-
- PDEBUG(ErrorF(" --- Chipset : %s \n", pScrn->chipset));
-
-
- /*
- * This shouldn't happen because such problems should be caught in
- * XGIProbe(), but check it just in case.
- */
- if (pScrn->chipset == NULL) {
- XGIErrorLog(pScrn, "ChipID 0x%04X is not recognised\n",
- pXGI->Chipset);
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- if (pXGI->Chipset < 0) {
- XGIErrorLog(pScrn, "Chipset \"%s\" is not recognised\n",
- pScrn->chipset);
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- /* Determine chipset and VGA engine type */
- pXGI->ChipFlags = 0;
- pXGI->XGI_SD_Flags = 0;
-
- switch (pXGI->Chipset) {
- case PCI_CHIP_XGIXG40:
- case PCI_CHIP_XGIXG20:
- pXGI->xgi_HwDevExt.jChipType = XG40;
- pXGI->myCR63 = 0x63;
- pXGI->mmioSize = 64;
- break;
- default:
- /* This driver currently only supports V3XE, V3XT, V5, V8 (all of
- * which are XG40 chips) and Z7 (which is XG20).
- */
- if (pXGI->pInt) {
- xf86FreeInt10(pXGI->pInt);
- }
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
-/* load frame_buffer */
-
- FbDevExist = FALSE;
- if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
- if ((fd = open("/dev/fb", 'r')) != -1) {
- PDEBUG(ErrorF("--- open /dev/fb.... \n"));
- ioctl(fd, FBIOGET_FSCREENINFO, &fix);
- if (fix.accel == FB_ACCEL_XGI_GLAMOUR) {
- PDEBUG(ErrorF("--- fix.accel.... \n"));
- FbDevExist = TRUE;
- }
- else
- PDEBUG(ErrorF("--- no fix.accel.... 0x%08lx \n", fix.accel));
- close(fd);
- }
- }
-
-
- /*
- * The first thing we should figure out is the depth, bpp, etc.
- * Additionally, determine the size of the HWCursor memory area.
- */
- pXGI->CursorSize = 4096;
- pix24flags = Support32bppFb;
-
-#ifdef XGIDUALHEAD
- /* In case of Dual Head, we need to determine if we are the "master" head or
- * the "slave" head. In order to do that, we set PrimInit to DONE in the
- * shared entity at the end of the first initialization. The second
- * initialization then knows that some things have already been done. THIS
- * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
- */
-
- if (xf86IsEntityShared(pScrn->entityList[0])) {
- if (pXGIEnt->lastInstance > 0) {
- if (!xf86IsPrimInitDone(pScrn->entityList[0])) {
- /* First Head (always CRT2) */
- pXGI->SecondHead = FALSE;
- pXGIEnt->pScrn_1 = pScrn;
- pXGIEnt->CRT2ModeNo = -1;
- pXGIEnt->CRT2ModeSet = FALSE;
- pXGI->DualHeadMode = TRUE;
- pXGIEnt->DisableDual = FALSE;
- pXGIEnt->BIOS = NULL;
- pXGIEnt->XGI_Pr = NULL;
- pXGIEnt->RenderAccelArray = NULL;
- }
- else {
- /* Second Head (always CRT1) */
- pXGI->SecondHead = TRUE;
- pXGIEnt->pScrn_2 = pScrn;
- pXGI->DualHeadMode = TRUE;
- }
- }
- else {
- /* Only one screen in config file - disable dual head mode */
- pXGI->SecondHead = FALSE;
- pXGI->DualHeadMode = FALSE;
- pXGIEnt->DisableDual = TRUE;
- }
- }
- else {
- /* Entity is not shared - disable dual head mode */
- pXGI->SecondHead = FALSE;
- pXGI->DualHeadMode = FALSE;
- }
-#endif
-
- /* Allocate VB_DEVICE_INFO (for mode switching code) and initialize it */
- pXGI->XGI_Pr = NULL;
- if (pXGIEnt && pXGIEnt->XGI_Pr) {
- pXGI->XGI_Pr = pXGIEnt->XGI_Pr;
- }
-
- if (!pXGI->XGI_Pr) {
- if (!(pXGI->XGI_Pr = xnfcalloc(sizeof(VB_DEVICE_INFO), 1))) {
- XGIErrorLog(pScrn,
- "Could not allocate memory for XGI_Pr private\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- if (pXGIEnt)
- pXGIEnt->XGI_Pr = pXGI->XGI_Pr;
-
- memset(pXGI->XGI_Pr, 0, sizeof(VB_DEVICE_INFO));
- }
-
- /* Get our relocated IO registers */
- pXGI->RelIO = (XGIIOADDRESS) (pXGI->IODBase |
-#ifdef XSERVER_LIBPCIACCESS
- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
-#else
- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
-#endif
- );
- pXGI->xgi_HwDevExt.pjIOAddress = (XGIIOADDRESS) (pXGI->RelIO + 0x30);
- xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
- (unsigned long) pXGI->RelIO);
-
- if (!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
- XGIErrorLog(pScrn, "xf86SetDepthBpp() error\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- /* Check that the returned depth is one we support */
- temp = 0;
- switch (pScrn->depth) {
- case 8:
- case 16:
- case 24:
-#if !defined(__powerpc__)
- case 15:
-#endif
- break;
- default:
- temp = 1;
- }
-
- if (temp) {
- XGIErrorLog(pScrn,
- "Given color depth (%d) is not supported by this driver/chipset\n",
- pScrn->depth);
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- xf86PrintDepthBpp(pScrn);
-
- /* Get the depth24 pixmap format */
- if (pScrn->depth == 24 && pix24bpp == 0) {
- pix24bpp = xf86GetBppFromDepth(pScrn, 24);
- }
-
- /*
- * This must happen after pScrn->display has been set because
- * xf86SetWeight references it.
- */
- if (pScrn->depth > 8) {
- /* The defaults are OK for us */
- rgb zeros = { 0, 0, 0 };
-
- if (!xf86SetWeight(pScrn, zeros, zeros)) {
- XGIErrorLog(pScrn, "xf86SetWeight() error\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- else {
- Bool ret = FALSE;
- switch (pScrn->depth) {
- case 15:
- if ((pScrn->weight.red != 5) ||
- (pScrn->weight.green != 5) || (pScrn->weight.blue != 5))
- ret = TRUE;
- break;
- case 16:
- if ((pScrn->weight.red != 5) ||
- (pScrn->weight.green != 6) || (pScrn->weight.blue != 5))
- ret = TRUE;
- break;
- case 24:
- if ((pScrn->weight.red != 8) ||
- (pScrn->weight.green != 8) || (pScrn->weight.blue != 8))
- ret = TRUE;
- break;
- }
- if (ret) {
- XGIErrorLog(pScrn,
- "RGB weight %d%d%d at depth %d not supported by hardware\n",
- (int) pScrn->weight.red,
- (int) pScrn->weight.green,
- (int) pScrn->weight.blue, pScrn->depth);
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- }
- }
-
- /* Set the current layout parameters */
- pXGI->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
- pXGI->CurrentLayout.depth = pScrn->depth;
- /* (Inside this function, we can use pScrn's contents anyway) */
-
- if (!xf86SetDefaultVisual(pScrn, -1)) {
- XGIErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- else {
- /* We don't support DirectColor at > 8bpp */
- if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
- XGIErrorLog(pScrn,
- "Given default visual (%s) is not supported at depth %d\n",
- xf86GetVisualName(pScrn->defaultVisual),
- pScrn->depth);
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- }
-
- /* Due to palette & timing problems we don't support 8bpp in DHM */
- if ((IS_DUAL_HEAD(pXGI)) && (pScrn->bitsPerPixel == 8)) {
- XGIErrorLog(pScrn,
- "Color depth 8 not supported in Dual Head mode.\n");
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- /*
- * The cmap layer needs this to be initialised.
- */
- {
- Gamma zeros = { 0.0, 0.0, 0.0 };
-
- if (!xf86SetGamma(pScrn, zeros)) {
- XGIErrorLog(pScrn, "xf86SetGamma() error\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- }
-
- /* We use a programamble clock */
- pScrn->progClock = TRUE;
-
- /* Set the bits per RGB for 8bpp mode */
- if (pScrn->depth == 8) {
- pScrn->rgbBits = 6;
- }
-
- from = X_DEFAULT;
-
- /* Unlock registers */
- xgiSaveUnlockExtRegisterLock(pXGI, &srlockReg, &crlockReg);
-
- /* Read BIOS for 300 and 315/330 series customization */
- pXGI->xgi_HwDevExt.pjVirtualRomBase = NULL;
- pXGI->BIOS = NULL;
- pXGI->xgi_HwDevExt.UseROM = FALSE;
-
- /* Evaluate options */
- xgiOptions(pScrn);
-
-#ifdef XGIMERGED
- /* Due to palette & timing problems we don't support 8bpp in MFBM */
- if ((pXGI->MergedFB) && (pScrn->bitsPerPixel == 8)) {
- XGIErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n",
- mergeddisstr);
- pXGI->MergedFB = pXGI->MergedFBAuto = FALSE;
- }
-#endif
-
- /* Do basic configuration */
-
- XGISetup(pScrn);
-
- from = X_PROBED;
-#ifdef XSERVER_LIBPCIACCESS
- pXGI->FbAddress = pXGI->PciInfo->regions[0].base_addr & 0xFFFFFFF0;
-#else
- if (pXGI->pEnt->device->MemBase != 0) {
- /*
- * XXX Should check that the config file value matches one of the
- * PCI base address values.
- */
- pXGI->FbAddress = pXGI->pEnt->device->MemBase;
- from = X_CONFIG;
- }
- else {
- pXGI->FbAddress = pXGI->PciInfo->memBase[0] & 0xFFFFFFF0;
- }
-#endif
-
- pXGI->realFbAddress = pXGI->FbAddress;
-
- xf86DrvMsg(pScrn->scrnIndex, from,
- "%sinear framebuffer at 0x%lX\n",
- IS_DUAL_HEAD(pXGI) ? "Global l" : "L",
- (unsigned long) pXGI->FbAddress);
-
-#ifdef XSERVER_LIBPCIACCESS
- pXGI->IOAddress = pXGI->PciInfo->regions[1].base_addr & 0xFFFFFFF0;
-#else
- if (pXGI->pEnt->device->IOBase != 0) {
- /*
- * XXX Should check that the config file value matches one of the
- * PCI base address values.
- */
- pXGI->IOAddress = pXGI->pEnt->device->IOBase;
- from = X_CONFIG;
- }
- else {
- pXGI->IOAddress = pXGI->PciInfo->memBase[1] & 0xFFFFFFF0;
- }
-#endif
-
- xf86DrvMsg(pScrn->scrnIndex, from,
- "MMIO registers at 0x%lX (size %ldK)\n",
- (unsigned long) pXGI->IOAddress, pXGI->mmioSize);
- pXGI->xgi_HwDevExt.bIntegratedMMEnabled = TRUE;
-
- /* Register the PCI-assigned resources. */
- if (xf86RegisterResources(pXGI->pEnt->index, NULL, ResExclusive)) {
- XGIErrorLog(pScrn,
- "xf86RegisterResources() found resource conflicts\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- from = X_PROBED;
- if (pXGI->pEnt->device->videoRam != 0) {
-
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Option \"VideoRAM\" ignored\n");
- }
-
- xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam);
-
- pXGI->FbMapSize = pXGI->availMem = pScrn->videoRam * 1024;
- pXGI->xgi_HwDevExt.ulVideoMemorySize = pScrn->videoRam * 1024;
- pXGI->xgi_HwDevExt.bSkipDramSizing = TRUE;
-
- /* Calculate real availMem according to Accel/TurboQueue and
- * HWCursur setting.
- *
- * TQ is max 64KiB. Reduce the available memory by 64KiB, and locate the
- * TQ at the beginning of this last 64KiB block. This is done even when
- * using the HWCursor, because the cursor only takes 2KiB and the queue
- * does not seem to last that far anyway.
- *
- * The TQ must be located at 32KB boundaries.
- */
- if (pScrn->videoRam < 3072) {
- if (pXGI->TurboQueue) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
- pXGI->TurboQueue = FALSE;
- }
- }
-
- pXGI->availMem -= (pXGI->TurboQueue) ? (64 * 1024) : pXGI->CursorSize;
-
-
- /* In dual head mode, we share availMem equally - so align it
- * to 8KB; this way, the address of the FB of the second
- * head is aligned to 4KB for mapping.
- *
- * Check MaxXFBMem setting. Since DRI is not supported in dual head
- * mode, we don't need the MaxXFBMem setting.
- */
- if (IS_DUAL_HEAD(pXGI)) {
- if (pXGI->maxxfbmem) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
- }
-
- pXGI->availMem &= 0xFFFFE000;
- pXGI->maxxfbmem = pXGI->availMem;
- }
- else if (pXGI->maxxfbmem) {
- if (pXGI->maxxfbmem > pXGI->availMem) {
- if (pXGI->xgifbMem) {
- pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Invalid MaxXFBMem setting. Using xgifb heap start information\n");
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
- pXGI->maxxfbmem = pXGI->availMem;
- }
- }
- else if (pXGI->xgifbMem) {
- if (pXGI->maxxfbmem > pXGI->xgifbMem * 1024) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "MaxXFBMem beyond xgifb heap start. Using xgifb heap start\n");
- pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
- }
- }
- }
- else if (pXGI->xgifbMem) {
- pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
- }
- else
- pXGI->maxxfbmem = pXGI->availMem;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
- pXGI->maxxfbmem / 1024);
-
- pXGI->CRT1off = -1;
-
- /* Detect video bridge and sense TV/VGA2 */
- XGIVGAPreInit(pScrn);
-
- /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */
- XGICRT1PreInit(pScrn);
-
- /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */
- XGILCDPreInit(pScrn);
-
- /* LCDA only supported under these conditions: */
- if (pXGI->ForceCRT1Type == CRT1_LCDA) {
- if (!
- (pXGI->XGI_Pr->
- VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV |
- VB_XGI302LV))) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Chipset/Video bridge does not support LCD-via-CRT1\n");
- pXGI->ForceCRT1Type = CRT1_VGA;
- }
- else if (!(pXGI->VBFlags & CRT2_LCD)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "No digitally connected LCD panel found, LCD-via-CRT1 "
- "disabled\n");
- pXGI->ForceCRT1Type = CRT1_VGA;
- }
- }
-
- /* Setup SD flags */
- pXGI->XGI_SD_Flags |= XGI_SD_ADDLSUPFLAG;
-
- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTV;
- }
-
-#ifdef ENABLE_YPBPR
- if (pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B)) {
- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTHIVISION;
- }
-#endif
-
-#ifdef TWDEBUG /* @@@ TEST @@@ */
- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTYPBPRAR;
- xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n");
-#endif
-
- /* Detect CRT2-TV and PAL/NTSC mode */
- XGITVPreInit(pScrn);
-
- /* Detect CRT2-VGA */
- XGICRT2PreInit(pScrn);
- PDEBUG(ErrorF("3496 pXGI->VBFlags =%x\n", pXGI->VBFlags));
-
- if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR)) {
- if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_YPBPR)) {
- pXGI->ForceTVType = -1;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "YPbPr TV output not supported\n");
- }
- }
-
- if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTHIVISION)) {
- if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_HIVISION)) {
- pXGI->ForceTVType = -1;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "HiVision TV output not supported\n");
- }
- }
-
- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
- pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
- }
- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTVPOS;
- }
- if (pXGI->XGI_Pr->
- VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
- pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTSCART | XGI_SD_SUPPORTVGA2);
- }
-
- if ((pXGI->XGI_Pr->
- VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | VB_XGI302LV))
- && (pXGI->VBFlags & CRT2_LCD)) {
- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTLCDA;
- }
-
- pXGI->VBFlags |= pXGI->ForceCRT1Type;
-
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "SDFlags %lx\n", pXGI->XGI_SD_Flags);
-#endif
-
-
- if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) {
- xf86DrvMsg(pScrn->scrnIndex, pXGI->CRT1gammaGiven ? X_CONFIG : X_INFO,
- "CRT1 gamma correction is %s\n",
- pXGI->CRT1gamma ? "enabled" : "disabled");
- }
-
- /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART, HIVISION, YPBPR) */
- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
- if (pXGI->ForceTVType != -1) {
- pXGI->VBFlags &= ~(TV_INTERFACE);
- pXGI->VBFlags |= pXGI->ForceTVType;
- if (pXGI->VBFlags & TV_YPBPR) {
- pXGI->VBFlags &= ~(TV_STANDARD);
- pXGI->VBFlags &= ~(TV_YPBPRAR);
- pXGI->VBFlags |= pXGI->ForceYPbPrType;
- pXGI->VBFlags |= pXGI->ForceYPbPrAR;
- }
- }
- }
-
- /* Check if CRT1 used or needed. There are three cases where this can
- * happen:
- * - No video bridge.
- * - No CRT2 output.
- * - Depth = 8 and bridge=LVDS|301B-DH
- * - LCDA
- */
- if (((pXGI->XGI_Pr->VBType & VB_XGIVB) == 0)
- || ((pXGI->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)) == 0)
- || ((pScrn->bitsPerPixel == 8)
- && (pXGI->XGI_Pr->VBType & VB_XGI301LV302LV))
- || (pXGI->VBFlags & CRT1_LCDA)) {
- pXGI->CRT1off = 0;
- }
-
-
- /* Handle TVStandard option */
- if ((pXGI->NonDefaultPAL != -1) || (pXGI->NonDefaultNTSC != -1)) {
- if (!(pXGI->XGI_Pr->VBType & VB_XGIVB)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "PALM, PALN and NTSCJ not supported on this hardware\n");
- pXGI->NonDefaultPAL = pXGI->NonDefaultNTSC = -1;
- pXGI->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ);
- pXGI->XGI_SD_Flags &=
- ~(XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
- }
- }
-
-#ifdef XGI_CP
- XGI_CP_DRIVER_RECONFIGOPT
-#endif
- /* Do some MergedFB mode initialisation */
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- pXGI->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
- if (!pXGI->CRT2pScrn) {
- XGIErrorLog(pScrn,
- "Failed to allocate memory for 2nd pScrn, %s\n",
- mergeddisstr);
- pXGI->MergedFB = FALSE;
- }
- else {
- memcpy(pXGI->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
- }
- }
-#endif
- PDEBUG(ErrorF("3674 pXGI->VBFlags =%x\n", pXGI->VBFlags));
-
- /* Determine CRT1<>CRT2 mode
- * Note: When using VESA or if the bridge is in slavemode, display
- * is ALWAYS in MIRROR_MODE!
- * This requires extra checks in functions using this flag!
- * (see xgi_video.c for example)
- */
- if (pXGI->VBFlags & DISPTYPE_DISP2) {
- if (pXGI->CRT1off) { /* CRT2 only ------------------------------- */
- if (IS_DUAL_HEAD(pXGI)) {
- XGIErrorLog(pScrn,
- "CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
- if (pXGIEnt)
- pXGIEnt->DisableDual = TRUE;
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- pXGI->pInt = NULL;
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- if (pXGI->MergedFBAuto) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1,
- mergeddisstr);
- }
- else {
- XGIErrorLog(pScrn, mergednocrt1, mergeddisstr);
- }
- if (pXGI->CRT2pScrn)
- xfree(pXGI->CRT2pScrn);
- pXGI->CRT2pScrn = NULL;
- pXGI->MergedFB = FALSE;
- }
-#endif
- pXGI->VBFlags |= VB_DISPMODE_SINGLE;
- }
- /* CRT1 and CRT2 - mirror or dual head ----- */
- else if (IS_DUAL_HEAD(pXGI)) {
- pXGI->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
- if (pXGIEnt)
- pXGIEnt->DisableDual = FALSE;
- }
- else
- pXGI->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
- }
- else { /* CRT1 only ------------------------------- */
- if (IS_DUAL_HEAD(pXGI)) {
- XGIErrorLog(pScrn,
- "No CRT2 output selected or no bridge detected. "
- "Dual Head mode can't initialize.\n");
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- pXGI->pInt = NULL;
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- if (pXGI->MergedFBAuto) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2,
- mergeddisstr);
- }
- else {
- XGIErrorLog(pScrn, mergednocrt2, mergeddisstr);
- }
- if (pXGI->CRT2pScrn)
- xfree(pXGI->CRT2pScrn);
- pXGI->CRT2pScrn = NULL;
- pXGI->MergedFB = FALSE;
- }
-#endif
- PDEBUG(ErrorF("3782 pXGI->VBFlags =%x\n", pXGI->VBFlags));
- pXGI->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
- }
-
- /* Init Ptrs for Save/Restore functions and calc MaxClock */
- XGIDACPreInit(pScrn);
-
- /* ********** end of VBFlags setup ********** */
-
- /* VBFlags are initialized now. Back them up for SlaveMode modes. */
- pXGI->VBFlags_backup = pXGI->VBFlags;
-
- /* Find out about paneldelaycompensation and evaluate option */
- if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
-
- }
-
- /* In dual head mode, both heads (currently) share the maxxfbmem equally.
- * If memory sharing is done differently, the following has to be changed;
- * the other modules (eg. accel and Xv) use dhmOffset for hardware
- * pointer settings relative to VideoRAM start and won't need to be changed.
- */
- if (IS_DUAL_HEAD(pXGI)) {
- if (!IS_SECOND_HEAD(pXGI)) {
- /* ===== First head (always CRT2) ===== */
- /* We use only half of the memory available */
- pXGI->maxxfbmem /= 2;
- /* Initialize dhmOffset */
- pXGI->dhmOffset = 0;
- /* Copy framebuffer addresses & sizes to entity */
- pXGIEnt->masterFbAddress = pXGI->FbAddress;
- pXGIEnt->masterFbSize = pXGI->maxxfbmem;
- pXGIEnt->slaveFbAddress = pXGI->FbAddress + pXGI->maxxfbmem;
- pXGIEnt->slaveFbSize = pXGI->maxxfbmem;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "%ldKB video RAM at 0x%lx available for master head (CRT2)\n",
- pXGI->maxxfbmem / 1024, pXGI->FbAddress);
- }
- else {
- /* ===== Second head (always CRT1) ===== */
- /* We use only half of the memory available */
- pXGI->maxxfbmem /= 2;
- /* Adapt FBAddress */
- pXGI->FbAddress += pXGI->maxxfbmem;
- /* Initialize dhmOffset */
- pXGI->dhmOffset = pXGI->availMem - pXGI->maxxfbmem;
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n",
- pXGI->maxxfbmem / 1024, pXGI->FbAddress);
- }
- }
- else
- pXGI->dhmOffset = 0;
-
- /* Note: Do not use availMem for anything from now. Use
- * maxxfbmem instead. (availMem does not take dual head
- * mode into account.)
- */
-
-#if !defined(__powerpc__)
- /* Now load and initialize VBE module. */
- if (xf86LoadSubModule(pScrn, "vbe")) {
- xf86LoaderReqSymLists(vbeSymbols, NULL);
- pXGI->pVbe = VBEExtendedInit(pXGI->pInt, pXGI->pEnt->index,
- SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
- if (!pXGI->pVbe) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Could not initialize VBE module for DDC\n");
- }
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Could not load VBE module\n");
- }
-
- XGIDDCPreInit(pScrn);
-#endif
- /* From here, we mainly deal with clocks and modes */
-
- /* Set the min pixel clock */
- pXGI->MinClock = 5000;
-
- xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
- pXGI->MinClock / 1000);
-
- from = X_PROBED;
- /*
- * If the user has specified ramdac speed in the XF86Config
- * file, we respect that setting.
- */
- if (pXGI->pEnt->device->dacSpeeds[0]) {
- int speed = 0;
- switch (pScrn->bitsPerPixel) {
- case 8:
- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP8];
- break;
- case 16:
- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP16];
- break;
- case 24:
- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP24];
- break;
- case 32:
- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP32];
- break;
- }
- if (speed == 0)
- pXGI->MaxClock = pXGI->pEnt->device->dacSpeeds[0];
- else
- pXGI->MaxClock = speed;
- from = X_CONFIG;
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
- pXGI->MaxClock / 1000);
-
- /*
- * Setup the ClockRanges, which describe what clock ranges are available,
- * and what sort of modes they can be used for.
- */
- clockRanges = xnfcalloc(sizeof(ClockRange), 1);
- clockRanges->next = NULL;
- clockRanges->minClock = pXGI->MinClock;
- clockRanges->maxClock = pXGI->MaxClock;
- clockRanges->clockIndex = -1; /* programmable */
- clockRanges->interlaceAllowed = TRUE;
- clockRanges->doubleScanAllowed = TRUE;
-
- /*
- * xf86ValidateModes will check that the mode HTotal and VTotal values
- * don't exceed the chipset's limit if pScrn->maxHValue and
- * pScrn->maxVValue are set. Since our XGIValidMode() already takes
- * care of this, we don't worry about setting them here.
- */
-
- /* Select valid modes from those available */
-#ifdef XGIMERGED
- pXGI->CheckForCRT2 = FALSE;
-#endif
- XGIDumpMonPtr(pScrn->monitor);
- i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048, /* min / max pitch */
- pScrn->bitsPerPixel * 8, 128, 2048, /* min / max height */
- pScrn->display->virtualX,
- pScrn->display->virtualY,
- pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
-
- if (i == -1) {
- XGIErrorLog(pScrn, "xf86ValidateModes() error\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- /* Check the virtual screen against the available memory */
-
- memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8))
- * pScrn->virtualY;
-
- if (memreq > pXGI->maxxfbmem) {
- XGIErrorLog(pScrn,
- "Virtual screen too big for memory; %ldK needed, %ldK available\n",
- memreq / 1024, pXGI->maxxfbmem / 1024);
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- pXGI->pInt = NULL;
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- else if (pXGI->loadDRI && !IS_DUAL_HEAD(pXGI)) {
- pXGI->maxxfbmem = memreq;
- pXGI->DRIheapstart = pXGI->DRIheapend = 0;
-
- if (pXGI->maxxfbmem == pXGI->availMem) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "All video memory used for framebuffer. DRI will be disabled.\n");
- pXGI->loadDRI = FALSE;
- }
- else {
- pXGI->DRIheapstart = pXGI->maxxfbmem;
- pXGI->DRIheapend = pXGI->availMem;
- }
- }
-
-
- /* Dual Head:
- * -) Go through mode list and mark all those modes as bad,
- * which are unsuitable for dual head mode.
- * -) Find the highest used pixelclock on the master head.
- */
- if (IS_DUAL_HEAD(pXGI) && !IS_SECOND_HEAD(pXGI)) {
- pXGIEnt->maxUsedClock = 0;
-
- if ((p = first = pScrn->modes)) {
- do {
- n = p->next;
-
- /* Modes that require the bridge to operate in SlaveMode
- * are not suitable for Dual Head mode.
- */
-
- /* Search for the highest clock on first head in order to calculate
- * max clock for second head (CRT1)
- */
- if ((p->status == MODE_OK)
- && (p->Clock > pXGIEnt->maxUsedClock)) {
- pXGIEnt->maxUsedClock = p->Clock;
- }
-
- p = n;
-
- } while (p != NULL && p != first);
- }
- }
-
- /* Prune the modes marked as invalid */
- xf86PruneDriverModes(pScrn);
-
- if (i == 0 || pScrn->modes == NULL) {
- XGIErrorLog(pScrn, "No valid modes found\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
-
- xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
-
- /* Set the current mode to the first in the list */
- pScrn->currentMode = pScrn->modes;
-
- /* Copy to CurrentLayout */
- pXGI->CurrentLayout.mode = pScrn->currentMode;
- pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1);
- }
-#endif
-
- /* Print the list of modes being used */
- xf86PrintModes(pScrn);
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- BOOLEAN acceptcustommodes = TRUE;
- BOOLEAN includelcdmodes = TRUE;
- BOOLEAN isfordvi = FALSE;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2);
-
- clockRanges->next = NULL;
- clockRanges->minClock = pXGI->MinClock;
- clockRanges->clockIndex = -1;
- clockRanges->interlaceAllowed = FALSE;
- clockRanges->doubleScanAllowed = FALSE;
-
- xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
- "Min pixel clock for CRT2 is %d MHz\n",
- clockRanges->minClock / 1000);
- xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
- "Max pixel clock for CRT2 is %d MHz\n",
- clockRanges->maxClock / 1000);
-
- if ((pXGI->XGI_Pr->
- VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)))
- {
- if (!(pXGI->VBFlags & (CRT2_LCD | CRT2_VGA)))
- includelcdmodes = FALSE;
- if (pXGI->VBFlags & CRT2_LCD)
- isfordvi = TRUE;
- if (pXGI->VBFlags & CRT2_TV)
- acceptcustommodes = FALSE;
- }
- else {
- includelcdmodes = FALSE;
- acceptcustommodes = FALSE;
- }
- }
-
- if (pXGI->MergedFB) {
-
- pXGI->CheckForCRT2 = TRUE;
- i = xf86ValidateModes(pXGI->CRT2pScrn,
- pXGI->CRT2pScrn->monitor->Modes,
- pXGI->CRT2pScrn->display->modes, clockRanges,
- NULL, 256, 4088,
- pXGI->CRT2pScrn->bitsPerPixel * 8, 128, 4096,
- pScrn->display->virtualX ? pScrn->virtualX : 0,
- pScrn->display->virtualY ? pScrn->virtualY : 0,
- pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
- pXGI->CheckForCRT2 = FALSE;
-
- if (i == -1) {
- XGIErrorLog(pScrn, "xf86ValidateModes() error, %s.\n",
- mergeddisstr);
- XGIFreeCRT2Structs(pXGI);
- pXGI->MergedFB = FALSE;
- }
-
- }
-
- if (pXGI->MergedFB) {
-
- if ((p = first = pXGI->CRT2pScrn->modes)) {
- do {
- n = p->next;
- p = n;
- } while (p != NULL && p != first);
- }
-
- xf86PruneDriverModes(pXGI->CRT2pScrn);
-
- if (i == 0 || pXGI->CRT2pScrn->modes == NULL) {
- XGIErrorLog(pScrn, "No valid modes found for CRT2; %s\n",
- mergeddisstr);
- XGIFreeCRT2Structs(pXGI);
- pXGI->MergedFB = FALSE;
- }
-
- }
-
- if (pXGI->MergedFB) {
-
- xf86SetCrtcForModes(pXGI->CRT2pScrn, INTERLACE_HALVE_V);
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2);
-
- xf86PrintModes(pXGI->CRT2pScrn);
-
- pXGI->CRT1Modes = pScrn->modes;
- pXGI->CRT1CurrentMode = pScrn->currentMode;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Generating MergedFB mode list\n");
-
- pScrn->modes = XGIGenerateModeList(pScrn, pXGI->MetaModes,
- pXGI->CRT1Modes,
- pXGI->CRT2pScrn->modes,
- pXGI->CRT2Position);
-
- if (!pScrn->modes) {
-
- XGIErrorLog(pScrn,
- "Failed to parse MetaModes or no modes found. %s.\n",
- mergeddisstr);
- XGIFreeCRT2Structs(pXGI);
- pScrn->modes = pXGI->CRT1Modes;
- pXGI->CRT1Modes = NULL;
- pXGI->MergedFB = FALSE;
-
- }
-
- }
-
- if (pXGI->MergedFB) {
-
- /* If no virtual dimension was given by the user,
- * calculate a sane one now. Adapts pScrn->virtualX,
- * pScrn->virtualY and pScrn->displayWidth.
- */
- XGIRecalcDefaultVirtualSize(pScrn);
-
- pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
- pScrn->currentMode = pScrn->modes;
-
- /* Update CurrentLayout */
- pXGI->CurrentLayout.mode = pScrn->currentMode;
- pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
-
- }
-#endif
-
- /* Set display resolution */
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- XGIMergedFBSetDpi(pScrn, pXGI->CRT2pScrn, pXGI->CRT2Position);
- }
- else
-#endif
- xf86SetDpi(pScrn, 0, 0);
-
- /* Load fb module */
- switch (pScrn->bitsPerPixel) {
- case 8:
- case 16:
- case 24:
- case 32:
- if (!xf86LoadSubModule(pScrn, "fb")) {
- XGIErrorLog(pScrn, "Failed to load fb module");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- break;
- default:
- XGIErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n",
- pScrn->bitsPerPixel);
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- xf86LoaderReqSymLists(fbSymbols, NULL);
-
- /* Load XAA if needed */
- if (!pXGI->NoAccel) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
- if (!xf86LoadSubModule(pScrn, "xaa")) {
- XGIErrorLog(pScrn, "Could not load xaa module\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- xf86LoaderReqSymLists(xaaSymbols, NULL);
- }
-
- /* Load shadowfb if needed */
- if (pXGI->ShadowFB) {
- if (!xf86LoadSubModule(pScrn, "shadowfb")) {
- XGIErrorLog(pScrn, "Could not load shadowfb module\n");
-
- if (pXGIEnt)
- pXGIEnt->ErrorAfterFirst = TRUE;
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
- XGIFreeRec(pScrn);
- return FALSE;
- }
- xf86LoaderReqSymLists(shadowSymbols, NULL);
- }
-
- /* Load the dri module if requested. */
-#ifdef XF86DRI
- if(pXGI->loadDRI) {
- if (xf86LoadSubModule(pScrn, "dri")) {
- xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL);
- }
- else {
- if (!IS_DUAL_HEAD(pXGI))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Remove >Load \"dri\"< from the Module section of your XF86Config file\n");
- }
- }
-#endif
-
-
- /* Now load and initialize VBE module for VESA and mode restoring. */
- if (pXGI->pVbe) {
- vbeFree(pXGI->pVbe);
- pXGI->pVbe = NULL;
- }
-
-#ifdef XGIDUALHEAD
- xf86SetPrimInitDone(pScrn->entityList[0]);
-#endif
-
- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
-
- if (pXGI->pInt)
- xf86FreeInt10(pXGI->pInt);
- pXGI->pInt = NULL;
-
- if (IS_DUAL_HEAD(pXGI)) {
- pXGI->XGI_SD_Flags |= XGI_SD_ISDUALHEAD;
- if (IS_SECOND_HEAD(pXGI))
- pXGI->XGI_SD_Flags |= XGI_SD_ISDHSECONDHEAD;
- else
- pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- pXGI->XGI_SD_Flags |= XGI_SD_ISDHXINERAMA;
- pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
- }
-#endif
- }
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB)
- pXGI->XGI_SD_Flags |= XGI_SD_ISMERGEDFB;
-#endif
-
- if (pXGI->enablexgictrl)
- pXGI->XGI_SD_Flags |= XGI_SD_ENABLED;
-
- return TRUE;
-}
-
-
-/*
- * Map the framebuffer and MMIO memory.
- */
-
-static Bool
-XGIMapMem(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);;
-
-#ifdef XSERVER_LIBPCIACCESS
- unsigned i;
-
- for (i = 0; i < 2; i++) {
- int err;
-
- err = pci_device_map_region(pXGI->PciInfo, i, TRUE);
- if (err) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Internal error: cound not map PCI region %u\n", i);
- return FALSE;
- }
- }
-
- pXGI->FbBase = pXGI->PciInfo->regions[0].memory;
- pXGI->IOBase = pXGI->PciInfo->regions[1].memory;
-#else
- int mmioFlags;
-
- /*
- * Map IO registers to virtual address space
- */
-#if !defined(__alpha__)
- mmioFlags = VIDMEM_MMIO;
-#else
- /*
- * For Alpha, we need to map SPARSE memory, since we need
- * byte/short access.
- */
- mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
-#endif
- pXGI->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
- pXGI->PciTag, pXGI->IOAddress, 0x10000);
- if (pXGI->IOBase == NULL)
- return FALSE;
-
-#ifdef __alpha__
- /*
- * for Alpha, we need to map DENSE memory as well, for
- * setting CPUToScreenColorExpandBase.
- */
- pXGI->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
- pXGI->PciTag, pXGI->IOAddress, 0x10000);
-
- if (pXGI->IOBaseDense == NULL)
- return FALSE;
-#endif /* __alpha__ */
-
- pXGI->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
- pXGI->PciTag,
- (unsigned long) pXGI->FbAddress,
- pXGI->FbMapSize);
-
- PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n", (ULONG) (pXGI->FbBase)));
-
- if (pXGI->FbBase == NULL)
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-
-/*
- * Unmap the framebuffer and MMIO memory.
- */
-
-static Bool
-XGIUnmapMem(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
-
-
- /* In dual head mode, we must not unmap if the other head still
- * assumes memory as mapped
- */
- if (IS_DUAL_HEAD(pXGI)) {
- if (pXGIEnt->MapCountIOBase) {
- pXGIEnt->MapCountIOBase--;
- if ((pXGIEnt->MapCountIOBase == 0) || (pXGIEnt->forceUnmapIOBase)) {
-#ifdef XSERVER_LIBPCIACCESS
- pci_device_unmap_region(pXGI->PciInfo, 1);
-#else
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->IOBase,
- (pXGI->mmioSize * 1024));
-#endif
- pXGIEnt->IOBase = NULL;
- pXGIEnt->MapCountIOBase = 0;
- pXGIEnt->forceUnmapIOBase = FALSE;
- }
- pXGI->IOBase = NULL;
- }
-#ifdef __alpha__
-#ifdef XSERVER_LIBPCIACCESS
-#error "How to do dense mapping on Alpha?"
-#else
- if (pXGIEnt->MapCountIOBaseDense) {
- pXGIEnt->MapCountIOBaseDense--;
- if ((pXGIEnt->MapCountIOBaseDense == 0)
- || (pXGIEnt->forceUnmapIOBaseDense)) {
- xf86UnMapVidMem(pScrn->scrnIndex,
- (pointer) pXGIEnt->IOBaseDense,
- (pXGI->mmioSize * 1024));
- pXGIEnt->IOBaseDense = NULL;
- pXGIEnt->MapCountIOBaseDense = 0;
- pXGIEnt->forceUnmapIOBaseDense = FALSE;
- }
- pXGI->IOBaseDense = NULL;
- }
-#endif
-#endif /* __alpha__ */
- if (pXGIEnt->MapCountFbBase) {
- pXGIEnt->MapCountFbBase--;
- if ((pXGIEnt->MapCountFbBase == 0) || (pXGIEnt->forceUnmapFbBase)) {
-#ifdef XSERVER_LIBPCIACCESS
- pci_device_unmap_region(pXGI->PciInfo, 0);
-#else
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->FbBase,
- pXGI->FbMapSize);
-#endif
- pXGIEnt->FbBase = NULL;
- pXGIEnt->MapCountFbBase = 0;
- pXGIEnt->forceUnmapFbBase = FALSE;
-
- }
- pXGI->FbBase = NULL;
- }
- }
- else {
-#ifdef XSERVER_LIBPCIACCESS
- pci_device_unmap_region(pXGI->PciInfo, 0);
- pci_device_unmap_region(pXGI->PciInfo, 1);
-#else
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBase,
- (pXGI->mmioSize * 1024));
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->FbBase,
- pXGI->FbMapSize);
-#endif
- pXGI->IOBase = NULL;
- pXGI->FbBase = NULL;
-
-#ifdef __alpha__
-#ifdef XSERVER_LIBPCIACCESS
-#error "How to do dense mapping on Alpha?"
-#else
- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBaseDense,
- (pXGI->mmioSize * 1024));
- pXGI->IOBaseDense = NULL;
-#endif
-#endif
- }
-
- return TRUE;
-}
-
-/*
- * This function saves the video state.
- */
-static void
-XGISave(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI;
- vgaRegPtr vgaReg;
- XGIRegPtr xgiReg;
-
- PDEBUG(ErrorF("XGISave()\n"));
-
- pXGI = XGIPTR(pScrn);
-
- /* We always save master & slave */
- if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
- return;
-
- vgaReg = &VGAHWPTR(pScrn)->SavedReg;
- xgiReg = &pXGI->SavedReg;
-
- vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
-
- xgiSaveUnlockExtRegisterLock(pXGI, &xgiReg->xgiRegs3C4[0x05],
- &xgiReg->xgiRegs3D4[0x80]);
-
- (*pXGI->XGISave) (pScrn, xgiReg);
-
- /* "Save" these again as they may have been changed prior to XGISave() call */
-}
-
-
-/*
- * Initialise a new mode. This is currently done using the
- * "initialise struct, restore/write struct to HW" model for
- * the old chipsets (5597/530/6326). For newer chipsets,
- * we use our own mode switching code (or VESA).
- */
-
-static Bool
-XGIModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- vgaRegPtr vgaReg;
- XGIPtr pXGI = XGIPTR(pScrn);
- XGIRegPtr xgiReg;
-#ifdef __powerpc__
- unsigned char tmpval;
-#endif
-
-
- /* PDEBUG(ErrorF("XGIModeInit(). \n")); */
- PDEBUG(ErrorF
- ("XGIModeInit Resolution (%d, %d) \n", mode->HDisplay,
- mode->VDisplay));
- PDEBUG(ErrorF("XGIModeInit VVRefresh (%8.3f) \n", mode->VRefresh));
- PDEBUG(ErrorF("XGIModeInit Color Depth (%d) \n", pScrn->depth));
-
- /* Jong Lin 08-26-2005; save current mode */
- Volari_SetDefaultIdleWait(pXGI, mode->HDisplay, pScrn->depth);
-
- andXGIIDXREG(XGICR, 0x11, 0x7f); /* Unlock CRTC registers */
-
- XGIModifyModeInfo(mode); /* Quick check of the mode parameters */
-
-
- if (IS_DUAL_HEAD(pXGI)) {
- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
-
- if (!(*pXGI->ModeInit) (pScrn, mode)) {
- XGIErrorLog(pScrn, "ModeInit() failed\n");
- return FALSE;
- }
-
- pScrn->vtSema = TRUE;
-
- /* Head 2 (slave) is always CRT1 */
- XGIPreSetMode(pScrn, mode, XGI_MODE_CRT1);
- if (!XGIBIOSSetModeCRT1(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn,
- mode)) {
- XGIErrorLog(pScrn, "XGIBIOSSetModeCRT1() failed\n");
- return FALSE;
- }
- XGIPostSetMode(pScrn, &pXGI->ModeReg);
- XGIAdjustFrame(pXGIEnt->pScrn_1->scrnIndex, pXGIEnt->pScrn_1->frameX0,
- pXGIEnt->pScrn_1->frameY0, 0);
- }
- else
- {
- /* For other chipsets, use the old method */
-
- /* Initialise the ModeReg values */
- if (!vgaHWInit(pScrn, mode)) {
- XGIErrorLog(pScrn, "vgaHWInit() failed\n");
- return FALSE;
- }
-
- /* Reset our PIOOffset as vgaHWInit might have reset it */
- VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
-#ifdef XSERVER_LIBPCIACCESS
- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
-#else
- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
-#endif
- ;
-
- /* Prepare the register contents */
- if (!(*pXGI->ModeInit) (pScrn, mode)) {
- XGIErrorLog(pScrn, "ModeInit() failed\n");
- return FALSE;
- }
-
- pScrn->vtSema = TRUE;
-
- /* Program the registers */
- vgaHWProtect(pScrn, TRUE);
- vgaReg = &hwp->ModeReg;
- xgiReg = &pXGI->ModeReg;
-
- vgaReg->Attribute[0x10] = 0x01;
- if (pScrn->bitsPerPixel > 8) {
- vgaReg->Graphics[0x05] = 0x00;
- }
-
- vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
-
- (*pXGI->XGIRestore) (pScrn, xgiReg);
-
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "REAL REGISTER CONTENTS AFTER SETMODE:\n");
- (*pXGI->ModeInit) (pScrn, mode);
-#endif
-
- vgaHWProtect(pScrn, FALSE);
- }
-
-
- if (pXGI->Chipset == PCI_CHIP_XGIXG40 ||
- pXGI->Chipset == PCI_CHIP_XGIXG20) {
- /* PDEBUG(XGIDumpRegs(pScrn)) ; */
- PDEBUG(ErrorF(" *** PreSetMode(). \n"));
- XGIPreSetMode(pScrn, mode, XGI_MODE_SIMU);
- /* PDEBUG(XGIDumpRegs(pScrn)) ; */
- PDEBUG(ErrorF(" *** Start SetMode() \n"));
-
- if (!XGIBIOSSetMode(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, mode)) {
- XGIErrorLog(pScrn, "XGIBIOSSetModeCRT() failed\n");
- return FALSE;
- }
- Volari_EnableAccelerator(pScrn);
- /* XGIPostSetMode(pScrn, &pXGI->ModeReg); */
- /* outXGIIDXREG(XGISR, 0x20, 0xA1) ; */
- /* PDEBUG(XGIDumpRegs(pScrn)) ; */
- }
-
- /* Update Currentlayout */
- pXGI->CurrentLayout.mode = mode;
-
-#ifdef __powerpc__
- inXGIIDXREG(XGICR, 0x4D, tmpval);
- if (pScrn->depth == 16)
- tmpval = (tmpval & 0xE0) | 0x0B; //word swap
- else if (pScrn->depth == 24)
- tmpval = (tmpval & 0xE0) | 0x15; //dword swap
- else
- tmpval = tmpval & 0xE0; // no swap
-
- outXGIIDXREG(XGICR, 0x4D, tmpval);
-#endif
-
- return TRUE;
-}
-
-
-/*
- * Restore the initial mode. To be used internally only!
- */
-static void
-XGIRestore(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- XGIRegPtr xgiReg = &pXGI->SavedReg;
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- vgaRegPtr vgaReg = &hwp->SavedReg;
-
-
- PDEBUG(ErrorF("XGIRestore():\n"));
-
- /* Wait for the accelerators */
- if (pXGI->AccelInfoPtr) {
- (*pXGI->AccelInfoPtr->Sync) (pScrn);
- }
-
- vgaHWProtect(pScrn, TRUE);
-
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-#endif
-
- (*pXGI->XGIRestore) (pScrn, xgiReg);
-
- vgaHWProtect(pScrn, TRUE);
- if (pXGI->Primary) {
- vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
- }
-
- xgiRestoreExtRegisterLock(pXGI, xgiReg->xgiRegs3C4[5],
- xgiReg->xgiRegs3D4[0x80]);
- vgaHWProtect(pScrn, FALSE);
-}
-
-
-/* Our generic BlockHandler for Xv */
-static void
-XGIBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- ScrnInfoPtr pScrn = xf86Screens[i];
- XGIPtr pXGI = XGIPTR(pScrn);
-
- pScreen->BlockHandler = pXGI->BlockHandler;
- (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
- pScreen->BlockHandler = XGIBlockHandler;
-
- if (pXGI->VideoTimerCallback) {
- (*pXGI->VideoTimerCallback) (pScrn, currentTime.milliseconds);
- }
-
- if (pXGI->RenderCallback) {
- (*pXGI->RenderCallback) (pScrn);
- }
-}
-
-/* Mandatory
- * This gets called at the start of each server generation
- *
- * We use pScrn and not CurrentLayout here, because the
- * properties we use have not changed (displayWidth,
- * depth, bitsPerPixel)
- */
-static Bool
-XGIScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
-{
- ScrnInfoPtr pScrn;
- vgaHWPtr hwp;
- XGIPtr pXGI;
- int ret;
- VisualPtr visual;
- unsigned long OnScreenSize;
- int height, width, displayWidth;
- unsigned char *FBStart;
- XGIEntPtr pXGIEnt = NULL;
-
- ErrorF("XGIScreenInit\n");
- pScrn = xf86Screens[pScreen->myNum];
-
- hwp = VGAHWPTR(pScrn);
-
- pXGI = XGIPTR(pScrn);
-
-#if !defined(__powerpc__)
- if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
- if (xf86LoadSubModule(pScrn, "vbe")) {
- xf86LoaderReqSymLists(vbeSymbols, NULL);
- pXGI->pVbe = VBEExtendedInit(NULL, pXGI->pEnt->index,
- SET_BIOS_SCRATCH |
- RESTORE_BIOS_SCRATCH);
- }
- else {
- XGIErrorLog(pScrn, "Failed to load VBE submodule\n");
- }
- }
-#endif /* if !defined(__powerpc__) */
-
- if (IS_DUAL_HEAD(pXGI)) {
- pXGIEnt = ENTITY_PRIVATE(pXGI);
- pXGIEnt->refCount++;
- }
-
- /* Map the VGA memory and get the VGA IO base */
- if (pXGI->Primary) {
- hwp->MapSize = 0x10000; /* Standard 64k VGA window */
- if (!vgaHWMapMem(pScrn)) {
- XGIErrorLog(pScrn, "Could not map VGA memory window\n");
- return FALSE;
- }
- }
- vgaHWGetIOBase(hwp);
-
- /* Patch the PIOOffset inside vgaHW to use
- * our relocated IO ports.
- */
- VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
-#ifdef XSERVER_LIBPCIACCESS
- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
-#else
- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
-#endif
- ;
-
- /* Map the XGI memory and MMIO areas */
- if (!XGIMapMem(pScrn)) {
- XGIErrorLog(pScrn, "XGIMapMem() failed\n");
- return FALSE;
- }
-
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-#endif
-
- /* Save the current state */
- XGISave(pScrn);
-
-
- PDEBUG(ErrorF("--- ScreenInit --- \n"));
- PDEBUG(XGIDumpRegs(pScrn));
-
- /* Initialise the first mode */
- if (!XGIModeInit(pScrn, pScrn->currentMode)) {
- XGIErrorLog(pScrn, "XGIModeInit() failed\n");
- return FALSE;
- }
-
- PDEBUG(ErrorF("--- XGIModeInit --- \n"));
- PDEBUG(XGIDumpRegs(pScrn));
-
- /* Darken the screen for aesthetic reasons */
- /* Not using Dual Head variant on purpose; we darken
- * the screen for both displays, and un-darken
- * it when the second head is finished
- */
- XGISaveScreen(pScreen, SCREEN_SAVER_ON);
-
- /* Set the viewport */
- XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- /*
- * The next step is to setup the screen's visuals, and initialise the
- * framebuffer code. In cases where the framebuffer's default
- * choices for things like visual layouts and bits per RGB are OK,
- * this may be as simple as calling the framebuffer's ScreenInit()
- * function. If not, the visuals will need to be setup before calling
- * a fb ScreenInit() function and fixed up after.
- *
- * For most PC hardware at depths >= 8, the defaults that cfb uses
- * are not appropriate. In this driver, we fixup the visuals after.
- */
-
- /*
- * Reset visual list.
- */
- miClearVisualTypes();
-
- /* Setup the visuals we support. */
-
- /*
- * For bpp > 8, the default visuals are not acceptable because we only
- * support TrueColor and not DirectColor.
- */
- if (!miSetVisualTypes(pScrn->depth,
- (pScrn->bitsPerPixel > 8) ?
- TrueColorMask : miGetDefaultVisualMask(pScrn->
- depth),
- pScrn->rgbBits, pScrn->defaultVisual)) {
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- XGIErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
- pScrn->bitsPerPixel);
- return FALSE;
- }
-
- width = pScrn->virtualX;
- height = pScrn->virtualY;
- displayWidth = pScrn->displayWidth;
-
- if (pXGI->Rotate) {
- height = pScrn->virtualX;
- width = pScrn->virtualY;
- }
-
- if (pXGI->ShadowFB) {
- pXGI->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
- pXGI->ShadowPtr = xalloc(pXGI->ShadowPitch * height);
- displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3);
- FBStart = pXGI->ShadowPtr;
- }
- else {
- pXGI->ShadowPtr = NULL;
- FBStart = pXGI->FbBase;
- }
-
- if (!miSetPixmapDepths()) {
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- XGIErrorLog(pScrn, "miSetPixmapDepths() failed\n");
- return FALSE;
- }
-
- /* Point cmdQueuePtr to pXGIEnt for shared usage
- * (same technique is then eventually used in DRIScreeninit).
- */
- if (IS_SECOND_HEAD(pXGI))
- pXGI->cmdQueueLenPtr = &(XGIPTR(pXGIEnt->pScrn_1)->cmdQueueLen);
- else
- pXGI->cmdQueueLenPtr = &(pXGI->cmdQueueLen);
-
- pXGI->cmdQueueLen = 0; /* Force an EngineIdle() at start */
-
-#ifdef XF86DRI
- if(pXGI->loadDRI) {
- /* No DRI in dual head mode */
- if (IS_DUAL_HEAD(pXGI)) {
- pXGI->directRenderingEnabled = FALSE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "DRI not supported in Dual Head mode\n");
- }
- else if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
- PDEBUG(ErrorF("--- DRI not supported \n"));
- xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
- "DRI not supported on this chipset\n");
- pXGI->directRenderingEnabled = FALSE;
- }
- else {
- pXGI->directRenderingEnabled = XGIDRIScreenInit(pScreen);
- PDEBUG(ErrorF("--- DRI supported \n"));
- }
- }
-#endif
-
- /*
- * Call the framebuffer layer's ScreenInit function, and fill in other
- * pScreen fields.
- */
- switch (pScrn->bitsPerPixel) {
- case 24:
- case 8:
- case 16:
- case 32:
- ret = fbScreenInit(pScreen, FBStart, width,
- height, pScrn->xDpi, pScrn->yDpi,
- displayWidth, pScrn->bitsPerPixel);
- break;
- default:
- ret = FALSE;
- break;
- }
- if (!ret) {
- XGIErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
- pScrn->bitsPerPixel);
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- return FALSE;
- }
-
- if (pScrn->bitsPerPixel > 8) {
- /* Fixup RGB ordering */
- visual = pScreen->visuals + pScreen->numVisuals;
- while (--visual >= pScreen->visuals) {
- if ((visual->class | DynamicClass) == DirectColor) {
- visual->offsetRed = pScrn->offset.red;
- visual->offsetGreen = pScrn->offset.green;
- visual->offsetBlue = pScrn->offset.blue;
- visual->redMask = pScrn->mask.red;
- visual->greenMask = pScrn->mask.green;
- visual->blueMask = pScrn->mask.blue;
- }
- }
- }
-
- /* Initialize RENDER ext; must be after RGB ordering fixed */
- fbPictureInit(pScreen, 0, 0);
-
- /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */
- if (!pXGI->ShadowFB)
- XGIDGAInit(pScreen);
-
- xf86SetBlackWhitePixels(pScreen);
-
- if (!pXGI->NoAccel) {
- /* Volari_EnableAccelerator(pScrn); */
- PDEBUG(ErrorF("---Volari Accel.. \n"));
- Volari_AccelInit(pScreen);
- }
-
- PDEBUG(ErrorF("--- AccelInit --- \n"));
- PDEBUG(XGIDumpRegs(pScrn));
-
- miInitializeBackingStore(pScreen);
- xf86SetBackingStore(pScreen);
- xf86SetSilkenMouse(pScreen);
-
- /* Initialise cursor functions */
- miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
-
- if (pXGI->HWCursor) {
- XGIHWCursorInit(pScreen);
- }
-
- /* Initialise default colourmap */
- if (!miCreateDefColormap(pScreen)) {
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- XGIErrorLog(pScrn, "miCreateDefColormap() failed\n");
- return FALSE;
- }
- if (!xf86HandleColormaps
- (pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
- XGILoadPalette, NULL,
- CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
- PDEBUG(ErrorF("XGILoadPalette() check-return. \n"));
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- XGIErrorLog(pScrn, "xf86HandleColormaps() failed\n");
- return FALSE;
- }
-
-/*
- if (!xf86HandleColormaps(pScreen, 256, 8, XGILoadPalette, NULL,
- CMAP_RELOAD_ON_MODE_SWITCH))
- {
- return FALSE;
- }
-*/
- xf86DPMSInit(pScreen, (DPMSSetProcPtr) XGIDisplayPowerManagementSet, 0);
-
- /* Init memPhysBase and fbOffset in pScrn */
- pScrn->memPhysBase = pXGI->FbAddress;
- pScrn->fbOffset = 0;
-
- pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
-
-#if defined(XvExtension)
- if (!pXGI->NoXvideo) {
- XGIInitVideo(pScreen);
- }
-#endif
-
-#ifdef XF86DRI
- if (pXGI->directRenderingEnabled) {
- /* Now that mi, drm and others have done their thing,
- * complete the DRI setup.
- */
- pXGI->directRenderingEnabled = XGIDRIFinishScreenInit(pScreen);
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering %sabled\n",
- (pXGI->directRenderingEnabled) ? "en" : "dis");
- if (pXGI->directRenderingEnabled) {
- /* TODO */
- /* XGISetLFBConfig(pXGI); */
- }
-#endif
-
- /* Wrap some funcs and setup remaining SD flags */
-
- pXGI->XGI_SD_Flags &= ~(XGI_SD_PSEUDOXINERAMA);
-
- pXGI->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = XGICloseScreen;
- if (IS_DUAL_HEAD(pXGI))
- pScreen->SaveScreen = XGISaveScreenDH;
- else
- pScreen->SaveScreen = XGISaveScreen;
-
- /* Install BlockHandler */
- pXGI->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = XGIBlockHandler;
-
- /* Report any unused options (only for the first generation) */
- if (serverGeneration == 1) {
- xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- }
-
- /* Clear frame buffer */
- /* For CRT2, we don't do that at this point in dual head
- * mode since the mode isn't switched at this time (it will
- * be reset when setting the CRT1 mode). Hence, we just
- * save the necessary data and clear the screen when
- * going through this for CRT1.
- */
-
- OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
- * (pScrn->bitsPerPixel >> 3);
-
- /* Turn on the screen now */
- /* We do this in dual head mode after second head is finished */
- if (IS_DUAL_HEAD(pXGI)) {
- if (IS_SECOND_HEAD(pXGI)) {
- bzero(pXGI->FbBase, OnScreenSize);
- bzero(pXGIEnt->FbBase1, pXGIEnt->OnScreenSize1);
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- }
- else {
- pXGIEnt->FbBase1 = pXGI->FbBase;
- pXGIEnt->OnScreenSize1 = OnScreenSize;
- }
- }
- else {
- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
- bzero(pXGI->FbBase, OnScreenSize);
- }
-
- pXGI->XGI_SD_Flags &= ~XGI_SD_ISDEPTH8;
- if (pXGI->CurrentLayout.bitsPerPixel == 8) {
- pXGI->XGI_SD_Flags |= XGI_SD_ISDEPTH8;
- pXGI->XGI_SD_Flags &= ~XGI_SD_SUPPORTXVGAMMA1;
- }
- PDEBUG(ErrorF("XGIScreenInit() End. \n"));
- XGIDumpPalette(pScrn);
- return TRUE;
-}
-
-/* Usually mandatory */
-Bool
-XGISwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- XGIPtr pXGI = XGIPTR(pScrn);
-
- ErrorF("XGISwitchMode\n");
-
- if (!pXGI->NoAccel) {
- if (pXGI->AccelInfoPtr) {
- (*pXGI->AccelInfoPtr->Sync) (pScrn);
- PDEBUG(ErrorF("XGISwitchMode Accel Enabled. \n"));
- }
- }
- PDEBUG(ErrorF
- ("XGISwitchMode (%d, %d) \n", mode->HDisplay, mode->VDisplay));
-
- if (!(XGIModeInit(xf86Screens[scrnIndex], mode)))
- return FALSE;
-
- /* Since RandR (indirectly) uses SwitchMode(), we need to
- * update our Xinerama info here, too, in case of resizing
- */
- return TRUE;
-}
-
-/* static void
-XGISetStartAddressCRT1(XGIPtr pXGI, unsigned long base)
-{
- unsigned char cr11backup;
-
- inXGIIDXREG(XGICR, 0x11, cr11backup);
- andXGIIDXREG(XGICR, 0x11, 0x7F);
- outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
- outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
- outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
-
-
- setXGIIDXREG(XGICR, 0x11, 0x7F,(cr11backup & 0x80));
-} */
-
-#ifdef XGIMERGED
-/* static Bool
-InRegion(int x, int y, region r)
-{
- return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
-} */
-
-/* static void
-XGIAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned long base;
-
- base = y * pXGI->CurrentLayout.displayWidth + x;
- switch(pXGI->CurrentLayout.bitsPerPixel)
- {
- case 16: base >>= 1; break;
- case 32: break;
- default: base >>= 2;
- }
- XGISetStartAddressCRT1(pXGI, base);
-} */
-
-/* static void
-XGIMergePointerMoved(int scrnIndex, int x, int y)
-{
- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
- XGIPtr pXGI = XGIPTR(pScrn1);
- ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
- region out, in1, in2, f2, f1;
- int deltax, deltay;
-
- f1.x0 = pXGI->CRT1frameX0;
- f1.x1 = pXGI->CRT1frameX1;
- f1.y0 = pXGI->CRT1frameY0;
- f1.y1 = pXGI->CRT1frameY1;
- f2.x0 = pScrn2->frameX0;
- f2.x1 = pScrn2->frameX1;
- f2.y0 = pScrn2->frameY0;
- f2.y1 = pScrn2->frameY1;
-
- out.x0 = pScrn1->frameX0;
- out.x1 = pScrn1->frameX1;
- out.y0 = pScrn1->frameY0;
- out.y1 = pScrn1->frameY1;
-
- in1 = out;
- in2 = out;
- switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
- {
- case xgiLeftOf:
- in1.x0 = f1.x0;
- in2.x1 = f2.x1;
- break;
- case xgiRightOf:
- in1.x1 = f1.x1;
- in2.x0 = f2.x0;
- break;
- case xgiBelow:
- in1.y1 = f1.y1;
- in2.y0 = f2.y0;
- break;
- case xgiAbove:
- in1.y0 = f1.y0;
- in2.y1 = f2.y1;
- break;
- case xgiClone:
- break;
- }
-
- deltay = 0;
- deltax = 0;
-
- if(InRegion(x, y, out))
- {
-
- if(InRegion(x, y, in1) && !InRegion(x, y, f1))
- {
- REBOUND(f1.x0, f1.x1, x);
- REBOUND(f1.y0, f1.y1, y);
- deltax = 1;
- }
- if(InRegion(x, y, in2) && !InRegion(x, y, f2))
- {
- REBOUND(f2.x0, f2.x1, x);
- REBOUND(f2.y0, f2.y1, y);
- deltax = 1;
- }
-
- }
- else
- {
-
- if(out.x0 > x)
- {
- deltax = x - out.x0;
- }
- if(out.x1 < x)
- {
- deltax = x - out.x1;
- }
- if(deltax)
- {
- pScrn1->frameX0 += deltax;
- pScrn1->frameX1 += deltax;
- f1.x0 += deltax;
- f1.x1 += deltax;
- f2.x0 += deltax;
- f2.x1 += deltax;
- }
-
- if(out.y0 > y)
- {
- deltay = y - out.y0;
- }
- if(out.y1 < y)
- {
- deltay = y - out.y1;
- }
- if(deltay)
- {
- pScrn1->frameY0 += deltay;
- pScrn1->frameY1 += deltay;
- f1.y0 += deltay;
- f1.y1 += deltay;
- f2.y0 += deltay;
- f2.y1 += deltay;
- }
-
- switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
- {
- case xgiLeftOf:
- if(x >= f1.x0)
- { REBOUND(f1.y0, f1.y1, y); }
- if(x <= f2.x1)
- { REBOUND(f2.y0, f2.y1, y); }
- break;
- case xgiRightOf:
- if(x <= f1.x1)
- { REBOUND(f1.y0, f1.y1, y); }
- if(x >= f2.x0)
- { REBOUND(f2.y0, f2.y1, y); }
- break;
- case xgiBelow:
- if(y <= f1.y1)
- { REBOUND(f1.x0, f1.x1, x); }
- if(y >= f2.y0)
- { REBOUND(f2.x0, f2.x1, x); }
- break;
- case xgiAbove:
- if(y >= f1.y0)
- { REBOUND(f1.x0, f1.x1, x); }
- if(y <= f2.y1)
- { REBOUND(f2.x0, f2.x1, x); }
- break;
- case xgiClone:
- break;
- }
-
- }
-
- if(deltax || deltay)
- {
- pXGI->CRT1frameX0 = f1.x0;
- pXGI->CRT1frameY0 = f1.y0;
- pScrn2->frameX0 = f2.x0;
- pScrn2->frameY0 = f2.y0;
-
- pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
- pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
- pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
- pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
- pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
- pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
-
- XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
- }
-} */
-
-
-/* static void
-XGIAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
- XGIPtr pXGI = XGIPTR(pScrn1);
- ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
- int VTotal = pXGI->CurrentLayout.mode->VDisplay;
- int HTotal = pXGI->CurrentLayout.mode->HDisplay;
- int VMax = VTotal;
- int HMax = HTotal;
-
- BOUND(x, 0, pScrn1->virtualX - HTotal);
- BOUND(y, 0, pScrn1->virtualY - VTotal);
-
- switch(SDMPTR(pScrn1)->CRT2Position)
- {
- case xgiLeftOf:
- pScrn2->frameX0 = x;
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
- pXGI->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
- BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
- break;
- case xgiRightOf:
- pXGI->CRT1frameX0 = x;
- BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
- pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
- break;
- case xgiAbove:
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- pScrn2->frameY0 = y;
- BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- pXGI->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
- break;
- case xgiBelow:
- BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- pXGI->CRT1frameY0 = y;
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
- break;
- case xgiClone:
- BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
- BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
- break;
- }
-
- BOUND(pXGI->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
- BOUND(pXGI->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
- BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
- BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
-
- pScrn1->frameX0 = x;
- pScrn1->frameY0 = y;
-
- pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
- pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
- pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
- pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
- pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
- pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
-
- XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
-} */
-#endif
-
-/*
- * This function is used to initialize the Start Address - the first
- * displayed location in the video memory.
- *
- * Usually mandatory
- */
-void
-XGIAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned long base;
- unsigned char ucSR5Stat, ucTemp;
-
- ErrorF("AdjustFrame %d\n", scrnIndex);
- inXGIIDXREG(XGISR, 0x05, ucSR5Stat);
- if (ucSR5Stat == 0xA1)
- ucSR5Stat = 0x86;
- outXGIIDXREG(XGISR, 0x05, 0x86);
-
- base = (pScrn->bitsPerPixel + 7) / 8;
- base *= x;
- base += pXGI->scrnOffset * y;
- base >>= 2;
-
- switch (pXGI->Chipset) {
- case PCI_CHIP_XGIXG40:
- default:
-
- ucTemp = base & 0xFF;
- outXGIIDXREG(XGICR, 0x0D, ucTemp);
- ucTemp = (base >> 8) & 0xFF;
- outXGIIDXREG(XGICR, 0x0C, ucTemp);
- ucTemp = (base >> 16) & 0xFF;
- outXGIIDXREG(XGISR, 0x0D, ucTemp);
- ucTemp = (base >> 24) & 0x01;
- setXGIIDXREG(XGISR, 0x37, 0xFE, ucTemp);
-
-/* if (pXGI->VBFlags) {
- XGI_UnLockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
- ucTemp = base & 0xFF ; outXGIIDXREG( XGIPART1, 6 , ucTemp ) ;
- ucTemp = (base>>8) & 0xFF ; outXGIIDXREG( XGIPART1, 5 , ucTemp ) ;
- ucTemp = (base>>16) & 0xFF ; outXGIIDXREG( XGIPART1, 4 , ucTemp ) ;
- ucTemp = (base>>24) & 0x01 ; ucTemp <<= 7 ;
- setXGIIDXREG( XGIPART1, 0x2, 0x7F, ucTemp ) ;
-
- XGI_LockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
- }
- */
- break;
-
- }
-
- outXGIIDXREG(XGISR, 0x05, ucSR5Stat);
-
-}
-
-/*
- * This is called when VT switching back to the X server. Its job is
- * to reinitialise the video mode.
- * Mandatory!
- */
-static Bool
-XGIEnterVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- XGIPtr pXGI = XGIPTR(pScrn);
-
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-
- if (!XGIModeInit(pScrn, pScrn->currentMode)) {
- XGIErrorLog(pScrn, "XGIEnterVT: XGIModeInit() failed\n");
- return FALSE;
- }
-
- XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
-#ifdef XF86DRI
- if (pXGI->directRenderingEnabled) {
- DRIUnlock(screenInfo.screens[scrnIndex]);
- }
-#endif
-
- if ((!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) && (pXGI->ResetXv)) {
- (pXGI->ResetXv) (pScrn);
- }
-
- return TRUE;
-}
-
-/*
- * This is called when VT switching away from the X server. Its job is
- * to restore the previous (text) mode.
- * Mandatory!
- */
-static void
-XGILeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- XGIPtr pXGI = XGIPTR(pScrn);
-#ifdef XF86DRI
- ScreenPtr pScreen;
-
- PDEBUG(ErrorF("XGILeaveVT()\n"));
- if (pXGI->directRenderingEnabled) {
- pScreen = screenInfo.screens[scrnIndex];
- DRILock(pScreen, 0);
- }
-#endif
-
- if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
- return;
-
- if (pXGI->CursorInfoPtr) {
- /* Because of the test and return above, we know that this is not
- * the second head.
- */
- pXGI->CursorInfoPtr->HideCursor(pScrn);
- XGI_WaitBeginRetrace(pXGI->RelIO);
- }
-
- XGIRestore(pScrn);
-
-
- /* We use (otherwise unused) bit 7 to indicate that we are running to keep
- * xgifb to change the displaymode (this would result in lethal display
- * corruption upon quitting X or changing to a VT until a reboot).
- */
- vgaHWLock(hwp);
-}
-
-
-/*
- * This is called at the end of each server generation. It restores the
- * original (text) mode. It should really also unmap the video memory too.
- * Mandatory!
- */
-static Bool
-XGICloseScreen(int scrnIndex, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- XGIPtr pXGI = XGIPTR(pScrn);
-
-
-#ifdef XF86DRI
- if (pXGI->directRenderingEnabled) {
- XGIDRICloseScreen(pScreen);
- pXGI->directRenderingEnabled = FALSE;
- }
-#endif
-
- if (pScrn->vtSema) {
- if (pXGI->CursorInfoPtr
- && (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI))) {
- pXGI->CursorInfoPtr->HideCursor(pScrn);
- XGI_WaitBeginRetrace(pXGI->RelIO);
- }
-
-
- XGIRestore(pScrn);
- vgaHWLock(hwp);
- }
-
- /* We should restore the mode number in case vtsema = false as well,
- * but since we haven't register access then we can't do it. I think
- * I need to rework the save/restore stuff, like saving the video
- * status when returning to the X server and by that save me the
- * trouble if xgifb was started from a textmode VT while X was on.
- */
-
- XGIUnmapMem(pScrn);
- vgaHWUnmapMem(pScrn);
-
- if (IS_DUAL_HEAD(pXGI)) {
- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
- pXGIEnt->refCount--;
- }
-
- if (pXGI->pInt) {
- xf86FreeInt10(pXGI->pInt);
- pXGI->pInt = NULL;
- }
-
- if (pXGI->AccelLinearScratch) {
- xf86FreeOffscreenLinear(pXGI->AccelLinearScratch);
- pXGI->AccelLinearScratch = NULL;
- }
-
- if (pXGI->AccelInfoPtr) {
- XAADestroyInfoRec(pXGI->AccelInfoPtr);
- pXGI->AccelInfoPtr = NULL;
- }
-
- if (pXGI->CursorInfoPtr) {
- xf86DestroyCursorInfoRec(pXGI->CursorInfoPtr);
- pXGI->CursorInfoPtr = NULL;
- }
-
- if (pXGI->ShadowPtr) {
- xfree(pXGI->ShadowPtr);
- pXGI->ShadowPtr = NULL;
- }
-
- if (pXGI->DGAModes) {
- xfree(pXGI->DGAModes);
- pXGI->DGAModes = NULL;
- }
-
- if (pXGI->adaptor) {
- xfree(pXGI->adaptor);
- pXGI->adaptor = NULL;
- pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
- }
-
- pScrn->vtSema = FALSE;
-
- /* Restore Blockhandler */
- pScreen->BlockHandler = pXGI->BlockHandler;
-
- pScreen->CloseScreen = pXGI->CloseScreen;
-
- return (*pScreen->CloseScreen) (scrnIndex, pScreen);
-}
-
-
-/* Free up any per-generation data structures */
-
-/* Optional */
-static void
-XGIFreeScreen(int scrnIndex, int flags)
-{
- if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) {
- vgaHWFreeHWRec(xf86Screens[scrnIndex]);
- }
-
- XGIFreeRec(xf86Screens[scrnIndex]);
-}
-
-
-/* Checks if a mode is suitable for the selected chipset. */
-
-static int
-XGIValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- XGIPtr pXGI = XGIPTR(pScrn);
- int HDisplay = mode->HDisplay;
- int VDisplay = mode->VDisplay;
- int Clock = mode->Clock;
- int i = 0;
- int VRefresh;
-
- VRefresh =
- (int) ((float) (Clock * 1000) /
- (float) (mode->VTotal * mode->HTotal) + 0.5);
-
- PDEBUG5(ErrorF("XGIValidMode()."));
- PDEBUG5(ErrorF
- ("CLK=%5.3fMhz %dx%d@%d ", (float) Clock / 1000, HDisplay,
- VDisplay, VRefresh));
- PDEBUG5(ErrorF("(VT,HT)=(%d,%d)\n", mode->VTotal, mode->HTotal));
-
- if (pXGI->VBFlags & CRT2_LCD) {
- if ((HDisplay > 1600 && VDisplay > 1200)
- || (HDisplay < 640 && VDisplay < 480)) {
- PDEBUG5(ErrorF("skip by LCD limit\n"));
- return (MODE_NOMODE);
- }
- /* if( VRefresh != 60) return(MODE_NOMODE) ; */
- }
- else if (pXGI->VBFlags & CRT2_TV) {
- if ((HDisplay > 1024 && VDisplay > 768) ||
- (HDisplay < 640 && VDisplay < 480) || (VRefresh != 60)) {
- PDEBUG5(ErrorF("skip by TV limit\n"));
- return (MODE_NOMODE);
- }
- }
- else if (pXGI->VBFlags & CRT2_VGA) {
- if ((HDisplay > 1600 && VDisplay > 1200) ||
- (HDisplay < 640 && VDisplay < 480)) {
- PDEBUG5(ErrorF("skip by CRT2 limit\n"));
- return (MODE_NOMODE);
- }
- }
-
- if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
- XgiMode = XG20_Mode;
- }
- else {
- XgiMode = XGI_Mode;
- }
-
- while ((XgiMode[i].Clock != Clock) ||
- (XgiMode[i].HDisplay != HDisplay) ||
- (XgiMode[i].VDisplay != VDisplay)) {
- if (XgiMode[i].Clock == 0) {
- PDEBUG5(ErrorF
- ("--- NO_Mode support for %dx%d@%dHz\n", HDisplay,
- VDisplay, VRefresh));
- return (MODE_NOMODE);
- }
- else
- i++;
- }
- PDEBUG5(ErrorF("Mode OK\n"));
-
- return (MODE_OK);
-}
-
-/* Do screen blanking
- *
- * Mandatory
- */
-static Bool
-XGISaveScreen(ScreenPtr pScreen, int mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if ((pScrn != NULL) && pScrn->vtSema) {
-
- XGIPtr pXGI = XGIPTR(pScrn);
-
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-#endif
- }
-
- return vgaHWSaveScreen(pScreen, mode);
-}
-
-/* SaveScreen for dual head mode */
-static Bool
-XGISaveScreenDH(ScreenPtr pScreen, int mode)
-{
-#ifdef XGIDUALHEAD
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if ((pScrn != NULL) && pScrn->vtSema) {
- XGIPtr pXGI = XGIPTR(pScrn);
-
- if (IS_SECOND_HEAD(pXGI)
- && ((!(pXGI->VBFlags & CRT1_LCDA))
- || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
-
- /* Slave head is always CRT1 */
- if (pXGI->VBFlags & CRT1_LCDA)
- pXGI->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
-
- return vgaHWSaveScreen(pScreen, mode);
- }
- else {
- /* Master head is always CRT2 */
- /* But we land here if CRT1 is LCDA, too */
-
- /* We can only blank LCD, not other CRT2 devices */
- if (!(pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)))
- return TRUE;
-
- /* enable access to extended sequencer registers */
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-#endif
- }
- }
-#endif
- return TRUE;
-}
-
-#ifdef DEBUG
-static void
-XGIDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock : %x\n", mode->Clock);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Display : %x\n",
- mode->CrtcHDisplay);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank Start : %x\n",
- mode->CrtcHBlankStart);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync Start : %x\n",
- mode->CrtcHSyncStart);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync End : %x\n",
- mode->CrtcHSyncEnd);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank End : %x\n",
- mode->CrtcHBlankEnd);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz HAdjusted : %x\n",
- mode->CrtcHAdjusted);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Display : %x\n",
- mode->CrtcVDisplay);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank Start : %x\n",
- mode->CrtcVBlankStart);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync Start : %x\n",
- mode->CrtcVSyncStart);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync End : %x\n",
- mode->CrtcVSyncEnd);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank End : %x\n",
- mode->CrtcVBlankEnd);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt VAdjusted : %x\n",
- mode->CrtcVAdjusted);
-}
-#endif
-
-static void
-XGIModifyModeInfo(DisplayModePtr mode)
-{
- if (mode->CrtcHBlankStart == mode->CrtcHDisplay)
- mode->CrtcHBlankStart++;
- if (mode->CrtcHBlankEnd == mode->CrtcHTotal)
- mode->CrtcHBlankEnd--;
- if (mode->CrtcVBlankStart == mode->CrtcVDisplay)
- mode->CrtcVBlankStart++;
- if (mode->CrtcVBlankEnd == mode->CrtcVTotal)
- mode->CrtcVBlankEnd--;
-}
-
-/* Things to do before a ModeSwitch. We set up the
- * video bridge configuration and the TurboQueue.
- */
-void
-XGIPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned char CR30, CR31, CR33;
- unsigned char CR3B = 0;
- unsigned char CR17, CR38 = 0;
- unsigned char CR35 = 0, CR79 = 0;
- unsigned long vbflag;
- int temp = 0;
- int crt1rateindex = 0;
- DisplayModePtr mymode;
-#ifdef XGIMERGED
- DisplayModePtr mymode2 = NULL;
-#endif
-
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- mymode = ((XGIMergedDisplayModePtr) mode->Private)->CRT1;
- mymode2 = ((XGIMergedDisplayModePtr) mode->Private)->CRT2;
- }
- else
-#endif
- mymode = mode;
-
- vbflag = pXGI->VBFlags;
- PDEBUG(ErrorF("VBFlags=0x%lx\n", pXGI->VBFlags));
-
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); /* Unlock Registers */
-#endif
-
- inXGIIDXREG(XGICR, 0x30, CR30);
- inXGIIDXREG(XGICR, 0x31, CR31);
- inXGIIDXREG(XGICR, 0x33, CR33);
-
- inXGIIDXREG(XGICR, 0x3b, CR3B);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
- "Before: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
- CR30, CR31, CR33, temp, CR38);
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n",
- pXGI->VBFlags);
-
- CR30 = 0x00;
- CR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */
- CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */
- CR35 = 0x00;
-
-
- if (!pXGI->AllowHotkey) {
- CR31 |= 0x80; /* Disable hotkey-switch */
- }
- CR79 &= ~0x10; /* Enable Backlight control on 315 series */
-
-
- if ((vbflag & CRT1_LCDA) && (viewmode == XGI_MODE_CRT1)) {
-
- CR38 |= 0x02;
-
- }
- else {
-
- switch (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
-
- case CRT2_TV:
-
- CR38 &= ~0xC0; /* Clear Pal M/N bits */
-
- if (vbflag & TV_YPBPR) { /* Video bridge */
- if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR) {
- CR30 |= 0x80;
- CR38 |= 0x08;
- if (vbflag & TV_YPBPR525P)
- CR38 |= 0x10;
- else if (vbflag & TV_YPBPR750P)
- CR38 |= 0x20;
- else if (vbflag & TV_YPBPR1080I)
- CR38 |= 0x30;
- CR31 &= ~0x01;
- if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPRAR) {
- CR3B &= ~0x03;
- if ((vbflag & TV_YPBPRAR) == TV_YPBPR43LB)
- CR3B |= 0x00;
- else if ((vbflag & TV_YPBPRAR) == TV_YPBPR43)
- CR3B |= 0x03;
- else if ((vbflag & TV_YPBPRAR) == TV_YPBPR169)
- CR3B |= 0x01;
- else
- CR3B |= 0x03;
- }
- }
- }
- else { /* All */
- if (vbflag & TV_SCART)
- CR30 |= 0x10;
- if (vbflag & TV_SVIDEO)
- CR30 |= 0x08;
- if (vbflag & TV_AVIDEO)
- CR30 |= 0x04;
- if (!(CR30 & 0x1C))
- CR30 |= 0x08; /* default: SVIDEO */
-
- if (vbflag & TV_PAL) {
- CR31 |= 0x01;
- CR35 |= 0x01;
- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
- if (vbflag & TV_PALM) {
- CR38 |= 0x40;
- CR35 |= 0x04;
- }
- else if (vbflag & TV_PALN) {
- CR38 |= 0x80;
- CR35 |= 0x08;
- }
- }
- }
- else {
- CR31 &= ~0x01;
- CR35 &= ~0x01;
- if (vbflag & TV_NTSCJ) {
- CR38 |= 0x40; /* TW, not BIOS */
- CR35 |= 0x02;
- }
- }
- if (vbflag & TV_SCART) {
- CR31 |= 0x01;
- CR35 |= 0x01;
- }
- }
-
- CR31 &= ~0x04; /* Clear NotSimuMode */
-#ifdef XGI_CP
- XGI_CP_DRIVER_CONFIG
-#endif
- break;
-
- case CRT2_LCD:
- CR30 |= 0x20;
- break;
-
- case CRT2_VGA:
- CR30 |= 0x40;
- break;
-
- default:
- CR30 |= 0x00;
- CR31 |= 0x20; /* VB_OUTPUT_DISABLE */
- }
-
- }
-
- if (vbflag & CRT1_LCDA) {
- switch (viewmode) {
- case XGI_MODE_CRT1:
- CR38 |= 0x01;
- break;
- case XGI_MODE_CRT2:
- if (vbflag & (CRT2_TV | CRT2_VGA)) {
- CR30 |= 0x02;
- CR38 |= 0x01;
- }
- else {
- CR38 |= 0x03;
- }
- break;
- case XGI_MODE_SIMU:
- default:
- if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
- CR30 |= 0x01;
- }
- break;
- }
- }
- else {
- if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
- CR30 |= 0x01;
- }
- }
-
- CR31 |= 0x40; /* Set Drivermode */
- CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */
- crt1rateindex = XGISearchCRT1Rate(pScrn, mymode);
-
- if (IS_DUAL_HEAD(pXGI)) {
- if (IS_SECOND_HEAD(pXGI)) {
- /* CRT1 */
- CR33 &= 0xf0;
- if (!(vbflag & CRT1_LCDA)) {
- CR33 |= (crt1rateindex & 0x0f);
- }
- }
- else {
- /* CRT2 */
- CR33 &= 0x0f;
- if (vbflag & CRT2_VGA) {
- CR33 |= ((crt1rateindex << 4) & 0xf0);
- }
- }
- }
- else
-#ifdef XGIMERGED
- if (pXGI->MergedFB) {
- CR33 = 0;
- if (!(vbflag & CRT1_LCDA)) {
- CR33 |= (crt1rateindex & 0x0f);
- }
- if (vbflag & CRT2_VGA) {
- CR33 |= (XGISearchCRT1Rate(pScrn, mymode2) << 4);
- }
- }
- else
-#endif
- {
- CR33 = 0;
- if (!(vbflag & CRT1_LCDA)) {
- CR33 |= (crt1rateindex & 0x0f);
- }
- if (vbflag & CRT2_VGA) {
- CR33 |= ((crt1rateindex & 0x0f) << 4);
- }
- if (vbflag & CRT2_ENABLE) {
- if (pXGI->CRT1off)
- CR33 &= 0xf0;
- }
- }
- outXGIIDXREG(XGICR, 0x30, CR30);
- outXGIIDXREG(XGICR, 0x31, CR31);
- outXGIIDXREG(XGICR, 0x33, CR33);
- if (temp) {
- outXGIIDXREG(XGICR, temp, CR38);
- }
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
- "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n",
- CR30, CR31, CR33, temp, CR38);
-
- if (pXGI->VBFlags & CRT2_ENABLE) {
- /* Switch on CRT1 for modes that require the bridge in SlaveMode */
- andXGIIDXREG(XGISR, 0x1f, 0x3f);
- inXGIIDXREG(XGICR, 0x17, CR17);
- if (!(CR17 & 0x80)) {
- orXGIIDXREG(XGICR, 0x17, 0x80);
- outXGIIDXREG(XGISR, 0x00, 0x01);
- usleep(10000);
- outXGIIDXREG(XGISR, 0x00, 0x03);
- }
- }
-}
-
-/* PostSetMode:
- * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
- * VESA uses the bridge in SlaveMode and switching CRT1 off while
- * the bridge is in SlaveMode not that clever...
- * -) Check if overlay can be used (depending on dotclock)
- * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
- * -) Save TV registers for further processing
- * -) Apply TV settings
- */
-static void
-XGIPostSetMode(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-/* unsigned char usScratchCR17;
- Bool flag = FALSE;
- Bool doit = TRUE; */
- int myclock;
- unsigned char sr2b, sr2c, tmpreg;
- float num, denum, postscalar, divider;
- PDEBUG(ErrorF(" XGIPostSetMode(). \n"));
-#ifdef TWDEBUG
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pXGI->CRT1off);
-#endif
-
-#ifdef UNLOCK_ALWAYS
- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
-#endif
-
- /* Determine if the video overlay can be used */
- if (!pXGI->NoXvideo) {
- inXGIIDXREG(XGISR, 0x2b, sr2b);
- inXGIIDXREG(XGISR, 0x2c, sr2c);
- divider = (sr2b & 0x80) ? 2.0 : 1.0;
- postscalar = (sr2c & 0x80) ?
- ((((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) :
- (((sr2c >> 5) & 0x03) + 1.0);
- num = (sr2b & 0x7f) + 1.0;
- denum = (sr2c & 0x1f) + 1.0;
- myclock =
- (int) ((14318 * (divider / postscalar) * (num / denum)) / 1000);
-
- pXGI->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA);
-/* switch(pXGI->xgi_HwDevExt.jChipType) {
- break;
- }
- */
- if (!(pXGI->MiscFlags & MISC_CRT1OVERLAY)) {
- if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI))
- xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
- "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
- myclock);
- }
- }
-
- /* Determine if the Panel Link scaler is active */
- pXGI->MiscFlags &= ~MISC_PANELLINKSCALER;
- if (pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
- if (pXGI->VBFlags & CRT1_LCDA) {
- inXGIIDXREG(XGIPART1, 0x35, tmpreg);
- tmpreg &= 0x04;
- if (!tmpreg)
- pXGI->MiscFlags |= MISC_PANELLINKSCALER;
- }
- }
-
- /* Determine if our very special TV mode is active */
- pXGI->MiscFlags &= ~MISC_TVNTSC1024;
- if ((pXGI->XGI_Pr->VBType & VB_XGIVB) && (pXGI->VBFlags & CRT2_TV)
- && (!(pXGI->VBFlags & TV_HIVISION))) {
- if (((pXGI->VBFlags & TV_YPBPR) && (pXGI->VBFlags & TV_YPBPR525I))
- || ((!(pXGI->VBFlags & TV_YPBPR))
- && (pXGI->VBFlags & (TV_NTSC | TV_PALM)))) {
- inXGIIDXREG(XGICR, 0x34, tmpreg);
- tmpreg &= 0x7f;
- if ((tmpreg == 0x64) || (tmpreg == 0x4a) || (tmpreg == 0x38)) {
- pXGI->MiscFlags |= MISC_TVNTSC1024;
- }
- }
- }
-
- /* Reset XV gamma correction */
- if (pXGI->ResetXvGamma) {
- (pXGI->ResetXvGamma) (pScrn);
- }
-
- /* Apply TV settings given by options
- * Do this even in DualHeadMode:
- * - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
- * - if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
- * -> Hence, in both cases, the settings must be re-applied.
- */
-}
-
-
-USHORT
-XGI_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode,
- unsigned long VBFlags)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- UShort i = (pXGI->CurrentLayout.bitsPerPixel + 7) / 8 - 1;
-
- if ((VBFlags & CRT1_LCDA)) {
- if ((mode->HDisplay > pXGI->LCDwidth) ||
- (mode->VDisplay > pXGI->LCDheight)) {
- return 0;
- }
- }
-
- return XGI_GetModeID(VBFlags, mode->HDisplay, mode->VDisplay,
- i, pXGI->LCDwidth, pXGI->LCDheight);
-}
-
-/* Calculate the vertical refresh rate from a mode */
-int
-XGICalcVRate(DisplayModePtr mode)
-{
- float hsync, refresh = 0;
-
- if (mode->HSync > 0.0)
- hsync = mode->HSync;
- else if (mode->HTotal > 0)
- hsync = (float) mode->Clock / (float) mode->HTotal;
- else
- hsync = 0.0;
-
- if (mode->VTotal > 0)
- refresh = hsync * 1000.0 / mode->VTotal;
-
- if (mode->Flags & V_INTERLACE)
- refresh *= 2.0;
-
- if (mode->Flags & V_DBLSCAN)
- refresh /= 2.0;
-
- if (mode->VScan > 1)
- refresh /= mode->VScan;
-
- if (mode->VRefresh > 0.0)
- refresh = mode->VRefresh;
-
- if (hsync == 0 || refresh == 0)
- return (0);
-
- return ((int) (refresh));
-}
-
-/* Calculate CR33 (rate index) for CRT1.
- * Calculation is done using currentmode, therefore it is
- * recommended to set VertRefresh and HorizSync to correct
- * values in config file.
- */
-unsigned char
-XGISearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
-/* XGIPtr pXGI = XGIPTR(pScrn); */
- int i = 0;
- int irefresh;
- unsigned short xres = mode->HDisplay;
- unsigned short yres = mode->VDisplay;
- unsigned char index;
- BOOLEAN checkxgi730 = FALSE;
-
- irefresh = XGICalcVRate(mode);
- if (!irefresh) {
- if (xres == 800 || xres == 1024 || xres == 1280)
- return 0x02;
- else
- return 0x01;
- }
-
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
-#endif
-
- /* We need the REAL refresh rate here */
- if (mode->Flags & V_INTERLACE)
- irefresh /= 2;
-
- /* Do not multiply by 2 when DBLSCAN! */
-
-#ifdef TWDEBUG
- xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
-#endif
-
- index = 0;
- while ((xgix_vrate[i].idx != 0) && (xgix_vrate[i].xres <= xres)) {
- if ((xgix_vrate[i].xres == xres) && (xgix_vrate[i].yres == yres)) {
- if ((checkxgi730 == FALSE)
- || (xgix_vrate[i].XGI730valid32bpp == TRUE)) {
- if (xgix_vrate[i].refresh == irefresh) {
- index = xgix_vrate[i].idx;
- break;
- }
- else if (xgix_vrate[i].refresh > irefresh) {
- if ((xgix_vrate[i].refresh - irefresh) <= 3) {
- index = xgix_vrate[i].idx;
- }
- else if (((checkxgi730 == FALSE)
- || (xgix_vrate[i - 1].XGI730valid32bpp == TRUE))
- && ((irefresh - xgix_vrate[i - 1].refresh) <= 2)
- && (xgix_vrate[i].idx != 1)) {
- index = xgix_vrate[i - 1].idx;
- }
- break;
- }
- else if ((irefresh - xgix_vrate[i].refresh) <= 2) {
- index = xgix_vrate[i].idx;
- break;
- }
- }
- }
- i++;
- }
- if (index > 0)
- return index;
- else {
- /* Default Rate index */
- if (xres == 800 || xres == 1024 || xres == 1280)
- return 0x02;
- else
- return 0x01;
- }
-}
-
-
-#define MODEID_OFF 0x449
-
-unsigned char
-XGI_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
-{
- return (XGI_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
-}
-
-unsigned char
-XGI_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
-{
- unsigned char ret = 0;
-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
- unsigned char *base;
-
- base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
- if (!base) {
- XGIErrorLog(pScrn, "(Could not map BIOS scratch area)\n");
- return 0;
- }
-
- ret = *(base + offset);
-
- /* value != 0xff means: set register */
- if (value != 0xff)
- *(base + offset) = value;
-
- xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
-#endif
- return ret;
-}
-
-void
-xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
- unsigned char *reg2)
-{
- register unsigned char val;
- unsigned long mylockcalls;
-
- pXGI->lockcalls++;
- mylockcalls = pXGI->lockcalls;
-
- /* check if already unlocked */
- inXGIIDXREG(XGISR, 0x05, val);
- if (val != 0xa1) {
- /* save State */
- if (reg1)
- *reg1 = val;
- /* unlock */
-/*
- outb (0x3c4, 0x20);
- val4 = inb (0x3c5);
- val4 |= 0x20;
- outb (0x3c5, val4);
-*/
- outXGIIDXREG(XGISR, 0x05, 0x86);
- inXGIIDXREG(XGISR, 0x05, val);
- if (val != 0xA1) {
-#ifdef TWDEBUG
- unsigned char val1, val2;
- int i;
-#endif
- XGIErrorLog(pXGI->pScrn,
- "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
- (void *) pXGI, (unsigned long) pXGI->RelIO, val,
- mylockcalls);
-#ifdef TWDEBUG
- for (i = 0; i <= 0x3f; i++) {
- inXGIIDXREG(XGISR, i, val1);
- inXGIIDXREG(0x3c4, i, val2);
- xf86DrvMsg(pXGI->pScrn->scrnIndex, X_INFO,
- "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n",
- i, val1, val2, mylockcalls);
- }
-#endif
- }
- }
-}
-
-void
-xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, unsigned char reg2)
-{
- /* restore lock */
-#ifndef UNLOCK_ALWAYS
- outXGIIDXREG(XGISR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
-#endif
-}
-
-
-#ifdef DEBUG
-void
-XGIDumpSR(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("SR xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x40; i += 0x10) {
- ErrorF("SR[%02X]:", i);
- for (j = 0; j < 16; j++) {
- inXGIIDXREG(XGISR, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
- ErrorF("\n");
-}
-
-void
-XGIDumpCR(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("CR xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x100; i += 0x10) {
- ErrorF("CR[%02X]:", i);
- for (j = 0; j < 16; j++) {
- inXGIIDXREG(XGICR, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpGR(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("GR xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("GR:");
- for (i = 0; i < 0x9; i += 0x10) {
- inXGIIDXREG(XGISR, i, temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
-}
-
-
-void
-XGIDumpPart0(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("PART0 xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x50; i += 0x10) {
- ErrorF("PART0[%02X]:", i);
- for (j = 0; j < 0x10; j++) {
- inXGIIDXREG(XGIPART0, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpPart05(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- int i, j;
- unsigned long temp;
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("PART05 xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x50; i += 0x10) {
- ErrorF("PART05[%02X]:", i);
- for (j = 0; j < 0x10; j++) {
- inXGIIDXREG(XGIPART05, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpPart1(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("PART1 xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x100; i += 0x10) {
- ErrorF("PART1[%02X]:", i);
- for (j = 0; j < 0x10; j++) {
- inXGIIDXREG(XGIPART1, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpPart2(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("PART2 xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x100; i += 0x10) {
- ErrorF("PART2[%02X]:", i);
- for (j = 0; j < 0x10; j++) {
- inXGIIDXREG(XGIPART2, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpPart3(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("PART3 xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
-
- for (i = 0; i < 0x100; i += 0x10) {
- ErrorF("PART3[%02X]:", i);
- for (j = 0; j < 0x10; j++) {
- inXGIIDXREG(XGIPART3, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpPart4(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i, j;
- unsigned long temp;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("PART4 xx\n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0x100; i += 0x10) {
- ErrorF("PART4[%02X]:", i);
- for (j = 0; j < 0x10; j++) {
- inXGIIDXREG(XGIPART4, (i + j), temp);
- ErrorF(" %02lX", temp);
- }
- ErrorF("\n");
- }
-}
-
-void
-XGIDumpMMIO(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- int i;
- unsigned long temp;
-/*
- ErrorF("----------------------------------------------------------------------\n") ;
- ErrorF("MMIO 85xx\n") ;
- ErrorF("----------------------------------------------------------------------\n") ;
- for( i = 0x8500 ; i < 0x8600 ; i+=0x10 )
- {
- ErrorF("[%04X]: %08lX %08lX %08lX %08lX\n",i,
- XGIMMIOLONG(i),
- XGIMMIOLONG(i+4),
- XGIMMIOLONG(i+8),
- XGIMMIOLONG(i+12)) ;
- }
-*/
-}
-#endif /* DEBUG */
-
-void
-XGIDumpRegs(ScrnInfoPtr pScrn)
-{
-#ifdef DEBUG
-
- XGIPtr pXGI = XGIPTR(pScrn);
-
- XGIDumpSR(pScrn);
- XGIDumpCR(pScrn);
-// XGIDumpGR(pScrn);
-// XGIDumpPalette(pScrn);
- XGIDumpMMIO(pScrn);
- if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
- XGIDumpPart0(pScrn);
- XGIDumpPart05(pScrn);
- XGIDumpPart1(pScrn);
- XGIDumpPart2(pScrn);
- XGIDumpPart3(pScrn);
- XGIDumpPart4(pScrn);
- }
-
-#endif /* DEBUG */
-}
-
-
-void
-XGIDumpPalette(ScrnInfoPtr pScrn)
-{
-#ifdef DEBUG
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned temp[3];
- int i, j;
-
- ErrorF
- ("----------------------------------------------------------------------\n");
- ErrorF("Palette \n");
- ErrorF
- ("----------------------------------------------------------------------\n");
- for (i = 0; i < 0xFF; i += 0x04) {
- for (j = 0; j < 16; j++) {
- outb(0x3c7, i + j);
- temp[0] = inb(0x3c9);
- temp[1] = inb(0x3c9);
- temp[2] = inb(0x3c9);
-
- ErrorF("PA[%02X]: %02X %02X %02X", i + j,
- temp[0], temp[1], temp[2]);
- }
- ErrorF("\n");
- }
- ErrorF("\n");
-#endif
-}
+/*
+ * XGI driver main code
+ *
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ * - driver entirely rewritten since 2001, only basic structure taken from
+ * old code (except xgi_dri.c, xgi_shadow.c, xgi_accel.c and parts of
+ * xgi_dga.c; these were mostly taken over; xgi_dri.c was changed for
+ * new versions of the DRI layer)
+ *
+ * This notice covers the entire driver code unless otherwise indicated.
+ *
+ * Formerly based on code which is
+ * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
+ * Written by:
+ * Alan Hourihane <alanh@fairlite.demon.co.uk>,
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
+ * David Thomas <davtom@dream.org.uk>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Jong 09/27/2007; added for PACKAGE_VERSION_MAJOR,... */
+#define PACKAGE_VERSION_MAJOR 1
+#define PACKAGE_VERSION_MINOR 1
+#define PACKAGE_VERSION_PATCHLEVEL 0
+
+#include "fb.h"
+#include "mibank.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "dixstruct.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+#include "shadowfb.h"
+#include "vbe.h"
+
+#include "mipointer.h"
+#include "mibstore.h"
+
+#include "xgi.h"
+#include "xgi_regs.h"
+#include "xgi_vb.h"
+#include "xgi_dac.h"
+#include "vb_def.h"
+#include "xgi_driver.h"
+#include "valid_mode.h"
+
+#define _XF86DGA_SERVER_
+#include <X11/extensions/xf86dgastr.h>
+
+#include "globals.h"
+
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#if defined(XvExtension)
+#include "xf86xv.h"
+#include <X11/extensions/Xv.h>
+#endif
+
+#ifdef XF86DRI
+#include "dri.h"
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#ifdef XSERVER_LIBPCIACCESS
+static Bool XGIPciProbe(DriverPtr drv, int entity_num,
+ struct pci_device *dev, intptr_t match_data);
+#else
+static Bool XGIProbe(DriverPtr drv, int flags);
+#endif
+
+void Volari_EnableAccelerator(ScrnInfoPtr pScrn);
+/* Globals (yes, these ARE really required to be global) */
+
+#ifdef XGIDUALHEAD
+static int XGIEntityIndex = -1;
+#endif
+
+/* Jong 09/19/2007; support modeline */
+int g_CountOfUserDefinedModes=0;
+xf86MonPtr g_pMonitorDVI=NULL; /* Jong 12/04/2007; used for filtering of CRT1 modes */
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+int FbDevExist;
+
+#define FBIOGET_FSCREENINFO 0x4602
+#define FB_ACCEL_XGI_GLAMOUR 41
+
+struct fb_fix_screeninfo
+{
+ char id[16]; /* identification string eg "TT Builtin" */
+ unsigned long smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ unsigned long smem_len; /* Length of frame buffer mem */
+ unsigned long type; /* see FB_TYPE_* */
+ unsigned long type_aux; /* Interleave for interleaved Planes */
+ unsigned long visual; /* see FB_VISUAL_* */
+ unsigned short xpanstep; /* zero if no hardware panning */
+ unsigned short ypanstep; /* zero if no hardware panning */
+ unsigned short ywrapstep; /* zero if no hardware ywrap */
+ unsigned long line_length; /* length of a line in bytes */
+ unsigned long mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ unsigned long mmio_len; /* Length of Memory Mapped I/O */
+ unsigned long accel; /* Type of acceleration available */
+ unsigned short reserved[3]; /* Reserved for future compatibility */
+};
+
+#ifdef XSERVER_LIBPCIACCESS
+#define XGI_DEVICE_MATCH(d, i) \
+ { 0x18ca, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+
+static const struct pci_id_match xgi_device_match[] = {
+ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG40, 0),
+ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG20, 1),
+ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG21, 2),
+ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG27, 3),
+ { 0, 0, 0 },
+};
+#endif
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec XGI = {
+ XGI_CURRENT_VERSION,
+ XGI_DRIVER_NAME,
+ XGIIdentify,
+#ifdef XSERVER_LIBPCIACCESS
+ NULL,
+#else
+ XGIProbe,
+#endif
+ XGIAvailableOptions,
+ NULL,
+ 0,
+ NULL,
+
+#ifdef XSERVER_LIBPCIACCESS
+ xgi_device_match,
+ XGIPciProbe
+#endif
+};
+
+static SymTabRec XGIChipsets[] = {
+ {PCI_CHIP_XGIXG40, "Volari V8_V5_V3XT"},
+ {PCI_CHIP_XGIXG20, "Volari Z7_Z9_Z9s"},
+ {PCI_CHIP_XGIXG21, "Volari Z9_Z9s"},
+ {PCI_CHIP_XGIXG27, "Volari Z11"},
+ {-1, NULL}
+};
+
+static PciChipsets XGIPciChipsets[] = {
+ {PCI_CHIP_XGIXG40, PCI_CHIP_XGIXG40, RES_SHARED_VGA},
+ {PCI_CHIP_XGIXG20, PCI_CHIP_XGIXG20, RES_SHARED_VGA},
+ {PCI_CHIP_XGIXG21, PCI_CHIP_XGIXG21, RES_SHARED_VGA },
+ {PCI_CHIP_XGIXG27, PCI_CHIP_XGIXG27, RES_SHARED_VGA },
+ {-1, -1, RES_UNDEFINED}
+};
+
+static const char *xaaSymbols[] = {
+ "XAACopyROP",
+ "XAACreateInfoRec",
+ "XAADestroyInfoRec",
+ "XAAFillMono8x8PatternRects",
+ "XAAPatternROP",
+ "XAAHelpPatternROP",
+ "XAAInit",
+ NULL
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWGetIndex",
+ "vgaHWInit",
+ "vgaHWLock",
+ "vgaHWMapMem",
+ "vgaHWUnmapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "fbPictureInit",
+ "fbScreenInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ "xf86InitCursor",
+ NULL
+};
+
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86SetDDCproperties",
+ "xf86InterpretEDID",
+ NULL
+};
+
+
+/* static const char *i2cSymbols[] = {
+ "xf86I2CBusInit",
+ "xf86CreateI2CBusRec",
+ NULL
+}; */
+
+static const char *int10Symbols[] = {
+ "xf86FreeInt10",
+ "xf86InitInt10",
+ "xf86ExecX86int10",
+ NULL
+};
+
+static const char *vbeSymbols[] = {
+ "VBEExtendedInit",
+ "vbeDoEDID",
+ "vbeFree",
+ "VBEGetVBEInfo",
+ "VBEFreeVBEInfo",
+ "VBEGetModeInfo",
+ "VBEFreeModeInfo",
+ "VBESaveRestore",
+ "VBESetVBEMode",
+ "VBEGetVBEMode",
+ "VBESetDisplayStart",
+ "VBESetGetLogicalScanlineLength",
+ NULL
+};
+
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAddMap",
+ "drmAgpAcquire",
+ "drmAgpAlloc",
+ "drmAgpBase",
+ "drmAgpBind",
+ "drmAgpEnable",
+ "drmAgpFree",
+ "drmAgpGetMode",
+ "drmAgpRelease",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmXGIAgpInit",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRICloseScreen",
+ "DRICreateInfoRec",
+ "DRIDestroyInfoRec",
+ "DRIFinishScreenInit",
+ "DRIGetSAREAPrivate",
+ "DRILock",
+ "DRIQueryVersion",
+ "DRIScreenInit",
+ "DRIUnlock",
+#ifdef XGINEWDRI2
+ "GlxSetVisualConfigs",
+ "DRICreatePCIBusID",
+#endif
+ NULL
+};
+#endif
+
+static MODULESETUPPROTO(xgiSetup);
+
+static XF86ModuleVersionInfo xgiVersRec = {
+ XGI_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+#ifdef XORG_VERSION_CURRENT
+ XORG_VERSION_CURRENT,
+#else
+ XF86_VERSION_CURRENT,
+#endif
+ PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+#ifdef ABI_VIDEODRV_VERSION
+ ABI_VIDEODRV_VERSION,
+#else
+ 6,
+#endif
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData xgiModuleData = { &xgiVersRec, xgiSetup, NULL };
+
+/*** static string ***/
+#ifdef XGIMERGED
+static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n";
+static const char *mergednocrt2 =
+ "No CRT2 output selected or no bridge detected. %s.\n";
+static const char *mergeddisstr = "MergedFB mode disabled";
+static const char *modesforstr =
+ "Modes for CRT%d: *********************************************\n";
+static const char *crtsetupstr =
+ "------------------------ CRT%d setup -------------------------\n";
+#endif
+
+typedef struct
+{
+ int width, height;
+ float VRefresh, HSync, DCLK;
+} ModeTiming;
+
+static const ModeTiming establish_timing[] = {
+ {800, 600, 60, 37.9, 40}, /* t1 D[0] */
+ {800, 600, 56, 35.1, 36}, /* t1 D[1] */
+ {640, 480, 75, 37.5, 31.5}, /* t1 D[2] */
+ {640, 480, 72, 37.9, 31.5}, /* t1 D[3] */
+ {-1, -1, -1, -1}, /* t1 D[4] 640x480@67Hz, ignore */
+ {640, 480, 60, 31.5, 25.175}, /* t1 D[5] */
+ {-1, -1, -1, -1}, /* t1 D[6] */
+ {-1, -1, -1, -1}, /* t1 D[7] */
+ {1280, 1024, 75, 80.0, 135}, /* t2 D[0] */
+ {1024, 768, 75, 60.0, 78.75}, /* t2 D[1] */
+ {1024, 768, 70, 56.5, 75}, /* t2 D[2] */
+ {1024, 768, 60, 48.4, 65}, /* t2 D[3] */
+ {-1, -1, -1, -1}, /* t2 D[4] 1024x768@87I, ignore */
+ {-1, -1, -1, -1}, /* t2 D[5] 832x624@75Hz, ignore */
+ {800, 600, 75, 46.9, 49.5}, /* t2 D[6] */
+ {800, 600, 72, 48.1, 50} /* t2 D[7] */
+};
+
+static const ModeTiming StdTiming[] = {
+ {640, 480, 60, 31.5, 25.175},
+ {640, 480, 72, 37.9, 31.5},
+ {640, 480, 75, 37.5, 31.5},
+ {640, 480, 85, 43.3, 36.0},
+
+ {800, 600, 56, 35.1, 36},
+ {800, 600, 60, 37.9, 40},
+ {800, 600, 72, 48.1, 50},
+ {800, 600, 75, 46.9, 49.5},
+ {800, 600, 85, 53.7, 56.25},
+
+ {1024, 768, 43, 35.5, 44.9},
+ {1024, 768, 60, 48.4, 65},
+ {1024, 768, 70, 56.5, 75},
+ {1024, 768, 75, 60, 78.75},
+ {1024, 768, 85, 68.7, 94.5},
+
+ {1152, 864, 75, 67.5, 108},
+
+ {1280, 960, 60, 60, 108},
+ {1280, 960, 85, 85.9, 148.5},
+ {1280, 1024, 60, 64.0, 108},
+ {1280, 1024, 75, 80, 135},
+ {1280, 1024, 85, 91.1, 157.5},
+
+ {1600, 1200, 60, 75, 162.0},
+ {1600, 1200, 65, 81.3, 175.5},
+ {1600, 1200, 70, 87.5, 189},
+ {1600, 1200, 75, 93.8, 202},
+ {1600, 1200, 85, 106.3, 229.5},
+
+ {1792, 1344, 60, 83.64, 204.75},
+ {1792, 1344, 75, 106.27, 261},
+
+ {1856, 1392, 60, 86.33, 218.25},
+ {1856, 1392, 75, 112.50, 288},
+
+ {1920, 1440, 60, 90, 234},
+ {1920, 1440, 75, 112.5, 297},
+ {-1, -1, -1, -1, -1},
+};
+
+
+static void XGIDumpPalette(ScrnInfoPtr pScrn);
+#ifdef DEBUG
+static void XGIDumpSR(ScrnInfoPtr pScrn);
+static void XGIDumpCR(ScrnInfoPtr pScrn);
+static void XGIDumpGR(ScrnInfoPtr pScrn);
+static void XGIDumpPart1(ScrnInfoPtr pScrn);
+static void XGIDumpPart2(ScrnInfoPtr pScrn);
+static void XGIDumpPart3(ScrnInfoPtr pScrn);
+static void XGIDumpPart4(ScrnInfoPtr pScrn);
+static void XGIDumpMMIO(ScrnInfoPtr pScrn);
+#endif
+
+static int XGICalcVRate(DisplayModePtr mode);
+static unsigned char XGISearchCRT1Rate(ScrnInfoPtr pScrn,
+ DisplayModePtr mode);
+static void xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
+ unsigned char *reg2);
+static void xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1,
+ unsigned char reg2);
+
+/* Jong 12/05/2007; check mode with monitor DDC */
+static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC);
+
+/* Jong 12/05/2007; filter mode list by monitor DDC */
+static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC);
+
+static pointer
+xgiSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&XGI, module, HaveDriverFuncs);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
+ shadowSymbols, ramdacSymbols, ddcSymbols,
+ vbeSymbols, int10Symbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
+ NULL);
+ return (pointer) TRUE;
+ }
+
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+
+static XGIPtr
+XGIGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an XGIRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate == NULL) {
+ XGIPtr pXGI = xnfcalloc(sizeof(XGIRec), 1);
+
+ /* Initialise it to 0 */
+ memset(pXGI, 0, sizeof(XGIRec));
+
+ pScrn->driverPrivate = pXGI;
+ pXGI->pScrn = pScrn;
+ }
+
+ return (XGIPtr) pScrn->driverPrivate;
+}
+
+static void
+XGIFreeRec(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ XGIEntPtr pXGIEnt = NULL;
+
+ /* Just to make sure... */
+ if (!pXGI)
+ return;
+
+ pXGIEnt = ENTITY_PRIVATE(pXGI);
+ if (pXGIEnt) {
+ if (!IS_SECOND_HEAD(pXGI)) {
+ /* Free memory only if we are first head; in case of an error
+ * during init of the second head, the server will continue -
+ * and we need the BIOS image and VB_DEVICE_INFO for the first
+ * head.
+ */
+ if (pXGIEnt->BIOS)
+ xfree(pXGIEnt->BIOS);
+ pXGIEnt->BIOS = pXGI->BIOS = NULL;
+ if (pXGIEnt->XGI_Pr)
+ xfree(pXGIEnt->XGI_Pr);
+ pXGIEnt->XGI_Pr = pXGI->XGI_Pr = NULL;
+ if (pXGIEnt->RenderAccelArray)
+ xfree(pXGIEnt->RenderAccelArray);
+ pXGIEnt->RenderAccelArray = pXGI->RenderAccelArray = NULL;
+ }
+ else {
+ pXGI->BIOS = NULL;
+ pXGI->XGI_Pr = NULL;
+ pXGI->RenderAccelArray = NULL;
+ }
+ }
+ else {
+ if (pXGI->BIOS)
+ xfree(pXGI->BIOS);
+ pXGI->BIOS = NULL;
+ if (pXGI->XGI_Pr)
+ xfree(pXGI->XGI_Pr);
+ pXGI->XGI_Pr = NULL;
+ if (pXGI->RenderAccelArray)
+ xfree(pXGI->RenderAccelArray);
+ pXGI->RenderAccelArray = NULL;
+ }
+
+#ifdef XGIMERGED
+ if (pXGI->MetaModes)
+ xfree(pXGI->MetaModes);
+ pXGI->MetaModes = NULL;
+
+ if (pXGI->CRT1Modes) {
+ if (pXGI->CRT1Modes != pScrn->modes) {
+ if (pScrn->modes) {
+ pScrn->currentMode = pScrn->modes;
+ do {
+ DisplayModePtr p = pScrn->currentMode->next;
+ if (pScrn->currentMode->Private)
+ xfree(pScrn->currentMode->Private);
+ xfree(pScrn->currentMode);
+ pScrn->currentMode = p;
+ } while (pScrn->currentMode != pScrn->modes);
+ }
+ pScrn->currentMode = pXGI->CRT1CurrentMode;
+ pScrn->modes = pXGI->CRT1Modes;
+ pXGI->CRT1CurrentMode = NULL;
+ pXGI->CRT1Modes = NULL;
+ }
+ }
+#endif
+ if (pXGI->pVbe)
+ vbeFree(pXGI->pVbe);
+ pXGI->pVbe = NULL;
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static void
+XGIDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ BOOLEAN docrt1 = TRUE, docrt2 = TRUE;
+ unsigned char sr1 = 0, cr17 = 0, cr63 = 0, sr11 = 0, pmreg = 0, sr7 = 0;
+ unsigned char p1_13 = 0, p2_0 = 0, oldpmreg = 0;
+ BOOLEAN backlight = TRUE;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "XGIDisplayPowerManagementSet(%d)\n", PowerManagementMode);
+
+ if (IS_DUAL_HEAD(pXGI)) {
+ if (IS_SECOND_HEAD(pXGI))
+ docrt2 = FALSE;
+ else
+ docrt1 = FALSE;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+#endif
+
+ switch (PowerManagementMode) {
+
+ case DPMSModeOn: /* HSync: On, VSync: On */
+ if (docrt1)
+ pXGI->Blank = FALSE;
+
+ sr1 = 0x00;
+ cr17 = 0x80;
+ pmreg = 0x00;
+ cr63 = 0x00;
+ sr7 = 0x10;
+ sr11 = (pXGI->LCDon & 0x0C);
+ p2_0 = 0x20;
+ p1_13 = 0x00;
+ backlight = TRUE;
+ break;
+
+ case DPMSModeSuspend: /* HSync: On, VSync: Off */
+ if (docrt1)
+ pXGI->Blank = TRUE;
+
+ sr1 = 0x20;
+ cr17 = 0x80;
+ pmreg = 0x80;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ sr11 = 0x08;
+ p2_0 = 0x40;
+ p1_13 = 0x80;
+ backlight = FALSE;
+ break;
+
+ case DPMSModeStandby: /* HSync: Off, VSync: On */
+ if (docrt1)
+ pXGI->Blank = TRUE;
+
+ sr1 = 0x20;
+ cr17 = 0x80;
+ pmreg = 0x40;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ sr11 = 0x08;
+ p2_0 = 0x80;
+ p1_13 = 0x40;
+ backlight = FALSE;
+ break;
+
+ case DPMSModeOff: /* HSync: Off, VSync: Off */
+ if (docrt1)
+ pXGI->Blank = TRUE;
+
+ sr1 = 0x20;
+ cr17 = 0x00;
+ pmreg = 0xc0;
+ cr63 = 0x40;
+ sr7 = 0x00;
+ sr11 = 0x08;
+ p2_0 = 0xc0;
+ p1_13 = 0xc0;
+ backlight = FALSE;
+ break;
+
+ default:
+ return;
+ }
+
+ if (docrt1) {
+ /* Set/Clear "Display On" bit
+ */
+ setXGIIDXREG(XGISR, 0x01, ~0x20, sr1);
+
+ if ((!(pXGI->VBFlags & CRT1_LCDA))
+ || (pXGI->XGI_Pr->VBType & VB_XGI301C)) {
+ inXGIIDXREG(XGISR, 0x1f, oldpmreg);
+ if (!pXGI->CRT1off) {
+ setXGIIDXREG(XGISR, 0x1f, 0x3f, pmreg);
+ }
+ }
+ oldpmreg &= 0xc0;
+ }
+
+ if ((docrt1) && (pmreg != oldpmreg)
+ && ((!(pXGI->VBFlags & CRT1_LCDA))
+ || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
+ outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
+ usleep(10000);
+ outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
+ }
+
+}
+
+/* Mandatory */
+static void
+XGIIdentify(int flags)
+{
+ xf86PrintChipsets(XGI_NAME, "driver for XGI chipsets", XGIChipsets);
+ PDEBUG(ErrorF(" --- XGIIdentify \n"));
+}
+
+static void
+XGIErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
+{
+ va_list ap;
+ static const char *str =
+ "**************************************************\n";
+
+ va_start(ap, format);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " ERROR:\n");
+ xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
+ va_end(ap);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " END OF MESSAGE\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+}
+
+#ifdef XSERVER_LIBPCIACCESS
+static Bool XGIPciProbe(DriverPtr drv, int entity_num,
+ struct pci_device *dev, intptr_t match_data)
+{
+ ScrnInfoPtr pScrn;
+
+
+ pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
+ NULL, NULL, NULL, NULL, NULL);
+ if (pScrn != NULL) {
+ XGIPtr pXGI;
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = XGI_CURRENT_VERSION;
+ pScrn->driverName = XGI_DRIVER_NAME;
+ pScrn->name = XGI_NAME;
+ pScrn->Probe = NULL;
+ pScrn->PreInit = XGIPreInit;
+ pScrn->ScreenInit = XGIScreenInit;
+ pScrn->SwitchMode = XGISwitchMode;
+ pScrn->AdjustFrame = XGIAdjustFrame;
+ pScrn->EnterVT = XGIEnterVT;
+ pScrn->LeaveVT = XGILeaveVT;
+ pScrn->FreeScreen = XGIFreeScreen;
+ pScrn->ValidMode = XGIValidMode;
+
+
+ pXGI = XGIGetRec(pScrn);
+ if (pXGI == NULL) {
+ return FALSE;
+ }
+
+ pXGI->PciInfo = dev;
+ }
+
+ return (pScrn != NULL);
+}
+
+#else
+
+/* Mandatory */
+static Bool
+XGIProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ *
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections =
+ xf86MatchDevice(XGI_DRIVER_NAME, &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ PDEBUG(ErrorF(" --- XGIProbe \n"));
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(XGI_NAME, PCI_VENDOR_XGI,
+ XGIChipsets, XGIPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ if (numUsed <= 0)
+ return FALSE;
+
+ if (flags & PROBE_DETECT) {
+ foundScreen = TRUE;
+ }
+ else
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+#ifdef XGIDUALHEAD
+ EntityInfoPtr pEnt;
+#endif
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = NULL;
+
+ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+ XGIPciChipsets, NULL, NULL,
+ NULL, NULL, NULL))) {
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = XGI_CURRENT_VERSION;
+ pScrn->driverName = XGI_DRIVER_NAME;
+ pScrn->name = XGI_NAME;
+ pScrn->Probe = XGIProbe;
+ pScrn->PreInit = XGIPreInit;
+ pScrn->ScreenInit = XGIScreenInit;
+ pScrn->SwitchMode = XGISwitchMode;
+ pScrn->AdjustFrame = XGIAdjustFrame;
+ pScrn->EnterVT = XGIEnterVT;
+ pScrn->LeaveVT = XGILeaveVT;
+ pScrn->FreeScreen = XGIFreeScreen;
+ pScrn->ValidMode = XGIValidMode;
+ foundScreen = TRUE;
+ }
+#ifdef XGIDUALHEAD
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+#endif
+ }
+ xfree(usedChips);
+
+ return foundScreen;
+}
+#endif
+
+
+/* Some helper functions for MergedFB mode */
+
+#ifdef XGIMERGED
+
+/* Copy and link two modes form mergedfb mode
+ * (Code base taken from mga driver)
+ * Copys mode i, links the result to dest, and returns it.
+ * Links i and j in Private record.
+ * If dest is NULL, return value is copy of i linked to itself.
+ * For mergedfb auto-config, we only check the dimension
+ * against virtualX/Y, if they were user-provided.
+ */
+static DisplayModePtr
+XGICopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
+ DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ DisplayModePtr mode;
+ int dx = 0, dy = 0;
+
+ if (!((mode = xalloc(sizeof(DisplayModeRec)))))
+ return dest;
+ memcpy(mode, i, sizeof(DisplayModeRec));
+ if (!((mode->Private = xalloc(sizeof(XGIMergedDisplayModeRec))))) {
+ xfree(mode);
+ return dest;
+ }
+ ((XGIMergedDisplayModePtr) mode->Private)->CRT1 = i;
+ ((XGIMergedDisplayModePtr) mode->Private)->CRT2 = j;
+ ((XGIMergedDisplayModePtr) mode->Private)->CRT2Position = srel;
+ mode->PrivSize = 0;
+
+ switch (srel) {
+ case xgiLeftOf:
+ case xgiRightOf:
+ if (!(pScrn->display->virtualX)) {
+ dx = i->HDisplay + j->HDisplay;
+ }
+ else {
+ dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
+ }
+ dx -= mode->HDisplay;
+ if (!(pScrn->display->virtualY)) {
+ dy = max(i->VDisplay, j->VDisplay);
+ }
+ else {
+ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+ }
+ dy -= mode->VDisplay;
+ break;
+ case xgiAbove:
+ case xgiBelow:
+ if (!(pScrn->display->virtualY)) {
+ dy = i->VDisplay + j->VDisplay;
+ }
+ else {
+ dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
+ }
+ dy -= mode->VDisplay;
+ if (!(pScrn->display->virtualX)) {
+ dx = max(i->HDisplay, j->HDisplay);
+ }
+ else {
+ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+ }
+ dx -= mode->HDisplay;
+ break;
+ case xgiClone:
+ if (!(pScrn->display->virtualX)) {
+ dx = max(i->HDisplay, j->HDisplay);
+ }
+ else {
+ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+ }
+ dx -= mode->HDisplay;
+ if (!(pScrn->display->virtualY)) {
+ dy = max(i->VDisplay, j->VDisplay);
+ }
+ else {
+ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+ }
+ dy -= mode->VDisplay;
+ break;
+ }
+ mode->HDisplay += dx;
+ mode->HSyncStart += dx;
+ mode->HSyncEnd += dx;
+ mode->HTotal += dx;
+ mode->VDisplay += dy;
+ mode->VSyncStart += dy;
+ mode->VSyncEnd += dy;
+ mode->VTotal += dy;
+ mode->Clock = 0;
+
+ if (((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) >
+ pXGI->maxxfbmem) || (mode->HDisplay > 4088)
+ || (mode->VDisplay > 4096)) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Skipped %dx%d, not enough video RAM or beyond hardware specs\n",
+ mode->HDisplay, mode->VDisplay);
+ xfree(mode->Private);
+ xfree(mode);
+
+ return dest;
+ }
+
+#ifdef XGIXINERAMA
+ if (srel != xgiClone) {
+ pXGI->AtLeastOneNonClone = TRUE;
+ }
+#endif
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Merged %dx%d and %dx%d to %dx%d%s\n",
+ i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay,
+ mode->HDisplay, mode->VDisplay,
+ (srel == xgiClone) ? " (Clone)" : "");
+
+ mode->next = mode;
+ mode->prev = mode;
+
+ if (dest) {
+ mode->next = dest->next; /* Insert node after "dest" */
+ dest->next->prev = mode;
+ mode->prev = dest;
+ dest->next = mode;
+ }
+
+ return mode;
+}
+
+/* Helper function to find a mode from a given name
+ * (Code base taken from mga driver)
+ */
+static DisplayModePtr
+XGIGetModeFromName(char *str, DisplayModePtr i)
+{
+ DisplayModePtr c = i;
+ if (!i)
+ return NULL;
+ do {
+ if (strcmp(str, c->name) == 0)
+ return c;
+ c = c->next;
+ } while (c != i);
+ return NULL;
+}
+
+static DisplayModePtr
+XGIFindWidestTallestMode(DisplayModePtr i, Bool tallest)
+{
+ DisplayModePtr c = i, d = NULL;
+ int max = 0;
+ if (!i)
+ return NULL;
+ do {
+ if (tallest) {
+ if (c->VDisplay > max) {
+ max = c->VDisplay;
+ d = c;
+ }
+ }
+ else {
+ if (c->HDisplay > max) {
+ max = c->HDisplay;
+ d = c;
+ }
+ }
+ c = c->next;
+ } while (c != i);
+ return d;
+}
+
+static DisplayModePtr
+XGIGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
+ DisplayModePtr i, DisplayModePtr j,
+ XGIScrn2Rel srel)
+{
+#ifdef XGIXINERAMA
+ XGIPtr pXGI = XGIPTR(pScrn);
+#endif
+ DisplayModePtr mode1 = NULL;
+ DisplayModePtr mode2 = NULL;
+ DisplayModePtr result = NULL;
+
+#ifdef XGIXINERAMA
+ pXGI->AtLeastOneNonClone = FALSE;
+#endif
+
+ switch (srel) {
+ case xgiLeftOf:
+ case xgiRightOf:
+ mode1 = XGIFindWidestTallestMode(i, FALSE);
+ mode2 = XGIFindWidestTallestMode(j, FALSE);
+ break;
+ case xgiAbove:
+ case xgiBelow:
+ mode1 = XGIFindWidestTallestMode(i, TRUE);
+ mode2 = XGIFindWidestTallestMode(j, TRUE);
+ break;
+ case xgiClone:
+ mode1 = i;
+ mode2 = j;
+ }
+
+ if (mode1 && mode2) {
+ return (XGICopyModeNLink(pScrn, result, mode1, mode2, srel));
+ }
+ else {
+ return NULL;
+ }
+}
+
+/* Generate the merged-fb mode modelist from metamodes
+ * (Code base taken from mga driver)
+ */
+static DisplayModePtr
+XGIGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char *str,
+ DisplayModePtr i, DisplayModePtr j,
+ XGIScrn2Rel srel)
+{
+#ifdef XGIXINERAMA
+ XGIPtr pXGI = XGIPTR(pScrn);
+#endif
+ char *strmode = str;
+ char modename[256];
+ Bool gotdash = FALSE;
+ XGIScrn2Rel sr;
+ DisplayModePtr mode1 = NULL;
+ DisplayModePtr mode2 = NULL;
+ DisplayModePtr result = NULL;
+
+#ifdef XGIXINERAMA
+ pXGI->AtLeastOneNonClone = FALSE;
+#endif
+
+ do {
+ switch (*str) {
+ case 0:
+ case '-':
+ case ' ':
+ if ((strmode != str)) {
+
+ strncpy(modename, strmode, str - strmode);
+ modename[str - strmode] = 0;
+
+ if (gotdash) {
+ if (mode1 == NULL)
+ return NULL;
+ mode2 = XGIGetModeFromName(modename, j);
+ if (!mode2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for CRT2\n",
+ modename);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping metamode \"%s-%s\".\n",
+ mode1->name, modename);
+ mode1 = NULL;
+ }
+ }
+ else {
+ mode1 = XGIGetModeFromName(modename, i);
+ if (!mode1) {
+ char *tmps = str;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode \"%s\" is not a supported mode for CRT1\n",
+ modename);
+ gotdash = FALSE;
+ while (*tmps == ' ')
+ tmps++;
+ if (*tmps == '-') { /* skip the next mode */
+ tmps++;
+ while ((*tmps == ' ') && (*tmps != 0))
+ tmps++; /* skip spaces */
+ while ((*tmps != ' ') && (*tmps != '-')
+ && (*tmps != 0))
+ tmps++; /* skip modename */
+ strncpy(modename, strmode, tmps - strmode);
+ modename[tmps - strmode] = 0;
+ str = tmps - 1;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping metamode \"%s\".\n", modename);
+ mode1 = NULL;
+ }
+ }
+ gotdash = FALSE;
+ }
+ strmode = str + 1;
+ gotdash |= (*str == '-');
+
+ if (*str != 0)
+ break;
+ /* Fall through otherwise */
+
+ default:
+ if (!gotdash && mode1) {
+ sr = srel;
+ if (!mode2) {
+ mode2 = XGIGetModeFromName(mode1->name, j);
+ sr = xgiClone;
+ }
+ if (!mode2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Mode: \"%s\" is not a supported mode for CRT2\n",
+ mode1->name);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping metamode \"%s\".\n", modename);
+ mode1 = NULL;
+ }
+ else {
+ result =
+ XGICopyModeNLink(pScrn, result, mode1, mode2, sr);
+ mode1 = NULL;
+ mode2 = NULL;
+ }
+ }
+ break;
+
+ }
+
+ } while (*(str++) != 0);
+
+ return result;
+}
+
+static DisplayModePtr
+XGIGenerateModeList(ScrnInfoPtr pScrn, char *str,
+ DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
+{
+ if (str != NULL) {
+ return (XGIGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No MetaModes given, linking %s modes by default\n",
+ (srel == xgiClone) ? "first" :
+ (((srel == xgiLeftOf)
+ || (srel == xgiRightOf)) ? "widest" : "tallest"));
+ return (XGIGenerateModeListFromLargestModes(pScrn, i, j, srel));
+ }
+}
+
+static void
+XGIRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
+{
+ DisplayModePtr mode, bmode;
+ int max;
+ static const char *str = "MergedFB: Virtual %s %d\n";
+
+ if (!(pScrn->display->virtualX)) {
+ mode = bmode = pScrn->modes;
+ max = 0;
+ do {
+ if (mode->HDisplay > max)
+ max = mode->HDisplay;
+ mode = mode->next;
+ } while (mode != bmode);
+ pScrn->virtualX = max;
+ pScrn->displayWidth = max;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
+ }
+ if (!(pScrn->display->virtualY)) {
+ mode = bmode = pScrn->modes;
+ max = 0;
+ do {
+ if (mode->VDisplay > max)
+ max = mode->VDisplay;
+ mode = mode->next;
+ } while (mode != bmode);
+ pScrn->virtualY = max;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
+ }
+}
+
+static void
+XGIMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, XGIScrn2Rel srel)
+{
+ XGIPtr pXGI = XGIPTR(pScrn1);
+ MessageType from = X_DEFAULT;
+ xf86MonPtr DDC1 = (xf86MonPtr) (pScrn1->monitor->DDC);
+ xf86MonPtr DDC2 = (xf86MonPtr) (pScrn2->monitor->DDC);
+ int ddcWidthmm = 0, ddcHeightmm = 0;
+ const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
+
+ /* This sets the DPI for MergedFB mode. The problem is that
+ * this can never be exact, because the output devices may
+ * have different dimensions. This function tries to compromise
+ * through a few assumptions, and it just calculates an average DPI
+ * value for both monitors.
+ */
+
+ /* Given DisplaySize should regard BOTH monitors */
+ pScrn1->widthmm = pScrn1->monitor->widthmm;
+ pScrn1->heightmm = pScrn1->monitor->heightmm;
+
+ /* Get DDC display size; if only either CRT1 or CRT2 provided these,
+ * assume equal dimensions for both, otherwise add dimensions
+ */
+ if ((DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
+ (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0))) {
+ ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
+ ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
+ switch (srel) {
+ case xgiLeftOf:
+ case xgiRightOf:
+ ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
+ break;
+ case xgiAbove:
+ case xgiBelow:
+ ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
+ default:
+ break;
+ }
+ }
+ else if (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
+ ddcWidthmm = DDC1->features.hsize * 10;
+ ddcHeightmm = DDC1->features.vsize * 10;
+ switch (srel) {
+ case xgiLeftOf:
+ case xgiRightOf:
+ ddcWidthmm *= 2;
+ break;
+ case xgiAbove:
+ case xgiBelow:
+ ddcHeightmm *= 2;
+ default:
+ break;
+ }
+ }
+ else if (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) {
+ ddcWidthmm = DDC2->features.hsize * 10;
+ ddcHeightmm = DDC2->features.vsize * 10;
+ switch (srel) {
+ case xgiLeftOf:
+ case xgiRightOf:
+ ddcWidthmm *= 2;
+ break;
+ case xgiAbove:
+ case xgiBelow:
+ ddcHeightmm *= 2;
+ default:
+ break;
+ }
+ }
+
+ if (monitorResolution > 0) {
+
+ /* Set command line given values (overrules given options) */
+ pScrn1->xDpi = monitorResolution;
+ pScrn1->yDpi = monitorResolution;
+ from = X_CMDLINE;
+
+ }
+ else if (pXGI->MergedFBXDPI) {
+
+ /* Set option-wise given values (overrule DisplaySize) */
+ pScrn1->xDpi = pXGI->MergedFBXDPI;
+ pScrn1->yDpi = pXGI->MergedFBYDPI;
+ from = X_CONFIG;
+
+ }
+ else if (pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
+
+ /* Set values calculated from given DisplaySize */
+ from = X_CONFIG;
+ if (pScrn1->widthmm > 0) {
+ pScrn1->xDpi =
+ (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+ }
+ if (pScrn1->heightmm > 0) {
+ pScrn1->yDpi =
+ (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+ }
+ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm,
+ pScrn1->heightmm);
+
+ }
+ else if (ddcWidthmm && ddcHeightmm) {
+
+ /* Set values from DDC-provided display size */
+ from = X_PROBED;
+ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
+ pScrn1->widthmm = ddcWidthmm;
+ pScrn1->heightmm = ddcHeightmm;
+ if (pScrn1->widthmm > 0) {
+ pScrn1->xDpi =
+ (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+ }
+ if (pScrn1->heightmm > 0) {
+ pScrn1->yDpi =
+ (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+ }
+
+ }
+ else {
+
+ pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
+
+ }
+
+ /* Sanity check */
+ if (pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
+ pScrn1->yDpi = pScrn1->xDpi;
+ if (pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
+ pScrn1->xDpi = pScrn1->yDpi;
+
+ pScrn2->xDpi = pScrn1->xDpi;
+ pScrn2->yDpi = pScrn1->yDpi;
+
+ xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
+ pScrn1->xDpi, pScrn1->yDpi);
+}
+
+static void
+XGIFreeCRT2Structs(XGIPtr pXGI)
+{
+ if (pXGI->CRT2pScrn) {
+ if (pXGI->CRT2pScrn->modes) {
+ while (pXGI->CRT2pScrn->modes)
+ xf86DeleteMode(&pXGI->CRT2pScrn->modes,
+ pXGI->CRT2pScrn->modes);
+ }
+ if (pXGI->CRT2pScrn->monitor) {
+ if (pXGI->CRT2pScrn->monitor->Modes) {
+ while (pXGI->CRT2pScrn->monitor->Modes)
+ xf86DeleteMode(&pXGI->CRT2pScrn->monitor->Modes,
+ pXGI->CRT2pScrn->monitor->Modes);
+ }
+ if (pXGI->CRT2pScrn->monitor->DDC)
+ xfree(pXGI->CRT2pScrn->monitor->DDC);
+ xfree(pXGI->CRT2pScrn->monitor);
+ }
+ xfree(pXGI->CRT2pScrn);
+ pXGI->CRT2pScrn = NULL;
+ }
+}
+
+#endif /* End of MergedFB helpers */
+
+static xf86MonPtr
+XGIInternalDDC(ScrnInfoPtr pScrn, int crtno)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned char buffer[256];
+
+ int RealOff;
+ unsigned char *page;
+
+ xf86MonPtr pMonitor = NULL;
+ xf86Int10InfoPtr pInt = NULL; /* Our int10 */
+
+ /*yilin 03/10/2008: set the monitor default size to 310mm x 240mm to fix KDE font too small problem*/
+ pScrn->monitor->widthmm = 310;
+ pScrn->monitor->heightmm = 240;
+
+ static char *crtno_means_str[] = {
+ "CRT1", "DVI", "CRT2"
+ };
+
+ if (crtno > 2 || crtno < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "XGIInternalDDC(): Can not get EDID for crtno = %d,abort.\n",
+ crtno);
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "XGIInternalDDC(): getting EDID for %s.\n",
+ crtno_means_str[crtno]);
+ }
+
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+ pInt = xf86InitInt10(pXGI->pEnt->index);
+ if (pInt == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "XGIInternalDDC(): Can not initialize pInt, abort.\n");
+ return NULL;
+ }
+
+ page = xf86Int10AllocPages(pInt, 1, &RealOff);
+ if (page == NULL) {
+ xf86FreeInt10(pInt);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "XGIInternalDDC(): Can not initialize real mode buffer, abort.\n");
+ return NULL;
+ }
+ }
+
+ if (pInt) {
+ pInt->ax = 0x4f15; /* VESA DDC supporting */
+ pInt->bx = 1; /* get EDID */
+ pInt->cx = crtno; /* port 0 or 1 for CRT 1 or 2 */
+ pInt->es = SEG_ADDR(RealOff);
+ pInt->di = SEG_OFF(RealOff);
+ pInt->num = 0x10;
+ xf86ExecX86int10(pInt);
+
+ PDEBUG3(ErrorF
+ ("ax = %04X bx = %04X cx = %04X dx = %04X si = %04X di = %04X es = %04X\n",
+ pInt->ax, pInt->bx, pInt->cx, pInt->dx, pInt->si, pInt->di,
+ pInt->es));
+
+ if ((pInt->ax & 0xff00) == 0) {
+ int i;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "XGIInternalDDC(): VESA get DDC success for CRT %d.\n",
+ crtno + 1);
+
+ for (i = 0; i < 128; i++) {
+ buffer[i] = page[i];
+ }
+
+#ifdef DEBUG5
+ for (i = 0; i < 128; i += 16) {
+ unsigned j;
+ ErrorF("EDID[%02X]", i);
+ for (j = 0; j < 16; j++) {
+ ErrorF(" %02X", buffer[i + j]);
+ }
+ ErrorF("\n");
+ }
+#endif /* DEBUG3 */
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ /* Jong 09/04/2007; Alan fixed abnormal EDID data */
+ /* pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer) ; */
+ if ( (buffer[0]==0) && (buffer[7]==0) )
+ {
+ for (i=1;i<7;i++)
+ {
+ if (buffer[i]!=0xFF)
+ break;
+ }
+ if (i==7)
+ {
+ pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer);
+ }
+ }
+
+ if (pMonitor == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "CRT%d DDC EDID corrupt\n", crtno + 1);
+ return (NULL);
+ }
+ xf86UnloadSubModule("ddc");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "XGIInternalDDC(): VESA get DDC fail for CRT %d.\n",
+ crtno + 1);
+ }
+
+ xf86Int10FreePages(pInt, page, 1);
+ xf86FreeInt10(pInt);
+ }
+ return pMonitor;
+}
+
+/* static xf86MonPtr
+XGIDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ if(IS_DUAL_HEAD(pXGI))
+ {
+ if(IS_SECOND_HEAD(pXGI))
+ {
+ *crtnum = 1;
+ return(XGIInternalDDC(pScrn, 0));
+ }
+ else
+ {
+ *crtnum = 2;
+ return(XGIInternalDDC(pScrn, 1));
+ }
+ }
+ else if(pXGI->CRT1off)
+ {
+ *crtnum = 2;
+ return(XGIInternalDDC(pScrn, 1));
+ }
+ else
+ {
+ *crtnum = 1;
+ return(XGIInternalDDC(pScrn, 0));
+ }
+} */
+
+
+#ifdef DEBUG5
+static void
+XGIDumpMonitorInfo(xf86MonPtr pMonitor)
+{
+ struct detailed_timings *pd_timings;
+ Uchar *pserial;
+ Uchar *pascii_data;
+ Uchar *pname;
+ struct monitor_ranges *pranges;
+ struct std_timings *pstd_t;
+ struct whitePoints *pwp;
+ int i, j;
+
+ if (pMonitor == NULL) {
+ ErrorF("Monitor is NULL");
+ return;
+ }
+
+ ErrorF("pMonitor->scrnIndex = %d\n", pMonitor->scrnIndex);
+ ErrorF
+ ("vendor = %c%c%c%c, prod_id = %x serial = %d week = %d year = %d\n",
+ pMonitor->vendor.name[0], pMonitor->vendor.name[1],
+ pMonitor->vendor.name[2], pMonitor->vendor.name[3],
+ pMonitor->vendor.prod_id, pMonitor->vendor.serial,
+ pMonitor->vendor.week, pMonitor->vendor.year);
+
+ ErrorF("ver = %d %d\n", pMonitor->ver.version, pMonitor->ver.revision);
+ ErrorF("intput type = %d voltage = %d setup = %d sync = %d\n",
+ pMonitor->features.input_type,
+ pMonitor->features.input_voltage,
+ pMonitor->features.input_setup, pMonitor->features.input_sync);
+ ErrorF("hsize = %d vsize = %d gamma=%8.3f\n",
+ pMonitor->features.hsize,
+ pMonitor->features.vsize, pMonitor->features.gamma);
+
+ ErrorF("dpms = %d display_type = %d msc = %d\n",
+ pMonitor->features.dpms,
+ pMonitor->features.display_type, pMonitor->features.msc);
+ ErrorF
+ ("redx,redy,greenx,greeny,bluex,bluey,whitex,whitey = %8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f\n",
+ pMonitor->features.redx, pMonitor->features.redy,
+ pMonitor->features.greenx, pMonitor->features.greeny,
+ pMonitor->features.bluex, pMonitor->features.bluey,
+ pMonitor->features.whitex, pMonitor->features.whitey);
+
+ ErrorF("established_timings = (t1)%d%d%d%d%d%d%d%d",
+ (pMonitor->timings1.t1 >> 7) & 1,
+ (pMonitor->timings1.t1 >> 6) & 1,
+ (pMonitor->timings1.t1 >> 5) & 1,
+ (pMonitor->timings1.t1 >> 4) & 1,
+ (pMonitor->timings1.t1 >> 3) & 1,
+ (pMonitor->timings1.t1 >> 2) & 1,
+ (pMonitor->timings1.t1 >> 1) & 1,
+ (pMonitor->timings1.t1 >> 0) & 1);
+ ErrorF("(t2) %d%d%d%d%d%d%d%d",
+ (pMonitor->timings1.t1 >> 7) & 1,
+ (pMonitor->timings1.t1 >> 6) & 1,
+ (pMonitor->timings1.t1 >> 5) & 1,
+ (pMonitor->timings1.t1 >> 4) & 1,
+ (pMonitor->timings1.t1 >> 3) & 1,
+ (pMonitor->timings1.t1 >> 2) & 1,
+ (pMonitor->timings1.t1 >> 1) & 1,
+ (pMonitor->timings1.t1 >> 0) & 1);
+ ErrorF("(t_manu)%d%d%d%d%d%d%d%d\n",
+ (pMonitor->timings1.t_manu >> 7) & 1,
+ (pMonitor->timings1.t_manu >> 6) & 1,
+ (pMonitor->timings1.t_manu >> 5) & 1,
+ (pMonitor->timings1.t_manu >> 4) & 1,
+ (pMonitor->timings1.t_manu >> 3) & 1,
+ (pMonitor->timings1.t_manu >> 2) & 1,
+ (pMonitor->timings1.t_manu >> 1) & 1,
+ (pMonitor->timings1.t_manu >> 0) & 1);
+
+ for (i = 0; i < 7; i++) {
+ ErrorF
+ ("std timing %d: hsize = %d, vsize = %d, refresh = %d, id = %d\n",
+ i, pMonitor->timings2[i].hsize, pMonitor->timings2[i].vsize,
+ pMonitor->timings2[i].refresh, pMonitor->timings2[i].id);
+ }
+
+ for (i = 0; i < 4; i++) {
+ ErrorF("Detail timing section %d\n", i);
+ ErrorF("type = %x\n", pMonitor->det_mon[i].type);
+ switch (pMonitor->det_mon[i].type) {
+ case DS_SERIAL:
+ ErrorF("type = %x DS_SERIAL = %x\n", pMonitor->det_mon[i].type,
+ DS_SERIAL);
+ break;
+ case DS_ASCII_STR:
+ ErrorF("type = %x DS_ASCII_STR = %x\n", pMonitor->det_mon[i].type,
+ DS_ASCII_STR);
+ break;
+ case DS_NAME:
+ ErrorF("type = %x DS_NAME = %x\n", pMonitor->det_mon[i].type,
+ DS_NAME);
+ break;
+ case DS_RANGES:
+ ErrorF("type = %x DS_RANGES = %x\n", pMonitor->det_mon[i].type,
+ DS_RANGES);
+ break;
+ case DS_WHITE_P:
+ ErrorF("type = %x DS_WHITE_P = %x\n", pMonitor->det_mon[i].type,
+ DS_WHITE_P);
+ break;
+ case DS_STD_TIMINGS:
+ ErrorF("type = %x DS_STD_TIMINGS = %x\n",
+ pMonitor->det_mon[i].type, DS_STD_TIMINGS);
+ break;
+ }
+ switch (pMonitor->det_mon[i].type) {
+ case DS_SERIAL:
+ pserial = pMonitor->det_mon[i].section.serial;
+ ErrorF("seial: ");
+ for (j = 0; j < 13; j++) {
+ ErrorF("%02X", pserial[j]);
+ }
+ ErrorF("\n");
+ break;
+ case DS_ASCII_STR:
+ pascii_data = pMonitor->det_mon[i].section.ascii_data;
+ ErrorF("ascii: ");
+ for (j = 0; j < 13; j++) {
+ ErrorF("%c", pascii_data[j]);
+ }
+ ErrorF("\n");
+ break;
+ case DS_NAME:
+ pname = pMonitor->det_mon[i].section.name;
+ ErrorF("name: ");
+ for (j = 0; j < 13; j++) {
+ ErrorF("%c", pname[j]);
+ }
+ ErrorF("\n");
+ break;
+ case DS_RANGES:
+ pranges = &(pMonitor->det_mon[i].section.ranges);
+ ErrorF
+ ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
+ pranges->min_v, pranges->max_v, pranges->min_h,
+ pranges->max_h, pranges->max_clock);
+ break;
+ case DS_WHITE_P:
+ pwp = pMonitor->det_mon[i].section.wp;
+ for (j = 0; j < 2; j++) {
+ ErrorF
+ ("wp[%d].index = %d white_x = %8.3f white_y = %8.3f white_gamma = %8.3f\n",
+ j, pwp[j].index, pwp[j].white_x, pwp[j].white_y,
+ pwp[j].white_gamma);
+ }
+ break;
+ case DS_STD_TIMINGS:
+ pstd_t = pMonitor->det_mon[i].section.std_t;
+ for (j = 0; j < 5; j++) {
+ ErrorF
+ ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
+ j, pstd_t[j].hsize, pstd_t[j].vsize, pstd_t[j].refresh,
+ pstd_t[j].id);
+ }
+ break;
+ case DT:
+
+ pd_timings = &pMonitor->det_mon[i].section.d_timings;
+ ErrorF("Detail Timing Descriptor\n");
+ ErrorF("clock = %d\n", pd_timings->clock);
+ ErrorF("h_active = %d\n", pd_timings->h_active);
+ ErrorF("h_blanking = %d\n", pd_timings->h_blanking);
+ ErrorF("v_active = %d\n", pd_timings->v_active);
+ ErrorF("v_blanking = %d\n", pd_timings->v_blanking);
+ ErrorF("h_sync_off = %d\n", pd_timings->h_sync_off);
+ ErrorF("h_sync_width = %d\n", pd_timings->h_sync_width);
+ ErrorF("v_sync_off = %d\n", pd_timings->v_sync_off);
+ ErrorF("v_sync_width = %d\n", pd_timings->v_sync_width);
+ ErrorF("h_size = %d\n", pd_timings->h_size);
+ ErrorF("v_size = %d\n", pd_timings->v_size);
+ ErrorF("h_border = %d\n", pd_timings->h_border);
+ ErrorF("v_border = %d\n", pd_timings->v_border);
+ ErrorF("interlaced = %d stereo = %x sync = %x misc = %x\n",
+ pd_timings->interlaced,
+ pd_timings->stereo, pd_timings->sync, pd_timings->misc);
+ break;
+ }
+ }
+
+ for (i = 0; i < 128; i += 16) {
+ ErrorF("rawData[%02X]:", i);
+ for (j = 0; j < 16; j++) {
+ ErrorF(" %02X", pMonitor->rawData[i + j]);
+ }
+ ErrorF("\n");
+ }
+}
+#endif
+
+static void
+XGIGetMonitorRangeByDDC(MonitorRangePtr range, xf86MonPtr pMonitor)
+{
+ int i, j;
+ float VF, HF;
+ struct detailed_timings *pd_timings;
+ struct monitor_ranges *pranges;
+ struct std_timings *pstd_t;
+
+ if ((range == NULL) || (pMonitor == NULL)) {
+ return; /* ignore */
+ }
+
+ PDEBUG5(ErrorF
+ ("establish timing t1 = %02x t2=%02x\n", pMonitor->timings1.t1,
+ pMonitor->timings1.t2));
+
+ for (i = 0, j = 0; i < 8; i++, j++)
+ {
+ if (establish_timing[j].width == -1) {
+ continue;
+ }
+
+ if (pMonitor->timings1.t1 & (1 << i))
+ {
+ PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
+ establish_timing[j].width,
+ establish_timing[j].height,
+ establish_timing[j].VRefresh,
+ establish_timing[j].HSync));
+
+ if (range->loH > establish_timing[j].HSync) {
+ range->loH = establish_timing[j].HSync;
+ }
+
+ if (range->hiH < establish_timing[j].HSync) {
+ range->hiH = establish_timing[j].HSync;
+ }
+
+ if (range->loV > establish_timing[j].VRefresh) {
+ range->loV = establish_timing[j].VRefresh;
+ }
+
+ if (range->hiV < establish_timing[j].VRefresh) {
+ range->hiV = establish_timing[j].VRefresh;
+ }
+ }
+ }
+
+ PDEBUG5(ErrorF
+ ("check establish timing t1:range ( %8.3f %8.3f %8.3f %8.3f )\n",
+ range->loH, range->loV, range->hiH, range->hiV));
+
+ for (i = 0; i < 8; i++, j++) {
+ if (establish_timing[j].width == -1) {
+ continue;
+ }
+
+ if (pMonitor->timings1.t2 & (1 << i)) {
+ PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
+ establish_timing[j].width,
+ establish_timing[j].height,
+ establish_timing[j].VRefresh,
+ establish_timing[j].HSync));
+
+ if (range->loH > establish_timing[j].HSync) {
+ range->loH = establish_timing[j].HSync;
+ }
+
+ if (range->hiH < establish_timing[j].HSync) {
+ range->hiH = establish_timing[j].HSync;
+ }
+
+ if (range->loV > establish_timing[j].VRefresh) {
+ range->loV = establish_timing[j].VRefresh;
+ }
+
+ if (range->hiV < establish_timing[j].VRefresh) {
+ range->hiV = establish_timing[j].VRefresh;
+ }
+ }
+ }
+ PDEBUG5(ErrorF
+ ("check establish timing t2:range ( %8.3f %8.3f %8.3f %8.3f )\n",
+ range->loH, range->loV, range->hiH, range->hiV));
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0; StdTiming[j].width != -1; j++) {
+ if ((StdTiming[j].width == pMonitor->timings2[i].hsize) &&
+ (StdTiming[j].height == pMonitor->timings2[i].vsize) &&
+ (StdTiming[j].VRefresh == pMonitor->timings2[i].refresh)) {
+ PDEBUG5(ErrorF("pMonitor->timings2[%d]= %d %d %d %d\n",
+ i,
+ pMonitor->timings2[i].hsize,
+ pMonitor->timings2[i].vsize,
+ pMonitor->timings2[i].refresh,
+ pMonitor->timings2[i].id));
+ HF = StdTiming[j].HSync;
+ VF = StdTiming[j].VRefresh;
+ if (range->loH > HF)
+ range->loH = HF;
+ if (range->loV > VF)
+ range->loV = VF;
+ if (range->hiH < HF)
+ range->hiH = HF;
+ if (range->hiV < VF)
+ range->hiV = VF;
+ break;
+ }
+ }
+ }
+ PDEBUG5(ErrorF
+ ("check standard timing :range ( %8.3f %8.3f %8.3f %8.3f )\n",
+ range->loH, range->loV, range->hiH, range->hiV));
+
+ for (i = 0; i < 4; i++) {
+ switch (pMonitor->det_mon[i].type) {
+ case DS_RANGES:
+ pranges = &(pMonitor->det_mon[i].section.ranges);
+ PDEBUG5(ErrorF
+ ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
+ pranges->min_v, pranges->max_v, pranges->min_h,
+ pranges->max_h, pranges->max_clock));
+
+ if (range->loH > pranges->min_h)
+ range->loH = pranges->min_h;
+ if (range->loV > pranges->min_v)
+ range->loV = pranges->min_v;
+ if (range->hiH < pranges->max_h)
+ range->hiH = pranges->max_h;
+ if (range->hiV < pranges->max_v)
+ range->hiV = pranges->max_v;
+ PDEBUG5(ErrorF
+ ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
+ range->loV, range->hiH, range->hiV));
+ break;
+
+ case DS_STD_TIMINGS:
+ pstd_t = pMonitor->det_mon[i].section.std_t;
+ for (j = 0; j < 5; j++) {
+ int k;
+ PDEBUG5(ErrorF
+ ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
+ j, pstd_t[j].hsize, pstd_t[j].vsize,
+ pstd_t[j].refresh, pstd_t[j].id));
+ for (k = 0; StdTiming[k].width != -1; k++) {
+ if ((StdTiming[k].width == pstd_t[j].hsize) &&
+ (StdTiming[k].height == pstd_t[j].vsize) &&
+ (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
+ if (range->loH > StdTiming[k].HSync)
+ range->loH = StdTiming[k].HSync;
+ if (range->hiH < StdTiming[k].HSync)
+ range->hiH = StdTiming[k].HSync;
+ if (range->loV > StdTiming[k].VRefresh)
+ range->loV = StdTiming[k].VRefresh;
+ if (range->hiV < StdTiming[k].VRefresh)
+ range->hiV = StdTiming[k].VRefresh;
+ break;
+ }
+
+ }
+ }
+ break;
+
+ case DT:
+
+ pd_timings = &pMonitor->det_mon[i].section.d_timings;
+
+ HF = pd_timings->clock / (pd_timings->h_active +
+ pd_timings->h_blanking);
+ VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
+ HF /= 1000; /* into KHz Domain */
+ if (range->loH > HF)
+ range->loH = HF;
+ if (range->hiH < HF)
+ range->hiH = HF;
+ if (range->loV > VF)
+ range->loV = VF;
+ if (range->hiV < VF)
+ range->hiV = VF;
+ PDEBUG(ErrorF
+ ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
+ HF, VF, range->loH, range->loV, range->hiH, range->hiV));
+ break;
+ }
+ }
+ PDEBUG5(ErrorF
+ ("Done range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, range->loV,
+ range->hiH, range->hiV));
+
+}
+
+static void
+XGISyncDDCMonitorRange(MonPtr monitor, MonitorRangePtr range)
+{
+ int i;
+ if ((monitor == NULL) || (range == NULL)) {
+ return;
+ }
+
+ for (i = 0; i < monitor->nHsync; i++) {
+ monitor->hsync[i].lo = range->loH;
+ monitor->hsync[i].hi = range->hiH;
+ }
+
+ for (i = 0; i < monitor->nVrefresh; i++) {
+ monitor->vrefresh[i].lo = range->loV;
+ monitor->vrefresh[i].hi = range->hiV;
+ }
+}
+
+static void
+XGIDDCPreInit(ScrnInfoPtr pScrn)
+{
+
+ XGIPtr pXGI = XGIPTR(pScrn);
+ xf86MonPtr pMonitor = NULL;
+ xf86MonPtr pMonitorDVI = NULL;
+ Bool didddc2;
+
+ static const char *ddcsstr =
+ "CRT%d DDC monitor info: ************************************\n";
+ static const char *ddcestr =
+ "End of CRT%d DDC monitor info ******************************\n";
+
+ /* Now for something completely different: DDC.
+ * For 300 and 315/330 series, we provide our
+ * own functions (in order to probe CRT2 as well)
+ * If these fail, use the VBE.
+ * All other chipsets will use VBE. No need to re-invent
+ * the wheel there.
+ */
+
+ pXGI->pVbe = NULL;
+ didddc2 = FALSE;
+
+ /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */
+ if (IS_DUAL_HEAD(pXGI) && (!didddc2) && !IS_SECOND_HEAD(pXGI))
+ didddc2 = TRUE;
+
+ if (!didddc2) {
+ /* If CRT1 is off or LCDA, skip DDC via VBE */
+ if ((pXGI->CRT1off) || (pXGI->VBFlags & CRT1_LCDA))
+ didddc2 = TRUE;
+ }
+
+ /* Now (re-)load and initialize the DDC module */
+ if (!didddc2) {
+
+ if (xf86LoadSubModule(pScrn, "ddc")) {
+
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ pMonitor = XGIInternalDDC(pScrn, 0);
+ if (pMonitor == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Could not retrieve DDC data\n");
+ }
+
+ if (pXGI->xgi_HwDevExt.jChipType == XG21) {
+ PDEBUG(ErrorF("Getting XG21 DVI EDID...\n"));
+ pMonitorDVI = XGIInternalDDC(pScrn, 1);
+ if (pMonitorDVI == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Could not retrieve DVI DDC data\n");
+ }
+ else /* Jong 12/04/2007; used for filtering of CRT1 modes */
+ g_pMonitorDVI=pMonitorDVI;
+
+ if ((pMonitor == NULL) && (pMonitorDVI != NULL)) {
+ pMonitor = pMonitorDVI;
+ }
+ }
+
+ }
+ }
+
+ /* initialize */
+
+ if (pMonitor) {
+ pXGI->CRT1Range.loH = 1000;
+ pXGI->CRT1Range.loV = 1000;
+ pXGI->CRT1Range.hiH = 0;
+ pXGI->CRT1Range.hiV = 0;
+ XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitor);
+ }
+ else {
+ pXGI->CRT1Range.loH = 0;
+ pXGI->CRT1Range.loV = 0;
+ pXGI->CRT1Range.hiH = 1000;
+ pXGI->CRT1Range.hiV = 1000;
+ }
+
+ if (pMonitorDVI) {
+ pXGI->CRT2Range.loV = 1000;
+ pXGI->CRT2Range.loH = 1000;
+ pXGI->CRT2Range.hiH = 0;
+ pXGI->CRT2Range.hiV = 0;
+ XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorDVI);
+ }
+ else {
+ pXGI->CRT2Range.loH = 0;
+ pXGI->CRT2Range.loV = 0;
+ pXGI->CRT2Range.hiH = 1000;
+ pXGI->CRT2Range.hiV = 1000;
+ }
+
+ if (pXGI->xgi_HwDevExt.jChipType == XG21) {
+ /* Mode range intersecting */
+ if (pXGI->CRT1Range.loH < pXGI->CRT2Range.loH) {
+ pXGI->CRT1Range.loH = pXGI->CRT2Range.loH;
+ }
+ if (pXGI->CRT1Range.loV < pXGI->CRT2Range.loV) {
+ pXGI->CRT1Range.loV = pXGI->CRT2Range.loV;
+ }
+ if (pXGI->CRT1Range.hiH > pXGI->CRT2Range.hiH) {
+ pXGI->CRT1Range.hiH = pXGI->CRT2Range.hiH;
+ }
+ if (pXGI->CRT1Range.hiV > pXGI->CRT2Range.hiV) {
+ pXGI->CRT1Range.hiV = pXGI->CRT2Range.hiV;
+ }
+ }
+
+ if (pMonitor) {
+ XGISyncDDCMonitorRange(pScrn->monitor, &pXGI->CRT1Range);
+ }
+
+ if (pScrn->monitor) {
+ pScrn->monitor->DDC = pMonitor;
+ }
+
+ return;
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ pXGI->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
+ if (pXGI->CRT2pScrn->monitor) {
+ DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
+ memcpy(pXGI->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
+ pXGI->CRT2pScrn->monitor->DDC = NULL;
+ pXGI->CRT2pScrn->monitor->Modes = NULL;
+ tempm = pScrn->monitor->Modes;
+ while (tempm) {
+ if (!(newm = xalloc(sizeof(DisplayModeRec))))
+ break;
+ memcpy(newm, tempm, sizeof(DisplayModeRec));
+ if (!(newm->name = xalloc(strlen(tempm->name) + 1))) {
+ xfree(newm);
+ break;
+ }
+ strcpy(newm->name, tempm->name);
+ if (!pXGI->CRT2pScrn->monitor->Modes)
+ pXGI->CRT2pScrn->monitor->Modes = newm;
+ if (currentm) {
+ currentm->next = newm;
+ newm->prev = currentm;
+ }
+ currentm = newm;
+ tempm = tempm->next;
+ }
+
+ if ((pMonitor = XGIInternalDDC(pXGI->CRT2pScrn, 1))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2);
+ xf86PrintEDID(pMonitor);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2);
+ xf86SetDDCproperties(pXGI->CRT2pScrn, pMonitor);
+
+ pXGI->CRT2pScrn->monitor->DDC = pMonitor;
+
+ /* use DDC data if no ranges in config file */
+ if (!pXGI->CRT2HSync) {
+ pXGI->CRT2pScrn->monitor->nHsync = 0;
+ }
+ if (!pXGI->CRT2VRefresh) {
+ pXGI->CRT2pScrn->monitor->nVrefresh = 0;
+ }
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Failed to read DDC data for CRT2\n");
+ }
+ }
+ else {
+ XGIErrorLog(pScrn,
+ "Failed to allocate memory for CRT2 monitor, %s.\n",
+ mergeddisstr);
+ if (pXGI->CRT2pScrn)
+ xfree(pXGI->CRT2pScrn);
+ pXGI->CRT2pScrn = NULL;
+ pXGI->MergedFB = FALSE;
+ }
+ }
+#endif
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1);
+ }
+#endif
+
+ /* end of DDC */
+}
+
+#ifdef DEBUG5
+static void
+XGIDumpModePtr(DisplayModePtr mode)
+{
+ if (mode == NULL)
+ return;
+
+ ErrorF("Dump DisplayModePtr mode\n");
+ ErrorF("name = %s\n", mode->name);
+ /* ModeStatus status; */
+ ErrorF("type = %d\n", mode->type);
+ ErrorF("Clock = %d\n", mode->Clock);
+ ErrorF("HDisplay = %d\n", mode->HDisplay);
+ ErrorF("HSyncStart = %d\n", mode->HSyncStart);
+ ErrorF("HSyncEnd = %d\n", mode->HSyncEnd);
+ ErrorF("HTotal = %d\n", mode->HTotal);
+ ErrorF("HSkew = %d\n", mode->HSkew);
+ ErrorF("VDisplay = %d\n", mode->VDisplay);
+ ErrorF("VSyncStart = %d\n", mode->VSyncStart);
+ ErrorF("VSyncEnd = %d\n", mode->VSyncEnd);
+ ErrorF("VTotal = %d\n", mode->VTotal);
+ ErrorF("VScan = %d\n", mode->VScan);
+ ErrorF("Flags = %d\n", mode->Flags);
+
+
+ ErrorF("ClockIndex = %d\n", mode->ClockIndex);
+ ErrorF("SynthClock = %d\n", mode->SynthClock);
+ ErrorF("CrtcHDisplay = %d\n", mode->CrtcHDisplay);
+ ErrorF("CrtcHBlankStart = %d\n", mode->CrtcHBlankStart);
+ ErrorF("CrtcHSyncStart = %d\n", mode->CrtcHSyncStart);
+ ErrorF("CrtcHSyncEnd = %d\n", mode->CrtcHSyncEnd);
+ ErrorF("CrtcHBlankEnd = %d\n", mode->CrtcHBlankEnd);
+ ErrorF("CrtcHTotal = %d\n", mode->CrtcHTotal);
+ ErrorF("CrtcHSkew = %d\n", mode->CrtcHSkew);
+ ErrorF("CrtcVDisplay = %d\n", mode->CrtcVDisplay);
+ ErrorF("CrtcVBlankStart = %d\n", mode->CrtcVBlankStart);
+ ErrorF("CrtcVSyncStart = %d\n", mode->CrtcVSyncStart);
+ ErrorF("CrtcVSyncEnd = %d\n", mode->CrtcVSyncEnd);
+ ErrorF("CrtcVBlankEnd = %d\n", mode->CrtcVBlankEnd);
+ ErrorF("CrtcVTotal = %d\n", mode->CrtcVTotal);
+ ErrorF("CrtcHAdjusted = %s\n", (mode->CrtcHAdjusted) ? "TRUE" : "FALSE");
+ ErrorF("CrtcVAdjusted = %s\n", (mode->CrtcVAdjusted) ? "TRUE" : "FALSE");
+ ErrorF("PrivSize = %d\n", mode->PrivSize);
+ /* INT32 * Private; */
+ ErrorF("PrivFlags = %d\n", mode->PrivFlags);
+ ErrorF("HSync = %8.3f\n", mode->HSync);
+ ErrorF("VRefresh = %8.3f\n", mode->VRefresh);
+}
+#endif
+
+static void
+XGIDumpMonPtr(MonPtr pMonitor)
+{
+#ifdef DEBUG5
+ int i;
+# if 0
+ DisplayModePtr mode;
+#endif
+
+ ErrorF("XGIDumpMonPtr() ... \n");
+ if (pMonitor == NULL) {
+ ErrorF("pMonitor is NULL\n");
+ }
+
+ ErrorF("id = %s, vendor = %s model = %s\n",
+ pMonitor->id, pMonitor->vendor, pMonitor->model);
+ ErrorF("nHsync = %d\n", pMonitor->nHsync);
+ ErrorF("nVrefresh = %d\n", pMonitor->nVrefresh);
+
+ for (i = 0; i < MAX_HSYNC; i++) {
+ ErrorF("hsync[%d] = (%8.3f,%8.3f)\n", i, pMonitor->hsync[i].lo,
+ pMonitor->hsync[i].hi);
+ }
+
+ for (i = 0; i < MAX_VREFRESH; i++) {
+ ErrorF("vrefresh[%d] = (%8.3f,%8.3f)\n", i, pMonitor->vrefresh[i].lo,
+ pMonitor->vrefresh[i].hi);
+ }
+
+ ErrorF("widthmm = %d, heightmm = %d\n",
+ pMonitor->widthmm, pMonitor->heightmm);
+ ErrorF("options = %p, DDC = %p\n", pMonitor->options, pMonitor->DDC);
+# if 0
+ mode = pMonitor->Modes;
+ while (1) {
+ XGIDumpModePtr(mode);
+ if (mode == pMonitor->Last) {
+ break;
+ }
+ mode = mode->next;
+ }
+# endif
+#endif /* DEBUG5 */
+}
+
+/* Jong 09/19/2007; support modeline of custom modes */
+int ModifyTypeOfSupportMode(DisplayModePtr availModes)
+{
+ int CountOfModifiedModes=0;
+ DisplayModePtr p=availModes;
+
+ while(p)
+ {
+ /* if( (p->HDisplay == 1440) && (p->VDisplay == 900)) */
+ if( p->type == 0) /* externel support modeline */
+ {
+ p->type = M_T_USERDEF;
+ CountOfModifiedModes++;
+ }
+
+ p=p->next;
+ }
+
+ return(CountOfModifiedModes);
+}
+
+
+/* Mandatory */
+static Bool
+XGIPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ XGIPtr pXGI;
+ MessageType from;
+ unsigned long int i;
+ int temp;
+ ClockRangePtr clockRanges;
+ int pix24flags;
+ int fd;
+ struct fb_fix_screeninfo fix;
+ XGIEntPtr pXGIEnt = NULL;
+ size_t memreq;
+
+#if defined(XGIMERGED) || defined(XGIDUALHEAD)
+ DisplayModePtr first, p, n;
+#endif
+ unsigned char srlockReg, crlockReg;
+ vbeInfoPtr pVbe;
+
+ /****************** Code Start ***********************/
+
+ ErrorF("XGIPreInit\n");
+
+ if (flags & PROBE_DETECT) {
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
+
+ if ((pVbe = VBEExtendedInit(NULL, index, 0))) {
+ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+ vbeFree(pVbe);
+ }
+ }
+ return TRUE;
+ }
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is the array of all screens,
+ * (pScrn is a pointer to one of these). Privates allocated using
+ * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
+ * for data that must persist across server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1) {
+ XGIErrorLog(pScrn, "Number of entities is not 1\n");
+ return FALSE;
+ }
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw")) {
+ XGIErrorLog(pScrn, "Could not load vgahw module\n");
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Due to the liberal license terms this is needed for
+ * keeping the copyright notice readable and intact in
+ * binary distributions. Removing this is a copyright
+ * infringement. Please read the license terms above.
+ */
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "XGI driver (%s)\n", XGI_RELEASE_DATE);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n");
+
+ /* Allocate a vgaHWRec */
+ if (!vgaHWGetHWRec(pScrn)) {
+ XGIErrorLog(pScrn, "Could not allocate VGA private\n");
+ return FALSE;
+ }
+
+ /* Allocate the XGIRec driverPrivate */
+ pXGI = XGIGetRec(pScrn);
+ if (pXGI == NULL) {
+ XGIErrorLog(pScrn, "Could not allocate memory for pXGI private\n");
+ return FALSE;
+ }
+
+ pXGI->IODBase = pScrn->domainIOBase;
+
+
+ /* Get the entity, and make sure it is PCI. */
+ pXGI->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pXGI->pEnt->location.type != BUS_PCI) {
+ XGIErrorLog(pScrn, "Entity's bus type is not PCI\n");
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+#ifdef XGIDUALHEAD
+ /* Allocate an entity private if necessary */
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ pXGIEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+ XGIEntityIndex)->ptr;
+ pXGI->entityPrivate = pXGIEnt;
+
+ /* If something went wrong, quit here */
+ if ((pXGIEnt->DisableDual) || (pXGIEnt->ErrorAfterFirst)) {
+ XGIErrorLog(pScrn,
+ "First head encountered fatal error, can't continue\n");
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+#endif
+
+ /* Find the PCI info for this screen */
+#ifndef XSERVER_LIBPCIACCESS
+ pXGI->PciInfo = xf86GetPciInfoForEntity(pXGI->pEnt->index);
+ pXGI->PciTag = pciTag(pXGI->PciInfo->bus, pXGI->PciInfo->device,
+ pXGI->PciInfo->func);
+#endif
+
+ pXGI->Primary = xf86IsPrimaryPci(pXGI->PciInfo);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "This adapter is %s display adapter\n",
+ (pXGI->Primary ? "primary" : "secondary"));
+
+ if (pXGI->Primary) {
+ VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
+ if (!vgaHWMapMem(pScrn)) {
+ XGIErrorLog(pScrn, "Could not map VGA memory\n");
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+
+ /* We "patch" the PIOOffset inside vgaHW in order to force
+ * the vgaHW module to use our relocated i/o ports.
+ */
+ VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
+#ifdef XSERVER_LIBPCIACCESS
+ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+#else
+ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+#endif
+ ;
+
+ pXGI->pInt = NULL;
+ if (!pXGI->Primary) {
+#if !defined(__alpha__)
+#if !defined(__powerpc__)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Initializing display adapter through int10\n");
+
+ if (xf86LoadSubModule(pScrn, "int10")) {
+ xf86LoaderReqSymLists(int10Symbols, NULL);
+ pXGI->pInt = xf86InitInt10(pXGI->pEnt->index);
+ }
+ else {
+ XGIErrorLog(pScrn, "Could not load int10 module\n");
+ }
+#endif /* !defined(__powerpc__) */
+#endif /* !defined(__alpha__) */
+ }
+
+ xf86SetOperatingState(resVgaMem, pXGI->pEnt->index, ResUnusedOpr);
+
+ /* Operations for which memory access is required */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ /* Operations for which I/O access is required */
+ pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ XGIErrorLog(pScrn, "Could not load ramdac module\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* Jong 09/19/2007; modify type of support modes to M_T_USERDEF */
+ g_CountOfUserDefinedModes=ModifyTypeOfSupportMode(pScrn->monitor->Modes);
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override. DANGEROUS!
+ */
+ if (pXGI->pEnt->device->chipset && *pXGI->pEnt->device->chipset) {
+ PDEBUG(ErrorF(" --- Chipset 1 \n"));
+ pScrn->chipset = pXGI->pEnt->device->chipset;
+ pXGI->Chipset = xf86StringToToken(XGIChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ }
+ else if (pXGI->pEnt->device->chipID >= 0) {
+ PDEBUG(ErrorF(" --- Chipset 2 \n"));
+ pXGI->Chipset = pXGI->pEnt->device->chipID;
+ pScrn->chipset =
+ (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pXGI->Chipset);
+ }
+ else {
+ PDEBUG(ErrorF(" --- Chipset 3 \n"));
+ from = X_PROBED;
+ pXGI->Chipset = DEVICE_ID(pXGI->PciInfo);
+ pScrn->chipset =
+ (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
+ }
+ if (pXGI->pEnt->device->chipRev >= 0) {
+ pXGI->ChipRev = pXGI->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pXGI->ChipRev);
+ }
+ else {
+ pXGI->ChipRev = CHIP_REVISION(pXGI->PciInfo);
+ }
+ pXGI->xgi_HwDevExt.jChipRevision = pXGI->ChipRev;
+
+ PDEBUG(ErrorF(" --- Chipset : %s \n", pScrn->chipset));
+
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * XGIProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ XGIErrorLog(pScrn, "ChipID 0x%04X is not recognised\n",
+ pXGI->Chipset);
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if (pXGI->Chipset < 0) {
+ XGIErrorLog(pScrn, "Chipset \"%s\" is not recognised\n",
+ pScrn->chipset);
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Determine chipset and VGA engine type */
+ pXGI->ChipFlags = 0;
+ pXGI->XGI_SD_Flags = 0;
+
+ switch (pXGI->Chipset) {
+ case PCI_CHIP_XGIXG40:
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21:
+ pXGI->xgi_HwDevExt.jChipType = XG40;
+ pXGI->myCR63 = 0x63;
+ pXGI->mmioSize = 64;
+ break;
+
+ case PCI_CHIP_XGIXG27:
+ pXGI->xgi_HwDevExt.jChipType = XG27;
+ pXGI->myCR63 = 0x63;
+ pXGI->mmioSize = 64;
+ break;
+
+ default:
+ /* This driver currently only supports V3XE, V3XT, V5, V8 (all of
+ * which are XG40 chips) and Z7 (which is XG20).
+ */
+ if (pXGI->pInt) {
+ xf86FreeInt10(pXGI->pInt);
+ }
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+/* load frame_buffer */
+
+ FbDevExist = FALSE;
+ if((pXGI->Chipset != PCI_CHIP_XGIXG20)&&(pXGI->Chipset != PCI_CHIP_XGIXG21)&&( pXGI->Chipset != PCI_CHIP_XGIXG27 ))
+ {
+ if ((fd = open("/dev/fb", 'r')) != -1) {
+ PDEBUG(ErrorF("--- open /dev/fb.... \n"));
+ ioctl(fd, FBIOGET_FSCREENINFO, &fix);
+ if (fix.accel == FB_ACCEL_XGI_GLAMOUR) {
+ PDEBUG(ErrorF("--- fix.accel.... \n"));
+ FbDevExist = TRUE;
+ }
+ else
+ PDEBUG(ErrorF("--- no fix.accel.... 0x%08lx \n", fix.accel));
+ close(fd);
+ }
+ }
+
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Additionally, determine the size of the HWCursor memory area.
+ */
+ pXGI->CursorSize = 4096;
+ pix24flags = Support32bppFb;
+
+#ifdef XGIDUALHEAD
+ /* In case of Dual Head, we need to determine if we are the "master" head or
+ * the "slave" head. In order to do that, we set PrimInit to DONE in the
+ * shared entity at the end of the first initialization. The second
+ * initialization then knows that some things have already been done. THIS
+ * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
+ */
+
+ if (xf86IsEntityShared(pScrn->entityList[0])) {
+ if (pXGIEnt->lastInstance > 0) {
+ if (!xf86IsPrimInitDone(pScrn->entityList[0])) {
+ /* First Head (always CRT2) */
+ pXGI->SecondHead = FALSE;
+ pXGIEnt->pScrn_1 = pScrn;
+ pXGIEnt->CRT2ModeNo = -1;
+ pXGIEnt->CRT2ModeSet = FALSE;
+ pXGI->DualHeadMode = TRUE;
+ pXGIEnt->DisableDual = FALSE;
+ pXGIEnt->BIOS = NULL;
+ pXGIEnt->XGI_Pr = NULL;
+ pXGIEnt->RenderAccelArray = NULL;
+ }
+ else {
+ /* Second Head (always CRT1) */
+ pXGI->SecondHead = TRUE;
+ pXGIEnt->pScrn_2 = pScrn;
+ pXGI->DualHeadMode = TRUE;
+ }
+ }
+ else {
+ /* Only one screen in config file - disable dual head mode */
+ pXGI->SecondHead = FALSE;
+ pXGI->DualHeadMode = FALSE;
+ pXGIEnt->DisableDual = TRUE;
+ }
+ }
+ else {
+ /* Entity is not shared - disable dual head mode */
+ pXGI->SecondHead = FALSE;
+ pXGI->DualHeadMode = FALSE;
+ }
+#endif
+
+ /* Allocate VB_DEVICE_INFO (for mode switching code) and initialize it */
+ pXGI->XGI_Pr = NULL;
+ if (pXGIEnt && pXGIEnt->XGI_Pr) {
+ pXGI->XGI_Pr = pXGIEnt->XGI_Pr;
+ }
+
+ if (!pXGI->XGI_Pr) {
+ if (!(pXGI->XGI_Pr = xnfcalloc(sizeof(VB_DEVICE_INFO), 1))) {
+ XGIErrorLog(pScrn,
+ "Could not allocate memory for XGI_Pr private\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if (pXGIEnt)
+ pXGIEnt->XGI_Pr = pXGI->XGI_Pr;
+
+ memset(pXGI->XGI_Pr, 0, sizeof(VB_DEVICE_INFO));
+ }
+
+ /* Get our relocated IO registers */
+ pXGI->RelIO = (XGIIOADDRESS) (pXGI->IODBase |
+#ifdef XSERVER_LIBPCIACCESS
+ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+#else
+ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+#endif
+ );
+ pXGI->xgi_HwDevExt.pjIOAddress = (XGIIOADDRESS) (pXGI->RelIO + 0x30);
+ xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
+ (unsigned long) pXGI->RelIO);
+
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
+ XGIErrorLog(pScrn, "xf86SetDepthBpp() error\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Check that the returned depth is one we support */
+ temp = 0;
+ switch (pScrn->depth) {
+ case 8:
+ case 16:
+ case 24:
+#if !defined(__powerpc__)
+ case 15:
+#endif
+ break;
+ default:
+ temp = 1;
+ }
+
+ if (temp) {
+ XGIErrorLog(pScrn,
+ "Given color depth (%d) is not supported by this driver/chipset\n",
+ pScrn->depth);
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0) {
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+ }
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = { 0, 0, 0 };
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ XGIErrorLog(pScrn, "xf86SetWeight() error\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ else {
+ Bool ret = FALSE;
+ switch (pScrn->depth) {
+ case 15:
+ if ((pScrn->weight.red != 5) ||
+ (pScrn->weight.green != 5) || (pScrn->weight.blue != 5))
+ ret = TRUE;
+ break;
+ case 16:
+ if ((pScrn->weight.red != 5) ||
+ (pScrn->weight.green != 6) || (pScrn->weight.blue != 5))
+ ret = TRUE;
+ break;
+ case 24:
+ if ((pScrn->weight.red != 8) ||
+ (pScrn->weight.green != 8) || (pScrn->weight.blue != 8))
+ ret = TRUE;
+ break;
+ }
+ if (ret) {
+ XGIErrorLog(pScrn,
+ "RGB weight %d%d%d at depth %d not supported by hardware\n",
+ (int) pScrn->weight.red,
+ (int) pScrn->weight.green,
+ (int) pScrn->weight.blue, pScrn->depth);
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ }
+
+ /* Set the current layout parameters */
+ pXGI->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+ pXGI->CurrentLayout.depth = pScrn->depth;
+ /* (Inside this function, we can use pScrn's contents anyway) */
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ XGIErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ else {
+ /* We don't support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ XGIErrorLog(pScrn,
+ "Given default visual (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual),
+ pScrn->depth);
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* Due to palette & timing problems we don't support 8bpp in DHM */
+ if ((IS_DUAL_HEAD(pXGI)) && (pScrn->bitsPerPixel == 8)) {
+ XGIErrorLog(pScrn,
+ "Color depth 8 not supported in Dual Head mode.\n");
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * The cmap layer needs this to be initialised.
+ */
+ {
+ Gamma zeros = { 0.0, 0.0, 0.0 };
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ XGIErrorLog(pScrn, "xf86SetGamma() error\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ pScrn->rgbBits = 6;
+ }
+
+ from = X_DEFAULT;
+
+ /* Unlock registers */
+ xgiSaveUnlockExtRegisterLock(pXGI, &srlockReg, &crlockReg);
+
+ /* Read BIOS for 300 and 315/330 series customization */
+ pXGI->xgi_HwDevExt.pjVirtualRomBase = NULL;
+ pXGI->BIOS = NULL;
+ pXGI->xgi_HwDevExt.UseROM = FALSE;
+
+ /* Evaluate options */
+ xgiOptions(pScrn);
+
+#ifdef XGIMERGED
+ /* Due to palette & timing problems we don't support 8bpp in MFBM */
+ if ((pXGI->MergedFB) && (pScrn->bitsPerPixel == 8)) {
+ XGIErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n",
+ mergeddisstr);
+ pXGI->MergedFB = pXGI->MergedFBAuto = FALSE;
+ }
+#endif
+
+ /* Do basic configuration */
+
+ XGISetup(pScrn);
+
+ from = X_PROBED;
+#ifdef XSERVER_LIBPCIACCESS
+ pXGI->FbAddress = pXGI->PciInfo->regions[0].base_addr & 0xFFFFFFF0;
+#else
+ if (pXGI->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pXGI->FbAddress = pXGI->pEnt->device->MemBase;
+ from = X_CONFIG;
+ }
+ else {
+ pXGI->FbAddress = pXGI->PciInfo->memBase[0] & 0xFFFFFFF0;
+ }
+#endif
+
+ pXGI->realFbAddress = pXGI->FbAddress;
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "%sinear framebuffer at 0x%lX\n",
+ IS_DUAL_HEAD(pXGI) ? "Global l" : "L",
+ (unsigned long) pXGI->FbAddress);
+
+#ifdef XSERVER_LIBPCIACCESS
+ pXGI->IOAddress = pXGI->PciInfo->regions[1].base_addr & 0xFFFFFFF0;
+#else
+ if (pXGI->pEnt->device->IOBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pXGI->IOAddress = pXGI->pEnt->device->IOBase;
+ from = X_CONFIG;
+ }
+ else {
+ pXGI->IOAddress = pXGI->PciInfo->memBase[1] & 0xFFFFFFF0;
+ }
+#endif
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "MMIO registers at 0x%lX (size %ldK)\n",
+ (unsigned long) pXGI->IOAddress, pXGI->mmioSize);
+ pXGI->xgi_HwDevExt.bIntegratedMMEnabled = TRUE;
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pXGI->pEnt->index, NULL, ResExclusive)) {
+ XGIErrorLog(pScrn,
+ "xf86RegisterResources() found resource conflicts\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ from = X_PROBED;
+ if (pXGI->pEnt->device->videoRam != 0) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"VideoRAM\" ignored\n");
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam);
+
+ pXGI->FbMapSize = pXGI->availMem = pScrn->videoRam * 1024;
+ pXGI->xgi_HwDevExt.ulVideoMemorySize = pScrn->videoRam * 1024;
+ pXGI->xgi_HwDevExt.bSkipDramSizing = TRUE;
+
+ /* Calculate real availMem according to Accel/TurboQueue and
+ * HWCursur setting.
+ *
+ * TQ is max 64KiB. Reduce the available memory by 64KiB, and locate the
+ * TQ at the beginning of this last 64KiB block. This is done even when
+ * using the HWCursor, because the cursor only takes 2KiB and the queue
+ * does not seem to last that far anyway.
+ *
+ * The TQ must be located at 32KB boundaries.
+ */
+ if (pScrn->videoRam < 3072) {
+ if (pXGI->TurboQueue) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
+ pXGI->TurboQueue = FALSE;
+ }
+ }
+
+ pXGI->availMem -= (pXGI->TurboQueue) ? (64 * 1024) : pXGI->CursorSize;
+
+
+ /* In dual head mode, we share availMem equally - so align it
+ * to 8KB; this way, the address of the FB of the second
+ * head is aligned to 4KB for mapping.
+ *
+ * Check MaxXFBMem setting. Since DRI is not supported in dual head
+ * mode, we don't need the MaxXFBMem setting.
+ */
+ if (IS_DUAL_HEAD(pXGI)) {
+ if (pXGI->maxxfbmem) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
+ }
+
+ pXGI->availMem &= 0xFFFFE000;
+ pXGI->maxxfbmem = pXGI->availMem;
+ }
+ else if (pXGI->maxxfbmem) {
+ if (pXGI->maxxfbmem > pXGI->availMem) {
+ if (pXGI->xgifbMem) {
+ pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid MaxXFBMem setting. Using xgifb heap start information\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
+ pXGI->maxxfbmem = pXGI->availMem;
+ }
+ }
+ else if (pXGI->xgifbMem) {
+ if (pXGI->maxxfbmem > pXGI->xgifbMem * 1024) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "MaxXFBMem beyond xgifb heap start. Using xgifb heap start\n");
+ pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
+ }
+ }
+ }
+ else if (pXGI->xgifbMem) {
+ pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
+ }
+ else
+ pXGI->maxxfbmem = pXGI->availMem;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
+ pXGI->maxxfbmem / 1024);
+
+ pXGI->CRT1off = -1;
+
+ /* Detect video bridge and sense TV/VGA2 */
+ XGIVGAPreInit(pScrn);
+
+ /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */
+ XGICRT1PreInit(pScrn);
+
+ /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */
+ XGILCDPreInit(pScrn);
+
+ /* LCDA only supported under these conditions: */
+ if (pXGI->ForceCRT1Type == CRT1_LCDA) {
+ if (!
+ (pXGI->XGI_Pr->
+ VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV |
+ VB_XGI302LV))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Chipset/Video bridge does not support LCD-via-CRT1\n");
+ pXGI->ForceCRT1Type = CRT1_VGA;
+ }
+ else if (!(pXGI->VBFlags & CRT2_LCD)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No digitally connected LCD panel found, LCD-via-CRT1 "
+ "disabled\n");
+ pXGI->ForceCRT1Type = CRT1_VGA;
+ }
+ }
+
+ /* Setup SD flags */
+ pXGI->XGI_SD_Flags |= XGI_SD_ADDLSUPFLAG;
+
+ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTV;
+ }
+
+#ifdef ENABLE_YPBPR
+ if (pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B)) {
+ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTHIVISION;
+ }
+#endif
+
+#ifdef TWDEBUG /* @@@ TEST @@@ */
+ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTYPBPRAR;
+ xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n");
+#endif
+
+ /* Detect CRT2-TV and PAL/NTSC mode */
+ XGITVPreInit(pScrn);
+
+ /* Detect CRT2-VGA */
+ XGICRT2PreInit(pScrn);
+ PDEBUG(ErrorF("3496 pXGI->VBFlags =%x\n", pXGI->VBFlags));
+
+ if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR)) {
+ if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_YPBPR)) {
+ pXGI->ForceTVType = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "YPbPr TV output not supported\n");
+ }
+ }
+
+ if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTHIVISION)) {
+ if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_HIVISION)) {
+ pXGI->ForceTVType = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "HiVision TV output not supported\n");
+ }
+ }
+
+ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+ pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
+ }
+ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTVPOS;
+ }
+ if (pXGI->XGI_Pr->
+ VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
+ pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTSCART | XGI_SD_SUPPORTVGA2);
+ }
+
+ if ((pXGI->XGI_Pr->
+ VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | VB_XGI302LV))
+ && (pXGI->VBFlags & CRT2_LCD)) {
+ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTLCDA;
+ }
+
+ pXGI->VBFlags |= pXGI->ForceCRT1Type;
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "SDFlags %lx\n", pXGI->XGI_SD_Flags);
+#endif
+
+
+ if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) {
+ xf86DrvMsg(pScrn->scrnIndex, pXGI->CRT1gammaGiven ? X_CONFIG : X_INFO,
+ "CRT1 gamma correction is %s\n",
+ pXGI->CRT1gamma ? "enabled" : "disabled");
+ }
+
+ /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART, HIVISION, YPBPR) */
+ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+ if (pXGI->ForceTVType != -1) {
+ pXGI->VBFlags &= ~(TV_INTERFACE);
+ pXGI->VBFlags |= pXGI->ForceTVType;
+ if (pXGI->VBFlags & TV_YPBPR) {
+ pXGI->VBFlags &= ~(TV_STANDARD);
+ pXGI->VBFlags &= ~(TV_YPBPRAR);
+ pXGI->VBFlags |= pXGI->ForceYPbPrType;
+ pXGI->VBFlags |= pXGI->ForceYPbPrAR;
+ }
+ }
+ }
+
+ /* Check if CRT1 used or needed. There are three cases where this can
+ * happen:
+ * - No video bridge.
+ * - No CRT2 output.
+ * - Depth = 8 and bridge=LVDS|301B-DH
+ * - LCDA
+ */
+ if (((pXGI->XGI_Pr->VBType & VB_XGIVB) == 0)
+ || ((pXGI->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)) == 0)
+ || ((pScrn->bitsPerPixel == 8)
+ && (pXGI->XGI_Pr->VBType & VB_XGI301LV302LV))
+ || (pXGI->VBFlags & CRT1_LCDA)) {
+ pXGI->CRT1off = 0;
+ }
+
+
+ /* Handle TVStandard option */
+ if ((pXGI->NonDefaultPAL != -1) || (pXGI->NonDefaultNTSC != -1)) {
+ if (!(pXGI->XGI_Pr->VBType & VB_XGIVB)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "PALM, PALN and NTSCJ not supported on this hardware\n");
+ pXGI->NonDefaultPAL = pXGI->NonDefaultNTSC = -1;
+ pXGI->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ);
+ pXGI->XGI_SD_Flags &=
+ ~(XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
+ }
+ }
+
+#ifdef XGI_CP
+ XGI_CP_DRIVER_RECONFIGOPT
+#endif
+ /* Do some MergedFB mode initialisation */
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ pXGI->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
+ if (!pXGI->CRT2pScrn) {
+ XGIErrorLog(pScrn,
+ "Failed to allocate memory for 2nd pScrn, %s\n",
+ mergeddisstr);
+ pXGI->MergedFB = FALSE;
+ }
+ else {
+ memcpy(pXGI->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
+ }
+ }
+#endif
+ PDEBUG(ErrorF("3674 pXGI->VBFlags =%x\n", pXGI->VBFlags));
+
+ /* Determine CRT1<>CRT2 mode
+ * Note: When using VESA or if the bridge is in slavemode, display
+ * is ALWAYS in MIRROR_MODE!
+ * This requires extra checks in functions using this flag!
+ * (see xgi_video.c for example)
+ */
+ if (pXGI->VBFlags & DISPTYPE_DISP2) {
+ if (pXGI->CRT1off) { /* CRT2 only ------------------------------- */
+ if (IS_DUAL_HEAD(pXGI)) {
+ XGIErrorLog(pScrn,
+ "CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
+ if (pXGIEnt)
+ pXGIEnt->DisableDual = TRUE;
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ pXGI->pInt = NULL;
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ if (pXGI->MergedFBAuto) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1,
+ mergeddisstr);
+ }
+ else {
+ XGIErrorLog(pScrn, mergednocrt1, mergeddisstr);
+ }
+ if (pXGI->CRT2pScrn)
+ xfree(pXGI->CRT2pScrn);
+ pXGI->CRT2pScrn = NULL;
+ pXGI->MergedFB = FALSE;
+ }
+#endif
+ pXGI->VBFlags |= VB_DISPMODE_SINGLE;
+ }
+ /* CRT1 and CRT2 - mirror or dual head ----- */
+ else if (IS_DUAL_HEAD(pXGI)) {
+ pXGI->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
+ if (pXGIEnt)
+ pXGIEnt->DisableDual = FALSE;
+ }
+ else
+ pXGI->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
+ }
+ else { /* CRT1 only ------------------------------- */
+ if (IS_DUAL_HEAD(pXGI)) {
+ XGIErrorLog(pScrn,
+ "No CRT2 output selected or no bridge detected. "
+ "Dual Head mode can't initialize.\n");
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ pXGI->pInt = NULL;
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ if (pXGI->MergedFBAuto) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2,
+ mergeddisstr);
+ }
+ else {
+ XGIErrorLog(pScrn, mergednocrt2, mergeddisstr);
+ }
+ if (pXGI->CRT2pScrn)
+ xfree(pXGI->CRT2pScrn);
+ pXGI->CRT2pScrn = NULL;
+ pXGI->MergedFB = FALSE;
+ }
+#endif
+ PDEBUG(ErrorF("3782 pXGI->VBFlags =%x\n", pXGI->VBFlags));
+ pXGI->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
+ }
+
+ /* Init Ptrs for Save/Restore functions and calc MaxClock */
+ XGIDACPreInit(pScrn);
+
+ /* ********** end of VBFlags setup ********** */
+
+ /* VBFlags are initialized now. Back them up for SlaveMode modes. */
+ pXGI->VBFlags_backup = pXGI->VBFlags;
+
+ /* Find out about paneldelaycompensation and evaluate option */
+ if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
+
+ }
+
+ /* In dual head mode, both heads (currently) share the maxxfbmem equally.
+ * If memory sharing is done differently, the following has to be changed;
+ * the other modules (eg. accel and Xv) use dhmOffset for hardware
+ * pointer settings relative to VideoRAM start and won't need to be changed.
+ */
+ if (IS_DUAL_HEAD(pXGI)) {
+ if (!IS_SECOND_HEAD(pXGI)) {
+ /* ===== First head (always CRT2) ===== */
+ /* We use only half of the memory available */
+ pXGI->maxxfbmem /= 2;
+ /* Initialize dhmOffset */
+ pXGI->dhmOffset = 0;
+ /* Copy framebuffer addresses & sizes to entity */
+ pXGIEnt->masterFbAddress = pXGI->FbAddress;
+ pXGIEnt->masterFbSize = pXGI->maxxfbmem;
+ pXGIEnt->slaveFbAddress = pXGI->FbAddress + pXGI->maxxfbmem;
+ pXGIEnt->slaveFbSize = pXGI->maxxfbmem;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%ldKB video RAM at 0x%lx available for master head (CRT2)\n",
+ pXGI->maxxfbmem / 1024, pXGI->FbAddress);
+ }
+ else {
+ /* ===== Second head (always CRT1) ===== */
+ /* We use only half of the memory available */
+ pXGI->maxxfbmem /= 2;
+ /* Adapt FBAddress */
+ pXGI->FbAddress += pXGI->maxxfbmem;
+ /* Initialize dhmOffset */
+ pXGI->dhmOffset = pXGI->availMem - pXGI->maxxfbmem;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n",
+ pXGI->maxxfbmem / 1024, pXGI->FbAddress);
+ }
+ }
+ else
+ pXGI->dhmOffset = 0;
+
+ /* Note: Do not use availMem for anything from now. Use
+ * maxxfbmem instead. (availMem does not take dual head
+ * mode into account.)
+ */
+
+#if !defined(__powerpc__)
+ /* Now load and initialize VBE module. */
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ pXGI->pVbe = VBEExtendedInit(pXGI->pInt, pXGI->pEnt->index,
+ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+ if (!pXGI->pVbe) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not initialize VBE module for DDC\n");
+ }
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not load VBE module\n");
+ }
+
+ XGIDDCPreInit(pScrn);
+#endif
+ /* From here, we mainly deal with clocks and modes */
+
+ /* Set the min pixel clock */
+ pXGI->MinClock = 5000;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pXGI->MinClock / 1000);
+
+ from = X_PROBED;
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pXGI->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pXGI->MaxClock = pXGI->pEnt->device->dacSpeeds[0];
+ else
+ pXGI->MaxClock = speed;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pXGI->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+ clockRanges->next = NULL;
+ clockRanges->minClock = pXGI->MinClock;
+ clockRanges->maxClock = pXGI->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our XGIValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+#ifdef XGIMERGED
+ pXGI->CheckForCRT2 = FALSE;
+#endif
+ XGIDumpMonPtr(pScrn->monitor);
+
+ /* Jong 12/05/2007; filter support modes of CRT1 by CRT2 DDC */
+ /* XGIFilterModeByDDC(pScrn->monitor->Modes, g_pMonitorDVI); */ /* Do it in XGIValidMode() */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048, /* min / max pitch */
+ pScrn->bitsPerPixel * 8, 128, 2048, /* min / max height */
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ XGIErrorLog(pScrn, "xf86ValidateModes() error\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Check the virtual screen against the available memory */
+
+ memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8))
+ * pScrn->virtualY;
+
+ if (memreq > pXGI->maxxfbmem) {
+ XGIErrorLog(pScrn,
+ "Virtual screen too big for memory; %ldK needed, %ldK available\n",
+ memreq / 1024, pXGI->maxxfbmem / 1024);
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ pXGI->pInt = NULL;
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ else if (pXGI->loadDRI && !IS_DUAL_HEAD(pXGI)) {
+ pXGI->maxxfbmem = memreq;
+ pXGI->DRIheapstart = pXGI->DRIheapend = 0;
+
+ if (pXGI->maxxfbmem == pXGI->availMem) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "All video memory used for framebuffer. DRI will be disabled.\n");
+ pXGI->loadDRI = FALSE;
+ }
+ else {
+ pXGI->DRIheapstart = pXGI->maxxfbmem;
+ pXGI->DRIheapend = pXGI->availMem;
+ }
+ }
+
+
+ /* Dual Head:
+ * -) Go through mode list and mark all those modes as bad,
+ * which are unsuitable for dual head mode.
+ * -) Find the highest used pixelclock on the master head.
+ */
+ if (IS_DUAL_HEAD(pXGI) && !IS_SECOND_HEAD(pXGI)) {
+ pXGIEnt->maxUsedClock = 0;
+
+ if ((p = first = pScrn->modes)) {
+ do {
+ n = p->next;
+
+ /* Modes that require the bridge to operate in SlaveMode
+ * are not suitable for Dual Head mode.
+ */
+
+ /* Search for the highest clock on first head in order to calculate
+ * max clock for second head (CRT1)
+ */
+ if ((p->status == MODE_OK)
+ && (p->Clock > pXGIEnt->maxUsedClock)) {
+ pXGIEnt->maxUsedClock = p->Clock;
+ }
+
+ p = n;
+
+ } while (p != NULL && p != first);
+ }
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ XGIErrorLog(pScrn, "No valid modes found\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Copy to CurrentLayout */
+ pXGI->CurrentLayout.mode = pScrn->currentMode;
+ pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1);
+ }
+#endif
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ BOOLEAN acceptcustommodes = TRUE;
+ BOOLEAN includelcdmodes = TRUE;
+ BOOLEAN isfordvi = FALSE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2);
+
+ clockRanges->next = NULL;
+ clockRanges->minClock = pXGI->MinClock;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = FALSE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "Min pixel clock for CRT2 is %d MHz\n",
+ clockRanges->minClock / 1000);
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+ "Max pixel clock for CRT2 is %d MHz\n",
+ clockRanges->maxClock / 1000);
+
+ if ((pXGI->XGI_Pr->
+ VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)))
+ {
+ if (!(pXGI->VBFlags & (CRT2_LCD | CRT2_VGA)))
+ includelcdmodes = FALSE;
+ if (pXGI->VBFlags & CRT2_LCD)
+ isfordvi = TRUE;
+ if (pXGI->VBFlags & CRT2_TV)
+ acceptcustommodes = FALSE;
+ }
+ else {
+ includelcdmodes = FALSE;
+ acceptcustommodes = FALSE;
+ }
+ }
+
+ if (pXGI->MergedFB) {
+
+ pXGI->CheckForCRT2 = TRUE;
+ i = xf86ValidateModes(pXGI->CRT2pScrn,
+ pXGI->CRT2pScrn->monitor->Modes,
+ pXGI->CRT2pScrn->display->modes, clockRanges,
+ NULL, 256, 4088,
+ pXGI->CRT2pScrn->bitsPerPixel * 8, 128, 4096,
+ pScrn->display->virtualX ? pScrn->virtualX : 0,
+ pScrn->display->virtualY ? pScrn->virtualY : 0,
+ pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
+ pXGI->CheckForCRT2 = FALSE;
+
+ if (i == -1) {
+ XGIErrorLog(pScrn, "xf86ValidateModes() error, %s.\n",
+ mergeddisstr);
+ XGIFreeCRT2Structs(pXGI);
+ pXGI->MergedFB = FALSE;
+ }
+
+ }
+
+ if (pXGI->MergedFB) {
+
+ if ((p = first = pXGI->CRT2pScrn->modes)) {
+ do {
+ n = p->next;
+ p = n;
+ } while (p != NULL && p != first);
+ }
+
+ xf86PruneDriverModes(pXGI->CRT2pScrn);
+
+ if (i == 0 || pXGI->CRT2pScrn->modes == NULL) {
+ XGIErrorLog(pScrn, "No valid modes found for CRT2; %s\n",
+ mergeddisstr);
+ XGIFreeCRT2Structs(pXGI);
+ pXGI->MergedFB = FALSE;
+ }
+
+ }
+
+ if (pXGI->MergedFB) {
+
+ xf86SetCrtcForModes(pXGI->CRT2pScrn, INTERLACE_HALVE_V);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2);
+
+ xf86PrintModes(pXGI->CRT2pScrn);
+
+ pXGI->CRT1Modes = pScrn->modes;
+ pXGI->CRT1CurrentMode = pScrn->currentMode;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Generating MergedFB mode list\n");
+
+ pScrn->modes = XGIGenerateModeList(pScrn, pXGI->MetaModes,
+ pXGI->CRT1Modes,
+ pXGI->CRT2pScrn->modes,
+ pXGI->CRT2Position);
+
+ if (!pScrn->modes) {
+
+ XGIErrorLog(pScrn,
+ "Failed to parse MetaModes or no modes found. %s.\n",
+ mergeddisstr);
+ XGIFreeCRT2Structs(pXGI);
+ pScrn->modes = pXGI->CRT1Modes;
+ pXGI->CRT1Modes = NULL;
+ pXGI->MergedFB = FALSE;
+
+ }
+
+ }
+
+ if (pXGI->MergedFB) {
+
+ /* If no virtual dimension was given by the user,
+ * calculate a sane one now. Adapts pScrn->virtualX,
+ * pScrn->virtualY and pScrn->displayWidth.
+ */
+ XGIRecalcDefaultVirtualSize(pScrn);
+
+ pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Update CurrentLayout */
+ pXGI->CurrentLayout.mode = pScrn->currentMode;
+ pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
+
+ }
+#endif
+
+ /* Set display resolution */
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ XGIMergedFBSetDpi(pScrn, pXGI->CRT2pScrn, pXGI->CRT2Position);
+ }
+ else
+#endif
+ xf86SetDpi(pScrn, 0, 0);
+
+ /*yilin@20080407 fix the font too small problem at low resolution*/
+ if((pScrn->xDpi < 65)||(pScrn->yDpi < 65))
+ {
+ pScrn->xDpi = 75;
+ pScrn->yDpi = 75;
+ }
+
+ /* Load fb module */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ if (!xf86LoadSubModule(pScrn, "fb")) {
+ XGIErrorLog(pScrn, "Failed to load fb module");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ break;
+ default:
+ XGIErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n",
+ pScrn->bitsPerPixel);
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(fbSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pXGI->NoAccel) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ XGIErrorLog(pScrn, "Could not load xaa module\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if (pXGI->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ XGIErrorLog(pScrn, "Could not load shadowfb module\n");
+
+ if (pXGIEnt)
+ pXGIEnt->ErrorAfterFirst = TRUE;
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+ XGIFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ /* Load the dri module if requested. */
+#ifdef XF86DRI
+ if(pXGI->loadDRI) {
+ if (xf86LoadSubModule(pScrn, "dri")) {
+ xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL);
+ }
+ else {
+ if (!IS_DUAL_HEAD(pXGI))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Remove >Load \"dri\"< from the Module section of your XF86Config file\n");
+ }
+ }
+#endif
+
+
+ /* Now load and initialize VBE module for VESA and mode restoring. */
+ if (pXGI->pVbe) {
+ vbeFree(pXGI->pVbe);
+ pXGI->pVbe = NULL;
+ }
+
+#ifdef XGIDUALHEAD
+ xf86SetPrimInitDone(pScrn->entityList[0]);
+#endif
+
+ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+
+ if (pXGI->pInt)
+ xf86FreeInt10(pXGI->pInt);
+ pXGI->pInt = NULL;
+
+ if (IS_DUAL_HEAD(pXGI)) {
+ pXGI->XGI_SD_Flags |= XGI_SD_ISDUALHEAD;
+ if (IS_SECOND_HEAD(pXGI))
+ pXGI->XGI_SD_Flags |= XGI_SD_ISDHSECONDHEAD;
+ else
+ pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ pXGI->XGI_SD_Flags |= XGI_SD_ISDHXINERAMA;
+ pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
+ }
+#endif
+ }
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB)
+ pXGI->XGI_SD_Flags |= XGI_SD_ISMERGEDFB;
+#endif
+
+ if (pXGI->enablexgictrl)
+ pXGI->XGI_SD_Flags |= XGI_SD_ENABLED;
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+XGIMapMem(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);;
+
+#ifdef XSERVER_LIBPCIACCESS
+ unsigned i;
+
+ for (i = 0; i < 2; i++) {
+ int err;
+
+ err = pci_device_map_region(pXGI->PciInfo, i, TRUE);
+ if (err) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: cound not map PCI region %u\n", i);
+ return FALSE;
+ }
+ }
+
+ pXGI->FbBase = pXGI->PciInfo->regions[0].memory;
+ pXGI->IOBase = pXGI->PciInfo->regions[1].memory;
+#else
+ int mmioFlags;
+
+ /*
+ * Map IO registers to virtual address space
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+#endif
+ pXGI->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pXGI->PciTag, pXGI->IOAddress, 0x10000);
+ if (pXGI->IOBase == NULL)
+ return FALSE;
+
+#ifdef __alpha__
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+ pXGI->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pXGI->PciTag, pXGI->IOAddress, 0x10000);
+
+ if (pXGI->IOBaseDense == NULL)
+ return FALSE;
+#endif /* __alpha__ */
+
+ pXGI->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pXGI->PciTag,
+ (unsigned long) pXGI->FbAddress,
+ pXGI->FbMapSize);
+
+ PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n", (ULONG) (pXGI->FbBase)));
+
+ if (pXGI->FbBase == NULL)
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+XGIUnmapMem(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+
+
+ /* In dual head mode, we must not unmap if the other head still
+ * assumes memory as mapped
+ */
+ if (IS_DUAL_HEAD(pXGI)) {
+ if (pXGIEnt->MapCountIOBase) {
+ pXGIEnt->MapCountIOBase--;
+ if ((pXGIEnt->MapCountIOBase == 0) || (pXGIEnt->forceUnmapIOBase)) {
+#ifdef XSERVER_LIBPCIACCESS
+ pci_device_unmap_region(pXGI->PciInfo, 1);
+#else
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->IOBase,
+ (pXGI->mmioSize * 1024));
+#endif
+ pXGIEnt->IOBase = NULL;
+ pXGIEnt->MapCountIOBase = 0;
+ pXGIEnt->forceUnmapIOBase = FALSE;
+ }
+ pXGI->IOBase = NULL;
+ }
+#ifdef __alpha__
+#ifdef XSERVER_LIBPCIACCESS
+#error "How to do dense mapping on Alpha?"
+#else
+ if (pXGIEnt->MapCountIOBaseDense) {
+ pXGIEnt->MapCountIOBaseDense--;
+ if ((pXGIEnt->MapCountIOBaseDense == 0)
+ || (pXGIEnt->forceUnmapIOBaseDense)) {
+ xf86UnMapVidMem(pScrn->scrnIndex,
+ (pointer) pXGIEnt->IOBaseDense,
+ (pXGI->mmioSize * 1024));
+ pXGIEnt->IOBaseDense = NULL;
+ pXGIEnt->MapCountIOBaseDense = 0;
+ pXGIEnt->forceUnmapIOBaseDense = FALSE;
+ }
+ pXGI->IOBaseDense = NULL;
+ }
+#endif
+#endif /* __alpha__ */
+ if (pXGIEnt->MapCountFbBase) {
+ pXGIEnt->MapCountFbBase--;
+ if ((pXGIEnt->MapCountFbBase == 0) || (pXGIEnt->forceUnmapFbBase)) {
+#ifdef XSERVER_LIBPCIACCESS
+ pci_device_unmap_region(pXGI->PciInfo, 0);
+#else
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->FbBase,
+ pXGI->FbMapSize);
+#endif
+ pXGIEnt->FbBase = NULL;
+ pXGIEnt->MapCountFbBase = 0;
+ pXGIEnt->forceUnmapFbBase = FALSE;
+
+ }
+ pXGI->FbBase = NULL;
+ }
+ }
+ else {
+#ifdef XSERVER_LIBPCIACCESS
+ pci_device_unmap_region(pXGI->PciInfo, 0);
+ pci_device_unmap_region(pXGI->PciInfo, 1);
+#else
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBase,
+ (pXGI->mmioSize * 1024));
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->FbBase,
+ pXGI->FbMapSize);
+#endif
+ pXGI->IOBase = NULL;
+ pXGI->FbBase = NULL;
+
+#ifdef __alpha__
+#ifdef XSERVER_LIBPCIACCESS
+#error "How to do dense mapping on Alpha?"
+#else
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBaseDense,
+ (pXGI->mmioSize * 1024));
+ pXGI->IOBaseDense = NULL;
+#endif
+#endif
+ }
+
+ return TRUE;
+}
+
+/*
+ * This function saves the video state.
+ */
+static void
+XGISave(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI;
+ vgaRegPtr vgaReg;
+ XGIRegPtr xgiReg;
+
+ PDEBUG(ErrorF("XGISave()\n"));
+
+ pXGI = XGIPTR(pScrn);
+
+ /* We always save master & slave */
+ if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
+ return;
+
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ xgiReg = &pXGI->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+ xgiSaveUnlockExtRegisterLock(pXGI, &xgiReg->xgiRegs3C4[0x05],
+ &xgiReg->xgiRegs3D4[0x80]);
+
+ (*pXGI->XGISave) (pScrn, xgiReg);
+
+ /* "Save" these again as they may have been changed prior to XGISave() call */
+}
+
+
+/*
+ * Initialise a new mode. This is currently done using the
+ * "initialise struct, restore/write struct to HW" model for
+ * the old chipsets (5597/530/6326). For newer chipsets,
+ * we use our own mode switching code (or VESA).
+ */
+
+static Bool
+XGIModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ XGIPtr pXGI = XGIPTR(pScrn);
+ XGIRegPtr xgiReg;
+#ifdef __powerpc__
+ unsigned char tmpval;
+#endif
+
+
+ /* PDEBUG(ErrorF("XGIModeInit(). \n")); */
+ PDEBUG(ErrorF
+ ("XGIModeInit Resolution (%d, %d) \n", mode->HDisplay,
+ mode->VDisplay));
+ PDEBUG(ErrorF("XGIModeInit VVRefresh (%8.3f) \n", mode->VRefresh));
+ PDEBUG(ErrorF("XGIModeInit Color Depth (%d) \n", pScrn->depth));
+
+ /* Jong Lin 08-26-2005; save current mode */
+ Volari_SetDefaultIdleWait(pXGI, mode->HDisplay, pScrn->depth);
+
+ andXGIIDXREG(XGICR, 0x11, 0x7f); /* Unlock CRTC registers */
+
+ XGIModifyModeInfo(mode); /* Quick check of the mode parameters */
+
+
+ if (IS_DUAL_HEAD(pXGI)) {
+ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+
+ if (!(*pXGI->ModeInit) (pScrn, mode)) {
+ XGIErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ /* Head 2 (slave) is always CRT1 */
+ XGIPreSetMode(pScrn, mode, XGI_MODE_CRT1);
+ if (!XGIBIOSSetModeCRT1(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn,
+ mode)) {
+ XGIErrorLog(pScrn, "XGIBIOSSetModeCRT1() failed\n");
+ return FALSE;
+ }
+ XGIPostSetMode(pScrn, &pXGI->ModeReg);
+ XGIAdjustFrame(pXGIEnt->pScrn_1->scrnIndex, pXGIEnt->pScrn_1->frameX0,
+ pXGIEnt->pScrn_1->frameY0, 0);
+ }
+ else
+ {
+ /* For other chipsets, use the old method */
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode)) {
+ XGIErrorLog(pScrn, "vgaHWInit() failed\n");
+ return FALSE;
+ }
+
+ /* Reset our PIOOffset as vgaHWInit might have reset it */
+ VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
+#ifdef XSERVER_LIBPCIACCESS
+ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+#else
+ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+#endif
+ ;
+
+ /* Prepare the register contents */
+ if (!(*pXGI->ModeInit) (pScrn, mode)) {
+ XGIErrorLog(pScrn, "ModeInit() failed\n");
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ xgiReg = &pXGI->ModeReg;
+
+ vgaReg->Attribute[0x10] = 0x01;
+ if (pScrn->bitsPerPixel > 8) {
+ vgaReg->Graphics[0x05] = 0x00;
+ }
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ (*pXGI->XGIRestore) (pScrn, xgiReg);
+
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+ (*pXGI->ModeInit) (pScrn, mode);
+#endif
+
+ vgaHWProtect(pScrn, FALSE);
+ }
+
+
+ if((pXGI->Chipset == PCI_CHIP_XGIXG40)||(pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27))
+ {
+ /* PDEBUG(XGIDumpRegs(pScrn)) ; */
+ PDEBUG(ErrorF(" *** PreSetMode(). \n"));
+ XGIPreSetMode(pScrn, mode, XGI_MODE_SIMU);
+ /* PDEBUG(XGIDumpRegs(pScrn)) ; */
+ PDEBUG(ErrorF(" *** Start SetMode() \n"));
+
+ if (!XGIBIOSSetMode(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, mode)) {
+ XGIErrorLog(pScrn, "XGIBIOSSetModeCRT() failed\n");
+ return FALSE;
+ }
+ Volari_EnableAccelerator(pScrn);
+ /* XGIPostSetMode(pScrn, &pXGI->ModeReg); */
+ /* outXGIIDXREG(XGISR, 0x20, 0xA1) ; */
+ /* PDEBUG(XGIDumpRegs(pScrn)) ; */
+ }
+
+ /* Update Currentlayout */
+ pXGI->CurrentLayout.mode = mode;
+
+#ifdef __powerpc__
+ inXGIIDXREG(XGICR, 0x4D, tmpval);
+ if (pScrn->depth == 16)
+ tmpval = (tmpval & 0xE0) | 0x0B; //word swap
+ else if (pScrn->depth == 24)
+ tmpval = (tmpval & 0xE0) | 0x15; //dword swap
+ else
+ tmpval = tmpval & 0xE0; // no swap
+
+ outXGIIDXREG(XGICR, 0x4D, tmpval);
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ * Restore the initial mode. To be used internally only!
+ */
+static void
+XGIRestore(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ XGIRegPtr xgiReg = &pXGI->SavedReg;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+
+
+ PDEBUG(ErrorF("XGIRestore():\n"));
+
+ /* Wait for the accelerators */
+ if (pXGI->AccelInfoPtr) {
+ (*pXGI->AccelInfoPtr->Sync) (pScrn);
+ }
+
+ vgaHWProtect(pScrn, TRUE);
+
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+#endif
+
+ (*pXGI->XGIRestore) (pScrn, xgiReg);
+
+ /* Jong 11/14/2007; resolve no display of DVI after leaving VT */
+ /* But there's no int10 for PPC... */
+ /* XGIRestorePrevMode(pScrn) ; */
+ /* works but mode is not exactly right because there're more than one mode 0x03 in table XGI330_SModeIDTable[] */
+ XGISetModeNew( &pXGI->xgi_HwDevExt, pXGI->XGI_Pr, 0x03);
+
+ vgaHWProtect(pScrn, TRUE);
+ if (pXGI->Primary) {
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ }
+
+ xgiRestoreExtRegisterLock(pXGI, xgiReg->xgiRegs3C4[5],
+ xgiReg->xgiRegs3D4[0x80]);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Our generic BlockHandler for Xv */
+static void
+XGIBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ ScrnInfoPtr pScrn = xf86Screens[i];
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ pScreen->BlockHandler = pXGI->BlockHandler;
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = XGIBlockHandler;
+
+ if (pXGI->VideoTimerCallback) {
+ (*pXGI->VideoTimerCallback) (pScrn, currentTime.milliseconds);
+ }
+
+ if (pXGI->RenderCallback) {
+ (*pXGI->RenderCallback) (pScrn);
+ }
+}
+
+/* Mandatory
+ * This gets called at the start of each server generation
+ *
+ * We use pScrn and not CurrentLayout here, because the
+ * properties we use have not changed (displayWidth,
+ * depth, bitsPerPixel)
+ */
+static Bool
+XGIScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ XGIPtr pXGI;
+ int ret;
+ VisualPtr visual;
+ unsigned long OnScreenSize;
+ int height, width, displayWidth;
+ unsigned char *FBStart;
+ XGIEntPtr pXGIEnt = NULL;
+
+ ErrorF("XGIScreenInit\n");
+ pScrn = xf86Screens[pScreen->myNum];
+
+ /* Jong 08/30/2007; no virtual screen for all cases */
+ /* Jong 08/22/2007; support modeline */
+ /* if(g_CountOfUserDefinedModes > 0) */
+ {
+ pScrn->virtualX=pScrn->currentMode->HDisplay;
+ pScrn->virtualY=pScrn->currentMode->VDisplay;
+ pScrn->displayWidth=pScrn->currentMode->HDisplay;
+ pScrn->frameX0=0;
+ pScrn->frameY0=0;
+ pScrn->frameX1=pScrn->currentMode->HDisplay-1;
+ pScrn->frameY1=pScrn->currentMode->VDisplay-1;
+ }
+
+ hwp = VGAHWPTR(pScrn);
+
+ pXGI = XGIPTR(pScrn);
+
+#if !defined(__powerpc__)
+ if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
+ if (xf86LoadSubModule(pScrn, "vbe")) {
+ xf86LoaderReqSymLists(vbeSymbols, NULL);
+ pXGI->pVbe = VBEExtendedInit(NULL, pXGI->pEnt->index,
+ SET_BIOS_SCRATCH |
+ RESTORE_BIOS_SCRATCH);
+ }
+ else {
+ XGIErrorLog(pScrn, "Failed to load VBE submodule\n");
+ }
+ }
+#endif /* if !defined(__powerpc__) */
+
+ if (IS_DUAL_HEAD(pXGI)) {
+ pXGIEnt = ENTITY_PRIVATE(pXGI);
+ pXGIEnt->refCount++;
+ }
+
+ /* Map the VGA memory and get the VGA IO base */
+ if (pXGI->Primary) {
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+ if (!vgaHWMapMem(pScrn)) {
+ XGIErrorLog(pScrn, "Could not map VGA memory window\n");
+ return FALSE;
+ }
+ }
+ vgaHWGetIOBase(hwp);
+
+ /* Patch the PIOOffset inside vgaHW to use
+ * our relocated IO ports.
+ */
+ VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
+#ifdef XSERVER_LIBPCIACCESS
+ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+#else
+ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+#endif
+ ;
+
+ /* Map the XGI memory and MMIO areas */
+ if (!XGIMapMem(pScrn)) {
+ XGIErrorLog(pScrn, "XGIMapMem() failed\n");
+ return FALSE;
+ }
+
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+#endif
+
+ /* Save the current state */
+ XGISave(pScrn);
+
+
+ PDEBUG(ErrorF("--- ScreenInit --- \n"));
+ PDEBUG(XGIDumpRegs(pScrn));
+
+ /* Initialise the first mode */
+ if (!XGIModeInit(pScrn, pScrn->currentMode)) {
+ XGIErrorLog(pScrn, "XGIModeInit() failed\n");
+ return FALSE;
+ }
+
+ PDEBUG(ErrorF("--- XGIModeInit --- \n"));
+ PDEBUG(XGIDumpRegs(pScrn));
+
+ /* Darken the screen for aesthetic reasons */
+ /* Not using Dual Head variant on purpose; we darken
+ * the screen for both displays, and un-darken
+ * it when the second head is finished
+ */
+ XGISaveScreen(pScreen, SCREEN_SAVER_ON);
+
+ /* Set the viewport */
+ XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor.
+ */
+ if (!miSetVisualTypes(pScrn->depth,
+ (pScrn->bitsPerPixel > 8) ?
+ TrueColorMask : miGetDefaultVisualMask(pScrn->
+ depth),
+ pScrn->rgbBits, pScrn->defaultVisual)) {
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ XGIErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
+ }
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+ if (pXGI->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ }
+
+ if (pXGI->ShadowFB) {
+ pXGI->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pXGI->ShadowPtr = xalloc(pXGI->ShadowPitch * height);
+ displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pXGI->ShadowPtr;
+ }
+ else {
+ pXGI->ShadowPtr = NULL;
+ FBStart = pXGI->FbBase;
+ }
+
+ if (!miSetPixmapDepths()) {
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ XGIErrorLog(pScrn, "miSetPixmapDepths() failed\n");
+ return FALSE;
+ }
+
+ /* Point cmdQueuePtr to pXGIEnt for shared usage
+ * (same technique is then eventually used in DRIScreeninit).
+ */
+ if (IS_SECOND_HEAD(pXGI))
+ pXGI->cmdQueueLenPtr = &(XGIPTR(pXGIEnt->pScrn_1)->cmdQueueLen);
+ else
+ pXGI->cmdQueueLenPtr = &(pXGI->cmdQueueLen);
+
+ pXGI->cmdQueueLen = 0; /* Force an EngineIdle() at start */
+
+#ifdef XF86DRI
+ if(pXGI->loadDRI) {
+ /* No DRI in dual head mode */
+ if (IS_DUAL_HEAD(pXGI)) {
+ pXGI->directRenderingEnabled = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DRI not supported in Dual Head mode\n");
+ }
+ else if ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27)) {
+ PDEBUG(ErrorF("--- DRI not supported \n"));
+ xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
+ "DRI not supported on this chipset\n");
+ pXGI->directRenderingEnabled = FALSE;
+ }
+ else {
+ pXGI->directRenderingEnabled = XGIDRIScreenInit(pScreen);
+ PDEBUG(ErrorF("--- DRI supported \n"));
+ }
+ }
+#endif
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+ switch (pScrn->bitsPerPixel) {
+ case 24:
+ case 8:
+ case 16:
+ case 32:
+ ret = fbScreenInit(pScreen, FBStart, width,
+ height, pScrn->xDpi, pScrn->yDpi,
+ displayWidth, pScrn->bitsPerPixel);
+ break;
+ default:
+ ret = FALSE;
+ break;
+ }
+ if (!ret) {
+ XGIErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
+ pScrn->bitsPerPixel);
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ return FALSE;
+ }
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /* Initialize RENDER ext; must be after RGB ordering fixed */
+ fbPictureInit(pScreen, 0, 0);
+
+ /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */
+ if (!pXGI->ShadowFB)
+ XGIDGAInit(pScreen);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (!pXGI->NoAccel) {
+ /* Volari_EnableAccelerator(pScrn); */
+ PDEBUG(ErrorF("---Volari Accel.. \n"));
+ Volari_AccelInit(pScreen);
+ }
+
+ PDEBUG(ErrorF("--- AccelInit --- \n"));
+ PDEBUG(XGIDumpRegs(pScrn));
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (pXGI->HWCursor) {
+ XGIHWCursorInit(pScreen);
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen)) {
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ XGIErrorLog(pScrn, "miCreateDefColormap() failed\n");
+ return FALSE;
+ }
+ if (!xf86HandleColormaps
+ (pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
+ XGILoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
+ PDEBUG(ErrorF("XGILoadPalette() check-return. \n"));
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ XGIErrorLog(pScrn, "xf86HandleColormaps() failed\n");
+ return FALSE;
+ }
+
+/*
+ if (!xf86HandleColormaps(pScreen, 256, 8, XGILoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH))
+ {
+ return FALSE;
+ }
+*/
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr) XGIDisplayPowerManagementSet, 0);
+
+ /* Init memPhysBase and fbOffset in pScrn */
+ pScrn->memPhysBase = pXGI->FbAddress;
+ pScrn->fbOffset = 0;
+
+ pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
+
+#if defined(XvExtension)
+ if (!pXGI->NoXvideo) {
+ XGIInitVideo(pScreen);
+ }
+#endif
+
+#ifdef XF86DRI
+ if (pXGI->directRenderingEnabled) {
+ /* Now that mi, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pXGI->directRenderingEnabled = XGIDRIFinishScreenInit(pScreen);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering %sabled\n",
+ (pXGI->directRenderingEnabled) ? "en" : "dis");
+ if (pXGI->directRenderingEnabled) {
+ /* TODO */
+ /* XGISetLFBConfig(pXGI); */
+ }
+#endif
+
+ /* Wrap some funcs and setup remaining SD flags */
+
+ pXGI->XGI_SD_Flags &= ~(XGI_SD_PSEUDOXINERAMA);
+
+ pXGI->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = XGICloseScreen;
+ if (IS_DUAL_HEAD(pXGI))
+ pScreen->SaveScreen = XGISaveScreenDH;
+ else
+ pScreen->SaveScreen = XGISaveScreen;
+
+ /* Install BlockHandler */
+ pXGI->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = XGIBlockHandler;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Clear frame buffer */
+ /* For CRT2, we don't do that at this point in dual head
+ * mode since the mode isn't switched at this time (it will
+ * be reset when setting the CRT1 mode). Hence, we just
+ * save the necessary data and clear the screen when
+ * going through this for CRT1.
+ */
+
+ OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
+ * (pScrn->bitsPerPixel >> 3);
+
+ /* Turn on the screen now */
+ /* We do this in dual head mode after second head is finished */
+ if (IS_DUAL_HEAD(pXGI)) {
+ if (IS_SECOND_HEAD(pXGI)) {
+ bzero(pXGI->FbBase, OnScreenSize);
+ bzero(pXGIEnt->FbBase1, pXGIEnt->OnScreenSize1);
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ }
+ else {
+ pXGIEnt->FbBase1 = pXGI->FbBase;
+ pXGIEnt->OnScreenSize1 = OnScreenSize;
+ }
+ }
+ else {
+ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+ bzero(pXGI->FbBase, OnScreenSize);
+ }
+
+ pXGI->XGI_SD_Flags &= ~XGI_SD_ISDEPTH8;
+ if (pXGI->CurrentLayout.bitsPerPixel == 8) {
+ pXGI->XGI_SD_Flags |= XGI_SD_ISDEPTH8;
+ pXGI->XGI_SD_Flags &= ~XGI_SD_SUPPORTXVGAMMA1;
+ }
+ PDEBUG(ErrorF("XGIScreenInit() End. \n"));
+ PDEBUG(XGIDumpPalette(pScrn));
+ PDEBUG(XGIDumpRegs(pScrn));
+
+ return TRUE;
+}
+
+/* Usually mandatory */
+Bool
+XGISwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ ErrorF("XGISwitchMode\n");
+
+ if (!pXGI->NoAccel) {
+ if (pXGI->AccelInfoPtr) {
+ (*pXGI->AccelInfoPtr->Sync) (pScrn);
+ PDEBUG(ErrorF("XGISwitchMode Accel Enabled. \n"));
+ }
+ }
+ PDEBUG(ErrorF
+ ("XGISwitchMode (%d, %d) \n", mode->HDisplay, mode->VDisplay));
+
+ if (!(XGIModeInit(xf86Screens[scrnIndex], mode)))
+ return FALSE;
+
+ /* Since RandR (indirectly) uses SwitchMode(), we need to
+ * update our Xinerama info here, too, in case of resizing
+ */
+ return TRUE;
+}
+
+/* static void
+XGISetStartAddressCRT1(XGIPtr pXGI, unsigned long base)
+{
+ unsigned char cr11backup;
+
+ inXGIIDXREG(XGICR, 0x11, cr11backup);
+ andXGIIDXREG(XGICR, 0x11, 0x7F);
+ outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
+ outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
+ outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
+
+
+ setXGIIDXREG(XGICR, 0x11, 0x7F,(cr11backup & 0x80));
+} */
+
+#ifdef XGIMERGED
+/* static Bool
+InRegion(int x, int y, region r)
+{
+ return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
+} */
+
+/* static void
+XGIAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned long base;
+
+ base = y * pXGI->CurrentLayout.displayWidth + x;
+ switch(pXGI->CurrentLayout.bitsPerPixel)
+ {
+ case 16: base >>= 1; break;
+ case 32: break;
+ default: base >>= 2;
+ }
+ XGISetStartAddressCRT1(pXGI, base);
+} */
+
+/* static void
+XGIMergePointerMoved(int scrnIndex, int x, int y)
+{
+ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+ XGIPtr pXGI = XGIPTR(pScrn1);
+ ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
+ region out, in1, in2, f2, f1;
+ int deltax, deltay;
+
+ f1.x0 = pXGI->CRT1frameX0;
+ f1.x1 = pXGI->CRT1frameX1;
+ f1.y0 = pXGI->CRT1frameY0;
+ f1.y1 = pXGI->CRT1frameY1;
+ f2.x0 = pScrn2->frameX0;
+ f2.x1 = pScrn2->frameX1;
+ f2.y0 = pScrn2->frameY0;
+ f2.y1 = pScrn2->frameY1;
+
+ out.x0 = pScrn1->frameX0;
+ out.x1 = pScrn1->frameX1;
+ out.y0 = pScrn1->frameY0;
+ out.y1 = pScrn1->frameY1;
+
+ in1 = out;
+ in2 = out;
+ switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
+ {
+ case xgiLeftOf:
+ in1.x0 = f1.x0;
+ in2.x1 = f2.x1;
+ break;
+ case xgiRightOf:
+ in1.x1 = f1.x1;
+ in2.x0 = f2.x0;
+ break;
+ case xgiBelow:
+ in1.y1 = f1.y1;
+ in2.y0 = f2.y0;
+ break;
+ case xgiAbove:
+ in1.y0 = f1.y0;
+ in2.y1 = f2.y1;
+ break;
+ case xgiClone:
+ break;
+ }
+
+ deltay = 0;
+ deltax = 0;
+
+ if(InRegion(x, y, out))
+ {
+
+ if(InRegion(x, y, in1) && !InRegion(x, y, f1))
+ {
+ REBOUND(f1.x0, f1.x1, x);
+ REBOUND(f1.y0, f1.y1, y);
+ deltax = 1;
+ }
+ if(InRegion(x, y, in2) && !InRegion(x, y, f2))
+ {
+ REBOUND(f2.x0, f2.x1, x);
+ REBOUND(f2.y0, f2.y1, y);
+ deltax = 1;
+ }
+
+ }
+ else
+ {
+
+ if(out.x0 > x)
+ {
+ deltax = x - out.x0;
+ }
+ if(out.x1 < x)
+ {
+ deltax = x - out.x1;
+ }
+ if(deltax)
+ {
+ pScrn1->frameX0 += deltax;
+ pScrn1->frameX1 += deltax;
+ f1.x0 += deltax;
+ f1.x1 += deltax;
+ f2.x0 += deltax;
+ f2.x1 += deltax;
+ }
+
+ if(out.y0 > y)
+ {
+ deltay = y - out.y0;
+ }
+ if(out.y1 < y)
+ {
+ deltay = y - out.y1;
+ }
+ if(deltay)
+ {
+ pScrn1->frameY0 += deltay;
+ pScrn1->frameY1 += deltay;
+ f1.y0 += deltay;
+ f1.y1 += deltay;
+ f2.y0 += deltay;
+ f2.y1 += deltay;
+ }
+
+ switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
+ {
+ case xgiLeftOf:
+ if(x >= f1.x0)
+ { REBOUND(f1.y0, f1.y1, y); }
+ if(x <= f2.x1)
+ { REBOUND(f2.y0, f2.y1, y); }
+ break;
+ case xgiRightOf:
+ if(x <= f1.x1)
+ { REBOUND(f1.y0, f1.y1, y); }
+ if(x >= f2.x0)
+ { REBOUND(f2.y0, f2.y1, y); }
+ break;
+ case xgiBelow:
+ if(y <= f1.y1)
+ { REBOUND(f1.x0, f1.x1, x); }
+ if(y >= f2.y0)
+ { REBOUND(f2.x0, f2.x1, x); }
+ break;
+ case xgiAbove:
+ if(y >= f1.y0)
+ { REBOUND(f1.x0, f1.x1, x); }
+ if(y <= f2.y1)
+ { REBOUND(f2.x0, f2.x1, x); }
+ break;
+ case xgiClone:
+ break;
+ }
+
+ }
+
+ if(deltax || deltay)
+ {
+ pXGI->CRT1frameX0 = f1.x0;
+ pXGI->CRT1frameY0 = f1.y0;
+ pScrn2->frameX0 = f2.x0;
+ pScrn2->frameY0 = f2.y0;
+
+ pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
+ pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
+ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
+ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+ pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
+ pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
+
+ XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
+ }
+} */
+
+
+/* static void
+XGIAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+ XGIPtr pXGI = XGIPTR(pScrn1);
+ ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
+ int VTotal = pXGI->CurrentLayout.mode->VDisplay;
+ int HTotal = pXGI->CurrentLayout.mode->HDisplay;
+ int VMax = VTotal;
+ int HMax = HTotal;
+
+ BOUND(x, 0, pScrn1->virtualX - HTotal);
+ BOUND(y, 0, pScrn1->virtualY - VTotal);
+
+ switch(SDMPTR(pScrn1)->CRT2Position)
+ {
+ case xgiLeftOf:
+ pScrn2->frameX0 = x;
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ pXGI->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
+ BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ break;
+ case xgiRightOf:
+ pXGI->CRT1frameX0 = x;
+ BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ break;
+ case xgiAbove:
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ pScrn2->frameY0 = y;
+ BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ pXGI->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
+ break;
+ case xgiBelow:
+ BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ pXGI->CRT1frameY0 = y;
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
+ break;
+ case xgiClone:
+ BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+ BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+ break;
+ }
+
+ BOUND(pXGI->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
+ BOUND(pXGI->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
+ BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
+ BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
+
+ pScrn1->frameX0 = x;
+ pScrn1->frameY0 = y;
+
+ pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
+ pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
+ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
+ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+ pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
+ pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
+
+ XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
+} */
+#endif
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ *
+ * Usually mandatory
+ */
+void
+XGIAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned long base;
+ unsigned char ucSR5Stat, ucTemp;
+
+ ErrorF("AdjustFrame %d\n", scrnIndex);
+ inXGIIDXREG(XGISR, 0x05, ucSR5Stat);
+ if (ucSR5Stat == 0xA1)
+ ucSR5Stat = 0x86;
+ outXGIIDXREG(XGISR, 0x05, 0x86);
+
+ base = (pScrn->bitsPerPixel + 7) / 8;
+ base *= x;
+ base += pXGI->scrnOffset * y;
+ base >>= 2;
+
+ switch (pXGI->Chipset) {
+ case PCI_CHIP_XGIXG40:
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21:
+ case PCI_CHIP_XGIXG27:
+ default:
+
+ ucTemp = base & 0xFF;
+ outXGIIDXREG(XGICR, 0x0D, ucTemp);
+ ucTemp = (base >> 8) & 0xFF;
+ outXGIIDXREG(XGICR, 0x0C, ucTemp);
+ ucTemp = (base >> 16) & 0xFF;
+ outXGIIDXREG(XGISR, 0x0D, ucTemp);
+ ucTemp = (base >> 24) & 0x01;
+ setXGIIDXREG(XGISR, 0x37, 0xFE, ucTemp);
+
+/* if (pXGI->VBFlags) {
+ XGI_UnLockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
+ ucTemp = base & 0xFF ; outXGIIDXREG( XGIPART1, 6 , ucTemp ) ;
+ ucTemp = (base>>8) & 0xFF ; outXGIIDXREG( XGIPART1, 5 , ucTemp ) ;
+ ucTemp = (base>>16) & 0xFF ; outXGIIDXREG( XGIPART1, 4 , ucTemp ) ;
+ ucTemp = (base>>24) & 0x01 ; ucTemp <<= 7 ;
+ setXGIIDXREG( XGIPART1, 0x2, 0x7F, ucTemp ) ;
+
+ XGI_LockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
+ }
+ */
+ break;
+
+ }
+
+ outXGIIDXREG(XGISR, 0x05, ucSR5Stat);
+
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ * Mandatory!
+ */
+static Bool
+XGIEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+
+ if (!XGIModeInit(pScrn, pScrn->currentMode)) {
+ XGIErrorLog(pScrn, "XGIEnterVT: XGIModeInit() failed\n");
+ return FALSE;
+ }
+
+ XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+#ifdef XF86DRI
+ if (pXGI->directRenderingEnabled) {
+ DRIUnlock(screenInfo.screens[scrnIndex]);
+ }
+#endif
+
+ if ((!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) && (pXGI->ResetXv)) {
+ (pXGI->ResetXv) (pScrn);
+ }
+
+ return TRUE;
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ * Mandatory!
+ */
+static void
+XGILeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ XGIPtr pXGI = XGIPTR(pScrn);
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+
+ PDEBUG(ErrorF("XGILeaveVT()\n"));
+ if (pXGI->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRILock(pScreen, 0);
+ }
+#endif
+
+ if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
+ return;
+
+ if (pXGI->CursorInfoPtr) {
+ /* Because of the test and return above, we know that this is not
+ * the second head.
+ */
+ pXGI->CursorInfoPtr->HideCursor(pScrn);
+ XGI_WaitBeginRetrace(pXGI->RelIO);
+ }
+
+ XGIRestore(pScrn);
+
+
+ /* We use (otherwise unused) bit 7 to indicate that we are running to keep
+ * xgifb to change the displaymode (this would result in lethal display
+ * corruption upon quitting X or changing to a VT until a reboot).
+ */
+ vgaHWLock(hwp);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ * Mandatory!
+ */
+static Bool
+XGICloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+
+#ifdef XF86DRI
+ if (pXGI->directRenderingEnabled) {
+ XGIDRICloseScreen(pScreen);
+ pXGI->directRenderingEnabled = FALSE;
+ }
+#endif
+
+ if (pScrn->vtSema) {
+ if (pXGI->CursorInfoPtr
+ && (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI))) {
+ pXGI->CursorInfoPtr->HideCursor(pScrn);
+ XGI_WaitBeginRetrace(pXGI->RelIO);
+ }
+
+
+ XGIRestore(pScrn);
+ vgaHWLock(hwp);
+ }
+
+ /* We should restore the mode number in case vtsema = false as well,
+ * but since we haven't register access then we can't do it. I think
+ * I need to rework the save/restore stuff, like saving the video
+ * status when returning to the X server and by that save me the
+ * trouble if xgifb was started from a textmode VT while X was on.
+ */
+
+ XGIUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+
+ if (IS_DUAL_HEAD(pXGI)) {
+ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+ pXGIEnt->refCount--;
+ }
+
+ if (pXGI->pInt) {
+ xf86FreeInt10(pXGI->pInt);
+ pXGI->pInt = NULL;
+ }
+
+ if (pXGI->AccelLinearScratch) {
+ xf86FreeOffscreenLinear(pXGI->AccelLinearScratch);
+ pXGI->AccelLinearScratch = NULL;
+ }
+
+ if (pXGI->AccelInfoPtr) {
+ XAADestroyInfoRec(pXGI->AccelInfoPtr);
+ pXGI->AccelInfoPtr = NULL;
+ }
+
+ if (pXGI->CursorInfoPtr) {
+ xf86DestroyCursorInfoRec(pXGI->CursorInfoPtr);
+ pXGI->CursorInfoPtr = NULL;
+ }
+
+ if (pXGI->ShadowPtr) {
+ xfree(pXGI->ShadowPtr);
+ pXGI->ShadowPtr = NULL;
+ }
+
+ if (pXGI->DGAModes) {
+ xfree(pXGI->DGAModes);
+ pXGI->DGAModes = NULL;
+ }
+
+ if (pXGI->adaptor) {
+ xfree(pXGI->adaptor);
+ pXGI->adaptor = NULL;
+ pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
+ }
+
+ pScrn->vtSema = FALSE;
+
+ /* Restore Blockhandler */
+ pScreen->BlockHandler = pXGI->BlockHandler;
+
+ pScreen->CloseScreen = pXGI->CloseScreen;
+
+ return (*pScreen->CloseScreen) (scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+XGIFreeScreen(int scrnIndex, int flags)
+{
+ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) {
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ }
+
+ XGIFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+static int
+XGIValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ XGIPtr pXGI = XGIPTR(pScrn);
+ int HDisplay = mode->HDisplay;
+ int VDisplay = mode->VDisplay;
+ int Clock = mode->Clock;
+ int i = 0;
+ int VRefresh;
+
+ VRefresh =
+ (int) ((float) (Clock * 1000) /
+ (float) (mode->VTotal * mode->HTotal) + 0.5);
+
+ /* Jong 08/21/2007; support modeline */
+ /* We skip mode checking here and need improvement further */
+ if(mode->type == M_T_USERDEF)
+ return(MODE_OK);
+
+ PDEBUG5(ErrorF("XGIValidMode()."));
+ PDEBUG5(ErrorF
+ ("CLK=%5.3fMhz %dx%d@%d ", (float) Clock / 1000, HDisplay,
+ VDisplay, VRefresh));
+ PDEBUG5(ErrorF("(VT,HT)=(%d,%d)\n", mode->VTotal, mode->HTotal));
+
+ if (pXGI->VBFlags & CRT2_LCD) {
+ if ((HDisplay > 1600 && VDisplay > 1200)
+ || (HDisplay < 640 && VDisplay < 480)) {
+ PDEBUG5(ErrorF("skip by LCD limit\n"));
+ return (MODE_NOMODE);
+ }
+ /* if( VRefresh != 60) return(MODE_NOMODE) ; */
+ }
+ else if (pXGI->VBFlags & CRT2_TV) {
+ if ((HDisplay > 1024 && VDisplay > 768) ||
+ (HDisplay < 640 && VDisplay < 480) || (VRefresh != 60)) {
+ PDEBUG5(ErrorF("skip by TV limit\n"));
+ return (MODE_NOMODE);
+ }
+ }
+ else if (pXGI->VBFlags & CRT2_VGA) {
+ if ((HDisplay > 1600 && VDisplay > 1200) ||
+ (HDisplay < 640 && VDisplay < 480)) {
+ PDEBUG5(ErrorF("skip by CRT2 limit\n"));
+ return (MODE_NOMODE);
+ }
+ }
+
+ if ((pXGI->Chipset == PCI_CHIP_XGIXG20) ||(pXGI->Chipset == PCI_CHIP_XGIXG21) ||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) {
+ XgiMode = XG20_Mode;
+ }
+ else {
+ XgiMode = XGI_Mode;
+ }
+
+ while ((XgiMode[i].Clock != Clock) ||
+ (XgiMode[i].HDisplay != HDisplay) ||
+ (XgiMode[i].VDisplay != VDisplay)) {
+ if (XgiMode[i].Clock == 0) {
+ PDEBUG5(ErrorF
+ ("--- NO_Mode support for %dx%d@%dHz\n", HDisplay,
+ VDisplay, VRefresh));
+ return (MODE_NOMODE);
+ }
+ else
+ i++;
+ }
+ PDEBUG5(ErrorF("Mode OK\n"));
+
+ /* Jong 12/05/2007; filter mode of CRT1 with CRT2 DDC for XG21 */
+ if(g_pMonitorDVI)
+ {
+ if(XGICheckModeByDDC(mode, g_pMonitorDVI) == FALSE)
+ return (MODE_NOMODE);
+ }
+
+ return (MODE_OK);
+}
+
+/* Do screen blanking
+ *
+ * Mandatory
+ */
+static Bool
+XGISaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if ((pScrn != NULL) && pScrn->vtSema) {
+
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+#endif
+ }
+
+ return vgaHWSaveScreen(pScreen, mode);
+}
+
+/* SaveScreen for dual head mode */
+static Bool
+XGISaveScreenDH(ScreenPtr pScreen, int mode)
+{
+#ifdef XGIDUALHEAD
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if ((pScrn != NULL) && pScrn->vtSema) {
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ if (IS_SECOND_HEAD(pXGI)
+ && ((!(pXGI->VBFlags & CRT1_LCDA))
+ || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
+
+ /* Slave head is always CRT1 */
+ if (pXGI->VBFlags & CRT1_LCDA)
+ pXGI->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
+
+ return vgaHWSaveScreen(pScreen, mode);
+ }
+ else {
+ /* Master head is always CRT2 */
+ /* But we land here if CRT1 is LCDA, too */
+
+ /* We can only blank LCD, not other CRT2 devices */
+ if (!(pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)))
+ return TRUE;
+
+ /* enable access to extended sequencer registers */
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+#endif
+ }
+ }
+#endif
+ return TRUE;
+}
+
+#ifdef DEBUG
+static void
+XGIDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock : %x\n", mode->Clock);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Display : %x\n",
+ mode->CrtcHDisplay);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank Start : %x\n",
+ mode->CrtcHBlankStart);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync Start : %x\n",
+ mode->CrtcHSyncStart);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync End : %x\n",
+ mode->CrtcHSyncEnd);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank End : %x\n",
+ mode->CrtcHBlankEnd);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz HAdjusted : %x\n",
+ mode->CrtcHAdjusted);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Display : %x\n",
+ mode->CrtcVDisplay);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank Start : %x\n",
+ mode->CrtcVBlankStart);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync Start : %x\n",
+ mode->CrtcVSyncStart);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync End : %x\n",
+ mode->CrtcVSyncEnd);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank End : %x\n",
+ mode->CrtcVBlankEnd);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt VAdjusted : %x\n",
+ mode->CrtcVAdjusted);
+}
+#endif
+
+static void
+XGIModifyModeInfo(DisplayModePtr mode)
+{
+ if (mode->CrtcHBlankStart == mode->CrtcHDisplay)
+ mode->CrtcHBlankStart++;
+ if (mode->CrtcHBlankEnd == mode->CrtcHTotal)
+ mode->CrtcHBlankEnd--;
+ if (mode->CrtcVBlankStart == mode->CrtcVDisplay)
+ mode->CrtcVBlankStart++;
+ if (mode->CrtcVBlankEnd == mode->CrtcVTotal)
+ mode->CrtcVBlankEnd--;
+}
+
+/* Things to do before a ModeSwitch. We set up the
+ * video bridge configuration and the TurboQueue.
+ */
+void
+XGIPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned char CR30, CR31, CR33;
+ unsigned char CR3B = 0;
+ unsigned char CR17, CR38 = 0;
+ unsigned char CR35 = 0, CR79 = 0;
+ unsigned long vbflag;
+ int temp = 0;
+ int crt1rateindex = 0;
+ DisplayModePtr mymode;
+#ifdef XGIMERGED
+ DisplayModePtr mymode2 = NULL;
+#endif
+
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ mymode = ((XGIMergedDisplayModePtr) mode->Private)->CRT1;
+ mymode2 = ((XGIMergedDisplayModePtr) mode->Private)->CRT2;
+ }
+ else
+#endif
+ mymode = mode;
+
+ vbflag = pXGI->VBFlags;
+ PDEBUG(ErrorF("VBFlags=0x%lx\n", pXGI->VBFlags));
+
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); /* Unlock Registers */
+#endif
+
+ inXGIIDXREG(XGICR, 0x30, CR30);
+ inXGIIDXREG(XGICR, 0x31, CR31);
+ inXGIIDXREG(XGICR, 0x33, CR33);
+
+ inXGIIDXREG(XGICR, 0x3b, CR3B);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
+ "Before: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
+ CR30, CR31, CR33, temp, CR38);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n",
+ pXGI->VBFlags);
+
+ CR30 = 0x00;
+ CR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */
+ CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */
+ CR35 = 0x00;
+
+
+ if (!pXGI->AllowHotkey) {
+ CR31 |= 0x80; /* Disable hotkey-switch */
+ }
+ CR79 &= ~0x10; /* Enable Backlight control on 315 series */
+
+
+ if ((vbflag & CRT1_LCDA) && (viewmode == XGI_MODE_CRT1)) {
+
+ CR38 |= 0x02;
+
+ }
+ else {
+
+ switch (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
+
+ case CRT2_TV:
+
+ CR38 &= ~0xC0; /* Clear Pal M/N bits */
+
+ if (vbflag & TV_YPBPR) { /* Video bridge */
+ if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR) {
+ CR30 |= 0x80;
+ CR38 |= 0x08;
+ if (vbflag & TV_YPBPR525P)
+ CR38 |= 0x10;
+ else if (vbflag & TV_YPBPR750P)
+ CR38 |= 0x20;
+ else if (vbflag & TV_YPBPR1080I)
+ CR38 |= 0x30;
+ CR31 &= ~0x01;
+ if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPRAR) {
+ CR3B &= ~0x03;
+ if ((vbflag & TV_YPBPRAR) == TV_YPBPR43LB)
+ CR3B |= 0x00;
+ else if ((vbflag & TV_YPBPRAR) == TV_YPBPR43)
+ CR3B |= 0x03;
+ else if ((vbflag & TV_YPBPRAR) == TV_YPBPR169)
+ CR3B |= 0x01;
+ else
+ CR3B |= 0x03;
+ }
+ }
+ }
+ else { /* All */
+ if (vbflag & TV_SCART)
+ CR30 |= 0x10;
+ if (vbflag & TV_SVIDEO)
+ CR30 |= 0x08;
+ if (vbflag & TV_AVIDEO)
+ CR30 |= 0x04;
+ if (!(CR30 & 0x1C))
+ CR30 |= 0x08; /* default: SVIDEO */
+
+ if (vbflag & TV_PAL) {
+ CR31 |= 0x01;
+ CR35 |= 0x01;
+ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+ if (vbflag & TV_PALM) {
+ CR38 |= 0x40;
+ CR35 |= 0x04;
+ }
+ else if (vbflag & TV_PALN) {
+ CR38 |= 0x80;
+ CR35 |= 0x08;
+ }
+ }
+ }
+ else {
+ CR31 &= ~0x01;
+ CR35 &= ~0x01;
+ if (vbflag & TV_NTSCJ) {
+ CR38 |= 0x40; /* TW, not BIOS */
+ CR35 |= 0x02;
+ }
+ }
+ if (vbflag & TV_SCART) {
+ CR31 |= 0x01;
+ CR35 |= 0x01;
+ }
+ }
+
+ CR31 &= ~0x04; /* Clear NotSimuMode */
+#ifdef XGI_CP
+ XGI_CP_DRIVER_CONFIG
+#endif
+ break;
+
+ case CRT2_LCD:
+ CR30 |= 0x20;
+ break;
+
+ case CRT2_VGA:
+ CR30 |= 0x40;
+ break;
+
+ default:
+ CR30 |= 0x00;
+ CR31 |= 0x20; /* VB_OUTPUT_DISABLE */
+ }
+
+ }
+
+ if (vbflag & CRT1_LCDA) {
+ switch (viewmode) {
+ case XGI_MODE_CRT1:
+ CR38 |= 0x01;
+ break;
+ case XGI_MODE_CRT2:
+ if (vbflag & (CRT2_TV | CRT2_VGA)) {
+ CR30 |= 0x02;
+ CR38 |= 0x01;
+ }
+ else {
+ CR38 |= 0x03;
+ }
+ break;
+ case XGI_MODE_SIMU:
+ default:
+ if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
+ CR30 |= 0x01;
+ }
+ break;
+ }
+ }
+ else {
+ if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
+ CR30 |= 0x01;
+ }
+ }
+
+ CR31 |= 0x40; /* Set Drivermode */
+ CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */
+ crt1rateindex = XGISearchCRT1Rate(pScrn, mymode);
+
+ if (IS_DUAL_HEAD(pXGI)) {
+ if (IS_SECOND_HEAD(pXGI)) {
+ /* CRT1 */
+ CR33 &= 0xf0;
+ if (!(vbflag & CRT1_LCDA)) {
+ CR33 |= (crt1rateindex & 0x0f);
+ }
+ }
+ else {
+ /* CRT2 */
+ CR33 &= 0x0f;
+ if (vbflag & CRT2_VGA) {
+ CR33 |= ((crt1rateindex << 4) & 0xf0);
+ }
+ }
+ }
+ else
+#ifdef XGIMERGED
+ if (pXGI->MergedFB) {
+ CR33 = 0;
+ if (!(vbflag & CRT1_LCDA)) {
+ CR33 |= (crt1rateindex & 0x0f);
+ }
+ if (vbflag & CRT2_VGA) {
+ CR33 |= (XGISearchCRT1Rate(pScrn, mymode2) << 4);
+ }
+ }
+ else
+#endif
+ {
+ CR33 = 0;
+ if (!(vbflag & CRT1_LCDA)) {
+ CR33 |= (crt1rateindex & 0x0f);
+ }
+ if (vbflag & CRT2_VGA) {
+ CR33 |= ((crt1rateindex & 0x0f) << 4);
+ }
+ if (vbflag & CRT2_ENABLE) {
+ if (pXGI->CRT1off)
+ CR33 &= 0xf0;
+ }
+ }
+ outXGIIDXREG(XGICR, 0x30, CR30);
+ outXGIIDXREG(XGICR, 0x31, CR31);
+ outXGIIDXREG(XGICR, 0x33, CR33);
+ if (temp) {
+ outXGIIDXREG(XGICR, temp, CR38);
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n",
+ CR30, CR31, CR33, temp, CR38);
+
+ if (pXGI->VBFlags & CRT2_ENABLE) {
+ /* Switch on CRT1 for modes that require the bridge in SlaveMode */
+ andXGIIDXREG(XGISR, 0x1f, 0x3f);
+ inXGIIDXREG(XGICR, 0x17, CR17);
+ if (!(CR17 & 0x80)) {
+ orXGIIDXREG(XGICR, 0x17, 0x80);
+ outXGIIDXREG(XGISR, 0x00, 0x01);
+ usleep(10000);
+ outXGIIDXREG(XGISR, 0x00, 0x03);
+ }
+ }
+}
+
+/* PostSetMode:
+ * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
+ * VESA uses the bridge in SlaveMode and switching CRT1 off while
+ * the bridge is in SlaveMode not that clever...
+ * -) Check if overlay can be used (depending on dotclock)
+ * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
+ * -) Save TV registers for further processing
+ * -) Apply TV settings
+ */
+static void
+XGIPostSetMode(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+/* unsigned char usScratchCR17;
+ Bool flag = FALSE;
+ Bool doit = TRUE; */
+ int myclock;
+ unsigned char sr2b, sr2c, tmpreg;
+ float num, denum, postscalar, divider;
+ PDEBUG(ErrorF(" XGIPostSetMode(). \n"));
+#ifdef TWDEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pXGI->CRT1off);
+#endif
+
+#ifdef UNLOCK_ALWAYS
+ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+#endif
+
+ /* Determine if the video overlay can be used */
+ if (!pXGI->NoXvideo) {
+ inXGIIDXREG(XGISR, 0x2b, sr2b);
+ inXGIIDXREG(XGISR, 0x2c, sr2c);
+ divider = (sr2b & 0x80) ? 2.0 : 1.0;
+ postscalar = (sr2c & 0x80) ?
+ ((((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) :
+ (((sr2c >> 5) & 0x03) + 1.0);
+ num = (sr2b & 0x7f) + 1.0;
+ denum = (sr2c & 0x1f) + 1.0;
+ myclock =
+ (int) ((14318 * (divider / postscalar) * (num / denum)) / 1000);
+
+ pXGI->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA);
+/* switch(pXGI->xgi_HwDevExt.jChipType) {
+ break;
+ }
+ */
+ if (!(pXGI->MiscFlags & MISC_CRT1OVERLAY)) {
+ if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI))
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
+ "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
+ myclock);
+ }
+ }
+
+ /* Determine if the Panel Link scaler is active */
+ pXGI->MiscFlags &= ~MISC_PANELLINKSCALER;
+ if (pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
+ if (pXGI->VBFlags & CRT1_LCDA) {
+ inXGIIDXREG(XGIPART1, 0x35, tmpreg);
+ tmpreg &= 0x04;
+ if (!tmpreg)
+ pXGI->MiscFlags |= MISC_PANELLINKSCALER;
+ }
+ }
+
+ /* Determine if our very special TV mode is active */
+ pXGI->MiscFlags &= ~MISC_TVNTSC1024;
+ if ((pXGI->XGI_Pr->VBType & VB_XGIVB) && (pXGI->VBFlags & CRT2_TV)
+ && (!(pXGI->VBFlags & TV_HIVISION))) {
+ if (((pXGI->VBFlags & TV_YPBPR) && (pXGI->VBFlags & TV_YPBPR525I))
+ || ((!(pXGI->VBFlags & TV_YPBPR))
+ && (pXGI->VBFlags & (TV_NTSC | TV_PALM)))) {
+ inXGIIDXREG(XGICR, 0x34, tmpreg);
+ tmpreg &= 0x7f;
+ if ((tmpreg == 0x64) || (tmpreg == 0x4a) || (tmpreg == 0x38)) {
+ pXGI->MiscFlags |= MISC_TVNTSC1024;
+ }
+ }
+ }
+
+ /* Reset XV gamma correction */
+ if (pXGI->ResetXvGamma) {
+ (pXGI->ResetXvGamma) (pScrn);
+ }
+
+ /* Apply TV settings given by options
+ * Do this even in DualHeadMode:
+ * - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
+ * - if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
+ * -> Hence, in both cases, the settings must be re-applied.
+ */
+}
+
+
+USHORT
+XGI_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ unsigned long VBFlags)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ UShort i = (pXGI->CurrentLayout.bitsPerPixel + 7) / 8 - 1;
+
+ if ((VBFlags & CRT1_LCDA)) {
+ if ((mode->HDisplay > pXGI->LCDwidth) ||
+ (mode->VDisplay > pXGI->LCDheight)) {
+ return 0;
+ }
+ }
+
+ return XGI_GetModeID(VBFlags, mode->HDisplay, mode->VDisplay,
+ i, pXGI->LCDwidth, pXGI->LCDheight);
+}
+
+/* Calculate the vertical refresh rate from a mode */
+int
+XGICalcVRate(DisplayModePtr mode)
+{
+ float hsync, refresh = 0;
+
+ if (mode->HSync > 0.0)
+ hsync = mode->HSync;
+ else if (mode->HTotal > 0)
+ hsync = (float) mode->Clock / (float) mode->HTotal;
+ else
+ hsync = 0.0;
+
+ if (mode->VTotal > 0)
+ refresh = hsync * 1000.0 / mode->VTotal;
+
+ if (mode->Flags & V_INTERLACE)
+ refresh *= 2.0;
+
+ if (mode->Flags & V_DBLSCAN)
+ refresh /= 2.0;
+
+ if (mode->VScan > 1)
+ refresh /= mode->VScan;
+
+ if (mode->VRefresh > 0.0)
+ refresh = mode->VRefresh;
+
+ if (hsync == 0 || refresh == 0)
+ return (0);
+
+ return ((int) (refresh));
+}
+
+/* Calculate CR33 (rate index) for CRT1.
+ * Calculation is done using currentmode, therefore it is
+ * recommended to set VertRefresh and HorizSync to correct
+ * values in config file.
+ */
+unsigned char
+XGISearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ int i = 0;
+ int irefresh;
+ unsigned short xres = mode->HDisplay;
+ unsigned short yres = mode->VDisplay;
+ unsigned char index;
+ BOOLEAN checkxgi730 = FALSE;
+
+ irefresh = XGICalcVRate(mode);
+ if (!irefresh) {
+ if (xres == 800 || xres == 1024 || xres == 1280)
+ return 0x02;
+ else
+ return 0x01;
+ }
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
+#endif
+
+ /* We need the REAL refresh rate here */
+ if (mode->Flags & V_INTERLACE)
+ irefresh /= 2;
+
+ /* Do not multiply by 2 when DBLSCAN! */
+
+#ifdef TWDEBUG
+ xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
+#endif
+
+ index = 0;
+ while ((xgix_vrate[i].idx != 0) && (xgix_vrate[i].xres <= xres)) {
+ if ((xgix_vrate[i].xres == xres) && (xgix_vrate[i].yres == yres)) {
+ if ((checkxgi730 == FALSE)
+ || (xgix_vrate[i].XGI730valid32bpp == TRUE)) {
+ if (xgix_vrate[i].refresh == irefresh) {
+ index = xgix_vrate[i].idx;
+ break;
+ }
+ else if (xgix_vrate[i].refresh > irefresh) {
+ if ((xgix_vrate[i].refresh - irefresh) <= 3) {
+ index = xgix_vrate[i].idx;
+ }
+ else if (((checkxgi730 == FALSE)
+ || (xgix_vrate[i - 1].XGI730valid32bpp == TRUE))
+ && ((irefresh - xgix_vrate[i - 1].refresh) <= 2)
+ && (xgix_vrate[i].idx != 1)) {
+ index = xgix_vrate[i - 1].idx;
+ }
+ break;
+ }
+ else if ((irefresh - xgix_vrate[i].refresh) <= 2) {
+ index = xgix_vrate[i].idx;
+ break;
+ }
+ }
+ }
+ i++;
+ }
+
+ /* Jong 10/19/2007; merge code */
+ /* Adjust to match table of VBIOS */
+ switch(pXGI->Chipset)
+ {
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21:
+ if((xres == 640) && (yres == 480))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 4;
+ }
+ }
+
+ if((xres == 800) && (yres == 600))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 5;
+ }
+
+ if (index>0)
+ {
+ index --;
+ }
+ }
+
+ if((xres == 1024) && (yres == 768))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 5;
+ }
+
+ if (index>0)
+ {
+ index --;
+ }
+ }
+
+ if((xres == 1280) && (yres == 1024))
+ {
+ if (index>0)
+ {
+ index --;
+ }
+ }
+
+ if((xres == 1600) && (yres == 1200))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 5;
+ }
+ }
+
+ if((xres >= 1920) && (yres >= 1440))
+ {
+ index = 0;
+ }
+
+ break;
+
+ case PCI_CHIP_XGIXG27:
+
+ if((xres == 640) && (yres == 480))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 4;
+ }
+ }
+
+ if((xres == 800) && (yres == 600))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 5;
+ }
+
+ if (index>0)
+ {
+ index --;
+ }
+ }
+
+ if((xres == 1024) && (yres == 768))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 5;
+ }
+
+ if (index>0)
+ {
+ index --;
+ }
+ }
+
+ if((xres == 1280) && (yres == 1024))
+ {
+ if (index>0)
+ {
+ index --;
+ }
+ }
+
+ if((xres == 1600) && (yres == 1200))
+ {
+ if (xgix_vrate[index].refresh>85)
+ {
+ index = 5;
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ if (index > 0)
+ return index;
+ else {
+ /* Default Rate index */
+ if (xres == 800 || xres == 1024 || xres == 1280)
+ return 0x02;
+ else
+ return 0x01;
+ }
+}
+
+
+#define MODEID_OFF 0x449
+
+unsigned char
+XGI_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
+{
+ return (XGI_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
+}
+
+unsigned char
+XGI_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
+{
+ unsigned char ret = 0;
+#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+ unsigned char *base;
+
+ base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
+ if (!base) {
+ XGIErrorLog(pScrn, "(Could not map BIOS scratch area)\n");
+ return 0;
+ }
+
+ ret = *(base + offset);
+
+ /* value != 0xff means: set register */
+ if (value != 0xff)
+ *(base + offset) = value;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
+#endif
+ return ret;
+}
+
+void
+xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
+ unsigned char *reg2)
+{
+ register unsigned char val;
+ unsigned long mylockcalls;
+
+ pXGI->lockcalls++;
+ mylockcalls = pXGI->lockcalls;
+
+ /* check if already unlocked */
+ inXGIIDXREG(XGISR, 0x05, val);
+ if (val != 0xa1) {
+ /* save State */
+ if (reg1)
+ *reg1 = val;
+ /* unlock */
+/*
+ outb (0x3c4, 0x20);
+ val4 = inb (0x3c5);
+ val4 |= 0x20;
+ outb (0x3c5, val4);
+*/
+ outXGIIDXREG(XGISR, 0x05, 0x86);
+ inXGIIDXREG(XGISR, 0x05, val);
+ if (val != 0xA1) {
+#ifdef TWDEBUG
+ unsigned char val1, val2;
+ int i;
+#endif
+ XGIErrorLog(pXGI->pScrn,
+ "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
+ (void *) pXGI, (unsigned long) pXGI->RelIO, val,
+ mylockcalls);
+#ifdef TWDEBUG
+ for (i = 0; i <= 0x3f; i++) {
+ inXGIIDXREG(XGISR, i, val1);
+ inXGIIDXREG(0x3c4, i, val2);
+ xf86DrvMsg(pXGI->pScrn->scrnIndex, X_INFO,
+ "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n",
+ i, val1, val2, mylockcalls);
+ }
+#endif
+ }
+ }
+}
+
+void
+xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, unsigned char reg2)
+{
+ /* restore lock */
+#ifndef UNLOCK_ALWAYS
+ outXGIIDXREG(XGISR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
+#endif
+}
+
+/* Jong 12/03/2007; */
+/*
+void XGICheckModeForMonitor(ScrnInfoPtr pScrn, )
+{
+ DisplayModePtr pCRT1Modes=pScrn->monitor->Modes;
+
+ if ((p = first = pScrn->monitor->Modes)) {
+ do {
+ xf86CheckModeForMonitor(p,
+ n = p->next;
+ p = n;
+ } while (p != NULL && p != first);
+ }
+
+ xf86PruneDriverModes(pXGI->CRT2pScrn);
+}
+*/
+
+/* Jong 12/05/2007; filter mode list by monitor DDC */
+static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC)
+{
+ DisplayModePtr first, p;
+
+ if ((p = first = pModeList))
+ {
+ do
+ {
+ if(XGICheckModeByDDC(p, pMonitorDDC) == FALSE)
+ xf86DeleteMode(&pModeList, pModeList);
+
+ p = p->next;
+ } while (p != NULL && p != first);
+ }
+}
+
+/* Jong 12/05/2007; filter mode list by monitor DDC */
+static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC)
+{
+ int i, j;
+ float VF, HF;
+ struct detailed_timings *pd_timings;
+ struct monitor_ranges *pranges;
+ struct std_timings *pstd_t;
+
+ int VRefresh=pMode->VRefresh;
+
+ if ((pMode == NULL) || (pMonitorDDC == NULL)) {
+ return(FALSE); /* ignore */
+ }
+
+ if( pMode->VRefresh == 0)
+ VRefresh = (int)((float)(pMode->Clock*1000)/(float)(pMode->VTotal*pMode->HTotal)+0.5);
+
+
+ for (i = 0, j = 0; i < 8; i++, j++)
+ {
+ if (establish_timing[j].width == -1)
+ {
+ continue;
+ }
+
+ if (pMonitorDDC->timings1.t1 & (1 << i))
+ {
+ if( (establish_timing[j].width == pMode->HDisplay) &&
+ (establish_timing[j].height == pMode->VDisplay) &&
+ (establish_timing[j].VRefresh == VRefresh) )
+ return(TRUE);
+ }
+ }
+
+ for (i = 0; i < 8; i++, j++)
+ {
+ if (establish_timing[j].width == -1)
+ {
+ continue;
+ }
+
+ if (pMonitorDDC->timings1.t2 & (1 << i))
+ {
+ if( (establish_timing[j].width == pMode->HDisplay) &&
+ (establish_timing[j].height == pMode->VDisplay) &&
+ (establish_timing[j].VRefresh == VRefresh) )
+ return(TRUE);
+ }
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ if ((pMode->HDisplay == pMonitorDDC->timings2[i].hsize) &&
+ (pMode->VDisplay == pMonitorDDC->timings2[i].vsize) &&
+ (VRefresh == pMonitorDDC->timings2[i].refresh))
+ return(TRUE);
+ }
+
+/* Jong 12/05/2007; Don't know how to do? */
+#if 0
+ for (i = 0; i < 4; i++)
+ {
+ switch (pMonitorDDC->det_mon[i].type)
+ {
+ case DS_RANGES:
+ pranges = &(pMonitorDDC->det_mon[i].section.ranges);
+ PDEBUG5(ErrorF
+ ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
+ pranges->min_v, pranges->max_v, pranges->min_h,
+ pranges->max_h, pranges->max_clock));
+
+ if (range->loH > pranges->min_h)
+ range->loH = pranges->min_h;
+ if (range->loV > pranges->min_v)
+ range->loV = pranges->min_v;
+ if (range->hiH < pranges->max_h)
+ range->hiH = pranges->max_h;
+ if (range->hiV < pranges->max_v)
+ range->hiV = pranges->max_v;
+ PDEBUG5(ErrorF
+ ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
+ range->loV, range->hiH, range->hiV));
+ break;
+
+ case DS_STD_TIMINGS:
+ pstd_t = pMonitorDDC->det_mon[i].section.std_t;
+ for (j = 0; j < 5; j++) {
+ int k;
+ PDEBUG5(ErrorF
+ ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
+ j, pstd_t[j].hsize, pstd_t[j].vsize,
+ pstd_t[j].refresh, pstd_t[j].id));
+ for (k = 0; StdTiming[k].width != -1; k++) {
+ if ((StdTiming[k].width == pstd_t[j].hsize) &&
+ (StdTiming[k].height == pstd_t[j].vsize) &&
+ (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
+ if (range->loH > StdTiming[k].HSync)
+ range->loH = StdTiming[k].HSync;
+ if (range->hiH < StdTiming[k].HSync)
+ range->hiH = StdTiming[k].HSync;
+ if (range->loV > StdTiming[k].VRefresh)
+ range->loV = StdTiming[k].VRefresh;
+ if (range->hiV < StdTiming[k].VRefresh)
+ range->hiV = StdTiming[k].VRefresh;
+ break;
+ }
+
+ }
+ }
+ break;
+
+ case DT:
+
+ pd_timings = &pMonitorDDC->det_mon[i].section.d_timings;
+
+ HF = pd_timings->clock / (pd_timings->h_active +
+ pd_timings->h_blanking);
+ VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
+ HF /= 1000; /* into KHz Domain */
+ if (range->loH > HF)
+ range->loH = HF;
+ if (range->hiH < HF)
+ range->hiH = HF;
+ if (range->loV > VF)
+ range->loV = VF;
+ if (range->hiV < VF)
+ range->hiV = VF;
+ PDEBUG(ErrorF
+ ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
+ HF, VF, range->loH, range->loV, range->hiH, range->hiV));
+ break;
+ }
+ }
+#endif
+
+ return(FALSE);
+}
+
+#ifdef DEBUG
+void
+XGIDumpSR(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("SR xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x40; i += 0x10) {
+ ErrorF("SR[%02X]:", i);
+ for (j = 0; j < 16; j++) {
+ inXGIIDXREG(XGISR, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+ ErrorF("\n");
+}
+
+void
+XGIDumpCR(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("CR xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x100; i += 0x10) {
+ ErrorF("CR[%02X]:", i);
+ for (j = 0; j < 16; j++) {
+ inXGIIDXREG(XGICR, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+
+void
+XGIDumpGR(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("GR xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("GR:");
+ for (i = 0; i < 0x9; i += 0x10) {
+ inXGIIDXREG(XGISR, i, temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+}
+
+#if 0
+void
+XGIDumpPart0(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("PART0 xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x50; i += 0x10) {
+ ErrorF("PART0[%02X]:", i);
+ for (j = 0; j < 0x10; j++) {
+ inXGIIDXREG(XGIPART0, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+
+void
+XGIDumpPart05(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ int i, j;
+ unsigned long temp;
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("PART05 xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x50; i += 0x10) {
+ ErrorF("PART05[%02X]:", i);
+ for (j = 0; j < 0x10; j++) {
+ inXGIIDXREG(XGIPART05, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+
+void
+XGIDumpPart1(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("PART1 xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x100; i += 0x10) {
+ ErrorF("PART1[%02X]:", i);
+ for (j = 0; j < 0x10; j++) {
+ inXGIIDXREG(XGIPART1, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+
+void
+XGIDumpPart2(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("PART2 xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x100; i += 0x10) {
+ ErrorF("PART2[%02X]:", i);
+ for (j = 0; j < 0x10; j++) {
+ inXGIIDXREG(XGIPART2, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+
+void
+XGIDumpPart3(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("PART3 xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+
+ for (i = 0; i < 0x100; i += 0x10) {
+ ErrorF("PART3[%02X]:", i);
+ for (j = 0; j < 0x10; j++) {
+ inXGIIDXREG(XGIPART3, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+
+void
+XGIDumpPart4(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i, j;
+ unsigned long temp;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("PART4 xx\n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0x100; i += 0x10) {
+ ErrorF("PART4[%02X]:", i);
+ for (j = 0; j < 0x10; j++) {
+ inXGIIDXREG(XGIPART4, (i + j), temp);
+ ErrorF(" %02lX", temp);
+ }
+ ErrorF("\n");
+ }
+}
+#endif
+
+void
+XGIDumpMMIO(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ int i;
+ unsigned long temp;
+/*
+ ErrorF("----------------------------------------------------------------------\n") ;
+ ErrorF("MMIO 85xx\n") ;
+ ErrorF("----------------------------------------------------------------------\n") ;
+ for( i = 0x8500 ; i < 0x8600 ; i+=0x10 )
+ {
+ ErrorF("[%04X]: %08lX %08lX %08lX %08lX\n",i,
+ XGIMMIOLONG(i),
+ XGIMMIOLONG(i+4),
+ XGIMMIOLONG(i+8),
+ XGIMMIOLONG(i+12)) ;
+ }
+*/
+}
+#endif /* DEBUG */
+
+void
+XGIDumpRegs(ScrnInfoPtr pScrn)
+{
+#ifdef DEBUG
+
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ XGIDumpSR(pScrn);
+ XGIDumpCR(pScrn);
+// XGIDumpGR(pScrn);
+// XGIDumpPalette(pScrn);
+ XGIDumpMMIO(pScrn);
+
+ /*
+ if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
+ XGIDumpPart0(pScrn);
+ XGIDumpPart05(pScrn);
+ XGIDumpPart1(pScrn);
+ XGIDumpPart2(pScrn);
+ XGIDumpPart3(pScrn);
+ XGIDumpPart4(pScrn);
+ } */
+
+#endif /* DEBUG */
+}
+
+
+void
+XGIDumpPalette(ScrnInfoPtr pScrn)
+{
+#ifdef DEBUG
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned temp[3];
+ int i, j;
+
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ ErrorF("Palette \n");
+ ErrorF
+ ("----------------------------------------------------------------------\n");
+ for (i = 0; i < 0xFF; i += 0x04) {
+ for (j = 0; j < 16; j++) {
+ outb(0x3c7, i + j);
+ temp[0] = inb(0x3c9);
+ temp[1] = inb(0x3c9);
+ temp[2] = inb(0x3c9);
+
+ ErrorF("PA[%02X]: %02X %02X %02X", i + j,
+ temp[0], temp[1], temp[2]);
+ }
+ ErrorF("\n");
+ }
+ ErrorF("\n");
+#endif
+}
diff --git a/src/xgi_driver.h b/src/xgi_driver.h
index cce0764..4004ccd 100644
--- a/src/xgi_driver.h
+++ b/src/xgi_driver.h
@@ -41,43 +41,81 @@ static const struct _xgi_vrate {
{1, 320, 200, 70, TRUE},
{1, 320, 240, 60, TRUE},
{1, 400, 300, 60, TRUE},
- {1, 512, 384, 60, TRUE},
+ {1, 512, 384, 60, TRUE},
{1, 640, 400, 72, TRUE},
- {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE},
- {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE},
- {7, 640, 480, 160, FALSE}, {8, 640, 480, 200, FALSE},
+ {1, 640, 480, 60, TRUE},
+ {2, 640, 480, 72, TRUE},
+ {3, 640, 480, 75, TRUE},
+ {4, 640, 480, 85, TRUE},
+ {5, 640, 480, 100, TRUE},
+ {6, 640, 480, 120, TRUE},
+ {7, 640, 480, 160, FALSE},
+ {8, 640, 480, 200, FALSE},
{1, 720, 480, 60, TRUE},
{1, 720, 576, 58, TRUE},
{1, 768, 576, 58, TRUE},
- {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE},
- {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE},
- {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE},
- {7, 800, 600, 120, FALSE}, {8, 800, 600, 160, FALSE},
- {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
- {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
- {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
+ {1, 800, 480, 60, TRUE},
+ {2, 800, 480, 75, TRUE},
+ {3, 800, 480, 85, TRUE},
+ {1, 800, 600, 56, TRUE},
+ {2, 800, 600, 60, TRUE},
+ {3, 800, 600, 72, TRUE},
+ {4, 800, 600, 75, TRUE},
+ {5, 800, 600, 85, TRUE},
+ {6, 800, 600, 105, TRUE},
+ {7, 800, 600, 120, FALSE},
+ {8, 800, 600, 160, FALSE},
+ {1, 848, 480, 39, TRUE},
+ {2, 848, 480, 60, TRUE},
+ {1, 856, 480, 39, TRUE},
+ {2, 856, 480, 60, TRUE},
+ {1, 1024, 576, 60, TRUE},
+ {2, 1024, 576, 75, TRUE},
+ {3, 1024, 576, 85, TRUE},
{1, 1024, 600, 60, TRUE},
- {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
- {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
+ {1, 1024, 768, 43, TRUE},
+ {2, 1024, 768, 60, TRUE},
+ {3, 1024, 768, 70, FALSE},
+ {4, 1024, 768, 75, FALSE},
+ {5, 1024, 768, 85, TRUE},
+ {6, 1024, 768, 100, TRUE},
{7, 1024, 768, 120, TRUE},
{1, 1152, 768, 60, TRUE},
- {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, FALSE},
- {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, FALSE}, {3, 1280, 720, 85, TRUE},
+ {1, 1152, 864, 75, TRUE},
+ {2, 1152, 864, 84, FALSE},
+ {1, 1280, 720, 60, TRUE},
+ {2, 1280, 720, 75, FALSE},
+ {3, 1280, 720, 85, TRUE},
{1, 1280, 768, 60, TRUE},
{1, 1280, 800, 60, TRUE},
- {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
- {1, 1280, 1024, 43, FALSE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, FALSE},
+ {1, 1280, 960, 60, TRUE},
+ {2, 1280, 960, 85, TRUE},
+ {1, 1280, 1024, 43, FALSE},
+ {2, 1280, 1024, 60, TRUE},
+ {3, 1280, 1024, 75, FALSE},
{4, 1280, 1024, 85, TRUE},
{1, 1360, 768, 60, TRUE},
- {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE},
- {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
- {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
+ {1, 1400, 1050, 60, TRUE},
+ {2, 1400, 1050, 75, TRUE},
+ {1, 1600, 1200, 60, TRUE},
+ {2, 1600, 1200, 65, TRUE},
+ {3, 1600, 1200, 70, TRUE},
+ {4, 1600, 1200, 75, TRUE},
+ {5, 1600, 1200, 85, TRUE},
+ {6, 1600, 1200, 100, TRUE},
{7, 1600, 1200, 120, TRUE},
{1, 1680, 1050, 60, TRUE},
- {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
- {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
- {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
- {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE},
+ {1, 1920, 1440, 60, TRUE},
+ {2, 1920, 1440, 65, TRUE},
+ {3, 1920, 1440, 70, TRUE},
+ {4, 1920, 1440, 75, TRUE},
+ {5, 1920, 1440, 85, TRUE},
+ {6, 1920, 1440, 100, TRUE},
+ {1, 2048, 1536, 60, TRUE},
+ {2, 2048, 1536, 65, TRUE},
+ {3, 2048, 1536, 70, TRUE},
+ {4, 2048, 1536, 75, TRUE},
+ {5, 2048, 1536, 85, TRUE},
{0, 0, 0, 0, FALSE}
};
diff --git a/src/xgi_opt.c b/src/xgi_opt.c
index cf92655..4aac85e 100644
--- a/src/xgi_opt.c
+++ b/src/xgi_opt.c
@@ -276,7 +276,7 @@ xgiOptions(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "2D Acceleration disabled\n");
}
- if (PCI_CHIP_XGIXG20 == pXGI->Chipset)
+ if ((pXGI->Chipset== PCI_CHIP_XGIXG20)||(pXGI->Chipset== PCI_CHIP_XGIXG21)||(pXGI->Chipset== PCI_CHIP_XGIXG27))
pXGI->NoXvideo = TRUE;
/* SWCursor
diff --git a/src/xgi_pci.h b/src/xgi_pci.h
index 4f9d258..bf8cf61 100644
--- a/src/xgi_pci.h
+++ b/src/xgi_pci.h
@@ -1,34 +1,36 @@
-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/******************************************************************
- * Define XGI new PCI device ID.
- ******************************************************************/
-
-
-#define PCI_VENDOR_XGI 0x18CA
-#define PCI_CHIP_XGIXG40 0x0040
-#define PCI_CHIP_XGIXG20 0x0020
+/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/******************************************************************
+ * Define XGI new PCI device ID.
+ ******************************************************************/
+
+
+#define PCI_VENDOR_XGI 0x18CA
+#define PCI_CHIP_XGIXG40 0x0040
+#define PCI_CHIP_XGIXG20 0x0020
+#define PCI_CHIP_XGIXG21 0x0021 /* Jong 01/07/2008; support New XG21 */
+#define PCI_CHIP_XGIXG27 0x0027
diff --git a/src/xgi_setup.c b/src/xgi_setup.c
index a06916b..0265d36 100644
--- a/src/xgi_setup.c
+++ b/src/xgi_setup.c
@@ -1,421 +1,686 @@
-/*
- * Basic hardware and memory detection
- *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1) Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3) The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
- *
- * Ideas and methods for old series based on code by Can-Ru Yeou, XGI Inc.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-#include "xf86.h"
-#include "fb.h"
-#include "xf1bpp.h"
-#include "xf4bpp.h"
-#include "xf86_OSproc.h"
-#include "xf86Resources.h"
-#include "xf86Version.h"
-
-#include "xf86cmap.h"
-
-#include "xgi.h"
-#include "xgi_regs.h"
-#include "xgi_dac.h"
-/* #include "valid_mode.h" */
-
-#define _XF86DGA_SERVER_
-#include <X11/extensions/xf86dgastr.h>
-
-#include "globals.h"
-#define DPMS_SERVER
-#include <X11/extensions/dpms.h>
-
-#include "vb_def.h"
-extern int FbDevExist;
-
-static Bool bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset,
- ULONG ulSet, ULONG *pulValue);
-static Bool bAccessNBridgePCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo,
- ULONG ulOffset, ULONG ulSet, ULONG *pulValue);
-static Bool XGI_IsXG21(ScrnInfoPtr pScrn);
-
-static void XGI_InitHwDevInfo(ScrnInfoPtr pScrn);
-
-static void
-xgiXG40_Setup(ScrnInfoPtr pScrn)
-{
- static const char *const dramChannelStr[5] = {
- "<invalid>", "Single", "Dual", "<invalid>", "Quad"
- };
-
- static const char *const dramTypeStr[4] = {
- "DDR SDRAM",
- "DDR2 SDRAM",
- "DDR2x SDRAM",
- ""
- };
-
-/*********************************************************************
- * Setup
- * Decide the following item of execution data:
- *
- * pXGI->BusWidth
- * pXGI->videoRam (with KB unit)
- * pXGI->CursorOffset (with Byte Unit)
- * pXGI->cmdQueueSize (with Byte Unit)
- * pXGI->cmdQueueSizeMask (with Byte Unit)
- * pXGI->cmdQueueOffset (with Byte Unit)
- * pXGI->cmdQueueLen = 0 ; // init value
- * pXGI->cmdQueueLenMin = 0x200 ; // init value
- * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
- *********************************************************************/
-
- XGIPtr pXGI = XGIPTR(pScrn);
- unsigned int ulMemConfig = 0;
- unsigned mem_per_channel;
- unsigned mem_channels = 1;
- unsigned long ulDramType = 0;
-
- PDEBUG4(ErrorF("xgiXG40_Setup()\n")) ;
-
- pXGI->MemClock = XG40Mclk(pXGI);
-
- /* SR14 DRAM Size Register
- * Default value: XXh
- * D[7:4] Memory size per channel {BChMemSize}
- * 0011: 8 MB
- * 0100: 16 MB
- * 0101: 32 MB
- * 0110: 64 MB
- * 0111: 128 MB
- * 1000: 256MB
- * others: reserved
- * D[3:2] Number of dram channels [1:0] {BChNum}
- * 00: uni-channel
- * 01: reserved
- * 10: dual-channel
- * 11: quad-channel
- * D1 Data width per channel selection {BDataWidth}
- * 0: 32-bits
- * 1: 64-bits
- * D0 Dram channel mapping {BReverseChMapping}
- * 0: Normal mapping
- * 1: Reversal mapping
- * Dual-channel: Logical channel A/B to physical channel B/A
- * Quad-channel: Logical channel A/B/C/D to physical channel
- * C/D/A/B
- */
-
- outXGIIDXREG(XGISR, 0x5, 0x86) ;
- inXGIIDXREG(XGISR, 0x14, ulMemConfig) ;
-
- /* FIXME: Is this correct? The SiS driver detects this differently
- * FIXME: for XG20.
- */
- inXGIIDXREG(XGISR, 0x3A, ulDramType) ;
-
- PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ;
- PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ;
-
- /* FIXME: Is this correct? The SiS driver detects this differently
- * FIXME: for XG20.
- */
- pXGI->BusWidth = (ulMemConfig & 0x02) ? 64 : 32;
-
- mem_per_channel = ((ulMemConfig >> 4) >= 3)
- ? (1 << (ulMemConfig >> 4)) * 1024
- : 8 * 1024;
-
-
- /* All XG20 family chips are single channel, so only test the channel
- * count field on XG40 family chips.
- */
- if (pXGI->Chipset == PCI_CHIP_XGIXG40) {
- /* Check the PCI revision field. For whatever reason, rev. 2 XG40
- * chips encode the DRAM channel count differently than other
- * revisions.
- */
- if (pXGI->ChipRev == 2) {
- switch ((ulMemConfig >> 2) & 0x1) {
- case 1:
- /* Dual channel */
- mem_channels = 2;
- break ;
- }
- }
- else {
- switch ((ulMemConfig >> 2) & 0x3) {
- case 2:
- /* Dual channel */
- mem_channels = 2;
- break ;
- case 3:
- /* Quad channel */
- mem_channels = 4;
- break ;
- }
- }
- }
-
- pScrn->videoRam = mem_per_channel * mem_channels;
-
- /* SR15 DRAM Address Mapping Register
- * Default value: XXh
- * D7 Channel interleaving configuration { BChConfig }
- * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel
- * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region
- * will be channel-interleaved as per BFineGranSize; the high-address region will be channel-
- * interleaved as per BCoarseGranSize[1:0]
- * D[6:5] Memory size of tile-mapped region {BTilingSize}
- * 00: 4 MB
- * 01: 8 MB
- * 10: 16 MB
- * 11: 32 MB
- * The following bits are effective only when D7=1
- * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize}
- * 0: 64 B
- * 1: 128 B
- * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize}
- * 00: 1KB
- * 01: 2KB
- * 10: 4KB
- * 11: 1MB
- * D[1:0] reserved
- */
-
- /* Accelerator parameter Initialization */
-
- pXGI->cmdQueueSize = (pXGI->Chipset == PCI_CHIP_XGIXG20)
- ? VOLARI_CQSIZEXG20 : VOLARI_CQSIZE;
- pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
- pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D);
-
-
- /* If FbDevExist, X.org driver uses 8MB only. The rest of the framebuffer
- * is used by the fbdev driver.
- */
- if (FbDevExist) {
- /* FIXME: Is it even possible to have less than 8Mb of video memory?
- */
- if (pScrn->videoRam < 8*1024) {
- pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize;
- }
- else if (pScrn->videoRam < 16*1024) {
- pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize;
- }
- else {
- pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize;
- }
- }
- else {
- pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize;
- }
-
- pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024;
- PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n",
- pScrn->videoRam, pXGI->cmdQueueSize)) ;
- PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n",
- pXGI->cmdQueueOffset, pXGI->CursorOffset)) ;
-
- pXGI->cmdQueueLen = 0 ;
- pXGI->cmdQueueLenMin = 0x200 ;
- pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
-
- /* Dual Chip support put here
- */
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Detected DRAM type : %s channel %s\n",
- dramChannelStr[mem_channels],
- dramTypeStr[(ulDramType & 0x02) >> 1]);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Detected memory clock : %3.3fMHz\n",
- pXGI->MemClock/1000.0);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Detected VRAM bus width is %d\n", pXGI->BusWidth);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024);
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ;
- XGI_InitHwDevInfo(pScrn);
-}
-
-void
-XGISetup(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- pXGI->Flags = 0;
- pXGI->VBFlags = 0;
-
- switch (pXGI->Chipset) {
- case PCI_CHIP_XGIXG40:
- case PCI_CHIP_XGIXG20:
- default:
- xgiXG40_Setup(pScrn);
- break;
- }
-}
-
-Bool
-XGI_IsXG21(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- Bool is_XG21 = FALSE;
-
- if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
- int temp;
-
- orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
- inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, temp);
-
- is_XG21 = ((temp & GPIOG_READ) != 0);
- }
-
- return is_XG21;
-}
-
-void
-XGI_InitHwDevInfo(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt;
- int i;
-
- pHwDevInfo->pDevice = pXGI ;
- pHwDevInfo->pjVirtualRomBase = pXGI->BIOS ;
- pHwDevInfo->pjCustomizedROMImage = NULL ;
- pHwDevInfo->pjVideoMemoryAddress = (UCHAR*)(pXGI->FbBase) ;
- PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n",(ULONG)(pXGI->FbBase))) ;
- PDEBUG(ErrorF("pHwDevInfo->pjVideoMemoryAddress = 0x%08lx\n",(ULONG)(pHwDevInfo->pjVideoMemoryAddress))) ;
- pHwDevInfo->ulVideoMemorySize = pXGI->FbMapSize ;
- pHwDevInfo->pjIOAddress = pXGI->RelIO + 0x30 ;
-
- switch (pXGI->Chipset) {
- case PCI_CHIP_XGIXG40:
- pHwDevInfo->jChipType = XG40 ;
- break ;
- case PCI_CHIP_XGIXG20:
- pHwDevInfo->jChipType = XGI_IsXG21(pScrn)?XG21:XG20 ;
- break ;
- default:
- pHwDevInfo->jChipType = XG40 ;
- break ;
- }
-
- pHwDevInfo->jChipRevision = pXGI->ChipRev;
- pHwDevInfo->ujVBChipID = VB_CHIP_UNKNOWN ;
- pHwDevInfo->ulExternalChip = 0 ;
-
- pHwDevInfo->ulCRT2LCDType = LCD_1024x768 ;
- pHwDevInfo->bIntegratedMMEnabled = FALSE ;
- pHwDevInfo->bSkipDramSizing = TRUE ;
-
- pHwDevInfo->pSR = pXGI->SRList ;
- pHwDevInfo->pCR = pXGI->CRList ;
- pHwDevInfo->pQueryVGAConfigSpace = (PXGI_QUERYSPACE) bAccessVGAPCIInfo;
-
- for( i = 0 ; i < ExtRegSize ; i++ ){
- pHwDevInfo->pSR[i].jIdx = 0xFF ;
- pHwDevInfo->pSR[i].jVal = 0xFF ;
- pHwDevInfo->pCR[i].jIdx = 0xFF ;
- pHwDevInfo->pCR[i].jVal = 0xFF ;
- }
-
- for( i = 0 ; i < VBIOS_VER_MAX_LENGTH ; i++ ){
- pHwDevInfo -> szVBIOSVer[i] = '\0' ;
- }
-
-
- XGINew_InitVBIOSData(pHwDevInfo, pXGI->XGI_Pr);
- PDEBUG(ErrorF("XGINew_InitVBIOSData(pHwDevInfo) done\n")) ;
-
- ErrorF("XGI_InitVBIOSData VBType = %x\n", pXGI->XGI_Pr->VBType);
- XGI_New_GetVBType(pXGI->XGI_Pr, pHwDevInfo); //yilin
- ErrorF("XGI_New_GetVBType VBType = %x\n", pXGI->XGI_Pr->VBType);
-
- // pHwDevInfo->ujVBChipID = VB_CHIP_301 ; //yilin
- if( pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C))
- {
- PDEBUG(ErrorF("VB chip = 301 \n")) ;
- pHwDevInfo->ujVBChipID = VB_CHIP_301 ;
- }
- else if( pXGI->VBFlags & ( VB_XGI302B| VB_XGI302LV ))
- {
- pHwDevInfo->ujVBChipID = VB_CHIP_302 ;
- }
-/*
- else if (pXGI->VBFlags & VB_LVDS) {
- pHwDevInfo->ulExternalChip |= 0x01 ;
- }
-*/ //yilin
-
-
- PDEBUG(ErrorF("pHwDevInfo->jChipType = %08lX done\n",pHwDevInfo->jChipType)) ;
-}
-
-Bool
-bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset, ULONG ulSet, ULONG *pulValue)
-{
- XGIPtr pXGI ;
-#ifdef XSERVER_LIBPCIACCESS
- int err;
-#else
- PCITAG pciDev;
-#endif
-
- if (!pHwDevInfo || !pulValue) {
- return FALSE;
- }
-
- pXGI = (XGIPtr)pHwDevInfo->pDevice ;
-#ifdef XSERVER_LIBPCIACCESS
- if (ulSet) {
- err = pci_device_cfg_write_u32(pXGI->PciInfo, *pulValue,
- ulOffset & ~3);
- } else {
- err = pci_device_cfg_write_u32(pXGI->PciInfo, pulValue,
- ulOffset & ~3);
- }
-
- return (err == 0);
-#else
- pciDev = pXGI->PciTag ;
-
- if (ulSet) {
- pciWriteLong(pciDev, ulOffset&0xFFFFFFFc, *pulValue);
- } else {
- *pulValue = pciReadLong(pciDev, ulOffset&0xFFFFFFFc);
- }
-
- return TRUE ;
-#endif
-}
+/*
+ * Basic hardware and memory detection
+ *
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Ideas and methods for old series based on code by Can-Ru Yeou, XGI Inc.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86.h"
+#include "fb.h"
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86Version.h"
+
+#include "xf86cmap.h"
+
+#include "xgi.h"
+#include "xgi_regs.h"
+#include "xgi_dac.h"
+/* #include "valid_mode.h" */
+
+#define _XF86DGA_SERVER_
+#include <X11/extensions/xf86dgastr.h>
+
+#include "globals.h"
+#define DPMS_SERVER
+#include <X11/extensions/dpms.h>
+
+#include "vb_def.h"
+extern int FbDevExist;
+
+static Bool bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset,
+ ULONG ulSet, ULONG *pulValue);
+static Bool bAccessNBridgePCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo,
+ ULONG ulOffset, ULONG ulSet, ULONG *pulValue);
+static Bool XGI_IsXG21(ScrnInfoPtr pScrn);
+
+static void XGI_InitHwDevInfo(ScrnInfoPtr pScrn);
+
+/* Jong 10/16/2007; merge code */
+static void
+xgiXG2X_Setup(ScrnInfoPtr pScrn)
+{
+
+/*********************************************************************
+ * Setup
+ * Decide the following item of execution data:
+ *
+ * pXGI->BusWidth
+ * pXGI->videoRam (with KB unit)
+ * pXGI->CursorOffset (with Byte Unit)
+ * pXGI->cmdQueueSize (with Byte Unit)
+ * pXGI->cmdQueueSizeMask (with Byte Unit)
+ * pXGI->cmdQueueOffset (with Byte Unit)
+ * pXGI->cmdQueueLen = 0 ; // init value
+ * pXGI->cmdQueueLenMin = 0x200 ; // init value
+ * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+ *********************************************************************/
+
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned int ulMemConfig = 0;
+ unsigned long ulMemSize = 0;
+ unsigned long ulDramType = 0;
+ char *dramTypeStr ;
+ unsigned long ulTemp ;
+
+ /* DumpDDIName("xgiXG2X_Setup()\n") ; */
+
+ inXGIIDXREG(XGICR, 0x48, ulTemp) ;
+ if(ulTemp & (1<<0)) /* GPIOH, CR48 D[0] read */
+ {
+ dramTypeStr = "DDRII DRAM" ;
+ }
+ else
+ {
+ dramTypeStr = "DDR DRAM" ;
+ }
+
+
+ pXGI->MemClock = XG40Mclk(pXGI);
+
+ /*********************************************************************************************************
+ * SR14 DRAM Size Register
+ * Default value: XXh
+ * D[7:4] Memory size per channel {BChMemSize}
+ * 0011: 8 MB
+ * 0100: 16 MB
+ * 0101: 32 MB
+ * 0110: 64 MB
+ * 0111: 128 MB
+ * 1000: 256MB
+ * others: reserved
+ * D[3:2] Number of dram channels [1:0] {BChNum}
+ * 00: uni-channel
+ * 01: reserved
+ * 10: dual-channel.
+ * 11: quad-channel
+ * D1 Data width per channel selection {BDataWidth}
+ * 0: 32-bits
+ * 1: 64-bits
+ * D0 Dram channel mapping {BReverseChMapping}
+ * 0: Normal mapping
+ * 1: Reversal mapping
+ * Dual-channel: Logical channel A/B to physical channel B/A
+ * Quad-channel: Logical channel A/B/C/D to physical channel C/D/A/B
+ *
+ *********************************************************************************************************/
+
+ outXGIIDXREG(XGISR, 0x5, 0x86) ;
+ inXGIIDXREG(XGISR, 0x14, ulMemConfig) ;
+ inXGIIDXREG(XGISR, 0x3A, ulDramType) ;
+
+ PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ;
+ PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ;
+
+ pXGI->BusWidth = (ulMemConfig & (1<<1) )?64:32 ;
+
+ switch(ulMemConfig>>4)
+ {
+ case 8:
+ ulMemSize = 256*1024 ;
+ break ;
+ case 7:
+ ulMemSize = 128*1024 ;
+ break ;
+ case 6:
+ ulMemSize = 64*1024 ;
+ break ;
+ case 5:
+ ulMemSize = 32*1024 ;
+ break ;
+ case 4:
+ ulMemSize = 16*1024 ;
+ break ;
+ case 3:
+ ulMemSize = 8*1024 ;
+ break ;
+ default:
+ ulMemSize = 8*1024 ;
+ }
+
+ if( pXGI->Chipset == PCI_CHIP_XGIXG40)
+ {
+ if ( (pciReadLong(pXGI->PciTag, 0x08) & 0xFF ) == 2 )
+ {
+ switch((ulMemConfig>>2)&0x1)
+ {
+ case 0:
+ /* Uni channel */
+ ulMemSize *= 1 ;
+ break ;
+ case 1:
+ /* Dual channel */
+ ulMemSize *= 2 ;
+ break ;
+ }
+ }
+ else
+ {
+ switch((ulMemConfig>>2)&0x3)
+ {
+ case 2:
+ /* Dual channel */
+ ulMemSize *= 2 ;
+ break ;
+ case 3:
+ /* Quad channel */
+ ulMemSize *= 4 ;
+ break ;
+ }
+ }
+ }
+
+ pScrn->videoRam = ulMemSize ;
+
+ /*********************************************************************************************************
+ * SR15 DRAM Address Mapping Register
+ * Default value: XXh
+ * D7 Channel interleaving configuration { BChConfig }
+ * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel
+ * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region
+ * will be channel-interleaved as per BFineGranSize; the high-address region will be channel-
+ * interleaved as per BCoarseGranSize[1:0]
+ * D[6:5] Memory size of tile-mapped region {BTilingSize}
+ * 00: 4 MB
+ * 01: 8 MB
+ * 10: 16 MB
+ * 11: 32 MB
+ * The following bits are effective only when D7=1
+ * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize}
+ * 0: 64 B
+ * 1: 128 B
+ * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize}
+ * 00: 1KB
+ * 01: 2KB
+ * 10: 4KB
+ * 11: 1MB
+ * D[1:0] reserved
+ *********************************************************************************************************/
+
+ /* Accelerator parameter Initialization */
+ if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 ))
+ {
+ pXGI->cmdQueueSize = VOLARI_CQSIZEXG20;
+ /* XgiMode = XG20_Mode ; */
+ PDEBUG(ErrorF(" ---XG20_Mode \n"));
+ }
+
+
+ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+ pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D);
+
+
+ /*
+ If FbDevExist, XFree86 driver use the 8MB only. The rest
+ frame buffer is used by other AP.
+ */
+
+ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) )
+ {
+ if( pScrn->videoRam < 8*1024 )
+ {
+ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ else if( pScrn->videoRam < 16*1024 )
+ {
+ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ else
+ {
+ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
+ }
+ }
+ else
+ {
+ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
+ }
+
+ pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024 ;
+ PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n",
+ pScrn->videoRam, pXGI->cmdQueueSize)) ;
+ PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n",
+ pXGI->cmdQueueOffset, pXGI->CursorOffset)) ;
+
+ pXGI->cmdQueueLen = 0 ;
+ pXGI->cmdQueueLenMin = 0x200 ;
+ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+
+ /*****************************************************************
+ * Dual Chip support put here *
+ *****************************************************************/
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM type : %s\n", dramTypeStr);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected memory clock : %3.3fMHz\n",
+ pXGI->MemClock/1000.0);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected VRAM bus width is %d\n", pXGI->BusWidth);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ;
+ XGI_InitHwDevInfo(pScrn);
+}
+
+static void
+xgiXG40_Setup(ScrnInfoPtr pScrn)
+{
+ static const char *const dramChannelStr[5] = {
+ "<invalid>", "Single", "Dual", "<invalid>", "Quad"
+ };
+
+ static const char *const dramTypeStr[4] = {
+ "DDR SDRAM",
+ "DDR2 SDRAM",
+ "DDR2x SDRAM",
+ ""
+ };
+
+/*********************************************************************
+ * Setup
+ * Decide the following item of execution data:
+ *
+ * pXGI->BusWidth
+ * pXGI->videoRam (with KB unit)
+ * pXGI->CursorOffset (with Byte Unit)
+ * pXGI->cmdQueueSize (with Byte Unit)
+ * pXGI->cmdQueueSizeMask (with Byte Unit)
+ * pXGI->cmdQueueOffset (with Byte Unit)
+ * pXGI->cmdQueueLen = 0 ; // init value
+ * pXGI->cmdQueueLenMin = 0x200 ; // init value
+ * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+ *********************************************************************/
+
+ XGIPtr pXGI = XGIPTR(pScrn);
+ unsigned int ulMemConfig = 0;
+ unsigned mem_per_channel;
+ unsigned mem_channels = 1;
+ unsigned long ulDramType = 0;
+
+ PDEBUG4(ErrorF("xgiXG40_Setup()\n")) ;
+
+ pXGI->MemClock = XG40Mclk(pXGI);
+
+ /* SR14 DRAM Size Register
+ * Default value: XXh
+ * D[7:4] Memory size per channel {BChMemSize}
+ * 0011: 8 MB
+ * 0100: 16 MB
+ * 0101: 32 MB
+ * 0110: 64 MB
+ * 0111: 128 MB
+ * 1000: 256MB
+ * others: reserved
+ * D[3:2] Number of dram channels [1:0] {BChNum}
+ * 00: uni-channel
+ * 01: reserved
+ * 10: dual-channel
+ * 11: quad-channel
+ * D1 Data width per channel selection {BDataWidth}
+ * 0: 32-bits
+ * 1: 64-bits
+ * D0 Dram channel mapping {BReverseChMapping}
+ * 0: Normal mapping
+ * 1: Reversal mapping
+ * Dual-channel: Logical channel A/B to physical channel B/A
+ * Quad-channel: Logical channel A/B/C/D to physical channel
+ * C/D/A/B
+ */
+
+ outXGIIDXREG(XGISR, 0x5, 0x86) ;
+ inXGIIDXREG(XGISR, 0x14, ulMemConfig) ;
+
+ /* FIXME: Is this correct? The SiS driver detects this differently
+ * FIXME: for XG20.
+ */
+ inXGIIDXREG(XGISR, 0x3A, ulDramType) ;
+
+ PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ;
+ PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ;
+
+ /* FIXME: Is this correct? The SiS driver detects this differently
+ * FIXME: for XG20.
+ */
+ pXGI->BusWidth = (ulMemConfig & 0x02) ? 64 : 32;
+
+ mem_per_channel = ((ulMemConfig >> 4) >= 3)
+ ? (1 << (ulMemConfig >> 4)) * 1024
+ : 8 * 1024;
+
+
+ /* All XG20 family chips are single channel, so only test the channel
+ * count field on XG40 family chips.
+ */
+ if (pXGI->Chipset == PCI_CHIP_XGIXG40) {
+ /* Check the PCI revision field. For whatever reason, rev. 2 XG40
+ * chips encode the DRAM channel count differently than other
+ * revisions.
+ */
+ if (pXGI->ChipRev == 2) {
+ switch ((ulMemConfig >> 2) & 0x1) {
+ case 1:
+ /* Dual channel */
+ mem_channels = 2;
+ break ;
+ }
+ }
+ else {
+ switch ((ulMemConfig >> 2) & 0x3) {
+ case 2:
+ /* Dual channel */
+ mem_channels = 2;
+ break ;
+ case 3:
+ /* Quad channel */
+ mem_channels = 4;
+ break ;
+ }
+ }
+ }
+
+ pScrn->videoRam = mem_per_channel * mem_channels;
+
+ /* SR15 DRAM Address Mapping Register
+ * Default value: XXh
+ * D7 Channel interleaving configuration { BChConfig }
+ * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel
+ * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region
+ * will be channel-interleaved as per BFineGranSize; the high-address region will be channel-
+ * interleaved as per BCoarseGranSize[1:0]
+ * D[6:5] Memory size of tile-mapped region {BTilingSize}
+ * 00: 4 MB
+ * 01: 8 MB
+ * 10: 16 MB
+ * 11: 32 MB
+ * The following bits are effective only when D7=1
+ * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize}
+ * 0: 64 B
+ * 1: 128 B
+ * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize}
+ * 00: 1KB
+ * 01: 2KB
+ * 10: 4KB
+ * 11: 1MB
+ * D[1:0] reserved
+ */
+
+ /* Accelerator parameter Initialization */
+
+ pXGI->cmdQueueSize = ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21||(pXGI->Chipset == PCI_CHIP_XGIXG27)))
+ ? VOLARI_CQSIZEXG20 : VOLARI_CQSIZE;
+ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+ pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D);
+
+
+ /* If FbDevExist, X.org driver uses 8MB only. The rest of the framebuffer
+ * is used by the fbdev driver.
+ */
+ if (FbDevExist) {
+ /* FIXME: Is it even possible to have less than 8Mb of video memory?
+ */
+ if (pScrn->videoRam < 8*1024) {
+ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize;
+ }
+ else if (pScrn->videoRam < 16*1024) {
+ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize;
+ }
+ else {
+ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize;
+ }
+ }
+ else {
+ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize;
+ }
+
+ pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024;
+ PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n",
+ pScrn->videoRam, pXGI->cmdQueueSize)) ;
+ PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n",
+ pXGI->cmdQueueOffset, pXGI->CursorOffset)) ;
+
+ pXGI->cmdQueueLen = 0 ;
+ pXGI->cmdQueueLenMin = 0x200 ;
+ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+
+ /* Dual Chip support put here
+ */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected DRAM type : %s channel %s\n",
+ dramChannelStr[mem_channels],
+ dramTypeStr[(ulDramType & 0x02) >> 1]);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected memory clock : %3.3fMHz\n",
+ pXGI->MemClock/1000.0);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected VRAM bus width is %d\n", pXGI->BusWidth);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ;
+ XGI_InitHwDevInfo(pScrn);
+}
+
+void
+XGISetup(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ pXGI->Flags = 0;
+ pXGI->VBFlags = 0;
+
+ /* Jong 10/16/2007; merge code */
+ switch (pXGI->Chipset) {
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21:
+ case PCI_CHIP_XGIXG27:
+ xgiXG2X_Setup(pScrn);
+ break;
+
+ case PCI_CHIP_XGIXG40:
+ default:
+ xgiXG40_Setup(pScrn);
+ break;
+ }
+}
+
+/* Jong 01/07/2008; Force to disable 2D engine by SR3A[6]=1 */
+Bool ForceToDisable2DEngine(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI ;
+ Bool bReturn=FALSE;
+ CARD8 bForce;
+
+ pXGI = XGIPTR(pScrn);
+
+ if(pXGI->Chipset == PCI_CHIP_XGIXG21)
+ {
+ inXGIIDXREG(XGISR, 0x3A, bForce) ;
+ bForce &= 0x40;
+
+ if(bForce == 0)
+ bReturn=FALSE;
+ else
+ bReturn=TRUE;
+ }
+ else
+ {
+ bReturn=FALSE;
+ }
+
+ return(bReturn);
+}
+
+Bool
+XGI_IsXG21(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ Bool is_XG21 = FALSE;
+
+ if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
+ int temp;
+
+ orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
+ inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, temp);
+
+ is_XG21 = ((temp & GPIOG_READ) != 0);
+ }
+
+ return is_XG21;
+}
+
+void
+XGI_InitHwDevInfo(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt;
+ int i;
+
+ pHwDevInfo->pDevice = pXGI ;
+ pHwDevInfo->pjVirtualRomBase = pXGI->BIOS ;
+ pHwDevInfo->pjCustomizedROMImage = NULL ;
+ pHwDevInfo->pjVideoMemoryAddress = (UCHAR*)(pXGI->FbBase) ;
+ PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n",(ULONG)(pXGI->FbBase))) ;
+ PDEBUG(ErrorF("pHwDevInfo->pjVideoMemoryAddress = 0x%08lx\n",(ULONG)(pHwDevInfo->pjVideoMemoryAddress))) ;
+ pHwDevInfo->ulVideoMemorySize = pXGI->FbMapSize ;
+ pHwDevInfo->pjIOAddress = pXGI->RelIO + 0x30 ;
+
+ switch (pXGI->Chipset) {
+ case PCI_CHIP_XGIXG40:
+ pHwDevInfo->jChipType = XG40 ;
+ break ;
+ case PCI_CHIP_XGIXG20:
+ pHwDevInfo->jChipType = XGI_IsXG21(pScrn)?XG21:XG20 ;
+ break ;
+ case PCI_CHIP_XGIXG27:
+ pHwDevInfo->jChipType = XG27;
+ break;
+ case PCI_CHIP_XGIXG21:
+ pHwDevInfo->jChipType = XG21;
+ break;
+ default:
+ pHwDevInfo->jChipType = XG40 ;
+ break ;
+ }
+
+ pHwDevInfo->jChipRevision = pXGI->ChipRev;
+ pHwDevInfo->ujVBChipID = VB_CHIP_UNKNOWN ;
+ pHwDevInfo->ulExternalChip = 0 ;
+
+ pHwDevInfo->ulCRT2LCDType = LCD_1024x768 ;
+ pHwDevInfo->bIntegratedMMEnabled = FALSE ;
+ pHwDevInfo->bSkipDramSizing = TRUE ;
+
+ pHwDevInfo->pSR = pXGI->SRList ;
+ pHwDevInfo->pCR = pXGI->CRList ;
+ pHwDevInfo->pQueryVGAConfigSpace = (PXGI_QUERYSPACE) bAccessVGAPCIInfo;
+
+ for( i = 0 ; i < ExtRegSize ; i++ ){
+ pHwDevInfo->pSR[i].jIdx = 0xFF ;
+ pHwDevInfo->pSR[i].jVal = 0xFF ;
+ pHwDevInfo->pCR[i].jIdx = 0xFF ;
+ pHwDevInfo->pCR[i].jVal = 0xFF ;
+ }
+
+ for( i = 0 ; i < VBIOS_VER_MAX_LENGTH ; i++ ){
+ pHwDevInfo -> szVBIOSVer[i] = '\0' ;
+ }
+
+
+ XGINew_InitVBIOSData(pHwDevInfo, pXGI->XGI_Pr);
+ PDEBUG(ErrorF("XGINew_InitVBIOSData(pHwDevInfo) done\n")) ;
+
+ ErrorF("XGI_InitVBIOSData VBType = %x\n", pXGI->XGI_Pr->VBType);
+ XGI_New_GetVBType(pXGI->XGI_Pr, pHwDevInfo); //yilin
+ ErrorF("XGI_New_GetVBType VBType = %x\n", pXGI->XGI_Pr->VBType);
+
+ // pHwDevInfo->ujVBChipID = VB_CHIP_301 ; //yilin
+ if( pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C))
+ {
+ PDEBUG(ErrorF("VB chip = 301 \n")) ;
+ pHwDevInfo->ujVBChipID = VB_CHIP_301 ;
+ }
+ else if( pXGI->VBFlags & ( VB_XGI302B| VB_XGI302LV ))
+ {
+ pHwDevInfo->ujVBChipID = VB_CHIP_302 ;
+ }
+/*
+ else if (pXGI->VBFlags & VB_LVDS) {
+ pHwDevInfo->ulExternalChip |= 0x01 ;
+ }
+*/ //yilin
+
+
+ PDEBUG(ErrorF("pHwDevInfo->jChipType = %08lX done\n",pHwDevInfo->jChipType)) ;
+}
+
+Bool
+bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset, ULONG ulSet, ULONG *pulValue)
+{
+ XGIPtr pXGI ;
+#ifdef XSERVER_LIBPCIACCESS
+ int err;
+#else
+ PCITAG pciDev;
+#endif
+
+ if (!pHwDevInfo || !pulValue) {
+ return FALSE;
+ }
+
+ pXGI = (XGIPtr)pHwDevInfo->pDevice ;
+#ifdef XSERVER_LIBPCIACCESS
+ if (ulSet) {
+ err = pci_device_cfg_write_u32(pXGI->PciInfo, *pulValue,
+ ulOffset & ~3);
+ } else {
+ err = pci_device_cfg_write_u32(pXGI->PciInfo, pulValue,
+ ulOffset & ~3);
+ }
+
+ return (err == 0);
+#else
+ pciDev = pXGI->PciTag ;
+
+ if (ulSet) {
+ pciWriteLong(pciDev, ulOffset&0xFFFFFFFc, *pulValue);
+ } else {
+ *pulValue = pciReadLong(pciDev, ulOffset&0xFFFFFFFc);
+ }
+
+ return TRUE ;
+#endif
+}
diff --git a/src/xgi_vga.c b/src/xgi_vga.c
index 8ff0cb0..4639d3e 100644
--- a/src/xgi_vga.c
+++ b/src/xgi_vga.c
@@ -1,263 +1,276 @@
-/*
- * Mode setup and basic video bridge detection
- *
- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1) Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3) The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Author: Thomas Winischhofer <thomas@winischhofer.net>
- *
- * Init() function for old series (except for TV and FIFO calculation)
- * previously based on code which is Copyright (C) 1998,1999 by Alan
- * Hourihane, Wigan, England
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86Version.h"
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-
-#include "xgi.h"
-#include "xgi_regs.h"
-#include "xgi_dac.h"
-
-#include "vb_def.h"
-
-Bool XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
-
-#define Midx 0
-#define Nidx 1
-#define VLDidx 2
-#define Pidx 3
-
-Bool
-XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
- XGIRegPtr pReg = &pXGI->ModeReg;
- vgaRegPtr vgaReg = &VGAHWPTR(pScrn)->ModeReg;
- int vgaIOBase;
- unsigned short temp;
- int offset;
- int clock = mode->Clock;
- unsigned int vclk[5];
-
- int num, denum, div, sbit, scale;
- unsigned short Threshold_Low, Threshold_High;
-
-PDEBUG(ErrorF("XG40Init()\n"));
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "XG40Init()\n");
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
- "virtualX = %d depth = %d Logical width = %d\n",
- pScrn->virtualX, pScrn->bitsPerPixel,
- pScrn->virtualX * pScrn->bitsPerPixel/8);
-
- vgaHWGetIOBase(VGAHWPTR(pScrn));
- vgaIOBase = VGAHWPTR(pScrn)->IOBase;
-
- (*pXGI->XGISave)(pScrn, pReg);
-
- outw(VGA_SEQ_INDEX, 0x8605);
-
- pReg->xgiRegs3C4[6] &= ~GENMASK(4:2);
-
- switch (pScrn->bitsPerPixel) {
- case 8:
- pXGI->DstColor = 0 ;
- pReg->xgiRegs3C4[6] |= 0x03;
- PDEBUG(ErrorF("8: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
- break;
- case 16:
- pXGI->DstColor = 1 << 16 ;
- PDEBUG(ErrorF("16: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
- if (pScrn->depth==15) {
- pReg->xgiRegs3C4[6] |= ((1 << 2) | 0x03);
- } else {
- pReg->xgiRegs3C4[6] |= ((2 << 2) | 0x03);
- }
- break;
- case 24:
- pReg->xgiRegs3C4[6] |= ((3 << 2) | 0x03);
- break;
- case 32:
- PDEBUG(ErrorF("32: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
- pXGI->DstColor = 2 << 16 ;
- pReg->xgiRegs3C4[6] |= ((4 << 2) | 0x03);
- break;
- }
-
- pXGI->scrnOffset = pScrn->displayWidth * ((pScrn->bitsPerPixel+7)/8);
- pXGI->scrnOffset += 15 ;
- pXGI->scrnOffset >>= 4 ;
- pXGI->scrnOffset <<= 4 ;
-
- PDEBUG(ErrorF("XG40Init: pScrn->displayWidth = %ld\n",pScrn->displayWidth )) ;
- PDEBUG(ErrorF("XG40Init: pScrn->bitsPerPixel = %ld\n",pScrn->bitsPerPixel )) ;
- PDEBUG(ErrorF("XG40Init: pXGI->scrnOffset = %ld\n",pXGI->scrnOffset )) ;
-
- pReg->xgiRegs3D4[0x19] = 0;
- pReg->xgiRegs3D4[0x1A] &= 0xFC;
-
- if (mode->Flags & V_INTERLACE) {
- offset = pXGI->scrnOffset >> 2;
- pReg->xgiRegs3C4[0x06] |= 0x20;
-
- temp = (mode->CrtcHSyncStart >> 3) -
- (mode->CrtcHTotal >> 3)/2;
- pReg->xgiRegs3D4[0x19] = GETVAR8(temp);
- pReg->xgiRegs3D4[0x1A] |= GETBITS(temp, 9:8);
- } else {
- offset = pXGI->scrnOffset >> 3;
- pReg->xgiRegs3C4[0x06] &= ~0x20;
- }
-
- pReg->xgiRegs3C4[0x07] |= 0x10; /* enable High Speed DAC */
- pReg->xgiRegs3C4[0x07] &= 0xFC;
- if (clock < 100000)
- pReg->xgiRegs3C4[0x07] |= 0x03;
- else if (clock < 200000)
- pReg->xgiRegs3C4[0x07] |= 0x02;
- else if (clock < 250000)
- pReg->xgiRegs3C4[0x07] |= 0x01;
-
- /* Extended Vertical Overflow */
- pReg->xgiRegs3C4[0x0A] =
- GETBITSTR(mode->CrtcVTotal -2, 10:10, 0:0) |
- GETBITSTR(mode->CrtcVDisplay -1, 10:10, 1:1) |
- GETBITSTR(mode->CrtcVBlankStart , 10:10, 2:2) |
- GETBITSTR(mode->CrtcVSyncStart , 10:10, 3:3) |
- GETBITSTR(mode->CrtcVBlankEnd , 8:8, 4:4) |
- GETBITSTR(mode->CrtcVSyncEnd , 4:4, 5:5) ;
-
- /* Extended Horizontal Overflow */
- pReg->xgiRegs3C4[0x0B] =
- GETBITSTR((mode->CrtcHTotal >> 3) - 5, 9:8, 1:0) |
- GETBITSTR((mode->CrtcHDisplay >> 3) - 1, 9:8, 3:2) |
- GETBITSTR((mode->CrtcHBlankStart >> 3) , 9:8, 5:4) |
- GETBITSTR((mode->CrtcHSyncStart >> 3) , 9:8, 7:6) ;
-
- pReg->xgiRegs3C4[0x0C] &= 0xF8;
- pReg->xgiRegs3C4[0x0C] |=
- GETBITSTR(mode->CrtcHBlankEnd >> 3, 7:6, 1:0) |
- GETBITSTR(mode->CrtcHSyncEnd >> 3, 5:5, 2:2) ;
-
- /* Screen Offset */
- vgaReg->CRTC[0x13] = GETVAR8(offset);
- pReg->xgiRegs3C4[0x0E] &= 0xF0;
- pReg->xgiRegs3C4[0x0E] |= GETBITS(offset, 11:8);
-
- /* line compare */
- if (mode->CrtcHDisplay > 0)
- pReg->xgiRegs3C4[0x0F] |= 0x08;
- else
- pReg->xgiRegs3C4[0x0F] &= 0xF7;
-
- pReg->xgiRegs3C4[0x10] =
- ((mode->CrtcHDisplay *((pScrn->bitsPerPixel+7)/8) + 63) >> 6)+1;
-
- /* Enable Linear */
- pReg->xgiRegs3C4[0x20] |= 0x81;
-
-
- /* Set vclk */
- if (compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) {
- pReg->xgiRegs3C4[0x2B] = (num -1) & 0x7f;
- if (div == 2)
- pReg->xgiRegs3C4[0x2B] |= 0x80;
- pReg->xgiRegs3C4[0x2C] = ((denum -1) & 0x1f);
- pReg->xgiRegs3C4[0x2C] |= (((scale-1)&3) << 5);
- if (sbit)
- pReg->xgiRegs3C4[0x2C] |= 0x80;
- pReg->xgiRegs3C4[0x2D] = 0x80;
- }
- else {
- /* if compute_vclk cannot handle the request clock try XGICalcClock! */
- XGICalcClock(pScrn, clock, 2, vclk);
- pReg->xgiRegs3C4[0x2B] = (vclk[Midx] - 1) & 0x7f ;
- pReg->xgiRegs3C4[0x2B] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
-
- /* bits [4:0] contain denumerator -MC */
- pReg->xgiRegs3C4[0x2C] = (vclk[Nidx] -1) & 0x1f ;
-
- if (vclk[Pidx] <= 4) {
- /* postscale 1,2,3,4 */
- pReg->xgiRegs3C4[0x2C] |= (vclk[Pidx] -1 ) << 5 ;
- pReg->xgiRegs3C4[0x2C] &= 0x7F;
- } else {
- /* postscale 6,8 */
- pReg->xgiRegs3C4[0x2C] |= ((vclk[Pidx] / 2) -1 ) << 5 ;
- pReg->xgiRegs3C4[0x2C] |= 0x80;
- }
- pReg->xgiRegs3C4[0x2D] = 0x80;
- } /* end of set vclk */
-
- if (clock > 150000) { /* enable two-pixel mode */
- pReg->xgiRegs3C4[0x07] |= 0x80;
- pReg->xgiRegs3C4[0x32] |= 0x08;
- } else {
- pReg->xgiRegs3C4[0x07] &= 0x7F;
- pReg->xgiRegs3C4[0x32] &= 0xF7;
- }
-
- /*pReg->xgiRegs3C2 = inb(0x3CC) | 0x0C;*/ /* Programmable Clock */
- pReg->xgiRegs3C2 = inb(pXGI->RelIO+0x4c) | 0x0C; /*Programmable Clock*/
-
- if (!pXGI->NoAccel) {
- /* Enable 2D accelerator.
- */
- pReg->xgiRegs3C4[0x1E] |= (SR1E_ENABLE_2D | SR1E_ENABLE_3D);
- }
-
- /* set threshold value */
- (*pXGI->SetThreshold)(pScrn, mode, &Threshold_Low, &Threshold_High);
- pReg->xgiRegs3C4[0x08] = GETBITSTR(Threshold_Low, 3:0, 7:4) | 0xF;
- pReg->xgiRegs3C4[0x0F] &= ~GENMASK(5:5);
- pReg->xgiRegs3C4[0x0F] |= GETBITSTR(Threshold_Low, 4:4, 5:5);
- pReg->xgiRegs3C4[0x09] &= ~GENMASK(3:0);
- pReg->xgiRegs3C4[0x09] |= GETBITS(Threshold_High, 3:0);
-
- return(TRUE);
-}
-
-/* Detect video bridge and set VBFlags accordingly */
-void XGIVGAPreInit(ScrnInfoPtr pScrn)
-{
- XGIPtr pXGI = XGIPTR(pScrn);
-
- switch (pXGI->Chipset) {
- case PCI_CHIP_XGIXG40:
- case PCI_CHIP_XGIXG20:
- default:
- pXGI->ModeInit = XG40Init;
- break;
- }
-
-
-}
-
+/*
+ * Mode setup and basic video bridge detection
+ *
+ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1) Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3) The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Init() function for old series (except for TV and FIFO calculation)
+ * previously based on code which is Copyright (C) 1998,1999 by Alan
+ * Hourihane, Wigan, England
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "xgi.h"
+#include "xgi_regs.h"
+#include "xgi_dac.h"
+
+#include "vb_def.h"
+
+Bool XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/* Jong 01/07/2008; force to disable 2D */
+extern Bool ForceToDisable2DEngine(ScrnInfoPtr pScrn);
+
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+
+Bool
+XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+ XGIRegPtr pReg = &pXGI->ModeReg;
+ vgaRegPtr vgaReg = &VGAHWPTR(pScrn)->ModeReg;
+ int vgaIOBase;
+ unsigned short temp;
+ int offset;
+ int clock = mode->Clock;
+ unsigned int vclk[5];
+
+ int num, denum, div, sbit, scale;
+ unsigned short Threshold_Low, Threshold_High;
+
+PDEBUG(ErrorF("XG40Init()\n"));
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "XG40Init()\n");
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "virtualX = %d depth = %d Logical width = %d\n",
+ pScrn->virtualX, pScrn->bitsPerPixel,
+ pScrn->virtualX * pScrn->bitsPerPixel/8);
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ (*pXGI->XGISave)(pScrn, pReg);
+
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ pReg->xgiRegs3C4[6] &= ~GENMASK(4:2);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pXGI->DstColor = 0 ;
+ pReg->xgiRegs3C4[6] |= 0x03;
+ PDEBUG(ErrorF("8: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
+ break;
+ case 16:
+ pXGI->DstColor = 1 << 16 ;
+ PDEBUG(ErrorF("16: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
+ if (pScrn->depth==15) {
+ pReg->xgiRegs3C4[6] |= ((1 << 2) | 0x03);
+ } else {
+ pReg->xgiRegs3C4[6] |= ((2 << 2) | 0x03);
+ }
+ break;
+ case 24:
+ pReg->xgiRegs3C4[6] |= ((3 << 2) | 0x03);
+ break;
+ case 32:
+ PDEBUG(ErrorF("32: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
+ pXGI->DstColor = 2 << 16 ;
+ pReg->xgiRegs3C4[6] |= ((4 << 2) | 0x03);
+ break;
+ }
+
+ pXGI->scrnOffset = pScrn->displayWidth * ((pScrn->bitsPerPixel+7)/8);
+ pXGI->scrnOffset += 15 ;
+ pXGI->scrnOffset >>= 4 ;
+ pXGI->scrnOffset <<= 4 ;
+
+ PDEBUG(ErrorF("XG40Init: pScrn->displayWidth = %ld\n",pScrn->displayWidth )) ;
+ PDEBUG(ErrorF("XG40Init: pScrn->bitsPerPixel = %ld\n",pScrn->bitsPerPixel )) ;
+ PDEBUG(ErrorF("XG40Init: pXGI->scrnOffset = %ld\n",pXGI->scrnOffset )) ;
+
+ pReg->xgiRegs3D4[0x19] = 0;
+ pReg->xgiRegs3D4[0x1A] &= 0xFC;
+
+ if (mode->Flags & V_INTERLACE) {
+ offset = pXGI->scrnOffset >> 2;
+ pReg->xgiRegs3C4[0x06] |= 0x20;
+
+ temp = (mode->CrtcHSyncStart >> 3) -
+ (mode->CrtcHTotal >> 3)/2;
+ pReg->xgiRegs3D4[0x19] = GETVAR8(temp);
+ pReg->xgiRegs3D4[0x1A] |= GETBITS(temp, 9:8);
+ } else {
+ offset = pXGI->scrnOffset >> 3;
+ pReg->xgiRegs3C4[0x06] &= ~0x20;
+ }
+
+ pReg->xgiRegs3C4[0x07] |= 0x10; /* enable High Speed DAC */
+ pReg->xgiRegs3C4[0x07] &= 0xFC;
+ if (clock < 100000)
+ pReg->xgiRegs3C4[0x07] |= 0x03;
+ else if (clock < 200000)
+ pReg->xgiRegs3C4[0x07] |= 0x02;
+ else if (clock < 250000)
+ pReg->xgiRegs3C4[0x07] |= 0x01;
+
+ /* Extended Vertical Overflow */
+ pReg->xgiRegs3C4[0x0A] =
+ GETBITSTR(mode->CrtcVTotal -2, 10:10, 0:0) |
+ GETBITSTR(mode->CrtcVDisplay -1, 10:10, 1:1) |
+ GETBITSTR(mode->CrtcVBlankStart , 10:10, 2:2) |
+ GETBITSTR(mode->CrtcVSyncStart , 10:10, 3:3) |
+ GETBITSTR(mode->CrtcVBlankEnd , 8:8, 4:4) |
+ GETBITSTR(mode->CrtcVSyncEnd , 4:4, 5:5) ;
+
+ /* Extended Horizontal Overflow */
+ pReg->xgiRegs3C4[0x0B] =
+ GETBITSTR((mode->CrtcHTotal >> 3) - 5, 9:8, 1:0) |
+ GETBITSTR((mode->CrtcHDisplay >> 3) - 1, 9:8, 3:2) |
+ GETBITSTR((mode->CrtcHBlankStart >> 3) , 9:8, 5:4) |
+ GETBITSTR((mode->CrtcHSyncStart >> 3) , 9:8, 7:6) ;
+
+ pReg->xgiRegs3C4[0x0C] &= 0xF8;
+ pReg->xgiRegs3C4[0x0C] |=
+ GETBITSTR(mode->CrtcHBlankEnd >> 3, 7:6, 1:0) |
+ GETBITSTR(mode->CrtcHSyncEnd >> 3, 5:5, 2:2) ;
+
+ /* Screen Offset */
+ vgaReg->CRTC[0x13] = GETVAR8(offset);
+ pReg->xgiRegs3C4[0x0E] &= 0xF0;
+ pReg->xgiRegs3C4[0x0E] |= GETBITS(offset, 11:8);
+
+ /* line compare */
+ if (mode->CrtcHDisplay > 0)
+ pReg->xgiRegs3C4[0x0F] |= 0x08;
+ else
+ pReg->xgiRegs3C4[0x0F] &= 0xF7;
+
+ pReg->xgiRegs3C4[0x10] =
+ ((mode->CrtcHDisplay *((pScrn->bitsPerPixel+7)/8) + 63) >> 6)+1;
+
+ /* Enable Linear */
+ pReg->xgiRegs3C4[0x20] |= 0x81;
+
+
+ /* Set vclk */
+ if (compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) {
+ pReg->xgiRegs3C4[0x2B] = (num -1) & 0x7f;
+ if (div == 2)
+ pReg->xgiRegs3C4[0x2B] |= 0x80;
+ pReg->xgiRegs3C4[0x2C] = ((denum -1) & 0x1f);
+ pReg->xgiRegs3C4[0x2C] |= (((scale-1)&3) << 5);
+ if (sbit)
+ pReg->xgiRegs3C4[0x2C] |= 0x80;
+ pReg->xgiRegs3C4[0x2D] = 0x80;
+ }
+ else {
+ /* if compute_vclk cannot handle the request clock try XGICalcClock! */
+ XGICalcClock(pScrn, clock, 2, vclk);
+ pReg->xgiRegs3C4[0x2B] = (vclk[Midx] - 1) & 0x7f ;
+ pReg->xgiRegs3C4[0x2B] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
+
+ /* bits [4:0] contain denumerator -MC */
+ pReg->xgiRegs3C4[0x2C] = (vclk[Nidx] -1) & 0x1f ;
+
+ if (vclk[Pidx] <= 4) {
+ /* postscale 1,2,3,4 */
+ pReg->xgiRegs3C4[0x2C] |= (vclk[Pidx] -1 ) << 5 ;
+ pReg->xgiRegs3C4[0x2C] &= 0x7F;
+ } else {
+ /* postscale 6,8 */
+ pReg->xgiRegs3C4[0x2C] |= ((vclk[Pidx] / 2) -1 ) << 5 ;
+ pReg->xgiRegs3C4[0x2C] |= 0x80;
+ }
+ pReg->xgiRegs3C4[0x2D] = 0x80;
+ } /* end of set vclk */
+
+ if (clock > 150000) { /* enable two-pixel mode */
+ pReg->xgiRegs3C4[0x07] |= 0x80;
+ pReg->xgiRegs3C4[0x32] |= 0x08;
+ } else {
+ pReg->xgiRegs3C4[0x07] &= 0x7F;
+ pReg->xgiRegs3C4[0x32] &= 0xF7;
+ }
+
+ /*pReg->xgiRegs3C2 = inb(0x3CC) | 0x0C;*/ /* Programmable Clock */
+ pReg->xgiRegs3C2 = inb(pXGI->RelIO+0x4c) | 0x0C; /*Programmable Clock*/
+
+ if (!pXGI->NoAccel) {
+ /* Enable 2D accelerator.
+ */
+ /* Jong 01/07/2008; disable 2D engine depend on SR3A[6]:1-> force to siable 2D */
+ if(pXGI->Chipset != PCI_CHIP_XGIXG21)
+ pReg->xgiRegs3C4[0x1E] |= 0x42;
+ else
+ {
+ if(ForceToDisable2DEngine(pScrn))
+ pReg->xgiRegs3C4[0x1E] |= 0x02;
+ }
+
+ }
+
+ /* set threshold value */
+ (*pXGI->SetThreshold)(pScrn, mode, &Threshold_Low, &Threshold_High);
+ pReg->xgiRegs3C4[0x08] = GETBITSTR(Threshold_Low, 3:0, 7:4) | 0xF;
+ pReg->xgiRegs3C4[0x0F] &= ~GENMASK(5:5);
+ pReg->xgiRegs3C4[0x0F] |= GETBITSTR(Threshold_Low, 4:4, 5:5);
+ pReg->xgiRegs3C4[0x09] &= ~GENMASK(3:0);
+ pReg->xgiRegs3C4[0x09] |= GETBITS(Threshold_High, 3:0);
+
+ return(TRUE);
+}
+
+/* Detect video bridge and set VBFlags accordingly */
+void XGIVGAPreInit(ScrnInfoPtr pScrn)
+{
+ XGIPtr pXGI = XGIPTR(pScrn);
+
+ switch (pXGI->Chipset) {
+ case PCI_CHIP_XGIXG40:
+ case PCI_CHIP_XGIXG20:
+ case PCI_CHIP_XGIXG21:
+ case PCI_CHIP_XGIXG27:
+ default:
+ pXGI->ModeInit = XG40Init;
+ break;
+ }
+
+
+}
+
diff --git a/xgi-xg20-21-27.patch b/xgi-xg20-21-27.patch
new file mode 100644
index 0000000..a55070d
--- /dev/null
+++ b/xgi-xg20-21-27.patch
@@ -0,0 +1,46676 @@
+diff --git a/src/init.c b/src/init.c
+index cc12b4f..12f3c80 100644
+--- a/src/init.c
++++ b/src/init.c
+@@ -1,1032 +1,1073 @@
+-/*
+- * Mode initializing code (CRT1 section)
+- * (Universal module for Linux kernel framebuffer and XFree86 4.x)
+- *
+- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+- *
+- * If distributed as part of the Linux kernel, the following license terms
+- * apply:
+- *
+- * * This program is free software; you can redistribute it and/or modify
+- * * it under the terms of the GNU General Public License as published by
+- * * the Free Software Foundation; either version 2 of the named License,
+- * * or any later version.
+- * *
+- * * This program is distributed in the hope that it will be useful,
+- * * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * * GNU General Public License for more details.
+- * *
+- * * You should have received a copy of the GNU General Public License
+- * * along with this program; if not, write to the Free Software
+- * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+- *
+- * Otherwise, the following license terms apply:
+- *
+- * * Redistribution and use in source and binary forms, with or without
+- * * modification, are permitted provided that the following conditions
+- * * are met:
+- * * 1) Redistributions of source code must retain the above copyright
+- * * notice, this list of conditions and the following disclaimer.
+- * * 2) Redistributions in binary form must reproduce the above copyright
+- * * notice, this list of conditions and the following disclaimer in the
+- * * documentation and/or other materials provided with the distribution.
+- * * 3) The name of the author may not be used to endorse or promote products
+- * * derived from this software without specific prior written permission.
+- * *
+- * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+- * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+- * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- * Author: Thomas Winischhofer <thomas@winischhofer.net>
+- *
+- * Formerly based on non-functional code-fragements for 300 series by XGI, Inc.
+- * Used by permission.
+- *
+- * TW says: This code looks awful, I know. But please don't do anything about
+- * this otherwise debugging will be hell.
+- * The code is extremely fragile as regards the different chipsets, different
+- * video bridges and combinations thereof. If anything is changed, extreme
+- * care has to be taken that that change doesn't break it for other chipsets,
+- * bridges or combinations thereof.
+- * All comments in this file are by me, regardless if they are marked TW or not.
+- *
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "init.h"
+-#include "vgatypes.h"
+-#include "vb_def.h"
+-#include "vb_setmode.h"
+-
+-/*********************************************/
+-/* HELPER: Get ModeID */
+-/*********************************************/
+-
+-USHORT
+-XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
+- int Depth, int LCDwidth, int LCDheight)
+-{
+- USHORT ModeIndex = 0;
+-
+- switch(HDisplay)
+- {
+- case 320:
+- if(VDisplay == 200)
+- ModeIndex = ModeIndex_320x200[Depth];
+- else if(VDisplay == 240)
+- ModeIndex = ModeIndex_320x240[Depth];
+-
+- break;
+- case 400:
+- if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
+- break;
+- case 512:
+- if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
+- break;
+- case 640:
+- if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
+- else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
+- break;
+- case 720:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
+- else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
+- }
+- break;
+- case 768:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
+- }
+- break;
+- case 800:
+- if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
+- else if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
+- }
+- break;
+- case 848:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
+- }
+- break;
+- case 856:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
+- }
+- break;
+- case 1024:
+- if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
+- else if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
+- }
+- break;
+- case 1152:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
+- }
+- break;
+- case 1280:
+- if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
+- else if(VDisplay == 720) {
+- if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
+- ModeIndex = ModeIndex_1280x720[Depth];
+- } else if(!(VBFlags & CRT1_LCDA)) {
+- ModeIndex = ModeIndex_1280x720[Depth];
+- }
+- } else if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
+- else if(VDisplay == 768) {
+- ModeIndex = ModeIndex_310_1280x768[Depth];
+- }
+- }
+- break;
+- case 1360:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
+- }
+- break;
+- case 1400:
+- break;
+- case 1600:
+- if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
+- break;
+- case 1680:
+- break;
+- case 1920:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
+- }
+- break;
+- case 2048:
+- if(!(VBFlags & CRT1_LCDA)) {
+- if(VDisplay == 1536) {
+- ModeIndex = ModeIndex_310_2048x1536[Depth];
+- }
+- }
+- break;
+- }
+-
+- return(ModeIndex);
+-}
+-
+-/*********************************************/
+-/* HELPER: SetReg, GetReg */
+-/*********************************************/
+-
+-void
+-XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data)
+-{
+- outb(port,index);
+- outb(port + 1,data);
+-}
+-
+-void
+-XGI_SetRegByte(XGIIOADDRESS port, USHORT data)
+-{
+- outb(port,data);
+-}
+-
+-void
+-XGI_SetRegShort(XGIIOADDRESS port, USHORT data)
+-{
+- outw(port,data);
+-}
+-
+-void
+-XGI_SetRegLong(XGIIOADDRESS port, ULONG data)
+-{
+- outl(port,data);
+-}
+-
+-UCHAR
+-XGI_GetReg(XGIIOADDRESS port, USHORT index)
+-{
+- outb(port,index);
+- return inb(port + 1);
+-}
+-
+-UCHAR
+-XGI_GetRegByte(XGIIOADDRESS port)
+-{
+- return inb(port);
+-}
+-
+-USHORT
+-XGI_GetRegShort(XGIIOADDRESS port)
+-{
+- return inw(port);
+-}
+-
+-ULONG
+-XGI_GetRegLong(XGIIOADDRESS port)
+-{
+- return inl(port);
+-}
+-
+-void
+-XGI_SetRegANDOR(XGIIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+-{
+- USHORT temp;
+-
+- temp = XGI_GetReg(Port,Index);
+- temp = (temp & (DataAND)) | DataOR;
+- XGI_SetReg(Port,Index,temp);
+-}
+-
+-void
+-XGI_SetRegAND(XGIIOADDRESS Port,USHORT Index,USHORT DataAND)
+-{
+- USHORT temp;
+-
+- temp = XGI_GetReg(Port,Index);
+- temp &= DataAND;
+- XGI_SetReg(Port,Index,temp);
+-}
+-
+-void
+-XGI_SetRegOR(XGIIOADDRESS Port,USHORT Index,USHORT DataOR)
+-{
+- USHORT temp;
+-
+- temp = XGI_GetReg(Port,Index);
+- temp |= DataOR;
+- XGI_SetReg(Port,Index,temp);
+-}
+-
+-/*********************************************/
+-/* HELPER: DisplayOn, DisplayOff */
+-/*********************************************/
+-
+-void
+-XGI_New_DisplayOn(VB_DEVICE_INFO *XGI_Pr)
+-{
+- XGI_SetRegAND(XGI_Pr->P3c4,0x01,0xDF);
+-}
+-
+-void
+-XGI_New_DisplayOff(VB_DEVICE_INFO *XGI_Pr)
+-{
+- XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x20);
+-}
+-
+-/*********************************************/
+-/* HELPER: Init PCI & Engines */
+-/*********************************************/
+-
+-static void
+-XGIInitPCIetc(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- switch(HwInfo->jChipType) {
+- case XG40:
+- case XG42:
+- case XG20:
+- XGI_SetReg(XGI_Pr->P3c4,0x20,0xa1);
+- /* - Enable 2D (0x40)
+- * - Enable 3D (0x02)
+- * - Enable 3D vertex command fetch (0x10)
+- * - Enable 3D command parser (0x08)
+- * - Enable 3D G/L transformation engine (0x80)
+- */
+- XGI_SetRegOR(XGI_Pr->P3c4, 0x1E,
+- SR1E_ENABLE_3D_TRANSFORM_ENGINE
+- | SR1E_ENABLE_2D
+- | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
+- | SR1E_ENABLE_3D_COMMAND_PARSER
+- | SR1E_ENABLE_3D);
+- break;
+- }
+-}
+-
+-/*********************************************/
+-/* HELPER: GetVBType */
+-/*********************************************/
+-
+-void
+-XGI_New_GetVBType(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- USHORT flag=0, rev=0, nolcd=0;
+-
+- XGI_Pr->VBType = 0;
+-
+- flag = XGI_GetReg(XGI_Pr->Part4Port,0x00);
+-PDEBUG(ErrorF("GetVBType: part4_0: %x \n",flag)); //yilin
+- if(flag > 3) return;
+-
+- rev = XGI_GetReg(XGI_Pr->Part4Port,0x01);
+-PDEBUG(ErrorF("GetVBType: part4_1: %x \n",rev)); //yilin
+-
+- if(flag >= 2) {
+- XGI_Pr->VBType = VB_XGI302B;
+- } else if(flag == 1) {
+- if(rev >= 0xC0) {
+- XGI_Pr->VBType = VB_XGI301C;
+- } else if(rev >= 0xB0) {
+- XGI_Pr->VBType = VB_XGI301B;
+- /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
+- nolcd = XGI_GetReg(XGI_Pr->Part4Port,0x23);
+- if(!(nolcd & 0x02)) XGI_Pr->VBType |= VB_NoLCD;
+- } else {
+- XGI_Pr->VBType = VB_XGI301;
+- }
+- }
+- if(XGI_Pr->VBType & (VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
+- if(rev >= 0xE0) {
+- flag = XGI_GetReg(XGI_Pr->Part4Port,0x39);
+- if(flag == 0xff) XGI_Pr->VBType = VB_XGI302LV;
+- else XGI_Pr->VBType = VB_XGI302ELV;
+- } else if(rev >= 0xD0) {
+- XGI_Pr->VBType = VB_XGI301LV;
+- }
+- }
+-PDEBUG(ErrorF("GetVBType: XGI_Pr->VBType=%x \n",XGI_Pr->VBType)); //yilin
+-}
+-
+-/*********************************************/
+-/* HELPER: SearchModeID */
+-/*********************************************/
+-
+-BOOLEAN
+-XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
+- const XGI_ExtStruct *EModeIDTable,
+- unsigned char VGAINFO, USHORT *ModeNo, USHORT *ModeIdIndex)
+-{
+- if (*ModeNo <= 0x13) {
+- if ((*ModeNo) <= 0x05)
+- (*ModeNo) |= 0x01;
+-
+- for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
+- if (SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo))
+- break;
+-
+- if (SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
+- return FALSE;
+- }
+-
+- if (*ModeNo == 0x07) {
+- if (VGAINFO & 0x10)
+- (*ModeIdIndex)++; /* 400 lines */
+- /* else 350 lines */
+- }
+-
+- if (*ModeNo <= 0x03) {
+- if (!(VGAINFO & 0x80))
+- (*ModeIdIndex)++;
+-
+- if (VGAINFO & 0x10)
+- (*ModeIdIndex)++; /* 400 lines */
+- /* else 350 lines */
+- }
+- /* else 200 lines */
+- }
+- else {
+-
+- for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
+- if (EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo))
+- break;
+-
+- if (EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+- return FALSE;
+- }
+- }
+-
+- return TRUE;
+-}
+-
+-/*********************************************/
+-/* HELPER: GetModePtr */
+-/*********************************************/
+-
+-UCHAR
+-XGI_GetModePtr(const XGI_StStruct *SModeIDTable, unsigned ModeType,
+- USHORT ModeNo, USHORT ModeIdIndex)
+-{
+- return (ModeNo <= 0x13)
+- ? SModeIDTable[ModeIdIndex].St_StTableIndex
+- : ((ModeType <= 0x02) ? 0x1B /* 02 -> ModeEGA */ : 0x0F);
+-}
+-
+-
+-/*********************************************/
+-/* HELPER: LowModeTests */
+-/*********************************************/
+-
+-static BOOLEAN
+-XGI_DoLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- USHORT temp,temp1,temp2;
+-
+- if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+- return(1);
+- temp = XGI_GetReg(XGI_Pr->P3d4,0x11);
+- XGI_SetRegOR(XGI_Pr->P3d4,0x11,0x80);
+- temp1 = XGI_GetReg(XGI_Pr->P3d4,0x00);
+- XGI_SetReg(XGI_Pr->P3d4,0x00,0x55);
+- temp2 = XGI_GetReg(XGI_Pr->P3d4,0x00);
+- XGI_SetReg(XGI_Pr->P3d4,0x00,temp1);
+- XGI_SetReg(XGI_Pr->P3d4,0x11,temp);
+- if (temp2 == 0x55)
+- return(0);
+- else
+- return(1);
+-}
+-
+-static void
+-XGI_SetLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- if(XGI_DoLowModeTest(XGI_Pr, ModeNo, HwInfo)) {
+- XGI_Pr->SetFlag |= LowModeTests;
+- }
+-}
+-
+-static void
+-XGI_HandleCRT1(VB_DEVICE_INFO *XGI_Pr)
+-{
+- XGI_SetRegAND(XGI_Pr->P3d4, 0x53, 0xbf);
+-}
+-
+-/*********************************************/
+-/* HELPER: GetOffset */
+-/*********************************************/
+-
+-USHORT
+-XGI_New_GetOffset(VB_DEVICE_INFO *XGI_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- USHORT xres, temp, colordepth, infoflag;
+-
+- infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+- xres = XGI_Pr->RefIndex[RefreshRateTableIndex].XRes;
+-
+- colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, XGI_Pr);
+-
+- temp = xres / 16;
+- if(infoflag & InterlaceMode) temp <<= 1;
+- temp *= colordepth;
+- if(xres % 16) {
+- colordepth >>= 1;
+- temp += colordepth;
+- }
+-
+- return(temp);
+-}
+-
+-/*********************************************/
+-/* RESET VCLK */
+-/*********************************************/
+-
+-static void
+-XGI_ResetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xCF,0x20);
+- XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[1].SR2B);
+- XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[1].SR2C);
+- XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xcf,0x10);
+- XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[0].SR2B);
+- XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[0].SR2C);
+- XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
+-}
+-
+-/*********************************************/
+-/* CRTC/2 */
+-/*********************************************/
+-
+-static void
+-XGI_New_SetCRT1CRTC(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- UCHAR index;
+- USHORT temp,i,j,modeflag;
+-
+- XGI_SetRegAND(XGI_Pr->P3d4,0x11,0x7f); /* unlock cr0-7 */
+-
+- if(ModeNo <= 0x13) {
+- modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- } else {
+- modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+-
+- for(i=0,j=0;i<=7;i++,j++) {
+- XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+- }
+- for(j=0x10;i<=10;i++,j++) {
+- XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+- }
+- for(j=0x15;i<=12;i++,j++) {
+- XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+- }
+- for(j=0x0A;i<=15;i++,j++) {
+- XGI_SetReg(XGI_Pr->P3c4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
+- }
+-
+- temp = XGI_Pr->XGINEWUB_CRT1Table[index].CR[16] & 0xE0;
+- XGI_SetReg(XGI_Pr->P3c4,0x0E,temp);
+-
+- temp = ((XGI_Pr->XGINEWUB_CRT1Table[index].CR[16]) & 0x01) << 5;
+- if(modeflag & DoubleScanMode) temp |= 0x80;
+- XGI_SetRegANDOR(XGI_Pr->P3d4,0x09,0x5F,temp);
+-
+- if(XGI_Pr->ModeType > ModeVGA) XGI_SetReg(XGI_Pr->P3d4,0x14,0x4F);
+-}
+-
+-/*********************************************/
+-/* OFFSET & PITCH */
+-/*********************************************/
+-/* (partly overruled by SetPitch() in XF86) */
+-/*********************************************/
+-
+-static void
+-XGI_New_SetCRT1Offset(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwInfo)
+-{
+- USHORT temp, DisplayUnit, infoflag;
+-
+- infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+-
+- DisplayUnit = XGI_New_GetOffset(XGI_Pr,ModeNo,ModeIdIndex,
+- RefreshRateTableIndex,HwInfo);
+-
+- temp = (DisplayUnit >> 8) & 0x0f;
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,temp);
+-
+- temp = DisplayUnit & 0xFF;
+- XGI_SetReg(XGI_Pr->P3d4,0x13,temp);
+-
+- if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+-
+- DisplayUnit <<= 5;
+- temp = (DisplayUnit & 0xff00) >> 8;
+- if(DisplayUnit & 0xff) temp++;
+- temp++;
+- XGI_SetReg(XGI_Pr->P3c4,0x10,temp);
+-}
+-
+-/*********************************************/
+-/* VCLK */
+-/*********************************************/
+-
+-static void
+-XGI_New_SetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwInfo, USHORT RefreshRateTableIndex)
+-{
+- USHORT index=0, clka, clkb;
+-
+- if((XGI_Pr->VBType & VB_XGI301BLV302BLV) && (XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
+- clka = XGI_Pr->VBVCLKData[index].Part4_A;
+- clkb = XGI_Pr->VBVCLKData[index].Part4_B;
+- } else {
+- clka = XGI_Pr->VCLKData[index].SR2B;
+- clkb = XGI_Pr->VCLKData[index].SR2C;
+- }
+-
+- XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xCF);
+- XGI_SetReg(XGI_Pr->P3c4,0x2B,clka);
+- XGI_SetReg(XGI_Pr->P3c4,0x2C,clkb);
+- XGI_SetReg(XGI_Pr->P3c4,0x2D,0x01);
+-}
+-
+-/*********************************************/
+-/* MODE REGISTERS */
+-/*********************************************/
+-
+-static void
+-XGI_New_SetVCLKState(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+- USHORT ModeNo, USHORT RefreshRateTableIndex,
+- USHORT ModeIdIndex)
+-{
+- USHORT data=0, VCLK=0, index=0;
+-
+- if(ModeNo > 0x13) {
+- VCLK = XGI_Pr->VCLKData[index].CLOCK;
+- }
+-
+- if(VCLK >= 166)
+- data |= 0x0c;
+-
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x32,0xf3,data);
+-
+- if(VCLK >= 166) {
+- XGI_SetRegAND(XGI_Pr->P3c4,0x1f,0xe7);
+- }
+-
+- /* DAC speed */
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x07,0xE8,0x10);
+-}
+-
+-static void
+-XGI_New_SetCRT1ModeRegs(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+- USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
+-{
+- USHORT data,infoflag=0,modeflag;
+- USHORT resindex = 0,xres;
+-
+- if(ModeNo > 0x13) {
+- modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+- xres = XGI_Pr->ModeResInfo[resindex].HTotal;
+- } else {
+- modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- xres = XGI_Pr->StResInfo[resindex].HTotal;
+- }
+-
+- /* Disable DPMS */
+- XGI_SetRegAND(XGI_Pr->P3c4,0x1F,0x3F);
+-
+- data = 0;
+- if(ModeNo > 0x13) {
+- if(XGI_Pr->ModeType > 0x02) {
+- data |= 0x02;
+- data |= ((XGI_Pr->ModeType - ModeVGA) << 2);
+- }
+- if(infoflag & InterlaceMode) data |= 0x20;
+- }
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x06,0xC0,data);
+-
+- data = 0;
+- if(infoflag & InterlaceMode) {
+- if(xres <= 800) data = 0x0020;
+- else if(xres <= 1024) data = 0x0035;
+- else data = 0x0048;
+- }
+- XGI_SetReg(XGI_Pr->P3d4,0x19,(data & 0xFF));
+- XGI_SetRegANDOR(XGI_Pr->P3d4,0x1a,0xFC,(data >> 8));
+-
+- if(modeflag & HalfDCLK) {
+- XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x08);
+- }
+-
+- data = 0;
+- if(modeflag & LineCompareOff) data = 0x08;
+-
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0F,0xB7,data);
+- if(XGI_Pr->ModeType == ModeEGA) {
+- if(ModeNo > 0x13) {
+- XGI_SetRegOR(XGI_Pr->P3c4,0x0F,0x40);
+- }
+- }
+-
+- XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xfb);
+-
+- data = 0x60;
+- if(XGI_Pr->ModeType != ModeText) {
+- data ^= 0x60;
+- if(XGI_Pr->ModeType != ModeEGA) {
+- data ^= 0xA0;
+- }
+- }
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x21,0x1F,data);
+-
+- XGI_New_SetVCLKState(XGI_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
+-}
+-
+-/*********************************************/
+-/* LOAD DAC */
+-/*********************************************/
+-
+-extern const uint8_t XGI_MDA_DAC[];
+-extern const uint8_t XGI_CGA_DAC[];
+-extern const uint8_t XGI_EGA_DAC[];
+-extern const uint8_t XGI_VGA_DAC[];
+-
+-void
+-XGI_New_LoadDAC(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+- USHORT ModeNo, USHORT ModeIdIndex)
+-{
+- USHORT data,data2;
+- USHORT time,i,j,k,m,n,o;
+- USHORT si,di,bx,dl,al,ah,dh;
+- USHORT shiftflag;
+- XGIIOADDRESS DACAddr, DACData;
+- const uint8_t *table = NULL;
+-
+- if(ModeNo <= 0x13) {
+- data = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- } else {
+- data = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- data &= DACInfoFlag;
+- time = 64;
+- if(data == 0x00) table = XGI_MDA_DAC;
+- if(data == 0x08) table = XGI_CGA_DAC;
+- if(data == 0x10) table = XGI_EGA_DAC;
+- if(data == 0x18) {
+- time = 256;
+- table = XGI_VGA_DAC;
+- }
+- if(time == 256) j = 16;
+- else j = time;
+-
+- if( ( (XGI_Pr->VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
+- (XGI_Pr->VBType & VB_NoLCD) ) ||
+- (XGI_Pr->VBInfo & SetCRT2ToLCDA) || /* LCDA */
+- (!(XGI_Pr->SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
+- DACAddr = XGI_Pr->P3c8;
+- DACData = XGI_Pr->P3c9;
+- shiftflag = 0;
+- XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
+- } else {
+- shiftflag = 1;
+- DACAddr = XGI_Pr->Part5Port;
+- DACData = XGI_Pr->Part5Port + 1;
+- }
+-
+- XGI_SetRegByte(DACAddr,0x00);
+-
+- for(i=0; i<j; i++) {
+- data = table[i];
+- for(k=0; k<3; k++) {
+- data2 = 0;
+- if(data & 0x01) data2 = 0x2A;
+- if(data & 0x02) data2 += 0x15;
+- if(shiftflag) data2 <<= 2;
+- XGI_SetRegByte(DACData, data2);
+- data >>= 2;
+- }
+- }
+-
+- if(time == 256) {
+- for(i = 16; i < 32; i++) {
+- data = table[i];
+- if(shiftflag) data <<= 2;
+- for(k = 0; k < 3; k++) XGI_SetRegByte(DACData, data);
+- }
+- si = 32;
+- for(m = 0; m < 9; m++) {
+- di = si;
+- bx = si + 4;
+- dl = 0;
+- for(n = 0; n < 3; n++) {
+- for(o = 0; o < 5; o++) {
+- dh = table[si];
+- ah = table[di];
+- al = table[bx];
+- si++;
+- XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
+- }
+- si -= 2;
+- for(o = 0; o < 3; o++) {
+- dh = table[bx];
+- ah = table[di];
+- al = table[si];
+- si--;
+- XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
+- }
+- dl++;
+- } /* for n < 3 */
+- si += 5;
+- } /* for m < 9 */
+- }
+-}
+-
+-/*********************************************/
+-/* SET CRT1 REGISTER GROUP */
+-/*********************************************/
+-
+-static void
+-XGI_New_SetCRT1Group(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+- USHORT ModeNo, USHORT ModeIdIndex)
+-{
+- const USHORT StandTableIndex = XGI_GetModePtr(XGI_Pr->SModeIDTable,
+- XGI_Pr->ModeType,
+- ModeNo, ModeIdIndex);
+- USHORT RefreshRateTableIndex = 0;
+-
+-
+-/*
+- if(XGI_Pr->SetFlag & LowModeTests) {
+- if(XGI_Pr->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+- XGI_New_DisableBridge(XGI_Pr, HwInfo);
+- }
+- }
+-*/
+- XGI_SetSeqRegs(StandTableIndex, XGI_Pr);
+- XGI_SetMiscRegs(StandTableIndex, XGI_Pr);
+- XGI_SetCRTCRegs(StandTableIndex, XGI_Pr);
+- XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, XGI_Pr);
+- XGI_SetGRCRegs(StandTableIndex, XGI_Pr);
+- XGI_ClearExt1Regs(ModeNo, XGI_Pr);
+- XGI_ResetCRT1VCLK(XGI_Pr, HwInfo);
+-
+- XGI_Pr->SetFlag &= (~ProgrammingCRT2);
+-
+-#ifdef LINUX_XF86
+- xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+- XGI_Pr->VBType, XGI_Pr->VBInfo);
+-#endif
+-
+- if(XGI_Pr->VBInfo & SetSimuScanMode) {
+- if(XGI_Pr->VBInfo & SetInSlaveMode) {
+- XGI_Pr->SetFlag |= ProgrammingCRT2;
+- }
+- }
+-
+- if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
+- XGI_Pr->SetFlag |= ProgrammingCRT2;
+- }
+-
+- if(!(XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
+- XGI_Pr->SetFlag &= ~ProgrammingCRT2;
+- }
+-
+- if(RefreshRateTableIndex != 0xFFFF) {
+- XGI_SetSync(RefreshRateTableIndex, XGI_Pr);
+- XGI_New_SetCRT1CRTC(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+- XGI_New_SetCRT1Offset(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+- XGI_New_SetCRT1VCLK(XGI_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+- }
+-
+- XGI_New_SetCRT1ModeRegs(XGI_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
+-
+- XGI_New_LoadDAC(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
+-}
+-
+-
+-/*********************************************/
+-/* XFree86: SET SCREEN PITCH */
+-/*********************************************/
+-
+-#ifdef LINUX_XF86
+-static void
+-XGI_SetPitchCRT1(VB_DEVICE_INFO *XGI_Pr, ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- UShort HDisplay = pXGI->scrnPitch >> 3;
+-
+- XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
+-}
+-#endif
+-
+-/*********************************************/
+-/* XFree86: XGIBIOSSetMode() */
+-/* for non-Dual-Head mode */
+-/*********************************************/
+-
+-#ifdef LINUX_XF86
+-BOOLEAN
+-XGIBIOSSetMode(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+- ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- UShort ModeNo=0;
+- BOOLEAN SetModeRet = FALSE ;
+- UShort HDisplay = pXGI->scrnOffset >> 3 ;
+-
+- ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
+- if(!ModeNo) return FALSE;
+-
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
+-
+-#if XGI_USING_BIOS_SETMODE
+- PDEBUG(ErrorF("XGI_USING_BIOS_SETMODE \n"));
+- if ((pXGI->pVbe != NULL) && (pXGI->pVbe->pInt10 != NULL)) {
+- xf86Int10InfoPtr pInt = pXGI->pVbe->pInt10;
+-
+- if (xf86LoadSubModule(pScrn, "int10")) {
+- pInt->num = 0x10;
+- pInt->ax = 0x80 | ModeNo;
+-
+- /* ah = 0, set mode */
+- xf86ExecX86int10(pInt);
+- SetModeRet = ((pInt->ax & 0x7f) == ModeNo);
+- }
+- }
+- else
+-#endif
+- {
+- PDEBUG(ErrorF("XGI_USING_C_code_SETMODE \n"));
+- SetModeRet = XGISetModeNew(HwInfo, XGI_Pr, ModeNo);
+- PDEBUG(ErrorF("out_of_C_code_SETMODE \n"));
+- }
+-
+-
+- /* SetPitch: Adapt to virtual size & position */
+- if (ModeNo > 0x13) {
+- XGI_SetReg(XGI_Pr->Part1Port, 0x2f, 1); //yilin for crt2pitch it shoude modify if not colone mode
+- XGI_SetReg(XGI_Pr->Part1Port, 0x07, (HDisplay & 0xFF));
+- XGI_SetRegANDOR(XGI_Pr->Part1Port, 0x09, 0xF0, (HDisplay>>8));
+-
+- XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
+- XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
+- }
+-
+- return SetModeRet;
+-}
+-
+-/*********************************************/
+-/* XFree86: XGIBIOSSetModeCRT1() */
+-/* for Dual-Head modes */
+-/*********************************************/
+-
+-BOOLEAN
+-XGIBIOSSetModeCRT1(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
+- ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- USHORT ModeIdIndex, ModeNo=0;
+- UCHAR backupreg=0;
+- unsigned vga_info;
+- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+- UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
+-
+-
+- ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
+- if(!ModeNo) return FALSE;
+-
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "Setting standard mode 0x%x on CRT1\n", ModeNo);
+-
+-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+- vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+-#else
+- vga_info = 0x11;
+-#endif
+- XGIInitPCIetc(XGI_Pr, HwInfo);
+-
+- XGI_SetReg(XGI_Pr->P3c4,0x05,0x86);
+-
+- if (!XGI_SearchModeID(XGI_Pr->SModeIDTable, XGI_Pr->EModeIDTable,
+- vga_info, &ModeNo, &ModeIdIndex)) {
+- return FALSE;
+- }
+-
+- /* Determine VBType */
+- XGI_New_GetVBType(XGI_Pr, HwInfo);
+-
+- if (XGI_Pr->VBType & VB_XGI301BLV302BLV) {
+- backupreg = XGI_GetReg(XGI_Pr->P3d4,0x38);
+- }
+-
+- /* Get VB information (connectors, connected devices) */
+- /* (We don't care if the current mode is a CRT2 mode) */
+- XGI_SetLowModeTest(XGI_Pr, ModeNo, HwInfo);
+-
+- /* Set mode on CRT1 */
+- XGI_New_SetCRT1Group(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
+- /* SetPitch: Adapt to virtual size & position */
+- XGI_SetPitchCRT1(XGI_Pr, pScrn);
+-
+-
+- /* Reset CRT2 if changing mode on CRT1 */
+- if(IS_DUAL_HEAD(pXGI)) {
+- if(pXGIEnt->CRT2ModeNo != -1) {
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "(Re-)Setting mode for CRT2\n");
+- backupcr30 = XGI_GetReg(XGI_Pr->P3d4,0x30);
+- backupcr31 = XGI_GetReg(XGI_Pr->P3d4,0x31);
+- backupcr35 = XGI_GetReg(XGI_Pr->P3d4,0x35);
+- backupcr38 = XGI_GetReg(XGI_Pr->P3d4,0x38);
+- if(XGI_Pr->VBType & VB_XGIVB) {
+- /* Backup LUT-enable */
+- if(pXGIEnt->CRT2ModeSet) {
+- backupp40d = XGI_GetReg(XGI_Pr->Part4Port,0x0d) & 0x08;
+- }
+- }
+- if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
+- XGI_SetReg(XGI_Pr->P3d4,0x30,pXGIEnt->CRT2CR30);
+- XGI_SetReg(XGI_Pr->P3d4,0x31,pXGIEnt->CRT2CR31);
+- XGI_SetReg(XGI_Pr->P3d4,0x35,pXGIEnt->CRT2CR35);
+- XGI_SetReg(XGI_Pr->P3d4,0x38,pXGIEnt->CRT2CR38);
+- }
+-
+- XGI_SetReg(XGI_Pr->P3d4,0x30,backupcr30);
+- XGI_SetReg(XGI_Pr->P3d4,0x31,backupcr31);
+- XGI_SetReg(XGI_Pr->P3d4,0x35,backupcr35);
+- XGI_SetReg(XGI_Pr->P3d4,0x38,backupcr38);
+- if(XGI_Pr->VBType & VB_XGIVB) {
+- XGI_SetRegANDOR(XGI_Pr->Part4Port,0x0d, ~0x08, backupp40d);
+- }
+- }
+- }
+-
+- /* Warning: From here, the custom mode entries in XGI_Pr are
+- * possibly overwritten
+- */
+-
+- XGI_HandleCRT1(XGI_Pr);
+-
+- XGI_New_DisplayOn(XGI_Pr);
+- XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
+-
+- /* Backup/Set ModeNo in BIOS scratch area */
+- XGI_GetSetModeID(pScrn,ModeNo);
+-
+- return TRUE;
+-}
+-#endif /* Linux_XF86 */
++/*
++ * Mode initializing code (CRT1 section)
++ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
++ *
++ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
++ *
++ * If distributed as part of the Linux kernel, the following license terms
++ * apply:
++ *
++ * * This program is free software; you can redistribute it and/or modify
++ * * it under the terms of the GNU General Public License as published by
++ * * the Free Software Foundation; either version 2 of the named License,
++ * * or any later version.
++ * *
++ * * This program is distributed in the hope that it will be useful,
++ * * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * * GNU General Public License for more details.
++ * *
++ * * You should have received a copy of the GNU General Public License
++ * * along with this program; if not, write to the Free Software
++ * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
++ *
++ * Otherwise, the following license terms apply:
++ *
++ * * Redistribution and use in source and binary forms, with or without
++ * * modification, are permitted provided that the following conditions
++ * * are met:
++ * * 1) Redistributions of source code must retain the above copyright
++ * * notice, this list of conditions and the following disclaimer.
++ * * 2) Redistributions in binary form must reproduce the above copyright
++ * * notice, this list of conditions and the following disclaimer in the
++ * * documentation and/or other materials provided with the distribution.
++ * * 3) The name of the author may not be used to endorse or promote products
++ * * derived from this software without specific prior written permission.
++ * *
++ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
++ * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Formerly based on non-functional code-fragements for 300 series by XGI, Inc.
++ * Used by permission.
++ *
++ * TW says: This code looks awful, I know. But please don't do anything about
++ * this otherwise debugging will be hell.
++ * The code is extremely fragile as regards the different chipsets, different
++ * video bridges and combinations thereof. If anything is changed, extreme
++ * care has to be taken that that change doesn't break it for other chipsets,
++ * bridges or combinations thereof.
++ * All comments in this file are by me, regardless if they are marked TW or not.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "init.h"
++#include "vgatypes.h"
++#include "vb_def.h"
++#include "vb_setmode.h"
++
++/*********************************************/
++/* HELPER: Get ModeID */
++/*********************************************/
++/* Jong 09/18/2007; patch to GIT */
++/* VGAEngine is not used; FSTN is always FALSE */
++USHORT
++XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
++ int Depth, int LCDwidth, int LCDheight)
++{
++ USHORT ModeIndex = 0;
++
++ switch(HDisplay)
++ {
++ case 320:
++ if(VDisplay == 200)
++ ModeIndex = ModeIndex_320x200[Depth];
++ else if(VDisplay == 240)
++ {
++ ModeIndex = ModeIndex_320x240[Depth];
++ }
++ break;
++ case 400:
++ if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
++ break;
++ case 512:
++ if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
++ break;
++ case 640:
++ if(VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth];
++ else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
++ break;
++ case 720:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth];
++ else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
++ }
++ break;
++ case 768:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
++ }
++ break;
++ case 800:
++ if(VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth];
++ else if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
++ }
++ break;
++ case 848:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
++ }
++ break;
++ case 856:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
++ }
++ break;
++ case 1024:
++ if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
++ else if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth];
++ }
++ break;
++ case 1152:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth];
++ }
++ break;
++ case 1280:
++ if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
++ else if(VDisplay == 720) {
++ if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
++ ModeIndex = ModeIndex_1280x720[Depth];
++ } else if(!(VBFlags & CRT1_LCDA)) {
++ ModeIndex = ModeIndex_1280x720[Depth];
++ }
++ } else if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 960) ModeIndex = ModeIndex_1280x960[Depth];
++ else if(VDisplay == 768) {
++ ModeIndex = ModeIndex_310_1280x768[Depth];
++ }
++ }
++ break;
++ case 1360:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 768) ModeIndex = ModeIndex_1360x768[Depth];
++ }
++ break;
++ case 1400:
++ break;
++ case 1600:
++ if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
++ break;
++ case 1680:
++ break;
++ case 1920:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
++ }
++ break;
++ case 2048:
++ if(!(VBFlags & CRT1_LCDA)) {
++ if(VDisplay == 1536) {
++ ModeIndex = ModeIndex_310_2048x1536[Depth];
++ }
++ }
++ break;
++ }
++
++ return(ModeIndex);
++}
++
++/*********************************************/
++/* HELPER: SetReg, GetReg */
++/*********************************************/
++
++void
++XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data)
++{
++ outb(port,index);
++ outb(port + 1,data);
++}
++
++void
++XGI_SetRegByte(XGIIOADDRESS port, USHORT data)
++{
++ outb(port,data);
++}
++
++void
++XGI_SetRegShort(XGIIOADDRESS port, USHORT data)
++{
++ outw(port,data);
++}
++
++void
++XGI_SetRegLong(XGIIOADDRESS port, ULONG data)
++{
++ outl(port,data);
++}
++
++UCHAR
++XGI_GetReg(XGIIOADDRESS port, USHORT index)
++{
++ outb(port,index);
++ return inb(port + 1);
++}
++
++UCHAR
++XGI_GetRegByte(XGIIOADDRESS port)
++{
++ return inb(port);
++}
++
++USHORT
++XGI_GetRegShort(XGIIOADDRESS port)
++{
++ return inw(port);
++}
++
++ULONG
++XGI_GetRegLong(XGIIOADDRESS port)
++{
++ return inl(port);
++}
++
++void
++XGI_SetRegANDOR(XGIIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
++{
++ USHORT temp;
++
++ temp = XGI_GetReg(Port,Index);
++ temp = (temp & (DataAND)) | DataOR;
++ XGI_SetReg(Port,Index,temp);
++}
++
++void
++XGI_SetRegAND(XGIIOADDRESS Port,USHORT Index,USHORT DataAND)
++{
++ USHORT temp;
++
++ temp = XGI_GetReg(Port,Index);
++ temp &= DataAND;
++ XGI_SetReg(Port,Index,temp);
++}
++
++void
++XGI_SetRegOR(XGIIOADDRESS Port,USHORT Index,USHORT DataOR)
++{
++ USHORT temp;
++
++ temp = XGI_GetReg(Port,Index);
++ temp |= DataOR;
++ XGI_SetReg(Port,Index,temp);
++}
++
++/*********************************************/
++/* HELPER: DisplayOn, DisplayOff */
++/*********************************************/
++
++void
++XGI_New_DisplayOn(VB_DEVICE_INFO *XGI_Pr)
++{
++ XGI_SetRegAND(XGI_Pr->P3c4,0x01,0xDF);
++}
++
++void
++XGI_New_DisplayOff(VB_DEVICE_INFO *XGI_Pr)
++{
++ XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x20);
++}
++
++/*********************************************/
++/* HELPER: Init PCI & Engines */
++/*********************************************/
++
++static void
++XGIInitPCIetc(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
++{
++ CARD8 bForce=0x00; /* Jong 01/07/2008; force to disable 2D */
++
++ switch(HwInfo->jChipType) {
++ case XG40:
++ case XG42:
++ case XG20:
++ case XG21:
++ XGI_SetReg(XGI_Pr->P3c4,0x20,0xa1);
++ /* - Enable 2D (0x40)
++ * - Enable 3D (0x02)
++ * - Enable 3D vertex command fetch (0x10)
++ * - Enable 3D command parser (0x08)
++ * - Enable 3D G/L transformation engine (0x80)
++ */
++ XGI_SetRegOR(XGI_Pr->P3c4, 0x1E,
++ SR1E_ENABLE_3D_TRANSFORM_ENGINE
++ | SR1E_ENABLE_2D
++ | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
++ | SR1E_ENABLE_3D_COMMAND_PARSER
++ | SR1E_ENABLE_3D);
++
++ /* Jong 01/07/2008; support forcing to disable 2D engine */
++ if(HwInfo->jChipType == XG21)
++ {
++ inXGIIDXREG(XGI_Pr->P3c4, 0x3A, bForce) ;
++ bForce &= 0x40;
++
++ if(bForce != 0x00)
++ XGI_SetRegAND(XGI_Pr->P3c4,0x1E,0xBF);
++ }
++
++ break;
++ }
++}
++
++/*********************************************/
++/* HELPER: GetVBType */
++/*********************************************/
++
++void
++XGI_New_GetVBType(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
++{
++ USHORT flag=0, rev=0, nolcd=0;
++
++ XGI_Pr->VBType = 0;
++
++ flag = XGI_GetReg(XGI_Pr->Part4Port,0x00);
++PDEBUG(ErrorF("GetVBType: part4_0: %x \n",flag)); //yilin
++ if(flag > 3) return;
++
++ rev = XGI_GetReg(XGI_Pr->Part4Port,0x01);
++PDEBUG(ErrorF("GetVBType: part4_1: %x \n",rev)); //yilin
++
++ if(flag >= 2) {
++ XGI_Pr->VBType = VB_XGI302B;
++ } else if(flag == 1) {
++ if(rev >= 0xC0) {
++ XGI_Pr->VBType = VB_XGI301C;
++ } else if(rev >= 0xB0) {
++ XGI_Pr->VBType = VB_XGI301B;
++ /* Check if 30xB DH version (no LCD support, use Panel Link instead) */
++ nolcd = XGI_GetReg(XGI_Pr->Part4Port,0x23);
++ if(!(nolcd & 0x02)) XGI_Pr->VBType |= VB_NoLCD;
++ } else {
++ XGI_Pr->VBType = VB_XGI301;
++ }
++ }
++ if(XGI_Pr->VBType & (VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
++ if(rev >= 0xE0) {
++ flag = XGI_GetReg(XGI_Pr->Part4Port,0x39);
++ if(flag == 0xff) XGI_Pr->VBType = VB_XGI302LV;
++ else XGI_Pr->VBType = VB_XGI302ELV;
++ } else if(rev >= 0xD0) {
++ XGI_Pr->VBType = VB_XGI301LV;
++ }
++ }
++PDEBUG(ErrorF("GetVBType: XGI_Pr->VBType=%x \n",XGI_Pr->VBType)); //yilin
++}
++
++/*********************************************/
++/* HELPER: SearchModeID */
++/*********************************************/
++
++BOOLEAN
++XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
++ const XGI_ExtStruct *EModeIDTable,
++ unsigned char VGAINFO, USHORT *ModeNo, USHORT *ModeIdIndex)
++{
++ if (*ModeNo <= 0x13) {
++ if ((*ModeNo) <= 0x05)
++ (*ModeNo) |= 0x01;
++
++ for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
++ if (SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo))
++ break;
++
++ if (SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
++ return FALSE;
++ }
++
++ if (*ModeNo == 0x07) {
++ if (VGAINFO & 0x10)
++ (*ModeIdIndex)++; /* 400 lines */
++ /* else 350 lines */
++ }
++
++ if (*ModeNo <= 0x03) {
++ if (!(VGAINFO & 0x80))
++ (*ModeIdIndex)++;
++
++ if (VGAINFO & 0x10)
++ (*ModeIdIndex)++; /* 400 lines */
++ /* else 350 lines */
++ }
++ /* else 200 lines */
++ }
++ else {
++
++ for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
++ if (EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo))
++ break;
++
++ if (EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
++ return FALSE;
++ }
++ }
++
++ return TRUE;
++}
++
++/*********************************************/
++/* HELPER: GetModePtr */
++/*********************************************/
++
++UCHAR
++XGI_GetModePtr(const XGI_StStruct *SModeIDTable, unsigned ModeType,
++ USHORT ModeNo, USHORT ModeIdIndex)
++{
++ return (ModeNo <= 0x13)
++ ? SModeIDTable[ModeIdIndex].St_StTableIndex
++ : ((ModeType <= 0x02) ? 0x1B /* 02 -> ModeEGA */ : 0x0F);
++}
++
++
++/*********************************************/
++/* HELPER: LowModeTests */
++/*********************************************/
++
++static BOOLEAN
++XGI_DoLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
++{
++ USHORT temp,temp1,temp2;
++
++ if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
++ return(1);
++ temp = XGI_GetReg(XGI_Pr->P3d4,0x11);
++ XGI_SetRegOR(XGI_Pr->P3d4,0x11,0x80);
++ temp1 = XGI_GetReg(XGI_Pr->P3d4,0x00);
++ XGI_SetReg(XGI_Pr->P3d4,0x00,0x55);
++ temp2 = XGI_GetReg(XGI_Pr->P3d4,0x00);
++ XGI_SetReg(XGI_Pr->P3d4,0x00,temp1);
++ XGI_SetReg(XGI_Pr->P3d4,0x11,temp);
++ if (temp2 == 0x55)
++ return(0);
++ else
++ return(1);
++}
++
++static void
++XGI_SetLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
++{
++ if(XGI_DoLowModeTest(XGI_Pr, ModeNo, HwInfo)) {
++ XGI_Pr->SetFlag |= LowModeTests;
++ }
++}
++
++static void
++XGI_HandleCRT1(VB_DEVICE_INFO *XGI_Pr)
++{
++ XGI_SetRegAND(XGI_Pr->P3d4, 0x53, 0xbf);
++}
++
++/*********************************************/
++/* HELPER: GetOffset */
++/*********************************************/
++
++USHORT
++XGI_New_GetOffset(VB_DEVICE_INFO *XGI_Pr,USHORT ModeNo,USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwInfo)
++{
++ USHORT xres, temp, colordepth, infoflag;
++
++ infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ xres = XGI_Pr->RefIndex[RefreshRateTableIndex].XRes;
++
++ colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, XGI_Pr);
++
++ temp = xres / 16;
++ if(infoflag & InterlaceMode) temp <<= 1;
++ temp *= colordepth;
++ if(xres % 16) {
++ colordepth >>= 1;
++ temp += colordepth;
++ }
++
++ return(temp);
++}
++
++/*********************************************/
++/* RESET VCLK */
++/*********************************************/
++
++static void
++XGI_ResetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
++{
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xCF,0x20);
++ XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[1].SR2B);
++ XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[1].SR2C);
++ XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xcf,0x10);
++ XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[0].SR2B);
++ XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[0].SR2C);
++ XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
++}
++
++/*********************************************/
++/* CRTC/2 */
++/*********************************************/
++
++static void
++XGI_New_SetCRT1CRTC(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwInfo)
++{
++ UCHAR index;
++ USHORT temp,i,j,modeflag;
++
++ XGI_SetRegAND(XGI_Pr->P3d4,0x11,0x7f); /* unlock cr0-7 */
++
++ if(ModeNo <= 0x13) {
++ modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ } else {
++ modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++
++ for(i=0,j=0;i<=7;i++,j++) {
++ XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
++ }
++ for(j=0x10;i<=10;i++,j++) {
++ XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
++ }
++ for(j=0x15;i<=12;i++,j++) {
++ XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
++ }
++ for(j=0x0A;i<=15;i++,j++) {
++ XGI_SetReg(XGI_Pr->P3c4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
++ }
++
++ temp = XGI_Pr->XGINEWUB_CRT1Table[index].CR[16] & 0xE0;
++ XGI_SetReg(XGI_Pr->P3c4,0x0E,temp);
++
++ temp = ((XGI_Pr->XGINEWUB_CRT1Table[index].CR[16]) & 0x01) << 5;
++ if(modeflag & DoubleScanMode) temp |= 0x80;
++ XGI_SetRegANDOR(XGI_Pr->P3d4,0x09,0x5F,temp);
++
++ if(XGI_Pr->ModeType > ModeVGA) XGI_SetReg(XGI_Pr->P3d4,0x14,0x4F);
++}
++
++/*********************************************/
++/* OFFSET & PITCH */
++/*********************************************/
++/* (partly overruled by SetPitch() in XF86) */
++/*********************************************/
++
++static void
++XGI_New_SetCRT1Offset(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwInfo)
++{
++ USHORT temp, DisplayUnit, infoflag;
++
++ infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++
++ DisplayUnit = XGI_New_GetOffset(XGI_Pr,ModeNo,ModeIdIndex,
++ RefreshRateTableIndex,HwInfo);
++
++ temp = (DisplayUnit >> 8) & 0x0f;
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,temp);
++
++ temp = DisplayUnit & 0xFF;
++ XGI_SetReg(XGI_Pr->P3d4,0x13,temp);
++
++ if(infoflag & InterlaceMode) DisplayUnit >>= 1;
++
++ DisplayUnit <<= 5;
++ temp = (DisplayUnit & 0xff00) >> 8;
++ if(DisplayUnit & 0xff) temp++;
++ temp++;
++ XGI_SetReg(XGI_Pr->P3c4,0x10,temp);
++}
++
++/*********************************************/
++/* VCLK */
++/*********************************************/
++
++static void
++XGI_New_SetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwInfo, USHORT RefreshRateTableIndex)
++{
++ USHORT index=0, clka, clkb;
++
++ if((XGI_Pr->VBType & VB_XGI301BLV302BLV) && (XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
++ clka = XGI_Pr->VBVCLKData[index].Part4_A;
++ clkb = XGI_Pr->VBVCLKData[index].Part4_B;
++ } else {
++ clka = XGI_Pr->VCLKData[index].SR2B;
++ clkb = XGI_Pr->VCLKData[index].SR2C;
++ }
++
++ XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xCF);
++ XGI_SetReg(XGI_Pr->P3c4,0x2B,clka);
++ XGI_SetReg(XGI_Pr->P3c4,0x2C,clkb);
++ XGI_SetReg(XGI_Pr->P3c4,0x2D,0x01);
++}
++
++/*********************************************/
++/* MODE REGISTERS */
++/*********************************************/
++
++static void
++XGI_New_SetVCLKState(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
++ USHORT ModeNo, USHORT RefreshRateTableIndex,
++ USHORT ModeIdIndex)
++{
++ USHORT data=0, VCLK=0, index=0;
++
++ if(ModeNo > 0x13) {
++ VCLK = XGI_Pr->VCLKData[index].CLOCK;
++ }
++
++ if(VCLK >= 166)
++ data |= 0x0c;
++
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x32,0xf3,data);
++
++ if(VCLK >= 166) {
++ XGI_SetRegAND(XGI_Pr->P3c4,0x1f,0xe7);
++ }
++
++ /* DAC speed */
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x07,0xE8,0x10);
++}
++
++static void
++XGI_New_SetCRT1ModeRegs(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
++ USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
++{
++ USHORT data,infoflag=0,modeflag;
++ USHORT resindex = 0,xres;
++
++ if(ModeNo > 0x13) {
++ modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ xres = XGI_Pr->ModeResInfo[resindex].HTotal;
++ } else {
++ modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ xres = XGI_Pr->StResInfo[resindex].HTotal;
++ }
++
++ /* Disable DPMS */
++ XGI_SetRegAND(XGI_Pr->P3c4,0x1F,0x3F);
++
++ data = 0;
++ if(ModeNo > 0x13) {
++ if(XGI_Pr->ModeType > 0x02) {
++ data |= 0x02;
++ data |= ((XGI_Pr->ModeType - ModeVGA) << 2);
++ }
++ if(infoflag & InterlaceMode) data |= 0x20;
++ }
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x06,0xC0,data);
++
++ data = 0;
++ if(infoflag & InterlaceMode) {
++ if(xres <= 800) data = 0x0020;
++ else if(xres <= 1024) data = 0x0035;
++ else data = 0x0048;
++ }
++ XGI_SetReg(XGI_Pr->P3d4,0x19,(data & 0xFF));
++ XGI_SetRegANDOR(XGI_Pr->P3d4,0x1a,0xFC,(data >> 8));
++
++ if(modeflag & HalfDCLK) {
++ XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x08);
++ }
++
++ data = 0;
++ if(modeflag & LineCompareOff) data = 0x08;
++
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0F,0xB7,data);
++ if(XGI_Pr->ModeType == ModeEGA) {
++ if(ModeNo > 0x13) {
++ XGI_SetRegOR(XGI_Pr->P3c4,0x0F,0x40);
++ }
++ }
++
++ XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xfb);
++
++ data = 0x60;
++ if(XGI_Pr->ModeType != ModeText) {
++ data ^= 0x60;
++ if(XGI_Pr->ModeType != ModeEGA) {
++ data ^= 0xA0;
++ }
++ }
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x21,0x1F,data);
++
++ XGI_New_SetVCLKState(XGI_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
++}
++
++/*********************************************/
++/* LOAD DAC */
++/*********************************************/
++
++extern const uint8_t XGI_MDA_DAC[];
++extern const uint8_t XGI_CGA_DAC[];
++extern const uint8_t XGI_EGA_DAC[];
++extern const uint8_t XGI_VGA_DAC[];
++
++void
++XGI_New_LoadDAC(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
++ USHORT ModeNo, USHORT ModeIdIndex)
++{
++ USHORT data,data2;
++ USHORT time,i,j,k,m,n,o;
++ USHORT si,di,bx,dl,al,ah,dh;
++ USHORT shiftflag;
++ XGIIOADDRESS DACAddr, DACData;
++ const uint8_t *table = NULL;
++
++ if(ModeNo <= 0x13) {
++ data = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ } else {
++ data = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ data &= DACInfoFlag;
++ time = 64;
++ if(data == 0x00) table = XGI_MDA_DAC;
++ if(data == 0x08) table = XGI_CGA_DAC;
++ if(data == 0x10) table = XGI_EGA_DAC;
++ if(data == 0x18) {
++ time = 256;
++ table = XGI_VGA_DAC;
++ }
++ if(time == 256) j = 16;
++ else j = time;
++
++ if( ( (XGI_Pr->VBInfo & SetCRT2ToLCD) && /* 301B-DH LCD */
++ (XGI_Pr->VBType & VB_NoLCD) ) ||
++ (XGI_Pr->VBInfo & SetCRT2ToLCDA) || /* LCDA */
++ (!(XGI_Pr->SetFlag & ProgrammingCRT2)) ) { /* Programming CRT1 */
++ DACAddr = XGI_Pr->P3c8;
++ DACData = XGI_Pr->P3c9;
++ shiftflag = 0;
++ XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
++ } else {
++ shiftflag = 1;
++ DACAddr = XGI_Pr->Part5Port;
++ DACData = XGI_Pr->Part5Port + 1;
++ }
++
++ XGI_SetRegByte(DACAddr,0x00);
++
++ for(i=0; i<j; i++) {
++ data = table[i];
++ for(k=0; k<3; k++) {
++ data2 = 0;
++ if(data & 0x01) data2 = 0x2A;
++ if(data & 0x02) data2 += 0x15;
++ if(shiftflag) data2 <<= 2;
++ XGI_SetRegByte(DACData, data2);
++ data >>= 2;
++ }
++ }
++
++ if(time == 256) {
++ for(i = 16; i < 32; i++) {
++ data = table[i];
++ if(shiftflag) data <<= 2;
++ for(k = 0; k < 3; k++) XGI_SetRegByte(DACData, data);
++ }
++ si = 32;
++ for(m = 0; m < 9; m++) {
++ di = si;
++ bx = si + 4;
++ dl = 0;
++ for(n = 0; n < 3; n++) {
++ for(o = 0; o < 5; o++) {
++ dh = table[si];
++ ah = table[di];
++ al = table[bx];
++ si++;
++ XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
++ }
++ si -= 2;
++ for(o = 0; o < 3; o++) {
++ dh = table[bx];
++ ah = table[di];
++ al = table[si];
++ si--;
++ XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
++ }
++ dl++;
++ } /* for n < 3 */
++ si += 5;
++ } /* for m < 9 */
++ }
++}
++
++/*********************************************/
++/* SET CRT1 REGISTER GROUP */
++/*********************************************/
++
++static void
++XGI_New_SetCRT1Group(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
++ USHORT ModeNo, USHORT ModeIdIndex)
++{
++ const USHORT StandTableIndex = XGI_GetModePtr(XGI_Pr->SModeIDTable,
++ XGI_Pr->ModeType,
++ ModeNo, ModeIdIndex);
++ USHORT RefreshRateTableIndex = 0;
++
++
++/*
++ if(XGI_Pr->SetFlag & LowModeTests) {
++ if(XGI_Pr->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
++ XGI_New_DisableBridge(XGI_Pr, HwInfo);
++ }
++ }
++*/
++ XGI_SetSeqRegs(StandTableIndex, XGI_Pr);
++ XGI_SetMiscRegs(StandTableIndex, XGI_Pr);
++ XGI_SetCRTCRegs(StandTableIndex, XGI_Pr);
++ XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, XGI_Pr);
++ XGI_SetGRCRegs(StandTableIndex, XGI_Pr);
++ XGI_ClearExt1Regs(ModeNo, XGI_Pr);
++ XGI_ResetCRT1VCLK(XGI_Pr, HwInfo);
++
++ XGI_Pr->SetFlag &= (~ProgrammingCRT2);
++
++#ifdef LINUX_XF86
++ xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
++ XGI_Pr->VBType, XGI_Pr->VBInfo);
++#endif
++
++ if(XGI_Pr->VBInfo & SetSimuScanMode) {
++ if(XGI_Pr->VBInfo & SetInSlaveMode) {
++ XGI_Pr->SetFlag |= ProgrammingCRT2;
++ }
++ }
++
++ if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
++ XGI_Pr->SetFlag |= ProgrammingCRT2;
++ }
++
++ if(!(XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
++ XGI_Pr->SetFlag &= ~ProgrammingCRT2;
++ }
++
++ if(RefreshRateTableIndex != 0xFFFF) {
++ XGI_SetSync(RefreshRateTableIndex, XGI_Pr);
++ XGI_New_SetCRT1CRTC(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
++ XGI_New_SetCRT1Offset(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
++ XGI_New_SetCRT1VCLK(XGI_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
++ }
++
++ XGI_New_SetCRT1ModeRegs(XGI_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
++
++ XGI_New_LoadDAC(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
++}
++
++
++/*********************************************/
++/* XFree86: SET SCREEN PITCH */
++/*********************************************/
++
++#ifdef LINUX_XF86
++static void
++XGI_SetPitchCRT1(VB_DEVICE_INFO *XGI_Pr, ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ UShort HDisplay = pXGI->scrnPitch >> 3;
++
++ XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
++}
++#endif
++
++/*********************************************/
++/* XFree86: XGIBIOSSetMode() */
++/* for non-Dual-Head mode */
++/*********************************************/
++
++#ifdef LINUX_XF86
++BOOLEAN
++XGIBIOSSetMode(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
++ ScrnInfoPtr pScrn, DisplayModePtr mode)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ UShort ModeNo=0;
++ BOOLEAN SetModeRet = FALSE ;
++ UShort HDisplay = pXGI->scrnOffset >> 3 ;
++
++ ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
++ if(!ModeNo) return FALSE;
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
++
++#if XGI_USING_BIOS_SETMODE
++ PDEBUG(ErrorF("XGI_USING_BIOS_SETMODE \n"));
++ if ((pXGI->pVbe != NULL) && (pXGI->pVbe->pInt10 != NULL)) {
++ xf86Int10InfoPtr pInt = pXGI->pVbe->pInt10;
++
++ if (xf86LoadSubModule(pScrn, "int10")) {
++ pInt->num = 0x10;
++ pInt->ax = 0x80 | ModeNo;
++
++ /* ah = 0, set mode */
++ xf86ExecX86int10(pInt);
++ SetModeRet = ((pInt->ax & 0x7f) == ModeNo);
++ }
++ }
++ else
++#endif
++ {
++ PDEBUG(ErrorF("XGI_USING_C_code_SETMODE \n"));
++ /* Jong 08/21/2007; support external modeline in X configuration file */
++ /* ------------------------------------------------------------------ */
++ HwInfo->BPP = pScrn->bitsPerPixel;
++ HwInfo->Frequency = mode->VRefresh;
++ HwInfo->Horizontal_ACTIVE = mode->HDisplay;
++ HwInfo->Vertical_ACTIVE = mode->VDisplay;
++ HwInfo->Interlace=FALSE;
++
++ if(mode->type == M_T_USERDEF) /* custom mode */
++ {
++ HwInfo->SpecifyTiming = TRUE;
++ HwInfo->Horizontal_FP = mode->HSyncStart - mode->HDisplay; /* HSyncStart - HDisplay */
++ HwInfo->Horizontal_BP = mode->HTotal - mode->HSyncEnd; /* HTotal - HSyncEnd */
++ HwInfo->Horizontal_SYNC = mode->HSyncEnd - mode->HSyncStart; /* HSyncEnd - HSyncStart */
++ HwInfo->Vertical_FP = mode->VSyncStart - mode->VDisplay;
++ HwInfo->Vertical_BP = mode->VTotal - mode->VSyncEnd;
++ HwInfo->Vertical_SYNC = mode->VSyncEnd - mode->VSyncStart;
++ HwInfo->DCLK = mode->Clock;
++ }
++ else
++ {
++ HwInfo->SpecifyTiming = FALSE;
++ }
++ /* ------------------------------------------------------------------ */
++
++ SetModeRet = XGISetModeNew(HwInfo, XGI_Pr, ModeNo);
++ PDEBUG(ErrorF("out_of_C_code_SETMODE \n"));
++ }
++
++
++ /* SetPitch: Adapt to virtual size & position */
++ if (ModeNo > 0x13) {
++ XGI_SetReg(XGI_Pr->Part1Port, 0x2f, 1); //yilin for crt2pitch it shoude modify if not colone mode
++ XGI_SetReg(XGI_Pr->Part1Port, 0x07, (HDisplay & 0xFF));
++ XGI_SetRegANDOR(XGI_Pr->Part1Port, 0x09, 0xF0, (HDisplay>>8));
++
++ XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
++ XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
++ }
++
++ return SetModeRet;
++}
++
++/*********************************************/
++/* XFree86: XGIBIOSSetModeCRT1() */
++/* for Dual-Head modes */
++/*********************************************/
++
++BOOLEAN
++XGIBIOSSetModeCRT1(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
++ ScrnInfoPtr pScrn, DisplayModePtr mode)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ USHORT ModeIdIndex, ModeNo=0;
++ UCHAR backupreg=0;
++ unsigned vga_info;
++ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
++ UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
++
++
++ ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
++ if(!ModeNo) return FALSE;
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "Setting standard mode 0x%x on CRT1\n", ModeNo);
++
++#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
++ vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
++#else
++ vga_info = 0x11;
++#endif
++ XGIInitPCIetc(XGI_Pr, HwInfo);
++
++ XGI_SetReg(XGI_Pr->P3c4,0x05,0x86);
++
++ if (!XGI_SearchModeID(XGI_Pr->SModeIDTable, XGI_Pr->EModeIDTable,
++ vga_info, &ModeNo, &ModeIdIndex)) {
++ return FALSE;
++ }
++
++ /* Determine VBType */
++ XGI_New_GetVBType(XGI_Pr, HwInfo);
++
++ if (XGI_Pr->VBType & VB_XGI301BLV302BLV) {
++ backupreg = XGI_GetReg(XGI_Pr->P3d4,0x38);
++ }
++
++ /* Get VB information (connectors, connected devices) */
++ /* (We don't care if the current mode is a CRT2 mode) */
++ XGI_SetLowModeTest(XGI_Pr, ModeNo, HwInfo);
++
++ /* Set mode on CRT1 */
++ XGI_New_SetCRT1Group(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
++ /* SetPitch: Adapt to virtual size & position */
++ XGI_SetPitchCRT1(XGI_Pr, pScrn);
++
++
++ /* Reset CRT2 if changing mode on CRT1 */
++ if(IS_DUAL_HEAD(pXGI)) {
++ if(pXGIEnt->CRT2ModeNo != -1) {
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "(Re-)Setting mode for CRT2\n");
++ backupcr30 = XGI_GetReg(XGI_Pr->P3d4,0x30);
++ backupcr31 = XGI_GetReg(XGI_Pr->P3d4,0x31);
++ backupcr35 = XGI_GetReg(XGI_Pr->P3d4,0x35);
++ backupcr38 = XGI_GetReg(XGI_Pr->P3d4,0x38);
++ if(XGI_Pr->VBType & VB_XGIVB) {
++ /* Backup LUT-enable */
++ if(pXGIEnt->CRT2ModeSet) {
++ backupp40d = XGI_GetReg(XGI_Pr->Part4Port,0x0d) & 0x08;
++ }
++ }
++ if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
++ XGI_SetReg(XGI_Pr->P3d4,0x30,pXGIEnt->CRT2CR30);
++ XGI_SetReg(XGI_Pr->P3d4,0x31,pXGIEnt->CRT2CR31);
++ XGI_SetReg(XGI_Pr->P3d4,0x35,pXGIEnt->CRT2CR35);
++ XGI_SetReg(XGI_Pr->P3d4,0x38,pXGIEnt->CRT2CR38);
++ }
++
++ XGI_SetReg(XGI_Pr->P3d4,0x30,backupcr30);
++ XGI_SetReg(XGI_Pr->P3d4,0x31,backupcr31);
++ XGI_SetReg(XGI_Pr->P3d4,0x35,backupcr35);
++ XGI_SetReg(XGI_Pr->P3d4,0x38,backupcr38);
++ if(XGI_Pr->VBType & VB_XGIVB) {
++ XGI_SetRegANDOR(XGI_Pr->Part4Port,0x0d, ~0x08, backupp40d);
++ }
++ }
++ }
++
++ /* Warning: From here, the custom mode entries in XGI_Pr are
++ * possibly overwritten
++ */
++
++ XGI_HandleCRT1(XGI_Pr);
++
++ XGI_New_DisplayOn(XGI_Pr);
++ XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
++
++ /* Backup/Set ModeNo in BIOS scratch area */
++ XGI_GetSetModeID(pScrn,ModeNo);
++
++ return TRUE;
++}
++#endif /* Linux_XF86 */
+diff --git a/src/init.h b/src/init.h
+index 5e668dc..32f61ee 100644
+--- a/src/init.h
++++ b/src/init.h
+@@ -84,6 +84,7 @@
+ /* Mode numbers */
+ static const USHORT ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f};
+ static const USHORT ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53};
++static const USHORT ModeIndex_320x240_FSTN[] = {0x5a, 0x5b, 0x00, 0x00}; /* FSTN */
+ static const USHORT ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54};
+ static const USHORT ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c};
+ static const USHORT ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e};
+diff --git a/src/osdef.h b/src/osdef.h
+diff --git a/src/valid_mode.h b/src/valid_mode.h
+diff --git a/src/vb_def.h b/src/vb_def.h
+index ff7d15d..5f43dd5 100644
+--- a/src/vb_def.h
++++ b/src/vb_def.h
+@@ -456,6 +456,11 @@
+ #define VB_XGI301LV 0x0008
+ #define VB_XGI302LV 0x0010
+ #define VB_LVDS_NS 0x0001 /* 3rd party chip */
++
++/* Jong 10/04/2007; merge code */
++#define VB_CH7017 0x0002
++#define VB_CH7007 0x0080 /* [Billy] 07/05/03 */
++
+ /* #define VB_LVDS_SI 0x0004 */
+
+ #define ModeInfoFlag 0x0007
+@@ -973,6 +978,19 @@
+ #define CHTVVCLK26_2 0x57
+ #define CHTVVCLK39 0x58
+ #define CHTVVCLK36 0x59
++
++/* Jong 10/04/2007; merge code */
++#define CH7007TVVCLK30_2 0x00 /* [Billy] 2007/05/18 For CH7007 */
++#define CH7007TVVCLK28_1 0x01
++#define CH7007TVVCLK43_6 0x02
++#define CH7007TVVCLK26_4 0x03
++#define CH7007TVVCLK24_6 0x04
++#define CH7007TVVCLK47_8 0x05
++#define CH7007TVVCLK31_5 0x06
++#define CH7007TVVCLK26_2 0x07
++#define CH7007TVVCLK39 0x08
++#define CH7007TVVCLK36 0x09
++
+ #define RES320x200 0x00
+ #define RES320x240 0x01
+ #define RES400x300 0x02
+diff --git a/src/vb_ext.c b/src/vb_ext.c
+index fa2a4f3..e8a16ce 100644
+--- a/src/vb_ext.c
++++ b/src/vb_ext.c
+@@ -76,6 +76,25 @@ static int XGINew_Is301B(PVB_DEVICE_INFO pVBInfo)
+ return !(XGI_GetReg((XGIIOADDRESS)pVBInfo->Part4Port, 0x01) > 0x0B0);
+ }
+
++/* --------------------------------------------------------------------- */
++/* Function : XGI_Is301C */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN XGI_Is301C( PVB_DEVICE_INFO pVBInfo )
++{
++ if ( ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->Part4Port , 0x01 ) & 0xF0 ) == 0xC0 )
++ return( 1 ) ;
++
++ if ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->Part4Port , 0x01 ) >= 0xD0 )
++ {
++ if ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->Part4Port , 0x39 ) == 0xE0 )
++ return( 1 ) ;
++ }
++
++ return( 0 ) ;
++}
+
+ /* --------------------------------------------------------------------- */
+ /* Function : XGINew_Sense */
+diff --git a/src/vb_ext.h b/src/vb_ext.h
+index 3477fce..9aaf447 100644
+--- a/src/vb_ext.h
++++ b/src/vb_ext.h
+@@ -27,7 +27,34 @@
+ #ifndef _VBEXT_
+ #define _VBEXT_
+
++/* Jong 10/04/2007; merge code */
++struct DWORDREGS {
++ ULONG Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
++};
++
++/* Jong 10/04/2007; merge code */
++struct WORDREGS {
++ USHORT ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si, hi_si, di ,hi_di, bp, hi_bp;
++};
++
++/* Jong 10/04/2007; merge code */
++struct BYTEREGS {
++ UCHAR al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch, hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
++};
++
++/* Jong 10/04/2007; merge code */
++typedef union _X86_REGS {
++ struct DWORDREGS e;
++ struct WORDREGS x;
++ struct BYTEREGS h;
++} X86_REGS, *PX86_REGS;
++
+ extern void XGI_GetSenseStatus(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+
++/* Jong 10/04/2007; merge code */
++extern void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo ) ;
++extern void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo);
++extern USHORT XGINew_SenseLCD(PXGI_HW_DEVICE_INFO,PVB_DEVICE_INFO pVBInfo);
++
+ #endif
+diff --git a/src/vb_init.c b/src/vb_init.c
+index 9ba85bb..7e4ba77 100644
+--- a/src/vb_init.c
++++ b/src/vb_init.c
+@@ -1,2960 +1,3742 @@
+-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+- *
+- * All Rights Reserved.
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining
+- * a copy of this software and associated documentation files (the
+- * "Software"), to deal in the Software without restriction, including
+- * without limitation on the rights to use, copy, modify, merge,
+- * publish, distribute, sublicense, and/or sell copies of the Software,
+- * and to permit persons to whom the Software is furnished to do so,
+- * subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice (including the
+- * next paragraph) shall be included in all copies or substantial
+- * portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+- * DEALINGS IN THE SOFTWARE.
+- */
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "osdef.h"
+-#include "vgatypes.h"
+-
+-
+-#ifdef LINUX_KERNEL
+-#include <linux/version.h>
+-#include <linux/types.h>
+-#include <linux/delay.h> /* udelay */
+-#include "XGIfb.h"
+-#endif
+-
+-#include "vb_def.h"
+-#include "vb_struct.h"
+-#include "vb_setmode.h"
+-#include "vb_init.h"
+-#include "vb_ext.h"
+-
+-#ifdef LINUX_XF86
+-#include "xf86.h"
+-#include "xf86PciInfo.h"
+-#include "xgi.h"
+-#include "xgi_regs.h"
+-#endif
+-
+-#ifdef LINUX_KERNEL
+-#include <asm/io.h>
+-#include <linux/types.h>
+-#endif
+-
+-
+-
+-
+-static UCHAR XGINew_ChannelAB;
+-static UCHAR XGINew_DataBusWidth;
+-
+-USHORT XGINew_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
+- {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
+- {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
+- {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
+- {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
+- {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
+- {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
+- {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
+- {0x09,0x08,0x01,0x01,0x00}};
+-
+-static const USHORT XGINew_SDRDRAM_TYPE[13][5]=
+-{
+- { 2,12, 9,64,0x35},
+- { 1,13, 9,64,0x44},
+- { 2,12, 8,32,0x31},
+- { 2,11, 9,32,0x25},
+- { 1,12, 9,32,0x34},
+- { 1,13, 8,32,0x40},
+- { 2,11, 8,16,0x21},
+- { 1,12, 8,16,0x30},
+- { 1,11, 9,16,0x24},
+- { 1,11, 8, 8,0x20},
+- { 2, 9, 8, 4,0x01},
+- { 1,10, 8, 4,0x10},
+- { 1, 9, 8, 2,0x00}
+-};
+-
+-static const USHORT XGINew_DDRDRAM_TYPE[4][5]=
+-{
+- { 2,12, 9,64,0x35},
+- { 2,12, 8,32,0x31},
+- { 2,11, 8,16,0x21},
+- { 2, 9, 8, 4,0x01}
+-};
+-
+-static const USHORT XGINew_DDRDRAM_TYPE340[4][5]=
+-{
+- { 2,13, 9,64,0x45},
+- { 2,12, 9,32,0x35},
+- { 2,12, 8,16,0x31},
+- { 2,11, 8, 8,0x21}
+-};
+-
+-static void XGINew_SetDRAMSize_340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static void XGINew_SetDRAMSize_XG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static void XGINew_SetMemoryClock(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static void XGINew_SetDRAMDefaultRegister340(PXGI_HW_DEVICE_INFO, USHORT,
+- PVB_DEVICE_INFO);
+-static void XGINew_SetDRAMDefaultRegisterXG45(PXGI_HW_DEVICE_INFO, USHORT,
+- PVB_DEVICE_INFO);
+-static UCHAR XGINew_Get340DRAMType(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-
+-static int XGINew_SetDDRChannel(int index, UCHAR ChannelNo,
+- UCHAR XGINew_ChannelAB, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo);
+-
+-static void XGINew_SetDRAMSizingType(int index ,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-static USHORT XGINew_SetDRAMSizeReg(int index,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-
+-static int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-
+-static int XGINew_CheckRanks(int RankNo, int index,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-static int XGINew_CheckRank(int RankNo, int index,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-static int XGINew_CheckDDRRank(int RankNo, int index,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-static int XGINew_CheckDDRRanks(int RankNo, int index,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
+-
+-static int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo);
+-static int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo);
+-
+-static int XGINew_DDRSizing340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static int XGINew_DDRSizingXG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static int XGINew_SDRSizing(PVB_DEVICE_INFO);
+-static int XGINew_DDRSizing(PVB_DEVICE_INFO);
+-
+-static void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT Port, PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT Port, PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT Port, PVB_DEVICE_INFO pVBInfo);
+-
+-static void XGINew_DisableChannelInterleaving(int index,
+- const USHORT XGINew_DDRDRAM_TYPE[][5], PVB_DEVICE_INFO pVBInfo);
+-
+-static void DualChipInit(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-
+-static void XGINew_DisableRefresh(PXGI_HW_DEVICE_INFO ,PVB_DEVICE_INFO);
+-static void XGINew_EnableRefresh(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-
+-static void XGINew_Delay15us(ULONG);
+-static void SetPowerConsume(PXGI_HW_DEVICE_INFO, USHORT);
+-static void XGINew_DDR1x_MRS_XG20(USHORT, PVB_DEVICE_INFO);
+-static void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-static void XGINew_ChkSenseStatus(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
+-
+-static int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
+- PVB_DEVICE_INFO pVBInfo);
+-static int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
+- PVB_DEVICE_INFO pVBInfo);
+-static UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo);
+-static void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-
+-static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
+-static ULONG UNIROM; /* UNIROM */
+-
+-
+-#ifdef LINUX_KERNEL
+-void DelayUS(ULONG MicroSeconds)
+-{
+- udelay(MicroSeconds);
+-}
+-#endif
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGIInitNew */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN XGIInitNew(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifndef LINUX_XF86
+- USHORT Mclockdata[ 30 ] , Eclockdata[ 30 ] ;
+- UCHAR j , SR11 , SR17 = 0 , SR18 = 0 , SR19 = 0 ;
+- UCHAR CR37 = 0 , CR38 = 0 , CR79 = 0 , CR7A = 0 ,
+- CR7B = 0 , CR36 = 0 , CR78 = 0 , CR3C = 0 ,
+- CR3D = 0 , CR3E = 0 , CR3F = 0 , CR35 = 0 ;
+-#endif
+- UCHAR i , temp = 0 , temp1 ,
+- VBIOSVersion[ 5 ] ;
+- ULONG base,ChipsetID,VendorID,GraphicVendorID;
+- PUCHAR volatile pVideoMemory;
+-
+- /* ULONG j, k ; */
+-
+- PXGI_DSReg pSR ;
+-
+- ULONG Temp ;
+-
+-
+- XGINew_InitVBIOSData(HwDeviceExtension, pVBInfo);
+-
+- pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr;
+-
+-
+- Newdebugcode( 0x99 ) ;
+-
+- /* if ( pVBInfo->ROMAddr == 0 ) */
+- /* return( FALSE ) ; */
+-
+- if ( pVBInfo->FBAddr == 0 )
+- return( FALSE ) ;
+-
+- if ( pVBInfo->BaseAddr == 0 )
+- return( FALSE ) ;
+-
+- XGI_SetRegByte((XGIIOADDRESS) ( USHORT )( pVBInfo->BaseAddr + 0x12 ) , 0x67 ) ; /* 3c2 <- 67 ,ynlai */
+-
+-
+- if ( !HwDeviceExtension->bIntegratedMMEnabled )
+- return( FALSE ) ; /* alan */
+-
+-
+-
+- XGI_MemoryCopy( VBIOSVersion , HwDeviceExtension->szVBIOSVer , 4 ) ;
+-
+- VBIOSVersion[ 4 ] = 0x0 ;
+-
+-
+- /* ReadVBIOSData */
+- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+-
+- /* 1.Openkey */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x05 , 0x86 ) ;
+-
+-
+-
+- /* 2.Reset Extended register */
+-
+- for( i = 0x06 ; i < 0x20 ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+-
+- for( i = 0x21 ; i <= 0x27 ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+-
+- /* for( i = 0x06 ; i <= 0x27 ; i++ ) */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ; */
+-
+-
+- if(( HwDeviceExtension->jChipType == XG20 ) || ( HwDeviceExtension->jChipType >= XG40))
+- {
+- for( i = 0x31 ; i <= 0x3B ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+- }
+- else
+- {
+- for( i = 0x31 ; i <= 0x3D ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
+- }
+-
+- if ( HwDeviceExtension->jChipType == XG42 ) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B , 0xC0 ) ;
+-
+- /* for( i = 0x30 ; i <= 0x3F ; i++ ) */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; */
+-
+- for( i = 0x79 ; i <= 0x7C ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; /* shampoo 0208 */
+-
+-
+-
+- if ( HwDeviceExtension->jChipType == XG20 )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x97, pVBInfo->CR97);
+-
+- /* 3.SetMemoryClock */
+- if (!(pVBInfo->SoftSetting & SoftDRAMType)) {
+- if ( HwDeviceExtension->jChipType == XG20 )
+- {
+- temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
+- }
+- else if (HwDeviceExtension->jChipType == XG45)
+- {
+- temp = 0x02 ;
+- }
+- else
+- {
+- temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
+- }
+- }
+-
+-
+- if ( HwDeviceExtension->jChipType == XG20 )
+- XGINew_RAMType = temp & 0x01 ;
+- else
+- {
+- XGINew_RAMType = temp & 0x03 ; /* alan */
+- }
+-
+- /* Get DRAM type */
+- if ( HwDeviceExtension->jChipType == XG45 )
+- { }
+- else if ( HwDeviceExtension->jChipType >= XG40 )
+- XGINew_RAMType = ( int )XGINew_Get340DRAMType( HwDeviceExtension , pVBInfo) ;
+-
+- if ( UNIROM == 1 ) XGINew_RAMType = 0;
+-
+-
+- if ( HwDeviceExtension->jChipType < XG40 )
+- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+-
+- /* 4.SetDefExt1Regs begin */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, pVBInfo->SR07);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x11, 0x0F);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, pVBInfo->SR1F);
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0x20); */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
+-
+-
+- /* SR11 = 0x0F ; */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x11 , SR11 ) ; */
+-
+-
+- if ( (HwDeviceExtension->jChipType != XG20) || (HwDeviceExtension->jChipType != XG45) ) /* kuku 2004/06/25 */
+- {
+- /* Set AGP Rate */
+- temp1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B ) ;
+- temp1 &= 0x02 ;
+- if ( temp1 == 0x02 )
+- {
+- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
+- ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8000002C ) ;
+- VendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+- VendorID &= 0x0000FFFF ;
+- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8001002C ) ;
+- GraphicVendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+- GraphicVendorID &= 0x0000FFFF;
+-
+- if ( ChipsetID == 0x7301039 )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x09 ) ;
+-
+- ChipsetID &= 0x0000FFFF ;
+-
+- if ( ( ChipsetID == 0x700E ) || ( ChipsetID == 0x1022 ) || ( ChipsetID == 0x1106 ) || ( ChipsetID == 0x10DE ) )
+- {
+- if ( ChipsetID == 0x1106 )
+- {
+- if ( ( VendorID == 0x1019 ) && ( GraphicVendorID == 0x1019 ) )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0D ) ;
+- else
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
+- }
+- else
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
+- }
+- }
+-
+- if ( HwDeviceExtension->jChipType >= XG40 )
+- {
+- /* Set AGP customize registers (in SetDefAGPRegs) Start */
+- for( i = 0x47 ; i <= 0x4C ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ i - 0x47 ] ) ;
+-
+- for( i = 0x70 ; i <= 0x71 ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 6 + i - 0x70 ] ) ;
+-
+- for( i = 0x74 ; i <= 0x77 ; i++ )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 8 + i - 0x74 ] ) ;
+- /* Set AGP customize registers (in SetDefAGPRegs) End */
+- /*[Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
+- XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
+- ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
+- if ( ChipsetID == 0x25308086 )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x77 , 0xF0 ) ;
+-
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x50 , 0 , &Temp ) ; /* Get */
+- Temp >>= 20 ;
+- Temp &= 0xF ;
+-
+- if ( Temp == 1 )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , 0x20 ) ; /* CR48 */
+- }
+-
+- if ( HwDeviceExtension->jChipType < XG40 )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x49 , pVBInfo->CR49[ 0 ] ) ;
+- } /* != XG20 */
+-
+- /* Set PCI */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x23, pVBInfo->SR23);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x24, pVBInfo->SR24);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
+-
+- if ( HwDeviceExtension->jChipType != XG20 ) /* kuku 2004/06/25 */
+- {
+- /* Set VB */
+- XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ; /* alan, disable VideoCapture */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , 0x00 ) ;
+- temp1 = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7B ) ; /* chk if BCLK>=100MHz */
+- temp = ( UCHAR )( ( temp1 >> 4 ) & 0x0F ) ;
+-
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02,
+- pVBInfo->CRT2Data_1_2);
+-
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x2E , 0x08 ) ; /* use VB */
+- } /* != XG20 */
+-
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x27 , 0x1F ) ;
+-
+- /* Not DDR */
+- if ((HwDeviceExtension->jChipType == XG42)
+- && XGINew_Get340DRAMType(HwDeviceExtension, pVBInfo) != 0) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, (pVBInfo->SR31 & 0x3F) | 0x40);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, (pVBInfo->SR32 & 0xFC) | 0x01);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, pVBInfo->SR31);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, pVBInfo->SR32);
+- }
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x33, pVBInfo->SR33);
+-
+-
+-
+- if ( HwDeviceExtension->jChipType >= XG40 )
+- SetPowerConsume ( HwDeviceExtension , pVBInfo->P3c4);
+-
+- if ( HwDeviceExtension->jChipType != XG20 ) /* kuku 2004/06/25 */
+- {
+- if ( XGI_BridgeIsOn( pVBInfo ) == 1 )
+- {
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0x1C);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, pVBInfo->CRT2Data_4_D);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, pVBInfo->CRT2Data_4_E);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, pVBInfo->CRT2Data_4_10);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0F, 0x3F);
+- }
+-
+- XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
+- }
+- } /* != XG20 */
+-
+- if ( HwDeviceExtension->jChipType < XG40 )
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x83 , 0x00 ) ;
+-
+-
+-
+- if ( HwDeviceExtension->jChipType >= XG40 )
+- {
+- if (HwDeviceExtension->jChipType == XG45)
+- XGINew_SetDRAMDefaultRegisterXG45( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
+- else
+- XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
+-
+- if ( HwDeviceExtension->bSkipDramSizing == TRUE )
+- {
+- pSR = HwDeviceExtension->pSR ;
+- if ( pSR!=NULL )
+- {
+- while( pSR->jIdx != 0xFF )
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , pSR->jIdx , pSR->jVal ) ;
+- pSR++ ;
+- }
+- }
+- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
+- } /* SkipDramSizing */
+- else
+- {
+-/* if ( HwDeviceExtension->jChipType == XG20 )
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , pVBInfo->SR15[0][XGINew_RAMType] ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , pVBInfo->SR15[1][XGINew_RAMType] ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x20 , 0x20 ) ;
+- }
+- else*/
+- if ( HwDeviceExtension->jChipType == XG45 )
+- XGINew_SetDRAMSize_XG45( HwDeviceExtension , pVBInfo) ;
+- else
+- XGINew_SetDRAMSize_340( HwDeviceExtension , pVBInfo) ;
+- }
+- } /* XG40 */
+-
+-
+-
+-
+- /* SetDefExt2Regs begin */
+-/*
+- AGP = 1 ;
+- temp =( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
+- temp &= 0x30 ;
+- if ( temp == 0x30 )
+- AGP = 0 ;
+-
+- if ( AGP == 0 )
+- pVBInfo->SR21 &= 0xEF ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , pVBInfo->SR21 ) ;
+- if ( AGP == 1 )
+- pVBInfo->SR22 &= 0x20;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x22 , pVBInfo->SR22 ) ;
+-*/
+-
+- base = 0x80000000;
+- XGI_SetRegLong(0xcf8, base);
+- Temp = (XGI_GetRegLong(0xcfc) & 0x0000FFFF);
+- if (Temp == 0x1039) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22 & 0xFE);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22);
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21, pVBInfo->SR21);
+-
+- if ( HwDeviceExtension->jChipType == XG40 ) /* Initialize seconary chip */
+- {
+- if ( CheckDualChip(pVBInfo) )
+- DualChipInit( HwDeviceExtension , pVBInfo) ;
+- /* SetDefExt2Regs end */
+- }
+-
+- if ( HwDeviceExtension->bSkipSense == FALSE )
+- {
+- XGI_SenseCRT1(pVBInfo) ;
+- /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
+- XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
+- }
+-
+- XGINew_ChkSenseStatus ( HwDeviceExtension , pVBInfo ) ;
+- XGINew_SetModeScratch ( HwDeviceExtension , pVBInfo ) ;
+-
+- Newdebugcode( 0x88 ) ;
+-
+- /* Johnson@062403. To save time for power management. */
+- /* DelayMS(1000); */
+- /* ~Johnson@062403. */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , 0x28 ) ; //0207 temp */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x36 , 0x02 ) ; //0207 temp */
+-
+- return( TRUE ) ;
+-} /* end of init */
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : DualChipInit */
+-/* Input : */
+-/* Output : */
+-/* Description : Initialize the secondary chip. */
+-/* --------------------------------------------------------------------- */
+-void DualChipInit( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifdef LINUX_XF86
+- USHORT BaseAddr2nd = (USHORT)(ULONG)HwDeviceExtension->pj2ndIOAddress ;
+-#else
+- USHORT BaseAddr2nd = (USHORT)HwDeviceExtension->pj2ndIOAddress ;
+-#endif
+- USHORT XGINew_P3C3 = pVBInfo->BaseAddr + VIDEO_SUBSYSTEM_ENABLE_PORT ;
+- USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT ;
+- USHORT XGINew_2ndP3C3 = BaseAddr2nd + VIDEO_SUBSYSTEM_ENABLE_PORT ;
+- USHORT XGINew_2ndP3D4 = BaseAddr2nd + CRTC_ADDRESS_PORT_COLOR ;
+- USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT ;
+- USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT ;
+- ULONG Temp ;
+- UCHAR tempal , i ;
+-
+- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+- pVBInfo->BaseAddr = (USHORT)HwDeviceExtension->pjIOAddress ;
+- /* Programming Congiguration Space in Secondary Chip */
+- /* set CRA1 D[6] = 1 */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0xBF , 0x40 ) ;
+-
+- /* Write 2nd Chip Configuration Info into Configuration Space */
+- /* Command CNFG04 */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND , 0 , &Temp ) ; /* Get */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND + 0x80 , 1 , &Temp ) ; /* Set */
+- /* Latency Timer CNFG0C */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c , 0 , &Temp ) ; /* Get */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c + 0x80 , 1 , &Temp ) ; /* Set */
+- /* Linear space */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 , 0 , &Temp ) ; /* Get */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 + 0x80 , 1 , &Temp ) ; /* Set */
+- /* MMIO space */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 , 0 , &Temp ) ; /* Get */
+- Temp += 0x40000;
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 + 0x80 , 1 , &Temp ) ; /* Set */
+- /* Relocated IO space */
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 , 0 , &Temp ) ; /* Get */
+- Temp += 0x80;
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 + 0x80 , 1 , &Temp ) ; /* Set */
+- /* Miscellaneous reg(input port 3cch,output port 3c2h) */
+- tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC ) ; /* 3cc */
+- XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2 , tempal ) ;
+- /* VGA enable reg(port 3C3h) */
+- tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3C3 ) ; /* 3c3 */
+- XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C3 , tempal ) ;
+- SetPowerConsume ( HwDeviceExtension , XGINew_2ndP3D4);
+- /* ----- CRA0=42, CRA1=81, CRA2=60, CRA3=20, CRA4=50, CRA5=40, CRA8=88 -----// */
+- /* ----- CRA9=10, CRAA=80, CRAB=01, CRAC=F1, CRAE=80, CRAF=45, CRB7=24 -----// */
+- /* primary chip */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA0 , 0x72 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0x81 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA2 , 0x60 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA3 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA4 , 0x50 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA5 , 0x40 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA8 , 0x88 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA9 , 0x10 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAA , 0x80 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAB , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAC , 0xF1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAE , 0x80 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAF , 0x45 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xB7 , 0x24 ) ;
+-
+- /* secondary chip */
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA0 , 0x72 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA1 , 0x81 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA2 , 0x60 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA3 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA4 , 0x50 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA5 , 0x40 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA8 , 0x88 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA9 , 0x10 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAA , 0x80 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAB , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAC , 0xF1 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAE , 0x80 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAF , 0x45 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xB7 , 0x24 ) ;
+-
+- /* 06/20/2003 [christine] CRT threshold setting request */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x78 , 0x40 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x79 , 0x0C ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7A , 0x34 ) ;
+-
+- /* OpenKey in 2nd chip */
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x86 ) ;
+-
+- /* Set PCI registers */
+- tempal = (UCHAR)XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x06 ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x06 , tempal ) ;
+-
+- for( i = 0x20 ; i <= 0x25 ; i++ )
+- {
+- tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
+- }
+- for(i = 0x31; i <= 0x32; i++ )
+- {
+- tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
+- }
+- XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , XGINew_2ndP3D4 , pVBInfo) ;
+-
+- for(i = 0x13; i <= 0x14; i++ )
+- {
+- tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
+- }
+-
+- /* Close key in 2nd chip */
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x00 ) ;
+-}
+-
+-
+-
+-
+-/* ============== alan ====================== */
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_Get340DRAMType */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-UCHAR XGINew_Get340DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR data ;
+-
+- if ( HwDeviceExtension->jChipType != XG20 )
+- {
+- if (pVBInfo->SoftSetting & SoftDRAMType) {
+- return (pVBInfo->SoftSetting & 0x07);
+- }
+- else
+- {
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ;
+-
+- if ( data == 0 )
+- data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) & 0x02 ) >> 1 ;
+-
+- return( data ) ;
+- }
+- }
+- else
+- {
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) & 0x01 ;
+-
+- if ( data == 1 )
+- data ++ ;
+-
+- return( data );
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_Delay15us */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-/*
+-void XGINew_Delay15us(ULONG ulMicrsoSec)
+-{
+-}
+-*/
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SDR_MRS */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ;
+- data &= 0x3F ; /* SR16 D7=0,D6=0 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) low */
+- /* XGINew_Delay15us( 0x100 ) ; */
+- data |= 0x80 ; /* SR16 D7=1,D6=0 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) high */
+- /* XGINew_Delay15us( 0x100 ) ; */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR1x_MRS_340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
+- if ( HwDeviceExtension->jChipType == XG42 ) /* XG42 BA0 & BA1 layout change */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+- else
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+-
+- /* Samsung F Die */
+- if (pVBInfo->DRAMTypeDefinition != 0x0C) {
+- DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+- if ( HwDeviceExtension->jChipType == XG42 )
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+- else
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- }
+-
+- DelayUS( 60 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+-
+- if (HwDeviceExtension->jChipType == XG45)
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ; /*TSop DRAM DLL pin jump to A9*/
+- else
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
+-
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
+- DelayUS( 1000 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
+- DelayUS( 500 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR2x_MRS_340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+- if ( HwDeviceExtension->jChipType == XG42 ) /*XG42 BA0 & BA1 layout change*/
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+- else
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+-
+- /* Samsung F Die */
+- if (pVBInfo->DRAMTypeDefinition != 0x0C) {
+- DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+- if ( HwDeviceExtension->jChipType == XG42 )
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+- else
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- }
+-
+- DelayUS( 60 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
+- DelayUS( 1000 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
+- DelayUS( 500 ) ;
+- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR2_MRS_340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT P3d4 = P3c4 + 0x10 ;
+- UCHAR data ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , 0x64 ) ; /* SR28 */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , 0x63 ) ; /* SR29 */
+- DelayUS( 200 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- DelayUS( 2 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
+-
+- if( P3c4 != pVBInfo->P3c4 )
+- {
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , data ) ; /* SR28 */
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , data ) ; /* SR29 */
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2A , data ) ; /* SR2A */
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2e , data ) ; /* SR2E */
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2f , data ) ; /* SR2F */
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x30 , data ) ; /* SR30 */
+- }
+- else
+- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+-
+- DelayUS( 1000 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- DelayUS( 1 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
+- DelayUS( 5) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
+- DelayUS( 5 ) ;
+- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x72 ) ; */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x06 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
+- DelayUS( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR1x_DefaultRegister */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT Port, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT P3d4 = Port ,
+- P3c4 = Port - 0x10 ;
+-#ifndef LINUX_XF86
+- UCHAR data ;
+-#endif
+- if ( HwDeviceExtension->jChipType == XG20 )
+- {
+- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+-
+- XGINew_DDR1x_MRS_XG20( P3c4 , pVBInfo) ;
+- }
+- else
+- {
+- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+-
+- switch( HwDeviceExtension->jChipType )
+- {
+- case XG41:
+- case XG42:
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+- break ;
+- default:
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+- break ;
+- }
+- if (HwDeviceExtension->jChipType != XG45)
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+- XGINew_DDR1x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR2x_DefaultRegister */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT Port, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT P3d4 = Port ,
+- P3c4 = Port - 0x10 ;
+-
+-#ifndef LINUX_XF86
+- UCHAR data ;
+-#endif
+-
+- XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
+-
+- /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
+- switch( HwDeviceExtension->jChipType )
+- {
+- case XG41:
+- case XG42:
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+- break ;
+- default:
+- /* keep following setting sequence, each setting in the same reg insert idle */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+- }
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ;
+- if ( HwDeviceExtension->jChipType == XG42 )
+- {
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+- }
+- else
+- {
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
+- }
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+-
+- XGINew_DDR2x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR2_DefaultRegister */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT Port, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT P3d4 = Port ,
+- P3c4 = Port - 0x10 ;
+-
+- /* keep following setting sequence, each setting in the same reg insert idle */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+- XGINew_DDR2_MRS_340( HwDeviceExtension , P3c4, pVBInfo ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMDefaultRegister340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR temp , temp1 , temp2 , temp3 ,
+- i , j , k ;
+-
+- USHORT P3d4 = Port ,
+- P3c4 = Port - 0x10 ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
+-
+- temp2 = 0 ;
+- for( i = 0 ; i < 4 ; i++ )
+- {
+- temp = pVBInfo->CR6B[ XGINew_RAMType ][ i ] ; /* CR6B DQS fine tune delay */
+- for( j = 0 ; j < 4 ; j++ )
+- {
+- temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp2 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6B ) ; /* Insert read command for delay */
+- temp2 &= 0xF0 ;
+- temp2 += 0x10 ;
+- }
+- }
+-
+- temp2 = 0 ;
+- for( i = 0 ; i < 4 ; i++ )
+- {
+- temp = pVBInfo->CR6E[ XGINew_RAMType ][ i ] ; /* CR6E DQM fine tune delay */
+- for( j = 0 ; j < 4 ; j++ )
+- {
+- temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , temp2 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6E ) ; /* Insert read command for delay */
+- temp2 &= 0xF0 ;
+- temp2 += 0x10 ;
+- }
+- }
+-
+- temp3 = 0 ;
+- for( k = 0 ; k < 4 ; k++ )
+- {
+- XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x6E , 0xFC , temp3 ) ; /* CR6E_D[1:0] select channel */
+- temp2 = 0 ;
+- for( i = 0 ; i < 8 ; i++ )
+- {
+- temp = pVBInfo->CR6F[ XGINew_RAMType ][ 8 * k + i ] ; /* CR6F DQ fine tune delay */
+- for( j = 0 ; j < 4 ; j++ )
+- {
+- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , temp2 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6F ) ; /* Insert read command for delay */
+- temp2 &= 0xF8 ;
+- temp2 += 0x08 ;
+- }
+- }
+- temp3 += 0x01 ;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
+-
+- temp2 = 0x80 ;
+- temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
+- for( j = 0 ; j < 4 ; j++ )
+- {
+- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
+- temp2 &= 0xF0 ;
+- temp2 += 0x10 ;
+- }
+-
+- temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
+- temp1 = temp & 0x03 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+-
+- temp = pVBInfo->CR40[ 3 ][ XGINew_RAMType ] ;
+- temp1 = temp & 0x0F ;
+- temp2 = ( temp >> 4 ) & 0x07 ;
+- temp3 = temp & 0x80 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , temp1 ) ; /* CR45 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , temp2 ) ; /* CR99 */
+- XGI_SetRegOR((XGIIOADDRESS) P3d4 , 0x40 , temp3 ) ; /* CR40_D[7] */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , pVBInfo->CR40[ 0 ][ XGINew_RAMType ] ) ; /* CR41 */
+-
+- for( j = 0 ; j <= 6 ; j++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
+-
+- for( j = 0 ; j <= 2 ; j++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
+-
+- for( j = 0 ; j < 2 ; j++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
+-
+- if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
+- XGI_SetReg((XGIIOADDRESS) P3c4, 0x1A, 0x87); /* SR1A */
+-
+- temp = XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) ;
+- if( temp == 0 )
+- XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+- else if ( temp == 0x02 )
+- XGINew_DDR2x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+- else
+- XGINew_DDR2_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+-}
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMDefaultRegisterXG45 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SetDRAMDefaultRegisterXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR temp , temp1 , temp2 ,
+- i , j , k ;
+-
+- USHORT P3d4 = Port ,
+- P3c4 = Port - 0x10 ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , pVBInfo->XG45CR6E[ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , pVBInfo->XG45CR6F[ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
+-
+- temp = 0x00 ;
+- for ( j = 0 ; j < 24 ; j ++ )
+- {
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp );
+- temp += 0x08 ;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
+-
+- temp2 = 0x80 ;
+- temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
+- for( j = 0 ; j < 4 ; j++ )
+- {
+- temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+- XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
+- temp2 &= 0xF0 ;
+- temp2 += 0x10 ;
+- }
+-
+- temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
+- temp1 = temp & 0x03 ;
+- temp2 |= temp1 ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
+-
+- temp = 0x00 ;
+- for ( j = 0 ; j < 3 ; j ++ )
+- {
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x40 , temp );
+- temp += 0x40 ;
+- }
+-
+- temp = 0x00 ;
+- for ( j = 0 ; j < 24 ; j ++ )
+- {
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , temp );
+- temp += 0x08 ;
+- }
+-
+- temp = 0x00 ;
+- for ( j = 0 ; j < 24 ; j ++ )
+- {
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x42 , temp );
+- temp += 0x08 ;
+- }
+-
+- for ( k = 0 ; k < 2 ; k ++ )
+- {
+- XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x04 , k * 0x04 );
+-
+- for ( i = 0 ; i < 3 ; i ++ )
+- {
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x03 , i * 0x01 );
+-
+- for ( j = 0 ; j < 32 ; j ++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x44 , j * 0x08 );
+- }
+- }
+-
+- for ( j = 0 ; j < 3 ; j ++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , j * 0x08 ) ; /* CR45 */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x84 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , 0x22 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
+-
+- for( j = 0 ; j <= 6 ; j++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
+-
+- for( j = 0 ; j <= 2 ; j++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0xC8 , 0x04 ) ;
+-
+- for( j = 0 ; j < 2 ; j++ )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x40 ) ;
+-
+- if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
+- XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
+- XGI_SetReg((XGIIOADDRESS) P3d4, 0x8D, 0x87); /* CR8D */
+-
+- XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1A , 0x87 ) ; /* SR1A */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+-}
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR_MRS */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+- PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+-
+- /* SR16 <- 1F,DF,2F,AF */
+- /* yriver modified SR16 <- 0F,DF,0F,AF */
+- /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
+- data = pVideoMemory[ 0xFB ] ;
+- /* data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ; */
+-
+- data &= 0x0F ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data |= 0xC0 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data &= 0x0F ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data |= 0x80 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data &= 0x0F ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data |= 0xD0 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data &= 0x0F ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+- data |= 0xA0 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
+-/*
+- else {
+- data &= 0x0F;
+- data |= 0x10;
+- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+-
+- if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
+- {
+- data &= 0x0F;
+- }
+-
+- data |= 0xC0;
+- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+-
+-
+- data &= 0x0F;
+- data |= 0x20;
+- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+- if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
+- {
+- data &= 0x0F;
+- }
+-
+- data |= 0x80;
+- XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
+- }
+-*/
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMSize_340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+- XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /* disable read cache */
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
+- data |= 0x20 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; /* Turn OFF Display */
+-
+- XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
+-
+- data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /* enable read cache */
+-}
+-
+-
+-/*--------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMSize_XG45 */
+-/*Input : */
+-/*Output : */
+-/*Description : */
+-/*--------------------------------------------------------------------- */
+-void XGINew_SetDRAMSize_XG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+- XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /*disable read cache*/
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
+- data |= 0x20 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; /*Turn OFF Display*/
+-
+- XGINew_DDRSizingXG45( HwDeviceExtension, pVBInfo ) ;
+-
+- data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /*enable read cache*/
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMModeRegister340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-
+-void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR data ;
+-
+- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+-
+- if (HwDeviceExtension->jChipType == XG45)
+- XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+- else
+- {
+- if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
+- {
+- data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ) >> 1 ;
+- if ( data == 0x01 )
+- XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+- else
+- XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+- }
+- else
+- XGINew_DDR2_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DisableRefresh */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B ) ;
+- data &= 0xF8 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , data ) ;
+-
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_EnableRefresh */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+-{
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
+-
+-
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DisableChannelInterleaving */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DisableChannelInterleaving(int index,
+- const USHORT XGINew_DDRDRAM_TYPE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
+- data &= 0x1F ;
+-
+- switch( XGINew_DDRDRAM_TYPE[ index ][ 3 ] )
+- {
+- case 64:
+- data |= 0 ;
+- break ;
+- case 32:
+- data |= 0x20 ;
+- break ;
+- case 16:
+- data |= 0x40 ;
+- break ;
+- case 4:
+- data |= 0x60 ;
+- break ;
+- default:
+- break ;
+- }
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMSizingType */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SetDRAMSizingType(int index , const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+-
+- data = DRAMTYPE_TABLE[ index ][ 4 ] ;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
+- /* should delay 50 ns */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetRank */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
+- const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+- int RankSize ;
+-
+- if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
+- return 0 ;
+-
+- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] / 2 * XGINew_DataBusWidth / 32 ;
+-
+- if ( ( RankNo * RankSize ) <= 128 )
+- {
+- data = 0 ;
+-
+- while( ( RankSize >>= 1 ) > 0 )
+- {
+- data += 0x10 ;
+- }
+- data |= ( RankNo - 1 ) << 2 ;
+- data |= ( XGINew_DataBusWidth / 64 ) & 2 ;
+- data |= XGINew_ChannelAB ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
+- /* should delay */
+- XGINew_SDR_MRS( pVBInfo ) ;
+- return( 1 ) ;
+- }
+- else
+- return( 0 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDDRChannel */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_SetDDRChannel(int index, UCHAR ChannelNo, UCHAR XGINew_ChannelAB,
+- const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data ;
+- int RankSize ;
+-
+- RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
+- /* RankSize = DRAMTYPE_TABLE[ index ][ 3 ] ; */
+- if ( ChannelNo * RankSize <= 128 )
+- {
+- data = 0 ;
+- while( ( RankSize >>= 1 ) > 0 )
+- {
+- data += 0x10 ;
+- }
+-
+- if ( ChannelNo == 2 )
+- data |= 0x0C ;
+-
+- data |= ( XGINew_DataBusWidth / 32 ) & 2 ;
+- data |= XGINew_ChannelAB ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
+- /* should delay */
+- XGINew_DDR_MRS( pVBInfo ) ;
+- return( 1 ) ;
+- }
+- else
+- return( 0 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckColumn */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- ULONG Increment , Position ;
+-
+- /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
+- Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
+-
+- for( i = 0 , Position = 0 ; i < 2 ; i++ )
+- {
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+- Position += Increment ;
+- }
+-
+- for( i = 0 , Position = 0 ; i < 2 ; i++ )
+- {
+- /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+- Position += Increment ;
+- }
+- return( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckBanks */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- ULONG Increment , Position ;
+-
+- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
+-
+- for( i = 0 , Position = 0 ; i < 4 ; i++ )
+- {
+- /* pVBInfo->FBAddr[ Position ] = Position ; */
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+- Position += Increment ;
+- }
+-
+- for( i = 0 , Position = 0 ; i < 4 ; i++ )
+- {
+- /* if (pVBInfo->FBAddr[ Position ] != Position ) */
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+- Position += Increment ;
+- }
+- return( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckRank */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_CheckRank(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- ULONG Increment , Position ;
+-
+- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
+- DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
+-
+- for( i = 0 , Position = 0 ; i < 2 ; i++ )
+- {
+- /* pVBInfo->FBAddr[ Position ] = Position ; */
+- /* *( ( PULONG )( pVBInfo->FBAddr ) ) = Position ; */
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+- Position += Increment ;
+- }
+-
+- for( i = 0 , Position = 0 ; i < 2 ; i++ )
+- {
+- /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
+- /* if ( ( *( PULONG )( pVBInfo->FBAddr ) ) != Position ) */
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+- Position += Increment ;
+- }
+- return( 1 );
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckDDRRank */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_CheckDDRRank(int RankNo, int index,
+- const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- ULONG Increment , Position ;
+- USHORT data ;
+-
+- Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
+- DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
+-
+- Increment += Increment / 2 ;
+-
+- Position = 0;
+- *( ( PULONG )( pVBInfo->FBAddr + Position + 0 ) ) = 0x01234567 ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position + 1 ) ) = 0x456789AB ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position + 2 ) ) = 0x55555555 ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position + 3 ) ) = 0x55555555 ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position + 4 ) ) = 0xAAAAAAAA ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position + 5 ) ) = 0xAAAAAAAA ;
+-
+- if ( ( *( PULONG )( pVBInfo->FBAddr + 1 ) ) == 0x456789AB )
+- return( 1 ) ;
+-
+- if ( ( *( PULONG )( pVBInfo->FBAddr + 0 ) ) == 0x01234567 )
+- return( 0 ) ;
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) ;
+- data &= 0xF3 ;
+- data |= 0x0E ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
+- data += 0x20 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
+-
+- return( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckRanks */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_CheckRanks(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int r ;
+-
+- for( r = RankNo ; r >= 1 ; r-- )
+- {
+- if ( !XGINew_CheckRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
+- return( 0 ) ;
+- }
+-
+- if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
+- return( 0 ) ;
+-
+- if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
+- return( 0 ) ;
+-
+- return( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckDDRRanks */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_CheckDDRRanks(int RankNo, int index,
+- const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int r ;
+-
+- for( r = RankNo ; r >= 1 ; r-- )
+- {
+- if ( !XGINew_CheckDDRRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
+- return( 0 ) ;
+- }
+-
+- if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
+- return( 0 ) ;
+-
+- if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
+- return( 0 ) ;
+-
+- return( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- UCHAR j ;
+-
+- for( i = 0 ; i < 13 ; i++ )
+- {
+- XGINew_SetDRAMSizingType( i , XGINew_SDRDRAM_TYPE , pVBInfo) ;
+-
+- for( j = 2 ; j > 0 ; j-- )
+- {
+- if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_SDRDRAM_TYPE , pVBInfo) )
+- continue ;
+- else
+- {
+- if ( XGINew_CheckRanks( j , i , XGINew_SDRDRAM_TYPE, pVBInfo) )
+- return( 1 ) ;
+- }
+- }
+- }
+- return( 0 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMSizeReg */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT XGINew_SetDRAMSizeReg(int index, const USHORT DRAMTYPE_TABLE[][5],
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data = 0 , memsize = 0 ;
+- int RankSize ;
+- UCHAR ChannelNo ;
+-
+- RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 ) ;
+- data &= 0x80 ;
+-
+- if ( data == 0x80 )
+- RankSize *= 2 ;
+-
+- data = 0 ;
+-
+- if( XGINew_ChannelAB == 3 )
+- ChannelNo = 4 ;
+- else
+- ChannelNo = XGINew_ChannelAB ;
+-
+- if ( ChannelNo * RankSize <= 256 )
+- {
+- while( ( RankSize >>= 1 ) > 0 )
+- {
+- data += 0x10 ;
+- }
+-
+- memsize = data >> 4 ;
+-
+- /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
+-
+- /* data |= XGINew_ChannelAB << 2 ; */
+- /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ; */
+-
+- /* should delay */
+- /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
+- }
+- return( memsize ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_ReadWriteRest */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- ULONG Position = 0 ;
+-
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+-
+- for( i = StartAddr ; i <= StopAddr ; i++ )
+- {
+- Position = 1 << i ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+- }
+-
+- DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+-
+- Position = 0 ;
+-
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+-
+- for( i = StartAddr ; i <= StopAddr ; i++ )
+- {
+- Position = 1 << i ;
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+- }
+- return( 1 ) ;
+-}
+-
+-
+-/*--------------------------------------------------------------------- */
+-/* Function : XGI45New_ReadWriteRest */
+-/* Input : */
+-/* Output : */
+-/* Description : return 0 : fail, 1 : pass */
+-/*--------------------------------------------------------------------- */
+-int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- ULONG Position = 0 ;
+-
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+-
+- for( i = StartAddr ; i <= StopAddr ; i++ )
+- {
+- Position = 1 << i ;
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+- }
+-
+- if ( XGINew_ChannelAB == 4 )
+- {
+- Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
+- *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
+- }
+-
+- DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+-
+- Position = 0 ;
+-
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+-
+- for( i = StartAddr ; i <= StopAddr ; i++ )
+- {
+- Position = 1 << i ;
+- if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
+- return( 0 ) ;
+- }
+-
+- if ( XGINew_ChannelAB == 4 )
+- {
+- Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
+- if( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position );
+- return( 0 ) ;
+- }
+- return( 1 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckFrequence */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR data ;
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
+-
+- if ( ( data & 0x10 ) == 0 )
+- {
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) ;
+- data = ( data & 0x02 ) >> 1 ;
+- return( data ) ;
+- }
+- else
+- return( data & 0x01 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_CheckChannel */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR i, data ;
+-
+- switch( HwDeviceExtension->jChipType )
+- {
+- case XG20:
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
+- data = data & 0x01;
+- XGINew_ChannelAB = 1 ; /* XG20 "JUST" one channel */
+-
+- if ( data == 0 ) /* Single_32_16 */
+- {
+- XGINew_DataBusWidth = 32 ; /* 32 bits */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 32bit */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* 22bit + 1 rank + 32bit */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
+-
+- if ( XGINew_ReadWriteRest( 23 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_DataBusWidth = 16 ; /* 16 bits */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 16bit */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
+-
+- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+- return ;
+- else
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
+-
+- }
+- else /* Dual_16_8 */
+- {
+- XGINew_DataBusWidth = 16 ; /* 16 bits */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
+-
+- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x31 ) ;
+-
+- if ( XGINew_ReadWriteRest( 22 , 22 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_DataBusWidth = 8 ; /* 8 bits */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
+-
+- if ( XGINew_ReadWriteRest( 22 , 21 , pVBInfo ) == 1 )
+- return ;
+- else
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
+- }
+- break ;
+-
+- case XG41:
+- if ( XGINew_CheckFrequence(pVBInfo) == 1 )
+- {
+- XGINew_DataBusWidth = 32 ; /* 32 bits */
+- XGINew_ChannelAB = 3 ; /* Quad Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
+-
+- if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 2 ; /* Dual channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x49 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 3 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
+-
+- if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
+- return ;
+- else
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x39 ) ;
+- }
+- else
+- { /* DDR */
+- XGINew_DataBusWidth = 64 ; /* 64 bits */
+- XGINew_ChannelAB = 2 ; /* Dual channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
+-
+- if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 1 ; /* Single channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x53 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 2 ; /* Dual channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 1 ; /* Single channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
+-
+- if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
+- return ;
+- else
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x43 ) ;
+- }
+-
+- break ;
+-
+- case XG42:
+-/*
+- XG42 SR14 D[3] Reserve
+- D[2] = 1, Dual Channel
+- = 0, Single Channel
+-
+- It's Different from Other XG40 Series.
+-*/
+- if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII, DDR2x */
+- {
+- XGINew_DataBusWidth = 32 ; /* 32 bits */
+- XGINew_ChannelAB = 2 ; /* 2 Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x44 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x34 ) ;
+- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 1 ; /* Single Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x40 ) ;
+-
+- if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+- return ;
+- else
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
+- }
+- }
+- else
+- { /* DDR */
+- XGINew_DataBusWidth = 64 ; /* 64 bits */
+- XGINew_ChannelAB = 1 ; /* 1 channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+- else
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
+- }
+- }
+-
+- break ;
+-
+- case XG45:
+-
+- XGINew_DataBusWidth = 64 ; /* 64 bits */
+- XGINew_ChannelAB = 4 ; /* 3+1 Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
+-
+- if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 3 ; /* 3 Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
+-
+- if ( XGI45New_ReadWriteRest( 26 , 24 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 2 ; /* 2 Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
+-
+- if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 1 ; /* 1 Channel */
+- for ( i = 0; i <= 2; i++)
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
+-
+- if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+- }
+-
+- XGINew_ChannelAB = 3 ; /* 3 Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
+-
+- if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 2 ; /* 2 Channel */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
+-
+- if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 1 ; /* 1 Channel */
+- for ( i = 0; i <= 2; i++)
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
+-
+- if ( XGI45New_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
+- return ;
+- }
+- break ;
+-
+- default: /* XG40 */
+-
+- if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII */
+- {
+- XGINew_DataBusWidth = 32 ; /* 32 bits */
+- XGINew_ChannelAB = 3 ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
+-
+- if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGINew_ChannelAB = 2 ; /* 2 channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- return ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
+-
+- if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
+- XGINew_ChannelAB = 3 ; /* 4 channels */
+- else
+- {
+- XGINew_ChannelAB = 2 ; /* 2 channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
+- }
+- }
+- else
+- { /* DDR */
+- XGINew_DataBusWidth = 64 ; /* 64 bits */
+- XGINew_ChannelAB = 2 ; /* 2 channels */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
+-
+- if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
+- return ;
+- else
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
+- }
+- }
+- break ;
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDRSizing340 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- USHORT memsize , addr ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
+- XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
+-
+- for( i = 0 ; i < 4 ; i++ )
+- {
+- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+- memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+- if ( memsize == 0 )
+- continue ;
+-
+- addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
+- if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+- continue ;
+-
+- if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
+- return( 1 ) ;
+- }
+- return( 0 ) ;
+-}
+-
+-
+-/*--------------------------------------------------------------------- */
+-/* Function : XGINew_DDRSizingXG45 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/*--------------------------------------------------------------------- */
+-int XGINew_DDRSizingXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- USHORT memsize , addr ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
+- XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
+-
+- for( i = 0 ; i < 4 ; i++ )
+- {
+- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+- memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
+- if ( memsize == 0 )
+- continue ;
+-
+- addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
+- if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
+- continue ;
+-
+- if ( XGI45New_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
+- return( 1 ) ;
+- }
+- return( 0 ) ;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDRSizing */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
+-{
+- int i ;
+- UCHAR j ;
+-
+- for( i = 0 ; i < 4 ; i++ )
+- {
+- XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE, pVBInfo ) ;
+- XGINew_DisableChannelInterleaving( i , XGINew_DDRDRAM_TYPE , pVBInfo) ;
+- for( j = 2 ; j > 0 ; j-- )
+- {
+- XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
+- if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE, pVBInfo ) )
+- continue ;
+- else
+- {
+- if ( XGINew_CheckDDRRanks( j , i , XGINew_DDRDRAM_TYPE, pVBInfo ) )
+- return( 1 ) ;
+- }
+- }
+- }
+- return( 0 ) ;
+-}
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetMemoryClock */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifndef LINUX_XF86
+- UCHAR tempal ;
+-#endif
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 , pVBInfo->MCLKData[ XGINew_RAMType ].SR28 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 , pVBInfo->MCLKData[ XGINew_RAMType ].SR29 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A , pVBInfo->MCLKData[ XGINew_RAMType ].SR2A ) ;
+-
+-
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , pVBInfo->ECLKData[ XGINew_RAMType ].SR2E ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , pVBInfo->ECLKData[ XGINew_RAMType ].SR2F ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , pVBInfo->ECLKData[ XGINew_RAMType ].SR30 ) ;
+-
+- /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
+- /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
+- if ( HwDeviceExtension->jChipType == XG42 )
+- {
+- if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
+- && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
+- || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
+- {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 , ( ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 ) & 0xFC ) | 0x02 ) ;
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* input : dx ,valid value : CR or second chip's CR */
+-/* */
+-/* SetPowerConsume : */
+-/* Description: reduce 40/43 power consumption in first chip or */
+-/* in second chip, assume CR A1 D[6]="1" in this case */
+-/* output : none */
+-/* --------------------------------------------------------------------- */
+-void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT XGI_P3d4Port )
+-{
+- ULONG lTemp ;
+- UCHAR bTemp;
+-
+- HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
+- if ((lTemp&0xFF)==0)
+- {
+- /* set CR58 D[5]=0 D[3]=0 */
+- XGI_SetRegAND((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 ) ;
+- bTemp = (UCHAR) XGI_GetReg((XGIIOADDRESS) XGI_P3d4Port , 0xCB ) ;
+- if (bTemp&0x20)
+- {
+- if (!(bTemp&0x10))
+- {
+- XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x20 ) ; /* CR58 D[5]=1 D[3]=0 */
+- }
+- else
+- {
+- XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x08 ) ; /* CR58 D[5]=0 D[3]=1 */
+- }
+-
+- }
+-
+- }
+-}
+-
+-
+-void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+-
+- /* ULONG ROMAddr = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
+- pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
+- pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
+- pVBInfo->BaseAddr = ( USHORT )HwDeviceExtension->pjIOAddress ;
+- pVBInfo->RelIO = HwDeviceExtension->pjIOAddress - 0x30;
+- pVBInfo->ISXPDOS = 0 ;
+-
+- pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
+- pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
+- pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
+- pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
+- pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
+- pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
+- pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
+- pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
+- pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
+- pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
+- pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
+- pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
+- pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
+- pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
+- pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
+- pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
+- pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
+-
+- pVBInfo->IF_DEF_LCDA = 1 ;
+- pVBInfo->IF_DEF_VideoCapture = 0 ;
+- pVBInfo->IF_DEF_ScaleLCD = 0 ;
+- pVBInfo->IF_DEF_OEMUtil = 0 ;
+- pVBInfo->IF_DEF_PWD = 0 ;
+-
+- if ( HwDeviceExtension->jChipType == XG20 ) /* kuku 2004/06/25 */
+- {
+- pVBInfo->IF_DEF_YPbPr = 0 ;
+- pVBInfo->IF_DEF_HiVision = 0 ;
+- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
+- }
+- else if ( HwDeviceExtension->jChipType >= XG40 )
+- {
+- pVBInfo->IF_DEF_YPbPr = 1 ;
+- pVBInfo->IF_DEF_HiVision = 1 ;
+- pVBInfo->IF_DEF_CRT2Monitor = 1 ;
+- }
+- else
+- {
+- pVBInfo->IF_DEF_YPbPr = 1 ;
+- pVBInfo->IF_DEF_HiVision = 1 ;
+- pVBInfo->IF_DEF_CRT2Monitor = 0 ;
+- }
+-
+- if (HwDeviceExtension->jChipType != XG20) {
+- /* alan, disable VideoCapture */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
+- }
+-
+- XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
+- InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : ReadVBIOSTablData */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifndef LINUX_XF86
+- ULONG ulOffset ;
+- UCHAR temp , index , l ;
+-#endif
+- PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
+- ULONG i ;
+- UCHAR j , k ;
+- ULONG ii , jj ;
+-
+- i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ; /* UniROM */
+- if ( i != 0 )
+- UNIROM = 1 ;
+-
+- ii = 0x90 ;
+- for( jj = 0x00 ; jj < 0x08 ; jj++ )
+- {
+- pVBInfo->MCLKData[ jj ].SR28 = pVideoMemory[ ii ] ;
+- pVBInfo->MCLKData[ jj ].SR29 = pVideoMemory[ ii + 1] ;
+- pVBInfo->MCLKData[ jj ].SR2A = pVideoMemory[ ii + 2] ;
+- pVBInfo->MCLKData[ jj ].CLOCK = pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
+- ii += 0x05 ;
+- }
+-
+- ii = 0xB8 ;
+- for( jj = 0x00 ; jj < 0x08 ; jj++ )
+- {
+- pVBInfo->ECLKData[ jj ].SR2E = pVideoMemory[ ii ] ;
+- pVBInfo->ECLKData[ jj ].SR2F=pVideoMemory[ ii + 1 ] ;
+- pVBInfo->ECLKData[ jj ].SR30= pVideoMemory[ ii + 2 ] ;
+- pVBInfo->ECLKData[ jj ].CLOCK= pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
+- ii += 0x05 ;
+- }
+-
+- /* Volari customize data area start */
+- /* if ( ChipType == XG40 ) */
+- if ( ChipType >= XG40 )
+- {
+- ii = 0xE0 ;
+- for( jj = 0x00 ; jj < 0x03 ; jj++ )
+- {
+- pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR13, SR14, and SR18 */
+- pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+- pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+- pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+- pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+- pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+- pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+- pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+- ii += 0x08 ;
+- }
+- ii = 0x110 ;
+- jj = 0x03 ;
+- pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR1B */
+- pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+- pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+- pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+- pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+- pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+- pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+- pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+-
+- pVBInfo->SR07 = pVideoMemory[0x74];
+- pVBInfo->SR1F = pVideoMemory[0x75];
+- pVBInfo->SR21 = pVideoMemory[0x76];
+- pVBInfo->SR22 = pVideoMemory[0x77];
+- pVBInfo->SR23 = pVideoMemory[0x78];
+- pVBInfo->SR24 = pVideoMemory[0x79];
+- pVBInfo->SR25[0] = pVideoMemory[0x7A];
+- pVBInfo->SR31 = pVideoMemory[0x7B];
+- pVBInfo->SR32 = pVideoMemory[0x7C];
+- pVBInfo->SR33 = pVideoMemory[0x7D];
+- ii = 0xF8 ;
+-
+- for( jj = 0 ; jj < 3 ; jj++ )
+- {
+- pVBInfo->CR40[ jj ][ 0 ] = pVideoMemory[ ii ] ;
+- pVBInfo->CR40[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+- pVBInfo->CR40[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+- pVBInfo->CR40[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+- pVBInfo->CR40[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+- pVBInfo->CR40[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+- pVBInfo->CR40[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+- pVBInfo->CR40[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+- ii += 0x08 ;
+- }
+-
+- ii = 0x118 ;
+- for( j = 3 ; j < 24 ; j++ )
+- {
+- pVBInfo->CR40[ j ][ 0 ] = pVideoMemory[ ii ] ;
+- pVBInfo->CR40[ j ][ 1 ] = pVideoMemory[ ii + 1 ] ;
+- pVBInfo->CR40[ j ][ 2 ] = pVideoMemory[ ii + 2 ] ;
+- pVBInfo->CR40[ j ][ 3 ] = pVideoMemory[ ii + 3 ] ;
+- pVBInfo->CR40[ j ][ 4 ] = pVideoMemory[ ii + 4 ] ;
+- pVBInfo->CR40[ j ][ 5 ] = pVideoMemory[ ii + 5 ] ;
+- pVBInfo->CR40[ j ][ 6 ] = pVideoMemory[ ii + 6 ] ;
+- pVBInfo->CR40[ j ][ 7 ] = pVideoMemory[ ii + 7 ] ;
+- ii += 0x08 ;
+- }
+-
+- i = pVideoMemory[ 0x1C0 ] | ( pVideoMemory[ 0x1C1 ] << 8 ) ;
+-
+- for( j = 0 ; j < 8 ; j++ )
+- {
+- for( k = 0 ; k < 4 ; k++ )
+- pVBInfo->CR6B[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
+- }
+-
+- i = pVideoMemory[ 0x1C2 ] | ( pVideoMemory[ 0x1C3 ] << 8 ) ;
+-
+- if (ChipType == XG45)
+- {
+- for( j = 0 ; j < 8 ; j++ )
+- {
+- pVBInfo->XG45CR6E[ j ] = pVideoMemory[i] ;
+- }
+- }
+- else
+- {
+- for( j = 0 ; j < 8 ; j++ )
+- {
+- for( k = 0 ; k < 4 ; k++ )
+- pVBInfo->CR6E[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
+- }
+- }
+-
+- i = pVideoMemory[ 0x1C4 ] | ( pVideoMemory[ 0x1C5 ] << 8 ) ;
+- if (ChipType == XG45)
+- {
+- for( j = 0 ; j < 8 ; j++ )
+- {
+- pVBInfo->XG45CR6F[ j ] = pVideoMemory[i] ;
+- }
+- }
+- else
+- {
+- for( j = 0 ; j < 8 ; j++ )
+- {
+- for( k = 0 ; k < 32 ; k++ )
+- pVBInfo->CR6F[ j ][ k ] = pVideoMemory[ i + 32 * j + k ] ;
+- }
+- }
+-
+- i = pVideoMemory[ 0x1C6 ] | ( pVideoMemory[ 0x1C7 ] << 8 ) ;
+-
+- for( j = 0 ; j < 8 ; j++ )
+- {
+- for( k = 0 ; k < 2 ; k++ )
+- pVBInfo->CR89[ j ][ k ] = pVideoMemory[ i + 2 * j + k ] ;
+- }
+-
+- i = pVideoMemory[ 0x1C8 ] | ( pVideoMemory[ 0x1C9 ] << 8 ) ;
+- for( j = 0 ; j < 12 ; j++ )
+- pVBInfo->AGPReg[ j ] = pVideoMemory[ i + j ] ;
+-
+- i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;
+- for( j = 0 ; j < 4 ; j++ )
+- pVBInfo->SR16[ j ] = pVideoMemory[ i + j ] ;
+-
+- pVBInfo->CRCF = pVideoMemory[0x1CA];
+- pVBInfo->DRAMTypeDefinition = pVideoMemory[0x1CB];
+- pVBInfo->I2CDefinition = pVideoMemory[0x1D1];
+- if ( ChipType == XG20 )
+- pVBInfo->CR97 = pVideoMemory[0x1D2];
+- }
+- /* Volari customize data area end */
+-}
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_DDR1x_MRS_XG20 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_DDR1x_MRS_XG20( USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
+-{
+-
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- DelayUS( 60 ) ;
+-
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
+- DelayUS( 60 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
+- DelayUS( 1000 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
+- DelayUS( 500 ) ;
+- /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
+- XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
+-}
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_SetDRAMModeRegister_XG20 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifndef LINUX_XF86
+- UCHAR data ;
+-#endif
+-
+- ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
+-
+- if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
+- XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
+- else
+- XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
+-}
+-
+-/* -------------------------------------------------------- */
+-/* Function : XGINew_ChkSenseStatus */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* -------------------------------------------------------- */
+-void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx=0 , temp , tempcx , CR3CData;
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 ) ;
+-
+- if ( temp & Monitor1Sense )
+- tempbx |= ActiveCRT1 ;
+- if ( temp & LCDSense )
+- tempbx |= ActiveLCD ;
+- if ( temp & Monitor2Sense )
+- tempbx |= ActiveCRT2 ;
+- if ( temp & TVSense )
+- {
+- tempbx |= ActiveTV ;
+- if ( temp & AVIDEOSense )
+- tempbx |= ( ActiveAVideo << 8 );
+- if ( temp & SVIDEOSense )
+- tempbx |= ( ActiveSVideo << 8 );
+- if ( temp & SCARTSense )
+- tempbx |= ( ActiveSCART << 8 );
+- if ( temp & HiTVSense )
+- tempbx |= ( ActiveHiTV << 8 );
+- if ( temp & YPbPrSense )
+- tempbx |= ( ActiveYPbPr << 8 );
+- }
+-
+- tempcx = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
+- tempcx |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ) ;
+-
+- if ( tempbx & tempcx )
+- {
+- CR3CData = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3c ) ;
+- if ( !( CR3CData & DisplayDeviceFromCMOS ) )
+- {
+- tempcx = 0x1FF0 ;
+- if (pVBInfo->SoftSetting & ModeSoftSetting) {
+- tempbx = 0x1FF0 ;
+- }
+- }
+- }
+- else
+- {
+- tempcx = 0x1FF0 ;
+- if (pVBInfo->SoftSetting & ModeSoftSetting) {
+- tempbx = 0x1FF0 ;
+- }
+- }
+-
+- tempbx &= tempcx ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d , ( tempbx & 0x00FF ) ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e , ( ( tempbx & 0xFF00 ) >> 8 )) ;
+-}
+-/* -------------------------------------------------------- */
+-/* Function : XGINew_SetModeScratch */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* -------------------------------------------------------- */
+-void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
+-{
+- USHORT temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
+- temp |= XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ;
+- temp |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) & ( DriverMode >> 8) ) << 8 ;
+-
+- if ( pVBInfo->IF_DEF_CRT2Monitor == 1)
+- {
+- if ( temp & ActiveCRT2 )
+- tempcl = SetCRT2ToRAMDAC ;
+- }
+-
+- if ( temp & ActiveLCD )
+- {
+- tempcl |= SetCRT2ToLCD ;
+- if ( temp & DriverMode )
+- {
+- if ( temp & ActiveTV )
+- {
+- tempch = SetToLCDA | EnableDualEdge ;
+- temp ^= SetCRT2ToLCD ;
+-
+- if ( ( temp >> 8 ) & ActiveAVideo )
+- tempcl |= SetCRT2ToAVIDEO ;
+- if ( ( temp >> 8 ) & ActiveSVideo )
+- tempcl |= SetCRT2ToSVIDEO ;
+- if ( ( temp >> 8 ) & ActiveSCART )
+- tempcl |= SetCRT2ToSCART ;
+-
+- if ( pVBInfo->IF_DEF_HiVision == 1 )
+- {
+- if ( ( temp >> 8 ) & ActiveHiTV )
+- tempcl |= SetCRT2ToHiVisionTV ;
+- }
+-
+- if ( pVBInfo->IF_DEF_YPbPr == 1 )
+- {
+- if ( ( temp >> 8 ) & ActiveYPbPr )
+- tempch |= SetYPbPr ;
+- }
+- }
+- }
+- }
+- else
+- {
+- if ( ( temp >> 8 ) & ActiveAVideo )
+- tempcl |= SetCRT2ToAVIDEO ;
+- if ( ( temp >> 8 ) & ActiveSVideo )
+- tempcl |= SetCRT2ToSVIDEO ;
+- if ( ( temp >> 8 ) & ActiveSCART )
+- tempcl |= SetCRT2ToSCART ;
+-
+- if ( pVBInfo->IF_DEF_HiVision == 1 )
+- {
+- if ( ( temp >> 8 ) & ActiveHiTV )
+- tempcl |= SetCRT2ToHiVisionTV ;
+- }
+-
+- if ( pVBInfo->IF_DEF_YPbPr == 1 )
+- {
+- if ( ( temp >> 8 ) & ActiveYPbPr )
+- tempch |= SetYPbPr ;
+- }
+- }
+-
+-
+- tempcl |= SetSimuScanMode ;
+- if ( (!( temp & ActiveCRT1 )) && ( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
+- tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
+- if ( ( temp & ActiveLCD ) && ( temp & ActiveTV ) )
+- tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30 , tempcl ) ;
+-
+- CR31Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) ;
+- CR31Data &= ~( SetNotSimuMode >> 8 ) ;
+- if ( !( temp & ActiveCRT1 ) )
+- CR31Data |= ( SetNotSimuMode >> 8 ) ;
+- CR31Data &= ~( DisableCRT2Display >> 8 ) ;
+- if (!( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
+- CR31Data |= ( DisableCRT2Display >> 8 ) ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31 , CR31Data ) ;
+-
+- CR38Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
+- CR38Data &= ~SetYPbPr ;
+- CR38Data |= tempch ;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38 , CR38Data ) ;
+-
+-}
++/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
++ *
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation on the rights to use, copy, modify, merge,
++ * publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so,
++ * subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
++ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "osdef.h"
++#include "vgatypes.h"
++
++
++#ifdef LINUX_KERNEL
++#include <linux/version.h>
++#include <linux/types.h>
++#include <linux/delay.h> /* udelay */
++#include "XGIfb.h"
++#endif
++
++#include "vb_def.h"
++#include "vb_struct.h"
++#include "vb_setmode.h"
++#include "vb_init.h"
++#include "vb_ext.h"
++
++#ifdef LINUX_XF86
++#include "xf86.h"
++#include "xf86PciInfo.h"
++#include "xgi.h"
++#include "xgi_regs.h"
++#endif
++
++#ifdef LINUX_KERNEL
++#include <asm/io.h>
++#include <linux/types.h>
++#endif
++
++
++
++
++static UCHAR XGINew_ChannelAB;
++static UCHAR XGINew_DataBusWidth;
++
++USHORT XGINew_DRAMType[17][5]={{0x0C,0x0A,0x02,0x40,0x39},{0x0D,0x0A,0x01,0x40,0x48},
++ {0x0C,0x09,0x02,0x20,0x35},{0x0D,0x09,0x01,0x20,0x44},
++ {0x0C,0x08,0x02,0x10,0x31},{0x0D,0x08,0x01,0x10,0x40},
++ {0x0C,0x0A,0x01,0x20,0x34},{0x0C,0x09,0x01,0x08,0x32},
++ {0x0B,0x08,0x02,0x08,0x21},{0x0C,0x08,0x01,0x08,0x30},
++ {0x0A,0x08,0x02,0x04,0x11},{0x0B,0x0A,0x01,0x10,0x28},
++ {0x09,0x08,0x02,0x02,0x01},{0x0B,0x09,0x01,0x08,0x24},
++ {0x0B,0x08,0x01,0x04,0x20},{0x0A,0x08,0x01,0x02,0x10},
++ {0x09,0x08,0x01,0x01,0x00}};
++
++static const USHORT XGINew_SDRDRAM_TYPE[13][5]=
++{
++ { 2,12, 9,64,0x35},
++ { 1,13, 9,64,0x44},
++ { 2,12, 8,32,0x31},
++ { 2,11, 9,32,0x25},
++ { 1,12, 9,32,0x34},
++ { 1,13, 8,32,0x40},
++ { 2,11, 8,16,0x21},
++ { 1,12, 8,16,0x30},
++ { 1,11, 9,16,0x24},
++ { 1,11, 8, 8,0x20},
++ { 2, 9, 8, 4,0x01},
++ { 1,10, 8, 4,0x10},
++ { 1, 9, 8, 2,0x00}
++};
++
++static const USHORT XGINew_DDRDRAM_TYPE[4][5]=
++{
++ { 2,12, 9,64,0x35},
++ { 2,12, 8,32,0x31},
++ { 2,11, 8,16,0x21},
++ { 2, 9, 8, 4,0x01}
++};
++
++static const USHORT XGINew_DDRDRAM_TYPE340[4][5]=
++{
++ { 2,13, 9,64,0x45},
++ { 2,12, 9,32,0x35},
++ { 2,12, 8,16,0x31},
++ { 2,11, 8, 8,0x21}
++};
++
++/* Jong 10/05/2007; merge code */
++USHORT XGINew_DDRDRAM_TYPE20[12][5]=
++{
++{ 2,14,11,128,0x5D},
++{ 2,14,10,64,0x59},
++{ 2,13,11,64,0x4D},
++{ 2,14, 9,32,0x55},
++{ 2,13,10,32,0x49},
++{ 2,12,11,32,0x3D},
++{ 2,14, 8,16,0x51},
++{ 2,13, 9,16,0x45},
++{ 2,12,10,16,0x39},
++{ 2,13, 8, 8,0x41},
++{ 2,12, 9, 8,0x35},
++{ 2,12, 8, 4,0x31}
++};
++
++static void XGINew_SetDRAMSize_340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static void XGINew_SetDRAMSize_XG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static void XGINew_SetMemoryClock(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static void XGINew_SetDRAMDefaultRegister340(PXGI_HW_DEVICE_INFO, USHORT,
++ PVB_DEVICE_INFO);
++static void XGINew_SetDRAMDefaultRegisterXG45(PXGI_HW_DEVICE_INFO, USHORT,
++ PVB_DEVICE_INFO);
++static UCHAR XGINew_Get340DRAMType(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++
++static int XGINew_SetDDRChannel(int index, UCHAR ChannelNo,
++ UCHAR XGINew_ChannelAB, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo);
++
++static void XGINew_SetDRAMSizingType(int index ,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++static USHORT XGINew_SetDRAMSizeReg(int index,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++
++static int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++
++static int XGINew_CheckRanks(int RankNo, int index,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++static int XGINew_CheckRank(int RankNo, int index,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++static int XGINew_CheckDDRRank(int RankNo, int index,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++static int XGINew_CheckDDRRanks(int RankNo, int index,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo);
++
++static int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo);
++static int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo);
++
++static int XGINew_DDRSizing340(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static int XGINew_DDRSizingXG45(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static int XGINew_SDRSizing(PVB_DEVICE_INFO);
++static int XGINew_DDRSizing(PVB_DEVICE_INFO);
++
++/* Jong 10/05/2007; merge code */
++static void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
++static UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
++static void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
++static UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
++
++static void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo);
++static void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo);
++static void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
++static void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
++static void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT P3c4, PVB_DEVICE_INFO pVBInfo);
++static void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT Port, PVB_DEVICE_INFO pVBInfo);
++static void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT Port, PVB_DEVICE_INFO pVBInfo);
++static void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT Port, PVB_DEVICE_INFO pVBInfo);
++
++static void XGINew_DisableChannelInterleaving(int index,
++ const USHORT XGINew_DDRDRAM_TYPE[][5], PVB_DEVICE_INFO pVBInfo);
++
++static void DualChipInit(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++
++static void XGINew_DisableRefresh(PXGI_HW_DEVICE_INFO ,PVB_DEVICE_INFO);
++static void XGINew_EnableRefresh(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++
++static void XGINew_Delay15us(ULONG);
++static void SetPowerConsume(PXGI_HW_DEVICE_INFO, USHORT);
++static void XGINew_DDR1x_MRS_XG20(USHORT, PVB_DEVICE_INFO);
++static void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++static void XGINew_ChkSenseStatus(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO);
++
++static int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
++ PVB_DEVICE_INFO pVBInfo);
++static int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
++ PVB_DEVICE_INFO pVBInfo);
++static UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo);
++static void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++
++static int XGINew_RAMType; /*int ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
++static ULONG UNIROM; /* UNIROM */
++
++
++#ifdef LINUX_KERNEL
++void DelayUS(ULONG MicroSeconds)
++{
++ udelay(MicroSeconds);
++}
++#endif
++
++/* --------------------------------------------------------------------- */
++/* Function : XGIInitNew */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN XGIInitNew(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++#ifndef LINUX_XF86
++ USHORT Mclockdata[ 30 ] , Eclockdata[ 30 ] ;
++ UCHAR j , SR11 , SR17 = 0 , SR18 = 0 , SR19 = 0 ;
++ UCHAR CR37 = 0 , CR38 = 0 , CR79 = 0 , CR7A = 0 ,
++ CR7B = 0 , CR36 = 0 , CR78 = 0 , CR3C = 0 ,
++ CR3D = 0 , CR3E = 0 , CR3F = 0 , CR35 = 0 ;
++#endif
++ UCHAR i , temp = 0 , temp1 ,
++ VBIOSVersion[ 5 ] ;
++ ULONG base,ChipsetID,VendorID,GraphicVendorID;
++ PUCHAR volatile pVideoMemory;
++
++ /* ULONG j, k ; */
++
++ PXGI_DSReg pSR ;
++
++ ULONG Temp ;
++
++
++ XGINew_InitVBIOSData(HwDeviceExtension, pVBInfo);
++
++ pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr;
++
++
++ Newdebugcode( 0x99 ) ;
++
++ /* if ( pVBInfo->ROMAddr == 0 ) */
++ /* return( FALSE ) ; */
++
++ if ( pVBInfo->FBAddr == 0 )
++ return( FALSE ) ;
++
++ if ( pVBInfo->BaseAddr == 0 )
++ return( FALSE ) ;
++
++ XGI_SetRegByte((XGIIOADDRESS) ( USHORT )( pVBInfo->BaseAddr + 0x12 ) , 0x67 ) ; /* 3c2 <- 67 ,ynlai */
++
++
++ if ( !HwDeviceExtension->bIntegratedMMEnabled )
++ return( FALSE ) ; /* alan */
++
++
++
++ XGI_MemoryCopy( VBIOSVersion , HwDeviceExtension->szVBIOSVer , 4 ) ;
++
++ VBIOSVersion[ 4 ] = 0x0 ;
++
++
++ /* ReadVBIOSData */
++ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
++
++ /* 1.Openkey */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x05 , 0x86 ) ;
++
++
++
++ /* 2.Reset Extended register */
++
++ for( i = 0x06 ; i < 0x20 ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
++
++ for( i = 0x21 ; i <= 0x27 ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
++
++ /* for( i = 0x06 ; i <= 0x27 ; i++ ) */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ; */
++
++
++ if(( HwDeviceExtension->jChipType == XG20 ) || ( HwDeviceExtension->jChipType >= XG40))
++ {
++ for( i = 0x31 ; i <= 0x3B ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
++ }
++ else
++ {
++ for( i = 0x31 ; i <= 0x3D ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , i , 0 ) ;
++ }
++
++ if ( HwDeviceExtension->jChipType == XG42 ) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B , 0xC0 ) ;
++
++ /* for( i = 0x30 ; i <= 0x3F ; i++ ) */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; */
++
++ for( i = 0x79 ; i <= 0x7C ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , 0 ) ; /* shampoo 0208 */
++
++ /* Jong 10/01/2007; SetDefPCIRegs */ /* alan 12/07/2006 */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ for( i = 0xD0 ; i <= 0xDB ; i++ )
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->pCRD0[i-0xd0] ) ;
++ for( i = 0xDE ; i <= 0xDF ; i++ )
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->pCRDE[i-0xdE] ) ;
++ }
++
++
++ if ( HwDeviceExtension->jChipType >= XG20 )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x97, pVBInfo->CR97);
++
++ /* 3.SetMemoryClock */
++ if (!(pVBInfo->SoftSetting & SoftDRAMType)) {
++ if (( HwDeviceExtension->jChipType == XG20 )||( HwDeviceExtension->jChipType == XG21 )||( HwDeviceExtension->jChipType == XG27 ))
++ {
++ temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
++ }
++ else if (HwDeviceExtension->jChipType == XG45)
++ {
++ temp = 0x02 ;
++ }
++ else
++ {
++ temp = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
++ }
++ }
++
++
++ if ( HwDeviceExtension->jChipType == XG20 )
++ XGINew_RAMType = temp & 0x01 ;
++ else
++ {
++ XGINew_RAMType = temp & 0x03 ; /* alan */
++ }
++
++ /* Get DRAM type */
++ if ( HwDeviceExtension->jChipType == XG45 )
++ { }
++ else if ( HwDeviceExtension->jChipType >= XG40 )
++ XGINew_RAMType = ( int )XGINew_Get340DRAMType( HwDeviceExtension , pVBInfo) ;
++
++ if ( UNIROM == 1 ) XGINew_RAMType = 0;
++
++ if ( HwDeviceExtension->jChipType < XG40 )
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ /* 4.SetDefExt1Regs begin */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, pVBInfo->SR07);
++
++ /* Jong 10/01/2007; add for ??? */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x40 , *pVBInfo->pSR40 ) ;
++ XGI_SetReg( (XGIIOADDRESS)pVBInfo->P3c4 , 0x41 , *pVBInfo->pSR41 ) ;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x11, 0x0F);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, pVBInfo->SR1F);
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0x20); */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
++
++ /* Jong 10/01/2007; added for ??? */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x36 , 0x70 ) ; /* Hsuan, 2006/01/01 H/W request for slow corner chip */
++ if ( HwDeviceExtension->jChipType == XG27 ) /* Alan 12/07/2006 */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x36 , *pVBInfo->pSR36 ) ;
++
++ /* SR11 = 0x0F ; */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x11 , SR11 ) ; */
++
++
++ if ( (HwDeviceExtension->jChipType != XG20)
++ &&(HwDeviceExtension->jChipType != XG21)
++ &&(HwDeviceExtension->jChipType != XG27)
++ &&(HwDeviceExtension->jChipType != XG45) ) /* kuku 2004/06/25 */
++ {
++ /* Set AGP Rate */
++ temp1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3B ) ;
++ temp1 &= 0x02 ;
++ if ( temp1 == 0x02 )
++ {
++ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
++ ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
++ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8000002C ) ;
++ VendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
++ VendorID &= 0x0000FFFF ;
++ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x8001002C ) ;
++ GraphicVendorID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
++ GraphicVendorID &= 0x0000FFFF;
++
++ if ( ChipsetID == 0x7301039 )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x09 ) ;
++
++ ChipsetID &= 0x0000FFFF ;
++
++ if ( ( ChipsetID == 0x700E ) || ( ChipsetID == 0x1022 ) || ( ChipsetID == 0x1106 ) || ( ChipsetID == 0x10DE ) )
++ {
++ if ( ChipsetID == 0x1106 )
++ {
++ if ( ( VendorID == 0x1019 ) && ( GraphicVendorID == 0x1019 ) )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0D ) ;
++ else
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
++ }
++ else
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x5F , 0x0B ) ;
++ }
++ }
++
++ if ( HwDeviceExtension->jChipType >= XG40 )
++ {
++ /* Set AGP customize registers (in SetDefAGPRegs) Start */
++ for( i = 0x47 ; i <= 0x4C ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ i - 0x47 ] ) ;
++
++ for( i = 0x70 ; i <= 0x71 ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 6 + i - 0x70 ] ) ;
++
++ for( i = 0x74 ; i <= 0x77 ; i++ )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , i , pVBInfo->AGPReg[ 8 + i - 0x74 ] ) ;
++ /* Set AGP customize registers (in SetDefAGPRegs) End */
++ /*[Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
++ XGI_SetRegLong((XGIIOADDRESS) 0xcf8 , 0x80000000 ) ;
++ ChipsetID = XGI_GetRegLong((XGIIOADDRESS) 0x0cfc ) ;
++ if ( ChipsetID == 0x25308086 )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x77 , 0xF0 ) ;
++
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x50 , 0 , &Temp ) ; /* Get */
++ Temp >>= 20 ;
++ Temp &= 0xF ;
++
++ if ( Temp == 1 )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , 0x20 ) ; /* CR48 */
++ }
++
++ if ( HwDeviceExtension->jChipType < XG40 )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x49 , pVBInfo->CR49[ 0 ] ) ;
++ } /* != XG20 */
++
++ /* Set PCI */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x23, pVBInfo->SR23);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x24, pVBInfo->SR24);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
++
++ if ( (HwDeviceExtension->jChipType != XG20) &&
++ (HwDeviceExtension->jChipType != XG21) &&
++ (HwDeviceExtension->jChipType != XG27) ) /* kuku 2004/06/25 */
++ {
++ /* Set VB */
++ XGI_UnLockCRT2( HwDeviceExtension, pVBInfo) ;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port , 0x3F , 0xEF , 0x00 ) ; /* alan, disable VideoCapture */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , 0x00 ) ;
++ temp1 = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7B ) ; /* chk if BCLK>=100MHz */
++ temp = ( UCHAR )( ( temp1 >> 4 ) & 0x0F ) ;
++
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02,
++ pVBInfo->CRT2Data_1_2);
++
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x2E , 0x08 ) ; /* use VB */
++ } /* != XG20 */
++
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x27 , 0x1F ) ;
++
++ /* Not DDR */
++ if ((HwDeviceExtension->jChipType == XG42)
++ && XGINew_Get340DRAMType(HwDeviceExtension, pVBInfo) != 0) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, (pVBInfo->SR31 & 0x3F) | 0x40);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, (pVBInfo->SR32 & 0xFC) | 0x01);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, pVBInfo->SR31);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, pVBInfo->SR32);
++ }
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x33, pVBInfo->SR33);
++
++
++
++ if ( HwDeviceExtension->jChipType >= XG40 )
++ SetPowerConsume ( HwDeviceExtension , pVBInfo->P3c4);
++
++ if ( (HwDeviceExtension->jChipType != XG20) &&
++ (HwDeviceExtension->jChipType != XG21) &&
++ (HwDeviceExtension->jChipType != XG27) ) /* kuku 2004/06/25 */
++ {
++ if ( XGI_BridgeIsOn( pVBInfo ) == 1 )
++ {
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0x1C);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, pVBInfo->CRT2Data_4_D);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, pVBInfo->CRT2Data_4_E);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, pVBInfo->CRT2Data_4_10);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0F, 0x3F);
++ }
++
++ XGI_LockCRT2( HwDeviceExtension, pVBInfo ) ;
++ }
++ } /* != XG20 */
++
++ if ( HwDeviceExtension->jChipType < XG40 )
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x83 , 0x00 ) ;
++
++
++ /* Jong 10/01/2007; added for ??? */
++ if ( HwDeviceExtension->bSkipSense == FALSE )
++ {
++ XGI_SenseCRT1(pVBInfo) ;
++ /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
++ if ( ( HwDeviceExtension->jChipType == XG21 ) && (pVBInfo->IF_DEF_CH7007) )
++ {
++ XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
++ }
++ if ( HwDeviceExtension->jChipType == XG21 )
++ {
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
++ temp = GetXG21FPBits( pVBInfo ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 , ~0x01, temp ) ;
++ }
++ if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , ~Monitor1Sense , Monitor1Sense ) ; /* Z9 default has CRT */
++ temp = GetXG27FPBits( pVBInfo ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 , ~0x03, temp ) ;
++ }
++ }
++
++ if ( HwDeviceExtension->jChipType >= XG40 )
++ {
++ if (HwDeviceExtension->jChipType == XG45)
++ XGINew_SetDRAMDefaultRegisterXG45( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
++ else
++ XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , pVBInfo->P3d4, pVBInfo ) ;
++
++ if ( HwDeviceExtension->bSkipDramSizing == TRUE )
++ {
++ pSR = HwDeviceExtension->pSR ;
++ if ( pSR!=NULL )
++ {
++ while( pSR->jIdx != 0xFF )
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , pSR->jIdx , pSR->jVal ) ;
++ pSR++ ;
++ }
++ }
++ /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
++ } /* SkipDramSizing */
++ else
++ {
++/* if ( HwDeviceExtension->jChipType == XG20 )
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , pVBInfo->SR15[0][XGINew_RAMType] ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , pVBInfo->SR15[1][XGINew_RAMType] ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x20 , 0x20 ) ;
++ }
++ else*/
++ if ( HwDeviceExtension->jChipType == XG45 )
++ XGINew_SetDRAMSize_XG45( HwDeviceExtension , pVBInfo) ;
++ else
++ XGINew_SetDRAMSize_340( HwDeviceExtension , pVBInfo) ;
++ }
++ } /* XG40 */
++
++
++
++
++ /* SetDefExt2Regs begin */
++/*
++ AGP = 1 ;
++ temp =( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) ;
++ temp &= 0x30 ;
++ if ( temp == 0x30 )
++ AGP = 0 ;
++
++ if ( AGP == 0 )
++ pVBInfo->SR21 &= 0xEF ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , pVBInfo->SR21 ) ;
++ if ( AGP == 1 )
++ pVBInfo->SR22 &= 0x20;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x22 , pVBInfo->SR22 ) ;
++*/
++
++ base = 0x80000000;
++ XGI_SetRegLong(0xcf8, base);
++ Temp = (XGI_GetRegLong(0xcfc) & 0x0000FFFF);
++ if (Temp == 0x1039) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22 & 0xFE);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x22, pVBInfo->SR22);
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21, pVBInfo->SR21);
++
++ if ( HwDeviceExtension->jChipType == XG40 ) /* Initialize seconary chip */
++ {
++ if ( CheckDualChip(pVBInfo) )
++ DualChipInit( HwDeviceExtension , pVBInfo) ;
++ /* SetDefExt2Regs end */
++ }
++
++ /* Jong 10/01/2007; be removed and recoded */
++#if 0
++ if ( HwDeviceExtension->bSkipSense == FALSE )
++ {
++ XGI_SenseCRT1(pVBInfo) ;
++ /* XGINew_DetectMonitor( HwDeviceExtension ) ; */
++ XGI_GetSenseStatus( HwDeviceExtension , pVBInfo ) ; /* sense CRT2 */
++ }
++#endif
++
++ XGINew_ChkSenseStatus ( HwDeviceExtension , pVBInfo ) ;
++ XGINew_SetModeScratch ( HwDeviceExtension , pVBInfo ) ;
++
++ Newdebugcode( 0x88 ) ;
++
++ /* Johnson@062403. To save time for power management. */
++ /* DelayMS(1000); */
++ /* ~Johnson@062403. */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , 0x28 ) ; //0207 temp */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x36 , 0x02 ) ; //0207 temp */
++
++ return( TRUE ) ;
++} /* end of init */
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : DualChipInit */
++/* Input : */
++/* Output : */
++/* Description : Initialize the secondary chip. */
++/* --------------------------------------------------------------------- */
++void DualChipInit( PXGI_HW_DEVICE_INFO HwDeviceExtension ,PVB_DEVICE_INFO pVBInfo)
++{
++#ifdef LINUX_XF86
++ USHORT BaseAddr2nd = (USHORT)(ULONG)HwDeviceExtension->pj2ndIOAddress ;
++#else
++ USHORT BaseAddr2nd = (USHORT)HwDeviceExtension->pj2ndIOAddress ;
++#endif
++ USHORT XGINew_P3C3 = pVBInfo->BaseAddr + VIDEO_SUBSYSTEM_ENABLE_PORT ;
++ USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT ;
++ USHORT XGINew_2ndP3C3 = BaseAddr2nd + VIDEO_SUBSYSTEM_ENABLE_PORT ;
++ USHORT XGINew_2ndP3D4 = BaseAddr2nd + CRTC_ADDRESS_PORT_COLOR ;
++ USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT ;
++ USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT ;
++ ULONG Temp ;
++ UCHAR tempal , i ;
++
++ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
++ pVBInfo->BaseAddr = (USHORT)HwDeviceExtension->pjIOAddress ;
++ /* Programming Congiguration Space in Secondary Chip */
++ /* set CRA1 D[6] = 1 */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0xBF , 0x40 ) ;
++
++ /* Write 2nd Chip Configuration Info into Configuration Space */
++ /* Command CNFG04 */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND , 0 , &Temp ) ; /* Get */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , PCI_COMMAND + 0x80 , 1 , &Temp ) ; /* Set */
++ /* Latency Timer CNFG0C */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c , 0 , &Temp ) ; /* Get */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x0c + 0x80 , 1 , &Temp ) ; /* Set */
++ /* Linear space */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 , 0 , &Temp ) ; /* Get */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x10 + 0x80 , 1 , &Temp ) ; /* Set */
++ /* MMIO space */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 , 0 , &Temp ) ; /* Get */
++ Temp += 0x40000;
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x14 + 0x80 , 1 , &Temp ) ; /* Set */
++ /* Relocated IO space */
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 , 0 , &Temp ) ; /* Get */
++ Temp += 0x80;
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x18 + 0x80 , 1 , &Temp ) ; /* Set */
++ /* Miscellaneous reg(input port 3cch,output port 3c2h) */
++ tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC ) ; /* 3cc */
++ XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2 , tempal ) ;
++ /* VGA enable reg(port 3C3h) */
++ tempal = XGI_GetRegByte((XGIIOADDRESS) XGINew_P3C3 ) ; /* 3c3 */
++ XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C3 , tempal ) ;
++ SetPowerConsume ( HwDeviceExtension , XGINew_2ndP3D4);
++ /* ----- CRA0=42, CRA1=81, CRA2=60, CRA3=20, CRA4=50, CRA5=40, CRA8=88 -----// */
++ /* ----- CRA9=10, CRAA=80, CRAB=01, CRAC=F1, CRAE=80, CRAF=45, CRB7=24 -----// */
++ /* primary chip */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA0 , 0x72 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA1 , 0x81 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA2 , 0x60 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA3 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA4 , 0x50 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA5 , 0x40 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA8 , 0x88 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xA9 , 0x10 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAA , 0x80 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAB , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAC , 0xF1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAE , 0x80 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xAF , 0x45 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0xB7 , 0x24 ) ;
++
++ /* secondary chip */
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA0 , 0x72 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA1 , 0x81 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA2 , 0x60 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA3 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA4 , 0x50 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA5 , 0x40 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA8 , 0x88 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xA9 , 0x10 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAA , 0x80 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAB , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAC , 0xF1 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAE , 0x80 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xAF , 0x45 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3D4 , 0xB7 , 0x24 ) ;
++
++ /* 06/20/2003 [christine] CRT threshold setting request */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x78 , 0x40 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x79 , 0x0C ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x7A , 0x34 ) ;
++
++ /* OpenKey in 2nd chip */
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x86 ) ;
++
++ /* Set PCI registers */
++ tempal = (UCHAR)XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x06 ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x06 , tempal ) ;
++
++ for( i = 0x20 ; i <= 0x25 ; i++ )
++ {
++ tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
++ }
++ for(i = 0x31; i <= 0x32; i++ )
++ {
++ tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
++ }
++ XGINew_SetDRAMDefaultRegister340( HwDeviceExtension , XGINew_2ndP3D4 , pVBInfo) ;
++
++ for(i = 0x13; i <= 0x14; i++ )
++ {
++ tempal = ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , i ) ;
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , i , tempal ) ;
++ }
++
++ /* Close key in 2nd chip */
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4 , 0x05 , 0x00 ) ;
++}
++
++
++
++
++/* ============== alan ====================== */
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_Get340DRAMType */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++UCHAR XGINew_Get340DRAMType( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR data, temp ; /* Jong 10/05/2007; merge code */
++
++ if ( HwDeviceExtension->jChipType < XG20 )
++ {
++ if (pVBInfo->SoftSetting & SoftDRAMType) {
++ return (pVBInfo->SoftSetting & 0x07);
++ }
++ else
++ {
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ;
++
++ if ( data == 0 )
++ data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x3A ) & 0x02 ) >> 1 ;
++
++ return( data ) ;
++ }
++ }
++ else if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ if ( pVBInfo->SoftSetting & SoftDRAMType )
++ {
++ data = pVBInfo->SoftSetting & 0x07 ;
++ return( data ) ;
++ }
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3B ) ;
++
++ if (( temp & 0x88 )==0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
++ data = 0 ; /*DDR*/
++ else
++ data = 1 ; /*DDRII*/
++ return( data ) ;
++ }
++ else if ( HwDeviceExtension->jChipType == XG21 )
++ {
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , ~0x02 ) ; /* Independent GPIO control */
++ DelayUS(800);
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , 0x80 ) ; /* Enable GPIOH read */
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ; /* GPIOF 0:DVI 1:DVO */
++
++ /* HOTPLUG_SUPPORT */
++ /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
++ if ( temp & 0x01 ) /* DVI read GPIOH */
++ data = 1 ; /*DDRII*/
++ else
++ data = 0 ; /*DDR*/
++
++ /*~HOTPLUG_SUPPORT */
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , 0x02 ) ;
++ return( data ) ;
++ }
++ else
++ {
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) & 0x01 ;
++
++ if ( data == 1 )
++ data ++ ;
++
++ return( data );
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_Delay15us */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++/*
++void XGINew_Delay15us(ULONG ulMicrsoSec)
++{
++}
++*/
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SDR_MRS */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SDR_MRS(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ;
++ data &= 0x3F ; /* SR16 D7=0,D6=0 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) low */
++ /* XGINew_Delay15us( 0x100 ) ; */
++ data |= 0x80 ; /* SR16 D7=1,D6=0 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ; /* enable mode register set(MRS) high */
++ /* XGINew_Delay15us( 0x100 ) ; */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR1x_MRS_340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR1x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
++ if ( HwDeviceExtension->jChipType == XG42 ) /* XG42 BA0 & BA1 layout change */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ else
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ /* Samsung F Die */
++ if (pVBInfo->DRAMTypeDefinition != 0x0C) {
++ DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
++ if ( HwDeviceExtension->jChipType == XG42 )
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ else
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ }
++
++ DelayUS( 60 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++
++ if (HwDeviceExtension->jChipType == XG45)
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ; /*TSop DRAM DLL pin jump to A9*/
++ else
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
++
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
++ DelayUS( 1000 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
++ DelayUS( 500 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR2x_MRS_340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR2x_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
++ if ( HwDeviceExtension->jChipType == XG42 ) /*XG42 BA0 & BA1 layout change*/
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ else
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ /* Samsung F Die */
++ if (pVBInfo->DRAMTypeDefinition != 0x0C) {
++ DelayUS( 3000 ) ; /* Delay 67 x 3 Delay15us */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
++ if ( HwDeviceExtension->jChipType == XG42 )
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ else
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ }
++
++ DelayUS( 60 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ; /*TSop DRAM DLL pin jump to A9*/
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 0 ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 1 ] ) ;
++ DelayUS( 1000 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
++ DelayUS( 500 ) ;
++ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 2 ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , pVBInfo->SR16[ 3 ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR2_MRS_340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR2_MRS_340(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT P3c4,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = P3c4 + 0x10 ;
++ UCHAR data ;
++
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , 0x64 ) ; /* SR28 */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , 0x63 ) ; /* SR29 */
++ DelayUS( 200 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x20 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ DelayUS( 2 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
++
++ if( P3c4 != pVBInfo->P3c4 )
++ {
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x28 , data ) ; /* SR28 */
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x29 , data ) ; /* SR29 */
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2A , data ) ; /* SR2A */
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2e , data ) ; /* SR2E */
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x2f , data ) ; /* SR2F */
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x30 , data ) ; /* SR30 */
++ }
++ else
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ DelayUS( 1000 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0xC5 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x23 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ DelayUS( 1 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
++ DelayUS( 5) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
++ DelayUS( 5 ) ;
++ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x72 ) ; */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x06 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
++ DelayUS( 1 ) ;
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDRII_Bootup_XG27 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDRII_Bootup_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = P3c4 + 0x10 ;
++ UCHAR data ;
++ XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ /* Set Double Frequency */
++ /* XGINew_SetReg1( P3d4 , 0x97 , 0x11 ) ; */ /* CR97 */
++ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x97 , pVBInfo->CR97 ) ; /* CR97 */
++
++ DelayUS( 200 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS2*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x80 ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS3*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0xC0 ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
++ DelayUS( 15) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS1*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ /*MRS, DLL Enable*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x0A ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ; /* Set SR16 */
++ /* DelayUS( 15 ) ; */
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* Set SR1B */
++ DelayUS( 60 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* Set SR1B */
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* Set SR18 */ /*MRS, DLL Reset*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x08 ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ; /* Set SR16 */
++
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x80 ) ; /* Set SR18 */ /*MRS, ODT*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x46 ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* Set SR18 */ /*EMRS*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ; /* Set SR19 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x20 ) ; /* Set SR16 */
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0xA0 ) ; /* Set SR16 */
++ DelayUS( 15 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* Set SR1B refresh control 000:close; 010:open */
++ DelayUS( 200 ) ;
++}
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR2_MRS_XG20 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR2_MRS_XG20( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = P3c4 + 0x10 ;
++ UCHAR data ;
++
++ XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
++
++ DelayUS( 200 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x80 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0xC0 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
++
++ /* XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ;*/ /* MRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x02 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
++
++ DelayUS( 15 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
++ DelayUS( 100 ) ;
++
++ /*XGINew_SetReg1( P3c4 , 0x18 , 0x52 ) ;*/ /* MRS2 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x05 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x85 ) ;
++
++ DelayUS( 200 ) ;
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR2_MRS_XG27 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR2_MRS_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = P3c4 + 0x10 ;
++ UCHAR data ;
++
++ XGINew_RAMType = ( int )XGINew_GetXG20DRAMType( HwDeviceExtension , pVBInfo ) ;
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ; /* CR97 */
++ DelayUS( 200 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS2 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x80 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x10 ) ;
++ DelayUS( 15 ) ; /* 06/11/23 XG27 A0 for CKE enable*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x90 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS3 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0xC0 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ DelayUS( 15 ) ; /*06/11/22 XG27 A0*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ; /* EMRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ DelayUS( 15 ) ; /*06/11/22 XG27 A0 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x06 ) ; /*[Billy]06/11/22 DLL Reset for XG27 Hynix DRAM*/
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ DelayUS( 15 ) ; /*06/11/23 XG27 A0*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ DelayUS( 30 ) ; /*06/11/23 XG27 A0 Start Auto-PreCharge*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
++ DelayUS( 60 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ; /* SR1B */
++
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x42 ) ; /* MRS1 */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x04 ) ; /* DLL without Reset for XG27 Hynix DRAM*/
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x80 ); /*XG27 OCD ON */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x46 );
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x18 , 0x00 );
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x19 , 0x40 );
++
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ DelayUS( 30 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++
++ DelayUS( 15 ) ; /*Start Auto-PreCharge*/
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x04 ) ; /* SR1B */
++ DelayUS( 200 ) ;
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ; /* SR1B */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR1x_DefaultRegister */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR1x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT Port, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = Port ,
++ P3c4 = Port - 0x10 ;
++#ifndef LINUX_XF86
++ UCHAR data ;
++#endif
++ if ( HwDeviceExtension->jChipType >= XG20 )
++ {
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
++
++ XGINew_DDR1x_MRS_XG20( P3c4 , pVBInfo) ;
++ }
++ else
++ {
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ switch( HwDeviceExtension->jChipType )
++ {
++ case XG41:
++ case XG42:
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
++ break ;
++ default:
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
++ break ;
++ }
++ if (HwDeviceExtension->jChipType != XG45)
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
++ XGINew_DDR1x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR2x_DefaultRegister */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR2x_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT Port, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = Port ,
++ P3c4 = Port - 0x10 ;
++
++#ifndef LINUX_XF86
++ UCHAR data ;
++#endif
++
++ XGINew_SetMemoryClock( HwDeviceExtension , pVBInfo ) ;
++
++ /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
++ switch( HwDeviceExtension->jChipType )
++ {
++ case XG41:
++ case XG42:
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
++ break ;
++ default:
++ /* keep following setting sequence, each setting in the same reg insert idle */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x88 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
++ }
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x11 ) ;
++ if ( HwDeviceExtension->jChipType == XG42 )
++ {
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
++ }
++ else
++ {
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
++ }
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
++
++ XGINew_DDR2x_MRS_340( HwDeviceExtension , P3c4 , pVBInfo ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR2_DefaultRegister */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR2_DefaultRegister(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT Port, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT P3d4 = Port ,
++ P3c4 = Port - 0x10 ;
++
++ /* keep following setting sequence, each setting in the same reg insert idle */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x00 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , 0x88 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x86 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x86 , pVBInfo->CR40[ 13 ][ XGINew_RAMType ] ) ; /* CR86 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , 0x77 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x00 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , 0x88 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x85 ) ; /* Insert read command for delay */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x85 , pVBInfo->CR40[ 12 ][ XGINew_RAMType ] ) ; /* CR85 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x82 , pVBInfo->CR40[ 11 ][ XGINew_RAMType ] ) ; /* CR82 */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x03 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
++
++ /* Jong 10/01/2007 */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ XGINew_DDRII_Bootup_XG27( HwDeviceExtension , P3c4 , pVBInfo) ;
++ else if ( HwDeviceExtension->jChipType >= XG20 )
++ XGINew_DDR2_MRS_XG20( HwDeviceExtension , P3c4, pVBInfo ) ;
++ else
++ XGINew_DDR2_MRS_340( HwDeviceExtension , P3c4, pVBInfo ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMDefaultRegister340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SetDRAMDefaultRegister340( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR temp , temp1 , temp2 , temp3 ,
++ i , j , k ;
++
++ USHORT P3d4 = Port ,
++ P3c4 = Port - 0x10 ;
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
++
++ temp2 = 0 ;
++ for( i = 0 ; i < 4 ; i++ )
++ {
++ temp = pVBInfo->CR6B[ XGINew_RAMType ][ i ] ; /* CR6B DQS fine tune delay */
++ for( j = 0 ; j < 4 ; j++ )
++ {
++ temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp2 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6B ) ; /* Insert read command for delay */
++ temp2 &= 0xF0 ;
++ temp2 += 0x10 ;
++ }
++ }
++
++ temp2 = 0 ;
++ for( i = 0 ; i < 4 ; i++ )
++ {
++ temp = pVBInfo->CR6E[ XGINew_RAMType ][ i ] ; /* CR6E DQM fine tune delay */
++ for( j = 0 ; j < 4 ; j++ )
++ {
++ temp1 = ( ( temp >> ( 2 * j ) ) & 0x03 ) << 2 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , temp2 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6E ) ; /* Insert read command for delay */
++ temp2 &= 0xF0 ;
++ temp2 += 0x10 ;
++ }
++ }
++
++ temp3 = 0 ;
++ for( k = 0 ; k < 4 ; k++ )
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x6E , 0xFC , temp3 ) ; /* CR6E_D[1:0] select channel */
++ temp2 = 0 ;
++ for( i = 0 ; i < 8 ; i++ )
++ {
++ temp = pVBInfo->CR6F[ XGINew_RAMType ][ 8 * k + i ] ; /* CR6F DQ fine tune delay */
++ for( j = 0 ; j < 4 ; j++ )
++ {
++ temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , temp2 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x6F ) ; /* Insert read command for delay */
++ temp2 &= 0xF8 ;
++ temp2 += 0x08 ;
++ }
++ }
++ temp3 += 0x01 ;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
++
++ temp2 = 0x80 ;
++ temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
++ for( j = 0 ; j < 4 ; j++ )
++ {
++ temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
++ temp2 &= 0xF0 ;
++ temp2 += 0x10 ;
++ }
++
++ temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
++ temp1 = temp & 0x03 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
++
++ temp = pVBInfo->CR40[ 3 ][ XGINew_RAMType ] ;
++ temp1 = temp & 0x0F ;
++ temp2 = ( temp >> 4 ) & 0x07 ;
++ temp3 = temp & 0x80 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , temp1 ) ; /* CR45 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , temp2 ) ; /* CR99 */
++ XGI_SetRegOR((XGIIOADDRESS) P3d4 , 0x40 , temp3 ) ; /* CR40_D[7] */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , pVBInfo->CR40[ 0 ][ XGINew_RAMType ] ) ; /* CR41 */
++
++ /* Jong 10/01/2007; */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ XGI_SetReg( (XGIIOADDRESS) P3d4 , 0x8F , *pVBInfo->pCR8F ) ; /* CR8F */
++
++ for( j = 0 ; j <= 6 ; j++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
++
++ for( j = 0 ; j <= 2 ; j++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
++
++ for( j = 0 ; j < 2 ; j++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
++
++ if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
++
++ /* Jong 10/01/2007 */
++ if ( XGINew_RAMType )
++ {
++ /*XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0xC0 ) ;*/ /* SR17 DDRII */
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0x80 ) ; /* SR17 DDRII */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0x02 ) ; /* SR17 DDRII */
++
++ }
++ else
++ XGI_SetReg( (XGIIOADDRESS) P3c4 , 0x17 , 0x00 ) ; /* SR17 DDR */
++
++ XGI_SetReg((XGIIOADDRESS) P3c4, 0x1A, 0x87); /* SR1A */
++
++ temp = XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) ;
++ if( temp == 0 )
++ XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
++ else if ( temp == 0x02 )
++ XGINew_DDR2x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
++ else
++ XGINew_DDR2_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
++
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMDefaultRegisterXG45 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SetDRAMDefaultRegisterXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT Port , PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR temp , temp1 , temp2 ,
++ i , j , k ;
++
++ USHORT P3d4 = Port ,
++ P3c4 = Port - 0x10 ;
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6D , pVBInfo->CR40[ 8 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6E , pVBInfo->XG45CR6E[ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6F , pVBInfo->XG45CR6F[ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x68 , pVBInfo->CR40[ 5 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x69 , pVBInfo->CR40[ 6 ][ XGINew_RAMType ] ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6A , pVBInfo->CR40[ 7 ][ XGINew_RAMType ] ) ;
++
++ temp = 0x00 ;
++ for ( j = 0 ; j < 24 ; j ++ )
++ {
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x6B , temp );
++ temp += 0x08 ;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x80 , pVBInfo->CR40[ 9 ][ XGINew_RAMType ] ) ; /* CR80 */
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x81 , pVBInfo->CR40[ 10 ][ XGINew_RAMType ] ) ; /* CR81 */
++
++ temp2 = 0x80 ;
++ temp = pVBInfo->CR89[ XGINew_RAMType ][ 0 ] ; /* CR89 terminator type select */
++ for( j = 0 ; j < 4 ; j++ )
++ {
++ temp1 = ( temp >> ( 2 * j ) ) & 0x03 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
++ XGI_GetReg((XGIIOADDRESS) P3d4 , 0x89 ) ; /* Insert read command for delay */
++ temp2 &= 0xF0 ;
++ temp2 += 0x10 ;
++ }
++
++ temp = pVBInfo->CR89[ XGINew_RAMType ][ 1 ] ;
++ temp1 = temp & 0x03 ;
++ temp2 |= temp1 ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x89 , temp2 ) ;
++
++ temp = 0x00 ;
++ for ( j = 0 ; j < 3 ; j ++ )
++ {
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x40 , temp );
++ temp += 0x40 ;
++ }
++
++ temp = 0x00 ;
++ for ( j = 0 ; j < 24 ; j ++ )
++ {
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x41 , temp );
++ temp += 0x08 ;
++ }
++
++ temp = 0x00 ;
++ for ( j = 0 ; j < 24 ; j ++ )
++ {
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x42 , temp );
++ temp += 0x08 ;
++ }
++
++ for ( k = 0 ; k < 2 ; k ++ )
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x04 , k * 0x04 );
++
++ for ( i = 0 ; i < 3 ; i ++ )
++ {
++
++ XGI_SetRegANDOR((XGIIOADDRESS) P3d4 , 0x43 , ~0x03 , i * 0x01 );
++
++ for ( j = 0 ; j < 32 ; j ++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x44 , j * 0x08 );
++ }
++ }
++
++ for ( j = 0 ; j < 3 ; j ++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x45 , j * 0x08 ) ; /* CR45 */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x97 , 0x84 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x98 , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x99 , 0x22 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x9A , 0x02 ) ;
++
++ for( j = 0 ; j <= 6 ; j++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x90 + j ) , pVBInfo->CR40[ 14 + j ][ XGINew_RAMType ] ) ; /* CR90 - CR96 */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x59 , pVBInfo->CR40[ 4 ][ XGINew_RAMType ] ) ; /* CR59 */
++
++ for( j = 0 ; j <= 2 ; j++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0xC3 + j ) , pVBInfo->CR40[ 21 + j ][ XGINew_RAMType ] ) ; /* CRC3 - CRC5 */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0xC8 , 0x04 ) ;
++
++ for( j = 0 ; j < 2 ; j++ )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , ( 0x8A + j ) , pVBInfo->CR40[ 1 + j ][ XGINew_RAMType ] ) ; /* CR8A - CR8B */
++
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x40 ) ;
++
++ if ( ( HwDeviceExtension->jChipType == XG41 ) || ( HwDeviceExtension->jChipType == XG42 ) )
++ XGI_SetReg((XGIIOADDRESS) P3d4 , 0x8C , 0x87 ) ;
++
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0xCF, pVBInfo->CRCF); /* CRCF */
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0x83, 0x09); /* CR83 */
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0x87, 0x00); /* CR87 */
++ XGI_SetReg((XGIIOADDRESS) P3d4, 0x8D, 0x87); /* CR8D */
++
++ XGINew_DDR1x_DefaultRegister( HwDeviceExtension, P3d4, pVBInfo ) ;
++
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1A , 0x87 ) ; /* SR1A */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR_MRS */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR_MRS(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
++
++ /* SR16 <- 1F,DF,2F,AF */
++ /* yriver modified SR16 <- 0F,DF,0F,AF */
++ /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
++ data = pVideoMemory[ 0xFB ] ;
++ /* data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 ) ; */
++
++ data &= 0x0F ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data |= 0xC0 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data &= 0x0F ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data |= 0x80 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data &= 0x0F ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data |= 0xD0 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data &= 0x0F ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++ data |= 0xA0 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x16 , data ) ;
++/*
++ else {
++ data &= 0x0F;
++ data |= 0x10;
++ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
++
++ if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
++ {
++ data &= 0x0F;
++ }
++
++ data |= 0xC0;
++ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
++
++
++ data &= 0x0F;
++ data |= 0x20;
++ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
++ if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10))
++ {
++ data &= 0x0F;
++ }
++
++ data |= 0x80;
++ XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x16,data);
++ }
++*/
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMSize_340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SetDRAMSize_340( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
++ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
++ XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /* disable read cache */
++
++ /* Jong 10/03/2007; add support for DVO, XG27, ...*/
++ XGI_DisplayOff(HwDeviceExtension, pVBInfo );
++ /* data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
++ data |= 0x20 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; */ /* Turn OFF Display */
++
++ XGINew_DDRSizing340( HwDeviceExtension, pVBInfo ) ;
++
++ data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /* enable read cache */
++}
++
++
++/*--------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMSize_XG45 */
++/*Input : */
++/*Output : */
++/*Description : */
++/*--------------------------------------------------------------------- */
++void XGINew_SetDRAMSize_XG45( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
++ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
++ XGISetModeNew(HwDeviceExtension, pVBInfo, 0x2e);
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data & 0xDF ) ) ; /*disable read cache*/
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1 ) ;
++ data |= 0x20 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x01 , data ) ; /*Turn OFF Display*/
++
++ XGINew_DDRSizingXG45( HwDeviceExtension, pVBInfo ) ;
++
++ data=XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x21 , ( USHORT )( data | 0x20 ) ) ; /*enable read cache*/
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMModeRegister340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++
++void XGINew_SetDRAMModeRegister340(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR data ;
++
++ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
++
++ if (HwDeviceExtension->jChipType == XG45)
++ XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
++ else
++ {
++ if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
++ {
++ data = ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) & 0x02 ) >> 1 ;
++ if ( data == 0x01 )
++ XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
++ else
++ XGINew_DDR1x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
++ }
++ else
++ XGINew_DDR2_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DisableRefresh */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DisableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B ) ;
++ data &= 0xF8 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , data ) ;
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_EnableRefresh */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_EnableRefresh( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
++{
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
++
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DisableChannelInterleaving */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DisableChannelInterleaving(int index,
++ const USHORT XGINew_DDRDRAM_TYPE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
++ data &= 0x1F ;
++
++ switch( XGINew_DDRDRAM_TYPE[ index ][ 3 ] )
++ {
++ case 64:
++ data |= 0 ;
++ break ;
++ case 32:
++ data |= 0x20 ;
++ break ;
++ case 16:
++ data |= 0x40 ;
++ break ;
++ case 4:
++ data |= 0x60 ;
++ break ;
++ default:
++ break ;
++ }
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMSizingType */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SetDRAMSizingType(int index , const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++
++ data = DRAMTYPE_TABLE[ index ][ 4 ] ;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x80 , data ) ;
++ /* should delay 50 ns */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetRank */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_SetRank(int index, UCHAR RankNo, UCHAR XGINew_ChannelAB,
++ const USHORT DRAMTYPE_TABLE[][5], PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++ int RankSize ;
++
++ if ( ( RankNo == 2 ) && ( DRAMTYPE_TABLE[ index ][ 0 ] == 2 ) )
++ return 0 ;
++
++ RankSize = DRAMTYPE_TABLE[ index ][ 3 ] / 2 * XGINew_DataBusWidth / 32 ;
++
++ if ( ( RankNo * RankSize ) <= 128 )
++ {
++ data = 0 ;
++
++ while( ( RankSize >>= 1 ) > 0 )
++ {
++ data += 0x10 ;
++ }
++ data |= ( RankNo - 1 ) << 2 ;
++ data |= ( XGINew_DataBusWidth / 64 ) & 2 ;
++ data |= XGINew_ChannelAB ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
++ /* should delay */
++ XGINew_SDR_MRS( pVBInfo ) ;
++ return( 1 ) ;
++ }
++ else
++ return( 0 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDDRChannel */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_SetDDRChannel(int index, UCHAR ChannelNo, UCHAR XGINew_ChannelAB,
++ const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data ;
++ int RankSize ;
++
++ RankSize = DRAMTYPE_TABLE[index][3]/2 * XGINew_DataBusWidth/32;
++ /* RankSize = DRAMTYPE_TABLE[ index ][ 3 ] ; */
++ if ( ChannelNo * RankSize <= 128 )
++ {
++ data = 0 ;
++ while( ( RankSize >>= 1 ) > 0 )
++ {
++ data += 0x10 ;
++ }
++
++ if ( ChannelNo == 2 )
++ data |= 0x0C ;
++
++ data |= ( XGINew_DataBusWidth / 32 ) & 2 ;
++ data |= XGINew_ChannelAB ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
++ /* should delay */
++ XGINew_DDR_MRS( pVBInfo ) ;
++ return( 1 ) ;
++ }
++ else
++ return( 0 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckColumn */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_CheckColumn(int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ ULONG Increment , Position ;
++
++ /* Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 1 ) ; */
++ Increment = 1 << ( 10 + XGINew_DataBusWidth / 64 ) ;
++
++ for( i = 0 , Position = 0 ; i < 2 ; i++ )
++ {
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++ Position += Increment ;
++ }
++
++ for( i = 0 , Position = 0 ; i < 2 ; i++ )
++ {
++ /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++ Position += Increment ;
++ }
++ return( 1 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckBanks */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_CheckBanks(int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ ULONG Increment , Position ;
++
++ Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + XGINew_DataBusWidth / 64 + 2 ) ;
++
++ for( i = 0 , Position = 0 ; i < 4 ; i++ )
++ {
++ /* pVBInfo->FBAddr[ Position ] = Position ; */
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++ Position += Increment ;
++ }
++
++ for( i = 0 , Position = 0 ; i < 4 ; i++ )
++ {
++ /* if (pVBInfo->FBAddr[ Position ] != Position ) */
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++ Position += Increment ;
++ }
++ return( 1 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckRank */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_CheckRank(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ ULONG Increment , Position ;
++
++ Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
++ DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
++
++ for( i = 0 , Position = 0 ; i < 2 ; i++ )
++ {
++ /* pVBInfo->FBAddr[ Position ] = Position ; */
++ /* *( ( PULONG )( pVBInfo->FBAddr ) ) = Position ; */
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++ Position += Increment ;
++ }
++
++ for( i = 0 , Position = 0 ; i < 2 ; i++ )
++ {
++ /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
++ /* if ( ( *( PULONG )( pVBInfo->FBAddr ) ) != Position ) */
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++ Position += Increment ;
++ }
++ return( 1 );
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckDDRRank */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_CheckDDRRank(int RankNo, int index,
++ const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ ULONG Increment , Position ;
++ USHORT data ;
++
++ Increment = 1 << ( DRAMTYPE_TABLE[ index ][ 2 ] + DRAMTYPE_TABLE[ index ][ 1 ] +
++ DRAMTYPE_TABLE[ index ][ 0 ] + XGINew_DataBusWidth / 64 + RankNo ) ;
++
++ Increment += Increment / 2 ;
++
++ Position = 0;
++ *( ( PULONG )( pVBInfo->FBAddr + Position + 0 ) ) = 0x01234567 ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position + 1 ) ) = 0x456789AB ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position + 2 ) ) = 0x55555555 ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position + 3 ) ) = 0x55555555 ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position + 4 ) ) = 0xAAAAAAAA ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position + 5 ) ) = 0xAAAAAAAA ;
++
++ if ( ( *( PULONG )( pVBInfo->FBAddr + 1 ) ) == 0x456789AB )
++ return( 1 ) ;
++
++ if ( ( *( PULONG )( pVBInfo->FBAddr + 0 ) ) == 0x01234567 )
++ return( 0 ) ;
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) ;
++ data &= 0xF3 ;
++ data |= 0x0E ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ;
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 ) ;
++ data += 0x20 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , data ) ;
++
++ return( 1 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckRanks */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_CheckRanks(int RankNo, int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int r ;
++
++ for( r = RankNo ; r >= 1 ; r-- )
++ {
++ if ( !XGINew_CheckRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
++ return( 0 ) ;
++ }
++
++ if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
++ return( 0 ) ;
++
++ if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
++ return( 0 ) ;
++
++ return( 1 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckDDRRanks */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_CheckDDRRanks(int RankNo, int index,
++ const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int r ;
++
++ for( r = RankNo ; r >= 1 ; r-- )
++ {
++ if ( !XGINew_CheckDDRRank( r , index , DRAMTYPE_TABLE, pVBInfo ) )
++ return( 0 ) ;
++ }
++
++ if ( !XGINew_CheckBanks( index , DRAMTYPE_TABLE, pVBInfo ) )
++ return( 0 ) ;
++
++ if ( !XGINew_CheckColumn( index , DRAMTYPE_TABLE, pVBInfo ) )
++ return( 0 ) ;
++
++ return( 1 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_SDRSizing(PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ UCHAR j ;
++
++ for( i = 0 ; i < 13 ; i++ )
++ {
++ XGINew_SetDRAMSizingType( i , XGINew_SDRDRAM_TYPE , pVBInfo) ;
++
++ for( j = 2 ; j > 0 ; j-- )
++ {
++ if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_SDRDRAM_TYPE , pVBInfo) )
++ continue ;
++ else
++ {
++ if ( XGINew_CheckRanks( j , i , XGINew_SDRDRAM_TYPE, pVBInfo) )
++ return( 1 ) ;
++ }
++ }
++ }
++ return( 0 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMSizeReg */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT XGINew_SetDRAMSizeReg(int index, const USHORT DRAMTYPE_TABLE[][5],
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data = 0 , memsize = 0 ;
++ int RankSize ;
++ UCHAR ChannelNo ;
++
++ RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 32 ;
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 ) ;
++ data &= 0x80 ;
++
++ if ( data == 0x80 )
++ RankSize *= 2 ;
++
++ data = 0 ;
++
++ if( XGINew_ChannelAB == 3 )
++ ChannelNo = 4 ;
++ else
++ ChannelNo = XGINew_ChannelAB ;
++
++ if ( ChannelNo * RankSize <= 256 )
++ {
++ while( ( RankSize >>= 1 ) > 0 )
++ {
++ data += 0x10 ;
++ }
++
++ memsize = data >> 4 ;
++
++ /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
++
++ /* data |= XGINew_ChannelAB << 2 ; */
++ /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , data ) ; */
++
++ /* should delay */
++ /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
++ }
++ return( memsize ) ;
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMSize20Reg */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT XGINew_SetDRAMSize20Reg( int index , USHORT DRAMTYPE_TABLE[][ 5 ], PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data = 0 , memsize = 0 ;
++ int RankSize ;
++ UCHAR ChannelNo ;
++
++ RankSize = DRAMTYPE_TABLE[ index ][ 3 ] * XGINew_DataBusWidth / 8 ;
++ data = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x13 ) ;
++ data &= 0x80 ;
++
++ if ( data == 0x80 )
++ RankSize *= 2 ;
++
++ data = 0 ;
++
++ if( XGINew_ChannelAB == 3 )
++ ChannelNo = 4 ;
++ else
++ ChannelNo = XGINew_ChannelAB ;
++
++ if ( ChannelNo * RankSize <= 256 )
++ {
++ while( ( RankSize >>= 1 ) > 0 )
++ {
++ data += 0x10 ;
++ }
++
++ memsize = data >> 4 ;
++
++ /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x14 ) & 0x0F ) | ( data & 0xF0 ) ) ;
++ DelayUS( 15 ) ;
++
++ /* data |= XGINew_ChannelAB << 2 ; */
++ /* data |= ( XGINew_DataBusWidth / 64 ) << 1 ; */
++ /* XGINew_SetReg1( pVBInfo->P3c4 , 0x14 , data ) ; */
++
++ /* should delay */
++ /* XGINew_SetDRAMModeRegister340( pVBInfo ) ; */
++ }
++ return( memsize ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_ReadWriteRest */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_ReadWriteRest( USHORT StopAddr, USHORT StartAddr,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ ULONG Position = 0 ;
++
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++
++ for( i = StartAddr ; i <= StopAddr ; i++ )
++ {
++ Position = 1 << i ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++ }
++
++ DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
++
++ Position = 0 ;
++
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++
++ for( i = StartAddr ; i <= StopAddr ; i++ )
++ {
++ Position = 1 << i ;
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++ }
++ return( 1 ) ;
++}
++
++
++/*--------------------------------------------------------------------- */
++/* Function : XGI45New_ReadWriteRest */
++/* Input : */
++/* Output : */
++/* Description : return 0 : fail, 1 : pass */
++/*--------------------------------------------------------------------- */
++int XGI45New_ReadWriteRest(USHORT StopAddr, USHORT StartAddr,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ ULONG Position = 0 ;
++
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++
++ for( i = StartAddr ; i <= StopAddr ; i++ )
++ {
++ Position = 1 << i ;
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++ }
++
++ if ( XGINew_ChannelAB == 4 )
++ {
++ Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
++ *( ( PULONG )( pVBInfo->FBAddr + Position ) ) = Position ;
++ }
++
++ DelayUS( 500 ) ; /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
++
++ Position = 0 ;
++
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++
++ for( i = StartAddr ; i <= StopAddr ; i++ )
++ {
++ Position = 1 << i ;
++ if ( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position )
++ return( 0 ) ;
++ }
++
++ if ( XGINew_ChannelAB == 4 )
++ {
++ Position = ( 1 << StopAddr ) + ( 1 << ( StopAddr - 1 ) );
++ if( ( *( PULONG )( pVBInfo->FBAddr + Position ) ) != Position );
++ return( 0 ) ;
++ }
++ return( 1 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckFrequence */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++UCHAR XGINew_CheckFrequence(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR data ;
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
++
++ if ( ( data & 0x10 ) == 0 )
++ {
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x39 ) ;
++ data = ( data & 0x02 ) >> 1 ;
++ return( data ) ;
++ }
++ else
++ return( data & 0x01 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_CheckChannel */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_CheckChannel(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR i, data ;
++
++ switch( HwDeviceExtension->jChipType )
++ {
++ case XG20:
++ case XG21:
++ data = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x97 ) ;
++ data = data & 0x01;
++ XGINew_ChannelAB = 1 ; /* XG20 "JUST" one channel */
++
++ if ( data == 0 ) /* Single_32_16 */
++ {
++ /* Jong 10/03/2007 */
++ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x1000000)
++ {
++
++ XGINew_DataBusWidth = 32 ; /* 32 bits */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 32bit */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
++ DelayUS( 15 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ /* Jong 10/03/2007 */
++ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ; /* 22bit + 1 rank + 32bit */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
++ DelayUS( 15 ) ;
++
++ if ( XGINew_ReadWriteRest( 23 , 23 , pVBInfo ) == 1 )
++ return ;
++ }
++ }
++
++ /* Jong 10/03/2007 */
++ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
++ {
++ XGINew_DataBusWidth = 16 ; /* 16 bits */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ; /* 22bit + 2 rank + 16bit */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
++ DelayUS( 15 ) ;
++
++ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
++ return ;
++ else
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
++
++ DelayUS( 15 ) ;
++ }
++ }
++ else /* Dual_16_8 */
++ {
++ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x800000)
++ {
++
++ XGINew_DataBusWidth = 16 ; /* 16 bits */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x41 ) ;
++ DelayUS( 15 ) ;
++
++ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
++ return ;
++
++ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
++ {
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x31 ) ;
++ DelayUS( 15 ) ;
++
++ if ( XGINew_ReadWriteRest( 22 , 22 , pVBInfo ) == 1 )
++ return ;
++ }
++ }
++
++
++ if (( HwDeviceExtension->ulVideoMemorySize - 1 ) > 0x400000)
++ {
++ XGINew_DataBusWidth = 8 ; /* 8 bits */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xB1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
++ DelayUS( 15 ) ;
++
++ if ( XGINew_ReadWriteRest( 22 , 21 , pVBInfo ) == 1 )
++ return ;
++ else
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x31 ) ;
++ DelayUS( 15 ) ;
++ }
++ }
++ break ;
++
++ case XG27:
++ XGINew_DataBusWidth = 16 ; /* 16 bits */
++ XGINew_ChannelAB = 1 ; /* Single channel */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x51 ) ; /* 32Mx16 bit*/
++ break ;
++
++ case XG41:
++ if ( XGINew_CheckFrequence(pVBInfo) == 1 )
++ {
++ XGINew_DataBusWidth = 32 ; /* 32 bits */
++ XGINew_ChannelAB = 3 ; /* Quad Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
++
++ if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 2 ; /* Dual channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x49 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 3 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
++
++ if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
++ return ;
++ else
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x39 ) ;
++ }
++ else
++ { /* DDR */
++ XGINew_DataBusWidth = 64 ; /* 64 bits */
++ XGINew_ChannelAB = 2 ; /* Dual channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
++
++ if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 1 ; /* Single channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x53 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 2 ; /* Dual channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 1 ; /* Single channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
++
++ if ( XGINew_ReadWriteRest( 8 , 4 , pVBInfo ) == 1 )
++ return ;
++ else
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x43 ) ;
++ }
++
++ break ;
++
++ case XG42:
++/*
++ XG42 SR14 D[3] Reserve
++ D[2] = 1, Dual Channel
++ = 0, Single Channel
++
++ It's Different from Other XG40 Series.
++*/
++ if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII, DDR2x */
++ {
++ XGINew_DataBusWidth = 32 ; /* 32 bits */
++ XGINew_ChannelAB = 2 ; /* 2 Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x44 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x34 ) ;
++ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 1 ; /* Single Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x40 ) ;
++
++ if ( XGINew_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
++ return ;
++ else
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x30 ) ;
++ }
++ }
++ else
++ { /* DDR */
++ XGINew_DataBusWidth = 64 ; /* 64 bits */
++ XGINew_ChannelAB = 1 ; /* 1 channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x52 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++ else
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x42 ) ;
++ }
++ }
++
++ break ;
++
++ case XG45:
++
++ XGINew_DataBusWidth = 64 ; /* 64 bits */
++ XGINew_ChannelAB = 4 ; /* 3+1 Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
++
++ if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 3 ; /* 3 Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
++
++ if ( XGI45New_ReadWriteRest( 26 , 24 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 2 ; /* 2 Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
++
++ if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 1 ; /* 1 Channel */
++ for ( i = 0; i <= 2; i++)
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
++
++ if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++ }
++
++ XGINew_ChannelAB = 3 ; /* 3 Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x58 ) ;
++
++ if ( XGI45New_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 2 ; /* 2 Channel */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x54 ) ;
++
++ if ( XGI45New_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 1 ; /* 1 Channel */
++ for ( i = 0; i <= 2; i++)
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x50+i ) ;
++
++ if ( XGI45New_ReadWriteRest( 23 , 22 , pVBInfo ) == 1 )
++ return ;
++ }
++ break ;
++
++ default: /* XG40 */
++
++ if ( XGINew_CheckFrequence(pVBInfo) == 1 ) /* DDRII */
++ {
++ XGINew_DataBusWidth = 32 ; /* 32 bits */
++ XGINew_ChannelAB = 3 ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4C ) ;
++
++ if ( XGINew_ReadWriteRest( 25 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGINew_ChannelAB = 2 ; /* 2 channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x48 ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ return ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x3C ) ;
++
++ if ( XGINew_ReadWriteRest( 24 , 23 , pVBInfo ) == 1 )
++ XGINew_ChannelAB = 3 ; /* 4 channels */
++ else
++ {
++ XGINew_ChannelAB = 2 ; /* 2 channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x38 ) ;
++ }
++ }
++ else
++ { /* DDR */
++ XGINew_DataBusWidth = 64 ; /* 64 bits */
++ XGINew_ChannelAB = 2 ; /* 2 channels */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0xA1 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x5A ) ;
++
++ if ( XGINew_ReadWriteRest( 25 , 24 , pVBInfo ) == 1 )
++ return ;
++ else
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x13 , 0x21 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x14 , 0x4A ) ;
++ }
++ }
++ break ;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDRSizing340 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_DDRSizing340( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ USHORT memsize , addr ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
++ XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
++
++ /* Jong 10/03/2007 */
++ if ( HwDeviceExtension->jChipType >= XG20 )
++ {
++ for( i = 0 ; i < 12 ; i++ )
++ {
++ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
++ memsize = XGINew_SetDRAMSize20Reg( i , XGINew_DDRDRAM_TYPE20, pVBInfo ) ;
++ if ( memsize == 0 )
++ continue ;
++
++ addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
++ if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
++ continue ;
++
++ if ( XGINew_ReadWriteRest( addr , 5, pVBInfo ) == 1 )
++ return( 1 ) ;
++ }
++ }
++ else
++ {
++ for( i = 0 ; i < 4 ; i++ )
++ {
++ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
++ memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
++ if ( memsize == 0 )
++ continue ;
++
++ addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
++ if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
++ continue ;
++
++ if ( XGINew_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
++ return( 1 ) ;
++ }
++ }
++ return( 0 ) ;
++}
++
++
++/*--------------------------------------------------------------------- */
++/* Function : XGINew_DDRSizingXG45 */
++/* Input : */
++/* Output : */
++/* Description : */
++/*--------------------------------------------------------------------- */
++int XGINew_DDRSizingXG45( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ USHORT memsize , addr ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x15 , 0x00 ) ; /* noninterleaving */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1C , 0x00 ) ; /* nontiling */
++ XGINew_CheckChannel( HwDeviceExtension, pVBInfo ) ;
++
++ for( i = 0 ; i < 4 ; i++ )
++ {
++ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
++ memsize = XGINew_SetDRAMSizeReg( i , XGINew_DDRDRAM_TYPE340, pVBInfo ) ;
++ if ( memsize == 0 )
++ continue ;
++
++ addr = memsize + ( XGINew_ChannelAB - 2 ) + 20 ;
++ if ( ( HwDeviceExtension->ulVideoMemorySize - 1 ) < ( ULONG )( 1 << addr ) )
++ continue ;
++
++ if ( XGI45New_ReadWriteRest( addr , 9, pVBInfo ) == 1 )
++ return( 1 ) ;
++ }
++ return( 0 ) ;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDRSizing */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++int XGINew_DDRSizing(PVB_DEVICE_INFO pVBInfo)
++{
++ int i ;
++ UCHAR j ;
++
++ for( i = 0 ; i < 4 ; i++ )
++ {
++ XGINew_SetDRAMSizingType( i , XGINew_DDRDRAM_TYPE, pVBInfo ) ;
++ XGINew_DisableChannelInterleaving( i , XGINew_DDRDRAM_TYPE , pVBInfo) ;
++ for( j = 2 ; j > 0 ; j-- )
++ {
++ XGINew_SetDDRChannel( i , j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE , pVBInfo ) ;
++ if ( !XGINew_SetRank( i , ( UCHAR )j , XGINew_ChannelAB , XGINew_DDRDRAM_TYPE, pVBInfo ) )
++ continue ;
++ else
++ {
++ if ( XGINew_CheckDDRRanks( j , i , XGINew_DDRDRAM_TYPE, pVBInfo ) )
++ return( 1 ) ;
++ }
++ }
++ }
++ return( 0 ) ;
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetMemoryClock */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SetMemoryClock( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++#ifndef LINUX_XF86
++ UCHAR tempal ;
++#endif
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x28 , pVBInfo->MCLKData[ XGINew_RAMType ].SR28 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x29 , pVBInfo->MCLKData[ XGINew_RAMType ].SR29 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2A , pVBInfo->MCLKData[ XGINew_RAMType ].SR2A ) ;
++
++
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , pVBInfo->ECLKData[ XGINew_RAMType ].SR2E ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , pVBInfo->ECLKData[ XGINew_RAMType ].SR2F ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , pVBInfo->ECLKData[ XGINew_RAMType ].SR30 ) ;
++
++ /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
++ /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
++ if ( HwDeviceExtension->jChipType == XG42 )
++ {
++ if ( ( pVBInfo->MCLKData[ XGINew_RAMType ].SR28 == 0x1C ) && ( pVBInfo->MCLKData[ XGINew_RAMType ].SR29 == 0x01 )
++ && ( ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x1C ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) )
++ || ( ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2E == 0x22 ) && ( pVBInfo->ECLKData[ XGINew_RAMType ].SR2F == 0x01 ) ) ) )
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 , ( ( UCHAR )XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x32 ) & 0xFC ) | 0x02 ) ;
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* input : dx ,valid value : CR or second chip's CR */
++/* */
++/* SetPowerConsume : */
++/* Description: reduce 40/43 power consumption in first chip or */
++/* in second chip, assume CR A1 D[6]="1" in this case */
++/* output : none */
++/* --------------------------------------------------------------------- */
++void SetPowerConsume ( PXGI_HW_DEVICE_INFO HwDeviceExtension , USHORT XGI_P3d4Port )
++{
++ ULONG lTemp ;
++ UCHAR bTemp;
++
++ HwDeviceExtension->pQueryVGAConfigSpace( HwDeviceExtension , 0x08 , 0 , &lTemp ) ; /* Get */
++ if ((lTemp&0xFF)==0)
++ {
++ /* set CR58 D[5]=0 D[3]=0 */
++ XGI_SetRegAND((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 ) ;
++ bTemp = (UCHAR) XGI_GetReg((XGIIOADDRESS) XGI_P3d4Port , 0xCB ) ;
++ if (bTemp&0x20)
++ {
++ if (!(bTemp&0x10))
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x20 ) ; /* CR58 D[5]=1 D[3]=0 */
++ }
++ else
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) XGI_P3d4Port , 0x58 , 0xD7 , 0x08 ) ; /* CR58 D[5]=0 D[3]=1 */
++ }
++
++ }
++
++ }
++}
++
++
++void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++
++ /* ULONG ROMAddr = (ULONG)HwDeviceExtension->pjVirtualRomBase; */
++ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
++ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
++ pVBInfo->BaseAddr = ( USHORT )HwDeviceExtension->pjIOAddress ;
++ pVBInfo->RelIO = HwDeviceExtension->pjIOAddress - 0x30;
++ pVBInfo->ISXPDOS = 0 ;
++
++ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
++ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
++ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
++ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
++ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
++ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
++ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
++ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
++ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
++ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
++ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
++ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
++ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
++ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
++ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
++ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
++ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
++
++ pVBInfo->IF_DEF_LCDA = 1 ;
++ pVBInfo->IF_DEF_VideoCapture = 0 ;
++ pVBInfo->IF_DEF_ScaleLCD = 0 ;
++ pVBInfo->IF_DEF_OEMUtil = 0 ;
++ pVBInfo->IF_DEF_PWD = 0 ;
++
++ if ( HwDeviceExtension->jChipType >= XG20 ) /* kuku 2004/06/25 */
++ {
++ pVBInfo->IF_DEF_YPbPr = 0 ;
++ pVBInfo->IF_DEF_HiVision = 0 ;
++ pVBInfo->IF_DEF_CRT2Monitor = 0 ;
++ }
++ else if ( HwDeviceExtension->jChipType >= XG40 )
++ {
++ pVBInfo->IF_DEF_YPbPr = 1 ;
++ pVBInfo->IF_DEF_HiVision = 1 ;
++ pVBInfo->IF_DEF_CRT2Monitor = 1 ;
++ }
++ else
++ {
++ pVBInfo->IF_DEF_YPbPr = 1 ;
++ pVBInfo->IF_DEF_HiVision = 1 ;
++ pVBInfo->IF_DEF_CRT2Monitor = 0 ;
++ }
++
++ if ( (HwDeviceExtension->jChipType != XG20) &&
++ (HwDeviceExtension->jChipType != XG21) &&
++ (HwDeviceExtension->jChipType != XG27)) {
++ /* alan, disable VideoCapture */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
++ }
++
++ XGI_GetVBType( pVBInfo ) ; /* Run XGI_GetVBType before InitTo330Pointer */
++ InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : ReadVBIOSTablData */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void ReadVBIOSTablData( UCHAR ChipType , PVB_DEVICE_INFO pVBInfo)
++{
++#ifndef LINUX_XF86
++ ULONG ulOffset ;
++ UCHAR temp , index , l ;
++#endif
++ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
++ ULONG i ;
++ UCHAR j , k ;
++ ULONG ii , jj ;
++
++ i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ; /* UniROM */
++ if ( i != 0 )
++ UNIROM = 1 ;
++
++ ii = 0x90 ;
++ for( jj = 0x00 ; jj < 0x08 ; jj++ )
++ {
++ pVBInfo->MCLKData[ jj ].SR28 = pVideoMemory[ ii ] ;
++ pVBInfo->MCLKData[ jj ].SR29 = pVideoMemory[ ii + 1] ;
++ pVBInfo->MCLKData[ jj ].SR2A = pVideoMemory[ ii + 2] ;
++ pVBInfo->MCLKData[ jj ].CLOCK = pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
++ ii += 0x05 ;
++ }
++
++ ii = 0xB8 ;
++ for( jj = 0x00 ; jj < 0x08 ; jj++ )
++ {
++ pVBInfo->ECLKData[ jj ].SR2E = pVideoMemory[ ii ] ;
++ pVBInfo->ECLKData[ jj ].SR2F=pVideoMemory[ ii + 1 ] ;
++ pVBInfo->ECLKData[ jj ].SR30= pVideoMemory[ ii + 2 ] ;
++ pVBInfo->ECLKData[ jj ].CLOCK= pVideoMemory[ ii + 3 ] | ( pVideoMemory[ ii + 4 ] << 8 ) ;
++ ii += 0x05 ;
++ }
++
++ /* Volari customize data area start */
++ /* if ( ChipType == XG40 ) */
++ if ( ChipType >= XG40 )
++ {
++ ii = 0xE0 ;
++ for( jj = 0x00 ; jj < 0x03 ; jj++ )
++ {
++ pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR13, SR14, and SR18 */
++ pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
++ pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
++ pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
++ pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
++ pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
++ pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
++ pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
++ ii += 0x08 ;
++ }
++ ii = 0x110 ;
++ jj = 0x03 ;
++ pVBInfo->SR15[ jj ][ 0 ] = pVideoMemory[ ii ] ; /* SR1B */
++ pVBInfo->SR15[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
++ pVBInfo->SR15[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
++ pVBInfo->SR15[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
++ pVBInfo->SR15[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
++ pVBInfo->SR15[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
++ pVBInfo->SR15[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
++ pVBInfo->SR15[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
++
++ pVBInfo->SR07 = pVideoMemory[0x74];
++ pVBInfo->SR1F = pVideoMemory[0x75];
++ pVBInfo->SR21 = pVideoMemory[0x76];
++ pVBInfo->SR22 = pVideoMemory[0x77];
++ pVBInfo->SR23 = pVideoMemory[0x78];
++ pVBInfo->SR24 = pVideoMemory[0x79];
++ pVBInfo->SR25[0] = pVideoMemory[0x7A];
++ pVBInfo->SR31 = pVideoMemory[0x7B];
++ pVBInfo->SR32 = pVideoMemory[0x7C];
++ pVBInfo->SR33 = pVideoMemory[0x7D];
++ ii = 0xF8 ;
++
++ for( jj = 0 ; jj < 3 ; jj++ )
++ {
++ pVBInfo->CR40[ jj ][ 0 ] = pVideoMemory[ ii ] ;
++ pVBInfo->CR40[ jj ][ 1 ] = pVideoMemory[ ii + 1 ] ;
++ pVBInfo->CR40[ jj ][ 2 ] = pVideoMemory[ ii + 2 ] ;
++ pVBInfo->CR40[ jj ][ 3 ] = pVideoMemory[ ii + 3 ] ;
++ pVBInfo->CR40[ jj ][ 4 ] = pVideoMemory[ ii + 4 ] ;
++ pVBInfo->CR40[ jj ][ 5 ] = pVideoMemory[ ii + 5 ] ;
++ pVBInfo->CR40[ jj ][ 6 ] = pVideoMemory[ ii + 6 ] ;
++ pVBInfo->CR40[ jj ][ 7 ] = pVideoMemory[ ii + 7 ] ;
++ ii += 0x08 ;
++ }
++
++ ii = 0x118 ;
++ for( j = 3 ; j < 24 ; j++ )
++ {
++ pVBInfo->CR40[ j ][ 0 ] = pVideoMemory[ ii ] ;
++ pVBInfo->CR40[ j ][ 1 ] = pVideoMemory[ ii + 1 ] ;
++ pVBInfo->CR40[ j ][ 2 ] = pVideoMemory[ ii + 2 ] ;
++ pVBInfo->CR40[ j ][ 3 ] = pVideoMemory[ ii + 3 ] ;
++ pVBInfo->CR40[ j ][ 4 ] = pVideoMemory[ ii + 4 ] ;
++ pVBInfo->CR40[ j ][ 5 ] = pVideoMemory[ ii + 5 ] ;
++ pVBInfo->CR40[ j ][ 6 ] = pVideoMemory[ ii + 6 ] ;
++ pVBInfo->CR40[ j ][ 7 ] = pVideoMemory[ ii + 7 ] ;
++ ii += 0x08 ;
++ }
++
++ i = pVideoMemory[ 0x1C0 ] | ( pVideoMemory[ 0x1C1 ] << 8 ) ;
++
++ for( j = 0 ; j < 8 ; j++ )
++ {
++ for( k = 0 ; k < 4 ; k++ )
++ pVBInfo->CR6B[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
++ }
++
++ i = pVideoMemory[ 0x1C2 ] | ( pVideoMemory[ 0x1C3 ] << 8 ) ;
++
++ if (ChipType == XG45)
++ {
++ for( j = 0 ; j < 8 ; j++ )
++ {
++ pVBInfo->XG45CR6E[ j ] = pVideoMemory[i] ;
++ }
++ }
++ else
++ {
++ for( j = 0 ; j < 8 ; j++ )
++ {
++ for( k = 0 ; k < 4 ; k++ )
++ pVBInfo->CR6E[ j ][ k ] = pVideoMemory[ i + 4 * j + k ] ;
++ }
++ }
++
++ i = pVideoMemory[ 0x1C4 ] | ( pVideoMemory[ 0x1C5 ] << 8 ) ;
++ if (ChipType == XG45)
++ {
++ for( j = 0 ; j < 8 ; j++ )
++ {
++ pVBInfo->XG45CR6F[ j ] = pVideoMemory[i] ;
++ }
++ }
++ else
++ {
++ for( j = 0 ; j < 8 ; j++ )
++ {
++ for( k = 0 ; k < 32 ; k++ )
++ pVBInfo->CR6F[ j ][ k ] = pVideoMemory[ i + 32 * j + k ] ;
++ }
++ }
++
++ i = pVideoMemory[ 0x1C6 ] | ( pVideoMemory[ 0x1C7 ] << 8 ) ;
++
++ for( j = 0 ; j < 8 ; j++ )
++ {
++ for( k = 0 ; k < 2 ; k++ )
++ pVBInfo->CR89[ j ][ k ] = pVideoMemory[ i + 2 * j + k ] ;
++ }
++
++ i = pVideoMemory[ 0x1C8 ] | ( pVideoMemory[ 0x1C9 ] << 8 ) ;
++ for( j = 0 ; j < 12 ; j++ )
++ pVBInfo->AGPReg[ j ] = pVideoMemory[ i + j ] ;
++
++ i = pVideoMemory[ 0x1CF ] | ( pVideoMemory[ 0x1D0 ] << 8 ) ;
++ for( j = 0 ; j < 4 ; j++ )
++ pVBInfo->SR16[ j ] = pVideoMemory[ i + j ] ;
++
++ /* Jong 10/03/2007 */
++ /*
++ pVBInfo->CRCF = pVideoMemory[0x1CA];
++ pVBInfo->DRAMTypeDefinition = pVideoMemory[0x1CB];
++ pVBInfo->I2CDefinition = pVideoMemory[0x1D1];
++ if ( ChipType == XG20 )
++ pVBInfo->CR97 = pVideoMemory[0x1D2]; */
++ if ( ChipType == XG21 )
++ {
++ if (pVideoMemory[ 0x67 ] & 0x80)
++ {
++ *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
++ }
++ if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
++ {
++ *pVBInfo->pCR2E = pVideoMemory[ i + 4 ] ;
++ *pVBInfo->pCR2F = pVideoMemory[ i + 5 ] ;
++ *pVBInfo->pCR46 = pVideoMemory[ i + 6 ] ;
++ *pVBInfo->pCR47 = pVideoMemory[ i + 7 ] ;
++ }
++ }
++
++ if ( ChipType == XG27 )
++ {
++ jj = i+j;
++ for( i = 0 ; i <= 0xB ; i++,jj++ )
++ pVBInfo->pCRD0[i] = pVideoMemory[ jj ] ;
++ for( i = 0x0 ; i <= 0x1 ; i++,jj++ )
++ pVBInfo->pCRDE[i] = pVideoMemory[ jj ] ;
++
++ *pVBInfo->pSR40 = pVideoMemory[ jj ] ;
++ jj++;
++ *pVBInfo->pSR41 = pVideoMemory[ jj ] ;
++
++ if (pVideoMemory[ 0x67 ] & 0x80)
++ {
++ *pVBInfo->pDVOSetting = pVideoMemory[ 0x67 ];
++ }
++ if ( (pVideoMemory[ 0x67 ] & 0xC0) == 0xC0 )
++ {
++ jj++;
++ *pVBInfo->pCR2E = pVideoMemory[ jj ] ;
++ *pVBInfo->pCR2F = pVideoMemory[ jj + 1 ] ;
++ *pVBInfo->pCR46 = pVideoMemory[ jj + 2 ] ;
++ *pVBInfo->pCR47 = pVideoMemory[ jj + 3 ] ;
++ }
++
++ }
++
++ pVBInfo->CRCF = pVideoMemory[ 0x1CA ] ;
++ pVBInfo->DRAMTypeDefinition = pVideoMemory[ 0x1CB ] ;
++ pVBInfo->I2CDefinition = pVideoMemory[ 0x1D1 ] ;
++ if ( ChipType >= XG20 )
++ {
++ pVBInfo->CR97 = pVideoMemory[ 0x1D2 ] ;
++ if ( ChipType == XG27 )
++ {
++ *pVBInfo->pSR36 = pVideoMemory[ 0x1D3 ] ;
++ *pVBInfo->pCR8F = pVideoMemory[ 0x1D5 ] ;
++ }
++ }
++ }
++ /* Volari customize data area end */
++
++ if ( ChipType == XG21 )
++ {
++ pVBInfo->IF_DEF_LVDS = 0 ;
++ if (pVideoMemory[ 0x65 ] & 0x1)
++ {
++ pVBInfo->IF_DEF_LVDS = 1 ;
++ i = pVideoMemory[ 0x316 ] | ( pVideoMemory[ 0x317 ] << 8 );
++ j = pVideoMemory[ i-1 ] ;
++ if ( j != 0xff )
++ {
++ k = 0;
++ do
++ {
++ pVBInfo->XG21_LVDSCapList[k].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
++ pVBInfo->XG21_LVDSCapList[k].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].VCLKData1 = pVideoMemory[ i + 18 ] ;
++ pVBInfo->XG21_LVDSCapList[k].VCLKData2 = pVideoMemory[ i + 19 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S1 = pVideoMemory[ i + 20 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S2 = pVideoMemory[ i + 21 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S3 = pVideoMemory[ i + 22 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S4 = pVideoMemory[ i + 23 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S5 = pVideoMemory[ i + 24 ] ;
++ i += 25;
++ j--;
++ k++;
++ } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
++ }
++ else
++ {
++ pVBInfo->XG21_LVDSCapList[0].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
++ pVBInfo->XG21_LVDSCapList[0].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].VCLKData1 = pVideoMemory[ i + 18 ] ;
++ pVBInfo->XG21_LVDSCapList[0].VCLKData2 = pVideoMemory[ i + 19 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S1 = pVideoMemory[ i + 20 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S2 = pVideoMemory[ i + 21 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S3 = pVideoMemory[ i + 22 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S4 = pVideoMemory[ i + 23 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S5 = pVideoMemory[ i + 24 ] ;
++ }
++ }
++ pVBInfo->IF_DEF_CH7007 = 0 ;
++ if ( ( pVideoMemory[ 0x65 ] & 0x02 ) ) /* For XG21 CH7007 */
++ {
++ /* VideoDebugPrint((0, "ReadVBIOSTablData: pVideoMemory[ 0x65 ] =%x\n",pVideoMemory[ 0x65 ])); */
++ pVBInfo->IF_DEF_CH7007 = 1 ; /* [Billy] 07/05/03 */
++ }
++ }
++
++ if ( ChipType == XG27 )
++ {
++ if (pVideoMemory[ 0x65 ] & 0x1)
++ {
++ i = pVideoMemory[ 0x316 ] | ( pVideoMemory[ 0x317 ] << 8 );
++ j = pVideoMemory[ i-1 ] ;
++ if ( j != 0xff )
++ {
++ k = 0;
++ do
++ {
++ pVBInfo->XG21_LVDSCapList[k].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
++ pVBInfo->XG21_LVDSCapList[k].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[k].VCLKData1 = pVideoMemory[ i + 18 ] ;
++ pVBInfo->XG21_LVDSCapList[k].VCLKData2 = pVideoMemory[ i + 19 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S1 = pVideoMemory[ i + 20 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S2 = pVideoMemory[ i + 21 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S3 = pVideoMemory[ i + 22 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S4 = pVideoMemory[ i + 23 ] ;
++ pVBInfo->XG21_LVDSCapList[k].PSC_S5 = pVideoMemory[ i + 24 ] ;
++ i += 25;
++ j--;
++ k++;
++ } while ( (j>0) && ( k < (sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct)) ) );
++ }
++ else
++ {
++ pVBInfo->XG21_LVDSCapList[0].LVDS_Capability = pVideoMemory[ i ] | ( pVideoMemory[ i + 1 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHT = pVideoMemory[ i + 2 ] | ( pVideoMemory[ i + 3 ] << 8 ) ;
++ pVBInfo->XG21_LVDSCapList[0].LVDSVT = pVideoMemory[ i + 4 ] | ( pVideoMemory[ i + 5 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHDE = pVideoMemory[ i + 6 ] | ( pVideoMemory[ i + 7 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSVDE = pVideoMemory[ i + 8 ] | ( pVideoMemory[ i + 9 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHFP = pVideoMemory[ i + 10 ] | ( pVideoMemory[ i + 11 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSVFP = pVideoMemory[ i + 12 ] | ( pVideoMemory[ i + 13 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC = pVideoMemory[ i + 14 ] | ( pVideoMemory[ i + 15 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC = pVideoMemory[ i + 16 ] | ( pVideoMemory[ i + 17 ] << 8 );
++ pVBInfo->XG21_LVDSCapList[0].VCLKData1 = pVideoMemory[ i + 18 ] ;
++ pVBInfo->XG21_LVDSCapList[0].VCLKData2 = pVideoMemory[ i + 19 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S1 = pVideoMemory[ i + 20 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S2 = pVideoMemory[ i + 21 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S3 = pVideoMemory[ i + 22 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S4 = pVideoMemory[ i + 23 ] ;
++ pVBInfo->XG21_LVDSCapList[0].PSC_S5 = pVideoMemory[ i + 24 ] ;
++ }
++ }
++ }
++
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_DDR1x_MRS_XG20 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_DDR1x_MRS_XG20( USHORT P3c4 , PVB_DEVICE_INFO pVBInfo)
++{
++
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ DelayUS( 60 ) ;
++
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x40 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x80 ) ;
++ DelayUS( 60 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x01 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
++ DelayUS( 1000 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x03 ) ;
++ DelayUS( 500 ) ;
++ /* XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , 0x31 ) ; */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x18 , pVBInfo->SR15[ 2 ][ XGINew_RAMType ] ) ; /* SR18 */
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x19 , 0x00 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x03 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x16 , 0x83 ) ;
++ XGI_SetReg((XGIIOADDRESS) P3c4 , 0x1B , 0x00 ) ;
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_SetDRAMModeRegister_XG20 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void XGINew_SetDRAMModeRegister_XG20(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++#ifndef LINUX_XF86
++ UCHAR data ;
++#endif
++
++ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
++
++ if ( XGINew_Get340DRAMType( HwDeviceExtension, pVBInfo) == 0 )
++ XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
++ else
++ XGINew_DDR2x_MRS_340( HwDeviceExtension, pVBInfo->P3c4, pVBInfo ) ;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , 0x03 ) ;
++}
++
++void XGINew_SetDRAMModeRegister_XG27( PXGI_HW_DEVICE_INFO HwDeviceExtension )
++{
++#ifndef LINUX_XF86
++ UCHAR data ;
++#endif
++ VB_DEVICE_INFO VBINF;
++ PVB_DEVICE_INFO pVBInfo = &VBINF;
++ pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase ;
++ pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ;
++ pVBInfo->BaseAddr = ( USHORT )HwDeviceExtension->pjIOAddress ;
++ pVBInfo->ISXPDOS = 0 ;
++
++ pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14 ;
++ pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24 ;
++ pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10 ;
++ pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e ;
++ pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12 ;
++ pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a ;
++ pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16 ;
++ pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17 ;
++ pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18 ;
++ pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19 ;
++ pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A ;
++ pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00 ;
++ pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04 ;
++ pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10 ;
++ pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12 ;
++ pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 ;
++ pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2 ;
++
++ InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
++
++ ReadVBIOSTablData( HwDeviceExtension->jChipType , pVBInfo) ;
++
++ if ( XGINew_GetXG20DRAMType( HwDeviceExtension, pVBInfo) == 0 )
++ XGINew_DDR1x_MRS_XG20( pVBInfo->P3c4, pVBInfo ) ;
++ else
++ /*XGINew_DDR2_MRS_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo ) ;*/
++ XGINew_DDRII_Bootup_XG27( HwDeviceExtension , pVBInfo->P3c4 , pVBInfo) ;
++
++ /*XGINew_SetReg1( pVBInfo->P3c4 , 0x1B , 0x03 ) ;*/
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1B , pVBInfo->SR15[ 3 ][ XGINew_RAMType ] ) ; /* SR1B */
++
++}
++
++/* -------------------------------------------------------- */
++/* Function : XGINew_ChkSenseStatus */
++/* Input : */
++/* Output : */
++/* Description : */
++/* -------------------------------------------------------- */
++void XGINew_ChkSenseStatus ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx=0 , temp , tempcx , CR3CData;
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x32 ) ;
++
++ if ( temp & Monitor1Sense )
++ tempbx |= ActiveCRT1 ;
++ if ( temp & LCDSense )
++ tempbx |= ActiveLCD ;
++ if ( temp & Monitor2Sense )
++ tempbx |= ActiveCRT2 ;
++ if ( temp & TVSense )
++ {
++ tempbx |= ActiveTV ;
++ if ( temp & AVIDEOSense )
++ tempbx |= ( ActiveAVideo << 8 );
++ if ( temp & SVIDEOSense )
++ tempbx |= ( ActiveSVideo << 8 );
++ if ( temp & SCARTSense )
++ tempbx |= ( ActiveSCART << 8 );
++ if ( temp & HiTVSense )
++ tempbx |= ( ActiveHiTV << 8 );
++ if ( temp & YPbPrSense )
++ tempbx |= ( ActiveYPbPr << 8 );
++ }
++
++ tempcx = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
++ tempcx |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ) ;
++
++ if ( tempbx & tempcx )
++ {
++ CR3CData = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3c ) ;
++ if ( !( CR3CData & DisplayDeviceFromCMOS ) )
++ {
++ tempcx = 0x1FF0 ;
++ if (pVBInfo->SoftSetting & ModeSoftSetting) {
++ tempbx = 0x1FF0 ;
++ }
++ }
++ }
++ else
++ {
++ tempcx = 0x1FF0 ;
++ if (pVBInfo->SoftSetting & ModeSoftSetting) {
++ tempbx = 0x1FF0 ;
++ }
++ }
++
++ tempbx &= tempcx ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d , ( tempbx & 0x00FF ) ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e , ( ( tempbx & 0xFF00 ) >> 8 )) ;
++}
++/* -------------------------------------------------------- */
++/* Function : XGINew_SetModeScratch */
++/* Input : */
++/* Output : */
++/* Description : */
++/* -------------------------------------------------------- */
++void XGINew_SetModeScratch ( PXGI_HW_DEVICE_INFO HwDeviceExtension , PVB_DEVICE_INFO pVBInfo )
++{
++ USHORT temp , tempcl = 0 , tempch = 0 , CR31Data , CR38Data;
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3d ) ;
++ temp |= XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x3e ) << 8 ;
++ temp |= ( XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) & ( DriverMode >> 8) ) << 8 ;
++
++ if ( pVBInfo->IF_DEF_CRT2Monitor == 1)
++ {
++ if ( temp & ActiveCRT2 )
++ tempcl = SetCRT2ToRAMDAC ;
++ }
++
++ if ( temp & ActiveLCD )
++ {
++ tempcl |= SetCRT2ToLCD ;
++ if ( temp & DriverMode )
++ {
++ if ( temp & ActiveTV )
++ {
++ tempch = SetToLCDA | EnableDualEdge ;
++ temp ^= SetCRT2ToLCD ;
++
++ if ( ( temp >> 8 ) & ActiveAVideo )
++ tempcl |= SetCRT2ToAVIDEO ;
++ if ( ( temp >> 8 ) & ActiveSVideo )
++ tempcl |= SetCRT2ToSVIDEO ;
++ if ( ( temp >> 8 ) & ActiveSCART )
++ tempcl |= SetCRT2ToSCART ;
++
++ if ( pVBInfo->IF_DEF_HiVision == 1 )
++ {
++ if ( ( temp >> 8 ) & ActiveHiTV )
++ tempcl |= SetCRT2ToHiVisionTV ;
++ }
++
++ if ( pVBInfo->IF_DEF_YPbPr == 1 )
++ {
++ if ( ( temp >> 8 ) & ActiveYPbPr )
++ tempch |= SetYPbPr ;
++ }
++ }
++ }
++ }
++ else
++ {
++ if ( ( temp >> 8 ) & ActiveAVideo )
++ tempcl |= SetCRT2ToAVIDEO ;
++ if ( ( temp >> 8 ) & ActiveSVideo )
++ tempcl |= SetCRT2ToSVIDEO ;
++ if ( ( temp >> 8 ) & ActiveSCART )
++ tempcl |= SetCRT2ToSCART ;
++
++ if ( pVBInfo->IF_DEF_HiVision == 1 )
++ {
++ if ( ( temp >> 8 ) & ActiveHiTV )
++ tempcl |= SetCRT2ToHiVisionTV ;
++ }
++
++ if ( pVBInfo->IF_DEF_YPbPr == 1 )
++ {
++ if ( ( temp >> 8 ) & ActiveYPbPr )
++ tempch |= SetYPbPr ;
++ }
++ }
++
++ tempcl |= SetSimuScanMode ;
++ if ( (!( temp & ActiveCRT1 )) && ( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
++ tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
++ if ( ( temp & ActiveLCD ) && ( temp & ActiveTV ) )
++ tempcl ^= ( SetSimuScanMode | SwitchToCRT2 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30 , tempcl ) ;
++
++ CR31Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x31 ) ;
++ CR31Data &= ~( SetNotSimuMode >> 8 ) ;
++ if ( !( temp & ActiveCRT1 ) )
++ CR31Data |= ( SetNotSimuMode >> 8 ) ;
++ CR31Data &= ~( DisableCRT2Display >> 8 ) ;
++ if (!( ( temp & ActiveLCD ) || ( temp & ActiveTV ) || ( temp & ActiveCRT2 ) ) )
++ CR31Data |= ( DisableCRT2Display >> 8 ) ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31 , CR31Data ) ;
++
++ CR38Data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
++ CR38Data &= ~SetYPbPr ;
++ CR38Data |= tempch ;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38 , CR38Data ) ;
++
++}
++
++/* -------------------------------------------------------- */
++/* Function : XGINew_GetXG21Sense */
++/* Input : */
++/* Output : */
++/* Description : */
++/* -------------------------------------------------------- */
++void XGINew_GetXG21Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR Temp;
++ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
++
++ pVBInfo->IF_DEF_LVDS = 0 ;
++
++ if ( ( pVideoMemory[ 0x65 ] & 0x01 ) ) /* For XG21 LVDS */
++ {
++ pVBInfo->IF_DEF_LVDS = 1 ;
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , LCDSense ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS on chip */
++ }
++ else
++ {
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* Enable GPIOA/B read */
++ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) & 0xC0;
++ if ( Temp == 0xC0 )
++ { /* DVI & DVO GPIOA/B pull high */
++ XGINew_SenseLCD( HwDeviceExtension, pVBInfo ) ;
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , LCDSense ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x20 , 0x20 ) ; /* Enable read GPIOF */
++ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) & 0x04 ;
++ if ( !Temp )
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0x80 ) ; /* TMDS on chip */
++ else
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* Only DVO on chip */
++
++ XGI_SetRegAND( (XGIIOADDRESS)pVBInfo->P3d4 , 0x4A , ~0x20 ) ; /* Disable read GPIOF */
++ }
++ }
++}
++
++/* -------------------------------------------------------- */
++/* Function : XGINew_GetXG27Sense */
++/* Input : */
++/* Output : */
++/* Description : */
++/* -------------------------------------------------------- */
++void XGINew_GetXG27Sense(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR Temp,bCR4A;
++ PUCHAR volatile pVideoMemory = ( PUCHAR )pVBInfo->ROMAddr ;
++
++ pVBInfo->IF_DEF_LVDS = 0 ;
++ bCR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x07 , 0x07 ) ; /* Enable GPIOA/B/C read */
++ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) & 0x07;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x4A , bCR4A ) ;
++
++ if ( Temp <= 0x02 )
++ {
++ pVBInfo->IF_DEF_LVDS = 1 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xC0 ) ; /* LVDS setting */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x30 , 0x21 ) ;
++ }
++ else
++ {
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 , ~0xE0 , 0xA0 ) ; /* TMDS/DVO setting */
++ }
++
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x32 , LCDSense ) ;
++}
++
++UCHAR GetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CR38,CR4A,temp;
++
++ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x10 , 0x10 ) ; /* enable GPIOE read */
++ CR38 = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
++ temp =0;
++ if ( ( CR38 & 0xE0 ) > 0x80 )
++ {
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
++ temp &= 0x08;
++ temp >>= 3;
++ }
++
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x4A , CR4A ) ;
++
++ return temp;
++}
++
++UCHAR GetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CR38,CR4A,temp;
++
++ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x03 , 0x03 ) ; /* enable GPIOA/B/C read */
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
++ if ( temp <= 2 )
++ {
++ temp &= 0x03;
++ }
++ else
++ {
++ temp = ((temp&0x04)>>1) || ((~temp)&0x01);
++ }
++
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4, 0x4A , CR4A ) ;
++
++ return temp;
++}
++
+diff --git a/src/vb_init.h b/src/vb_init.h
+index 0ee7f4e..7412a6e 100644
+--- a/src/vb_init.h
++++ b/src/vb_init.h
+@@ -33,5 +33,8 @@ extern void XGINew_SetModeScratch(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo);
+
+ extern void ReadVBIOSTablData(UCHAR ChipType, PVB_DEVICE_INFO pVBInfo);
++
++extern XGI21_LVDSCapStruct XGI21_LCDCapList;
++
+ #endif
+
+diff --git a/src/vb_setmode.c b/src/vb_setmode.c
+index 11431ce..cd1afc7 100644
+--- a/src/vb_setmode.c
++++ b/src/vb_setmode.c
+@@ -1,8012 +1,9890 @@
+-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+- *
+- * All Rights Reserved.
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining
+- * a copy of this software and associated documentation files (the
+- * "Software"), to deal in the Software without restriction, including
+- * without limitation on the rights to use, copy, modify, merge,
+- * publish, distribute, sublicense, and/or sell copies of the Software,
+- * and to permit persons to whom the Software is furnished to do so,
+- * subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice (including the
+- * next paragraph) shall be included in all copies or substantial
+- * portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+- * DEALINGS IN THE SOFTWARE.
+- */
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "osdef.h"
+-
+-#ifdef LINUX_XF86
+-#include "xf86.h"
+-#include "xf86PciInfo.h"
+-#include "xgi.h"
+-#include "xgi_regs.h"
+-#endif
+-
+-#ifdef LINUX_KERNEL
+-#include <asm/io.h>
+-#include <linux/types.h>
+-#include <linux/version.h>
+-#include "XGIfb.h"
+-#endif
+-
+-#include "vb_def.h"
+-#include "vgatypes.h"
+-#include "vb_struct.h"
+-#include "vb_table.h"
+-#include "vb_setmode.h"
+-
+-#define IndexMask 0xff
+-#ifndef XGI_MASK_DUAL_CHIP
+-#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */
+-#endif
+-
+-
+-BOOLEAN CheckDualChip(PVB_DEVICE_INFO pVBInfo);
+-static BOOLEAN XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo);
+-
+-BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, USHORT * i,
+- PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-BOOLEAN XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo);
+-USHORT XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-USHORT XGI_GetRatePtrCRT2(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-static USHORT XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-USHORT XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo);
+-static unsigned XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-static const void *XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-static const void *XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo);
+-void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
+-void XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo);
+-void XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo);
+-void XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo);
+-void SetDualChipRegs(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
+-void XGI_DisplayOn(PVB_DEVICE_INFO pVBInfo);
+-void XGI_DisplayOff(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+-static void XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo);
+-
+-void XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension);
+-void XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension);
+-void XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-
+-void XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetVBType(PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void InitTo330Pointer(UCHAR, PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
+-void XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
+-void SetSpectrum(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
+- PVB_DEVICE_INFO pVBInfo);
+-USHORT XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PVB_DEVICE_INFO pVBInfo);
+-void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
+-void XGI_LockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
+-void XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo);
+-void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo);
+-void XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo);
+-static void XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo);
+-static unsigned XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
+- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
+-static void XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di,
+- PVB_DEVICE_INFO pVBInfo);
+-USHORT XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo);
+-USHORT XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo);
+-static const XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(USHORT tempcx,
+- PVB_DEVICE_INFO pVBInfo);
+-
+-
+-const uint8_t XGI_MDA_DAC[] = {
+- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+- 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
+-};
+-
+-const uint8_t XGI_CGA_DAC[] = {
+- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
+-};
+-
+-const uint8_t XGI_EGA_DAC[] = {
+- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
+- 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
+- 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
+- 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
+- 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
+- 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
+- 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
+- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
+-};
+-
+-const uint8_t XGI_VGA_DAC[] = {
+- 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+- 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+- 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
+- 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
+- 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
+- 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
+- 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
+- 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
+- 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
+- 0x0B, 0x0C, 0x0D, 0x0F, 0x10
+-};
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : InitTo330Pointer */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-InitTo330Pointer(UCHAR ChipType, PVB_DEVICE_INFO pVBInfo)
+-{
+- pVBInfo->SModeIDTable = XGI330_SModeIDTable;
+- pVBInfo->StandTable = XGI330_StandTable;
+- pVBInfo->EModeIDTable = XGI330_EModeIDTable;
+- pVBInfo->RefIndex = XGI330_RefIndex;
+- pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table;
+-
+- /* add for new UNIVGABIOS */
+- /* XGINew_UBLCDDataTable = (XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
+- /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
+-
+-
+- if (ChipType >= XG40) {
+- (void) memcpy(pVBInfo->MCLKData, XGI340New_MCLKData, sizeof(XGI340New_MCLKData));
+- (void) memcpy(pVBInfo->ECLKData, XGI340_ECLKData, sizeof(XGI340_ECLKData));
+- }
+- else {
+- (void) memcpy(pVBInfo->MCLKData, XGI330New_MCLKData, sizeof(XGI330New_MCLKData));
+- (void) memcpy(pVBInfo->ECLKData, XGI330_ECLKData, sizeof(XGI330_ECLKData));
+- }
+-
+- pVBInfo->VCLKData = XGI_VCLKData;
+- pVBInfo->VBVCLKData = XGI_VBVCLKData;
+- pVBInfo->ScreenOffset = XGI330_ScreenOffset;
+- pVBInfo->StResInfo = XGI330_StResInfo;
+- pVBInfo->ModeResInfo = XGI330_ModeResInfo;
+-
+- pVBInfo->OutputSelect = XGI330_OutputSelect;
+- pVBInfo->SoftSetting = XGI330_SoftSetting;
+- pVBInfo->SR07 = XGI330_SR07;
+- pVBInfo->LCDResInfo = 0;
+- pVBInfo->LCDTypeInfo = 0;
+- pVBInfo->LCDInfo = 0;
+- pVBInfo->VBInfo = 0;
+- pVBInfo->TVInfo = 0;
+-
+-
+- (void) memcpy(pVBInfo->SR15, XGI340_SR13, sizeof(XGI340_SR13));
+- (void) memcpy(pVBInfo->CR40, XGI340_CR41, sizeof(XGI340_CR41));
+- (void) memcpy(pVBInfo->SR25, XGI330_SR25, sizeof(XGI330_SR25));
+- pVBInfo->SR31 = XGI330_SR31;
+- pVBInfo->SR32 = XGI330_SR32;
+- (void) memcpy(pVBInfo->CR6B, XGI340_CR6B, sizeof(XGI340_CR6B));
+- if (ChipType == XG45) {
+- (void) memcpy(pVBInfo->XG45CR6E, XGI45_CR6E, sizeof(XGI45_CR6E));
+- (void) memcpy(pVBInfo->XG45CR6F, XGI45_CR6F, sizeof(XGI45_CR6F));
+- }
+- else {
+- (void) memcpy(pVBInfo->CR6E, XGI340_CR6E, sizeof(XGI340_CR6E));
+- (void) memcpy(pVBInfo->CR6F, XGI340_CR6F, sizeof(XGI340_CR6F));
+- }
+- (void) memcpy(pVBInfo->CR89, XGI340_CR89, sizeof(XGI340_CR89));
+- (void) memcpy(pVBInfo->AGPReg, XGI340_AGPReg, sizeof(XGI340_AGPReg));
+- (void) memcpy(pVBInfo->SR16, XGI340_SR16, sizeof(XGI340_SR16));
+- pVBInfo->CRCF = XG40_CRCF;
+- pVBInfo->DRAMTypeDefinition = XG40_DRAMTypeDefinition;
+-
+-
+- (void) memcpy(pVBInfo->CR49, XGI330_CR49, sizeof(XGI330_CR49));
+- pVBInfo->SR1F = XGI330_SR1F;
+- pVBInfo->SR21 = XGI330_SR21;
+- pVBInfo->SR22 = XGI330_SR22;
+- pVBInfo->SR23 = XGI330_SR23;
+- pVBInfo->SR24 = XGI330_SR24;
+- pVBInfo->SR33 = XGI330_SR33;
+-
+-
+-
+- pVBInfo->CRT2Data_1_2 = XGI330_CRT2Data_1_2;
+- pVBInfo->CRT2Data_4_D = XGI330_CRT2Data_4_D;
+- pVBInfo->CRT2Data_4_E = XGI330_CRT2Data_4_E;
+- pVBInfo->CRT2Data_4_10 = XGI330_CRT2Data_4_10;
+- pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
+- pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
+- pVBInfo->pYCSenseData = &XGI330_YCSenseData;
+- pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
+- pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
+- pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
+-
+- pVBInfo->NTSCTiming = XGI330_NTSCTiming;
+- pVBInfo->PALTiming = XGI330_PALTiming;
+- pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
+- pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
+- pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
+- pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
+- pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
+- pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
+- pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
+- pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
+- pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
+- pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
+- pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
+- pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
+-
+-
+- (void) memcpy(& pVBInfo->TimingH, XGI_TimingH, sizeof(XGI_TimingH));
+- (void) memcpy(& pVBInfo->TimingV, XGI_TimingV, sizeof(XGI_TimingV));
+-
+- pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC;
+- pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC;
+- pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL;
+- pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL;
+-
+- /* 310 customization related */
+- if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
+- pVBInfo->LCDCapList = XGI_LCDDLCapList;
+- else
+- pVBInfo->LCDCapList = XGI_LCDCapList;
+-
+- pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
+- pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
+-
+-
+- pVBInfo->I2CDefinition = XG40_I2CDefinition;
+-
+- if (ChipType == XG20)
+- pVBInfo->CR97 = XG20_CR97;
+-}
+-
+-
+-
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGISetModeNew */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo,
+- USHORT ModeNo)
+-{
+-#ifndef LINUX_XF86
+- ULONG temp;
+- USHORT KeepLockReg;
+-#endif
+- USHORT ModeIdIndex;
+- /* PUCHAR pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
+- USHORT temp_mode_no;
+-
+- pVBInfo->IF_DEF_VideoCapture = 1;
+- pVBInfo->IF_DEF_ScaleLCD = 1;
+-
+-
+- if (ModeNo & 0x80) {
+- ModeNo = ModeNo & 0x7F;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
+-
+- if (HwDeviceExtension->jChipType != XG20) /* kuku 2004/06/25 1.Openkey */
+- XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
+-
+- temp_mode_no = ModeNo;
+- XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11,
+- &temp_mode_no, &ModeIdIndex);
+-
+- if (HwDeviceExtension->jChipType != XG20) { /* kuku 2004/06/25 */
+- PDEBUG(ErrorF("XGI_GetVBInfo \n"));
+- XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
+- PDEBUG(ErrorF("XGI_GetTVInfo \n"));
+- XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
+- PDEBUG(ErrorF("XGI_GetLCDInfo \n"));
+- XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
+- PDEBUG(ErrorF("XGI_DisableBridge \n"));
+- XGI_DisableBridge(HwDeviceExtension, pVBInfo);
+-
+-
+- if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
+- XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
+- pVBInfo);
+- }
+- }
+- else {
+- if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
+- XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
+- pVBInfo);
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
+- pVBInfo);
+- }
+- }
+- }
+-
+- PDEBUG(ErrorF(" vb_setmode 474\n")); // yilin
+- if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
+- switch (HwDeviceExtension->ujVBChipID) {
+- case VB_CHIP_301:
+- PDEBUG(ErrorF(" vb_setmode 301\n")); //yilin
+- XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
+- break;
+-
+- case VB_CHIP_302:
+- XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
+- break;
+-
+- default:
+- break;
+- }
+- }
+- ErrorF("492 Part2 0 = %x ",
+- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+- XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
+- XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212 */
+- XGI_EnableBridge(HwDeviceExtension, pVBInfo);
+- ErrorF("497 Part2 0 = %x ",
+- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+- } /* !XG20 */
+- else {
+- if (ModeNo <= 0x13) {
+- pVBInfo->ModeType =
+- pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag & ModeInfoFlag;
+- }
+- else {
+- pVBInfo->ModeType =
+- pVBInfo->EModeIDTable[ModeIdIndex].
+- Ext_ModeFlag & ModeInfoFlag;
+- }
+- pVBInfo->SetFlag = 0;
+- pVBInfo->VBInfo = DisableCRT2Display;
+- XGI_DisplayOff(pVBInfo);
+- XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+- XGI_DisplayOn(pVBInfo);
+- }
+-
+-/*
+- if ( ModeNo <= 0x13 )
+- {
+- modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
+- }
+- else
+- {
+- modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
+- }
+- pVBInfo->ModeType = modeflag&ModeInfoFlag ;
+- pVBInfo->SetFlag = 0x00 ;
+- pVBInfo->VBInfo = DisableCRT2Display ;
+- temp = XGINew_CheckMemorySize( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
+-
+- if ( temp == 0 )
+- return( 0 ) ;
+-
+- XGI_DisplayOff( pVBInfo) ;
+- XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
+- XGI_DisplayOn( pVBInfo) ;
+-*/
+- ErrorF("Part2 0 = %x ",
+- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+- XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
+-
+- if (HwDeviceExtension->jChipType != XG20) /* kuku 2004/06/25 */
+- XGI_LockCRT2(HwDeviceExtension, pVBInfo);
+-
+- return (TRUE);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1Group */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
+- pVBInfo->ModeType,
+- ModeNo, ModeIdIndex);
+- USHORT RefreshRateTableIndex;
+- USHORT b3CC;
+- USHORT temp;
+-
+- USHORT XGINew_P3cc = pVBInfo->P3cc;
+-#ifndef LINUX_XF86
+- USHORT XGINew_P3c2 = pVBInfo->P3c2;
+-#endif
+-
+- /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
+- XGI_SetSeqRegs(StandTableIndex, pVBInfo);
+- XGI_SetMiscRegs(StandTableIndex, pVBInfo);
+- XGI_SetCRTCRegs(StandTableIndex, pVBInfo);
+- XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
+- XGI_SetGRCRegs(StandTableIndex, pVBInfo);
+- XGI_ClearExt1Regs(ModeNo, pVBInfo);
+-
+- temp = ~ProgrammingCRT2;
+- pVBInfo->SetFlag &= temp;
+- pVBInfo->SelectCRT2Rate = 0;
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (pVBInfo->
+- VBInfo & (SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode)) {
+- pVBInfo->SetFlag |= ProgrammingCRT2;
+- }
+- }
+-
+- RefreshRateTableIndex = XGI_GetRatePtrCRT2(ModeNo, ModeIdIndex, pVBInfo);
+-
+- if (RefreshRateTableIndex != 0xFFFF) {
+- XGI_SetSync(RefreshRateTableIndex, pVBInfo);
+- XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo,
+- HwDeviceExtension);
+- XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex, pVBInfo);
+- XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- HwDeviceExtension, pVBInfo);
+- XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
+- RefreshRateTableIndex, pVBInfo);
+- }
+-
+- if (HwDeviceExtension->jChipType == XG20) {
+- if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x4E);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE9);
+- b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
+- XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
+- }
+- else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE3);
+- b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
+- XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
+- }
+- }
+-
+- pVBInfo->SetFlag &= (~ProgrammingCRT2);
+- XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
+- XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex, pVBInfo);
+-
+- if (HwDeviceExtension->jChipType == XG40) { /* Copy reg settings to 2nd chip */
+- if (CheckDualChip(pVBInfo))
+- SetDualChipRegs(HwDeviceExtension, pVBInfo);
+- }
+-
+- /* XGI_LoadCharacter(); //dif ifdef TVFont */
+-
+- XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetSeqRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetSeqRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+-{
+- unsigned SRdata;
+- unsigned i;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
+- SRdata = pVBInfo->StandTable[StandTableIndex].SR[0];
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- SRdata |= 0x01;
+- }
+- else {
+- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+- if (pVBInfo->VBInfo & SetInSlaveMode)
+- SRdata |= 0x01;
+- }
+- }
+-
+- SRdata |= 0x20; /* screen off */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SRdata); /* Set SR1 */
+-
+- /* Get SR2, SR3, and SR4 from table and set in hardware.
+- */
+- for (i = 2; i <= 4; i++) {
+- SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, SRdata);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetMiscRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetMiscRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+-{
+- UCHAR Miscdata;
+-
+- Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
+-/*
+- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
+- {
+- if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
+- {
+- Miscdata |= 0x0C ;
+- }
+- }
+-*/
+-
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRTCRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRTCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+-{
+- unsigned i;
+-
+- /* Unlock CRTC */
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x7f);
+-
+- for (i = 0; i <= 0x18; i++) {
+- /* Get CRTC from file */
+- const unsigned CRTCdata =
+- pVBInfo->StandTable[StandTableIndex].CRTC[i];
+-
+- /* Set CRTC( 3d4 ) */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, i, CRTCdata);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetATTRegs(unsigned ModeNo, unsigned StandTableIndex, unsigned ModeIdIndex,
+- const VB_DEVICE_INFO *pVBInfo)
+-{
+- unsigned i;
+- const unsigned modeflag = (ModeNo <= 0x13)
+- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-
+- for (i = 0; i <= 0x13; i++) {
+- UCHAR ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
+-
+- if (modeflag & Charx8Dot) { /* ifndef Dot9 */
+- if (i == 0x13) {
+- /* Pixel shift. If screen on LCD or TV is shifted left or
+- * right, this might be the cause.
+- */
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+- ARdata = 0;
+- else {
+- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
+- if (pVBInfo->VBInfo & SetInSlaveMode)
+- ARdata = 0;
+- }
+- }
+- }
+- }
+-
+- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, i); /* set index */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, ARdata); /* set data */
+- }
+-
+- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x14); /* set index */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x00); /* set data */
+-
+- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* Enable Attribute */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x20);
+- XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetGRCRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetGRCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
+-{
+- unsigned i;
+-
+- for (i = 0; i <= 8; i++) {
+- /* Get GR from file and set GR (3ce)
+- */
+- const unsigned GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3ce, i, GRdata);
+- }
+-
+- if (pVBInfo->ModeType > ModeVGA) {
+- /* 256 color disable */
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_ClearExt1Regs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_ClearExt1Regs(unsigned ModeNo, const VB_DEVICE_INFO *pVBInfo)
+-{
+- unsigned i;
+-
+- /* Clear SR0A-SR0E */
+- for (i = 0x0A; i <= 0x0E; i++) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, 0x00);
+- }
+-
+- /* This code came from the old XGI_New_ClearExt1Regs in init.c. Since
+- * it wasn't included in the newer code drop from XGI, I'm not sure if
+- * it's necessary on the Volari chips. I've included it here, ifdefed
+- * out, for future reference.
+- * - idr
+- */
+-#if 0
+- XGI_SetRegAND(pVBInfo->P3c4, 0x37, 0xFE);
+- if ((ModeNo == 0x06) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
+- XGI_SetReg(pVBInfo->P3c4, 0x0e, 0x20);
+- }
+-#else
+- (void) ModeNo;
+-#endif
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetRatePtrCRT2 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetRatePtrCRT2(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 }
+- , LCDARefreshIndex[] = {
+- 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01};
+-
+- USHORT RefreshRateTableIndex, i, modeflag, index, temp;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- if (ModeNo < 0x14)
+- return (0xFFFF);
+-
+- index = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
+- index = index >> pVBInfo->SelectCRT2Rate;
+- index &= 0x0F;
+-
+- if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD))
+- index = 0;
+-
+- if (index > 0)
+- index--;
+-
+- if (pVBInfo->SetFlag & ProgrammingCRT2) {
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+- | VB_XGI301C))
+- temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x0F]; /* 301b */
+- else
+- temp = LCDRefreshIndex[pVBInfo->LCDResInfo & 0x0F];
+-
+- if (index > temp) {
+- index = temp;
+- }
+- }
+- }
+-
+- RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
+- ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
+- i = 0;
+-
+- do {
+- if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
+- break;
+- temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+- temp &= ModeInfoFlag;
+- if (temp < pVBInfo->ModeType)
+- break;
+-
+- i++;
+- index--;
+-
+- } while (index != 0xFFFF);
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- temp =
+- pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+- if (temp & InterlaceMode) {
+- i++;
+- }
+- }
+- }
+-
+- i--;
+- if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
+- temp =
+- XGI_AjustCRT2Rate(ModeNo, ModeIdIndex, RefreshRateTableIndex, &i,
+- pVBInfo);
+- }
+- return (RefreshRateTableIndex + i); /*return(0x01|(temp1<<1)); */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_AjustCRT2Rate */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, USHORT * i,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, tempbx, resinfo, modeflag, infoflag;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+- tempax = 0;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+- tempax |= SupportRAMDAC2;
+-
+- if (pVBInfo->VBType & VB_XGI301C)
+- tempax |= SupportCRT2in301C;
+- }
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
+- tempax |= SupportLCD;
+-
+- if (pVBInfo->LCDResInfo != Panel1280x1024) {
+- if (pVBInfo->LCDResInfo != Panel1280x960) {
+- if (pVBInfo->LCDInfo & LCDNonExpanding) {
+- if (resinfo >= 9) {
+- tempax = 0;
+- return (0);
+- }
+- }
+- }
+- }
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
+- tempax |= SupportYPbPr;
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (resinfo == 4)
+- return (0);
+-
+- if (resinfo == 3)
+- return (0);
+-
+- if (resinfo > 7)
+- return (0);
+- }
+- }
+- else {
+- tempax |= SupportHiVisionTV;
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (resinfo == 4)
+- return (0);
+-
+- if (resinfo == 3) {
+- if (pVBInfo->SetFlag & TVSimuMode)
+- return (0);
+- }
+-
+- if (resinfo > 7)
+- return (0);
+- }
+- }
+- }
+- else {
+- if (pVBInfo->
+- VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
+- SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
+- tempax |= SupportTV;
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+- | VB_XGI301C)) {
+- tempax |= SupportTV1024;
+- }
+-
+- if (!(pVBInfo->VBInfo & SetPALTV)) {
+- if (modeflag & NoSupportSimuTV) {
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (!(pVBInfo->VBInfo & SetNotSimuMode)) {
+- return (0);
+- }
+- }
+- }
+- }
+- }
+- }
+-
+- for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx;
+- (*i)--) {
+- infoflag =
+- pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+- if (infoflag & tempax) {
+- return (1);
+- }
+- if ((*i) == 0)
+- break;
+- }
+-
+- for ((*i) = 0;; (*i)++) {
+- infoflag =
+- pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+- if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+- return (0);
+- }
+-
+- if (infoflag & tempax) {
+- return (1);
+- }
+- }
+- return (1);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetSync */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetSync(unsigned RefreshRateTableIndex, const VB_DEVICE_INFO *pVBInfo)
+-{
+- const unsigned sync =
+- (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8) & 0xC0;
+-
+- /* Set Misc(3c2) */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, sync | 0x2F);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1CRTC */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension)
+-{
+- UCHAR index, data;
+-#ifndef LINUX_XF86
+- USHORT temp, tempah, j, modeflag, ResInfo, DisplayType;
+-#endif
+- USHORT i;
+-
+- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
+- index = index & IndexMask;
+-
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
+- data &= 0x7F;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+-
+- for (i = 0; i < 8; i++)
+- pVBInfo->TimingH.data[i] =
+- pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
+-
+- for (i = 0; i < 7; i++)
+- pVBInfo->TimingV.data[i] =
+- pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
+-
+- XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+-
+-
+-
+- XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+-
+-
+- if (pVBInfo->ModeType > 0x03)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0x4F);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1Timing_H */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension)
+-{
+- UCHAR data, data1, pushax;
+- USHORT i, j;
+-
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
+- /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
+-
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
+- data &= 0x7F;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data);
+-
+- data = pVBInfo->TimingH.data[0];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0, data);
+-
+- for (i = 0x01; i <= 0x04; i++) {
+- data = pVBInfo->TimingH.data[i];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 1), data);
+- }
+-
+- for (i = 0x05; i <= 0x06; i++) {
+- data = pVBInfo->TimingH.data[i];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i + 6), data);
+- }
+-
+- j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
+- j &= 0x1F;
+- data = pVBInfo->TimingH.data[7];
+- data &= 0xE0;
+- data |= j;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, data);
+-
+- if (HwDeviceExtension->jChipType == XG20) {
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04);
+- data = data - 1;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04, data);
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05);
+- data1 = data;
+- data1 &= 0xE0;
+- data &= 0x1F;
+- if (data == 0) {
+- pushax = data;
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c);
+- data &= 0xFB;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c, data);
+- data = pushax;
+- }
+- data = data - 1;
+- data |= data1;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05, data);
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
+- data = data >> 5;
+- data = data + 3;
+- if (data > 7)
+- data = data - 7;
+- data = data << 5;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, ~0xE0, data);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1Timing_V */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR data;
+- USHORT i, j;
+-
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
+- /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , 0x7f , 0x00 ) ; */
+-
+- for (i = 0x00; i <= 0x01; i++) {
+- data = pVBInfo->TimingV.data[i];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 6), data);
+- }
+-
+- for (i = 0x02; i <= 0x03; i++) {
+- data = pVBInfo->TimingV.data[i];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x0e), data);
+- }
+-
+- for (i = 0x04; i <= 0x05; i++) {
+- data = pVBInfo->TimingV.data[i];
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x11), data);
+- }
+-
+- j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a);
+- j &= 0xC0;
+- data = pVBInfo->TimingV.data[6];
+- data &= 0x3F;
+- data |= j;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a, data);
+-
+- data = pVBInfo->TimingV.data[6];
+- data &= 0x80;
+- data = data >> 2;
+-
+- if (ModeNo <= 0x13)
+- i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- else
+- i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-
+- i &= DoubleScanMode;
+- if (i)
+- data |= 0x80;
+-
+- j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09);
+- j &= 0x5F;
+- data |= j;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09, data);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1DE */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, tempbx, tempcx, temp, modeflag;
+- UCHAR data;
+- const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+-
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- tempax = pVBInfo->StResInfo[resindex].HTotal;
+- tempbx = pVBInfo->StResInfo[resindex].VTotal;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- tempax = pVBInfo->ModeResInfo[resindex].HTotal;
+- tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
+- }
+-
+- if (modeflag & HalfDCLK)
+- tempax = tempax >> 1;
+-
+- if (ModeNo > 0x13) {
+- if (modeflag & HalfDCLK)
+- tempax = tempax << 1;
+-
+- temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+-
+- if (temp & InterlaceMode)
+- tempbx = tempbx >> 1;
+-
+- if (modeflag & DoubleScanMode)
+- tempbx = tempbx << 1;
+- }
+-
+- tempcx = 8;
+-
+- /* if ( !( modeflag & Charx8Dot ) ) */
+- /* tempcx = 9 ; */
+-
+- tempax /= tempcx;
+- tempax -= 1;
+- tempbx -= 1;
+- tempcx = tempax;
+- temp = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
+- data &= 0x7F;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x01, (USHORT) (tempcx & 0xff));
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0b, ~0x0c,
+- (USHORT) ((tempcx & 0x0ff00) >> 10));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x12, (USHORT) (tempbx & 0xff));
+- tempax = 0;
+- tempbx = tempbx >> 8;
+-
+- if (tempbx & 0x01)
+- tempax |= 0x02;
+-
+- if (tempbx & 0x02)
+- tempax |= 0x40;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, ~0x42, tempax);
+- data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x07);
+- data &= 0xFF;
+- tempax = 0;
+-
+- if (tempbx & 0x04)
+- tempax |= 0x02;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0a, ~0x02, tempax);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, temp);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetResInfo */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- return (ModeNo <= 0x13)
+- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo
+- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+-}
+-
+-
+-static void
+-get_mode_xres_yres(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo,
+- unsigned *width, unsigned *height)
+-{
+- const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+- unsigned xres;
+- unsigned yres;
+-
+-
+- if (ModeNo <= 0x13) {
+- xres = pVBInfo->StResInfo[resindex].HTotal;
+- yres = pVBInfo->StResInfo[resindex].VTotal;
+- }
+- else {
+- const unsigned modeflag =
+- pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-
+- xres = pVBInfo->ModeResInfo[resindex].HTotal;
+- yres = pVBInfo->ModeResInfo[resindex].VTotal;
+-
+- if (modeflag & HalfDCLK)
+- xres *= 2;
+-
+- if (modeflag & DoubleScanMode)
+- yres *= 2;
+- }
+-
+- *width = xres;
+- *height = yres;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1Offset */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp, ah, al, temp2, i, DisplayUnit;
+-
+- /* GetOffset */
+- temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+- temp = temp >> 8;
+- temp = pVBInfo->ScreenOffset[temp];
+-
+- temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+- temp2 &= InterlaceMode;
+-
+- if (temp2)
+- temp = temp << 1;
+-
+- temp2 = pVBInfo->ModeType - ModeEGA;
+-
+- switch (temp2) {
+- case 0:
+- temp2 = 1;
+- break;
+- case 1:
+- temp2 = 2;
+- break;
+- case 2:
+- temp2 = 4;
+- break;
+- case 3:
+- temp2 = 4;
+- break;
+- case 4:
+- temp2 = 6;
+- break;
+- case 5:
+- temp2 = 8;
+- break;
+- default:
+- break;
+- }
+-
+- if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
+- temp = temp * temp2 + temp2 / 2;
+- else
+- temp *= temp2;
+-
+- /* SetOffset */
+- DisplayUnit = temp;
+- temp2 = temp;
+- temp = temp >> 8; /* ah */
+- temp &= 0x0F;
+- i = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E);
+- i &= 0xF0;
+- i |= temp;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E, i);
+-
+- temp = (UCHAR) temp2;
+- temp &= 0xFF; /* al */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x13, temp);
+-
+- /* SetDisplayUnit */
+- temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+- temp2 &= InterlaceMode;
+- if (temp2)
+- DisplayUnit >>= 1;
+-
+- DisplayUnit = DisplayUnit << 5;
+- ah = (DisplayUnit & 0xff00) >> 8;
+- al = DisplayUnit & 0x00ff;
+- if (al == 0)
+- ah += 1;
+- else
+- ah += 2;
+-
+- if (HwDeviceExtension->jChipType == XG20)
+- if ((ModeNo == 0x4A) | (ModeNo == 0x49))
+- ah -= 1;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, ah);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1VCLK */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- unsigned index;
+- unsigned clka;
+- unsigned clkb;
+-
+- if ((pVBInfo->VBType & VB_XGI301BLV302BLV)
+- && (pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+- index = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- pVBInfo);
+-
+- clka = pVBInfo->VBVCLKData[index].Part4_A;
+- clkb = pVBInfo->VBVCLKData[index].Part4_B;
+- }
+- else {
+- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+-
+- clka = pVBInfo->VCLKData[index].SR2B;
+- clkb = pVBInfo->VCLKData[index].SR2C;
+- }
+-
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0xCF);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, clka);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, clkb);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2D, 0x01);
+-
+- if ((HwDeviceExtension->jChipType == XG20)
+- && (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK)) {
+- UCHAR data;
+-
+- /* FIXME: Does this actually serve any purpose? This register is
+- * FIXME: already written above.
+- */
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, data);
+-
+- /* FIXME: The logic here seems wrong. It looks like its possible
+- * FIXME: for the (data << 1) to cause a bit to creep into the index
+- * FIXME: part. THere's no documentation for this register, so I have
+- * FIXME: no way of knowing. :(
+- */
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C);
+- index = data;
+- index &= 0xE0;
+- data &= 0x1F;
+- data = data << 1;
+- data += 1;
+- data |= index;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, data);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1FIFO */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data;
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
+- data &= 0xfe;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
+-
+- if (ModeNo > 0x13) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0x34);
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
+- data &= 0xF0;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
+- data |= 0x01;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0xAE);
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
+- data &= 0xF0;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT1ModeRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data, data2, data3, infoflag = 0, modeflag, resindex, xres;
+-
+- if (ModeNo > 0x13) {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+- }
+- else
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+-
+- if (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31) & 0x01)
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
+-
+- if (ModeNo > 0x13)
+- data = infoflag;
+- else
+- data = 0;
+-
+- data2 = 0;
+-
+- if (ModeNo > 0x13) {
+- if (pVBInfo->ModeType > 0x02) {
+- data2 |= 0x02;
+- data3 = pVBInfo->ModeType - ModeVGA;
+- data3 = data3 << 2;
+- data2 |= data3;
+- }
+- }
+-
+- data &= InterlaceMode;
+-
+- if (data)
+- data2 |= 0x20;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, ~0x3F, data2);
+- /* XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x06,data2); */
+- resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
+- if (ModeNo <= 0x13)
+- xres = pVBInfo->StResInfo[resindex].HTotal;
+- else
+- xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
+-
+- data = 0x0000;
+- if (infoflag & InterlaceMode) {
+- if (xres == 1024)
+- data = 0x0035;
+- else if (xres == 1280)
+- data = 0x0048;
+- }
+-
+- data2 = data & 0x00FF;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFF, data2);
+- data2 = (data & 0xFF00) >> 8;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFC, data2);
+-
+- if (modeflag & HalfDCLK)
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xF7, 0x08);
+-
+- data2 = 0;
+-
+- if (modeflag & LineCompareOff)
+- data2 |= 0x08;
+-
+- if (ModeNo > 0x13) {
+- if (pVBInfo->ModeType == ModeEGA)
+- data2 |= 0x40;
+- }
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0F, ~0x48, data2);
+- data = 0x60;
+- if (pVBInfo->ModeType != ModeText) {
+- data = data ^ 0x60;
+- if (pVBInfo->ModeType != ModeEGA) {
+- data = data ^ 0xA0;
+- }
+- }
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x21, 0x1F, data);
+-
+- XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
+- pVBInfo);
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
+-
+- if (HwDeviceExtension->jChipType == XG20) {
+- if (data & 0x40)
+- data = 0x33;
+- else
+- data = 0x73;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x51, 0x02);
+- }
+- else {
+- if (data & 0x40)
+- data = 0x2c;
+- else
+- data = 0x6c;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
+- }
+-
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetVCLKState */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data, data2 = 0;
+- SHORT VCLK;
+-
+- UCHAR index;
+-
+- if (ModeNo <= 0x13)
+- VCLK = 0;
+- else {
+- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+- index &= IndexMask;
+- VCLK = pVBInfo->VCLKData[index].CLOCK;
+- }
+-
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
+- data &= 0xf3;
+- if (VCLK >= 200)
+- data |= 0x0c; /* VCLK > 200 */
+-
+- if (HwDeviceExtension->jChipType == XG20)
+- data &= ~0x04; /* 2 pixel mode */
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, data);
+-
+- if (HwDeviceExtension->jChipType != XG20) {
+- data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
+- data &= 0xE7;
+- if (VCLK < 200)
+- data |= 0x10;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, data);
+- }
+-
+- if ((VCLK >= 0) && (VCLK < 135))
+- data2 = 0x03;
+- else if ((VCLK >= 135) && (VCLK < 160))
+- data2 = 0x02;
+- else if ((VCLK >= 160) && (VCLK < 260))
+- data2 = 0x01;
+- else if (VCLK > 260)
+- data2 = 0x00;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x07, 0xFC, data2);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_LoadDAC */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, ah, dh;
+- const uint8_t *table = NULL;
+-
+- if (ModeNo <= 0x13)
+- data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- else
+- data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-
+- data &= DACInfoFlag;
+- time = 64;
+-
+- if (data == 0x00)
+- table = XGI_MDA_DAC;
+- else if (data == 0x08)
+- table = XGI_CGA_DAC;
+- else if (data == 0x10)
+- table = XGI_EGA_DAC;
+- else if (data == 0x18) {
+- time = 256;
+- table = XGI_VGA_DAC;
+- }
+-
+- if (time == 256)
+- j = 16;
+- else
+- j = time;
+-
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c6, 0xFF);
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
+-
+- for (i = 0; i < j; i++) {
+- data = table[i];
+-
+- for (k = 0; k < 3; k++) {
+- data2 = 0;
+-
+- if (data & 0x01)
+- data2 = 0x2A;
+-
+- if (data & 0x02)
+- data2 += 0x15;
+-
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data2);
+- data = data >> 2;
+- }
+- }
+-
+- if (time == 256) {
+- for (i = 16; i < 32; i++) {
+- data = table[i];
+-
+- for (k = 0; k < 3; k++)
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data);
+- }
+-
+- si = 32;
+-
+- for (m = 0; m < 9; m++) {
+- di = si;
+- bx = si + 0x04;
+- dl = 0;
+-
+- for (n = 0; n < 3; n++) {
+- for (o = 0; o < 5; o++) {
+- dh = table[si];
+- ah = table[di];
+- al = table[bx];
+- si++;
+- XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
+- ah, al, dh);
+- }
+-
+- si -= 2;
+-
+- for (o = 0; o < 3; o++) {
+- dh = table[bx];
+- ah = table[di];
+- al = table[si];
+- si--;
+- XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
+- ah, al, dh);
+- }
+-
+- dl++;
+- }
+-
+- si += 5;
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_WriteDAC */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift, unsigned ordering,
+- uint8_t ah, uint8_t al, uint8_t dh)
+-{
+- USHORT temp, bh, bl;
+-
+- if (shift) {
+- ah <<= 2;
+- al <<= 2;
+- dh <<= 2;
+- }
+-
+- bh = ah;
+- bl = al;
+-
+- if (ordering != 0) {
+- temp = bh;
+- bh = dh;
+- dh = temp;
+- if (ordering == 1) {
+- temp = bl;
+- bl = dh;
+- dh = temp;
+- }
+- else {
+- temp = bl;
+- bl = bh;
+- bh = temp;
+- }
+- }
+- XGI_SetRegByte(dac_data, dh);
+- XGI_SetRegByte(dac_data, bh);
+- XGI_SetRegByte(dac_data, bl);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLCDAGroup */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT RefreshRateTableIndex;
+- /* USHORT temp ; */
+-
+- /* pVBInfo->SelectCRT2Rate = 0 ; */
+-
+- pVBInfo->SetFlag |= ProgrammingCRT2;
+- RefreshRateTableIndex = XGI_GetRatePtrCRT2(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+- XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- HwDeviceExtension, pVBInfo);
+- XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+- XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+-}
+-
+-
+-/**
+- * Get LVDS resolution information.
+- */
+-void
+-XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- unsigned xres;
+- unsigned yres;
+-
+-
+- get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
+-
+- if (xres == 720)
+- xres = 640;
+-
+- pVBInfo->VGAHDE = xres;
+- pVBInfo->HDE = xres;
+- pVBInfo->VGAVDE = yres;
+- pVBInfo->VDE = yres;
+-}
+-
+-
+-static void
+-get_HDE_VDE(PVB_DEVICE_INFO pVBInfo, USHORT *HDE, USHORT *VDE)
+-{
+- switch (pVBInfo->LCDResInfo) {
+- case Panel1024x768:
+- case Panel1024x768x75:
+- *HDE = 1024;
+- *VDE = 768;
+- break;
+-
+- case Panel1280x1024:
+- case Panel1280x1024x75:
+- *HDE = 1280;
+- *VDE = 1024;
+- break;
+-
+- case Panel1400x1050:
+- *HDE = 1400;
+- *VDE = 1050;
+- break;
+-
+- default:
+- *HDE = 1600;
+- *VDE = 1200;
+- break;
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetLVDSData */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx;
+- XGI330_LVDSDataStruct *LCDPtr = NULL;
+-
+- tempbx = 2;
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- LCDPtr =
+- (XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+- ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- pVBInfo->VGAHT = LCDPtr->VGAHT;
+- pVBInfo->VGAVT = LCDPtr->VGAVT;
+- pVBInfo->HT = LCDPtr->LCDHT;
+- pVBInfo->VT = LCDPtr->LCDVT;
+- }
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))) {
+- get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_ModCRT1Regs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR index;
+- USHORT tempbx, i;
+- XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
+- XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
+- /* XGI330_CHTVDataStruct *TVPtr = NULL ; */
+-
+- if (ModeNo <= 0x13)
+- index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+- else
+- index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+-
+- index = index & IndexMask;
+-
+- if ((pVBInfo->IF_DEF_ScaleLCD == 0)
+- || ((pVBInfo->IF_DEF_ScaleLCD == 1)
+- && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
+- tempbx = 0;
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- LCDPtr =
+- (XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+- ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+-
+- for (i = 0; i < 8; i++)
+- pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
+- }
+-
+- XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
+-
+- tempbx = 1;
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- LCDPtr1 =
+- (XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+- ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- for (i = 0; i < 7; i++)
+- pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
+- }
+-
+- XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
+- }
+-}
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLVDSRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
+- unsigned long temp, temp1, temp2, temp3, push3;
+- XGI330_LCDDataDesStruct *LCDPtr = NULL;
+- XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
+-
+- if (ModeNo > 0x13)
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- else
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+-
+- if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
+- if (pVBInfo->IF_DEF_OEMUtil == 1) {
+- tempbx = 8;
+- LCDPtr =
+- (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+- ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- }
+-
+- if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == 0)) {
+- tempbx = 3;
+- if (pVBInfo->LCDInfo & EnableScalingLCD)
+- LCDPtr1 =
+- (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(tempbx, ModeNo,
+- ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- else
+- LCDPtr =
+- (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
+- ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- }
+-
+- XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+- push1 = tempbx;
+- push2 = tempax;
+-
+- /* GetLCDResInfo */
+- if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
+- get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
+-
+- pVBInfo->VGAHDE = pVBInfo->HDE;
+- pVBInfo->VGAVDE = pVBInfo->VDE;
+- }
+-
+- tempax = pVBInfo->HT;
+-
+- tempbx = (pVBInfo->LCDInfo & EnableScalingLCD)
+- ? LCDPtr1->LCDHDES : LCDPtr->LCDHDES;
+-
+- tempcx = pVBInfo->HDE;
+- tempbx = tempbx & 0x0fff;
+- tempcx += tempbx;
+-
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
+-
+- tempcx = tempcx >> 3;
+- tempbx = tempbx >> 3;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16,
+- (USHORT) (tempbx & 0xff));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17,
+- (USHORT) (tempcx & 0xff));
+-
+- tempax = pVBInfo->HT;
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD)
+- tempbx = LCDPtr1->LCDHRS;
+- else
+- tempbx = LCDPtr->LCDHRS;
+-
+- tempcx = push2;
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD)
+- tempcx = LCDPtr1->LCDHSync;
+-
+- tempcx += tempbx;
+-
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- /* FIXME: Won't this *always* set tempax to zero? */
+- tempax = tempbx & 0x07;
+- tempax = tempax >> 5;
+- tempcx = tempcx >> 3;
+- tempbx = tempbx >> 3;
+-
+- tempcx &= 0x1f;
+- tempax |= tempcx;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x15, tempax);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x14,
+- (USHORT) (tempbx & 0xff));
+-
+- tempax = pVBInfo->VT;
+- if (pVBInfo->LCDInfo & EnableScalingLCD)
+- tempbx = LCDPtr1->LCDVDES;
+- else
+- tempbx = LCDPtr->LCDVDES;
+- tempcx = pVBInfo->VDE;
+-
+- tempbx = tempbx & 0x0fff;
+- tempcx += tempbx;
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1b,
+- (USHORT) (tempbx & 0xff));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1c,
+- (USHORT) (tempcx & 0xff));
+-
+- tempbx = (tempbx >> 8) & 0x07;
+- tempcx = (tempcx >> 8) & 0x07;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1d,
+- (USHORT) ((tempcx << 3) | tempbx));
+-
+- tempax = pVBInfo->VT;
+- if (pVBInfo->LCDInfo & EnableScalingLCD)
+- tempbx = LCDPtr1->LCDVRS;
+- else
+- tempbx = LCDPtr->LCDVRS;
+-
+- /* tempbx = tempbx >> 4 ; */
+- tempcx = push1;
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD)
+- tempcx = LCDPtr1->LCDVSync;
+-
+- tempcx += tempbx;
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18,
+- (USHORT) (tempbx & 0xff));
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, ~0x0f,
+- (USHORT) (tempcx & 0x0f));
+-
+- tempax = ((tempbx >> 8) & 0x07) << 3;
+-
+- tempbx = pVBInfo->VGAVDE;
+- if (tempbx != pVBInfo->VDE)
+- tempax |= 0x40;
+-
+- if (pVBInfo->LCDInfo & EnableLVDSDDA)
+- tempax |= 0x40;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1a, 0x07,
+- tempax);
+-
+- tempcx = pVBInfo->VGAVT;
+- tempbx = pVBInfo->VDE;
+- tempax = pVBInfo->VGAVDE;
+- tempcx -= tempax;
+-
+- temp = tempax; /* 0430 ylshieh */
+- temp1 = (temp << 18) / tempbx;
+-
+- tempdx = (USHORT) ((temp << 18) % tempbx);
+-
+- if (tempdx != 0)
+- temp1 += 1;
+-
+- temp2 = temp1;
+- push3 = temp2;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x37,
+- (USHORT) (temp2 & 0xff));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x36,
+- (USHORT) ((temp2 >> 8) & 0xff));
+-
+- tempbx = (USHORT) (temp2 >> 16);
+- tempax = tempbx & 0x03;
+-
+- tempbx = pVBInfo->VGAVDE;
+- if (tempbx == pVBInfo->VDE)
+- tempax |= 0x04;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x35, tempax);
+-
+- if (pVBInfo->VBType & VB_XGI301C) {
+- temp2 = push3;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3c,
+- (USHORT) (temp2 & 0xff));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3b,
+- (USHORT) ((temp2 >> 8) & 0xff));
+- tempbx = (USHORT) (temp2 >> 16);
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x3a, ~0xc0,
+- (USHORT) ((tempbx & 0xff) << 6));
+-
+- tempcx = pVBInfo->VGAVDE;
+- if (tempcx == pVBInfo->VDE)
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
+- ~0x0c, 0x00);
+- else
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
+- ~0x0c, 0x08);
+- }
+-
+- tempcx = pVBInfo->VGAHDE;
+- tempbx = pVBInfo->HDE;
+-
+- temp1 = tempcx << 16;
+-
+- tempax = (USHORT) (temp1 / tempbx);
+-
+- if ((tempbx & 0xffff) == (tempcx & 0xffff))
+- tempax = 65535;
+-
+- temp3 = tempax;
+- temp1 = pVBInfo->VGAHDE << 16;
+-
+- temp1 /= temp3;
+- temp3 = temp3 << 16;
+- temp1 -= 1;
+-
+- temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
+-
+- tempax = (USHORT) (temp3 & 0xff);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1f, tempax);
+-
+- temp1 = pVBInfo->VGAVDE << 18;
+- temp1 = temp1 / push3;
+- tempbx = (USHORT) (temp1 & 0xffff);
+-
+- if (pVBInfo->LCDResInfo == Panel1024x768)
+- tempbx -= 1;
+-
+- tempax = ((tempbx >> 8) & 0xff) << 3;
+- tempax |= (USHORT) ((temp3 >> 8) & 0x07);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x20,
+- (USHORT) (tempax & 0xff));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x21,
+- (USHORT) (tempbx & 0xff));
+-
+- temp3 = temp3 >> 16;
+-
+- if (modeflag & HalfDCLK)
+- temp3 = temp3 >> 1;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x22,
+- (USHORT) ((temp3 >> 8) & 0xff));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x23,
+- (USHORT) (temp3 & 0xff));
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT2ECLK */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR di[2];
+- int i;
+- const unsigned vclkindex =
+- XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
+-
+- XGI_GetVCLKLen(vclkindex, di, pVBInfo);
+- XGI_GetLCDVCLKPtr(di, pVBInfo);
+-
+- for (i = 0; i < 4; i++) {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, ~0x30,
+- (USHORT) (0x10 * i));
+- if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+- && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, di[0]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, di[1]);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2b, di[0]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2c, di[1]);
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_UpdateModeInfo */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempcl, tempch, temp, tempbl, tempax;
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- tempcl = 0;
+- tempch = 0;
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
+-
+- if (!(temp & 0x20)) {
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
+- if (temp & 0x80) {
+- if ((HwDeviceExtension->jChipType == XG20)
+- || (HwDeviceExtension->jChipType >= XG40))
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53);
+- else
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
+-
+- if (!(temp & 0x40))
+- tempcl |= ActiveCRT1;
+- }
+- }
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e);
+- temp &= 0x0f;
+-
+- if (!(temp == 0x08)) {
+- tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
+- if (tempax & 0x04)
+- tempcl = tempcl | ActiveLCD;
+-
+- temp &= 0x05;
+-
+- if (!(tempcl & ActiveLCD))
+- if (temp == 0x01)
+- tempcl |= ActiveCRT2;
+-
+- if (temp == 0x04)
+- tempcl |= ActiveLCD;
+-
+- if (temp == 0x05) {
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00);
+-
+- if (!(temp & 0x08))
+- tempch |= ActiveAVideo;
+-
+- if (!(temp & 0x04))
+- tempch |= ActiveSVideo;
+-
+- if (temp & 0x02)
+- tempch |= ActiveSCART;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (temp & 0x01)
+- tempch |= ActiveHiTV;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+- temp =
+- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d);
+-
+- if (temp & 0x10)
+- tempch |= ActiveYPbPr;
+- }
+-
+- if (tempch != 0)
+- tempcl |= ActiveTV;
+- }
+- }
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d);
+- if (tempcl & ActiveLCD) {
+- if ((pVBInfo->SetFlag & ReserveTVOption)) {
+- if (temp & ActiveTV)
+- tempcl |= ActiveTV;
+- }
+- }
+- temp = tempcl;
+- tempbl = ~ModeSwitchStatus;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x3d, tempbl, temp);
+-
+- if (!(pVBInfo->SetFlag & ReserveTVOption))
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e, tempch);
+- }
+- else {
+- return;
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetVBType */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetVBType(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT flag, tempbx, tempah;
+-
+- tempbx = VB_XGI302B;
+- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
+- if (flag != 0x02) {
+- tempbx = VB_XGI301;
+- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x01);
+- if (flag >= 0xB0) {
+- tempbx = VB_XGI301B;
+- if (flag >= 0xC0) {
+- tempbx = VB_XGI301C;
+- if (flag >= 0xD0) {
+- tempbx = VB_XGI301LV;
+- if (flag >= 0xE0) {
+- tempbx = VB_XGI302LV;
+- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port,
+- 0x39);
+- if (tempah != 0xFF)
+- tempbx = VB_XGI301C;
+- }
+- }
+- }
+-
+- if (tempbx & (VB_XGI301B | VB_XGI302B)) {
+- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x23);
+-
+- if (!(flag & 0x02))
+- tempbx = tempbx | VB_NoLCD;
+- }
+- }
+- }
+-
+- pVBInfo->VBType = tempbx;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetVBInfo */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, push, tempbx, temp, modeflag;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- pVBInfo->SetFlag = 0;
+- pVBInfo->ModeType = modeflag & ModeInfoFlag;
+- tempbx = 0;
+-
+- if (pVBInfo->VBType & 0xFFFF) {
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30); /* Check Display Device */
+- tempbx = tempbx | temp;
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
+- push = temp;
+- push = push << 8;
+- tempax = temp << 8;
+- tempbx = tempbx | tempax;
+- temp =
+- (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA |
+- SetInSlaveMode | DisableCRT2Display);
+- temp = 0xFFFF ^ temp;
+- tempbx &= temp;
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38);
+-
+- if (pVBInfo->IF_DEF_LCDA == 1) {
+- /* if ( ( pVBInfo->VBType & VB_XGI302B ) || ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) */
+- if (pVBInfo->
+- VBType & (VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (temp & EnableDualEdge) {
+- tempbx |= SetCRT2ToDualEdge;
+-
+- if (temp & SetToLCDA)
+- tempbx |= SetCRT2ToLCDA;
+- }
+- }
+- }
+-
+- if (pVBInfo->IF_DEF_YPbPr == 1) {
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV)
+- || (pVBInfo->VBType & VB_XGI301C)) {
+- if (temp & SetYPbPr) { /* temp = CR38 */
+- if (pVBInfo->IF_DEF_HiVision == 1) {
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35); /* shampoo add for new scratch */
+- temp &= YPbPrMode;
+- tempbx |= SetCRT2ToHiVisionTV;
+-
+- if (temp != YPbPrMode1080i) {
+- tempbx &= (~SetCRT2ToHiVisionTV);
+- tempbx |= SetCRT2ToYPbPr;
+- }
+- }
+-
+- /* tempbx |= SetCRT2ToYPbPr ; */
+- }
+- }
+- }
+-
+- tempax = push; /* restore CR31 */
+-
+- if (pVBInfo->IF_DEF_YPbPr == 1) {
+- if (pVBInfo->IF_DEF_HiVision == 1)
+- temp = 0x09FC;
+- else
+- temp = 0x097C;
+- }
+- else {
+- if (pVBInfo->IF_DEF_HiVision == 1)
+- temp = 0x01FC;
+- else
+- temp = 0x017C;
+- }
+-
+-
+- if (!(tempbx & temp)) {
+- tempax |= DisableCRT2Display;
+- tempbx = 0;
+- }
+-
+- if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
+- if (!(pVBInfo->VBType & VB_NoLCD)) {
+- if (tempbx & SetCRT2ToLCDA) {
+- if (tempbx & SetSimuScanMode)
+- tempbx &=
+- (~
+- (SetCRT2ToLCD | SetCRT2ToRAMDAC | SwitchToCRT2));
+- else
+- tempbx &=
+- (~
+- (SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV |
+- SwitchToCRT2));
+- }
+- }
+- }
+-
+- /* shampoo add */
+- if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
+- if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
+- if (tempbx & SetCRT2ToRAMDAC) {
+- tempbx &=
+- (0xFF00 | SetCRT2ToRAMDAC | SwitchToCRT2 |
+- SetSimuScanMode);
+- tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+- }
+- }
+- else
+- tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV));
+- }
+-
+- if (!(pVBInfo->VBType & VB_NoLCD)) {
+- if (tempbx & SetCRT2ToLCD) {
+- tempbx &=
+- (0xFF00 | SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode);
+- tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+- }
+- }
+-
+- if (tempbx & SetCRT2ToSCART) {
+- tempbx &=
+- (0xFF00 | SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode);
+- tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
+- }
+-
+- if (pVBInfo->IF_DEF_YPbPr == 1) {
+- if (tempbx & SetCRT2ToYPbPr)
+- tempbx &= (0xFF00 | SwitchToCRT2 | SetSimuScanMode);
+- }
+-
+- if (pVBInfo->IF_DEF_HiVision == 1) {
+- if (tempbx & SetCRT2ToHiVisionTV)
+- tempbx &=
+- (0xFF00 | SetCRT2ToHiVisionTV | SwitchToCRT2 |
+- SetSimuScanMode);
+- }
+-
+- if (tempax & DisableCRT2Display) { /* Set Display Device Info */
+- if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
+- tempbx = DisableCRT2Display;
+- }
+-
+- if (!(tempbx & DisableCRT2Display)) {
+- if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
+- if (pVBInfo->IF_DEF_LCDA == 1) {
+- if (!(tempbx & SetCRT2ToLCDA))
+- tempbx |= (SetInSlaveMode | SetSimuScanMode);
+- }
+-
+- if (pVBInfo->IF_DEF_VideoCapture == 1) {
+- if ((HwDeviceExtension->jChipType >= XG40)
+- && (HwDeviceExtension->jChipType <= XG45)) {
+- if (ModeNo <= 13) {
+- /* CRT2 not need to support */
+- if (!(tempbx & SetCRT2ToRAMDAC)) {
+- tempbx &= (0x00FF | (~SetInSlaveMode));
+- pVBInfo->SetFlag |= EnableVCMode;
+- }
+- }
+- }
+- }
+- }
+-
+- /*LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
+- if ((tempbx & SetInSlaveMode) && (tempbx & SetCRT2ToLCDA)) {
+- tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToDualEdge);
+- pVBInfo->SetFlag |= ReserveTVOption;
+- }
+- }
+- }
+-
+- pVBInfo->VBInfo = tempbx;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetTVInfo */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp, tempbx = 0, resinfo = 0, modeflag, index1;
+-
+- tempbx = 0;
+- resinfo = 0;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
+- tempbx = temp;
+- if (tempbx & SetPALTV) {
+- tempbx &=
+- (SetCHTVOverScan | SetPALMTV | SetPALNTV | SetPALTV);
+- if (tempbx & SetPALMTV)
+- tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
+- }
+- else
+- tempbx &= (SetCHTVOverScan | SetNTSCJ | SetPALTV);
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToSCART)
+- tempbx |= SetPALTV;
+-
+- if (pVBInfo->IF_DEF_YPbPr == 1) {
+- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+- index1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
+- index1 &= YPbPrMode;
+-
+- if (index1 == YPbPrMode525i)
+- tempbx |= SetYPbPrMode525i;
+-
+- if (index1 == YPbPrMode525p)
+- tempbx = tempbx | SetYPbPrMode525p;
+- if (index1 == YPbPrMode750p)
+- tempbx = tempbx | SetYPbPrMode750p;
+- }
+- }
+-
+- if (pVBInfo->IF_DEF_HiVision == 1) {
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
+- }
+- }
+-
+- if ((pVBInfo->VBInfo & SetInSlaveMode)
+- && (!(pVBInfo->VBInfo & SetNotSimuMode)))
+- tempbx |= TVSimuMode;
+-
+- if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo == 8)) /* NTSC 1024x768, */
+- tempbx |= NTSC1024x768;
+-
+- tempbx |= RPLLDIV2XO;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (pVBInfo->VBInfo & SetInSlaveMode)
+- tempbx &= (~RPLLDIV2XO);
+- }
+- else {
+- if (tempbx & (SetYPbPrMode525p | SetYPbPrMode750p))
+- tempbx &= (~RPLLDIV2XO);
+- else if (!
+- (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV |
+- VB_XGI302LV | VB_XGI301C))) {
+- if (tempbx & TVSimuMode)
+- tempbx &= (~RPLLDIV2XO);
+- }
+- }
+- }
+- pVBInfo->TVInfo = tempbx;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetLCDInfo */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
+-
+- pVBInfo->LCDResInfo = 0;
+- pVBInfo->LCDTypeInfo = 0;
+- pVBInfo->LCDInfo = 0;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo// */
+- }
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
+- tempbx = temp & 0x0F;
+-
+- if (tempbx == 0)
+- tempbx = Panel1024x768; /* default */
+-
+- /* LCD75 [2003/8/22] Vicent */
+- if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
+- if (pVBInfo->VBInfo & DriverMode) {
+- tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+- tempax &= 0x0F;
+- else
+- tempax = tempax >> 4;
+-
+- if ((resinfo == 6) || (resinfo == 9)) {
+- if (tempax >= 3)
+- tempbx |= PanelRef75Hz;
+- }
+- else if ((resinfo == 7) || (resinfo == 8)) {
+- if (tempax >= 4)
+- tempbx |= PanelRef75Hz;
+- }
+- }
+- }
+-
+- pVBInfo->LCDResInfo = tempbx;
+-
+- /* End of LCD75 */
+-
+- if (pVBInfo->IF_DEF_OEMUtil == 1) {
+- pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
+- }
+-
+- if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+- return 0;
+- }
+-
+- tempbx = 0;
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
+-
+- temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
+-
+- if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
+- temp &= ~EnableScalingLCD;
+-
+- tempbx |= temp;
+-
+- LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
+-
+- tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
+-
+- if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C))
+- && (tempax & LCDDualLink)) {
+- tempbx |= SetLCDDualLink;
+- }
+-
+- if ((pVBInfo->LCDResInfo == Panel1400x1050)
+- && (pVBInfo->VBInfo & SetCRT2ToLCD) && (ModeNo > 0x13)
+- && (resinfo == 9) && (!(tempbx & EnableScalingLCD)))
+- tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
+-
+-/*
+- if ( tempax & LCDBToA )
+- {
+- tempbx |= SetLCDBToA ;
+- }
+-*/
+-
+- if (pVBInfo->IF_DEF_ExpLink == 1) {
+- if (modeflag & HalfDCLK) {
+- /* if ( !( pVBInfo->LCDInfo&LCDNonExpanding ) ) */
+- if (!(tempbx & SetLCDtoNonExpanding)) {
+- tempbx |= EnableLVDSDDA;
+- }
+- else {
+- if (ModeNo > 0x13) {
+- if (pVBInfo->LCDResInfo == Panel1024x768) {
+- if (resinfo == 4) { /* 512x384 */
+- tempbx |= EnableLVDSDDA;
+- }
+- }
+- }
+- }
+- }
+- }
+-
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (pVBInfo->VBInfo & SetNotSimuMode) {
+- tempbx |= LCDVESATiming;
+- }
+- }
+- else {
+- tempbx |= LCDVESATiming;
+- }
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x39);
+- if (temp & ReduceTiming) {
+- tempbx |= EnableReduceTiming;
+- }
+-
+- pVBInfo->LCDInfo = tempbx;
+-
+- if (pVBInfo->IF_DEF_PWD == 1) {
+- if (pVBInfo->LCDInfo & SetPWDEnable) {
+- if ((pVBInfo->VBType & VB_XGI302LV)
+- || (pVBInfo->VBType & VB_XGI301C)) {
+- if (!(tempax & PWDEnable)) {
+- pVBInfo->LCDInfo &= ~SetPWDEnable;
+- }
+- }
+- }
+- }
+-
+- {
+- if (tempax & (LockLCDBToA | StLCDBToA)) {
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (!(tempax & LockLCDBToA)) {
+- if (ModeNo <= 0x13) {
+- pVBInfo->VBInfo &=
+- ~(SetSimuScanMode | SetInSlaveMode |
+- SetCRT2ToLCD);
+- pVBInfo->VBInfo |= SetCRT2ToLCDA | SetCRT2ToDualEdge;
+- }
+- }
+- }
+- }
+- }
+-
+- return (1);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
+- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT memorysize, modeflag, temp, temp1, tmp;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- /* ModeType = modeflag&ModeInfoFlag ; // Get mode type */
+-
+- memorysize = modeflag & MemoryInfoFlag;
+- memorysize = memorysize > MemorySizeShift;
+- memorysize++; /* Get memory size */
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x14); /* Get DRAM Size */
+- tmp = temp;
+-
+- if (HwDeviceExtension->jChipType == XG40) {
+- temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+- if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+- temp <<= 2;
+- }
+- else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
+- temp <<= 1;
+- }
+- }
+- else if (HwDeviceExtension->jChipType == XG42) {
+- temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+- if ((tmp & 0x04) == 0x04) { /* Dual channels */
+- temp <<= 1;
+- }
+- }
+- else if (HwDeviceExtension->jChipType == XG45) {
+- temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+- if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
+- temp <<= 2;
+- }
+- else if ((tmp & 0x0c) == 0x08) { /* triple channels */
+- temp1 = temp;
+- temp <<= 1;
+- temp += temp1;
+- }
+- else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
+- temp <<= 1;
+- }
+- }
+- if (temp < memorysize)
+- return (FALSE);
+- else
+- return (TRUE);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_DisplayOn */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_DisplayOn(PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x00);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_DisplayOff */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_DisplayOff(PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x20);
+-}
+-
+-
+-/**
+- * Wait for vertical or horizontal blanking period.
+- */
+-void
+-XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo)
+-{
+- while ((XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
+- break;
+-
+- while (!(XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
+- break;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SenseCRT1 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-
+-void
+-XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
+- 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7,
+- 0x04, 0x00, 0x00, 0x05, 0x00
+- };
+-
+- UCHAR SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
+-
+- UCHAR CR17, CR63, SR31;
+- USHORT temp;
+- UCHAR DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
+-
+- int i;
+-#ifndef LINUX_XF86
+- int j;
+-#endif
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
+-
+- /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x57, 0x4A);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
+- (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) |
+- 0x02));
+-
+- SR31 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31);
+- CR63 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
+- SR01 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, (UCHAR) (SR01 & 0xDF));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, (UCHAR) (CR63 & 0xBF));
+-
+- CR17 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17, (UCHAR) (CR17 | 0x80));
+-
+- SR1F = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, (UCHAR) (SR1F | 0x04));
+-
+- SR07 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, (UCHAR) (SR07 & 0xFB));
+- SR06 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06, (UCHAR) (SR06 & 0xC3));
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x00);
+-
+- for (i = 0; i < 8; i++)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) i, CRTCData[i]);
+-
+- for (i = 8; i < 11; i++)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 8),
+- CRTCData[i]);
+-
+- for (i = 11; i < 13; i++)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 4),
+- CRTCData[i]);
+-
+- for (i = 13; i < 16; i++)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i - 3),
+- CRTCData[i]);
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E,
+- (UCHAR) (CRTCData[16] & 0xE0));
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0x00);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE1);
+-
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
+- for (i = 0; i < 256; i++) {
+- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
+- (UCHAR) DAC_TEST_PARMS[0]);
+- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
+- (UCHAR) DAC_TEST_PARMS[1]);
+- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
+- (UCHAR) DAC_TEST_PARMS[2]);
+- }
+-
+- XGI_VBLongWait(pVBInfo);
+- XGI_VBLongWait(pVBInfo);
+- XGI_VBLongWait(pVBInfo);
+-
+- XGINew_LCD_Wait_Time(0x01, pVBInfo);
+- XGI_WaitDisplay(pVBInfo);
+-
+- temp = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3c2);
+- if (temp & 0x10) {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x20);
+- }
+- else {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x00);
+- }
+-
+- /* alan, avoid display something, set BLACK DAC if not restore DAC */
+- XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
+-
+- for (i = 0; i < 256; i++) {
+- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
+- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
+- XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SR01);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, CR63);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, SR31);
+-
+- /* [2004/05/11] Vicent */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
+- (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) &
+- 0xFD));
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-CheckDualChip(PVB_DEVICE_INFO pVBInfo)
+-{
+- /* Check H/W trap that 2nd chip is present or not. */
+- return ((BOOLEAN)
+- (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3A) &
+- XGI_MASK_DUAL_CHIP));
+-}
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : SetDualChipRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-SetDualChipRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+-
+-#ifdef LINUX_XF86
+- USHORT BaseAddr2nd = (USHORT) (ULONG) HwDeviceExtension->pj2ndIOAddress;
+-#else
+- USHORT BaseAddr2nd = (USHORT) HwDeviceExtension->pj2ndIOAddress;
+-#endif
+- USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT;
+- USHORT XGINew_2ndP3CE = BaseAddr2nd + GRAPH_ADDRESS_PORT;
+- USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT;
+- USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT;
+- UCHAR tempal, i;
+- pVBInfo->BaseAddr = (USHORT) HwDeviceExtension->pjIOAddress;
+- for (i = 0x00; i <= 0x04; i++) { /* SR0 - SR4 */
+- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, i);
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, i, tempal);
+- }
+- for (i = 0x00; i <= 0x08; i++) { /* GR0 - GR8 */
+- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3ce, i);
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3CE, i, tempal);
+- }
+- /* OpenKey in 2nd chip */
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x86);
+-
+- /* Copy SR06 to 2nd chip */
+- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x06, tempal);
+-
+- /* Copy SR21 to 2nd chip */
+- tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21);
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x21, tempal);
+-
+- /* Miscellaneous reg(input port 3cch,output port 3c2h) */
+- tempal = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC); /* 3cc */
+- XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2, tempal);
+-
+- /* Close key in 2nd chip */
+- XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x00);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT2Group301 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, ModeIdIndex, RefreshRateTableIndex;
+- USHORT temp_mode_no;
+-
+- tempbx = pVBInfo->VBInfo;
+- pVBInfo->SetFlag |= ProgrammingCRT2;
+-
+- temp_mode_no = ModeNo;
+- XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11,
+- &temp_mode_no, &ModeIdIndex);
+-
+-
+- pVBInfo->SelectCRT2Rate = 4;
+- RefreshRateTableIndex = XGI_GetRatePtrCRT2(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_SaveCRT2Info(ModeNo, pVBInfo);
+- XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+- XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+- RefreshRateTableIndex, pVBInfo);
+- XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
+- RefreshRateTableIndex, pVBInfo);
+- XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+- RefreshRateTableIndex, pVBInfo);
+- XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- HwDeviceExtension, pVBInfo);
+- XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
+- RefreshRateTableIndex, pVBInfo);
+- XGI_SetTap4Regs(pVBInfo);
+- XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- HwDeviceExtension, pVBInfo);
+- XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+- XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_AutoThreshold(pVBInfo);
+- return 1;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_AutoThreshold */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo)
+-{
+- if (!(pVBInfo->SetFlag & Win9xDOSMode))
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x40);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SaveCRT2Info */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp1, temp2;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
+- temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
+- temp2 = ~(SetInSlaveMode >> 8);
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, temp2, temp1);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetCRT2ResInfo */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- unsigned xres;
+- unsigned yres;
+-
+-
+- get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
+-
+- if ((pVBInfo->VBInfo & SetCRT2ToLCD)
+- && !(pVBInfo->LCDInfo & (EnableScalingLCD | LCDNonExpanding))) {
+- switch (pVBInfo->LCDResInfo) {
+- case Panel1600x1200:
+- if (!(pVBInfo->LCDInfo & LCDVESATiming) && (yres == 1024)) {
+- yres = 1056;
+- }
+- break;
+-
+-
+- case Panel1280x1024:
+- if (yres == 400)
+- yres = 405;
+- else if (yres == 350)
+- yres = 360;
+- else if ((pVBInfo->LCDInfo & LCDVESATiming) && (yres == 360)) {
+- yres = 375;
+- }
+- break;
+-
+-
+- case Panel1024x768:
+- if (!(pVBInfo->LCDInfo & (LCDVESATiming | LCDNonExpanding))) {
+- if (yres == 350) {
+- yres = 357;
+- }
+- else if (yres == 400) {
+- yres = 420;
+- }
+- else if (yres == 480) {
+- yres = 525;
+- }
+- }
+-
+- break;
+- }
+-
+- if (xres == 720)
+- xres = 640;
+- }
+-
+- pVBInfo->VGAHDE = xres;
+- pVBInfo->HDE = xres;
+- pVBInfo->VGAVDE = yres;
+- pVBInfo->VDE = yres;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_IsLCDDualLink */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo)
+-{
+- return (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) != 0)
+- && ((pVBInfo->LCDInfo & SetLCDDualLink) != 0));
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetCRT2Data */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax = 0, tempbx, modeflag, resinfo;
+-#ifndef LINUX_XF86
+- USHORT CRT2Index, ResIndex;
+-#endif
+-
+- XGI_LCDDataStruct *LCDPtr = NULL;
+- XGI_TVDataStruct *TVPtr = NULL;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- }
+-
+- pVBInfo->NewFlickerMode = 0;
+- pVBInfo->RVBHRS = 50;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+- XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- pVBInfo);
+- return;
+- }
+-
+- tempbx = 4;
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- LCDPtr =
+- (XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+-
+- PDEBUG(ErrorF
+- ("C code setmode: ModeNo: 0x%08lX VGAHT:0x%081X \n", ModeNo,
+- LCDPtr->VGAHT));
+- pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
+- pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
+- pVBInfo->VGAHT = LCDPtr->VGAHT;
+- pVBInfo->VGAVT = LCDPtr->VGAVT;
+- pVBInfo->HT = LCDPtr->LCDHT;
+- pVBInfo->VT = LCDPtr->LCDVT;
+-
+- if (pVBInfo->LCDResInfo == Panel1024x768) {
+- tempax = 1024;
+- tempbx = 768;
+-
+- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+- if (pVBInfo->VGAVDE == 357)
+- tempbx = 527;
+- else if (pVBInfo->VGAVDE == 420)
+- tempbx = 620;
+- else if (pVBInfo->VGAVDE == 525)
+- tempbx = 775;
+- else if (pVBInfo->VGAVDE == 600)
+- tempbx = 775;
+- /* else if(pVBInfo->VGAVDE==350) tempbx=560; */
+- /* else if(pVBInfo->VGAVDE==400) tempbx=640; */
+- else
+- tempbx = 768;
+- }
+- else
+- tempbx = 768;
+- }
+- else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
+- tempax = 1024;
+- tempbx = 768;
+- }
+- else if (pVBInfo->LCDResInfo == Panel1280x1024) {
+- tempax = 1280;
+- if (pVBInfo->VGAVDE == 360)
+- tempbx = 768;
+- else if (pVBInfo->VGAVDE == 375)
+- tempbx = 800;
+- else if (pVBInfo->VGAVDE == 405)
+- tempbx = 864;
+- else
+- tempbx = 1024;
+- }
+- else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
+- tempax = 1280;
+- tempbx = 1024;
+- }
+- else if (pVBInfo->LCDResInfo == Panel1280x960) {
+- tempax = 1280;
+- if (pVBInfo->VGAVDE == 350)
+- tempbx = 700;
+- else if (pVBInfo->VGAVDE == 400)
+- tempbx = 800;
+- else if (pVBInfo->VGAVDE == 1024)
+- tempbx = 960;
+- else
+- tempbx = 960;
+- }
+- else if (pVBInfo->LCDResInfo == Panel1400x1050) {
+- tempax = 1400;
+- tempbx = 1050;
+-
+- if (pVBInfo->VGAVDE == 1024) {
+- tempax = 1280;
+- tempbx = 1024;
+- }
+- }
+- else if (pVBInfo->LCDResInfo == Panel1600x1200) {
+- tempax = 1600;
+- tempbx = 1200; /* alan 10/14/2003 */
+- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+- if (pVBInfo->VGAVDE == 350)
+- tempbx = 875;
+- else if (pVBInfo->VGAVDE == 400)
+- tempbx = 1000;
+- }
+- }
+-
+- if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD)) {
+- tempax = pVBInfo->VGAHDE;
+- tempbx = pVBInfo->VGAVDE;
+- }
+-
+- pVBInfo->HDE = tempax;
+- pVBInfo->VDE = tempbx;
+- return;
+- }
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
+- tempbx = 4;
+- TVPtr =
+- (XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex, pVBInfo);
+- pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
+- pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
+- pVBInfo->VGAHT = TVPtr->VGAHT;
+- pVBInfo->VGAVT = TVPtr->VGAVT;
+- pVBInfo->HDE = TVPtr->TVHDE;
+- pVBInfo->VDE = TVPtr->TVVDE;
+- pVBInfo->RVBHRS = TVPtr->RVBHRS;
+- pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (resinfo == 0x08)
+- pVBInfo->NewFlickerMode = 0x40;
+- else if (resinfo == 0x09)
+- pVBInfo->NewFlickerMode = 0x40;
+- else if (resinfo == 0x12)
+- pVBInfo->NewFlickerMode = 0x40;
+-
+- if (pVBInfo->VGAVDE == 350)
+- pVBInfo->TVInfo |= TVSimuMode;
+-
+- tempax = ExtHiTVHT;
+- tempbx = ExtHiTVVT;
+-
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (pVBInfo->TVInfo & TVSimuMode) {
+- tempax = StHiTVHT;
+- tempbx = StHiTVVT;
+-
+- if (!(modeflag & Charx8Dot)) {
+- tempax = StHiTextTVHT;
+- tempbx = StHiTextTVVT;
+- }
+- }
+- }
+- }
+- else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+- if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+- tempax = YPbPrTV750pHT; /* Ext750pTVHT */
+- tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
+- }
+-
+- if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+- tempax = YPbPrTV525pHT; /* Ext525pTVHT */
+- tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
+- }
+- else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+- tempax = YPbPrTV525iHT; /* Ext525iTVHT */
+- tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
+- if (pVBInfo->TVInfo & NTSC1024x768)
+- tempax = NTSC1024x768HT;
+- }
+- }
+- else {
+- tempax = PALHT;
+- tempbx = PALVT;
+- if (!(pVBInfo->TVInfo & SetPALTV)) {
+- tempax = NTSCHT;
+- tempbx = NTSCVT;
+- if (pVBInfo->TVInfo & NTSC1024x768)
+- tempax = NTSC1024x768HT;
+- }
+- }
+-
+- pVBInfo->HT = tempax;
+- pVBInfo->VT = tempbx;
+- return;
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT2VCLK */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR di[2];
+- const unsigned vclkindex =
+- XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
+-
+- XGI_GetVCLKLen(vclkindex, di, pVBInfo);
+- XGI_GetLCDVCLKPtr(di, pVBInfo);
+-
+- if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 *//* 301 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x10);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
+- }
+- else { /* 301b/302b/301lv/302lv */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
+- }
+-
+- if ((pVBInfo->LCDInfo & EnableReduceTiming)
+- && (pVBInfo->LCDResInfo == Panel1600x1200)) {
+- if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0A) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x5A);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, 0x24);
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00, 0x12);
+-
+- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x28);
+- else
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x08);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GETLCDVCLKPtr */
+-/* Input : */
+-/* Output : al -> VCLK Index */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo)
+-{
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- if ((pVBInfo->IF_DEF_ScaleLCD != 1)
+- || !(pVBInfo->LCDInfo & EnableScalingLCD)) {
+- const unsigned index = XGI_GetLCDCapPtr1(pVBInfo);
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
+- di[0] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
+- di[1] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
+- }
+- else { /* LCDA */
+- di[0] = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
+- di[1] = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
+- }
+- }
+- }
+-
+- return;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetVCLKPtr */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-unsigned
+-XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
+- USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- unsigned vclk;
+- const unsigned modeflag = (ModeNo <= 0x13)
+- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-
+-
+- if ((pVBInfo->SetFlag & ProgrammingCRT2)
+- && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
+- const unsigned index = XGI_GetLCDCapPtr(pVBInfo);
+- vclk = pVBInfo->LCDCapList[index].LCD_VCLK;
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+- return vclk;
+-
+- /* {TV} */
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (pVBInfo->TVInfo & TVSimuMode) {
+- vclk = (modeflag & Charx8Dot)
+- ? HiTVSimuVCLK : HiTVTextVCLK;
+- }
+- else {
+- vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
+- ? HiTVVCLKDIV2 : HiTVVCLK;
+- }
+-
+- return vclk;
+- }
+- else if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+- return YPbPr750pVCLK;
+- }
+- else if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+- return YPbPr525pVCLK;
+- }
+-
+- vclk = NTSC1024VCLK;
+-
+- if (!(pVBInfo->TVInfo & NTSC1024x768)) {
+- vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
+- ? TVVCLKDIV2 : TVVCLK;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV)
+- return vclk;
+- }
+- } /* {End of VB} */
+-
+- vclk = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
+- vclk = (vclk >> 2) & 0x03;
+-
+- /* for Dot8 Scaling LCD */
+- if ((pVBInfo->LCDInfo & EnableScalingLCD)
+- && (modeflag & Charx8Dot)
+- && ((pVBInfo->IF_DEF_VideoCapture) == 1)) {
+- vclk = VCLK25_175; /* ; set to VCLK25MHz always */
+- }
+-
+- if (ModeNo <= 0x13)
+- return vclk;
+-
+- return pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetVCLKLen */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di, PVB_DEVICE_INFO pVBInfo)
+-{
+- if (pVBInfo->
+- VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV |
+- VB_XGI302LV | VB_XGI301C)) {
+- if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+- && (pVBInfo->SetFlag & ProgrammingCRT2)) {
+- di[0] = XGI_VBVCLKData[vclkindex].SR2B;
+- di[1] = XGI_VBVCLKData[vclkindex].SR2C;
+- }
+- }
+- else {
+- di[0] = XGI_VCLKData[vclkindex].SR2B;
+- di[1] = XGI_VCLKData[vclkindex].SR2C;
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT2Offset */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT2Offset(USHORT ModeNo,
+- USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT offset;
+- UCHAR temp;
+-
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- return;
+- }
+-
+- offset =
+- XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- HwDeviceExtension, pVBInfo);
+- temp = (UCHAR) (offset & 0xFF);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp);
+- temp = (UCHAR) ((offset & 0xFF00) >> 8);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, temp);
+- temp = (UCHAR) (((offset >> 3) & 0xFF) + 1);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetOffset */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp,
+- colordepth,
+- modeinfo, index, infoflag;
+-
+- modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+- if (ModeNo <= 0x14)
+- infoflag = 0;
+- else
+- infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+-
+-
+- index = (modeinfo >> 8) & 0xFF;
+-
+- temp = pVBInfo->ScreenOffset[index];
+-
+- if (infoflag & InterlaceMode) {
+- temp = temp << 1;
+- }
+-
+- colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
+-
+- if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
+- return (temp * colordepth + (colordepth >> 1));
+- }
+- else
+- return (temp * colordepth);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT2FIFO */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT2FIFO(PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_PreSetGroup1 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempcx = 0, CRT1Index = 0, resinfo = 0;
+-#ifndef LINUX_XF86
+- USHORT temp = 0, tempax = 0, tempbx = 0, pushbx = 0, modeflag;
+-#endif
+-
+- if (ModeNo > 0x13) {
+- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+- CRT1Index &= IndexMask;
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- }
+-
+- XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
+- HwDeviceExtension, pVBInfo);
+- XGI_SetCRT2FIFO(pVBInfo);
+- /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
+-
+- for (tempcx = 4; tempcx < 7; tempcx++) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, tempcx, 0x0);
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetGroup1 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp = 0,
+- tempax = 0,
+- tempbx = 0,
+- tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
+-
+- if (ModeNo > 0x13) {
+- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+- CRT1Index &= IndexMask;
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- }
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- /* bainy change table name */
+- if (modeflag & HalfDCLK) {
+- temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
+- temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
+- temp);
+- temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
+- tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
+- pushbx = pVBInfo->VGAHDE / 2 + 16;
+- tempcx = tempcx >> 1;
+- tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+- tempcx += tempbx;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+- tempbx |=
+- ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
+- tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+- tempcx &= 0x1F;
+- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
+- temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+- tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+- }
+-
+- tempbx += 4;
+- tempcx += 4;
+-
+- if (tempcx > (pVBInfo->VGAHT / 2))
+- tempcx = pVBInfo->VGAHT / 2;
+-
+- temp = tempbx & 0x00FF;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
+- }
+- else {
+- temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
+- temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
+- temp);
+- temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
+- tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
+- pushbx = pVBInfo->VGAHDE + 16;
+- tempcx = tempcx >> 1;
+- tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
+- tempcx += tempbx;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
+- tempbx |=
+- ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5] & 0xC0) << 2);
+- tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
+- tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
+- tempcx &= 0x1F;
+- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
+- temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
+- tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
+- tempbx += 16;
+- tempcx += 16;
+- }
+-
+- if (tempcx > pVBInfo->VGAHT)
+- tempcx = pVBInfo->VGAHT;
+-
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
+- }
+-
+- tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
+- tempbx = pushbx;
+- tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+- tempax |= (tempbx & 0xFF00);
+- temp = (tempax & 0xFF00) >> 8;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp);
+- tempcx = (pVBInfo->VGAVT - 1);
+- temp = tempcx & 0x00FF;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
+- tempbx = pVBInfo->VGAVDE - 1;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, temp);
+- temp = ((tempbx & 0xFF00) << 3) >> 8;
+- temp |= ((tempcx & 0xFF00) >> 8);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, temp);
+-
+- tempax = pVBInfo->VGAVDE;
+- tempbx = pVBInfo->VGAVDE;
+- tempcx = pVBInfo->VGAVT;
+- tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
+- tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+-
+- if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
+- tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
+- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+-
+- if (temp & 0x04)
+- tempbx |= 0x0100;
+-
+- if (temp & 0x080)
+- tempbx |= 0x0200;
+-
+- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
+-
+- if (temp & 0x08)
+- tempbx |= 0x0400;
+-
+- temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
+- tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
+- }
+-
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
+- temp = ((tempbx & 0xFF00) >> 8) << 4;
+- temp = ((tempcx & 0x000F) | (temp));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, temp);
+- tempax = 0;
+-
+- if (modeflag & DoubleScanMode)
+- tempax |= 0x80;
+-
+- if (modeflag & HalfDCLK)
+- tempax |= 0x40;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLockRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT push1,
+- push2, tempax, tempbx = 0, tempcx, temp, resinfo, modeflag, CRT1Index;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+- CRT1Index &= IndexMask;
+- }
+-
+- if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
+- return;
+- }
+-
+- temp = 0xFF; /* set MAX HT */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
+- /* if ( modeflag & Charx8Dot ) tempcx = 0x08 ; */
+- /* else */
+- tempcx = 0x08;
+-
+- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+- modeflag |= Charx8Dot;
+-
+- tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
+-
+- if (modeflag & HalfDCLK)
+- tempax = tempax >> 1;
+-
+- tempax = (tempax / tempcx) - 1;
+- tempbx |= ((tempax & 0x00FF) << 8);
+- temp = tempax & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x04, temp);
+-
+- temp = (tempbx & 0xFF00) >> 8;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (!
+- (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)))
+- temp += 2;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
+- if (resinfo == 7)
+- temp -= 2;
+- }
+- }
+- else if (resinfo == 7)
+- temp -= 2;
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
+-
+- if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
+- if (pVBInfo->VBInfo & SetCRT2ToTV)
+- tempax = pVBInfo->VGAHT;
+- else
+- tempax = XGI_GetVGAHT2(pVBInfo);
+- }
+-
+- if (tempax >= pVBInfo->VGAHT) {
+- tempax = pVBInfo->VGAHT;
+- }
+-
+- if (modeflag & HalfDCLK) {
+- tempax = tempax >> 1;
+- }
+-
+- tempax = (tempax / tempcx) - 5;
+- tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- temp = (tempbx & 0x00FF) - 1;
+- if (!(modeflag & HalfDCLK)) {
+- temp -= 6;
+- if (pVBInfo->TVInfo & TVSimuMode) {
+- temp -= 4;
+- if (ModeNo > 0x13)
+- temp -= 10;
+- }
+- }
+- }
+- else {
+- /* tempcx = tempbx & 0x00FF ; */
+- tempbx = (tempbx & 0xFF00) >> 8;
+- tempcx = (tempcx + tempbx) >> 1;
+- temp = (tempcx & 0x00FF) + 2;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- temp -= 1;
+- if (!(modeflag & HalfDCLK)) {
+- if ((modeflag & Charx8Dot)) {
+- temp += 4;
+- if (pVBInfo->VGAHDE >= 800) {
+- temp -= 6;
+- }
+- }
+- }
+- }
+- else {
+- if (!(modeflag & HalfDCLK)) {
+- temp -= 4;
+- if (pVBInfo->LCDResInfo != Panel1280x960) {
+- if (pVBInfo->VGAHDE >= 800) {
+- temp -= 7;
+- if (pVBInfo->ModeType == ModeEGA) {
+- if (pVBInfo->VGAVDE == 1024) {
+- temp += 15;
+- if (pVBInfo->LCDResInfo != Panel1280x1024) {
+- temp += 7;
+- }
+- }
+- }
+-
+- if (pVBInfo->VGAHDE >= 1280) {
+- if (pVBInfo->LCDResInfo != Panel1280x960) {
+- if (!
+- (pVBInfo->
+- LCDInfo & (LCDNonExpanding |
+- EnableScalingLCD))) {
+- temp += 28;
+- }
+- }
+- }
+- }
+- }
+- }
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (pVBInfo->TVInfo & TVSimuMode) {
+- if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11)
+- || (ModeNo == 0x13) || (ModeNo == 0x0F)) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x5b);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
+- }
+-
+- if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
+- if (pVBInfo->TVInfo & SetNTSCTV) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x61);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x41);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
+- }
+- }
+-
+- if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)) {
+- if (pVBInfo->TVInfo & SetNTSCTV) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x54);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x55);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
+- }
+- }
+-
+- if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D)
+- || (ModeNo == 0x50)) {
+- if (pVBInfo->TVInfo & SetNTSCTV) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x30);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2f);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x02);
+- }
+- }
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
+-
+- tempbx = pVBInfo->VGAVT;
+- push1 = tempbx;
+- tempcx = 0x121;
+- tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
+-
+- if (tempbx == 357)
+- tempbx = 350;
+- if (tempbx == 360)
+- tempbx = 350;
+- if (tempbx == 375)
+- tempbx = 350;
+- if (tempbx == 405)
+- tempbx = 400;
+- if (tempbx == 525)
+- tempbx = 480;
+-
+- push2 = tempbx;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+- if (pVBInfo->LCDResInfo == Panel1024x768) {
+- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+- if (tempbx == 350)
+- tempbx += 5;
+- if (tempbx == 480)
+- tempbx += 5;
+- }
+- }
+- }
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
+- tempbx = push2;
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
+-
+- if (tempbx & 0x0100) {
+- tempcx |= 0x0002;
+- }
+-
+- tempax = 0x000B;
+-
+- if (modeflag & DoubleScanMode) {
+- tempax |= 0x08000;
+- }
+-
+- if (tempbx & 0x0200) {
+- tempcx |= 0x0040;
+- }
+-
+- temp = (tempax & 0xFF00) >> 8;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
+-
+- if (tempbx & 0x0400) {
+- tempcx |= 0x0600;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
+-
+- tempax = push1;
+- tempax -= tempbx; /* 0x0C Vertical Retrace Start */
+- tempax = tempax >> 2;
+- push1 = tempax; /* push ax */
+-
+- if (resinfo != 0x09) {
+- tempax = tempax << 1;
+- tempbx += tempax;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+- tempbx -= 10;
+- else {
+- if (pVBInfo->TVInfo & TVSimuMode) {
+- if (pVBInfo->TVInfo & SetPALTV) {
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- if (!
+- (pVBInfo->
+- TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p
+- | SetYPbPrMode1080i)))
+- tempbx += 40;
+- }
+- else
+- tempbx += 40;
+- }
+- }
+- }
+- }
+- else
+- tempbx -= 10;
+- }
+- else {
+- if (pVBInfo->TVInfo & TVSimuMode) {
+- if (pVBInfo->TVInfo & SetPALTV) {
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- if (!
+- (pVBInfo->
+- TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p |
+- SetYPbPrMode1080i)))
+- tempbx += 40;
+- }
+- else
+- tempbx += 40;
+- }
+- }
+- }
+- tempax = push1;
+- tempax = tempax >> 2;
+- tempax++;
+- tempax += tempbx;
+- push1 = tempax; /* push ax */
+-
+- if ((pVBInfo->TVInfo & SetPALTV)) {
+- if (tempbx <= 513) {
+- if (tempax >= 513) {
+- tempbx = 513;
+- }
+- }
+- }
+-
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
+-
+- if (tempbx & 0x0100) {
+- tempcx |= 0x0008;
+- }
+-
+- if (tempbx & 0x0200) {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
+- }
+-
+- tempbx++;
+-
+- if (tempbx & 0x0100) {
+- tempcx |= 0x0004;
+- }
+-
+- if (tempbx & 0x0200) {
+- tempcx |= 0x0080;
+- }
+-
+- if (tempbx & 0x0400) {
+- tempcx |= 0x0C00;
+- }
+-
+- tempbx = push1; /* pop ax */
+- temp = tempbx & 0x00FF;
+- temp &= 0x0F;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
+-
+- if (tempbx & 0x0010) {
+- tempcx |= 0x2000;
+- }
+-
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
+- temp = (tempcx & 0x0FF00) >> 8;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
+- tempax = modeflag;
+- temp = (tempax & 0xFF00) >> 8;
+-
+- temp = (temp >> 1) & 0x09;
+-
+- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+- temp |= 0x01;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
+-
+- if (pVBInfo->LCDInfo & LCDRGB18Bit)
+- temp = 0x80;
+- else
+- temp = 0x00;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
+-
+- return;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetGroup2 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT i,
+- j,
+- tempax,
+- tempbx, tempcx, temp, push1, push2, modeflag, resinfo, crt2crtc;
+-#ifndef LINUX_XF86
+- USHORT temp1, temp3, resindex, xres;
+-#endif
+-/* XGINew_RY1COE = 0 ,
+- XGINew_RY2COE = 0 ,
+- XGINew_RY3COE = 0 ,
+- XGINew_RY4COE = 0 ,
+- XGINew_RY5COE = 0 ,
+- XGINew_RY6COE = 0 ,
+- XGINew_RY7COE = 0 ;
+-*/
+-
+-#ifndef LINUX_XF86
+- UCHAR *PhasePoint;
+-#endif
+- const UCHAR *TimingPoint;
+-
+- ULONG longtemp, tempeax, tempebx, temp2, tempecx;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+- crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+- }
+-
+- tempax = 0;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
+- tempax |= 0x0800;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+- tempax |= 0x0400;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToSCART)
+- tempax |= 0x0200;
+-
+- if (!(pVBInfo->TVInfo & SetPALTV))
+- tempax |= 0x1000;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+- tempax |= 0x0100;
+-
+- if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+- tempax &= 0xfe00;
+-
+- ErrorF("Part2 0 = %x ",
+- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+- ErrorF(" pVBInfo->VBInfo =%x", pVBInfo->VBInfo);
+-
+- tempax = (tempax & 0xff00) >> 8;
+- ErrorF("tempax = %x ", tempax);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0, tempax);
+- TimingPoint = pVBInfo->NTSCTiming;
+-
+- if (pVBInfo->TVInfo & SetPALTV) {
+- TimingPoint = pVBInfo->PALTiming;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- TimingPoint = pVBInfo->HiTVExtTiming;
+-
+- if (pVBInfo->VBInfo & SetInSlaveMode)
+- TimingPoint = pVBInfo->HiTVSt2Timing;
+-
+- if (pVBInfo->SetFlag & TVSimuMode)
+- TimingPoint = pVBInfo->HiTVSt1Timing;
+-
+- if (!(modeflag & Charx8Dot))
+- TimingPoint = pVBInfo->HiTVTextTiming;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+- if (pVBInfo->TVInfo & SetYPbPrMode525i)
+- TimingPoint = pVBInfo->YPbPr525iTiming;
+-
+- if (pVBInfo->TVInfo & SetYPbPrMode525p)
+- TimingPoint = pVBInfo->YPbPr525pTiming;
+-
+- if (pVBInfo->TVInfo & SetYPbPrMode750p)
+- TimingPoint = pVBInfo->YPbPr750pTiming;
+- }
+-
+- for (i = 0x01, j = 0; i <= 0x2D; i++, j++) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]);
+- }
+-
+- for (i = 0x39; i <= 0x45; i++, j++) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
+- }
+-
+- temp = pVBInfo->NewFlickerMode;
+- temp &= 0x80;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xFF, temp);
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+- tempax = 950;
+-
+- if (pVBInfo->TVInfo & SetPALTV)
+- tempax = 520;
+- else
+- tempax = 440;
+-
+- if (pVBInfo->VDE <= tempax) {
+- tempax -= pVBInfo->VDE;
+- tempax = tempax >> 2;
+- tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
+- push1 = tempax;
+- temp = (tempax & 0xFF00) >> 8;
+- temp += (USHORT) TimingPoint[0];
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (pVBInfo->
+- VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
+- SetCRT2ToYPbPr)) {
+- tempcx = pVBInfo->VGAHDE;
+- if (tempcx >= 1024) {
+- temp = 0x17; /* NTSC */
+- if (pVBInfo->TVInfo & SetPALTV)
+- temp = 0x19; /* PAL */
+- }
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
+- tempax = push1;
+- temp = (tempax & 0xFF00) >> 8;
+- temp += TimingPoint[1];
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if ((pVBInfo->
+- VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART
+- | SetCRT2ToYPbPr))) {
+- tempcx = pVBInfo->VGAHDE;
+- if (tempcx >= 1024) {
+- temp = 0x1D; /* NTSC */
+- if (pVBInfo->TVInfo & SetPALTV)
+- temp = 0x52; /* PAL */
+- }
+- }
+- }
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, temp);
+- }
+-
+- /* 301b */
+- tempcx = pVBInfo->HT;
+-
+- if (XGI_IsLCDDualLink(pVBInfo))
+- tempcx = tempcx >> 1;
+-
+- tempcx -= 2;
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1B, temp);
+-
+- temp = (tempcx & 0xFF00) >> 8;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
+-
+- tempcx = pVBInfo->HT >> 1;
+- push1 = tempcx; /* push cx */
+- tempcx += 7;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- tempcx -= 4;
+- }
+-
+- temp = tempcx & 0x00FF;
+- temp = temp << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x22, 0x0F, temp);
+-
+- tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+- tempbx += tempcx;
+- push2 = tempbx;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x24, temp);
+- temp = (tempbx & 0xFF00) >> 8;
+- temp = temp << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, 0x0F, temp);
+-
+- tempbx = push2;
+- tempbx = tempbx + 8;
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- tempbx = tempbx - 4;
+- tempcx = tempbx;
+- }
+-
+- temp = (tempbx & 0x00FF) << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x29, 0x0F, temp);
+-
+- j += 2;
+- tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x27, temp);
+- temp = ((tempcx & 0xFF00) >> 8) << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x28, 0x0F, temp);
+-
+- tempcx += 8;
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- tempcx -= 4;
+- }
+-
+- temp = tempcx & 0xFF;
+- temp = temp << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2A, 0x0F, temp);
+-
+- tempcx = push1; /* pop cx */
+- j += 2;
+- temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
+- tempcx -= temp;
+- temp = tempcx & 0x00FF;
+- temp = temp << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2D, 0x0F, temp);
+-
+- tempcx -= 11;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+- tempax = XGI_GetVGAHT2(pVBInfo);
+- tempcx = tempax - 1;
+- }
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2E, temp);
+-
+- tempbx = pVBInfo->VDE;
+-
+- if (pVBInfo->VGAVDE == 360)
+- tempbx = 746;
+- if (pVBInfo->VGAVDE == 375)
+- tempbx = 746;
+- if (pVBInfo->VGAVDE == 405)
+- tempbx = 853;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+- if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
+- tempbx = tempbx >> 1;
+- }
+- else
+- tempbx = tempbx >> 1;
+- }
+-
+- tempbx -= 2;
+- temp = tempbx & 0x00FF;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (ModeNo == 0x2f)
+- temp += 1;
+- }
+- }
+- }
+- else {
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (ModeNo == 0x2f)
+- temp += 1;
+- }
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2F, temp);
+-
+- temp = (tempcx & 0xFF00) >> 8;
+- temp |= ((tempbx & 0xFF00) >> 8) << 6;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
+- temp |= 0x10;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+- temp |= 0x20;
+- }
+- }
+- else {
+- temp |= 0x10;
+- if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
+- temp |= 0x20;
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, temp);
+-
+- if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
+- tempbx = pVBInfo->VDE;
+- tempcx = tempbx - 2;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
+- tempbx = tempbx >> 1;
+- }
+-
+- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+- temp = 0;
+- if (tempcx & 0x0400)
+- temp |= 0x20;
+-
+- if (tempbx & 0x0400)
+- temp |= 0x40;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, temp);
+- }
+-
+- temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, temp);
+- temp = (tempbx - 3) & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x47, temp);
+- }
+-
+- tempbx = tempbx & 0x00FF;
+-
+- if (!(modeflag & HalfDCLK)) {
+- tempcx = pVBInfo->VGAHDE;
+- if (tempcx >= pVBInfo->HDE) {
+- tempbx |= 0x2000;
+- tempax &= 0x00FF;
+- }
+- }
+-
+- tempcx = 0x0101;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b */
+- if (pVBInfo->VGAHDE >= 1024) {
+- tempcx = 0x1920;
+- if (pVBInfo->VGAHDE >= 1280) {
+- tempcx = 0x1420;
+- tempbx = tempbx & 0xDFFF;
+- }
+- }
+- }
+-
+- if (!(tempbx & 0x2000)) {
+- if (modeflag & HalfDCLK) {
+- tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
+- }
+-
+- push1 = tempbx;
+- tempeax = pVBInfo->VGAHDE;
+- tempebx = (tempcx & 0xFF00) >> 8;
+- longtemp = tempeax * tempebx;
+- tempecx = tempcx & 0x00FF;
+- longtemp = longtemp / tempecx;
+-
+- /* 301b */
+- tempecx = 8 * 1024;
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- tempecx = tempecx * 8;
+- }
+-
+- longtemp = longtemp * tempecx;
+- tempecx = pVBInfo->HDE;
+- temp2 = longtemp % tempecx;
+- tempeax = longtemp / tempecx;
+- if (temp2 != 0) {
+- tempeax += 1;
+- }
+-
+- tempax = (USHORT) tempeax;
+-
+- /* 301b */
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- tempcx = ((tempax & 0xFF00) >> 5) >> 8;
+- }
+- /* end 301b */
+-
+- tempbx = push1;
+- tempbx =
+- (USHORT) (((tempeax & 0x0000FF00) & 0x1F00) | (tempbx & 0x00FF));
+- tempax = (USHORT) (((tempeax & 0x000000FF) << 8) | (tempax & 0x00FF));
+- temp = (tempax & 0xFF00) >> 8;
+- }
+- else {
+- temp = (tempax & 0x00FF) >> 8;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x44, temp);
+- temp = (tempbx & 0xFF00) >> 8;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x45, ~0x03F, temp);
+- temp = tempcx & 0x00FF;
+-
+- if (tempbx & 0x2000)
+- temp = 0;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+- temp |= 0x18;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, ~0x1F, temp);
+- if (pVBInfo->TVInfo & SetPALTV) {
+- tempbx = 0x0382;
+- tempcx = 0x007e;
+- }
+- else {
+- tempbx = 0x0369;
+- tempcx = 0x0061;
+- }
+-
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4b, temp);
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4c, temp);
+-
+- temp = ((tempcx & 0xFF00) >> 8) & 0x03;
+- temp = temp << 2;
+- temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+- temp |= 0x10;
+-
+- if (pVBInfo->TVInfo & SetYPbPrMode525p)
+- temp |= 0x20;
+-
+- if (pVBInfo->TVInfo & SetYPbPrMode750p)
+- temp |= 0x60;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d, temp);
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43); /* 301b change */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, (USHORT) (temp - 3));
+-
+- if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
+- if (pVBInfo->TVInfo & NTSC1024x768) {
+- TimingPoint = XGI_NTSC1024AdjTime;
+- for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
+- TimingPoint[j]);
+- }
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, 0x72);
+- }
+- }
+-
+- /* [ycchen] 01/14/03 Modify for 301C PALM Support */
+- if (pVBInfo->VBType & VB_XGI301C) {
+- if (pVBInfo->TVInfo & SetPALMTV)
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x08, 0x08); /* PALM Mode */
+- }
+-
+- if (pVBInfo->TVInfo & SetPALMTV) {
+- tempax = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01);
+- tempax--;
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, tempax);
+-
+- /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xEF);
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, 0x00);
+- }
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- return;
+- }
+- ErrorF("5935 Part2 0 = %x ",
+- XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLCDRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT push1,
+- push2,
+- pushbx,
+- tempax,
+- tempbx,
+- tempcx, temp, tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
+-
+- XGI_LCDDesStruct *LCDBDesPtr = NULL;
+- XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
+-
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+- resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
+- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+- CRT1Index &= IndexMask;
+- }
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
+- return;
+- }
+-
+- tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
+-
+- if (XGI_IsLCDDualLink(pVBInfo))
+- tempbx = tempbx >> 1;
+-
+- tempbx -= 1;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2C, temp);
+- temp = (tempbx & 0xFF00) >> 8;
+- temp = temp << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2B, 0x0F, temp);
+- temp = 0x01;
+-
+- if (pVBInfo->LCDResInfo == Panel1280x1024) {
+- if (pVBInfo->ModeType == ModeEGA) {
+- if (pVBInfo->VGAHDE >= 1024) {
+- temp = 0x02;
+- if (pVBInfo->LCDInfo & LCDVESATiming)
+- temp = 0x01;
+- }
+- }
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, temp);
+- tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
+- push1 = tempbx;
+- tempbx--;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x03, temp);
+- temp = ((tempbx & 0xFF00) >> 8) & 0x07;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0C, ~0x07, temp);
+-
+- tempcx = pVBInfo->VT - 1;
+- push2 = tempcx + 1;
+- temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x19, temp);
+- temp = (tempcx & 0xFF00) >> 8;
+- temp = temp << 5;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, temp);
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
+-
+- /* Customized LCDB Des no add */
+- LCDBDesPtr = (XGI_LCDDesStruct *) XGI_GetLcdPtr(5, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD) {
+- tempbx = pVBInfo->HDE;
+- tempcx = pVBInfo->VDE;
+- }
+- else {
+- get_HDE_VDE(pVBInfo, & tempbx, & tempcx);
+- }
+-
+- pushbx = tempbx;
+- tempax = pVBInfo->VT;
+- pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
+- pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
+- pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
+- pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
+- tempbx = pVBInfo->LCDVDES;
+- tempcx += tempbx;
+-
+- if (tempcx >= tempax)
+- tempcx -= tempax; /* lcdvdes */
+-
+- temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x05, temp);
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x06, temp);
+- tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
+- tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
+- tempah = tempch;
+- tempah = tempah << 3;
+- tempah |= tempbh;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, tempah);
+-
+- /* getlcdsync() */
+- XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+- if (pVBInfo->LCDInfo & EnableScalingLCD) {
+- LCDPtr1 =
+- (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- tempbx = LCDPtr1->LCDVSync;
+- }
+- tempcx = tempbx;
+- tempax = pVBInfo->VT;
+- tempbx = pVBInfo->LCDVRS;
+-
+- /* if ( SetLCD_Info & EnableScalingLCD ) */
+- tempcx += tempbx;
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x04, temp);
+- temp = (tempbx & 0xFF00) >> 8;
+- temp = temp << 4;
+- temp |= (tempcx & 0x000F);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
+- tempcx = pushbx;
+- tempax = pVBInfo->HT;
+- tempbx = pVBInfo->LCDHDES;
+- tempbx &= 0x0FFF;
+-
+- if (XGI_IsLCDDualLink(pVBInfo)) {
+- tempax = tempax >> 1;
+- tempbx = tempbx >> 1;
+- tempcx = tempcx >> 1;
+- }
+-
+- if (pVBInfo->VBType & VB_XGI302LV)
+- tempbx += 1;
+-
+- if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
+- tempbx += 1;
+-
+- tempcx += tempbx;
+-
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
+- temp = ((tempbx & 0xFF00) >> 8) << 4;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x20, temp);
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
+- temp = (tempcx & 0xFF00) >> 8;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, temp);
+-
+- /* getlcdsync() */
+- XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
+- if (pVBInfo->LCDInfo & EnableScalingLCD) {
+- LCDPtr1 =
+- (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
+- RefreshRateTableIndex,
+- pVBInfo);
+- tempax = LCDPtr1->LCDHSync;
+- }
+- tempcx = tempax;
+- tempax = pVBInfo->HT;
+- tempbx = pVBInfo->LCDHRS;
+- /* if ( SetLCD_Info & EnableScalingLCD) */
+- if (XGI_IsLCDDualLink(pVBInfo)) {
+- tempax = tempax >> 1;
+- tempbx = tempbx >> 1;
+- tempcx = tempcx >> 1;
+- }
+-
+- if (pVBInfo->VBType & VB_XGI302LV)
+- tempbx += 1;
+-
+- tempcx += tempbx;
+-
+- if (tempcx >= tempax)
+- tempcx -= tempax;
+-
+- temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1C, temp);
+-
+- temp = (tempbx & 0xFF00) >> 8;
+- temp = temp << 4;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
+- temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x21, temp);
+-
+- if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
+- if (pVBInfo->VGAVDE == 525) {
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+- | VB_XGI301C)) {
+- temp = 0xC6;
+- }
+- else
+- temp = 0xC4;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, 0xB3);
+- }
+-
+- if (pVBInfo->VGAVDE == 420) {
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+- | VB_XGI301C)) {
+- temp = 0x4F;
+- }
+- else
+- temp = 0x4E;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetTap4Ptr */
+-/* Input : */
+-/* Output : di -> Tap4 Reg. Setting Pointer */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-const XGI301C_Tap4TimingStruct *
+-XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, tempbx, i;
+-
+- const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+-
+- if (tempcx == 0) {
+- tempax = pVBInfo->VGAHDE;
+- tempbx = pVBInfo->HDE;
+- }
+- else {
+- tempax = pVBInfo->VGAVDE;
+- tempbx = pVBInfo->VDE;
+- }
+-
+- if (tempax < tempbx)
+- return &EnlargeTap4Timing[0];
+- else if (tempax == tempbx)
+- return &NoScaleTap4Timing[0]; /* 1:1 */
+- else
+- Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
+-
+- if (pVBInfo->TVInfo & SetPALTV)
+- Tap4TimingPtr = PALTap4Timing;
+-
+-
+- if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
+- if (pVBInfo->TVInfo & SetYPbPrMode525i)
+- Tap4TimingPtr = YPbPr525iTap4Timing;
+- if (pVBInfo->TVInfo & SetYPbPrMode525p)
+- Tap4TimingPtr = YPbPr525pTap4Timing;
+- if (pVBInfo->TVInfo & SetYPbPrMode750p)
+- Tap4TimingPtr = YPbPr750pTap4Timing;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+- Tap4TimingPtr = HiTVTap4Timing;
+-
+- i = 0;
+- while (Tap4TimingPtr[i].DE != 0xFFFF) {
+- if (Tap4TimingPtr[i].DE == tempax)
+- break;
+- i++;
+- }
+- return &Tap4TimingPtr[i];
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetTap4Regs */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo)
+-{
+-
+-#ifndef LINUX_XF86
+- USHORT tempcx;
+-#endif
+- USHORT i, j;
+-
+- const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
+-
+- if (!(pVBInfo->VBType & VB_XGI301C))
+- return;
+-
+-#ifndef Tap4
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
+-#else /* Tap4 Setting */
+-
+- Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
+- for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
+- Tap4TimingPtr->Reg[j]);
+-
+- if ((pVBInfo->VBInfo & SetCRT2ToTV)
+- && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
+- Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
+- for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
+- Tap4TimingPtr->Reg[j]);
+- }
+-
+- if ((pVBInfo->VBInfo & SetCRT2ToTV)
+- && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
+- else
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
+-#endif
+-}
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetGroup3 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT i;
+- const UCHAR *tempdi;
+- USHORT modeflag;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+- }
+-
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x00, 0x00);
+- if (pVBInfo->TVInfo & SetPALTV) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xF5);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xB7);
+- }
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+- return;
+- }
+-
+- if (pVBInfo->TVInfo & SetPALMTV) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x3D, 0xA8);
+- }
+-
+- if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
+- || (pVBInfo->VBInfo & SetCRT2ToYPbPr)) {
+- if (pVBInfo->TVInfo & SetYPbPrMode525i) {
+- return;
+- }
+- tempdi = pVBInfo->HiTVGroup3Data;
+- if (pVBInfo->SetFlag & TVSimuMode) {
+- tempdi = pVBInfo->HiTVGroup3Simu;
+- if (!(modeflag & Charx8Dot)) {
+- tempdi = pVBInfo->HiTVGroup3Text;
+- }
+- }
+-
+- if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+- tempdi = pVBInfo->Ren525pGroup3;
+- }
+- if (pVBInfo->TVInfo & SetYPbPrMode750p) {
+- tempdi = pVBInfo->Ren750pGroup3;
+- }
+-
+- for (i = 0; i <= 0x3E; i++) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, i, tempdi[i]);
+- }
+- if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
+- if (pVBInfo->TVInfo & SetYPbPrMode525p) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x28, 0x3f);
+- }
+- }
+- }
+- return;
+-} /* {end of XGI_SetGroup3} */
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetGroup4 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+- PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, tempcx, tempbx, modeflag, temp, temp2;
+-#ifndef LINUX_XF86
+- USHORT push1;
+-#endif
+-
+- ULONG tempebx, tempeax, templong;
+-
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+- }
+-
+- temp = pVBInfo->RVBHCFACT;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x13, temp);
+-
+- tempbx = pVBInfo->RVBHCMAX;
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x14, temp);
+- temp2 = ((tempbx & 0xFF00) >> 8) << 7;
+- tempcx = pVBInfo->VGAHT - 1;
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x16, temp);
+-
+- temp = ((tempcx & 0xFF00) >> 8) << 3;
+- temp2 |= temp;
+-
+- tempcx = pVBInfo->VGAVT - 1;
+- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+- tempcx -= 5;
+- }
+-
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x17, temp);
+- temp = temp2 | ((tempcx & 0xFF00) >> 8);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x15, temp);
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, 0x08);
+- tempcx = pVBInfo->VBInfo;
+- tempbx = pVBInfo->VGAHDE;
+-
+- if (modeflag & HalfDCLK) {
+- tempbx = tempbx >> 1;
+- }
+-
+- if (XGI_IsLCDDualLink(pVBInfo))
+- tempbx = tempbx >> 1;
+-
+- if (tempcx & SetCRT2ToHiVisionTV) {
+- temp = 0;
+- if (tempbx <= 1024)
+- temp = 0xA0;
+- if (tempbx == 1280)
+- temp = 0xC0;
+- }
+- else if (tempcx & SetCRT2ToTV) {
+- temp = 0xA0;
+- if (tempbx <= 800)
+- temp = 0x80;
+- }
+- else {
+- temp = 0x80;
+- if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+- temp = 0;
+- if (tempbx > 800)
+- temp = 0x60;
+- }
+- }
+-
+- if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
+- temp = 0x00;
+- if (pVBInfo->VGAHDE == 1280)
+- temp = 0x40;
+- if (pVBInfo->VGAHDE == 1024)
+- temp = 0x20;
+- }
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
+-
+- tempebx = pVBInfo->VDE;
+-
+- if (tempcx & SetCRT2ToHiVisionTV) {
+- if (!(temp & 0xE000))
+- tempbx = tempbx >> 1;
+- }
+-
+- tempcx = pVBInfo->RVBHRS;
+- temp = tempcx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x18, temp);
+-
+- tempeax = pVBInfo->VGAVDE;
+- tempcx |= 0x04000;
+-
+-
+- if (tempeax <= tempebx) {
+- tempcx = (tempcx & (~0x4000));
+- tempeax = pVBInfo->VGAVDE;
+- }
+- else {
+- tempeax -= tempebx;
+- }
+-
+-
+- templong = (tempeax * 256 * 1024) % tempebx;
+- tempeax = (tempeax * 256 * 1024) / tempebx;
+- tempebx = tempeax;
+-
+- if (templong != 0) {
+- tempebx++;
+- }
+-
+-
+- temp = (USHORT) (tempebx & 0x000000FF);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1B, temp);
+-
+- temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1A, temp);
+- tempbx = (USHORT) (tempebx >> 16);
+- temp = tempbx & 0x00FF;
+- temp = temp << 4;
+- temp |= ((tempcx & 0xFF00) >> 8);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x19, temp);
+-
+- /* 301b */
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- temp = 0x0028;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1C, temp);
+- tempax = pVBInfo->VGAHDE;
+- if (modeflag & HalfDCLK) {
+- tempax = tempax >> 1;
+- }
+-
+- if (XGI_IsLCDDualLink(pVBInfo))
+- tempax = tempax >> 1;
+-
+- /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
+- if (pVBInfo->VBInfo & SetCRT2ToLCD) {
+- if (tempax > 800)
+- tempax -= 800;
+- }
+- else {
+- if (pVBInfo->VGAHDE > 800) {
+- if (pVBInfo->VGAHDE == 1024)
+- tempax = (tempax * 25 / 32) - 1;
+- else
+- tempax = (tempax * 20 / 32) - 1;
+- }
+- }
+- tempax -= 1;
+-
+-/*
+- if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
+- {
+- if ( pVBInfo->VBType & VB_XGI301LV )
+- {
+- if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
+- {
+- if ( pVBInfo->VGAHDE > 800 )
+- {
+- if ( pVBInfo->VGAHDE == 1024 )
+- tempax = ( tempax * 25 / 32 ) - 1 ;
+- else
+- tempax = ( tempax * 20 / 32 ) - 1 ;
+- }
+- }
+- }
+- else
+- {
+- if ( pVBInfo->VGAHDE > 800 )
+- {
+- if ( pVBInfo->VGAHDE == 1024 )
+- tempax = ( tempax * 25 / 32 ) - 1 ;
+- else
+- tempax = ( tempax * 20 / 32 ) - 1 ;
+- }
+- }
+- }
+-*/
+-
+- temp = (tempax & 0xFF00) >> 8;
+- temp = ((temp & 0x0003) << 4);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, temp);
+- temp = (tempax & 0x00FF);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1D, temp);
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
+- if (pVBInfo->VGAHDE > 800) {
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, 0x08);
+- }
+- }
+- temp = 0x0036;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (!
+- (pVBInfo->
+- TVInfo & (NTSC1024x768 | SetYPbPrMode525p | SetYPbPrMode750p
+- | SetYPbPrMode1080i))) {
+- temp |= 0x0001;
+- if ((pVBInfo->VBInfo & SetInSlaveMode)
+- && (!(pVBInfo->TVInfo & TVSimuMode)))
+- temp &= (~0x0001);
+- }
+- }
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, 0x00C0,
+- temp);
+- tempbx = pVBInfo->HT;
+- if (XGI_IsLCDDualLink(pVBInfo))
+- tempbx = tempbx >> 1;
+- tempbx = (tempbx >> 1) - 2;
+- temp = ((tempbx & 0x0700) >> 8) << 3;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, 0x00C0,
+- temp);
+- temp = tempbx & 0x00FF;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x22, temp);
+- }
+- /* end 301b */
+-
+- if (pVBInfo->ISXPDOS == 0)
+- XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetGroup5 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT Pindex, Pdata;
+-
+- Pindex = pVBInfo->Part5Port;
+- Pdata = pVBInfo->Part5Port + 1;
+- if (pVBInfo->ModeType == ModeVGA) {
+- if (!
+- (pVBInfo->
+- VBInfo & (SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag))) {
+- XGINew_EnableCRT2(pVBInfo);
+- /* LoadDAC2(pVBInfo->Part5Port,ModeNo,ModeIdIndex); */
+- }
+- }
+- return;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetLcdPtr */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-const void *
+-XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT i, tempdx, tempcx, tempbx, tempal, modeflag, table;
+-
+- const XGI330_LCDDataTablStruct *tempdi = 0;
+-
+-
+- tempbx = BX;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+- }
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
+- if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x14) {
+- tempal = 0x0A;
+- }
+- else if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0F) {
+- tempal = 0x0B;
+- }
+- }
+-
+- tempal = tempal & 0x0f;
+-
+- if (tempbx <= 1) { /* ExpLink */
+- if (ModeNo <= 0x13) {
+- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
+- }
+- else {
+- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- if (ModeNo <= 0x13)
+- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
+- else
+- tempal =
+- pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
+- }
+-
+- if (tempbx & 0x01)
+- tempal = (tempal >> 4);
+-
+- tempal = (tempal & 0x0f);
+- }
+-
+- tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
+- if ((tempbx == 5) || (tempbx) == 7)
+- tempcx = LCDDesDataLen2;
+- else if ((tempbx == 3) || (tempbx == 8))
+- tempcx = LVDSDesDataLen2;
+- }
+- /* mov di, word ptr cs:LCDDataList[bx] */
+- /* tempdi=pVideoMemory[LCDDataList+tempbx*2]|(pVideoMemory[LCDDataList+tempbx*2+1]<<8); */
+-
+- switch (tempbx) {
+- case 0:
+- tempdi = XGI_EPLLCDCRT1Ptr_H;
+- break;
+- case 1:
+- tempdi = XGI_EPLLCDCRT1Ptr_V;
+- break;
+- case 2:
+- tempdi = XGI_EPLLCDDataPtr;
+- break;
+- case 3:
+- tempdi = XGI_EPLLCDDesDataPtr;
+- break;
+- case 4:
+- tempdi = XGI_LCDDataTable;
+- break;
+- case 5:
+- tempdi = XGI_LCDDesDataTable;
+- break;
+- case 6:
+- tempdi = XGI_EPLCHLCDRegPtr;
+- break;
+- case 7:
+- case 8:
+- case 9:
+- tempdi = 0;
+- break;
+- default:
+- break;
+- }
+-
+- if (tempdi == 0x00) /* OEMUtil */
+- return 0;
+-
+- table = tempbx;
+- i = 0;
+-
+- while (tempdi[i].PANELID != 0xff) {
+- tempdx = pVBInfo->LCDResInfo;
+- if (tempbx & 0x0080) { /* OEMUtil */
+- tempbx &= (~0x0080);
+- tempdx = pVBInfo->LCDTypeInfo;
+- }
+-
+- if (pVBInfo->LCDInfo & EnableScalingLCD) {
+- if ((pVBInfo->LCDInfo & EnableReduceTiming)
+- && (pVBInfo->LCDResInfo == Panel1600x1200)) {
+- tempdx = Panel1600x1200_1;
+- }
+- else {
+- tempdx &= (~PanelResInfo);
+- }
+- }
+- if (tempdi[i].PANELID == tempdx) {
+- tempbx = tempdi[i].MASK;
+- tempdx = pVBInfo->LCDInfo;
+-
+- if (ModeNo <= 0x13) /* alan 09/10/2003 */
+- tempdx |= SetLCDStdMode;
+-
+- if (modeflag & HalfDCLK)
+- tempdx |= SetLCDLowResolution;
+-
+- tempbx &= tempdx;
+- if (tempbx == tempdi[i].CAP)
+- break;
+- }
+- i++;
+- }
+-
+- if (table == 0) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_LVDSCRT11024x768_1_H[tempal];
+- break;
+- case 1:
+- return &XGI_LVDSCRT11024x768_2_H[tempal];
+- break;
+- case 2:
+- return &XGI_LVDSCRT11280x1024_1_H[tempal];
+- break;
+- case 3:
+- return &XGI_LVDSCRT11280x1024_2_H[tempal];
+- break;
+- case 4:
+- return &XGI_LVDSCRT11400x1050_1_H[tempal];
+- break;
+- case 5:
+- return &XGI_LVDSCRT11400x1050_2_H[tempal];
+- break;
+- case 6:
+- return &XGI_LVDSCRT11600x1200_1_H[tempal];
+- break;
+- case 7:
+- return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
+- break;
+- case 8:
+- return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
+- break;
+- case 9:
+- return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
+- break;
+- case 10:
+- return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 1) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_LVDSCRT11024x768_1_V[tempal];
+- break;
+- case 1:
+- return &XGI_LVDSCRT11024x768_2_V[tempal];
+- break;
+- case 2:
+- return &XGI_LVDSCRT11280x1024_1_V[tempal];
+- break;
+- case 3:
+- return &XGI_LVDSCRT11280x1024_2_V[tempal];
+- break;
+- case 4:
+- return &XGI_LVDSCRT11400x1050_1_V[tempal];
+- break;
+- case 5:
+- return &XGI_LVDSCRT11400x1050_2_V[tempal];
+- break;
+- case 6:
+- return &XGI_LVDSCRT11600x1200_1_V[tempal];
+- break;
+- case 7:
+- return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
+- break;
+- case 8:
+- return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
+- break;
+- case 9:
+- return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
+- break;
+- case 10:
+- return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 2) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_LVDS1024x768Data_1[tempal];
+- break;
+- case 1:
+- return &XGI_LVDS1024x768Data_2[tempal];
+- break;
+- case 2:
+- return &XGI_LVDS1280x1024Data_1[tempal];
+- break;
+- case 3:
+- return &XGI_LVDS1280x1024Data_2[tempal];
+- break;
+- case 4:
+- return &XGI_LVDS1400x1050Data_1[tempal];
+- break;
+- case 5:
+- return &XGI_LVDS1400x1050Data_2[tempal];
+- break;
+- case 6:
+- return &XGI_LVDS1600x1200Data_1[tempal];
+- break;
+- case 7:
+- return &XGI_LVDSNoScalingData[tempal];
+- break;
+- case 8:
+- return &XGI_LVDS1024x768Data_1x75[tempal];
+- break;
+- case 9:
+- return &XGI_LVDS1024x768Data_2x75[tempal];
+- break;
+- case 10:
+- return &XGI_LVDS1280x1024Data_1x75[tempal];
+- break;
+- case 11:
+- return &XGI_LVDS1280x1024Data_2x75[tempal];
+- break;
+- case 12:
+- return &XGI_LVDSNoScalingDatax75[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 3) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_LVDS1024x768Des_1[tempal];
+- break;
+- case 1:
+- return &XGI_LVDS1024x768Des_3[tempal];
+- break;
+- case 2:
+- return &XGI_LVDS1024x768Des_2[tempal];
+- break;
+- case 3:
+- return &XGI_LVDS1280x1024Des_1[tempal];
+- break;
+- case 4:
+- return &XGI_LVDS1280x1024Des_2[tempal];
+- break;
+- case 5:
+- return &XGI_LVDS1400x1050Des_1[tempal];
+- break;
+- case 6:
+- return &XGI_LVDS1400x1050Des_2[tempal];
+- break;
+- case 7:
+- return &XGI_LVDS1600x1200Des_1[tempal];
+- break;
+- case 8:
+- return &XGI_LVDSNoScalingDesData[tempal];
+- break;
+- case 9:
+- return &XGI_LVDS1024x768Des_1x75[tempal];
+- break;
+- case 10:
+- return &XGI_LVDS1024x768Des_3x75[tempal];
+- break;
+- case 11:
+- return &XGI_LVDS1024x768Des_2x75[tempal];
+- break;
+- case 12:
+- return &XGI_LVDS1280x1024Des_1x75[tempal];
+- break;
+- case 13:
+- return &XGI_LVDS1280x1024Des_2x75[tempal];
+- break;
+- case 14:
+- return &XGI_LVDSNoScalingDesDatax75[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 4) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_ExtLCD1024x768Data[tempal];
+- break;
+- case 1:
+- return &XGI_StLCD1024x768Data[tempal];
+- break;
+- case 2:
+- return &XGI_CetLCD1024x768Data[tempal];
+- break;
+- case 3:
+- return &XGI_ExtLCD1280x1024Data[tempal];
+- break;
+- case 4:
+- return &XGI_StLCD1280x1024Data[tempal];
+- break;
+- case 5:
+- return &XGI_CetLCD1280x1024Data[tempal];
+- break;
+- case 6:
+- return &XGI_ExtLCD1400x1050Data[tempal];
+- break;
+- case 7:
+- return &XGI_StLCD1400x1050Data[tempal];
+- break;
+- case 8:
+- return &XGI_CetLCD1400x1050Data[tempal];
+- break;
+- case 9:
+- return &XGI_ExtLCD1600x1200Data[tempal];
+- break;
+- case 10:
+- return &XGI_StLCD1600x1200Data[tempal];
+- break;
+- case 11:
+- return &XGI_NoScalingData[tempal];
+- break;
+- case 12:
+- return &XGI_ExtLCD1024x768x75Data[tempal];
+- break;
+- case 13:
+- return &XGI_ExtLCD1024x768x75Data[tempal];
+- break;
+- case 14:
+- return &XGI_CetLCD1024x768x75Data[tempal];
+- break;
+- case 15:
+- return &XGI_ExtLCD1280x1024x75Data[tempal];
+- break;
+- case 16:
+- return &XGI_StLCD1280x1024x75Data[tempal];
+- break;
+- case 17:
+- return &XGI_CetLCD1280x1024x75Data[tempal];
+- break;
+- case 18:
+- return &XGI_NoScalingDatax75[tempal];
+- break;
+- case 19:
+- return &XGI_NoScalingData_1[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 5) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_ExtLCDDes1024x768Data[tempal];
+- break;
+- case 1:
+- return &XGI_StLCDDes1024x768Data[tempal];
+- break;
+- case 2:
+- return &XGI_CetLCDDes1024x768Data[tempal];
+- break;
+- case 3:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_ExtLCDDLDes1280x1024Data[tempal];
+- else
+- return &XGI_ExtLCDDes1280x1024Data[tempal];
+- break;
+- case 4:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_StLCDDLDes1280x1024Data[tempal];
+- else
+- return &XGI_StLCDDes1280x1024Data[tempal];
+- break;
+- case 5:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_CetLCDDLDes1280x1024Data[tempal];
+- else
+- return &XGI_CetLCDDes1280x1024Data[tempal];
+- break;
+- case 6:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_ExtLCDDLDes1400x1050Data[tempal];
+- else
+- return &XGI_ExtLCDDes1400x1050Data[tempal];
+- break;
+- case 7:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_StLCDDLDes1400x1050Data[tempal];
+- else
+- return &XGI_StLCDDes1400x1050Data[tempal];
+- break;
+- case 8:
+- return &XGI_CetLCDDes1400x1050Data[tempal];
+- break;
+- case 9:
+- return &XGI_CetLCDDes1400x1050Data2[tempal];
+- break;
+- case 10:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_ExtLCDDLDes1600x1200Data[tempal];
+- else
+- return &XGI_ExtLCDDes1600x1200Data[tempal];
+- break;
+- case 11:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_StLCDDLDes1600x1200Data[tempal];
+- else
+- return &XGI_StLCDDes1600x1200Data[tempal];
+- break;
+- case 12:
+- return &XGI_NoScalingDesData[tempal];
+- break;
+- case 13:
+- return &XGI_ExtLCDDes1024x768x75Data[tempal];
+- break;
+- case 14:
+- return &XGI_StLCDDes1024x768x75Data[tempal];
+- break;
+- case 15:
+- return &XGI_CetLCDDes1024x768x75Data[tempal];
+- break;
+- case 16:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
+- else
+- return &XGI_ExtLCDDes1280x1024x75Data[tempal];
+- break;
+- case 17:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_StLCDDLDes1280x1024x75Data[tempal];
+- else
+- return &XGI_StLCDDes1280x1024x75Data[tempal];
+- break;
+- case 18:
+- if ((pVBInfo->VBType & VB_XGI301LV)
+- || (pVBInfo->VBType & VB_XGI302LV))
+- return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
+- else
+- return &XGI_CetLCDDes1280x1024x75Data[tempal];
+- break;
+- case 19:
+- return &XGI_NoScalingDesDatax75[tempal];
+- break;
+- case 20:
+- return &XGI_NoScalingDesData_1[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 6) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_CH7017LV1024x768[tempal];
+- break;
+- case 1:
+- return &XGI_CH7017LV1400x1050[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- return 0;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetTVPtr */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-const void *
+-XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT i, tempdx, tempbx, tempal, modeflag, table;
+- const XGI330_TVDataTablStruct *tempdi = NULL;
+-
+- tempbx = BX;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+- }
+-
+- tempal = tempal & 0x3f;
+- table = tempbx;
+-
+- switch (tempbx) {
+- case 0:
+- tempdi = 0; /*EPLCHTVCRT1Ptr_H; */
+- break;
+- case 1:
+- tempdi = 0; /*EPLCHTVCRT1Ptr_V; */
+- break;
+- case 2:
+- tempdi = XGI_EPLCHTVDataPtr;
+- break;
+- case 3:
+- tempdi = 0;
+- break;
+- case 4:
+- tempdi = XGI_TVDataTable;
+- break;
+- case 5:
+- tempdi = 0;
+- break;
+- case 6:
+- tempdi = XGI_EPLCHTVRegPtr;
+- break;
+- default:
+- break;
+- }
+-
+- if (tempdi == 0x00) /* OEMUtil */
+- return (0);
+-
+- tempdx = pVBInfo->TVInfo;
+-
+- if (pVBInfo->VBInfo & SetInSlaveMode)
+- tempdx = tempdx | SetTVLockMode;
+-
+- if (modeflag & HalfDCLK)
+- tempdx = tempdx | SetTVLowResolution;
+-
+- i = 0;
+-
+- while (tempdi[i].MASK != 0xffff) {
+- if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
+- break;
+- i++;
+- }
+-
+- if (table == 0x04) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_ExtPALData[tempal];
+- break;
+- case 1:
+- return &XGI_ExtNTSCData[tempal];
+- break;
+- case 2:
+- return &XGI_StPALData[tempal];
+- break;
+- case 3:
+- return &XGI_StNTSCData[tempal];
+- break;
+- case 4:
+- return &XGI_ExtHiTVData[tempal];
+- break;
+- case 5:
+- return &XGI_St2HiTVData[tempal];
+- break;
+- case 6:
+- return &XGI_ExtYPbPr525iData[tempal];
+- break;
+- case 7:
+- return &XGI_ExtYPbPr525pData[tempal];
+- break;
+- case 8:
+- return &XGI_ExtYPbPr750pData[tempal];
+- break;
+- case 9:
+- return &XGI_StYPbPr525iData[tempal];
+- break;
+- case 10:
+- return &XGI_StYPbPr525pData[tempal];
+- break;
+- case 11:
+- return &XGI_StYPbPr750pData[tempal];
+- break;
+- case 12: /* avoid system hang */
+- return &XGI_ExtNTSCData[tempal];
+- break;
+- case 13:
+- return &XGI_St1HiTVData[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 0x02) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_CHTVUNTSCData[tempal];
+- break;
+- case 1:
+- return &XGI_CHTVONTSCData[tempal];
+- break;
+- case 2:
+- return &XGI_CHTVUPALData[tempal];
+- break;
+- case 3:
+- return &XGI_CHTVOPALData[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- else if (table == 0x06) {
+- switch (tempdi[i].DATAPTR) {
+- case 0:
+- return &XGI_CHTVRegUNTSC[tempal];
+- break;
+- case 1:
+- return &XGI_CHTVRegONTSC[tempal];
+- break;
+- case 2:
+- return &XGI_CHTVRegUPAL[tempal];
+- break;
+- case 3:
+- return &XGI_CHTVRegOPAL[tempal];
+- break;
+- default:
+- break;
+- }
+- }
+- return (0);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_BacklightByDrv */
+-/* Input : */
+-/* Output : TRUE -> Skip backlight control */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR tempah;
+-
+- tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3A);
+- if (tempah & BacklightControlBit)
+- return TRUE;
+- else
+- return FALSE;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_FirePWDDisable */
+-/* Input : */
+-/* Output : */
+-/* Description : Turn off VDD & Backlight : Fire disable procedure */
+-/* --------------------------------------------------------------------- */
+-/*
+-void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
+-{
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
+-}
+-*/
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_FirePWDEnable */
+-/* Input : */
+-/* Output : */
+-/* Description : Turn on VDD & Backlight : Fire enable procedure */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x26, 0x03, 0xFC);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_EnableGatingCRT */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x40);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_DisableGatingCRT */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x00);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetPanelDelay */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
+-/* : bl : 2 ; T2 : the duration signal on and Vdd on */
+-/* : bl : 3 ; T3 : the duration between CPL off and signal off */
+-/* : bl : 4 ; T4 : the duration signal off and Vdd off */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT index;
+-#ifndef LINUX_XF86
+- USHORT temp;
+-#endif
+-
+- index = XGI_GetLCDCapPtr(pVBInfo);
+-
+- if (tempbl == 1)
+- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S1, pVBInfo);
+-
+- if (tempbl == 2)
+- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S2, pVBInfo);
+-
+- if (tempbl == 3)
+- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S3, pVBInfo);
+-
+- if (tempbl == 4)
+- XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S4, pVBInfo);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetPanelPower */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* I/O : ah = 0011b = 03h ; Backlight on, Power on */
+-/* = 0111b = 07h ; Backlight on, Power off */
+-/* = 1011b = 0Bh ; Backlight off, Power on */
+-/* = 1111b = 0Fh ; Backlight off, Power off */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
+-{
+- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x26, tempbl,
+- tempah);
+- else
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x11, tempbl, tempah);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_IsLCDON */
+-/* Input : */
+-/* Output : FALSE : Skip PSC Control */
+-/* TRUE: Disable PSC */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax;
+-
+- tempax = pVBInfo->VBInfo;
+- if (tempax & SetCRT2ToDualEdge)
+- return FALSE;
+- else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
+- return TRUE;
+-
+- return FALSE;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_EnablePWD */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT index, temp;
+-
+- index = XGI_GetLCDCapPtr(pVBInfo);
+- temp = pVBInfo->LCDCapList[index].PWD_2B;
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2B, temp);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2C,
+- pVBInfo->LCDCapList[index].PWD_2C);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2D,
+- pVBInfo->LCDCapList[index].PWD_2D);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2E,
+- pVBInfo->LCDCapList[index].PWD_2E);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2F,
+- pVBInfo->LCDCapList[index].PWD_2F);
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_DisablePWD */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_DisableChISLCD */
+-/* Input : */
+-/* Output : FALSE -> Not LCD Mode */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, tempah;
+-
+- tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
+- tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
+-
+- if (tempbx & (EnableChA | DisableChA)) {
+- if (!(tempah & 0x08)) /* Chk LCDA Mode */
+- return FALSE;
+- }
+-
+- if (!(tempbx & (EnableChB | DisableChB)))
+- return FALSE;
+-
+- if (tempah & 0x01) /* Chk LCDB Mode */
+- return TRUE;
+-
+- return FALSE;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_EnableChISLCD */
+-/* Input : */
+-/* Output : 0 -> Not LCD mode */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, tempah;
+-
+-
+- tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
+- tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
+-
+- if (tempbx & (EnableChA | DisableChA)) {
+- if (!(tempah & 0x08)) /* Chk LCDA Mode */
+- return FALSE;
+- }
+-
+- if (!(tempbx & (EnableChB | DisableChB)))
+- return FALSE;
+-
+- if (tempah & 0x01) /* Chk LCDB Mode */
+- return TRUE;
+-
+- return FALSE;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetLCDCapPtr */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo)
+-{
+- UCHAR tempal, tempah, tempbl, i;
+-
+- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36);
+- tempal = tempah & 0x0F;
+- tempah = tempah & 0xF0;
+- i = 0;
+- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+-
+- while (tempbl != 0xFF) {
+- if (tempbl & 0x80) { /* OEMUtil */
+- tempal = tempah;
+- tempbl = tempbl & ~(0x80);
+- }
+-
+- if (tempal == tempbl)
+- break;
+-
+- i++;
+-
+- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+- }
+-
+- return i;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetLCDCapPtr1 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempah, tempal, tempbl, i;
+-
+- tempal = pVBInfo->LCDResInfo;
+- tempah = pVBInfo->LCDTypeInfo;
+-
+- i = 0;
+- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+-
+- while (tempbl != 0xFF) {
+- if ((tempbl & 0x80) && (tempbl != 0x80)) {
+- tempal = tempah;
+- tempbl &= ~0x80;
+- }
+-
+- if (tempal == tempbl)
+- break;
+-
+- i++;
+- tempbl = pVBInfo->LCDCapList[i].LCD_ID;
+- }
+-
+- if (tempbl == 0xFF) {
+- pVBInfo->LCDResInfo = Panel1024x768;
+- pVBInfo->LCDTypeInfo = 0;
+- i = 0;
+- }
+-
+- return i;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetLCDSync */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT Index;
+-
+- Index = XGI_GetLCDCapPtr(pVBInfo);
+- *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
+- *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
+-
+- return;
+-}
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_EnableBridge */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifndef LINUX_XF86
+- USHORT tempax;
+-#endif
+- USHORT tempbl, tempah;
+-
+- if (pVBInfo->SetFlag == Win9xDOSMode) {
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- XGI_DisplayOn(pVBInfo);
+- return;
+- }
+- else /* LVDS or CH7017 */
+- return;
+- }
+-
+-
+- if (HwDeviceExtension->jChipType < XG40) {
+- if (!XGI_DisableChISLCD(pVBInfo)) {
+- if ((XGI_EnableChISLCD(pVBInfo))
+- || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
+- if (pVBInfo->LCDInfo & SetPWDEnable) {
+- XGI_EnablePWD(pVBInfo);
+- }
+- else {
+- pVBInfo->LCDInfo &= (~SetPWDEnable);
+- if (pVBInfo->
+- VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+- tempbl = 0xFD;
+- tempah = 0x02;
+- }
+- else {
+- tempbl = 0xFB;
+- tempah = 0x00;
+- }
+-
+- XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+- XGI_SetPanelDelay(1, pVBInfo);
+- }
+- }
+- }
+- } /* Not 340 */
+-
+-
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (!(pVBInfo->SetFlag & DisableChA)) {
+- if (pVBInfo->SetFlag & EnableChA) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+- }
+- else {
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+- }
+- }
+- }
+-
+- if (!(pVBInfo->SetFlag & DisableChB)) {
+- if ((pVBInfo->SetFlag & EnableChB)
+- || (pVBInfo->
+- VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC)))
+- {
+- tempah =
+- (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
+- tempah &= 0xDF;
+- if (pVBInfo->VBInfo & SetInSlaveMode) {
+- if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
+- tempah |= 0x20;
+- }
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, tempah);
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E,
+- SR1E_ENABLE_CRT2);
+-
+-
+- tempah =
+- (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port,
+- 0x2E);
+-
+- if (!(tempah & 0x80))
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+-
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
+- }
+- }
+-
+- if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
+- || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, ~0xE0, 0x20); /* shampoo 0129 */
+- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+- if (!XGI_DisableChISLCD(pVBInfo)) {
+- if (XGI_EnableChISLCD(pVBInfo)
+- || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x2A, 0x7F); /* LVDS PLL power on */
+- }
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
+- }
+- }
+-
+- tempah = 0x00;
+-
+- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+- tempah = 0xc0;
+-
+- if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+- tempah = tempah & 0x40;
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+- tempah = tempah ^ 0xC0;
+-
+- if (pVBInfo->SetFlag & DisableChB)
+- tempah &= 0xBF;
+-
+- if (pVBInfo->SetFlag & DisableChA)
+- tempah &= 0x7F;
+-
+- if (pVBInfo->SetFlag & EnableChB)
+- tempah |= 0x40;
+-
+- if (pVBInfo->SetFlag & EnableChA)
+- tempah |= 0x80;
+- }
+- }
+- }
+- }
+-
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
+-
+- if (pVBInfo->SetFlag & Win9xDOSMode) {
+- XGI_DisplayOn(pVBInfo);
+- return;
+- }
+-
+- if (!(pVBInfo->SetFlag & DisableChA)) {
+- XGI_VBLongWait(pVBInfo);
+- if (!(pVBInfo->SetFlag & GatingCRT)) {
+- XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
+- XGI_DisplayOn(pVBInfo);
+- XGI_VBLongWait(pVBInfo);
+- }
+- }
+- } /* 301 */
+- else { /* LVDS */
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA))
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
+-
+-
+-
+- tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E);
+- if (!(tempah & 0x80))
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+-
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F);
+- XGI_DisplayOn(pVBInfo);
+- } /* End of VB */
+-
+-
+- if (HwDeviceExtension->jChipType < XG40) {
+- if (!XGI_EnableChISLCD(pVBInfo)) {
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- if (XGI_BacklightByDrv(pVBInfo))
+- return;
+- }
+- else
+- return;
+- }
+-
+- if (pVBInfo->LCDInfo & SetPWDEnable) {
+- XGI_FirePWDEnable(pVBInfo);
+- return;
+- }
+-
+- XGI_SetPanelDelay(2, pVBInfo);
+-
+- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+- tempah = 0x01;
+- tempbl = 0xFE; /* turn on backlght */
+- }
+- else {
+- tempbl = 0xF7;
+- tempah = 0x00;
+- }
+- XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_DisableBridge */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, tempbx, tempah = 0, tempbl = 0;
+-
+- if (pVBInfo->SetFlag == Win9xDOSMode)
+- return;
+-
+-
+- if (HwDeviceExtension->jChipType < XG40) {
+- if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+- || (XGI_DisableChISLCD(pVBInfo))) {
+- if (!XGI_IsLCDON(pVBInfo)) {
+- if (pVBInfo->LCDInfo & SetPWDEnable)
+- XGI_EnablePWD(pVBInfo);
+- else {
+- pVBInfo->LCDInfo &= ~SetPWDEnable;
+- XGI_DisablePWD(pVBInfo);
+- if (pVBInfo->
+- VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+- tempbx = 0xFE; /* not 01h */
+- tempax = 0;
+- }
+- else {
+- tempbx = 0xF7; /* not 08h */
+- tempax = 0x08;
+- }
+- XGI_SetPanelPower(tempax, tempbx, pVBInfo);
+- XGI_SetPanelDelay(3, pVBInfo);
+- }
+- } /* end if(!XGI_IsLCDON(pVBInfo)) */
+- }
+- }
+-
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- tempah = 0x3F;
+- if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+- tempah = 0x7F; /* Disable Channel A */
+- if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+- tempah = 0xBF; /* Disable Channel B */
+-
+- if (pVBInfo->SetFlag & DisableChB)
+- tempah &= 0xBF; /* force to disable Cahnnel */
+-
+- if (pVBInfo->SetFlag & DisableChA)
+- tempah &= 0x7F; /* Force to disable Channel B */
+- }
+- }
+- }
+-
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
+-
+- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+- if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
+- || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo)))
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
+- }
+-
+- if ((pVBInfo->SetFlag & DisableChA)
+- || (pVBInfo->
+- VBInfo & (DisableCRT2Display | SetCRT2ToLCDA |
+- SetSimuScanMode))) {
+- if (pVBInfo->SetFlag & GatingCRT)
+- XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
+- XGI_DisplayOff(pVBInfo);
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- if ((pVBInfo->SetFlag & DisableChA)
+- || (pVBInfo->VBInfo & SetCRT2ToLCDA))
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
+- }
+-
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
+-
+- if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xdf);
+-
+- if ((pVBInfo->SetFlag & DisableChB)
+- || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
+- || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+- && (pVBInfo->
+- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+-
+- if ((pVBInfo->SetFlag & DisableChB)
+- || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
+- || (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+- || (pVBInfo->
+- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
+- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
+- }
+- }
+- else { /* {301} */
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
+- }
+-
+- if (pVBInfo->
+- VBInfo & (DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode))
+- XGI_DisplayOff(pVBInfo);
+- }
+-
+-
+-
+-
+- if (HwDeviceExtension->jChipType < XG40) {
+- if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+- || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) {
+- if (pVBInfo->LCDInfo & SetPWDEnable) {
+- if (pVBInfo->LCDInfo & SetPWDEnable)
+- XGI_BacklightByDrv(pVBInfo);
+- else {
+- XGI_SetPanelDelay(4, pVBInfo);
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- tempbl = 0xFD;
+- tempah = 0x00;
+- }
+- else {
+- tempbl = 0xFB;
+- tempah = 0x04;
+- }
+- }
+- }
+- XGI_SetPanelPower(tempah, tempbl, pVBInfo);
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetTVPtrIndex */
+-/* Input : */
+-/* Output : */
+-/* Description : bx 0 : ExtNTSC */
+-/* 1 : StNTSC */
+-/* 2 : ExtPAL */
+-/* 3 : StPAL */
+-/* 4 : ExtHiTV */
+-/* 5 : StHiTV */
+-/* 6 : Ext525i */
+-/* 7 : St525i */
+-/* 8 : Ext525p */
+-/* 9 : St525p */
+-/* A : Ext750p */
+-/* B : St750p */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx = 0;
+-
+- if (pVBInfo->TVInfo & SetPALTV)
+- tempbx = 2;
+- if (pVBInfo->TVInfo & SetYPbPrMode1080i)
+- tempbx = 4;
+- if (pVBInfo->TVInfo & SetYPbPrMode525i)
+- tempbx = 6;
+- if (pVBInfo->TVInfo & SetYPbPrMode525p)
+- tempbx = 8;
+- if (pVBInfo->TVInfo & SetYPbPrMode750p)
+- tempbx = 10;
+- if (pVBInfo->TVInfo & TVSimuMode)
+- tempbx++;
+-
+- return tempbx;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_OEM310Setting */
+-/* Input : */
+-/* Output : */
+-/* Description : Customized Param. for 301 */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- if (pVBInfo->SetFlag & Win9xDOSMode)
+- return;
+-
+- /* GetPart1IO(); */
+- XGI_SetDelayComp(pVBInfo);
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
+- XGI_SetLCDCap(pVBInfo);
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- /* GetPart2IO() */
+- XGI_SetPhaseIncr(pVBInfo);
+- XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
+- XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
+-
+- if (pVBInfo->VBType & VB_XGI301)
+- XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetDelayComp */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT index;
+-
+- UCHAR tempah, tempbl, tempbh;
+-#ifndef LINUX_XF86
+- UCHAR temp;
+-#endif
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (pVBInfo->
+- VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV |
+- SetCRT2ToRAMDAC)) {
+- tempbl = 0;
+- tempbh = 0;
+-
+- index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
+- tempbl = pVBInfo->XGI_TVDelayList[index];
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
+- | VB_XGI301C))
+- tempbl = pVBInfo->XGI_TVDelayList2[index];
+-
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+- tempbl = tempbl >> 4;
+-/*
+- if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
+- tempbl = CRT2Delay1 ; // Get CRT2 Delay
+-
+- if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
+- tempbl = CRT2Delay2 ;
+-*/
+- if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+- index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
+- tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
+- tempbl = tempbh;
+- }
+-
+- tempbl &= 0x0F;
+- tempbh &= 0xF0;
+- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D);
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)) { /* Channel B */
+- tempah &= 0xF0;
+- tempah |= tempbl;
+- }
+-
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
+- tempah &= 0x0F;
+- tempah |= tempbh;
+- }
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D, tempah);
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLCDCap */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempcx;
+-
+- tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
+- /* Set 301LV Capability */
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x24,
+- (UCHAR) (tempcx & 0x1F));
+- }
+- /* VB Driving */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D,
+- ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
+- (USHORT) ((tempcx &
+- (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >>
+- 8));
+- }
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if (pVBInfo->VBInfo & SetCRT2ToLCD)
+- XGI_SetLCDCap_B(tempcx, pVBInfo);
+- else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+- XGI_SetLCDCap_A(tempcx, pVBInfo);
+-
+- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+- if (tempcx & EnableSpectrum)
+- SetSpectrum(pVBInfo);
+- }
+- }
+- else /* LVDS,CH7017 */
+- XGI_SetLCDCap_A(tempcx, pVBInfo);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLCDCap_A */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT temp;
+-
+- temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
+-
+- if (temp & LCDRGB18Bit) {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F, (USHORT) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
+- }
+- else {
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F,
+- (USHORT) (0x30 | (tempcx & 0x00C0)));
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
+- }
+-
+-/*
+- if ( tempcx & EnableLCD24bpp ) // 24bits
+- {
+- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x30|(tempcx&0x00C0)) );
+- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x00);
+- }
+- else
+- {
+- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x20|(tempcx&0x00C0)) );//Enable Dither
+- XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x80);
+- }
+-*/
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetLCDCap_B */
+-/* Input : cx -> LCD Capability */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
+-{
+- if (tempcx & EnableLCD24bpp) /* 24bits */
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0,
+- (USHORT) (((tempcx & 0x00ff) >> 6) | 0x0c));
+- else
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0, (USHORT) (((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : SetSpectrum */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-SetSpectrum(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT index;
+-
+- index = XGI_GetLCDCapPtr(pVBInfo);
+-
+- XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
+- XGI_WaitEndRetrace(pVBInfo->RelIO);
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
+- XGI_WaitEndRetrace(pVBInfo->RelIO);
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x31,
+- pVBInfo->LCDCapList[index].Spectrum_31);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x32,
+- pVBInfo->LCDCapList[index].Spectrum_32);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x33,
+- pVBInfo->LCDCapList[index].Spectrum_33);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x34,
+- pVBInfo->LCDCapList[index].Spectrum_34);
+- XGI_WaitEndRetrace(pVBInfo->RelIO);
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetAntiFlicker */
+-/* Input : */
+-/* Output : */
+-/* Description : Set TV Customized Param. */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, index;
+-
+- UCHAR tempah;
+-
+- if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
+- return;
+-
+- tempbx = XGI_GetTVPtrIndex(pVBInfo);
+- tempbx &= 0xFE;
+-
+- if (ModeNo <= 0x13) {
+- index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
+- }
+- else {
+- index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
+- }
+-
+- tempbx += index;
+- tempah = TVAntiFlickList[tempbx];
+- tempah = tempah << 4;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetEdgeEnhance */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, index;
+-
+- UCHAR tempah;
+-
+-
+- tempbx = XGI_GetTVPtrIndex(pVBInfo);
+- tempbx &= 0xFE;
+-
+- if (ModeNo <= 0x13) {
+- index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
+- }
+- else {
+- index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
+- }
+-
+- tempbx += index;
+- tempah = TVEdgeList[tempbx];
+- tempah = tempah << 5;
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetPhaseIncr */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx;
+-
+- UCHAR tempcl, tempch;
+-
+- ULONG tempData;
+-
+- XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+- tempData = TVPhaseList[tempbx];
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x31,
+- (USHORT) (tempData & 0x000000FF));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x32,
+- (USHORT) ((tempData & 0x0000FF00) >> 8));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x33,
+- (USHORT) ((tempData & 0x00FF0000) >> 16));
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x34,
+- (USHORT) ((tempData & 0xFF000000) >> 24));
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetYFilter */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempbx, index;
+-
+- UCHAR tempcl, tempch, tempal;
+- const UCHAR *filterPtr;
+-
+- XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
+-
+- switch (tempbx) {
+- case 0x00:
+- case 0x04:
+- filterPtr = NTSCYFilter1;
+- break;
+-
+- case 0x01:
+- filterPtr = PALYFilter1;
+- break;
+-
+- case 0x02:
+- case 0x05:
+- case 0x0D:
+- filterPtr = PALMYFilter1;
+- break;
+-
+- case 0x03:
+- filterPtr = PALNYFilter1;
+- break;
+-
+- case 0x08:
+- case 0x0C:
+- filterPtr = NTSCYFilter2;
+- break;
+-
+- case 0x0A:
+- filterPtr = PALMYFilter2;
+- break;
+-
+- case 0x0B:
+- filterPtr = PALNYFilter2;
+- break;
+-
+- case 0x09:
+- filterPtr = PALYFilter2;
+- break;
+-
+- default:
+- return;
+- }
+-
+- if (ModeNo <= 0x13)
+- tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+- else
+- tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+-
+- if (tempcl == 0)
+- index = tempal * 4;
+- else
+- index = tempal * 7;
+-
+- if ((tempcl == 0) && (tempch == 1)) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35, 0);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36, 0);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37, 0);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
+- filterPtr[index++]);
+- }
+- else {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35,
+- filterPtr[index++]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36,
+- filterPtr[index++]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37,
+- filterPtr[index++]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
+- filterPtr[index++]);
+- }
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x48,
+- filterPtr[index++]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x49,
+- filterPtr[index++]);
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4A,
+- filterPtr[index++]);
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetTVPtrIndex2 */
+-/* Input : */
+-/* Output : bx 0 : NTSC */
+-/* 1 : PAL */
+-/* 2 : PALM */
+-/* 3 : PALN */
+-/* 4 : NTSC1024x768 */
+-/* 5 : PAL-M 1024x768 */
+-/* 6-7: reserved */
+-/* cl 0 : YFilter1 */
+-/* 1 : YFilter2 */
+-/* ch 0 : 301A */
+-/* 1 : 301B/302B/301LV/302LV */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- *tempbx = 0;
+- *tempcl = 0;
+- *tempch = 0;
+-
+- if (pVBInfo->TVInfo & SetPALTV)
+- *tempbx = 1;
+-
+- if (pVBInfo->TVInfo & SetPALMTV)
+- *tempbx = 2;
+-
+- if (pVBInfo->TVInfo & SetPALNTV)
+- *tempbx = 3;
+-
+- if (pVBInfo->TVInfo & NTSC1024x768) {
+- *tempbx = 4;
+- if (pVBInfo->TVInfo & SetPALMTV)
+- *tempbx = 5;
+- }
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- if ((!(pVBInfo->VBInfo & SetInSlaveMode))
+- || (pVBInfo->TVInfo & TVSimuMode)) {
+- *tempbx += 8;
+- *tempcl += 1;
+- }
+- }
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C))
+- *tempch++;
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_SetCRT2ModeRegs */
+-/* Input : */
+-/* Output : */
+-/* Description : Origin code for crt2group */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+-#ifndef LINUX_XF86
+- USHORT i, j;
+-#endif
+- USHORT tempbl;
+- SHORT tempcl;
+-
+- UCHAR tempah;
+-
+- /* XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
+- tempah = 0;
+- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+- tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00);
+- tempah &= ~0x10; /* BTRAMDAC */
+- tempah |= 0x40; /* BTRAM */
+-
+- if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
+- tempah = 0x40; /* BTDRAM */
+- if (ModeNo > 0x13) {
+- tempcl = pVBInfo->ModeType;
+- tempcl -= ModeVGA;
+- if (tempcl >= 0) {
+- tempah = (0x008 >> tempcl); /* BT Color */
+- if (tempah == 0)
+- tempah = 1;
+- tempah |= 0x040;
+- }
+- }
+- if (pVBInfo->VBInfo & SetInSlaveMode)
+- tempah ^= 0x50; /* BTDAC */
+- }
+- }
+-
+-/* 0210 shampoo
+- if ( pVBInfo->VBInfo & DisableCRT2Display )
+- {
+- tempah = 0 ;
+- }
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , tempah ) ;
+- if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
+- {
+- tempcl = pVBInfo->ModeType ;
+- if ( ModeNo > 0x13 )
+- {
+- tempcl -= ModeVGA ;
+- if ( ( tempcl > 0 ) || ( tempcl == 0 ) )
+- {
+- tempah=(0x008>>tempcl) ;
+- if ( tempah == 0 )
+- tempah = 1 ;
+- tempah |= 0x040;
+- }
+- }
+- else
+- {
+- tempah = 0x040 ;
+- }
+-
+- if ( pVBInfo->VBInfo & SetInSlaveMode )
+- {
+- tempah = ( tempah ^ 0x050 ) ;
+- }
+- }
+-*/
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah);
+- tempah = 0x08;
+- tempbl = 0xf0;
+-
+- if (pVBInfo->VBInfo & DisableCRT2Display)
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
+- tempah);
+- else {
+- tempah = 0x00;
+- tempbl = 0xff;
+-
+- if (pVBInfo->
+- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
+- SetCRT2ToLCDA)) {
+- if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
+- && (!(pVBInfo->VBInfo & SetSimuScanMode))) {
+- tempbl &= 0xf7;
+- tempah |= 0x01;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
+- tempbl, tempah);
+- }
+- else {
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
+- tempbl &= 0xf7;
+- tempah |= 0x01;
+- }
+-
+- if (pVBInfo->
+- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
+- tempbl &= 0xf8;
+- tempah = 0x01;
+-
+- if (!(pVBInfo->VBInfo & SetInSlaveMode))
+- tempah |= 0x02;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+- tempah = tempah ^ 0x05;
+- if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
+- tempah = tempah ^ 0x01;
+- }
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+- tempah |= 0x08;
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
+- tempbl, tempah);
+- }
+- else
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
+- tempbl, tempah);
+- }
+- }
+- else
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
+- tempah);
+- }
+-
+- if (pVBInfo->
+- VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
+- SetCRT2ToLCDA)) {
+- tempah &= (~0x08);
+- if ((pVBInfo->ModeType == ModeVGA)
+- && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
+- tempah |= 0x010;
+- }
+- tempah |= 0x080;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- /* if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) */
+- /* { */
+- tempah |= 0x020;
+- if (ModeNo > 0x13) {
+- if (pVBInfo->VBInfo & DriverMode)
+- tempah = tempah ^ 0x20;
+- }
+- /* } */
+- }
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, ~0x0BF,
+- tempah);
+- tempah = 0;
+-
+- if (pVBInfo->LCDInfo & SetLCDDualLink)
+- tempah |= 0x40;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- /* if ( ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) && ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) ) */
+- /* { */
+- if (pVBInfo->TVInfo & RPLLDIV2XO)
+- tempah |= 0x40;
+- /* } */
+- }
+-
+- if ((pVBInfo->LCDResInfo == Panel1280x1024)
+- || (pVBInfo->LCDResInfo == Panel1280x1024x75))
+- tempah |= 0x80;
+-
+- if (pVBInfo->LCDResInfo == Panel1280x960)
+- tempah |= 0x80;
+-
+- XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0C, tempah);
+- }
+-
+- if (pVBInfo->
+- VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
+- VB_XGI301C)) {
+- tempah = 0;
+- tempbl = 0xfb;
+-
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+- tempbl = 0xff;
+- if (pVBInfo->VBInfo & SetCRT2ToLCDA)
+- tempah |= 0x04; /* shampoo 0129 */
+- }
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x13, tempbl,
+- tempah);
+- tempah = 0x00;
+- tempbl = 0xcf;
+- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+- tempah |= 0x30;
+- }
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2c, tempbl,
+- tempah);
+- tempah = 0;
+- tempbl = 0x3f;
+-
+- if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
+- if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
+- tempah |= 0xc0;
+- }
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, tempbl,
+- tempah);
+- }
+-
+- tempah = 0;
+- tempbl = 0x7f;
+- if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
+- tempbl = 0xff;
+- if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
+- tempah |= 0x80;
+- }
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x23, tempbl, tempah);
+-
+- if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
+- if (pVBInfo->LCDInfo & SetLCDDualLink) {
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x20);
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x34, 0x10);
+- }
+- }
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetRAMDAC2DATA */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, CRT1Index;
+-#ifndef LINUX_XF86
+- USHORT temp, ResInfo, DisplayType;
+-#endif
+-
+- pVBInfo->RVBHCMAX = 1;
+- pVBInfo->RVBHCFACT = 1;
+-
+- if (ModeNo <= 0x13) {
+- const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
+- pVBInfo->ModeType,
+- ModeNo, ModeIdIndex);
+-
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
+- tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
+- temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+- CRT1Index &= IndexMask;
+- temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
+- temp2 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+- tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
+- tempbx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
+- tempcx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
+- tempcx &= 0x0100;
+- tempcx = tempcx << 2;
+- tempbx |= tempcx;
+- temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+- }
+-
+- if (temp1 & 0x01)
+- tempbx |= 0x0100;
+-
+- if (temp1 & 0x20)
+- tempbx |= 0x0200;
+- tempax += 5;
+-
+- if (modeflag & Charx8Dot)
+- tempax *= 8;
+- else
+- tempax *= 9;
+-
+- pVBInfo->VGAHT = tempax;
+- pVBInfo->HT = tempax;
+- tempbx++;
+- pVBInfo->VGAVT = tempbx;
+- pVBInfo->VT = tempbx;
+-}
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetColorDepth */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetColorDepth(USHORT ModeNo, USHORT ModeIdIndex,
+- const VB_DEVICE_INFO *pVBInfo)
+-{
+- USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
+- SHORT index;
+- USHORT modeflag;
+-
+- if (ModeNo <= 0x13) {
+- modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
+- }
+- else {
+- modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+- }
+-
+- index = (modeflag & ModeInfoFlag) - ModeEGA;
+-
+- if (index < 0)
+- index = 0;
+-
+- return (ColorDepth[index]);
+-}
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_UnLockCRT2 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+-
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
+-
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_LockCRT2 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_LockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGINew_EnableCRT2 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo)
+-{
+- XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E, SR1E_ENABLE_CRT2);
+-}
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT i, j;
+-
+- ULONG temp, flag;
+-
+- flag = 0;
+-
+- for (i = 0; i < DelayTime; i++) {
+- for (j = 0; j < 66; j++) {
+- temp = XGI_GetRegLong((XGIIOADDRESS) 0x61);
+- temp &= 0x10;
+-
+- if (temp == flag)
+- continue;
+-
+- flag = temp;
+- }
+- }
+-}
+-
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_BridgeIsOn */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-BOOLEAN
+-XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT flag;
+-
+- flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
+- if ((flag == 1) || (flag == 2))
+- return (1); /* 301b */
+- else
+- return (0);
+-}
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_VBLongWait */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-void
+-XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo)
+-{
+- USHORT tempal, temp, i, j;
+-
+- if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
+- temp = 0;
+- for (i = 0; i < 3; i++) {
+- for (j = 0; j < 100; j++) {
+- tempal = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
+- if (temp & 0x01) { /* VBWaitMode2 */
+- if ((tempal & 0x08)) {
+- continue;
+- }
+-
+- if (!(tempal & 0x08)) {
+- break;
+- }
+- }
+- else { /* VBWaitMode1 */
+- if (!(tempal & 0x08)) {
+- continue;
+- }
+-
+- if ((tempal & 0x08)) {
+- break;
+- }
+- }
+- }
+- temp = temp ^ 0x01;
+- }
+- }
+- else {
+- XGI_WaitEndRetrace(pVBInfo->RelIO);
+- }
+- return;
+-}
+-
+-
+-
+-
+-/* --------------------------------------------------------------------- */
+-/* Function : XGI_GetVGAHT2 */
+-/* Input : */
+-/* Output : */
+-/* Description : */
+-/* --------------------------------------------------------------------- */
+-USHORT
+-XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo)
+-{
+- ULONG tempax, tempbx;
+-
+- tempbx =
+- ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) & 0xFFFF;
+- tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
+- tempax = (tempax * pVBInfo->HT) / tempbx;
+-
+- return ((USHORT) tempax);
+-}
+-
+-
+-/**
+- * Get magic index into clock table.
+- *
+- * \bugs
+- * I'm pretty sure the first if-statement is wrong. It will \b always
+- * evaluate to true.
+- */
+-unsigned
+-XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
+- USHORT RefreshRateTableIndex,
+- PVB_DEVICE_INFO pVBInfo)
+-{
+- unsigned VCLKIndex;
+- const unsigned modeflag = (ModeNo <= 0x13)
+- ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
+- : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+-
+-
+- if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b */
+- VCLKIndex = (pVBInfo->LCDResInfo != Panel1024x768)
+- ? (VCLK108_2 + 5) : (VCLK65 + 2);
+- }
+- else { /* for TV */
+- if (pVBInfo->VBInfo & SetCRT2ToTV) {
+- if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
+- VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
+- ? HiTVVCLKDIV2 : HiTVVCLK;
+-
+- VCLKIndex += 25;
+-
+- if (pVBInfo->SetFlag & TVSimuMode) {
+- VCLKIndex = (modeflag & Charx8Dot)
+- ? HiTVSimuVCLK : HiTVTextVCLK;
+-
+- VCLKIndex += 25;
+- }
+-
+- if (pVBInfo->VBType & VB_XGI301LV) {
+- switch (pVBInfo->VBExtInfo) {
+- case VB_YPbPr1080i:
+- /* VCLKIndex already set to correct value? */
+- break;
+- case VB_YPbPr750p:
+- VCLKIndex = YPbPr750pVCLK;
+- break;
+- case VB_YPbPr525p:
+- VCLKIndex = YPbPr525pVCLK;
+- break;
+- case VB_YPbPr525i:
+- VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
+- ? YPbPr525iVCLK_2 : YPbPr525iVCLK;
+- break;
+- }
+- }
+- }
+- else {
+- VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
+- ? TVVCLKDIV2 : TVVCLK;
+-
+- VCLKIndex += 25;
+- }
+- }
+- else { /* for CRT2 */
+- VCLKIndex = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
+- VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+- if (ModeNo > 0x13) {
+- VCLKIndex =
+- (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK
+- & IndexMask);
+- }
+- }
+- }
+-
+- return VCLKIndex;
+-}
++/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
++ *
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation on the rights to use, copy, modify, merge,
++ * publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so,
++ * subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
++ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "osdef.h"
++
++#ifdef LINUX_XF86
++#include "xf86.h"
++#include "xf86PciInfo.h"
++#include "xgi.h"
++#include "xgi_regs.h"
++#endif
++
++#ifdef LINUX_KERNEL
++#include <asm/io.h>
++#include <linux/types.h>
++#include <linux/version.h>
++#include "XGIfb.h"
++#endif
++
++#include "vb_def.h"
++#include "vgatypes.h"
++#include "vb_struct.h"
++#include "vb_table.h"
++#include "vb_setmode.h"
++
++#define IndexMask 0xff
++#ifndef XGI_MASK_DUAL_CHIP
++#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */
++#endif
++
++
++BOOLEAN CheckDualChip(PVB_DEVICE_INFO pVBInfo);
++static BOOLEAN XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo);
++
++BOOLEAN XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, USHORT * i,
++ PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetRatePtrCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo);
++static unsigned XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo);
++void XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo);
++void XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++static const void *XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++static const void *XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo);
++void XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++void XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo);
++void XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo);
++void XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo);
++void SetDualChipRegs(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
++void XGI_DisplayOn(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo);
++void XGI_DisplayOff(PXGI_HW_DEVICE_INFO HwDeviceExtension,PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
++/* Jong 10/03/2007 */
++void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
++void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo);
++void XGI_UpdateXG21CRTC(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo, USHORT RefreshRateTableIndex);
++
++static void XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo);
++void XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo);
++
++void XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension);
++void XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension);
++void XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++
++void XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_GetVBType(PVB_DEVICE_INFO pVBInfo);
++void XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void InitTo330Pointer(UCHAR, PVB_DEVICE_INFO pVBInfo);
++void XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo);
++void XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
++void SetSpectrum(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
++ PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PVB_DEVICE_INFO pVBInfo);
++void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
++void XGI_LockCRT2(PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO pVBInfo);
++void XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo);
++void XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo);
++void XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo);
++static void XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo);
++static unsigned XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
++ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
++static void XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di,
++ PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo);
++USHORT XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo);
++static const XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo);
++
++/* Jong 10/03/2007 */
++void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
++void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
++UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo);
++UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo);
++void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
++void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
++void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
++UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo );
++
++const uint8_t XGI_MDA_DAC[] = {
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
++ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
++ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
++ 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
++ 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F
++};
++
++const uint8_t XGI_CGA_DAC[] = {
++ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
++ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
++ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
++ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
++ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
++ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
++ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
++ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
++};
++
++const uint8_t XGI_EGA_DAC[] = {
++ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15,
++ 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35,
++ 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D,
++ 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D,
++ 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17,
++ 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37,
++ 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F,
++ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F
++};
++
++const uint8_t XGI_VGA_DAC[] = {
++ 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
++ 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
++ 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
++ 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
++ 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F,
++ 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00,
++ 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18,
++ 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04,
++ 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10,
++ 0x0B, 0x0C, 0x0D, 0x0F, 0x10
++};
++
++
++/* --------------------------------------------------------------------- */
++/* Function : InitTo330Pointer */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++InitTo330Pointer(UCHAR ChipType, PVB_DEVICE_INFO pVBInfo)
++{
++ pVBInfo->SModeIDTable = XGI330_SModeIDTable;
++ pVBInfo->StandTable = XGI330_StandTable;
++ pVBInfo->EModeIDTable = XGI330_EModeIDTable;
++ pVBInfo->RefIndex = XGI330_RefIndex;
++ pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table;
++
++ /* add for new UNIVGABIOS */
++ /* XGINew_UBLCDDataTable = (XGI_LCDDataTablStruct *) XGI_LCDDataTable ; */
++ /* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable ; */
++
++
++ if (ChipType >= XG40) {
++ (void) memcpy(pVBInfo->MCLKData, XGI340New_MCLKData, sizeof(XGI340New_MCLKData));
++ (void) memcpy(pVBInfo->ECLKData, XGI340_ECLKData, sizeof(XGI340_ECLKData));
++ }
++ else {
++ (void) memcpy(pVBInfo->MCLKData, XGI330New_MCLKData, sizeof(XGI330New_MCLKData));
++ (void) memcpy(pVBInfo->ECLKData, XGI330_ECLKData, sizeof(XGI330_ECLKData));
++ }
++
++ pVBInfo->VCLKData = XGI_VCLKData;
++ pVBInfo->VBVCLKData = XGI_VBVCLKData;
++ pVBInfo->ScreenOffset = XGI330_ScreenOffset;
++ pVBInfo->StResInfo = XGI330_StResInfo;
++ pVBInfo->ModeResInfo = XGI330_ModeResInfo;
++
++ pVBInfo->OutputSelect = XGI330_OutputSelect;
++ pVBInfo->SoftSetting = XGI330_SoftSetting;
++ pVBInfo->SR07 = XGI330_SR07;
++ pVBInfo->LCDResInfo = 0;
++ pVBInfo->LCDTypeInfo = 0;
++ pVBInfo->LCDInfo = 0;
++ pVBInfo->VBInfo = 0;
++ pVBInfo->TVInfo = 0;
++
++
++ (void) memcpy(pVBInfo->SR15, XGI340_SR13, sizeof(XGI340_SR13));
++ (void) memcpy(pVBInfo->CR40, XGI340_CR41, sizeof(XGI340_CR41));
++ (void) memcpy(pVBInfo->SR25, XGI330_SR25, sizeof(XGI330_SR25));
++ pVBInfo->SR31 = XGI330_SR31;
++ pVBInfo->SR32 = XGI330_SR32;
++ (void) memcpy(pVBInfo->CR6B, XGI340_CR6B, sizeof(XGI340_CR6B));
++ if (ChipType == XG45) {
++ (void) memcpy(pVBInfo->XG45CR6E, XGI45_CR6E, sizeof(XGI45_CR6E));
++ (void) memcpy(pVBInfo->XG45CR6F, XGI45_CR6F, sizeof(XGI45_CR6F));
++ }
++ else {
++ (void) memcpy(pVBInfo->CR6E, XGI340_CR6E, sizeof(XGI340_CR6E));
++ (void) memcpy(pVBInfo->CR6F, XGI340_CR6F, sizeof(XGI340_CR6F));
++ }
++ (void) memcpy(pVBInfo->CR89, XGI340_CR89, sizeof(XGI340_CR89));
++ (void) memcpy(pVBInfo->AGPReg, XGI340_AGPReg, sizeof(XGI340_AGPReg));
++ (void) memcpy(pVBInfo->SR16, XGI340_SR16, sizeof(XGI340_SR16));
++ pVBInfo->CRCF = XG40_CRCF;
++ pVBInfo->DRAMTypeDefinition = XG40_DRAMTypeDefinition;
++
++
++ (void) memcpy(pVBInfo->CR49, XGI330_CR49, sizeof(XGI330_CR49));
++ pVBInfo->SR1F = XGI330_SR1F;
++ pVBInfo->SR21 = XGI330_SR21;
++ pVBInfo->SR22 = XGI330_SR22;
++ pVBInfo->SR23 = XGI330_SR23;
++ pVBInfo->SR24 = XGI330_SR24;
++ pVBInfo->SR33 = XGI330_SR33;
++
++
++
++ pVBInfo->CRT2Data_1_2 = XGI330_CRT2Data_1_2;
++ pVBInfo->CRT2Data_4_D = XGI330_CRT2Data_4_D;
++ pVBInfo->CRT2Data_4_E = XGI330_CRT2Data_4_E;
++ pVBInfo->CRT2Data_4_10 = XGI330_CRT2Data_4_10;
++ pVBInfo->pRGBSenseData = &XGI330_RGBSenseData;
++ pVBInfo->pVideoSenseData = &XGI330_VideoSenseData;
++ pVBInfo->pYCSenseData = &XGI330_YCSenseData;
++ pVBInfo->pRGBSenseData2 = &XGI330_RGBSenseData2;
++ pVBInfo->pVideoSenseData2 = &XGI330_VideoSenseData2;
++ pVBInfo->pYCSenseData2 = &XGI330_YCSenseData2;
++
++ pVBInfo->NTSCTiming = XGI330_NTSCTiming;
++ pVBInfo->PALTiming = XGI330_PALTiming;
++ pVBInfo->HiTVExtTiming = XGI330_HiTVExtTiming;
++ pVBInfo->HiTVSt1Timing = XGI330_HiTVSt1Timing;
++ pVBInfo->HiTVSt2Timing = XGI330_HiTVSt2Timing;
++ pVBInfo->HiTVTextTiming = XGI330_HiTVTextTiming;
++ pVBInfo->YPbPr750pTiming = XGI330_YPbPr750pTiming;
++ pVBInfo->YPbPr525pTiming = XGI330_YPbPr525pTiming;
++ pVBInfo->YPbPr525iTiming = XGI330_YPbPr525iTiming;
++ pVBInfo->HiTVGroup3Data = XGI330_HiTVGroup3Data;
++ pVBInfo->HiTVGroup3Simu = XGI330_HiTVGroup3Simu;
++ pVBInfo->HiTVGroup3Text = XGI330_HiTVGroup3Text;
++ pVBInfo->Ren525pGroup3 = XGI330_Ren525pGroup3;
++ pVBInfo->Ren750pGroup3 = XGI330_Ren750pGroup3;
++
++
++ (void) memcpy(& pVBInfo->TimingH, XGI_TimingH, sizeof(XGI_TimingH));
++ (void) memcpy(& pVBInfo->TimingV, XGI_TimingV, sizeof(XGI_TimingV));
++
++ /* Jong 10/17/2007; merge code */
++ pVBInfo->UpdateCRT1 = (XGI_XG21CRT1Struct *) XGI_UpdateCRT1Table ;
++
++ pVBInfo->CHTVVCLKUNTSC = XGI330_CHTVVCLKUNTSC;
++ pVBInfo->CHTVVCLKONTSC = XGI330_CHTVVCLKONTSC;
++ pVBInfo->CHTVVCLKUPAL = XGI330_CHTVVCLKUPAL;
++ pVBInfo->CHTVVCLKOPAL = XGI330_CHTVVCLKOPAL;
++
++ /* 310 customization related */
++ if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV))
++ pVBInfo->LCDCapList = XGI_LCDDLCapList;
++ else
++ pVBInfo->LCDCapList = XGI_LCDCapList;
++
++ /* Jong 10/03/2007 */
++ if ( ( ChipType == XG21 ) || ( ChipType == XG27 ) )
++ pVBInfo->XG21_LVDSCapList = XGI21_LCDCapList ;
++
++ pVBInfo->XGI_TVDelayList = XGI301TVDelayList;
++ pVBInfo->XGI_TVDelayList2 = XGI301TVDelayList2;
++
++
++ pVBInfo->I2CDefinition = XG40_I2CDefinition;
++
++ /* Jong 10/03/2007 */
++ if (ChipType >= XG20)
++ pVBInfo->CR97 = XG20_CR97;
++
++
++ /* Jong 10/03/2007 */
++ if ( ChipType == XG27 )
++ {
++ /* pVBInfo->MCLKData = (XGI_MCLKDataStruct *) XGI27New_MCLKData ; */
++ (void) memcpy(pVBInfo->MCLKData, XGI27New_MCLKData, sizeof(XGI27New_MCLKData));
++
++ /* pVBInfo->CR40 = XGI27_cr41 ; */
++ (void) memcpy(pVBInfo->CR40, XGI27_cr41, sizeof(XGI27_cr41));
++
++ pVBInfo->CR97 = XG27_CR97 ;
++ pVBInfo->pSR36 = &XG27_SR36 ;
++ pVBInfo->pCR8F = &XG27_CR8F ;
++ pVBInfo->pCRD0 = XG27_CRD0 ;
++ pVBInfo->pCRDE = XG27_CRDE ;
++ pVBInfo->pSR40 = &XG27_SR40 ;
++ pVBInfo->pSR41 = &XG27_SR41 ;
++ }
++
++ if ( ChipType >= XG20 )
++ {
++ pVBInfo->pDVOSetting = &XG21_DVOSetting ;
++ pVBInfo->pCR2E = &XG21_CR2E ;
++ pVBInfo->pCR2F = &XG21_CR2F ;
++ pVBInfo->pCR46 = &XG21_CR46 ;
++ pVBInfo->pCR47 = &XG21_CR47 ;
++ }
++
++}
++
++
++
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGISetModeNew */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo,
++ USHORT ModeNo)
++{
++#ifndef LINUX_XF86
++ ULONG temp;
++ USHORT KeepLockReg;
++#endif
++ USHORT ModeIdIndex;
++ /* PUCHAR pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress ; */
++ USHORT temp_mode_no;
++
++ pVBInfo->IF_DEF_LVDS = 0 ;
++ pVBInfo->IF_DEF_VideoCapture = 1;
++ pVBInfo->IF_DEF_ScaleLCD = 1;
++
++ unsigned vga_info; /* Jong 11/28/2007 */
++
++ /* Jong 10/03/2007 */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ if ( ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) & 0xE0 ) == 0xC0 )
++ {
++ if ( XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x30 ) & 0x20 )
++ {
++ pVBInfo->IF_DEF_LVDS = 1 ;
++ }
++ }
++ }
++
++ /* Jong 10/03/20007 */
++ if ( HwDeviceExtension->jChipType < XG20 ) /* kuku 2004/06/25 */
++ XGI_GetVBType( pVBInfo ) ;
++
++ /* Jong 10/17/2007; merge code */
++ InitTo330Pointer( HwDeviceExtension->jChipType, pVBInfo ) ;
++
++ if (ModeNo & 0x80) {
++ ModeNo = ModeNo & 0x7F;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
++
++ /* Jong 10/03/2007 */
++ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 1.Openkey */
++ XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
++
++ /* Jong 10/03/2007 */
++ HwDeviceExtension->SpecialMode = FALSE;
++
++/* Jong 11/27/2007 */
++#if 0 /* can't get pScrn */
++#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
++ vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
++#else
++ vga_info = 0x11; /* set default mode 3 */
++#endif
++#endif
++
++ /* Jong 11/28/2007; pVBInfo field is not matching VGAINFO argument */
++ /* if ( !XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, pVBInfo , &ModeNo , &ModeIdIndex) ) */
++ if ( !XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11, &ModeNo , &ModeIdIndex) )
++ {
++ switch (HwDeviceExtension->BPP)
++ {
++ case 8: ModeNo = 0x2E;
++ HwDeviceExtension->SpecialMode = TRUE;
++ break;
++ case 15: ModeNo = 0x43;
++ HwDeviceExtension->SpecialMode = TRUE;
++ break;
++ case 16: ModeNo = 0x44;
++ HwDeviceExtension->SpecialMode = TRUE;
++ break;
++ case 32: ModeNo = 0x62;
++ HwDeviceExtension->SpecialMode = TRUE;
++ break;
++ default:
++ return FALSE;
++ break;
++ }
++
++ /* Jong 10/03/2007 */
++ if (HwDeviceExtension->SpecialMode)
++ {
++
++ /* Jong 11/28/2007; pVBInfo field is not matching VGAINFO argument */
++ /* XGI_SearchModeID( pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, pVBInfo, &ModeNo , &ModeIdIndex ) ; */
++ XGI_SearchModeID( pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11, &ModeNo , &ModeIdIndex ) ;
++ if ( !(HwDeviceExtension->SpecifyTiming) )
++ {
++ int i = 0;
++ while ( SpecialModeTiming[i].Horizontal_ACTIVE != 0 )
++ {
++ if ( ( SpecialModeTiming[i].Horizontal_ACTIVE==HwDeviceExtension->Horizontal_ACTIVE ) &&
++ ( (SpecialModeTiming[i].Vertical_ACTIVE<<(SpecialModeTiming[i].Interlace&0x1))==HwDeviceExtension->Vertical_ACTIVE ) )
++ {
++ if ( ( ( SpecialModeTiming[i].FrameRate-HwDeviceExtension->Frequency ) < 2.0 ) ||
++ ( ( SpecialModeTiming[i].FrameRate-HwDeviceExtension->Frequency ) > -2.0 ) )
++ {
++ HwDeviceExtension->Horizontal_FP = SpecialModeTiming[i].Horizontal_FP;
++ HwDeviceExtension->Horizontal_SYNC = SpecialModeTiming[i].Horizontal_SYNC;
++ HwDeviceExtension->Horizontal_BP = SpecialModeTiming[i].Horizontal_BP;
++ HwDeviceExtension->Vertical_FP = SpecialModeTiming[i].Vertical_FP;
++ HwDeviceExtension->Vertical_SYNC = SpecialModeTiming[i].Vertical_SYNC;
++ HwDeviceExtension->Vertical_BP = SpecialModeTiming[i].Vertical_BP;
++ HwDeviceExtension->DCLK = SpecialModeTiming[i].DCLK;
++ HwDeviceExtension->Interlace = SpecialModeTiming[i].Interlace & 0x1;
++ break;
++ }
++ }
++ i++;
++ }
++ if ( SpecialModeTiming[i].Horizontal_ACTIVE == 0 )
++ {
++ return FALSE; /* currently not support */
++ }
++ }
++ }
++ }
++
++ if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
++ PDEBUG(ErrorF("XGI_GetVBInfo \n"));
++ XGI_GetVBInfo(ModeNo, ModeIdIndex, HwDeviceExtension, pVBInfo);
++ PDEBUG(ErrorF("XGI_GetTVInfo \n"));
++ XGI_GetTVInfo(ModeNo, ModeIdIndex, pVBInfo);
++ PDEBUG(ErrorF("XGI_GetLCDInfo \n"));
++ XGI_GetLCDInfo(ModeNo, ModeIdIndex, pVBInfo);
++ PDEBUG(ErrorF("XGI_DisableBridge \n"));
++
++ /* Jong 10/17/2007; merge code */
++ if ( pVBInfo->VBInfo & ( SetSimuScanMode | SwitchToCRT2 ) )
++ {
++ if (HwDeviceExtension->SpecialMode)
++ {
++ return FALSE;
++ }
++ }
++
++ XGI_DisableBridge(HwDeviceExtension, pVBInfo);
++
++
++ if (pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
++ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
++ pVBInfo);
++ }
++ }
++ else {
++ if (!(pVBInfo->VBInfo & SwitchToCRT2)) {
++ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex,
++ pVBInfo);
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ XGI_SetLCDAGroup(ModeNo, ModeIdIndex, HwDeviceExtension,
++ pVBInfo);
++ }
++ }
++ }
++
++ PDEBUG(ErrorF(" vb_setmode 474\n")); // yilin
++ if (pVBInfo->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
++ switch (HwDeviceExtension->ujVBChipID) {
++ case VB_CHIP_301:
++ PDEBUG(ErrorF(" vb_setmode 301\n")); //yilin
++ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
++ break;
++
++ case VB_CHIP_302:
++ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, pVBInfo); /*add for CRT2 */
++ break;
++
++ default:
++ break;
++ }
++ }
++ ErrorF("492 Part2 0 = %x ",
++ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
++ XGI_SetCRT2ModeRegs(ModeNo, HwDeviceExtension, pVBInfo);
++ XGI_OEM310Setting(ModeNo, ModeIdIndex, pVBInfo); /*0212 */
++ XGI_EnableBridge(HwDeviceExtension, pVBInfo);
++ ErrorF("497 Part2 0 = %x ",
++ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
++ } /* !XG20 */
++ else
++ {
++ /* Jong 10/04/2007 */
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ if ( !XGI_XG21CheckLVDSMode(ModeNo , ModeIdIndex, pVBInfo) )
++ {
++ return FALSE;
++ }
++ }
++
++ if (ModeNo <= 0x13) {
++ pVBInfo->ModeType =
++ pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag & ModeInfoFlag;
++ }
++ else {
++ pVBInfo->ModeType =
++ pVBInfo->EModeIDTable[ModeIdIndex].
++ Ext_ModeFlag & ModeInfoFlag;
++ }
++
++ pVBInfo->SetFlag = 0;
++ if ( pVBInfo->IF_DEF_CH7007 != 1 )
++ {
++ pVBInfo->VBInfo = DisableCRT2Display;
++ }
++
++ XGI_DisplayOff(HwDeviceExtension,pVBInfo);
++ XGI_SetCRT1Group(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
++ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
++ }
++
++/*
++ if ( ModeNo <= 0x13 )
++ {
++ modeflag = pVBInfo->SModeIDTable[ ModeIdIndex ].St_ModeFlag ;
++ }
++ else
++ {
++ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex ].Ext_ModeFlag ;
++ }
++ pVBInfo->ModeType = modeflag&ModeInfoFlag ;
++ pVBInfo->SetFlag = 0x00 ;
++ pVBInfo->VBInfo = DisableCRT2Display ;
++ temp = XGINew_CheckMemorySize( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
++
++ if ( temp == 0 )
++ return( 0 ) ;
++
++ XGI_DisplayOff( HwDeviceExtension,pVBInfo) ;
++ XGI_SetCRT1Group( HwDeviceExtension , ModeNo , ModeIdIndex, pVBInfo ) ;
++ XGI_DisplayOn( HwDeviceExtension, pVBInfo) ;
++*/
++ ErrorF("Part2 0 = %x ",
++ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
++ XGI_UpdateModeInfo(HwDeviceExtension, pVBInfo);
++
++ /* Jong 10/04/2007 */
++ if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
++ XGI_LockCRT2(HwDeviceExtension, pVBInfo);
++
++ return (TRUE);
++}
++
++/* Jong 10/17/2007; merge code */
++void XGI_SetCRTVCLK(PVB_DEVICE_INFO pVBInfo, double dwPixelClock)
++{
++struct factor
++{
++ int sr2b7;
++ int sr2c7;
++ int sr2c6;
++ int sr2c5;
++ int dividend ;
++ int divisor ;
++};
++
++struct factor kind[16]=
++{
++ {0,0,0,0,1,1},
++ {0,0,0,1,1,2},
++ {0,0,1,0,1,3},
++ {0,0,1,1,1,4},
++ {1,0,0,0,2,1},
++ {1,0,0,1,2,2},
++ {1,0,1,0,2,3},
++ {1,0,1,1,2,4},
++ {0,1,0,0,1,1},
++ {0,1,0,1,1,4},
++ {0,1,1,0,1,6},
++ {0,1,1,1,1,8},
++ {1,1,0,0,2,1},
++ {1,1,0,1,2,4},
++ {1,1,1,0,2,6},
++ {1,1,1,1,2,8}
++};
++ int ii,jj,kk,ll,sr2b,sr2c,Numerator,DeNumerator;
++ double factor1,tempclock,vclk,temp1,min,clock;
++
++
++ vclk=(double)dwPixelClock;
++ min=99.0;
++ for(ii=2;ii<=31;ii++) /* (DeNumerator1)It's value must >=2 */
++ {
++ for(jj=0;jj<=127;jj++) /* (Numerator1) */
++ {
++
++ for(kk=0;kk<=15;kk++)
++ {
++ tempclock=14.318*kind[kk].dividend*(jj+1)/(ii+1);
++ if ( (tempclock >= 150 ) && ( tempclock <= 380) )
++ {
++ tempclock = tempclock / kind[kk].divisor ;
++ temp1=fabs(vclk-tempclock);
++ if(temp1<min)
++ {
++ clock=tempclock;
++ DeNumerator=ii;
++ Numerator=jj;
++ min=temp1;
++ factor1=(double) (kind[kk].dividend / kind[kk].divisor);
++ ll=kk;
++ }
++ }
++ }
++ }
++ }
++ sr2b=128*kind[ll].sr2b7+Numerator;
++ sr2c=128*kind[ll].sr2c7+64*kind[ll].sr2c6+32*kind[ll].sr2c5+DeNumerator;
++
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , (unsigned char) sr2b) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , (unsigned char) sr2c) ;
++}
++
++/* Jong 10/17/2007; merge code */
++void XGI_SetCRTTiming(
++ PXGI_HW_DEVICE_INFO pXGIHWDE,
++ PVB_DEVICE_INFO pVBInfo
++ )
++{
++ int HT, VT, HDE, VDE, HRS, VRS, HRE, VRE, VGAHDE, VGAVDE, VGAHT, VGAVT;
++ int HorizontalActivePixel, HorizontalFrontPorch, HorizontalSyncWidth, HorizontalBackPorch;
++ int VerticalActivePixel, VerticalFrontPorch, VerticalSyncWidth, VerticalBackPorch;
++ int temp1;
++ UCHAR temp;
++
++ HorizontalActivePixel = pXGIHWDE->Horizontal_ACTIVE;
++ HorizontalFrontPorch = pXGIHWDE->Horizontal_FP;
++ HorizontalSyncWidth = pXGIHWDE->Horizontal_SYNC;
++ HorizontalBackPorch = pXGIHWDE->Horizontal_BP;
++ VerticalActivePixel = pXGIHWDE->Vertical_ACTIVE >> (pXGIHWDE->Interlace & 0x1);
++ VerticalFrontPorch = pXGIHWDE->Vertical_FP;
++ VerticalSyncWidth = pXGIHWDE->Vertical_SYNC;
++ VerticalBackPorch = pXGIHWDE->Vertical_BP;
++
++ HT = HorizontalActivePixel + HorizontalFrontPorch + HorizontalSyncWidth + HorizontalBackPorch;
++ HDE = HorizontalActivePixel;
++ HRS = HorizontalActivePixel + HorizontalFrontPorch;
++ HRE = HorizontalActivePixel + HorizontalFrontPorch + HorizontalSyncWidth;
++ HT = HT / 8;
++ HDE = HDE / 8;
++ HRS = HRS / 8;
++ HRE = HRE / 8;
++ VGAHT = HT - 5;
++ VGAHDE = HDE - 1;
++ HDE = HDE - 1;
++ HT = HT - 1;
++ HRS = HRS + 3;
++ HRE = HRE + 3;
++
++ /*
++ HRS = HRS + 2;
++ HRE = HRE + 2;
++ */
++
++ VT = VerticalActivePixel + VerticalFrontPorch + VerticalSyncWidth + VerticalBackPorch;
++ VDE = VerticalActivePixel;
++ VRS = VerticalActivePixel + VerticalFrontPorch;
++ VRE = VerticalActivePixel + VerticalFrontPorch + VerticalSyncWidth;
++ VGAVT = VT - 2;
++ VGAVDE = VDE - 1;
++ VRS = VRS - 1;
++ VRE = VRE - 1;
++ VDE = VDE - 1;
++ VT = VT - 1;
++
++
++ temp = XGINew_GetReg1( pVBInfo->P3c4 , 0x06 ) ;
++ temp = ((temp & 0x1c ) >> 2) * 8;
++ if (temp == 0)
++ temp = 8;
++ temp1 = HorizontalActivePixel * temp / 8;
++ temp1 = temp1 / 8;
++ temp = temp1 / 8 + 1;
++
++ if (pXGIHWDE->Interlace)
++ {
++ temp1 = temp1 << 1;
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x00, 0x86);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x7f, 0x00);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x00, 0x00, (VGAHT & 0xff)); /* HT */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x01, 0x00, (VGAHDE & 0xff)); /* HDEE */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x02, 0x00, (HDE & 0xff)); /* HBS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x03, 0xe0, (HT & 0x1f)); /* HBE */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x04, 0x00, (HRS & 0xff)); /* HRS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x05, 0x60, (((HT & 0x20) << 2) | (HRE & 0x1f))); /* HRE */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x06, 0x00, (VGAVT & 0xff)); /* VT */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, 0x00, (((VRS & 0x0200) >> 2) | ((VDE & 0x0200) >> 3) | ((VGAVT & 0x0200) >> 4)| ((VGAVDE & 0x0100) >> 5) | ((VRS & 0x0100) >> 6) | ((VDE & 0x0100) >> 7) | ((VGAVT & 0x0100) >> 8)));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x09, 0xdf, ((VGAVDE & 0x0200) >> 4));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x10, 0x00, (VRS & 0xff)); /* VRS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0xf0, (VRE & 0x0f)); /* VRE */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x12, 0x00, (VDE & 0xff)); /* VDEE */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x13, 0x00, (temp1 & 0xff));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x15, 0x00, (VGAVDE & 0xff)); /* VBS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x16, 0x00, (VT & 0xff)); /* VBE */
++
++ if ( pXGIHWDE->jChipType == XG21 )
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, 0x00, ((HRS-1) & 0xff)); /* HRS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, 0x00, (((HRE-1) & 0x3f)<<2) | (((HRS-1) & 0x0300) >> 8)); /* HRS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x33, 0xFE, (((VRS) & 0x01))); /* VRS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x34, 0x00, (((VRS) & 0x01FE)>>1)); /* VRS */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x3F, 0x00, (((VRS) & 0x0600)>>9) | (((VRE) & 0x003F)<<2 )); /* VRS */
++
++ }
++ if ( pXGIHWDE->jChipType == XG27 )
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, 0x00, ((HRS-1) & 0xff)); /* HRS SR2E[7:0] */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, 0x00, (((HRE-1) & 0x3f)<<2) | (((HRS-1) & 0x0300) >> 8)); /* HRE SR2F[7:2] HRS SR2F[1:0] */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x34, 0x00, ((VRS) & 0x0FF) ); /* VRS SR34[7:0] */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x35, 0xF8, (((VRS) & 0x0700)>>8)); /* VRS SR35[2:0] */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x3F, 0xFC, (((VRE) & 0x003F)<<2 )); /* VRE SR3F[7:2] */
++
++ }
++ if (VerticalActivePixel > 1024)
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0f, 0xf7, 0x08);
++ }
++ else
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, 0xef, ((VGAVDE & 0x0100) >> 4));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x09, 0xbf, ((VGAVDE & 0x0200) >> 3));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x18, 0x00, (VGAVDE & 0x0ff));
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0xff, 0x80);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0a, 0xc0, (((VRE & 0x10) << 1) | ((VT & 0x0100) >> 4) | ((VRS & 0x0400) >> 7) | ((VGAVDE & 0x0400) >> 8) | ((VDE & 0x0400) >> 9) | ((VGAVT & 0x0400) >> 10)));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0b, 0x00, (((VGAHT & 0xff00) >> 8) | ((VGAHDE & 0xff00) >> 6) | ((HDE & 0xff00) >> 4) | ((HRS & 0xff00) >> 2)));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0c, 0xf8, (((HRE & 0x20) >> 3) | ((HT & 0xc0) >> 6)));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, 0xf0, ((temp1 & 0xff00) >> 8));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x10, 0x00, temp);
++
++
++
++ XGI_SetCRTVCLK (pVBInfo, pXGIHWDE->DCLK);
++
++ if (pXGIHWDE->BPP==0x20)
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0xE0, 0x0f);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF, 0x0);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, 0xE3, 0x10);
++ temp = ((pXGIHWDE->Horizontal_ACTIVE / 8 * pXGIHWDE->BPP) / 64) + 1;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, temp);
++ }
++ if (pXGIHWDE->BPP==0x10)
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0xE0, 0x0f);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF, 0x0);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, 0xE3, 0x08);
++ temp = ((pXGIHWDE->Horizontal_ACTIVE / 8 * pXGIHWDE->BPP) / 64) + 1;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, temp);
++ }
++ if (pXGIHWDE->BPP==0x8)
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, 0xE3, 0x00);
++ temp = ((pXGIHWDE->Horizontal_ACTIVE / 8 * pXGIHWDE->BPP) / 64) + 1;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, temp);
++ }
++
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1Group */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1Group(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
++ pVBInfo->ModeType,
++ ModeNo, ModeIdIndex);
++ USHORT RefreshRateTableIndex;
++ USHORT b3CC;
++ USHORT temp;
++
++ USHORT XGINew_P3cc = pVBInfo->P3cc;
++#ifndef LINUX_XF86
++ USHORT XGINew_P3c2 = pVBInfo->P3c2;
++#endif
++
++ /* XGINew_CRT1Mode = ModeNo ; // SaveModeID */
++ XGI_SetSeqRegs(StandTableIndex, pVBInfo);
++ XGI_SetMiscRegs(StandTableIndex, pVBInfo);
++ XGI_SetCRTCRegs(StandTableIndex, pVBInfo);
++ XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, pVBInfo);
++ XGI_SetGRCRegs(StandTableIndex, pVBInfo);
++ XGI_ClearExt1Regs(ModeNo, pVBInfo);
++
++ /* Jong 10/19/2007; merge code */
++ /* Jong 04/23/2008; All XG20,21,27 should do this */
++ /* if ( HwDeviceExtension->jChipType == XG27 ) */
++ if ( HwDeviceExtension->jChipType >= XG20 )
++ {
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ XGI_SetDefaultVCLK( pVBInfo ) ;
++ }
++ }
++
++ temp = ~ProgrammingCRT2;
++ pVBInfo->SetFlag &= temp;
++ pVBInfo->SelectCRT2Rate = 0;
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (pVBInfo->
++ VBInfo & (SetSimuScanMode | SetCRT2ToLCDA | SetInSlaveMode)) {
++ pVBInfo->SetFlag |= ProgrammingCRT2;
++ }
++ }
++
++ /* Jong 10/05/2007; merge code */
++ /* RefreshRateTableIndex = XGI_GetRatePtrCRT2( ModeNo, ModeIdIndex, pVBInfo); */
++ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
++
++ if (RefreshRateTableIndex != 0xFFFF) {
++ XGI_SetSync(RefreshRateTableIndex, pVBInfo);
++ XGI_SetCRT1CRTC(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo,
++ HwDeviceExtension);
++ XGI_SetCRT1DE(HwDeviceExtension, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex, pVBInfo);
++ XGI_SetCRT1Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ HwDeviceExtension, pVBInfo);
++ XGI_SetCRT1VCLK(ModeNo, ModeIdIndex, HwDeviceExtension,
++ RefreshRateTableIndex, pVBInfo);
++ }
++
++ /* Jong 10/04/2007; merge code */
++ /* if (HwDeviceExtension->jChipType == XG20) { */
++ if ( ( HwDeviceExtension->jChipType >= XG20 ) &&
++ ( HwDeviceExtension->jChipType < XG27 ) ) /* fix H/W DCLK/2 bug */
++ {
++ if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x4E);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE9);
++ b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
++ XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
++ }
++ else if ((ModeNo == 0x04) | (ModeNo == 0x05) | (ModeNo == 0x0D)) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE3);
++ b3CC = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3cc);
++ XGI_SetRegByte((XGIIOADDRESS) XGINew_P3cc, (b3CC |= 0x0C));
++ }
++ }
++
++ /* Jong 10/04/2007; merge code */
++ if ( HwDeviceExtension->jChipType >= XG21 )
++ {
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x38 ) ;
++ if ( temp & 0xA0 )
++ {
++
++ /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x4A , ~0x20 ) ;*/ /* Enable write GPIOF */
++ /*XGINew_SetRegAND( pVBInfo->P3d4 , 0x48 , ~0x20 ) ;*/ /* P. DWN */
++ /* XG21 CRT1 Timing */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ XGI_SetXG27CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
++ else
++ XGI_SetXG21CRTC( ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo );
++
++ XGI_UpdateXG21CRTC( ModeNo , pVBInfo , RefreshRateTableIndex) ;
++
++ if ( HwDeviceExtension->jChipType == XG27 )
++ XGI_SetXG27LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
++ else
++ XGI_SetXG21LCD( pVBInfo , RefreshRateTableIndex , ModeNo );
++
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ if ( HwDeviceExtension->jChipType == XG27 )
++ XGI_SetXG27LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
++ else
++ XGI_SetXG21LVDSPara(ModeNo,ModeIdIndex, pVBInfo );
++ }
++ /*XGINew_SetRegOR( pVBInfo->P3d4 , 0x48 , 0x20 ) ;*/ /* P. ON */
++ }
++ }
++
++ /* Jong 10/04/2007; merge code */
++ if ( HwDeviceExtension->SpecialMode )
++ {
++ XGI_SetCRTTiming( HwDeviceExtension, pVBInfo );
++ }
++
++ pVBInfo->SetFlag &= (~ProgrammingCRT2);
++ XGI_SetCRT1FIFO(ModeNo, HwDeviceExtension, pVBInfo);
++ XGI_SetCRT1ModeRegs(HwDeviceExtension, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex, pVBInfo);
++
++ if (HwDeviceExtension->jChipType == XG40) { /* Copy reg settings to 2nd chip */
++ if (CheckDualChip(pVBInfo))
++ SetDualChipRegs(HwDeviceExtension, pVBInfo);
++ }
++
++ /* XGI_LoadCharacter(); //dif ifdef TVFont */
++
++ XGI_LoadDAC(ModeNo, ModeIdIndex, pVBInfo);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetSeqRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetSeqRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
++{
++ unsigned SRdata;
++ unsigned i;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */
++ SRdata = pVBInfo->StandTable[StandTableIndex].SR[0];
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ SRdata |= 0x01;
++ }
++ else {
++ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
++ if (pVBInfo->VBInfo & SetInSlaveMode)
++ SRdata |= 0x01;
++ }
++ }
++
++ SRdata |= 0x20; /* screen off */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SRdata); /* Set SR1 */
++
++ /* Get SR2, SR3, and SR4 from table and set in hardware.
++ */
++ for (i = 2; i <= 4; i++) {
++ SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, SRdata);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetMiscRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetMiscRegs(USHORT StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
++{
++ UCHAR Miscdata;
++
++ Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
++/*
++ if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
++ {
++ if ( pVBInfo->VBInfo & SetCRT2ToLCDA )
++ {
++ Miscdata |= 0x0C ;
++ }
++ }
++*/
++
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, Miscdata); /* Set Misc(3c2) */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRTCRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRTCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
++{
++ unsigned i;
++
++ /* Unlock CRTC */
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x7f);
++
++ for (i = 0; i <= 0x18; i++) {
++ /* Get CRTC from file */
++ const unsigned CRTCdata =
++ pVBInfo->StandTable[StandTableIndex].CRTC[i];
++
++ /* Set CRTC( 3d4 ) */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, i, CRTCdata);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetATTRegs(unsigned ModeNo, unsigned StandTableIndex, unsigned ModeIdIndex,
++ const VB_DEVICE_INFO *pVBInfo)
++{
++ unsigned i;
++ const unsigned modeflag = (ModeNo <= 0x13)
++ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
++ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++
++ for (i = 0; i <= 0x13; i++) {
++ UCHAR ARdata = pVBInfo->StandTable[StandTableIndex].ATTR[i];
++
++ if (modeflag & Charx8Dot) { /* ifndef Dot9 */
++ if (i == 0x13) {
++ /* Pixel shift. If screen on LCD or TV is shifted left or
++ * right, this might be the cause.
++ */
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
++ ARdata = 0;
++ else {
++ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD)) {
++ if (pVBInfo->VBInfo & SetInSlaveMode)
++ ARdata = 0;
++ }
++ }
++ }
++ }
++
++ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, i); /* set index */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, ARdata); /* set data */
++ }
++
++ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* reset 3da */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x14); /* set index */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x00); /* set data */
++
++ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da); /* Enable Attribute */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c0, 0x20);
++ XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetGRCRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetGRCRegs(unsigned StandTableIndex, const VB_DEVICE_INFO *pVBInfo)
++{
++ unsigned i;
++
++ for (i = 0; i <= 8; i++) {
++ /* Get GR from file and set GR (3ce)
++ */
++ const unsigned GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3ce, i, GRdata);
++ }
++
++ if (pVBInfo->ModeType > ModeVGA) {
++ /* 256 color disable */
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3ce, 0x05, 0xBF);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_ClearExt1Regs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_ClearExt1Regs(unsigned ModeNo, const VB_DEVICE_INFO *pVBInfo)
++{
++ unsigned i;
++
++ /* Clear SR0A-SR0E */
++ for (i = 0x0A; i <= 0x0E; i++) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, i, 0x00);
++ }
++
++ /* This code came from the old XGI_New_ClearExt1Regs in init.c. Since
++ * it wasn't included in the newer code drop from XGI, I'm not sure if
++ * it's necessary on the Volari chips. I've included it here, ifdefed
++ * out, for future reference.
++ * - idr
++ */
++#if 0
++ XGI_SetRegAND(pVBInfo->P3c4, 0x37, 0xFE);
++ if ((ModeNo == 0x06) || ((ModeNo >= 0x0e) && (ModeNo <= 0x13))) {
++ XGI_SetReg(pVBInfo->P3c4, 0x0e, 0x20);
++ }
++#else
++ (void) ModeNo;
++#endif
++}
++
++/* Jong 10/17/2007; merge code */
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetDefaultVCLK */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++UCHAR XGI_SetDefaultVCLK( PVB_DEVICE_INFO pVBInfo )
++{
++ /* Jong 04/22/2008; XGINew_ -> XGI_*/
++ /* Jong 04/23/2008; coding error: VCLKData[0]-> 0x10:25MHz; VCLKData[1]-> 0x20:28MHz */
++ /* XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ; */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x10 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 0 ].SR2B ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 0 ].SR2C ) ;
++
++ /* XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x10 ) ; */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , 0x20 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->VCLKData[ 1 ].SR2B ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->VCLKData[ 1 ].SR2C ) ;
++
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 ) ;
++ return( 0 ) ;
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetRatePtrCRT2 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetRatePtrCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ SHORT LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01 }
++ , LCDARefreshIndex[] = {
++ 0x00, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01};
++
++ USHORT RefreshRateTableIndex, i, modeflag, index, temp;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ if (ModeNo < 0x14)
++ return (0xFFFF);
++
++ index = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
++ index = index >> pVBInfo->SelectCRT2Rate;
++ index &= 0x0F;
++
++ if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD))
++ index = 0;
++
++ if (index > 0)
++ index--;
++
++ if (pVBInfo->SetFlag & ProgrammingCRT2) {
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++
++ /* Jong 10/03/2007; merge code */
++ if( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
++ | VB_XGI301C))
++ temp = LCDARefreshIndex[pVBInfo->LCDResInfo & 0x0F]; /* 301b */
++ else
++ temp = LCDRefreshIndex[pVBInfo->LCDResInfo & 0x0F];
++
++ if (index > temp) {
++ index = temp;
++ }
++ }
++ else
++ {
++ index = 0 ;
++ }
++ }
++ }
++
++ RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex;
++ ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
++
++ /* Jong 10/03/2007; merge code */
++ /* Do the similiar adjustment like XGISearchCRT1Rate() */
++ if ( HwDeviceExtension->jChipType >= XG20 ) /* for XG20, XG21, XG27 */
++ {
++ /*
++ if ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag & XG2xNotSupport )
++ {
++ index++;
++ }
++ */
++
++ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 800 ) &&
++ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 600 ) )
++ {
++ index++;
++ }
++ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1024 ) &&
++ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 768 ) )
++ {
++ index++;
++ }
++ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1280 ) &&
++ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 1024 ) )
++ {
++ index++;
++ }
++
++ /* Jong 11/29/2007; fix bugs of 1600x1200; set limitation to 60Hz */
++ /* It should need to check refresh rate supporting of output device */
++ if ( ( pVBInfo->RefIndex[ RefreshRateTableIndex ].XRes == 1600 ) &&
++ ( pVBInfo->RefIndex[ RefreshRateTableIndex ].YRes == 1200 ) )
++ {
++ index=0;
++ }
++ }
++
++ /* Jong 11/29/2007; according to CR33(index) to update refresh table index */
++ i = 0 ;
++ do
++ {
++ if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo)
++ break;
++ temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
++ temp &= ModeInfoFlag;
++ if (temp < pVBInfo->ModeType)
++ break;
++
++ i++;
++ index--;
++
++ } while (index != 0xFFFF);
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ temp =
++ pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
++ if (temp & InterlaceMode) {
++ i++;
++ }
++ }
++ }
++
++ i--;
++ if ((pVBInfo->SetFlag & ProgrammingCRT2)) {
++ temp =
++ XGI_AjustCRT2Rate(ModeNo, ModeIdIndex, RefreshRateTableIndex, &i,
++ pVBInfo);
++ }
++
++ return (RefreshRateTableIndex + i); /*return(0x01|(temp1<<1)); */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_AjustCRT2Rate */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_AjustCRT2Rate(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, USHORT * i,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, tempbx, resinfo, modeflag, infoflag;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID;
++ tempax = 0;
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
++ tempax |= SupportRAMDAC2;
++
++ if (pVBInfo->VBType & VB_XGI301C)
++ tempax |= SupportCRT2in301C;
++ }
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
++ tempax |= SupportLCD;
++
++ if (pVBInfo->LCDResInfo != Panel1280x1024) {
++ if (pVBInfo->LCDResInfo != Panel1280x960) {
++ if (pVBInfo->LCDInfo & LCDNonExpanding) {
++ if (resinfo >= 9) {
++ tempax = 0;
++ return (0);
++ }
++ }
++ }
++ }
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ && (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
++ tempax |= SupportYPbPr;
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (resinfo == 4)
++ return (0);
++
++ if (resinfo == 3)
++ return (0);
++
++ if (resinfo > 7)
++ return (0);
++ }
++ }
++ else {
++ tempax |= SupportHiVisionTV;
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (resinfo == 4)
++ return (0);
++
++ if (resinfo == 3) {
++ if (pVBInfo->SetFlag & TVSimuMode)
++ return (0);
++ }
++
++ if (resinfo > 7)
++ return (0);
++ }
++ }
++ }
++ else {
++ if (pVBInfo->
++ VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
++ SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
++ tempax |= SupportTV;
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
++ | VB_XGI301C)) {
++ tempax |= SupportTV1024;
++ }
++
++ if (!(pVBInfo->VBInfo & SetPALTV)) {
++ if (modeflag & NoSupportSimuTV) {
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (!(pVBInfo->VBInfo & SetNotSimuMode)) {
++ return (0);
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ else /* for LVDS */
++ {
++ if ( pVBInfo->VBInfo & SetCRT2ToLCD )
++ {
++ tempax |= SupportLCD ;
++
++ if ( resinfo > 0x08 )
++ return( 0 ) ; /* 1024x768 */
++
++ if ( pVBInfo->LCDResInfo < Panel1024x768 )
++ {
++ if ( resinfo > 0x07 )
++ return( 0 ) ; /* 800x600 */
++
++ if ( resinfo == 0x04 )
++ return( 0 ) ; /* 512x384 */
++ }
++ }
++ }
++
++ for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx;
++ (*i)--) {
++ infoflag =
++ pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
++ if (infoflag & tempax) {
++ return (1);
++ }
++ if ((*i) == 0)
++ break;
++ }
++
++ for ((*i) = 0;; (*i)++) {
++ infoflag =
++ pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
++ if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
++ return (0);
++ }
++
++ if (infoflag & tempax) {
++ return (1);
++ }
++ }
++ return (1);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetSync */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetSync(unsigned RefreshRateTableIndex, const VB_DEVICE_INFO *pVBInfo)
++{
++ const unsigned sync =
++ (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8) & 0xC0;
++
++ /* Set Misc(3c2) */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c2, sync | 0x2F);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1CRTC */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1CRTC(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension)
++{
++ UCHAR index, data;
++#ifndef LINUX_XF86
++ USHORT temp, tempah, j, modeflag, ResInfo, DisplayType;
++#endif
++ USHORT i;
++
++ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
++ index = index & IndexMask;
++
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
++ data &= 0x7F;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
++
++ for (i = 0; i < 8; i++)
++ pVBInfo->TimingH.data[i] =
++ pVBInfo->XGINEWUB_CRT1Table[index].CR[i];
++
++ for (i = 0; i < 7; i++)
++ pVBInfo->TimingV.data[i] =
++ pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8];
++
++ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
++
++
++
++ XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
++
++
++ if (pVBInfo->ModeType > 0x03)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x14, 0x4F);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1Timing_H */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1Timing_H(PVB_DEVICE_INFO pVBInfo,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension)
++{
++ UCHAR data, data1, pushax;
++ USHORT i, j;
++
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
++ /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 ,0x11 , 0x7f , 0x00 ) ; */
++
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
++ data &= 0x7F;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data);
++
++ data = pVBInfo->TimingH.data[0];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0, data);
++
++ for (i = 0x01; i <= 0x04; i++) {
++ data = pVBInfo->TimingH.data[i];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 1), data);
++ }
++
++ for (i = 0x05; i <= 0x06; i++) {
++ data = pVBInfo->TimingH.data[i];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i + 6), data);
++ }
++
++ j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
++ j &= 0x1F;
++ data = pVBInfo->TimingH.data[7];
++ data &= 0xE0;
++ data |= j;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, data);
++
++ /* Jong 10/04/2007; merge code */
++ if (HwDeviceExtension->jChipType >= XG20) {
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04);
++ data = data - 1;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x04, data);
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05);
++ data1 = data;
++ data1 &= 0xE0;
++ data &= 0x1F;
++ if (data == 0) {
++ pushax = data;
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c);
++ data &= 0xFB;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0c, data);
++ data = pushax;
++ }
++ data = data - 1;
++ data |= data1;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x05, data);
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0e);
++ data = data >> 5;
++ data = data + 3;
++ if (data > 7)
++ data = data - 7;
++ data = data << 5;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0e, ~0xE0, data);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1Timing_V */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1Timing_V(USHORT ModeIdIndex, USHORT ModeNo,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR data;
++ USHORT i, j;
++
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0 ) ; */
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4 , 0x56 , 0 ) ; */
++ /* XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , 0x7f , 0x00 ) ; */
++
++ for (i = 0x00; i <= 0x01; i++) {
++ data = pVBInfo->TimingV.data[i];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 6), data);
++ }
++
++ for (i = 0x02; i <= 0x03; i++) {
++ data = pVBInfo->TimingV.data[i];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x0e), data);
++ }
++
++ for (i = 0x04; i <= 0x05; i++) {
++ data = pVBInfo->TimingV.data[i];
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 0x11), data);
++ }
++
++ j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a);
++ j &= 0xC0;
++ data = pVBInfo->TimingV.data[6];
++ data &= 0x3F;
++ data |= j;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0a, data);
++
++ data = pVBInfo->TimingV.data[6];
++ data &= 0x80;
++ data = data >> 2;
++
++ if (ModeNo <= 0x13)
++ i = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ else
++ i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++
++ i &= DoubleScanMode;
++ if (i)
++ data |= 0x80;
++
++ j = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09);
++ j &= 0x5F;
++ data |= j;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x09, data);
++}
++
++/* Jong 10/04/2007; merge code */
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetXG21CRTC */
++/* Input : Stand or enhance CRTC table */
++/* Output : Fill CRT Hsync/Vsync to SR2E/SR2F/SR30/SR33/SR34/SR3F */
++/* Description : Set LCD timing */
++/* --------------------------------------------------------------------- */
++void XGI_SetXG21CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
++ USHORT Temp1, Temp2, Temp3 ;
++
++ if ( ModeNo <= 0x13 )
++ {
++ StandTableIndex = XGI_GetModePtr( pVBInfo->SModeIDTable,
++ pVBInfo->ModeType,
++ ModeNo, ModeIdIndex);
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
++ Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
++ Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
++ Tempcx = Tempax ;
++ Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
++ Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
++ if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
++ Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
++ Tempdx <<= 2 ; /* Tempdx << 2 */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
++
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR16 VRS */
++ Tempbx = Tempax ; /* Tempbx=Tempax */
++ Tempax &= 0x01 ; /* Tempax: VRS[0] */
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS */
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax: CR7 VRS */
++ Tempdx = Tempbx >> 1 ; /* Tempdx: VRS[7:1] */
++ Tempcx = Tempax & 0x04 ; /* Tempcx: CR7[2] */
++ Tempcx <<= 5 ; /* Tempcx[7]: VRS[8] */
++ Tempdx |= Tempcx ; /* Tempdx: VRS[8:1] */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempdx ) ; /* SR34[7:0]: VRS[8:1] */
++
++ Temp1 = Tempcx << 1 ; /* Temp1[8]: VRS[8] UCHAR -> USHORT */
++ Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
++ Tempax &= 0x80 ; /* Tempax[7]: CR7[7] */
++ Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
++ Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
++
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR16 VRE */
++ Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
++ Temp2 = Temp1 & 0x3F0 ; /* Temp2[9:4]: VRS[9:4] */
++ Temp2 |= Tempax ; /* Temp2[9:0]: VRE[9:0] */
++ Temp3 = Temp1 & 0x0F ; /* Temp3[3:0]: VRS[3:0] */
++ if ( Tempax < Temp3 ) /* VRE[3:0]<VRS[3:0] */
++ Temp2 |= 0x10 ; /* Temp2: VRE + 0x10 */
++ Temp2 &= 0xFF ; /* Temp2[7:0]: VRE[7:0] */
++ Tempax = (UCHAR)Temp2 ; /* Tempax[7:0]: VRE[7:0] */
++ Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
++ Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
++ Temp1 >>= 9 ; /* [10:9]->[1:0] */
++ Tempbx = (UCHAR)Temp1 ; /* Tempbx[1:0]: VRS[10:9] */
++ Tempax |= Tempbx ; /* VRE[5:0]VRS[10:9] */
++ Tempax &= 0x7F ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
++ }
++ else
++ {
++ index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
++ Tempcx = Tempax ; /* Tempcx: HRS */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
++
++ Tempdx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SRB */
++ Tempdx &= 0xC0 ; /* Tempdx[7:6]: SRB[7:6] */
++ Temp1 = Tempdx ; /* Temp1[7:6]: HRS[9:8] */
++ Temp1 <<= 2 ; /* Temp1[9:8]: HRS[9:8] */
++ Temp1 |= Tempax ; /* Temp1[9:0]: HRS[9:0] */
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
++ Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
++
++ Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
++ Tempbx &= 0x04 ; /* Tempbx[2]: HRE[5] */
++ Tempbx <<= 3 ; /* Tempbx[5]: HRE[5] */
++ Tempax |= Tempbx ; /* Tempax[5:0]: HRE[5:0] */
++
++ Temp2 = Temp1 & 0x3C0 ; /* Temp2[9:6]: HRS[9:6] */
++ Temp2 |= Tempax ; /* Temp2[9:0]: HRE[9:0] */
++
++ Tempcx &= 0x3F ; /* Tempcx[5:0]: HRS[5:0] */
++ if( Tempax < Tempcx ) /* HRE < HRS */
++ Temp2 |= 0x40 ; /* Temp2 + 0x40 */
++
++ Temp2 &= 0xFF ;
++ Tempax = (UCHAR)Temp2 ; /* Tempax: HRE[7:0] */
++ Tempax <<= 2 ; /* Tempax[7:2]: HRE[5:0] */
++ Tempdx >>= 6 ; /* Tempdx[7:6]->[1:0] HRS[9:8] */
++ Tempax |= Tempdx ; /* HRE[5:0]HRS[9:8] */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F D[7:2]->HRE, D[1:0]->HRS */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
++ Tempbx = Tempax ; /* Tempbx: VRS */
++ Tempax &= 0x01 ; /* Tempax[0]: VRS[0] */
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x33 , Tempax ) ; /* SR33[0]->VRS[0] */
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[2][7] VRE */
++ Tempcx = Tempbx >> 1 ; /* Tempcx[6:0]: VRS[7:1] */
++ Tempdx = Tempax & 0x04 ; /* Tempdx[2]: CR7[2] */
++ Tempdx <<= 5 ; /* Tempdx[7]: VRS[8] */
++ Tempcx |= Tempdx ; /* Tempcx[7:0]: VRS[8:1] */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempcx ) ; /* SR34[8:1]->VRS */
++
++ Temp1 = Tempdx ; /* Temp1[7]: Tempdx[7] */
++ Temp1 <<= 1 ; /* Temp1[8]: VRS[8] */
++ Temp1 |= Tempbx ; /* Temp1[8:0]: VRS[8:0] */
++ Tempax &= 0x80 ;
++ Temp2 = Tempax << 2 ; /* Temp2[9]: VRS[9] */
++ Temp1 |= Temp2 ; /* Temp1[9:0]: VRS[9:0] */
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SRA */
++ Tempax &= 0x08 ; /* Tempax[3]: VRS[3] */
++ Temp2 = Tempax ;
++ Temp2 <<= 7 ; /* Temp2[10]: VRS[10] */
++ Temp1 |= Temp2 ; /* Temp1[10:0]: VRS[10:0] */
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
++ Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
++ Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SRA */
++ Tempbx &= 0x20 ; /* Tempbx[5]: VRE[5] */
++ Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
++ Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
++ Temp2 = Temp1 & 0x7E0 ; /* Temp2[10:5]: VRS[10:5] */
++ Temp2 |= Tempax ; /* Temp2[10:5]: VRE[10:5] */
++
++ Temp3 = Temp1 & 0x1F ; /* Temp3[4:0]: VRS[4:0] */
++ if ( Tempax < Temp3 ) /* VRE < VRS */
++ Temp2 |= 0x20 ; /* VRE + 0x20 */
++
++ Temp2 &= 0xFF ;
++ Tempax = (UCHAR)Temp2 ; /* Tempax: VRE[7:0] */
++ Tempax <<= 2 ; /* Tempax[7:0]; VRE[5:0]00 */
++ Temp1 &= 0x600 ; /* Temp1[10:9]: VRS[10:9] */
++ Temp1 >>= 9 ; /* Temp1[1:0]: VRS[10:9] */
++ Tempbx = (UCHAR)Temp1 ;
++ Tempax |= Tempbx ; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
++ Tempax &= 0x7F ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , Tempax ) ; /* SR3F D[7:2]->VRE D[1:0]->VRS */
++ }
++}
++
++/* Jong 10/04/2007; merge code */
++void XGI_SetXG27CRTC(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx ;
++
++ if ( ModeNo <= 0x13 )
++ {
++ /* Jong 10/05/2007; merge code */
++ /* StandTableIndex = XGI_GetModePtr( ModeNo , ModeIdIndex, pVBInfo ) ; */
++ StandTableIndex = XGI_GetModePtr( pVBInfo->SModeIDTable,
++ pVBInfo->ModeType,
++ ModeNo, ModeIdIndex);
++
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 4 ] ; /* CR04 HRS */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E [7:0]->HRS */
++ Tempbx = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 5 ] ; /* Tempbx: CR05 HRE */
++ Tempbx &= 0x1F ; /* Tempbx: HRE[4:0] */
++ Tempcx = Tempax ;
++ Tempcx &= 0xE0 ; /* Tempcx: HRS[7:5] */
++ Tempdx = Tempcx | Tempbx ; /* Tempdx(HRE): HRS[7:5]HRE[4:0] */
++ if ( Tempbx < ( Tempax & 0x1F ) ) /* IF HRE < HRS */
++ Tempdx |= 0x20 ; /* Tempdx: HRE = HRE + 0x20 */
++ Tempdx <<= 2 ; /* Tempdx << 2 */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempdx ) ; /* SR2F [7:2]->HRE */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
++
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 16 ] ; /* Tempax: CR10 VRS */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS */
++ Tempcx = Tempax ; /* Tempcx=Tempax=VRS[7:0] */
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 7 ] ; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
++ Tempbx = Tempax ; /* Tempbx=CR07 */
++ Tempax &= 0x04 ; /* Tempax[2]: CR07[2] VRS[8] */
++ Tempax >>= 2;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x01, Tempax ) ; /* SR35 D[0]->VRS D[8] */
++ Tempcx |= (Tempax << 8) ; /* Tempcx[8] |= VRS[8] */
++ Tempcx |= (Tempbx & 0x80)<<2; /* Tempcx[9] |= VRS[9] */
++
++
++ Tempax = pVBInfo->StandTable[ StandTableIndex ].CRTC[ 17 ] ; /* CR11 VRE */
++ Tempax &= 0x0F ; /* Tempax: VRE[3:0] */
++ Tempbx = Tempcx ; /* Tempbx=Tempcx=VRS[9:0] */
++ Tempbx &= 0x3F0 ; /* Tempbx[9:4]: VRS[9:4] */
++ Tempbx |= Tempax ; /* Tempbx[9:0]: VRE[9:0] */
++ if ( Tempax <= (Tempcx & 0x0F) ) /* VRE[3:0]<=VRS[3:0] */
++ Tempbx |= 0x10 ; /* Tempbx: VRE + 0x10 */
++ Tempax = (UCHAR)Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
++ Tempax <<= 2 ; /* Tempax << 2: VRE[5:0] */
++ Tempcx = (Tempcx&0x600)>>8; /* Tempcx VRS[10:9] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC, Tempax ) ; /* SR3F D[7:2]->VRE D[5:0] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x06, Tempcx ) ; /* SR35 D[2:1]->VRS[10:9] */
++ }
++ else
++ {
++ index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC ;
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
++ Tempbx = Tempax ; /* Tempbx: HRS[7:0] */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , Tempax ) ; /* SR2E[7:0]->HRS */
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
++ Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
++ Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 4 ] ; /* CR5 HRE */
++ Tempax &= 0x1F ; /* Tempax[4:0]: HRE[4:0] */
++ Tempcx = Tempax ; /* Tempcx: HRE[4:0] */
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 6 ] ; /* SRC */
++ Tempax &= 0x04 ; /* Tempax[2]: HRE[5] */
++ Tempax <<= 3 ; /* Tempax[5]: HRE[5] */
++ Tempcx |= Tempax ; /* Tempcx[5:0]: HRE[5:0] */
++
++ Tempbx = Tempbx & 0x3C0 ; /* Tempbx[9:6]: HRS[9:6] */
++ Tempbx |= Tempcx ; /* Tempbx: HRS[9:6]HRE[5:0] */
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 3 ] ; /* Tempax: CR4 HRS */
++ Tempax &= 0x3F ; /* Tempax: HRS[5:0] */
++ if( Tempcx <= Tempax ) /* HRE[5:0] < HRS[5:0] */
++ Tempbx += 0x40 ; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 5 ] ; /* SR0B */
++ Tempax &= 0xC0 ; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
++ Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
++ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , Tempax ) ; /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0xE3 , 00 ) ;
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 10 ] ; /* CR10 VRS */
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , Tempax ) ; /* SR34[7:0]->VRS[7:0] */
++
++ Tempcx = Tempax ; /* Tempcx <= VRS[7:0] */
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 9 ] ; /* CR7[7][2] VRS[9][8] */
++ Tempbx = Tempax ; /* Tempbx <= CR07[7:0] */
++ Tempax = Tempax & 0x04 ; /* Tempax[2]: CR7[2]: VRS[8] */
++ Tempax >>= 2 ; /* Tempax[0]: VRS[8] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x01 , Tempax ) ; /* SR35[0]: VRS[8] */
++ Tempcx |= (Tempax<<8) ; /* Tempcx <= VRS[8:0] */
++ Tempcx |= ((Tempbx&0x80)<<2) ; /* Tempcx <= VRS[9:0] */
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempax: SR0A */
++ Tempax &= 0x08; /* SR0A[3] VRS[10] */
++ Tempcx |= (Tempax<<7) ; /* Tempcx <= VRS[10:0] */
++
++
++ Tempax = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 11 ] ; /* Tempax: CR11 VRE */
++ Tempax &= 0x0F ; /* Tempax[3:0]: VRE[3:0] */
++ Tempbx = pVBInfo->XGINEWUB_CRT1Table[ index ].CR[ 14 ] ; /* Tempbx: SR0A */
++ Tempbx &= 0x20 ; /* Tempbx[5]: SR0A[5]: VRE[4] */
++ Tempbx >>= 1 ; /* Tempbx[4]: VRE[4] */
++ Tempax |= Tempbx ; /* Tempax[4:0]: VRE[4:0] */
++ Tempbx = Tempcx ; /* Tempbx: VRS[10:0] */
++ Tempbx &= 0x7E0 ; /* Tempbx[10:5]: VRS[10:5] */
++ Tempbx |= Tempax ; /* Tempbx: VRS[10:5]VRE[4:0] */
++
++ if ( Tempbx <= Tempcx ) /* VRE <= VRS */
++ Tempbx |= 0x20 ; /* VRE + 0x20 */
++
++ Tempax = (Tempbx<<2) & 0xFF ; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC , Tempax ) ; /* SR3F[7:2]:VRE[5:0] */
++ Tempax = Tempcx >> 8;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x07 , Tempax ) ; /* SR35[2:0]:VRS[10:8] */
++ }
++}
++
++
++/* Jong 10/04/2007; merge code */
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetXG21LCD */
++/* Input : */
++/* Output : FCLK duty cycle, FCLK delay compensation */
++/* Description : All values set zero */
++/* --------------------------------------------------------------------- */
++void XGI_SetXG21LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
++{
++ USHORT Data , Temp , b3CC ;
++ USHORT XGI_P3cc ;
++
++ if ( ModeNo > 0x13 )
++ Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
++ XGI_P3cc = pVBInfo->P3cc ;
++
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , 0x00 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , 0x00 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , 0x00 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , 0x00 ) ;
++ if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
++ {
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
++ }
++
++ Temp = XGI_GetReg( pVBInfo->P3d4 , 0x37 ) ;
++
++ if ( Temp & 0x01 )
++ {
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x06 , 0x40 ) ; /* 18 bits FP */
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , 0x40 ) ;
++ }
++
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
++
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 ) ;
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 ) ;
++
++ if ( ModeNo <= 0x13 )
++ {
++ b3CC = (UCHAR) XGI_GetRegByte( (XGIIOADDRESS) XGI_P3cc ) ;
++ if ( b3CC & 0x40 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
++ if ( b3CC & 0x80 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
++ }
++ else
++ {
++ if ( Data & 0x4000 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
++ if ( Data & 0x8000 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
++ }
++}
++
++/* Jong 10/04/2007; merge code */
++void XGI_SetXG27LCD(PVB_DEVICE_INFO pVBInfo,USHORT RefreshRateTableIndex,USHORT ModeNo)
++{
++ USHORT Data , Temp , b3CC ;
++ USHORT XGI_P3cc ;
++
++ if ( ModeNo > 0x13 )
++ Data = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_InfoFlag ;
++ XGI_P3cc = pVBInfo->P3cc ;
++
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , 0x00 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , 0x00 ) ;
++ XGI_SetReg( pVBInfo->P3d4 , 0x46 , 0x00 ) ;
++ XGI_SetReg( pVBInfo->P3d4 , 0x47 , 0x00 ) ;
++
++ Temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 ) ;
++ if ( ( Temp & 0x03 ) == 0 ) /* dual 12 */
++ {
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , 0x13 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , 0x13 ) ;
++ }
++
++ if ( ((*pVBInfo->pDVOSetting)&0xC0) == 0xC0 )
++ {
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2E , *pVBInfo->pCR2E ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2F , *pVBInfo->pCR2F ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x46 , *pVBInfo->pCR46 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x47 , *pVBInfo->pCR47 ) ;
++ }
++
++ XGI_SetXG27FPBits(pVBInfo);
++
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1E , 0x01 ) ; /* Negative blank polarity */
++
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 ) ; /* Hsync polarity */
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 ) ; /* Vsync polarity */
++
++ if ( ModeNo <= 0x13 )
++ {
++ b3CC = (UCHAR) XGI_GetRegByte( (XGIIOADDRESS) XGI_P3cc ) ;
++ if ( b3CC & 0x40 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
++ if ( b3CC & 0x80 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
++ }
++ else
++ {
++ if ( Data & 0x4000 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , 0x20 ) ; /* Hsync polarity */
++ if ( Data & 0x8000 )
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , 0x80 ) ; /* Vsync polarity */
++ }
++}
++
++/* Jong 10/04/2007; merge code */
++/* --------------------------------------------------------------------- */
++/* Function : XGI_UpdateXG21CRTC */
++/* Input : */
++/* Output : CRT1 CRTC */
++/* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
++/* --------------------------------------------------------------------- */
++void XGI_UpdateXG21CRTC( USHORT ModeNo , PVB_DEVICE_INFO pVBInfo , USHORT RefreshRateTableIndex )
++{
++ int i , index = -1;
++
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , 0x7F ) ; /* Unlock CR0~7 */
++ if ( ModeNo <= 0x13 )
++ {
++ for( i = 0 ; i < 12 ; i++ )
++ {
++ if ( ModeNo == pVBInfo->UpdateCRT1[ i ].ModeID )
++ index = i ;
++ }
++ }
++ else
++ {
++ if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x60 ) )
++ index = 12 ;
++ else if ( ModeNo == 0x2E && ( pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRT1CRTC == RES640x480x72 ) )
++ index = 13 ;
++ else if ( ModeNo == 0x2F )
++ index = 14 ;
++ else if ( ModeNo == 0x50 )
++ index = 15 ;
++ else if ( ModeNo == 0x59 )
++ index = 16 ;
++ }
++
++ if( index != -1 )
++ {
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x02 , pVBInfo->UpdateCRT1[ index ].CR02 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x03 , pVBInfo->UpdateCRT1[ index ].CR03 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x15 , pVBInfo->UpdateCRT1[ index ].CR15 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x16 , pVBInfo->UpdateCRT1[ index ].CR16 ) ;
++ }
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1DE */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1DE(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, tempbx, tempcx, temp, modeflag;
++ UCHAR data;
++ const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
++
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ tempax = pVBInfo->StResInfo[resindex].HTotal;
++ tempbx = pVBInfo->StResInfo[resindex].VTotal;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ tempax = pVBInfo->ModeResInfo[resindex].HTotal;
++ tempbx = pVBInfo->ModeResInfo[resindex].VTotal;
++ }
++
++ if (modeflag & HalfDCLK)
++ tempax = tempax >> 1;
++
++ if (ModeNo > 0x13) {
++ if (modeflag & HalfDCLK)
++ tempax = tempax << 1;
++
++ temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++
++ if (temp & InterlaceMode)
++ tempbx = tempbx >> 1;
++
++ if (modeflag & DoubleScanMode)
++ tempbx = tempbx << 1;
++ }
++
++ tempcx = 8;
++
++ /* if ( !( modeflag & Charx8Dot ) ) */
++ /* tempcx = 9 ; */
++
++ tempax /= tempcx;
++ tempax -= 1;
++ tempbx -= 1;
++ tempcx = tempax;
++ temp = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11);
++ data &= 0x7F;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x01, (USHORT) (tempcx & 0xff));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0b, ~0x0c,
++ (USHORT) ((tempcx & 0x0ff00) >> 10));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x12, (USHORT) (tempbx & 0xff));
++ tempax = 0;
++ tempbx = tempbx >> 8;
++
++ if (tempbx & 0x01)
++ tempax |= 0x02;
++
++ if (tempbx & 0x02)
++ tempax |= 0x40;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x07, ~0x42, tempax);
++ data = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x07);
++ data &= 0xFF;
++ tempax = 0;
++
++ if (tempbx & 0x04)
++ tempax |= 0x02;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x0a, ~0x02, tempax);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, temp);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetResInfo */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ return (ModeNo <= 0x13)
++ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo
++ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++}
++
++
++static void
++get_mode_xres_yres(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo,
++ unsigned *width, unsigned *height)
++{
++ const USHORT resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
++ unsigned xres;
++ unsigned yres;
++
++
++ if (ModeNo <= 0x13) {
++ xres = pVBInfo->StResInfo[resindex].HTotal;
++ yres = pVBInfo->StResInfo[resindex].VTotal;
++ }
++ else {
++ const unsigned modeflag =
++ pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++
++ xres = pVBInfo->ModeResInfo[resindex].HTotal;
++ yres = pVBInfo->ModeResInfo[resindex].VTotal;
++
++ if (modeflag & HalfDCLK)
++ xres *= 2;
++
++ if (modeflag & DoubleScanMode)
++ yres *= 2;
++ }
++
++ *width = xres;
++ *height = yres;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1Offset */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1Offset(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp, ah, al, temp2, i, DisplayUnit;
++
++ /* GetOffset */
++ temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
++ temp = temp >> 8;
++ temp = pVBInfo->ScreenOffset[temp];
++
++ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ temp2 &= InterlaceMode;
++
++ if (temp2)
++ temp = temp << 1;
++
++ temp2 = pVBInfo->ModeType - ModeEGA;
++
++ switch (temp2) {
++ case 0:
++ temp2 = 1;
++ break;
++ case 1:
++ temp2 = 2;
++ break;
++ case 2:
++ temp2 = 4;
++ break;
++ case 3:
++ temp2 = 4;
++ break;
++ case 4:
++ temp2 = 6;
++ break;
++ case 5:
++ temp2 = 8;
++ break;
++ default:
++ break;
++ }
++
++ if ((ModeNo >= 0x26) && (ModeNo <= 0x28))
++ temp = temp * temp2 + temp2 / 2;
++ else
++ temp *= temp2;
++
++ /* SetOffset */
++ DisplayUnit = temp;
++ temp2 = temp;
++ temp = temp >> 8; /* ah */
++ temp &= 0x0F;
++ i = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E);
++ i &= 0xF0;
++ i |= temp;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E, i);
++
++ temp = (UCHAR) temp2;
++ temp &= 0xFF; /* al */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x13, temp);
++
++ /* SetDisplayUnit */
++ temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ temp2 &= InterlaceMode;
++ if (temp2)
++ DisplayUnit >>= 1;
++
++ DisplayUnit = DisplayUnit << 5;
++ ah = (DisplayUnit & 0xff00) >> 8;
++ al = DisplayUnit & 0x00ff;
++ if (al == 0)
++ ah += 1;
++ else
++ ah += 2;
++
++ /* Jong 10/04/2007; merge code */
++ if (HwDeviceExtension->jChipType >= XG20)
++ if ((ModeNo == 0x4A) | (ModeNo == 0x49))
++ ah -= 1;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x10, ah);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1VCLK */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1VCLK(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ unsigned index;
++ unsigned clka;
++ unsigned clkb;
++ unsigned data; /* Jong 10/04/2007; merge code */
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ index = pVBInfo->RefIndex[ RefreshRateTableIndex ].Ext_CRTVCLK ;
++ clka = pVBInfo->VCLKData[ index ].SR2B;
++ clkb = pVBInfo->VCLKData[ index ].SR2C;
++ }
++ else if ((pVBInfo->VBType & VB_XGI301BLV302BLV)
++ && (pVBInfo->VBInfo & SetCRT2ToLCDA)) {
++ index = XGI_GetVCLK2Ptr(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ pVBInfo);
++
++ clka = pVBInfo->VBVCLKData[index].Part4_A;
++ clkb = pVBInfo->VBVCLKData[index].Part4_B;
++ }
++ else {
++ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
++
++ clka = pVBInfo->VCLKData[index].SR2B;
++ clkb = pVBInfo->VCLKData[index].SR2C;
++ }
++
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0xCF);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, clka);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, clkb);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2D, 0x01);
++
++ /* Jong 10/04/2007; merge code */
++ if ((HwDeviceExtension->jChipType >= XG20)
++ && (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK)) {
++ UCHAR data;
++
++ /* FIXME: Does this actually serve any purpose? This register is
++ * FIXME: already written above.
++ */
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, data);
++
++ /* FIXME: The logic here seems wrong. It looks like its possible
++ * FIXME: for the (data << 1) to cause a bit to creep into the index
++ * FIXME: part. THere's no documentation for this register, so I have
++ * FIXME: no way of knowing. :(
++ */
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C);
++ index = data;
++ index &= 0xE0;
++ data &= 0x1F;
++ data = data << 1;
++ data += 1;
++ data |= index;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, data);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1FIFO */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1FIFO(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data;
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
++ data &= 0xfe;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data); /* diable auto-threshold */
++
++ if (ModeNo > 0x13) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0x34);
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
++ data &= 0xF0;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D);
++ data |= 0x01;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3D, data);
++ }
++ else {
++ if (HwDeviceExtension->jChipType == XG27)
++ {
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x08 , 0x0E ) ;
++ data = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 ) ;
++ data &= 0xC0 ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , data | 0x20 ) ;
++ }
++ else
++ {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x08, 0xAE);
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09);
++ data &= 0xF0;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x09, data);
++ }
++ }
++
++ /* Jong 10/17/2007; merge code */
++ if (HwDeviceExtension->jChipType == XG21)
++ {
++ XGI_SetXG21FPBits(pVBInfo); /* Fix SR9[7:6] can't read back */
++ }
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT1ModeRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT1ModeRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data, data2, data3, infoflag = 0, modeflag, resindex, xres;
++
++ if (ModeNo > 0x13) {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++ }
++ else
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
++
++ if (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31) & 0x01)
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
++
++ if (ModeNo > 0x13)
++ data = infoflag;
++ else
++ data = 0;
++
++ data2 = 0;
++
++ if (ModeNo > 0x13) {
++ if (pVBInfo->ModeType > 0x02) {
++ data2 |= 0x02;
++ data3 = pVBInfo->ModeType - ModeVGA;
++ data3 = data3 << 2;
++ data2 |= data3;
++ }
++ }
++
++ data &= InterlaceMode;
++
++ if (data)
++ data2 |= 0x20;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x06, ~0x3F, data2);
++ /* XGI_SetReg((XGIIOADDRESS)pVBInfo->P3c4,0x06,data2); */
++ resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
++ if (ModeNo <= 0x13)
++ xres = pVBInfo->StResInfo[resindex].HTotal;
++ else
++ xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
++
++ data = 0x0000;
++ if (infoflag & InterlaceMode) {
++ if (xres == 1024)
++ data = 0x0035;
++ else if (xres == 1280)
++ data = 0x0048;
++ }
++
++ data2 = data & 0x00FF;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFF, data2);
++ data2 = (data & 0xFF00) >> 8;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x19, 0xFC, data2);
++
++ if (modeflag & HalfDCLK)
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xF7, 0x08);
++
++ data2 = 0;
++
++ if (modeflag & LineCompareOff)
++ data2 |= 0x08;
++
++ if (ModeNo > 0x13) {
++ if (pVBInfo->ModeType == ModeEGA)
++ data2 |= 0x40;
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x0F, ~0x48, data2);
++ data = 0x60;
++ if (pVBInfo->ModeType != ModeText) {
++ data = data ^ 0x60;
++ if (pVBInfo->ModeType != ModeEGA) {
++ data = data ^ 0xA0;
++ }
++ }
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x21, 0x1F, data);
++
++ XGI_SetVCLKState(HwDeviceExtension, ModeNo, RefreshRateTableIndex,
++ pVBInfo);
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
++
++ /* Jong 10/04/2007; merge code */
++ if (HwDeviceExtension->jChipType == XG27 )
++ {
++ if ( data & 0x40 )
++ data = 0x2c ;
++ else
++ data = 0x6c ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x52 , data ) ;
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x51 , 0x10 ) ;
++ }
++ else if (HwDeviceExtension->jChipType >= XG20)
++ {
++ if (data & 0x40)
++ data = 0x33;
++ else
++ data = 0x73;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x51, 0x02);
++ }
++ else {
++ if (data & 0x40)
++ data = 0x2c;
++ else
++ data = 0x6c;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x52, data);
++ }
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetVCLKState */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetVCLKState(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data, data2 = 0;
++ SHORT VCLK;
++
++ UCHAR index;
++
++ if (ModeNo <= 0x13)
++ VCLK = 0;
++ else {
++ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
++ index &= IndexMask;
++ VCLK = pVBInfo->VCLKData[index].CLOCK;
++ }
++
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
++ data &= 0xf3;
++ if (VCLK >= 200)
++ data |= 0x0c; /* VCLK > 200 */
++
++ /* Jong 10/04/2007; merge code */
++ if (HwDeviceExtension->jChipType >= XG20)
++ data &= ~0x04; /* 2 pixel mode */
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, data);
++
++ /* Jong 10/04/2007; merge code */
++ if (HwDeviceExtension->jChipType < XG20) {
++ data = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
++ data &= 0xE7;
++ if (VCLK < 200)
++ data |= 0x10;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, data);
++ }
++
++ /* Jong for Adavantech LCD ripple issue
++ if ((VCLK >= 0) && (VCLK < 135))
++ data2 = 0x03;
++ else if ((VCLK >= 135) && (VCLK < 160))
++ data2 = 0x02;
++ else if ((VCLK >= 160) && (VCLK < 260))
++ data2 = 0x01;
++ else if (VCLK > 260)
++ data2 = 0x00; */
++
++ data2 = 0x00 ;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x07, 0xFC, data2);
++
++ /* Jong 10/04/2007; merge code */
++ if (HwDeviceExtension->jChipType >= XG27 )
++ {
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x40 , 0xFC , data2&0x03 ) ;
++ }
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_LoadDAC */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_LoadDAC(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT data, data2, time, i, j, k, m, n, o, si, di, bx, dl, al, ah, dh;
++ const uint8_t *table = NULL;
++
++ if (ModeNo <= 0x13)
++ data = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ else
++ data = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++
++ data &= DACInfoFlag;
++ time = 64;
++
++ if (data == 0x00)
++ table = XGI_MDA_DAC;
++ else if (data == 0x08)
++ table = XGI_CGA_DAC;
++ else if (data == 0x10)
++ table = XGI_EGA_DAC;
++ else if (data == 0x18) {
++ time = 256;
++ table = XGI_VGA_DAC;
++ }
++
++ if (time == 256)
++ j = 16;
++ else
++ j = time;
++
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c6, 0xFF);
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
++
++ for (i = 0; i < j; i++) {
++ data = table[i];
++
++ for (k = 0; k < 3; k++) {
++ data2 = 0;
++
++ if (data & 0x01)
++ data2 = 0x2A;
++
++ if (data & 0x02)
++ data2 += 0x15;
++
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data2);
++ data = data >> 2;
++ }
++ }
++
++ if (time == 256) {
++ for (i = 16; i < 32; i++) {
++ data = table[i];
++
++ for (k = 0; k < 3; k++)
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c9, data);
++ }
++
++ si = 32;
++
++ for (m = 0; m < 9; m++) {
++ di = si;
++ bx = si + 0x04;
++ dl = 0;
++
++ for (n = 0; n < 3; n++) {
++ for (o = 0; o < 5; o++) {
++ dh = table[si];
++ ah = table[di];
++ al = table[bx];
++ si++;
++ XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
++ ah, al, dh);
++ }
++
++ si -= 2;
++
++ for (o = 0; o < 3; o++) {
++ dh = table[bx];
++ ah = table[di];
++ al = table[si];
++ si--;
++ XGI_WriteDAC((XGIIOADDRESS) pVBInfo->P3c9, 0, dl,
++ ah, al, dh);
++ }
++
++ dl++;
++ }
++
++ si += 5;
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_WriteDAC */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift, unsigned ordering,
++ uint8_t ah, uint8_t al, uint8_t dh)
++{
++ USHORT temp, bh, bl;
++
++ if (shift) {
++ ah <<= 2;
++ al <<= 2;
++ dh <<= 2;
++ }
++
++ bh = ah;
++ bl = al;
++
++ if (ordering != 0) {
++ temp = bh;
++ bh = dh;
++ dh = temp;
++ if (ordering == 1) {
++ temp = bl;
++ bl = dh;
++ dh = temp;
++ }
++ else {
++ temp = bl;
++ bl = bh;
++ bh = temp;
++ }
++ }
++ XGI_SetRegByte(dac_data, dh);
++ XGI_SetRegByte(dac_data, bh);
++ XGI_SetRegByte(dac_data, bl);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLCDAGroup */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLCDAGroup(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT RefreshRateTableIndex;
++ /* USHORT temp ; */
++
++ /* pVBInfo->SelectCRT2Rate = 0 ; */
++
++ pVBInfo->SetFlag |= ProgrammingCRT2;
++ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
++ XGI_GetLVDSResInfo(ModeNo, ModeIdIndex, pVBInfo);
++ XGI_GetLVDSData(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
++ XGI_ModCRT1Regs(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ HwDeviceExtension, pVBInfo);
++ XGI_SetLVDSRegs(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
++ XGI_SetCRT2ECLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
++}
++
++
++/**
++ * Get LVDS resolution information.
++ */
++void
++XGI_GetLVDSResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ unsigned xres;
++ unsigned yres;
++
++
++ get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
++
++ if (xres == 720)
++ xres = 640;
++
++ pVBInfo->VGAHDE = xres;
++ pVBInfo->HDE = xres;
++ pVBInfo->VGAVDE = yres;
++ pVBInfo->VDE = yres;
++}
++
++
++static void
++get_HDE_VDE(PVB_DEVICE_INFO pVBInfo, USHORT *HDE, USHORT *VDE)
++{
++ switch (pVBInfo->LCDResInfo) {
++ case Panel1024x768:
++ case Panel1024x768x75:
++ *HDE = 1024;
++ *VDE = 768;
++ break;
++
++ case Panel1280x1024:
++ case Panel1280x1024x75:
++ *HDE = 1280;
++ *VDE = 1024;
++ break;
++
++ case Panel1400x1050:
++ *HDE = 1400;
++ *VDE = 1050;
++ break;
++
++ default:
++ *HDE = 1600;
++ *VDE = 1200;
++ break;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetLVDSData */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetLVDSData(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx;
++ XGI330_LVDSDataStruct *LCDPtr = NULL;
++
++ tempbx = 2;
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ LCDPtr =
++ (XGI330_LVDSDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
++ ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ pVBInfo->VGAHT = LCDPtr->VGAHT;
++ pVBInfo->VGAVT = LCDPtr->VGAVT;
++ pVBInfo->HT = LCDPtr->LCDHT;
++ pVBInfo->VT = LCDPtr->LCDVT;
++ }
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD))) {
++ get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_ModCRT1Regs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_ModCRT1Regs(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR index;
++ USHORT tempbx, i;
++ XGI_LVDSCRT1HDataStruct *LCDPtr = NULL;
++ XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL;
++ /* XGI330_CHTVDataStruct *TVPtr = NULL ; */
++
++ if (ModeNo <= 0x13)
++ index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ else
++ index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++
++ index = index & IndexMask;
++
++ if ((pVBInfo->IF_DEF_ScaleLCD == 0)
++ || ((pVBInfo->IF_DEF_ScaleLCD == 1)
++ && (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
++ tempbx = 0;
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ LCDPtr =
++ (XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
++ ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++
++ for (i = 0; i < 8; i++)
++ pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i];
++ }
++
++ XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension);
++
++ tempbx = 1;
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ LCDPtr1 =
++ (XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
++ ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ for (i = 0; i < 7; i++)
++ pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i];
++ }
++
++ XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo);
++ }
++}
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLVDSRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLVDSRegs(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, tempax, tempcx, tempdx, push1, push2, modeflag;
++ unsigned long temp, temp1, temp2, temp3, push3;
++ XGI330_LCDDataDesStruct *LCDPtr = NULL;
++ XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
++
++ if (ModeNo > 0x13)
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ else
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++
++ if (!(pVBInfo->SetFlag & Win9xDOSMode)) {
++ if (pVBInfo->IF_DEF_OEMUtil == 1) {
++ tempbx = 8;
++ LCDPtr =
++ (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
++ ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ }
++
++ if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == 0)) {
++ tempbx = 3;
++ if (pVBInfo->LCDInfo & EnableScalingLCD)
++ LCDPtr1 =
++ (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(tempbx, ModeNo,
++ ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ else
++ LCDPtr =
++ (XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(tempbx, ModeNo,
++ ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ }
++
++ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
++ push1 = tempbx;
++ push2 = tempax;
++
++ /* GetLCDResInfo */
++ if (pVBInfo->LCDInfo & SetLCDtoNonExpanding) {
++ get_HDE_VDE(pVBInfo, & pVBInfo->HDE, & pVBInfo->VDE);
++
++ pVBInfo->VGAHDE = pVBInfo->HDE;
++ pVBInfo->VGAVDE = pVBInfo->VDE;
++ }
++
++ tempax = pVBInfo->HT;
++
++ tempbx = (pVBInfo->LCDInfo & EnableScalingLCD)
++ ? LCDPtr1->LCDHDES : LCDPtr->LCDHDES;
++
++ tempcx = pVBInfo->HDE;
++ tempbx = tempbx & 0x0fff;
++ tempcx += tempbx;
++
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, tempbx & 0x07);
++
++ tempcx = tempcx >> 3;
++ tempbx = tempbx >> 3;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16,
++ (USHORT) (tempbx & 0xff));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17,
++ (USHORT) (tempcx & 0xff));
++
++ tempax = pVBInfo->HT;
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD)
++ tempbx = LCDPtr1->LCDHRS;
++ else
++ tempbx = LCDPtr->LCDHRS;
++
++ tempcx = push2;
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD)
++ tempcx = LCDPtr1->LCDHSync;
++
++ tempcx += tempbx;
++
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ /* FIXME: Won't this *always* set tempax to zero? */
++ tempax = tempbx & 0x07;
++ tempax = tempax >> 5;
++ tempcx = tempcx >> 3;
++ tempbx = tempbx >> 3;
++
++ tempcx &= 0x1f;
++ tempax |= tempcx;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x15, tempax);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x14,
++ (USHORT) (tempbx & 0xff));
++
++ tempax = pVBInfo->VT;
++ if (pVBInfo->LCDInfo & EnableScalingLCD)
++ tempbx = LCDPtr1->LCDVDES;
++ else
++ tempbx = LCDPtr->LCDVDES;
++ tempcx = pVBInfo->VDE;
++
++ tempbx = tempbx & 0x0fff;
++ tempcx += tempbx;
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1b,
++ (USHORT) (tempbx & 0xff));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1c,
++ (USHORT) (tempcx & 0xff));
++
++ tempbx = (tempbx >> 8) & 0x07;
++ tempcx = (tempcx >> 8) & 0x07;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1d,
++ (USHORT) ((tempcx << 3) | tempbx));
++
++ tempax = pVBInfo->VT;
++ if (pVBInfo->LCDInfo & EnableScalingLCD)
++ tempbx = LCDPtr1->LCDVRS;
++ else
++ tempbx = LCDPtr->LCDVRS;
++
++ /* tempbx = tempbx >> 4 ; */
++ tempcx = push1;
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD)
++ tempcx = LCDPtr1->LCDVSync;
++
++ tempcx += tempbx;
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18,
++ (USHORT) (tempbx & 0xff));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, ~0x0f,
++ (USHORT) (tempcx & 0x0f));
++
++ tempax = ((tempbx >> 8) & 0x07) << 3;
++
++ tempbx = pVBInfo->VGAVDE;
++ if (tempbx != pVBInfo->VDE)
++ tempax |= 0x40;
++
++ if (pVBInfo->LCDInfo & EnableLVDSDDA)
++ tempax |= 0x40;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1a, 0x07,
++ tempax);
++
++ tempcx = pVBInfo->VGAVT;
++ tempbx = pVBInfo->VDE;
++ tempax = pVBInfo->VGAVDE;
++ tempcx -= tempax;
++
++ temp = tempax; /* 0430 ylshieh */
++ temp1 = (temp << 18) / tempbx;
++
++ tempdx = (USHORT) ((temp << 18) % tempbx);
++
++ if (tempdx != 0)
++ temp1 += 1;
++
++ temp2 = temp1;
++ push3 = temp2;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x37,
++ (USHORT) (temp2 & 0xff));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x36,
++ (USHORT) ((temp2 >> 8) & 0xff));
++
++ tempbx = (USHORT) (temp2 >> 16);
++ tempax = tempbx & 0x03;
++
++ tempbx = pVBInfo->VGAVDE;
++ if (tempbx == pVBInfo->VDE)
++ tempax |= 0x04;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x35, tempax);
++
++ if (pVBInfo->VBType & VB_XGI301C) {
++ temp2 = push3;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3c,
++ (USHORT) (temp2 & 0xff));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x3b,
++ (USHORT) ((temp2 >> 8) & 0xff));
++ tempbx = (USHORT) (temp2 >> 16);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x3a, ~0xc0,
++ (USHORT) ((tempbx & 0xff) << 6));
++
++ tempcx = pVBInfo->VGAVDE;
++ if (tempcx == pVBInfo->VDE)
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
++ ~0x0c, 0x00);
++ else
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30,
++ ~0x0c, 0x08);
++ }
++
++ tempcx = pVBInfo->VGAHDE;
++ tempbx = pVBInfo->HDE;
++
++ temp1 = tempcx << 16;
++
++ tempax = (USHORT) (temp1 / tempbx);
++
++ if ((tempbx & 0xffff) == (tempcx & 0xffff))
++ tempax = 65535;
++
++ temp3 = tempax;
++ temp1 = pVBInfo->VGAHDE << 16;
++
++ temp1 /= temp3;
++ temp3 = temp3 << 16;
++ temp1 -= 1;
++
++ temp3 = (temp3 & 0xffff0000) + (temp1 & 0xffff);
++
++ tempax = (USHORT) (temp3 & 0xff);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1f, tempax);
++
++ temp1 = pVBInfo->VGAVDE << 18;
++ temp1 = temp1 / push3;
++ tempbx = (USHORT) (temp1 & 0xffff);
++
++ if (pVBInfo->LCDResInfo == Panel1024x768)
++ tempbx -= 1;
++
++ tempax = ((tempbx >> 8) & 0xff) << 3;
++ tempax |= (USHORT) ((temp3 >> 8) & 0x07);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x20,
++ (USHORT) (tempax & 0xff));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x21,
++ (USHORT) (tempbx & 0xff));
++
++ temp3 = temp3 >> 16;
++
++ if (modeflag & HalfDCLK)
++ temp3 = temp3 >> 1;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x22,
++ (USHORT) ((temp3 >> 8) & 0xff));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x23,
++ (USHORT) (temp3 & 0xff));
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT2ECLK */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT2ECLK(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR di[2];
++ int i;
++ const unsigned vclkindex =
++ XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
++
++ XGI_GetVCLKLen(vclkindex, di, pVBInfo);
++ XGI_GetLCDVCLKPtr(di, pVBInfo);
++
++ for (i = 0; i < 4; i++) {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, ~0x30,
++ (USHORT) (0x10 * i));
++ if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
++ && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2e, di[0]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2f, di[1]);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2b, di[0]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2c, di[1]);
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_UpdateModeInfo */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_UpdateModeInfo(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempcl, tempch, temp, tempbl, tempax;
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ tempcl = 0;
++ tempch = 0;
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
++
++ if (!(temp & 0x20)) {
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
++ if (temp & 0x80) {
++ /* Jong 10/04/2007; merge code */
++ if ((HwDeviceExtension->jChipType >= XG20)
++ || (HwDeviceExtension->jChipType >= XG40))
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53);
++ else
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
++
++ if (!(temp & 0x40))
++ tempcl |= ActiveCRT1;
++ }
++ }
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e);
++ temp &= 0x0f;
++
++ if (!(temp == 0x08)) {
++ tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
++ if (tempax & 0x04)
++ tempcl = tempcl | ActiveLCD;
++
++ temp &= 0x05;
++
++ if (!(tempcl & ActiveLCD))
++ if (temp == 0x01)
++ tempcl |= ActiveCRT2;
++
++ if (temp == 0x04)
++ tempcl |= ActiveLCD;
++
++ if (temp == 0x05) {
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x00);
++
++ if (!(temp & 0x08))
++ tempch |= ActiveAVideo;
++
++ if (!(temp & 0x04))
++ tempch |= ActiveSVideo;
++
++ if (temp & 0x02)
++ tempch |= ActiveSCART;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (temp & 0x01)
++ tempch |= ActiveHiTV;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
++ temp =
++ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d);
++
++ if (temp & 0x10)
++ tempch |= ActiveYPbPr;
++ }
++
++ if (tempch != 0)
++ tempcl |= ActiveTV;
++ }
++ }
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3d);
++ if (tempcl & ActiveLCD) {
++ if ((pVBInfo->SetFlag & ReserveTVOption)) {
++ if (temp & ActiveTV)
++ tempcl |= ActiveTV;
++ }
++ }
++ temp = tempcl;
++ tempbl = ~ModeSwitchStatus;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x3d, tempbl, temp);
++
++ if (!(pVBInfo->SetFlag & ReserveTVOption))
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3e, tempch);
++ }
++ else {
++ return;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetVBType */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetVBType(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT flag, tempbx, tempah;
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ tempbx = VB_XGI302B;
++ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
++ if (flag != 0x02) {
++ tempbx = VB_XGI301;
++ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x01);
++ if (flag >= 0xB0) {
++ tempbx = VB_XGI301B;
++ if (flag >= 0xC0) {
++ tempbx = VB_XGI301C;
++ if (flag >= 0xD0) {
++ tempbx = VB_XGI301LV;
++ if (flag >= 0xE0) {
++ tempbx = VB_XGI302LV;
++ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port,
++ 0x39);
++ if (tempah != 0xFF)
++ tempbx = VB_XGI301C;
++ }
++ }
++ }
++
++ if (tempbx & (VB_XGI301B | VB_XGI302B)) {
++ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x23);
++
++ if (!(flag & 0x02))
++ tempbx = tempbx | VB_NoLCD;
++ }
++ }
++ }
++
++ pVBInfo->VBType = tempbx;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetVBInfo */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetVBInfo(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, push, tempbx, temp, modeflag;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ pVBInfo->SetFlag = 0;
++ pVBInfo->ModeType = modeflag & ModeInfoFlag;
++ tempbx = 0;
++
++ if (pVBInfo->VBType & 0xFFFF) {
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x30); /* Check Display Device */
++ tempbx = tempbx | temp;
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x31);
++ push = temp;
++ push = push << 8;
++ tempax = temp << 8;
++ tempbx = tempbx | tempax;
++ temp =
++ (SetCRT2ToDualEdge | SetCRT2ToYPbPr | SetCRT2ToLCDA |
++ SetInSlaveMode | DisableCRT2Display);
++ temp = 0xFFFF ^ temp;
++ tempbx &= temp;
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x38);
++
++ if (pVBInfo->IF_DEF_LCDA == 1) {
++ /* if ( ( pVBInfo->VBType & VB_XGI302B ) || ( pVBInfo->VBType & VB_XGI301LV ) || ( pVBInfo->VBType & VB_XGI302LV ) || ( pVBInfo->VBType & VB_XGI301C ) ) */
++ if (pVBInfo->
++ VBType & (VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (temp & EnableDualEdge) {
++ tempbx |= SetCRT2ToDualEdge;
++
++ if (temp & SetToLCDA)
++ tempbx |= SetCRT2ToLCDA;
++ }
++ }
++ }
++
++ if (pVBInfo->IF_DEF_YPbPr == 1) {
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV)
++ || (pVBInfo->VBType & VB_XGI301C)) {
++ if (temp & SetYPbPr) { /* temp = CR38 */
++ if (pVBInfo->IF_DEF_HiVision == 1) {
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35); /* shampoo add for new scratch */
++ temp &= YPbPrMode;
++ tempbx |= SetCRT2ToHiVisionTV;
++
++ if (temp != YPbPrMode1080i) {
++ tempbx &= (~SetCRT2ToHiVisionTV);
++ tempbx |= SetCRT2ToYPbPr;
++ }
++ }
++
++ /* tempbx |= SetCRT2ToYPbPr ; */
++ }
++ }
++ }
++
++ tempax = push; /* restore CR31 */
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ if (pVBInfo->IF_DEF_YPbPr == 1) {
++ if (pVBInfo->IF_DEF_HiVision == 1)
++ temp = 0x09FC;
++ else
++ temp = 0x097C;
++ }
++ else {
++ if (pVBInfo->IF_DEF_HiVision == 1)
++ temp = 0x01FC;
++ else
++ temp = 0x017C;
++ }
++ }
++ else /* 3nd party chip */
++ {
++ if ( pVBInfo->IF_DEF_CH7017 == 1 )
++ temp = ( SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA ) ;
++ else if ( pVBInfo->IF_DEF_CH7007 == 1 ) /* [Billy] 07/05/03 */
++ {
++ temp = SetCRT2ToTV ;
++ }
++ else
++ temp = SetCRT2ToLCD ;
++ }
++
++
++ if (!(tempbx & temp)) {
++ tempax |= DisableCRT2Display;
++ tempbx = 0;
++ }
++
++ if (pVBInfo->IF_DEF_LCDA == 1) { /* Select Display Device */
++ if (!(pVBInfo->VBType & VB_NoLCD)) {
++ if (tempbx & SetCRT2ToLCDA) {
++ if (tempbx & SetSimuScanMode)
++ tempbx &=
++ (~
++ (SetCRT2ToLCD | SetCRT2ToRAMDAC | SwitchToCRT2));
++ else
++ tempbx &=
++ (~
++ (SetCRT2ToLCD | SetCRT2ToRAMDAC | SetCRT2ToTV |
++ SwitchToCRT2));
++ }
++ }
++ }
++
++ /* shampoo add */
++ if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
++ if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
++ if (tempbx & SetCRT2ToRAMDAC) {
++ tempbx &=
++ (0xFF00 | SetCRT2ToRAMDAC | SwitchToCRT2 |
++ SetSimuScanMode);
++ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
++ }
++ }
++ else
++ tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV));
++ }
++
++ if (!(pVBInfo->VBType & VB_NoLCD)) {
++ if (tempbx & SetCRT2ToLCD) {
++ tempbx &=
++ (0xFF00 | SetCRT2ToLCD | SwitchToCRT2 | SetSimuScanMode);
++ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
++ }
++ }
++
++ if (tempbx & SetCRT2ToSCART) {
++ tempbx &=
++ (0xFF00 | SetCRT2ToSCART | SwitchToCRT2 | SetSimuScanMode);
++ tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
++ }
++
++ if (pVBInfo->IF_DEF_YPbPr == 1) {
++ if (tempbx & SetCRT2ToYPbPr)
++ tempbx &= (0xFF00 | SwitchToCRT2 | SetSimuScanMode);
++ }
++
++ if (pVBInfo->IF_DEF_HiVision == 1) {
++ if (tempbx & SetCRT2ToHiVisionTV)
++ tempbx &=
++ (0xFF00 | SetCRT2ToHiVisionTV | SwitchToCRT2 |
++ SetSimuScanMode);
++ }
++
++ if (tempax & DisableCRT2Display) { /* Set Display Device Info */
++ if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode)))
++ tempbx = DisableCRT2Display;
++ }
++
++ if (!(tempbx & DisableCRT2Display)) {
++ if ((!(tempbx & DriverMode)) || (!(modeflag & CRT2Mode))) {
++ if (pVBInfo->IF_DEF_LCDA == 1) {
++ if (!(tempbx & SetCRT2ToLCDA))
++ tempbx |= (SetInSlaveMode | SetSimuScanMode);
++ }
++
++ if (pVBInfo->IF_DEF_VideoCapture == 1) {
++ if ((HwDeviceExtension->jChipType >= XG40)
++ && (HwDeviceExtension->jChipType <= XG45)) {
++ if (ModeNo <= 13) {
++ /* CRT2 not need to support */
++ if (!(tempbx & SetCRT2ToRAMDAC)) {
++ tempbx &= (0x00FF | (~SetInSlaveMode));
++ pVBInfo->SetFlag |= EnableVCMode;
++ }
++ }
++ }
++ }
++ }
++
++ /*LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
++ if ((tempbx & SetInSlaveMode) && (tempbx & SetCRT2ToLCDA)) {
++ tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToDualEdge);
++ pVBInfo->SetFlag |= ReserveTVOption;
++ }
++ }
++ }
++
++ pVBInfo->VBInfo = tempbx;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetTVInfo */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetTVInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp, tempbx = 0, resinfo = 0, modeflag, index1;
++
++ tempbx = 0;
++ resinfo = 0;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
++ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
++ tempbx = temp;
++ if (tempbx & SetPALTV) {
++ tempbx &=
++ (SetCHTVOverScan | SetPALMTV | SetPALNTV | SetPALTV);
++ if (tempbx & SetPALMTV)
++ tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
++ }
++ else
++ tempbx &= (SetCHTVOverScan | SetNTSCJ | SetPALTV);
++ }
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ if (pVBInfo->VBInfo & SetCRT2ToSCART)
++ tempbx |= SetPALTV;
++ }
++
++ if (pVBInfo->IF_DEF_YPbPr == 1) {
++ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
++ index1 = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x35);
++ index1 &= YPbPrMode;
++
++ if (index1 == YPbPrMode525i)
++ tempbx |= SetYPbPrMode525i;
++
++ if (index1 == YPbPrMode525p)
++ tempbx = tempbx | SetYPbPrMode525p;
++ if (index1 == YPbPrMode750p)
++ tempbx = tempbx | SetYPbPrMode750p;
++ }
++ }
++
++ if (pVBInfo->IF_DEF_HiVision == 1) {
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ tempbx = tempbx | SetYPbPrMode1080i | SetPALTV;
++ }
++ }
++
++ /* Jong 10/17/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ if ((pVBInfo->VBInfo & SetInSlaveMode)
++ && (!(pVBInfo->VBInfo & SetNotSimuMode)))
++ tempbx |= TVSimuMode;
++
++ if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo == 8)) /* NTSC 1024x768, */
++ tempbx |= NTSC1024x768;
++
++ tempbx |= RPLLDIV2XO;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (pVBInfo->VBInfo & SetInSlaveMode)
++ tempbx &= (~RPLLDIV2XO);
++ }
++ else {
++ if (tempbx & (SetYPbPrMode525p | SetYPbPrMode750p))
++ tempbx &= (~RPLLDIV2XO);
++ else if (!
++ (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV |
++ VB_XGI302LV | VB_XGI301C))) {
++ if (tempbx & TVSimuMode)
++ tempbx &= (~RPLLDIV2XO);
++ }
++ }
++ }
++ }
++ pVBInfo->TVInfo = tempbx;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetLCDInfo */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_GetLCDInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp, tempax, tempbx, modeflag, resinfo = 0, LCDIdIndex;
++
++ pVBInfo->LCDResInfo = 0;
++ pVBInfo->LCDTypeInfo = 0;
++ pVBInfo->LCDInfo = 0;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo// */
++ }
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
++ tempbx = temp & 0x0F;
++
++ if (tempbx == 0)
++ tempbx = Panel1024x768; /* default */
++
++ /* LCD75 [2003/8/22] Vicent */
++ if ((tempbx == Panel1024x768) || (tempbx == Panel1280x1024)) {
++ if (pVBInfo->VBInfo & DriverMode) {
++ tempax = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x33);
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
++ tempax &= 0x0F;
++ else
++ tempax = tempax >> 4;
++
++ if ((resinfo == 6) || (resinfo == 9)) {
++ if (tempax >= 3)
++ tempbx |= PanelRef75Hz;
++ }
++ else if ((resinfo == 7) || (resinfo == 8)) {
++ if (tempax >= 4)
++ tempbx |= PanelRef75Hz;
++ }
++ }
++ }
++
++ pVBInfo->LCDResInfo = tempbx;
++
++ /* End of LCD75 */
++
++ if (pVBInfo->IF_DEF_OEMUtil == 1) {
++ pVBInfo->LCDTypeInfo = (temp & 0xf0) >> 4;
++ }
++
++ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
++ return 0;
++ }
++
++ tempbx = 0;
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
++
++ temp &= (ScalingLCD | LCDNonExpanding | LCDSyncBit | SetPWDEnable);
++
++ if ((pVBInfo->IF_DEF_ScaleLCD == 1) && (temp & LCDNonExpanding))
++ temp &= ~EnableScalingLCD;
++
++ tempbx |= temp;
++
++ LCDIdIndex = XGI_GetLCDCapPtr1(pVBInfo);
++
++ tempax = pVBInfo->LCDCapList[LCDIdIndex].LCD_Capability;
++
++ /* Jong 10/17/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 ) /* shampoo */
++ {
++ if (((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C))
++ && (tempax & LCDDualLink)) {
++ tempbx |= SetLCDDualLink;
++ }
++ }
++
++ /* Jong 10/17/1007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ if ((pVBInfo->LCDResInfo == Panel1400x1050)
++ && (pVBInfo->VBInfo & SetCRT2ToLCD) && (ModeNo > 0x13)
++ && (resinfo == 9) && (!(tempbx & EnableScalingLCD)))
++ tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
++ }
++
++/*
++ if ( tempax & LCDBToA )
++ {
++ tempbx |= SetLCDBToA ;
++ }
++*/
++
++ if (pVBInfo->IF_DEF_ExpLink == 1) {
++ if (modeflag & HalfDCLK) {
++ /* if ( !( pVBInfo->LCDInfo&LCDNonExpanding ) ) */
++ if (!(tempbx & SetLCDtoNonExpanding)) {
++ tempbx |= EnableLVDSDDA;
++ }
++ else {
++ if (ModeNo > 0x13) {
++ if (pVBInfo->LCDResInfo == Panel1024x768) {
++ if (resinfo == 4) { /* 512x384 */
++ tempbx |= EnableLVDSDDA;
++ }
++ }
++ }
++ }
++ }
++ }
++
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (pVBInfo->VBInfo & SetNotSimuMode) {
++ tempbx |= LCDVESATiming;
++ }
++ }
++ else {
++ tempbx |= LCDVESATiming;
++ }
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x39);
++ if (temp & ReduceTiming) {
++ tempbx |= EnableReduceTiming;
++ }
++
++ pVBInfo->LCDInfo = tempbx;
++
++ if (pVBInfo->IF_DEF_PWD == 1) {
++ if (pVBInfo->LCDInfo & SetPWDEnable) {
++ if ((pVBInfo->VBType & VB_XGI302LV)
++ || (pVBInfo->VBType & VB_XGI301C)) {
++ if (!(tempax & PWDEnable)) {
++ pVBInfo->LCDInfo &= ~SetPWDEnable;
++ }
++ }
++ }
++ }
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ if (tempax & (LockLCDBToA | StLCDBToA)) {
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (!(tempax & LockLCDBToA)) {
++ if (ModeNo <= 0x13) {
++ pVBInfo->VBInfo &=
++ ~(SetSimuScanMode | SetInSlaveMode |
++ SetCRT2ToLCD);
++ pVBInfo->VBInfo |= SetCRT2ToLCDA | SetCRT2ToDualEdge;
++ }
++ }
++ }
++ }
++ }
++
++ return (1);
++}
++
++/* Jong 10/04/2007; defined in init.c */
++/* Function : XGI_SearchModeID */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++
++/* --------------------------------------------------------------------- */
++/* Function : */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGINew_CheckMemorySize(PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,
++ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT memorysize, modeflag, temp, temp1, tmp;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ /* ModeType = modeflag&ModeInfoFlag ; // Get mode type */
++
++ memorysize = modeflag & MemoryInfoFlag;
++ memorysize = memorysize > MemorySizeShift;
++ memorysize++; /* Get memory size */
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x14); /* Get DRAM Size */
++ tmp = temp;
++
++ if (HwDeviceExtension->jChipType == XG40) {
++ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
++ if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
++ temp <<= 2;
++ }
++ else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
++ temp <<= 1;
++ }
++ }
++ else if (HwDeviceExtension->jChipType == XG42) {
++ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
++ if ((tmp & 0x04) == 0x04) { /* Dual channels */
++ temp <<= 1;
++ }
++ }
++ else if (HwDeviceExtension->jChipType == XG45) {
++ temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
++ if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
++ temp <<= 2;
++ }
++ else if ((tmp & 0x0c) == 0x08) { /* triple channels */
++ temp1 = temp;
++ temp <<= 1;
++ temp += temp1;
++ }
++ else if ((tmp & 0x0c) == 0x04) { /* Dual channels */
++ temp <<= 1;
++ }
++ }
++ if (temp < memorysize)
++ return (FALSE);
++ else
++ return (TRUE);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_DisplayOn */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_DisplayOn(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x00);
++
++ /* Jong 10/04/2007; merge code */
++ if ( HwDeviceExtension->jChipType == XG21 )
++ {
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ if (!(XGI_XG21GetPSCValue( pVBInfo )&0x1))
++ {
++ XGI_XG21BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
++ XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
++ }
++ if (!(XGI_XG21GetPSCValue( pVBInfo )&0x20))
++ {
++ XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
++ }
++ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
++ XGI_XG21BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
++ }
++ else
++ {
++ XGI_XG21BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
++ }
++
++ }
++
++ /* Jong 10/04/2007; merge code */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ if (!(XGI_XG27GetPSCValue( pVBInfo )&0x1))
++ {
++ XGI_XG27BLSignalVDD( 0x01 , 0x01, pVBInfo ) ; /* LVDS VDD on */
++ XGI_XG21SetPanelDelay( 2,pVBInfo ) ;
++ }
++ if (!(XGI_XG27GetPSCValue( pVBInfo )&0x20))
++ {
++ XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* LVDS signal on */
++ }
++ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
++ XGI_XG27BLSignalVDD( 0x02 , 0x02, pVBInfo ) ; /* LVDS backlight on */
++ }
++ else
++ {
++ XGI_XG27BLSignalVDD( 0x20 , 0x20, pVBInfo ) ; /* DVO/DVI signal on */
++ }
++ }
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_DisplayOff */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_DisplayOff(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ /* Jong 10/04/2007; merge code */
++ if ( HwDeviceExtension->jChipType == XG21 )
++ {
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ XGI_XG21BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
++ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
++ }
++ else
++ {
++ XGI_XG21BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
++ }
++ }
++
++ /* Jong 10/04/2007; merge code */
++ if ( HwDeviceExtension->jChipType == XG27 )
++ {
++ if ((XGI_XG27GetPSCValue( pVBInfo )&0x2))
++ {
++ XGI_XG27BLSignalVDD( 0x02 , 0x00, pVBInfo ) ; /* LVDS backlight off */
++ XGI_XG21SetPanelDelay( 3,pVBInfo ) ;
++ }
++
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ XGI_XG27BLSignalVDD( 0x20 , 0x00, pVBInfo ) ; /* DVO/DVI signal off */
++ }
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x01, 0xDF, 0x20);
++}
++
++
++/**
++ * Wait for vertical or horizontal blanking period.
++ */
++void
++XGI_WaitDisplay(PVB_DEVICE_INFO pVBInfo)
++{
++ while ((XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
++ break;
++
++ while (!(XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da) & 0x01))
++ break;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SenseCRT1 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++
++void
++XGI_SenseCRT1(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CRTCData[17] = { 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81,
++ 0x0B, 0x3E, 0xE9, 0x0B, 0xDF, 0xE7,
++ 0x04, 0x00, 0x00, 0x05, 0x00
++ };
++
++ UCHAR SR01 = 0, SR1F = 0, SR07 = 0, SR06 = 0;
++
++ UCHAR CR17, CR63, SR31;
++ USHORT temp;
++ UCHAR DAC_TEST_PARMS[3] = { 0x0F, 0x0F, 0x0F };
++
++ int i;
++#ifndef LINUX_XF86
++ int j;
++#endif
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x05, 0x86);
++
++ /* [2004/05/06] Vicent to fix XG42 single LCD sense to CRT+LCD */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x57, 0x4A);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
++ (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) |
++ 0x02));
++
++ SR31 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31);
++ CR63 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63);
++ SR01 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01);
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, (UCHAR) (SR01 & 0xDF));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, (UCHAR) (CR63 & 0xBF));
++
++ CR17 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x17, (UCHAR) (CR17 | 0x80));
++
++ SR1F = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x1F, (UCHAR) (SR1F | 0x04));
++
++ SR07 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x07, (UCHAR) (SR07 & 0xFB));
++ SR06 = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06, (UCHAR) (SR06 & 0xC3));
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x11, 0x00);
++
++ for (i = 0; i < 8; i++)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) i, CRTCData[i]);
++
++ for (i = 8; i < 11; i++)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 8),
++ CRTCData[i]);
++
++ for (i = 11; i < 13; i++)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, (USHORT) (i + 4),
++ CRTCData[i]);
++
++ for (i = 13; i < 16; i++)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, (USHORT) (i - 3),
++ CRTCData[i]);
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x0E,
++ (UCHAR) (CRTCData[16] & 0xE0));
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, 0x00);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2B, 0x1B);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x2C, 0xE1);
++
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
++ for (i = 0; i < 256; i++) {
++ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
++ (UCHAR) DAC_TEST_PARMS[0]);
++ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
++ (UCHAR) DAC_TEST_PARMS[1]);
++ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1),
++ (UCHAR) DAC_TEST_PARMS[2]);
++ }
++
++ XGI_VBLongWait(pVBInfo);
++ XGI_VBLongWait(pVBInfo);
++ XGI_VBLongWait(pVBInfo);
++
++ XGINew_LCD_Wait_Time(0x01, pVBInfo);
++ XGI_WaitDisplay(pVBInfo);
++
++ temp = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3c2);
++ if (temp & 0x10) {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x20);
++ }
++ else {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x32, 0xDF, 0x00);
++ }
++
++ /* alan, avoid display something, set BLACK DAC if not restore DAC */
++ XGI_SetRegByte((XGIIOADDRESS) pVBInfo->P3c8, 0x00);
++
++ for (i = 0; i < 256; i++) {
++ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
++ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
++ XGI_SetRegByte((XGIIOADDRESS) (USHORT) (pVBInfo->P3c8 + 1), 0);
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x01, SR01);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x63, CR63);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x31, SR31);
++
++ /* [2004/05/11] Vicent */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53,
++ (UCHAR) (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x53) &
++ 0xFD));
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++CheckDualChip(PVB_DEVICE_INFO pVBInfo)
++{
++ /* Check H/W trap that 2nd chip is present or not. */
++ return ((BOOLEAN)
++ (XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x3A) &
++ XGI_MASK_DUAL_CHIP));
++}
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : SetDualChipRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++SetDualChipRegs(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++
++#ifdef LINUX_XF86
++ USHORT BaseAddr2nd = (USHORT) (ULONG) HwDeviceExtension->pj2ndIOAddress;
++#else
++ USHORT BaseAddr2nd = (USHORT) HwDeviceExtension->pj2ndIOAddress;
++#endif
++ USHORT XGINew_P3CC = pVBInfo->BaseAddr + MISC_OUTPUT_REG_READ_PORT;
++ USHORT XGINew_2ndP3CE = BaseAddr2nd + GRAPH_ADDRESS_PORT;
++ USHORT XGINew_2ndP3C4 = BaseAddr2nd + SEQ_ADDRESS_PORT;
++ USHORT XGINew_2ndP3C2 = BaseAddr2nd + MISC_OUTPUT_REG_WRITE_PORT;
++ UCHAR tempal, i;
++ pVBInfo->BaseAddr = (USHORT) HwDeviceExtension->pjIOAddress;
++ for (i = 0x00; i <= 0x04; i++) { /* SR0 - SR4 */
++ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, i);
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, i, tempal);
++ }
++ for (i = 0x00; i <= 0x08; i++) { /* GR0 - GR8 */
++ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3ce, i);
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3CE, i, tempal);
++ }
++ /* OpenKey in 2nd chip */
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x86);
++
++ /* Copy SR06 to 2nd chip */
++ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x06);
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x06, tempal);
++
++ /* Copy SR21 to 2nd chip */
++ tempal = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x21);
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x21, tempal);
++
++ /* Miscellaneous reg(input port 3cch,output port 3c2h) */
++ tempal = (UCHAR) XGI_GetRegByte((XGIIOADDRESS) XGINew_P3CC); /* 3cc */
++ XGI_SetRegByte((XGIIOADDRESS) XGINew_2ndP3C2, tempal);
++
++ /* Close key in 2nd chip */
++ XGI_SetReg((XGIIOADDRESS) XGINew_2ndP3C4, 0x05, 0x00);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT2Group301 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, ModeIdIndex, RefreshRateTableIndex;
++ USHORT temp_mode_no;
++
++ tempbx = pVBInfo->VBInfo;
++ pVBInfo->SetFlag |= ProgrammingCRT2;
++
++ temp_mode_no = ModeNo;
++ XGI_SearchModeID(pVBInfo->SModeIDTable, pVBInfo->EModeIDTable, 0x11,
++ &temp_mode_no, &ModeIdIndex);
++
++
++ pVBInfo->SelectCRT2Rate = 4;
++ RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
++ XGI_SaveCRT2Info(ModeNo, pVBInfo);
++ XGI_GetCRT2ResInfo(ModeNo, ModeIdIndex, pVBInfo);
++ XGI_GetCRT2Data(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
++ XGI_PreSetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
++ RefreshRateTableIndex, pVBInfo);
++ XGI_SetGroup1(ModeNo, ModeIdIndex, HwDeviceExtension,
++ RefreshRateTableIndex, pVBInfo);
++ XGI_SetLockRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
++ RefreshRateTableIndex, pVBInfo);
++ XGI_SetGroup2(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ HwDeviceExtension, pVBInfo);
++ XGI_SetLCDRegs(ModeNo, ModeIdIndex, HwDeviceExtension,
++ RefreshRateTableIndex, pVBInfo);
++ XGI_SetTap4Regs(pVBInfo);
++ XGI_SetGroup3(ModeNo, ModeIdIndex, pVBInfo);
++ XGI_SetGroup4(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ HwDeviceExtension, pVBInfo);
++ XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
++ XGI_SetGroup5(ModeNo, ModeIdIndex, pVBInfo);
++ XGI_AutoThreshold(pVBInfo);
++ return 1;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_AutoThreshold */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_AutoThreshold(PVB_DEVICE_INFO pVBInfo)
++{
++ if (!(pVBInfo->SetFlag & Win9xDOSMode))
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x40);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SaveCRT2Info */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SaveCRT2Info(USHORT ModeNo, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp1, temp2;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
++ temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
++ temp2 = ~(SetInSlaveMode >> 8);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x31, temp2, temp1);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetCRT2ResInfo */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetCRT2ResInfo(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ unsigned xres;
++ unsigned yres;
++
++
++ get_mode_xres_yres(ModeNo, ModeIdIndex, pVBInfo, &xres, &yres);
++
++ if ((pVBInfo->VBInfo & SetCRT2ToLCD)
++ && !(pVBInfo->LCDInfo & (EnableScalingLCD | LCDNonExpanding))) {
++ switch (pVBInfo->LCDResInfo) {
++ case Panel1600x1200:
++ if (!(pVBInfo->LCDInfo & LCDVESATiming) && (yres == 1024)) {
++ yres = 1056;
++ }
++ break;
++
++
++ case Panel1280x1024:
++ if (yres == 400)
++ yres = 405;
++ else if (yres == 350)
++ yres = 360;
++ else if ((pVBInfo->LCDInfo & LCDVESATiming) && (yres == 360)) {
++ yres = 375;
++ }
++ break;
++
++
++ case Panel1024x768:
++ if (!(pVBInfo->LCDInfo & (LCDVESATiming | LCDNonExpanding))) {
++ if (yres == 350) {
++ yres = 357;
++ }
++ else if (yres == 400) {
++ yres = 420;
++ }
++ else if (yres == 480) {
++ yres = 525;
++ }
++ }
++
++ break;
++ }
++
++ if (xres == 720)
++ xres = 640;
++ }
++
++ pVBInfo->VGAHDE = xres;
++ pVBInfo->HDE = xres;
++ pVBInfo->VGAVDE = yres;
++ pVBInfo->VDE = yres;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_IsLCDDualLink */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_IsLCDDualLink(PVB_DEVICE_INFO pVBInfo)
++{
++ return (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) != 0)
++ && ((pVBInfo->LCDInfo & SetLCDDualLink) != 0));
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetCRT2Data */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetCRT2Data(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax = 0, tempbx, modeflag, resinfo;
++#ifndef LINUX_XF86
++ USHORT CRT2Index, ResIndex;
++#endif
++
++ XGI_LCDDataStruct *LCDPtr = NULL;
++ XGI_TVDataStruct *TVPtr = NULL;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
++
++ pVBInfo->NewFlickerMode = 0;
++ pVBInfo->RVBHRS = 50;
++
++ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
++ XGI_GetRAMDAC2DATA(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ pVBInfo);
++ return;
++ }
++
++ tempbx = 4;
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ LCDPtr =
++ (XGI_LCDDataStruct *) XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++
++ PDEBUG(ErrorF
++ ("C code setmode: ModeNo: 0x%08lX VGAHT:0x%081X \n", ModeNo,
++ LCDPtr->VGAHT));
++ pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX;
++ pVBInfo->RVBHCFACT = LCDPtr->RVBHCFACT;
++ pVBInfo->VGAHT = LCDPtr->VGAHT;
++ pVBInfo->VGAVT = LCDPtr->VGAVT;
++ pVBInfo->HT = LCDPtr->LCDHT;
++ pVBInfo->VT = LCDPtr->LCDVT;
++
++ if (pVBInfo->LCDResInfo == Panel1024x768) {
++ tempax = 1024;
++ tempbx = 768;
++
++ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
++ if (pVBInfo->VGAVDE == 357)
++ tempbx = 527;
++ else if (pVBInfo->VGAVDE == 420)
++ tempbx = 620;
++ else if (pVBInfo->VGAVDE == 525)
++ tempbx = 775;
++ else if (pVBInfo->VGAVDE == 600)
++ tempbx = 775;
++ /* else if(pVBInfo->VGAVDE==350) tempbx=560; */
++ /* else if(pVBInfo->VGAVDE==400) tempbx=640; */
++ else
++ tempbx = 768;
++ }
++ else
++ tempbx = 768;
++ }
++ else if (pVBInfo->LCDResInfo == Panel1024x768x75) {
++ tempax = 1024;
++ tempbx = 768;
++ }
++ else if (pVBInfo->LCDResInfo == Panel1280x1024) {
++ tempax = 1280;
++ if (pVBInfo->VGAVDE == 360)
++ tempbx = 768;
++ else if (pVBInfo->VGAVDE == 375)
++ tempbx = 800;
++ else if (pVBInfo->VGAVDE == 405)
++ tempbx = 864;
++ else
++ tempbx = 1024;
++ }
++ else if (pVBInfo->LCDResInfo == Panel1280x1024x75) {
++ tempax = 1280;
++ tempbx = 1024;
++ }
++ else if (pVBInfo->LCDResInfo == Panel1280x960) {
++ tempax = 1280;
++ if (pVBInfo->VGAVDE == 350)
++ tempbx = 700;
++ else if (pVBInfo->VGAVDE == 400)
++ tempbx = 800;
++ else if (pVBInfo->VGAVDE == 1024)
++ tempbx = 960;
++ else
++ tempbx = 960;
++ }
++ else if (pVBInfo->LCDResInfo == Panel1400x1050) {
++ tempax = 1400;
++ tempbx = 1050;
++
++ if (pVBInfo->VGAVDE == 1024) {
++ tempax = 1280;
++ tempbx = 1024;
++ }
++ }
++ else if (pVBInfo->LCDResInfo == Panel1600x1200) {
++ tempax = 1600;
++ tempbx = 1200; /* alan 10/14/2003 */
++ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
++ if (pVBInfo->VGAVDE == 350)
++ tempbx = 875;
++ else if (pVBInfo->VGAVDE == 400)
++ tempbx = 1000;
++ }
++ }
++
++ if (pVBInfo->LCDInfo & (LCDNonExpanding | EnableScalingLCD)) {
++ tempax = pVBInfo->VGAHDE;
++ tempbx = pVBInfo->VGAVDE;
++ }
++
++ pVBInfo->HDE = tempax;
++ pVBInfo->VDE = tempbx;
++ return;
++ }
++
++ if (pVBInfo->VBInfo & (SetCRT2ToTV)) {
++ tempbx = 4;
++ TVPtr =
++ (XGI_TVDataStruct *) XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex, pVBInfo);
++ pVBInfo->RVBHCMAX = TVPtr->RVBHCMAX;
++ pVBInfo->RVBHCFACT = TVPtr->RVBHCFACT;
++ pVBInfo->VGAHT = TVPtr->VGAHT;
++ pVBInfo->VGAVT = TVPtr->VGAVT;
++ pVBInfo->HDE = TVPtr->TVHDE;
++ pVBInfo->VDE = TVPtr->TVVDE;
++ pVBInfo->RVBHRS = TVPtr->RVBHRS;
++ pVBInfo->NewFlickerMode = TVPtr->FlickerMode;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (resinfo == 0x08)
++ pVBInfo->NewFlickerMode = 0x40;
++ else if (resinfo == 0x09)
++ pVBInfo->NewFlickerMode = 0x40;
++ else if (resinfo == 0x12)
++ pVBInfo->NewFlickerMode = 0x40;
++
++ if (pVBInfo->VGAVDE == 350)
++ pVBInfo->TVInfo |= TVSimuMode;
++
++ tempax = ExtHiTVHT;
++ tempbx = ExtHiTVVT;
++
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (pVBInfo->TVInfo & TVSimuMode) {
++ tempax = StHiTVHT;
++ tempbx = StHiTVVT;
++
++ if (!(modeflag & Charx8Dot)) {
++ tempax = StHiTextTVHT;
++ tempbx = StHiTextTVVT;
++ }
++ }
++ }
++ }
++ else if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
++ if (pVBInfo->TVInfo & SetYPbPrMode750p) {
++ tempax = YPbPrTV750pHT; /* Ext750pTVHT */
++ tempbx = YPbPrTV750pVT; /* Ext750pTVVT */
++ }
++
++ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
++ tempax = YPbPrTV525pHT; /* Ext525pTVHT */
++ tempbx = YPbPrTV525pVT; /* Ext525pTVVT */
++ }
++ else if (pVBInfo->TVInfo & SetYPbPrMode525i) {
++ tempax = YPbPrTV525iHT; /* Ext525iTVHT */
++ tempbx = YPbPrTV525iVT; /* Ext525iTVVT */
++ if (pVBInfo->TVInfo & NTSC1024x768)
++ tempax = NTSC1024x768HT;
++ }
++ }
++ else {
++ tempax = PALHT;
++ tempbx = PALVT;
++ if (!(pVBInfo->TVInfo & SetPALTV)) {
++ tempax = NTSCHT;
++ tempbx = NTSCVT;
++ if (pVBInfo->TVInfo & NTSC1024x768)
++ tempax = NTSC1024x768HT;
++ }
++ }
++
++ pVBInfo->HT = tempax;
++ pVBInfo->VT = tempbx;
++ return;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT2VCLK */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT2VCLK(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR di[2];
++ const unsigned vclkindex =
++ XGI_GetVCLKPtr(RefreshRateTableIndex, ModeNo, ModeIdIndex, pVBInfo);
++
++ XGI_GetVCLKLen(vclkindex, di, pVBInfo);
++ XGI_GetLCDVCLKPtr(di, pVBInfo);
++
++ if (pVBInfo->VBType & VB_XGI301) { /* shampoo 0129 *//* 301 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x10);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
++ }
++ else { /* 301b/302b/301lv/302lv */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, di[0]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, di[1]);
++ }
++
++ if ((pVBInfo->LCDInfo & EnableReduceTiming)
++ && (pVBInfo->LCDResInfo == Panel1600x1200)) {
++ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0A) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0A, 0x5A);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0B, 0x24);
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00, 0x12);
++
++ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x28);
++ else
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x12, 0x08);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GETLCDVCLKPtr */
++/* Input : */
++/* Output : al -> VCLK Index */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetLCDVCLKPtr(UCHAR *di, PVB_DEVICE_INFO pVBInfo)
++{
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ if ((pVBInfo->IF_DEF_ScaleLCD != 1)
++ || !(pVBInfo->LCDInfo & EnableScalingLCD)) {
++ const unsigned index = XGI_GetLCDCapPtr1(pVBInfo);
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCD) { /* LCDB */
++ di[0] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData1;
++ di[1] = pVBInfo->LCDCapList[index].LCUCHAR_VCLKData2;
++ }
++ else { /* LCDA */
++ di[0] = pVBInfo->LCDCapList[index].LCDA_VCLKData1;
++ di[1] = pVBInfo->LCDCapList[index].LCDA_VCLKData2;
++ }
++ }
++ }
++
++ return;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetVCLKPtr */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++unsigned
++XGI_GetVCLKPtr(USHORT RefreshRateTableIndex, USHORT ModeNo,
++ USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ unsigned vclk;
++ const unsigned modeflag = (ModeNo <= 0x13)
++ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
++ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++
++
++ if ((pVBInfo->SetFlag & ProgrammingCRT2)
++ && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
++ const unsigned index = XGI_GetLCDCapPtr(pVBInfo);
++ vclk = pVBInfo->LCDCapList[index].LCD_VCLK;
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
++ return vclk;
++
++ /* {TV} */
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (pVBInfo->TVInfo & TVSimuMode) {
++ vclk = (modeflag & Charx8Dot)
++ ? HiTVSimuVCLK : HiTVTextVCLK;
++ }
++ else {
++ vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
++ ? HiTVVCLKDIV2 : HiTVVCLK;
++ }
++
++ return vclk;
++ }
++ else if (pVBInfo->TVInfo & SetYPbPrMode750p) {
++ return YPbPr750pVCLK;
++ }
++ else if (pVBInfo->TVInfo & SetYPbPrMode525p) {
++ return YPbPr525pVCLK;
++ }
++
++ vclk = NTSC1024VCLK;
++
++ if (!(pVBInfo->TVInfo & NTSC1024x768)) {
++ vclk = (pVBInfo->TVInfo & RPLLDIV2XO)
++ ? TVVCLKDIV2 : TVVCLK;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV)
++ return vclk;
++ }
++ } /* {End of VB} */
++
++ vclk = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
++ vclk = (vclk >> 2) & 0x03;
++
++ /* for Dot8 Scaling LCD */
++ if ((pVBInfo->LCDInfo & EnableScalingLCD)
++ && (modeflag & Charx8Dot)
++ && ((pVBInfo->IF_DEF_VideoCapture) == 1)) {
++ vclk = VCLK25_175; /* ; set to VCLK25MHz always */
++ }
++
++ if (ModeNo <= 0x13)
++ return vclk;
++
++ return pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetVCLKLen */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetVCLKLen(unsigned vclkindex, UCHAR *di, PVB_DEVICE_INFO pVBInfo)
++{
++ if (pVBInfo->
++ VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B | VB_XGI301LV |
++ VB_XGI302LV | VB_XGI301C)) {
++ if ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
++ && (pVBInfo->SetFlag & ProgrammingCRT2)) {
++ di[0] = XGI_VBVCLKData[vclkindex].SR2B;
++ di[1] = XGI_VBVCLKData[vclkindex].SR2C;
++ }
++ }
++ else {
++ di[0] = XGI_VCLKData[vclkindex].SR2B;
++ di[1] = XGI_VCLKData[vclkindex].SR2C;
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT2Offset */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT2Offset(USHORT ModeNo,
++ USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT offset;
++ UCHAR temp;
++
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ return;
++ }
++
++ offset =
++ XGI_GetOffset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ HwDeviceExtension, pVBInfo);
++ temp = (UCHAR) (offset & 0xFF);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp);
++ temp = (UCHAR) ((offset & 0xFF00) >> 8);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, temp);
++ temp = (UCHAR) (((offset >> 3) & 0xFF) + 1);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetOffset */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetOffset(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp,
++ colordepth,
++ modeinfo, index, infoflag,
++ ColorDepth[] = { 0x01 , 0x02 , 0x04 } ;
++
++ modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo;
++ if (ModeNo <= 0x14)
++ infoflag = 0;
++ else
++ infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
++
++
++ index = (modeinfo >> 8) & 0xFF;
++
++ temp = pVBInfo->ScreenOffset[index];
++
++ if (infoflag & InterlaceMode) {
++ temp = temp << 1;
++ }
++
++ colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, pVBInfo);
++
++ /* Jong 10/04/2007; merge code */
++ if ( ( ModeNo >= 0x7C ) && ( ModeNo <= 0x7E ) )
++ {
++ temp = ModeNo - 0x7C ;
++ colordepth = ColorDepth[ temp ] ;
++ temp = 0x6B ;
++ if ( infoflag & InterlaceMode )
++ {
++ temp = temp << 1 ;
++ }
++ return( temp * colordepth ) ;
++ }
++ else
++ return( temp * colordepth ) ;
++
++ /*
++ if ((ModeNo >= 0x26) && (ModeNo <= 0x28)) {
++ return (temp * colordepth + (colordepth >> 1));
++ }
++ else
++ return (temp * colordepth); */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT2FIFO */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT2FIFO(PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_PreSetGroup1 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_PreSetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempcx = 0, CRT1Index = 0, resinfo = 0;
++#ifndef LINUX_XF86
++ USHORT temp = 0, tempax = 0, tempbx = 0, pushbx = 0, modeflag;
++#endif
++
++ if (ModeNo > 0x13) {
++ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++ CRT1Index &= IndexMask;
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
++
++ XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex,
++ HwDeviceExtension, pVBInfo);
++ XGI_SetCRT2FIFO(pVBInfo);
++ /* XGI_SetCRT2Sync(ModeNo,RefreshRateTableIndex); */
++
++ for (tempcx = 4; tempcx < 7; tempcx++) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, tempcx, 0x0);
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x02, 0x44); /* temp 0206 */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetGroup1 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetGroup1(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp = 0,
++ tempax = 0,
++ tempbx = 0,
++ tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
++
++ if (ModeNo > 0x13) {
++ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++ CRT1Index &= IndexMask;
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ }
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ /* bainy change table name */
++ if (modeflag & HalfDCLK) {
++ temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
++ temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
++ temp);
++ temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
++ tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
++ pushbx = pVBInfo->VGAHDE / 2 + 16;
++ tempcx = tempcx >> 1;
++ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
++ tempcx += tempbx;
++
++ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
++ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
++ tempbx |=
++ ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
++ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
++ tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
++ tempcx &= 0x1F;
++ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15];
++ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
++ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
++ }
++
++ tempbx += 4;
++ tempcx += 4;
++
++ if (tempcx > (pVBInfo->VGAHT / 2))
++ tempcx = pVBInfo->VGAHT / 2;
++
++ temp = tempbx & 0x00FF;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
++ }
++ else {
++ temp = (pVBInfo->VGAHT - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, temp);
++ temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, ~0x0F0,
++ temp);
++ temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp);
++ tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
++ pushbx = pVBInfo->VGAHDE + 16;
++ tempcx = tempcx >> 1;
++ tempbx = pushbx + tempcx; /* bx BTVGA@HRS 0x0B,0x0C */
++ tempcx += tempbx;
++
++ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
++ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
++ tempbx |=
++ ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5] & 0xC0) << 2);
++ tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
++ tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
++ tempcx &= 0x1F;
++ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6];
++ temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */
++ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */
++ tempbx += 16;
++ tempcx += 16;
++ }
++
++ if (tempcx > pVBInfo->VGAHT)
++ tempcx = pVBInfo->VGAHT;
++
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
++ }
++
++ tempax = (tempax & 0x00FF) | (tempbx & 0xFF00);
++ tempbx = pushbx;
++ tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
++ tempax |= (tempbx & 0xFF00);
++ temp = (tempax & 0xFF00) >> 8;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp);
++ tempcx = (pVBInfo->VGAVT - 1);
++ temp = tempcx & 0x00FF;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
++ tempbx = pVBInfo->VGAVDE - 1;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, temp);
++ temp = ((tempbx & 0xFF00) << 3) >> 8;
++ temp |= ((tempcx & 0xFF00) >> 8);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, temp);
++
++ tempax = pVBInfo->VGAVDE;
++ tempbx = pVBInfo->VGAVDE;
++ tempcx = pVBInfo->VGAVT;
++ tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
++ tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
++
++ if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
++ tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
++ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
++
++ if (temp & 0x04)
++ tempbx |= 0x0100;
++
++ if (temp & 0x080)
++ tempbx |= 0x0200;
++
++ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14];
++
++ if (temp & 0x08)
++ tempbx |= 0x0400;
++
++ temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11];
++ tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
++ }
++
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
++ temp = ((tempbx & 0xFF00) >> 8) << 4;
++ temp = ((tempcx & 0x000F) | (temp));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, temp);
++ tempax = 0;
++
++ if (modeflag & DoubleScanMode)
++ tempax |= 0x80;
++
++ if (modeflag & HalfDCLK)
++ tempax |= 0x40;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2C, ~0x0C0, tempax);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLockRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLockRegs(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT push1,
++ push2, tempax, tempbx = 0, tempcx, temp, resinfo, modeflag, CRT1Index;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++ CRT1Index &= IndexMask;
++ }
++
++ if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
++ return;
++ }
++
++ temp = 0xFF; /* set MAX HT */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x03, temp);
++ /* if ( modeflag & Charx8Dot ) tempcx = 0x08 ; */
++ /* else */
++ tempcx = 0x08;
++
++ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
++ modeflag |= Charx8Dot;
++
++ tempax = pVBInfo->VGAHDE; /* 0x04 Horizontal Display End */
++
++ if (modeflag & HalfDCLK)
++ tempax = tempax >> 1;
++
++ tempax = (tempax / tempcx) - 1;
++ tempbx |= ((tempax & 0x00FF) << 8);
++ temp = tempax & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x04, temp);
++
++ temp = (tempbx & 0xFF00) >> 8;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ if (!
++ (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)))
++ temp += 2;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ if (pVBInfo->VBExtInfo == VB_YPbPr1080i) {
++ if (resinfo == 7)
++ temp -= 2;
++ }
++ }
++ else if (resinfo == 7)
++ temp -= 2;
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
++
++ if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
++ if (pVBInfo->VBInfo & SetCRT2ToTV)
++ tempax = pVBInfo->VGAHT;
++ else
++ tempax = XGI_GetVGAHT2(pVBInfo);
++ }
++
++ if (tempax >= pVBInfo->VGAHT) {
++ tempax = pVBInfo->VGAHT;
++ }
++
++ if (modeflag & HalfDCLK) {
++ tempax = tempax >> 1;
++ }
++
++ tempax = (tempax / tempcx) - 5;
++ tempcx = tempax; /* 20030401 0x07 horizontal Retrace Start */
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ temp = (tempbx & 0x00FF) - 1;
++ if (!(modeflag & HalfDCLK)) {
++ temp -= 6;
++ if (pVBInfo->TVInfo & TVSimuMode) {
++ temp -= 4;
++ if (ModeNo > 0x13)
++ temp -= 10;
++ }
++ }
++ }
++ else {
++ /* tempcx = tempbx & 0x00FF ; */
++ tempbx = (tempbx & 0xFF00) >> 8;
++ tempcx = (tempcx + tempbx) >> 1;
++ temp = (tempcx & 0x00FF) + 2;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ temp -= 1;
++ if (!(modeflag & HalfDCLK)) {
++ if ((modeflag & Charx8Dot)) {
++ temp += 4;
++ if (pVBInfo->VGAHDE >= 800) {
++ temp -= 6;
++ }
++ }
++ }
++ }
++ else {
++ if (!(modeflag & HalfDCLK)) {
++ temp -= 4;
++ if (pVBInfo->LCDResInfo != Panel1280x960) {
++ if (pVBInfo->VGAHDE >= 800) {
++ temp -= 7;
++ if (pVBInfo->ModeType == ModeEGA) {
++ if (pVBInfo->VGAVDE == 1024) {
++ temp += 15;
++ if (pVBInfo->LCDResInfo != Panel1280x1024) {
++ temp += 7;
++ }
++ }
++ }
++
++ if (pVBInfo->VGAHDE >= 1280) {
++ if (pVBInfo->LCDResInfo != Panel1280x960) {
++ if (!
++ (pVBInfo->
++ LCDInfo & (LCDNonExpanding |
++ EnableScalingLCD))) {
++ temp += 28;
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ if (pVBInfo->TVInfo & TVSimuMode) {
++ if ((ModeNo == 0x06) || (ModeNo == 0x10) || (ModeNo == 0x11)
++ || (ModeNo == 0x13) || (ModeNo == 0x0F)) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x5b);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
++ }
++
++ if ((ModeNo == 0x00) || (ModeNo == 0x01)) {
++ if (pVBInfo->TVInfo & SetNTSCTV) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x61);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2A);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x41);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
++ }
++ }
++
++ if ((ModeNo == 0x02) || (ModeNo == 0x03) || (ModeNo == 0x07)) {
++ if (pVBInfo->TVInfo & SetNTSCTV) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x54);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x55);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x00);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, 0xF0);
++ }
++ }
++
++ if ((ModeNo == 0x04) || (ModeNo == 0x05) || (ModeNo == 0x0D)
++ || (ModeNo == 0x50)) {
++ if (pVBInfo->TVInfo & SetNTSCTV) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x30);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x03);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x07, 0x2f);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x08, 0x02);
++ }
++ }
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x18, 0x03); /* 0x18 SR0B */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0xF0, 0x00);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x09, 0xFF); /* 0x09 Set Max VT */
++
++ tempbx = pVBInfo->VGAVT;
++ push1 = tempbx;
++ tempcx = 0x121;
++ tempbx = pVBInfo->VGAVDE; /* 0x0E Virtical Display End */
++
++ if (tempbx == 357)
++ tempbx = 350;
++ if (tempbx == 360)
++ tempbx = 350;
++ if (tempbx == 375)
++ tempbx = 350;
++ if (tempbx == 405)
++ tempbx = 400;
++ if (tempbx == 525)
++ tempbx = 480;
++
++ push2 = tempbx;
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
++ if (pVBInfo->LCDResInfo == Panel1024x768) {
++ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
++ if (tempbx == 350)
++ tempbx += 5;
++ if (tempbx == 480)
++ tempbx += 5;
++ }
++ }
++ }
++ tempbx--;
++ temp = tempbx & 0x00FF;
++ tempbx--;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
++ tempbx = push2;
++ tempbx--;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0E, temp);
++
++ if (tempbx & 0x0100) {
++ tempcx |= 0x0002;
++ }
++
++ tempax = 0x000B;
++
++ if (modeflag & DoubleScanMode) {
++ tempax |= 0x08000;
++ }
++
++ if (tempbx & 0x0200) {
++ tempcx |= 0x0040;
++ }
++
++ temp = (tempax & 0xFF00) >> 8;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, temp);
++
++ if (tempbx & 0x0400) {
++ tempcx |= 0x0600;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
++
++ tempax = push1;
++ tempax -= tempbx; /* 0x0C Vertical Retrace Start */
++ tempax = tempax >> 2;
++ push1 = tempax; /* push ax */
++
++ if (resinfo != 0x09) {
++ tempax = tempax << 1;
++ tempbx += tempax;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ if (pVBInfo->TVInfo & SetYPbPrMode1080i)
++ tempbx -= 10;
++ else {
++ if (pVBInfo->TVInfo & TVSimuMode) {
++ if (pVBInfo->TVInfo & SetPALTV) {
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ if (!
++ (pVBInfo->
++ TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p
++ | SetYPbPrMode1080i)))
++ tempbx += 40;
++ }
++ else
++ tempbx += 40;
++ }
++ }
++ }
++ }
++ else
++ tempbx -= 10;
++ }
++ else {
++ if (pVBInfo->TVInfo & TVSimuMode) {
++ if (pVBInfo->TVInfo & SetPALTV) {
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ if (!
++ (pVBInfo->
++ TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p |
++ SetYPbPrMode1080i)))
++ tempbx += 40;
++ }
++ else
++ tempbx += 40;
++ }
++ }
++ }
++ tempax = push1;
++ tempax = tempax >> 2;
++ tempax++;
++ tempax += tempbx;
++ push1 = tempax; /* push ax */
++
++ if ((pVBInfo->TVInfo & SetPALTV)) {
++ if (tempbx <= 513) {
++ if (tempax >= 513) {
++ tempbx = 513;
++ }
++ }
++ }
++
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0C, temp);
++ tempbx--;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x10, temp);
++
++ if (tempbx & 0x0100) {
++ tempcx |= 0x0008;
++ }
++
++ if (tempbx & 0x0200) {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x0B, 0x0FF, 0x20);
++ }
++
++ tempbx++;
++
++ if (tempbx & 0x0100) {
++ tempcx |= 0x0004;
++ }
++
++ if (tempbx & 0x0200) {
++ tempcx |= 0x0080;
++ }
++
++ if (tempbx & 0x0400) {
++ tempcx |= 0x0C00;
++ }
++
++ tempbx = push1; /* pop ax */
++ temp = tempbx & 0x00FF;
++ temp &= 0x0F;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
++
++ if (tempbx & 0x0010) {
++ tempcx |= 0x2000;
++ }
++
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0A, temp); /* 0x0A CR07 */
++ temp = (tempcx & 0x0FF00) >> 8;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x17, temp); /* 0x17 SR0A */
++ tempax = modeflag;
++ temp = (tempax & 0xFF00) >> 8;
++
++ temp = (temp >> 1) & 0x09;
++
++ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
++ temp |= 0x01;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x16, temp); /* 0x16 SR01 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x0F, 0); /* 0x0F CR14 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x12, 0); /* 0x12 CR17 */
++
++ if (pVBInfo->LCDInfo & LCDRGB18Bit)
++ temp = 0x80;
++ else
++ temp = 0x00;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, temp); /* 0x1A SR0E */
++
++ return;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetGroup2 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetGroup2(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT i,
++ j,
++ tempax,
++ tempbx, tempcx, temp, push1, push2, modeflag, resinfo, crt2crtc;
++#ifndef LINUX_XF86
++ USHORT temp1, temp3, resindex, xres;
++#endif
++/* XGINew_RY1COE = 0 ,
++ XGINew_RY2COE = 0 ,
++ XGINew_RY3COE = 0 ,
++ XGINew_RY4COE = 0 ,
++ XGINew_RY5COE = 0 ,
++ XGINew_RY6COE = 0 ,
++ XGINew_RY7COE = 0 ;
++*/
++
++#ifndef LINUX_XF86
++ UCHAR *PhasePoint;
++#endif
++ const UCHAR *TimingPoint;
++
++ ULONG longtemp, tempeax, tempebx, temp2, tempecx;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
++ crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ }
++
++ tempax = 0;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToAVIDEO))
++ tempax |= 0x0800;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
++ tempax |= 0x0400;
++
++ if (pVBInfo->VBInfo & SetCRT2ToSCART)
++ tempax |= 0x0200;
++
++ if (!(pVBInfo->TVInfo & SetPALTV))
++ tempax |= 0x1000;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
++ tempax |= 0x0100;
++
++ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
++ tempax &= 0xfe00;
++
++ ErrorF("Part2 0 = %x ",
++ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
++ ErrorF(" pVBInfo->VBInfo =%x", pVBInfo->VBInfo);
++
++ tempax = (tempax & 0xff00) >> 8;
++ ErrorF("tempax = %x ", tempax);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0, tempax);
++ TimingPoint = pVBInfo->NTSCTiming;
++
++ if (pVBInfo->TVInfo & SetPALTV) {
++ TimingPoint = pVBInfo->PALTiming;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ TimingPoint = pVBInfo->HiTVExtTiming;
++
++ if (pVBInfo->VBInfo & SetInSlaveMode)
++ TimingPoint = pVBInfo->HiTVSt2Timing;
++
++ if (pVBInfo->SetFlag & TVSimuMode)
++ TimingPoint = pVBInfo->HiTVSt1Timing;
++
++ if (!(modeflag & Charx8Dot))
++ TimingPoint = pVBInfo->HiTVTextTiming;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
++ if (pVBInfo->TVInfo & SetYPbPrMode525i)
++ TimingPoint = pVBInfo->YPbPr525iTiming;
++
++ if (pVBInfo->TVInfo & SetYPbPrMode525p)
++ TimingPoint = pVBInfo->YPbPr525pTiming;
++
++ if (pVBInfo->TVInfo & SetYPbPrMode750p)
++ TimingPoint = pVBInfo->YPbPr750pTiming;
++ }
++
++ for (i = 0x01, j = 0; i <= 0x2D; i++, j++) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]);
++ }
++
++ for (i = 0x39; i <= 0x45; i++, j++) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
++ }
++
++ temp = pVBInfo->NewFlickerMode;
++ temp &= 0x80;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xFF, temp);
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
++ tempax = 950;
++
++ if (pVBInfo->TVInfo & SetPALTV)
++ tempax = 520;
++ else
++ tempax = 440;
++
++ if (pVBInfo->VDE <= tempax) {
++ tempax -= pVBInfo->VDE;
++ tempax = tempax >> 2;
++ tempax = (tempax & 0x00FF) | ((tempax & 0x00FF) << 8);
++ push1 = tempax;
++ temp = (tempax & 0xFF00) >> 8;
++ temp += (USHORT) TimingPoint[0];
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (pVBInfo->
++ VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART |
++ SetCRT2ToYPbPr)) {
++ tempcx = pVBInfo->VGAHDE;
++ if (tempcx >= 1024) {
++ temp = 0x17; /* NTSC */
++ if (pVBInfo->TVInfo & SetPALTV)
++ temp = 0x19; /* PAL */
++ }
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
++ tempax = push1;
++ temp = (tempax & 0xFF00) >> 8;
++ temp += TimingPoint[1];
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if ((pVBInfo->
++ VBInfo & (SetCRT2ToAVIDEO | SetCRT2ToSVIDEO | SetCRT2ToSCART
++ | SetCRT2ToYPbPr))) {
++ tempcx = pVBInfo->VGAHDE;
++ if (tempcx >= 1024) {
++ temp = 0x1D; /* NTSC */
++ if (pVBInfo->TVInfo & SetPALTV)
++ temp = 0x52; /* PAL */
++ }
++ }
++ }
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, temp);
++ }
++
++ /* 301b */
++ tempcx = pVBInfo->HT;
++
++ if (XGI_IsLCDDualLink(pVBInfo))
++ tempcx = tempcx >> 1;
++
++ tempcx -= 2;
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1B, temp);
++
++ temp = (tempcx & 0xFF00) >> 8;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F, temp);
++
++ tempcx = pVBInfo->HT >> 1;
++ push1 = tempcx; /* push cx */
++ tempcx += 7;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ tempcx -= 4;
++ }
++
++ temp = tempcx & 0x00FF;
++ temp = temp << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x22, 0x0F, temp);
++
++ tempbx = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
++ tempbx += tempcx;
++ push2 = tempbx;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x24, temp);
++ temp = (tempbx & 0xFF00) >> 8;
++ temp = temp << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, 0x0F, temp);
++
++ tempbx = push2;
++ tempbx = tempbx + 8;
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ tempbx = tempbx - 4;
++ tempcx = tempbx;
++ }
++
++ temp = (tempbx & 0x00FF) << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x29, 0x0F, temp);
++
++ j += 2;
++ tempcx += (TimingPoint[j] | ((TimingPoint[j + 1]) << 8));
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x27, temp);
++ temp = ((tempcx & 0xFF00) >> 8) << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x28, 0x0F, temp);
++
++ tempcx += 8;
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ tempcx -= 4;
++ }
++
++ temp = tempcx & 0xFF;
++ temp = temp << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2A, 0x0F, temp);
++
++ tempcx = push1; /* pop cx */
++ j += 2;
++ temp = TimingPoint[j] | ((TimingPoint[j + 1]) << 8);
++ tempcx -= temp;
++ temp = tempcx & 0x00FF;
++ temp = temp << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2D, 0x0F, temp);
++
++ tempcx -= 11;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
++ tempax = XGI_GetVGAHT2(pVBInfo);
++ tempcx = tempax - 1;
++ }
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2E, temp);
++
++ tempbx = pVBInfo->VDE;
++
++ if (pVBInfo->VGAVDE == 360)
++ tempbx = 746;
++ if (pVBInfo->VGAVDE == 375)
++ tempbx = 746;
++ if (pVBInfo->VGAVDE == 405)
++ tempbx = 853;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
++ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
++ tempbx = tempbx >> 1;
++ }
++ else
++ tempbx = tempbx >> 1;
++ }
++
++ tempbx -= 2;
++ temp = tempbx & 0x00FF;
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (ModeNo == 0x2f)
++ temp += 1;
++ }
++ }
++ }
++ else {
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (ModeNo == 0x2f)
++ temp += 1;
++ }
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2F, temp);
++
++ temp = (tempcx & 0xFF00) >> 8;
++ temp |= ((tempbx & 0xFF00) >> 8) << 6;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) {
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ if (pVBInfo->TVInfo & SetYPbPrMode1080i) {
++ temp |= 0x10;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
++ temp |= 0x20;
++ }
++ }
++ else {
++ temp |= 0x10;
++ if (!(pVBInfo->VBInfo & SetCRT2ToSVIDEO))
++ temp |= 0x20;
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, temp);
++
++ if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* TV gatingno */
++ tempbx = pVBInfo->VDE;
++ tempcx = tempbx - 2;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))
++ tempbx = tempbx >> 1;
++ }
++
++ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
++ temp = 0;
++ if (tempcx & 0x0400)
++ temp |= 0x20;
++
++ if (tempbx & 0x0400)
++ temp |= 0x40;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x10, temp);
++ }
++
++ temp = (((tempbx - 3) & 0x0300) >> 8) << 5;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, temp);
++ temp = (tempbx - 3) & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x47, temp);
++ }
++
++ tempbx = tempbx & 0x00FF;
++
++ if (!(modeflag & HalfDCLK)) {
++ tempcx = pVBInfo->VGAHDE;
++ if (tempcx >= pVBInfo->HDE) {
++ tempbx |= 0x2000;
++ tempax &= 0x00FF;
++ }
++ }
++
++ tempcx = 0x0101;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) { /*301b */
++ if (pVBInfo->VGAHDE >= 1024) {
++ tempcx = 0x1920;
++ if (pVBInfo->VGAHDE >= 1280) {
++ tempcx = 0x1420;
++ tempbx = tempbx & 0xDFFF;
++ }
++ }
++ }
++
++ if (!(tempbx & 0x2000)) {
++ if (modeflag & HalfDCLK) {
++ tempcx = (tempcx & 0xFF00) | ((tempcx & 0x00FF) << 1);
++ }
++
++ push1 = tempbx;
++ tempeax = pVBInfo->VGAHDE;
++ tempebx = (tempcx & 0xFF00) >> 8;
++ longtemp = tempeax * tempebx;
++ tempecx = tempcx & 0x00FF;
++ longtemp = longtemp / tempecx;
++
++ /* 301b */
++ tempecx = 8 * 1024;
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ tempecx = tempecx * 8;
++ }
++
++ longtemp = longtemp * tempecx;
++ tempecx = pVBInfo->HDE;
++ temp2 = longtemp % tempecx;
++ tempeax = longtemp / tempecx;
++ if (temp2 != 0) {
++ tempeax += 1;
++ }
++
++ tempax = (USHORT) tempeax;
++
++ /* 301b */
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ tempcx = ((tempax & 0xFF00) >> 5) >> 8;
++ }
++ /* end 301b */
++
++ tempbx = push1;
++ tempbx =
++ (USHORT) (((tempeax & 0x0000FF00) & 0x1F00) | (tempbx & 0x00FF));
++ tempax = (USHORT) (((tempeax & 0x000000FF) << 8) | (tempax & 0x00FF));
++ temp = (tempax & 0xFF00) >> 8;
++ }
++ else {
++ temp = (tempax & 0x00FF) >> 8;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x44, temp);
++ temp = (tempbx & 0xFF00) >> 8;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x45, ~0x03F, temp);
++ temp = tempcx & 0x00FF;
++
++ if (tempbx & 0x2000)
++ temp = 0;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
++ temp |= 0x18;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x46, ~0x1F, temp);
++ if (pVBInfo->TVInfo & SetPALTV) {
++ tempbx = 0x0382;
++ tempcx = 0x007e;
++ }
++ else {
++ tempbx = 0x0369;
++ tempcx = 0x0061;
++ }
++
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4b, temp);
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4c, temp);
++
++ temp = ((tempcx & 0xFF00) >> 8) & 0x03;
++ temp = temp << 2;
++ temp |= ((tempbx & 0xFF00) >> 8) & 0x03;
++
++ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
++ temp |= 0x10;
++
++ if (pVBInfo->TVInfo & SetYPbPrMode525p)
++ temp |= 0x20;
++
++ if (pVBInfo->TVInfo & SetYPbPrMode750p)
++ temp |= 0x60;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4d, temp);
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43); /* 301b change */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, (USHORT) (temp - 3));
++
++ if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) {
++ if (pVBInfo->TVInfo & NTSC1024x768) {
++ TimingPoint = XGI_NTSC1024AdjTime;
++ for (i = 0x1c, j = 0; i <= 0x30; i++, j++) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
++ TimingPoint[j]);
++ }
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x43, 0x72);
++ }
++ }
++
++ /* [ycchen] 01/14/03 Modify for 301C PALM Support */
++ if (pVBInfo->VBType & VB_XGI301C) {
++ if (pVBInfo->TVInfo & SetPALMTV)
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x08, 0x08); /* PALM Mode */
++ }
++
++ if (pVBInfo->TVInfo & SetPALMTV) {
++ tempax = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01);
++ tempax--;
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, tempax);
++
++ /* if ( !( pVBInfo->VBType & VB_XGI301C ) ) */
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xEF);
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
++ if (!(pVBInfo->VBInfo & SetInSlaveMode)) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, 0x00);
++ }
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ return;
++ }
++ ErrorF("5935 Part2 0 = %x ",
++ XGI_GetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0));
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLCDRegs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLCDRegs(USHORT ModeNo, USHORT ModeIdIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT push1,
++ push2,
++ pushbx,
++ tempax,
++ tempbx,
++ tempcx, temp, tempah, tempbh, tempch, resinfo, modeflag, CRT1Index;
++
++ XGI_LCDDesStruct *LCDBDesPtr = NULL;
++ XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL;
++
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
++ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++ CRT1Index &= IndexMask;
++ }
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) {
++ return;
++ }
++
++ tempbx = pVBInfo->HDE; /* RHACTE=HDE-1 */
++
++ if (XGI_IsLCDDualLink(pVBInfo))
++ tempbx = tempbx >> 1;
++
++ tempbx -= 1;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2C, temp);
++ temp = (tempbx & 0xFF00) >> 8;
++ temp = temp << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x2B, 0x0F, temp);
++ temp = 0x01;
++
++ if (pVBInfo->LCDResInfo == Panel1280x1024) {
++ if (pVBInfo->ModeType == ModeEGA) {
++ if (pVBInfo->VGAHDE >= 1024) {
++ temp = 0x02;
++ if (pVBInfo->LCDInfo & LCDVESATiming)
++ temp = 0x01;
++ }
++ }
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x0B, temp);
++ tempbx = pVBInfo->VDE; /* RTVACTEO=(VDE-1)&0xFF */
++ push1 = tempbx;
++ tempbx--;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x03, temp);
++ temp = ((tempbx & 0xFF00) >> 8) & 0x07;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0C, ~0x07, temp);
++
++ tempcx = pVBInfo->VT - 1;
++ push2 = tempcx + 1;
++ temp = tempcx & 0x00FF; /* RVTVT=VT-1 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x19, temp);
++ temp = (tempcx & 0xFF00) >> 8;
++ temp = temp << 5;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, temp);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x09, 0xF0, 0x00);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0xF0, 0x00);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x17, 0xFB, 0x00);
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x18, 0xDF, 0x00);
++
++ /* Customized LCDB Des no add */
++ LCDBDesPtr = (XGI_LCDDesStruct *) XGI_GetLcdPtr(5, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD) {
++ tempbx = pVBInfo->HDE;
++ tempcx = pVBInfo->VDE;
++ }
++ else {
++ get_HDE_VDE(pVBInfo, & tempbx, & tempcx);
++ }
++
++ pushbx = tempbx;
++ tempax = pVBInfo->VT;
++ pVBInfo->LCDHDES = LCDBDesPtr->LCDHDES;
++ pVBInfo->LCDHRS = LCDBDesPtr->LCDHRS;
++ pVBInfo->LCDVDES = LCDBDesPtr->LCDVDES;
++ pVBInfo->LCDVRS = LCDBDesPtr->LCDVRS;
++ tempbx = pVBInfo->LCDVDES;
++ tempcx += tempbx;
++
++ if (tempcx >= tempax)
++ tempcx -= tempax; /* lcdvdes */
++
++ temp = tempbx & 0x00FF; /* RVEQ1EQ=lcdvdes */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x05, temp);
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x06, temp);
++ tempch = ((tempcx & 0xFF00) >> 8) & 0x07;
++ tempbh = ((tempbx & 0xFF00) >> 8) & 0x07;
++ tempah = tempch;
++ tempah = tempah << 3;
++ tempah |= tempbh;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x02, tempah);
++
++ /* getlcdsync() */
++ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
++ if (pVBInfo->LCDInfo & EnableScalingLCD) {
++ LCDPtr1 =
++ (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ tempbx = LCDPtr1->LCDVSync;
++ }
++ tempcx = tempbx;
++ tempax = pVBInfo->VT;
++ tempbx = pVBInfo->LCDVRS;
++
++ /* if ( SetLCD_Info & EnableScalingLCD ) */
++ tempcx += tempbx;
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ temp = tempbx & 0x00FF; /* RTVACTEE=lcdvrs */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x04, temp);
++ temp = (tempbx & 0xFF00) >> 8;
++ temp = temp << 4;
++ temp |= (tempcx & 0x000F);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x01, temp);
++ tempcx = pushbx;
++ tempax = pVBInfo->HT;
++ tempbx = pVBInfo->LCDHDES;
++ tempbx &= 0x0FFF;
++
++ if (XGI_IsLCDDualLink(pVBInfo)) {
++ tempax = tempax >> 1;
++ tempbx = tempbx >> 1;
++ tempcx = tempcx >> 1;
++ }
++
++ if (pVBInfo->VBType & VB_XGI302LV)
++ tempbx += 1;
++
++ if (pVBInfo->VBType & VB_XGI301C) /* tap4 */
++ tempbx += 1;
++
++ tempcx += tempbx;
++
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1F, temp); /* RHBLKE=lcdhdes */
++ temp = ((tempbx & 0xFF00) >> 8) << 4;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x20, temp);
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x23, temp); /* RHEQPLE=lcdhdee */
++ temp = (tempcx & 0xFF00) >> 8;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x25, temp);
++
++ /* getlcdsync() */
++ XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
++ if (pVBInfo->LCDInfo & EnableScalingLCD) {
++ LCDPtr1 =
++ (XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(4, ModeNo, ModeIdIndex,
++ RefreshRateTableIndex,
++ pVBInfo);
++ tempax = LCDPtr1->LCDHSync;
++ }
++ tempcx = tempax;
++ tempax = pVBInfo->HT;
++ tempbx = pVBInfo->LCDHRS;
++ /* if ( SetLCD_Info & EnableScalingLCD) */
++ if (XGI_IsLCDDualLink(pVBInfo)) {
++ tempax = tempax >> 1;
++ tempbx = tempbx >> 1;
++ tempcx = tempcx >> 1;
++ }
++
++ if (pVBInfo->VBType & VB_XGI302LV)
++ tempbx += 1;
++
++ tempcx += tempbx;
++
++ if (tempcx >= tempax)
++ tempcx -= tempax;
++
++ temp = tempbx & 0x00FF; /* RHBURSTS=lcdhrs */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x1C, temp);
++
++ temp = (tempbx & 0xFF00) >> 8;
++ temp = temp << 4;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1D, ~0x0F0, temp);
++ temp = tempcx & 0x00FF; /* RHSYEXP2S=lcdhre */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x21, temp);
++
++ if (!(pVBInfo->LCDInfo & LCDVESATiming)) {
++ if (pVBInfo->VGAVDE == 525) {
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
++ | VB_XGI301C)) {
++ temp = 0xC6;
++ }
++ else
++ temp = 0xC4;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x30, 0xB3);
++ }
++
++ if (pVBInfo->VGAVDE == 420) {
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
++ | VB_XGI301C)) {
++ temp = 0x4F;
++ }
++ else
++ temp = 0x4E;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x2f, temp);
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetTap4Ptr */
++/* Input : */
++/* Output : di -> Tap4 Reg. Setting Pointer */
++/* Description : */
++/* --------------------------------------------------------------------- */
++const XGI301C_Tap4TimingStruct *
++XGI_GetTap4Ptr(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, tempbx, i;
++
++ const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
++
++ if (tempcx == 0) {
++ tempax = pVBInfo->VGAHDE;
++ tempbx = pVBInfo->HDE;
++ }
++ else {
++ tempax = pVBInfo->VGAVDE;
++ tempbx = pVBInfo->VDE;
++ }
++
++ if (tempax < tempbx)
++ return &EnlargeTap4Timing[0];
++ else if (tempax == tempbx)
++ return &NoScaleTap4Timing[0]; /* 1:1 */
++ else
++ Tap4TimingPtr = NTSCTap4Timing; /* NTSC */
++
++ if (pVBInfo->TVInfo & SetPALTV)
++ Tap4TimingPtr = PALTap4Timing;
++
++
++ if (pVBInfo->VBInfo & SetCRT2ToYPbPr) {
++ if (pVBInfo->TVInfo & SetYPbPrMode525i)
++ Tap4TimingPtr = YPbPr525iTap4Timing;
++ if (pVBInfo->TVInfo & SetYPbPrMode525p)
++ Tap4TimingPtr = YPbPr525pTap4Timing;
++ if (pVBInfo->TVInfo & SetYPbPrMode750p)
++ Tap4TimingPtr = YPbPr750pTap4Timing;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
++ Tap4TimingPtr = HiTVTap4Timing;
++
++ i = 0;
++ while (Tap4TimingPtr[i].DE != 0xFFFF) {
++ if (Tap4TimingPtr[i].DE == tempax)
++ break;
++ i++;
++ }
++ return &Tap4TimingPtr[i];
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetTap4Regs */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetTap4Regs(PVB_DEVICE_INFO pVBInfo)
++{
++
++#ifndef LINUX_XF86
++ USHORT tempcx;
++#endif
++ USHORT i, j;
++
++ const XGI301C_Tap4TimingStruct *Tap4TimingPtr;
++
++ if (!(pVBInfo->VBType & VB_XGI301C))
++ return;
++
++#ifndef Tap4
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, 0xEB); /* Disable Tap4 */
++#else /* Tap4 Setting */
++
++ Tap4TimingPtr = XGI_GetTap4Ptr(0, pVBInfo); /* Set Horizontal Scaling */
++ for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
++ Tap4TimingPtr->Reg[j]);
++
++ if ((pVBInfo->VBInfo & SetCRT2ToTV)
++ && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
++ Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
++ for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, i,
++ Tap4TimingPtr->Reg[j]);
++ }
++
++ if ((pVBInfo->VBInfo & SetCRT2ToTV)
++ && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
++ else
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
++#endif
++}
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetGroup3 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetGroup3(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT i;
++ const UCHAR *tempdi;
++ USHORT modeflag;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ }
++
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x00, 0x00);
++ if (pVBInfo->TVInfo & SetPALTV) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xF5);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xB7);
++ }
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
++ return;
++ }
++
++ if (pVBInfo->TVInfo & SetPALMTV) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x13, 0xFA);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x14, 0xC8);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x3D, 0xA8);
++ }
++
++ if ((pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
++ || (pVBInfo->VBInfo & SetCRT2ToYPbPr)) {
++ if (pVBInfo->TVInfo & SetYPbPrMode525i) {
++ return;
++ }
++ tempdi = pVBInfo->HiTVGroup3Data;
++ if (pVBInfo->SetFlag & TVSimuMode) {
++ tempdi = pVBInfo->HiTVGroup3Simu;
++ if (!(modeflag & Charx8Dot)) {
++ tempdi = pVBInfo->HiTVGroup3Text;
++ }
++ }
++
++ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
++ tempdi = pVBInfo->Ren525pGroup3;
++ }
++ if (pVBInfo->TVInfo & SetYPbPrMode750p) {
++ tempdi = pVBInfo->Ren750pGroup3;
++ }
++
++ for (i = 0; i <= 0x3E; i++) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, i, tempdi[i]);
++ }
++ if (pVBInfo->VBType & VB_XGI301C) { /* Marcovision */
++ if (pVBInfo->TVInfo & SetYPbPrMode525p) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part3Port, 0x28, 0x3f);
++ }
++ }
++ }
++ return;
++} /* {end of XGI_SetGroup3} */
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetGroup4 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetGroup4(USHORT ModeNo, USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
++ PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, tempcx, tempbx, modeflag, temp, temp2;
++#ifndef LINUX_XF86
++ USHORT push1;
++#endif
++
++ ULONG tempebx, tempeax, templong;
++
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
++ }
++
++ temp = pVBInfo->RVBHCFACT;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x13, temp);
++
++ tempbx = pVBInfo->RVBHCMAX;
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x14, temp);
++ temp2 = ((tempbx & 0xFF00) >> 8) << 7;
++ tempcx = pVBInfo->VGAHT - 1;
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x16, temp);
++
++ temp = ((tempcx & 0xFF00) >> 8) << 3;
++ temp2 |= temp;
++
++ tempcx = pVBInfo->VGAVT - 1;
++ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
++ tempcx -= 5;
++ }
++
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x17, temp);
++ temp = temp2 | ((tempcx & 0xFF00) >> 8);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x15, temp);
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, 0x08);
++ tempcx = pVBInfo->VBInfo;
++ tempbx = pVBInfo->VGAHDE;
++
++ if (modeflag & HalfDCLK) {
++ tempbx = tempbx >> 1;
++ }
++
++ if (XGI_IsLCDDualLink(pVBInfo))
++ tempbx = tempbx >> 1;
++
++ if (tempcx & SetCRT2ToHiVisionTV) {
++ temp = 0;
++ if (tempbx <= 1024)
++ temp = 0xA0;
++ if (tempbx == 1280)
++ temp = 0xC0;
++ }
++ else if (tempcx & SetCRT2ToTV) {
++ temp = 0xA0;
++ if (tempbx <= 800)
++ temp = 0x80;
++ }
++ else {
++ temp = 0x80;
++ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
++ temp = 0;
++ if (tempbx > 800)
++ temp = 0x60;
++ }
++ }
++
++ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)) {
++ temp = 0x00;
++ if (pVBInfo->VGAHDE == 1280)
++ temp = 0x40;
++ if (pVBInfo->VGAHDE == 1024)
++ temp = 0x20;
++ }
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0E, ~0xEF, temp);
++
++ tempebx = pVBInfo->VDE;
++
++ if (tempcx & SetCRT2ToHiVisionTV) {
++ if (!(temp & 0xE000))
++ tempbx = tempbx >> 1;
++ }
++
++ tempcx = pVBInfo->RVBHRS;
++ temp = tempcx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x18, temp);
++
++ tempeax = pVBInfo->VGAVDE;
++ tempcx |= 0x04000;
++
++
++ if (tempeax <= tempebx) {
++ tempcx = (tempcx & (~0x4000));
++ tempeax = pVBInfo->VGAVDE;
++ }
++ else {
++ tempeax -= tempebx;
++ }
++
++
++ templong = (tempeax * 256 * 1024) % tempebx;
++ tempeax = (tempeax * 256 * 1024) / tempebx;
++ tempebx = tempeax;
++
++ if (templong != 0) {
++ tempebx++;
++ }
++
++
++ temp = (USHORT) (tempebx & 0x000000FF);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1B, temp);
++
++ temp = (USHORT) ((tempebx & 0x0000FF00) >> 8);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1A, temp);
++ tempbx = (USHORT) (tempebx >> 16);
++ temp = tempbx & 0x00FF;
++ temp = temp << 4;
++ temp |= ((tempcx & 0xFF00) >> 8);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x19, temp);
++
++ /* 301b */
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ temp = 0x0028;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1C, temp);
++ tempax = pVBInfo->VGAHDE;
++ if (modeflag & HalfDCLK) {
++ tempax = tempax >> 1;
++ }
++
++ if (XGI_IsLCDDualLink(pVBInfo))
++ tempax = tempax >> 1;
++
++ /* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
++ if (pVBInfo->VBInfo & SetCRT2ToLCD) {
++ if (tempax > 800)
++ tempax -= 800;
++ }
++ else {
++ if (pVBInfo->VGAHDE > 800) {
++ if (pVBInfo->VGAHDE == 1024)
++ tempax = (tempax * 25 / 32) - 1;
++ else
++ tempax = (tempax * 20 / 32) - 1;
++ }
++ }
++ tempax -= 1;
++
++/*
++ if ( pVBInfo->VBInfo & ( SetCRT2ToTV | SetCRT2ToHiVisionTV ) )
++ {
++ if ( pVBInfo->VBType & VB_XGI301LV )
++ {
++ if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i ) ) )
++ {
++ if ( pVBInfo->VGAHDE > 800 )
++ {
++ if ( pVBInfo->VGAHDE == 1024 )
++ tempax = ( tempax * 25 / 32 ) - 1 ;
++ else
++ tempax = ( tempax * 20 / 32 ) - 1 ;
++ }
++ }
++ }
++ else
++ {
++ if ( pVBInfo->VGAHDE > 800 )
++ {
++ if ( pVBInfo->VGAHDE == 1024 )
++ tempax = ( tempax * 25 / 32 ) - 1 ;
++ else
++ tempax = ( tempax * 20 / 32 ) - 1 ;
++ }
++ }
++ }
++*/
++
++ temp = (tempax & 0xFF00) >> 8;
++ temp = ((temp & 0x0003) << 4);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, temp);
++ temp = (tempax & 0x00FF);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x1D, temp);
++
++ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
++ if (pVBInfo->VGAHDE > 800) {
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1E, 0x08);
++ }
++ }
++ temp = 0x0036;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ if (!
++ (pVBInfo->
++ TVInfo & (NTSC1024x768 | SetYPbPrMode525p | SetYPbPrMode750p
++ | SetYPbPrMode1080i))) {
++ temp |= 0x0001;
++ if ((pVBInfo->VBInfo & SetInSlaveMode)
++ && (!(pVBInfo->TVInfo & TVSimuMode)))
++ temp &= (~0x0001);
++ }
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, 0x00C0,
++ temp);
++ tempbx = pVBInfo->HT;
++ if (XGI_IsLCDDualLink(pVBInfo))
++ tempbx = tempbx >> 1;
++ tempbx = (tempbx >> 1) - 2;
++ temp = ((tempbx & 0x0700) >> 8) << 3;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, 0x00C0,
++ temp);
++ temp = tempbx & 0x00FF;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x22, temp);
++ }
++ /* end 301b */
++
++ if (pVBInfo->ISXPDOS == 0)
++ XGI_SetCRT2VCLK(ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetGroup5 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetGroup5(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT Pindex, Pdata;
++
++ Pindex = pVBInfo->Part5Port;
++ Pdata = pVBInfo->Part5Port + 1;
++ if (pVBInfo->ModeType == ModeVGA) {
++ if (!
++ (pVBInfo->
++ VBInfo & (SetInSlaveMode | LoadDACFlag | CRT2DisplayFlag))) {
++ XGINew_EnableCRT2(pVBInfo);
++ /* LoadDAC2(pVBInfo->Part5Port,ModeNo,ModeIdIndex); */
++ }
++ }
++ return;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetLcdPtr */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++const void *
++XGI_GetLcdPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT i, tempdx, tempcx, tempbx, tempal, modeflag, table;
++
++ const XGI330_LCDDataTablStruct *tempdi = 0;
++
++
++ tempbx = BX;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ }
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
++ if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x14) {
++ tempal = 0x0A;
++ }
++ else if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO == 0x0F) {
++ tempal = 0x0B;
++ }
++ }
++
++ tempal = tempal & 0x0f;
++
++ if (tempbx <= 1) { /* ExpLink */
++ if (ModeNo <= 0x13) {
++ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
++ }
++ else {
++ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ if (ModeNo <= 0x13)
++ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
++ else
++ tempal =
++ pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
++ }
++
++ if (tempbx & 0x01)
++ tempal = (tempal >> 4);
++
++ tempal = (tempal & 0x0f);
++ }
++
++ tempcx = LCDLenList[tempbx]; /* mov cl,byte ptr cs:LCDLenList[bx] */
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD) { /* ScaleLCD */
++ if ((tempbx == 5) || (tempbx) == 7)
++ tempcx = LCDDesDataLen2;
++ else if ((tempbx == 3) || (tempbx == 8))
++ tempcx = LVDSDesDataLen2;
++ }
++ /* mov di, word ptr cs:LCDDataList[bx] */
++ /* tempdi=pVideoMemory[LCDDataList+tempbx*2]|(pVideoMemory[LCDDataList+tempbx*2+1]<<8); */
++
++ switch (tempbx) {
++ case 0:
++ tempdi = XGI_EPLLCDCRT1Ptr_H;
++ break;
++ case 1:
++ tempdi = XGI_EPLLCDCRT1Ptr_V;
++ break;
++ case 2:
++ tempdi = XGI_EPLLCDDataPtr;
++ break;
++ case 3:
++ tempdi = XGI_EPLLCDDesDataPtr;
++ break;
++ case 4:
++ tempdi = XGI_LCDDataTable;
++ break;
++ case 5:
++ tempdi = XGI_LCDDesDataTable;
++ break;
++ case 6:
++ tempdi = XGI_EPLCHLCDRegPtr;
++ break;
++ case 7:
++ case 8:
++ case 9:
++ tempdi = 0;
++ break;
++ default:
++ break;
++ }
++
++ if (tempdi == 0x00) /* OEMUtil */
++ return 0;
++
++ table = tempbx;
++ i = 0;
++
++ while (tempdi[i].PANELID != 0xff) {
++ tempdx = pVBInfo->LCDResInfo;
++ if (tempbx & 0x0080) { /* OEMUtil */
++ tempbx &= (~0x0080);
++ tempdx = pVBInfo->LCDTypeInfo;
++ }
++
++ if (pVBInfo->LCDInfo & EnableScalingLCD) {
++ if ((pVBInfo->LCDInfo & EnableReduceTiming)
++ && (pVBInfo->LCDResInfo == Panel1600x1200)) {
++ tempdx = Panel1600x1200_1;
++ }
++ else {
++ tempdx &= (~PanelResInfo);
++ }
++ }
++ if (tempdi[i].PANELID == tempdx) {
++ tempbx = tempdi[i].MASK;
++ tempdx = pVBInfo->LCDInfo;
++
++ if (ModeNo <= 0x13) /* alan 09/10/2003 */
++ tempdx |= SetLCDStdMode;
++
++ if (modeflag & HalfDCLK)
++ tempdx |= SetLCDLowResolution;
++
++ tempbx &= tempdx;
++ if (tempbx == tempdi[i].CAP)
++ break;
++ }
++ i++;
++ }
++
++ if (table == 0) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_LVDSCRT11024x768_1_H[tempal];
++ break;
++ case 1:
++ return &XGI_LVDSCRT11024x768_2_H[tempal];
++ break;
++ case 2:
++ return &XGI_LVDSCRT11280x1024_1_H[tempal];
++ break;
++ case 3:
++ return &XGI_LVDSCRT11280x1024_2_H[tempal];
++ break;
++ case 4:
++ return &XGI_LVDSCRT11400x1050_1_H[tempal];
++ break;
++ case 5:
++ return &XGI_LVDSCRT11400x1050_2_H[tempal];
++ break;
++ case 6:
++ return &XGI_LVDSCRT11600x1200_1_H[tempal];
++ break;
++ case 7:
++ return &XGI_LVDSCRT11024x768_1_Hx75[tempal];
++ break;
++ case 8:
++ return &XGI_LVDSCRT11024x768_2_Hx75[tempal];
++ break;
++ case 9:
++ return &XGI_LVDSCRT11280x1024_1_Hx75[tempal];
++ break;
++ case 10:
++ return &XGI_LVDSCRT11280x1024_2_Hx75[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 1) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_LVDSCRT11024x768_1_V[tempal];
++ break;
++ case 1:
++ return &XGI_LVDSCRT11024x768_2_V[tempal];
++ break;
++ case 2:
++ return &XGI_LVDSCRT11280x1024_1_V[tempal];
++ break;
++ case 3:
++ return &XGI_LVDSCRT11280x1024_2_V[tempal];
++ break;
++ case 4:
++ return &XGI_LVDSCRT11400x1050_1_V[tempal];
++ break;
++ case 5:
++ return &XGI_LVDSCRT11400x1050_2_V[tempal];
++ break;
++ case 6:
++ return &XGI_LVDSCRT11600x1200_1_V[tempal];
++ break;
++ case 7:
++ return &XGI_LVDSCRT11024x768_1_Vx75[tempal];
++ break;
++ case 8:
++ return &XGI_LVDSCRT11024x768_2_Vx75[tempal];
++ break;
++ case 9:
++ return &XGI_LVDSCRT11280x1024_1_Vx75[tempal];
++ break;
++ case 10:
++ return &XGI_LVDSCRT11280x1024_2_Vx75[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 2) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_LVDS1024x768Data_1[tempal];
++ break;
++ case 1:
++ return &XGI_LVDS1024x768Data_2[tempal];
++ break;
++ case 2:
++ return &XGI_LVDS1280x1024Data_1[tempal];
++ break;
++ case 3:
++ return &XGI_LVDS1280x1024Data_2[tempal];
++ break;
++ case 4:
++ return &XGI_LVDS1400x1050Data_1[tempal];
++ break;
++ case 5:
++ return &XGI_LVDS1400x1050Data_2[tempal];
++ break;
++ case 6:
++ return &XGI_LVDS1600x1200Data_1[tempal];
++ break;
++ case 7:
++ return &XGI_LVDSNoScalingData[tempal];
++ break;
++ case 8:
++ return &XGI_LVDS1024x768Data_1x75[tempal];
++ break;
++ case 9:
++ return &XGI_LVDS1024x768Data_2x75[tempal];
++ break;
++ case 10:
++ return &XGI_LVDS1280x1024Data_1x75[tempal];
++ break;
++ case 11:
++ return &XGI_LVDS1280x1024Data_2x75[tempal];
++ break;
++ case 12:
++ return &XGI_LVDSNoScalingDatax75[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 3) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_LVDS1024x768Des_1[tempal];
++ break;
++ case 1:
++ return &XGI_LVDS1024x768Des_3[tempal];
++ break;
++ case 2:
++ return &XGI_LVDS1024x768Des_2[tempal];
++ break;
++ case 3:
++ return &XGI_LVDS1280x1024Des_1[tempal];
++ break;
++ case 4:
++ return &XGI_LVDS1280x1024Des_2[tempal];
++ break;
++ case 5:
++ return &XGI_LVDS1400x1050Des_1[tempal];
++ break;
++ case 6:
++ return &XGI_LVDS1400x1050Des_2[tempal];
++ break;
++ case 7:
++ return &XGI_LVDS1600x1200Des_1[tempal];
++ break;
++ case 8:
++ return &XGI_LVDSNoScalingDesData[tempal];
++ break;
++ case 9:
++ return &XGI_LVDS1024x768Des_1x75[tempal];
++ break;
++ case 10:
++ return &XGI_LVDS1024x768Des_3x75[tempal];
++ break;
++ case 11:
++ return &XGI_LVDS1024x768Des_2x75[tempal];
++ break;
++ case 12:
++ return &XGI_LVDS1280x1024Des_1x75[tempal];
++ break;
++ case 13:
++ return &XGI_LVDS1280x1024Des_2x75[tempal];
++ break;
++ case 14:
++ return &XGI_LVDSNoScalingDesDatax75[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 4) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_ExtLCD1024x768Data[tempal];
++ break;
++ case 1:
++ return &XGI_StLCD1024x768Data[tempal];
++ break;
++ case 2:
++ return &XGI_CetLCD1024x768Data[tempal];
++ break;
++ case 3:
++ return &XGI_ExtLCD1280x1024Data[tempal];
++ break;
++ case 4:
++ return &XGI_StLCD1280x1024Data[tempal];
++ break;
++ case 5:
++ return &XGI_CetLCD1280x1024Data[tempal];
++ break;
++ case 6:
++ return &XGI_ExtLCD1400x1050Data[tempal];
++ break;
++ case 7:
++ return &XGI_StLCD1400x1050Data[tempal];
++ break;
++ case 8:
++ return &XGI_CetLCD1400x1050Data[tempal];
++ break;
++ case 9:
++ return &XGI_ExtLCD1600x1200Data[tempal];
++ break;
++ case 10:
++ return &XGI_StLCD1600x1200Data[tempal];
++ break;
++ case 11:
++ return &XGI_NoScalingData[tempal];
++ break;
++ case 12:
++ return &XGI_ExtLCD1024x768x75Data[tempal];
++ break;
++ case 13:
++ return &XGI_ExtLCD1024x768x75Data[tempal];
++ break;
++ case 14:
++ return &XGI_CetLCD1024x768x75Data[tempal];
++ break;
++ case 15:
++ return &XGI_ExtLCD1280x1024x75Data[tempal];
++ break;
++ case 16:
++ return &XGI_StLCD1280x1024x75Data[tempal];
++ break;
++ case 17:
++ return &XGI_CetLCD1280x1024x75Data[tempal];
++ break;
++ case 18:
++ return &XGI_NoScalingDatax75[tempal];
++ break;
++ case 19:
++ return &XGI_NoScalingData_1[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 5) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_ExtLCDDes1024x768Data[tempal];
++ break;
++ case 1:
++ return &XGI_StLCDDes1024x768Data[tempal];
++ break;
++ case 2:
++ return &XGI_CetLCDDes1024x768Data[tempal];
++ break;
++ case 3:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_ExtLCDDLDes1280x1024Data[tempal];
++ else
++ return &XGI_ExtLCDDes1280x1024Data[tempal];
++ break;
++ case 4:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_StLCDDLDes1280x1024Data[tempal];
++ else
++ return &XGI_StLCDDes1280x1024Data[tempal];
++ break;
++ case 5:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_CetLCDDLDes1280x1024Data[tempal];
++ else
++ return &XGI_CetLCDDes1280x1024Data[tempal];
++ break;
++ case 6:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_ExtLCDDLDes1400x1050Data[tempal];
++ else
++ return &XGI_ExtLCDDes1400x1050Data[tempal];
++ break;
++ case 7:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_StLCDDLDes1400x1050Data[tempal];
++ else
++ return &XGI_StLCDDes1400x1050Data[tempal];
++ break;
++ case 8:
++ return &XGI_CetLCDDes1400x1050Data[tempal];
++ break;
++ case 9:
++ return &XGI_CetLCDDes1400x1050Data2[tempal];
++ break;
++ case 10:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_ExtLCDDLDes1600x1200Data[tempal];
++ else
++ return &XGI_ExtLCDDes1600x1200Data[tempal];
++ break;
++ case 11:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_StLCDDLDes1600x1200Data[tempal];
++ else
++ return &XGI_StLCDDes1600x1200Data[tempal];
++ break;
++ case 12:
++ return &XGI_NoScalingDesData[tempal];
++ break;
++ case 13:
++ return &XGI_ExtLCDDes1024x768x75Data[tempal];
++ break;
++ case 14:
++ return &XGI_StLCDDes1024x768x75Data[tempal];
++ break;
++ case 15:
++ return &XGI_CetLCDDes1024x768x75Data[tempal];
++ break;
++ case 16:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
++ else
++ return &XGI_ExtLCDDes1280x1024x75Data[tempal];
++ break;
++ case 17:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_StLCDDLDes1280x1024x75Data[tempal];
++ else
++ return &XGI_StLCDDes1280x1024x75Data[tempal];
++ break;
++ case 18:
++ if ((pVBInfo->VBType & VB_XGI301LV)
++ || (pVBInfo->VBType & VB_XGI302LV))
++ return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
++ else
++ return &XGI_CetLCDDes1280x1024x75Data[tempal];
++ break;
++ case 19:
++ return &XGI_NoScalingDesDatax75[tempal];
++ break;
++ case 20:
++ return &XGI_NoScalingDesData_1[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 6) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_CH7017LV1024x768[tempal];
++ break;
++ case 1:
++ return &XGI_CH7017LV1400x1050[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ return 0;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetTVPtr */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++const void *
++XGI_GetTVPtr(USHORT BX, USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT i, tempdx, tempbx, tempal, modeflag, table;
++ const XGI330_TVDataTablStruct *tempdi = NULL;
++
++ tempbx = BX;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
++ }
++
++ tempal = tempal & 0x3f;
++ table = tempbx;
++
++ switch (tempbx) {
++ case 0:
++ tempdi = 0; /*EPLCHTVCRT1Ptr_H; */
++ break;
++ case 1:
++ tempdi = 0; /*EPLCHTVCRT1Ptr_V; */
++ break;
++ case 2:
++ tempdi = XGI_EPLCHTVDataPtr;
++ break;
++ case 3:
++ tempdi = 0;
++ break;
++ case 4:
++ tempdi = XGI_TVDataTable;
++ break;
++ case 5:
++ tempdi = 0;
++ break;
++ case 6:
++ tempdi = XGI_EPLCHTVRegPtr;
++ break;
++ default:
++ break;
++ }
++
++ if (tempdi == 0x00) /* OEMUtil */
++ return (0);
++
++ tempdx = pVBInfo->TVInfo;
++
++ if (pVBInfo->VBInfo & SetInSlaveMode)
++ tempdx = tempdx | SetTVLockMode;
++
++ if (modeflag & HalfDCLK)
++ tempdx = tempdx | SetTVLowResolution;
++
++ i = 0;
++
++ while (tempdi[i].MASK != 0xffff) {
++ if ((tempdx & tempdi[i].MASK) == tempdi[i].CAP)
++ break;
++ i++;
++ }
++
++ if (table == 0x04) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_ExtPALData[tempal];
++ break;
++ case 1:
++ return &XGI_ExtNTSCData[tempal];
++ break;
++ case 2:
++ return &XGI_StPALData[tempal];
++ break;
++ case 3:
++ return &XGI_StNTSCData[tempal];
++ break;
++ case 4:
++ return &XGI_ExtHiTVData[tempal];
++ break;
++ case 5:
++ return &XGI_St2HiTVData[tempal];
++ break;
++ case 6:
++ return &XGI_ExtYPbPr525iData[tempal];
++ break;
++ case 7:
++ return &XGI_ExtYPbPr525pData[tempal];
++ break;
++ case 8:
++ return &XGI_ExtYPbPr750pData[tempal];
++ break;
++ case 9:
++ return &XGI_StYPbPr525iData[tempal];
++ break;
++ case 10:
++ return &XGI_StYPbPr525pData[tempal];
++ break;
++ case 11:
++ return &XGI_StYPbPr750pData[tempal];
++ break;
++ case 12: /* avoid system hang */
++ return &XGI_ExtNTSCData[tempal];
++ break;
++ case 13:
++ return &XGI_St1HiTVData[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 0x02) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_CHTVUNTSCData[tempal];
++ break;
++ case 1:
++ return &XGI_CHTVONTSCData[tempal];
++ break;
++ case 2:
++ return &XGI_CHTVUPALData[tempal];
++ break;
++ case 3:
++ return &XGI_CHTVOPALData[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ else if (table == 0x06) {
++ switch (tempdi[i].DATAPTR) {
++ case 0:
++ return &XGI_CHTVRegUNTSC[tempal];
++ break;
++ case 1:
++ return &XGI_CHTVRegONTSC[tempal];
++ break;
++ case 2:
++ return &XGI_CHTVRegUPAL[tempal];
++ break;
++ case 3:
++ return &XGI_CHTVRegOPAL[tempal];
++ break;
++ default:
++ break;
++ }
++ }
++ return (0);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_BacklightByDrv */
++/* Input : */
++/* Output : TRUE -> Skip backlight control */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_BacklightByDrv(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR tempah;
++
++ tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x3A);
++ if (tempah & BacklightControlBit)
++ return TRUE;
++ else
++ return FALSE;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_FirePWDDisable */
++/* Input : */
++/* Output : */
++/* Description : Turn off VDD & Backlight : Fire disable procedure */
++/* --------------------------------------------------------------------- */
++/*
++void XGI_FirePWDDisable( PVB_DEVICE_INFO pVBInfo )
++{
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port , 0x26 , 0x00 , 0xFC ) ;
++}
++*/
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_FirePWDEnable */
++/* Input : */
++/* Output : */
++/* Description : Turn on VDD & Backlight : Fire enable procedure */
++/* --------------------------------------------------------------------- */
++void
++XGI_FirePWDEnable(PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x26, 0x03, 0xFC);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_EnableGatingCRT */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_EnableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x40);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_DisableGatingCRT */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_DisableGatingCRT(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3d4, 0x63, 0xBF, 0x00);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetPanelDelay */
++/* Input : */
++/* Output : */
++/* Description : */
++/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
++/* : bl : 2 ; T2 : the duration signal on and Vdd on */
++/* : bl : 3 ; T3 : the duration between CPL off and signal off */
++/* : bl : 4 ; T4 : the duration signal off and Vdd off */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT index;
++#ifndef LINUX_XF86
++ USHORT temp;
++#endif
++
++ index = XGI_GetLCDCapPtr(pVBInfo);
++
++ if (tempbl == 1)
++ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S1, pVBInfo);
++
++ if (tempbl == 2)
++ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S2, pVBInfo);
++
++ if (tempbl == 3)
++ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S3, pVBInfo);
++
++ if (tempbl == 4)
++ XGINew_LCD_Wait_Time(pVBInfo->LCDCapList[index].PSC_S4, pVBInfo);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetPanelPower */
++/* Input : */
++/* Output : */
++/* Description : */
++/* I/O : ah = 0011b = 03h ; Backlight on, Power on */
++/* = 0111b = 07h ; Backlight on, Power off */
++/* = 1011b = 0Bh ; Backlight off, Power on */
++/* = 1111b = 0Fh ; Backlight off, Power off */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetPanelPower(USHORT tempah, USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
++{
++ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x26, tempbl,
++ tempah);
++ else
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->P3c4, 0x11, tempbl, tempah);
++}
++
++/* Jong 10/04/2007; merge code */
++UCHAR XG21GPIODataTransfer(UCHAR ujDate)
++{
++ UCHAR ujRet = 0;
++ UCHAR i = 0;
++
++ for (i=0; i<8; i++)
++ {
++ ujRet = ujRet << 1;
++ /* ujRet |= GETBITS(ujDate >> i, 0:0); */
++ ujRet |= (ujDate >> i) & 1;
++ }
++
++ return ujRet;
++}
++
++/* Jong 10/04/2007; merge code */
++/*----------------------------------------------------------------------------*/
++/* output */
++/* bl[5] : LVDS signal */
++/* bl[1] : LVDS backlight */
++/* bl[0] : LVDS VDD */
++/*----------------------------------------------------------------------------*/
++UCHAR XGI_XG21GetPSCValue(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CR4A,temp;
++
++ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x23 ) ; /* enable GPIO write */
++
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
++
++ temp = XG21GPIODataTransfer(temp);
++ temp &= 0x23;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , CR4A ) ;
++ return temp;
++}
++
++/* Jong 10/04/2007; merge code */
++/*----------------------------------------------------------------------------*/
++/* output */
++/* bl[5] : LVDS signal */
++/* bl[1] : LVDS backlight */
++/* bl[0] : LVDS VDD */
++/*----------------------------------------------------------------------------*/
++UCHAR XGI_XG27GetPSCValue(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CR4A,CRB4,temp;
++
++ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~0x0C ) ; /* enable GPIO write */
++
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 ) ;
++
++ temp &= 0x0C;
++ temp >>= 2;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , CR4A ) ;
++ CRB4 = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 ) ;
++ temp |= ((CRB4&0x04)<<3);
++ return temp;
++}
++
++/* Jong 10/04/2007; merge code */
++/*----------------------------------------------------------------------------*/
++/* input */
++/* bl[5] : 1;LVDS signal on */
++/* bl[1] : 1;LVDS backlight on */
++/* bl[0] : 1:LVDS VDD on */
++/* bh: 100000b : clear bit 5, to set bit5 */
++/* 000010b : clear bit 1, to set bit1 */
++/* 000001b : clear bit 0, to set bit0 */
++/*----------------------------------------------------------------------------*/
++void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CR4A,temp;
++
++ CR4A = XGI_GetReg( (XGIIOADDRESS)pVBInfo->P3d4 , 0x4A ) ;
++ tempbh &= 0x23;
++ tempbl &= 0x23;
++ XGI_SetRegAND( (XGIIOADDRESS)pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
++
++ if (tempbh&0x20)
++ {
++ temp = (tempbl>>4)&0x02;
++
++ XGI_SetRegANDOR( (XGIIOADDRESS)pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
++
++ }
++
++ temp = XGI_GetReg( (XGIIOADDRESS)pVBInfo->P3d4 , 0x48 ) ;
++
++ temp = XG21GPIODataTransfer(temp);
++
++ temp &= ~tempbh;
++ temp |= tempbl;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , temp ) ;
++}
++
++/* Jong 10/04/2007; merge code */
++void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR CR4A,temp;
++ USHORT tempbh0,tempbl0;
++
++ tempbh0 = tempbh;
++ tempbl0 = tempbl;
++ tempbh0 &= 0x20;
++ tempbl0 &= 0x20;
++ tempbh0 >>= 3;
++ tempbl0 >>= 3;
++
++ if (tempbh&0x20)
++ {
++ temp = (tempbl>>4)&0x02;
++
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , ~0x02 , temp) ; /* CR B4[1] */
++
++ }
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0xB4 , ~tempbh0 , tempbl0 ) ;
++
++ CR4A = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A ) ;
++ tempbh &= 0x03;
++ tempbl &= 0x03;
++ tempbh <<= 2;
++ tempbl <<= 2; /* GPIOC,GPIOD */
++ XGI_SetRegAND( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4A , ~tempbh ) ; /* enable GPIO write */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x48 , ~tempbh , tempbl ) ;
++}
++
++/* Jong 10/04/2007; merge code */
++/* --------------------------------------------------------------------- */
++USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT index ;
++
++ index = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x36 ) ;
++ if (index<sizeof(XGI21_LCDCapList)/sizeof(XGI21_LVDSCapStruct))
++ {
++ return index;
++ }
++ return 0;
++}
++
++/* Jong 10/04/2007; merge code */
++/* --------------------------------------------------------------------- */
++/* Function : XGI_XG21SetPanelDelay */
++/* Input : */
++/* Output : */
++/* Description : */
++/* I/P : bl : 1 ; T1 : the duration between CPL on and signal on */
++/* : bl : 2 ; T2 : the duration signal on and Vdd on */
++/* : bl : 3 ; T3 : the duration between CPL off and signal off */
++/* : bl : 4 ; T4 : the duration signal off and Vdd off */
++/* --------------------------------------------------------------------- */
++void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT index ;
++
++ index = XGI_GetLVDSOEMTableIndex( pVBInfo );
++ if ( tempbl == 1 )
++ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S1, pVBInfo ) ;
++
++ if ( tempbl == 2 )
++ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S2, pVBInfo ) ;
++
++ if ( tempbl == 3 )
++ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S3, pVBInfo ) ;
++
++ if ( tempbl == 4 )
++ XGINew_LCD_Wait_Time( pVBInfo->XG21_LVDSCapList[ index ].PSC_S4, pVBInfo ) ;
++}
++
++/* Jong 10/04/2007; merge code */
++BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
++{
++ USHORT xres ,
++ yres ,
++ colordepth ,
++ modeflag ,
++ resindex ,
++ lvdstableindex;
++
++ resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
++ if ( ModeNo <= 0x13 )
++ {
++ xres = pVBInfo->StResInfo[ resindex ].HTotal ;
++ yres = pVBInfo->StResInfo[ resindex ].VTotal ;
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ }
++ else
++ {
++ xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
++ yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
++ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
++ }
++
++ if ( !( modeflag & Charx8Dot ) )
++ {
++ xres /= 9;
++ xres *= 8;
++ }
++
++ if ( ModeNo > 0x13 )
++ {
++ if ( ( ModeNo>0x13 ) && ( modeflag & HalfDCLK ) )
++ {
++ xres *= 2 ;
++ }
++ if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
++ {
++ yres *= 2 ;
++ }
++ }
++
++ lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
++ if ( xres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) )
++ return FALSE;
++
++ if ( yres > (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE) )
++ return FALSE;
++
++ if ( ModeNo > 0x13 )
++ {
++ if ( ( xres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE) ) ||
++ ( yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE)) )
++ {
++ colordepth = XGI_GetColorDepth( ModeNo , ModeIdIndex, pVBInfo ) ;
++ if ( colordepth > 2 )
++ {
++ return FALSE;
++ }
++ }
++ }
++ return TRUE;
++}
++
++/* Jong 10/04/2007; merge code */
++void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR temp;
++
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 ) ; /* D[0] 1: 18bit */
++ temp = ( temp & 1 ) << 6;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x06 , ~0x40 , temp ) ; /* SR06[6] 18bit Dither */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
++
++}
++
++/* Jong 10/04/2007; merge code */
++void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR temp;
++
++ temp = XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x37 ) ; /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
++ temp = ( temp & 3 ) << 6;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x06 , ~0xc0 , temp & 0x80 ) ; /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x09 , ~0xc0 , temp | 0x80 ) ; /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
++
++}
++
++/* Jong 10/04/2007; merge code */
++void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
++{
++ UCHAR temp,Miscdata;
++ USHORT xres ,
++ yres ,
++ colordepth ,
++ modeflag ,
++ resindex ,
++ lvdstableindex ;
++ USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
++ USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
++ USHORT value;
++
++ lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
++
++ temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
++ temp &= LCDPolarity;
++ Miscdata =(UCHAR) XGI_GetRegByte(pVBInfo->P3cc) ;
++
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
++
++ temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
++
++ XGI_SetXG21FPBits(pVBInfo);
++ resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
++ if ( ModeNo <= 0x13 )
++ {
++ xres = pVBInfo->StResInfo[ resindex ].HTotal ;
++ yres = pVBInfo->StResInfo[ resindex ].VTotal ;
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ }
++ else
++ {
++ xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
++ yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
++ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
++ }
++
++ if (!( modeflag & Charx8Dot ))
++ xres = xres * 8 / 9;
++
++ LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
++
++ LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
++ if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
++ {
++ LVDSHBS -= xres/4 ;
++ }
++ if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
++
++ LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
++ if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
++
++ LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
++ if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
++
++ LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
++
++ LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
++
++ LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
++ if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
++ {
++ LVDSVBS += yres/2 ;
++ }
++ if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
++
++ LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
++ if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
++
++ LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
++ if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
++
++ LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
++
++ temp = ( UCHAR )XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
++
++ if (!( modeflag & Charx8Dot ))
++ {
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1 , 0x1 ) ;
++ }
++
++ /* HT SR0B[1:0] CR00 */
++ value = ( LVDSHT >> 3 ) - 5;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
++
++ /* HBS SR0B[5:4] CR02 */
++ value = ( LVDSHBS >> 3 ) - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
++
++ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
++ value = ( LVDSHBE >> 3 ) - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
++
++ /* HRS SR0B[7:6] CR04 */
++ value = ( LVDSHRS >> 3 ) + 2;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
++
++ /* Panel HRS SR2F[1:0] SR2E[7:0] */
++ value--;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
++
++ /* HRE SR0C[2] CR05[4:0] */
++ value = ( LVDSHRE >> 3 ) + 2;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
++
++ /* Panel HRE SR2F[7:2] */
++ value--;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
++
++ /* VT SR0A[0] CR07[5][0] CR06 */
++ value = LVDSVT - 2 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
++
++ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
++ value = LVDSVBS - 1 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
++
++ /* VBE SR0A[4] CR16 */
++ value = LVDSVBE - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
++
++ /* VRS SR0A[3] CR7[7][2] CR10 */
++ value = LVDSVRS - 1 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
++
++ /* Panel VRS SR3F[1:0] SR34[7:0] SR33[0] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0x03 , ( value & 0x600 ) >> 9 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , (value >> 1) & 0xFF ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x33 , ~0x01 , value & 0x01 ) ;
++
++ /* VRE SR0A[5] CR11[3:0] */
++ value = LVDSVRE - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
++
++ /* Panel VRE SR3F[7:2] */ /* SR3F[7] has to be 0, h/w bug */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0x7C ) ;
++
++ for ( temp=0, value = 0; temp < 3; temp++)
++ {
++
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
++ value += 0x10;
++ }
++
++ if (!( modeflag & Charx8Dot ))
++ {
++ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x13 ) ; /* set index */
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
++
++ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* Enable Attribute */
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x20 ) ;
++
++ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
++ }
++
++
++}
++
++/* Jong 10/04/2007; merge code */
++/* no shadow case */
++void XGI_SetXG27LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo )
++{
++ UCHAR temp,Miscdata;
++ USHORT xres ,
++ yres ,
++ colordepth ,
++ modeflag ,
++ resindex ,
++ lvdstableindex ;
++ USHORT LVDSHT,LVDSHBS,LVDSHRS,LVDSHRE,LVDSHBE;
++ USHORT LVDSVT,LVDSVBS,LVDSVRS,LVDSVRE,LVDSVBE;
++ USHORT value;
++
++ lvdstableindex = XGI_GetLVDSOEMTableIndex( pVBInfo );
++ temp = (UCHAR) ( ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & (LCDPolarity << 8 ) ) >> 8 );
++ temp &= LCDPolarity;
++ Miscdata =(UCHAR) XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3cc) ;
++
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c2 , (Miscdata & 0x3F) | temp ) ;
++
++ temp = (UCHAR) ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability & LCDPolarity ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x80 , temp&0x80 ) ; /* SR35[7] FP VSync polarity */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x30 , ~0x20 , (temp&0x40)>>1 ) ; /* SR30[5] FP HSync polarity */
++
++ XGI_SetXG27FPBits(pVBInfo);
++ resindex = XGI_GetResInfo( ModeNo , ModeIdIndex, pVBInfo ) ;
++ if ( ModeNo <= 0x13 )
++ {
++ xres = pVBInfo->StResInfo[ resindex ].HTotal ;
++ yres = pVBInfo->StResInfo[ resindex ].VTotal ;
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
++ }
++ else
++ {
++ xres = pVBInfo->ModeResInfo[ resindex ].HTotal ; /* xres->ax */
++ yres = pVBInfo->ModeResInfo[ resindex ].VTotal ; /* yres->bx */
++ modeflag = pVBInfo->EModeIDTable[ ModeIdIndex].Ext_ModeFlag ; /* si+St_ModeFlag */
++ }
++
++ if (!( modeflag & Charx8Dot ))
++ xres = xres * 8 / 9;
++
++ LVDSHT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHT;
++
++ LVDSHBS = xres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE - xres ) / 2 ;
++ if ( ( ModeNo<=0x13 ) && ( modeflag & HalfDCLK ) )
++ {
++ LVDSHBS -= xres/4 ;
++ }
++ if (LVDSHBS > LVDSHT) LVDSHBS -= LVDSHT ;
++
++ LVDSHRS = LVDSHBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHFP ;
++ if (LVDSHRS > LVDSHT) LVDSHRS -= LVDSHT ;
++
++ LVDSHRE = LVDSHRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHSYNC ;
++ if (LVDSHRE > LVDSHT) LVDSHRE -= LVDSHT ;
++
++ LVDSHBE = LVDSHBS + LVDSHT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE ;
++
++ LVDSVT = pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVT;
++
++ LVDSVBS = yres + ( pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE - yres ) / 2 ;
++ if ( ( ModeNo>0x13 ) && ( modeflag & DoubleScanMode ) )
++ {
++ LVDSVBS += yres/2 ;
++ }
++ if (LVDSVBS > LVDSVT) LVDSVBS -= LVDSVT ;
++
++ LVDSVRS = LVDSVBS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVFP ;
++ if (LVDSVRS > LVDSVT) LVDSVRS -= LVDSVT ;
++
++ LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC ;
++ if (LVDSVRE > LVDSVT) LVDSVRE -= LVDSVT ;
++
++ LVDSVBE = LVDSVBS + LVDSVT - pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE ;
++
++ temp = ( UCHAR )XGI_GetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , temp & 0x7f ) ; /* Unlock CRTC */
++
++ if (!( modeflag & Charx8Dot ))
++ {
++ XGI_SetRegOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x1 , 0x1 ) ;
++ }
++
++ /* HT SR0B[1:0] CR00 */
++ value = ( LVDSHT >> 3 ) - 5;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x03 , ( value & 0x300 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x0 , (value & 0xFF) ) ;
++
++ /* HBS SR0B[5:4] CR02 */
++ value = ( LVDSHBS >> 3 ) - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0x30 , ( value & 0x300 ) >> 4 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x2 , (value & 0xFF) ) ;
++
++ /* HBE SR0C[1:0] CR05[7] CR03[4:0] */
++ value = ( LVDSHBE >> 3 ) - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x03 , ( value & 0xC0 ) >> 6 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x80 , ( value & 0x20 ) << 2 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x03 , ~0x1F , value & 0x1F ) ;
++
++ /* HRS SR0B[7:6] CR04 */
++ value = ( LVDSHRS >> 3 ) + 2;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0B , ~0xC0 , ( value & 0x300 ) >> 2 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x4 , (value & 0xFF) ) ;
++
++ /* Panel HRS SR2F[1:0] SR2E[7:0] */
++ value--;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0x03 , ( value & 0x300 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2E , (value & 0xFF) ) ;
++
++ /* HRE SR0C[2] CR05[4:0] */
++ value = ( LVDSHRE >> 3 ) + 2;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0C , ~0x04 , ( value & 0x20 ) >> 3 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x05 , ~0x1F , value & 0x1F ) ;
++
++ /* Panel HRE SR2F[7:2] */
++ value--;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2F , ~0xFC , value << 2 ) ;
++
++ /* VT SR0A[0] CR07[5][0] CR06 */
++ value = LVDSVT - 2 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x01 , ( value & 0x400 ) >> 10 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x01 , ( value & 0x100 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x06 , (value & 0xFF) ) ;
++
++ /* VBS SR0A[2] CR09[5] CR07[3] CR15 */
++ value = LVDSVBS - 1 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x04 , ( value & 0x400 ) >> 8 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x09 , ~0x20 , ( value & 0x200 ) >> 4 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x08 , ( value & 0x100 ) >> 5 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x15 , (value & 0xFF) ) ;
++
++ /* VBE SR0A[4] CR16 */
++ value = LVDSVBE - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x10 , ( value & 0x100 ) >> 4 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x16 , (value & 0xFF) ) ;
++
++ /* VRS SR0A[3] CR7[7][2] CR10 */
++ value = LVDSVRS - 1 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x08 , ( value & 0x400 ) >> 7 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x80 , ( value & 0x200 ) >> 2 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x07 , ~0x04 , ( value & 0x100 ) >> 6 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3d4 , 0x10 , (value & 0xFF) ) ;
++
++ /* Panel VRS SR35[2:0] SR34[7:0] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x35 , ~0x07 , ( value & 0x700 ) >> 8 ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x34 , value & 0xFF ) ;
++
++ /* VRE SR0A[5] CR11[3:0] */
++ value = LVDSVRE - 1;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x0A , ~0x20 , ( value & 0x10 ) << 1 ) ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3d4 , 0x11 , ~0x0F , value & 0x0F ) ;
++
++ /* Panel VRE SR3F[7:2] */
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x3F , ~0xFC , ( value << 2 ) & 0xFC ) ;
++
++ for ( temp=0, value = 0; temp < 3; temp++)
++ {
++
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->P3c4 , 0x31 , ~0x30 , value ) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2B , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1) ;
++ XGI_SetReg( (XGIIOADDRESS) pVBInfo->P3c4 , 0x2C , pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2) ;
++ value += 0x10;
++ }
++
++ if (!( modeflag & Charx8Dot ))
++ {
++ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x13 ) ; /* set index */
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x00 ) ; /* set data, panning = 0, shift left 1 dot*/
++
++ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* Enable Attribute */
++ XGI_SetRegByte( (XGIIOADDRESS) pVBInfo->P3c0 , 0x20 ) ;
++
++ XGI_GetRegByte( (XGIIOADDRESS) pVBInfo->P3da ) ; /* reset 3da */
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_IsLCDON */
++/* Input : */
++/* Output : FALSE : Skip PSC Control */
++/* TRUE: Disable PSC */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_IsLCDON(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax;
++
++ tempax = pVBInfo->VBInfo;
++ if (tempax & SetCRT2ToDualEdge)
++ return FALSE;
++ else if (tempax & (DisableCRT2Display | SwitchToCRT2 | SetSimuScanMode))
++ return TRUE;
++
++ return FALSE;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_EnablePWD */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_EnablePWD(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT index, temp;
++
++ index = XGI_GetLCDCapPtr(pVBInfo);
++ temp = pVBInfo->LCDCapList[index].PWD_2B;
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2B, temp);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2C,
++ pVBInfo->LCDCapList[index].PWD_2C);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2D,
++ pVBInfo->LCDCapList[index].PWD_2D);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2E,
++ pVBInfo->LCDCapList[index].PWD_2E);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x2F,
++ pVBInfo->LCDCapList[index].PWD_2F);
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x80); /* enable PWD */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_DisablePWD */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_DisablePWD(PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x7F); /* disable PWD */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_DisableChISLCD */
++/* Input : */
++/* Output : FALSE -> Not LCD Mode */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_DisableChISLCD(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, tempah;
++
++ tempbx = pVBInfo->SetFlag & (DisableChA | DisableChB);
++ tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
++
++ if (tempbx & (EnableChA | DisableChA)) {
++ if (!(tempah & 0x08)) /* Chk LCDA Mode */
++ return FALSE;
++ }
++
++ if (!(tempbx & (EnableChB | DisableChB)))
++ return FALSE;
++
++ if (tempah & 0x01) /* Chk LCDB Mode */
++ return TRUE;
++
++ return FALSE;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_EnableChISLCD */
++/* Input : */
++/* Output : 0 -> Not LCD mode */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_EnableChISLCD(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, tempah;
++
++
++ tempbx = pVBInfo->SetFlag & (EnableChA | EnableChB);
++ tempah = ~((USHORT) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E));
++
++ if (tempbx & (EnableChA | DisableChA)) {
++ if (!(tempah & 0x08)) /* Chk LCDA Mode */
++ return FALSE;
++ }
++
++ if (!(tempbx & (EnableChB | DisableChB)))
++ return FALSE;
++
++ if (tempah & 0x01) /* Chk LCDB Mode */
++ return TRUE;
++
++ return FALSE;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetLCDCapPtr */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetLCDCapPtr(PVB_DEVICE_INFO pVBInfo)
++{
++ UCHAR tempal, tempah, tempbl, i;
++
++ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x36);
++ tempal = tempah & 0x0F;
++ tempah = tempah & 0xF0;
++ i = 0;
++ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
++
++ while (tempbl != 0xFF) {
++ if (tempbl & 0x80) { /* OEMUtil */
++ tempal = tempah;
++ tempbl = tempbl & ~(0x80);
++ }
++
++ if (tempal == tempbl)
++ break;
++
++ i++;
++
++ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
++ }
++
++ return i;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetLCDCapPtr1 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetLCDCapPtr1(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempah, tempal, tempbl, i;
++
++ tempal = pVBInfo->LCDResInfo;
++ tempah = pVBInfo->LCDTypeInfo;
++
++ i = 0;
++ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
++
++ while (tempbl != 0xFF) {
++ if ((tempbl & 0x80) && (tempbl != 0x80)) {
++ tempal = tempah;
++ tempbl &= ~0x80;
++ }
++
++ if (tempal == tempbl)
++ break;
++
++ i++;
++ tempbl = pVBInfo->LCDCapList[i].LCD_ID;
++ }
++
++ if (tempbl == 0xFF) {
++ pVBInfo->LCDResInfo = Panel1024x768;
++ pVBInfo->LCDTypeInfo = 0;
++ i = 0;
++ }
++
++ return i;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetLCDSync */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetLCDSync(USHORT * HSyncWidth, USHORT * VSyncWidth,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT Index;
++
++ Index = XGI_GetLCDCapPtr(pVBInfo);
++ *HSyncWidth = pVBInfo->LCDCapList[Index].LCD_HSyncWidth;
++ *VSyncWidth = pVBInfo->LCDCapList[Index].LCD_VSyncWidth;
++
++ return;
++}
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_EnableBridge */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++#ifndef LINUX_XF86
++ USHORT tempax;
++#endif
++ USHORT tempbl, tempah;
++
++ if (pVBInfo->SetFlag == Win9xDOSMode) {
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
++ return;
++ }
++ else /* LVDS or CH7017 */
++ return;
++ }
++
++
++ if (HwDeviceExtension->jChipType < XG40) {
++ if (!XGI_DisableChISLCD(pVBInfo)) {
++ if ((XGI_EnableChISLCD(pVBInfo))
++ || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) {
++ if (pVBInfo->LCDInfo & SetPWDEnable) {
++ XGI_EnablePWD(pVBInfo);
++ }
++ else {
++ pVBInfo->LCDInfo &= (~SetPWDEnable);
++ if (pVBInfo->
++ VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
++ tempbl = 0xFD;
++ tempah = 0x02;
++ }
++ else {
++ tempbl = 0xFB;
++ tempah = 0x00;
++ }
++
++ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
++ XGI_SetPanelDelay(1, pVBInfo);
++ }
++ }
++ }
++ } /* Not 340 */
++
++
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (!(pVBInfo->SetFlag & DisableChA)) {
++ if (pVBInfo->SetFlag & EnableChA) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
++ }
++ else {
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
++ }
++ }
++ }
++
++ if (!(pVBInfo->SetFlag & DisableChB)) {
++ if ((pVBInfo->SetFlag & EnableChB)
++ || (pVBInfo->
++ VBInfo & (SetCRT2ToLCD | SetCRT2ToTV | SetCRT2ToRAMDAC)))
++ {
++ tempah =
++ (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32);
++ tempah &= 0xDF;
++ if (pVBInfo->VBInfo & SetInSlaveMode) {
++ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
++ tempah |= 0x20;
++ }
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->P3c4, 0x32, tempah);
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E,
++ SR1E_ENABLE_CRT2);
++
++
++ tempah =
++ (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port,
++ 0x2E);
++
++ if (!(tempah & 0x80))
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
++
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
++ }
++ }
++
++ if ((pVBInfo->SetFlag & (EnableChA | EnableChB))
++ || (!(pVBInfo->VBInfo & DisableCRT2Display))) {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, ~0xE0, 0x20); /* shampoo 0129 */
++ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
++ if (!XGI_DisableChISLCD(pVBInfo)) {
++ if (XGI_EnableChISLCD(pVBInfo)
++ || (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x2A, 0x7F); /* LVDS PLL power on */
++ }
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
++ }
++ }
++
++ tempah = 0x00;
++
++ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
++ tempah = 0xc0;
++
++ if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
++ tempah = tempah & 0x40;
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
++ tempah = tempah ^ 0xC0;
++
++ if (pVBInfo->SetFlag & DisableChB)
++ tempah &= 0xBF;
++
++ if (pVBInfo->SetFlag & DisableChA)
++ tempah &= 0x7F;
++
++ if (pVBInfo->SetFlag & EnableChB)
++ tempah |= 0x40;
++
++ if (pVBInfo->SetFlag & EnableChA)
++ tempah |= 0x80;
++ }
++ }
++ }
++ }
++
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
++
++ if (pVBInfo->SetFlag & Win9xDOSMode) {
++ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
++ return;
++ }
++
++ if (!(pVBInfo->SetFlag & DisableChA)) {
++ XGI_VBLongWait(pVBInfo);
++ if (!(pVBInfo->SetFlag & GatingCRT)) {
++ XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
++ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
++ XGI_VBLongWait(pVBInfo);
++ }
++ }
++ } /* 301 */
++ else { /* LVDS */
++
++ if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD | SetCRT2ToLCDA))
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
++
++
++
++ tempah = (UCHAR) XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E);
++ if (!(tempah & 0x80))
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
++
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x7F);
++ XGI_DisplayOn(HwDeviceExtension, pVBInfo);
++ } /* End of VB */
++
++
++ if (HwDeviceExtension->jChipType < XG40) {
++ if (!XGI_EnableChISLCD(pVBInfo)) {
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ if (XGI_BacklightByDrv(pVBInfo))
++ return;
++ }
++ else
++ return;
++ }
++
++ if (pVBInfo->LCDInfo & SetPWDEnable) {
++ XGI_FirePWDEnable(pVBInfo);
++ return;
++ }
++
++ XGI_SetPanelDelay(2, pVBInfo);
++
++ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
++ tempah = 0x01;
++ tempbl = 0xFE; /* turn on backlght */
++ }
++ else {
++ tempbl = 0xF7;
++ tempah = 0x00;
++ }
++ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_DisableBridge */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, tempbx, tempah = 0, tempbl = 0;
++
++ if (pVBInfo->SetFlag == Win9xDOSMode)
++ return;
++
++
++ if (HwDeviceExtension->jChipType < XG40) {
++ if ((!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
++ || (XGI_DisableChISLCD(pVBInfo))) {
++ if (!XGI_IsLCDON(pVBInfo)) {
++ if (pVBInfo->LCDInfo & SetPWDEnable)
++ XGI_EnablePWD(pVBInfo);
++ else {
++ pVBInfo->LCDInfo &= ~SetPWDEnable;
++ XGI_DisablePWD(pVBInfo);
++ if (pVBInfo->
++ VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
++ tempbx = 0xFE; /* not 01h */
++ tempax = 0;
++ }
++ else {
++ tempbx = 0xF7; /* not 08h */
++ tempax = 0x08;
++ }
++ XGI_SetPanelPower(tempax, tempbx, pVBInfo);
++ XGI_SetPanelDelay(3, pVBInfo);
++ }
++ } /* end if(!XGI_IsLCDON(pVBInfo)) */
++ }
++ }
++
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ tempah = 0x3F;
++ if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
++ tempah = 0x7F; /* Disable Channel A */
++ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
++ tempah = 0xBF; /* Disable Channel B */
++
++ if (pVBInfo->SetFlag & DisableChB)
++ tempah &= 0xBF; /* force to disable Cahnnel */
++
++ if (pVBInfo->SetFlag & DisableChA)
++ tempah &= 0x7F; /* Force to disable Channel B */
++ }
++ }
++ }
++
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
++
++ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
++ if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
++ || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo)))
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
++ }
++
++ if ((pVBInfo->SetFlag & DisableChA)
++ || (pVBInfo->
++ VBInfo & (DisableCRT2Display | SetCRT2ToLCDA |
++ SetSimuScanMode))) {
++ if (pVBInfo->SetFlag & GatingCRT)
++ XGI_EnableGatingCRT(HwDeviceExtension, pVBInfo);
++ XGI_DisplayOff(HwDeviceExtension, pVBInfo);
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ if ((pVBInfo->SetFlag & DisableChA)
++ || (pVBInfo->VBInfo & SetCRT2ToLCDA))
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
++ }
++
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
++
++ if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part2Port, 0x00, 0xdf);
++
++ if ((pVBInfo->SetFlag & DisableChB)
++ || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
++ || ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
++ && (pVBInfo->
++ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
++
++ if ((pVBInfo->SetFlag & DisableChB)
++ || (pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))
++ || (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
++ || (pVBInfo->
++ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
++ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
++ }
++ }
++ else { /* {301} */
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
++ }
++
++ if (pVBInfo->
++ VBInfo & (DisableCRT2Display | SetCRT2ToLCDA | SetSimuScanMode))
++ XGI_DisplayOff(HwDeviceExtension,pVBInfo);
++ }
++
++
++
++
++ if (HwDeviceExtension->jChipType < XG40) {
++ if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
++ || (XGI_DisableChISLCD(pVBInfo)) || (XGI_IsLCDON(pVBInfo))) {
++ if (pVBInfo->LCDInfo & SetPWDEnable) {
++ if (pVBInfo->LCDInfo & SetPWDEnable)
++ XGI_BacklightByDrv(pVBInfo);
++ else {
++ XGI_SetPanelDelay(4, pVBInfo);
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ tempbl = 0xFD;
++ tempah = 0x00;
++ }
++ else {
++ tempbl = 0xFB;
++ tempah = 0x04;
++ }
++ }
++ }
++ XGI_SetPanelPower(tempah, tempbl, pVBInfo);
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetTVPtrIndex */
++/* Input : */
++/* Output : */
++/* Description : bx 0 : ExtNTSC */
++/* 1 : StNTSC */
++/* 2 : ExtPAL */
++/* 3 : StPAL */
++/* 4 : ExtHiTV */
++/* 5 : StHiTV */
++/* 6 : Ext525i */
++/* 7 : St525i */
++/* 8 : Ext525p */
++/* 9 : St525p */
++/* A : Ext750p */
++/* B : St750p */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetTVPtrIndex(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx = 0;
++
++ if (pVBInfo->TVInfo & SetPALTV)
++ tempbx = 2;
++ if (pVBInfo->TVInfo & SetYPbPrMode1080i)
++ tempbx = 4;
++ if (pVBInfo->TVInfo & SetYPbPrMode525i)
++ tempbx = 6;
++ if (pVBInfo->TVInfo & SetYPbPrMode525p)
++ tempbx = 8;
++ if (pVBInfo->TVInfo & SetYPbPrMode750p)
++ tempbx = 10;
++ if (pVBInfo->TVInfo & TVSimuMode)
++ tempbx++;
++
++ return tempbx;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_OEM310Setting */
++/* Input : */
++/* Output : */
++/* Description : Customized Param. for 301 */
++/* --------------------------------------------------------------------- */
++void
++XGI_OEM310Setting(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ if (pVBInfo->SetFlag & Win9xDOSMode)
++ return;
++
++ /* GetPart1IO(); */
++ XGI_SetDelayComp(pVBInfo);
++
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))
++ XGI_SetLCDCap(pVBInfo);
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ /* GetPart2IO() */
++ XGI_SetPhaseIncr(pVBInfo);
++ XGI_SetYFilter(ModeNo, ModeIdIndex, pVBInfo);
++ XGI_SetAntiFlicker(ModeNo, ModeIdIndex, pVBInfo);
++
++ if (pVBInfo->VBType & VB_XGI301)
++ XGI_SetEdgeEnhance(ModeNo, ModeIdIndex, pVBInfo);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetDelayComp */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetDelayComp(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT index;
++
++ UCHAR tempah, tempbl, tempbh;
++#ifndef LINUX_XF86
++ UCHAR temp;
++#endif
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (pVBInfo->
++ VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA | SetCRT2ToTV |
++ SetCRT2ToRAMDAC)) {
++ tempbl = 0;
++ tempbh = 0;
++
++ index = XGI_GetTVPtrIndex(pVBInfo); /* Get TV Delay */
++ tempbl = pVBInfo->XGI_TVDelayList[index];
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV
++ | VB_XGI301C))
++ tempbl = pVBInfo->XGI_TVDelayList2[index];
++
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
++ tempbl = tempbl >> 4;
++/*
++ if ( pVBInfo->VBInfo & SetCRT2ToRAMDAC )
++ tempbl = CRT2Delay1 ; // Get CRT2 Delay
++
++ if ( pVBInfo->VBType & ( VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C ) )
++ tempbl = CRT2Delay2 ;
++*/
++ if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
++ index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
++ tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
++ tempbl = tempbh;
++ }
++
++ tempbl &= 0x0F;
++ tempbh &= 0xF0;
++ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D);
++
++ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV)) { /* Channel B */
++ tempah &= 0xF0;
++ tempah |= tempbl;
++ }
++
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) { /* Channel A */
++ tempah &= 0x0F;
++ tempah |= tempbh;
++ }
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x2D, tempah);
++ }
++ }
++ /* Jong 10/04/2007; merge code */
++ else if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ tempbl = 0;
++ tempbh = 0;
++ if ( pVBInfo->VBInfo & SetCRT2ToLCD )
++ {
++ tempah = pVBInfo->LCDCapList[ XGI_GetLCDCapPtr(pVBInfo) ].LCD_DelayCompensation ; /* / Get LCD Delay */
++ tempah &= 0x0f ;
++ tempah = tempah << 4 ;
++ XGI_SetRegANDOR( (XGIIOADDRESS) pVBInfo->Part1Port , 0x2D , 0x0f , tempah ) ;
++ }
++ }
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLCDCap */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLCDCap(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempcx;
++
++ tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
++ /* Set 301LV Capability */
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x24,
++ (UCHAR) (tempcx & 0x1F));
++ }
++ /* VB Driving */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D,
++ ~((EnableVBCLKDRVLOW | EnablePLLSPLOW) >> 8),
++ (USHORT) ((tempcx &
++ (EnableVBCLKDRVLOW | EnablePLLSPLOW)) >>
++ 8));
++ }
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if (pVBInfo->VBInfo & SetCRT2ToLCD)
++ XGI_SetLCDCap_B(tempcx, pVBInfo);
++ else if (pVBInfo->VBInfo & SetCRT2ToLCDA)
++ XGI_SetLCDCap_A(tempcx, pVBInfo);
++
++ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
++ if (tempcx & EnableSpectrum)
++ SetSpectrum(pVBInfo);
++ }
++ }
++ else /* LVDS,CH7017 */
++ XGI_SetLCDCap_A(tempcx, pVBInfo);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLCDCap_A */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLCDCap_A(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT temp;
++
++ temp = XGI_GetReg((XGIIOADDRESS) pVBInfo->P3d4, 0x37);
++
++ if (temp & LCDRGB18Bit) {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F, (USHORT) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
++ }
++ else {
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x19, 0x0F,
++ (USHORT) (0x30 | (tempcx & 0x00C0)));
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
++ }
++
++/*
++ if ( tempcx & EnableLCD24bpp ) // 24bits
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x30|(tempcx&0x00C0)) );
++ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x00);
++ }
++ else
++ {
++ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x19, 0x0F,(USHORT)(0x20|(tempcx&0x00C0)) );//Enable Dither
++ XGI_SetRegANDOR((XGIIOADDRESS)pVBInfo->Part1Port,0x1A,0x7F,0x80);
++ }
++*/
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetLCDCap_B */
++/* Input : cx -> LCD Capability */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetLCDCap_B(USHORT tempcx, PVB_DEVICE_INFO pVBInfo)
++{
++ if (tempcx & EnableLCD24bpp) /* 24bits */
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0,
++ (USHORT) (((tempcx & 0x00ff) >> 6) | 0x0c));
++ else
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x1A, 0xE0, (USHORT) (((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : SetSpectrum */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++SetSpectrum(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT index;
++
++ index = XGI_GetLCDCapPtr(pVBInfo);
++
++ XGI_SetRegAND((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
++ XGI_WaitEndRetrace(pVBInfo->RelIO);
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
++ XGI_WaitEndRetrace(pVBInfo->RelIO);
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x31,
++ pVBInfo->LCDCapList[index].Spectrum_31);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x32,
++ pVBInfo->LCDCapList[index].Spectrum_32);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x33,
++ pVBInfo->LCDCapList[index].Spectrum_33);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x34,
++ pVBInfo->LCDCapList[index].Spectrum_34);
++ XGI_WaitEndRetrace(pVBInfo->RelIO);
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x30, 0x40); /* enable spectrum */
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetAntiFlicker */
++/* Input : */
++/* Output : */
++/* Description : Set TV Customized Param. */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetAntiFlicker(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, index;
++
++ UCHAR tempah;
++
++ if (pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))
++ return;
++
++ tempbx = XGI_GetTVPtrIndex(pVBInfo);
++ tempbx &= 0xFE;
++
++ if (ModeNo <= 0x13) {
++ index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVFlickerIndex;
++ }
++ else {
++ index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVFlickerIndex;
++ }
++
++ tempbx += index;
++ tempah = TVAntiFlickList[tempbx];
++ tempah = tempah << 4;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetEdgeEnhance */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetEdgeEnhance(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, index;
++
++ UCHAR tempah;
++
++
++ tempbx = XGI_GetTVPtrIndex(pVBInfo);
++ tempbx &= 0xFE;
++
++ if (ModeNo <= 0x13) {
++ index = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVEdgeIndex;
++ }
++ else {
++ index = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVEdgeIndex;
++ }
++
++ tempbx += index;
++ tempah = TVEdgeList[tempbx];
++ tempah = tempah << 5;
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part2Port, 0x3A, 0x1F, tempah);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetPhaseIncr */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetPhaseIncr(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx;
++
++ UCHAR tempcl, tempch;
++
++ ULONG tempData;
++
++ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
++ tempData = TVPhaseList[tempbx];
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x31,
++ (USHORT) (tempData & 0x000000FF));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x32,
++ (USHORT) ((tempData & 0x0000FF00) >> 8));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x33,
++ (USHORT) ((tempData & 0x00FF0000) >> 16));
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x34,
++ (USHORT) ((tempData & 0xFF000000) >> 24));
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetYFilter */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetYFilter(USHORT ModeNo, USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempbx, index;
++
++ UCHAR tempcl, tempch, tempal;
++ const UCHAR *filterPtr;
++
++ XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */
++
++ switch (tempbx) {
++ case 0x00:
++ case 0x04:
++ filterPtr = NTSCYFilter1;
++ break;
++
++ case 0x01:
++ filterPtr = PALYFilter1;
++ break;
++
++ case 0x02:
++ case 0x05:
++ case 0x0D:
++ filterPtr = PALMYFilter1;
++ break;
++
++ case 0x03:
++ filterPtr = PALNYFilter1;
++ break;
++
++ case 0x08:
++ case 0x0C:
++ filterPtr = NTSCYFilter2;
++ break;
++
++ case 0x0A:
++ filterPtr = PALMYFilter2;
++ break;
++
++ case 0x0B:
++ filterPtr = PALNYFilter2;
++ break;
++
++ case 0x09:
++ filterPtr = PALYFilter2;
++ break;
++
++ default:
++ return;
++ }
++
++ if (ModeNo <= 0x13)
++ tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
++ else
++ tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
++
++ if (tempcl == 0)
++ index = tempal * 4;
++ else
++ index = tempal * 7;
++
++ if ((tempcl == 0) && (tempch == 1)) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35, 0);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36, 0);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37, 0);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
++ filterPtr[index++]);
++ }
++ else {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x35,
++ filterPtr[index++]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x36,
++ filterPtr[index++]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x37,
++ filterPtr[index++]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x38,
++ filterPtr[index++]);
++ }
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x48,
++ filterPtr[index++]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x49,
++ filterPtr[index++]);
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part2Port, 0x4A,
++ filterPtr[index++]);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetTVPtrIndex2 */
++/* Input : */
++/* Output : bx 0 : NTSC */
++/* 1 : PAL */
++/* 2 : PALM */
++/* 3 : PALN */
++/* 4 : NTSC1024x768 */
++/* 5 : PAL-M 1024x768 */
++/* 6-7: reserved */
++/* cl 0 : YFilter1 */
++/* 1 : YFilter2 */
++/* ch 0 : 301A */
++/* 1 : 301B/302B/301LV/302LV */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetTVPtrIndex2(USHORT * tempbx, UCHAR * tempcl, UCHAR * tempch,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ *tempbx = 0;
++ *tempcl = 0;
++ *tempch = 0;
++
++ if (pVBInfo->TVInfo & SetPALTV)
++ *tempbx = 1;
++
++ if (pVBInfo->TVInfo & SetPALMTV)
++ *tempbx = 2;
++
++ if (pVBInfo->TVInfo & SetPALNTV)
++ *tempbx = 3;
++
++ if (pVBInfo->TVInfo & NTSC1024x768) {
++ *tempbx = 4;
++ if (pVBInfo->TVInfo & SetPALMTV)
++ *tempbx = 5;
++ }
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ if ((!(pVBInfo->VBInfo & SetInSlaveMode))
++ || (pVBInfo->TVInfo & TVSimuMode)) {
++ *tempbx += 8;
++ *tempcl += 1;
++ }
++ }
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C))
++ *tempch++;
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_SetCRT2ModeRegs */
++/* Input : */
++/* Output : */
++/* Description : Origin code for crt2group */
++/* --------------------------------------------------------------------- */
++void
++XGI_SetCRT2ModeRegs(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension,
++ PVB_DEVICE_INFO pVBInfo)
++{
++#ifndef LINUX_XF86
++ USHORT i, j;
++#endif
++ USHORT tempbl;
++ SHORT tempcl;
++
++ UCHAR tempah;
++
++ /* XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x03 , 0x00 ) ; // fix write part1 index 0 BTDRAM bit Bug */
++ tempah = 0;
++ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
++ tempah = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00);
++ tempah &= ~0x10; /* BTRAMDAC */
++ tempah |= 0x40; /* BTRAM */
++
++ if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
++ tempah = 0x40; /* BTDRAM */
++ if (ModeNo > 0x13) {
++ tempcl = pVBInfo->ModeType;
++ tempcl -= ModeVGA;
++ if (tempcl >= 0) {
++ tempah = (0x008 >> tempcl); /* BT Color */
++ if (tempah == 0)
++ tempah = 1;
++ tempah |= 0x040;
++ }
++ }
++ if (pVBInfo->VBInfo & SetInSlaveMode)
++ tempah ^= 0x50; /* BTDAC */
++ }
++ }
++
++/* 0210 shampoo
++ if ( pVBInfo->VBInfo & DisableCRT2Display )
++ {
++ tempah = 0 ;
++ }
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port , 0x00 , tempah ) ;
++ if ( pVBInfo->VBInfo & ( SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD ) )
++ {
++ tempcl = pVBInfo->ModeType ;
++ if ( ModeNo > 0x13 )
++ {
++ tempcl -= ModeVGA ;
++ if ( ( tempcl > 0 ) || ( tempcl == 0 ) )
++ {
++ tempah=(0x008>>tempcl) ;
++ if ( tempah == 0 )
++ tempah = 1 ;
++ tempah |= 0x040;
++ }
++ }
++ else
++ {
++ tempah = 0x040 ;
++ }
++
++ if ( pVBInfo->VBInfo & SetInSlaveMode )
++ {
++ tempah = ( tempah ^ 0x050 ) ;
++ }
++ }
++*/
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part1Port, 0x00, tempah);
++ tempah = 0x08;
++ tempbl = 0xf0;
++
++ if (pVBInfo->VBInfo & DisableCRT2Display)
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
++ tempah);
++ else {
++ tempah = 0x00;
++ tempbl = 0xff;
++
++ if (pVBInfo->
++ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
++ SetCRT2ToLCDA)) {
++ if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
++ && (!(pVBInfo->VBInfo & SetSimuScanMode))) {
++ tempbl &= 0xf7;
++ tempah |= 0x01;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
++ tempbl, tempah);
++ }
++ else {
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
++ tempbl &= 0xf7;
++ tempah |= 0x01;
++ }
++
++ if (pVBInfo->
++ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD)) {
++ tempbl &= 0xf8;
++ tempah = 0x01;
++
++ if (!(pVBInfo->VBInfo & SetInSlaveMode))
++ tempah |= 0x02;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
++ tempah = tempah ^ 0x05;
++ if (!(pVBInfo->VBInfo & SetCRT2ToLCD))
++ tempah = tempah ^ 0x01;
++ }
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
++ tempah |= 0x08;
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
++ tempbl, tempah);
++ }
++ else
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e,
++ tempbl, tempah);
++ }
++ }
++ else
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2e, tempbl,
++ tempah);
++ }
++
++ if (pVBInfo->
++ VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV | SetCRT2ToLCD |
++ SetCRT2ToLCDA)) {
++ tempah &= (~0x08);
++ if ((pVBInfo->ModeType == ModeVGA)
++ && (!(pVBInfo->VBInfo & SetInSlaveMode))) {
++ tempah |= 0x010;
++ }
++ tempah |= 0x080;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ /* if ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) */
++ /* { */
++ tempah |= 0x020;
++ if (ModeNo > 0x13) {
++ if (pVBInfo->VBInfo & DriverMode)
++ tempah = tempah ^ 0x20;
++ }
++ /* } */
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x0D, ~0x0BF,
++ tempah);
++ tempah = 0;
++
++ if (pVBInfo->LCDInfo & SetLCDDualLink)
++ tempah |= 0x40;
++
++ if (pVBInfo->VBInfo & SetCRT2ToTV) {
++ /* if ( ( !( pVBInfo->VBInfo & SetCRT2ToHiVisionTV ) ) && ( !( pVBInfo->TVInfo & ( SetYPbPrMode525p | SetYPbPrMode750p ) ) ) ) */
++ /* { */
++ if (pVBInfo->TVInfo & RPLLDIV2XO)
++ tempah |= 0x40;
++ /* } */
++ }
++
++ if ((pVBInfo->LCDResInfo == Panel1280x1024)
++ || (pVBInfo->LCDResInfo == Panel1280x1024x75))
++ tempah |= 0x80;
++
++ if (pVBInfo->LCDResInfo == Panel1280x960)
++ tempah |= 0x80;
++
++ XGI_SetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x0C, tempah);
++ }
++
++ if (pVBInfo->
++ VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV |
++ VB_XGI301C)) {
++ tempah = 0;
++ tempbl = 0xfb;
++
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
++ tempbl = 0xff;
++ if (pVBInfo->VBInfo & SetCRT2ToLCDA)
++ tempah |= 0x04; /* shampoo 0129 */
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x13, tempbl,
++ tempah);
++ tempah = 0x00;
++ tempbl = 0xcf;
++ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
++ tempah |= 0x30;
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2c, tempbl,
++ tempah);
++ tempah = 0;
++ tempbl = 0x3f;
++
++ if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
++ if (pVBInfo->VBInfo & SetCRT2ToDualEdge)
++ tempah |= 0xc0;
++ }
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x21, tempbl,
++ tempah);
++ }
++
++ tempah = 0;
++ tempbl = 0x7f;
++ if (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) {
++ tempbl = 0xff;
++ if (!(pVBInfo->VBInfo & SetCRT2ToDualEdge))
++ tempah |= 0x80;
++ }
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x23, tempbl, tempah);
++
++ if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
++ if (pVBInfo->LCDInfo & SetLCDDualLink) {
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x27, 0x20);
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->Part4Port, 0x34, 0x10);
++ }
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetRAMDAC2DATA */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_GetRAMDAC2DATA(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempax, tempbx, temp1, temp2, modeflag = 0, tempcx, CRT1Index;
++#ifndef LINUX_XF86
++ USHORT temp, ResInfo, DisplayType;
++#endif
++
++ pVBInfo->RVBHCMAX = 1;
++ pVBInfo->RVBHCFACT = 1;
++
++ if (ModeNo <= 0x13) {
++ const USHORT StandTableIndex = XGI_GetModePtr(pVBInfo->SModeIDTable,
++ pVBInfo->ModeType,
++ ModeNo, ModeIdIndex);
++
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ tempax = pVBInfo->StandTable[StandTableIndex].CRTC[0];
++ tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[6];
++ temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
++ CRT1Index &= IndexMask;
++ temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
++ temp2 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
++ tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
++ tempbx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
++ tempcx = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
++ tempcx &= 0x0100;
++ tempcx = tempcx << 2;
++ tempbx |= tempcx;
++ temp1 = (USHORT) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
++ }
++
++ if (temp1 & 0x01)
++ tempbx |= 0x0100;
++
++ if (temp1 & 0x20)
++ tempbx |= 0x0200;
++ tempax += 5;
++
++ if (modeflag & Charx8Dot)
++ tempax *= 8;
++ else
++ tempax *= 9;
++
++ pVBInfo->VGAHT = tempax;
++ pVBInfo->HT = tempax;
++ tempbx++;
++ pVBInfo->VGAVT = tempbx;
++ pVBInfo->VT = tempbx;
++}
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetColorDepth */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetColorDepth(USHORT ModeNo, USHORT ModeIdIndex,
++ const VB_DEVICE_INFO *pVBInfo)
++{
++ USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8 };
++ SHORT index;
++ USHORT modeflag;
++
++ if (ModeNo <= 0x13) {
++ modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
++ }
++ else {
++ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++ }
++
++ index = (modeflag & ModeInfoFlag) - ModeEGA;
++
++ if (index < 0)
++ index = 0;
++
++ return (ColorDepth[index]);
++}
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_UnLockCRT2 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2f, 0xFF, 0x01);
++
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_LockCRT2 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_LockCRT2(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetRegANDOR((XGIIOADDRESS) pVBInfo->Part1Port, 0x2F, 0xFE, 0x00);
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGINew_EnableCRT2 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGINew_EnableCRT2(PVB_DEVICE_INFO pVBInfo)
++{
++ XGI_SetRegOR((XGIIOADDRESS) pVBInfo->P3c4, 0x1E, SR1E_ENABLE_CRT2);
++}
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGINew_LCD_Wait_Time(UCHAR DelayTime, PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT i, j;
++
++ ULONG temp, flag;
++
++ flag = 0;
++
++ for (i = 0; i < DelayTime; i++) {
++ for (j = 0; j < 66; j++) {
++ temp = XGI_GetRegLong((XGIIOADDRESS) 0x61);
++ temp &= 0x10;
++
++ if (temp == flag)
++ continue;
++
++ flag = temp;
++ }
++ }
++}
++
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_BridgeIsOn */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++BOOLEAN
++XGI_BridgeIsOn(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT flag;
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 1 )
++ {
++ return( 1 ) ;
++ }
++ else
++ {
++ flag = XGI_GetReg((XGIIOADDRESS) pVBInfo->Part4Port, 0x00);
++ if ((flag == 1) || (flag == 2))
++ return (1); /* 301b */
++ else
++ return (0);
++ }
++}
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_VBLongWait */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++void
++XGI_VBLongWait(PVB_DEVICE_INFO pVBInfo)
++{
++ USHORT tempal, temp, i, j;
++
++ if (!(pVBInfo->VBInfo & SetCRT2ToTV)) {
++ temp = 0;
++ for (i = 0; i < 3; i++) {
++ for (j = 0; j < 100; j++) {
++ tempal = XGI_GetRegByte((XGIIOADDRESS) pVBInfo->P3da);
++ if (temp & 0x01) { /* VBWaitMode2 */
++ if ((tempal & 0x08)) {
++ continue;
++ }
++
++ if (!(tempal & 0x08)) {
++ break;
++ }
++ }
++ else { /* VBWaitMode1 */
++ if (!(tempal & 0x08)) {
++ continue;
++ }
++
++ if ((tempal & 0x08)) {
++ break;
++ }
++ }
++ }
++ temp = temp ^ 0x01;
++ }
++ }
++ else {
++ XGI_WaitEndRetrace(pVBInfo->RelIO);
++ }
++ return;
++}
++
++
++
++
++/* --------------------------------------------------------------------- */
++/* Function : XGI_GetVGAHT2 */
++/* Input : */
++/* Output : */
++/* Description : */
++/* --------------------------------------------------------------------- */
++USHORT
++XGI_GetVGAHT2(PVB_DEVICE_INFO pVBInfo)
++{
++ ULONG tempax, tempbx;
++
++ tempbx =
++ ((pVBInfo->VGAVT - pVBInfo->VGAVDE) * pVBInfo->RVBHCMAX) & 0xFFFF;
++ tempax = (pVBInfo->VT - pVBInfo->VDE) * pVBInfo->RVBHCFACT;
++ tempax = (tempax * pVBInfo->HT) / tempbx;
++
++ return ((USHORT) tempax);
++}
++
++
++/**
++ * Get magic index into clock table.
++ *
++ * \bugs
++ * I'm pretty sure the first if-statement is wrong. It will \b always
++ * evaluate to true.
++ */
++unsigned
++XGI_GetVCLK2Ptr(USHORT ModeNo, USHORT ModeIdIndex,
++ USHORT RefreshRateTableIndex,
++ PVB_DEVICE_INFO pVBInfo)
++{
++ /* Jong 10/08/2007; merge code */
++ USHORT tempbx ;
++ UCHAR *CHTVVCLKPtr = NULL ;
++
++ unsigned VCLKIndex;
++ USHORT CRT2Index;
++
++ /* Jong 10/08/2007; merge code */
++ USHORT LCDXlat1VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
++ USHORT LCDXlat2VCLK[ 4 ] = { VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 , VCLK108_2 + 5 } ;
++ USHORT LVDSXlat1VCLK[ 4 ] = { VCLK40 , VCLK40 , VCLK40 , VCLK40 } ;
++ USHORT LVDSXlat2VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
++ USHORT LVDSXlat3VCLK[ 4 ] = { VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 , VCLK65 + 2 } ;
++
++ const unsigned modeflag = (ModeNo <= 0x13)
++ ? pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
++ : pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
++
++ /* Jong 10/04/2007; merge code */
++ if ( pVBInfo->IF_DEF_LVDS == 0 )
++ {
++ CRT2Index = CRT2Index >> 6 ; /* for LCD */
++
++ if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b */
++ VCLKIndex = (pVBInfo->LCDResInfo != Panel1024x768)
++ ? (VCLK108_2 + 5) : (VCLK65 + 2);
++ }
++ else
++ {
++ if (pVBInfo->VBInfo & SetCRT2ToTV) /* for TV */
++ {
++ if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV)
++ {
++ VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
++ ? HiTVVCLKDIV2 : HiTVVCLK;
++
++ VCLKIndex += 25;
++
++ if (pVBInfo->SetFlag & TVSimuMode) {
++ VCLKIndex = (modeflag & Charx8Dot)
++ ? HiTVSimuVCLK : HiTVTextVCLK;
++
++ VCLKIndex += 25;
++ }
++
++ if (pVBInfo->VBType & VB_XGI301LV) {
++ switch (pVBInfo->VBExtInfo) {
++ case VB_YPbPr1080i:
++ /* VCLKIndex already set to correct value? */
++ break;
++ case VB_YPbPr750p:
++ VCLKIndex = YPbPr750pVCLK;
++ break;
++ case VB_YPbPr525p:
++ VCLKIndex = YPbPr525pVCLK;
++ break;
++ case VB_YPbPr525i:
++ VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
++ ? YPbPr525iVCLK_2 : YPbPr525iVCLK;
++ break;
++ }
++ }
++ }
++ else {
++ VCLKIndex = (pVBInfo->SetFlag & RPLLDIV2XO)
++ ? TVVCLKDIV2 : TVVCLK;
++
++ VCLKIndex += 25;
++ }
++ }
++ else /* for CRT2 */
++ {
++ VCLKIndex = XGI_GetRegByte((XGIIOADDRESS) (pVBInfo->P3ca + 0x02));
++ VCLKIndex = ((VCLKIndex >> 2) & 0x03);
++ if (ModeNo > 0x13) {
++ VCLKIndex =
++ (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK
++ & IndexMask);
++ }
++ }
++ }
++ }
++ else /* Jong 10/04/2007; merge code */
++ { /* LVDS */
++ if ( ModeNo <= 0x13 )
++ VCLKIndex = CRT2Index ;
++ else
++ VCLKIndex = CRT2Index ;
++
++ if ( pVBInfo->IF_DEF_CH7005 == 1 )
++ {
++ if ( !( pVBInfo->VBInfo & SetCRT2ToLCD ) )
++ {
++ VCLKIndex &= 0x1f ;
++ tempbx = 0 ;
++
++ if ( pVBInfo->VBInfo & SetPALTV )
++ tempbx += 2 ;
++
++ if ( pVBInfo->VBInfo & SetCHTVOverScan )
++ tempbx += 1 ;
++
++ switch( tempbx )
++ {
++ case 0:
++ CHTVVCLKPtr = pVBInfo->CHTVVCLKUNTSC ;
++ break ;
++ case 1:
++ CHTVVCLKPtr = pVBInfo->CHTVVCLKONTSC ;
++ break;
++ case 2:
++ CHTVVCLKPtr = pVBInfo->CHTVVCLKUPAL ;
++ break ;
++ case 3:
++ CHTVVCLKPtr = pVBInfo->CHTVVCLKOPAL ;
++ break ;
++ default:
++ break ;
++ }
++
++ VCLKIndex = CHTVVCLKPtr[ VCLKIndex ] ;
++ }
++ }
++ else
++ {
++ VCLKIndex = VCLKIndex >> 6 ;
++ if ( ( pVBInfo->LCDResInfo == Panel800x600 ) || ( pVBInfo->LCDResInfo == Panel320x480 ) )
++ VCLKIndex = LVDSXlat1VCLK[ VCLKIndex ] ;
++ else if ( ( pVBInfo->LCDResInfo == Panel1024x768 ) || ( pVBInfo->LCDResInfo == Panel1024x768x75 ) )
++ VCLKIndex = LVDSXlat2VCLK[ VCLKIndex ] ;
++ else
++ VCLKIndex = LVDSXlat3VCLK[ VCLKIndex ] ;
++ }
++ }
++
++ return VCLKIndex;
++}
+diff --git a/src/vb_setmode.h b/src/vb_setmode.h
+index 558e68d..1b37395 100644
+--- a/src/vb_setmode.h
++++ b/src/vb_setmode.h
+@@ -34,8 +34,8 @@ extern void XGI_LongWait( PVB_DEVICE_INFO );
+ extern void XGI_SetCRT2ModeRegs(USHORT ModeNo,PXGI_HW_DEVICE_INFO, PVB_DEVICE_INFO );
+ extern void XGI_DisableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+ extern void XGI_EnableBridge(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+-extern void XGI_DisplayOff( PVB_DEVICE_INFO );
+-extern void XGI_DisplayOn( PVB_DEVICE_INFO );
++extern void XGI_DisplayOff( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
++extern void XGI_DisplayOn( PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+ extern void XGI_GetVBType(PVB_DEVICE_INFO);
+ extern void XGI_SenseCRT1(PVB_DEVICE_INFO );
+ extern void XGI_GetVGAType(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+@@ -44,6 +44,9 @@ extern void XGI_GetTVInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INF
+ extern void XGI_SetCRT1Offset(USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+ extern void XGI_SetLCDAGroup(USHORT ModeNo,USHORT ModeIdIndex,PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO );
+
++/* Jong 10/04/2007; merge code */
++extern USHORT XGI_GetResInfo(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo);
++
+ extern BOOLEAN XGISetModeNew(PXGI_HW_DEVICE_INFO HwDeviceExtension,
+ PVB_DEVICE_INFO pVBInfo, USHORT ModeNo);
+
+@@ -51,7 +54,7 @@ extern BOOLEAN CheckDualChip(PVB_DEVICE_INFO );
+ extern BOOLEAN XGI_GetLCDInfo(USHORT ModeNo,USHORT ModeIdIndex,PVB_DEVICE_INFO );
+ extern BOOLEAN XGI_BridgeIsOn( PVB_DEVICE_INFO );
+ extern BOOLEAN XGI_SetCRT2Group301(USHORT ModeNo, PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO);
+-extern USHORT XGI_GetRatePtrCRT2( USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
++extern USHORT XGI_GetRatePtrCRT2( PXGI_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO );
+
+ extern USHORT XGI_GetColorDepth(USHORT ModeNo, USHORT ModeIdIndex,
+ const VB_DEVICE_INFO *pVBInfo);
+@@ -73,6 +76,15 @@ extern void XGI_SetGRCRegs(unsigned StandTableIndex,
+
+ extern void XGI_ClearExt1Regs(unsigned ModeNo, const VB_DEVICE_INFO *pVBInfo);
+
++extern void XGI_SetXG21FPBits(PVB_DEVICE_INFO pVBInfo);
++extern void XGI_SetXG27FPBits(PVB_DEVICE_INFO pVBInfo);
++extern void XGI_XG21BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++extern void XGI_XG27BLSignalVDD(USHORT tempbh,USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++extern void XGI_XG21SetPanelDelay(USHORT tempbl, PVB_DEVICE_INFO pVBInfo);
++extern BOOLEAN XGI_XG21CheckLVDSMode(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
++extern void XGI_SetXG21LVDSPara(USHORT ModeNo,USHORT ModeIdIndex, PVB_DEVICE_INFO pVBInfo );
++extern USHORT XGI_GetLVDSOEMTableIndex(PVB_DEVICE_INFO pVBInfo);
++
+ extern void XGI_SetSync(unsigned RefreshRateTableIndex,
+ const VB_DEVICE_INFO *pVBInfo);
+ #endif
+diff --git a/src/vb_struct.h b/src/vb_struct.h
+index 072a024..2ba26cf 100644
+--- a/src/vb_struct.h
++++ b/src/vb_struct.h
+@@ -1,499 +1,574 @@
+-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+- *
+- * All Rights Reserved.
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining
+- * a copy of this software and associated documentation files (the
+- * "Software"), to deal in the Software without restriction, including
+- * without limitation on the rights to use, copy, modify, merge,
+- * publish, distribute, sublicense, and/or sell copies of the Software,
+- * and to permit persons to whom the Software is furnished to do so,
+- * subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice (including the
+- * next paragraph) shall be included in all copies or substantial
+- * portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+- * DEALINGS IN THE SOFTWARE.
+- */
+-
+-
+-#ifndef _VB_STRUCT_
+-#define _VB_STRUCT_
+-
+-
+-typedef struct _XGI_PanelDelayTblStruct
+-{
+- UCHAR timer[2];
+-} XGI_PanelDelayTblStruct;
+-
+-typedef struct _XGI_LCDDataStruct
+-{
+- USHORT RVBHCMAX;
+- USHORT RVBHCFACT;
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT LCDHT;
+- USHORT LCDVT;
+-} XGI_LCDDataStruct;
+-
+-
+-typedef struct _XGI_LVDSCRT1HDataStruct
+-{
+- UCHAR Reg[8];
+-} XGI_LVDSCRT1HDataStruct;
+-typedef struct _XGI_LVDSCRT1VDataStruct
+-{
+- UCHAR Reg[7];
+-} XGI_LVDSCRT1VDataStruct;
+-
+-
+-typedef struct _XGI_TVDataStruct
+-{
+- USHORT RVBHCMAX;
+- USHORT RVBHCFACT;
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT TVHDE;
+- USHORT TVVDE;
+- USHORT RVBHRS;
+- UCHAR FlickerMode;
+- USHORT HALFRVBHRS;
+- UCHAR RY1COE;
+- UCHAR RY2COE;
+- UCHAR RY3COE;
+- UCHAR RY4COE;
+-} XGI_TVDataStruct;
+-
+-typedef struct _XGI_LVDSDataStruct
+-{
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT LCDHT;
+- USHORT LCDVT;
+-} XGI_LVDSDataStruct;
+-
+-typedef struct _XGI_LVDSDesStruct
+-{
+- USHORT LCDHDES;
+- USHORT LCDVDES;
+-} XGI_LVDSDesStruct;
+-
+-typedef struct _XGI_LVDSCRT1DataStruct
+-{
+- UCHAR CR[15];
+-} XGI_LVDSCRT1DataStruct;
+-
+-/*add for LCDA*/
+-
+-
+-typedef struct _XGI_StStruct
+-{
+- UCHAR St_ModeID;
+- USHORT St_ModeFlag;
+- UCHAR St_StTableIndex;
+- UCHAR St_CRT2CRTC;
+- UCHAR St_CRT2CRTC2;
+- UCHAR St_ResInfo;
+- UCHAR VB_StTVFlickerIndex;
+- UCHAR VB_StTVEdgeIndex;
+- UCHAR VB_StTVYFilterIndex;
+-} XGI_StStruct;
+-
+-typedef struct _XGI_StandTableStruct
+-{
+- UCHAR CRT_COLS;
+- UCHAR ROWS;
+- UCHAR CHAR_HEIGHT;
+- USHORT CRT_LEN;
+- UCHAR SR[4];
+- UCHAR MISC;
+- UCHAR CRTC[0x19];
+- UCHAR ATTR[0x14];
+- UCHAR GRC[9];
+-} XGI_StandTableStruct;
+-
+-typedef struct _XGI_ExtStruct
+-{
+- UCHAR Ext_ModeID;
+- USHORT Ext_ModeFlag;
+- USHORT Ext_ModeInfo;
+- USHORT Ext_Point;
+- USHORT Ext_VESAID;
+- UCHAR Ext_VESAMEMSize;
+- UCHAR Ext_RESINFO;
+- UCHAR VB_ExtTVFlickerIndex;
+- UCHAR VB_ExtTVEdgeIndex;
+- UCHAR VB_ExtTVYFilterIndex;
+- UCHAR REFindex;
+-} XGI_ExtStruct;
+-
+-typedef struct _XGI_Ext2Struct
+-{
+- USHORT Ext_InfoFlag;
+- UCHAR Ext_CRT1CRTC;
+- UCHAR Ext_CRTVCLK;
+- UCHAR Ext_CRT2CRTC;
+- UCHAR Ext_CRT2CRTC2;
+- UCHAR ModeID;
+- USHORT XRes;
+- USHORT YRes;
+- /* USHORT ROM_OFFSET; */
+-} XGI_Ext2Struct;
+-
+-
+-typedef struct _XGI_MCLKDataStruct
+-{
+- UCHAR SR28,SR29,SR2A;
+- USHORT CLOCK;
+-} XGI_MCLKDataStruct;
+-
+-typedef struct _XGI_ECLKDataStruct
+-{
+- UCHAR SR2E,SR2F,SR30;
+- USHORT CLOCK;
+-} XGI_ECLKDataStruct;
+-
+-typedef struct _XGI_VCLKDataStruct
+-{
+- UCHAR SR2B,SR2C;
+- USHORT CLOCK;
+-} XGI_VCLKDataStruct;
+-
+-typedef struct _XGI_VBVCLKDataStruct
+-{
+- UCHAR Part4_A,Part4_B;
+- USHORT CLOCK;
+-} XGI_VBVCLKDataStruct;
+-
+-typedef struct _XGI_StResInfoStruct
+-{
+- USHORT HTotal;
+- USHORT VTotal;
+-} XGI_StResInfoStruct;
+-
+-typedef struct _XGI_ModeResInfoStruct
+-{
+- USHORT HTotal;
+- USHORT VTotal;
+- UCHAR XChar;
+- UCHAR YChar;
+-} XGI_ModeResInfoStruct;
+-
+-typedef struct _XGI_LCDNBDesStruct
+-{
+- UCHAR NB[12];
+-} XGI_LCDNBDesStruct;
+- /*add for new UNIVGABIOS*/
+-typedef struct _XGI_LCDDesStruct
+-{
+- USHORT LCDHDES;
+- USHORT LCDHRS;
+- USHORT LCDVDES;
+- USHORT LCDVRS;
+-} XGI_LCDDesStruct;
+-
+-typedef struct _XGI_LCDDataTablStruct
+-{
+- UCHAR PANELID;
+- USHORT MASK;
+- USHORT CAP;
+- USHORT DATAPTR;
+-} XGI_LCDDataTablStruct;
+-
+-typedef struct _XGI_TVTablDataStruct
+-{
+- USHORT MASK;
+- USHORT CAP;
+- USHORT DATAPTR;
+-} XGI_TVDataTablStruct;
+-
+-typedef struct _XGI330_LCDDesDataStruct
+-{
+- USHORT LCDHDES;
+- USHORT LCDHRS;
+- USHORT LCDVDES;
+- USHORT LCDVRS;
+-} XGI330_LCDDataDesStruct;
+-
+-
+-typedef struct _XGI330_LVDSDataStruct
+-{
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT LCDHT;
+- USHORT LCDVT;
+-} XGI330_LVDSDataStruct;
+-
+-typedef struct _XGI330_LCDDesDataStruct2
+-{
+- USHORT LCDHDES;
+- USHORT LCDHRS;
+- USHORT LCDVDES;
+- USHORT LCDVRS;
+- USHORT LCDHSync;
+- USHORT LCDVSync;
+-} XGI330_LCDDataDesStruct2;
+-
+-typedef struct _XGI330_LCDDataStruct
+-{
+- USHORT RVBHCMAX;
+- USHORT RVBHCFACT;
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT LCDHT;
+- USHORT LCDVT;
+-} XGI330_LCDDataStruct;
+-
+-
+-typedef struct _XGI330_TVDataStruct
+-{
+- USHORT RVBHCMAX;
+- USHORT RVBHCFACT;
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT TVHDE;
+- USHORT TVVDE;
+- USHORT RVBHRS;
+- UCHAR FlickerMode;
+- USHORT HALFRVBHRS;
+-} XGI330_TVDataStruct;
+-
+-typedef struct _XGI330_LCDDataTablStruct
+-{
+- UCHAR PANELID;
+- USHORT MASK;
+- USHORT CAP;
+- USHORT DATAPTR;
+-} XGI330_LCDDataTablStruct;
+-
+-typedef struct _XGI330_TVDataTablStruct
+-{
+- USHORT MASK;
+- USHORT CAP;
+- USHORT DATAPTR;
+-} XGI330_TVDataTablStruct;
+-
+-
+-typedef struct _XGI330_CHTVDataStruct
+-{
+- USHORT VGAHT;
+- USHORT VGAVT;
+- USHORT LCDHT;
+- USHORT LCDVT;
+-} XGI330_CHTVDataStruct;
+-
+-typedef struct _XGI_TimingHStruct
+-{
+- UCHAR data[8];
+-} XGI_TimingHStruct;
+-
+-typedef struct _XGI_TimingVStruct
+-{
+- UCHAR data[7];
+-} XGI_TimingVStruct;
+-
+-typedef struct _XGI330_CHTVRegDataStruct
+-{
+- UCHAR Reg[16];
+-} XGI330_CHTVRegDataStruct;
+-
+-typedef struct _XGI330_LCDCapStruct
+-{
+- UCHAR LCD_ID;
+- USHORT LCD_Capability;
+- UCHAR LCD_SetFlag;
+- UCHAR LCD_DelayCompensation;
+- UCHAR LCD_HSyncWidth;
+- UCHAR LCD_VSyncWidth;
+- UCHAR LCD_VCLK;
+- UCHAR LCDA_VCLKData1;
+- UCHAR LCDA_VCLKData2;
+- UCHAR LCUCHAR_VCLKData1;
+- UCHAR LCUCHAR_VCLKData2;
+- UCHAR PSC_S1;
+- UCHAR PSC_S2;
+- UCHAR PSC_S3;
+- UCHAR PSC_S4;
+- UCHAR PSC_S5;
+- UCHAR PWD_2B;
+- UCHAR PWD_2C;
+- UCHAR PWD_2D;
+- UCHAR PWD_2E;
+- UCHAR PWD_2F;
+- UCHAR Spectrum_31;
+- UCHAR Spectrum_32;
+- UCHAR Spectrum_33;
+- UCHAR Spectrum_34;
+-} XGI330_LCDCapStruct;
+-
+-typedef struct _XGI_CRT1TableStruct
+-{
+- UCHAR CR[15];
+-} XGI_CRT1TableStruct;
+-
+-
+-typedef struct _XGI330_VCLKDataStruct
+-{
+- UCHAR SR2B,SR2C;
+- USHORT CLOCK;
+-} XGI330_VCLKDataStruct;
+-
+-typedef struct _XGI301C_Tap4TimingStruct
+-{
+- USHORT DE;
+- UCHAR Reg[64]; /* C0-FF */
+-} XGI301C_Tap4TimingStruct;
+-
+-typedef struct _XGI_New_StandTableStruct
+-{
+- UCHAR CRT_COLS;
+- UCHAR ROWS;
+- UCHAR CHAR_HEIGHT;
+- USHORT CRT_LEN;
+- UCHAR SR[4];
+- UCHAR MISC;
+- UCHAR CRTC[0x19];
+- UCHAR ATTR[0x14];
+- UCHAR GRC[9];
+-} XGI_New_StandTableStruct;
+-
+-typedef UCHAR DRAM8Type[8];
+-typedef UCHAR DRAM4Type[4];
+-typedef UCHAR DRAM32Type[32];
+-typedef UCHAR DRAM2Type[2];
+-
+-typedef struct _VB_DEVICE_INFO VB_DEVICE_INFO,*PVB_DEVICE_INFO;
+-
+-#define AGP_REG_SIZE 12
+-#define CR40_SIZE 24
+-#define CR6B_SIZE 8
+-#define CR6E_SIZE 8
+-#define CR6F_SIZE 8
+-#define CR89_SIZE 8
+-#define SR15_SIZE 4
+-#define MCLK_SIZE 8
+-#define ECLK_SIZE 8
+-
+-struct _VB_DEVICE_INFO
+-{
+- BOOLEAN ISXPDOS;
+- USHORT P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
+- USHORT P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
+- USHORT Part0Port,Part1Port,Part2Port;
+- USHORT Part3Port,Part4Port,Part5Port;
+- USHORT RVBHCFACT,RVBHCMAX,RVBHRS;
+- USHORT VGAVT,VGAHT,VGAVDE,VGAHDE;
+- USHORT VT,HT,VDE,HDE;
+- USHORT LCDHRS,LCDVRS,LCDHDES,LCDVDES;
+-
+- USHORT ModeType;
+- USHORT IF_DEF_TRUMPION,IF_DEF_DSTN;
+- USHORT IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
+- USHORT IF_DEF_LCDA,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
+- USHORT IF_DEF_ExpLink;
+- USHORT IF_DEF_HiVision;
+- USHORT LCDResInfo,LCDTypeInfo, VBType;/*301b*/
+- USHORT VBInfo,TVInfo,LCDInfo;
+- USHORT VBExtInfo;/*301lv*/
+- USHORT SetFlag;
+- USHORT NewFlickerMode;
+- USHORT SelectCRT2Rate;
+-
+- PUCHAR ROMAddr;
+- PUCHAR FBAddr;
+- USHORT BaseAddr;
+- XGIIOADDRESS RelIO;
+-
+- DRAM4Type CR6B[CR6B_SIZE];
+-
+- UCHAR XG45CR6E[CR6E_SIZE];
+- UCHAR XG45CR6F[CR6F_SIZE];
+- DRAM4Type CR6E[CR6E_SIZE];
+- DRAM32Type CR6F[CR6F_SIZE];
+- DRAM2Type CR89[CR89_SIZE];
+-
+- DRAM8Type SR15[SR15_SIZE]; /* pointer : point to array */
+- DRAM8Type CR40[CR40_SIZE];
+- UCHAR SoftSetting;
+- UCHAR OutputSelect;
+-
+- const USHORT *pRGBSenseData;
+- const USHORT *pRGBSenseData2; /*301b*/
+- const USHORT *pVideoSenseData;
+- const USHORT *pVideoSenseData2;
+- const USHORT *pYCSenseData;
+- const USHORT *pYCSenseData2;
+-
+- UCHAR SR07;
+- UCHAR CR49[2];
+- UCHAR SR1F;
+- UCHAR AGPReg[AGP_REG_SIZE];
+- UCHAR SR16[4];
+- UCHAR SR21;
+- UCHAR SR22;
+- UCHAR SR23;
+- UCHAR SR24;
+- UCHAR SR25[2];
+- UCHAR SR31;
+- UCHAR SR32;
+- UCHAR SR33;
+- UCHAR CRCF;
+- UCHAR CRT2Data_1_2;
+- UCHAR CRT2Data_4_D;
+- UCHAR CRT2Data_4_E;
+- UCHAR CRT2Data_4_10;
+- XGI_MCLKDataStruct MCLKData[MCLK_SIZE];
+- XGI_ECLKDataStruct ECLKData[ECLK_SIZE];
+-
+- const UCHAR *XGI_TVDelayList;
+- const UCHAR *XGI_TVDelayList2;
+- const UCHAR *CHTVVCLKUNTSC;
+- const UCHAR *CHTVVCLKONTSC;
+- const UCHAR *CHTVVCLKUPAL;
+- const UCHAR *CHTVVCLKOPAL;
+- const UCHAR *NTSCTiming;
+- const UCHAR *PALTiming;
+- const UCHAR *HiTVExtTiming;
+- const UCHAR *HiTVSt1Timing;
+- const UCHAR *HiTVSt2Timing;
+- const UCHAR *HiTVTextTiming;
+- const UCHAR *YPbPr750pTiming;
+- const UCHAR *YPbPr525pTiming;
+- const UCHAR *YPbPr525iTiming;
+- const UCHAR *HiTVGroup3Data;
+- const UCHAR *HiTVGroup3Simu;
+- const UCHAR *HiTVGroup3Text;
+- const UCHAR *Ren525pGroup3;
+- const UCHAR *Ren750pGroup3;
+- const UCHAR *ScreenOffset;
+- UCHAR DRAMTypeDefinition;
+- UCHAR I2CDefinition;
+- UCHAR CR97;
+-
+- const XGI330_LCDCapStruct *LCDCapList;
+-
+- XGI_TimingHStruct TimingH;
+- XGI_TimingVStruct TimingV;
+-
+- const XGI_StStruct *SModeIDTable;
+- const XGI_StandTableStruct *StandTable;
+- const XGI_ExtStruct *EModeIDTable;
+- const XGI_Ext2Struct *RefIndex;
+- /* XGINew_CRT1TableStruct *CRT1Table; */
+- const XGI_CRT1TableStruct *XGINEWUB_CRT1Table;
+- const XGI_VCLKDataStruct *VCLKData;
+- const XGI_VBVCLKDataStruct *VBVCLKData;
+- const XGI_StResInfoStruct *StResInfo;
+- const XGI_ModeResInfoStruct *ModeResInfo;
+-}; /* _VB_DEVICE_INFO */
+-
+-#define _VB_STRUCT_
+-#endif /* _VB_STRUCT_ */
++/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
++ *
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation on the rights to use, copy, modify, merge,
++ * publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so,
++ * subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
++ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++
++
++#ifndef _VB_STRUCT_
++#define _VB_STRUCT_
++
++
++typedef struct _XGI_PanelDelayTblStruct
++{
++ UCHAR timer[2];
++} XGI_PanelDelayTblStruct;
++
++typedef struct _XGI_LCDDataStruct
++{
++ USHORT RVBHCMAX;
++ USHORT RVBHCFACT;
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT LCDHT;
++ USHORT LCDVT;
++} XGI_LCDDataStruct;
++
++
++typedef struct _XGI_LVDSCRT1HDataStruct
++{
++ UCHAR Reg[8];
++} XGI_LVDSCRT1HDataStruct;
++typedef struct _XGI_LVDSCRT1VDataStruct
++{
++ UCHAR Reg[7];
++} XGI_LVDSCRT1VDataStruct;
++
++
++typedef struct _XGI_TVDataStruct
++{
++ USHORT RVBHCMAX;
++ USHORT RVBHCFACT;
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT TVHDE;
++ USHORT TVVDE;
++ USHORT RVBHRS;
++ UCHAR FlickerMode;
++ USHORT HALFRVBHRS;
++ UCHAR RY1COE;
++ UCHAR RY2COE;
++ UCHAR RY3COE;
++ UCHAR RY4COE;
++} XGI_TVDataStruct;
++
++typedef struct _XGI_LVDSDataStruct
++{
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT LCDHT;
++ USHORT LCDVT;
++} XGI_LVDSDataStruct;
++
++typedef struct _XGI_LVDSDesStruct
++{
++ USHORT LCDHDES;
++ USHORT LCDVDES;
++} XGI_LVDSDesStruct;
++
++typedef struct _XGI_LVDSCRT1DataStruct
++{
++ UCHAR CR[15];
++} XGI_LVDSCRT1DataStruct;
++
++/*add for LCDA*/
++
++
++typedef struct _XGI_StStruct
++{
++ UCHAR St_ModeID;
++ USHORT St_ModeFlag;
++ UCHAR St_StTableIndex;
++ UCHAR St_CRT2CRTC;
++ UCHAR St_CRT2CRTC2;
++ UCHAR St_ResInfo;
++ UCHAR VB_StTVFlickerIndex;
++ UCHAR VB_StTVEdgeIndex;
++ UCHAR VB_StTVYFilterIndex;
++} XGI_StStruct;
++
++typedef struct _XGI_StandTableStruct
++{
++ UCHAR CRT_COLS;
++ UCHAR ROWS;
++ UCHAR CHAR_HEIGHT;
++ USHORT CRT_LEN;
++ UCHAR SR[4];
++ UCHAR MISC;
++ UCHAR CRTC[0x19];
++ UCHAR ATTR[0x14];
++ UCHAR GRC[9];
++} XGI_StandTableStruct;
++
++typedef struct _XGI_ExtStruct
++{
++ UCHAR Ext_ModeID;
++ USHORT Ext_ModeFlag;
++ USHORT Ext_ModeInfo;
++ USHORT Ext_Point;
++ USHORT Ext_VESAID;
++ UCHAR Ext_VESAMEMSize;
++ UCHAR Ext_RESINFO;
++ UCHAR VB_ExtTVFlickerIndex;
++ UCHAR VB_ExtTVEdgeIndex;
++ UCHAR VB_ExtTVYFilterIndex;
++ UCHAR REFindex;
++} XGI_ExtStruct;
++
++typedef struct _XGI_Ext2Struct
++{
++ USHORT Ext_InfoFlag;
++ UCHAR Ext_CRT1CRTC;
++ UCHAR Ext_CRTVCLK;
++ UCHAR Ext_CRT2CRTC;
++ UCHAR Ext_CRT2CRTC2;
++ UCHAR ModeID;
++ USHORT XRes;
++ USHORT YRes;
++ /* USHORT ROM_OFFSET; */
++} XGI_Ext2Struct;
++
++
++typedef struct _XGI_MCLKDataStruct
++{
++ UCHAR SR28,SR29,SR2A;
++ USHORT CLOCK;
++} XGI_MCLKDataStruct;
++
++typedef struct _XGI_ECLKDataStruct
++{
++ UCHAR SR2E,SR2F,SR30;
++ USHORT CLOCK;
++} XGI_ECLKDataStruct;
++
++typedef struct _XGI_VCLKDataStruct
++{
++ UCHAR SR2B,SR2C;
++ USHORT CLOCK;
++} XGI_VCLKDataStruct;
++
++typedef struct _XGI_VBVCLKDataStruct
++{
++ UCHAR Part4_A,Part4_B;
++ USHORT CLOCK;
++} XGI_VBVCLKDataStruct;
++
++typedef struct _XGI_StResInfoStruct
++{
++ USHORT HTotal;
++ USHORT VTotal;
++} XGI_StResInfoStruct;
++
++typedef struct _XGI_ModeResInfoStruct
++{
++ USHORT HTotal;
++ USHORT VTotal;
++ UCHAR XChar;
++ UCHAR YChar;
++} XGI_ModeResInfoStruct;
++
++typedef struct _XGI_LCDNBDesStruct
++{
++ UCHAR NB[12];
++} XGI_LCDNBDesStruct;
++ /*add for new UNIVGABIOS*/
++typedef struct _XGI_LCDDesStruct
++{
++ USHORT LCDHDES;
++ USHORT LCDHRS;
++ USHORT LCDVDES;
++ USHORT LCDVRS;
++} XGI_LCDDesStruct;
++
++typedef struct _XGI_LCDDataTablStruct
++{
++ UCHAR PANELID;
++ USHORT MASK;
++ USHORT CAP;
++ USHORT DATAPTR;
++} XGI_LCDDataTablStruct;
++
++typedef struct _XGI_TVTablDataStruct
++{
++ USHORT MASK;
++ USHORT CAP;
++ USHORT DATAPTR;
++} XGI_TVDataTablStruct;
++
++typedef struct _XGI330_LCDDesDataStruct
++{
++ USHORT LCDHDES;
++ USHORT LCDHRS;
++ USHORT LCDVDES;
++ USHORT LCDVRS;
++} XGI330_LCDDataDesStruct;
++
++
++typedef struct _XGI330_LVDSDataStruct
++{
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT LCDHT;
++ USHORT LCDVT;
++} XGI330_LVDSDataStruct;
++
++typedef struct _XGI330_LCDDesDataStruct2
++{
++ USHORT LCDHDES;
++ USHORT LCDHRS;
++ USHORT LCDVDES;
++ USHORT LCDVRS;
++ USHORT LCDHSync;
++ USHORT LCDVSync;
++} XGI330_LCDDataDesStruct2;
++
++typedef struct _XGI330_LCDDataStruct
++{
++ USHORT RVBHCMAX;
++ USHORT RVBHCFACT;
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT LCDHT;
++ USHORT LCDVT;
++} XGI330_LCDDataStruct;
++
++
++typedef struct _XGI330_TVDataStruct
++{
++ USHORT RVBHCMAX;
++ USHORT RVBHCFACT;
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT TVHDE;
++ USHORT TVVDE;
++ USHORT RVBHRS;
++ UCHAR FlickerMode;
++ USHORT HALFRVBHRS;
++} XGI330_TVDataStruct;
++
++typedef struct _XGI330_LCDDataTablStruct
++{
++ UCHAR PANELID;
++ USHORT MASK;
++ USHORT CAP;
++ USHORT DATAPTR;
++} XGI330_LCDDataTablStruct;
++
++typedef struct _XGI330_TVDataTablStruct
++{
++ USHORT MASK;
++ USHORT CAP;
++ USHORT DATAPTR;
++} XGI330_TVDataTablStruct;
++
++
++typedef struct _XGI330_CHTVDataStruct
++{
++ USHORT VGAHT;
++ USHORT VGAVT;
++ USHORT LCDHT;
++ USHORT LCDVT;
++} XGI330_CHTVDataStruct;
++
++typedef struct _XGI_TimingHStruct
++{
++ UCHAR data[8];
++} XGI_TimingHStruct;
++
++typedef struct _XGI_TimingVStruct
++{
++ UCHAR data[7];
++} XGI_TimingVStruct;
++
++/* Jong 10/04/2007; merge code */
++typedef struct _XGI_CH7007TV_TimingHStruct
++{
++ UCHAR data[10];
++} XGI_CH7007TV_TimingHStruct;
++
++/* Jong 10/04/2007; merge code */
++typedef struct _XGI_CH7007TV_TimingVStruct
++{
++ UCHAR data[10];
++} XGI_CH7007TV_TimingVStruct;
++
++/* Jong 10/04/2007; merge code */
++typedef struct _XGI_XG21CRT1Struct
++{
++ UCHAR ModeID,CR02,CR03,CR15,CR16;
++} XGI_XG21CRT1Struct;
++
++typedef struct _XGI330_CHTVRegDataStruct
++{
++ UCHAR Reg[16];
++} XGI330_CHTVRegDataStruct;
++
++typedef struct _XGI330_LCDCapStruct
++{
++ UCHAR LCD_ID;
++ USHORT LCD_Capability;
++ UCHAR LCD_SetFlag;
++ UCHAR LCD_DelayCompensation;
++ UCHAR LCD_HSyncWidth;
++ UCHAR LCD_VSyncWidth;
++ UCHAR LCD_VCLK;
++ UCHAR LCDA_VCLKData1;
++ UCHAR LCDA_VCLKData2;
++ UCHAR LCUCHAR_VCLKData1;
++ UCHAR LCUCHAR_VCLKData2;
++ UCHAR PSC_S1;
++ UCHAR PSC_S2;
++ UCHAR PSC_S3;
++ UCHAR PSC_S4;
++ UCHAR PSC_S5;
++ UCHAR PWD_2B;
++ UCHAR PWD_2C;
++ UCHAR PWD_2D;
++ UCHAR PWD_2E;
++ UCHAR PWD_2F;
++ UCHAR Spectrum_31;
++ UCHAR Spectrum_32;
++ UCHAR Spectrum_33;
++ UCHAR Spectrum_34;
++} XGI330_LCDCapStruct;
++
++/* Jong 10/04/2007; merge code */
++typedef struct _XGI21_LVDSCapStruct
++{
++ USHORT LVDS_Capability;
++ USHORT LVDSHT;
++ USHORT LVDSVT;
++ USHORT LVDSHDE;
++ USHORT LVDSVDE;
++ USHORT LVDSHFP;
++ USHORT LVDSVFP;
++ USHORT LVDSHSYNC;
++ USHORT LVDSVSYNC;
++ UCHAR VCLKData1;
++ UCHAR VCLKData2;
++ UCHAR PSC_S1;
++ UCHAR PSC_S2;
++ UCHAR PSC_S3;
++ UCHAR PSC_S4;
++ UCHAR PSC_S5;
++} XGI21_LVDSCapStruct;
++
++typedef struct _XGI_CRT1TableStruct
++{
++ UCHAR CR[15];
++} XGI_CRT1TableStruct;
++
++
++typedef struct _XGI330_VCLKDataStruct
++{
++ UCHAR SR2B,SR2C;
++ USHORT CLOCK;
++} XGI330_VCLKDataStruct;
++
++typedef struct _XGI301C_Tap4TimingStruct
++{
++ USHORT DE;
++ UCHAR Reg[64]; /* C0-FF */
++} XGI301C_Tap4TimingStruct;
++
++typedef struct _XGI_New_StandTableStruct
++{
++ UCHAR CRT_COLS;
++ UCHAR ROWS;
++ UCHAR CHAR_HEIGHT;
++ USHORT CRT_LEN;
++ UCHAR SR[4];
++ UCHAR MISC;
++ UCHAR CRTC[0x19];
++ UCHAR ATTR[0x14];
++ UCHAR GRC[9];
++} XGI_New_StandTableStruct;
++
++typedef UCHAR DRAM8Type[8];
++typedef UCHAR DRAM4Type[4];
++typedef UCHAR DRAM32Type[32];
++typedef UCHAR DRAM2Type[2];
++
++typedef struct _VB_DEVICE_INFO VB_DEVICE_INFO,*PVB_DEVICE_INFO;
++
++#define AGP_REG_SIZE 12
++#define CR40_SIZE 24
++#define CR6B_SIZE 8
++#define CR6E_SIZE 8
++#define CR6F_SIZE 8
++#define CR89_SIZE 8
++#define SR15_SIZE 4
++#define MCLK_SIZE 8
++#define ECLK_SIZE 8
++
++struct _VB_DEVICE_INFO
++{
++ BOOLEAN ISXPDOS;
++ USHORT P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
++ USHORT P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
++ USHORT Part0Port,Part1Port,Part2Port;
++ USHORT Part3Port,Part4Port,Part5Port;
++ USHORT RVBHCFACT,RVBHCMAX,RVBHRS;
++ USHORT VGAVT,VGAHT,VGAVDE,VGAHDE;
++ USHORT VT,HT,VDE,HDE;
++ USHORT LCDHRS,LCDVRS,LCDHDES,LCDVDES;
++
++ USHORT ModeType;
++ USHORT IF_DEF_TRUMPION,IF_DEF_DSTN;
++ USHORT IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
++ USHORT IF_DEF_CH7017,IF_DEF_LCDA,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
++ USHORT IF_DEF_ExpLink;
++ USHORT IF_DEF_CH7005,IF_DEF_HiVision; /* Jong 10/08/2007; merge code */
++ USHORT IF_DEF_CH7007; /* Jong 10/04/2007; merge code */
++ USHORT LCDResInfo,LCDTypeInfo, VBType;/*301b*/
++ USHORT VBInfo,TVInfo,LCDInfo;
++ USHORT VBExtInfo;/*301lv*/
++ USHORT SetFlag;
++ USHORT NewFlickerMode;
++ USHORT SelectCRT2Rate;
++
++ PUCHAR ROMAddr;
++ PUCHAR FBAddr;
++ USHORT BaseAddr;
++ XGIIOADDRESS RelIO;
++
++ DRAM4Type CR6B[CR6B_SIZE];
++
++ UCHAR XG45CR6E[CR6E_SIZE];
++ UCHAR XG45CR6F[CR6F_SIZE];
++ DRAM4Type CR6E[CR6E_SIZE];
++ DRAM32Type CR6F[CR6F_SIZE];
++ DRAM2Type CR89[CR89_SIZE];
++
++ DRAM8Type SR15[SR15_SIZE]; /* pointer : point to array */
++ DRAM8Type CR40[CR40_SIZE];
++ UCHAR SoftSetting;
++ UCHAR OutputSelect;
++
++ USHORT IF_DEF_LVDS; /* Jong 10/05/2007; merge code */
++
++ const USHORT *pRGBSenseData;
++ const USHORT *pRGBSenseData2; /*301b*/
++ const USHORT *pVideoSenseData;
++ const USHORT *pVideoSenseData2;
++ const USHORT *pYCSenseData;
++ const USHORT *pYCSenseData2;
++
++ UCHAR SR07;
++ UCHAR CR49[2];
++ UCHAR SR1F;
++ UCHAR AGPReg[AGP_REG_SIZE];
++ UCHAR SR16[4];
++ UCHAR SR21;
++ UCHAR SR22;
++ UCHAR SR23;
++ UCHAR SR24;
++ UCHAR SR25[2];
++ UCHAR SR31;
++ UCHAR SR32;
++ UCHAR SR33;
++
++ /* Jong 10/05/2007; merge code */
++ UCHAR *pSR36;
++ UCHAR CRCF;
++ UCHAR *pCRD0;
++ UCHAR *pCRDE;
++ UCHAR *pCR8F;
++ UCHAR *pSR40;
++ UCHAR *pSR41;
++ UCHAR *pDVOSetting;
++ UCHAR *pCR2E;
++ UCHAR *pCR2F;
++ UCHAR *pCR46;
++ UCHAR *pCR47;
++
++ UCHAR CRT2Data_1_2;
++ UCHAR CRT2Data_4_D;
++ UCHAR CRT2Data_4_E;
++ UCHAR CRT2Data_4_10;
++ XGI_MCLKDataStruct MCLKData[MCLK_SIZE];
++ XGI_ECLKDataStruct ECLKData[ECLK_SIZE];
++
++ const UCHAR *XGI_TVDelayList;
++ const UCHAR *XGI_TVDelayList2;
++ const UCHAR *CHTVVCLKUNTSC;
++ const UCHAR *CHTVVCLKONTSC;
++ const UCHAR *CHTVVCLKUPAL;
++ const UCHAR *CHTVVCLKOPAL;
++ const UCHAR *NTSCTiming;
++ const UCHAR *PALTiming;
++ const UCHAR *HiTVExtTiming;
++ const UCHAR *HiTVSt1Timing;
++ const UCHAR *HiTVSt2Timing;
++ const UCHAR *HiTVTextTiming;
++ const UCHAR *YPbPr750pTiming;
++ const UCHAR *YPbPr525pTiming;
++ const UCHAR *YPbPr525iTiming;
++ const UCHAR *HiTVGroup3Data;
++ const UCHAR *HiTVGroup3Simu;
++ const UCHAR *HiTVGroup3Text;
++ const UCHAR *Ren525pGroup3;
++ const UCHAR *Ren750pGroup3;
++ const UCHAR *ScreenOffset;
++ UCHAR DRAMTypeDefinition;
++ UCHAR I2CDefinition;
++ UCHAR CR97;
++
++ const XGI330_LCDCapStruct *LCDCapList;
++ XGI21_LVDSCapStruct *XG21_LVDSCapList; /* Jong 10/05/2007; merge code */
++
++ XGI_TimingHStruct TimingH;
++ XGI_TimingVStruct TimingV;
++
++ const XGI_StStruct *SModeIDTable;
++ const XGI_StandTableStruct *StandTable;
++ const XGI_ExtStruct *EModeIDTable;
++ const XGI_Ext2Struct *RefIndex;
++ /* XGINew_CRT1TableStruct *CRT1Table; */
++ const XGI_CRT1TableStruct *XGINEWUB_CRT1Table;
++ const XGI_VCLKDataStruct *VCLKData;
++ const XGI_VBVCLKDataStruct *VBVCLKData;
++ const XGI_StResInfoStruct *StResInfo;
++ const XGI_ModeResInfoStruct *ModeResInfo;
++ XGI_XG21CRT1Struct *UpdateCRT1; /* Jong 10/05/2007; merge code */
++}; /* _VB_DEVICE_INFO */
++
++/* Jong 10/04/2007; merge code */
++typedef struct
++{
++ USHORT Horizontal_ACTIVE;
++ USHORT Horizontal_FP;
++ USHORT Horizontal_SYNC;
++ USHORT Horizontal_BP;
++ USHORT Vertical_ACTIVE;
++ USHORT Vertical_FP;
++ USHORT Vertical_SYNC;
++ USHORT Vertical_BP;
++ double DCLK;
++ UCHAR FrameRate;
++ UCHAR Interlace;
++ USHORT Margin;
++} TimingInfo;
++
++#define _VB_STRUCT_
++#endif /* _VB_STRUCT_ */
+diff --git a/src/vb_table.h b/src/vb_table.h
+index 2b31679..b26427c 100644
+--- a/src/vb_table.h
++++ b/src/vb_table.h
+@@ -84,7 +84,36 @@ static const DRAM8Type XGI340_CR41[CR40_SIZE] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 23 CRC5 */
+ };
+
+-static const DRAM4Type XGI340_CR6B[CR6B_SIZE]={
++/* Jong 10/04/2007; merge code */
++UCHAR XGI27_cr41[24][8]=
++{
++{0x20,0x60,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
++{0x04,0x44,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
++{0x04,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
++{0xb5,0x03,0xa4,0x00,0x00,0x00,0x00,0x00},/* 3 CR40[7],CR99[2:0],CR45[3:0]*/
++{0xf0,0xf5,0xf0,0x00,0x00,0x00,0x00,0x00},/* 4 CR59 */
++{0xa4,0x1C,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
++{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
++{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
++{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
++{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
++{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
++{0x48,0xa8,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
++{0x77,0x88,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
++{0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
++{0x44,0x32,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
++{0x44,0x33,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
++{0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
++{0x44,0x63,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
++{0x0A,0x14,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
++{0x0C,0x0B,0x0C,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
++{0x05,0x22,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
++{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
++{0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
++{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
++};
++
++UCHAR XGI340_CR6B[8][4]={
+ {0xaa, 0xaa, 0xaa, 0xaa},
+ {0xaa, 0xaa, 0xaa, 0xaa},
+ {0xaa, 0xaa, 0xaa, 0xaa},
+@@ -275,7 +304,32 @@ static const XGI_ExtStruct XGI330_EModeIDTable[]=
+ {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+ };
+
+-static const XGI_StandTableStruct XGI330_StandTable[]=
++/* Jong 10/04/2007; merge code */
++TimingInfo SpecialModeTiming[]=
++{
++ {1280,110, 40,220, 720, 5, 5, 20,
++ 74.18, 60, 0, 0
++ },
++ {1440, 80,152,232, 900, 1, 3, 28,
++ 106.472, 60, 0, 0
++ },
++ {1920, 88, 44,148, 540, 2, 5, 15,
++ 74.11, 60, 1, 0
++ },
++ {1920,120,208,328, 1080, 1, 3, 34,
++ 172.8, 60, 0, 0
++ },
++ {1920,128,208,336, 1200, 1, 3, 38,
++ 193.16, 60, 0, 0
++ },
++ { 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0
++ }
++};
++
++
++
++XGI_StandTableStruct XGI330_StandTable[]=
+ {
+ /* MD_0_200 */
+ {
+@@ -719,6 +773,27 @@ static const XGI_TimingHStruct XGI_TimingH[]=
+ static const XGI_TimingVStruct XGI_TimingV[]=
+ {{{0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
+
++/* Jong 10/04/2007; merge code */
++XGI_XG21CRT1Struct XGI_UpdateCRT1Table[]=
++{
++ {0x01,0x27,0x91,0x8f,0xc0}, /* 00 */
++ {0x03,0x4f,0x83,0x8f,0xc0}, /* 01 */
++ {0x05,0x27,0x91,0x8f,0xc0}, /* 02 */
++ {0x06,0x4f,0x83,0x8f,0xc0}, /* 03 */
++ {0x07,0x4f,0x83,0x8f,0xc0}, /* 04 */
++ {0x0d,0x27,0x91,0x8f,0xc0}, /* 05 */
++ {0x0e,0x4f,0x83,0x8f,0xc0}, /* 06 */
++ {0x0f,0x4f,0x83,0x5d,0xc0}, /* 07 */
++ {0x10,0x4f,0x83,0x5d,0xc0}, /* 08 */
++ {0x11,0x4f,0x83,0xdf,0x0c}, /* 09 */
++ {0x12,0x4f,0x83,0xdf,0x0c}, /* 10 */
++ {0x13,0x4f,0x83,0x8f,0xc0}, /* 11 */
++ {0x2e,0x4f,0x83,0xdf,0x0c}, /* 12 */
++ {0x2e,0x4f,0x87,0xdf,0xc0}, /* 13 */
++ {0x2f,0x4f,0x83,0x8f,0xc0}, /* 14 */
++ {0x50,0x27,0x91,0xdf,0x0c}, /* 15 */
++ {0x59,0x27,0x91,0x8f,0xc0} /* 16 */
++};
+
+ static const XGI_CRT1TableStruct XGI_CRT1Table[]=
+ {
+@@ -2542,6 +2617,74 @@ static const XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[]=
+ {{ 0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9 }} /* ; 05 (x1024) */
+ };
+
++/* Jong 10/04/2007; merge code */
++XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[]=
++{
++ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
++ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
++ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
++ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
++ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
++ 0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
++ {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
++ 0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
++ {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
++ 0x18,0x84,0xdf,0x57,0x00,0x00,0x01,0x00 }},
++ {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
++ 0x90,0x8c,0x57,0xed,0x20,0x00,0x06,0x01 }}
++};
++
++/* Jong 10/04/2007; merge code */
++XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[]=
++{
++ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
++ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
++ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
++ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
++ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
++ 0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
++ {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
++ 0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
++ {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
++ 0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,0x00 }},
++ {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
++ 0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,0x01 }}
++};
++
++/* Jong 10/04/2007; merge code */
++XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[]=
++{
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
++ {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
++ 0x50,0x84,0xdf,0xed,0x00,0x00,0x05,0x00 }},
++ {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
++ 0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,0x01 }}
++};
++
++/* Jong 10/04/2007; merge code */
++XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[]=
++{
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
++ {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
++ 0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
++ {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
++ 0x20,0x83,0xdf,0x70,0x00,0x00,0x05,0x00 }},
++ {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
++ 0x90,0x8c,0x57,0xed,0x20,0x00,0x05,0x01 }}
++};
++
+ /*add for new UNIVGABIOS*/
+ static const XGI330_LCDDataTablStruct XGI_LCDDataTable[]=
+ {
+@@ -2787,7 +2930,37 @@ static const XGI330_LCDCapStruct XGI_LCDCapList[]=
+ 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
+ };
+
+-static const XGI_Ext2Struct XGI330_RefIndex[]=
++/* Jong 10/04/2007; merge code */
++XGI21_LVDSCapStruct XGI21_LCDCapList[]=
++{
++ {DisableLCD24bpp + LCDPolarity,
++ 2160,1250,1600,1200, 64, 1, 192, 3,
++ 0x70,0x24,0x20,0x04,0x0A,0x02,0xC8
++ },
++ {DisableLCD24bpp + LCDPolarity,
++ 1688,1066,1280,1024, 48, 1, 112, 3,
++ 0x70,0x44,0x20,0x04,0x0A,0x02,0xC8
++ },
++ {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
++ 1344, 806,1024, 768, 24, 3, 136, 6,
++ 0x6C,0x65,0x20,0x04,0x0A,0x02,0xC8
++ },
++ {DisableLCD24bpp + LCDPolarity,
++ 1056, 628, 800, 600, 40, 1, 128, 4,
++ 0x42,0xE2,0x20,0x14,0x0A,0x02,0x00
++ },
++ {DisableLCD24bpp + LCDPolarity,
++ 928, 525, 800, 480, 40, 13, 48, 3,
++ 0x52,0xC5,0x20,0x14,0x0A,0x02,0x00
++ },
++ {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
++ 800, 525, 640, 480, 16, 10, 96, 2,
++ 0x1B,0xE1,0x20,0x04,0x0A,0x02,0xC8
++ }
++
++};
++
++XGI_Ext2Struct XGI330_RefIndex[]=
+ {
+ {Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x59, 320, 200},/* 00 */
+ {Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00,0x10,0x00, 320, 400},/* 01 */
+@@ -2888,6 +3061,18 @@ static const XGI_MCLKDataStruct XGI340New_MCLKData[MCLK_SIZE]=
+ { 0x29,0x01,0x81,300}
+ };
+
++/* Jong 10/04/2007; merge code */
++static const XGI_MCLKDataStruct XGI27New_MCLKData[]=
++{
++ { 0x5c,0x23,0x01,166},
++ { 0x19,0x02,0x01,124},
++ { 0x7C,0x08,0x80,200},
++ { 0x79,0x06,0x80,250},
++ { 0x29,0x01,0x81,300},
++ { 0x5c,0x23,0x01,166},
++ { 0x5c,0x23,0x01,166},
++ { 0x5c,0x23,0x01,166}
++};
+
+ static const UCHAR XGI330_ScreenOffset[]={ 0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,0x78,0x80,0x2d,0x35,0x57,0x48 };
+
+@@ -2930,6 +3115,20 @@ static const XGI_ModeResInfoStruct XGI330_ModeResInfo[]=
+ static const UCHAR XGI330_OutputSelect = 0x40;
+ static const UCHAR XGI330_SoftSetting = 0x30;
+ static const UCHAR XGI330_SR07 = 0x18;
++static const UCHAR XG21_DVOSetting = 0x00 ;
++static const UCHAR XG21_CR2E = 0x00 ;
++static const UCHAR XG21_CR2F = 0x00 ;
++static const UCHAR XG21_CR46 = 0x00 ;
++static const UCHAR XG21_CR47 = 0x00 ;
++
++UCHAR XG27_CR97 = 0xC1 ;
++UCHAR XG27_SR36 = 0x30 ;
++UCHAR XG27_CR8F = 0x09 ;
++UCHAR XG27_CRD0[] = {0,0,0,0,0,0,0,0x82,0x00,0x66,0x01,0x00} ;
++UCHAR XG27_CRDE[] = {0,0} ;
++UCHAR XG27_SR40 = 0x04 ;
++UCHAR XG27_SR41 = 0x00 ;
++
+
+ static const UCHAR XGI330_CR49[2] = { 0xaa, 0x88 };
+ static const UCHAR XGI330_SR1F = 0x00;
+diff --git a/src/vgatypes.h b/src/vgatypes.h
+index dda97fe..f26ea57 100644
+--- a/src/vgatypes.h
++++ b/src/vgatypes.h
+@@ -150,6 +150,7 @@ typedef enum _XGI_CHIP_TYPE {
+ XG45,
+ XG20 = 48,
+ XG21,
++ XG27,
+ MAX_XGI_CHIP
+ } XGI_CHIP_TYPE;
+ #endif
+@@ -279,6 +280,25 @@ struct _XGI_HW_DEVICE_INFO
+
+ UCHAR szVBIOSVer[VBIOS_VER_MAX_LENGTH];
+
++ /* Jong 09/18/2007; patch to GIT */
++ /* Jong 08/17/2007; Alan's code to support custom mode of modeline */
++ /* --------------------------------------------------------------------- */
++ UCHAR BPP;
++ UCHAR Frequency;
++ USHORT Horizontal_ACTIVE;
++ USHORT Vertical_ACTIVE;
++ UCHAR SpecialMode;
++
++ UCHAR SpecifyTiming; /* Set 1 for specifying timing*/
++ USHORT Horizontal_FP; /* Alan 08/10/2007; HSyncStart - HDisplay */
++ USHORT Horizontal_BP; /* Alan 08/10/2007; HTotal - HSyncEnd */
++ USHORT Horizontal_SYNC; /* Alan 08/10/2007; HSyncEnd - HSyncStart */
++ USHORT Vertical_FP;
++ USHORT Vertical_BP;
++ USHORT Vertical_SYNC;
++ double DCLK;
++ UCHAR Interlace; /* Alan 08/10/2007; specify interlace or not */
++ /* --------------------------------------------------------------------- */
+ };
+ #endif
+
+diff --git a/src/xgi.h b/src/xgi.h
+index 0f016d2..9a89bd7 100644
+--- a/src/xgi.h
++++ b/src/xgi.h
+@@ -1,890 +1,904 @@
+-/*
+- * Main global data and definitions
+- *
+- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1) Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2) Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3) The name of the author may not be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- * Authors: Thomas Winischhofer <thomas@winischhofer.net>
+- * others (old code base)
+- *
+- */
+-#ifndef _XGI_H_
+-#define _XGI_H_
+-
+-/***************
+-
+-#define DEBUG2
+-#define DEBUG
+-#define DEBUG1
+-#define DEBUG3
+-#define DEBUG4
+-#define DEBUG5
+-*****************/
+-
+-
+-#ifdef DEBUG
+-#define PDEBUG(p) p
+-#else
+-#define PDEBUG(p)
+-#endif
+-
+-#ifdef DEBUG1
+-#define PDEBUG1(p) p
+-#else
+-#define PDEBUG1(p)
+-#endif
+-
+-#ifdef DEBUG2
+-#define PDEBUG2(p) p
+-#else
+-#define PDEBUG2(p)
+-#endif
+-
+-#ifdef DEBUG3
+-#define PDEBUG3(p) p
+-#else
+-#define PDEBUG3(p)
+-#endif
+-
+-#ifdef DEBUG4
+-#define PDEBUG4(p) p
+-#else
+-#define PDEBUG4(p)
+-#endif
+-
+-#ifdef DEBUG5
+-#define PDEBUG5(p) p
+-#else
+-#define PDEBUG5(p)
+-#endif
+-
+-/* Always unlock the registers (should be set!) */
+-#define UNLOCK_ALWAYS
+-
+-#undef XGI_CP
+-
+-#ifdef XSERVER_LIBPCIACCESS
+-#include <pciaccess.h>
+-#else
+-#include "xf86Pci.h"
+-#endif
+-#include "xf86Cursor.h"
+-#include "xf86xv.h"
+-#include "compiler.h"
+-#include "xaa.h"
+-#include "vgaHW.h"
+-#include "vbe.h"
+-
+-#ifdef XORG_VERSION_CURRENT
+-#include "xorgVersion.h"
+-#endif
+-
+-#include "xgi_pci.h"
+-#include "osdef.h"
+-#include "vgatypes.h"
+-#include "vb_struct.h"
+-
+-#ifdef XF86DRI
+-#define XGINEWDRI
+-#undef XGINEWDRI2
+-#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,99,0) /* Adapt this when the time has come */
+-#define XGINEWDRI2
+-#endif
+-#include "xf86drm.h"
+-#include "sarea.h"
+-#define _XF86DRI_SERVER_
+-#include "xf86dri.h"
+-#include "dri.h"
+-#include "GL/glxint.h"
+-#include "xgi_dri.h"
+-#endif
+-
+-#ifdef XSERVER_LIBPCIACCESS
+-#define VENDOR_ID(p) (p)->vendor_id
+-#define DEVICE_ID(p) (p)->device_id
+-#define SUBSYS_ID(p) (p)->subdevice_id
+-#define CHIP_REVISION(p) (p)->revision
+-#else
+-#define VENDOR_ID(p) (p)->vendor
+-#define DEVICE_ID(p) (p)->chipType
+-#define SUBSYS_ID(p) (p)->subsysCard
+-#define CHIP_REVISION(p) (p)->chipRev
+-#endif
+-
+-#if 1
+-#define XGIDUALHEAD /* Include Dual Head code */
+-#endif
+-
+-#if 1
+-#define XGIMERGED /* Include Merged-FB mode */
+-#endif
+-
+-#ifdef XGIMERGED
+-#if 1
+-#define XGIXINERAMA /* Include Pseudo-Xinerama for MergedFB mode */
+-#define XGI_XINERAMA_MAJOR_VERSION 1
+-#define XGI_XINERAMA_MINOR_VERSION 1
+-#endif
+-#endif
+-
+-#if 1
+-#define XGIGAMMA /* Include code for gamma correction */
+-#endif
+-
+-#if 1 /* Include code for color hardware cursors */
+-#define XGI_ARGB_CURSOR
+-#endif
+-
+-#if 0 /* Include YPbPr support on VB */
+-#define ENABLE_YPBPR
+-#endif
+-
+-#ifdef XGIMERGED
+-#ifdef XGIXINERAMA
+-#define NEED_REPLIES /* ? */
+-#define EXTENSION_PROC_ARGS void *
+-#include "extnsionst.h" /* required */
+-#include <X11/extensions/panoramiXproto.h> /* required */
+-#endif
+-#endif
+-
+-#if 1
+-#define XGIVRAMQ /* Use VRAM queue mode on 315 series */
+-#endif
+-
+-#undef XGI315DRI /* define this if dri is adapted for 315/330 series */
+-
+-#ifndef PCI_VENDOR_XGI
+-#define PCI_VENDOR_XGI 0x18CA
+-#endif
+-#ifndef PCI_CHIP_XGIXG40
+-#define PCI_CHIP_XGIXG40 0x0040
+-#endif
+-#ifndef PCI_CHIP_XGIXG20
+-#define PCI_CHIP_XGIXG20 0x0020
+-#endif
+-
+-#define CONFIG_DRM_XGI
+-
+-#define XGI_NAME "XGI"
+-#define XGI_DRIVER_NAME "xgi"
+-#define XGI_CURRENT_VERSION ((PACKAGE_VERSION_MAJOR << 16) | \
+- (PACKAGE_VERSION_MINOR << 8) | \
+- PACKAGE_VERSION_PATCHLEVEL)
+-
+-/* pXGI->Flags (old series only) */
+-#define SYNCDRAM 0x00000001
+-#define RAMFLAG 0x00000002
+-#define ESS137xPRESENT 0x00000004
+-#define SECRETFLAG 0x00000008
+-#define A6326REVAB 0x00000010
+-#define MMIOMODE 0x00010000
+-#define LFBQMODE 0x00020000
+-#define AGPQMODE 0x00040000
+-#define UMA 0x80000000
+-
+-#define BIOS_BASE 0xC0000
+-#define BIOS_SIZE 0x10000
+-
+-#define SR_BUFFER_SIZE 5
+-#define CR_BUFFER_SIZE 5
+-
+-#define XGI_VBFlagsVersion 1
+-
+-/* VBFlags - if anything is changed here, increase VBFlagsVersion! */
+-#define CRT2_DEFAULT 0x00000001
+-#define CRT2_LCD 0x00000002 /* Never change the order of the CRT2_XXX entries */
+-#define CRT2_TV 0x00000004
+-#define CRT2_VGA 0x00000008
+-#define TV_NTSC 0x00000010
+-#define TV_PAL 0x00000020
+-#define TV_HIVISION 0x00000040
+-#define TV_YPBPR 0x00000080
+-#define TV_AVIDEO 0x00000100
+-#define TV_SVIDEO 0x00000200
+-#define TV_SCART 0x00000400
+-#define VB_CONEXANT 0x00000800 /* 661 series only */
+-#define VB_TRUMPION VB_CONEXANT /* 300 series only */
+-#define TV_PALM 0x00001000
+-#define TV_PALN 0x00002000
+-#define TV_NTSCJ 0x00001000
+-#define VB_302ELV 0x00004000
+-#define TV_CHSCART 0x00008000
+-#define TV_CHYPBPR525I 0x00010000
+-#define CRT1_VGA 0x00000000
+-#define CRT1_LCDA 0x00020000
+-#define VGA2_CONNECTED 0x00040000
+-#define DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
+-
+-#define SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
+-#define MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
+-#define DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
+-
+-/* Aliases: */
+-#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
+-#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
+-#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR)
+-
+-/* Only if TV_YPBPR is set: */
+-#define TV_YPBPR525I TV_NTSC
+-#define TV_YPBPR525P TV_PAL
+-#define TV_YPBPR750P TV_PALM
+-#define TV_YPBPR1080I TV_PALN
+-#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
+-
+-#define TV_YPBPR43LB TV_CHSCART
+-#define TV_YPBPR43 TV_CHYPBPR525I
+-#define TV_YPBPR169 (TV_CHSCART | TV_CHYPBPR525I)
+-#define TV_YPBPRAR (TV_CHSCART | TV_CHYPBPR525I)
+-
+-
+-#define DISPTYPE_DISP2 CRT2_ENABLE
+-#define DISPTYPE_DISP1 DISPTYPE_CRT1
+-#define VB_DISPMODE_SINGLE SINGLE_MODE /* alias */
+-#define VB_DISPMODE_MIRROR MIRROR_MODE /* alias */
+-#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */
+-#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
+-
+-/* PresetMode argument */
+-#define XGI_MODE_SIMU 0
+-#define XGI_MODE_CRT1 1
+-#define XGI_MODE_CRT2 2
+-
+-/* pXGI->MiscFlags */
+-#define MISC_CRT1OVERLAY 0x00000001 /* Current display mode supports overlay */
+-#define MISC_PANELLINKSCALER 0x00000002 /* Panel link is currently scaling */
+-#define MISC_CRT1OVERLAYGAMMA 0x00000004 /* Current display mode supports overlay gamma corr on CRT1 */
+-#define MISC_TVNTSC1024 0x00000008 /* Current display mode is TV NTSC/PALM/YPBPR525I 1024x768 */
+-
+-
+-#define HW_DEVICE_EXTENSION XGI_HW_DEVICE_INFO
+-
+-#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
+-#define GENMASK(mask) BITMASK(1?mask,0?mask)
+-
+-typedef unsigned long ULong;
+-typedef unsigned short UShort;
+-typedef unsigned char UChar;
+-
+-
+-/* ChipFlags */
+-/* Use only lower 16 bit for chip id! (xgictrl) */
+-#define XGICF_LARGEOVERLAY 0x00000001
+-#define XGICF_Is651 0x00000002
+-#define XGICF_IsM650 0x00000004
+-#define XGICF_IsM652 0x00000008
+-#define XGICF_IsM653 0x00000010
+-#define XGICF_Is652 0x00000020
+-#define XGICF_Is65x (XGICF_Is651|XGICF_IsM650|XGICF_IsM652|XGICF_IsM653|XGICF_Is652)
+-#define XGICF_IsM661 0x00000100 /* M661FX */
+-#define XGICF_IsM741 0x00000200
+-#define XGICF_IsM760 0x00000400
+-#define XGICF_IsM661M 0x00000800 /* M661MX */
+-#define XGICF_IsM66x (XGICF_IsM661 | XGICF_IsM741 | XGICF_IsM760 | XGICF_IsM661M)
+-#define XGICF_315Core 0x00010000 /* 3D: Real 315 */
+-#define XGICF_Real256ECore 0x00020000 /* 3D: Similar to 315 core, no T&L? (65x, 661, 740, 741) */
+-#define XGICF_XabreCore 0x00040000 /* 3D: Real Xabre */
+-#define XGICF_Ultra256Core 0x00080000 /* 3D: Similar to Xabre, no T&L?, no P:Shader? (660, 760) */
+-#define XGICF_UseLCDA 0x01000000
+-#define XGICF_760UMA 0x10000000 /* 760: UMA active */
+-#define XGICF_CRT2HWCKaputt 0x20000000 /* CRT2 Mono HWCursor engine buggy */
+-#define XGICF_Glamour3 0x40000000
+-#define XGICF_Integrated 0x80000000
+-
+-/* Direct Xv-API */
+-#define XGI_SD_IS300SERIES 0x00000001
+-#define XGI_SD_IS315SERIES 0x00000002
+-#define XGI_SD_IS330SERIES 0x00000004
+-#define XGI_SD_SUPPORTPALMN 0x00000008 /* tv chip supports pal-m, pal-n */
+-#define XGI_SD_SUPPORT2OVL 0x00000010 /* set = 2 overlays, clear = support SWITCHCRT xv prop */
+-#define XGI_SD_SUPPORTTVPOS 0x00000020 /* supports changing tv position */
+-#define XGI_SD_ISDUALHEAD 0x00000040 /* Driver is in dual head mode */
+-#define XGI_SD_ISMERGEDFB 0x00000080 /* Driver is in merged fb mode */
+-#define XGI_SD_ISDHSECONDHEAD 0x00000100 /* Dual head: This is CRT1 (=second head) */
+-#define XGI_SD_ISDHXINERAMA 0x00000200 /* Dual head: We are running Xinerama */
+-#define XGI_SD_VBHASSCART 0x00000400 /* videobridge has SCART instead of VGA2 */
+-#define XGI_SD_ISDEPTH8 0x00000800 /* Depth is 8, no independent gamma correction */
+-#define XGI_SD_ENABLED 0x00002000 /* xgictrl is enabled (by option) */
+-#define XGI_SD_PSEUDOXINERAMA 0x00004000 /* pseudo xinerama is active */
+-#define XGI_SD_SUPPORTLCDA 0x00008000 /* Support LCD Channel A */
+-#define XGI_SD_SUPPORTNTSCJ 0x00010000 /* tv chip supports ntsc-j */
+-#define XGI_SD_ADDLSUPFLAG 0x00020000 /* 1 = the following flags are valid */
+-#define XGI_SD_SUPPORTVGA2 0x00040000 /* CRT2=VGA supported */
+-#define XGI_SD_SUPPORTSCART 0x00080000 /* CRT2=SCART supported */
+-#define XGI_SD_SUPPORTOVERSCAN 0x00100000 /* Overscan flag supported */
+-#define XGI_SD_SUPPORTXVGAMMA1 0x00200000 /* Xv Gamma correction for CRT1 supported */
+-#define XGI_SD_SUPPORTTV 0x00400000 /* CRT2=TV supported */
+-#define XGI_SD_SUPPORTYPBPR 0x00800000 /* CRT2=YPbPr (525i, 525p, 750p, 1080i) is supported */
+-#define XGI_SD_SUPPORTHIVISION 0x01000000 /* CRT2=HiVision is supported */
+-#define XGI_SD_SUPPORTYPBPRAR 0x02000000 /* YPbPr aspect ratio is supported */
+-#define XGI_SD_SUPPORTSCALE 0x04000000 /* Scaling of LCD panel supported */
+-#define XGI_SD_SUPPORTCENTER 0x08000000 /* If scaling supported: Centering of screen [NOT] supported (TMDS only) */
+-
+-#define XGI_DIRECTKEY 0x03145792
+-
+-/* XGICtrl: Check mode for CRT2 */
+-#define XGI_CF2_LCD 0x01
+-#define XGI_CF2_TV 0x02
+-#define XGI_CF2_VGA2 0x04
+-#define XGI_CF2_TVPAL 0x08
+-#define XGI_CF2_TVNTSC 0x10 /* + NTSC-J */
+-#define XGI_CF2_TVPALM 0x20
+-#define XGI_CF2_TVPALN 0x40
+-#define XGI_CF2_CRT1LCDA 0x80
+-#define XGI_CF2_TYPEMASK (XGI_CF2_LCD | XGI_CF2_TV | XGI_CF2_VGA2 | XGI_CF2_CRT1LCDA)
+-#define XGI_CF2_TVSPECIAL (XGI_CF2_LCD | XGI_CF2_TV)
+-#define XGI_CF2_TVSPECMASK (XGI_CF2_TVPAL | XGI_CF2_TVNTSC | XGI_CF2_TVPALM | XGI_CF2_TVPALN)
+-#define XGI_CF2_TVHIVISION XGI_CF2_TVPAL
+-#define XGI_CF2_TVYPBPR525I XGI_CF2_TVNTSC
+-#define XGI_CF2_TVYPBPR525P (XGI_CF2_TVPAL | XGI_CF2_TVNTSC)
+-#define XGI_CF2_TVYPBPR750P XGI_CF2_TVPALM
+-#define XGI_CF2_TVYPBPR1080I (XGI_CF2_TVPALM | XGI_CF2_TVPAL)
+-
+-/* AGP stuff for DRI */
+-#define AGP_PAGE_SIZE 4096
+-#define AGP_PAGES 2048 /* Default: 2048 pages @ 4096 = 8MB */
+-/* 300 */
+-#define AGP_CMDBUF_PAGES 256
+-#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
+-/* 315/330 */
+-#define AGP_VTXBUF_PAGES 512
+-#define AGP_VTXBUF_SIZE (AGP_PAGE_SIZE * AGP_VTXBUF_PAGES)
+-
+-#define VOLARI_CQSIZE (1024*1024)
+-#define VOLARI_CQSIZEXG20 (128*1024)
+-#define VOLARI_CURSOR_SHAPE_SIZE (64*64*4)
+-
+-/* For backup of register contents */
+-typedef struct {
+- unsigned char xgiRegs3C4[0x50];
+- unsigned char xgiRegs3D4[0x90];
+- unsigned char xgiRegs3C2;
+- unsigned char xgiCapt[0x60];
+- unsigned char xgiVid[0x50];
+- unsigned char VBPart1[0x50];
+- unsigned char VBPart2[0x100];
+- unsigned char VBPart3[0x50];
+- unsigned char VBPart4[0x50];
+- unsigned short ch70xx[64];
+- unsigned long xgiMMIO85C0;
+- unsigned char xgi6326tv[0x46];
+- unsigned long xgiRegsPCI50, xgiRegsPCIA0;
+-} XGIRegRec, *XGIRegPtr;
+-
+-
+-/* XGIFBLayout is mainly there because of DGA. It holds the
+- * current layout parameters needed for acceleration and other
+- * stuff. When switching mode using DGA, these are set up
+- * accordingly and not necessarily match pScrn's. Therefore,
+- * driver modules should read these values instead of pScrn's.
+- */
+-typedef struct {
+- int bitsPerPixel; /* = pScrn->bitsPerPixel */
+- int depth; /* = pScrn->depth */
+- int displayWidth; /* = pScrn->displayWidth */
+- DisplayModePtr mode; /* = pScrn->currentMode */
+-} XGIFBLayout;
+-
+-/* Dual head private entity structure */
+-typedef struct {
+- ScrnInfoPtr pScrn_1;
+- ScrnInfoPtr pScrn_2;
+- unsigned char * BIOS;
+- VB_DEVICE_INFO *XGI_Pr;
+- int CRT2ModeNo; /* Current display mode for CRT2 */
+- Bool CRT2ModeSet; /* CRT2 mode has been set */
+- unsigned char CRT2CR30, CRT2CR31, CRT2CR35, CRT2CR38;
+- int refCount;
+-
+- /**
+- * Number of entities
+- *
+- * \bug
+- * This field is tested in one place, but it doesn't appear to ever be
+- * set or modified.
+- */
+- int lastInstance;
+-
+- Bool DisableDual; /* Emergency flag */
+- Bool ErrorAfterFirst; /* Emergency flag: Error after first init -> Abort second */
+- int maxUsedClock; /* Max used pixelclock on master head */
+-
+- /**
+- * Framebuffer addresses and sizes
+- *
+- * \bug
+- * These 4 fields are set, but the stored values don't appear to be used.
+- */
+- unsigned long masterFbAddress;
+- unsigned long masterFbSize;
+- unsigned long slaveFbAddress;
+- unsigned long slaveFbSize;
+-
+- unsigned char * FbBase; /* VRAM linear address */
+- unsigned char * IOBase; /* MMIO linear address */
+-
+- /**
+- * Map / unmap queue counter.
+- *
+- * \bug
+- * These vales are tested, set to zero, or decremented. However, I don't
+- * see anywhere in the code where they are incremented.
+- */
+- unsigned short MapCountIOBase;
+- unsigned short MapCountFbBase;
+-
+- Bool forceUnmapIOBase; /* ignore counter and unmap */
+- Bool forceUnmapFbBase; /* ignore counter and unmap */
+-#ifdef __alpha__
+- unsigned char * IOBaseDense; /* MMIO for Alpha platform */
+- unsigned short MapCountIOBaseDense;
+- Bool forceUnmapIOBaseDense; /* ignore counter and unmap */
+-#endif
+- BOOLEAN CRT1gamma;
+-
+- /**
+- * \bug This field is tested and set to \c NULL but never used.
+- */
+- unsigned char *RenderAccelArray;
+- unsigned char * FbBase1;
+- unsigned long OnScreenSize1;
+-
+-#ifdef XGI_CP
+- XGI_CP_H_ENT
+-#endif
+-} XGIEntRec, *XGIEntPtr;
+-
+-#define XGIPTR(p) ((XGIPtr)((p)->driverPrivate))
+-#define XAAPTR(p) ((XAAInfoRecPtr)(XGIPTR(p)->AccelInfoPtr))
+-
+-#define ExtRegSize 0x40
+-
+-
+-/* Relative merge position */
+-typedef enum {
+- xgiLeftOf,
+- xgiRightOf,
+- xgiAbove,
+- xgiBelow,
+- xgiClone
+-} XGIScrn2Rel;
+-
+-typedef struct MonitorRange {
+- float loH,hiH,loV,hiV ;
+-}MonitorRangeRec,*MonitorRangePtr ;
+-
+-typedef struct {
+- ScrnInfoPtr pScrn; /* -------------- DON'T INSERT ANYTHING HERE --------------- */
+-#ifdef XSERVER_LIBPCIACCESS
+- struct pci_device * PciInfo;
+-#else
+- pciVideoPtr PciInfo; /* -------- OTHERWISE xgi_dri.so MUST BE RECOMPILED -------- */
+- PCITAG PciTag;
+-#endif
+- EntityInfoPtr pEnt;
+- int Chipset;
+- int ChipRev;
+- VB_DEVICE_INFO *XGI_Pr; /* For new mode switching code */
+- unsigned long FbAddress; /* VRAM physical address (in DHM: for each Fb!) */
+- unsigned long realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */
+- unsigned char * FbBase; /* VRAM virtual linear address */
+- CARD32 IOAddress; /* MMIO physical address */
+- unsigned char * IOBase; /* MMIO linear address */
+- IOADDRESS IODBase; /* Base of PIO memory area */
+-#ifdef __alpha__
+- unsigned char * IOBaseDense; /* MMIO for Alpha platform */
+-#endif
+- XGIIOADDRESS RelIO; /* Relocated IO Ports baseaddress */
+- unsigned char * BIOS;
+- int MemClock;
+- int BusWidth;
+- int MinClock;
+- int MaxClock;
+- int Flags; /* HW config flags */
+- long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */
+- long availMem; /* Really available Fb mem (minus TQ, HWCursor) */
+- unsigned long maxxfbmem; /* limit fb memory X is to use to this (KB) */
+- unsigned long xgifbMem; /* heapstart of xgifb (if running) */
+- unsigned long dhmOffset; /* Offset to memory for each head (0 or ..) */
+- DGAModePtr DGAModes;
+- int numDGAModes;
+- Bool DGAactive;
+- Bool NoAccel;
+- Bool NoXvideo;
+- Bool TurboQueue;
+- int ForceCRT1Type;
+- int ForceCRT2Type;
+- int OptROMUsage;
+- Bool ValidWidth;
+- unsigned char myCR63;
+- unsigned long VBFlags; /* Video bridge configuration */
+- unsigned long VBFlags_backup; /* Backup for SlaveMode-modes */
+-
+- short scrnOffset; /* Screen pitch (data) */
+- short scrnPitch; /* Screen pitch (display; regarding interlace) */
+- unsigned long DstColor;
+- int xcurrent; /* for temp use in accel */
+- int ycurrent; /* for temp use in accel */
+- int CommandReg;
+-
+- Bool HWCursor;
+- CARD16 CursorSize; /* Size of HWCursor area (bytes) */
+- xf86CursorInfoPtr CursorInfoPtr;
+- unsigned CursorOffset;
+-
+- /**
+- * \bug This field is set to \c FALSE but never used.
+- */
+- Bool DoColorExpand;
+-
+- XGIRegRec SavedReg;
+- XGIRegRec ModeReg;
+- XAAInfoRecPtr AccelInfoPtr;
+- CloseScreenProcPtr CloseScreen;
+- Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode);
+- void (*XGISave)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+- void (*XGISave2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+- void (*XGISave3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+- void (*XGIRestore)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+- void (*XGIRestore2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+- void (*XGIRestore3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
+- void (*LoadCRT2Palette)(ScrnInfoPtr pScrn, int numColors,
+- int *indicies, LOCO *colors, VisualPtr pVisual);
+-
+- int cmdQueueLen; /* Current cmdQueueLength (for 2D and 3D) */
+- unsigned long cmdQueueLenMax;
+- unsigned long cmdQueueLenMin;
+- unsigned char *cmdQueueBase;
+- int *cmdQueueLenPtr; /* Ptr to variable holding the current queue length */
+- unsigned int cmdQueueOffset;
+- unsigned int cmdQueueSize;
+- unsigned long cmdQueueSizeMask;
+-
+- /**
+- * \bug This field is set but never used.
+- */
+- unsigned int agpWantedPages;
+-
+-#ifdef XF86DRI
+- unsigned long agpHandle;
+- unsigned long agpAddr;
+- unsigned char *agpBase;
+- unsigned int agpSize;
+- unsigned long agpVtxBufAddr; /* 315 series */
+- unsigned char *agpVtxBufBase;
+- unsigned int agpVtxBufSize;
+- unsigned int agpVtxBufFree;
+- xgiRegion agp;
+- Bool irqEnabled;
+- int irq;
+-#endif
+- unsigned long DRIheapstart, DRIheapend;
+-
+- void (*RenderCallback)(ScrnInfoPtr);
+-
+- /**
+- * \bug This field is tested and set to \c NULL but never used.
+- */
+- unsigned char *RenderAccelArray;
+-
+- /**
+- * \bug This field is to \c TRUE but never used.
+- */
+- Bool doRender;
+-
+- int PerColorExpandBufferSize;
+- int ColorExpandBufferNumber;
+- unsigned char *ColorExpandBufferAddr[32];
+- int ColorExpandBufferScreenOffset[32];
+-
+- /**
+- * \bug This field is read but never initialized.
+- */
+- int ImageWriteBufferSize;
+-
+- unsigned char *ImageWriteBufferAddr;
+-
+- int Rotate;
+-
+- /* ShadowFB support */
+- Bool ShadowFB;
+- unsigned char *ShadowPtr;
+- int ShadowPitch;
+-
+- /**
+- * \bug This field is set but never used.
+- */
+- Bool loadDRI;
+-
+-#ifdef XF86DRI
+- Bool directRenderingEnabled;
+- DRIInfoPtr pDRIInfo;
+- int drmSubFD;
+- int numVisualConfigs;
+- __GLXvisualConfig* pVisualConfigs;
+- XGIConfigPrivPtr pVisualConfigsPriv;
+-#endif
+-
+- HW_DEVICE_EXTENSION xgi_HwDevExt; /* For new mode switching code */
+- XF86VideoAdaptorPtr adaptor;
+- ScreenBlockHandlerProcPtr BlockHandler;
+-
+- /**
+- * \bug This field is tested and used but never set.
+- */
+- void (*VideoTimerCallback)(ScrnInfoPtr, Time);
+-
+- void (*ResetXv)(ScrnInfoPtr);
+- void (*ResetXvGamma)(ScrnInfoPtr);
+-
+- OptionInfoPtr Options;
+-
+- /**
+- * \bug This field is used but never initialized.
+- */
+- unsigned char LCDon;
+- Bool Blank;
+- int CRT1off; /* 1=CRT1 off, 0=CRT1 on */
+- CARD16 LCDheight; /* Vertical resolution of LCD panel */
+- CARD16 LCDwidth; /* Horizontal resolution of LCD panel */
+- vbeInfoPtr pVbe; /* For VESA mode switching */
+- UCHAR ScratchSet[16];
+- MonitorRangeRec CRT1Range,CRT2Range;
+-
+-#ifdef XGIDUALHEAD
+- BOOL DualHeadMode; /* TRUE if we use dual head mode */
+- BOOL SecondHead; /* TRUE is this is the second head */
+- XGIEntPtr entityPrivate; /* Ptr to private entity (see above) */
+-#endif
+- XGIFBLayout CurrentLayout; /* Current framebuffer layout */
+- BOOL Primary; /* Display adapter is primary */
+- xf86Int10InfoPtr pInt; /* Our int10 */
+-
+- /**
+- * Use our own default modes?
+- *
+- * \bug This field is set but never used.
+- */
+- Bool noInternalModes;
+-
+- int ForceTVType, SenseYPbPr;
+- int NonDefaultPAL, NonDefaultNTSC;
+- unsigned long ForceYPbPrType, ForceYPbPrAR;
+- unsigned long lockcalls; /* Count unlock calls for debug */
+-
+- Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation;
+- Atom xvAutopaintColorKey, xvSetDefaults, xvSwitchCRT;
+- Atom xvDisableGfx, xvDisableGfxLR, xvTVXPosition, xvTVYPosition;
+- Atom xvDisableColorkey, xvUseChromakey, xvChromaMin, xvChromaMax;
+- Atom xvInsideChromakey, xvYUVChromakey;
+- Atom xvGammaRed, xvGammaGreen, xvGammaBlue;
+-#ifdef XGI_CP
+- XGI_CP_H
+-#endif
+- unsigned long ChipFlags;
+- unsigned long XGI_SD_Flags;
+- int vb;
+- BOOLEAN restorebyset;
+- BOOLEAN nocrt2ddcdetection;
+- BOOLEAN forcecrt2redetection;
+- BOOLEAN CRT1gamma, CRT1gammaGiven, CRT2gamma, XvGamma, XvGammaGiven;
+- int XvDefCon, XvDefBri, XvDefHue, XvDefSat;
+- BOOLEAN XvDefDisableGfx, XvDefDisableGfxLR;
+- BOOLEAN XvUseMemcpy;
+- int XvGammaRed, XvGammaGreen, XvGammaBlue;
+- CARD8 XvGammaRampRed[256], XvGammaRampGreen[256], XvGammaRampBlue[256];
+- BOOLEAN disablecolorkeycurrent;
+- CARD32 colorKey;
+- CARD32 MiscFlags;
+- FBLinearPtr AccelLinearScratch;
+- float zClearVal;
+- unsigned long bClrColor, dwColor;
+- int AllowHotkey;
+- BOOLEAN enablexgictrl;
+- short Video_MaxWidth, Video_MaxHeight;
+- short scrnPitch2;
+- unsigned long mmioSize;
+-#ifdef XGIMERGED
+- Bool MergedFB, MergedFBAuto;
+- XGIScrn2Rel CRT2Position;
+- char * CRT2HSync;
+- char * CRT2VRefresh;
+- char * MetaModes;
+- ScrnInfoPtr CRT2pScrn;
+- DisplayModePtr CRT1Modes;
+- DisplayModePtr CRT1CurrentMode;
+- int CRT1frameX0;
+- int CRT1frameY0;
+- int CRT1frameX1;
+- int CRT1frameY1;
+- Bool CheckForCRT2;
+- int MergedFBXDPI, MergedFBYDPI;
+-#ifdef XGIXINERAMA
+- Bool UsexgiXinerama;
+- Bool CRT2IsScrn0;
+- ExtensionEntry *XineramaExtEntry;
+- int xgiXineramaVX, xgiXineramaVY;
+- Bool AtLeastOneNonClone;
+-#endif
+-#endif
+-
+- /* Added for 3D */
+- unsigned long cmdQueue_shareWP_only2D;
+- unsigned long *pCQ_shareWritePort;
+- void (*SetThreshold)(ScrnInfoPtr pScrn, DisplayModePtr mode,
+- unsigned short *Low, unsigned short *High);
+-
+- XGI_DSReg SRList[ExtRegSize] ;
+- XGI_DSReg CRList[ExtRegSize] ;
+-
+- /**
+- * Total number of iterations to wait in \c Volari_Idle.
+- */
+- unsigned int idle_wait_count;
+-
+-//:::: for capture
+- Bool v4l_videoin;
+- int v4l_devnum; /* v4l device number, 0,1,2....*/
+-//~::::
+-} XGIRec, *XGIPtr;
+-
+-#ifdef XGIDUALHEAD
+-# define IS_DUAL_HEAD(x) ((x)->DualHeadMode)
+-# define IS_SECOND_HEAD(x) ((x)->SecondHead)
+-# define ENTITY_PRIVATE(x) ((x)->entityPrivate)
+-#else
+-# define IS_DUAL_HEAD(x) FALSE
+-# define IS_SECOND_HEAD(x) FALSE
+-# define ENTITY_PRIVATE(x) NULL
+-#endif
+-
+-
+-#define SEQ_ADDRESS_PORT 0x0014
+-#define MISC_OUTPUT_REG_WRITE_PORT 0x0012
+-#define MISC_OUTPUT_REG_READ_PORT 0x001C
+-#define GRAPH_ADDRESS_PORT 0x001E
+-#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
+-#define CRTC_ADDRESS_PORT_COLOR 0x0024
+-#define PCI_COMMAND 0x04
+-
+-#define SDMPTR(x) ((XGIMergedDisplayModePtr)(x->currentMode->Private))
+-#define CDMPTR ((XGIMergedDisplayModePtr)(pXGI->CurrentLayout.mode->Private))
+-
+-#define BOUND(test,low,hi) { \
+- if(test < low) test = low; \
+- if(test > hi) test = hi; }
+-
+-#define REBOUND(low,hi,test) { \
+- if(test < low) { \
+- hi += test-low; \
+- low = test; } \
+- if(test > hi) { \
+- low += test-hi; \
+- hi = test; } }
+-
+-typedef struct _MergedDisplayModeRec {
+- DisplayModePtr CRT1;
+- DisplayModePtr CRT2;
+- XGIScrn2Rel CRT2Position;
+-} XGIMergedDisplayModeRec, *XGIMergedDisplayModePtr;
+-
+-
+-typedef struct _region {
+- int x0,x1,y0,y1;
+-} region;
+-
+-
+-extern void xgiOptions(ScrnInfoPtr pScrn);
+-extern const OptionInfoRec * XGIAvailableOptions(int chipid, int busid);
+-extern void XGISetup(ScrnInfoPtr pScrn);
+-extern void XGIVGAPreInit(ScrnInfoPtr pScrn);
+-extern Bool XGIAccelInit(ScreenPtr pScreen);
+-extern Bool XGIHWCursorInit(ScreenPtr pScreen);
+-extern Bool XGIDGAInit(ScreenPtr pScreen);
+-extern void XGIInitVideo(ScreenPtr pScreen);
+-
+-extern int XGI_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn);
+-
+-int XG40Mclk(XGIPtr pXGI);
+-
+-void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
+-int compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+- int *out_sbit, int *out_scale);
+-
+-void XGI_WaitBeginRetrace(XGIIOADDRESS RelIO);
+-void XGI_WaitEndRetrace(XGIIOADDRESS RelIO);
+-
+-/* 2005/11/21 added by jjtseng */
+-#define DelayS(sec) usleep((sec)*1000000)
+-#define DelayMS(millisec) usleep((millisec)*1000)
+-#define DelayUS(microsec) usleep((microsec))
+-/*~jjtseng 2005/11/21 */
+-
+-Bool Volari_AccelInit(ScreenPtr pScreen) ;
+-/* void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+-/* void XGI_LockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+-/* void XGI_DisableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+-/* void XGI_EnableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
+-#endif
+-
+-extern USHORT XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
+- int Depth, int LCDwith, int LCDheight);
+-
+-extern BOOLEAN XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
+- const XGI_ExtStruct *EModeIDTable, unsigned char VGAINFO,
+- USHORT *ModeNo, USHORT *ModeIdIndex);
+-
+-extern UCHAR XGI_GetModePtr(const XGI_StStruct *SModeIDTable,
+- unsigned ModeType, USHORT ModeNo, USHORT ModeIdIndex);
+-
+-extern void XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data);
+-extern void XGI_SetRegByte(XGIIOADDRESS port, USHORT data);
+-extern void XGI_SetRegShort(XGIIOADDRESS port, USHORT data);
+-extern void XGI_SetRegLong(XGIIOADDRESS port, ULONG data);
+-extern UCHAR XGI_GetReg(XGIIOADDRESS port, USHORT index);
+-extern UCHAR XGI_GetRegByte(XGIIOADDRESS port);
+-extern USHORT XGI_GetRegShort(XGIIOADDRESS port);
+-extern ULONG XGI_GetRegLong(XGIIOADDRESS port);
+-extern void XGI_SetRegANDOR(XGIIOADDRESS Port, USHORT Index, USHORT DataAND,
+- USHORT DataOR);
+-extern void XGI_SetRegAND(XGIIOADDRESS Port, USHORT Index, USHORT DataAND);
+-extern void XGI_SetRegOR(XGIIOADDRESS Port, USHORT Index, USHORT DataOR);
+-
+-extern void XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift,
+- unsigned ordering, uint8_t red, uint8_t green, uint8_t blue);
+-
+-#ifdef DEBUG
+-void XGIDumpRegs(ScrnInfoPtr pScrn);
+-
+-/**
+- * Write value to the PC's 0x80 debug port.
+- *
+- * \bug
+- * I'm pretty sure the debug 0x80 only exists on PCs. Should this routine
+- * be a no-op on non-x86 and non-x86-64 architectures?
+- */
+-#define Newdebugcode(dbg_code) outb(0x80, dbg_code)
+-#else
+-#define Newdebugcode(dbg_code)
+-#endif
++/*
++ * Main global data and definitions
++ *
++ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1) Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2) Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3) The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Authors: Thomas Winischhofer <thomas@winischhofer.net>
++ * others (old code base)
++ *
++ */
++#ifndef _XGI_H_
++#define _XGI_H_
++
++/***************
++#define DEBUG2
++#define DEBUG
++#define DEBUG1
++#define DEBUG3
++#define DEBUG4
++#define DEBUG5
++*****************/
++
++
++#ifdef DEBUG
++#define PDEBUG(p) p
++#else
++#define PDEBUG(p)
++#endif
++
++#ifdef DEBUG1
++#define PDEBUG1(p) p
++#else
++#define PDEBUG1(p)
++#endif
++
++#ifdef DEBUG2
++#define PDEBUG2(p) p
++#else
++#define PDEBUG2(p)
++#endif
++
++#ifdef DEBUG3
++#define PDEBUG3(p) p
++#else
++#define PDEBUG3(p)
++#endif
++
++#ifdef DEBUG4
++#define PDEBUG4(p) p
++#else
++#define PDEBUG4(p)
++#endif
++
++#ifdef DEBUG5
++#define PDEBUG5(p) p
++#else
++#define PDEBUG5(p)
++#endif
++
++/* Always unlock the registers (should be set!) */
++#define UNLOCK_ALWAYS
++
++#undef XGI_CP
++
++#ifdef XSERVER_LIBPCIACCESS
++#include <pciaccess.h>
++#else
++#include "xf86Pci.h"
++#endif
++#include "xf86Cursor.h"
++#include "xf86xv.h"
++#include "compiler.h"
++#include "xaa.h"
++#include "vgaHW.h"
++#include "vbe.h"
++
++#ifdef XORG_VERSION_CURRENT
++#include "xorgVersion.h"
++#endif
++
++#include "xgi_pci.h"
++#include "osdef.h"
++#include "vgatypes.h"
++#include "vb_struct.h"
++
++#ifdef XF86DRI
++#define XGINEWDRI
++#undef XGINEWDRI2
++#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,4,99,99,0) /* Adapt this when the time has come */
++#define XGINEWDRI2
++#endif
++#include "xf86drm.h"
++#include "sarea.h"
++#define _XF86DRI_SERVER_
++#include "xf86dri.h"
++#include "dri.h"
++#include "GL/glxint.h"
++#include "xgi_dri.h"
++#endif
++
++#ifdef XSERVER_LIBPCIACCESS
++#define VENDOR_ID(p) (p)->vendor_id
++#define DEVICE_ID(p) (p)->device_id
++#define SUBSYS_ID(p) (p)->subdevice_id
++#define CHIP_REVISION(p) (p)->revision
++#else
++#define VENDOR_ID(p) (p)->vendor
++#define DEVICE_ID(p) (p)->chipType
++#define SUBSYS_ID(p) (p)->subsysCard
++#define CHIP_REVISION(p) (p)->chipRev
++#endif
++
++#if 1
++#define XGIDUALHEAD /* Include Dual Head code */
++#endif
++
++#if 1
++#define XGIMERGED /* Include Merged-FB mode */
++#endif
++
++#ifdef XGIMERGED
++#if 1
++#define XGIXINERAMA /* Include Pseudo-Xinerama for MergedFB mode */
++#define XGI_XINERAMA_MAJOR_VERSION 1
++#define XGI_XINERAMA_MINOR_VERSION 1
++#endif
++#endif
++
++#if 1
++#define XGIGAMMA /* Include code for gamma correction */
++#endif
++
++/* Jong 09/28/2007; disable this because it causes cursor drawing incorrectly */
++#if 0 /* Include code for color hardware cursors */
++#define XGI_ARGB_CURSOR
++#endif
++
++#if 0 /* Include YPbPr support on VB */
++#define ENABLE_YPBPR
++#endif
++
++#ifdef XGIMERGED
++#ifdef XGIXINERAMA
++#define NEED_REPLIES /* ? */
++#define EXTENSION_PROC_ARGS void *
++#include "extnsionst.h" /* required */
++#include <X11/extensions/panoramiXproto.h> /* required */
++#endif
++#endif
++
++#if 1
++#define XGIVRAMQ /* Use VRAM queue mode on 315 series */
++#endif
++
++#undef XGI315DRI /* define this if dri is adapted for 315/330 series */
++
++#ifndef PCI_VENDOR_XGI
++#define PCI_VENDOR_XGI 0x18CA
++#endif
++#ifndef PCI_CHIP_XGIXG40
++#define PCI_CHIP_XGIXG40 0x0040
++#endif
++#ifndef PCI_CHIP_XGIXG20
++#define PCI_CHIP_XGIXG20 0x0020
++#endif
++
++/* Jong 09/18/2007; patch to GIT */
++#ifndef PCI_CHIP_XGIXG27
++#define PCI_CHIP_XGIXG27 0x0027
++#endif
++
++/* Jong 01/07/2008; support New XG21 */
++#ifndef PCI_CHIP_XGIXG21
++#define PCI_CHIP_XGIXG21 0x0021
++#endif
++
++#define CONFIG_DRM_XGI
++
++#define XGI_NAME "XGI"
++#define XGI_DRIVER_NAME "xgi"
++#define XGI_CURRENT_VERSION ((PACKAGE_VERSION_MAJOR << 16) | \
++ (PACKAGE_VERSION_MINOR << 8) | \
++ PACKAGE_VERSION_PATCHLEVEL)
++
++/* pXGI->Flags (old series only) */
++#define SYNCDRAM 0x00000001
++#define RAMFLAG 0x00000002
++#define ESS137xPRESENT 0x00000004
++#define SECRETFLAG 0x00000008
++#define A6326REVAB 0x00000010
++#define MMIOMODE 0x00010000
++#define LFBQMODE 0x00020000
++#define AGPQMODE 0x00040000
++#define UMA 0x80000000
++
++#define BIOS_BASE 0xC0000
++#define BIOS_SIZE 0x10000
++
++#define SR_BUFFER_SIZE 5
++#define CR_BUFFER_SIZE 5
++
++#define XGI_VBFlagsVersion 1
++
++/* VBFlags - if anything is changed here, increase VBFlagsVersion! */
++#define CRT2_DEFAULT 0x00000001
++#define CRT2_LCD 0x00000002 /* Never change the order of the CRT2_XXX entries */
++#define CRT2_TV 0x00000004
++#define CRT2_VGA 0x00000008
++#define TV_NTSC 0x00000010
++#define TV_PAL 0x00000020
++#define TV_HIVISION 0x00000040
++#define TV_YPBPR 0x00000080
++#define TV_AVIDEO 0x00000100
++#define TV_SVIDEO 0x00000200
++#define TV_SCART 0x00000400
++#define VB_CONEXANT 0x00000800 /* 661 series only */
++#define VB_TRUMPION VB_CONEXANT /* 300 series only */
++#define TV_PALM 0x00001000
++#define TV_PALN 0x00002000
++#define TV_NTSCJ 0x00001000
++#define VB_302ELV 0x00004000
++#define TV_CHSCART 0x00008000
++#define TV_CHYPBPR525I 0x00010000
++#define CRT1_VGA 0x00000000
++#define CRT1_LCDA 0x00020000
++#define VGA2_CONNECTED 0x00040000
++#define DISPTYPE_CRT1 0x00080000 /* CRT1 connected and used */
++
++#define SINGLE_MODE 0x20000000 /* CRT1 or CRT2; determined by DISPTYPE_CRTx */
++#define MIRROR_MODE 0x40000000 /* CRT1 + CRT2 identical (mirror mode) */
++#define DUALVIEW_MODE 0x80000000 /* CRT1 + CRT2 independent (dual head mode) */
++
++/* Aliases: */
++#define CRT2_ENABLE (CRT2_LCD | CRT2_TV | CRT2_VGA)
++#define TV_STANDARD (TV_NTSC | TV_PAL | TV_PALM | TV_PALN | TV_NTSCJ)
++#define TV_INTERFACE (TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR)
++
++/* Only if TV_YPBPR is set: */
++#define TV_YPBPR525I TV_NTSC
++#define TV_YPBPR525P TV_PAL
++#define TV_YPBPR750P TV_PALM
++#define TV_YPBPR1080I TV_PALN
++#define TV_YPBPRALL (TV_YPBPR525I | TV_YPBPR525P | TV_YPBPR750P | TV_YPBPR1080I)
++
++#define TV_YPBPR43LB TV_CHSCART
++#define TV_YPBPR43 TV_CHYPBPR525I
++#define TV_YPBPR169 (TV_CHSCART | TV_CHYPBPR525I)
++#define TV_YPBPRAR (TV_CHSCART | TV_CHYPBPR525I)
++
++
++#define DISPTYPE_DISP2 CRT2_ENABLE
++#define DISPTYPE_DISP1 DISPTYPE_CRT1
++#define VB_DISPMODE_SINGLE SINGLE_MODE /* alias */
++#define VB_DISPMODE_MIRROR MIRROR_MODE /* alias */
++#define VB_DISPMODE_DUAL DUALVIEW_MODE /* alias */
++#define DISPLAY_MODE (SINGLE_MODE | MIRROR_MODE | DUALVIEW_MODE)
++
++/* PresetMode argument */
++#define XGI_MODE_SIMU 0
++#define XGI_MODE_CRT1 1
++#define XGI_MODE_CRT2 2
++
++/* pXGI->MiscFlags */
++#define MISC_CRT1OVERLAY 0x00000001 /* Current display mode supports overlay */
++#define MISC_PANELLINKSCALER 0x00000002 /* Panel link is currently scaling */
++#define MISC_CRT1OVERLAYGAMMA 0x00000004 /* Current display mode supports overlay gamma corr on CRT1 */
++#define MISC_TVNTSC1024 0x00000008 /* Current display mode is TV NTSC/PALM/YPBPR525I 1024x768 */
++
++
++#define HW_DEVICE_EXTENSION XGI_HW_DEVICE_INFO
++
++#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l))
++#define GENMASK(mask) BITMASK(1?mask,0?mask)
++
++typedef unsigned long ULong;
++typedef unsigned short UShort;
++typedef unsigned char UChar;
++
++
++/* ChipFlags */
++/* Use only lower 16 bit for chip id! (xgictrl) */
++#define XGICF_LARGEOVERLAY 0x00000001
++#define XGICF_Is651 0x00000002
++#define XGICF_IsM650 0x00000004
++#define XGICF_IsM652 0x00000008
++#define XGICF_IsM653 0x00000010
++#define XGICF_Is652 0x00000020
++#define XGICF_Is65x (XGICF_Is651|XGICF_IsM650|XGICF_IsM652|XGICF_IsM653|XGICF_Is652)
++#define XGICF_IsM661 0x00000100 /* M661FX */
++#define XGICF_IsM741 0x00000200
++#define XGICF_IsM760 0x00000400
++#define XGICF_IsM661M 0x00000800 /* M661MX */
++#define XGICF_IsM66x (XGICF_IsM661 | XGICF_IsM741 | XGICF_IsM760 | XGICF_IsM661M)
++#define XGICF_315Core 0x00010000 /* 3D: Real 315 */
++#define XGICF_Real256ECore 0x00020000 /* 3D: Similar to 315 core, no T&L? (65x, 661, 740, 741) */
++#define XGICF_XabreCore 0x00040000 /* 3D: Real Xabre */
++#define XGICF_Ultra256Core 0x00080000 /* 3D: Similar to Xabre, no T&L?, no P:Shader? (660, 760) */
++#define XGICF_UseLCDA 0x01000000
++#define XGICF_760UMA 0x10000000 /* 760: UMA active */
++#define XGICF_CRT2HWCKaputt 0x20000000 /* CRT2 Mono HWCursor engine buggy */
++#define XGICF_Glamour3 0x40000000
++#define XGICF_Integrated 0x80000000
++
++/* Direct Xv-API */
++#define XGI_SD_IS300SERIES 0x00000001
++#define XGI_SD_IS315SERIES 0x00000002
++#define XGI_SD_IS330SERIES 0x00000004
++#define XGI_SD_SUPPORTPALMN 0x00000008 /* tv chip supports pal-m, pal-n */
++#define XGI_SD_SUPPORT2OVL 0x00000010 /* set = 2 overlays, clear = support SWITCHCRT xv prop */
++#define XGI_SD_SUPPORTTVPOS 0x00000020 /* supports changing tv position */
++#define XGI_SD_ISDUALHEAD 0x00000040 /* Driver is in dual head mode */
++#define XGI_SD_ISMERGEDFB 0x00000080 /* Driver is in merged fb mode */
++#define XGI_SD_ISDHSECONDHEAD 0x00000100 /* Dual head: This is CRT1 (=second head) */
++#define XGI_SD_ISDHXINERAMA 0x00000200 /* Dual head: We are running Xinerama */
++#define XGI_SD_VBHASSCART 0x00000400 /* videobridge has SCART instead of VGA2 */
++#define XGI_SD_ISDEPTH8 0x00000800 /* Depth is 8, no independent gamma correction */
++#define XGI_SD_ENABLED 0x00002000 /* xgictrl is enabled (by option) */
++#define XGI_SD_PSEUDOXINERAMA 0x00004000 /* pseudo xinerama is active */
++#define XGI_SD_SUPPORTLCDA 0x00008000 /* Support LCD Channel A */
++#define XGI_SD_SUPPORTNTSCJ 0x00010000 /* tv chip supports ntsc-j */
++#define XGI_SD_ADDLSUPFLAG 0x00020000 /* 1 = the following flags are valid */
++#define XGI_SD_SUPPORTVGA2 0x00040000 /* CRT2=VGA supported */
++#define XGI_SD_SUPPORTSCART 0x00080000 /* CRT2=SCART supported */
++#define XGI_SD_SUPPORTOVERSCAN 0x00100000 /* Overscan flag supported */
++#define XGI_SD_SUPPORTXVGAMMA1 0x00200000 /* Xv Gamma correction for CRT1 supported */
++#define XGI_SD_SUPPORTTV 0x00400000 /* CRT2=TV supported */
++#define XGI_SD_SUPPORTYPBPR 0x00800000 /* CRT2=YPbPr (525i, 525p, 750p, 1080i) is supported */
++#define XGI_SD_SUPPORTHIVISION 0x01000000 /* CRT2=HiVision is supported */
++#define XGI_SD_SUPPORTYPBPRAR 0x02000000 /* YPbPr aspect ratio is supported */
++#define XGI_SD_SUPPORTSCALE 0x04000000 /* Scaling of LCD panel supported */
++#define XGI_SD_SUPPORTCENTER 0x08000000 /* If scaling supported: Centering of screen [NOT] supported (TMDS only) */
++
++#define XGI_DIRECTKEY 0x03145792
++
++/* XGICtrl: Check mode for CRT2 */
++#define XGI_CF2_LCD 0x01
++#define XGI_CF2_TV 0x02
++#define XGI_CF2_VGA2 0x04
++#define XGI_CF2_TVPAL 0x08
++#define XGI_CF2_TVNTSC 0x10 /* + NTSC-J */
++#define XGI_CF2_TVPALM 0x20
++#define XGI_CF2_TVPALN 0x40
++#define XGI_CF2_CRT1LCDA 0x80
++#define XGI_CF2_TYPEMASK (XGI_CF2_LCD | XGI_CF2_TV | XGI_CF2_VGA2 | XGI_CF2_CRT1LCDA)
++#define XGI_CF2_TVSPECIAL (XGI_CF2_LCD | XGI_CF2_TV)
++#define XGI_CF2_TVSPECMASK (XGI_CF2_TVPAL | XGI_CF2_TVNTSC | XGI_CF2_TVPALM | XGI_CF2_TVPALN)
++#define XGI_CF2_TVHIVISION XGI_CF2_TVPAL
++#define XGI_CF2_TVYPBPR525I XGI_CF2_TVNTSC
++#define XGI_CF2_TVYPBPR525P (XGI_CF2_TVPAL | XGI_CF2_TVNTSC)
++#define XGI_CF2_TVYPBPR750P XGI_CF2_TVPALM
++#define XGI_CF2_TVYPBPR1080I (XGI_CF2_TVPALM | XGI_CF2_TVPAL)
++
++/* AGP stuff for DRI */
++#define AGP_PAGE_SIZE 4096
++#define AGP_PAGES 2048 /* Default: 2048 pages @ 4096 = 8MB */
++/* 300 */
++#define AGP_CMDBUF_PAGES 256
++#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
++/* 315/330 */
++#define AGP_VTXBUF_PAGES 512
++#define AGP_VTXBUF_SIZE (AGP_PAGE_SIZE * AGP_VTXBUF_PAGES)
++
++#define VOLARI_CQSIZE (1024*1024)
++#define VOLARI_CQSIZEXG20 (128*1024)
++#define VOLARI_CURSOR_SHAPE_SIZE (64*64*4)
++
++/* For backup of register contents */
++typedef struct {
++ unsigned char xgiRegs3C4[0x50];
++ unsigned char xgiRegs3D4[0x90];
++ unsigned char xgiRegs3C2;
++ unsigned char xgiCapt[0x60];
++ unsigned char xgiVid[0x50];
++ unsigned char VBPart1[0x50];
++ unsigned char VBPart2[0x100];
++ unsigned char VBPart3[0x50];
++ unsigned char VBPart4[0x50];
++ unsigned short ch70xx[64];
++ unsigned long xgiMMIO85C0;
++ unsigned char xgi6326tv[0x46];
++ unsigned long xgiRegsPCI50, xgiRegsPCIA0;
++} XGIRegRec, *XGIRegPtr;
++
++
++/* XGIFBLayout is mainly there because of DGA. It holds the
++ * current layout parameters needed for acceleration and other
++ * stuff. When switching mode using DGA, these are set up
++ * accordingly and not necessarily match pScrn's. Therefore,
++ * driver modules should read these values instead of pScrn's.
++ */
++typedef struct {
++ int bitsPerPixel; /* = pScrn->bitsPerPixel */
++ int depth; /* = pScrn->depth */
++ int displayWidth; /* = pScrn->displayWidth */
++ DisplayModePtr mode; /* = pScrn->currentMode */
++} XGIFBLayout;
++
++/* Dual head private entity structure */
++typedef struct {
++ ScrnInfoPtr pScrn_1;
++ ScrnInfoPtr pScrn_2;
++ unsigned char * BIOS;
++ VB_DEVICE_INFO *XGI_Pr;
++ int CRT2ModeNo; /* Current display mode for CRT2 */
++ Bool CRT2ModeSet; /* CRT2 mode has been set */
++ unsigned char CRT2CR30, CRT2CR31, CRT2CR35, CRT2CR38;
++ int refCount;
++
++ /**
++ * Number of entities
++ *
++ * \bug
++ * This field is tested in one place, but it doesn't appear to ever be
++ * set or modified.
++ */
++ int lastInstance;
++
++ Bool DisableDual; /* Emergency flag */
++ Bool ErrorAfterFirst; /* Emergency flag: Error after first init -> Abort second */
++ int maxUsedClock; /* Max used pixelclock on master head */
++
++ /**
++ * Framebuffer addresses and sizes
++ *
++ * \bug
++ * These 4 fields are set, but the stored values don't appear to be used.
++ */
++ unsigned long masterFbAddress;
++ unsigned long masterFbSize;
++ unsigned long slaveFbAddress;
++ unsigned long slaveFbSize;
++
++ unsigned char * FbBase; /* VRAM linear address */
++ unsigned char * IOBase; /* MMIO linear address */
++
++ /**
++ * Map / unmap queue counter.
++ *
++ * \bug
++ * These vales are tested, set to zero, or decremented. However, I don't
++ * see anywhere in the code where they are incremented.
++ */
++ unsigned short MapCountIOBase;
++ unsigned short MapCountFbBase;
++
++ Bool forceUnmapIOBase; /* ignore counter and unmap */
++ Bool forceUnmapFbBase; /* ignore counter and unmap */
++#ifdef __alpha__
++ unsigned char * IOBaseDense; /* MMIO for Alpha platform */
++ unsigned short MapCountIOBaseDense;
++ Bool forceUnmapIOBaseDense; /* ignore counter and unmap */
++#endif
++ BOOLEAN CRT1gamma;
++
++ /**
++ * \bug This field is tested and set to \c NULL but never used.
++ */
++ unsigned char *RenderAccelArray;
++ unsigned char * FbBase1;
++ unsigned long OnScreenSize1;
++
++#ifdef XGI_CP
++ XGI_CP_H_ENT
++#endif
++} XGIEntRec, *XGIEntPtr;
++
++#define XGIPTR(p) ((XGIPtr)((p)->driverPrivate))
++#define XAAPTR(p) ((XAAInfoRecPtr)(XGIPTR(p)->AccelInfoPtr))
++
++#define ExtRegSize 0x40
++
++
++/* Relative merge position */
++typedef enum {
++ xgiLeftOf,
++ xgiRightOf,
++ xgiAbove,
++ xgiBelow,
++ xgiClone
++} XGIScrn2Rel;
++
++typedef struct MonitorRange {
++ float loH,hiH,loV,hiV ;
++}MonitorRangeRec,*MonitorRangePtr ;
++
++typedef struct {
++ ScrnInfoPtr pScrn; /* -------------- DON'T INSERT ANYTHING HERE --------------- */
++#ifdef XSERVER_LIBPCIACCESS
++ struct pci_device * PciInfo;
++#else
++ pciVideoPtr PciInfo; /* -------- OTHERWISE xgi_dri.so MUST BE RECOMPILED -------- */
++ PCITAG PciTag;
++#endif
++ EntityInfoPtr pEnt;
++ int Chipset;
++ int ChipRev;
++ VB_DEVICE_INFO *XGI_Pr; /* For new mode switching code */
++ unsigned long FbAddress; /* VRAM physical address (in DHM: for each Fb!) */
++ unsigned long realFbAddress; /* For DHM/PCI mem mapping: store global FBAddress */
++ unsigned char * FbBase; /* VRAM virtual linear address */
++ CARD32 IOAddress; /* MMIO physical address */
++ unsigned char * IOBase; /* MMIO linear address */
++ IOADDRESS IODBase; /* Base of PIO memory area */
++#ifdef __alpha__
++ unsigned char * IOBaseDense; /* MMIO for Alpha platform */
++#endif
++ XGIIOADDRESS RelIO; /* Relocated IO Ports baseaddress */
++ unsigned char * BIOS;
++ int MemClock;
++ int BusWidth;
++ int MinClock;
++ int MaxClock;
++ int Flags; /* HW config flags */
++ long FbMapSize; /* Used for Mem Mapping - DON'T CHANGE THIS */
++ long availMem; /* Really available Fb mem (minus TQ, HWCursor) */
++ unsigned long maxxfbmem; /* limit fb memory X is to use to this (KB) */
++ unsigned long xgifbMem; /* heapstart of xgifb (if running) */
++ unsigned long dhmOffset; /* Offset to memory for each head (0 or ..) */
++ DGAModePtr DGAModes;
++ int numDGAModes;
++ Bool DGAactive;
++ Bool NoAccel;
++ Bool NoXvideo;
++ Bool TurboQueue;
++ int ForceCRT1Type;
++ int ForceCRT2Type;
++ int OptROMUsage;
++ Bool ValidWidth;
++ unsigned char myCR63;
++ unsigned long VBFlags; /* Video bridge configuration */
++ unsigned long VBFlags_backup; /* Backup for SlaveMode-modes */
++
++ short scrnOffset; /* Screen pitch (data) */
++ short scrnPitch; /* Screen pitch (display; regarding interlace) */
++ unsigned long DstColor;
++ int xcurrent; /* for temp use in accel */
++ int ycurrent; /* for temp use in accel */
++ int CommandReg;
++
++ Bool HWCursor;
++ CARD16 CursorSize; /* Size of HWCursor area (bytes) */
++ xf86CursorInfoPtr CursorInfoPtr;
++ unsigned CursorOffset;
++
++ /**
++ * \bug This field is set to \c FALSE but never used.
++ */
++ Bool DoColorExpand;
++
++ XGIRegRec SavedReg;
++ XGIRegRec ModeReg;
++ XAAInfoRecPtr AccelInfoPtr;
++ CloseScreenProcPtr CloseScreen;
++ Bool (*ModeInit)(ScrnInfoPtr pScrn, DisplayModePtr mode);
++ void (*XGISave)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
++ void (*XGISave2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
++ void (*XGISave3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
++ void (*XGIRestore)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
++ void (*XGIRestore2)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
++ void (*XGIRestore3)(ScrnInfoPtr pScrn, XGIRegPtr xgireg);
++ void (*LoadCRT2Palette)(ScrnInfoPtr pScrn, int numColors,
++ int *indicies, LOCO *colors, VisualPtr pVisual);
++
++ int cmdQueueLen; /* Current cmdQueueLength (for 2D and 3D) */
++ unsigned long cmdQueueLenMax;
++ unsigned long cmdQueueLenMin;
++ unsigned char *cmdQueueBase;
++ int *cmdQueueLenPtr; /* Ptr to variable holding the current queue length */
++ unsigned int cmdQueueOffset;
++ unsigned int cmdQueueSize;
++ unsigned long cmdQueueSizeMask;
++
++ /**
++ * \bug This field is set but never used.
++ */
++ unsigned int agpWantedPages;
++
++#ifdef XF86DRI
++ unsigned long agpHandle;
++ unsigned long agpAddr;
++ unsigned char *agpBase;
++ unsigned int agpSize;
++ unsigned long agpVtxBufAddr; /* 315 series */
++ unsigned char *agpVtxBufBase;
++ unsigned int agpVtxBufSize;
++ unsigned int agpVtxBufFree;
++ xgiRegion agp;
++ Bool irqEnabled;
++ int irq;
++#endif
++ unsigned long DRIheapstart, DRIheapend;
++
++ void (*RenderCallback)(ScrnInfoPtr);
++
++ /**
++ * \bug This field is tested and set to \c NULL but never used.
++ */
++ unsigned char *RenderAccelArray;
++
++ /**
++ * \bug This field is to \c TRUE but never used.
++ */
++ Bool doRender;
++
++ int PerColorExpandBufferSize;
++ int ColorExpandBufferNumber;
++ unsigned char *ColorExpandBufferAddr[32];
++ int ColorExpandBufferScreenOffset[32];
++
++ /**
++ * \bug This field is read but never initialized.
++ */
++ int ImageWriteBufferSize;
++
++ unsigned char *ImageWriteBufferAddr;
++
++ int Rotate;
++
++ /* ShadowFB support */
++ Bool ShadowFB;
++ unsigned char *ShadowPtr;
++ int ShadowPitch;
++
++ /**
++ * \bug This field is set but never used.
++ */
++ Bool loadDRI;
++
++#ifdef XF86DRI
++ Bool directRenderingEnabled;
++ DRIInfoPtr pDRIInfo;
++ int drmSubFD;
++ int numVisualConfigs;
++ __GLXvisualConfig* pVisualConfigs;
++ XGIConfigPrivPtr pVisualConfigsPriv;
++#endif
++
++ HW_DEVICE_EXTENSION xgi_HwDevExt; /* For new mode switching code */
++ XF86VideoAdaptorPtr adaptor;
++ ScreenBlockHandlerProcPtr BlockHandler;
++
++ /**
++ * \bug This field is tested and used but never set.
++ */
++ void (*VideoTimerCallback)(ScrnInfoPtr, Time);
++
++ void (*ResetXv)(ScrnInfoPtr);
++ void (*ResetXvGamma)(ScrnInfoPtr);
++
++ OptionInfoPtr Options;
++
++ /**
++ * \bug This field is used but never initialized.
++ */
++ unsigned char LCDon;
++ Bool Blank;
++ int CRT1off; /* 1=CRT1 off, 0=CRT1 on */
++ CARD16 LCDheight; /* Vertical resolution of LCD panel */
++ CARD16 LCDwidth; /* Horizontal resolution of LCD panel */
++ vbeInfoPtr pVbe; /* For VESA mode switching */
++ UCHAR ScratchSet[16];
++ MonitorRangeRec CRT1Range,CRT2Range;
++
++#ifdef XGIDUALHEAD
++ BOOL DualHeadMode; /* TRUE if we use dual head mode */
++ BOOL SecondHead; /* TRUE is this is the second head */
++ XGIEntPtr entityPrivate; /* Ptr to private entity (see above) */
++#endif
++ XGIFBLayout CurrentLayout; /* Current framebuffer layout */
++ BOOL Primary; /* Display adapter is primary */
++ xf86Int10InfoPtr pInt; /* Our int10 */
++
++ /**
++ * Use our own default modes?
++ *
++ * \bug This field is set but never used.
++ */
++ Bool noInternalModes;
++
++ int ForceTVType, SenseYPbPr;
++ int NonDefaultPAL, NonDefaultNTSC;
++ unsigned long ForceYPbPrType, ForceYPbPrAR;
++ unsigned long lockcalls; /* Count unlock calls for debug */
++
++ Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation;
++ Atom xvAutopaintColorKey, xvSetDefaults, xvSwitchCRT;
++ Atom xvDisableGfx, xvDisableGfxLR, xvTVXPosition, xvTVYPosition;
++ Atom xvDisableColorkey, xvUseChromakey, xvChromaMin, xvChromaMax;
++ Atom xvInsideChromakey, xvYUVChromakey;
++ Atom xvGammaRed, xvGammaGreen, xvGammaBlue;
++#ifdef XGI_CP
++ XGI_CP_H
++#endif
++ unsigned long ChipFlags;
++ unsigned long XGI_SD_Flags;
++ BOOLEAN UseHWARGBCursor;
++ BOOLEAN HWARGBCursor;
++ int vb;
++ BOOLEAN restorebyset;
++ BOOLEAN nocrt2ddcdetection;
++ BOOLEAN forcecrt2redetection;
++ BOOLEAN CRT1gamma, CRT1gammaGiven, CRT2gamma, XvGamma, XvGammaGiven;
++ int XvDefCon, XvDefBri, XvDefHue, XvDefSat;
++ BOOLEAN XvDefDisableGfx, XvDefDisableGfxLR;
++ BOOLEAN XvUseMemcpy;
++ int XvGammaRed, XvGammaGreen, XvGammaBlue;
++ CARD8 XvGammaRampRed[256], XvGammaRampGreen[256], XvGammaRampBlue[256];
++ BOOLEAN disablecolorkeycurrent;
++ CARD32 colorKey;
++ CARD32 MiscFlags;
++ FBLinearPtr AccelLinearScratch;
++ float zClearVal;
++ unsigned long bClrColor, dwColor;
++ int AllowHotkey;
++ BOOLEAN enablexgictrl;
++ short Video_MaxWidth, Video_MaxHeight;
++ short scrnPitch2;
++ int CurXPreset ;
++ int CurYPreset ;
++ unsigned long mmioSize;
++#ifdef XGIMERGED
++ Bool MergedFB, MergedFBAuto;
++ XGIScrn2Rel CRT2Position;
++ char * CRT2HSync;
++ char * CRT2VRefresh;
++ char * MetaModes;
++ ScrnInfoPtr CRT2pScrn;
++ DisplayModePtr CRT1Modes;
++ DisplayModePtr CRT1CurrentMode;
++ int CRT1frameX0;
++ int CRT1frameY0;
++ int CRT1frameX1;
++ int CRT1frameY1;
++ Bool CheckForCRT2;
++ int MergedFBXDPI, MergedFBYDPI;
++#ifdef XGIXINERAMA
++ Bool UsexgiXinerama;
++ Bool CRT2IsScrn0;
++ ExtensionEntry *XineramaExtEntry;
++ int xgiXineramaVX, xgiXineramaVY;
++ Bool AtLeastOneNonClone;
++#endif
++#endif
++
++ /* Added for 3D */
++ unsigned long cmdQueue_shareWP_only2D;
++ unsigned long *pCQ_shareWritePort;
++ void (*SetThreshold)(ScrnInfoPtr pScrn, DisplayModePtr mode,
++ unsigned short *Low, unsigned short *High);
++
++ XGI_DSReg SRList[ExtRegSize] ;
++ XGI_DSReg CRList[ExtRegSize] ;
++
++ /**
++ * Total number of iterations to wait in \c Volari_Idle.
++ */
++ unsigned int idle_wait_count;
++
++//:::: for capture
++ Bool v4l_videoin;
++ int v4l_devnum; /* v4l device number, 0,1,2....*/
++//~::::
++} XGIRec, *XGIPtr;
++
++#ifdef XGIDUALHEAD
++# define IS_DUAL_HEAD(x) ((x)->DualHeadMode)
++# define IS_SECOND_HEAD(x) ((x)->SecondHead)
++# define ENTITY_PRIVATE(x) ((x)->entityPrivate)
++#else
++# define IS_DUAL_HEAD(x) FALSE
++# define IS_SECOND_HEAD(x) FALSE
++# define ENTITY_PRIVATE(x) NULL
++#endif
++
++
++#define SEQ_ADDRESS_PORT 0x0014
++#define MISC_OUTPUT_REG_WRITE_PORT 0x0012
++#define MISC_OUTPUT_REG_READ_PORT 0x001C
++#define GRAPH_ADDRESS_PORT 0x001E
++#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
++#define CRTC_ADDRESS_PORT_COLOR 0x0024
++#define PCI_COMMAND 0x04
++
++#define SDMPTR(x) ((XGIMergedDisplayModePtr)(x->currentMode->Private))
++#define CDMPTR ((XGIMergedDisplayModePtr)(pXGI->CurrentLayout.mode->Private))
++
++#define BOUND(test,low,hi) { \
++ if(test < low) test = low; \
++ if(test > hi) test = hi; }
++
++#define REBOUND(low,hi,test) { \
++ if(test < low) { \
++ hi += test-low; \
++ low = test; } \
++ if(test > hi) { \
++ low += test-hi; \
++ hi = test; } }
++
++typedef struct _MergedDisplayModeRec {
++ DisplayModePtr CRT1;
++ DisplayModePtr CRT2;
++ XGIScrn2Rel CRT2Position;
++} XGIMergedDisplayModeRec, *XGIMergedDisplayModePtr;
++
++
++typedef struct _region {
++ int x0,x1,y0,y1;
++} region;
++
++
++extern void xgiOptions(ScrnInfoPtr pScrn);
++extern const OptionInfoRec * XGIAvailableOptions(int chipid, int busid);
++extern void XGISetup(ScrnInfoPtr pScrn);
++extern void XGIVGAPreInit(ScrnInfoPtr pScrn);
++extern Bool XGIAccelInit(ScreenPtr pScreen);
++extern Bool XGIHWCursorInit(ScreenPtr pScreen);
++extern Bool XGIDGAInit(ScreenPtr pScreen);
++extern void XGIInitVideo(ScreenPtr pScreen);
++
++extern int XGI_GetCHTVlumabandwidthcvbs(ScrnInfoPtr pScrn);
++
++int XG40Mclk(XGIPtr pXGI);
++
++void XGINew_InitVBIOSData(PXGI_HW_DEVICE_INFO HwDeviceExtension, PVB_DEVICE_INFO pVBInfo) ;
++int compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
++ int *out_sbit, int *out_scale);
++
++void XGI_WaitBeginRetrace(XGIIOADDRESS RelIO);
++void XGI_WaitEndRetrace(XGIIOADDRESS RelIO);
++
++/* 2005/11/21 added by jjtseng */
++#define DelayS(sec) usleep((sec)*1000000)
++#define DelayMS(millisec) usleep((millisec)*1000)
++#define DelayUS(microsec) usleep((microsec))
++/*~jjtseng 2005/11/21 */
++
++Bool Volari_AccelInit(ScreenPtr pScreen) ;
++/* void XGI_UnLockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
++/* void XGI_LockCRT2(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
++/* void XGI_DisableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
++/* void XGI_EnableBridge(PXGI_HW_DEVICE_INFO,USHORT BaseAddr); */
++#endif
++
++extern USHORT XGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
++ int Depth, int LCDwith, int LCDheight);
++
++extern BOOLEAN XGI_SearchModeID(const XGI_StStruct *SModeIDTable,
++ const XGI_ExtStruct *EModeIDTable, unsigned char VGAINFO,
++ USHORT *ModeNo, USHORT *ModeIdIndex);
++
++extern UCHAR XGI_GetModePtr(const XGI_StStruct *SModeIDTable,
++ unsigned ModeType, USHORT ModeNo, USHORT ModeIdIndex);
++
++extern void XGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data);
++extern void XGI_SetRegByte(XGIIOADDRESS port, USHORT data);
++extern void XGI_SetRegShort(XGIIOADDRESS port, USHORT data);
++extern void XGI_SetRegLong(XGIIOADDRESS port, ULONG data);
++extern UCHAR XGI_GetReg(XGIIOADDRESS port, USHORT index);
++extern UCHAR XGI_GetRegByte(XGIIOADDRESS port);
++extern USHORT XGI_GetRegShort(XGIIOADDRESS port);
++extern ULONG XGI_GetRegLong(XGIIOADDRESS port);
++extern void XGI_SetRegANDOR(XGIIOADDRESS Port, USHORT Index, USHORT DataAND,
++ USHORT DataOR);
++extern void XGI_SetRegAND(XGIIOADDRESS Port, USHORT Index, USHORT DataAND);
++extern void XGI_SetRegOR(XGIIOADDRESS Port, USHORT Index, USHORT DataOR);
++
++extern void XGI_WriteDAC(XGIIOADDRESS dac_data, unsigned shift,
++ unsigned ordering, uint8_t red, uint8_t green, uint8_t blue);
++
++#ifdef DEBUG
++void XGIDumpRegs(ScrnInfoPtr pScrn);
++
++/**
++ * Write value to the PC's 0x80 debug port.
++ *
++ * \bug
++ * I'm pretty sure the debug 0x80 only exists on PCs. Should this routine
++ * be a no-op on non-x86 and non-x86-64 architectures?
++ */
++#define Newdebugcode(dbg_code) outb(0x80, dbg_code)
++#else
++#define Newdebugcode(dbg_code)
++#endif
+diff --git a/src/xgi_accel.c b/src/xgi_accel.c
+index 330ed5d..2490348 100644
+--- a/src/xgi_accel.c
++++ b/src/xgi_accel.c
+@@ -1,850 +1,879 @@
+-/*
+- *
+- * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
+- * Parts Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
+- *
+- * Licensed under the following terms:
+- *
+- * Permission to use, copy, modify, distribute, and sell this software and its
+- * documentation for any purpose is hereby granted without fee, provided that
+- * the above copyright notice appears in all copies and that both that copyright
+- * notice and this permission notice appear in supporting documentation, and
+- * and that the name of the copyright holder not be used in advertising
+- * or publicity pertaining to distribution of the software without specific,
+- * written prior permission. The copyright holder makes no representations
+- * about the suitability of this software for any purpose. It is provided
+- * "as is" without expressed or implied warranty.
+- *
+- * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+- * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+- * PERFORMANCE OF THIS SOFTWARE.
+- *
+- * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>,
+- * Mike Chapman <mike@paranoia.com>,
+- * Juanjo Santamarta <santamarta@ctv.es>,
+- * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
+- * David Thomas <davtom@dream.org.uk>,
+- * Thomas Winischhofer <thomas@winischhofer.net>.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "xf86.h"
+-#include "xf86_OSproc.h"
+-
+-#include "xf86PciInfo.h"
+-#include "xf86Pci.h"
+-
+-#include <compiler.h>
+-#include <miline.h>
+-
+-#include "xgi_accel.h"
+-#include "xgi_regs.h"
+-#include "xgi.h"
+-#include "vb_def.h"
+-
+-#include "xaarop.h"
+-#include <xaa.h>
+-#include <xaalocal.h>
+-#include <xf86fbman.h>
+-
+-/*************************************************************************/
+-
+-void Volari_Sync(ScrnInfoPtr pScrn);
+-
+-static void Volari_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+- int xdir, int ydir, int rop,
+- unsigned int planemask, int trans_color);
+-static void Volari_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+- int x1, int y1, int x2, int y2,
+- int width, int height);
+-static void Volari_SetupForSolidFill(ScrnInfoPtr pScrn, int color,
+- int rop, unsigned int planemask);
+-static void Volari_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
+- int x, int y, int w, int h);
+-static void Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
+- int patx, int paty, int fg, int bg,
+- int rop, unsigned int planemask);
+-static void Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+- int patx, int paty,
+- int x, int y, int w, int h);
+-
+-void Volari_EnableAccelerator(ScrnInfoPtr pScrn) ;
+-static void Volari_InitCmdQueue(ScrnInfoPtr pScrn) ;
+-static void Volari_DisableDualPipe(ScrnInfoPtr pScrn) ;
+-static void Volari_DisableCmdQueue(ScrnInfoPtr pScrn) ;
+-
+-extern int FbDevExist;
+-
+-#if X_BYTE_ORDER == X_BIG_ENDIAN
+-static CARD32 BE_SWAP32 (CARD32 val)
+-{
+- if (CurrentColorDepth == 8)
+- return ((((val) & 0x000000ff) << 24) | \
+- (((val) & 0x0000ff00) << 8) | \
+- (((val) & 0x00ff0000) >> 8) | \
+- (((val) & 0xff000000) >> 24));
+- if (CurrentColorDepth == 24)
+- return val;
+- if (CurrentColorDepth == 16)
+- return ((((val) & 0x0000ffff) << 16) | \
+- (((val) & 0xffff0000) >> 16));
+-}
+-#else
+-static CARD32 BE_SWAP32 (CARD32 val)
+-{
+- return val;
+-}
+-#endif
+-
+-
+-#ifdef DEBUG
+-static void dump_cq_read_pointer(unsigned int cqrp)
+-{
+- static const char *const field_name[8] = {
+- "all idle",
+- "hardware queues empty",
+- "2D idle",
+- "3D idle",
+- "hardware command queue empty",
+- "2D queue empty",
+- "3D queue empty",
+- "software command queue empty",
+- };
+- unsigned i;
+-
+- xf86DrvMsg(0, X_INFO, "IO(0x85CC) = 0x%08x\n", cqrp);
+- for (i = 31; i > 23; i--) {
+- if ((cqrp & (1U << i)) != 0) {
+- xf86DrvMsg(0, X_INFO, " %s\n", field_name[31 - i]);
+- }
+- }
+-}
+-#endif /* DEBUG */
+-
+-
+-void Volari_SetDefaultIdleWait(XGIPtr pXGI, unsigned HDisplay,
+- unsigned depth)
+-{
+- static const unsigned wait_table[5][4] = {
+- { 1, 1, 1, 1 },
+- { 65535, 1, 1000, 3000 },
+- { 65535, 160, 1200, 4000 },
+- { 65535, 200, 1600, 6000 },
+- { 65535, 500, 2000, 8000 }
+- };
+-
+- if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
+- unsigned i;
+-
+- switch (HDisplay) {
+- case 640: i = 1; break;
+- case 800: i = 2; break;
+- case 1024: i = 3; break;
+- case 1280: i = 4; break;
+- default: i = 0; break;
+- }
+-
+- pXGI->idle_wait_count = wait_table[i][3 & (depth / 8)];
+- }
+- else {
+- pXGI->idle_wait_count = 65535;
+- }
+-}
+-
+-void Volari_Idle(XGIPtr pXGI)
+-{
+- int i;
+-#ifdef DEBUG
+- unsigned int last_cqrp = 0;
+-#endif /* DEBUG */
+-
+- do {
+- int bIdle = 0;
+- unsigned int cqrp;
+-
+- for (i = 0; i < pXGI->idle_wait_count; i++) {
+- cqrp = MMIO_IN32(pXGI->IOBase, 0x85CC);
+- if (cqrp & IDLE_ALL) {
+- bIdle = 1;
+- break;
+- }
+- }
+-
+- if (bIdle)
+- break;
+-
+-#ifdef DEBUG
+- if (last_cqrp != cqrp) {
+- dump_cq_read_pointer(cqrp);
+- last_cqrp = cqrp;
+- }
+-
+- sleep(1);
+-#endif /* DEBUG */
+-
+- if (pXGI->Chipset == PCI_CHIP_XGIXG20)
+- usleep(1);
+- } while (1);
+-}
+-
+-
+-void
+-Volari_EnableAccelerator(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- PDEBUG(ErrorF("Volari_EnableAccelerator()\n")) ;
+-
+- switch (pXGI->Chipset) {
+- case PCI_CHIP_XGIXG40:
+- default:
+- orXGIIDXREG(XGISR, 0x1E,
+- SR1E_ENABLE_3D_TRANSFORM_ENGINE
+- | SR1E_ENABLE_2D
+- | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
+- | SR1E_ENABLE_3D_COMMAND_PARSER
+- | SR1E_ENABLE_3D);
+- }
+-
+-
+- if( pXGI->TurboQueue )
+- {
+- Volari_InitCmdQueue(pScrn) ;
+- }
+-}
+-
+-static void
+-Volari_InitCmdQueue(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned long ulXGITempRP ;
+- unsigned long ulCR55 ;
+- unsigned long ulSR26 ;
+- unsigned long temp ;
+- /* unsigned long ulFlag = 0 ; */
+-/*
+- PDEBUG(ErrorF("Volari_InitCmdQueue()\n"));
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
+-*/
+- inXGIIDXREG(XGICR, 0x55, ulCR55) ;
+- andXGIIDXREG(XGICR, 0x55, 0x33) ;
+- orXGIIDXREG(XGISR, 0x26, 1) ; /* reset cmd queue */
+-
+- w_port = Volari_GetSwWP() ; /* GuardBand() Init */
+- r_port = Volari_GetHwRP() ;
+-
+- if( pXGI->Chipset == PCI_CHIP_XGIXG20 )
+- {
+- Alignment = 1 ; /* 64 bits */
+-
+- switch(pXGI->cmdQueueSize)
+- {
+- case 64*1024:
+- ulSR26 = 0x40 + 0x00 ;
+- break ;
+- case 128*1024:
+- ulSR26 = 0x40 + 0x04 ;
+- break ;
+- default:
+- /* reset the command queue information */
+-
+- pXGI->cmdQueueSize = 128*1024 ; /* reset the command queue */
+- pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+- if( FbDevExist )
+- {
+- if( pScrn->videoRam < 8*1024 )
+- {
+- pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
+- }
+- else if( pScrn->videoRam < 16*1024 )
+- {
+- pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
+- }
+- else
+- {
+- pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
+- }
+- }
+- else
+- {
+- pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
+- }
+-
+- pXGI->cmdQueueLen = 0 ;
+- pXGI->cmdQueueLenMin = 0x200 ;
+- pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+-
+- ulSR26 = 0x40 ;
+- break ;
+- }
+- }
+- else
+- {
+- Alignment = 2 ; /* 128 bits */
+-
+- switch(pXGI->cmdQueueSize)
+- {
+- case 512*1024:
+- ulSR26 = 0x40 + 0x00 ;
+- break ;
+- case 1024*1024:
+- ulSR26 = 0x40 + 0x04 ;
+- break ;
+- case 2*1024*1024:
+- ulSR26 = 0x40 + 0x08 ;
+- break ;
+- case 4*1024*1024:
+- ulSR26 = 0x40 + 0x0C ;
+- break ;
+- default:
+- /* reset the command queue information */
+-
+- pXGI->cmdQueueSize = 512*1024 ; /* reset the command queue */
+- pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+- if( FbDevExist )
+- {
+- if( pScrn->videoRam < 8*1024 )
+- {
+- pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
+- }
+- else if( pScrn->videoRam < 16*1024 )
+- {
+- pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
+- }
+- else
+- {
+- pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
+- }
+- }
+- else
+- {
+- pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
+- }
+-
+- pXGI->cmdQueueLen = 0 ;
+- pXGI->cmdQueueLenMin = 0x200 ;
+- pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+-
+- ulSR26 = 0x40 ;
+- break ;
+- }
+- }
+-
+- pXGI->CursorOffset = pXGI->cmdQueueOffset - VOLARI_CURSOR_SHAPE_SIZE;
+-
+- temp = (unsigned long)pXGI->FbBase ;
+- temp += pXGI->cmdQueueOffset ;
+- pXGI->cmdQueueBase = (unsigned char *)temp ;
+-/*
+- PDEBUG(ErrorF( "pXGI->FbBase = 0x%lX\n", pXGI->FbBase )) ;
+- PDEBUG(ErrorF( "pXGI->cmdQueueOffset = 0x%lX\n", pXGI->cmdQueueOffset )) ;
+- PDEBUG(ErrorF( "pXGI->cmdQueueBase = 0x%lX\n", pXGI->cmdQueueBase )) ;
+-*/
+- outXGIIDXREG(XGISR, 0x26, ulSR26) ;
+-
+- ulXGITempRP=Volari_GetHwRP() ;
+-/*
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
+- PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
+-*/
+- /* XGI315 */
+- pXGI->cmdQueue_shareWP_only2D = ulXGITempRP;
+- /* pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D); */
+-
+- Volari_UpdateHwWP(ulXGITempRP) ;
+-
+-
+-
+- MMIO_OUT32(pXGI->IOBase, 0x85C0, pXGI->cmdQueueOffset) ;
+-
+- outXGIIDXREG(XGICR, 0x55, ulCR55) ;
+-
+- if(pXGI->Chipset == PCI_CHIP_XGIXG40)
+- {
+- Volari_Idle(pXGI);
+- Volari_DisableDualPipe(pScrn) ;
+- Volari_Idle(pXGI);
+-
+- }
+- PDEBUG(ErrorF("Volari_InitCmdQueue() done.\n")) ;
+-}
+-
+-static void
+-Volari_DisableDualPipe(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn) ;
+- unsigned long ulTemp ;
+- unsigned long ulValue = MMIO_IN32(pXGI->IOBase, 0x8240) ;
+- ulValue |= 1 << 10 ; /* D[10] = 1, Disable Dual Pipe. */
+-
+- ulTemp = Volari_GetSwWP() ;
+-
+- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp) = (CARD32)BE_SWAP32(GR_SKPC_HEADER + 0x8240) ;
+- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+4) = (CARD32)BE_SWAP32(ulValue) ;
+-
+- if( pXGI->Chipset == PCI_CHIP_XGIXG40 )
+- {
+- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+8) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
+- *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+12) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
+-
+- ulTemp += 0x10 ;
+- }
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 )
+- ulTemp += 0x08 ;
+-
+- ulTemp &= pXGI->cmdQueueSizeMask ;
+- Volari_UpdateHwWP(ulTemp) ;
+-}
+-
+-void
+-Volari_DisableAccelerator(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn) ;
+-
+- PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn)\n")) ;
+-
+- Volari_Idle(pXGI);
+-
+- if( pXGI->TurboQueue )
+- {
+- Volari_DisableCmdQueue(pScrn) ;
+- }
+-
+- andXGIIDXREG(XGISR, 0x1E,
+- ~(SR1E_ENABLE_3D_TRANSFORM_ENGINE
+- | SR1E_ENABLE_2D
+- | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
+- | SR1E_ENABLE_3D_COMMAND_PARSER
+- | SR1E_ENABLE_3D));
+-/* PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn) Done, GBCount = %ld\n",GBCount)) ; */
+-}
+-
+-static void
+-Volari_DisableCmdQueue(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn) ;
+-
+- andXGIIDXREG(XGISR, 0x26, 0x0F) ;
+-}
+-
+-void
+-Volari_InitializeAccelerator(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- pXGI->DoColorExpand = FALSE;
+-}
+-
+-Bool
+-Volari_AccelInit(ScreenPtr pScreen)
+-{
+- XAAInfoRecPtr infoPtr;
+- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+- XGIPtr pXGI = XGIPTR(pScrn);
+- int reservedFbSize;
+- long UsableFbSize;
+- unsigned char *AvailBufBase;
+- BoxRec Avail;
+- int i;
+-
+-
+- Avail.x1 = 0; Avail.y1 = 0; Avail.x2 = 0; Avail.y2 = 0;
+-
+- PDEBUG1(ErrorF("Volari_AccelInit()\n" )) ;
+-
+- pXGI->AccelInfoPtr = infoPtr = XAACreateInfoRec();
+- if (!infoPtr) return FALSE;
+-
+- Volari_InitializeAccelerator(pScrn);
+-
+- infoPtr->Flags = LINEAR_FRAMEBUFFER |
+- OFFSCREEN_PIXMAPS |
+- PIXMAP_CACHE;
+-
+- /* sync */
+- infoPtr->Sync = Volari_Sync;
+-
+- if ((pScrn->bitsPerPixel != 8) &&
+- (pScrn->bitsPerPixel != 16) &&
+- (pScrn->bitsPerPixel != 32))
+- {
+- return FALSE;
+- }
+-
+-#ifdef XGIG2_SCR2SCRCOPY
+- /* BitBlt */
+- infoPtr->SetupForScreenToScreenCopy = Volari_SetupForScreenToScreenCopy;
+- infoPtr->SubsequentScreenToScreenCopy = Volari_SubsequentScreenToScreenCopy;
+- infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
+-#endif
+-
+-#ifdef XGIG2_SOLIDFILL
+- /* solid fills */
+- infoPtr->SetupForSolidFill = Volari_SetupForSolidFill;
+- infoPtr->SubsequentSolidFillRect = Volari_SubsequentSolidFillRect;
+- infoPtr->SolidFillFlags = NO_PLANEMASK;
+-#endif
+-
+-#ifdef XGIG2_8X8MONOPATFILL
+- /* 8x8 mono pattern fill */
+- infoPtr->SetupForMono8x8PatternFill = Volari_SetupForMonoPatternFill;
+- infoPtr->SubsequentMono8x8PatternFillRect = Volari_SubsequentMonoPatternFill;
+- infoPtr->Mono8x8PatternFillFlags =
+- NO_PLANEMASK |
+- HARDWARE_PATTERN_SCREEN_ORIGIN |
+- HARDWARE_PATTERN_PROGRAMMED_BITS |
+- /* 2005/08/15 modified by jjtseng */
+- /* NO_TRANSPARENCY | */
+- /*~ jjtseng 2005/08/15 */
+- BIT_ORDER_IN_BYTE_MSBFIRST ;
+-#endif /* XGIG2_8X8MONOPATFILL */
+-
+- /* init Frame Buffer Manager */
+- reservedFbSize = 0;
+- if (pXGI->TurboQueue)
+- {
+- reservedFbSize += pXGI->cmdQueueSize ;
+- }
+-
+- if (pXGI->HWCursor)
+- {
+- reservedFbSize += VOLARI_CURSOR_SHAPE_SIZE;
+- }
+-
+-#ifdef XGIG2_COLOREXPSCANLN
+- reservedFbSize += (pXGI->ColorExpandBufferNumber * pXGI->PerColorExpandBufferSize);
+-#endif
+-
+- UsableFbSize = pXGI->FbMapSize - reservedFbSize;
+- AvailBufBase = pXGI->FbBase + UsableFbSize;
+-
+- for (i = 0; i < pXGI->ColorExpandBufferNumber; i++) {
+- const int base = i * pXGI->PerColorExpandBufferSize;
+-
+- pXGI->ColorExpandBufferAddr[i] = AvailBufBase + base;
+- pXGI->ColorExpandBufferScreenOffset[i] = UsableFbSize + base;
+- }
+-
+-#ifdef XGIG2_IMAGEWRITE
+- reservedFbSize += pXGI->ImageWriteBufferSize;
+- UsableFbSize = pXGI->FbMapSize - reservedFbSize;
+- pXGI->ImageWriteBufferAddr = AvailBufBase = pXGI->FbBase + UsableFbSize;
+- infoPtr->ImageWriteRange = pXGI->ImageWriteBufferAddr;
+-#endif /* XGIG2_IMAGEWRITE */
+-
+- Avail.x1 = 0;
+- Avail.y1 = 0;
+-
+-/*
+- Avail.x2 = pScrn->displayWidth;
+-
+- ErrorF("FbDevExist=%s\n",FbDevExist?"TRUE":"FALSE");
+-
+- if (FbDevExist)
+- {
+- if( UsableFbSize >= 8*1024*1024 )
+- {
+- UsableFbSize = 8*1024*1024 ;
+- }
+- else
+- {
+- UsableFbSize = 4*1024*1024 ;
+- }
+- }
+-
+- PDEBUG1(ErrorF( "UsabelFbSize = %08lx\n", UsableFbSize )) ;
+- Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
+-
+- if ((unsigned long)Avail.y2 > 8192)
+- {
+- Avail.y2 = 8192 ;
+- }
+-*/
+-
+- UsableFbSize = pXGI->CursorOffset ;
+- Avail.x1 = 0 ;
+- Avail.y1 = 0 ;
+- Avail.x2 = pScrn->displayWidth;
+- Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
+-
+-
+- if ((unsigned long)Avail.y2 > 8192)
+- {
+- Avail.y2 = 8192 ;
+- }
+-
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Usable FBSize = %08lx\n", UsableFbSize ) ;
+-
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Frame Buffer From (%d,%d) To (%d,%d)\n",
+- Avail.x1, Avail.y1, Avail.x2, Avail.y2);
+-
+- xf86InitFBManager(pScreen, &Avail);
+-
+- return(XAAInit(pScreen, infoPtr));
+-
+-}
+-
+-void
+-Volari_Sync(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- PDEBUG1(ErrorF("Volari_Sync()\n"));
+- pXGI->DoColorExpand = FALSE;
+- Volari_Idle(pXGI);
+-}
+-
+-static int xgiG2_ALUConv[] =
+-{
+- 0x00, /* dest = 0; 0, GXclear, 0 */
+- 0x88, /* dest &= src; DSa, GXand, 0x1 */
+- 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+- 0xCC, /* dest = src; S, GXcopy, 0x3 */
+- 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+- 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+- 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+- 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+- 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+- 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+- 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+- 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+- 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+- 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+- 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+- 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+-};
+-/* same ROP but with Pattern as Source */
+-static int xgiG2_PatALUConv[] =
+-{
+- 0x00, /* dest = 0; 0, GXclear, 0 */
+- 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+- 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+- 0xF0, /* dest = src; P, GXcopy, 0x3 */
+- 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+- 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+- 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+- 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+- 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+- 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+- 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+- 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+- 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+- 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+- 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+- 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+-};
+-
+-static void
+-Volari_SetupForScreenToScreenCopy(
+- ScrnInfoPtr pScrn,
+- int xdir, int ydir, int rop,
+- unsigned int planemask, int trans_color)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-#ifdef SHOW_XAAINFO
+- XAAInfoRecPtr pXAA = XAAPTR(pScrn);
+-/*
+- ErrorF("XAAInfoPtr->UsingPixmapCache = %s\n"
+- "XAAInfoPtr->CanDoMono8x8 = %s\n"
+- "XAAInfoPtr->CanDoColor8x8 = %s\n"
+- "XAAInfoPtr->CachePixelGranularity = %d\n"
+- "XAAInfoPtr->MaxCacheableTileWidth = %d\n"
+- "XAAInfoPtr->MaxCacheableTileHeight = %d\n"
+- "XAAInfoPtr->MaxCacheableStippleWidth = %d\n"
+- "XAAInfoPtr->MaxCacheableStippleHeight = %d\n"
+- "XAAInfoPtr->MonoPatternPitch = %d\n"
+- "XAAInfoPtr->CacheWidthMono8x8Pattern = %d\n"
+- "XAAInfoPtr->CacheHeightMono8x8Pattern = %d\n"
+- "XAAInfoPtr->ColorPatternPitch = %d\n"
+- "XAAInfoPtr->CacheWidthColor8x8Pattern = %d\n"
+- "XAAInfoPtr->CacheHeightColor8x8Pattern = %d\n"
+- "XAAInfoPtr->CacheColorExpandDensity = %d\n"
+- "XAAInfoPtr->maxOffPixWidth = %d\n"
+- "XAAInfoPtr->maxOffPixHeight= %d\n"
+- "XAAInfoPtr->NeedToSync = %s\n"
+- "\n",
+- pXAA->UsingPixmapCache ? "True" : "False",
+- pXAA->CanDoMono8x8 ? "True" : "False",
+- pXAA->CanDoColor8x8 ? "True" : "False",
+- pXAA->CachePixelGranularity,
+- pXAA->MaxCacheableTileWidth,
+- pXAA->MaxCacheableTileHeight,
+- pXAA->MaxCacheableStippleWidth,
+- pXAA->MaxCacheableStippleHeight,
+- pXAA->MonoPatternPitch,
+- pXAA->CacheWidthMono8x8Pattern,
+- pXAA->CacheHeightMono8x8Pattern,
+- pXAA->ColorPatternPitch,
+- pXAA->CacheWidthColor8x8Pattern,
+- pXAA->CacheHeightColor8x8Pattern,
+- pXAA->CacheColorExpandDensity,
+- pXAA->maxOffPixWidth,
+- pXAA->maxOffPixHeight,
+- pXAA->NeedToSync ? "True" : "False");
+-*/
+-#endif
+-
+- PDEBUG1(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
+- xdir, ydir, rop, planemask, trans_color));
+-
+- Volari_ResetCmd ;
+- GuardBand(0x20 * Alignment);
+- Volari_SetupDSTColorDepth(pXGI->DstColor);
+- Volari_SetupSRCPitch(pXGI->scrnOffset) ;
+- Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
+- Volari_SetupROP(xgiG2_ALUConv[rop]) ;
+-}
+-
+-static void
+-Volari_SubsequentScreenToScreenCopy(
+- ScrnInfoPtr pScrn,
+- int src_x, int src_y,
+- int dst_x, int dst_y,
+- int width, int height)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- long srcbase, dstbase;
+-/*
+- PDEBUG1(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
+- src_x, src_y,
+- dst_x, dst_y,
+- width, height));
+-*/
+- srcbase=dstbase=0;
+- if (src_y >= 2048)
+- {
+- srcbase=pXGI->scrnOffset*src_y;
+- src_y=0;
+- }
+- if (dst_y >= pScrn->virtualY)
+- {
+- dstbase=pXGI->scrnOffset*dst_y;
+- dst_y=0;
+- }
+- /*
+- PDEBUG1(ErrorF("SrcBase = %08lX DstBase = %08lX\n",srcbase,dstbase)) ;
+- PDEBUG1(ErrorF("SrcX = %08lX SrcY = %08lX\n",src_x,src_y)) ;
+- PDEBUG1(ErrorF("DstX = %08lX DstY = %08lX\n",dst_x,dst_y)) ;
+-*/
+- GuardBand(0x30 * Alignment);
+- Volari_SetupSRCBase(srcbase);
+- Volari_SetupDSTBase(dstbase);
+- Volari_SetupSRCXY(src_x,src_y) ;
+- Volari_SetupDSTXY(dst_x,dst_y) ;
+- Volari_SetupRect(width, height) ;
+- Volari_DoCMD ;
+-}
+-
+-static void
+-Volari_SetupForSolidFill(ScrnInfoPtr pScrn,
+- int color, int rop, unsigned int planemask)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- PDEBUG1(ErrorF("Volari_SetupForSolidFill()\n")) ;
+- PDEBUG1(ErrorF("Color = #%08lX ",color)) ;
+- PDEBUG1(ErrorF("DstPitch = #%04lX ",(pXGI->scrnOffset))) ;
+- PDEBUG1(ErrorF("\n")) ;
+-
+- Volari_ResetCmd ;
+- GuardBand(0x28 * Alignment);
+- Volari_SetupPATFG(color) ;
+- Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
+- Volari_SetupDSTColorDepth(XGIPTR(pScrn)->DstColor) ;
+- Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
+- Volari_SetupCMDFlag(PATFG | BITBLT) ;
+-}
+-
+-static void
+-Volari_SubsequentSolidFillRect(
+- ScrnInfoPtr pScrn,
+- int x, int y,
+- int width, int height)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned long dstbase = 0 ;
+-
+- PDEBUG1(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
+- x, y, width, height));
+-
+- dstbase=0;
+- if (y>=2048)
+- {
+- dstbase=pXGI->scrnOffset*y;
+- y=0;
+- }
+-
+- GuardBand(0x20 * Alignment);
+- Volari_SetupDSTBase(dstbase) ;
+- Volari_SetupDSTXY(x,y) ;
+- Volari_SetupRect(width,height) ;
+- Volari_DoCMD ;
+-
+-}
+-
+-static void
+-Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
+- int pat0, int pat1,
+- int fg, int bg,
+- int rop, unsigned int planemask)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- PDEBUG1(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
+- pat0, pat1, fg, bg, rop, planemask));
+-
+- Volari_ResetCmd ;
+- GuardBand(0x40 * Alignment);
+- Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
+- Volari_SetupMONOPAT0(pat0) ;
+- Volari_SetupMONOPAT1(pat1) ;
+- Volari_SetupPATFG(fg) ;
+- Volari_SetupPATBG(bg) ;
+- Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
+- Volari_SetupDSTColorDepth(pXGI->DstColor) ;
+- Volari_SetupCMDFlag(PATMONO | BITBLT) ;
+-}
+-
+-static void
+-Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
+- int patx, int paty,
+- int x, int y, int w, int h)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- long dstbase;
+-
+- PDEBUG1(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
+- patx, paty, x, y, w, h));
+- dstbase=0;
+- if (y>=2048)
+- {
+- dstbase=pXGI->scrnOffset*y;
+- y=0;
+- }
+-
+- GuardBand(0x20 * Alignment);
+- Volari_SetupDSTBase(dstbase) ;
+- Volari_SetupDSTXY(x,y) ;
+- Volari_SetupRect(w,h) ;
+- Volari_DoCMD ;
+- /*Volari_Idle(pXGI)*/;
+-}
+-
+-/************************************************************************/
+-
++/*
++ *
++ * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
++ * Parts Copyright (C) 2001-2004 Thomas Winischhofer, Vienna, Austria.
++ *
++ * Licensed under the following terms:
++ *
++ * Permission to use, copy, modify, distribute, and sell this software and its
++ * documentation for any purpose is hereby granted without fee, provided that
++ * the above copyright notice appears in all copies and that both that copyright
++ * notice and this permission notice appear in supporting documentation, and
++ * and that the name of the copyright holder not be used in advertising
++ * or publicity pertaining to distribution of the software without specific,
++ * written prior permission. The copyright holder makes no representations
++ * about the suitability of this software for any purpose. It is provided
++ * "as is" without expressed or implied warranty.
++ *
++ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
++ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
++ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
++ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
++ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
++ * PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>,
++ * Mike Chapman <mike@paranoia.com>,
++ * Juanjo Santamarta <santamarta@ctv.es>,
++ * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
++ * David Thomas <davtom@dream.org.uk>,
++ * Thomas Winischhofer <thomas@winischhofer.net>.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "xf86.h"
++#include "xf86_OSproc.h"
++
++#include "xf86PciInfo.h"
++#include "xf86Pci.h"
++
++#include <compiler.h>
++#include <miline.h>
++
++#include "xgi_accel.h"
++#include "xgi_regs.h"
++#include "xgi.h"
++#include "vb_def.h"
++
++#include "xaarop.h"
++#include <xaa.h>
++#include <xaalocal.h>
++#include <xf86fbman.h>
++
++/*************************************************************************/
++
++void Volari_Sync(ScrnInfoPtr pScrn);
++
++static void Volari_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
++ int xdir, int ydir, int rop,
++ unsigned int planemask, int trans_color);
++static void Volari_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
++ int x1, int y1, int x2, int y2,
++ int width, int height);
++static void Volari_SetupForSolidFill(ScrnInfoPtr pScrn, int color,
++ int rop, unsigned int planemask);
++static void Volari_SubsequentSolidFillRect(ScrnInfoPtr pScrn,
++ int x, int y, int w, int h);
++static void Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
++ int patx, int paty, int fg, int bg,
++ int rop, unsigned int planemask);
++static void Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
++ int patx, int paty,
++ int x, int y, int w, int h);
++
++void Volari_EnableAccelerator(ScrnInfoPtr pScrn) ;
++static void Volari_InitCmdQueue(ScrnInfoPtr pScrn) ;
++static void Volari_DisableDualPipe(ScrnInfoPtr pScrn) ;
++static void Volari_DisableCmdQueue(ScrnInfoPtr pScrn) ;
++
++/* Jong 01/07/2008; force to disable 2D */
++extern Bool ForceToDisable2DEngine(ScrnInfoPtr pScrn);
++
++extern int FbDevExist;
++
++#if X_BYTE_ORDER == X_BIG_ENDIAN
++static CARD32 BE_SWAP32 (CARD32 val)
++{
++ if (CurrentColorDepth == 8)
++ return ((((val) & 0x000000ff) << 24) | \
++ (((val) & 0x0000ff00) << 8) | \
++ (((val) & 0x00ff0000) >> 8) | \
++ (((val) & 0xff000000) >> 24));
++ if (CurrentColorDepth == 24)
++ return val;
++ if (CurrentColorDepth == 16)
++ return ((((val) & 0x0000ffff) << 16) | \
++ (((val) & 0xffff0000) >> 16));
++}
++#else
++static CARD32 BE_SWAP32 (CARD32 val)
++{
++ return val;
++}
++#endif
++
++
++#ifdef DEBUG
++static void dump_cq_read_pointer(unsigned int cqrp)
++{
++ static const char *const field_name[8] = {
++ "all idle",
++ "hardware queues empty",
++ "2D idle",
++ "3D idle",
++ "hardware command queue empty",
++ "2D queue empty",
++ "3D queue empty",
++ "software command queue empty",
++ };
++ unsigned i;
++
++ xf86DrvMsg(0, X_INFO, "IO(0x85CC) = 0x%08x\n", cqrp);
++ for (i = 31; i > 23; i--) {
++ if ((cqrp & (1U << i)) != 0) {
++ xf86DrvMsg(0, X_INFO, " %s\n", field_name[31 - i]);
++ }
++ }
++}
++#endif /* DEBUG */
++
++
++void Volari_SetDefaultIdleWait(XGIPtr pXGI, unsigned HDisplay,
++ unsigned depth)
++{
++ static const unsigned wait_table[5][4] = {
++ { 1, 1, 1, 1 },
++ { 65535, 1, 1000, 3000 },
++ { 65535, 160, 1200, 4000 },
++ { 65535, 200, 1600, 6000 },
++ { 65535, 500, 2000, 8000 }
++ };
++
++ if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
++ unsigned i;
++
++ switch (HDisplay) {
++ case 640: i = 1; break;
++ case 800: i = 2; break;
++ case 1024: i = 3; break;
++ case 1280: i = 4; break;
++ default: i = 0; break;
++ }
++
++ pXGI->idle_wait_count = wait_table[i][3 & (depth / 8)];
++ }
++ else {
++ pXGI->idle_wait_count = 65535;
++ }
++}
++
++void Volari_Idle(XGIPtr pXGI)
++{
++ int i;
++#ifdef DEBUG
++ unsigned int last_cqrp = 0;
++#endif /* DEBUG */
++
++ do {
++ int bIdle = 0;
++ unsigned int cqrp;
++
++ for (i = 0; i < pXGI->idle_wait_count; i++) {
++ cqrp = MMIO_IN32(pXGI->IOBase, 0x85CC);
++ if (cqrp & IDLE_ALL) {
++ bIdle = 1;
++ break;
++ }
++ }
++
++ if (bIdle)
++ break;
++
++#ifdef DEBUG
++ if (last_cqrp != cqrp) {
++ dump_cq_read_pointer(cqrp);
++ last_cqrp = cqrp;
++ }
++
++ sleep(1);
++#endif /* DEBUG */
++
++ if (pXGI->Chipset == PCI_CHIP_XGIXG20)
++ usleep(1);
++ } while (1);
++}
++
++
++void
++Volari_EnableAccelerator(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ PDEBUG(ErrorF("Volari_EnableAccelerator()\n")) ;
++
++ switch (pXGI->Chipset) {
++ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21: /* Jong 01/07/2008; support new XG21 */
++ case PCI_CHIP_XGIXG27:
++ case PCI_CHIP_XGIXG40:
++ default:
++ orXGIIDXREG(XGISR, 0x1E,
++ SR1E_ENABLE_3D_TRANSFORM_ENGINE
++ | SR1E_ENABLE_2D
++ | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
++ | SR1E_ENABLE_3D_COMMAND_PARSER
++ | SR1E_ENABLE_3D);
++
++ /* Jong 01/07/2008; force to disable 2D */
++ if(pXGI->Chipset == PCI_CHIP_XGIXG21)
++ {
++ if(ForceToDisable2DEngine(pScrn))
++ {
++ andXGIIDXREG(XGISR, 0x1E, 0xBF) ;
++ }
++ }
++
++ break;
++ }
++
++
++ if( pXGI->TurboQueue )
++ {
++ Volari_InitCmdQueue(pScrn) ;
++ }
++}
++
++static void
++Volari_InitCmdQueue(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned long ulXGITempRP ;
++ unsigned long ulCR55 ;
++ unsigned long ulSR26 ;
++ unsigned long temp ;
++ /* unsigned long ulFlag = 0 ; */
++/*
++ PDEBUG(ErrorF("Volari_InitCmdQueue()\n"));
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
++*/
++ inXGIIDXREG(XGICR, 0x55, ulCR55) ;
++ andXGIIDXREG(XGICR, 0x55, 0x33) ;
++ orXGIIDXREG(XGISR, 0x26, 1) ; /* reset cmd queue */
++
++ w_port = Volari_GetSwWP() ; /* GuardBand() Init */
++ r_port = Volari_GetHwRP() ;
++
++ if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 ))
++ {
++ Alignment = 1 ; /* 64 bits */
++
++ switch(pXGI->cmdQueueSize)
++ {
++ case 64*1024:
++ ulSR26 = 0x40 + 0x00 ;
++ break ;
++ case 128*1024:
++ ulSR26 = 0x40 + 0x04 ;
++ break ;
++ default:
++ /* reset the command queue information */
++
++ pXGI->cmdQueueSize = 128*1024 ; /* reset the command queue */
++ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
++
++ /* Jong 09/18/2007; bug fixing for ??? */
++ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) )
++ {
++ if( pScrn->videoRam < 8*1024 )
++ {
++ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ else if( pScrn->videoRam < 16*1024 )
++ {
++ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ else
++ {
++ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ }
++ else
++ {
++ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
++ }
++
++ pXGI->cmdQueueLen = 0 ;
++ pXGI->cmdQueueLenMin = 0x200 ;
++ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
++
++ ulSR26 = 0x40 ;
++ break ;
++ }
++ }
++ else
++ {
++ Alignment = 2 ; /* 128 bits */
++
++ switch(pXGI->cmdQueueSize)
++ {
++ case 512*1024:
++ ulSR26 = 0x40 + 0x00 ;
++ break ;
++ case 1024*1024:
++ ulSR26 = 0x40 + 0x04 ;
++ break ;
++ case 2*1024*1024:
++ ulSR26 = 0x40 + 0x08 ;
++ break ;
++ case 4*1024*1024:
++ ulSR26 = 0x40 + 0x0C ;
++ break ;
++ default:
++ /* reset the command queue information */
++
++ pXGI->cmdQueueSize = 512*1024 ; /* reset the command queue */
++ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
++
++ /* Jong 09/18/2007; bug fixing for ??? */
++ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ))
++ {
++ if( pScrn->videoRam < 8*1024 )
++ {
++ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ else if( pScrn->videoRam < 16*1024 )
++ {
++ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ else
++ {
++ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ }
++ else
++ {
++ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
++ }
++
++ pXGI->cmdQueueLen = 0 ;
++ pXGI->cmdQueueLenMin = 0x200 ;
++ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
++
++ ulSR26 = 0x40 ;
++ break ;
++ }
++ }
++
++ pXGI->CursorOffset = pXGI->cmdQueueOffset - VOLARI_CURSOR_SHAPE_SIZE;
++
++ temp = (unsigned long)pXGI->FbBase ;
++ temp += pXGI->cmdQueueOffset ;
++ pXGI->cmdQueueBase = (unsigned char *)temp ;
++/*
++ PDEBUG(ErrorF( "pXGI->FbBase = 0x%lX\n", pXGI->FbBase )) ;
++ PDEBUG(ErrorF( "pXGI->cmdQueueOffset = 0x%lX\n", pXGI->cmdQueueOffset )) ;
++ PDEBUG(ErrorF( "pXGI->cmdQueueBase = 0x%lX\n", pXGI->cmdQueueBase )) ;
++*/
++ outXGIIDXREG(XGISR, 0x26, ulSR26) ;
++
++ ulXGITempRP=Volari_GetHwRP() ;
++/*
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c0, XGIMMIOLONG(0x85c0))) ;
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c4, XGIMMIOLONG(0x85c4))) ;
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85c8, XGIMMIOLONG(0x85c8))) ;
++ PDEBUG(ErrorF( "pXGI->IOBase = 0x%08lX, [%04X] = 0x%08lX\n",(unsigned long)(pXGI->IOBase),0x85cc, XGIMMIOLONG(0x85cc))) ;
++*/
++ /* XGI315 */
++ pXGI->cmdQueue_shareWP_only2D = ulXGITempRP;
++ /* pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D); */
++
++ Volari_UpdateHwWP(ulXGITempRP) ;
++
++
++
++ MMIO_OUT32(pXGI->IOBase, 0x85C0, pXGI->cmdQueueOffset) ;
++
++ outXGIIDXREG(XGICR, 0x55, ulCR55) ;
++
++ if(pXGI->Chipset == PCI_CHIP_XGIXG40)
++ {
++ Volari_Idle(pXGI);
++ Volari_DisableDualPipe(pScrn) ;
++ Volari_Idle(pXGI);
++
++ }
++ PDEBUG(ErrorF("Volari_InitCmdQueue() done.\n")) ;
++}
++
++static void
++Volari_DisableDualPipe(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn) ;
++ unsigned long ulTemp ;
++ unsigned long ulValue = MMIO_IN32(pXGI->IOBase, 0x8240) ;
++ ulValue |= 1 << 10 ; /* D[10] = 1, Disable Dual Pipe. */
++
++ ulTemp = Volari_GetSwWP() ;
++
++ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp) = (CARD32)BE_SWAP32(GR_SKPC_HEADER + 0x8240) ;
++ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+4) = (CARD32)BE_SWAP32(ulValue) ;
++
++ if( pXGI->Chipset == PCI_CHIP_XGIXG40 )
++ {
++ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+8) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
++ *(CARD32 *)(pXGI->cmdQueueBase+ulTemp+12) = (CARD32)BE_SWAP32(GR_NIL_CMD) ;
++
++ ulTemp += 0x10 ;
++ }
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 ) || ( pXGI->Chipset == PCI_CHIP_XGIXG21 ) || ( pXGI->Chipset == PCI_CHIP_XGIXG27 ))
++ ulTemp += 0x08 ;
++
++ ulTemp &= pXGI->cmdQueueSizeMask ;
++ Volari_UpdateHwWP(ulTemp) ;
++}
++
++void
++Volari_DisableAccelerator(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn) ;
++
++ PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn)\n")) ;
++
++ Volari_Idle(pXGI);
++
++ if( pXGI->TurboQueue )
++ {
++ Volari_DisableCmdQueue(pScrn) ;
++ }
++
++ andXGIIDXREG(XGISR, 0x1E,
++ ~(SR1E_ENABLE_3D_TRANSFORM_ENGINE
++ | SR1E_ENABLE_2D
++ | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
++ | SR1E_ENABLE_3D_COMMAND_PARSER
++ | SR1E_ENABLE_3D));
++/* PDEBUG(ErrorF("Volari_DisableAccelerator(pScrn) Done, GBCount = %ld\n",GBCount)) ; */
++}
++
++static void
++Volari_DisableCmdQueue(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn) ;
++
++ andXGIIDXREG(XGISR, 0x26, 0x0F) ;
++}
++
++void
++Volari_InitializeAccelerator(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ pXGI->DoColorExpand = FALSE;
++}
++
++Bool
++Volari_AccelInit(ScreenPtr pScreen)
++{
++ XAAInfoRecPtr infoPtr;
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ XGIPtr pXGI = XGIPTR(pScrn);
++ int reservedFbSize;
++ long UsableFbSize;
++ unsigned char *AvailBufBase;
++ BoxRec Avail;
++ int i;
++
++
++ Avail.x1 = 0; Avail.y1 = 0; Avail.x2 = 0; Avail.y2 = 0;
++
++ PDEBUG1(ErrorF("Volari_AccelInit()\n" )) ;
++
++ pXGI->AccelInfoPtr = infoPtr = XAACreateInfoRec();
++ if (!infoPtr) return FALSE;
++
++ Volari_InitializeAccelerator(pScrn);
++
++ infoPtr->Flags = LINEAR_FRAMEBUFFER |
++ OFFSCREEN_PIXMAPS |
++ PIXMAP_CACHE;
++
++ /* sync */
++ infoPtr->Sync = Volari_Sync;
++
++ if ((pScrn->bitsPerPixel != 8) &&
++ (pScrn->bitsPerPixel != 16) &&
++ (pScrn->bitsPerPixel != 32))
++ {
++ return FALSE;
++ }
++
++ /* Jong 01/07/2008; force to disable 2D based on SR3A[6] for XG21 */
++ if( !((pXGI->Chipset == PCI_CHIP_XGIXG21) && ForceToDisable2DEngine(pScrn)) )
++ {
++#ifdef XGIG2_SCR2SCRCOPY
++ /* BitBlt */
++ /* Jong 08/24/2007; cause an extra rectangle drawing at top-left corner while clicking "Computer" on Suse SP1 (Xorg6.9.0) */
++ if(pScrn->bitsPerPixel != 8)
++ {
++ infoPtr->SetupForScreenToScreenCopy = Volari_SetupForScreenToScreenCopy;
++ infoPtr->SubsequentScreenToScreenCopy = Volari_SubsequentScreenToScreenCopy;
++ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY;
++ }
++#endif
++
++#ifdef XGIG2_SOLIDFILL
++ /* solid fills */
++ infoPtr->SetupForSolidFill = Volari_SetupForSolidFill;
++ infoPtr->SubsequentSolidFillRect = Volari_SubsequentSolidFillRect;
++ infoPtr->SolidFillFlags = NO_PLANEMASK;
++#endif
++
++#ifdef XGIG2_8X8MONOPATFILL
++ /* 8x8 mono pattern fill */
++ infoPtr->SetupForMono8x8PatternFill = Volari_SetupForMonoPatternFill;
++ infoPtr->SubsequentMono8x8PatternFillRect = Volari_SubsequentMonoPatternFill;
++ infoPtr->Mono8x8PatternFillFlags =
++ NO_PLANEMASK |
++ HARDWARE_PATTERN_SCREEN_ORIGIN |
++ HARDWARE_PATTERN_PROGRAMMED_BITS |
++ /* 2005/08/15 modified by jjtseng */
++ /* NO_TRANSPARENCY | */
++ /*~ jjtseng 2005/08/15 */
++ BIT_ORDER_IN_BYTE_MSBFIRST ;
++#endif /* XGIG2_8X8MONOPATFILL */
++ }
++
++ /* init Frame Buffer Manager */
++ reservedFbSize = 0;
++ if (pXGI->TurboQueue)
++ {
++ reservedFbSize += pXGI->cmdQueueSize ;
++ }
++
++ if (pXGI->HWCursor)
++ {
++ reservedFbSize += VOLARI_CURSOR_SHAPE_SIZE;
++ }
++
++#ifdef XGIG2_COLOREXPSCANLN
++ reservedFbSize += (pXGI->ColorExpandBufferNumber * pXGI->PerColorExpandBufferSize);
++#endif
++
++ UsableFbSize = pXGI->FbMapSize - reservedFbSize;
++ AvailBufBase = pXGI->FbBase + UsableFbSize;
++
++ for (i = 0; i < pXGI->ColorExpandBufferNumber; i++) {
++ const int base = i * pXGI->PerColorExpandBufferSize;
++
++ pXGI->ColorExpandBufferAddr[i] = AvailBufBase + base;
++ pXGI->ColorExpandBufferScreenOffset[i] = UsableFbSize + base;
++ }
++
++#ifdef XGIG2_IMAGEWRITE
++ reservedFbSize += pXGI->ImageWriteBufferSize;
++ UsableFbSize = pXGI->FbMapSize - reservedFbSize;
++ pXGI->ImageWriteBufferAddr = AvailBufBase = pXGI->FbBase + UsableFbSize;
++ infoPtr->ImageWriteRange = pXGI->ImageWriteBufferAddr;
++#endif /* XGIG2_IMAGEWRITE */
++
++ Avail.x1 = 0;
++ Avail.y1 = 0;
++
++/*
++ Avail.x2 = pScrn->displayWidth;
++
++ ErrorF("FbDevExist=%s\n",FbDevExist?"TRUE":"FALSE");
++
++ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) )
++ {
++ if( UsableFbSize >= 8*1024*1024 )
++ {
++ UsableFbSize = 8*1024*1024 ;
++ }
++ else
++ {
++ UsableFbSize = 4*1024*1024 ;
++ }
++ }
++
++ PDEBUG1(ErrorF( "UsabelFbSize = %08lx\n", UsableFbSize )) ;
++ Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
++
++ if ((unsigned long)Avail.y2 > 8192)
++ {
++ Avail.y2 = 8192 ;
++ }
++*/
++
++ UsableFbSize = pXGI->CursorOffset ;
++ Avail.x1 = 0 ;
++ Avail.y1 = 0 ;
++ Avail.x2 = pScrn->displayWidth;
++ Avail.y2 = UsableFbSize / pXGI->scrnOffset ;
++
++
++ if ((unsigned long)Avail.y2 > 8192)
++ {
++ Avail.y2 = 8192 ;
++ }
++
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Usable FBSize = %08lx\n", UsableFbSize ) ;
++
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Frame Buffer From (%d,%d) To (%d,%d)\n",
++ Avail.x1, Avail.y1, Avail.x2, Avail.y2);
++
++ xf86InitFBManager(pScreen, &Avail);
++
++ return(XAAInit(pScreen, infoPtr));
++
++}
++
++void
++Volari_Sync(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ PDEBUG1(ErrorF("Volari_Sync()\n"));
++ pXGI->DoColorExpand = FALSE;
++ Volari_Idle(pXGI);
++}
++
++static int xgiG2_ALUConv[] =
++{
++ 0x00, /* dest = 0; 0, GXclear, 0 */
++ 0x88, /* dest &= src; DSa, GXand, 0x1 */
++ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
++ 0xCC, /* dest = src; S, GXcopy, 0x3 */
++ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
++ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
++ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
++ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
++ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
++ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
++ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
++ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
++ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
++ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
++ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
++ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
++};
++/* same ROP but with Pattern as Source */
++static int xgiG2_PatALUConv[] =
++{
++ 0x00, /* dest = 0; 0, GXclear, 0 */
++ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
++ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
++ 0xF0, /* dest = src; P, GXcopy, 0x3 */
++ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
++ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
++ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
++ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
++ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
++ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
++ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
++ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
++ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
++ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
++ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
++ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
++};
++
++static void
++Volari_SetupForScreenToScreenCopy(
++ ScrnInfoPtr pScrn,
++ int xdir, int ydir, int rop,
++ unsigned int planemask, int trans_color)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++#ifdef SHOW_XAAINFO
++ XAAInfoRecPtr pXAA = XAAPTR(pScrn);
++/*
++ ErrorF("XAAInfoPtr->UsingPixmapCache = %s\n"
++ "XAAInfoPtr->CanDoMono8x8 = %s\n"
++ "XAAInfoPtr->CanDoColor8x8 = %s\n"
++ "XAAInfoPtr->CachePixelGranularity = %d\n"
++ "XAAInfoPtr->MaxCacheableTileWidth = %d\n"
++ "XAAInfoPtr->MaxCacheableTileHeight = %d\n"
++ "XAAInfoPtr->MaxCacheableStippleWidth = %d\n"
++ "XAAInfoPtr->MaxCacheableStippleHeight = %d\n"
++ "XAAInfoPtr->MonoPatternPitch = %d\n"
++ "XAAInfoPtr->CacheWidthMono8x8Pattern = %d\n"
++ "XAAInfoPtr->CacheHeightMono8x8Pattern = %d\n"
++ "XAAInfoPtr->ColorPatternPitch = %d\n"
++ "XAAInfoPtr->CacheWidthColor8x8Pattern = %d\n"
++ "XAAInfoPtr->CacheHeightColor8x8Pattern = %d\n"
++ "XAAInfoPtr->CacheColorExpandDensity = %d\n"
++ "XAAInfoPtr->maxOffPixWidth = %d\n"
++ "XAAInfoPtr->maxOffPixHeight= %d\n"
++ "XAAInfoPtr->NeedToSync = %s\n"
++ "\n",
++ pXAA->UsingPixmapCache ? "True" : "False",
++ pXAA->CanDoMono8x8 ? "True" : "False",
++ pXAA->CanDoColor8x8 ? "True" : "False",
++ pXAA->CachePixelGranularity,
++ pXAA->MaxCacheableTileWidth,
++ pXAA->MaxCacheableTileHeight,
++ pXAA->MaxCacheableStippleWidth,
++ pXAA->MaxCacheableStippleHeight,
++ pXAA->MonoPatternPitch,
++ pXAA->CacheWidthMono8x8Pattern,
++ pXAA->CacheHeightMono8x8Pattern,
++ pXAA->ColorPatternPitch,
++ pXAA->CacheWidthColor8x8Pattern,
++ pXAA->CacheHeightColor8x8Pattern,
++ pXAA->CacheColorExpandDensity,
++ pXAA->maxOffPixWidth,
++ pXAA->maxOffPixHeight,
++ pXAA->NeedToSync ? "True" : "False");
++*/
++#endif
++
++ PDEBUG1(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
++ xdir, ydir, rop, planemask, trans_color));
++
++ Volari_ResetCmd ;
++ GuardBand(0x20 * Alignment);
++ Volari_SetupDSTColorDepth(pXGI->DstColor);
++ Volari_SetupSRCPitch(pXGI->scrnOffset) ;
++ Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
++ Volari_SetupROP(xgiG2_ALUConv[rop]) ;
++}
++
++static void
++Volari_SubsequentScreenToScreenCopy(
++ ScrnInfoPtr pScrn,
++ int src_x, int src_y,
++ int dst_x, int dst_y,
++ int width, int height)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ long srcbase, dstbase;
++/*
++ PDEBUG1(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
++ src_x, src_y,
++ dst_x, dst_y,
++ width, height));
++*/
++ srcbase=dstbase=0;
++ if (src_y >= 2048)
++ {
++ srcbase=pXGI->scrnOffset*src_y;
++ src_y=0;
++ }
++ if (dst_y >= pScrn->virtualY)
++ {
++ dstbase=pXGI->scrnOffset*dst_y;
++ dst_y=0;
++ }
++ /*
++ PDEBUG1(ErrorF("SrcBase = %08lX DstBase = %08lX\n",srcbase,dstbase)) ;
++ PDEBUG1(ErrorF("SrcX = %08lX SrcY = %08lX\n",src_x,src_y)) ;
++ PDEBUG1(ErrorF("DstX = %08lX DstY = %08lX\n",dst_x,dst_y)) ;
++*/
++ GuardBand(0x30 * Alignment);
++ Volari_SetupSRCBase(srcbase);
++ Volari_SetupDSTBase(dstbase);
++ Volari_SetupSRCXY(src_x,src_y) ;
++ Volari_SetupDSTXY(dst_x,dst_y) ;
++ Volari_SetupRect(width, height) ;
++ Volari_DoCMD ;
++}
++
++static void
++Volari_SetupForSolidFill(ScrnInfoPtr pScrn,
++ int color, int rop, unsigned int planemask)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ PDEBUG1(ErrorF("Volari_SetupForSolidFill()\n")) ;
++ PDEBUG1(ErrorF("Color = #%08lX ",color)) ;
++ PDEBUG1(ErrorF("DstPitch = #%04lX ",(pXGI->scrnOffset))) ;
++ PDEBUG1(ErrorF("\n")) ;
++
++ Volari_ResetCmd ;
++ GuardBand(0x28 * Alignment);
++ Volari_SetupPATFG(color) ;
++ Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
++ Volari_SetupDSTColorDepth(XGIPTR(pScrn)->DstColor) ;
++ Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
++ Volari_SetupCMDFlag(PATFG | BITBLT) ;
++}
++
++static void
++Volari_SubsequentSolidFillRect(
++ ScrnInfoPtr pScrn,
++ int x, int y,
++ int width, int height)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned long dstbase = 0 ;
++
++ PDEBUG1(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
++ x, y, width, height));
++
++ dstbase=0;
++ if (y>=2048)
++ {
++ dstbase=pXGI->scrnOffset*y;
++ y=0;
++ }
++
++ GuardBand(0x20 * Alignment);
++ Volari_SetupDSTBase(dstbase) ;
++ Volari_SetupDSTXY(x,y) ;
++ Volari_SetupRect(width,height) ;
++ Volari_DoCMD ;
++
++}
++
++static void
++Volari_SetupForMonoPatternFill(ScrnInfoPtr pScrn,
++ int pat0, int pat1,
++ int fg, int bg,
++ int rop, unsigned int planemask)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ PDEBUG1(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
++ pat0, pat1, fg, bg, rop, planemask));
++
++ Volari_ResetCmd ;
++ GuardBand(0x40 * Alignment);
++ Volari_SetupDSTRect(pXGI->scrnOffset, Dst_Hight) ;
++ Volari_SetupMONOPAT0(pat0) ;
++ Volari_SetupMONOPAT1(pat1) ;
++ Volari_SetupPATFG(fg) ;
++ Volari_SetupPATBG(bg) ;
++ Volari_SetupROP(xgiG2_PatALUConv[rop]) ;
++ Volari_SetupDSTColorDepth(pXGI->DstColor) ;
++ Volari_SetupCMDFlag(PATMONO | BITBLT) ;
++}
++
++static void
++Volari_SubsequentMonoPatternFill(ScrnInfoPtr pScrn,
++ int patx, int paty,
++ int x, int y, int w, int h)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ long dstbase;
++
++ PDEBUG1(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
++ patx, paty, x, y, w, h));
++ dstbase=0;
++ if (y>=2048)
++ {
++ dstbase=pXGI->scrnOffset*y;
++ y=0;
++ }
++
++ GuardBand(0x20 * Alignment);
++ Volari_SetupDSTBase(dstbase) ;
++ Volari_SetupDSTXY(x,y) ;
++ Volari_SetupRect(w,h) ;
++ Volari_DoCMD ;
++ /*Volari_Idle(pXGI)*/;
++}
++
++/************************************************************************/
++
+diff --git a/src/xgi_accel.h b/src/xgi_accel.h
+index 8f5d005..a0fa9f5 100644
+--- a/src/xgi_accel.h
++++ b/src/xgi_accel.h
+@@ -116,6 +116,8 @@
+
+ #define BandSize 0x10
+
++/* Jong 09/27/2007; recover for compiler error */
++typedef unsigned long ulong ;
+ /* typedef unsigned long ulong ; */
+
+ unsigned long r_port, w_port ;
+@@ -248,7 +250,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateHwWP(ulTemp) ;\
+@@ -280,7 +282,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -314,7 +316,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -346,7 +348,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -379,7 +381,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -412,7 +414,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -445,7 +447,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -488,7 +490,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -538,7 +540,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -564,7 +566,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -589,7 +591,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -614,7 +616,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -647,7 +649,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -672,7 +674,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -709,7 +711,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -734,7 +736,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -759,7 +761,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -830,7 +832,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -855,7 +857,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -880,7 +882,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -905,7 +907,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -930,7 +932,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+@@ -955,7 +957,7 @@ extern void Volari_Idle(XGIPtr pXGI);
+ (CARD32)BE_SWAP32(GR_NIL_CMD) ;\
+ ulTemp += 0x10 ;\
+ } \
+- else if( pXGI->Chipset == PCI_CHIP_XGIXG20 ) \
++ else if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) \
+ ulTemp += 0x08 ;\
+ ulTemp &= pXGI->cmdQueueSizeMask ;\
+ Volari_UpdateSwWP(ulTemp) ;\
+diff --git a/src/xgi_common.h b/src/xgi_common.h
+diff --git a/src/xgi_cursor.c b/src/xgi_cursor.c
+index a66eed1..2d5d8c6 100644
+--- a/src/xgi_cursor.c
++++ b/src/xgi_cursor.c
+@@ -67,10 +67,24 @@ Volari_ShowCursor(ScrnInfoPtr pScrn)
+ /* unsigned long cursor_addr = pXGI->CursorOffset ; */
+ unsigned long cursor_base = pXGI->CursorOffset/1024 ;
+
+- xgiG2CRT1_EnableHWCursor(cursor_base, 0);
+- if (pXGI->VBFlags & CRT2_ENABLE) {
+- xgiG2CRT2_EnableHWCursor(cursor_base, 0);
++ /* Jong 09/19/2007; bug fixing for ??? */
++ if( pXGI->HWARGBCursor )
++ {
++ xgiG2CRT1_EnableARGBHWCursor(cursor_base, 0);
++ if (pXGI->VBFlags & CRT2_ENABLE)
++ {
++ xgiG2CRT2_EnableARGBHWCursor(cursor_base, 0);
++ }
+ }
++ else
++ {
++ xgiG2CRT1_EnableHWCursor(cursor_base, 0);
++ if (pXGI->VBFlags & CRT2_ENABLE)
++ {
++ xgiG2CRT2_EnableHWCursor(cursor_base, 0);
++ }
++ }
++
+ XGIG1_SetCursorPosition(pScrn, currX, currY) ;
+ XGI_WaitEndRetrace(pXGI->RelIO);
+ }
+@@ -163,6 +177,66 @@ Volari_UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+ return TRUE;
+ }
+
++/* Jong 09/19/2007; Is this required? */
++Bool
++Volari_UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
++{
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++ DisplayModePtr mode = pScrn->currentMode;
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ if (mode->Flags & V_INTERLACE)
++ {
++ return FALSE;
++ }
++
++ /* DumpDDIName("Volari_UserHWCursorARGB()\n") ; */
++
++ return TRUE ;
++}
++
++/* Jong 09/19/2007; Is this required? */
++static void
++Volari_LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCursor)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned long cursor_addr = pXGI->CursorOffset ;
++ unsigned long cursor_base = pXGI->CursorOffset/1024 ;
++ unsigned char *pCursorShape ;
++ int i , j ; CARD32 *pDest,*pSrc ;
++ CursorBitsPtr pCursorBits = pCursor->bits ;
++
++
++ /* DumpDDIName("Volari_LoadCursorARGB()\n") ; */
++ pXGI->HWARGBCursor = TRUE ;
++ pCursorShape = pXGI->FbBase + cursor_addr ;
++
++ pSrc = pCursorBits->argb ;
++
++ pXGI->CurXPreset = 64-pCursorBits->width ;
++ pXGI->CurYPreset = 64-pCursorBits->height ;
++
++ for( i = 64 - pCursorBits->height ; i< 64 ; i++ )
++ {
++ pDest = (CARD32 *)(pCursorShape + i*64*4 ) ;
++ for( j = 64-pCursorBits->width ; j < 64 ; j++, pSrc++ )
++ {
++ pDest[j] = *pSrc ;
++ }
++ }
++
++ xgiG2CRT1_SetCursorAddressPattern(cursor_base,0) ;
++
++ if (pXGI->VBFlags & CRT2_ENABLE) {
++ xgiG2CRT2_SetCursorAddressPattern(cursor_base,0) ;
++ /* xgiG1CRT2_SetCursorAddress(cursor_base) ; */
++ /* xgiG1CRT2_SetCursorPatternSelect(0) ; */
++ }
++ XGIG1_SetCursorPosition(pScrn, currX, currY) ;
++ PDEBUG4(vWaitCRT1VerticalRetrace(pScrn)) ;
++ PDEBUG4(XGIDumpMMIO(pScrn));
++}
++
+ Bool
+ XGIHWCursorInit(ScreenPtr pScreen)
+ {
+@@ -179,6 +253,8 @@ XGIHWCursorInit(ScreenPtr pScreen)
+
+ case PCI_CHIP_XGIXG40:
+ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21:
++ case PCI_CHIP_XGIXG27:
+ default:
+ PDEBUG(ErrorF("--- HWCursorInit() \n"));
+ infoPtr->MaxWidth = 64;
+@@ -192,6 +268,13 @@ XGIHWCursorInit(ScreenPtr pScreen)
+ infoPtr->LoadCursorImage = Volari_LoadCursorImage;
+ infoPtr->UseHWCursor = Volari_UseHWCursor;
+ /* infoPtr->RealizeCursor = XGIRealizeCursorColor ; // */
++
++ /* Jong 09/19/2007; Is this required */
++ #ifdef XGI_ARGB_CURSOR
++ infoPtr->UseHWCursorARGB = Volari_UseHWCursorARGB ;
++ infoPtr->LoadCursorARGB = Volari_LoadCursorARGB ;
++ #endif
++
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+diff --git a/src/xgi_cursor.h b/src/xgi_cursor.h
+index a29e3cb..64bb87f 100644
+--- a/src/xgi_cursor.h
++++ b/src/xgi_cursor.h
+@@ -190,4 +190,27 @@
+ XGIMMIOLONG(0x8520) =BE_SWAP32(ulTemp) ;\
+ }
+
++/* Jong 09/19/2007; added for ??? */
++#define xgiG2CRT1_EnableARGBHWCursor(cursor_base,pat_id)\
++ {\
++ CARD32 ulTemp ;\
++ ulTemp = XGIMMIOLONG(0x8500) ;\
++ ulTemp &= 0x00FC0000 ;\
++ ulTemp |= 0xE<<28 ;\
++ ulTemp |= (cursor_base) & 0x3FFFF ;\
++ ulTemp |= ((pat_id)&0xF)<<24 ;\
++ XGIMMIOLONG(0x8500) = ulTemp ;\
++ }
++
++#define xgiG2CRT2_EnableARGBHWCursor(cursor_base,pat_id)\
++ {\
++ CARD32 ulTemp ;\
++ ulTemp = XGIMMIOLONG(0x8500) ;\
++ ulTemp &= 0x00FC0000 ;\
++ ulTemp |= 0xE<<28 ;\
++ ulTemp |= (cursor_base) & 0x3FFFF ;\
++ ulTemp |= ((pat_id)&0xF)<<24 ;\
++ XGIMMIOLONG(0x8500) = ulTemp ;\
++ }
++
+ /*******************************************************************/
+diff --git a/src/xgi_dac.c b/src/xgi_dac.c
+index b8155e0..9a95001 100644
+--- a/src/xgi_dac.c
++++ b/src/xgi_dac.c
+@@ -359,7 +359,7 @@ Volari_Restore(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
+ int vgaIOBase;
+ int i;
+
+-PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
++ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "Volari_Restore(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)\n");
+
+@@ -386,8 +386,12 @@ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
+ | SR1E_ENABLE_3D));
+ PDEBUG(XGIDumpRegs(pScrn));
+ #endif
+- PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
++
++ PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
++
+ for (i = 0x19; i < 0x5C; i++) {
++ /* Jong 09/19/2007; added for ??? */
++ if((i!=0x48 && i!=0x4a)|| ((pXGI->Chipset != PCI_CHIP_XGIXG20)&&(pXGI->Chipset != PCI_CHIP_XGIXG21)&&(pXGI->Chipset != PCI_CHIP_XGIXG27)))
+ outXGIIDXREG(XGICR, i, xgiReg->xgiRegs3D4[i]);
+ }
+
+@@ -407,7 +411,7 @@ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
+ }
+
+
+-// yilin restore the VB register
++ // yilin restore the VB register
+ outXGIIDXREG(XGIPART1, 0x2f, 0x01);
+ for (i=0; i<0x50; i++)
+ {
+@@ -432,7 +436,7 @@ PDEBUG(ErrorF("--- Volari_Restore(). \n")) ;
+ /* MemClock needs this to take effect */
+
+ outw(VGA_SEQ_INDEX, 0x0100); /* Synchronous Reset */
+- PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
++ PDEBUG(XGIDumpRegs(pScrn)) ; //yilin
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "Volari_Restore(ScrnInfoPtr pScrn, XGIRegPtr xgiReg) Done\n");
+
+@@ -452,7 +456,7 @@ Volari_Threshold(ScrnInfoPtr pScrn, DisplayModePtr mode,
+ /**
+ * Calculate available memory bandwidth for an XG40 series chip.
+ *
+- * \sa XG20_MemBandWidth
++ * \sa XG40_MemBandWidth
+ */
+ static int XG40_MemBandWidth(ScrnInfoPtr pScrn)
+ {
+@@ -480,7 +484,7 @@ static int XG40_MemBandWidth(ScrnInfoPtr pScrn)
+ /**
+ * Calculate available memory bandwidth for an XG20 series chip.
+ *
+- * \sa XG40_MemBandWidth
++ * \sa XG20_MemBandWidth
+ */
+ static int XG20_MemBandWidth(ScrnInfoPtr pScrn)
+ {
+@@ -491,8 +495,35 @@ static int XG20_MemBandWidth(ScrnInfoPtr pScrn)
+ const float magic = 1.44;
+ float total = (mclk * bus) / bpp;
+
++ /* Jong 09/19/2007; support DDRII and double pixel clock */
++ unsigned long SR39, CR97 ;
++
+ PDEBUG5(ErrorF("mclk: %d, bus: %d, magic: %f, bpp: %d\n",
+ mclk, bus, magic, bpp));
++
++ total = mclk*bus/bpp;
++
++ /* Jong 04/26/2007; support DDRII and double pixel clock */
++ /*-------------------------------------------------------*/
++ inXGIIDXREG(XGISR, 0x39, SR39);
++ inXGIIDXREG(XGICR, 0x97, CR97);
++
++ if (CR97 & 0x10)
++ {
++ if (CR97 & 0x01)
++ {
++ total *= 2;
++ }
++ }
++ else
++ {
++ if (SR39 & 0x2)
++ {
++ total *= 2;
++ }
++ }
++ /*-------------------------------------------------------*/
++
+ PDEBUG5(ErrorF("Total Adapter Bandwidth is %fM\n", total/1000));
+
+ return (int)(total / magic);
+@@ -606,7 +637,7 @@ PDEBUG(ErrorF("XGIDACPreInit()\n"));
+ pXGI->XGIRestore = Volari_Restore;
+ pXGI->SetThreshold = Volari_Threshold;
+
+- pXGI->MaxClock = (pXGI->Chipset == PCI_CHIP_XGIXG20)
++ pXGI->MaxClock = ((pXGI->Chipset == PCI_CHIP_XGIXG20) || (pXGI->Chipset == PCI_CHIP_XGIXG21) || (pXGI->Chipset == PCI_CHIP_XGIXG27))
+ ? XG20_MemBandWidth(pScrn) : XG40_MemBandWidth(pScrn);
+ }
+
+diff --git a/src/xgi_dac.h b/src/xgi_dac.h
+diff --git a/src/xgi_dga.c b/src/xgi_dga.c
+diff --git a/src/xgi_dri.c b/src/xgi_dri.c
+index b76ecbd..08b58e1 100644
+--- a/src/xgi_dri.c
++++ b/src/xgi_dri.c
+@@ -38,6 +38,12 @@
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
++
++/* Jong 09/27/2007; added for PACKAGE_VERSION_MAJOR,... */
++#define PACKAGE_VERSION_MAJOR 1
++#define PACKAGE_VERSION_MINOR 1
++#define PACKAGE_VERSION_PATCHLEVEL 0
++
+ #include "xf86.h"
+ #include "xf86_OSproc.h"
+ #include "xf86Priv.h"
+diff --git a/src/xgi_dri.h b/src/xgi_dri.h
+diff --git a/src/xgi_driver.c b/src/xgi_driver.c
+index cb01f9d..a1ef47b 100644
+--- a/src/xgi_driver.c
++++ b/src/xgi_driver.c
+@@ -1,6036 +1,6458 @@
+-/*
+- * XGI driver main code
+- *
+- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1) Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2) Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3) The name of the author may not be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- * Author: Thomas Winischhofer <thomas@winischhofer.net>
+- * - driver entirely rewritten since 2001, only basic structure taken from
+- * old code (except xgi_dri.c, xgi_shadow.c, xgi_accel.c and parts of
+- * xgi_dga.c; these were mostly taken over; xgi_dri.c was changed for
+- * new versions of the DRI layer)
+- *
+- * This notice covers the entire driver code unless otherwise indicated.
+- *
+- * Formerly based on code which is
+- * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
+- * Written by:
+- * Alan Hourihane <alanh@fairlite.demon.co.uk>,
+- * Mike Chapman <mike@paranoia.com>,
+- * Juanjo Santamarta <santamarta@ctv.es>,
+- * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
+- * David Thomas <davtom@dream.org.uk>.
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "fb.h"
+-#include "mibank.h"
+-#include "micmap.h"
+-#include "xf86.h"
+-#include "xf86Priv.h"
+-#include "xf86_OSproc.h"
+-#include "xf86Resources.h"
+-#include "dixstruct.h"
+-#include "xf86Version.h"
+-#include "xf86PciInfo.h"
+-#include "xf86Pci.h"
+-#include "xf86cmap.h"
+-#include "vgaHW.h"
+-#include "xf86RAC.h"
+-#include "shadowfb.h"
+-#include "vbe.h"
+-
+-#include "mipointer.h"
+-#include "mibstore.h"
+-
+-#include "xgi.h"
+-#include "xgi_regs.h"
+-#include "xgi_vb.h"
+-#include "xgi_dac.h"
+-#include "vb_def.h"
+-#include "xgi_driver.h"
+-#include "valid_mode.h"
+-
+-#define _XF86DGA_SERVER_
+-#include <X11/extensions/xf86dgastr.h>
+-
+-#include "globals.h"
+-
+-#define DPMS_SERVER
+-#include <X11/extensions/dpms.h>
+-
+-#if defined(XvExtension)
+-#include "xf86xv.h"
+-#include <X11/extensions/Xv.h>
+-#endif
+-
+-#ifdef XF86DRI
+-#include "dri.h"
+-#endif
+-
+-#ifdef HAVE_UNISTD_H
+-#include <unistd.h>
+-#endif
+-
+-#include <fcntl.h>
+-#include <sys/ioctl.h>
+-
+-#ifdef XSERVER_LIBPCIACCESS
+-static Bool XGIPciProbe(DriverPtr drv, int entity_num,
+- struct pci_device *dev, intptr_t match_data);
+-#else
+-static Bool XGIProbe(DriverPtr drv, int flags);
+-#endif
+-
+-void Volari_EnableAccelerator(ScrnInfoPtr pScrn);
+-/* Globals (yes, these ARE really required to be global) */
+-
+-#ifdef XGIDUALHEAD
+-static int XGIEntityIndex = -1;
+-#endif
+-
+-/*
+- * This is intentionally screen-independent. It indicates the binding
+- * choice made in the first PreInit.
+- */
+-static int pix24bpp = 0;
+-int FbDevExist;
+-
+-#define FBIOGET_FSCREENINFO 0x4602
+-#define FB_ACCEL_XGI_GLAMOUR 41
+-
+-struct fb_fix_screeninfo
+-{
+- char id[16]; /* identification string eg "TT Builtin" */
+- unsigned long smem_start; /* Start of frame buffer mem */
+- /* (physical address) */
+- unsigned long smem_len; /* Length of frame buffer mem */
+- unsigned long type; /* see FB_TYPE_* */
+- unsigned long type_aux; /* Interleave for interleaved Planes */
+- unsigned long visual; /* see FB_VISUAL_* */
+- unsigned short xpanstep; /* zero if no hardware panning */
+- unsigned short ypanstep; /* zero if no hardware panning */
+- unsigned short ywrapstep; /* zero if no hardware ywrap */
+- unsigned long line_length; /* length of a line in bytes */
+- unsigned long mmio_start; /* Start of Memory Mapped I/O */
+- /* (physical address) */
+- unsigned long mmio_len; /* Length of Memory Mapped I/O */
+- unsigned long accel; /* Type of acceleration available */
+- unsigned short reserved[3]; /* Reserved for future compatibility */
+-};
+-
+-#ifdef XSERVER_LIBPCIACCESS
+-#define XGI_DEVICE_MATCH(d, i) \
+- { 0x18ca, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+-
+-static const struct pci_id_match xgi_device_match[] = {
+- XGI_DEVICE_MATCH(PCI_CHIP_XGIXG40, 0),
+- XGI_DEVICE_MATCH(PCI_CHIP_XGIXG20, 1),
+-
+- { 0, 0, 0 },
+-};
+-#endif
+-
+-/*
+- * This contains the functions needed by the server after loading the driver
+- * module. It must be supplied, and gets passed back by the SetupProc
+- * function in the dynamic case. In the static case, a reference to this
+- * is compiled in, and this requires that the name of this DriverRec be
+- * an upper-case version of the driver name.
+- */
+-
+-DriverRec XGI = {
+- XGI_CURRENT_VERSION,
+- XGI_DRIVER_NAME,
+- XGIIdentify,
+-#ifdef XSERVER_LIBPCIACCESS
+- NULL,
+-#else
+- XGIProbe,
+-#endif
+- XGIAvailableOptions,
+- NULL,
+- 0,
+- NULL,
+-
+-#ifdef XSERVER_LIBPCIACCESS
+- xgi_device_match,
+- XGIPciProbe
+-#endif
+-};
+-
+-static SymTabRec XGIChipsets[] = {
+- {PCI_CHIP_XGIXG40, "Volari V8_V5_V3XT"},
+- {PCI_CHIP_XGIXG20, "Volari Z7"},
+- {-1, NULL}
+-};
+-
+-static PciChipsets XGIPciChipsets[] = {
+- {PCI_CHIP_XGIXG40, PCI_CHIP_XGIXG40, RES_SHARED_VGA},
+- {PCI_CHIP_XGIXG20, PCI_CHIP_XGIXG20, RES_SHARED_VGA},
+- {-1, -1, RES_UNDEFINED}
+-};
+-
+-static const char *xaaSymbols[] = {
+- "XAACopyROP",
+- "XAACreateInfoRec",
+- "XAADestroyInfoRec",
+- "XAAFillMono8x8PatternRects",
+- "XAAPatternROP",
+- "XAAHelpPatternROP",
+- "XAAInit",
+- NULL
+-};
+-
+-static const char *vgahwSymbols[] = {
+- "vgaHWFreeHWRec",
+- "vgaHWGetHWRec",
+- "vgaHWGetIOBase",
+- "vgaHWGetIndex",
+- "vgaHWInit",
+- "vgaHWLock",
+- "vgaHWMapMem",
+- "vgaHWUnmapMem",
+- "vgaHWProtect",
+- "vgaHWRestore",
+- "vgaHWSave",
+- "vgaHWSaveScreen",
+- "vgaHWUnlock",
+- NULL
+-};
+-
+-static const char *fbSymbols[] = {
+- "fbPictureInit",
+- "fbScreenInit",
+- NULL
+-};
+-
+-static const char *shadowSymbols[] = {
+- "ShadowFBInit",
+- NULL
+-};
+-
+-static const char *ramdacSymbols[] = {
+- "xf86CreateCursorInfoRec",
+- "xf86DestroyCursorInfoRec",
+- "xf86InitCursor",
+- NULL
+-};
+-
+-
+-static const char *ddcSymbols[] = {
+- "xf86PrintEDID",
+- "xf86SetDDCproperties",
+- "xf86InterpretEDID",
+- NULL
+-};
+-
+-
+-/* static const char *i2cSymbols[] = {
+- "xf86I2CBusInit",
+- "xf86CreateI2CBusRec",
+- NULL
+-}; */
+-
+-static const char *int10Symbols[] = {
+- "xf86FreeInt10",
+- "xf86InitInt10",
+- "xf86ExecX86int10",
+- NULL
+-};
+-
+-static const char *vbeSymbols[] = {
+- "VBEExtendedInit",
+- "vbeDoEDID",
+- "vbeFree",
+- "VBEGetVBEInfo",
+- "VBEFreeVBEInfo",
+- "VBEGetModeInfo",
+- "VBEFreeModeInfo",
+- "VBESaveRestore",
+- "VBESetVBEMode",
+- "VBEGetVBEMode",
+- "VBESetDisplayStart",
+- "VBESetGetLogicalScanlineLength",
+- NULL
+-};
+-
+-#ifdef XF86DRI
+-static const char *drmSymbols[] = {
+- "drmAddMap",
+- "drmAgpAcquire",
+- "drmAgpAlloc",
+- "drmAgpBase",
+- "drmAgpBind",
+- "drmAgpEnable",
+- "drmAgpFree",
+- "drmAgpGetMode",
+- "drmAgpRelease",
+- "drmCtlInstHandler",
+- "drmGetInterruptFromBusID",
+- "drmXGIAgpInit",
+- NULL
+-};
+-
+-static const char *driSymbols[] = {
+- "DRICloseScreen",
+- "DRICreateInfoRec",
+- "DRIDestroyInfoRec",
+- "DRIFinishScreenInit",
+- "DRIGetSAREAPrivate",
+- "DRILock",
+- "DRIQueryVersion",
+- "DRIScreenInit",
+- "DRIUnlock",
+-#ifdef XGINEWDRI2
+- "GlxSetVisualConfigs",
+- "DRICreatePCIBusID",
+-#endif
+- NULL
+-};
+-#endif
+-
+-static MODULESETUPPROTO(xgiSetup);
+-
+-static XF86ModuleVersionInfo xgiVersRec = {
+- XGI_DRIVER_NAME,
+- MODULEVENDORSTRING,
+- MODINFOSTRING1,
+- MODINFOSTRING2,
+-#ifdef XORG_VERSION_CURRENT
+- XORG_VERSION_CURRENT,
+-#else
+- XF86_VERSION_CURRENT,
+-#endif
+- PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+- ABI_CLASS_VIDEODRV, /* This is a video driver */
+-#ifdef ABI_VIDEODRV_VERSION
+- ABI_VIDEODRV_VERSION,
+-#else
+- 6,
+-#endif
+- MOD_CLASS_VIDEODRV,
+- {0, 0, 0, 0}
+-};
+-
+-XF86ModuleData xgiModuleData = { &xgiVersRec, xgiSetup, NULL };
+-
+-/*** static string ***/
+-#ifdef XGIMERGED
+-static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n";
+-static const char *mergednocrt2 =
+- "No CRT2 output selected or no bridge detected. %s.\n";
+-static const char *mergeddisstr = "MergedFB mode disabled";
+-static const char *modesforstr =
+- "Modes for CRT%d: *********************************************\n";
+-static const char *crtsetupstr =
+- "------------------------ CRT%d setup -------------------------\n";
+-#endif
+-
+-typedef struct
+-{
+- int width, height;
+- float VRefresh, HSync, DCLK;
+-} ModeTiming;
+-
+-static const ModeTiming establish_timing[] = {
+- {800, 600, 60, 37.9, 40}, /* t1 D[0] */
+- {800, 600, 56, 35.1, 36}, /* t1 D[1] */
+- {640, 480, 75, 37.5, 31.5}, /* t1 D[2] */
+- {640, 480, 72, 37.9, 31.5}, /* t1 D[3] */
+- {-1, -1, -1, -1}, /* t1 D[4] 640x480@67Hz, ignore */
+- {640, 480, 60, 31.5, 25.175}, /* t1 D[5] */
+- {-1, -1, -1, -1}, /* t1 D[6] */
+- {-1, -1, -1, -1}, /* t1 D[7] */
+- {1280, 1024, 75, 80.0, 135}, /* t2 D[0] */
+- {1024, 768, 75, 60.0, 78.75}, /* t2 D[1] */
+- {1024, 768, 70, 56.5, 75}, /* t2 D[2] */
+- {1024, 768, 60, 48.4, 65}, /* t2 D[3] */
+- {-1, -1, -1, -1}, /* t2 D[4] 1024x768@87I, ignore */
+- {-1, -1, -1, -1}, /* t2 D[5] 832x624@75Hz, ignore */
+- {800, 600, 75, 46.9, 49.5}, /* t2 D[6] */
+- {800, 600, 72, 48.1, 50} /* t2 D[7] */
+-};
+-
+-static const ModeTiming StdTiming[] = {
+- {640, 480, 60, 31.5, 25.175},
+- {640, 480, 72, 37.9, 31.5},
+- {640, 480, 75, 37.5, 31.5},
+- {640, 480, 85, 43.3, 36.0},
+-
+- {800, 600, 56, 35.1, 36},
+- {800, 600, 60, 37.9, 40},
+- {800, 600, 72, 48.1, 50},
+- {800, 600, 75, 46.9, 49.5},
+- {800, 600, 85, 53.7, 56.25},
+-
+- {1024, 768, 43, 35.5, 44.9},
+- {1024, 768, 60, 48.4, 65},
+- {1024, 768, 70, 56.5, 75},
+- {1024, 768, 75, 60, 78.75},
+- {1024, 768, 85, 68.7, 94.5},
+-
+- {1152, 864, 75, 67.5, 108},
+-
+- {1280, 960, 60, 60, 108},
+- {1280, 960, 85, 85.9, 148.5},
+- {1280, 1024, 60, 64.0, 108},
+- {1280, 1024, 75, 80, 135},
+- {1280, 1024, 85, 91.1, 157.5},
+-
+- {1600, 1200, 60, 75, 162.0},
+- {1600, 1200, 65, 81.3, 175.5},
+- {1600, 1200, 70, 87.5, 189},
+- {1600, 1200, 75, 93.8, 202},
+- {1600, 1200, 85, 106.3, 229.5},
+-
+- {1792, 1344, 60, 83.64, 204.75},
+- {1792, 1344, 75, 106.27, 261},
+-
+- {1856, 1392, 60, 86.33, 218.25},
+- {1856, 1392, 75, 112.50, 288},
+-
+- {1920, 1440, 60, 90, 234},
+- {1920, 1440, 75, 112.5, 297},
+- {-1, -1, -1, -1, -1},
+-};
+-
+-
+-static void XGIDumpPalette(ScrnInfoPtr pScrn);
+-#ifdef DEBUG
+-static void XGIDumpSR(ScrnInfoPtr pScrn);
+-static void XGIDumpCR(ScrnInfoPtr pScrn);
+-static void XGIDumpGR(ScrnInfoPtr pScrn);
+-static void XGIDumpPart1(ScrnInfoPtr pScrn);
+-static void XGIDumpPart2(ScrnInfoPtr pScrn);
+-static void XGIDumpPart3(ScrnInfoPtr pScrn);
+-static void XGIDumpPart4(ScrnInfoPtr pScrn);
+-static void XGIDumpMMIO(ScrnInfoPtr pScrn);
+-#endif
+-
+-static int XGICalcVRate(DisplayModePtr mode);
+-static unsigned char XGISearchCRT1Rate(ScrnInfoPtr pScrn,
+- DisplayModePtr mode);
+-static void xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
+- unsigned char *reg2);
+-static void xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1,
+- unsigned char reg2);
+-
+-
+-static pointer
+-xgiSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+-{
+- static Bool setupDone = FALSE;
+-
+- if (!setupDone) {
+- setupDone = TRUE;
+- xf86AddDriver(&XGI, module, HaveDriverFuncs);
+- LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
+- shadowSymbols, ramdacSymbols, ddcSymbols,
+- vbeSymbols, int10Symbols,
+-#ifdef XF86DRI
+- drmSymbols, driSymbols,
+-#endif
+- NULL);
+- return (pointer) TRUE;
+- }
+-
+- if (errmaj)
+- *errmaj = LDR_ONCEONLY;
+- return NULL;
+-}
+-
+-
+-static XGIPtr
+-XGIGetRec(ScrnInfoPtr pScrn)
+-{
+- /*
+- * Allocate an XGIRec, and hook it into pScrn->driverPrivate.
+- * pScrn->driverPrivate is initialised to NULL, so we can check if
+- * the allocation has already been done.
+- */
+- if (pScrn->driverPrivate == NULL) {
+- XGIPtr pXGI = xnfcalloc(sizeof(XGIRec), 1);
+-
+- /* Initialise it to 0 */
+- memset(pXGI, 0, sizeof(XGIRec));
+-
+- pScrn->driverPrivate = pXGI;
+- pXGI->pScrn = pScrn;
+- }
+-
+- return (XGIPtr) pScrn->driverPrivate;
+-}
+-
+-static void
+-XGIFreeRec(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- XGIEntPtr pXGIEnt = NULL;
+-
+- /* Just to make sure... */
+- if (!pXGI)
+- return;
+-
+- pXGIEnt = ENTITY_PRIVATE(pXGI);
+- if (pXGIEnt) {
+- if (!IS_SECOND_HEAD(pXGI)) {
+- /* Free memory only if we are first head; in case of an error
+- * during init of the second head, the server will continue -
+- * and we need the BIOS image and VB_DEVICE_INFO for the first
+- * head.
+- */
+- if (pXGIEnt->BIOS)
+- xfree(pXGIEnt->BIOS);
+- pXGIEnt->BIOS = pXGI->BIOS = NULL;
+- if (pXGIEnt->XGI_Pr)
+- xfree(pXGIEnt->XGI_Pr);
+- pXGIEnt->XGI_Pr = pXGI->XGI_Pr = NULL;
+- if (pXGIEnt->RenderAccelArray)
+- xfree(pXGIEnt->RenderAccelArray);
+- pXGIEnt->RenderAccelArray = pXGI->RenderAccelArray = NULL;
+- }
+- else {
+- pXGI->BIOS = NULL;
+- pXGI->XGI_Pr = NULL;
+- pXGI->RenderAccelArray = NULL;
+- }
+- }
+- else {
+- if (pXGI->BIOS)
+- xfree(pXGI->BIOS);
+- pXGI->BIOS = NULL;
+- if (pXGI->XGI_Pr)
+- xfree(pXGI->XGI_Pr);
+- pXGI->XGI_Pr = NULL;
+- if (pXGI->RenderAccelArray)
+- xfree(pXGI->RenderAccelArray);
+- pXGI->RenderAccelArray = NULL;
+- }
+-
+-#ifdef XGIMERGED
+- if (pXGI->MetaModes)
+- xfree(pXGI->MetaModes);
+- pXGI->MetaModes = NULL;
+-
+- if (pXGI->CRT1Modes) {
+- if (pXGI->CRT1Modes != pScrn->modes) {
+- if (pScrn->modes) {
+- pScrn->currentMode = pScrn->modes;
+- do {
+- DisplayModePtr p = pScrn->currentMode->next;
+- if (pScrn->currentMode->Private)
+- xfree(pScrn->currentMode->Private);
+- xfree(pScrn->currentMode);
+- pScrn->currentMode = p;
+- } while (pScrn->currentMode != pScrn->modes);
+- }
+- pScrn->currentMode = pXGI->CRT1CurrentMode;
+- pScrn->modes = pXGI->CRT1Modes;
+- pXGI->CRT1CurrentMode = NULL;
+- pXGI->CRT1Modes = NULL;
+- }
+- }
+-#endif
+- if (pXGI->pVbe)
+- vbeFree(pXGI->pVbe);
+- pXGI->pVbe = NULL;
+- if (pScrn->driverPrivate == NULL)
+- return;
+- xfree(pScrn->driverPrivate);
+- pScrn->driverPrivate = NULL;
+-}
+-
+-static void
+-XGIDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+- int flags)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- BOOLEAN docrt1 = TRUE, docrt2 = TRUE;
+- unsigned char sr1 = 0, cr17 = 0, cr63 = 0, sr11 = 0, pmreg = 0, sr7 = 0;
+- unsigned char p1_13 = 0, p2_0 = 0, oldpmreg = 0;
+- BOOLEAN backlight = TRUE;
+-
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+- "XGIDisplayPowerManagementSet(%d)\n", PowerManagementMode);
+-
+- if (IS_DUAL_HEAD(pXGI)) {
+- if (IS_SECOND_HEAD(pXGI))
+- docrt2 = FALSE;
+- else
+- docrt1 = FALSE;
+- }
+-
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-#endif
+-
+- switch (PowerManagementMode) {
+-
+- case DPMSModeOn: /* HSync: On, VSync: On */
+- if (docrt1)
+- pXGI->Blank = FALSE;
+-
+- sr1 = 0x00;
+- cr17 = 0x80;
+- pmreg = 0x00;
+- cr63 = 0x00;
+- sr7 = 0x10;
+- sr11 = (pXGI->LCDon & 0x0C);
+- p2_0 = 0x20;
+- p1_13 = 0x00;
+- backlight = TRUE;
+- break;
+-
+- case DPMSModeSuspend: /* HSync: On, VSync: Off */
+- if (docrt1)
+- pXGI->Blank = TRUE;
+-
+- sr1 = 0x20;
+- cr17 = 0x80;
+- pmreg = 0x80;
+- cr63 = 0x40;
+- sr7 = 0x00;
+- sr11 = 0x08;
+- p2_0 = 0x40;
+- p1_13 = 0x80;
+- backlight = FALSE;
+- break;
+-
+- case DPMSModeStandby: /* HSync: Off, VSync: On */
+- if (docrt1)
+- pXGI->Blank = TRUE;
+-
+- sr1 = 0x20;
+- cr17 = 0x80;
+- pmreg = 0x40;
+- cr63 = 0x40;
+- sr7 = 0x00;
+- sr11 = 0x08;
+- p2_0 = 0x80;
+- p1_13 = 0x40;
+- backlight = FALSE;
+- break;
+-
+- case DPMSModeOff: /* HSync: Off, VSync: Off */
+- if (docrt1)
+- pXGI->Blank = TRUE;
+-
+- sr1 = 0x20;
+- cr17 = 0x00;
+- pmreg = 0xc0;
+- cr63 = 0x40;
+- sr7 = 0x00;
+- sr11 = 0x08;
+- p2_0 = 0xc0;
+- p1_13 = 0xc0;
+- backlight = FALSE;
+- break;
+-
+- default:
+- return;
+- }
+-
+- if (docrt1) {
+- /* Set/Clear "Display On" bit
+- */
+- setXGIIDXREG(XGISR, 0x01, ~0x20, sr1);
+-
+- if ((!(pXGI->VBFlags & CRT1_LCDA))
+- || (pXGI->XGI_Pr->VBType & VB_XGI301C)) {
+- inXGIIDXREG(XGISR, 0x1f, oldpmreg);
+- if (!pXGI->CRT1off) {
+- setXGIIDXREG(XGISR, 0x1f, 0x3f, pmreg);
+- }
+- }
+- oldpmreg &= 0xc0;
+- }
+-
+- if ((docrt1) && (pmreg != oldpmreg)
+- && ((!(pXGI->VBFlags & CRT1_LCDA))
+- || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
+- outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
+- usleep(10000);
+- outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
+- }
+-
+-}
+-
+-/* Mandatory */
+-static void
+-XGIIdentify(int flags)
+-{
+- xf86PrintChipsets(XGI_NAME, "driver for XGI chipsets", XGIChipsets);
+- PDEBUG(ErrorF(" --- XGIIdentify \n"));
+-}
+-
+-static void
+-XGIErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
+-{
+- va_list ap;
+- static const char *str =
+- "**************************************************\n";
+-
+- va_start(ap, format);
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " ERROR:\n");
+- xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
+- va_end(ap);
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- " END OF MESSAGE\n");
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
+-}
+-
+-#ifdef XSERVER_LIBPCIACCESS
+-static Bool XGIPciProbe(DriverPtr drv, int entity_num,
+- struct pci_device *dev, intptr_t match_data)
+-{
+- ScrnInfoPtr pScrn;
+-
+-
+- pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
+- NULL, NULL, NULL, NULL, NULL);
+- if (pScrn != NULL) {
+- XGIPtr pXGI;
+-
+- /* Fill in what we can of the ScrnInfoRec */
+- pScrn->driverVersion = XGI_CURRENT_VERSION;
+- pScrn->driverName = XGI_DRIVER_NAME;
+- pScrn->name = XGI_NAME;
+- pScrn->Probe = NULL;
+- pScrn->PreInit = XGIPreInit;
+- pScrn->ScreenInit = XGIScreenInit;
+- pScrn->SwitchMode = XGISwitchMode;
+- pScrn->AdjustFrame = XGIAdjustFrame;
+- pScrn->EnterVT = XGIEnterVT;
+- pScrn->LeaveVT = XGILeaveVT;
+- pScrn->FreeScreen = XGIFreeScreen;
+- pScrn->ValidMode = XGIValidMode;
+-
+-
+- pXGI = XGIGetRec(pScrn);
+- if (pXGI == NULL) {
+- return FALSE;
+- }
+-
+- pXGI->PciInfo = dev;
+- }
+-
+- return (pScrn != NULL);
+-}
+-
+-#else
+-
+-/* Mandatory */
+-static Bool
+-XGIProbe(DriverPtr drv, int flags)
+-{
+- int i;
+- GDevPtr *devSections;
+- int *usedChips;
+- int numDevSections;
+- int numUsed;
+- Bool foundScreen = FALSE;
+-
+- /*
+- * The aim here is to find all cards that this driver can handle,
+- * and for the ones not already claimed by another driver, claim the
+- * slot, and allocate a ScrnInfoRec.
+- *
+- * This should be a minimal probe, and it should under no circumstances
+- * change the state of the hardware. Because a device is found, don't
+- * assume that it will be used. Don't do any initialisations other than
+- * the required ScrnInfoRec initialisations. Don't allocate any new
+- * data structures.
+- *
+- */
+-
+- /*
+- * Next we check, if there has been a chipset override in the config file.
+- * For this we must find out if there is an active device section which
+- * is relevant, i.e., which has no driver specified or has THIS driver
+- * specified.
+- */
+-
+- if ((numDevSections =
+- xf86MatchDevice(XGI_DRIVER_NAME, &devSections)) <= 0) {
+- /*
+- * There's no matching device section in the config file, so quit
+- * now.
+- */
+- return FALSE;
+- }
+-
+- PDEBUG(ErrorF(" --- XGIProbe \n"));
+- /*
+- * We need to probe the hardware first. We then need to see how this
+- * fits in with what is given in the config file, and allow the config
+- * file info to override any contradictions.
+- */
+-
+- /*
+- * All of the cards this driver supports are PCI, so the "probing" just
+- * amounts to checking the PCI data that the server has already collected.
+- */
+- if (xf86GetPciVideoInfo() == NULL) {
+- /*
+- * We won't let anything in the config file override finding no
+- * PCI video cards at all. This seems reasonable now, but we'll see.
+- */
+- return FALSE;
+- }
+-
+- numUsed = xf86MatchPciInstances(XGI_NAME, PCI_VENDOR_XGI,
+- XGIChipsets, XGIPciChipsets, devSections,
+- numDevSections, drv, &usedChips);
+-
+- /* Free it since we don't need that list after this */
+- xfree(devSections);
+- if (numUsed <= 0)
+- return FALSE;
+-
+- if (flags & PROBE_DETECT) {
+- foundScreen = TRUE;
+- }
+- else
+- for (i = 0; i < numUsed; i++) {
+- ScrnInfoPtr pScrn;
+-#ifdef XGIDUALHEAD
+- EntityInfoPtr pEnt;
+-#endif
+-
+- /* Allocate a ScrnInfoRec and claim the slot */
+- pScrn = NULL;
+-
+- if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
+- XGIPciChipsets, NULL, NULL,
+- NULL, NULL, NULL))) {
+- /* Fill in what we can of the ScrnInfoRec */
+- pScrn->driverVersion = XGI_CURRENT_VERSION;
+- pScrn->driverName = XGI_DRIVER_NAME;
+- pScrn->name = XGI_NAME;
+- pScrn->Probe = XGIProbe;
+- pScrn->PreInit = XGIPreInit;
+- pScrn->ScreenInit = XGIScreenInit;
+- pScrn->SwitchMode = XGISwitchMode;
+- pScrn->AdjustFrame = XGIAdjustFrame;
+- pScrn->EnterVT = XGIEnterVT;
+- pScrn->LeaveVT = XGILeaveVT;
+- pScrn->FreeScreen = XGIFreeScreen;
+- pScrn->ValidMode = XGIValidMode;
+- foundScreen = TRUE;
+- }
+-#ifdef XGIDUALHEAD
+- pEnt = xf86GetEntityInfo(usedChips[i]);
+-
+-#endif
+- }
+- xfree(usedChips);
+-
+- return foundScreen;
+-}
+-#endif
+-
+-
+-/* Some helper functions for MergedFB mode */
+-
+-#ifdef XGIMERGED
+-
+-/* Copy and link two modes form mergedfb mode
+- * (Code base taken from mga driver)
+- * Copys mode i, links the result to dest, and returns it.
+- * Links i and j in Private record.
+- * If dest is NULL, return value is copy of i linked to itself.
+- * For mergedfb auto-config, we only check the dimension
+- * against virtualX/Y, if they were user-provided.
+- */
+-static DisplayModePtr
+-XGICopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
+- DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- DisplayModePtr mode;
+- int dx = 0, dy = 0;
+-
+- if (!((mode = xalloc(sizeof(DisplayModeRec)))))
+- return dest;
+- memcpy(mode, i, sizeof(DisplayModeRec));
+- if (!((mode->Private = xalloc(sizeof(XGIMergedDisplayModeRec))))) {
+- xfree(mode);
+- return dest;
+- }
+- ((XGIMergedDisplayModePtr) mode->Private)->CRT1 = i;
+- ((XGIMergedDisplayModePtr) mode->Private)->CRT2 = j;
+- ((XGIMergedDisplayModePtr) mode->Private)->CRT2Position = srel;
+- mode->PrivSize = 0;
+-
+- switch (srel) {
+- case xgiLeftOf:
+- case xgiRightOf:
+- if (!(pScrn->display->virtualX)) {
+- dx = i->HDisplay + j->HDisplay;
+- }
+- else {
+- dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
+- }
+- dx -= mode->HDisplay;
+- if (!(pScrn->display->virtualY)) {
+- dy = max(i->VDisplay, j->VDisplay);
+- }
+- else {
+- dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+- }
+- dy -= mode->VDisplay;
+- break;
+- case xgiAbove:
+- case xgiBelow:
+- if (!(pScrn->display->virtualY)) {
+- dy = i->VDisplay + j->VDisplay;
+- }
+- else {
+- dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
+- }
+- dy -= mode->VDisplay;
+- if (!(pScrn->display->virtualX)) {
+- dx = max(i->HDisplay, j->HDisplay);
+- }
+- else {
+- dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+- }
+- dx -= mode->HDisplay;
+- break;
+- case xgiClone:
+- if (!(pScrn->display->virtualX)) {
+- dx = max(i->HDisplay, j->HDisplay);
+- }
+- else {
+- dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
+- }
+- dx -= mode->HDisplay;
+- if (!(pScrn->display->virtualY)) {
+- dy = max(i->VDisplay, j->VDisplay);
+- }
+- else {
+- dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
+- }
+- dy -= mode->VDisplay;
+- break;
+- }
+- mode->HDisplay += dx;
+- mode->HSyncStart += dx;
+- mode->HSyncEnd += dx;
+- mode->HTotal += dx;
+- mode->VDisplay += dy;
+- mode->VSyncStart += dy;
+- mode->VSyncEnd += dy;
+- mode->VTotal += dy;
+- mode->Clock = 0;
+-
+- if (((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) >
+- pXGI->maxxfbmem) || (mode->HDisplay > 4088)
+- || (mode->VDisplay > 4096)) {
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Skipped %dx%d, not enough video RAM or beyond hardware specs\n",
+- mode->HDisplay, mode->VDisplay);
+- xfree(mode->Private);
+- xfree(mode);
+-
+- return dest;
+- }
+-
+-#ifdef XGIXINERAMA
+- if (srel != xgiClone) {
+- pXGI->AtLeastOneNonClone = TRUE;
+- }
+-#endif
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Merged %dx%d and %dx%d to %dx%d%s\n",
+- i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay,
+- mode->HDisplay, mode->VDisplay,
+- (srel == xgiClone) ? " (Clone)" : "");
+-
+- mode->next = mode;
+- mode->prev = mode;
+-
+- if (dest) {
+- mode->next = dest->next; /* Insert node after "dest" */
+- dest->next->prev = mode;
+- mode->prev = dest;
+- dest->next = mode;
+- }
+-
+- return mode;
+-}
+-
+-/* Helper function to find a mode from a given name
+- * (Code base taken from mga driver)
+- */
+-static DisplayModePtr
+-XGIGetModeFromName(char *str, DisplayModePtr i)
+-{
+- DisplayModePtr c = i;
+- if (!i)
+- return NULL;
+- do {
+- if (strcmp(str, c->name) == 0)
+- return c;
+- c = c->next;
+- } while (c != i);
+- return NULL;
+-}
+-
+-static DisplayModePtr
+-XGIFindWidestTallestMode(DisplayModePtr i, Bool tallest)
+-{
+- DisplayModePtr c = i, d = NULL;
+- int max = 0;
+- if (!i)
+- return NULL;
+- do {
+- if (tallest) {
+- if (c->VDisplay > max) {
+- max = c->VDisplay;
+- d = c;
+- }
+- }
+- else {
+- if (c->HDisplay > max) {
+- max = c->HDisplay;
+- d = c;
+- }
+- }
+- c = c->next;
+- } while (c != i);
+- return d;
+-}
+-
+-static DisplayModePtr
+-XGIGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
+- DisplayModePtr i, DisplayModePtr j,
+- XGIScrn2Rel srel)
+-{
+-#ifdef XGIXINERAMA
+- XGIPtr pXGI = XGIPTR(pScrn);
+-#endif
+- DisplayModePtr mode1 = NULL;
+- DisplayModePtr mode2 = NULL;
+- DisplayModePtr result = NULL;
+-
+-#ifdef XGIXINERAMA
+- pXGI->AtLeastOneNonClone = FALSE;
+-#endif
+-
+- switch (srel) {
+- case xgiLeftOf:
+- case xgiRightOf:
+- mode1 = XGIFindWidestTallestMode(i, FALSE);
+- mode2 = XGIFindWidestTallestMode(j, FALSE);
+- break;
+- case xgiAbove:
+- case xgiBelow:
+- mode1 = XGIFindWidestTallestMode(i, TRUE);
+- mode2 = XGIFindWidestTallestMode(j, TRUE);
+- break;
+- case xgiClone:
+- mode1 = i;
+- mode2 = j;
+- }
+-
+- if (mode1 && mode2) {
+- return (XGICopyModeNLink(pScrn, result, mode1, mode2, srel));
+- }
+- else {
+- return NULL;
+- }
+-}
+-
+-/* Generate the merged-fb mode modelist from metamodes
+- * (Code base taken from mga driver)
+- */
+-static DisplayModePtr
+-XGIGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char *str,
+- DisplayModePtr i, DisplayModePtr j,
+- XGIScrn2Rel srel)
+-{
+-#ifdef XGIXINERAMA
+- XGIPtr pXGI = XGIPTR(pScrn);
+-#endif
+- char *strmode = str;
+- char modename[256];
+- Bool gotdash = FALSE;
+- XGIScrn2Rel sr;
+- DisplayModePtr mode1 = NULL;
+- DisplayModePtr mode2 = NULL;
+- DisplayModePtr result = NULL;
+-
+-#ifdef XGIXINERAMA
+- pXGI->AtLeastOneNonClone = FALSE;
+-#endif
+-
+- do {
+- switch (*str) {
+- case 0:
+- case '-':
+- case ' ':
+- if ((strmode != str)) {
+-
+- strncpy(modename, strmode, str - strmode);
+- modename[str - strmode] = 0;
+-
+- if (gotdash) {
+- if (mode1 == NULL)
+- return NULL;
+- mode2 = XGIGetModeFromName(modename, j);
+- if (!mode2) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Mode \"%s\" is not a supported mode for CRT2\n",
+- modename);
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Skipping metamode \"%s-%s\".\n",
+- mode1->name, modename);
+- mode1 = NULL;
+- }
+- }
+- else {
+- mode1 = XGIGetModeFromName(modename, i);
+- if (!mode1) {
+- char *tmps = str;
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Mode \"%s\" is not a supported mode for CRT1\n",
+- modename);
+- gotdash = FALSE;
+- while (*tmps == ' ')
+- tmps++;
+- if (*tmps == '-') { /* skip the next mode */
+- tmps++;
+- while ((*tmps == ' ') && (*tmps != 0))
+- tmps++; /* skip spaces */
+- while ((*tmps != ' ') && (*tmps != '-')
+- && (*tmps != 0))
+- tmps++; /* skip modename */
+- strncpy(modename, strmode, tmps - strmode);
+- modename[tmps - strmode] = 0;
+- str = tmps - 1;
+- }
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Skipping metamode \"%s\".\n", modename);
+- mode1 = NULL;
+- }
+- }
+- gotdash = FALSE;
+- }
+- strmode = str + 1;
+- gotdash |= (*str == '-');
+-
+- if (*str != 0)
+- break;
+- /* Fall through otherwise */
+-
+- default:
+- if (!gotdash && mode1) {
+- sr = srel;
+- if (!mode2) {
+- mode2 = XGIGetModeFromName(mode1->name, j);
+- sr = xgiClone;
+- }
+- if (!mode2) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Mode: \"%s\" is not a supported mode for CRT2\n",
+- mode1->name);
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Skipping metamode \"%s\".\n", modename);
+- mode1 = NULL;
+- }
+- else {
+- result =
+- XGICopyModeNLink(pScrn, result, mode1, mode2, sr);
+- mode1 = NULL;
+- mode2 = NULL;
+- }
+- }
+- break;
+-
+- }
+-
+- } while (*(str++) != 0);
+-
+- return result;
+-}
+-
+-static DisplayModePtr
+-XGIGenerateModeList(ScrnInfoPtr pScrn, char *str,
+- DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
+-{
+- if (str != NULL) {
+- return (XGIGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
+- }
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "No MetaModes given, linking %s modes by default\n",
+- (srel == xgiClone) ? "first" :
+- (((srel == xgiLeftOf)
+- || (srel == xgiRightOf)) ? "widest" : "tallest"));
+- return (XGIGenerateModeListFromLargestModes(pScrn, i, j, srel));
+- }
+-}
+-
+-static void
+-XGIRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
+-{
+- DisplayModePtr mode, bmode;
+- int max;
+- static const char *str = "MergedFB: Virtual %s %d\n";
+-
+- if (!(pScrn->display->virtualX)) {
+- mode = bmode = pScrn->modes;
+- max = 0;
+- do {
+- if (mode->HDisplay > max)
+- max = mode->HDisplay;
+- mode = mode->next;
+- } while (mode != bmode);
+- pScrn->virtualX = max;
+- pScrn->displayWidth = max;
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
+- }
+- if (!(pScrn->display->virtualY)) {
+- mode = bmode = pScrn->modes;
+- max = 0;
+- do {
+- if (mode->VDisplay > max)
+- max = mode->VDisplay;
+- mode = mode->next;
+- } while (mode != bmode);
+- pScrn->virtualY = max;
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
+- }
+-}
+-
+-static void
+-XGIMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, XGIScrn2Rel srel)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn1);
+- MessageType from = X_DEFAULT;
+- xf86MonPtr DDC1 = (xf86MonPtr) (pScrn1->monitor->DDC);
+- xf86MonPtr DDC2 = (xf86MonPtr) (pScrn2->monitor->DDC);
+- int ddcWidthmm = 0, ddcHeightmm = 0;
+- const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
+-
+- /* This sets the DPI for MergedFB mode. The problem is that
+- * this can never be exact, because the output devices may
+- * have different dimensions. This function tries to compromise
+- * through a few assumptions, and it just calculates an average DPI
+- * value for both monitors.
+- */
+-
+- /* Given DisplaySize should regard BOTH monitors */
+- pScrn1->widthmm = pScrn1->monitor->widthmm;
+- pScrn1->heightmm = pScrn1->monitor->heightmm;
+-
+- /* Get DDC display size; if only either CRT1 or CRT2 provided these,
+- * assume equal dimensions for both, otherwise add dimensions
+- */
+- if ((DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
+- (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0))) {
+- ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
+- ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
+- switch (srel) {
+- case xgiLeftOf:
+- case xgiRightOf:
+- ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
+- break;
+- case xgiAbove:
+- case xgiBelow:
+- ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
+- default:
+- break;
+- }
+- }
+- else if (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
+- ddcWidthmm = DDC1->features.hsize * 10;
+- ddcHeightmm = DDC1->features.vsize * 10;
+- switch (srel) {
+- case xgiLeftOf:
+- case xgiRightOf:
+- ddcWidthmm *= 2;
+- break;
+- case xgiAbove:
+- case xgiBelow:
+- ddcHeightmm *= 2;
+- default:
+- break;
+- }
+- }
+- else if (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) {
+- ddcWidthmm = DDC2->features.hsize * 10;
+- ddcHeightmm = DDC2->features.vsize * 10;
+- switch (srel) {
+- case xgiLeftOf:
+- case xgiRightOf:
+- ddcWidthmm *= 2;
+- break;
+- case xgiAbove:
+- case xgiBelow:
+- ddcHeightmm *= 2;
+- default:
+- break;
+- }
+- }
+-
+- if (monitorResolution > 0) {
+-
+- /* Set command line given values (overrules given options) */
+- pScrn1->xDpi = monitorResolution;
+- pScrn1->yDpi = monitorResolution;
+- from = X_CMDLINE;
+-
+- }
+- else if (pXGI->MergedFBXDPI) {
+-
+- /* Set option-wise given values (overrule DisplaySize) */
+- pScrn1->xDpi = pXGI->MergedFBXDPI;
+- pScrn1->yDpi = pXGI->MergedFBYDPI;
+- from = X_CONFIG;
+-
+- }
+- else if (pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
+-
+- /* Set values calculated from given DisplaySize */
+- from = X_CONFIG;
+- if (pScrn1->widthmm > 0) {
+- pScrn1->xDpi =
+- (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+- }
+- if (pScrn1->heightmm > 0) {
+- pScrn1->yDpi =
+- (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+- }
+- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm,
+- pScrn1->heightmm);
+-
+- }
+- else if (ddcWidthmm && ddcHeightmm) {
+-
+- /* Set values from DDC-provided display size */
+- from = X_PROBED;
+- xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
+- pScrn1->widthmm = ddcWidthmm;
+- pScrn1->heightmm = ddcHeightmm;
+- if (pScrn1->widthmm > 0) {
+- pScrn1->xDpi =
+- (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
+- }
+- if (pScrn1->heightmm > 0) {
+- pScrn1->yDpi =
+- (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
+- }
+-
+- }
+- else {
+-
+- pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
+-
+- }
+-
+- /* Sanity check */
+- if (pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
+- pScrn1->yDpi = pScrn1->xDpi;
+- if (pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
+- pScrn1->xDpi = pScrn1->yDpi;
+-
+- pScrn2->xDpi = pScrn1->xDpi;
+- pScrn2->yDpi = pScrn1->yDpi;
+-
+- xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
+- pScrn1->xDpi, pScrn1->yDpi);
+-}
+-
+-static void
+-XGIFreeCRT2Structs(XGIPtr pXGI)
+-{
+- if (pXGI->CRT2pScrn) {
+- if (pXGI->CRT2pScrn->modes) {
+- while (pXGI->CRT2pScrn->modes)
+- xf86DeleteMode(&pXGI->CRT2pScrn->modes,
+- pXGI->CRT2pScrn->modes);
+- }
+- if (pXGI->CRT2pScrn->monitor) {
+- if (pXGI->CRT2pScrn->monitor->Modes) {
+- while (pXGI->CRT2pScrn->monitor->Modes)
+- xf86DeleteMode(&pXGI->CRT2pScrn->monitor->Modes,
+- pXGI->CRT2pScrn->monitor->Modes);
+- }
+- if (pXGI->CRT2pScrn->monitor->DDC)
+- xfree(pXGI->CRT2pScrn->monitor->DDC);
+- xfree(pXGI->CRT2pScrn->monitor);
+- }
+- xfree(pXGI->CRT2pScrn);
+- pXGI->CRT2pScrn = NULL;
+- }
+-}
+-
+-#endif /* End of MergedFB helpers */
+-
+-static xf86MonPtr
+-XGIInternalDDC(ScrnInfoPtr pScrn, int crtno)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned char buffer[256];
+-
+- int RealOff;
+- unsigned char *page;
+-
+- xf86MonPtr pMonitor = NULL;
+- xf86Int10InfoPtr pInt = NULL; /* Our int10 */
+-
+- static char *crtno_means_str[] = {
+- "CRT1", "DVI", "CRT2"
+- };
+-
+- if (crtno > 2 || crtno < 0) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "XGIInternalDDC(): Can not get EDID for crtno = %d,abort.\n",
+- crtno);
+- }
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "XGIInternalDDC(): getting EDID for %s.\n",
+- crtno_means_str[crtno]);
+- }
+-
+- if (xf86LoadSubModule(pScrn, "int10")) {
+- xf86LoaderReqSymLists(int10Symbols, NULL);
+- pInt = xf86InitInt10(pXGI->pEnt->index);
+- if (pInt == NULL) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "XGIInternalDDC(): Can not initialize pInt, abort.\n");
+- return NULL;
+- }
+-
+- page = xf86Int10AllocPages(pInt, 1, &RealOff);
+- if (page == NULL) {
+- xf86FreeInt10(pInt);
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "XGIInternalDDC(): Can not initialize real mode buffer, abort.\n");
+- return NULL;
+- }
+- }
+-
+- if (pInt) {
+- pInt->ax = 0x4f15; /* VESA DDC supporting */
+- pInt->bx = 1; /* get EDID */
+- pInt->cx = crtno; /* port 0 or 1 for CRT 1 or 2 */
+- pInt->es = SEG_ADDR(RealOff);
+- pInt->di = SEG_OFF(RealOff);
+- pInt->num = 0x10;
+- xf86ExecX86int10(pInt);
+-
+- PDEBUG3(ErrorF
+- ("ax = %04X bx = %04X cx = %04X dx = %04X si = %04X di = %04X es = %04X\n",
+- pInt->ax, pInt->bx, pInt->cx, pInt->dx, pInt->si, pInt->di,
+- pInt->es));
+-
+- if ((pInt->ax & 0xff00) == 0) {
+- int i;
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "XGIInternalDDC(): VESA get DDC success for CRT %d.\n",
+- crtno + 1);
+-
+- for (i = 0; i < 128; i++) {
+- buffer[i] = page[i];
+- }
+-
+-#ifdef DEBUG5
+- for (i = 0; i < 128; i += 16) {
+- unsigned j;
+- ErrorF("EDID[%02X]", i);
+- for (j = 0; j < 16; j++) {
+- ErrorF(" %02X", buffer[i + j]);
+- }
+- ErrorF("\n");
+- }
+-#endif /* DEBUG3 */
+-
+- xf86LoaderReqSymLists(ddcSymbols, NULL);
+- pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer);
+-
+- if (pMonitor == NULL) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "CRT%d DDC EDID corrupt\n", crtno + 1);
+- return (NULL);
+- }
+- xf86UnloadSubModule("ddc");
+- }
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "XGIInternalDDC(): VESA get DDC fail for CRT %d.\n",
+- crtno + 1);
+- }
+-
+- xf86Int10FreePages(pInt, page, 1);
+- xf86FreeInt10(pInt);
+- }
+- return pMonitor;
+-}
+-
+-/* static xf86MonPtr
+-XGIDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- if(IS_DUAL_HEAD(pXGI))
+- {
+- if(IS_SECOND_HEAD(pXGI))
+- {
+- *crtnum = 1;
+- return(XGIInternalDDC(pScrn, 0));
+- }
+- else
+- {
+- *crtnum = 2;
+- return(XGIInternalDDC(pScrn, 1));
+- }
+- }
+- else if(pXGI->CRT1off)
+- {
+- *crtnum = 2;
+- return(XGIInternalDDC(pScrn, 1));
+- }
+- else
+- {
+- *crtnum = 1;
+- return(XGIInternalDDC(pScrn, 0));
+- }
+-} */
+-
+-
+-#ifdef DEBUG5
+-static void
+-XGIDumpMonitorInfo(xf86MonPtr pMonitor)
+-{
+- struct detailed_timings *pd_timings;
+- Uchar *pserial;
+- Uchar *pascii_data;
+- Uchar *pname;
+- struct monitor_ranges *pranges;
+- struct std_timings *pstd_t;
+- struct whitePoints *pwp;
+- int i, j;
+-
+- if (pMonitor == NULL) {
+- ErrorF("Monitor is NULL");
+- return;
+- }
+-
+- ErrorF("pMonitor->scrnIndex = %d\n", pMonitor->scrnIndex);
+- ErrorF
+- ("vendor = %c%c%c%c, prod_id = %x serial = %d week = %d year = %d\n",
+- pMonitor->vendor.name[0], pMonitor->vendor.name[1],
+- pMonitor->vendor.name[2], pMonitor->vendor.name[3],
+- pMonitor->vendor.prod_id, pMonitor->vendor.serial,
+- pMonitor->vendor.week, pMonitor->vendor.year);
+-
+- ErrorF("ver = %d %d\n", pMonitor->ver.version, pMonitor->ver.revision);
+- ErrorF("intput type = %d voltage = %d setup = %d sync = %d\n",
+- pMonitor->features.input_type,
+- pMonitor->features.input_voltage,
+- pMonitor->features.input_setup, pMonitor->features.input_sync);
+- ErrorF("hsize = %d vsize = %d gamma=%8.3f\n",
+- pMonitor->features.hsize,
+- pMonitor->features.vsize, pMonitor->features.gamma);
+-
+- ErrorF("dpms = %d display_type = %d msc = %d\n",
+- pMonitor->features.dpms,
+- pMonitor->features.display_type, pMonitor->features.msc);
+- ErrorF
+- ("redx,redy,greenx,greeny,bluex,bluey,whitex,whitey = %8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f\n",
+- pMonitor->features.redx, pMonitor->features.redy,
+- pMonitor->features.greenx, pMonitor->features.greeny,
+- pMonitor->features.bluex, pMonitor->features.bluey,
+- pMonitor->features.whitex, pMonitor->features.whitey);
+-
+- ErrorF("established_timings = (t1)%d%d%d%d%d%d%d%d",
+- (pMonitor->timings1.t1 >> 7) & 1,
+- (pMonitor->timings1.t1 >> 6) & 1,
+- (pMonitor->timings1.t1 >> 5) & 1,
+- (pMonitor->timings1.t1 >> 4) & 1,
+- (pMonitor->timings1.t1 >> 3) & 1,
+- (pMonitor->timings1.t1 >> 2) & 1,
+- (pMonitor->timings1.t1 >> 1) & 1,
+- (pMonitor->timings1.t1 >> 0) & 1);
+- ErrorF("(t2) %d%d%d%d%d%d%d%d",
+- (pMonitor->timings1.t1 >> 7) & 1,
+- (pMonitor->timings1.t1 >> 6) & 1,
+- (pMonitor->timings1.t1 >> 5) & 1,
+- (pMonitor->timings1.t1 >> 4) & 1,
+- (pMonitor->timings1.t1 >> 3) & 1,
+- (pMonitor->timings1.t1 >> 2) & 1,
+- (pMonitor->timings1.t1 >> 1) & 1,
+- (pMonitor->timings1.t1 >> 0) & 1);
+- ErrorF("(t_manu)%d%d%d%d%d%d%d%d\n",
+- (pMonitor->timings1.t_manu >> 7) & 1,
+- (pMonitor->timings1.t_manu >> 6) & 1,
+- (pMonitor->timings1.t_manu >> 5) & 1,
+- (pMonitor->timings1.t_manu >> 4) & 1,
+- (pMonitor->timings1.t_manu >> 3) & 1,
+- (pMonitor->timings1.t_manu >> 2) & 1,
+- (pMonitor->timings1.t_manu >> 1) & 1,
+- (pMonitor->timings1.t_manu >> 0) & 1);
+-
+- for (i = 0; i < 7; i++) {
+- ErrorF
+- ("std timing %d: hsize = %d, vsize = %d, refresh = %d, id = %d\n",
+- i, pMonitor->timings2[i].hsize, pMonitor->timings2[i].vsize,
+- pMonitor->timings2[i].refresh, pMonitor->timings2[i].id);
+- }
+-
+- for (i = 0; i < 4; i++) {
+- ErrorF("Detail timing section %d\n", i);
+- ErrorF("type = %x\n", pMonitor->det_mon[i].type);
+- switch (pMonitor->det_mon[i].type) {
+- case DS_SERIAL:
+- ErrorF("type = %x DS_SERIAL = %x\n", pMonitor->det_mon[i].type,
+- DS_SERIAL);
+- break;
+- case DS_ASCII_STR:
+- ErrorF("type = %x DS_ASCII_STR = %x\n", pMonitor->det_mon[i].type,
+- DS_ASCII_STR);
+- break;
+- case DS_NAME:
+- ErrorF("type = %x DS_NAME = %x\n", pMonitor->det_mon[i].type,
+- DS_NAME);
+- break;
+- case DS_RANGES:
+- ErrorF("type = %x DS_RANGES = %x\n", pMonitor->det_mon[i].type,
+- DS_RANGES);
+- break;
+- case DS_WHITE_P:
+- ErrorF("type = %x DS_WHITE_P = %x\n", pMonitor->det_mon[i].type,
+- DS_WHITE_P);
+- break;
+- case DS_STD_TIMINGS:
+- ErrorF("type = %x DS_STD_TIMINGS = %x\n",
+- pMonitor->det_mon[i].type, DS_STD_TIMINGS);
+- break;
+- }
+- switch (pMonitor->det_mon[i].type) {
+- case DS_SERIAL:
+- pserial = pMonitor->det_mon[i].section.serial;
+- ErrorF("seial: ");
+- for (j = 0; j < 13; j++) {
+- ErrorF("%02X", pserial[j]);
+- }
+- ErrorF("\n");
+- break;
+- case DS_ASCII_STR:
+- pascii_data = pMonitor->det_mon[i].section.ascii_data;
+- ErrorF("ascii: ");
+- for (j = 0; j < 13; j++) {
+- ErrorF("%c", pascii_data[j]);
+- }
+- ErrorF("\n");
+- break;
+- case DS_NAME:
+- pname = pMonitor->det_mon[i].section.name;
+- ErrorF("name: ");
+- for (j = 0; j < 13; j++) {
+- ErrorF("%c", pname[j]);
+- }
+- ErrorF("\n");
+- break;
+- case DS_RANGES:
+- pranges = &(pMonitor->det_mon[i].section.ranges);
+- ErrorF
+- ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
+- pranges->min_v, pranges->max_v, pranges->min_h,
+- pranges->max_h, pranges->max_clock);
+- break;
+- case DS_WHITE_P:
+- pwp = pMonitor->det_mon[i].section.wp;
+- for (j = 0; j < 2; j++) {
+- ErrorF
+- ("wp[%d].index = %d white_x = %8.3f white_y = %8.3f white_gamma = %8.3f\n",
+- j, pwp[j].index, pwp[j].white_x, pwp[j].white_y,
+- pwp[j].white_gamma);
+- }
+- break;
+- case DS_STD_TIMINGS:
+- pstd_t = pMonitor->det_mon[i].section.std_t;
+- for (j = 0; j < 5; j++) {
+- ErrorF
+- ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
+- j, pstd_t[j].hsize, pstd_t[j].vsize, pstd_t[j].refresh,
+- pstd_t[j].id);
+- }
+- break;
+- case DT:
+-
+- pd_timings = &pMonitor->det_mon[i].section.d_timings;
+- ErrorF("Detail Timing Descriptor\n");
+- ErrorF("clock = %d\n", pd_timings->clock);
+- ErrorF("h_active = %d\n", pd_timings->h_active);
+- ErrorF("h_blanking = %d\n", pd_timings->h_blanking);
+- ErrorF("v_active = %d\n", pd_timings->v_active);
+- ErrorF("v_blanking = %d\n", pd_timings->v_blanking);
+- ErrorF("h_sync_off = %d\n", pd_timings->h_sync_off);
+- ErrorF("h_sync_width = %d\n", pd_timings->h_sync_width);
+- ErrorF("v_sync_off = %d\n", pd_timings->v_sync_off);
+- ErrorF("v_sync_width = %d\n", pd_timings->v_sync_width);
+- ErrorF("h_size = %d\n", pd_timings->h_size);
+- ErrorF("v_size = %d\n", pd_timings->v_size);
+- ErrorF("h_border = %d\n", pd_timings->h_border);
+- ErrorF("v_border = %d\n", pd_timings->v_border);
+- ErrorF("interlaced = %d stereo = %x sync = %x misc = %x\n",
+- pd_timings->interlaced,
+- pd_timings->stereo, pd_timings->sync, pd_timings->misc);
+- break;
+- }
+- }
+-
+- for (i = 0; i < 128; i += 16) {
+- ErrorF("rawData[%02X]:", i);
+- for (j = 0; j < 16; j++) {
+- ErrorF(" %02X", pMonitor->rawData[i + j]);
+- }
+- ErrorF("\n");
+- }
+-}
+-#endif
+-
+-static void
+-XGIGetMonitorRangeByDDC(MonitorRangePtr range, xf86MonPtr pMonitor)
+-{
+- int i, j;
+- float VF, HF;
+- struct detailed_timings *pd_timings;
+- struct monitor_ranges *pranges;
+- struct std_timings *pstd_t;
+-
+- if ((range == NULL) || (pMonitor == NULL)) {
+- return; /* ignore */
+- }
+-
+- PDEBUG5(ErrorF
+- ("establish timing t1 = %02x t2=%02x\n", pMonitor->timings1.t1,
+- pMonitor->timings1.t2));
+- for (i = 0, j = 0; i < 8; i++, j++) {
+- if (establish_timing[j].width == -1) {
+- continue;
+- }
+-
+- if (pMonitor->timings1.t1 & (1 << i)) {
+- PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
+- establish_timing[j].width,
+- establish_timing[j].height,
+- establish_timing[j].VRefresh,
+- establish_timing[j].HSync));
+-
+- if (range->loH > establish_timing[j].HSync) {
+- range->loH = establish_timing[j].HSync;
+- }
+-
+- if (range->hiH < establish_timing[j].HSync) {
+- range->hiH = establish_timing[j].HSync;
+- }
+-
+- if (range->loV > establish_timing[j].VRefresh) {
+- range->loV = establish_timing[j].VRefresh;
+- }
+-
+- if (range->hiV < establish_timing[j].VRefresh) {
+- range->hiV = establish_timing[j].VRefresh;
+- }
+- }
+- }
+- PDEBUG5(ErrorF
+- ("check establish timing t1:range ( %8.3f %8.3f %8.3f %8.3f )\n",
+- range->loH, range->loV, range->hiH, range->hiV));
+-
+- for (i = 0; i < 8; i++, j++) {
+- if (establish_timing[j].width == -1) {
+- continue;
+- }
+-
+- if (pMonitor->timings1.t2 & (1 << i)) {
+- PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
+- establish_timing[j].width,
+- establish_timing[j].height,
+- establish_timing[j].VRefresh,
+- establish_timing[j].HSync));
+-
+- if (range->loH > establish_timing[j].HSync) {
+- range->loH = establish_timing[j].HSync;
+- }
+-
+- if (range->hiH < establish_timing[j].HSync) {
+- range->hiH = establish_timing[j].HSync;
+- }
+-
+- if (range->loV > establish_timing[j].VRefresh) {
+- range->loV = establish_timing[j].VRefresh;
+- }
+-
+- if (range->hiV < establish_timing[j].VRefresh) {
+- range->hiV = establish_timing[j].VRefresh;
+- }
+- }
+- }
+- PDEBUG5(ErrorF
+- ("check establish timing t2:range ( %8.3f %8.3f %8.3f %8.3f )\n",
+- range->loH, range->loV, range->hiH, range->hiV));
+-
+- for (i = 0; i < 8; i++) {
+- for (j = 0; StdTiming[j].width != -1; j++) {
+- if ((StdTiming[j].width == pMonitor->timings2[i].hsize) &&
+- (StdTiming[j].height == pMonitor->timings2[i].vsize) &&
+- (StdTiming[j].VRefresh == pMonitor->timings2[i].refresh)) {
+- PDEBUG5(ErrorF("pMonitor->timings2[%d]= %d %d %d %d\n",
+- i,
+- pMonitor->timings2[i].hsize,
+- pMonitor->timings2[i].vsize,
+- pMonitor->timings2[i].refresh,
+- pMonitor->timings2[i].id));
+- HF = StdTiming[j].HSync;
+- VF = StdTiming[j].VRefresh;
+- if (range->loH > HF)
+- range->loH = HF;
+- if (range->loV > VF)
+- range->loV = VF;
+- if (range->hiH < HF)
+- range->hiH = HF;
+- if (range->hiV < VF)
+- range->hiV = VF;
+- break;
+- }
+- }
+- }
+- PDEBUG5(ErrorF
+- ("check standard timing :range ( %8.3f %8.3f %8.3f %8.3f )\n",
+- range->loH, range->loV, range->hiH, range->hiV));
+-
+- for (i = 0; i < 4; i++) {
+- switch (pMonitor->det_mon[i].type) {
+- case DS_RANGES:
+- pranges = &(pMonitor->det_mon[i].section.ranges);
+- PDEBUG5(ErrorF
+- ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
+- pranges->min_v, pranges->max_v, pranges->min_h,
+- pranges->max_h, pranges->max_clock));
+-
+- if (range->loH > pranges->min_h)
+- range->loH = pranges->min_h;
+- if (range->loV > pranges->min_v)
+- range->loV = pranges->min_v;
+- if (range->hiH < pranges->max_h)
+- range->hiH = pranges->max_h;
+- if (range->hiV < pranges->max_v)
+- range->hiV = pranges->max_v;
+- PDEBUG5(ErrorF
+- ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
+- range->loV, range->hiH, range->hiV));
+- break;
+-
+- case DS_STD_TIMINGS:
+- pstd_t = pMonitor->det_mon[i].section.std_t;
+- for (j = 0; j < 5; j++) {
+- int k;
+- PDEBUG5(ErrorF
+- ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
+- j, pstd_t[j].hsize, pstd_t[j].vsize,
+- pstd_t[j].refresh, pstd_t[j].id));
+- for (k = 0; StdTiming[k].width != -1; k++) {
+- if ((StdTiming[k].width == pstd_t[j].hsize) &&
+- (StdTiming[k].height == pstd_t[j].vsize) &&
+- (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
+- if (range->loH > StdTiming[k].HSync)
+- range->loH = StdTiming[k].HSync;
+- if (range->hiH < StdTiming[k].HSync)
+- range->hiH = StdTiming[k].HSync;
+- if (range->loV > StdTiming[k].VRefresh)
+- range->loV = StdTiming[k].VRefresh;
+- if (range->hiV < StdTiming[k].VRefresh)
+- range->hiV = StdTiming[k].VRefresh;
+- break;
+- }
+-
+- }
+- }
+- break;
+-
+- case DT:
+-
+- pd_timings = &pMonitor->det_mon[i].section.d_timings;
+-
+- HF = pd_timings->clock / (pd_timings->h_active +
+- pd_timings->h_blanking);
+- VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
+- HF /= 1000; /* into KHz Domain */
+- if (range->loH > HF)
+- range->loH = HF;
+- if (range->hiH < HF)
+- range->hiH = HF;
+- if (range->loV > VF)
+- range->loV = VF;
+- if (range->hiV < VF)
+- range->hiV = VF;
+- PDEBUG(ErrorF
+- ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
+- HF, VF, range->loH, range->loV, range->hiH, range->hiV));
+- break;
+- }
+- }
+- PDEBUG5(ErrorF
+- ("Done range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, range->loV,
+- range->hiH, range->hiV));
+-
+-}
+-
+-static void
+-XGISyncDDCMonitorRange(MonPtr monitor, MonitorRangePtr range)
+-{
+- int i;
+- if ((monitor == NULL) || (range == NULL)) {
+- return;
+- }
+-
+- for (i = 0; i < monitor->nHsync; i++) {
+- monitor->hsync[i].lo = range->loH;
+- monitor->hsync[i].hi = range->hiH;
+- }
+-
+- for (i = 0; i < monitor->nVrefresh; i++) {
+- monitor->vrefresh[i].lo = range->loV;
+- monitor->vrefresh[i].hi = range->hiV;
+- }
+-}
+-
+-static void
+-XGIDDCPreInit(ScrnInfoPtr pScrn)
+-{
+-
+- XGIPtr pXGI = XGIPTR(pScrn);
+- xf86MonPtr pMonitor = NULL;
+- xf86MonPtr pMonitorDVI = NULL;
+- Bool didddc2;
+-
+- static const char *ddcsstr =
+- "CRT%d DDC monitor info: ************************************\n";
+- static const char *ddcestr =
+- "End of CRT%d DDC monitor info ******************************\n";
+-
+- /* Now for something completely different: DDC.
+- * For 300 and 315/330 series, we provide our
+- * own functions (in order to probe CRT2 as well)
+- * If these fail, use the VBE.
+- * All other chipsets will use VBE. No need to re-invent
+- * the wheel there.
+- */
+-
+- pXGI->pVbe = NULL;
+- didddc2 = FALSE;
+-
+- /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */
+- if (IS_DUAL_HEAD(pXGI) && (!didddc2) && !IS_SECOND_HEAD(pXGI))
+- didddc2 = TRUE;
+-
+- if (!didddc2) {
+- /* If CRT1 is off or LCDA, skip DDC via VBE */
+- if ((pXGI->CRT1off) || (pXGI->VBFlags & CRT1_LCDA))
+- didddc2 = TRUE;
+- }
+-
+- /* Now (re-)load and initialize the DDC module */
+- if (!didddc2) {
+-
+- if (xf86LoadSubModule(pScrn, "ddc")) {
+-
+- xf86LoaderReqSymLists(ddcSymbols, NULL);
+-
+- pMonitor = XGIInternalDDC(pScrn, 0);
+- if (pMonitor == NULL) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Could not retrieve DDC data\n");
+- }
+-
+- if (pXGI->xgi_HwDevExt.jChipType == XG21) {
+- PDEBUG(ErrorF("Getting XG21 DVI EDID...\n"));
+- pMonitorDVI = XGIInternalDDC(pScrn, 1);
+- if (pMonitorDVI == NULL) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Could not retrieve DVI DDC data\n");
+- }
+-
+- if ((pMonitor == NULL) && (pMonitorDVI != NULL)) {
+- pMonitor = pMonitorDVI;
+- }
+- }
+-
+- }
+- }
+-
+- /* initialize */
+-
+- if (pMonitor) {
+- pXGI->CRT1Range.loH = 1000;
+- pXGI->CRT1Range.loV = 1000;
+- pXGI->CRT1Range.hiH = 0;
+- pXGI->CRT1Range.hiV = 0;
+- XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitor);
+- }
+- else {
+- pXGI->CRT1Range.loH = 0;
+- pXGI->CRT1Range.loV = 0;
+- pXGI->CRT1Range.hiH = 1000;
+- pXGI->CRT1Range.hiV = 1000;
+- }
+-
+- if (pMonitorDVI) {
+- pXGI->CRT2Range.loV = 1000;
+- pXGI->CRT2Range.loH = 1000;
+- pXGI->CRT2Range.hiH = 0;
+- pXGI->CRT2Range.hiV = 0;
+- XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorDVI);
+- }
+- else {
+- pXGI->CRT2Range.loH = 0;
+- pXGI->CRT2Range.loV = 0;
+- pXGI->CRT2Range.hiH = 1000;
+- pXGI->CRT2Range.hiV = 1000;
+- }
+-
+- if (pXGI->xgi_HwDevExt.jChipType == XG21) {
+- /* Mode range intersecting */
+- if (pXGI->CRT1Range.loH < pXGI->CRT2Range.loH) {
+- pXGI->CRT1Range.loH = pXGI->CRT2Range.loH;
+- }
+- if (pXGI->CRT1Range.loV < pXGI->CRT2Range.loV) {
+- pXGI->CRT1Range.loV = pXGI->CRT2Range.loV;
+- }
+- if (pXGI->CRT1Range.hiH > pXGI->CRT2Range.hiH) {
+- pXGI->CRT1Range.hiH = pXGI->CRT2Range.hiH;
+- }
+- if (pXGI->CRT1Range.hiV > pXGI->CRT2Range.hiV) {
+- pXGI->CRT1Range.hiV = pXGI->CRT2Range.hiV;
+- }
+- }
+-
+- if (pMonitor) {
+- XGISyncDDCMonitorRange(pScrn->monitor, &pXGI->CRT1Range);
+- }
+-
+- if (pScrn->monitor) {
+- pScrn->monitor->DDC = pMonitor;
+- }
+-
+- return;
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- pXGI->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
+- if (pXGI->CRT2pScrn->monitor) {
+- DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
+- memcpy(pXGI->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
+- pXGI->CRT2pScrn->monitor->DDC = NULL;
+- pXGI->CRT2pScrn->monitor->Modes = NULL;
+- tempm = pScrn->monitor->Modes;
+- while (tempm) {
+- if (!(newm = xalloc(sizeof(DisplayModeRec))))
+- break;
+- memcpy(newm, tempm, sizeof(DisplayModeRec));
+- if (!(newm->name = xalloc(strlen(tempm->name) + 1))) {
+- xfree(newm);
+- break;
+- }
+- strcpy(newm->name, tempm->name);
+- if (!pXGI->CRT2pScrn->monitor->Modes)
+- pXGI->CRT2pScrn->monitor->Modes = newm;
+- if (currentm) {
+- currentm->next = newm;
+- newm->prev = currentm;
+- }
+- currentm = newm;
+- tempm = tempm->next;
+- }
+-
+- if ((pMonitor = XGIInternalDDC(pXGI->CRT2pScrn, 1))) {
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2);
+- xf86PrintEDID(pMonitor);
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2);
+- xf86SetDDCproperties(pXGI->CRT2pScrn, pMonitor);
+-
+- pXGI->CRT2pScrn->monitor->DDC = pMonitor;
+-
+- /* use DDC data if no ranges in config file */
+- if (!pXGI->CRT2HSync) {
+- pXGI->CRT2pScrn->monitor->nHsync = 0;
+- }
+- if (!pXGI->CRT2VRefresh) {
+- pXGI->CRT2pScrn->monitor->nVrefresh = 0;
+- }
+- }
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "Failed to read DDC data for CRT2\n");
+- }
+- }
+- else {
+- XGIErrorLog(pScrn,
+- "Failed to allocate memory for CRT2 monitor, %s.\n",
+- mergeddisstr);
+- if (pXGI->CRT2pScrn)
+- xfree(pXGI->CRT2pScrn);
+- pXGI->CRT2pScrn = NULL;
+- pXGI->MergedFB = FALSE;
+- }
+- }
+-#endif
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1);
+- }
+-#endif
+-
+- /* end of DDC */
+-}
+-
+-#ifdef DEBUG5
+-static void
+-XGIDumpModePtr(DisplayModePtr mode)
+-{
+- if (mode == NULL)
+- return;
+-
+- ErrorF("Dump DisplayModePtr mode\n");
+- ErrorF("name = %s\n", mode->name);
+- /* ModeStatus status; */
+- ErrorF("type = %d\n", mode->type);
+- ErrorF("Clock = %d\n", mode->Clock);
+- ErrorF("HDisplay = %d\n", mode->HDisplay);
+- ErrorF("HSyncStart = %d\n", mode->HSyncStart);
+- ErrorF("HSyncEnd = %d\n", mode->HSyncEnd);
+- ErrorF("HTotal = %d\n", mode->HTotal);
+- ErrorF("HSkew = %d\n", mode->HSkew);
+- ErrorF("VDisplay = %d\n", mode->VDisplay);
+- ErrorF("VSyncStart = %d\n", mode->VSyncStart);
+- ErrorF("VSyncEnd = %d\n", mode->VSyncEnd);
+- ErrorF("VTotal = %d\n", mode->VTotal);
+- ErrorF("VScan = %d\n", mode->VScan);
+- ErrorF("Flags = %d\n", mode->Flags);
+-
+-
+- ErrorF("ClockIndex = %d\n", mode->ClockIndex);
+- ErrorF("SynthClock = %d\n", mode->SynthClock);
+- ErrorF("CrtcHDisplay = %d\n", mode->CrtcHDisplay);
+- ErrorF("CrtcHBlankStart = %d\n", mode->CrtcHBlankStart);
+- ErrorF("CrtcHSyncStart = %d\n", mode->CrtcHSyncStart);
+- ErrorF("CrtcHSyncEnd = %d\n", mode->CrtcHSyncEnd);
+- ErrorF("CrtcHBlankEnd = %d\n", mode->CrtcHBlankEnd);
+- ErrorF("CrtcHTotal = %d\n", mode->CrtcHTotal);
+- ErrorF("CrtcHSkew = %d\n", mode->CrtcHSkew);
+- ErrorF("CrtcVDisplay = %d\n", mode->CrtcVDisplay);
+- ErrorF("CrtcVBlankStart = %d\n", mode->CrtcVBlankStart);
+- ErrorF("CrtcVSyncStart = %d\n", mode->CrtcVSyncStart);
+- ErrorF("CrtcVSyncEnd = %d\n", mode->CrtcVSyncEnd);
+- ErrorF("CrtcVBlankEnd = %d\n", mode->CrtcVBlankEnd);
+- ErrorF("CrtcVTotal = %d\n", mode->CrtcVTotal);
+- ErrorF("CrtcHAdjusted = %s\n", (mode->CrtcHAdjusted) ? "TRUE" : "FALSE");
+- ErrorF("CrtcVAdjusted = %s\n", (mode->CrtcVAdjusted) ? "TRUE" : "FALSE");
+- ErrorF("PrivSize = %d\n", mode->PrivSize);
+- /* INT32 * Private; */
+- ErrorF("PrivFlags = %d\n", mode->PrivFlags);
+- ErrorF("HSync = %8.3f\n", mode->HSync);
+- ErrorF("VRefresh = %8.3f\n", mode->VRefresh);
+-}
+-#endif
+-
+-static void
+-XGIDumpMonPtr(MonPtr pMonitor)
+-{
+-#ifdef DEBUG5
+- int i;
+-# if 0
+- DisplayModePtr mode;
+-#endif
+-
+- ErrorF("XGIDumpMonPtr() ... \n");
+- if (pMonitor == NULL) {
+- ErrorF("pMonitor is NULL\n");
+- }
+-
+- ErrorF("id = %s, vendor = %s model = %s\n",
+- pMonitor->id, pMonitor->vendor, pMonitor->model);
+- ErrorF("nHsync = %d\n", pMonitor->nHsync);
+- ErrorF("nVrefresh = %d\n", pMonitor->nVrefresh);
+-
+- for (i = 0; i < MAX_HSYNC; i++) {
+- ErrorF("hsync[%d] = (%8.3f,%8.3f)\n", i, pMonitor->hsync[i].lo,
+- pMonitor->hsync[i].hi);
+- }
+-
+- for (i = 0; i < MAX_VREFRESH; i++) {
+- ErrorF("vrefresh[%d] = (%8.3f,%8.3f)\n", i, pMonitor->vrefresh[i].lo,
+- pMonitor->vrefresh[i].hi);
+- }
+-
+- ErrorF("widthmm = %d, heightmm = %d\n",
+- pMonitor->widthmm, pMonitor->heightmm);
+- ErrorF("options = %p, DDC = %p\n", pMonitor->options, pMonitor->DDC);
+-# if 0
+- mode = pMonitor->Modes;
+- while (1) {
+- XGIDumpModePtr(mode);
+- if (mode == pMonitor->Last) {
+- break;
+- }
+- mode = mode->next;
+- }
+-# endif
+-#endif /* DEBUG5 */
+-}
+-
+-/* Mandatory */
+-static Bool
+-XGIPreInit(ScrnInfoPtr pScrn, int flags)
+-{
+- XGIPtr pXGI;
+- MessageType from;
+- unsigned long int i;
+- int temp;
+- ClockRangePtr clockRanges;
+- int pix24flags;
+- int fd;
+- struct fb_fix_screeninfo fix;
+- XGIEntPtr pXGIEnt = NULL;
+- size_t memreq;
+-
+-#if defined(XGIMERGED) || defined(XGIDUALHEAD)
+- DisplayModePtr first, p, n;
+-#endif
+- unsigned char srlockReg, crlockReg;
+- vbeInfoPtr pVbe;
+-
+- /****************** Code Start ***********************/
+-
+- ErrorF("XGIPreInit\n");
+-
+- if (flags & PROBE_DETECT) {
+- if (xf86LoadSubModule(pScrn, "vbe")) {
+- int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
+-
+- if ((pVbe = VBEExtendedInit(NULL, index, 0))) {
+- ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
+- vbeFree(pVbe);
+- }
+- }
+- return TRUE;
+- }
+-
+- /*
+- * Note: This function is only called once at server startup, and
+- * not at the start of each server generation. This means that
+- * only things that are persistent across server generations can
+- * be initialised here. xf86Screens[] is the array of all screens,
+- * (pScrn is a pointer to one of these). Privates allocated using
+- * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
+- * for data that must persist across server generations.
+- *
+- * Per-generation data should be allocated with
+- * AllocateScreenPrivateIndex() from the ScreenInit() function.
+- */
+-
+- /* Check the number of entities, and fail if it isn't one. */
+- if (pScrn->numEntities != 1) {
+- XGIErrorLog(pScrn, "Number of entities is not 1\n");
+- return FALSE;
+- }
+-
+- /* The vgahw module should be loaded here when needed */
+- if (!xf86LoadSubModule(pScrn, "vgahw")) {
+- XGIErrorLog(pScrn, "Could not load vgahw module\n");
+- return FALSE;
+- }
+-
+- xf86LoaderReqSymLists(vgahwSymbols, NULL);
+-
+- /* Due to the liberal license terms this is needed for
+- * keeping the copyright notice readable and intact in
+- * binary distributions. Removing this is a copyright
+- * infringement. Please read the license terms above.
+- */
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "XGI driver (%s)\n", XGI_RELEASE_DATE);
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n");
+-
+- /* Allocate a vgaHWRec */
+- if (!vgaHWGetHWRec(pScrn)) {
+- XGIErrorLog(pScrn, "Could not allocate VGA private\n");
+- return FALSE;
+- }
+-
+- /* Allocate the XGIRec driverPrivate */
+- pXGI = XGIGetRec(pScrn);
+- if (pXGI == NULL) {
+- XGIErrorLog(pScrn, "Could not allocate memory for pXGI private\n");
+- return FALSE;
+- }
+-
+- pXGI->IODBase = pScrn->domainIOBase;
+-
+-
+- /* Get the entity, and make sure it is PCI. */
+- pXGI->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+- if (pXGI->pEnt->location.type != BUS_PCI) {
+- XGIErrorLog(pScrn, "Entity's bus type is not PCI\n");
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+-#ifdef XGIDUALHEAD
+- /* Allocate an entity private if necessary */
+- if (xf86IsEntityShared(pScrn->entityList[0])) {
+- pXGIEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+- XGIEntityIndex)->ptr;
+- pXGI->entityPrivate = pXGIEnt;
+-
+- /* If something went wrong, quit here */
+- if ((pXGIEnt->DisableDual) || (pXGIEnt->ErrorAfterFirst)) {
+- XGIErrorLog(pScrn,
+- "First head encountered fatal error, can't continue\n");
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- }
+-#endif
+-
+- /* Find the PCI info for this screen */
+-#ifndef XSERVER_LIBPCIACCESS
+- pXGI->PciInfo = xf86GetPciInfoForEntity(pXGI->pEnt->index);
+- pXGI->PciTag = pciTag(pXGI->PciInfo->bus, pXGI->PciInfo->device,
+- pXGI->PciInfo->func);
+-#endif
+-
+- pXGI->Primary = xf86IsPrimaryPci(pXGI->PciInfo);
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "This adapter is %s display adapter\n",
+- (pXGI->Primary ? "primary" : "secondary"));
+-
+- if (pXGI->Primary) {
+- VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
+- if (!vgaHWMapMem(pScrn)) {
+- XGIErrorLog(pScrn, "Could not map VGA memory\n");
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- }
+- vgaHWGetIOBase(VGAHWPTR(pScrn));
+-
+- /* We "patch" the PIOOffset inside vgaHW in order to force
+- * the vgaHW module to use our relocated i/o ports.
+- */
+- VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
+-#ifdef XSERVER_LIBPCIACCESS
+- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+-#else
+- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+-#endif
+- ;
+-
+- pXGI->pInt = NULL;
+- if (!pXGI->Primary) {
+-#if !defined(__alpha__)
+-#if !defined(__powerpc__)
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Initializing display adapter through int10\n");
+-
+- if (xf86LoadSubModule(pScrn, "int10")) {
+- xf86LoaderReqSymLists(int10Symbols, NULL);
+- pXGI->pInt = xf86InitInt10(pXGI->pEnt->index);
+- }
+- else {
+- XGIErrorLog(pScrn, "Could not load int10 module\n");
+- }
+-#endif /* !defined(__powerpc__) */
+-#endif /* !defined(__alpha__) */
+- }
+-
+- xf86SetOperatingState(resVgaMem, pXGI->pEnt->index, ResUnusedOpr);
+-
+- /* Operations for which memory access is required */
+- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+- /* Operations for which I/O access is required */
+- pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+-
+- /* The ramdac module should be loaded here when needed */
+- if (!xf86LoadSubModule(pScrn, "ramdac")) {
+- XGIErrorLog(pScrn, "Could not load ramdac module\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- xf86LoaderReqSymLists(ramdacSymbols, NULL);
+-
+- /* Set pScrn->monitor */
+- pScrn->monitor = pScrn->confScreen->monitor;
+-
+- /*
+- * Set the Chipset and ChipRev, allowing config file entries to
+- * override. DANGEROUS!
+- */
+- if (pXGI->pEnt->device->chipset && *pXGI->pEnt->device->chipset) {
+- PDEBUG(ErrorF(" --- Chipset 1 \n"));
+- pScrn->chipset = pXGI->pEnt->device->chipset;
+- pXGI->Chipset = xf86StringToToken(XGIChipsets, pScrn->chipset);
+- from = X_CONFIG;
+- }
+- else if (pXGI->pEnt->device->chipID >= 0) {
+- PDEBUG(ErrorF(" --- Chipset 2 \n"));
+- pXGI->Chipset = pXGI->pEnt->device->chipID;
+- pScrn->chipset =
+- (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
+-
+- from = X_CONFIG;
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+- pXGI->Chipset);
+- }
+- else {
+- PDEBUG(ErrorF(" --- Chipset 3 \n"));
+- from = X_PROBED;
+- pXGI->Chipset = DEVICE_ID(pXGI->PciInfo);
+- pScrn->chipset =
+- (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
+- }
+- if (pXGI->pEnt->device->chipRev >= 0) {
+- pXGI->ChipRev = pXGI->pEnt->device->chipRev;
+- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+- pXGI->ChipRev);
+- }
+- else {
+- pXGI->ChipRev = CHIP_REVISION(pXGI->PciInfo);
+- }
+- pXGI->xgi_HwDevExt.jChipRevision = pXGI->ChipRev;
+-
+- PDEBUG(ErrorF(" --- Chipset : %s \n", pScrn->chipset));
+-
+-
+- /*
+- * This shouldn't happen because such problems should be caught in
+- * XGIProbe(), but check it just in case.
+- */
+- if (pScrn->chipset == NULL) {
+- XGIErrorLog(pScrn, "ChipID 0x%04X is not recognised\n",
+- pXGI->Chipset);
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- if (pXGI->Chipset < 0) {
+- XGIErrorLog(pScrn, "Chipset \"%s\" is not recognised\n",
+- pScrn->chipset);
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- /* Determine chipset and VGA engine type */
+- pXGI->ChipFlags = 0;
+- pXGI->XGI_SD_Flags = 0;
+-
+- switch (pXGI->Chipset) {
+- case PCI_CHIP_XGIXG40:
+- case PCI_CHIP_XGIXG20:
+- pXGI->xgi_HwDevExt.jChipType = XG40;
+- pXGI->myCR63 = 0x63;
+- pXGI->mmioSize = 64;
+- break;
+- default:
+- /* This driver currently only supports V3XE, V3XT, V5, V8 (all of
+- * which are XG40 chips) and Z7 (which is XG20).
+- */
+- if (pXGI->pInt) {
+- xf86FreeInt10(pXGI->pInt);
+- }
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+-/* load frame_buffer */
+-
+- FbDevExist = FALSE;
+- if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
+- if ((fd = open("/dev/fb", 'r')) != -1) {
+- PDEBUG(ErrorF("--- open /dev/fb.... \n"));
+- ioctl(fd, FBIOGET_FSCREENINFO, &fix);
+- if (fix.accel == FB_ACCEL_XGI_GLAMOUR) {
+- PDEBUG(ErrorF("--- fix.accel.... \n"));
+- FbDevExist = TRUE;
+- }
+- else
+- PDEBUG(ErrorF("--- no fix.accel.... 0x%08lx \n", fix.accel));
+- close(fd);
+- }
+- }
+-
+-
+- /*
+- * The first thing we should figure out is the depth, bpp, etc.
+- * Additionally, determine the size of the HWCursor memory area.
+- */
+- pXGI->CursorSize = 4096;
+- pix24flags = Support32bppFb;
+-
+-#ifdef XGIDUALHEAD
+- /* In case of Dual Head, we need to determine if we are the "master" head or
+- * the "slave" head. In order to do that, we set PrimInit to DONE in the
+- * shared entity at the end of the first initialization. The second
+- * initialization then knows that some things have already been done. THIS
+- * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
+- */
+-
+- if (xf86IsEntityShared(pScrn->entityList[0])) {
+- if (pXGIEnt->lastInstance > 0) {
+- if (!xf86IsPrimInitDone(pScrn->entityList[0])) {
+- /* First Head (always CRT2) */
+- pXGI->SecondHead = FALSE;
+- pXGIEnt->pScrn_1 = pScrn;
+- pXGIEnt->CRT2ModeNo = -1;
+- pXGIEnt->CRT2ModeSet = FALSE;
+- pXGI->DualHeadMode = TRUE;
+- pXGIEnt->DisableDual = FALSE;
+- pXGIEnt->BIOS = NULL;
+- pXGIEnt->XGI_Pr = NULL;
+- pXGIEnt->RenderAccelArray = NULL;
+- }
+- else {
+- /* Second Head (always CRT1) */
+- pXGI->SecondHead = TRUE;
+- pXGIEnt->pScrn_2 = pScrn;
+- pXGI->DualHeadMode = TRUE;
+- }
+- }
+- else {
+- /* Only one screen in config file - disable dual head mode */
+- pXGI->SecondHead = FALSE;
+- pXGI->DualHeadMode = FALSE;
+- pXGIEnt->DisableDual = TRUE;
+- }
+- }
+- else {
+- /* Entity is not shared - disable dual head mode */
+- pXGI->SecondHead = FALSE;
+- pXGI->DualHeadMode = FALSE;
+- }
+-#endif
+-
+- /* Allocate VB_DEVICE_INFO (for mode switching code) and initialize it */
+- pXGI->XGI_Pr = NULL;
+- if (pXGIEnt && pXGIEnt->XGI_Pr) {
+- pXGI->XGI_Pr = pXGIEnt->XGI_Pr;
+- }
+-
+- if (!pXGI->XGI_Pr) {
+- if (!(pXGI->XGI_Pr = xnfcalloc(sizeof(VB_DEVICE_INFO), 1))) {
+- XGIErrorLog(pScrn,
+- "Could not allocate memory for XGI_Pr private\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- if (pXGIEnt)
+- pXGIEnt->XGI_Pr = pXGI->XGI_Pr;
+-
+- memset(pXGI->XGI_Pr, 0, sizeof(VB_DEVICE_INFO));
+- }
+-
+- /* Get our relocated IO registers */
+- pXGI->RelIO = (XGIIOADDRESS) (pXGI->IODBase |
+-#ifdef XSERVER_LIBPCIACCESS
+- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+-#else
+- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+-#endif
+- );
+- pXGI->xgi_HwDevExt.pjIOAddress = (XGIIOADDRESS) (pXGI->RelIO + 0x30);
+- xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
+- (unsigned long) pXGI->RelIO);
+-
+- if (!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
+- XGIErrorLog(pScrn, "xf86SetDepthBpp() error\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- /* Check that the returned depth is one we support */
+- temp = 0;
+- switch (pScrn->depth) {
+- case 8:
+- case 16:
+- case 24:
+-#if !defined(__powerpc__)
+- case 15:
+-#endif
+- break;
+- default:
+- temp = 1;
+- }
+-
+- if (temp) {
+- XGIErrorLog(pScrn,
+- "Given color depth (%d) is not supported by this driver/chipset\n",
+- pScrn->depth);
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- xf86PrintDepthBpp(pScrn);
+-
+- /* Get the depth24 pixmap format */
+- if (pScrn->depth == 24 && pix24bpp == 0) {
+- pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+- }
+-
+- /*
+- * This must happen after pScrn->display has been set because
+- * xf86SetWeight references it.
+- */
+- if (pScrn->depth > 8) {
+- /* The defaults are OK for us */
+- rgb zeros = { 0, 0, 0 };
+-
+- if (!xf86SetWeight(pScrn, zeros, zeros)) {
+- XGIErrorLog(pScrn, "xf86SetWeight() error\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- else {
+- Bool ret = FALSE;
+- switch (pScrn->depth) {
+- case 15:
+- if ((pScrn->weight.red != 5) ||
+- (pScrn->weight.green != 5) || (pScrn->weight.blue != 5))
+- ret = TRUE;
+- break;
+- case 16:
+- if ((pScrn->weight.red != 5) ||
+- (pScrn->weight.green != 6) || (pScrn->weight.blue != 5))
+- ret = TRUE;
+- break;
+- case 24:
+- if ((pScrn->weight.red != 8) ||
+- (pScrn->weight.green != 8) || (pScrn->weight.blue != 8))
+- ret = TRUE;
+- break;
+- }
+- if (ret) {
+- XGIErrorLog(pScrn,
+- "RGB weight %d%d%d at depth %d not supported by hardware\n",
+- (int) pScrn->weight.red,
+- (int) pScrn->weight.green,
+- (int) pScrn->weight.blue, pScrn->depth);
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- }
+- }
+-
+- /* Set the current layout parameters */
+- pXGI->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+- pXGI->CurrentLayout.depth = pScrn->depth;
+- /* (Inside this function, we can use pScrn's contents anyway) */
+-
+- if (!xf86SetDefaultVisual(pScrn, -1)) {
+- XGIErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- else {
+- /* We don't support DirectColor at > 8bpp */
+- if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+- XGIErrorLog(pScrn,
+- "Given default visual (%s) is not supported at depth %d\n",
+- xf86GetVisualName(pScrn->defaultVisual),
+- pScrn->depth);
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- }
+-
+- /* Due to palette & timing problems we don't support 8bpp in DHM */
+- if ((IS_DUAL_HEAD(pXGI)) && (pScrn->bitsPerPixel == 8)) {
+- XGIErrorLog(pScrn,
+- "Color depth 8 not supported in Dual Head mode.\n");
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- /*
+- * The cmap layer needs this to be initialised.
+- */
+- {
+- Gamma zeros = { 0.0, 0.0, 0.0 };
+-
+- if (!xf86SetGamma(pScrn, zeros)) {
+- XGIErrorLog(pScrn, "xf86SetGamma() error\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- }
+-
+- /* We use a programamble clock */
+- pScrn->progClock = TRUE;
+-
+- /* Set the bits per RGB for 8bpp mode */
+- if (pScrn->depth == 8) {
+- pScrn->rgbBits = 6;
+- }
+-
+- from = X_DEFAULT;
+-
+- /* Unlock registers */
+- xgiSaveUnlockExtRegisterLock(pXGI, &srlockReg, &crlockReg);
+-
+- /* Read BIOS for 300 and 315/330 series customization */
+- pXGI->xgi_HwDevExt.pjVirtualRomBase = NULL;
+- pXGI->BIOS = NULL;
+- pXGI->xgi_HwDevExt.UseROM = FALSE;
+-
+- /* Evaluate options */
+- xgiOptions(pScrn);
+-
+-#ifdef XGIMERGED
+- /* Due to palette & timing problems we don't support 8bpp in MFBM */
+- if ((pXGI->MergedFB) && (pScrn->bitsPerPixel == 8)) {
+- XGIErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n",
+- mergeddisstr);
+- pXGI->MergedFB = pXGI->MergedFBAuto = FALSE;
+- }
+-#endif
+-
+- /* Do basic configuration */
+-
+- XGISetup(pScrn);
+-
+- from = X_PROBED;
+-#ifdef XSERVER_LIBPCIACCESS
+- pXGI->FbAddress = pXGI->PciInfo->regions[0].base_addr & 0xFFFFFFF0;
+-#else
+- if (pXGI->pEnt->device->MemBase != 0) {
+- /*
+- * XXX Should check that the config file value matches one of the
+- * PCI base address values.
+- */
+- pXGI->FbAddress = pXGI->pEnt->device->MemBase;
+- from = X_CONFIG;
+- }
+- else {
+- pXGI->FbAddress = pXGI->PciInfo->memBase[0] & 0xFFFFFFF0;
+- }
+-#endif
+-
+- pXGI->realFbAddress = pXGI->FbAddress;
+-
+- xf86DrvMsg(pScrn->scrnIndex, from,
+- "%sinear framebuffer at 0x%lX\n",
+- IS_DUAL_HEAD(pXGI) ? "Global l" : "L",
+- (unsigned long) pXGI->FbAddress);
+-
+-#ifdef XSERVER_LIBPCIACCESS
+- pXGI->IOAddress = pXGI->PciInfo->regions[1].base_addr & 0xFFFFFFF0;
+-#else
+- if (pXGI->pEnt->device->IOBase != 0) {
+- /*
+- * XXX Should check that the config file value matches one of the
+- * PCI base address values.
+- */
+- pXGI->IOAddress = pXGI->pEnt->device->IOBase;
+- from = X_CONFIG;
+- }
+- else {
+- pXGI->IOAddress = pXGI->PciInfo->memBase[1] & 0xFFFFFFF0;
+- }
+-#endif
+-
+- xf86DrvMsg(pScrn->scrnIndex, from,
+- "MMIO registers at 0x%lX (size %ldK)\n",
+- (unsigned long) pXGI->IOAddress, pXGI->mmioSize);
+- pXGI->xgi_HwDevExt.bIntegratedMMEnabled = TRUE;
+-
+- /* Register the PCI-assigned resources. */
+- if (xf86RegisterResources(pXGI->pEnt->index, NULL, ResExclusive)) {
+- XGIErrorLog(pScrn,
+- "xf86RegisterResources() found resource conflicts\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- from = X_PROBED;
+- if (pXGI->pEnt->device->videoRam != 0) {
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Option \"VideoRAM\" ignored\n");
+- }
+-
+- xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam);
+-
+- pXGI->FbMapSize = pXGI->availMem = pScrn->videoRam * 1024;
+- pXGI->xgi_HwDevExt.ulVideoMemorySize = pScrn->videoRam * 1024;
+- pXGI->xgi_HwDevExt.bSkipDramSizing = TRUE;
+-
+- /* Calculate real availMem according to Accel/TurboQueue and
+- * HWCursur setting.
+- *
+- * TQ is max 64KiB. Reduce the available memory by 64KiB, and locate the
+- * TQ at the beginning of this last 64KiB block. This is done even when
+- * using the HWCursor, because the cursor only takes 2KiB and the queue
+- * does not seem to last that far anyway.
+- *
+- * The TQ must be located at 32KB boundaries.
+- */
+- if (pScrn->videoRam < 3072) {
+- if (pXGI->TurboQueue) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
+- pXGI->TurboQueue = FALSE;
+- }
+- }
+-
+- pXGI->availMem -= (pXGI->TurboQueue) ? (64 * 1024) : pXGI->CursorSize;
+-
+-
+- /* In dual head mode, we share availMem equally - so align it
+- * to 8KB; this way, the address of the FB of the second
+- * head is aligned to 4KB for mapping.
+- *
+- * Check MaxXFBMem setting. Since DRI is not supported in dual head
+- * mode, we don't need the MaxXFBMem setting.
+- */
+- if (IS_DUAL_HEAD(pXGI)) {
+- if (pXGI->maxxfbmem) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
+- }
+-
+- pXGI->availMem &= 0xFFFFE000;
+- pXGI->maxxfbmem = pXGI->availMem;
+- }
+- else if (pXGI->maxxfbmem) {
+- if (pXGI->maxxfbmem > pXGI->availMem) {
+- if (pXGI->xgifbMem) {
+- pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Invalid MaxXFBMem setting. Using xgifb heap start information\n");
+- }
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
+- pXGI->maxxfbmem = pXGI->availMem;
+- }
+- }
+- else if (pXGI->xgifbMem) {
+- if (pXGI->maxxfbmem > pXGI->xgifbMem * 1024) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "MaxXFBMem beyond xgifb heap start. Using xgifb heap start\n");
+- pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
+- }
+- }
+- }
+- else if (pXGI->xgifbMem) {
+- pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
+- }
+- else
+- pXGI->maxxfbmem = pXGI->availMem;
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
+- pXGI->maxxfbmem / 1024);
+-
+- pXGI->CRT1off = -1;
+-
+- /* Detect video bridge and sense TV/VGA2 */
+- XGIVGAPreInit(pScrn);
+-
+- /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */
+- XGICRT1PreInit(pScrn);
+-
+- /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */
+- XGILCDPreInit(pScrn);
+-
+- /* LCDA only supported under these conditions: */
+- if (pXGI->ForceCRT1Type == CRT1_LCDA) {
+- if (!
+- (pXGI->XGI_Pr->
+- VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV |
+- VB_XGI302LV))) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Chipset/Video bridge does not support LCD-via-CRT1\n");
+- pXGI->ForceCRT1Type = CRT1_VGA;
+- }
+- else if (!(pXGI->VBFlags & CRT2_LCD)) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "No digitally connected LCD panel found, LCD-via-CRT1 "
+- "disabled\n");
+- pXGI->ForceCRT1Type = CRT1_VGA;
+- }
+- }
+-
+- /* Setup SD flags */
+- pXGI->XGI_SD_Flags |= XGI_SD_ADDLSUPFLAG;
+-
+- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTV;
+- }
+-
+-#ifdef ENABLE_YPBPR
+- if (pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B)) {
+- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTHIVISION;
+- }
+-#endif
+-
+-#ifdef TWDEBUG /* @@@ TEST @@@ */
+- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTYPBPRAR;
+- xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n");
+-#endif
+-
+- /* Detect CRT2-TV and PAL/NTSC mode */
+- XGITVPreInit(pScrn);
+-
+- /* Detect CRT2-VGA */
+- XGICRT2PreInit(pScrn);
+- PDEBUG(ErrorF("3496 pXGI->VBFlags =%x\n", pXGI->VBFlags));
+-
+- if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR)) {
+- if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_YPBPR)) {
+- pXGI->ForceTVType = -1;
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "YPbPr TV output not supported\n");
+- }
+- }
+-
+- if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTHIVISION)) {
+- if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_HIVISION)) {
+- pXGI->ForceTVType = -1;
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "HiVision TV output not supported\n");
+- }
+- }
+-
+- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+- pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
+- }
+- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTVPOS;
+- }
+- if (pXGI->XGI_Pr->
+- VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
+- pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTSCART | XGI_SD_SUPPORTVGA2);
+- }
+-
+- if ((pXGI->XGI_Pr->
+- VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | VB_XGI302LV))
+- && (pXGI->VBFlags & CRT2_LCD)) {
+- pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTLCDA;
+- }
+-
+- pXGI->VBFlags |= pXGI->ForceCRT1Type;
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "SDFlags %lx\n", pXGI->XGI_SD_Flags);
+-#endif
+-
+-
+- if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) {
+- xf86DrvMsg(pScrn->scrnIndex, pXGI->CRT1gammaGiven ? X_CONFIG : X_INFO,
+- "CRT1 gamma correction is %s\n",
+- pXGI->CRT1gamma ? "enabled" : "disabled");
+- }
+-
+- /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART, HIVISION, YPBPR) */
+- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+- if (pXGI->ForceTVType != -1) {
+- pXGI->VBFlags &= ~(TV_INTERFACE);
+- pXGI->VBFlags |= pXGI->ForceTVType;
+- if (pXGI->VBFlags & TV_YPBPR) {
+- pXGI->VBFlags &= ~(TV_STANDARD);
+- pXGI->VBFlags &= ~(TV_YPBPRAR);
+- pXGI->VBFlags |= pXGI->ForceYPbPrType;
+- pXGI->VBFlags |= pXGI->ForceYPbPrAR;
+- }
+- }
+- }
+-
+- /* Check if CRT1 used or needed. There are three cases where this can
+- * happen:
+- * - No video bridge.
+- * - No CRT2 output.
+- * - Depth = 8 and bridge=LVDS|301B-DH
+- * - LCDA
+- */
+- if (((pXGI->XGI_Pr->VBType & VB_XGIVB) == 0)
+- || ((pXGI->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)) == 0)
+- || ((pScrn->bitsPerPixel == 8)
+- && (pXGI->XGI_Pr->VBType & VB_XGI301LV302LV))
+- || (pXGI->VBFlags & CRT1_LCDA)) {
+- pXGI->CRT1off = 0;
+- }
+-
+-
+- /* Handle TVStandard option */
+- if ((pXGI->NonDefaultPAL != -1) || (pXGI->NonDefaultNTSC != -1)) {
+- if (!(pXGI->XGI_Pr->VBType & VB_XGIVB)) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "PALM, PALN and NTSCJ not supported on this hardware\n");
+- pXGI->NonDefaultPAL = pXGI->NonDefaultNTSC = -1;
+- pXGI->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ);
+- pXGI->XGI_SD_Flags &=
+- ~(XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
+- }
+- }
+-
+-#ifdef XGI_CP
+- XGI_CP_DRIVER_RECONFIGOPT
+-#endif
+- /* Do some MergedFB mode initialisation */
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- pXGI->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
+- if (!pXGI->CRT2pScrn) {
+- XGIErrorLog(pScrn,
+- "Failed to allocate memory for 2nd pScrn, %s\n",
+- mergeddisstr);
+- pXGI->MergedFB = FALSE;
+- }
+- else {
+- memcpy(pXGI->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
+- }
+- }
+-#endif
+- PDEBUG(ErrorF("3674 pXGI->VBFlags =%x\n", pXGI->VBFlags));
+-
+- /* Determine CRT1<>CRT2 mode
+- * Note: When using VESA or if the bridge is in slavemode, display
+- * is ALWAYS in MIRROR_MODE!
+- * This requires extra checks in functions using this flag!
+- * (see xgi_video.c for example)
+- */
+- if (pXGI->VBFlags & DISPTYPE_DISP2) {
+- if (pXGI->CRT1off) { /* CRT2 only ------------------------------- */
+- if (IS_DUAL_HEAD(pXGI)) {
+- XGIErrorLog(pScrn,
+- "CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
+- if (pXGIEnt)
+- pXGIEnt->DisableDual = TRUE;
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- pXGI->pInt = NULL;
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- if (pXGI->MergedFBAuto) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1,
+- mergeddisstr);
+- }
+- else {
+- XGIErrorLog(pScrn, mergednocrt1, mergeddisstr);
+- }
+- if (pXGI->CRT2pScrn)
+- xfree(pXGI->CRT2pScrn);
+- pXGI->CRT2pScrn = NULL;
+- pXGI->MergedFB = FALSE;
+- }
+-#endif
+- pXGI->VBFlags |= VB_DISPMODE_SINGLE;
+- }
+- /* CRT1 and CRT2 - mirror or dual head ----- */
+- else if (IS_DUAL_HEAD(pXGI)) {
+- pXGI->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
+- if (pXGIEnt)
+- pXGIEnt->DisableDual = FALSE;
+- }
+- else
+- pXGI->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
+- }
+- else { /* CRT1 only ------------------------------- */
+- if (IS_DUAL_HEAD(pXGI)) {
+- XGIErrorLog(pScrn,
+- "No CRT2 output selected or no bridge detected. "
+- "Dual Head mode can't initialize.\n");
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- pXGI->pInt = NULL;
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- if (pXGI->MergedFBAuto) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2,
+- mergeddisstr);
+- }
+- else {
+- XGIErrorLog(pScrn, mergednocrt2, mergeddisstr);
+- }
+- if (pXGI->CRT2pScrn)
+- xfree(pXGI->CRT2pScrn);
+- pXGI->CRT2pScrn = NULL;
+- pXGI->MergedFB = FALSE;
+- }
+-#endif
+- PDEBUG(ErrorF("3782 pXGI->VBFlags =%x\n", pXGI->VBFlags));
+- pXGI->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
+- }
+-
+- /* Init Ptrs for Save/Restore functions and calc MaxClock */
+- XGIDACPreInit(pScrn);
+-
+- /* ********** end of VBFlags setup ********** */
+-
+- /* VBFlags are initialized now. Back them up for SlaveMode modes. */
+- pXGI->VBFlags_backup = pXGI->VBFlags;
+-
+- /* Find out about paneldelaycompensation and evaluate option */
+- if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
+-
+- }
+-
+- /* In dual head mode, both heads (currently) share the maxxfbmem equally.
+- * If memory sharing is done differently, the following has to be changed;
+- * the other modules (eg. accel and Xv) use dhmOffset for hardware
+- * pointer settings relative to VideoRAM start and won't need to be changed.
+- */
+- if (IS_DUAL_HEAD(pXGI)) {
+- if (!IS_SECOND_HEAD(pXGI)) {
+- /* ===== First head (always CRT2) ===== */
+- /* We use only half of the memory available */
+- pXGI->maxxfbmem /= 2;
+- /* Initialize dhmOffset */
+- pXGI->dhmOffset = 0;
+- /* Copy framebuffer addresses & sizes to entity */
+- pXGIEnt->masterFbAddress = pXGI->FbAddress;
+- pXGIEnt->masterFbSize = pXGI->maxxfbmem;
+- pXGIEnt->slaveFbAddress = pXGI->FbAddress + pXGI->maxxfbmem;
+- pXGIEnt->slaveFbSize = pXGI->maxxfbmem;
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "%ldKB video RAM at 0x%lx available for master head (CRT2)\n",
+- pXGI->maxxfbmem / 1024, pXGI->FbAddress);
+- }
+- else {
+- /* ===== Second head (always CRT1) ===== */
+- /* We use only half of the memory available */
+- pXGI->maxxfbmem /= 2;
+- /* Adapt FBAddress */
+- pXGI->FbAddress += pXGI->maxxfbmem;
+- /* Initialize dhmOffset */
+- pXGI->dhmOffset = pXGI->availMem - pXGI->maxxfbmem;
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n",
+- pXGI->maxxfbmem / 1024, pXGI->FbAddress);
+- }
+- }
+- else
+- pXGI->dhmOffset = 0;
+-
+- /* Note: Do not use availMem for anything from now. Use
+- * maxxfbmem instead. (availMem does not take dual head
+- * mode into account.)
+- */
+-
+-#if !defined(__powerpc__)
+- /* Now load and initialize VBE module. */
+- if (xf86LoadSubModule(pScrn, "vbe")) {
+- xf86LoaderReqSymLists(vbeSymbols, NULL);
+- pXGI->pVbe = VBEExtendedInit(pXGI->pInt, pXGI->pEnt->index,
+- SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+- if (!pXGI->pVbe) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Could not initialize VBE module for DDC\n");
+- }
+- }
+- else {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Could not load VBE module\n");
+- }
+-
+- XGIDDCPreInit(pScrn);
+-#endif
+- /* From here, we mainly deal with clocks and modes */
+-
+- /* Set the min pixel clock */
+- pXGI->MinClock = 5000;
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+- pXGI->MinClock / 1000);
+-
+- from = X_PROBED;
+- /*
+- * If the user has specified ramdac speed in the XF86Config
+- * file, we respect that setting.
+- */
+- if (pXGI->pEnt->device->dacSpeeds[0]) {
+- int speed = 0;
+- switch (pScrn->bitsPerPixel) {
+- case 8:
+- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP8];
+- break;
+- case 16:
+- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP16];
+- break;
+- case 24:
+- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP24];
+- break;
+- case 32:
+- speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP32];
+- break;
+- }
+- if (speed == 0)
+- pXGI->MaxClock = pXGI->pEnt->device->dacSpeeds[0];
+- else
+- pXGI->MaxClock = speed;
+- from = X_CONFIG;
+- }
+- xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+- pXGI->MaxClock / 1000);
+-
+- /*
+- * Setup the ClockRanges, which describe what clock ranges are available,
+- * and what sort of modes they can be used for.
+- */
+- clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+- clockRanges->next = NULL;
+- clockRanges->minClock = pXGI->MinClock;
+- clockRanges->maxClock = pXGI->MaxClock;
+- clockRanges->clockIndex = -1; /* programmable */
+- clockRanges->interlaceAllowed = TRUE;
+- clockRanges->doubleScanAllowed = TRUE;
+-
+- /*
+- * xf86ValidateModes will check that the mode HTotal and VTotal values
+- * don't exceed the chipset's limit if pScrn->maxHValue and
+- * pScrn->maxVValue are set. Since our XGIValidMode() already takes
+- * care of this, we don't worry about setting them here.
+- */
+-
+- /* Select valid modes from those available */
+-#ifdef XGIMERGED
+- pXGI->CheckForCRT2 = FALSE;
+-#endif
+- XGIDumpMonPtr(pScrn->monitor);
+- i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048, /* min / max pitch */
+- pScrn->bitsPerPixel * 8, 128, 2048, /* min / max height */
+- pScrn->display->virtualX,
+- pScrn->display->virtualY,
+- pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
+-
+- if (i == -1) {
+- XGIErrorLog(pScrn, "xf86ValidateModes() error\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- /* Check the virtual screen against the available memory */
+-
+- memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8))
+- * pScrn->virtualY;
+-
+- if (memreq > pXGI->maxxfbmem) {
+- XGIErrorLog(pScrn,
+- "Virtual screen too big for memory; %ldK needed, %ldK available\n",
+- memreq / 1024, pXGI->maxxfbmem / 1024);
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- pXGI->pInt = NULL;
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- else if (pXGI->loadDRI && !IS_DUAL_HEAD(pXGI)) {
+- pXGI->maxxfbmem = memreq;
+- pXGI->DRIheapstart = pXGI->DRIheapend = 0;
+-
+- if (pXGI->maxxfbmem == pXGI->availMem) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "All video memory used for framebuffer. DRI will be disabled.\n");
+- pXGI->loadDRI = FALSE;
+- }
+- else {
+- pXGI->DRIheapstart = pXGI->maxxfbmem;
+- pXGI->DRIheapend = pXGI->availMem;
+- }
+- }
+-
+-
+- /* Dual Head:
+- * -) Go through mode list and mark all those modes as bad,
+- * which are unsuitable for dual head mode.
+- * -) Find the highest used pixelclock on the master head.
+- */
+- if (IS_DUAL_HEAD(pXGI) && !IS_SECOND_HEAD(pXGI)) {
+- pXGIEnt->maxUsedClock = 0;
+-
+- if ((p = first = pScrn->modes)) {
+- do {
+- n = p->next;
+-
+- /* Modes that require the bridge to operate in SlaveMode
+- * are not suitable for Dual Head mode.
+- */
+-
+- /* Search for the highest clock on first head in order to calculate
+- * max clock for second head (CRT1)
+- */
+- if ((p->status == MODE_OK)
+- && (p->Clock > pXGIEnt->maxUsedClock)) {
+- pXGIEnt->maxUsedClock = p->Clock;
+- }
+-
+- p = n;
+-
+- } while (p != NULL && p != first);
+- }
+- }
+-
+- /* Prune the modes marked as invalid */
+- xf86PruneDriverModes(pScrn);
+-
+- if (i == 0 || pScrn->modes == NULL) {
+- XGIErrorLog(pScrn, "No valid modes found\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+-
+- xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+-
+- /* Set the current mode to the first in the list */
+- pScrn->currentMode = pScrn->modes;
+-
+- /* Copy to CurrentLayout */
+- pXGI->CurrentLayout.mode = pScrn->currentMode;
+- pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1);
+- }
+-#endif
+-
+- /* Print the list of modes being used */
+- xf86PrintModes(pScrn);
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- BOOLEAN acceptcustommodes = TRUE;
+- BOOLEAN includelcdmodes = TRUE;
+- BOOLEAN isfordvi = FALSE;
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2);
+-
+- clockRanges->next = NULL;
+- clockRanges->minClock = pXGI->MinClock;
+- clockRanges->clockIndex = -1;
+- clockRanges->interlaceAllowed = FALSE;
+- clockRanges->doubleScanAllowed = FALSE;
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+- "Min pixel clock for CRT2 is %d MHz\n",
+- clockRanges->minClock / 1000);
+- xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
+- "Max pixel clock for CRT2 is %d MHz\n",
+- clockRanges->maxClock / 1000);
+-
+- if ((pXGI->XGI_Pr->
+- VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)))
+- {
+- if (!(pXGI->VBFlags & (CRT2_LCD | CRT2_VGA)))
+- includelcdmodes = FALSE;
+- if (pXGI->VBFlags & CRT2_LCD)
+- isfordvi = TRUE;
+- if (pXGI->VBFlags & CRT2_TV)
+- acceptcustommodes = FALSE;
+- }
+- else {
+- includelcdmodes = FALSE;
+- acceptcustommodes = FALSE;
+- }
+- }
+-
+- if (pXGI->MergedFB) {
+-
+- pXGI->CheckForCRT2 = TRUE;
+- i = xf86ValidateModes(pXGI->CRT2pScrn,
+- pXGI->CRT2pScrn->monitor->Modes,
+- pXGI->CRT2pScrn->display->modes, clockRanges,
+- NULL, 256, 4088,
+- pXGI->CRT2pScrn->bitsPerPixel * 8, 128, 4096,
+- pScrn->display->virtualX ? pScrn->virtualX : 0,
+- pScrn->display->virtualY ? pScrn->virtualY : 0,
+- pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
+- pXGI->CheckForCRT2 = FALSE;
+-
+- if (i == -1) {
+- XGIErrorLog(pScrn, "xf86ValidateModes() error, %s.\n",
+- mergeddisstr);
+- XGIFreeCRT2Structs(pXGI);
+- pXGI->MergedFB = FALSE;
+- }
+-
+- }
+-
+- if (pXGI->MergedFB) {
+-
+- if ((p = first = pXGI->CRT2pScrn->modes)) {
+- do {
+- n = p->next;
+- p = n;
+- } while (p != NULL && p != first);
+- }
+-
+- xf86PruneDriverModes(pXGI->CRT2pScrn);
+-
+- if (i == 0 || pXGI->CRT2pScrn->modes == NULL) {
+- XGIErrorLog(pScrn, "No valid modes found for CRT2; %s\n",
+- mergeddisstr);
+- XGIFreeCRT2Structs(pXGI);
+- pXGI->MergedFB = FALSE;
+- }
+-
+- }
+-
+- if (pXGI->MergedFB) {
+-
+- xf86SetCrtcForModes(pXGI->CRT2pScrn, INTERLACE_HALVE_V);
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2);
+-
+- xf86PrintModes(pXGI->CRT2pScrn);
+-
+- pXGI->CRT1Modes = pScrn->modes;
+- pXGI->CRT1CurrentMode = pScrn->currentMode;
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "Generating MergedFB mode list\n");
+-
+- pScrn->modes = XGIGenerateModeList(pScrn, pXGI->MetaModes,
+- pXGI->CRT1Modes,
+- pXGI->CRT2pScrn->modes,
+- pXGI->CRT2Position);
+-
+- if (!pScrn->modes) {
+-
+- XGIErrorLog(pScrn,
+- "Failed to parse MetaModes or no modes found. %s.\n",
+- mergeddisstr);
+- XGIFreeCRT2Structs(pXGI);
+- pScrn->modes = pXGI->CRT1Modes;
+- pXGI->CRT1Modes = NULL;
+- pXGI->MergedFB = FALSE;
+-
+- }
+-
+- }
+-
+- if (pXGI->MergedFB) {
+-
+- /* If no virtual dimension was given by the user,
+- * calculate a sane one now. Adapts pScrn->virtualX,
+- * pScrn->virtualY and pScrn->displayWidth.
+- */
+- XGIRecalcDefaultVirtualSize(pScrn);
+-
+- pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
+- pScrn->currentMode = pScrn->modes;
+-
+- /* Update CurrentLayout */
+- pXGI->CurrentLayout.mode = pScrn->currentMode;
+- pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
+-
+- }
+-#endif
+-
+- /* Set display resolution */
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- XGIMergedFBSetDpi(pScrn, pXGI->CRT2pScrn, pXGI->CRT2Position);
+- }
+- else
+-#endif
+- xf86SetDpi(pScrn, 0, 0);
+-
+- /* Load fb module */
+- switch (pScrn->bitsPerPixel) {
+- case 8:
+- case 16:
+- case 24:
+- case 32:
+- if (!xf86LoadSubModule(pScrn, "fb")) {
+- XGIErrorLog(pScrn, "Failed to load fb module");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- break;
+- default:
+- XGIErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n",
+- pScrn->bitsPerPixel);
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- xf86LoaderReqSymLists(fbSymbols, NULL);
+-
+- /* Load XAA if needed */
+- if (!pXGI->NoAccel) {
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
+- if (!xf86LoadSubModule(pScrn, "xaa")) {
+- XGIErrorLog(pScrn, "Could not load xaa module\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- xf86LoaderReqSymLists(xaaSymbols, NULL);
+- }
+-
+- /* Load shadowfb if needed */
+- if (pXGI->ShadowFB) {
+- if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+- XGIErrorLog(pScrn, "Could not load shadowfb module\n");
+-
+- if (pXGIEnt)
+- pXGIEnt->ErrorAfterFirst = TRUE;
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+- XGIFreeRec(pScrn);
+- return FALSE;
+- }
+- xf86LoaderReqSymLists(shadowSymbols, NULL);
+- }
+-
+- /* Load the dri module if requested. */
+-#ifdef XF86DRI
+- if(pXGI->loadDRI) {
+- if (xf86LoadSubModule(pScrn, "dri")) {
+- xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL);
+- }
+- else {
+- if (!IS_DUAL_HEAD(pXGI))
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Remove >Load \"dri\"< from the Module section of your XF86Config file\n");
+- }
+- }
+-#endif
+-
+-
+- /* Now load and initialize VBE module for VESA and mode restoring. */
+- if (pXGI->pVbe) {
+- vbeFree(pXGI->pVbe);
+- pXGI->pVbe = NULL;
+- }
+-
+-#ifdef XGIDUALHEAD
+- xf86SetPrimInitDone(pScrn->entityList[0]);
+-#endif
+-
+- xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
+-
+- if (pXGI->pInt)
+- xf86FreeInt10(pXGI->pInt);
+- pXGI->pInt = NULL;
+-
+- if (IS_DUAL_HEAD(pXGI)) {
+- pXGI->XGI_SD_Flags |= XGI_SD_ISDUALHEAD;
+- if (IS_SECOND_HEAD(pXGI))
+- pXGI->XGI_SD_Flags |= XGI_SD_ISDHSECONDHEAD;
+- else
+- pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
+-#ifdef PANORAMIX
+- if (!noPanoramiXExtension) {
+- pXGI->XGI_SD_Flags |= XGI_SD_ISDHXINERAMA;
+- pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
+- }
+-#endif
+- }
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB)
+- pXGI->XGI_SD_Flags |= XGI_SD_ISMERGEDFB;
+-#endif
+-
+- if (pXGI->enablexgictrl)
+- pXGI->XGI_SD_Flags |= XGI_SD_ENABLED;
+-
+- return TRUE;
+-}
+-
+-
+-/*
+- * Map the framebuffer and MMIO memory.
+- */
+-
+-static Bool
+-XGIMapMem(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);;
+-
+-#ifdef XSERVER_LIBPCIACCESS
+- unsigned i;
+-
+- for (i = 0; i < 2; i++) {
+- int err;
+-
+- err = pci_device_map_region(pXGI->PciInfo, i, TRUE);
+- if (err) {
+- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "Internal error: cound not map PCI region %u\n", i);
+- return FALSE;
+- }
+- }
+-
+- pXGI->FbBase = pXGI->PciInfo->regions[0].memory;
+- pXGI->IOBase = pXGI->PciInfo->regions[1].memory;
+-#else
+- int mmioFlags;
+-
+- /*
+- * Map IO registers to virtual address space
+- */
+-#if !defined(__alpha__)
+- mmioFlags = VIDMEM_MMIO;
+-#else
+- /*
+- * For Alpha, we need to map SPARSE memory, since we need
+- * byte/short access.
+- */
+- mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+-#endif
+- pXGI->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+- pXGI->PciTag, pXGI->IOAddress, 0x10000);
+- if (pXGI->IOBase == NULL)
+- return FALSE;
+-
+-#ifdef __alpha__
+- /*
+- * for Alpha, we need to map DENSE memory as well, for
+- * setting CPUToScreenColorExpandBase.
+- */
+- pXGI->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+- pXGI->PciTag, pXGI->IOAddress, 0x10000);
+-
+- if (pXGI->IOBaseDense == NULL)
+- return FALSE;
+-#endif /* __alpha__ */
+-
+- pXGI->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+- pXGI->PciTag,
+- (unsigned long) pXGI->FbAddress,
+- pXGI->FbMapSize);
+-
+- PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n", (ULONG) (pXGI->FbBase)));
+-
+- if (pXGI->FbBase == NULL)
+- return FALSE;
+-#endif
+-
+- return TRUE;
+-}
+-
+-
+-/*
+- * Unmap the framebuffer and MMIO memory.
+- */
+-
+-static Bool
+-XGIUnmapMem(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+-
+-
+- /* In dual head mode, we must not unmap if the other head still
+- * assumes memory as mapped
+- */
+- if (IS_DUAL_HEAD(pXGI)) {
+- if (pXGIEnt->MapCountIOBase) {
+- pXGIEnt->MapCountIOBase--;
+- if ((pXGIEnt->MapCountIOBase == 0) || (pXGIEnt->forceUnmapIOBase)) {
+-#ifdef XSERVER_LIBPCIACCESS
+- pci_device_unmap_region(pXGI->PciInfo, 1);
+-#else
+- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->IOBase,
+- (pXGI->mmioSize * 1024));
+-#endif
+- pXGIEnt->IOBase = NULL;
+- pXGIEnt->MapCountIOBase = 0;
+- pXGIEnt->forceUnmapIOBase = FALSE;
+- }
+- pXGI->IOBase = NULL;
+- }
+-#ifdef __alpha__
+-#ifdef XSERVER_LIBPCIACCESS
+-#error "How to do dense mapping on Alpha?"
+-#else
+- if (pXGIEnt->MapCountIOBaseDense) {
+- pXGIEnt->MapCountIOBaseDense--;
+- if ((pXGIEnt->MapCountIOBaseDense == 0)
+- || (pXGIEnt->forceUnmapIOBaseDense)) {
+- xf86UnMapVidMem(pScrn->scrnIndex,
+- (pointer) pXGIEnt->IOBaseDense,
+- (pXGI->mmioSize * 1024));
+- pXGIEnt->IOBaseDense = NULL;
+- pXGIEnt->MapCountIOBaseDense = 0;
+- pXGIEnt->forceUnmapIOBaseDense = FALSE;
+- }
+- pXGI->IOBaseDense = NULL;
+- }
+-#endif
+-#endif /* __alpha__ */
+- if (pXGIEnt->MapCountFbBase) {
+- pXGIEnt->MapCountFbBase--;
+- if ((pXGIEnt->MapCountFbBase == 0) || (pXGIEnt->forceUnmapFbBase)) {
+-#ifdef XSERVER_LIBPCIACCESS
+- pci_device_unmap_region(pXGI->PciInfo, 0);
+-#else
+- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->FbBase,
+- pXGI->FbMapSize);
+-#endif
+- pXGIEnt->FbBase = NULL;
+- pXGIEnt->MapCountFbBase = 0;
+- pXGIEnt->forceUnmapFbBase = FALSE;
+-
+- }
+- pXGI->FbBase = NULL;
+- }
+- }
+- else {
+-#ifdef XSERVER_LIBPCIACCESS
+- pci_device_unmap_region(pXGI->PciInfo, 0);
+- pci_device_unmap_region(pXGI->PciInfo, 1);
+-#else
+- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBase,
+- (pXGI->mmioSize * 1024));
+- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->FbBase,
+- pXGI->FbMapSize);
+-#endif
+- pXGI->IOBase = NULL;
+- pXGI->FbBase = NULL;
+-
+-#ifdef __alpha__
+-#ifdef XSERVER_LIBPCIACCESS
+-#error "How to do dense mapping on Alpha?"
+-#else
+- xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBaseDense,
+- (pXGI->mmioSize * 1024));
+- pXGI->IOBaseDense = NULL;
+-#endif
+-#endif
+- }
+-
+- return TRUE;
+-}
+-
+-/*
+- * This function saves the video state.
+- */
+-static void
+-XGISave(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI;
+- vgaRegPtr vgaReg;
+- XGIRegPtr xgiReg;
+-
+- PDEBUG(ErrorF("XGISave()\n"));
+-
+- pXGI = XGIPTR(pScrn);
+-
+- /* We always save master & slave */
+- if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
+- return;
+-
+- vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+- xgiReg = &pXGI->SavedReg;
+-
+- vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+-
+- xgiSaveUnlockExtRegisterLock(pXGI, &xgiReg->xgiRegs3C4[0x05],
+- &xgiReg->xgiRegs3D4[0x80]);
+-
+- (*pXGI->XGISave) (pScrn, xgiReg);
+-
+- /* "Save" these again as they may have been changed prior to XGISave() call */
+-}
+-
+-
+-/*
+- * Initialise a new mode. This is currently done using the
+- * "initialise struct, restore/write struct to HW" model for
+- * the old chipsets (5597/530/6326). For newer chipsets,
+- * we use our own mode switching code (or VESA).
+- */
+-
+-static Bool
+-XGIModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+- vgaHWPtr hwp = VGAHWPTR(pScrn);
+- vgaRegPtr vgaReg;
+- XGIPtr pXGI = XGIPTR(pScrn);
+- XGIRegPtr xgiReg;
+-#ifdef __powerpc__
+- unsigned char tmpval;
+-#endif
+-
+-
+- /* PDEBUG(ErrorF("XGIModeInit(). \n")); */
+- PDEBUG(ErrorF
+- ("XGIModeInit Resolution (%d, %d) \n", mode->HDisplay,
+- mode->VDisplay));
+- PDEBUG(ErrorF("XGIModeInit VVRefresh (%8.3f) \n", mode->VRefresh));
+- PDEBUG(ErrorF("XGIModeInit Color Depth (%d) \n", pScrn->depth));
+-
+- /* Jong Lin 08-26-2005; save current mode */
+- Volari_SetDefaultIdleWait(pXGI, mode->HDisplay, pScrn->depth);
+-
+- andXGIIDXREG(XGICR, 0x11, 0x7f); /* Unlock CRTC registers */
+-
+- XGIModifyModeInfo(mode); /* Quick check of the mode parameters */
+-
+-
+- if (IS_DUAL_HEAD(pXGI)) {
+- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+-
+- if (!(*pXGI->ModeInit) (pScrn, mode)) {
+- XGIErrorLog(pScrn, "ModeInit() failed\n");
+- return FALSE;
+- }
+-
+- pScrn->vtSema = TRUE;
+-
+- /* Head 2 (slave) is always CRT1 */
+- XGIPreSetMode(pScrn, mode, XGI_MODE_CRT1);
+- if (!XGIBIOSSetModeCRT1(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn,
+- mode)) {
+- XGIErrorLog(pScrn, "XGIBIOSSetModeCRT1() failed\n");
+- return FALSE;
+- }
+- XGIPostSetMode(pScrn, &pXGI->ModeReg);
+- XGIAdjustFrame(pXGIEnt->pScrn_1->scrnIndex, pXGIEnt->pScrn_1->frameX0,
+- pXGIEnt->pScrn_1->frameY0, 0);
+- }
+- else
+- {
+- /* For other chipsets, use the old method */
+-
+- /* Initialise the ModeReg values */
+- if (!vgaHWInit(pScrn, mode)) {
+- XGIErrorLog(pScrn, "vgaHWInit() failed\n");
+- return FALSE;
+- }
+-
+- /* Reset our PIOOffset as vgaHWInit might have reset it */
+- VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
+-#ifdef XSERVER_LIBPCIACCESS
+- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+-#else
+- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+-#endif
+- ;
+-
+- /* Prepare the register contents */
+- if (!(*pXGI->ModeInit) (pScrn, mode)) {
+- XGIErrorLog(pScrn, "ModeInit() failed\n");
+- return FALSE;
+- }
+-
+- pScrn->vtSema = TRUE;
+-
+- /* Program the registers */
+- vgaHWProtect(pScrn, TRUE);
+- vgaReg = &hwp->ModeReg;
+- xgiReg = &pXGI->ModeReg;
+-
+- vgaReg->Attribute[0x10] = 0x01;
+- if (pScrn->bitsPerPixel > 8) {
+- vgaReg->Graphics[0x05] = 0x00;
+- }
+-
+- vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+-
+- (*pXGI->XGIRestore) (pScrn, xgiReg);
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "REAL REGISTER CONTENTS AFTER SETMODE:\n");
+- (*pXGI->ModeInit) (pScrn, mode);
+-#endif
+-
+- vgaHWProtect(pScrn, FALSE);
+- }
+-
+-
+- if (pXGI->Chipset == PCI_CHIP_XGIXG40 ||
+- pXGI->Chipset == PCI_CHIP_XGIXG20) {
+- /* PDEBUG(XGIDumpRegs(pScrn)) ; */
+- PDEBUG(ErrorF(" *** PreSetMode(). \n"));
+- XGIPreSetMode(pScrn, mode, XGI_MODE_SIMU);
+- /* PDEBUG(XGIDumpRegs(pScrn)) ; */
+- PDEBUG(ErrorF(" *** Start SetMode() \n"));
+-
+- if (!XGIBIOSSetMode(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, mode)) {
+- XGIErrorLog(pScrn, "XGIBIOSSetModeCRT() failed\n");
+- return FALSE;
+- }
+- Volari_EnableAccelerator(pScrn);
+- /* XGIPostSetMode(pScrn, &pXGI->ModeReg); */
+- /* outXGIIDXREG(XGISR, 0x20, 0xA1) ; */
+- /* PDEBUG(XGIDumpRegs(pScrn)) ; */
+- }
+-
+- /* Update Currentlayout */
+- pXGI->CurrentLayout.mode = mode;
+-
+-#ifdef __powerpc__
+- inXGIIDXREG(XGICR, 0x4D, tmpval);
+- if (pScrn->depth == 16)
+- tmpval = (tmpval & 0xE0) | 0x0B; //word swap
+- else if (pScrn->depth == 24)
+- tmpval = (tmpval & 0xE0) | 0x15; //dword swap
+- else
+- tmpval = tmpval & 0xE0; // no swap
+-
+- outXGIIDXREG(XGICR, 0x4D, tmpval);
+-#endif
+-
+- return TRUE;
+-}
+-
+-
+-/*
+- * Restore the initial mode. To be used internally only!
+- */
+-static void
+-XGIRestore(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- XGIRegPtr xgiReg = &pXGI->SavedReg;
+- vgaHWPtr hwp = VGAHWPTR(pScrn);
+- vgaRegPtr vgaReg = &hwp->SavedReg;
+-
+-
+- PDEBUG(ErrorF("XGIRestore():\n"));
+-
+- /* Wait for the accelerators */
+- if (pXGI->AccelInfoPtr) {
+- (*pXGI->AccelInfoPtr->Sync) (pScrn);
+- }
+-
+- vgaHWProtect(pScrn, TRUE);
+-
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-#endif
+-
+- (*pXGI->XGIRestore) (pScrn, xgiReg);
+-
+- vgaHWProtect(pScrn, TRUE);
+- if (pXGI->Primary) {
+- vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+- }
+-
+- xgiRestoreExtRegisterLock(pXGI, xgiReg->xgiRegs3C4[5],
+- xgiReg->xgiRegs3D4[0x80]);
+- vgaHWProtect(pScrn, FALSE);
+-}
+-
+-
+-/* Our generic BlockHandler for Xv */
+-static void
+-XGIBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
+-{
+- ScreenPtr pScreen = screenInfo.screens[i];
+- ScrnInfoPtr pScrn = xf86Screens[i];
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- pScreen->BlockHandler = pXGI->BlockHandler;
+- (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+- pScreen->BlockHandler = XGIBlockHandler;
+-
+- if (pXGI->VideoTimerCallback) {
+- (*pXGI->VideoTimerCallback) (pScrn, currentTime.milliseconds);
+- }
+-
+- if (pXGI->RenderCallback) {
+- (*pXGI->RenderCallback) (pScrn);
+- }
+-}
+-
+-/* Mandatory
+- * This gets called at the start of each server generation
+- *
+- * We use pScrn and not CurrentLayout here, because the
+- * properties we use have not changed (displayWidth,
+- * depth, bitsPerPixel)
+- */
+-static Bool
+-XGIScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+-{
+- ScrnInfoPtr pScrn;
+- vgaHWPtr hwp;
+- XGIPtr pXGI;
+- int ret;
+- VisualPtr visual;
+- unsigned long OnScreenSize;
+- int height, width, displayWidth;
+- unsigned char *FBStart;
+- XGIEntPtr pXGIEnt = NULL;
+-
+- ErrorF("XGIScreenInit\n");
+- pScrn = xf86Screens[pScreen->myNum];
+-
+- hwp = VGAHWPTR(pScrn);
+-
+- pXGI = XGIPTR(pScrn);
+-
+-#if !defined(__powerpc__)
+- if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
+- if (xf86LoadSubModule(pScrn, "vbe")) {
+- xf86LoaderReqSymLists(vbeSymbols, NULL);
+- pXGI->pVbe = VBEExtendedInit(NULL, pXGI->pEnt->index,
+- SET_BIOS_SCRATCH |
+- RESTORE_BIOS_SCRATCH);
+- }
+- else {
+- XGIErrorLog(pScrn, "Failed to load VBE submodule\n");
+- }
+- }
+-#endif /* if !defined(__powerpc__) */
+-
+- if (IS_DUAL_HEAD(pXGI)) {
+- pXGIEnt = ENTITY_PRIVATE(pXGI);
+- pXGIEnt->refCount++;
+- }
+-
+- /* Map the VGA memory and get the VGA IO base */
+- if (pXGI->Primary) {
+- hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+- if (!vgaHWMapMem(pScrn)) {
+- XGIErrorLog(pScrn, "Could not map VGA memory window\n");
+- return FALSE;
+- }
+- }
+- vgaHWGetIOBase(hwp);
+-
+- /* Patch the PIOOffset inside vgaHW to use
+- * our relocated IO ports.
+- */
+- VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
+-#ifdef XSERVER_LIBPCIACCESS
+- (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
+-#else
+- (pXGI->PciInfo->ioBase[2] & 0xFFFC)
+-#endif
+- ;
+-
+- /* Map the XGI memory and MMIO areas */
+- if (!XGIMapMem(pScrn)) {
+- XGIErrorLog(pScrn, "XGIMapMem() failed\n");
+- return FALSE;
+- }
+-
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-#endif
+-
+- /* Save the current state */
+- XGISave(pScrn);
+-
+-
+- PDEBUG(ErrorF("--- ScreenInit --- \n"));
+- PDEBUG(XGIDumpRegs(pScrn));
+-
+- /* Initialise the first mode */
+- if (!XGIModeInit(pScrn, pScrn->currentMode)) {
+- XGIErrorLog(pScrn, "XGIModeInit() failed\n");
+- return FALSE;
+- }
+-
+- PDEBUG(ErrorF("--- XGIModeInit --- \n"));
+- PDEBUG(XGIDumpRegs(pScrn));
+-
+- /* Darken the screen for aesthetic reasons */
+- /* Not using Dual Head variant on purpose; we darken
+- * the screen for both displays, and un-darken
+- * it when the second head is finished
+- */
+- XGISaveScreen(pScreen, SCREEN_SAVER_ON);
+-
+- /* Set the viewport */
+- XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+-
+- /*
+- * The next step is to setup the screen's visuals, and initialise the
+- * framebuffer code. In cases where the framebuffer's default
+- * choices for things like visual layouts and bits per RGB are OK,
+- * this may be as simple as calling the framebuffer's ScreenInit()
+- * function. If not, the visuals will need to be setup before calling
+- * a fb ScreenInit() function and fixed up after.
+- *
+- * For most PC hardware at depths >= 8, the defaults that cfb uses
+- * are not appropriate. In this driver, we fixup the visuals after.
+- */
+-
+- /*
+- * Reset visual list.
+- */
+- miClearVisualTypes();
+-
+- /* Setup the visuals we support. */
+-
+- /*
+- * For bpp > 8, the default visuals are not acceptable because we only
+- * support TrueColor and not DirectColor.
+- */
+- if (!miSetVisualTypes(pScrn->depth,
+- (pScrn->bitsPerPixel > 8) ?
+- TrueColorMask : miGetDefaultVisualMask(pScrn->
+- depth),
+- pScrn->rgbBits, pScrn->defaultVisual)) {
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- XGIErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
+- pScrn->bitsPerPixel);
+- return FALSE;
+- }
+-
+- width = pScrn->virtualX;
+- height = pScrn->virtualY;
+- displayWidth = pScrn->displayWidth;
+-
+- if (pXGI->Rotate) {
+- height = pScrn->virtualX;
+- width = pScrn->virtualY;
+- }
+-
+- if (pXGI->ShadowFB) {
+- pXGI->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+- pXGI->ShadowPtr = xalloc(pXGI->ShadowPitch * height);
+- displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+- FBStart = pXGI->ShadowPtr;
+- }
+- else {
+- pXGI->ShadowPtr = NULL;
+- FBStart = pXGI->FbBase;
+- }
+-
+- if (!miSetPixmapDepths()) {
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- XGIErrorLog(pScrn, "miSetPixmapDepths() failed\n");
+- return FALSE;
+- }
+-
+- /* Point cmdQueuePtr to pXGIEnt for shared usage
+- * (same technique is then eventually used in DRIScreeninit).
+- */
+- if (IS_SECOND_HEAD(pXGI))
+- pXGI->cmdQueueLenPtr = &(XGIPTR(pXGIEnt->pScrn_1)->cmdQueueLen);
+- else
+- pXGI->cmdQueueLenPtr = &(pXGI->cmdQueueLen);
+-
+- pXGI->cmdQueueLen = 0; /* Force an EngineIdle() at start */
+-
+-#ifdef XF86DRI
+- if(pXGI->loadDRI) {
+- /* No DRI in dual head mode */
+- if (IS_DUAL_HEAD(pXGI)) {
+- pXGI->directRenderingEnabled = FALSE;
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+- "DRI not supported in Dual Head mode\n");
+- }
+- else if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
+- PDEBUG(ErrorF("--- DRI not supported \n"));
+- xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
+- "DRI not supported on this chipset\n");
+- pXGI->directRenderingEnabled = FALSE;
+- }
+- else {
+- pXGI->directRenderingEnabled = XGIDRIScreenInit(pScreen);
+- PDEBUG(ErrorF("--- DRI supported \n"));
+- }
+- }
+-#endif
+-
+- /*
+- * Call the framebuffer layer's ScreenInit function, and fill in other
+- * pScreen fields.
+- */
+- switch (pScrn->bitsPerPixel) {
+- case 24:
+- case 8:
+- case 16:
+- case 32:
+- ret = fbScreenInit(pScreen, FBStart, width,
+- height, pScrn->xDpi, pScrn->yDpi,
+- displayWidth, pScrn->bitsPerPixel);
+- break;
+- default:
+- ret = FALSE;
+- break;
+- }
+- if (!ret) {
+- XGIErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
+- pScrn->bitsPerPixel);
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- return FALSE;
+- }
+-
+- if (pScrn->bitsPerPixel > 8) {
+- /* Fixup RGB ordering */
+- visual = pScreen->visuals + pScreen->numVisuals;
+- while (--visual >= pScreen->visuals) {
+- if ((visual->class | DynamicClass) == DirectColor) {
+- visual->offsetRed = pScrn->offset.red;
+- visual->offsetGreen = pScrn->offset.green;
+- visual->offsetBlue = pScrn->offset.blue;
+- visual->redMask = pScrn->mask.red;
+- visual->greenMask = pScrn->mask.green;
+- visual->blueMask = pScrn->mask.blue;
+- }
+- }
+- }
+-
+- /* Initialize RENDER ext; must be after RGB ordering fixed */
+- fbPictureInit(pScreen, 0, 0);
+-
+- /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */
+- if (!pXGI->ShadowFB)
+- XGIDGAInit(pScreen);
+-
+- xf86SetBlackWhitePixels(pScreen);
+-
+- if (!pXGI->NoAccel) {
+- /* Volari_EnableAccelerator(pScrn); */
+- PDEBUG(ErrorF("---Volari Accel.. \n"));
+- Volari_AccelInit(pScreen);
+- }
+-
+- PDEBUG(ErrorF("--- AccelInit --- \n"));
+- PDEBUG(XGIDumpRegs(pScrn));
+-
+- miInitializeBackingStore(pScreen);
+- xf86SetBackingStore(pScreen);
+- xf86SetSilkenMouse(pScreen);
+-
+- /* Initialise cursor functions */
+- miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+-
+- if (pXGI->HWCursor) {
+- XGIHWCursorInit(pScreen);
+- }
+-
+- /* Initialise default colourmap */
+- if (!miCreateDefColormap(pScreen)) {
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- XGIErrorLog(pScrn, "miCreateDefColormap() failed\n");
+- return FALSE;
+- }
+- if (!xf86HandleColormaps
+- (pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
+- XGILoadPalette, NULL,
+- CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
+- PDEBUG(ErrorF("XGILoadPalette() check-return. \n"));
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- XGIErrorLog(pScrn, "xf86HandleColormaps() failed\n");
+- return FALSE;
+- }
+-
+-/*
+- if (!xf86HandleColormaps(pScreen, 256, 8, XGILoadPalette, NULL,
+- CMAP_RELOAD_ON_MODE_SWITCH))
+- {
+- return FALSE;
+- }
+-*/
+- xf86DPMSInit(pScreen, (DPMSSetProcPtr) XGIDisplayPowerManagementSet, 0);
+-
+- /* Init memPhysBase and fbOffset in pScrn */
+- pScrn->memPhysBase = pXGI->FbAddress;
+- pScrn->fbOffset = 0;
+-
+- pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
+-
+-#if defined(XvExtension)
+- if (!pXGI->NoXvideo) {
+- XGIInitVideo(pScreen);
+- }
+-#endif
+-
+-#ifdef XF86DRI
+- if (pXGI->directRenderingEnabled) {
+- /* Now that mi, drm and others have done their thing,
+- * complete the DRI setup.
+- */
+- pXGI->directRenderingEnabled = XGIDRIFinishScreenInit(pScreen);
+- }
+-
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering %sabled\n",
+- (pXGI->directRenderingEnabled) ? "en" : "dis");
+- if (pXGI->directRenderingEnabled) {
+- /* TODO */
+- /* XGISetLFBConfig(pXGI); */
+- }
+-#endif
+-
+- /* Wrap some funcs and setup remaining SD flags */
+-
+- pXGI->XGI_SD_Flags &= ~(XGI_SD_PSEUDOXINERAMA);
+-
+- pXGI->CloseScreen = pScreen->CloseScreen;
+- pScreen->CloseScreen = XGICloseScreen;
+- if (IS_DUAL_HEAD(pXGI))
+- pScreen->SaveScreen = XGISaveScreenDH;
+- else
+- pScreen->SaveScreen = XGISaveScreen;
+-
+- /* Install BlockHandler */
+- pXGI->BlockHandler = pScreen->BlockHandler;
+- pScreen->BlockHandler = XGIBlockHandler;
+-
+- /* Report any unused options (only for the first generation) */
+- if (serverGeneration == 1) {
+- xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+- }
+-
+- /* Clear frame buffer */
+- /* For CRT2, we don't do that at this point in dual head
+- * mode since the mode isn't switched at this time (it will
+- * be reset when setting the CRT1 mode). Hence, we just
+- * save the necessary data and clear the screen when
+- * going through this for CRT1.
+- */
+-
+- OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
+- * (pScrn->bitsPerPixel >> 3);
+-
+- /* Turn on the screen now */
+- /* We do this in dual head mode after second head is finished */
+- if (IS_DUAL_HEAD(pXGI)) {
+- if (IS_SECOND_HEAD(pXGI)) {
+- bzero(pXGI->FbBase, OnScreenSize);
+- bzero(pXGIEnt->FbBase1, pXGIEnt->OnScreenSize1);
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- }
+- else {
+- pXGIEnt->FbBase1 = pXGI->FbBase;
+- pXGIEnt->OnScreenSize1 = OnScreenSize;
+- }
+- }
+- else {
+- XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
+- bzero(pXGI->FbBase, OnScreenSize);
+- }
+-
+- pXGI->XGI_SD_Flags &= ~XGI_SD_ISDEPTH8;
+- if (pXGI->CurrentLayout.bitsPerPixel == 8) {
+- pXGI->XGI_SD_Flags |= XGI_SD_ISDEPTH8;
+- pXGI->XGI_SD_Flags &= ~XGI_SD_SUPPORTXVGAMMA1;
+- }
+- PDEBUG(ErrorF("XGIScreenInit() End. \n"));
+- XGIDumpPalette(pScrn);
+- return TRUE;
+-}
+-
+-/* Usually mandatory */
+-Bool
+-XGISwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- ErrorF("XGISwitchMode\n");
+-
+- if (!pXGI->NoAccel) {
+- if (pXGI->AccelInfoPtr) {
+- (*pXGI->AccelInfoPtr->Sync) (pScrn);
+- PDEBUG(ErrorF("XGISwitchMode Accel Enabled. \n"));
+- }
+- }
+- PDEBUG(ErrorF
+- ("XGISwitchMode (%d, %d) \n", mode->HDisplay, mode->VDisplay));
+-
+- if (!(XGIModeInit(xf86Screens[scrnIndex], mode)))
+- return FALSE;
+-
+- /* Since RandR (indirectly) uses SwitchMode(), we need to
+- * update our Xinerama info here, too, in case of resizing
+- */
+- return TRUE;
+-}
+-
+-/* static void
+-XGISetStartAddressCRT1(XGIPtr pXGI, unsigned long base)
+-{
+- unsigned char cr11backup;
+-
+- inXGIIDXREG(XGICR, 0x11, cr11backup);
+- andXGIIDXREG(XGICR, 0x11, 0x7F);
+- outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
+- outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
+- outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
+-
+-
+- setXGIIDXREG(XGICR, 0x11, 0x7F,(cr11backup & 0x80));
+-} */
+-
+-#ifdef XGIMERGED
+-/* static Bool
+-InRegion(int x, int y, region r)
+-{
+- return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
+-} */
+-
+-/* static void
+-XGIAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned long base;
+-
+- base = y * pXGI->CurrentLayout.displayWidth + x;
+- switch(pXGI->CurrentLayout.bitsPerPixel)
+- {
+- case 16: base >>= 1; break;
+- case 32: break;
+- default: base >>= 2;
+- }
+- XGISetStartAddressCRT1(pXGI, base);
+-} */
+-
+-/* static void
+-XGIMergePointerMoved(int scrnIndex, int x, int y)
+-{
+- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+- XGIPtr pXGI = XGIPTR(pScrn1);
+- ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
+- region out, in1, in2, f2, f1;
+- int deltax, deltay;
+-
+- f1.x0 = pXGI->CRT1frameX0;
+- f1.x1 = pXGI->CRT1frameX1;
+- f1.y0 = pXGI->CRT1frameY0;
+- f1.y1 = pXGI->CRT1frameY1;
+- f2.x0 = pScrn2->frameX0;
+- f2.x1 = pScrn2->frameX1;
+- f2.y0 = pScrn2->frameY0;
+- f2.y1 = pScrn2->frameY1;
+-
+- out.x0 = pScrn1->frameX0;
+- out.x1 = pScrn1->frameX1;
+- out.y0 = pScrn1->frameY0;
+- out.y1 = pScrn1->frameY1;
+-
+- in1 = out;
+- in2 = out;
+- switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
+- {
+- case xgiLeftOf:
+- in1.x0 = f1.x0;
+- in2.x1 = f2.x1;
+- break;
+- case xgiRightOf:
+- in1.x1 = f1.x1;
+- in2.x0 = f2.x0;
+- break;
+- case xgiBelow:
+- in1.y1 = f1.y1;
+- in2.y0 = f2.y0;
+- break;
+- case xgiAbove:
+- in1.y0 = f1.y0;
+- in2.y1 = f2.y1;
+- break;
+- case xgiClone:
+- break;
+- }
+-
+- deltay = 0;
+- deltax = 0;
+-
+- if(InRegion(x, y, out))
+- {
+-
+- if(InRegion(x, y, in1) && !InRegion(x, y, f1))
+- {
+- REBOUND(f1.x0, f1.x1, x);
+- REBOUND(f1.y0, f1.y1, y);
+- deltax = 1;
+- }
+- if(InRegion(x, y, in2) && !InRegion(x, y, f2))
+- {
+- REBOUND(f2.x0, f2.x1, x);
+- REBOUND(f2.y0, f2.y1, y);
+- deltax = 1;
+- }
+-
+- }
+- else
+- {
+-
+- if(out.x0 > x)
+- {
+- deltax = x - out.x0;
+- }
+- if(out.x1 < x)
+- {
+- deltax = x - out.x1;
+- }
+- if(deltax)
+- {
+- pScrn1->frameX0 += deltax;
+- pScrn1->frameX1 += deltax;
+- f1.x0 += deltax;
+- f1.x1 += deltax;
+- f2.x0 += deltax;
+- f2.x1 += deltax;
+- }
+-
+- if(out.y0 > y)
+- {
+- deltay = y - out.y0;
+- }
+- if(out.y1 < y)
+- {
+- deltay = y - out.y1;
+- }
+- if(deltay)
+- {
+- pScrn1->frameY0 += deltay;
+- pScrn1->frameY1 += deltay;
+- f1.y0 += deltay;
+- f1.y1 += deltay;
+- f2.y0 += deltay;
+- f2.y1 += deltay;
+- }
+-
+- switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
+- {
+- case xgiLeftOf:
+- if(x >= f1.x0)
+- { REBOUND(f1.y0, f1.y1, y); }
+- if(x <= f2.x1)
+- { REBOUND(f2.y0, f2.y1, y); }
+- break;
+- case xgiRightOf:
+- if(x <= f1.x1)
+- { REBOUND(f1.y0, f1.y1, y); }
+- if(x >= f2.x0)
+- { REBOUND(f2.y0, f2.y1, y); }
+- break;
+- case xgiBelow:
+- if(y <= f1.y1)
+- { REBOUND(f1.x0, f1.x1, x); }
+- if(y >= f2.y0)
+- { REBOUND(f2.x0, f2.x1, x); }
+- break;
+- case xgiAbove:
+- if(y >= f1.y0)
+- { REBOUND(f1.x0, f1.x1, x); }
+- if(y <= f2.y1)
+- { REBOUND(f2.x0, f2.x1, x); }
+- break;
+- case xgiClone:
+- break;
+- }
+-
+- }
+-
+- if(deltax || deltay)
+- {
+- pXGI->CRT1frameX0 = f1.x0;
+- pXGI->CRT1frameY0 = f1.y0;
+- pScrn2->frameX0 = f2.x0;
+- pScrn2->frameY0 = f2.y0;
+-
+- pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
+- pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
+- pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
+- pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+- pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
+- pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
+-
+- XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
+- }
+-} */
+-
+-
+-/* static void
+-XGIAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
+-{
+- ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
+- XGIPtr pXGI = XGIPTR(pScrn1);
+- ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
+- int VTotal = pXGI->CurrentLayout.mode->VDisplay;
+- int HTotal = pXGI->CurrentLayout.mode->HDisplay;
+- int VMax = VTotal;
+- int HMax = HTotal;
+-
+- BOUND(x, 0, pScrn1->virtualX - HTotal);
+- BOUND(y, 0, pScrn1->virtualY - VTotal);
+-
+- switch(SDMPTR(pScrn1)->CRT2Position)
+- {
+- case xgiLeftOf:
+- pScrn2->frameX0 = x;
+- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+- pXGI->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
+- BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+- break;
+- case xgiRightOf:
+- pXGI->CRT1frameX0 = x;
+- BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+- pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
+- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+- break;
+- case xgiAbove:
+- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+- pScrn2->frameY0 = y;
+- BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+- pXGI->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
+- break;
+- case xgiBelow:
+- BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+- pXGI->CRT1frameY0 = y;
+- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+- pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
+- break;
+- case xgiClone:
+- BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
+- BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
+- BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
+- BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
+- break;
+- }
+-
+- BOUND(pXGI->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
+- BOUND(pXGI->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
+- BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
+- BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
+-
+- pScrn1->frameX0 = x;
+- pScrn1->frameY0 = y;
+-
+- pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
+- pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
+- pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
+- pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
+- pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
+- pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
+-
+- XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
+-} */
+-#endif
+-
+-/*
+- * This function is used to initialize the Start Address - the first
+- * displayed location in the video memory.
+- *
+- * Usually mandatory
+- */
+-void
+-XGIAdjustFrame(int scrnIndex, int x, int y, int flags)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned long base;
+- unsigned char ucSR5Stat, ucTemp;
+-
+- ErrorF("AdjustFrame %d\n", scrnIndex);
+- inXGIIDXREG(XGISR, 0x05, ucSR5Stat);
+- if (ucSR5Stat == 0xA1)
+- ucSR5Stat = 0x86;
+- outXGIIDXREG(XGISR, 0x05, 0x86);
+-
+- base = (pScrn->bitsPerPixel + 7) / 8;
+- base *= x;
+- base += pXGI->scrnOffset * y;
+- base >>= 2;
+-
+- switch (pXGI->Chipset) {
+- case PCI_CHIP_XGIXG40:
+- default:
+-
+- ucTemp = base & 0xFF;
+- outXGIIDXREG(XGICR, 0x0D, ucTemp);
+- ucTemp = (base >> 8) & 0xFF;
+- outXGIIDXREG(XGICR, 0x0C, ucTemp);
+- ucTemp = (base >> 16) & 0xFF;
+- outXGIIDXREG(XGISR, 0x0D, ucTemp);
+- ucTemp = (base >> 24) & 0x01;
+- setXGIIDXREG(XGISR, 0x37, 0xFE, ucTemp);
+-
+-/* if (pXGI->VBFlags) {
+- XGI_UnLockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
+- ucTemp = base & 0xFF ; outXGIIDXREG( XGIPART1, 6 , ucTemp ) ;
+- ucTemp = (base>>8) & 0xFF ; outXGIIDXREG( XGIPART1, 5 , ucTemp ) ;
+- ucTemp = (base>>16) & 0xFF ; outXGIIDXREG( XGIPART1, 4 , ucTemp ) ;
+- ucTemp = (base>>24) & 0x01 ; ucTemp <<= 7 ;
+- setXGIIDXREG( XGIPART1, 0x2, 0x7F, ucTemp ) ;
+-
+- XGI_LockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
+- }
+- */
+- break;
+-
+- }
+-
+- outXGIIDXREG(XGISR, 0x05, ucSR5Stat);
+-
+-}
+-
+-/*
+- * This is called when VT switching back to the X server. Its job is
+- * to reinitialise the video mode.
+- * Mandatory!
+- */
+-static Bool
+-XGIEnterVT(int scrnIndex, int flags)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-
+- if (!XGIModeInit(pScrn, pScrn->currentMode)) {
+- XGIErrorLog(pScrn, "XGIEnterVT: XGIModeInit() failed\n");
+- return FALSE;
+- }
+-
+- XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+-
+-#ifdef XF86DRI
+- if (pXGI->directRenderingEnabled) {
+- DRIUnlock(screenInfo.screens[scrnIndex]);
+- }
+-#endif
+-
+- if ((!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) && (pXGI->ResetXv)) {
+- (pXGI->ResetXv) (pScrn);
+- }
+-
+- return TRUE;
+-}
+-
+-/*
+- * This is called when VT switching away from the X server. Its job is
+- * to restore the previous (text) mode.
+- * Mandatory!
+- */
+-static void
+-XGILeaveVT(int scrnIndex, int flags)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- vgaHWPtr hwp = VGAHWPTR(pScrn);
+- XGIPtr pXGI = XGIPTR(pScrn);
+-#ifdef XF86DRI
+- ScreenPtr pScreen;
+-
+- PDEBUG(ErrorF("XGILeaveVT()\n"));
+- if (pXGI->directRenderingEnabled) {
+- pScreen = screenInfo.screens[scrnIndex];
+- DRILock(pScreen, 0);
+- }
+-#endif
+-
+- if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
+- return;
+-
+- if (pXGI->CursorInfoPtr) {
+- /* Because of the test and return above, we know that this is not
+- * the second head.
+- */
+- pXGI->CursorInfoPtr->HideCursor(pScrn);
+- XGI_WaitBeginRetrace(pXGI->RelIO);
+- }
+-
+- XGIRestore(pScrn);
+-
+-
+- /* We use (otherwise unused) bit 7 to indicate that we are running to keep
+- * xgifb to change the displaymode (this would result in lethal display
+- * corruption upon quitting X or changing to a VT until a reboot).
+- */
+- vgaHWLock(hwp);
+-}
+-
+-
+-/*
+- * This is called at the end of each server generation. It restores the
+- * original (text) mode. It should really also unmap the video memory too.
+- * Mandatory!
+- */
+-static Bool
+-XGICloseScreen(int scrnIndex, ScreenPtr pScreen)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- vgaHWPtr hwp = VGAHWPTR(pScrn);
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+-
+-#ifdef XF86DRI
+- if (pXGI->directRenderingEnabled) {
+- XGIDRICloseScreen(pScreen);
+- pXGI->directRenderingEnabled = FALSE;
+- }
+-#endif
+-
+- if (pScrn->vtSema) {
+- if (pXGI->CursorInfoPtr
+- && (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI))) {
+- pXGI->CursorInfoPtr->HideCursor(pScrn);
+- XGI_WaitBeginRetrace(pXGI->RelIO);
+- }
+-
+-
+- XGIRestore(pScrn);
+- vgaHWLock(hwp);
+- }
+-
+- /* We should restore the mode number in case vtsema = false as well,
+- * but since we haven't register access then we can't do it. I think
+- * I need to rework the save/restore stuff, like saving the video
+- * status when returning to the X server and by that save me the
+- * trouble if xgifb was started from a textmode VT while X was on.
+- */
+-
+- XGIUnmapMem(pScrn);
+- vgaHWUnmapMem(pScrn);
+-
+- if (IS_DUAL_HEAD(pXGI)) {
+- XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
+- pXGIEnt->refCount--;
+- }
+-
+- if (pXGI->pInt) {
+- xf86FreeInt10(pXGI->pInt);
+- pXGI->pInt = NULL;
+- }
+-
+- if (pXGI->AccelLinearScratch) {
+- xf86FreeOffscreenLinear(pXGI->AccelLinearScratch);
+- pXGI->AccelLinearScratch = NULL;
+- }
+-
+- if (pXGI->AccelInfoPtr) {
+- XAADestroyInfoRec(pXGI->AccelInfoPtr);
+- pXGI->AccelInfoPtr = NULL;
+- }
+-
+- if (pXGI->CursorInfoPtr) {
+- xf86DestroyCursorInfoRec(pXGI->CursorInfoPtr);
+- pXGI->CursorInfoPtr = NULL;
+- }
+-
+- if (pXGI->ShadowPtr) {
+- xfree(pXGI->ShadowPtr);
+- pXGI->ShadowPtr = NULL;
+- }
+-
+- if (pXGI->DGAModes) {
+- xfree(pXGI->DGAModes);
+- pXGI->DGAModes = NULL;
+- }
+-
+- if (pXGI->adaptor) {
+- xfree(pXGI->adaptor);
+- pXGI->adaptor = NULL;
+- pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
+- }
+-
+- pScrn->vtSema = FALSE;
+-
+- /* Restore Blockhandler */
+- pScreen->BlockHandler = pXGI->BlockHandler;
+-
+- pScreen->CloseScreen = pXGI->CloseScreen;
+-
+- return (*pScreen->CloseScreen) (scrnIndex, pScreen);
+-}
+-
+-
+-/* Free up any per-generation data structures */
+-
+-/* Optional */
+-static void
+-XGIFreeScreen(int scrnIndex, int flags)
+-{
+- if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) {
+- vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+- }
+-
+- XGIFreeRec(xf86Screens[scrnIndex]);
+-}
+-
+-
+-/* Checks if a mode is suitable for the selected chipset. */
+-
+-static int
+-XGIValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+- XGIPtr pXGI = XGIPTR(pScrn);
+- int HDisplay = mode->HDisplay;
+- int VDisplay = mode->VDisplay;
+- int Clock = mode->Clock;
+- int i = 0;
+- int VRefresh;
+-
+- VRefresh =
+- (int) ((float) (Clock * 1000) /
+- (float) (mode->VTotal * mode->HTotal) + 0.5);
+-
+- PDEBUG5(ErrorF("XGIValidMode()."));
+- PDEBUG5(ErrorF
+- ("CLK=%5.3fMhz %dx%d@%d ", (float) Clock / 1000, HDisplay,
+- VDisplay, VRefresh));
+- PDEBUG5(ErrorF("(VT,HT)=(%d,%d)\n", mode->VTotal, mode->HTotal));
+-
+- if (pXGI->VBFlags & CRT2_LCD) {
+- if ((HDisplay > 1600 && VDisplay > 1200)
+- || (HDisplay < 640 && VDisplay < 480)) {
+- PDEBUG5(ErrorF("skip by LCD limit\n"));
+- return (MODE_NOMODE);
+- }
+- /* if( VRefresh != 60) return(MODE_NOMODE) ; */
+- }
+- else if (pXGI->VBFlags & CRT2_TV) {
+- if ((HDisplay > 1024 && VDisplay > 768) ||
+- (HDisplay < 640 && VDisplay < 480) || (VRefresh != 60)) {
+- PDEBUG5(ErrorF("skip by TV limit\n"));
+- return (MODE_NOMODE);
+- }
+- }
+- else if (pXGI->VBFlags & CRT2_VGA) {
+- if ((HDisplay > 1600 && VDisplay > 1200) ||
+- (HDisplay < 640 && VDisplay < 480)) {
+- PDEBUG5(ErrorF("skip by CRT2 limit\n"));
+- return (MODE_NOMODE);
+- }
+- }
+-
+- if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
+- XgiMode = XG20_Mode;
+- }
+- else {
+- XgiMode = XGI_Mode;
+- }
+-
+- while ((XgiMode[i].Clock != Clock) ||
+- (XgiMode[i].HDisplay != HDisplay) ||
+- (XgiMode[i].VDisplay != VDisplay)) {
+- if (XgiMode[i].Clock == 0) {
+- PDEBUG5(ErrorF
+- ("--- NO_Mode support for %dx%d@%dHz\n", HDisplay,
+- VDisplay, VRefresh));
+- return (MODE_NOMODE);
+- }
+- else
+- i++;
+- }
+- PDEBUG5(ErrorF("Mode OK\n"));
+-
+- return (MODE_OK);
+-}
+-
+-/* Do screen blanking
+- *
+- * Mandatory
+- */
+-static Bool
+-XGISaveScreen(ScreenPtr pScreen, int mode)
+-{
+- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+-
+- if ((pScrn != NULL) && pScrn->vtSema) {
+-
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-#endif
+- }
+-
+- return vgaHWSaveScreen(pScreen, mode);
+-}
+-
+-/* SaveScreen for dual head mode */
+-static Bool
+-XGISaveScreenDH(ScreenPtr pScreen, int mode)
+-{
+-#ifdef XGIDUALHEAD
+- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+-
+- if ((pScrn != NULL) && pScrn->vtSema) {
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- if (IS_SECOND_HEAD(pXGI)
+- && ((!(pXGI->VBFlags & CRT1_LCDA))
+- || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
+-
+- /* Slave head is always CRT1 */
+- if (pXGI->VBFlags & CRT1_LCDA)
+- pXGI->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
+-
+- return vgaHWSaveScreen(pScreen, mode);
+- }
+- else {
+- /* Master head is always CRT2 */
+- /* But we land here if CRT1 is LCDA, too */
+-
+- /* We can only blank LCD, not other CRT2 devices */
+- if (!(pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)))
+- return TRUE;
+-
+- /* enable access to extended sequencer registers */
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-#endif
+- }
+- }
+-#endif
+- return TRUE;
+-}
+-
+-#ifdef DEBUG
+-static void
+-XGIDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock : %x\n", mode->Clock);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Display : %x\n",
+- mode->CrtcHDisplay);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank Start : %x\n",
+- mode->CrtcHBlankStart);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync Start : %x\n",
+- mode->CrtcHSyncStart);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync End : %x\n",
+- mode->CrtcHSyncEnd);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank End : %x\n",
+- mode->CrtcHBlankEnd);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz HAdjusted : %x\n",
+- mode->CrtcHAdjusted);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Display : %x\n",
+- mode->CrtcVDisplay);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank Start : %x\n",
+- mode->CrtcVBlankStart);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync Start : %x\n",
+- mode->CrtcVSyncStart);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync End : %x\n",
+- mode->CrtcVSyncEnd);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank End : %x\n",
+- mode->CrtcVBlankEnd);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt VAdjusted : %x\n",
+- mode->CrtcVAdjusted);
+-}
+-#endif
+-
+-static void
+-XGIModifyModeInfo(DisplayModePtr mode)
+-{
+- if (mode->CrtcHBlankStart == mode->CrtcHDisplay)
+- mode->CrtcHBlankStart++;
+- if (mode->CrtcHBlankEnd == mode->CrtcHTotal)
+- mode->CrtcHBlankEnd--;
+- if (mode->CrtcVBlankStart == mode->CrtcVDisplay)
+- mode->CrtcVBlankStart++;
+- if (mode->CrtcVBlankEnd == mode->CrtcVTotal)
+- mode->CrtcVBlankEnd--;
+-}
+-
+-/* Things to do before a ModeSwitch. We set up the
+- * video bridge configuration and the TurboQueue.
+- */
+-void
+-XGIPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned char CR30, CR31, CR33;
+- unsigned char CR3B = 0;
+- unsigned char CR17, CR38 = 0;
+- unsigned char CR35 = 0, CR79 = 0;
+- unsigned long vbflag;
+- int temp = 0;
+- int crt1rateindex = 0;
+- DisplayModePtr mymode;
+-#ifdef XGIMERGED
+- DisplayModePtr mymode2 = NULL;
+-#endif
+-
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- mymode = ((XGIMergedDisplayModePtr) mode->Private)->CRT1;
+- mymode2 = ((XGIMergedDisplayModePtr) mode->Private)->CRT2;
+- }
+- else
+-#endif
+- mymode = mode;
+-
+- vbflag = pXGI->VBFlags;
+- PDEBUG(ErrorF("VBFlags=0x%lx\n", pXGI->VBFlags));
+-
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); /* Unlock Registers */
+-#endif
+-
+- inXGIIDXREG(XGICR, 0x30, CR30);
+- inXGIIDXREG(XGICR, 0x31, CR31);
+- inXGIIDXREG(XGICR, 0x33, CR33);
+-
+- inXGIIDXREG(XGICR, 0x3b, CR3B);
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
+- "Before: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
+- CR30, CR31, CR33, temp, CR38);
+-
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n",
+- pXGI->VBFlags);
+-
+- CR30 = 0x00;
+- CR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */
+- CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */
+- CR35 = 0x00;
+-
+-
+- if (!pXGI->AllowHotkey) {
+- CR31 |= 0x80; /* Disable hotkey-switch */
+- }
+- CR79 &= ~0x10; /* Enable Backlight control on 315 series */
+-
+-
+- if ((vbflag & CRT1_LCDA) && (viewmode == XGI_MODE_CRT1)) {
+-
+- CR38 |= 0x02;
+-
+- }
+- else {
+-
+- switch (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
+-
+- case CRT2_TV:
+-
+- CR38 &= ~0xC0; /* Clear Pal M/N bits */
+-
+- if (vbflag & TV_YPBPR) { /* Video bridge */
+- if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR) {
+- CR30 |= 0x80;
+- CR38 |= 0x08;
+- if (vbflag & TV_YPBPR525P)
+- CR38 |= 0x10;
+- else if (vbflag & TV_YPBPR750P)
+- CR38 |= 0x20;
+- else if (vbflag & TV_YPBPR1080I)
+- CR38 |= 0x30;
+- CR31 &= ~0x01;
+- if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPRAR) {
+- CR3B &= ~0x03;
+- if ((vbflag & TV_YPBPRAR) == TV_YPBPR43LB)
+- CR3B |= 0x00;
+- else if ((vbflag & TV_YPBPRAR) == TV_YPBPR43)
+- CR3B |= 0x03;
+- else if ((vbflag & TV_YPBPRAR) == TV_YPBPR169)
+- CR3B |= 0x01;
+- else
+- CR3B |= 0x03;
+- }
+- }
+- }
+- else { /* All */
+- if (vbflag & TV_SCART)
+- CR30 |= 0x10;
+- if (vbflag & TV_SVIDEO)
+- CR30 |= 0x08;
+- if (vbflag & TV_AVIDEO)
+- CR30 |= 0x04;
+- if (!(CR30 & 0x1C))
+- CR30 |= 0x08; /* default: SVIDEO */
+-
+- if (vbflag & TV_PAL) {
+- CR31 |= 0x01;
+- CR35 |= 0x01;
+- if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
+- if (vbflag & TV_PALM) {
+- CR38 |= 0x40;
+- CR35 |= 0x04;
+- }
+- else if (vbflag & TV_PALN) {
+- CR38 |= 0x80;
+- CR35 |= 0x08;
+- }
+- }
+- }
+- else {
+- CR31 &= ~0x01;
+- CR35 &= ~0x01;
+- if (vbflag & TV_NTSCJ) {
+- CR38 |= 0x40; /* TW, not BIOS */
+- CR35 |= 0x02;
+- }
+- }
+- if (vbflag & TV_SCART) {
+- CR31 |= 0x01;
+- CR35 |= 0x01;
+- }
+- }
+-
+- CR31 &= ~0x04; /* Clear NotSimuMode */
+-#ifdef XGI_CP
+- XGI_CP_DRIVER_CONFIG
+-#endif
+- break;
+-
+- case CRT2_LCD:
+- CR30 |= 0x20;
+- break;
+-
+- case CRT2_VGA:
+- CR30 |= 0x40;
+- break;
+-
+- default:
+- CR30 |= 0x00;
+- CR31 |= 0x20; /* VB_OUTPUT_DISABLE */
+- }
+-
+- }
+-
+- if (vbflag & CRT1_LCDA) {
+- switch (viewmode) {
+- case XGI_MODE_CRT1:
+- CR38 |= 0x01;
+- break;
+- case XGI_MODE_CRT2:
+- if (vbflag & (CRT2_TV | CRT2_VGA)) {
+- CR30 |= 0x02;
+- CR38 |= 0x01;
+- }
+- else {
+- CR38 |= 0x03;
+- }
+- break;
+- case XGI_MODE_SIMU:
+- default:
+- if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
+- CR30 |= 0x01;
+- }
+- break;
+- }
+- }
+- else {
+- if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
+- CR30 |= 0x01;
+- }
+- }
+-
+- CR31 |= 0x40; /* Set Drivermode */
+- CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */
+- crt1rateindex = XGISearchCRT1Rate(pScrn, mymode);
+-
+- if (IS_DUAL_HEAD(pXGI)) {
+- if (IS_SECOND_HEAD(pXGI)) {
+- /* CRT1 */
+- CR33 &= 0xf0;
+- if (!(vbflag & CRT1_LCDA)) {
+- CR33 |= (crt1rateindex & 0x0f);
+- }
+- }
+- else {
+- /* CRT2 */
+- CR33 &= 0x0f;
+- if (vbflag & CRT2_VGA) {
+- CR33 |= ((crt1rateindex << 4) & 0xf0);
+- }
+- }
+- }
+- else
+-#ifdef XGIMERGED
+- if (pXGI->MergedFB) {
+- CR33 = 0;
+- if (!(vbflag & CRT1_LCDA)) {
+- CR33 |= (crt1rateindex & 0x0f);
+- }
+- if (vbflag & CRT2_VGA) {
+- CR33 |= (XGISearchCRT1Rate(pScrn, mymode2) << 4);
+- }
+- }
+- else
+-#endif
+- {
+- CR33 = 0;
+- if (!(vbflag & CRT1_LCDA)) {
+- CR33 |= (crt1rateindex & 0x0f);
+- }
+- if (vbflag & CRT2_VGA) {
+- CR33 |= ((crt1rateindex & 0x0f) << 4);
+- }
+- if (vbflag & CRT2_ENABLE) {
+- if (pXGI->CRT1off)
+- CR33 &= 0xf0;
+- }
+- }
+- outXGIIDXREG(XGICR, 0x30, CR30);
+- outXGIIDXREG(XGICR, 0x31, CR31);
+- outXGIIDXREG(XGICR, 0x33, CR33);
+- if (temp) {
+- outXGIIDXREG(XGICR, temp, CR38);
+- }
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+- "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n",
+- CR30, CR31, CR33, temp, CR38);
+-
+- if (pXGI->VBFlags & CRT2_ENABLE) {
+- /* Switch on CRT1 for modes that require the bridge in SlaveMode */
+- andXGIIDXREG(XGISR, 0x1f, 0x3f);
+- inXGIIDXREG(XGICR, 0x17, CR17);
+- if (!(CR17 & 0x80)) {
+- orXGIIDXREG(XGICR, 0x17, 0x80);
+- outXGIIDXREG(XGISR, 0x00, 0x01);
+- usleep(10000);
+- outXGIIDXREG(XGISR, 0x00, 0x03);
+- }
+- }
+-}
+-
+-/* PostSetMode:
+- * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
+- * VESA uses the bridge in SlaveMode and switching CRT1 off while
+- * the bridge is in SlaveMode not that clever...
+- * -) Check if overlay can be used (depending on dotclock)
+- * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
+- * -) Save TV registers for further processing
+- * -) Apply TV settings
+- */
+-static void
+-XGIPostSetMode(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-/* unsigned char usScratchCR17;
+- Bool flag = FALSE;
+- Bool doit = TRUE; */
+- int myclock;
+- unsigned char sr2b, sr2c, tmpreg;
+- float num, denum, postscalar, divider;
+- PDEBUG(ErrorF(" XGIPostSetMode(). \n"));
+-#ifdef TWDEBUG
+- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pXGI->CRT1off);
+-#endif
+-
+-#ifdef UNLOCK_ALWAYS
+- xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
+-#endif
+-
+- /* Determine if the video overlay can be used */
+- if (!pXGI->NoXvideo) {
+- inXGIIDXREG(XGISR, 0x2b, sr2b);
+- inXGIIDXREG(XGISR, 0x2c, sr2c);
+- divider = (sr2b & 0x80) ? 2.0 : 1.0;
+- postscalar = (sr2c & 0x80) ?
+- ((((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) :
+- (((sr2c >> 5) & 0x03) + 1.0);
+- num = (sr2b & 0x7f) + 1.0;
+- denum = (sr2c & 0x1f) + 1.0;
+- myclock =
+- (int) ((14318 * (divider / postscalar) * (num / denum)) / 1000);
+-
+- pXGI->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA);
+-/* switch(pXGI->xgi_HwDevExt.jChipType) {
+- break;
+- }
+- */
+- if (!(pXGI->MiscFlags & MISC_CRT1OVERLAY)) {
+- if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI))
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
+- "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
+- myclock);
+- }
+- }
+-
+- /* Determine if the Panel Link scaler is active */
+- pXGI->MiscFlags &= ~MISC_PANELLINKSCALER;
+- if (pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
+- if (pXGI->VBFlags & CRT1_LCDA) {
+- inXGIIDXREG(XGIPART1, 0x35, tmpreg);
+- tmpreg &= 0x04;
+- if (!tmpreg)
+- pXGI->MiscFlags |= MISC_PANELLINKSCALER;
+- }
+- }
+-
+- /* Determine if our very special TV mode is active */
+- pXGI->MiscFlags &= ~MISC_TVNTSC1024;
+- if ((pXGI->XGI_Pr->VBType & VB_XGIVB) && (pXGI->VBFlags & CRT2_TV)
+- && (!(pXGI->VBFlags & TV_HIVISION))) {
+- if (((pXGI->VBFlags & TV_YPBPR) && (pXGI->VBFlags & TV_YPBPR525I))
+- || ((!(pXGI->VBFlags & TV_YPBPR))
+- && (pXGI->VBFlags & (TV_NTSC | TV_PALM)))) {
+- inXGIIDXREG(XGICR, 0x34, tmpreg);
+- tmpreg &= 0x7f;
+- if ((tmpreg == 0x64) || (tmpreg == 0x4a) || (tmpreg == 0x38)) {
+- pXGI->MiscFlags |= MISC_TVNTSC1024;
+- }
+- }
+- }
+-
+- /* Reset XV gamma correction */
+- if (pXGI->ResetXvGamma) {
+- (pXGI->ResetXvGamma) (pScrn);
+- }
+-
+- /* Apply TV settings given by options
+- * Do this even in DualHeadMode:
+- * - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
+- * - if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
+- * -> Hence, in both cases, the settings must be re-applied.
+- */
+-}
+-
+-
+-USHORT
+-XGI_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode,
+- unsigned long VBFlags)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- UShort i = (pXGI->CurrentLayout.bitsPerPixel + 7) / 8 - 1;
+-
+- if ((VBFlags & CRT1_LCDA)) {
+- if ((mode->HDisplay > pXGI->LCDwidth) ||
+- (mode->VDisplay > pXGI->LCDheight)) {
+- return 0;
+- }
+- }
+-
+- return XGI_GetModeID(VBFlags, mode->HDisplay, mode->VDisplay,
+- i, pXGI->LCDwidth, pXGI->LCDheight);
+-}
+-
+-/* Calculate the vertical refresh rate from a mode */
+-int
+-XGICalcVRate(DisplayModePtr mode)
+-{
+- float hsync, refresh = 0;
+-
+- if (mode->HSync > 0.0)
+- hsync = mode->HSync;
+- else if (mode->HTotal > 0)
+- hsync = (float) mode->Clock / (float) mode->HTotal;
+- else
+- hsync = 0.0;
+-
+- if (mode->VTotal > 0)
+- refresh = hsync * 1000.0 / mode->VTotal;
+-
+- if (mode->Flags & V_INTERLACE)
+- refresh *= 2.0;
+-
+- if (mode->Flags & V_DBLSCAN)
+- refresh /= 2.0;
+-
+- if (mode->VScan > 1)
+- refresh /= mode->VScan;
+-
+- if (mode->VRefresh > 0.0)
+- refresh = mode->VRefresh;
+-
+- if (hsync == 0 || refresh == 0)
+- return (0);
+-
+- return ((int) (refresh));
+-}
+-
+-/* Calculate CR33 (rate index) for CRT1.
+- * Calculation is done using currentmode, therefore it is
+- * recommended to set VertRefresh and HorizSync to correct
+- * values in config file.
+- */
+-unsigned char
+-XGISearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+-/* XGIPtr pXGI = XGIPTR(pScrn); */
+- int i = 0;
+- int irefresh;
+- unsigned short xres = mode->HDisplay;
+- unsigned short yres = mode->VDisplay;
+- unsigned char index;
+- BOOLEAN checkxgi730 = FALSE;
+-
+- irefresh = XGICalcVRate(mode);
+- if (!irefresh) {
+- if (xres == 800 || xres == 1024 || xres == 1280)
+- return 0x02;
+- else
+- return 0x01;
+- }
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
+-#endif
+-
+- /* We need the REAL refresh rate here */
+- if (mode->Flags & V_INTERLACE)
+- irefresh /= 2;
+-
+- /* Do not multiply by 2 when DBLSCAN! */
+-
+-#ifdef TWDEBUG
+- xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
+-#endif
+-
+- index = 0;
+- while ((xgix_vrate[i].idx != 0) && (xgix_vrate[i].xres <= xres)) {
+- if ((xgix_vrate[i].xres == xres) && (xgix_vrate[i].yres == yres)) {
+- if ((checkxgi730 == FALSE)
+- || (xgix_vrate[i].XGI730valid32bpp == TRUE)) {
+- if (xgix_vrate[i].refresh == irefresh) {
+- index = xgix_vrate[i].idx;
+- break;
+- }
+- else if (xgix_vrate[i].refresh > irefresh) {
+- if ((xgix_vrate[i].refresh - irefresh) <= 3) {
+- index = xgix_vrate[i].idx;
+- }
+- else if (((checkxgi730 == FALSE)
+- || (xgix_vrate[i - 1].XGI730valid32bpp == TRUE))
+- && ((irefresh - xgix_vrate[i - 1].refresh) <= 2)
+- && (xgix_vrate[i].idx != 1)) {
+- index = xgix_vrate[i - 1].idx;
+- }
+- break;
+- }
+- else if ((irefresh - xgix_vrate[i].refresh) <= 2) {
+- index = xgix_vrate[i].idx;
+- break;
+- }
+- }
+- }
+- i++;
+- }
+- if (index > 0)
+- return index;
+- else {
+- /* Default Rate index */
+- if (xres == 800 || xres == 1024 || xres == 1280)
+- return 0x02;
+- else
+- return 0x01;
+- }
+-}
+-
+-
+-#define MODEID_OFF 0x449
+-
+-unsigned char
+-XGI_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
+-{
+- return (XGI_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
+-}
+-
+-unsigned char
+-XGI_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
+-{
+- unsigned char ret = 0;
+-#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
+- unsigned char *base;
+-
+- base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
+- if (!base) {
+- XGIErrorLog(pScrn, "(Could not map BIOS scratch area)\n");
+- return 0;
+- }
+-
+- ret = *(base + offset);
+-
+- /* value != 0xff means: set register */
+- if (value != 0xff)
+- *(base + offset) = value;
+-
+- xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
+-#endif
+- return ret;
+-}
+-
+-void
+-xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
+- unsigned char *reg2)
+-{
+- register unsigned char val;
+- unsigned long mylockcalls;
+-
+- pXGI->lockcalls++;
+- mylockcalls = pXGI->lockcalls;
+-
+- /* check if already unlocked */
+- inXGIIDXREG(XGISR, 0x05, val);
+- if (val != 0xa1) {
+- /* save State */
+- if (reg1)
+- *reg1 = val;
+- /* unlock */
+-/*
+- outb (0x3c4, 0x20);
+- val4 = inb (0x3c5);
+- val4 |= 0x20;
+- outb (0x3c5, val4);
+-*/
+- outXGIIDXREG(XGISR, 0x05, 0x86);
+- inXGIIDXREG(XGISR, 0x05, val);
+- if (val != 0xA1) {
+-#ifdef TWDEBUG
+- unsigned char val1, val2;
+- int i;
+-#endif
+- XGIErrorLog(pXGI->pScrn,
+- "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
+- (void *) pXGI, (unsigned long) pXGI->RelIO, val,
+- mylockcalls);
+-#ifdef TWDEBUG
+- for (i = 0; i <= 0x3f; i++) {
+- inXGIIDXREG(XGISR, i, val1);
+- inXGIIDXREG(0x3c4, i, val2);
+- xf86DrvMsg(pXGI->pScrn->scrnIndex, X_INFO,
+- "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n",
+- i, val1, val2, mylockcalls);
+- }
+-#endif
+- }
+- }
+-}
+-
+-void
+-xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, unsigned char reg2)
+-{
+- /* restore lock */
+-#ifndef UNLOCK_ALWAYS
+- outXGIIDXREG(XGISR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
+-#endif
+-}
+-
+-
+-#ifdef DEBUG
+-void
+-XGIDumpSR(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("SR xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x40; i += 0x10) {
+- ErrorF("SR[%02X]:", i);
+- for (j = 0; j < 16; j++) {
+- inXGIIDXREG(XGISR, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+- ErrorF("\n");
+-}
+-
+-void
+-XGIDumpCR(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("CR xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x100; i += 0x10) {
+- ErrorF("CR[%02X]:", i);
+- for (j = 0; j < 16; j++) {
+- inXGIIDXREG(XGICR, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpGR(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("GR xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("GR:");
+- for (i = 0; i < 0x9; i += 0x10) {
+- inXGIIDXREG(XGISR, i, temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+-}
+-
+-
+-void
+-XGIDumpPart0(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("PART0 xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x50; i += 0x10) {
+- ErrorF("PART0[%02X]:", i);
+- for (j = 0; j < 0x10; j++) {
+- inXGIIDXREG(XGIPART0, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpPart05(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- int i, j;
+- unsigned long temp;
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("PART05 xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x50; i += 0x10) {
+- ErrorF("PART05[%02X]:", i);
+- for (j = 0; j < 0x10; j++) {
+- inXGIIDXREG(XGIPART05, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpPart1(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("PART1 xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x100; i += 0x10) {
+- ErrorF("PART1[%02X]:", i);
+- for (j = 0; j < 0x10; j++) {
+- inXGIIDXREG(XGIPART1, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpPart2(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("PART2 xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x100; i += 0x10) {
+- ErrorF("PART2[%02X]:", i);
+- for (j = 0; j < 0x10; j++) {
+- inXGIIDXREG(XGIPART2, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpPart3(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("PART3 xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+-
+- for (i = 0; i < 0x100; i += 0x10) {
+- ErrorF("PART3[%02X]:", i);
+- for (j = 0; j < 0x10; j++) {
+- inXGIIDXREG(XGIPART3, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpPart4(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i, j;
+- unsigned long temp;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("PART4 xx\n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0x100; i += 0x10) {
+- ErrorF("PART4[%02X]:", i);
+- for (j = 0; j < 0x10; j++) {
+- inXGIIDXREG(XGIPART4, (i + j), temp);
+- ErrorF(" %02lX", temp);
+- }
+- ErrorF("\n");
+- }
+-}
+-
+-void
+-XGIDumpMMIO(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- int i;
+- unsigned long temp;
+-/*
+- ErrorF("----------------------------------------------------------------------\n") ;
+- ErrorF("MMIO 85xx\n") ;
+- ErrorF("----------------------------------------------------------------------\n") ;
+- for( i = 0x8500 ; i < 0x8600 ; i+=0x10 )
+- {
+- ErrorF("[%04X]: %08lX %08lX %08lX %08lX\n",i,
+- XGIMMIOLONG(i),
+- XGIMMIOLONG(i+4),
+- XGIMMIOLONG(i+8),
+- XGIMMIOLONG(i+12)) ;
+- }
+-*/
+-}
+-#endif /* DEBUG */
+-
+-void
+-XGIDumpRegs(ScrnInfoPtr pScrn)
+-{
+-#ifdef DEBUG
+-
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- XGIDumpSR(pScrn);
+- XGIDumpCR(pScrn);
+-// XGIDumpGR(pScrn);
+-// XGIDumpPalette(pScrn);
+- XGIDumpMMIO(pScrn);
+- if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
+- XGIDumpPart0(pScrn);
+- XGIDumpPart05(pScrn);
+- XGIDumpPart1(pScrn);
+- XGIDumpPart2(pScrn);
+- XGIDumpPart3(pScrn);
+- XGIDumpPart4(pScrn);
+- }
+-
+-#endif /* DEBUG */
+-}
+-
+-
+-void
+-XGIDumpPalette(ScrnInfoPtr pScrn)
+-{
+-#ifdef DEBUG
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned temp[3];
+- int i, j;
+-
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- ErrorF("Palette \n");
+- ErrorF
+- ("----------------------------------------------------------------------\n");
+- for (i = 0; i < 0xFF; i += 0x04) {
+- for (j = 0; j < 16; j++) {
+- outb(0x3c7, i + j);
+- temp[0] = inb(0x3c9);
+- temp[1] = inb(0x3c9);
+- temp[2] = inb(0x3c9);
+-
+- ErrorF("PA[%02X]: %02X %02X %02X", i + j,
+- temp[0], temp[1], temp[2]);
+- }
+- ErrorF("\n");
+- }
+- ErrorF("\n");
+-#endif
+-}
++/*
++ * XGI driver main code
++ *
++ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1) Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2) Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3) The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ * - driver entirely rewritten since 2001, only basic structure taken from
++ * old code (except xgi_dri.c, xgi_shadow.c, xgi_accel.c and parts of
++ * xgi_dga.c; these were mostly taken over; xgi_dri.c was changed for
++ * new versions of the DRI layer)
++ *
++ * This notice covers the entire driver code unless otherwise indicated.
++ *
++ * Formerly based on code which is
++ * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
++ * Written by:
++ * Alan Hourihane <alanh@fairlite.demon.co.uk>,
++ * Mike Chapman <mike@paranoia.com>,
++ * Juanjo Santamarta <santamarta@ctv.es>,
++ * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
++ * David Thomas <davtom@dream.org.uk>.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++/* Jong 09/27/2007; added for PACKAGE_VERSION_MAJOR,... */
++#define PACKAGE_VERSION_MAJOR 1
++#define PACKAGE_VERSION_MINOR 1
++#define PACKAGE_VERSION_PATCHLEVEL 0
++
++#include "fb.h"
++#include "mibank.h"
++#include "micmap.h"
++#include "xf86.h"
++#include "xf86Priv.h"
++#include "xf86_OSproc.h"
++#include "xf86Resources.h"
++#include "dixstruct.h"
++#include "xf86Version.h"
++#include "xf86PciInfo.h"
++#include "xf86Pci.h"
++#include "xf86cmap.h"
++#include "vgaHW.h"
++#include "xf86RAC.h"
++#include "shadowfb.h"
++#include "vbe.h"
++
++#include "mipointer.h"
++#include "mibstore.h"
++
++#include "xgi.h"
++#include "xgi_regs.h"
++#include "xgi_vb.h"
++#include "xgi_dac.h"
++#include "vb_def.h"
++#include "xgi_driver.h"
++#include "valid_mode.h"
++
++#define _XF86DGA_SERVER_
++#include <X11/extensions/xf86dgastr.h>
++
++#include "globals.h"
++
++#define DPMS_SERVER
++#include <X11/extensions/dpms.h>
++
++#if defined(XvExtension)
++#include "xf86xv.h"
++#include <X11/extensions/Xv.h>
++#endif
++
++#ifdef XF86DRI
++#include "dri.h"
++#endif
++
++#ifdef HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++
++#include <fcntl.h>
++#include <sys/ioctl.h>
++
++#ifdef XSERVER_LIBPCIACCESS
++static Bool XGIPciProbe(DriverPtr drv, int entity_num,
++ struct pci_device *dev, intptr_t match_data);
++#else
++static Bool XGIProbe(DriverPtr drv, int flags);
++#endif
++
++void Volari_EnableAccelerator(ScrnInfoPtr pScrn);
++/* Globals (yes, these ARE really required to be global) */
++
++#ifdef XGIDUALHEAD
++static int XGIEntityIndex = -1;
++#endif
++
++/* Jong 09/19/2007; support modeline */
++int g_CountOfUserDefinedModes=0;
++xf86MonPtr g_pMonitorDVI=NULL; /* Jong 12/04/2007; used for filtering of CRT1 modes */
++
++/*
++ * This is intentionally screen-independent. It indicates the binding
++ * choice made in the first PreInit.
++ */
++static int pix24bpp = 0;
++int FbDevExist;
++
++#define FBIOGET_FSCREENINFO 0x4602
++#define FB_ACCEL_XGI_GLAMOUR 41
++
++struct fb_fix_screeninfo
++{
++ char id[16]; /* identification string eg "TT Builtin" */
++ unsigned long smem_start; /* Start of frame buffer mem */
++ /* (physical address) */
++ unsigned long smem_len; /* Length of frame buffer mem */
++ unsigned long type; /* see FB_TYPE_* */
++ unsigned long type_aux; /* Interleave for interleaved Planes */
++ unsigned long visual; /* see FB_VISUAL_* */
++ unsigned short xpanstep; /* zero if no hardware panning */
++ unsigned short ypanstep; /* zero if no hardware panning */
++ unsigned short ywrapstep; /* zero if no hardware ywrap */
++ unsigned long line_length; /* length of a line in bytes */
++ unsigned long mmio_start; /* Start of Memory Mapped I/O */
++ /* (physical address) */
++ unsigned long mmio_len; /* Length of Memory Mapped I/O */
++ unsigned long accel; /* Type of acceleration available */
++ unsigned short reserved[3]; /* Reserved for future compatibility */
++};
++
++#ifdef XSERVER_LIBPCIACCESS
++#define XGI_DEVICE_MATCH(d, i) \
++ { 0x18ca, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
++
++static const struct pci_id_match xgi_device_match[] = {
++ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG40, 0),
++ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG20, 1),
++ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG21, 2),
++ XGI_DEVICE_MATCH(PCI_CHIP_XGIXG27, 3),
++ { 0, 0, 0 },
++};
++#endif
++
++/*
++ * This contains the functions needed by the server after loading the driver
++ * module. It must be supplied, and gets passed back by the SetupProc
++ * function in the dynamic case. In the static case, a reference to this
++ * is compiled in, and this requires that the name of this DriverRec be
++ * an upper-case version of the driver name.
++ */
++
++DriverRec XGI = {
++ XGI_CURRENT_VERSION,
++ XGI_DRIVER_NAME,
++ XGIIdentify,
++#ifdef XSERVER_LIBPCIACCESS
++ NULL,
++#else
++ XGIProbe,
++#endif
++ XGIAvailableOptions,
++ NULL,
++ 0,
++ NULL,
++
++#ifdef XSERVER_LIBPCIACCESS
++ xgi_device_match,
++ XGIPciProbe
++#endif
++};
++
++static SymTabRec XGIChipsets[] = {
++ {PCI_CHIP_XGIXG40, "Volari V8_V5_V3XT"},
++ {PCI_CHIP_XGIXG20, "Volari Z7_Z9_Z9s"},
++ {PCI_CHIP_XGIXG21, "Volari Z9_Z9s"},
++ {PCI_CHIP_XGIXG27, "Volari Z11"},
++ {-1, NULL}
++};
++
++static PciChipsets XGIPciChipsets[] = {
++ {PCI_CHIP_XGIXG40, PCI_CHIP_XGIXG40, RES_SHARED_VGA},
++ {PCI_CHIP_XGIXG20, PCI_CHIP_XGIXG20, RES_SHARED_VGA},
++ {PCI_CHIP_XGIXG21, PCI_CHIP_XGIXG21, RES_SHARED_VGA },
++ {PCI_CHIP_XGIXG27, PCI_CHIP_XGIXG27, RES_SHARED_VGA },
++ {-1, -1, RES_UNDEFINED}
++};
++
++static const char *xaaSymbols[] = {
++ "XAACopyROP",
++ "XAACreateInfoRec",
++ "XAADestroyInfoRec",
++ "XAAFillMono8x8PatternRects",
++ "XAAPatternROP",
++ "XAAHelpPatternROP",
++ "XAAInit",
++ NULL
++};
++
++static const char *vgahwSymbols[] = {
++ "vgaHWFreeHWRec",
++ "vgaHWGetHWRec",
++ "vgaHWGetIOBase",
++ "vgaHWGetIndex",
++ "vgaHWInit",
++ "vgaHWLock",
++ "vgaHWMapMem",
++ "vgaHWUnmapMem",
++ "vgaHWProtect",
++ "vgaHWRestore",
++ "vgaHWSave",
++ "vgaHWSaveScreen",
++ "vgaHWUnlock",
++ NULL
++};
++
++static const char *fbSymbols[] = {
++ "fbPictureInit",
++ "fbScreenInit",
++ NULL
++};
++
++static const char *shadowSymbols[] = {
++ "ShadowFBInit",
++ NULL
++};
++
++static const char *ramdacSymbols[] = {
++ "xf86CreateCursorInfoRec",
++ "xf86DestroyCursorInfoRec",
++ "xf86InitCursor",
++ NULL
++};
++
++
++static const char *ddcSymbols[] = {
++ "xf86PrintEDID",
++ "xf86SetDDCproperties",
++ "xf86InterpretEDID",
++ NULL
++};
++
++
++/* static const char *i2cSymbols[] = {
++ "xf86I2CBusInit",
++ "xf86CreateI2CBusRec",
++ NULL
++}; */
++
++static const char *int10Symbols[] = {
++ "xf86FreeInt10",
++ "xf86InitInt10",
++ "xf86ExecX86int10",
++ NULL
++};
++
++static const char *vbeSymbols[] = {
++ "VBEExtendedInit",
++ "vbeDoEDID",
++ "vbeFree",
++ "VBEGetVBEInfo",
++ "VBEFreeVBEInfo",
++ "VBEGetModeInfo",
++ "VBEFreeModeInfo",
++ "VBESaveRestore",
++ "VBESetVBEMode",
++ "VBEGetVBEMode",
++ "VBESetDisplayStart",
++ "VBESetGetLogicalScanlineLength",
++ NULL
++};
++
++#ifdef XF86DRI
++static const char *drmSymbols[] = {
++ "drmAddMap",
++ "drmAgpAcquire",
++ "drmAgpAlloc",
++ "drmAgpBase",
++ "drmAgpBind",
++ "drmAgpEnable",
++ "drmAgpFree",
++ "drmAgpGetMode",
++ "drmAgpRelease",
++ "drmCtlInstHandler",
++ "drmGetInterruptFromBusID",
++ "drmXGIAgpInit",
++ NULL
++};
++
++static const char *driSymbols[] = {
++ "DRICloseScreen",
++ "DRICreateInfoRec",
++ "DRIDestroyInfoRec",
++ "DRIFinishScreenInit",
++ "DRIGetSAREAPrivate",
++ "DRILock",
++ "DRIQueryVersion",
++ "DRIScreenInit",
++ "DRIUnlock",
++#ifdef XGINEWDRI2
++ "GlxSetVisualConfigs",
++ "DRICreatePCIBusID",
++#endif
++ NULL
++};
++#endif
++
++static MODULESETUPPROTO(xgiSetup);
++
++static XF86ModuleVersionInfo xgiVersRec = {
++ XGI_DRIVER_NAME,
++ MODULEVENDORSTRING,
++ MODINFOSTRING1,
++ MODINFOSTRING2,
++#ifdef XORG_VERSION_CURRENT
++ XORG_VERSION_CURRENT,
++#else
++ XF86_VERSION_CURRENT,
++#endif
++ PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
++ ABI_CLASS_VIDEODRV, /* This is a video driver */
++#ifdef ABI_VIDEODRV_VERSION
++ ABI_VIDEODRV_VERSION,
++#else
++ 6,
++#endif
++ MOD_CLASS_VIDEODRV,
++ {0, 0, 0, 0}
++};
++
++XF86ModuleData xgiModuleData = { &xgiVersRec, xgiSetup, NULL };
++
++/*** static string ***/
++#ifdef XGIMERGED
++static const char *mergednocrt1 = "CRT1 not detected or forced off. %s.\n";
++static const char *mergednocrt2 =
++ "No CRT2 output selected or no bridge detected. %s.\n";
++static const char *mergeddisstr = "MergedFB mode disabled";
++static const char *modesforstr =
++ "Modes for CRT%d: *********************************************\n";
++static const char *crtsetupstr =
++ "------------------------ CRT%d setup -------------------------\n";
++#endif
++
++typedef struct
++{
++ int width, height;
++ float VRefresh, HSync, DCLK;
++} ModeTiming;
++
++static const ModeTiming establish_timing[] = {
++ {800, 600, 60, 37.9, 40}, /* t1 D[0] */
++ {800, 600, 56, 35.1, 36}, /* t1 D[1] */
++ {640, 480, 75, 37.5, 31.5}, /* t1 D[2] */
++ {640, 480, 72, 37.9, 31.5}, /* t1 D[3] */
++ {-1, -1, -1, -1}, /* t1 D[4] 640x480@67Hz, ignore */
++ {640, 480, 60, 31.5, 25.175}, /* t1 D[5] */
++ {-1, -1, -1, -1}, /* t1 D[6] */
++ {-1, -1, -1, -1}, /* t1 D[7] */
++ {1280, 1024, 75, 80.0, 135}, /* t2 D[0] */
++ {1024, 768, 75, 60.0, 78.75}, /* t2 D[1] */
++ {1024, 768, 70, 56.5, 75}, /* t2 D[2] */
++ {1024, 768, 60, 48.4, 65}, /* t2 D[3] */
++ {-1, -1, -1, -1}, /* t2 D[4] 1024x768@87I, ignore */
++ {-1, -1, -1, -1}, /* t2 D[5] 832x624@75Hz, ignore */
++ {800, 600, 75, 46.9, 49.5}, /* t2 D[6] */
++ {800, 600, 72, 48.1, 50} /* t2 D[7] */
++};
++
++static const ModeTiming StdTiming[] = {
++ {640, 480, 60, 31.5, 25.175},
++ {640, 480, 72, 37.9, 31.5},
++ {640, 480, 75, 37.5, 31.5},
++ {640, 480, 85, 43.3, 36.0},
++
++ {800, 600, 56, 35.1, 36},
++ {800, 600, 60, 37.9, 40},
++ {800, 600, 72, 48.1, 50},
++ {800, 600, 75, 46.9, 49.5},
++ {800, 600, 85, 53.7, 56.25},
++
++ {1024, 768, 43, 35.5, 44.9},
++ {1024, 768, 60, 48.4, 65},
++ {1024, 768, 70, 56.5, 75},
++ {1024, 768, 75, 60, 78.75},
++ {1024, 768, 85, 68.7, 94.5},
++
++ {1152, 864, 75, 67.5, 108},
++
++ {1280, 960, 60, 60, 108},
++ {1280, 960, 85, 85.9, 148.5},
++ {1280, 1024, 60, 64.0, 108},
++ {1280, 1024, 75, 80, 135},
++ {1280, 1024, 85, 91.1, 157.5},
++
++ {1600, 1200, 60, 75, 162.0},
++ {1600, 1200, 65, 81.3, 175.5},
++ {1600, 1200, 70, 87.5, 189},
++ {1600, 1200, 75, 93.8, 202},
++ {1600, 1200, 85, 106.3, 229.5},
++
++ {1792, 1344, 60, 83.64, 204.75},
++ {1792, 1344, 75, 106.27, 261},
++
++ {1856, 1392, 60, 86.33, 218.25},
++ {1856, 1392, 75, 112.50, 288},
++
++ {1920, 1440, 60, 90, 234},
++ {1920, 1440, 75, 112.5, 297},
++ {-1, -1, -1, -1, -1},
++};
++
++
++static void XGIDumpPalette(ScrnInfoPtr pScrn);
++#ifdef DEBUG
++static void XGIDumpSR(ScrnInfoPtr pScrn);
++static void XGIDumpCR(ScrnInfoPtr pScrn);
++static void XGIDumpGR(ScrnInfoPtr pScrn);
++static void XGIDumpPart1(ScrnInfoPtr pScrn);
++static void XGIDumpPart2(ScrnInfoPtr pScrn);
++static void XGIDumpPart3(ScrnInfoPtr pScrn);
++static void XGIDumpPart4(ScrnInfoPtr pScrn);
++static void XGIDumpMMIO(ScrnInfoPtr pScrn);
++#endif
++
++static int XGICalcVRate(DisplayModePtr mode);
++static unsigned char XGISearchCRT1Rate(ScrnInfoPtr pScrn,
++ DisplayModePtr mode);
++static void xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
++ unsigned char *reg2);
++static void xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1,
++ unsigned char reg2);
++
++/* Jong 12/05/2007; check mode with monitor DDC */
++static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC);
++
++/* Jong 12/05/2007; filter mode list by monitor DDC */
++static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC);
++
++static pointer
++xgiSetup(pointer module, pointer opts, int *errmaj, int *errmin)
++{
++ static Bool setupDone = FALSE;
++
++ if (!setupDone) {
++ setupDone = TRUE;
++ xf86AddDriver(&XGI, module, HaveDriverFuncs);
++ LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols,
++ shadowSymbols, ramdacSymbols, ddcSymbols,
++ vbeSymbols, int10Symbols,
++#ifdef XF86DRI
++ drmSymbols, driSymbols,
++#endif
++ NULL);
++ return (pointer) TRUE;
++ }
++
++ if (errmaj)
++ *errmaj = LDR_ONCEONLY;
++ return NULL;
++}
++
++
++static XGIPtr
++XGIGetRec(ScrnInfoPtr pScrn)
++{
++ /*
++ * Allocate an XGIRec, and hook it into pScrn->driverPrivate.
++ * pScrn->driverPrivate is initialised to NULL, so we can check if
++ * the allocation has already been done.
++ */
++ if (pScrn->driverPrivate == NULL) {
++ XGIPtr pXGI = xnfcalloc(sizeof(XGIRec), 1);
++
++ /* Initialise it to 0 */
++ memset(pXGI, 0, sizeof(XGIRec));
++
++ pScrn->driverPrivate = pXGI;
++ pXGI->pScrn = pScrn;
++ }
++
++ return (XGIPtr) pScrn->driverPrivate;
++}
++
++static void
++XGIFreeRec(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ XGIEntPtr pXGIEnt = NULL;
++
++ /* Just to make sure... */
++ if (!pXGI)
++ return;
++
++ pXGIEnt = ENTITY_PRIVATE(pXGI);
++ if (pXGIEnt) {
++ if (!IS_SECOND_HEAD(pXGI)) {
++ /* Free memory only if we are first head; in case of an error
++ * during init of the second head, the server will continue -
++ * and we need the BIOS image and VB_DEVICE_INFO for the first
++ * head.
++ */
++ if (pXGIEnt->BIOS)
++ xfree(pXGIEnt->BIOS);
++ pXGIEnt->BIOS = pXGI->BIOS = NULL;
++ if (pXGIEnt->XGI_Pr)
++ xfree(pXGIEnt->XGI_Pr);
++ pXGIEnt->XGI_Pr = pXGI->XGI_Pr = NULL;
++ if (pXGIEnt->RenderAccelArray)
++ xfree(pXGIEnt->RenderAccelArray);
++ pXGIEnt->RenderAccelArray = pXGI->RenderAccelArray = NULL;
++ }
++ else {
++ pXGI->BIOS = NULL;
++ pXGI->XGI_Pr = NULL;
++ pXGI->RenderAccelArray = NULL;
++ }
++ }
++ else {
++ if (pXGI->BIOS)
++ xfree(pXGI->BIOS);
++ pXGI->BIOS = NULL;
++ if (pXGI->XGI_Pr)
++ xfree(pXGI->XGI_Pr);
++ pXGI->XGI_Pr = NULL;
++ if (pXGI->RenderAccelArray)
++ xfree(pXGI->RenderAccelArray);
++ pXGI->RenderAccelArray = NULL;
++ }
++
++#ifdef XGIMERGED
++ if (pXGI->MetaModes)
++ xfree(pXGI->MetaModes);
++ pXGI->MetaModes = NULL;
++
++ if (pXGI->CRT1Modes) {
++ if (pXGI->CRT1Modes != pScrn->modes) {
++ if (pScrn->modes) {
++ pScrn->currentMode = pScrn->modes;
++ do {
++ DisplayModePtr p = pScrn->currentMode->next;
++ if (pScrn->currentMode->Private)
++ xfree(pScrn->currentMode->Private);
++ xfree(pScrn->currentMode);
++ pScrn->currentMode = p;
++ } while (pScrn->currentMode != pScrn->modes);
++ }
++ pScrn->currentMode = pXGI->CRT1CurrentMode;
++ pScrn->modes = pXGI->CRT1Modes;
++ pXGI->CRT1CurrentMode = NULL;
++ pXGI->CRT1Modes = NULL;
++ }
++ }
++#endif
++ if (pXGI->pVbe)
++ vbeFree(pXGI->pVbe);
++ pXGI->pVbe = NULL;
++ if (pScrn->driverPrivate == NULL)
++ return;
++ xfree(pScrn->driverPrivate);
++ pScrn->driverPrivate = NULL;
++}
++
++static void
++XGIDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
++ int flags)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ BOOLEAN docrt1 = TRUE, docrt2 = TRUE;
++ unsigned char sr1 = 0, cr17 = 0, cr63 = 0, sr11 = 0, pmreg = 0, sr7 = 0;
++ unsigned char p1_13 = 0, p2_0 = 0, oldpmreg = 0;
++ BOOLEAN backlight = TRUE;
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
++ "XGIDisplayPowerManagementSet(%d)\n", PowerManagementMode);
++
++ if (IS_DUAL_HEAD(pXGI)) {
++ if (IS_SECOND_HEAD(pXGI))
++ docrt2 = FALSE;
++ else
++ docrt1 = FALSE;
++ }
++
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++#endif
++
++ switch (PowerManagementMode) {
++
++ case DPMSModeOn: /* HSync: On, VSync: On */
++ if (docrt1)
++ pXGI->Blank = FALSE;
++
++ sr1 = 0x00;
++ cr17 = 0x80;
++ pmreg = 0x00;
++ cr63 = 0x00;
++ sr7 = 0x10;
++ sr11 = (pXGI->LCDon & 0x0C);
++ p2_0 = 0x20;
++ p1_13 = 0x00;
++ backlight = TRUE;
++ break;
++
++ case DPMSModeSuspend: /* HSync: On, VSync: Off */
++ if (docrt1)
++ pXGI->Blank = TRUE;
++
++ sr1 = 0x20;
++ cr17 = 0x80;
++ pmreg = 0x80;
++ cr63 = 0x40;
++ sr7 = 0x00;
++ sr11 = 0x08;
++ p2_0 = 0x40;
++ p1_13 = 0x80;
++ backlight = FALSE;
++ break;
++
++ case DPMSModeStandby: /* HSync: Off, VSync: On */
++ if (docrt1)
++ pXGI->Blank = TRUE;
++
++ sr1 = 0x20;
++ cr17 = 0x80;
++ pmreg = 0x40;
++ cr63 = 0x40;
++ sr7 = 0x00;
++ sr11 = 0x08;
++ p2_0 = 0x80;
++ p1_13 = 0x40;
++ backlight = FALSE;
++ break;
++
++ case DPMSModeOff: /* HSync: Off, VSync: Off */
++ if (docrt1)
++ pXGI->Blank = TRUE;
++
++ sr1 = 0x20;
++ cr17 = 0x00;
++ pmreg = 0xc0;
++ cr63 = 0x40;
++ sr7 = 0x00;
++ sr11 = 0x08;
++ p2_0 = 0xc0;
++ p1_13 = 0xc0;
++ backlight = FALSE;
++ break;
++
++ default:
++ return;
++ }
++
++ if (docrt1) {
++ /* Set/Clear "Display On" bit
++ */
++ setXGIIDXREG(XGISR, 0x01, ~0x20, sr1);
++
++ if ((!(pXGI->VBFlags & CRT1_LCDA))
++ || (pXGI->XGI_Pr->VBType & VB_XGI301C)) {
++ inXGIIDXREG(XGISR, 0x1f, oldpmreg);
++ if (!pXGI->CRT1off) {
++ setXGIIDXREG(XGISR, 0x1f, 0x3f, pmreg);
++ }
++ }
++ oldpmreg &= 0xc0;
++ }
++
++ if ((docrt1) && (pmreg != oldpmreg)
++ && ((!(pXGI->VBFlags & CRT1_LCDA))
++ || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
++ outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
++ usleep(10000);
++ outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
++ }
++
++}
++
++/* Mandatory */
++static void
++XGIIdentify(int flags)
++{
++ xf86PrintChipsets(XGI_NAME, "driver for XGI chipsets", XGIChipsets);
++ PDEBUG(ErrorF(" --- XGIIdentify \n"));
++}
++
++static void
++XGIErrorLog(ScrnInfoPtr pScrn, const char *format, ...)
++{
++ va_list ap;
++ static const char *str =
++ "**************************************************\n";
++
++ va_start(ap, format);
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " ERROR:\n");
++ xf86VDrvMsgVerb(pScrn->scrnIndex, X_ERROR, 1, format, ap);
++ va_end(ap);
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ " END OF MESSAGE\n");
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, str);
++}
++
++#ifdef XSERVER_LIBPCIACCESS
++static Bool XGIPciProbe(DriverPtr drv, int entity_num,
++ struct pci_device *dev, intptr_t match_data)
++{
++ ScrnInfoPtr pScrn;
++
++
++ pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL,
++ NULL, NULL, NULL, NULL, NULL);
++ if (pScrn != NULL) {
++ XGIPtr pXGI;
++
++ /* Fill in what we can of the ScrnInfoRec */
++ pScrn->driverVersion = XGI_CURRENT_VERSION;
++ pScrn->driverName = XGI_DRIVER_NAME;
++ pScrn->name = XGI_NAME;
++ pScrn->Probe = NULL;
++ pScrn->PreInit = XGIPreInit;
++ pScrn->ScreenInit = XGIScreenInit;
++ pScrn->SwitchMode = XGISwitchMode;
++ pScrn->AdjustFrame = XGIAdjustFrame;
++ pScrn->EnterVT = XGIEnterVT;
++ pScrn->LeaveVT = XGILeaveVT;
++ pScrn->FreeScreen = XGIFreeScreen;
++ pScrn->ValidMode = XGIValidMode;
++
++
++ pXGI = XGIGetRec(pScrn);
++ if (pXGI == NULL) {
++ return FALSE;
++ }
++
++ pXGI->PciInfo = dev;
++ }
++
++ return (pScrn != NULL);
++}
++
++#else
++
++/* Mandatory */
++static Bool
++XGIProbe(DriverPtr drv, int flags)
++{
++ int i;
++ GDevPtr *devSections;
++ int *usedChips;
++ int numDevSections;
++ int numUsed;
++ Bool foundScreen = FALSE;
++
++ /*
++ * The aim here is to find all cards that this driver can handle,
++ * and for the ones not already claimed by another driver, claim the
++ * slot, and allocate a ScrnInfoRec.
++ *
++ * This should be a minimal probe, and it should under no circumstances
++ * change the state of the hardware. Because a device is found, don't
++ * assume that it will be used. Don't do any initialisations other than
++ * the required ScrnInfoRec initialisations. Don't allocate any new
++ * data structures.
++ *
++ */
++
++ /*
++ * Next we check, if there has been a chipset override in the config file.
++ * For this we must find out if there is an active device section which
++ * is relevant, i.e., which has no driver specified or has THIS driver
++ * specified.
++ */
++
++ if ((numDevSections =
++ xf86MatchDevice(XGI_DRIVER_NAME, &devSections)) <= 0) {
++ /*
++ * There's no matching device section in the config file, so quit
++ * now.
++ */
++ return FALSE;
++ }
++
++ PDEBUG(ErrorF(" --- XGIProbe \n"));
++ /*
++ * We need to probe the hardware first. We then need to see how this
++ * fits in with what is given in the config file, and allow the config
++ * file info to override any contradictions.
++ */
++
++ /*
++ * All of the cards this driver supports are PCI, so the "probing" just
++ * amounts to checking the PCI data that the server has already collected.
++ */
++ if (xf86GetPciVideoInfo() == NULL) {
++ /*
++ * We won't let anything in the config file override finding no
++ * PCI video cards at all. This seems reasonable now, but we'll see.
++ */
++ return FALSE;
++ }
++
++ numUsed = xf86MatchPciInstances(XGI_NAME, PCI_VENDOR_XGI,
++ XGIChipsets, XGIPciChipsets, devSections,
++ numDevSections, drv, &usedChips);
++
++ /* Free it since we don't need that list after this */
++ xfree(devSections);
++ if (numUsed <= 0)
++ return FALSE;
++
++ if (flags & PROBE_DETECT) {
++ foundScreen = TRUE;
++ }
++ else
++ for (i = 0; i < numUsed; i++) {
++ ScrnInfoPtr pScrn;
++#ifdef XGIDUALHEAD
++ EntityInfoPtr pEnt;
++#endif
++
++ /* Allocate a ScrnInfoRec and claim the slot */
++ pScrn = NULL;
++
++ if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
++ XGIPciChipsets, NULL, NULL,
++ NULL, NULL, NULL))) {
++ /* Fill in what we can of the ScrnInfoRec */
++ pScrn->driverVersion = XGI_CURRENT_VERSION;
++ pScrn->driverName = XGI_DRIVER_NAME;
++ pScrn->name = XGI_NAME;
++ pScrn->Probe = XGIProbe;
++ pScrn->PreInit = XGIPreInit;
++ pScrn->ScreenInit = XGIScreenInit;
++ pScrn->SwitchMode = XGISwitchMode;
++ pScrn->AdjustFrame = XGIAdjustFrame;
++ pScrn->EnterVT = XGIEnterVT;
++ pScrn->LeaveVT = XGILeaveVT;
++ pScrn->FreeScreen = XGIFreeScreen;
++ pScrn->ValidMode = XGIValidMode;
++ foundScreen = TRUE;
++ }
++#ifdef XGIDUALHEAD
++ pEnt = xf86GetEntityInfo(usedChips[i]);
++
++#endif
++ }
++ xfree(usedChips);
++
++ return foundScreen;
++}
++#endif
++
++
++/* Some helper functions for MergedFB mode */
++
++#ifdef XGIMERGED
++
++/* Copy and link two modes form mergedfb mode
++ * (Code base taken from mga driver)
++ * Copys mode i, links the result to dest, and returns it.
++ * Links i and j in Private record.
++ * If dest is NULL, return value is copy of i linked to itself.
++ * For mergedfb auto-config, we only check the dimension
++ * against virtualX/Y, if they were user-provided.
++ */
++static DisplayModePtr
++XGICopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
++ DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ DisplayModePtr mode;
++ int dx = 0, dy = 0;
++
++ if (!((mode = xalloc(sizeof(DisplayModeRec)))))
++ return dest;
++ memcpy(mode, i, sizeof(DisplayModeRec));
++ if (!((mode->Private = xalloc(sizeof(XGIMergedDisplayModeRec))))) {
++ xfree(mode);
++ return dest;
++ }
++ ((XGIMergedDisplayModePtr) mode->Private)->CRT1 = i;
++ ((XGIMergedDisplayModePtr) mode->Private)->CRT2 = j;
++ ((XGIMergedDisplayModePtr) mode->Private)->CRT2Position = srel;
++ mode->PrivSize = 0;
++
++ switch (srel) {
++ case xgiLeftOf:
++ case xgiRightOf:
++ if (!(pScrn->display->virtualX)) {
++ dx = i->HDisplay + j->HDisplay;
++ }
++ else {
++ dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
++ }
++ dx -= mode->HDisplay;
++ if (!(pScrn->display->virtualY)) {
++ dy = max(i->VDisplay, j->VDisplay);
++ }
++ else {
++ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
++ }
++ dy -= mode->VDisplay;
++ break;
++ case xgiAbove:
++ case xgiBelow:
++ if (!(pScrn->display->virtualY)) {
++ dy = i->VDisplay + j->VDisplay;
++ }
++ else {
++ dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
++ }
++ dy -= mode->VDisplay;
++ if (!(pScrn->display->virtualX)) {
++ dx = max(i->HDisplay, j->HDisplay);
++ }
++ else {
++ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
++ }
++ dx -= mode->HDisplay;
++ break;
++ case xgiClone:
++ if (!(pScrn->display->virtualX)) {
++ dx = max(i->HDisplay, j->HDisplay);
++ }
++ else {
++ dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
++ }
++ dx -= mode->HDisplay;
++ if (!(pScrn->display->virtualY)) {
++ dy = max(i->VDisplay, j->VDisplay);
++ }
++ else {
++ dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
++ }
++ dy -= mode->VDisplay;
++ break;
++ }
++ mode->HDisplay += dx;
++ mode->HSyncStart += dx;
++ mode->HSyncEnd += dx;
++ mode->HTotal += dx;
++ mode->VDisplay += dy;
++ mode->VSyncStart += dy;
++ mode->VSyncEnd += dy;
++ mode->VTotal += dy;
++ mode->Clock = 0;
++
++ if (((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) >
++ pXGI->maxxfbmem) || (mode->HDisplay > 4088)
++ || (mode->VDisplay > 4096)) {
++
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ "Skipped %dx%d, not enough video RAM or beyond hardware specs\n",
++ mode->HDisplay, mode->VDisplay);
++ xfree(mode->Private);
++ xfree(mode);
++
++ return dest;
++ }
++
++#ifdef XGIXINERAMA
++ if (srel != xgiClone) {
++ pXGI->AtLeastOneNonClone = TRUE;
++ }
++#endif
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Merged %dx%d and %dx%d to %dx%d%s\n",
++ i->HDisplay, i->VDisplay, j->HDisplay, j->VDisplay,
++ mode->HDisplay, mode->VDisplay,
++ (srel == xgiClone) ? " (Clone)" : "");
++
++ mode->next = mode;
++ mode->prev = mode;
++
++ if (dest) {
++ mode->next = dest->next; /* Insert node after "dest" */
++ dest->next->prev = mode;
++ mode->prev = dest;
++ dest->next = mode;
++ }
++
++ return mode;
++}
++
++/* Helper function to find a mode from a given name
++ * (Code base taken from mga driver)
++ */
++static DisplayModePtr
++XGIGetModeFromName(char *str, DisplayModePtr i)
++{
++ DisplayModePtr c = i;
++ if (!i)
++ return NULL;
++ do {
++ if (strcmp(str, c->name) == 0)
++ return c;
++ c = c->next;
++ } while (c != i);
++ return NULL;
++}
++
++static DisplayModePtr
++XGIFindWidestTallestMode(DisplayModePtr i, Bool tallest)
++{
++ DisplayModePtr c = i, d = NULL;
++ int max = 0;
++ if (!i)
++ return NULL;
++ do {
++ if (tallest) {
++ if (c->VDisplay > max) {
++ max = c->VDisplay;
++ d = c;
++ }
++ }
++ else {
++ if (c->HDisplay > max) {
++ max = c->HDisplay;
++ d = c;
++ }
++ }
++ c = c->next;
++ } while (c != i);
++ return d;
++}
++
++static DisplayModePtr
++XGIGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
++ DisplayModePtr i, DisplayModePtr j,
++ XGIScrn2Rel srel)
++{
++#ifdef XGIXINERAMA
++ XGIPtr pXGI = XGIPTR(pScrn);
++#endif
++ DisplayModePtr mode1 = NULL;
++ DisplayModePtr mode2 = NULL;
++ DisplayModePtr result = NULL;
++
++#ifdef XGIXINERAMA
++ pXGI->AtLeastOneNonClone = FALSE;
++#endif
++
++ switch (srel) {
++ case xgiLeftOf:
++ case xgiRightOf:
++ mode1 = XGIFindWidestTallestMode(i, FALSE);
++ mode2 = XGIFindWidestTallestMode(j, FALSE);
++ break;
++ case xgiAbove:
++ case xgiBelow:
++ mode1 = XGIFindWidestTallestMode(i, TRUE);
++ mode2 = XGIFindWidestTallestMode(j, TRUE);
++ break;
++ case xgiClone:
++ mode1 = i;
++ mode2 = j;
++ }
++
++ if (mode1 && mode2) {
++ return (XGICopyModeNLink(pScrn, result, mode1, mode2, srel));
++ }
++ else {
++ return NULL;
++ }
++}
++
++/* Generate the merged-fb mode modelist from metamodes
++ * (Code base taken from mga driver)
++ */
++static DisplayModePtr
++XGIGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char *str,
++ DisplayModePtr i, DisplayModePtr j,
++ XGIScrn2Rel srel)
++{
++#ifdef XGIXINERAMA
++ XGIPtr pXGI = XGIPTR(pScrn);
++#endif
++ char *strmode = str;
++ char modename[256];
++ Bool gotdash = FALSE;
++ XGIScrn2Rel sr;
++ DisplayModePtr mode1 = NULL;
++ DisplayModePtr mode2 = NULL;
++ DisplayModePtr result = NULL;
++
++#ifdef XGIXINERAMA
++ pXGI->AtLeastOneNonClone = FALSE;
++#endif
++
++ do {
++ switch (*str) {
++ case 0:
++ case '-':
++ case ' ':
++ if ((strmode != str)) {
++
++ strncpy(modename, strmode, str - strmode);
++ modename[str - strmode] = 0;
++
++ if (gotdash) {
++ if (mode1 == NULL)
++ return NULL;
++ mode2 = XGIGetModeFromName(modename, j);
++ if (!mode2) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Mode \"%s\" is not a supported mode for CRT2\n",
++ modename);
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Skipping metamode \"%s-%s\".\n",
++ mode1->name, modename);
++ mode1 = NULL;
++ }
++ }
++ else {
++ mode1 = XGIGetModeFromName(modename, i);
++ if (!mode1) {
++ char *tmps = str;
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Mode \"%s\" is not a supported mode for CRT1\n",
++ modename);
++ gotdash = FALSE;
++ while (*tmps == ' ')
++ tmps++;
++ if (*tmps == '-') { /* skip the next mode */
++ tmps++;
++ while ((*tmps == ' ') && (*tmps != 0))
++ tmps++; /* skip spaces */
++ while ((*tmps != ' ') && (*tmps != '-')
++ && (*tmps != 0))
++ tmps++; /* skip modename */
++ strncpy(modename, strmode, tmps - strmode);
++ modename[tmps - strmode] = 0;
++ str = tmps - 1;
++ }
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Skipping metamode \"%s\".\n", modename);
++ mode1 = NULL;
++ }
++ }
++ gotdash = FALSE;
++ }
++ strmode = str + 1;
++ gotdash |= (*str == '-');
++
++ if (*str != 0)
++ break;
++ /* Fall through otherwise */
++
++ default:
++ if (!gotdash && mode1) {
++ sr = srel;
++ if (!mode2) {
++ mode2 = XGIGetModeFromName(mode1->name, j);
++ sr = xgiClone;
++ }
++ if (!mode2) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Mode: \"%s\" is not a supported mode for CRT2\n",
++ mode1->name);
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Skipping metamode \"%s\".\n", modename);
++ mode1 = NULL;
++ }
++ else {
++ result =
++ XGICopyModeNLink(pScrn, result, mode1, mode2, sr);
++ mode1 = NULL;
++ mode2 = NULL;
++ }
++ }
++ break;
++
++ }
++
++ } while (*(str++) != 0);
++
++ return result;
++}
++
++static DisplayModePtr
++XGIGenerateModeList(ScrnInfoPtr pScrn, char *str,
++ DisplayModePtr i, DisplayModePtr j, XGIScrn2Rel srel)
++{
++ if (str != NULL) {
++ return (XGIGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "No MetaModes given, linking %s modes by default\n",
++ (srel == xgiClone) ? "first" :
++ (((srel == xgiLeftOf)
++ || (srel == xgiRightOf)) ? "widest" : "tallest"));
++ return (XGIGenerateModeListFromLargestModes(pScrn, i, j, srel));
++ }
++}
++
++static void
++XGIRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
++{
++ DisplayModePtr mode, bmode;
++ int max;
++ static const char *str = "MergedFB: Virtual %s %d\n";
++
++ if (!(pScrn->display->virtualX)) {
++ mode = bmode = pScrn->modes;
++ max = 0;
++ do {
++ if (mode->HDisplay > max)
++ max = mode->HDisplay;
++ mode = mode->next;
++ } while (mode != bmode);
++ pScrn->virtualX = max;
++ pScrn->displayWidth = max;
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", max);
++ }
++ if (!(pScrn->display->virtualY)) {
++ mode = bmode = pScrn->modes;
++ max = 0;
++ do {
++ if (mode->VDisplay > max)
++ max = mode->VDisplay;
++ mode = mode->next;
++ } while (mode != bmode);
++ pScrn->virtualY = max;
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", max);
++ }
++}
++
++static void
++XGIMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, XGIScrn2Rel srel)
++{
++ XGIPtr pXGI = XGIPTR(pScrn1);
++ MessageType from = X_DEFAULT;
++ xf86MonPtr DDC1 = (xf86MonPtr) (pScrn1->monitor->DDC);
++ xf86MonPtr DDC2 = (xf86MonPtr) (pScrn2->monitor->DDC);
++ int ddcWidthmm = 0, ddcHeightmm = 0;
++ const char *dsstr = "MergedFB: Display dimensions: (%d, %d) mm\n";
++
++ /* This sets the DPI for MergedFB mode. The problem is that
++ * this can never be exact, because the output devices may
++ * have different dimensions. This function tries to compromise
++ * through a few assumptions, and it just calculates an average DPI
++ * value for both monitors.
++ */
++
++ /* Given DisplaySize should regard BOTH monitors */
++ pScrn1->widthmm = pScrn1->monitor->widthmm;
++ pScrn1->heightmm = pScrn1->monitor->heightmm;
++
++ /* Get DDC display size; if only either CRT1 or CRT2 provided these,
++ * assume equal dimensions for both, otherwise add dimensions
++ */
++ if ((DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
++ (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0))) {
++ ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
++ ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
++ switch (srel) {
++ case xgiLeftOf:
++ case xgiRightOf:
++ ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
++ break;
++ case xgiAbove:
++ case xgiBelow:
++ ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
++ default:
++ break;
++ }
++ }
++ else if (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
++ ddcWidthmm = DDC1->features.hsize * 10;
++ ddcHeightmm = DDC1->features.vsize * 10;
++ switch (srel) {
++ case xgiLeftOf:
++ case xgiRightOf:
++ ddcWidthmm *= 2;
++ break;
++ case xgiAbove:
++ case xgiBelow:
++ ddcHeightmm *= 2;
++ default:
++ break;
++ }
++ }
++ else if (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) {
++ ddcWidthmm = DDC2->features.hsize * 10;
++ ddcHeightmm = DDC2->features.vsize * 10;
++ switch (srel) {
++ case xgiLeftOf:
++ case xgiRightOf:
++ ddcWidthmm *= 2;
++ break;
++ case xgiAbove:
++ case xgiBelow:
++ ddcHeightmm *= 2;
++ default:
++ break;
++ }
++ }
++
++ if (monitorResolution > 0) {
++
++ /* Set command line given values (overrules given options) */
++ pScrn1->xDpi = monitorResolution;
++ pScrn1->yDpi = monitorResolution;
++ from = X_CMDLINE;
++
++ }
++ else if (pXGI->MergedFBXDPI) {
++
++ /* Set option-wise given values (overrule DisplaySize) */
++ pScrn1->xDpi = pXGI->MergedFBXDPI;
++ pScrn1->yDpi = pXGI->MergedFBYDPI;
++ from = X_CONFIG;
++
++ }
++ else if (pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
++
++ /* Set values calculated from given DisplaySize */
++ from = X_CONFIG;
++ if (pScrn1->widthmm > 0) {
++ pScrn1->xDpi =
++ (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
++ }
++ if (pScrn1->heightmm > 0) {
++ pScrn1->yDpi =
++ (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
++ }
++ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm,
++ pScrn1->heightmm);
++
++ }
++ else if (ddcWidthmm && ddcHeightmm) {
++
++ /* Set values from DDC-provided display size */
++ from = X_PROBED;
++ xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
++ pScrn1->widthmm = ddcWidthmm;
++ pScrn1->heightmm = ddcHeightmm;
++ if (pScrn1->widthmm > 0) {
++ pScrn1->xDpi =
++ (int) ((double) pScrn1->virtualX * 25.4 / pScrn1->widthmm);
++ }
++ if (pScrn1->heightmm > 0) {
++ pScrn1->yDpi =
++ (int) ((double) pScrn1->virtualY * 25.4 / pScrn1->heightmm);
++ }
++
++ }
++ else {
++
++ pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
++
++ }
++
++ /* Sanity check */
++ if (pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
++ pScrn1->yDpi = pScrn1->xDpi;
++ if (pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
++ pScrn1->xDpi = pScrn1->yDpi;
++
++ pScrn2->xDpi = pScrn1->xDpi;
++ pScrn2->yDpi = pScrn1->yDpi;
++
++ xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
++ pScrn1->xDpi, pScrn1->yDpi);
++}
++
++static void
++XGIFreeCRT2Structs(XGIPtr pXGI)
++{
++ if (pXGI->CRT2pScrn) {
++ if (pXGI->CRT2pScrn->modes) {
++ while (pXGI->CRT2pScrn->modes)
++ xf86DeleteMode(&pXGI->CRT2pScrn->modes,
++ pXGI->CRT2pScrn->modes);
++ }
++ if (pXGI->CRT2pScrn->monitor) {
++ if (pXGI->CRT2pScrn->monitor->Modes) {
++ while (pXGI->CRT2pScrn->monitor->Modes)
++ xf86DeleteMode(&pXGI->CRT2pScrn->monitor->Modes,
++ pXGI->CRT2pScrn->monitor->Modes);
++ }
++ if (pXGI->CRT2pScrn->monitor->DDC)
++ xfree(pXGI->CRT2pScrn->monitor->DDC);
++ xfree(pXGI->CRT2pScrn->monitor);
++ }
++ xfree(pXGI->CRT2pScrn);
++ pXGI->CRT2pScrn = NULL;
++ }
++}
++
++#endif /* End of MergedFB helpers */
++
++static xf86MonPtr
++XGIInternalDDC(ScrnInfoPtr pScrn, int crtno)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned char buffer[256];
++
++ int RealOff;
++ unsigned char *page;
++
++ xf86MonPtr pMonitor = NULL;
++ xf86Int10InfoPtr pInt = NULL; /* Our int10 */
++
++ /*yilin 03/10/2008: set the monitor default size to 310mm x 240mm to fix KDE font too small problem*/
++ pScrn->monitor->widthmm = 310;
++ pScrn->monitor->heightmm = 240;
++
++ static char *crtno_means_str[] = {
++ "CRT1", "DVI", "CRT2"
++ };
++
++ if (crtno > 2 || crtno < 0) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "XGIInternalDDC(): Can not get EDID for crtno = %d,abort.\n",
++ crtno);
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "XGIInternalDDC(): getting EDID for %s.\n",
++ crtno_means_str[crtno]);
++ }
++
++ if (xf86LoadSubModule(pScrn, "int10")) {
++ xf86LoaderReqSymLists(int10Symbols, NULL);
++ pInt = xf86InitInt10(pXGI->pEnt->index);
++ if (pInt == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "XGIInternalDDC(): Can not initialize pInt, abort.\n");
++ return NULL;
++ }
++
++ page = xf86Int10AllocPages(pInt, 1, &RealOff);
++ if (page == NULL) {
++ xf86FreeInt10(pInt);
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "XGIInternalDDC(): Can not initialize real mode buffer, abort.\n");
++ return NULL;
++ }
++ }
++
++ if (pInt) {
++ pInt->ax = 0x4f15; /* VESA DDC supporting */
++ pInt->bx = 1; /* get EDID */
++ pInt->cx = crtno; /* port 0 or 1 for CRT 1 or 2 */
++ pInt->es = SEG_ADDR(RealOff);
++ pInt->di = SEG_OFF(RealOff);
++ pInt->num = 0x10;
++ xf86ExecX86int10(pInt);
++
++ PDEBUG3(ErrorF
++ ("ax = %04X bx = %04X cx = %04X dx = %04X si = %04X di = %04X es = %04X\n",
++ pInt->ax, pInt->bx, pInt->cx, pInt->dx, pInt->si, pInt->di,
++ pInt->es));
++
++ if ((pInt->ax & 0xff00) == 0) {
++ int i;
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "XGIInternalDDC(): VESA get DDC success for CRT %d.\n",
++ crtno + 1);
++
++ for (i = 0; i < 128; i++) {
++ buffer[i] = page[i];
++ }
++
++#ifdef DEBUG5
++ for (i = 0; i < 128; i += 16) {
++ unsigned j;
++ ErrorF("EDID[%02X]", i);
++ for (j = 0; j < 16; j++) {
++ ErrorF(" %02X", buffer[i + j]);
++ }
++ ErrorF("\n");
++ }
++#endif /* DEBUG3 */
++
++ xf86LoaderReqSymLists(ddcSymbols, NULL);
++
++ /* Jong 09/04/2007; Alan fixed abnormal EDID data */
++ /* pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer) ; */
++ if ( (buffer[0]==0) && (buffer[7]==0) )
++ {
++ for (i=1;i<7;i++)
++ {
++ if (buffer[i]!=0xFF)
++ break;
++ }
++ if (i==7)
++ {
++ pMonitor = xf86InterpretEDID(pScrn->scrnIndex, buffer);
++ }
++ }
++
++ if (pMonitor == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "CRT%d DDC EDID corrupt\n", crtno + 1);
++ return (NULL);
++ }
++ xf86UnloadSubModule("ddc");
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "XGIInternalDDC(): VESA get DDC fail for CRT %d.\n",
++ crtno + 1);
++ }
++
++ xf86Int10FreePages(pInt, page, 1);
++ xf86FreeInt10(pInt);
++ }
++ return pMonitor;
++}
++
++/* static xf86MonPtr
++XGIDoPrivateDDC(ScrnInfoPtr pScrn, int *crtnum)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ if(IS_DUAL_HEAD(pXGI))
++ {
++ if(IS_SECOND_HEAD(pXGI))
++ {
++ *crtnum = 1;
++ return(XGIInternalDDC(pScrn, 0));
++ }
++ else
++ {
++ *crtnum = 2;
++ return(XGIInternalDDC(pScrn, 1));
++ }
++ }
++ else if(pXGI->CRT1off)
++ {
++ *crtnum = 2;
++ return(XGIInternalDDC(pScrn, 1));
++ }
++ else
++ {
++ *crtnum = 1;
++ return(XGIInternalDDC(pScrn, 0));
++ }
++} */
++
++
++#ifdef DEBUG5
++static void
++XGIDumpMonitorInfo(xf86MonPtr pMonitor)
++{
++ struct detailed_timings *pd_timings;
++ Uchar *pserial;
++ Uchar *pascii_data;
++ Uchar *pname;
++ struct monitor_ranges *pranges;
++ struct std_timings *pstd_t;
++ struct whitePoints *pwp;
++ int i, j;
++
++ if (pMonitor == NULL) {
++ ErrorF("Monitor is NULL");
++ return;
++ }
++
++ ErrorF("pMonitor->scrnIndex = %d\n", pMonitor->scrnIndex);
++ ErrorF
++ ("vendor = %c%c%c%c, prod_id = %x serial = %d week = %d year = %d\n",
++ pMonitor->vendor.name[0], pMonitor->vendor.name[1],
++ pMonitor->vendor.name[2], pMonitor->vendor.name[3],
++ pMonitor->vendor.prod_id, pMonitor->vendor.serial,
++ pMonitor->vendor.week, pMonitor->vendor.year);
++
++ ErrorF("ver = %d %d\n", pMonitor->ver.version, pMonitor->ver.revision);
++ ErrorF("intput type = %d voltage = %d setup = %d sync = %d\n",
++ pMonitor->features.input_type,
++ pMonitor->features.input_voltage,
++ pMonitor->features.input_setup, pMonitor->features.input_sync);
++ ErrorF("hsize = %d vsize = %d gamma=%8.3f\n",
++ pMonitor->features.hsize,
++ pMonitor->features.vsize, pMonitor->features.gamma);
++
++ ErrorF("dpms = %d display_type = %d msc = %d\n",
++ pMonitor->features.dpms,
++ pMonitor->features.display_type, pMonitor->features.msc);
++ ErrorF
++ ("redx,redy,greenx,greeny,bluex,bluey,whitex,whitey = %8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f,%8.3f\n",
++ pMonitor->features.redx, pMonitor->features.redy,
++ pMonitor->features.greenx, pMonitor->features.greeny,
++ pMonitor->features.bluex, pMonitor->features.bluey,
++ pMonitor->features.whitex, pMonitor->features.whitey);
++
++ ErrorF("established_timings = (t1)%d%d%d%d%d%d%d%d",
++ (pMonitor->timings1.t1 >> 7) & 1,
++ (pMonitor->timings1.t1 >> 6) & 1,
++ (pMonitor->timings1.t1 >> 5) & 1,
++ (pMonitor->timings1.t1 >> 4) & 1,
++ (pMonitor->timings1.t1 >> 3) & 1,
++ (pMonitor->timings1.t1 >> 2) & 1,
++ (pMonitor->timings1.t1 >> 1) & 1,
++ (pMonitor->timings1.t1 >> 0) & 1);
++ ErrorF("(t2) %d%d%d%d%d%d%d%d",
++ (pMonitor->timings1.t1 >> 7) & 1,
++ (pMonitor->timings1.t1 >> 6) & 1,
++ (pMonitor->timings1.t1 >> 5) & 1,
++ (pMonitor->timings1.t1 >> 4) & 1,
++ (pMonitor->timings1.t1 >> 3) & 1,
++ (pMonitor->timings1.t1 >> 2) & 1,
++ (pMonitor->timings1.t1 >> 1) & 1,
++ (pMonitor->timings1.t1 >> 0) & 1);
++ ErrorF("(t_manu)%d%d%d%d%d%d%d%d\n",
++ (pMonitor->timings1.t_manu >> 7) & 1,
++ (pMonitor->timings1.t_manu >> 6) & 1,
++ (pMonitor->timings1.t_manu >> 5) & 1,
++ (pMonitor->timings1.t_manu >> 4) & 1,
++ (pMonitor->timings1.t_manu >> 3) & 1,
++ (pMonitor->timings1.t_manu >> 2) & 1,
++ (pMonitor->timings1.t_manu >> 1) & 1,
++ (pMonitor->timings1.t_manu >> 0) & 1);
++
++ for (i = 0; i < 7; i++) {
++ ErrorF
++ ("std timing %d: hsize = %d, vsize = %d, refresh = %d, id = %d\n",
++ i, pMonitor->timings2[i].hsize, pMonitor->timings2[i].vsize,
++ pMonitor->timings2[i].refresh, pMonitor->timings2[i].id);
++ }
++
++ for (i = 0; i < 4; i++) {
++ ErrorF("Detail timing section %d\n", i);
++ ErrorF("type = %x\n", pMonitor->det_mon[i].type);
++ switch (pMonitor->det_mon[i].type) {
++ case DS_SERIAL:
++ ErrorF("type = %x DS_SERIAL = %x\n", pMonitor->det_mon[i].type,
++ DS_SERIAL);
++ break;
++ case DS_ASCII_STR:
++ ErrorF("type = %x DS_ASCII_STR = %x\n", pMonitor->det_mon[i].type,
++ DS_ASCII_STR);
++ break;
++ case DS_NAME:
++ ErrorF("type = %x DS_NAME = %x\n", pMonitor->det_mon[i].type,
++ DS_NAME);
++ break;
++ case DS_RANGES:
++ ErrorF("type = %x DS_RANGES = %x\n", pMonitor->det_mon[i].type,
++ DS_RANGES);
++ break;
++ case DS_WHITE_P:
++ ErrorF("type = %x DS_WHITE_P = %x\n", pMonitor->det_mon[i].type,
++ DS_WHITE_P);
++ break;
++ case DS_STD_TIMINGS:
++ ErrorF("type = %x DS_STD_TIMINGS = %x\n",
++ pMonitor->det_mon[i].type, DS_STD_TIMINGS);
++ break;
++ }
++ switch (pMonitor->det_mon[i].type) {
++ case DS_SERIAL:
++ pserial = pMonitor->det_mon[i].section.serial;
++ ErrorF("seial: ");
++ for (j = 0; j < 13; j++) {
++ ErrorF("%02X", pserial[j]);
++ }
++ ErrorF("\n");
++ break;
++ case DS_ASCII_STR:
++ pascii_data = pMonitor->det_mon[i].section.ascii_data;
++ ErrorF("ascii: ");
++ for (j = 0; j < 13; j++) {
++ ErrorF("%c", pascii_data[j]);
++ }
++ ErrorF("\n");
++ break;
++ case DS_NAME:
++ pname = pMonitor->det_mon[i].section.name;
++ ErrorF("name: ");
++ for (j = 0; j < 13; j++) {
++ ErrorF("%c", pname[j]);
++ }
++ ErrorF("\n");
++ break;
++ case DS_RANGES:
++ pranges = &(pMonitor->det_mon[i].section.ranges);
++ ErrorF
++ ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
++ pranges->min_v, pranges->max_v, pranges->min_h,
++ pranges->max_h, pranges->max_clock);
++ break;
++ case DS_WHITE_P:
++ pwp = pMonitor->det_mon[i].section.wp;
++ for (j = 0; j < 2; j++) {
++ ErrorF
++ ("wp[%d].index = %d white_x = %8.3f white_y = %8.3f white_gamma = %8.3f\n",
++ j, pwp[j].index, pwp[j].white_x, pwp[j].white_y,
++ pwp[j].white_gamma);
++ }
++ break;
++ case DS_STD_TIMINGS:
++ pstd_t = pMonitor->det_mon[i].section.std_t;
++ for (j = 0; j < 5; j++) {
++ ErrorF
++ ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
++ j, pstd_t[j].hsize, pstd_t[j].vsize, pstd_t[j].refresh,
++ pstd_t[j].id);
++ }
++ break;
++ case DT:
++
++ pd_timings = &pMonitor->det_mon[i].section.d_timings;
++ ErrorF("Detail Timing Descriptor\n");
++ ErrorF("clock = %d\n", pd_timings->clock);
++ ErrorF("h_active = %d\n", pd_timings->h_active);
++ ErrorF("h_blanking = %d\n", pd_timings->h_blanking);
++ ErrorF("v_active = %d\n", pd_timings->v_active);
++ ErrorF("v_blanking = %d\n", pd_timings->v_blanking);
++ ErrorF("h_sync_off = %d\n", pd_timings->h_sync_off);
++ ErrorF("h_sync_width = %d\n", pd_timings->h_sync_width);
++ ErrorF("v_sync_off = %d\n", pd_timings->v_sync_off);
++ ErrorF("v_sync_width = %d\n", pd_timings->v_sync_width);
++ ErrorF("h_size = %d\n", pd_timings->h_size);
++ ErrorF("v_size = %d\n", pd_timings->v_size);
++ ErrorF("h_border = %d\n", pd_timings->h_border);
++ ErrorF("v_border = %d\n", pd_timings->v_border);
++ ErrorF("interlaced = %d stereo = %x sync = %x misc = %x\n",
++ pd_timings->interlaced,
++ pd_timings->stereo, pd_timings->sync, pd_timings->misc);
++ break;
++ }
++ }
++
++ for (i = 0; i < 128; i += 16) {
++ ErrorF("rawData[%02X]:", i);
++ for (j = 0; j < 16; j++) {
++ ErrorF(" %02X", pMonitor->rawData[i + j]);
++ }
++ ErrorF("\n");
++ }
++}
++#endif
++
++static void
++XGIGetMonitorRangeByDDC(MonitorRangePtr range, xf86MonPtr pMonitor)
++{
++ int i, j;
++ float VF, HF;
++ struct detailed_timings *pd_timings;
++ struct monitor_ranges *pranges;
++ struct std_timings *pstd_t;
++
++ if ((range == NULL) || (pMonitor == NULL)) {
++ return; /* ignore */
++ }
++
++ PDEBUG5(ErrorF
++ ("establish timing t1 = %02x t2=%02x\n", pMonitor->timings1.t1,
++ pMonitor->timings1.t2));
++
++ for (i = 0, j = 0; i < 8; i++, j++)
++ {
++ if (establish_timing[j].width == -1) {
++ continue;
++ }
++
++ if (pMonitor->timings1.t1 & (1 << i))
++ {
++ PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
++ establish_timing[j].width,
++ establish_timing[j].height,
++ establish_timing[j].VRefresh,
++ establish_timing[j].HSync));
++
++ if (range->loH > establish_timing[j].HSync) {
++ range->loH = establish_timing[j].HSync;
++ }
++
++ if (range->hiH < establish_timing[j].HSync) {
++ range->hiH = establish_timing[j].HSync;
++ }
++
++ if (range->loV > establish_timing[j].VRefresh) {
++ range->loV = establish_timing[j].VRefresh;
++ }
++
++ if (range->hiV < establish_timing[j].VRefresh) {
++ range->hiV = establish_timing[j].VRefresh;
++ }
++ }
++ }
++
++ PDEBUG5(ErrorF
++ ("check establish timing t1:range ( %8.3f %8.3f %8.3f %8.3f )\n",
++ range->loH, range->loV, range->hiH, range->hiV));
++
++ for (i = 0; i < 8; i++, j++) {
++ if (establish_timing[j].width == -1) {
++ continue;
++ }
++
++ if (pMonitor->timings1.t2 & (1 << i)) {
++ PDEBUG5(ErrorF("Support %dx%d@%4.1fHz Hseq = %8.3fKHz\n",
++ establish_timing[j].width,
++ establish_timing[j].height,
++ establish_timing[j].VRefresh,
++ establish_timing[j].HSync));
++
++ if (range->loH > establish_timing[j].HSync) {
++ range->loH = establish_timing[j].HSync;
++ }
++
++ if (range->hiH < establish_timing[j].HSync) {
++ range->hiH = establish_timing[j].HSync;
++ }
++
++ if (range->loV > establish_timing[j].VRefresh) {
++ range->loV = establish_timing[j].VRefresh;
++ }
++
++ if (range->hiV < establish_timing[j].VRefresh) {
++ range->hiV = establish_timing[j].VRefresh;
++ }
++ }
++ }
++ PDEBUG5(ErrorF
++ ("check establish timing t2:range ( %8.3f %8.3f %8.3f %8.3f )\n",
++ range->loH, range->loV, range->hiH, range->hiV));
++
++ for (i = 0; i < 8; i++) {
++ for (j = 0; StdTiming[j].width != -1; j++) {
++ if ((StdTiming[j].width == pMonitor->timings2[i].hsize) &&
++ (StdTiming[j].height == pMonitor->timings2[i].vsize) &&
++ (StdTiming[j].VRefresh == pMonitor->timings2[i].refresh)) {
++ PDEBUG5(ErrorF("pMonitor->timings2[%d]= %d %d %d %d\n",
++ i,
++ pMonitor->timings2[i].hsize,
++ pMonitor->timings2[i].vsize,
++ pMonitor->timings2[i].refresh,
++ pMonitor->timings2[i].id));
++ HF = StdTiming[j].HSync;
++ VF = StdTiming[j].VRefresh;
++ if (range->loH > HF)
++ range->loH = HF;
++ if (range->loV > VF)
++ range->loV = VF;
++ if (range->hiH < HF)
++ range->hiH = HF;
++ if (range->hiV < VF)
++ range->hiV = VF;
++ break;
++ }
++ }
++ }
++ PDEBUG5(ErrorF
++ ("check standard timing :range ( %8.3f %8.3f %8.3f %8.3f )\n",
++ range->loH, range->loV, range->hiH, range->hiV));
++
++ for (i = 0; i < 4; i++) {
++ switch (pMonitor->det_mon[i].type) {
++ case DS_RANGES:
++ pranges = &(pMonitor->det_mon[i].section.ranges);
++ PDEBUG5(ErrorF
++ ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
++ pranges->min_v, pranges->max_v, pranges->min_h,
++ pranges->max_h, pranges->max_clock));
++
++ if (range->loH > pranges->min_h)
++ range->loH = pranges->min_h;
++ if (range->loV > pranges->min_v)
++ range->loV = pranges->min_v;
++ if (range->hiH < pranges->max_h)
++ range->hiH = pranges->max_h;
++ if (range->hiV < pranges->max_v)
++ range->hiV = pranges->max_v;
++ PDEBUG5(ErrorF
++ ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
++ range->loV, range->hiH, range->hiV));
++ break;
++
++ case DS_STD_TIMINGS:
++ pstd_t = pMonitor->det_mon[i].section.std_t;
++ for (j = 0; j < 5; j++) {
++ int k;
++ PDEBUG5(ErrorF
++ ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
++ j, pstd_t[j].hsize, pstd_t[j].vsize,
++ pstd_t[j].refresh, pstd_t[j].id));
++ for (k = 0; StdTiming[k].width != -1; k++) {
++ if ((StdTiming[k].width == pstd_t[j].hsize) &&
++ (StdTiming[k].height == pstd_t[j].vsize) &&
++ (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
++ if (range->loH > StdTiming[k].HSync)
++ range->loH = StdTiming[k].HSync;
++ if (range->hiH < StdTiming[k].HSync)
++ range->hiH = StdTiming[k].HSync;
++ if (range->loV > StdTiming[k].VRefresh)
++ range->loV = StdTiming[k].VRefresh;
++ if (range->hiV < StdTiming[k].VRefresh)
++ range->hiV = StdTiming[k].VRefresh;
++ break;
++ }
++
++ }
++ }
++ break;
++
++ case DT:
++
++ pd_timings = &pMonitor->det_mon[i].section.d_timings;
++
++ HF = pd_timings->clock / (pd_timings->h_active +
++ pd_timings->h_blanking);
++ VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
++ HF /= 1000; /* into KHz Domain */
++ if (range->loH > HF)
++ range->loH = HF;
++ if (range->hiH < HF)
++ range->hiH = HF;
++ if (range->loV > VF)
++ range->loV = VF;
++ if (range->hiV < VF)
++ range->hiV = VF;
++ PDEBUG(ErrorF
++ ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
++ HF, VF, range->loH, range->loV, range->hiH, range->hiV));
++ break;
++ }
++ }
++ PDEBUG5(ErrorF
++ ("Done range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH, range->loV,
++ range->hiH, range->hiV));
++
++}
++
++static void
++XGISyncDDCMonitorRange(MonPtr monitor, MonitorRangePtr range)
++{
++ int i;
++ if ((monitor == NULL) || (range == NULL)) {
++ return;
++ }
++
++ for (i = 0; i < monitor->nHsync; i++) {
++ monitor->hsync[i].lo = range->loH;
++ monitor->hsync[i].hi = range->hiH;
++ }
++
++ for (i = 0; i < monitor->nVrefresh; i++) {
++ monitor->vrefresh[i].lo = range->loV;
++ monitor->vrefresh[i].hi = range->hiV;
++ }
++}
++
++static void
++XGIDDCPreInit(ScrnInfoPtr pScrn)
++{
++
++ XGIPtr pXGI = XGIPTR(pScrn);
++ xf86MonPtr pMonitor = NULL;
++ xf86MonPtr pMonitorDVI = NULL;
++ Bool didddc2;
++
++ static const char *ddcsstr =
++ "CRT%d DDC monitor info: ************************************\n";
++ static const char *ddcestr =
++ "End of CRT%d DDC monitor info ******************************\n";
++
++ /* Now for something completely different: DDC.
++ * For 300 and 315/330 series, we provide our
++ * own functions (in order to probe CRT2 as well)
++ * If these fail, use the VBE.
++ * All other chipsets will use VBE. No need to re-invent
++ * the wheel there.
++ */
++
++ pXGI->pVbe = NULL;
++ didddc2 = FALSE;
++
++ /* In dual head mode, probe DDC using VBE only for CRT1 (second head) */
++ if (IS_DUAL_HEAD(pXGI) && (!didddc2) && !IS_SECOND_HEAD(pXGI))
++ didddc2 = TRUE;
++
++ if (!didddc2) {
++ /* If CRT1 is off or LCDA, skip DDC via VBE */
++ if ((pXGI->CRT1off) || (pXGI->VBFlags & CRT1_LCDA))
++ didddc2 = TRUE;
++ }
++
++ /* Now (re-)load and initialize the DDC module */
++ if (!didddc2) {
++
++ if (xf86LoadSubModule(pScrn, "ddc")) {
++
++ xf86LoaderReqSymLists(ddcSymbols, NULL);
++
++ pMonitor = XGIInternalDDC(pScrn, 0);
++ if (pMonitor == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Could not retrieve DDC data\n");
++ }
++
++ if (pXGI->xgi_HwDevExt.jChipType == XG21) {
++ PDEBUG(ErrorF("Getting XG21 DVI EDID...\n"));
++ pMonitorDVI = XGIInternalDDC(pScrn, 1);
++ if (pMonitorDVI == NULL) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Could not retrieve DVI DDC data\n");
++ }
++ else /* Jong 12/04/2007; used for filtering of CRT1 modes */
++ g_pMonitorDVI=pMonitorDVI;
++
++ if ((pMonitor == NULL) && (pMonitorDVI != NULL)) {
++ pMonitor = pMonitorDVI;
++ }
++ }
++
++ }
++ }
++
++ /* initialize */
++
++ if (pMonitor) {
++ pXGI->CRT1Range.loH = 1000;
++ pXGI->CRT1Range.loV = 1000;
++ pXGI->CRT1Range.hiH = 0;
++ pXGI->CRT1Range.hiV = 0;
++ XGIGetMonitorRangeByDDC(&(pXGI->CRT1Range), pMonitor);
++ }
++ else {
++ pXGI->CRT1Range.loH = 0;
++ pXGI->CRT1Range.loV = 0;
++ pXGI->CRT1Range.hiH = 1000;
++ pXGI->CRT1Range.hiV = 1000;
++ }
++
++ if (pMonitorDVI) {
++ pXGI->CRT2Range.loV = 1000;
++ pXGI->CRT2Range.loH = 1000;
++ pXGI->CRT2Range.hiH = 0;
++ pXGI->CRT2Range.hiV = 0;
++ XGIGetMonitorRangeByDDC(&(pXGI->CRT2Range), pMonitorDVI);
++ }
++ else {
++ pXGI->CRT2Range.loH = 0;
++ pXGI->CRT2Range.loV = 0;
++ pXGI->CRT2Range.hiH = 1000;
++ pXGI->CRT2Range.hiV = 1000;
++ }
++
++ if (pXGI->xgi_HwDevExt.jChipType == XG21) {
++ /* Mode range intersecting */
++ if (pXGI->CRT1Range.loH < pXGI->CRT2Range.loH) {
++ pXGI->CRT1Range.loH = pXGI->CRT2Range.loH;
++ }
++ if (pXGI->CRT1Range.loV < pXGI->CRT2Range.loV) {
++ pXGI->CRT1Range.loV = pXGI->CRT2Range.loV;
++ }
++ if (pXGI->CRT1Range.hiH > pXGI->CRT2Range.hiH) {
++ pXGI->CRT1Range.hiH = pXGI->CRT2Range.hiH;
++ }
++ if (pXGI->CRT1Range.hiV > pXGI->CRT2Range.hiV) {
++ pXGI->CRT1Range.hiV = pXGI->CRT2Range.hiV;
++ }
++ }
++
++ if (pMonitor) {
++ XGISyncDDCMonitorRange(pScrn->monitor, &pXGI->CRT1Range);
++ }
++
++ if (pScrn->monitor) {
++ pScrn->monitor->DDC = pMonitor;
++ }
++
++ return;
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ pXGI->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
++ if (pXGI->CRT2pScrn->monitor) {
++ DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
++ memcpy(pXGI->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
++ pXGI->CRT2pScrn->monitor->DDC = NULL;
++ pXGI->CRT2pScrn->monitor->Modes = NULL;
++ tempm = pScrn->monitor->Modes;
++ while (tempm) {
++ if (!(newm = xalloc(sizeof(DisplayModeRec))))
++ break;
++ memcpy(newm, tempm, sizeof(DisplayModeRec));
++ if (!(newm->name = xalloc(strlen(tempm->name) + 1))) {
++ xfree(newm);
++ break;
++ }
++ strcpy(newm->name, tempm->name);
++ if (!pXGI->CRT2pScrn->monitor->Modes)
++ pXGI->CRT2pScrn->monitor->Modes = newm;
++ if (currentm) {
++ currentm->next = newm;
++ newm->prev = currentm;
++ }
++ currentm = newm;
++ tempm = tempm->next;
++ }
++
++ if ((pMonitor = XGIInternalDDC(pXGI->CRT2pScrn, 1))) {
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcsstr, 2);
++ xf86PrintEDID(pMonitor);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, ddcestr, 2);
++ xf86SetDDCproperties(pXGI->CRT2pScrn, pMonitor);
++
++ pXGI->CRT2pScrn->monitor->DDC = pMonitor;
++
++ /* use DDC data if no ranges in config file */
++ if (!pXGI->CRT2HSync) {
++ pXGI->CRT2pScrn->monitor->nHsync = 0;
++ }
++ if (!pXGI->CRT2VRefresh) {
++ pXGI->CRT2pScrn->monitor->nVrefresh = 0;
++ }
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Failed to read DDC data for CRT2\n");
++ }
++ }
++ else {
++ XGIErrorLog(pScrn,
++ "Failed to allocate memory for CRT2 monitor, %s.\n",
++ mergeddisstr);
++ if (pXGI->CRT2pScrn)
++ xfree(pXGI->CRT2pScrn);
++ pXGI->CRT2pScrn = NULL;
++ pXGI->MergedFB = FALSE;
++ }
++ }
++#endif
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 1);
++ }
++#endif
++
++ /* end of DDC */
++}
++
++#ifdef DEBUG5
++static void
++XGIDumpModePtr(DisplayModePtr mode)
++{
++ if (mode == NULL)
++ return;
++
++ ErrorF("Dump DisplayModePtr mode\n");
++ ErrorF("name = %s\n", mode->name);
++ /* ModeStatus status; */
++ ErrorF("type = %d\n", mode->type);
++ ErrorF("Clock = %d\n", mode->Clock);
++ ErrorF("HDisplay = %d\n", mode->HDisplay);
++ ErrorF("HSyncStart = %d\n", mode->HSyncStart);
++ ErrorF("HSyncEnd = %d\n", mode->HSyncEnd);
++ ErrorF("HTotal = %d\n", mode->HTotal);
++ ErrorF("HSkew = %d\n", mode->HSkew);
++ ErrorF("VDisplay = %d\n", mode->VDisplay);
++ ErrorF("VSyncStart = %d\n", mode->VSyncStart);
++ ErrorF("VSyncEnd = %d\n", mode->VSyncEnd);
++ ErrorF("VTotal = %d\n", mode->VTotal);
++ ErrorF("VScan = %d\n", mode->VScan);
++ ErrorF("Flags = %d\n", mode->Flags);
++
++
++ ErrorF("ClockIndex = %d\n", mode->ClockIndex);
++ ErrorF("SynthClock = %d\n", mode->SynthClock);
++ ErrorF("CrtcHDisplay = %d\n", mode->CrtcHDisplay);
++ ErrorF("CrtcHBlankStart = %d\n", mode->CrtcHBlankStart);
++ ErrorF("CrtcHSyncStart = %d\n", mode->CrtcHSyncStart);
++ ErrorF("CrtcHSyncEnd = %d\n", mode->CrtcHSyncEnd);
++ ErrorF("CrtcHBlankEnd = %d\n", mode->CrtcHBlankEnd);
++ ErrorF("CrtcHTotal = %d\n", mode->CrtcHTotal);
++ ErrorF("CrtcHSkew = %d\n", mode->CrtcHSkew);
++ ErrorF("CrtcVDisplay = %d\n", mode->CrtcVDisplay);
++ ErrorF("CrtcVBlankStart = %d\n", mode->CrtcVBlankStart);
++ ErrorF("CrtcVSyncStart = %d\n", mode->CrtcVSyncStart);
++ ErrorF("CrtcVSyncEnd = %d\n", mode->CrtcVSyncEnd);
++ ErrorF("CrtcVBlankEnd = %d\n", mode->CrtcVBlankEnd);
++ ErrorF("CrtcVTotal = %d\n", mode->CrtcVTotal);
++ ErrorF("CrtcHAdjusted = %s\n", (mode->CrtcHAdjusted) ? "TRUE" : "FALSE");
++ ErrorF("CrtcVAdjusted = %s\n", (mode->CrtcVAdjusted) ? "TRUE" : "FALSE");
++ ErrorF("PrivSize = %d\n", mode->PrivSize);
++ /* INT32 * Private; */
++ ErrorF("PrivFlags = %d\n", mode->PrivFlags);
++ ErrorF("HSync = %8.3f\n", mode->HSync);
++ ErrorF("VRefresh = %8.3f\n", mode->VRefresh);
++}
++#endif
++
++static void
++XGIDumpMonPtr(MonPtr pMonitor)
++{
++#ifdef DEBUG5
++ int i;
++# if 0
++ DisplayModePtr mode;
++#endif
++
++ ErrorF("XGIDumpMonPtr() ... \n");
++ if (pMonitor == NULL) {
++ ErrorF("pMonitor is NULL\n");
++ }
++
++ ErrorF("id = %s, vendor = %s model = %s\n",
++ pMonitor->id, pMonitor->vendor, pMonitor->model);
++ ErrorF("nHsync = %d\n", pMonitor->nHsync);
++ ErrorF("nVrefresh = %d\n", pMonitor->nVrefresh);
++
++ for (i = 0; i < MAX_HSYNC; i++) {
++ ErrorF("hsync[%d] = (%8.3f,%8.3f)\n", i, pMonitor->hsync[i].lo,
++ pMonitor->hsync[i].hi);
++ }
++
++ for (i = 0; i < MAX_VREFRESH; i++) {
++ ErrorF("vrefresh[%d] = (%8.3f,%8.3f)\n", i, pMonitor->vrefresh[i].lo,
++ pMonitor->vrefresh[i].hi);
++ }
++
++ ErrorF("widthmm = %d, heightmm = %d\n",
++ pMonitor->widthmm, pMonitor->heightmm);
++ ErrorF("options = %p, DDC = %p\n", pMonitor->options, pMonitor->DDC);
++# if 0
++ mode = pMonitor->Modes;
++ while (1) {
++ XGIDumpModePtr(mode);
++ if (mode == pMonitor->Last) {
++ break;
++ }
++ mode = mode->next;
++ }
++# endif
++#endif /* DEBUG5 */
++}
++
++/* Jong 09/19/2007; support modeline of custom modes */
++int ModifyTypeOfSupportMode(DisplayModePtr availModes)
++{
++ int CountOfModifiedModes=0;
++ DisplayModePtr p=availModes;
++
++ while(p)
++ {
++ /* if( (p->HDisplay == 1440) && (p->VDisplay == 900)) */
++ if( p->type == 0) /* externel support modeline */
++ {
++ p->type = M_T_USERDEF;
++ CountOfModifiedModes++;
++ }
++
++ p=p->next;
++ }
++
++ return(CountOfModifiedModes);
++}
++
++
++/* Mandatory */
++static Bool
++XGIPreInit(ScrnInfoPtr pScrn, int flags)
++{
++ XGIPtr pXGI;
++ MessageType from;
++ unsigned long int i;
++ int temp;
++ ClockRangePtr clockRanges;
++ int pix24flags;
++ int fd;
++ struct fb_fix_screeninfo fix;
++ XGIEntPtr pXGIEnt = NULL;
++ size_t memreq;
++
++#if defined(XGIMERGED) || defined(XGIDUALHEAD)
++ DisplayModePtr first, p, n;
++#endif
++ unsigned char srlockReg, crlockReg;
++ vbeInfoPtr pVbe;
++
++ /****************** Code Start ***********************/
++
++ ErrorF("XGIPreInit\n");
++
++ if (flags & PROBE_DETECT) {
++ if (xf86LoadSubModule(pScrn, "vbe")) {
++ int index = xf86GetEntityInfo(pScrn->entityList[0])->index;
++
++ if ((pVbe = VBEExtendedInit(NULL, index, 0))) {
++ ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
++ vbeFree(pVbe);
++ }
++ }
++ return TRUE;
++ }
++
++ /*
++ * Note: This function is only called once at server startup, and
++ * not at the start of each server generation. This means that
++ * only things that are persistent across server generations can
++ * be initialised here. xf86Screens[] is the array of all screens,
++ * (pScrn is a pointer to one of these). Privates allocated using
++ * xf86AllocateScrnInfoPrivateIndex() are too, and should be used
++ * for data that must persist across server generations.
++ *
++ * Per-generation data should be allocated with
++ * AllocateScreenPrivateIndex() from the ScreenInit() function.
++ */
++
++ /* Check the number of entities, and fail if it isn't one. */
++ if (pScrn->numEntities != 1) {
++ XGIErrorLog(pScrn, "Number of entities is not 1\n");
++ return FALSE;
++ }
++
++ /* The vgahw module should be loaded here when needed */
++ if (!xf86LoadSubModule(pScrn, "vgahw")) {
++ XGIErrorLog(pScrn, "Could not load vgahw module\n");
++ return FALSE;
++ }
++
++ xf86LoaderReqSymLists(vgahwSymbols, NULL);
++
++ /* Due to the liberal license terms this is needed for
++ * keeping the copyright notice readable and intact in
++ * binary distributions. Removing this is a copyright
++ * infringement. Please read the license terms above.
++ */
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "XGI driver (%s)\n", XGI_RELEASE_DATE);
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Copyright (C) 2001-2004 Thomas Winischhofer <thomas@winischhofer.net> and others\n");
++
++ /* Allocate a vgaHWRec */
++ if (!vgaHWGetHWRec(pScrn)) {
++ XGIErrorLog(pScrn, "Could not allocate VGA private\n");
++ return FALSE;
++ }
++
++ /* Allocate the XGIRec driverPrivate */
++ pXGI = XGIGetRec(pScrn);
++ if (pXGI == NULL) {
++ XGIErrorLog(pScrn, "Could not allocate memory for pXGI private\n");
++ return FALSE;
++ }
++
++ pXGI->IODBase = pScrn->domainIOBase;
++
++
++ /* Get the entity, and make sure it is PCI. */
++ pXGI->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
++ if (pXGI->pEnt->location.type != BUS_PCI) {
++ XGIErrorLog(pScrn, "Entity's bus type is not PCI\n");
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++#ifdef XGIDUALHEAD
++ /* Allocate an entity private if necessary */
++ if (xf86IsEntityShared(pScrn->entityList[0])) {
++ pXGIEnt = xf86GetEntityPrivate(pScrn->entityList[0],
++ XGIEntityIndex)->ptr;
++ pXGI->entityPrivate = pXGIEnt;
++
++ /* If something went wrong, quit here */
++ if ((pXGIEnt->DisableDual) || (pXGIEnt->ErrorAfterFirst)) {
++ XGIErrorLog(pScrn,
++ "First head encountered fatal error, can't continue\n");
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ }
++#endif
++
++ /* Find the PCI info for this screen */
++#ifndef XSERVER_LIBPCIACCESS
++ pXGI->PciInfo = xf86GetPciInfoForEntity(pXGI->pEnt->index);
++ pXGI->PciTag = pciTag(pXGI->PciInfo->bus, pXGI->PciInfo->device,
++ pXGI->PciInfo->func);
++#endif
++
++ pXGI->Primary = xf86IsPrimaryPci(pXGI->PciInfo);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "This adapter is %s display adapter\n",
++ (pXGI->Primary ? "primary" : "secondary"));
++
++ if (pXGI->Primary) {
++ VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
++ if (!vgaHWMapMem(pScrn)) {
++ XGIErrorLog(pScrn, "Could not map VGA memory\n");
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ }
++ vgaHWGetIOBase(VGAHWPTR(pScrn));
++
++ /* We "patch" the PIOOffset inside vgaHW in order to force
++ * the vgaHW module to use our relocated i/o ports.
++ */
++ VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
++#ifdef XSERVER_LIBPCIACCESS
++ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
++#else
++ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
++#endif
++ ;
++
++ pXGI->pInt = NULL;
++ if (!pXGI->Primary) {
++#if !defined(__alpha__)
++#if !defined(__powerpc__)
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Initializing display adapter through int10\n");
++
++ if (xf86LoadSubModule(pScrn, "int10")) {
++ xf86LoaderReqSymLists(int10Symbols, NULL);
++ pXGI->pInt = xf86InitInt10(pXGI->pEnt->index);
++ }
++ else {
++ XGIErrorLog(pScrn, "Could not load int10 module\n");
++ }
++#endif /* !defined(__powerpc__) */
++#endif /* !defined(__alpha__) */
++ }
++
++ xf86SetOperatingState(resVgaMem, pXGI->pEnt->index, ResUnusedOpr);
++
++ /* Operations for which memory access is required */
++ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
++ /* Operations for which I/O access is required */
++ pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
++
++ /* The ramdac module should be loaded here when needed */
++ if (!xf86LoadSubModule(pScrn, "ramdac")) {
++ XGIErrorLog(pScrn, "Could not load ramdac module\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ xf86LoaderReqSymLists(ramdacSymbols, NULL);
++
++ /* Set pScrn->monitor */
++ pScrn->monitor = pScrn->confScreen->monitor;
++
++ /* Jong 09/19/2007; modify type of support modes to M_T_USERDEF */
++ g_CountOfUserDefinedModes=ModifyTypeOfSupportMode(pScrn->monitor->Modes);
++
++ /*
++ * Set the Chipset and ChipRev, allowing config file entries to
++ * override. DANGEROUS!
++ */
++ if (pXGI->pEnt->device->chipset && *pXGI->pEnt->device->chipset) {
++ PDEBUG(ErrorF(" --- Chipset 1 \n"));
++ pScrn->chipset = pXGI->pEnt->device->chipset;
++ pXGI->Chipset = xf86StringToToken(XGIChipsets, pScrn->chipset);
++ from = X_CONFIG;
++ }
++ else if (pXGI->pEnt->device->chipID >= 0) {
++ PDEBUG(ErrorF(" --- Chipset 2 \n"));
++ pXGI->Chipset = pXGI->pEnt->device->chipID;
++ pScrn->chipset =
++ (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
++
++ from = X_CONFIG;
++ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
++ pXGI->Chipset);
++ }
++ else {
++ PDEBUG(ErrorF(" --- Chipset 3 \n"));
++ from = X_PROBED;
++ pXGI->Chipset = DEVICE_ID(pXGI->PciInfo);
++ pScrn->chipset =
++ (char *) xf86TokenToString(XGIChipsets, pXGI->Chipset);
++ }
++ if (pXGI->pEnt->device->chipRev >= 0) {
++ pXGI->ChipRev = pXGI->pEnt->device->chipRev;
++ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
++ pXGI->ChipRev);
++ }
++ else {
++ pXGI->ChipRev = CHIP_REVISION(pXGI->PciInfo);
++ }
++ pXGI->xgi_HwDevExt.jChipRevision = pXGI->ChipRev;
++
++ PDEBUG(ErrorF(" --- Chipset : %s \n", pScrn->chipset));
++
++
++ /*
++ * This shouldn't happen because such problems should be caught in
++ * XGIProbe(), but check it just in case.
++ */
++ if (pScrn->chipset == NULL) {
++ XGIErrorLog(pScrn, "ChipID 0x%04X is not recognised\n",
++ pXGI->Chipset);
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ if (pXGI->Chipset < 0) {
++ XGIErrorLog(pScrn, "Chipset \"%s\" is not recognised\n",
++ pScrn->chipset);
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ /* Determine chipset and VGA engine type */
++ pXGI->ChipFlags = 0;
++ pXGI->XGI_SD_Flags = 0;
++
++ switch (pXGI->Chipset) {
++ case PCI_CHIP_XGIXG40:
++ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21:
++ pXGI->xgi_HwDevExt.jChipType = XG40;
++ pXGI->myCR63 = 0x63;
++ pXGI->mmioSize = 64;
++ break;
++
++ case PCI_CHIP_XGIXG27:
++ pXGI->xgi_HwDevExt.jChipType = XG27;
++ pXGI->myCR63 = 0x63;
++ pXGI->mmioSize = 64;
++ break;
++
++ default:
++ /* This driver currently only supports V3XE, V3XT, V5, V8 (all of
++ * which are XG40 chips) and Z7 (which is XG20).
++ */
++ if (pXGI->pInt) {
++ xf86FreeInt10(pXGI->pInt);
++ }
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++/* load frame_buffer */
++
++ FbDevExist = FALSE;
++ if((pXGI->Chipset != PCI_CHIP_XGIXG20)&&(pXGI->Chipset != PCI_CHIP_XGIXG21)&&( pXGI->Chipset != PCI_CHIP_XGIXG27 ))
++ {
++ if ((fd = open("/dev/fb", 'r')) != -1) {
++ PDEBUG(ErrorF("--- open /dev/fb.... \n"));
++ ioctl(fd, FBIOGET_FSCREENINFO, &fix);
++ if (fix.accel == FB_ACCEL_XGI_GLAMOUR) {
++ PDEBUG(ErrorF("--- fix.accel.... \n"));
++ FbDevExist = TRUE;
++ }
++ else
++ PDEBUG(ErrorF("--- no fix.accel.... 0x%08lx \n", fix.accel));
++ close(fd);
++ }
++ }
++
++
++ /*
++ * The first thing we should figure out is the depth, bpp, etc.
++ * Additionally, determine the size of the HWCursor memory area.
++ */
++ pXGI->CursorSize = 4096;
++ pix24flags = Support32bppFb;
++
++#ifdef XGIDUALHEAD
++ /* In case of Dual Head, we need to determine if we are the "master" head or
++ * the "slave" head. In order to do that, we set PrimInit to DONE in the
++ * shared entity at the end of the first initialization. The second
++ * initialization then knows that some things have already been done. THIS
++ * ALWAYS ASSUMES THAT THE FIRST DEVICE INITIALIZED IS THE MASTER!
++ */
++
++ if (xf86IsEntityShared(pScrn->entityList[0])) {
++ if (pXGIEnt->lastInstance > 0) {
++ if (!xf86IsPrimInitDone(pScrn->entityList[0])) {
++ /* First Head (always CRT2) */
++ pXGI->SecondHead = FALSE;
++ pXGIEnt->pScrn_1 = pScrn;
++ pXGIEnt->CRT2ModeNo = -1;
++ pXGIEnt->CRT2ModeSet = FALSE;
++ pXGI->DualHeadMode = TRUE;
++ pXGIEnt->DisableDual = FALSE;
++ pXGIEnt->BIOS = NULL;
++ pXGIEnt->XGI_Pr = NULL;
++ pXGIEnt->RenderAccelArray = NULL;
++ }
++ else {
++ /* Second Head (always CRT1) */
++ pXGI->SecondHead = TRUE;
++ pXGIEnt->pScrn_2 = pScrn;
++ pXGI->DualHeadMode = TRUE;
++ }
++ }
++ else {
++ /* Only one screen in config file - disable dual head mode */
++ pXGI->SecondHead = FALSE;
++ pXGI->DualHeadMode = FALSE;
++ pXGIEnt->DisableDual = TRUE;
++ }
++ }
++ else {
++ /* Entity is not shared - disable dual head mode */
++ pXGI->SecondHead = FALSE;
++ pXGI->DualHeadMode = FALSE;
++ }
++#endif
++
++ /* Allocate VB_DEVICE_INFO (for mode switching code) and initialize it */
++ pXGI->XGI_Pr = NULL;
++ if (pXGIEnt && pXGIEnt->XGI_Pr) {
++ pXGI->XGI_Pr = pXGIEnt->XGI_Pr;
++ }
++
++ if (!pXGI->XGI_Pr) {
++ if (!(pXGI->XGI_Pr = xnfcalloc(sizeof(VB_DEVICE_INFO), 1))) {
++ XGIErrorLog(pScrn,
++ "Could not allocate memory for XGI_Pr private\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ if (pXGIEnt)
++ pXGIEnt->XGI_Pr = pXGI->XGI_Pr;
++
++ memset(pXGI->XGI_Pr, 0, sizeof(VB_DEVICE_INFO));
++ }
++
++ /* Get our relocated IO registers */
++ pXGI->RelIO = (XGIIOADDRESS) (pXGI->IODBase |
++#ifdef XSERVER_LIBPCIACCESS
++ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
++#else
++ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
++#endif
++ );
++ pXGI->xgi_HwDevExt.pjIOAddress = (XGIIOADDRESS) (pXGI->RelIO + 0x30);
++ xf86DrvMsg(pScrn->scrnIndex, from, "Relocated IO registers at 0x%lX\n",
++ (unsigned long) pXGI->RelIO);
++
++ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, pix24flags)) {
++ XGIErrorLog(pScrn, "xf86SetDepthBpp() error\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ /* Check that the returned depth is one we support */
++ temp = 0;
++ switch (pScrn->depth) {
++ case 8:
++ case 16:
++ case 24:
++#if !defined(__powerpc__)
++ case 15:
++#endif
++ break;
++ default:
++ temp = 1;
++ }
++
++ if (temp) {
++ XGIErrorLog(pScrn,
++ "Given color depth (%d) is not supported by this driver/chipset\n",
++ pScrn->depth);
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ xf86PrintDepthBpp(pScrn);
++
++ /* Get the depth24 pixmap format */
++ if (pScrn->depth == 24 && pix24bpp == 0) {
++ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
++ }
++
++ /*
++ * This must happen after pScrn->display has been set because
++ * xf86SetWeight references it.
++ */
++ if (pScrn->depth > 8) {
++ /* The defaults are OK for us */
++ rgb zeros = { 0, 0, 0 };
++
++ if (!xf86SetWeight(pScrn, zeros, zeros)) {
++ XGIErrorLog(pScrn, "xf86SetWeight() error\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ else {
++ Bool ret = FALSE;
++ switch (pScrn->depth) {
++ case 15:
++ if ((pScrn->weight.red != 5) ||
++ (pScrn->weight.green != 5) || (pScrn->weight.blue != 5))
++ ret = TRUE;
++ break;
++ case 16:
++ if ((pScrn->weight.red != 5) ||
++ (pScrn->weight.green != 6) || (pScrn->weight.blue != 5))
++ ret = TRUE;
++ break;
++ case 24:
++ if ((pScrn->weight.red != 8) ||
++ (pScrn->weight.green != 8) || (pScrn->weight.blue != 8))
++ ret = TRUE;
++ break;
++ }
++ if (ret) {
++ XGIErrorLog(pScrn,
++ "RGB weight %d%d%d at depth %d not supported by hardware\n",
++ (int) pScrn->weight.red,
++ (int) pScrn->weight.green,
++ (int) pScrn->weight.blue, pScrn->depth);
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ }
++ }
++
++ /* Set the current layout parameters */
++ pXGI->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
++ pXGI->CurrentLayout.depth = pScrn->depth;
++ /* (Inside this function, we can use pScrn's contents anyway) */
++
++ if (!xf86SetDefaultVisual(pScrn, -1)) {
++ XGIErrorLog(pScrn, "xf86SetDefaultVisual() error\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ else {
++ /* We don't support DirectColor at > 8bpp */
++ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
++ XGIErrorLog(pScrn,
++ "Given default visual (%s) is not supported at depth %d\n",
++ xf86GetVisualName(pScrn->defaultVisual),
++ pScrn->depth);
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ }
++
++ /* Due to palette & timing problems we don't support 8bpp in DHM */
++ if ((IS_DUAL_HEAD(pXGI)) && (pScrn->bitsPerPixel == 8)) {
++ XGIErrorLog(pScrn,
++ "Color depth 8 not supported in Dual Head mode.\n");
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ /*
++ * The cmap layer needs this to be initialised.
++ */
++ {
++ Gamma zeros = { 0.0, 0.0, 0.0 };
++
++ if (!xf86SetGamma(pScrn, zeros)) {
++ XGIErrorLog(pScrn, "xf86SetGamma() error\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ }
++
++ /* We use a programamble clock */
++ pScrn->progClock = TRUE;
++
++ /* Set the bits per RGB for 8bpp mode */
++ if (pScrn->depth == 8) {
++ pScrn->rgbBits = 6;
++ }
++
++ from = X_DEFAULT;
++
++ /* Unlock registers */
++ xgiSaveUnlockExtRegisterLock(pXGI, &srlockReg, &crlockReg);
++
++ /* Read BIOS for 300 and 315/330 series customization */
++ pXGI->xgi_HwDevExt.pjVirtualRomBase = NULL;
++ pXGI->BIOS = NULL;
++ pXGI->xgi_HwDevExt.UseROM = FALSE;
++
++ /* Evaluate options */
++ xgiOptions(pScrn);
++
++#ifdef XGIMERGED
++ /* Due to palette & timing problems we don't support 8bpp in MFBM */
++ if ((pXGI->MergedFB) && (pScrn->bitsPerPixel == 8)) {
++ XGIErrorLog(pScrn, "MergedFB: Color depth 8 not supported, %s\n",
++ mergeddisstr);
++ pXGI->MergedFB = pXGI->MergedFBAuto = FALSE;
++ }
++#endif
++
++ /* Do basic configuration */
++
++ XGISetup(pScrn);
++
++ from = X_PROBED;
++#ifdef XSERVER_LIBPCIACCESS
++ pXGI->FbAddress = pXGI->PciInfo->regions[0].base_addr & 0xFFFFFFF0;
++#else
++ if (pXGI->pEnt->device->MemBase != 0) {
++ /*
++ * XXX Should check that the config file value matches one of the
++ * PCI base address values.
++ */
++ pXGI->FbAddress = pXGI->pEnt->device->MemBase;
++ from = X_CONFIG;
++ }
++ else {
++ pXGI->FbAddress = pXGI->PciInfo->memBase[0] & 0xFFFFFFF0;
++ }
++#endif
++
++ pXGI->realFbAddress = pXGI->FbAddress;
++
++ xf86DrvMsg(pScrn->scrnIndex, from,
++ "%sinear framebuffer at 0x%lX\n",
++ IS_DUAL_HEAD(pXGI) ? "Global l" : "L",
++ (unsigned long) pXGI->FbAddress);
++
++#ifdef XSERVER_LIBPCIACCESS
++ pXGI->IOAddress = pXGI->PciInfo->regions[1].base_addr & 0xFFFFFFF0;
++#else
++ if (pXGI->pEnt->device->IOBase != 0) {
++ /*
++ * XXX Should check that the config file value matches one of the
++ * PCI base address values.
++ */
++ pXGI->IOAddress = pXGI->pEnt->device->IOBase;
++ from = X_CONFIG;
++ }
++ else {
++ pXGI->IOAddress = pXGI->PciInfo->memBase[1] & 0xFFFFFFF0;
++ }
++#endif
++
++ xf86DrvMsg(pScrn->scrnIndex, from,
++ "MMIO registers at 0x%lX (size %ldK)\n",
++ (unsigned long) pXGI->IOAddress, pXGI->mmioSize);
++ pXGI->xgi_HwDevExt.bIntegratedMMEnabled = TRUE;
++
++ /* Register the PCI-assigned resources. */
++ if (xf86RegisterResources(pXGI->pEnt->index, NULL, ResExclusive)) {
++ XGIErrorLog(pScrn,
++ "xf86RegisterResources() found resource conflicts\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ from = X_PROBED;
++ if (pXGI->pEnt->device->videoRam != 0) {
++
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Option \"VideoRAM\" ignored\n");
++ }
++
++ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d KB\n", pScrn->videoRam);
++
++ pXGI->FbMapSize = pXGI->availMem = pScrn->videoRam * 1024;
++ pXGI->xgi_HwDevExt.ulVideoMemorySize = pScrn->videoRam * 1024;
++ pXGI->xgi_HwDevExt.bSkipDramSizing = TRUE;
++
++ /* Calculate real availMem according to Accel/TurboQueue and
++ * HWCursur setting.
++ *
++ * TQ is max 64KiB. Reduce the available memory by 64KiB, and locate the
++ * TQ at the beginning of this last 64KiB block. This is done even when
++ * using the HWCursor, because the cursor only takes 2KiB and the queue
++ * does not seem to last that far anyway.
++ *
++ * The TQ must be located at 32KB boundaries.
++ */
++ if (pScrn->videoRam < 3072) {
++ if (pXGI->TurboQueue) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Not enough video RAM for TurboQueue. TurboQueue disabled\n");
++ pXGI->TurboQueue = FALSE;
++ }
++ }
++
++ pXGI->availMem -= (pXGI->TurboQueue) ? (64 * 1024) : pXGI->CursorSize;
++
++
++ /* In dual head mode, we share availMem equally - so align it
++ * to 8KB; this way, the address of the FB of the second
++ * head is aligned to 4KB for mapping.
++ *
++ * Check MaxXFBMem setting. Since DRI is not supported in dual head
++ * mode, we don't need the MaxXFBMem setting.
++ */
++ if (IS_DUAL_HEAD(pXGI)) {
++ if (pXGI->maxxfbmem) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "MaxXFBMem not used in Dual Head mode. Using all VideoRAM.\n");
++ }
++
++ pXGI->availMem &= 0xFFFFE000;
++ pXGI->maxxfbmem = pXGI->availMem;
++ }
++ else if (pXGI->maxxfbmem) {
++ if (pXGI->maxxfbmem > pXGI->availMem) {
++ if (pXGI->xgifbMem) {
++ pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Invalid MaxXFBMem setting. Using xgifb heap start information\n");
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Invalid MaxXFBMem setting. Using all VideoRAM for framebuffer\n");
++ pXGI->maxxfbmem = pXGI->availMem;
++ }
++ }
++ else if (pXGI->xgifbMem) {
++ if (pXGI->maxxfbmem > pXGI->xgifbMem * 1024) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "MaxXFBMem beyond xgifb heap start. Using xgifb heap start\n");
++ pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
++ }
++ }
++ }
++ else if (pXGI->xgifbMem) {
++ pXGI->maxxfbmem = pXGI->xgifbMem * 1024;
++ }
++ else
++ pXGI->maxxfbmem = pXGI->availMem;
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %ldK of framebuffer memory\n",
++ pXGI->maxxfbmem / 1024);
++
++ pXGI->CRT1off = -1;
++
++ /* Detect video bridge and sense TV/VGA2 */
++ XGIVGAPreInit(pScrn);
++
++ /* Detect CRT1 (via DDC1 and DDC2, hence via VGA port; regardless of LCDA) */
++ XGICRT1PreInit(pScrn);
++
++ /* Detect LCD (connected via CRT2, regardless of LCDA) and LCD resolution */
++ XGILCDPreInit(pScrn);
++
++ /* LCDA only supported under these conditions: */
++ if (pXGI->ForceCRT1Type == CRT1_LCDA) {
++ if (!
++ (pXGI->XGI_Pr->
++ VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV |
++ VB_XGI302LV))) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Chipset/Video bridge does not support LCD-via-CRT1\n");
++ pXGI->ForceCRT1Type = CRT1_VGA;
++ }
++ else if (!(pXGI->VBFlags & CRT2_LCD)) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "No digitally connected LCD panel found, LCD-via-CRT1 "
++ "disabled\n");
++ pXGI->ForceCRT1Type = CRT1_VGA;
++ }
++ }
++
++ /* Setup SD flags */
++ pXGI->XGI_SD_Flags |= XGI_SD_ADDLSUPFLAG;
++
++ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
++ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTV;
++ }
++
++#ifdef ENABLE_YPBPR
++ if (pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B)) {
++ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTHIVISION;
++ }
++#endif
++
++#ifdef TWDEBUG /* @@@ TEST @@@ */
++ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTYPBPRAR;
++ xf86DrvMsg(0, X_INFO, "TEST: Support Aspect Ratio\n");
++#endif
++
++ /* Detect CRT2-TV and PAL/NTSC mode */
++ XGITVPreInit(pScrn);
++
++ /* Detect CRT2-VGA */
++ XGICRT2PreInit(pScrn);
++ PDEBUG(ErrorF("3496 pXGI->VBFlags =%x\n", pXGI->VBFlags));
++
++ if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR)) {
++ if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_YPBPR)) {
++ pXGI->ForceTVType = -1;
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "YPbPr TV output not supported\n");
++ }
++ }
++
++ if (!(pXGI->XGI_SD_Flags & XGI_SD_SUPPORTHIVISION)) {
++ if ((pXGI->ForceTVType != -1) && (pXGI->ForceTVType & TV_HIVISION)) {
++ pXGI->ForceTVType = -1;
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "HiVision TV output not supported\n");
++ }
++ }
++
++ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
++ pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
++ }
++ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
++ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTTVPOS;
++ }
++ if (pXGI->XGI_Pr->
++ VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
++ pXGI->XGI_SD_Flags |= (XGI_SD_SUPPORTSCART | XGI_SD_SUPPORTVGA2);
++ }
++
++ if ((pXGI->XGI_Pr->
++ VBType & (VB_XGI301C | VB_XGI302B | VB_XGI301LV | VB_XGI302LV))
++ && (pXGI->VBFlags & CRT2_LCD)) {
++ pXGI->XGI_SD_Flags |= XGI_SD_SUPPORTLCDA;
++ }
++
++ pXGI->VBFlags |= pXGI->ForceCRT1Type;
++
++#ifdef TWDEBUG
++ xf86DrvMsg(0, X_INFO, "SDFlags %lx\n", pXGI->XGI_SD_Flags);
++#endif
++
++
++ if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI)) {
++ xf86DrvMsg(pScrn->scrnIndex, pXGI->CRT1gammaGiven ? X_CONFIG : X_INFO,
++ "CRT1 gamma correction is %s\n",
++ pXGI->CRT1gamma ? "enabled" : "disabled");
++ }
++
++ /* Eventually overrule TV Type (SVIDEO, COMPOSITE, SCART, HIVISION, YPBPR) */
++ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
++ if (pXGI->ForceTVType != -1) {
++ pXGI->VBFlags &= ~(TV_INTERFACE);
++ pXGI->VBFlags |= pXGI->ForceTVType;
++ if (pXGI->VBFlags & TV_YPBPR) {
++ pXGI->VBFlags &= ~(TV_STANDARD);
++ pXGI->VBFlags &= ~(TV_YPBPRAR);
++ pXGI->VBFlags |= pXGI->ForceYPbPrType;
++ pXGI->VBFlags |= pXGI->ForceYPbPrAR;
++ }
++ }
++ }
++
++ /* Check if CRT1 used or needed. There are three cases where this can
++ * happen:
++ * - No video bridge.
++ * - No CRT2 output.
++ * - Depth = 8 and bridge=LVDS|301B-DH
++ * - LCDA
++ */
++ if (((pXGI->XGI_Pr->VBType & VB_XGIVB) == 0)
++ || ((pXGI->VBFlags & (CRT2_VGA | CRT2_LCD | CRT2_TV)) == 0)
++ || ((pScrn->bitsPerPixel == 8)
++ && (pXGI->XGI_Pr->VBType & VB_XGI301LV302LV))
++ || (pXGI->VBFlags & CRT1_LCDA)) {
++ pXGI->CRT1off = 0;
++ }
++
++
++ /* Handle TVStandard option */
++ if ((pXGI->NonDefaultPAL != -1) || (pXGI->NonDefaultNTSC != -1)) {
++ if (!(pXGI->XGI_Pr->VBType & VB_XGIVB)) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "PALM, PALN and NTSCJ not supported on this hardware\n");
++ pXGI->NonDefaultPAL = pXGI->NonDefaultNTSC = -1;
++ pXGI->VBFlags &= ~(TV_PALN | TV_PALM | TV_NTSCJ);
++ pXGI->XGI_SD_Flags &=
++ ~(XGI_SD_SUPPORTPALMN | XGI_SD_SUPPORTNTSCJ);
++ }
++ }
++
++#ifdef XGI_CP
++ XGI_CP_DRIVER_RECONFIGOPT
++#endif
++ /* Do some MergedFB mode initialisation */
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ pXGI->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
++ if (!pXGI->CRT2pScrn) {
++ XGIErrorLog(pScrn,
++ "Failed to allocate memory for 2nd pScrn, %s\n",
++ mergeddisstr);
++ pXGI->MergedFB = FALSE;
++ }
++ else {
++ memcpy(pXGI->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
++ }
++ }
++#endif
++ PDEBUG(ErrorF("3674 pXGI->VBFlags =%x\n", pXGI->VBFlags));
++
++ /* Determine CRT1<>CRT2 mode
++ * Note: When using VESA or if the bridge is in slavemode, display
++ * is ALWAYS in MIRROR_MODE!
++ * This requires extra checks in functions using this flag!
++ * (see xgi_video.c for example)
++ */
++ if (pXGI->VBFlags & DISPTYPE_DISP2) {
++ if (pXGI->CRT1off) { /* CRT2 only ------------------------------- */
++ if (IS_DUAL_HEAD(pXGI)) {
++ XGIErrorLog(pScrn,
++ "CRT1 not detected or forced off. Dual Head mode can't initialize.\n");
++ if (pXGIEnt)
++ pXGIEnt->DisableDual = TRUE;
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ pXGI->pInt = NULL;
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ if (pXGI->MergedFBAuto) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt1,
++ mergeddisstr);
++ }
++ else {
++ XGIErrorLog(pScrn, mergednocrt1, mergeddisstr);
++ }
++ if (pXGI->CRT2pScrn)
++ xfree(pXGI->CRT2pScrn);
++ pXGI->CRT2pScrn = NULL;
++ pXGI->MergedFB = FALSE;
++ }
++#endif
++ pXGI->VBFlags |= VB_DISPMODE_SINGLE;
++ }
++ /* CRT1 and CRT2 - mirror or dual head ----- */
++ else if (IS_DUAL_HEAD(pXGI)) {
++ pXGI->VBFlags |= (VB_DISPMODE_DUAL | DISPTYPE_CRT1);
++ if (pXGIEnt)
++ pXGIEnt->DisableDual = FALSE;
++ }
++ else
++ pXGI->VBFlags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1);
++ }
++ else { /* CRT1 only ------------------------------- */
++ if (IS_DUAL_HEAD(pXGI)) {
++ XGIErrorLog(pScrn,
++ "No CRT2 output selected or no bridge detected. "
++ "Dual Head mode can't initialize.\n");
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ pXGI->pInt = NULL;
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ if (pXGI->MergedFBAuto) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, mergednocrt2,
++ mergeddisstr);
++ }
++ else {
++ XGIErrorLog(pScrn, mergednocrt2, mergeddisstr);
++ }
++ if (pXGI->CRT2pScrn)
++ xfree(pXGI->CRT2pScrn);
++ pXGI->CRT2pScrn = NULL;
++ pXGI->MergedFB = FALSE;
++ }
++#endif
++ PDEBUG(ErrorF("3782 pXGI->VBFlags =%x\n", pXGI->VBFlags));
++ pXGI->VBFlags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1);
++ }
++
++ /* Init Ptrs for Save/Restore functions and calc MaxClock */
++ XGIDACPreInit(pScrn);
++
++ /* ********** end of VBFlags setup ********** */
++
++ /* VBFlags are initialized now. Back them up for SlaveMode modes. */
++ pXGI->VBFlags_backup = pXGI->VBFlags;
++
++ /* Find out about paneldelaycompensation and evaluate option */
++ if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
++
++ }
++
++ /* In dual head mode, both heads (currently) share the maxxfbmem equally.
++ * If memory sharing is done differently, the following has to be changed;
++ * the other modules (eg. accel and Xv) use dhmOffset for hardware
++ * pointer settings relative to VideoRAM start and won't need to be changed.
++ */
++ if (IS_DUAL_HEAD(pXGI)) {
++ if (!IS_SECOND_HEAD(pXGI)) {
++ /* ===== First head (always CRT2) ===== */
++ /* We use only half of the memory available */
++ pXGI->maxxfbmem /= 2;
++ /* Initialize dhmOffset */
++ pXGI->dhmOffset = 0;
++ /* Copy framebuffer addresses & sizes to entity */
++ pXGIEnt->masterFbAddress = pXGI->FbAddress;
++ pXGIEnt->masterFbSize = pXGI->maxxfbmem;
++ pXGIEnt->slaveFbAddress = pXGI->FbAddress + pXGI->maxxfbmem;
++ pXGIEnt->slaveFbSize = pXGI->maxxfbmem;
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "%ldKB video RAM at 0x%lx available for master head (CRT2)\n",
++ pXGI->maxxfbmem / 1024, pXGI->FbAddress);
++ }
++ else {
++ /* ===== Second head (always CRT1) ===== */
++ /* We use only half of the memory available */
++ pXGI->maxxfbmem /= 2;
++ /* Adapt FBAddress */
++ pXGI->FbAddress += pXGI->maxxfbmem;
++ /* Initialize dhmOffset */
++ pXGI->dhmOffset = pXGI->availMem - pXGI->maxxfbmem;
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "%ldKB video RAM at 0x%lx available for slave head (CRT1)\n",
++ pXGI->maxxfbmem / 1024, pXGI->FbAddress);
++ }
++ }
++ else
++ pXGI->dhmOffset = 0;
++
++ /* Note: Do not use availMem for anything from now. Use
++ * maxxfbmem instead. (availMem does not take dual head
++ * mode into account.)
++ */
++
++#if !defined(__powerpc__)
++ /* Now load and initialize VBE module. */
++ if (xf86LoadSubModule(pScrn, "vbe")) {
++ xf86LoaderReqSymLists(vbeSymbols, NULL);
++ pXGI->pVbe = VBEExtendedInit(pXGI->pInt, pXGI->pEnt->index,
++ SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
++ if (!pXGI->pVbe) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Could not initialize VBE module for DDC\n");
++ }
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Could not load VBE module\n");
++ }
++
++ XGIDDCPreInit(pScrn);
++#endif
++ /* From here, we mainly deal with clocks and modes */
++
++ /* Set the min pixel clock */
++ pXGI->MinClock = 5000;
++
++ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
++ pXGI->MinClock / 1000);
++
++ from = X_PROBED;
++ /*
++ * If the user has specified ramdac speed in the XF86Config
++ * file, we respect that setting.
++ */
++ if (pXGI->pEnt->device->dacSpeeds[0]) {
++ int speed = 0;
++ switch (pScrn->bitsPerPixel) {
++ case 8:
++ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP8];
++ break;
++ case 16:
++ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP16];
++ break;
++ case 24:
++ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP24];
++ break;
++ case 32:
++ speed = pXGI->pEnt->device->dacSpeeds[DAC_BPP32];
++ break;
++ }
++ if (speed == 0)
++ pXGI->MaxClock = pXGI->pEnt->device->dacSpeeds[0];
++ else
++ pXGI->MaxClock = speed;
++ from = X_CONFIG;
++ }
++ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
++ pXGI->MaxClock / 1000);
++
++ /*
++ * Setup the ClockRanges, which describe what clock ranges are available,
++ * and what sort of modes they can be used for.
++ */
++ clockRanges = xnfcalloc(sizeof(ClockRange), 1);
++ clockRanges->next = NULL;
++ clockRanges->minClock = pXGI->MinClock;
++ clockRanges->maxClock = pXGI->MaxClock;
++ clockRanges->clockIndex = -1; /* programmable */
++ clockRanges->interlaceAllowed = TRUE;
++ clockRanges->doubleScanAllowed = TRUE;
++
++ /*
++ * xf86ValidateModes will check that the mode HTotal and VTotal values
++ * don't exceed the chipset's limit if pScrn->maxHValue and
++ * pScrn->maxVValue are set. Since our XGIValidMode() already takes
++ * care of this, we don't worry about setting them here.
++ */
++
++ /* Select valid modes from those available */
++#ifdef XGIMERGED
++ pXGI->CheckForCRT2 = FALSE;
++#endif
++ XGIDumpMonPtr(pScrn->monitor);
++
++ /* Jong 12/05/2007; filter support modes of CRT1 by CRT2 DDC */
++ /* XGIFilterModeByDDC(pScrn->monitor->Modes, g_pMonitorDVI); */ /* Do it in XGIValidMode() */
++
++ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes, clockRanges, NULL, 256, 2048, /* min / max pitch */
++ pScrn->bitsPerPixel * 8, 128, 2048, /* min / max height */
++ pScrn->display->virtualX,
++ pScrn->display->virtualY,
++ pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
++
++ if (i == -1) {
++ XGIErrorLog(pScrn, "xf86ValidateModes() error\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ /* Check the virtual screen against the available memory */
++
++ memreq = (pScrn->virtualX * ((pScrn->bitsPerPixel + 7) / 8))
++ * pScrn->virtualY;
++
++ if (memreq > pXGI->maxxfbmem) {
++ XGIErrorLog(pScrn,
++ "Virtual screen too big for memory; %ldK needed, %ldK available\n",
++ memreq / 1024, pXGI->maxxfbmem / 1024);
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ pXGI->pInt = NULL;
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ else if (pXGI->loadDRI && !IS_DUAL_HEAD(pXGI)) {
++ pXGI->maxxfbmem = memreq;
++ pXGI->DRIheapstart = pXGI->DRIheapend = 0;
++
++ if (pXGI->maxxfbmem == pXGI->availMem) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "All video memory used for framebuffer. DRI will be disabled.\n");
++ pXGI->loadDRI = FALSE;
++ }
++ else {
++ pXGI->DRIheapstart = pXGI->maxxfbmem;
++ pXGI->DRIheapend = pXGI->availMem;
++ }
++ }
++
++
++ /* Dual Head:
++ * -) Go through mode list and mark all those modes as bad,
++ * which are unsuitable for dual head mode.
++ * -) Find the highest used pixelclock on the master head.
++ */
++ if (IS_DUAL_HEAD(pXGI) && !IS_SECOND_HEAD(pXGI)) {
++ pXGIEnt->maxUsedClock = 0;
++
++ if ((p = first = pScrn->modes)) {
++ do {
++ n = p->next;
++
++ /* Modes that require the bridge to operate in SlaveMode
++ * are not suitable for Dual Head mode.
++ */
++
++ /* Search for the highest clock on first head in order to calculate
++ * max clock for second head (CRT1)
++ */
++ if ((p->status == MODE_OK)
++ && (p->Clock > pXGIEnt->maxUsedClock)) {
++ pXGIEnt->maxUsedClock = p->Clock;
++ }
++
++ p = n;
++
++ } while (p != NULL && p != first);
++ }
++ }
++
++ /* Prune the modes marked as invalid */
++ xf86PruneDriverModes(pScrn);
++
++ if (i == 0 || pScrn->modes == NULL) {
++ XGIErrorLog(pScrn, "No valid modes found\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++
++ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
++
++ /* Set the current mode to the first in the list */
++ pScrn->currentMode = pScrn->modes;
++
++ /* Copy to CurrentLayout */
++ pXGI->CurrentLayout.mode = pScrn->currentMode;
++ pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 1);
++ }
++#endif
++
++ /* Print the list of modes being used */
++ xf86PrintModes(pScrn);
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ BOOLEAN acceptcustommodes = TRUE;
++ BOOLEAN includelcdmodes = TRUE;
++ BOOLEAN isfordvi = FALSE;
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, crtsetupstr, 2);
++
++ clockRanges->next = NULL;
++ clockRanges->minClock = pXGI->MinClock;
++ clockRanges->clockIndex = -1;
++ clockRanges->interlaceAllowed = FALSE;
++ clockRanges->doubleScanAllowed = FALSE;
++
++ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
++ "Min pixel clock for CRT2 is %d MHz\n",
++ clockRanges->minClock / 1000);
++ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT,
++ "Max pixel clock for CRT2 is %d MHz\n",
++ clockRanges->maxClock / 1000);
++
++ if ((pXGI->XGI_Pr->
++ VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C | VB_XGI302B)))
++ {
++ if (!(pXGI->VBFlags & (CRT2_LCD | CRT2_VGA)))
++ includelcdmodes = FALSE;
++ if (pXGI->VBFlags & CRT2_LCD)
++ isfordvi = TRUE;
++ if (pXGI->VBFlags & CRT2_TV)
++ acceptcustommodes = FALSE;
++ }
++ else {
++ includelcdmodes = FALSE;
++ acceptcustommodes = FALSE;
++ }
++ }
++
++ if (pXGI->MergedFB) {
++
++ pXGI->CheckForCRT2 = TRUE;
++ i = xf86ValidateModes(pXGI->CRT2pScrn,
++ pXGI->CRT2pScrn->monitor->Modes,
++ pXGI->CRT2pScrn->display->modes, clockRanges,
++ NULL, 256, 4088,
++ pXGI->CRT2pScrn->bitsPerPixel * 8, 128, 4096,
++ pScrn->display->virtualX ? pScrn->virtualX : 0,
++ pScrn->display->virtualY ? pScrn->virtualY : 0,
++ pXGI->maxxfbmem, LOOKUP_BEST_REFRESH);
++ pXGI->CheckForCRT2 = FALSE;
++
++ if (i == -1) {
++ XGIErrorLog(pScrn, "xf86ValidateModes() error, %s.\n",
++ mergeddisstr);
++ XGIFreeCRT2Structs(pXGI);
++ pXGI->MergedFB = FALSE;
++ }
++
++ }
++
++ if (pXGI->MergedFB) {
++
++ if ((p = first = pXGI->CRT2pScrn->modes)) {
++ do {
++ n = p->next;
++ p = n;
++ } while (p != NULL && p != first);
++ }
++
++ xf86PruneDriverModes(pXGI->CRT2pScrn);
++
++ if (i == 0 || pXGI->CRT2pScrn->modes == NULL) {
++ XGIErrorLog(pScrn, "No valid modes found for CRT2; %s\n",
++ mergeddisstr);
++ XGIFreeCRT2Structs(pXGI);
++ pXGI->MergedFB = FALSE;
++ }
++
++ }
++
++ if (pXGI->MergedFB) {
++
++ xf86SetCrtcForModes(pXGI->CRT2pScrn, INTERLACE_HALVE_V);
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, modesforstr, 2);
++
++ xf86PrintModes(pXGI->CRT2pScrn);
++
++ pXGI->CRT1Modes = pScrn->modes;
++ pXGI->CRT1CurrentMode = pScrn->currentMode;
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Generating MergedFB mode list\n");
++
++ pScrn->modes = XGIGenerateModeList(pScrn, pXGI->MetaModes,
++ pXGI->CRT1Modes,
++ pXGI->CRT2pScrn->modes,
++ pXGI->CRT2Position);
++
++ if (!pScrn->modes) {
++
++ XGIErrorLog(pScrn,
++ "Failed to parse MetaModes or no modes found. %s.\n",
++ mergeddisstr);
++ XGIFreeCRT2Structs(pXGI);
++ pScrn->modes = pXGI->CRT1Modes;
++ pXGI->CRT1Modes = NULL;
++ pXGI->MergedFB = FALSE;
++
++ }
++
++ }
++
++ if (pXGI->MergedFB) {
++
++ /* If no virtual dimension was given by the user,
++ * calculate a sane one now. Adapts pScrn->virtualX,
++ * pScrn->virtualY and pScrn->displayWidth.
++ */
++ XGIRecalcDefaultVirtualSize(pScrn);
++
++ pScrn->modes = pScrn->modes->next; /* We get the last from GenerateModeList(), skip to first */
++ pScrn->currentMode = pScrn->modes;
++
++ /* Update CurrentLayout */
++ pXGI->CurrentLayout.mode = pScrn->currentMode;
++ pXGI->CurrentLayout.displayWidth = pScrn->displayWidth;
++
++ }
++#endif
++
++ /* Set display resolution */
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ XGIMergedFBSetDpi(pScrn, pXGI->CRT2pScrn, pXGI->CRT2Position);
++ }
++ else
++#endif
++ xf86SetDpi(pScrn, 0, 0);
++
++ /*yilin@20080407 fix the font too small problem at low resolution*/
++ if((pScrn->xDpi < 65)||(pScrn->yDpi < 65))
++ {
++ pScrn->xDpi = 75;
++ pScrn->yDpi = 75;
++ }
++
++ /* Load fb module */
++ switch (pScrn->bitsPerPixel) {
++ case 8:
++ case 16:
++ case 24:
++ case 32:
++ if (!xf86LoadSubModule(pScrn, "fb")) {
++ XGIErrorLog(pScrn, "Failed to load fb module");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ break;
++ default:
++ XGIErrorLog(pScrn, "Unsupported framebuffer bpp (%d)\n",
++ pScrn->bitsPerPixel);
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ xf86LoaderReqSymLists(fbSymbols, NULL);
++
++ /* Load XAA if needed */
++ if (!pXGI->NoAccel) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Accel enabled\n");
++ if (!xf86LoadSubModule(pScrn, "xaa")) {
++ XGIErrorLog(pScrn, "Could not load xaa module\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ xf86LoaderReqSymLists(xaaSymbols, NULL);
++ }
++
++ /* Load shadowfb if needed */
++ if (pXGI->ShadowFB) {
++ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
++ XGIErrorLog(pScrn, "Could not load shadowfb module\n");
++
++ if (pXGIEnt)
++ pXGIEnt->ErrorAfterFirst = TRUE;
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++ XGIFreeRec(pScrn);
++ return FALSE;
++ }
++ xf86LoaderReqSymLists(shadowSymbols, NULL);
++ }
++
++ /* Load the dri module if requested. */
++#ifdef XF86DRI
++ if(pXGI->loadDRI) {
++ if (xf86LoadSubModule(pScrn, "dri")) {
++ xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL);
++ }
++ else {
++ if (!IS_DUAL_HEAD(pXGI))
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ "Remove >Load \"dri\"< from the Module section of your XF86Config file\n");
++ }
++ }
++#endif
++
++
++ /* Now load and initialize VBE module for VESA and mode restoring. */
++ if (pXGI->pVbe) {
++ vbeFree(pXGI->pVbe);
++ pXGI->pVbe = NULL;
++ }
++
++#ifdef XGIDUALHEAD
++ xf86SetPrimInitDone(pScrn->entityList[0]);
++#endif
++
++ xgiRestoreExtRegisterLock(pXGI, srlockReg, crlockReg);
++
++ if (pXGI->pInt)
++ xf86FreeInt10(pXGI->pInt);
++ pXGI->pInt = NULL;
++
++ if (IS_DUAL_HEAD(pXGI)) {
++ pXGI->XGI_SD_Flags |= XGI_SD_ISDUALHEAD;
++ if (IS_SECOND_HEAD(pXGI))
++ pXGI->XGI_SD_Flags |= XGI_SD_ISDHSECONDHEAD;
++ else
++ pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
++#ifdef PANORAMIX
++ if (!noPanoramiXExtension) {
++ pXGI->XGI_SD_Flags |= XGI_SD_ISDHXINERAMA;
++ pXGI->XGI_SD_Flags &= ~(XGI_SD_SUPPORTXVGAMMA1);
++ }
++#endif
++ }
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB)
++ pXGI->XGI_SD_Flags |= XGI_SD_ISMERGEDFB;
++#endif
++
++ if (pXGI->enablexgictrl)
++ pXGI->XGI_SD_Flags |= XGI_SD_ENABLED;
++
++ return TRUE;
++}
++
++
++/*
++ * Map the framebuffer and MMIO memory.
++ */
++
++static Bool
++XGIMapMem(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);;
++
++#ifdef XSERVER_LIBPCIACCESS
++ unsigned i;
++
++ for (i = 0; i < 2; i++) {
++ int err;
++
++ err = pci_device_map_region(pXGI->PciInfo, i, TRUE);
++ if (err) {
++ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
++ "Internal error: cound not map PCI region %u\n", i);
++ return FALSE;
++ }
++ }
++
++ pXGI->FbBase = pXGI->PciInfo->regions[0].memory;
++ pXGI->IOBase = pXGI->PciInfo->regions[1].memory;
++#else
++ int mmioFlags;
++
++ /*
++ * Map IO registers to virtual address space
++ */
++#if !defined(__alpha__)
++ mmioFlags = VIDMEM_MMIO;
++#else
++ /*
++ * For Alpha, we need to map SPARSE memory, since we need
++ * byte/short access.
++ */
++ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
++#endif
++ pXGI->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
++ pXGI->PciTag, pXGI->IOAddress, 0x10000);
++ if (pXGI->IOBase == NULL)
++ return FALSE;
++
++#ifdef __alpha__
++ /*
++ * for Alpha, we need to map DENSE memory as well, for
++ * setting CPUToScreenColorExpandBase.
++ */
++ pXGI->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
++ pXGI->PciTag, pXGI->IOAddress, 0x10000);
++
++ if (pXGI->IOBaseDense == NULL)
++ return FALSE;
++#endif /* __alpha__ */
++
++ pXGI->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
++ pXGI->PciTag,
++ (unsigned long) pXGI->FbAddress,
++ pXGI->FbMapSize);
++
++ PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n", (ULONG) (pXGI->FbBase)));
++
++ if (pXGI->FbBase == NULL)
++ return FALSE;
++#endif
++
++ return TRUE;
++}
++
++
++/*
++ * Unmap the framebuffer and MMIO memory.
++ */
++
++static Bool
++XGIUnmapMem(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
++
++
++ /* In dual head mode, we must not unmap if the other head still
++ * assumes memory as mapped
++ */
++ if (IS_DUAL_HEAD(pXGI)) {
++ if (pXGIEnt->MapCountIOBase) {
++ pXGIEnt->MapCountIOBase--;
++ if ((pXGIEnt->MapCountIOBase == 0) || (pXGIEnt->forceUnmapIOBase)) {
++#ifdef XSERVER_LIBPCIACCESS
++ pci_device_unmap_region(pXGI->PciInfo, 1);
++#else
++ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->IOBase,
++ (pXGI->mmioSize * 1024));
++#endif
++ pXGIEnt->IOBase = NULL;
++ pXGIEnt->MapCountIOBase = 0;
++ pXGIEnt->forceUnmapIOBase = FALSE;
++ }
++ pXGI->IOBase = NULL;
++ }
++#ifdef __alpha__
++#ifdef XSERVER_LIBPCIACCESS
++#error "How to do dense mapping on Alpha?"
++#else
++ if (pXGIEnt->MapCountIOBaseDense) {
++ pXGIEnt->MapCountIOBaseDense--;
++ if ((pXGIEnt->MapCountIOBaseDense == 0)
++ || (pXGIEnt->forceUnmapIOBaseDense)) {
++ xf86UnMapVidMem(pScrn->scrnIndex,
++ (pointer) pXGIEnt->IOBaseDense,
++ (pXGI->mmioSize * 1024));
++ pXGIEnt->IOBaseDense = NULL;
++ pXGIEnt->MapCountIOBaseDense = 0;
++ pXGIEnt->forceUnmapIOBaseDense = FALSE;
++ }
++ pXGI->IOBaseDense = NULL;
++ }
++#endif
++#endif /* __alpha__ */
++ if (pXGIEnt->MapCountFbBase) {
++ pXGIEnt->MapCountFbBase--;
++ if ((pXGIEnt->MapCountFbBase == 0) || (pXGIEnt->forceUnmapFbBase)) {
++#ifdef XSERVER_LIBPCIACCESS
++ pci_device_unmap_region(pXGI->PciInfo, 0);
++#else
++ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGIEnt->FbBase,
++ pXGI->FbMapSize);
++#endif
++ pXGIEnt->FbBase = NULL;
++ pXGIEnt->MapCountFbBase = 0;
++ pXGIEnt->forceUnmapFbBase = FALSE;
++
++ }
++ pXGI->FbBase = NULL;
++ }
++ }
++ else {
++#ifdef XSERVER_LIBPCIACCESS
++ pci_device_unmap_region(pXGI->PciInfo, 0);
++ pci_device_unmap_region(pXGI->PciInfo, 1);
++#else
++ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBase,
++ (pXGI->mmioSize * 1024));
++ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->FbBase,
++ pXGI->FbMapSize);
++#endif
++ pXGI->IOBase = NULL;
++ pXGI->FbBase = NULL;
++
++#ifdef __alpha__
++#ifdef XSERVER_LIBPCIACCESS
++#error "How to do dense mapping on Alpha?"
++#else
++ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pXGI->IOBaseDense,
++ (pXGI->mmioSize * 1024));
++ pXGI->IOBaseDense = NULL;
++#endif
++#endif
++ }
++
++ return TRUE;
++}
++
++/*
++ * This function saves the video state.
++ */
++static void
++XGISave(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI;
++ vgaRegPtr vgaReg;
++ XGIRegPtr xgiReg;
++
++ PDEBUG(ErrorF("XGISave()\n"));
++
++ pXGI = XGIPTR(pScrn);
++
++ /* We always save master & slave */
++ if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
++ return;
++
++ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
++ xgiReg = &pXGI->SavedReg;
++
++ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
++
++ xgiSaveUnlockExtRegisterLock(pXGI, &xgiReg->xgiRegs3C4[0x05],
++ &xgiReg->xgiRegs3D4[0x80]);
++
++ (*pXGI->XGISave) (pScrn, xgiReg);
++
++ /* "Save" these again as they may have been changed prior to XGISave() call */
++}
++
++
++/*
++ * Initialise a new mode. This is currently done using the
++ * "initialise struct, restore/write struct to HW" model for
++ * the old chipsets (5597/530/6326). For newer chipsets,
++ * we use our own mode switching code (or VESA).
++ */
++
++static Bool
++XGIModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
++{
++ vgaHWPtr hwp = VGAHWPTR(pScrn);
++ vgaRegPtr vgaReg;
++ XGIPtr pXGI = XGIPTR(pScrn);
++ XGIRegPtr xgiReg;
++#ifdef __powerpc__
++ unsigned char tmpval;
++#endif
++
++
++ /* PDEBUG(ErrorF("XGIModeInit(). \n")); */
++ PDEBUG(ErrorF
++ ("XGIModeInit Resolution (%d, %d) \n", mode->HDisplay,
++ mode->VDisplay));
++ PDEBUG(ErrorF("XGIModeInit VVRefresh (%8.3f) \n", mode->VRefresh));
++ PDEBUG(ErrorF("XGIModeInit Color Depth (%d) \n", pScrn->depth));
++
++ /* Jong Lin 08-26-2005; save current mode */
++ Volari_SetDefaultIdleWait(pXGI, mode->HDisplay, pScrn->depth);
++
++ andXGIIDXREG(XGICR, 0x11, 0x7f); /* Unlock CRTC registers */
++
++ XGIModifyModeInfo(mode); /* Quick check of the mode parameters */
++
++
++ if (IS_DUAL_HEAD(pXGI)) {
++ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
++
++ if (!(*pXGI->ModeInit) (pScrn, mode)) {
++ XGIErrorLog(pScrn, "ModeInit() failed\n");
++ return FALSE;
++ }
++
++ pScrn->vtSema = TRUE;
++
++ /* Head 2 (slave) is always CRT1 */
++ XGIPreSetMode(pScrn, mode, XGI_MODE_CRT1);
++ if (!XGIBIOSSetModeCRT1(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn,
++ mode)) {
++ XGIErrorLog(pScrn, "XGIBIOSSetModeCRT1() failed\n");
++ return FALSE;
++ }
++ XGIPostSetMode(pScrn, &pXGI->ModeReg);
++ XGIAdjustFrame(pXGIEnt->pScrn_1->scrnIndex, pXGIEnt->pScrn_1->frameX0,
++ pXGIEnt->pScrn_1->frameY0, 0);
++ }
++ else
++ {
++ /* For other chipsets, use the old method */
++
++ /* Initialise the ModeReg values */
++ if (!vgaHWInit(pScrn, mode)) {
++ XGIErrorLog(pScrn, "vgaHWInit() failed\n");
++ return FALSE;
++ }
++
++ /* Reset our PIOOffset as vgaHWInit might have reset it */
++ VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
++#ifdef XSERVER_LIBPCIACCESS
++ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
++#else
++ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
++#endif
++ ;
++
++ /* Prepare the register contents */
++ if (!(*pXGI->ModeInit) (pScrn, mode)) {
++ XGIErrorLog(pScrn, "ModeInit() failed\n");
++ return FALSE;
++ }
++
++ pScrn->vtSema = TRUE;
++
++ /* Program the registers */
++ vgaHWProtect(pScrn, TRUE);
++ vgaReg = &hwp->ModeReg;
++ xgiReg = &pXGI->ModeReg;
++
++ vgaReg->Attribute[0x10] = 0x01;
++ if (pScrn->bitsPerPixel > 8) {
++ vgaReg->Graphics[0x05] = 0x00;
++ }
++
++ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
++
++ (*pXGI->XGIRestore) (pScrn, xgiReg);
++
++#ifdef TWDEBUG
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "REAL REGISTER CONTENTS AFTER SETMODE:\n");
++ (*pXGI->ModeInit) (pScrn, mode);
++#endif
++
++ vgaHWProtect(pScrn, FALSE);
++ }
++
++
++ if((pXGI->Chipset == PCI_CHIP_XGIXG40)||(pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27))
++ {
++ /* PDEBUG(XGIDumpRegs(pScrn)) ; */
++ PDEBUG(ErrorF(" *** PreSetMode(). \n"));
++ XGIPreSetMode(pScrn, mode, XGI_MODE_SIMU);
++ /* PDEBUG(XGIDumpRegs(pScrn)) ; */
++ PDEBUG(ErrorF(" *** Start SetMode() \n"));
++
++ if (!XGIBIOSSetMode(pXGI->XGI_Pr, &pXGI->xgi_HwDevExt, pScrn, mode)) {
++ XGIErrorLog(pScrn, "XGIBIOSSetModeCRT() failed\n");
++ return FALSE;
++ }
++ Volari_EnableAccelerator(pScrn);
++ /* XGIPostSetMode(pScrn, &pXGI->ModeReg); */
++ /* outXGIIDXREG(XGISR, 0x20, 0xA1) ; */
++ /* PDEBUG(XGIDumpRegs(pScrn)) ; */
++ }
++
++ /* Update Currentlayout */
++ pXGI->CurrentLayout.mode = mode;
++
++#ifdef __powerpc__
++ inXGIIDXREG(XGICR, 0x4D, tmpval);
++ if (pScrn->depth == 16)
++ tmpval = (tmpval & 0xE0) | 0x0B; //word swap
++ else if (pScrn->depth == 24)
++ tmpval = (tmpval & 0xE0) | 0x15; //dword swap
++ else
++ tmpval = tmpval & 0xE0; // no swap
++
++ outXGIIDXREG(XGICR, 0x4D, tmpval);
++#endif
++
++ return TRUE;
++}
++
++
++/*
++ * Restore the initial mode. To be used internally only!
++ */
++static void
++XGIRestore(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ XGIRegPtr xgiReg = &pXGI->SavedReg;
++ vgaHWPtr hwp = VGAHWPTR(pScrn);
++ vgaRegPtr vgaReg = &hwp->SavedReg;
++
++
++ PDEBUG(ErrorF("XGIRestore():\n"));
++
++ /* Wait for the accelerators */
++ if (pXGI->AccelInfoPtr) {
++ (*pXGI->AccelInfoPtr->Sync) (pScrn);
++ }
++
++ vgaHWProtect(pScrn, TRUE);
++
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++#endif
++
++ (*pXGI->XGIRestore) (pScrn, xgiReg);
++
++ /* Jong 11/14/2007; resolve no display of DVI after leaving VT */
++ /* But there's no int10 for PPC... */
++ /* XGIRestorePrevMode(pScrn) ; */
++ /* works but mode is not exactly right because there're more than one mode 0x03 in table XGI330_SModeIDTable[] */
++ XGISetModeNew( &pXGI->xgi_HwDevExt, pXGI->XGI_Pr, 0x03);
++
++ vgaHWProtect(pScrn, TRUE);
++ if (pXGI->Primary) {
++ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
++ }
++
++ xgiRestoreExtRegisterLock(pXGI, xgiReg->xgiRegs3C4[5],
++ xgiReg->xgiRegs3D4[0x80]);
++ vgaHWProtect(pScrn, FALSE);
++}
++
++
++/* Our generic BlockHandler for Xv */
++static void
++XGIBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
++{
++ ScreenPtr pScreen = screenInfo.screens[i];
++ ScrnInfoPtr pScrn = xf86Screens[i];
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ pScreen->BlockHandler = pXGI->BlockHandler;
++ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
++ pScreen->BlockHandler = XGIBlockHandler;
++
++ if (pXGI->VideoTimerCallback) {
++ (*pXGI->VideoTimerCallback) (pScrn, currentTime.milliseconds);
++ }
++
++ if (pXGI->RenderCallback) {
++ (*pXGI->RenderCallback) (pScrn);
++ }
++}
++
++/* Mandatory
++ * This gets called at the start of each server generation
++ *
++ * We use pScrn and not CurrentLayout here, because the
++ * properties we use have not changed (displayWidth,
++ * depth, bitsPerPixel)
++ */
++static Bool
++XGIScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
++{
++ ScrnInfoPtr pScrn;
++ vgaHWPtr hwp;
++ XGIPtr pXGI;
++ int ret;
++ VisualPtr visual;
++ unsigned long OnScreenSize;
++ int height, width, displayWidth;
++ unsigned char *FBStart;
++ XGIEntPtr pXGIEnt = NULL;
++
++ ErrorF("XGIScreenInit\n");
++ pScrn = xf86Screens[pScreen->myNum];
++
++ /* Jong 08/30/2007; no virtual screen for all cases */
++ /* Jong 08/22/2007; support modeline */
++ /* if(g_CountOfUserDefinedModes > 0) */
++ {
++ pScrn->virtualX=pScrn->currentMode->HDisplay;
++ pScrn->virtualY=pScrn->currentMode->VDisplay;
++ pScrn->displayWidth=pScrn->currentMode->HDisplay;
++ pScrn->frameX0=0;
++ pScrn->frameY0=0;
++ pScrn->frameX1=pScrn->currentMode->HDisplay-1;
++ pScrn->frameY1=pScrn->currentMode->VDisplay-1;
++ }
++
++ hwp = VGAHWPTR(pScrn);
++
++ pXGI = XGIPTR(pScrn);
++
++#if !defined(__powerpc__)
++ if (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) {
++ if (xf86LoadSubModule(pScrn, "vbe")) {
++ xf86LoaderReqSymLists(vbeSymbols, NULL);
++ pXGI->pVbe = VBEExtendedInit(NULL, pXGI->pEnt->index,
++ SET_BIOS_SCRATCH |
++ RESTORE_BIOS_SCRATCH);
++ }
++ else {
++ XGIErrorLog(pScrn, "Failed to load VBE submodule\n");
++ }
++ }
++#endif /* if !defined(__powerpc__) */
++
++ if (IS_DUAL_HEAD(pXGI)) {
++ pXGIEnt = ENTITY_PRIVATE(pXGI);
++ pXGIEnt->refCount++;
++ }
++
++ /* Map the VGA memory and get the VGA IO base */
++ if (pXGI->Primary) {
++ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
++ if (!vgaHWMapMem(pScrn)) {
++ XGIErrorLog(pScrn, "Could not map VGA memory window\n");
++ return FALSE;
++ }
++ }
++ vgaHWGetIOBase(hwp);
++
++ /* Patch the PIOOffset inside vgaHW to use
++ * our relocated IO ports.
++ */
++ VGAHWPTR(pScrn)->PIOOffset = pXGI->IODBase - 0x380 +
++#ifdef XSERVER_LIBPCIACCESS
++ (pXGI->PciInfo->regions[2].base_addr & 0xFFFC)
++#else
++ (pXGI->PciInfo->ioBase[2] & 0xFFFC)
++#endif
++ ;
++
++ /* Map the XGI memory and MMIO areas */
++ if (!XGIMapMem(pScrn)) {
++ XGIErrorLog(pScrn, "XGIMapMem() failed\n");
++ return FALSE;
++ }
++
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++#endif
++
++ /* Save the current state */
++ XGISave(pScrn);
++
++
++ PDEBUG(ErrorF("--- ScreenInit --- \n"));
++ PDEBUG(XGIDumpRegs(pScrn));
++
++ /* Initialise the first mode */
++ if (!XGIModeInit(pScrn, pScrn->currentMode)) {
++ XGIErrorLog(pScrn, "XGIModeInit() failed\n");
++ return FALSE;
++ }
++
++ PDEBUG(ErrorF("--- XGIModeInit --- \n"));
++ PDEBUG(XGIDumpRegs(pScrn));
++
++ /* Darken the screen for aesthetic reasons */
++ /* Not using Dual Head variant on purpose; we darken
++ * the screen for both displays, and un-darken
++ * it when the second head is finished
++ */
++ XGISaveScreen(pScreen, SCREEN_SAVER_ON);
++
++ /* Set the viewport */
++ XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
++
++ /*
++ * The next step is to setup the screen's visuals, and initialise the
++ * framebuffer code. In cases where the framebuffer's default
++ * choices for things like visual layouts and bits per RGB are OK,
++ * this may be as simple as calling the framebuffer's ScreenInit()
++ * function. If not, the visuals will need to be setup before calling
++ * a fb ScreenInit() function and fixed up after.
++ *
++ * For most PC hardware at depths >= 8, the defaults that cfb uses
++ * are not appropriate. In this driver, we fixup the visuals after.
++ */
++
++ /*
++ * Reset visual list.
++ */
++ miClearVisualTypes();
++
++ /* Setup the visuals we support. */
++
++ /*
++ * For bpp > 8, the default visuals are not acceptable because we only
++ * support TrueColor and not DirectColor.
++ */
++ if (!miSetVisualTypes(pScrn->depth,
++ (pScrn->bitsPerPixel > 8) ?
++ TrueColorMask : miGetDefaultVisualMask(pScrn->
++ depth),
++ pScrn->rgbBits, pScrn->defaultVisual)) {
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ XGIErrorLog(pScrn, "miSetVisualTypes() failed (bpp %d)\n",
++ pScrn->bitsPerPixel);
++ return FALSE;
++ }
++
++ width = pScrn->virtualX;
++ height = pScrn->virtualY;
++ displayWidth = pScrn->displayWidth;
++
++ if (pXGI->Rotate) {
++ height = pScrn->virtualX;
++ width = pScrn->virtualY;
++ }
++
++ if (pXGI->ShadowFB) {
++ pXGI->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
++ pXGI->ShadowPtr = xalloc(pXGI->ShadowPitch * height);
++ displayWidth = pXGI->ShadowPitch / (pScrn->bitsPerPixel >> 3);
++ FBStart = pXGI->ShadowPtr;
++ }
++ else {
++ pXGI->ShadowPtr = NULL;
++ FBStart = pXGI->FbBase;
++ }
++
++ if (!miSetPixmapDepths()) {
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ XGIErrorLog(pScrn, "miSetPixmapDepths() failed\n");
++ return FALSE;
++ }
++
++ /* Point cmdQueuePtr to pXGIEnt for shared usage
++ * (same technique is then eventually used in DRIScreeninit).
++ */
++ if (IS_SECOND_HEAD(pXGI))
++ pXGI->cmdQueueLenPtr = &(XGIPTR(pXGIEnt->pScrn_1)->cmdQueueLen);
++ else
++ pXGI->cmdQueueLenPtr = &(pXGI->cmdQueueLen);
++
++ pXGI->cmdQueueLen = 0; /* Force an EngineIdle() at start */
++
++#ifdef XF86DRI
++ if(pXGI->loadDRI) {
++ /* No DRI in dual head mode */
++ if (IS_DUAL_HEAD(pXGI)) {
++ pXGI->directRenderingEnabled = FALSE;
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "DRI not supported in Dual Head mode\n");
++ }
++ else if ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21)||(pXGI->Chipset == PCI_CHIP_XGIXG27)) {
++ PDEBUG(ErrorF("--- DRI not supported \n"));
++ xf86DrvMsg(pScrn->scrnIndex, X_NOT_IMPLEMENTED,
++ "DRI not supported on this chipset\n");
++ pXGI->directRenderingEnabled = FALSE;
++ }
++ else {
++ pXGI->directRenderingEnabled = XGIDRIScreenInit(pScreen);
++ PDEBUG(ErrorF("--- DRI supported \n"));
++ }
++ }
++#endif
++
++ /*
++ * Call the framebuffer layer's ScreenInit function, and fill in other
++ * pScreen fields.
++ */
++ switch (pScrn->bitsPerPixel) {
++ case 24:
++ case 8:
++ case 16:
++ case 32:
++ ret = fbScreenInit(pScreen, FBStart, width,
++ height, pScrn->xDpi, pScrn->yDpi,
++ displayWidth, pScrn->bitsPerPixel);
++ break;
++ default:
++ ret = FALSE;
++ break;
++ }
++ if (!ret) {
++ XGIErrorLog(pScrn, "Unsupported bpp (%d) or fbScreenInit() failed\n",
++ pScrn->bitsPerPixel);
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ return FALSE;
++ }
++
++ if (pScrn->bitsPerPixel > 8) {
++ /* Fixup RGB ordering */
++ visual = pScreen->visuals + pScreen->numVisuals;
++ while (--visual >= pScreen->visuals) {
++ if ((visual->class | DynamicClass) == DirectColor) {
++ visual->offsetRed = pScrn->offset.red;
++ visual->offsetGreen = pScrn->offset.green;
++ visual->offsetBlue = pScrn->offset.blue;
++ visual->redMask = pScrn->mask.red;
++ visual->greenMask = pScrn->mask.green;
++ visual->blueMask = pScrn->mask.blue;
++ }
++ }
++ }
++
++ /* Initialize RENDER ext; must be after RGB ordering fixed */
++ fbPictureInit(pScreen, 0, 0);
++
++ /* hardware cursor needs to wrap this layer <-- TW: what does that mean? */
++ if (!pXGI->ShadowFB)
++ XGIDGAInit(pScreen);
++
++ xf86SetBlackWhitePixels(pScreen);
++
++ if (!pXGI->NoAccel) {
++ /* Volari_EnableAccelerator(pScrn); */
++ PDEBUG(ErrorF("---Volari Accel.. \n"));
++ Volari_AccelInit(pScreen);
++ }
++
++ PDEBUG(ErrorF("--- AccelInit --- \n"));
++ PDEBUG(XGIDumpRegs(pScrn));
++
++ miInitializeBackingStore(pScreen);
++ xf86SetBackingStore(pScreen);
++ xf86SetSilkenMouse(pScreen);
++
++ /* Initialise cursor functions */
++ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
++
++ if (pXGI->HWCursor) {
++ XGIHWCursorInit(pScreen);
++ }
++
++ /* Initialise default colourmap */
++ if (!miCreateDefColormap(pScreen)) {
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ XGIErrorLog(pScrn, "miCreateDefColormap() failed\n");
++ return FALSE;
++ }
++ if (!xf86HandleColormaps
++ (pScreen, 256, (pScrn->depth == 8) ? 8 : pScrn->rgbBits,
++ XGILoadPalette, NULL,
++ CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) {
++ PDEBUG(ErrorF("XGILoadPalette() check-return. \n"));
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ XGIErrorLog(pScrn, "xf86HandleColormaps() failed\n");
++ return FALSE;
++ }
++
++/*
++ if (!xf86HandleColormaps(pScreen, 256, 8, XGILoadPalette, NULL,
++ CMAP_RELOAD_ON_MODE_SWITCH))
++ {
++ return FALSE;
++ }
++*/
++ xf86DPMSInit(pScreen, (DPMSSetProcPtr) XGIDisplayPowerManagementSet, 0);
++
++ /* Init memPhysBase and fbOffset in pScrn */
++ pScrn->memPhysBase = pXGI->FbAddress;
++ pScrn->fbOffset = 0;
++
++ pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
++
++#if defined(XvExtension)
++ if (!pXGI->NoXvideo) {
++ XGIInitVideo(pScreen);
++ }
++#endif
++
++#ifdef XF86DRI
++ if (pXGI->directRenderingEnabled) {
++ /* Now that mi, drm and others have done their thing,
++ * complete the DRI setup.
++ */
++ pXGI->directRenderingEnabled = XGIDRIFinishScreenInit(pScreen);
++ }
++
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering %sabled\n",
++ (pXGI->directRenderingEnabled) ? "en" : "dis");
++ if (pXGI->directRenderingEnabled) {
++ /* TODO */
++ /* XGISetLFBConfig(pXGI); */
++ }
++#endif
++
++ /* Wrap some funcs and setup remaining SD flags */
++
++ pXGI->XGI_SD_Flags &= ~(XGI_SD_PSEUDOXINERAMA);
++
++ pXGI->CloseScreen = pScreen->CloseScreen;
++ pScreen->CloseScreen = XGICloseScreen;
++ if (IS_DUAL_HEAD(pXGI))
++ pScreen->SaveScreen = XGISaveScreenDH;
++ else
++ pScreen->SaveScreen = XGISaveScreen;
++
++ /* Install BlockHandler */
++ pXGI->BlockHandler = pScreen->BlockHandler;
++ pScreen->BlockHandler = XGIBlockHandler;
++
++ /* Report any unused options (only for the first generation) */
++ if (serverGeneration == 1) {
++ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
++ }
++
++ /* Clear frame buffer */
++ /* For CRT2, we don't do that at this point in dual head
++ * mode since the mode isn't switched at this time (it will
++ * be reset when setting the CRT1 mode). Hence, we just
++ * save the necessary data and clear the screen when
++ * going through this for CRT1.
++ */
++
++ OnScreenSize = pScrn->displayWidth * pScrn->currentMode->VDisplay
++ * (pScrn->bitsPerPixel >> 3);
++
++ /* Turn on the screen now */
++ /* We do this in dual head mode after second head is finished */
++ if (IS_DUAL_HEAD(pXGI)) {
++ if (IS_SECOND_HEAD(pXGI)) {
++ bzero(pXGI->FbBase, OnScreenSize);
++ bzero(pXGIEnt->FbBase1, pXGIEnt->OnScreenSize1);
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ }
++ else {
++ pXGIEnt->FbBase1 = pXGI->FbBase;
++ pXGIEnt->OnScreenSize1 = OnScreenSize;
++ }
++ }
++ else {
++ XGISaveScreen(pScreen, SCREEN_SAVER_OFF);
++ bzero(pXGI->FbBase, OnScreenSize);
++ }
++
++ pXGI->XGI_SD_Flags &= ~XGI_SD_ISDEPTH8;
++ if (pXGI->CurrentLayout.bitsPerPixel == 8) {
++ pXGI->XGI_SD_Flags |= XGI_SD_ISDEPTH8;
++ pXGI->XGI_SD_Flags &= ~XGI_SD_SUPPORTXVGAMMA1;
++ }
++ PDEBUG(ErrorF("XGIScreenInit() End. \n"));
++ PDEBUG(XGIDumpPalette(pScrn));
++ PDEBUG(XGIDumpRegs(pScrn));
++
++ return TRUE;
++}
++
++/* Usually mandatory */
++Bool
++XGISwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ ErrorF("XGISwitchMode\n");
++
++ if (!pXGI->NoAccel) {
++ if (pXGI->AccelInfoPtr) {
++ (*pXGI->AccelInfoPtr->Sync) (pScrn);
++ PDEBUG(ErrorF("XGISwitchMode Accel Enabled. \n"));
++ }
++ }
++ PDEBUG(ErrorF
++ ("XGISwitchMode (%d, %d) \n", mode->HDisplay, mode->VDisplay));
++
++ if (!(XGIModeInit(xf86Screens[scrnIndex], mode)))
++ return FALSE;
++
++ /* Since RandR (indirectly) uses SwitchMode(), we need to
++ * update our Xinerama info here, too, in case of resizing
++ */
++ return TRUE;
++}
++
++/* static void
++XGISetStartAddressCRT1(XGIPtr pXGI, unsigned long base)
++{
++ unsigned char cr11backup;
++
++ inXGIIDXREG(XGICR, 0x11, cr11backup);
++ andXGIIDXREG(XGICR, 0x11, 0x7F);
++ outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
++ outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
++ outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
++
++
++ setXGIIDXREG(XGICR, 0x11, 0x7F,(cr11backup & 0x80));
++} */
++
++#ifdef XGIMERGED
++/* static Bool
++InRegion(int x, int y, region r)
++{
++ return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
++} */
++
++/* static void
++XGIAdjustFrameHW_CRT1(ScrnInfoPtr pScrn, int x, int y)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned long base;
++
++ base = y * pXGI->CurrentLayout.displayWidth + x;
++ switch(pXGI->CurrentLayout.bitsPerPixel)
++ {
++ case 16: base >>= 1; break;
++ case 32: break;
++ default: base >>= 2;
++ }
++ XGISetStartAddressCRT1(pXGI, base);
++} */
++
++/* static void
++XGIMergePointerMoved(int scrnIndex, int x, int y)
++{
++ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
++ XGIPtr pXGI = XGIPTR(pScrn1);
++ ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
++ region out, in1, in2, f2, f1;
++ int deltax, deltay;
++
++ f1.x0 = pXGI->CRT1frameX0;
++ f1.x1 = pXGI->CRT1frameX1;
++ f1.y0 = pXGI->CRT1frameY0;
++ f1.y1 = pXGI->CRT1frameY1;
++ f2.x0 = pScrn2->frameX0;
++ f2.x1 = pScrn2->frameX1;
++ f2.y0 = pScrn2->frameY0;
++ f2.y1 = pScrn2->frameY1;
++
++ out.x0 = pScrn1->frameX0;
++ out.x1 = pScrn1->frameX1;
++ out.y0 = pScrn1->frameY0;
++ out.y1 = pScrn1->frameY1;
++
++ in1 = out;
++ in2 = out;
++ switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
++ {
++ case xgiLeftOf:
++ in1.x0 = f1.x0;
++ in2.x1 = f2.x1;
++ break;
++ case xgiRightOf:
++ in1.x1 = f1.x1;
++ in2.x0 = f2.x0;
++ break;
++ case xgiBelow:
++ in1.y1 = f1.y1;
++ in2.y0 = f2.y0;
++ break;
++ case xgiAbove:
++ in1.y0 = f1.y0;
++ in2.y1 = f2.y1;
++ break;
++ case xgiClone:
++ break;
++ }
++
++ deltay = 0;
++ deltax = 0;
++
++ if(InRegion(x, y, out))
++ {
++
++ if(InRegion(x, y, in1) && !InRegion(x, y, f1))
++ {
++ REBOUND(f1.x0, f1.x1, x);
++ REBOUND(f1.y0, f1.y1, y);
++ deltax = 1;
++ }
++ if(InRegion(x, y, in2) && !InRegion(x, y, f2))
++ {
++ REBOUND(f2.x0, f2.x1, x);
++ REBOUND(f2.y0, f2.y1, y);
++ deltax = 1;
++ }
++
++ }
++ else
++ {
++
++ if(out.x0 > x)
++ {
++ deltax = x - out.x0;
++ }
++ if(out.x1 < x)
++ {
++ deltax = x - out.x1;
++ }
++ if(deltax)
++ {
++ pScrn1->frameX0 += deltax;
++ pScrn1->frameX1 += deltax;
++ f1.x0 += deltax;
++ f1.x1 += deltax;
++ f2.x0 += deltax;
++ f2.x1 += deltax;
++ }
++
++ if(out.y0 > y)
++ {
++ deltay = y - out.y0;
++ }
++ if(out.y1 < y)
++ {
++ deltay = y - out.y1;
++ }
++ if(deltay)
++ {
++ pScrn1->frameY0 += deltay;
++ pScrn1->frameY1 += deltay;
++ f1.y0 += deltay;
++ f1.y1 += deltay;
++ f2.y0 += deltay;
++ f2.y1 += deltay;
++ }
++
++ switch(((XGIMergedDisplayModePtr)pXGI->CurrentLayout.mode->Private)->CRT2Position)
++ {
++ case xgiLeftOf:
++ if(x >= f1.x0)
++ { REBOUND(f1.y0, f1.y1, y); }
++ if(x <= f2.x1)
++ { REBOUND(f2.y0, f2.y1, y); }
++ break;
++ case xgiRightOf:
++ if(x <= f1.x1)
++ { REBOUND(f1.y0, f1.y1, y); }
++ if(x >= f2.x0)
++ { REBOUND(f2.y0, f2.y1, y); }
++ break;
++ case xgiBelow:
++ if(y <= f1.y1)
++ { REBOUND(f1.x0, f1.x1, x); }
++ if(y >= f2.y0)
++ { REBOUND(f2.x0, f2.x1, x); }
++ break;
++ case xgiAbove:
++ if(y >= f1.y0)
++ { REBOUND(f1.x0, f1.x1, x); }
++ if(y <= f2.y1)
++ { REBOUND(f2.x0, f2.x1, x); }
++ break;
++ case xgiClone:
++ break;
++ }
++
++ }
++
++ if(deltax || deltay)
++ {
++ pXGI->CRT1frameX0 = f1.x0;
++ pXGI->CRT1frameY0 = f1.y0;
++ pScrn2->frameX0 = f2.x0;
++ pScrn2->frameY0 = f2.y0;
++
++ pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
++ pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
++ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
++ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
++ pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
++ pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
++
++ XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
++ }
++} */
++
++
++/* static void
++XGIAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
++{
++ ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
++ XGIPtr pXGI = XGIPTR(pScrn1);
++ ScrnInfoPtr pScrn2 = pXGI->CRT2pScrn;
++ int VTotal = pXGI->CurrentLayout.mode->VDisplay;
++ int HTotal = pXGI->CurrentLayout.mode->HDisplay;
++ int VMax = VTotal;
++ int HMax = HTotal;
++
++ BOUND(x, 0, pScrn1->virtualX - HTotal);
++ BOUND(y, 0, pScrn1->virtualY - VTotal);
++
++ switch(SDMPTR(pScrn1)->CRT2Position)
++ {
++ case xgiLeftOf:
++ pScrn2->frameX0 = x;
++ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
++ pXGI->CRT1frameX0 = x + CDMPTR->CRT2->HDisplay;
++ BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
++ break;
++ case xgiRightOf:
++ pXGI->CRT1frameX0 = x;
++ BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
++ pScrn2->frameX0 = x + CDMPTR->CRT1->HDisplay;
++ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
++ break;
++ case xgiAbove:
++ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
++ pScrn2->frameY0 = y;
++ BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
++ pXGI->CRT1frameY0 = y + CDMPTR->CRT2->VDisplay;
++ break;
++ case xgiBelow:
++ BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
++ pXGI->CRT1frameY0 = y;
++ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
++ pScrn2->frameY0 = y + CDMPTR->CRT1->VDisplay;
++ break;
++ case xgiClone:
++ BOUND(pXGI->CRT1frameX0, x, x + HMax - CDMPTR->CRT1->HDisplay);
++ BOUND(pXGI->CRT1frameY0, y, y + VMax - CDMPTR->CRT1->VDisplay);
++ BOUND(pScrn2->frameX0, x, x + HMax - CDMPTR->CRT2->HDisplay);
++ BOUND(pScrn2->frameY0, y, y + VMax - CDMPTR->CRT2->VDisplay);
++ break;
++ }
++
++ BOUND(pXGI->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
++ BOUND(pXGI->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
++ BOUND(pScrn2->frameX0, 0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
++ BOUND(pScrn2->frameY0, 0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
++
++ pScrn1->frameX0 = x;
++ pScrn1->frameY0 = y;
++
++ pXGI->CRT1frameX1 = pXGI->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
++ pXGI->CRT1frameY1 = pXGI->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
++ pScrn2->frameX1 = pScrn2->frameX0 + CDMPTR->CRT2->HDisplay - 1;
++ pScrn2->frameY1 = pScrn2->frameY0 + CDMPTR->CRT2->VDisplay - 1;
++ pScrn1->frameX1 = pScrn1->frameX0 + pXGI->CurrentLayout.mode->HDisplay - 1;
++ pScrn1->frameY1 = pScrn1->frameY0 + pXGI->CurrentLayout.mode->VDisplay - 1;
++
++ XGIAdjustFrameHW_CRT1(pScrn1, pXGI->CRT1frameX0, pXGI->CRT1frameY0);
++} */
++#endif
++
++/*
++ * This function is used to initialize the Start Address - the first
++ * displayed location in the video memory.
++ *
++ * Usually mandatory
++ */
++void
++XGIAdjustFrame(int scrnIndex, int x, int y, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned long base;
++ unsigned char ucSR5Stat, ucTemp;
++
++ ErrorF("AdjustFrame %d\n", scrnIndex);
++ inXGIIDXREG(XGISR, 0x05, ucSR5Stat);
++ if (ucSR5Stat == 0xA1)
++ ucSR5Stat = 0x86;
++ outXGIIDXREG(XGISR, 0x05, 0x86);
++
++ base = (pScrn->bitsPerPixel + 7) / 8;
++ base *= x;
++ base += pXGI->scrnOffset * y;
++ base >>= 2;
++
++ switch (pXGI->Chipset) {
++ case PCI_CHIP_XGIXG40:
++ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21:
++ case PCI_CHIP_XGIXG27:
++ default:
++
++ ucTemp = base & 0xFF;
++ outXGIIDXREG(XGICR, 0x0D, ucTemp);
++ ucTemp = (base >> 8) & 0xFF;
++ outXGIIDXREG(XGICR, 0x0C, ucTemp);
++ ucTemp = (base >> 16) & 0xFF;
++ outXGIIDXREG(XGISR, 0x0D, ucTemp);
++ ucTemp = (base >> 24) & 0x01;
++ setXGIIDXREG(XGISR, 0x37, 0xFE, ucTemp);
++
++/* if (pXGI->VBFlags) {
++ XGI_UnLockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
++ ucTemp = base & 0xFF ; outXGIIDXREG( XGIPART1, 6 , ucTemp ) ;
++ ucTemp = (base>>8) & 0xFF ; outXGIIDXREG( XGIPART1, 5 , ucTemp ) ;
++ ucTemp = (base>>16) & 0xFF ; outXGIIDXREG( XGIPART1, 4 , ucTemp ) ;
++ ucTemp = (base>>24) & 0x01 ; ucTemp <<= 7 ;
++ setXGIIDXREG( XGIPART1, 0x2, 0x7F, ucTemp ) ;
++
++ XGI_LockCRT2(&(pXGI->xgi_HwDevExt),pXGI->pVBInfo);
++ }
++ */
++ break;
++
++ }
++
++ outXGIIDXREG(XGISR, 0x05, ucSR5Stat);
++
++}
++
++/*
++ * This is called when VT switching back to the X server. Its job is
++ * to reinitialise the video mode.
++ * Mandatory!
++ */
++static Bool
++XGIEnterVT(int scrnIndex, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++
++ if (!XGIModeInit(pScrn, pScrn->currentMode)) {
++ XGIErrorLog(pScrn, "XGIEnterVT: XGIModeInit() failed\n");
++ return FALSE;
++ }
++
++ XGIAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
++
++#ifdef XF86DRI
++ if (pXGI->directRenderingEnabled) {
++ DRIUnlock(screenInfo.screens[scrnIndex]);
++ }
++#endif
++
++ if ((!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI)) && (pXGI->ResetXv)) {
++ (pXGI->ResetXv) (pScrn);
++ }
++
++ return TRUE;
++}
++
++/*
++ * This is called when VT switching away from the X server. Its job is
++ * to restore the previous (text) mode.
++ * Mandatory!
++ */
++static void
++XGILeaveVT(int scrnIndex, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ vgaHWPtr hwp = VGAHWPTR(pScrn);
++ XGIPtr pXGI = XGIPTR(pScrn);
++#ifdef XF86DRI
++ ScreenPtr pScreen;
++
++ PDEBUG(ErrorF("XGILeaveVT()\n"));
++ if (pXGI->directRenderingEnabled) {
++ pScreen = screenInfo.screens[scrnIndex];
++ DRILock(pScreen, 0);
++ }
++#endif
++
++ if (IS_DUAL_HEAD(pXGI) && IS_SECOND_HEAD(pXGI))
++ return;
++
++ if (pXGI->CursorInfoPtr) {
++ /* Because of the test and return above, we know that this is not
++ * the second head.
++ */
++ pXGI->CursorInfoPtr->HideCursor(pScrn);
++ XGI_WaitBeginRetrace(pXGI->RelIO);
++ }
++
++ XGIRestore(pScrn);
++
++
++ /* We use (otherwise unused) bit 7 to indicate that we are running to keep
++ * xgifb to change the displaymode (this would result in lethal display
++ * corruption upon quitting X or changing to a VT until a reboot).
++ */
++ vgaHWLock(hwp);
++}
++
++
++/*
++ * This is called at the end of each server generation. It restores the
++ * original (text) mode. It should really also unmap the video memory too.
++ * Mandatory!
++ */
++static Bool
++XGICloseScreen(int scrnIndex, ScreenPtr pScreen)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ vgaHWPtr hwp = VGAHWPTR(pScrn);
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++
++#ifdef XF86DRI
++ if (pXGI->directRenderingEnabled) {
++ XGIDRICloseScreen(pScreen);
++ pXGI->directRenderingEnabled = FALSE;
++ }
++#endif
++
++ if (pScrn->vtSema) {
++ if (pXGI->CursorInfoPtr
++ && (!IS_DUAL_HEAD(pXGI) || !IS_SECOND_HEAD(pXGI))) {
++ pXGI->CursorInfoPtr->HideCursor(pScrn);
++ XGI_WaitBeginRetrace(pXGI->RelIO);
++ }
++
++
++ XGIRestore(pScrn);
++ vgaHWLock(hwp);
++ }
++
++ /* We should restore the mode number in case vtsema = false as well,
++ * but since we haven't register access then we can't do it. I think
++ * I need to rework the save/restore stuff, like saving the video
++ * status when returning to the X server and by that save me the
++ * trouble if xgifb was started from a textmode VT while X was on.
++ */
++
++ XGIUnmapMem(pScrn);
++ vgaHWUnmapMem(pScrn);
++
++ if (IS_DUAL_HEAD(pXGI)) {
++ XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
++ pXGIEnt->refCount--;
++ }
++
++ if (pXGI->pInt) {
++ xf86FreeInt10(pXGI->pInt);
++ pXGI->pInt = NULL;
++ }
++
++ if (pXGI->AccelLinearScratch) {
++ xf86FreeOffscreenLinear(pXGI->AccelLinearScratch);
++ pXGI->AccelLinearScratch = NULL;
++ }
++
++ if (pXGI->AccelInfoPtr) {
++ XAADestroyInfoRec(pXGI->AccelInfoPtr);
++ pXGI->AccelInfoPtr = NULL;
++ }
++
++ if (pXGI->CursorInfoPtr) {
++ xf86DestroyCursorInfoRec(pXGI->CursorInfoPtr);
++ pXGI->CursorInfoPtr = NULL;
++ }
++
++ if (pXGI->ShadowPtr) {
++ xfree(pXGI->ShadowPtr);
++ pXGI->ShadowPtr = NULL;
++ }
++
++ if (pXGI->DGAModes) {
++ xfree(pXGI->DGAModes);
++ pXGI->DGAModes = NULL;
++ }
++
++ if (pXGI->adaptor) {
++ xfree(pXGI->adaptor);
++ pXGI->adaptor = NULL;
++ pXGI->ResetXv = pXGI->ResetXvGamma = NULL;
++ }
++
++ pScrn->vtSema = FALSE;
++
++ /* Restore Blockhandler */
++ pScreen->BlockHandler = pXGI->BlockHandler;
++
++ pScreen->CloseScreen = pXGI->CloseScreen;
++
++ return (*pScreen->CloseScreen) (scrnIndex, pScreen);
++}
++
++
++/* Free up any per-generation data structures */
++
++/* Optional */
++static void
++XGIFreeScreen(int scrnIndex, int flags)
++{
++ if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) {
++ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
++ }
++
++ XGIFreeRec(xf86Screens[scrnIndex]);
++}
++
++
++/* Checks if a mode is suitable for the selected chipset. */
++
++static int
++XGIValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
++{
++ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
++ XGIPtr pXGI = XGIPTR(pScrn);
++ int HDisplay = mode->HDisplay;
++ int VDisplay = mode->VDisplay;
++ int Clock = mode->Clock;
++ int i = 0;
++ int VRefresh;
++
++ VRefresh =
++ (int) ((float) (Clock * 1000) /
++ (float) (mode->VTotal * mode->HTotal) + 0.5);
++
++ /* Jong 08/21/2007; support modeline */
++ /* We skip mode checking here and need improvement further */
++ if(mode->type == M_T_USERDEF)
++ return(MODE_OK);
++
++ PDEBUG5(ErrorF("XGIValidMode()."));
++ PDEBUG5(ErrorF
++ ("CLK=%5.3fMhz %dx%d@%d ", (float) Clock / 1000, HDisplay,
++ VDisplay, VRefresh));
++ PDEBUG5(ErrorF("(VT,HT)=(%d,%d)\n", mode->VTotal, mode->HTotal));
++
++ if (pXGI->VBFlags & CRT2_LCD) {
++ if ((HDisplay > 1600 && VDisplay > 1200)
++ || (HDisplay < 640 && VDisplay < 480)) {
++ PDEBUG5(ErrorF("skip by LCD limit\n"));
++ return (MODE_NOMODE);
++ }
++ /* if( VRefresh != 60) return(MODE_NOMODE) ; */
++ }
++ else if (pXGI->VBFlags & CRT2_TV) {
++ if ((HDisplay > 1024 && VDisplay > 768) ||
++ (HDisplay < 640 && VDisplay < 480) || (VRefresh != 60)) {
++ PDEBUG5(ErrorF("skip by TV limit\n"));
++ return (MODE_NOMODE);
++ }
++ }
++ else if (pXGI->VBFlags & CRT2_VGA) {
++ if ((HDisplay > 1600 && VDisplay > 1200) ||
++ (HDisplay < 640 && VDisplay < 480)) {
++ PDEBUG5(ErrorF("skip by CRT2 limit\n"));
++ return (MODE_NOMODE);
++ }
++ }
++
++ if ((pXGI->Chipset == PCI_CHIP_XGIXG20) ||(pXGI->Chipset == PCI_CHIP_XGIXG21) ||( pXGI->Chipset == PCI_CHIP_XGIXG27 )) {
++ XgiMode = XG20_Mode;
++ }
++ else {
++ XgiMode = XGI_Mode;
++ }
++
++ while ((XgiMode[i].Clock != Clock) ||
++ (XgiMode[i].HDisplay != HDisplay) ||
++ (XgiMode[i].VDisplay != VDisplay)) {
++ if (XgiMode[i].Clock == 0) {
++ PDEBUG5(ErrorF
++ ("--- NO_Mode support for %dx%d@%dHz\n", HDisplay,
++ VDisplay, VRefresh));
++ return (MODE_NOMODE);
++ }
++ else
++ i++;
++ }
++ PDEBUG5(ErrorF("Mode OK\n"));
++
++ /* Jong 12/05/2007; filter mode of CRT1 with CRT2 DDC for XG21 */
++ if(g_pMonitorDVI)
++ {
++ if(XGICheckModeByDDC(mode, g_pMonitorDVI) == FALSE)
++ return (MODE_NOMODE);
++ }
++
++ return (MODE_OK);
++}
++
++/* Do screen blanking
++ *
++ * Mandatory
++ */
++static Bool
++XGISaveScreen(ScreenPtr pScreen, int mode)
++{
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++
++ if ((pScrn != NULL) && pScrn->vtSema) {
++
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++#endif
++ }
++
++ return vgaHWSaveScreen(pScreen, mode);
++}
++
++/* SaveScreen for dual head mode */
++static Bool
++XGISaveScreenDH(ScreenPtr pScreen, int mode)
++{
++#ifdef XGIDUALHEAD
++ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
++
++ if ((pScrn != NULL) && pScrn->vtSema) {
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ if (IS_SECOND_HEAD(pXGI)
++ && ((!(pXGI->VBFlags & CRT1_LCDA))
++ || (pXGI->XGI_Pr->VBType & VB_XGI301C))) {
++
++ /* Slave head is always CRT1 */
++ if (pXGI->VBFlags & CRT1_LCDA)
++ pXGI->Blank = xf86IsUnblank(mode) ? FALSE : TRUE;
++
++ return vgaHWSaveScreen(pScreen, mode);
++ }
++ else {
++ /* Master head is always CRT2 */
++ /* But we land here if CRT1 is LCDA, too */
++
++ /* We can only blank LCD, not other CRT2 devices */
++ if (!(pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)))
++ return TRUE;
++
++ /* enable access to extended sequencer registers */
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++#endif
++ }
++ }
++#endif
++ return TRUE;
++}
++
++#ifdef DEBUG
++static void
++XGIDumpModeInfo(ScrnInfoPtr pScrn, DisplayModePtr mode)
++{
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock : %x\n", mode->Clock);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Display : %x\n",
++ mode->CrtcHDisplay);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank Start : %x\n",
++ mode->CrtcHBlankStart);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync Start : %x\n",
++ mode->CrtcHSyncStart);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Sync End : %x\n",
++ mode->CrtcHSyncEnd);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Blank End : %x\n",
++ mode->CrtcHBlankEnd);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Total : %x\n", mode->CrtcHTotal);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz Skew : %x\n", mode->CrtcHSkew);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hz HAdjusted : %x\n",
++ mode->CrtcHAdjusted);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Display : %x\n",
++ mode->CrtcVDisplay);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank Start : %x\n",
++ mode->CrtcVBlankStart);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync Start : %x\n",
++ mode->CrtcVSyncStart);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Sync End : %x\n",
++ mode->CrtcVSyncEnd);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Blank End : %x\n",
++ mode->CrtcVBlankEnd);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt Total : %x\n", mode->CrtcVTotal);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vt VAdjusted : %x\n",
++ mode->CrtcVAdjusted);
++}
++#endif
++
++static void
++XGIModifyModeInfo(DisplayModePtr mode)
++{
++ if (mode->CrtcHBlankStart == mode->CrtcHDisplay)
++ mode->CrtcHBlankStart++;
++ if (mode->CrtcHBlankEnd == mode->CrtcHTotal)
++ mode->CrtcHBlankEnd--;
++ if (mode->CrtcVBlankStart == mode->CrtcVDisplay)
++ mode->CrtcVBlankStart++;
++ if (mode->CrtcVBlankEnd == mode->CrtcVTotal)
++ mode->CrtcVBlankEnd--;
++}
++
++/* Things to do before a ModeSwitch. We set up the
++ * video bridge configuration and the TurboQueue.
++ */
++void
++XGIPreSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int viewmode)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned char CR30, CR31, CR33;
++ unsigned char CR3B = 0;
++ unsigned char CR17, CR38 = 0;
++ unsigned char CR35 = 0, CR79 = 0;
++ unsigned long vbflag;
++ int temp = 0;
++ int crt1rateindex = 0;
++ DisplayModePtr mymode;
++#ifdef XGIMERGED
++ DisplayModePtr mymode2 = NULL;
++#endif
++
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ mymode = ((XGIMergedDisplayModePtr) mode->Private)->CRT1;
++ mymode2 = ((XGIMergedDisplayModePtr) mode->Private)->CRT2;
++ }
++ else
++#endif
++ mymode = mode;
++
++ vbflag = pXGI->VBFlags;
++ PDEBUG(ErrorF("VBFlags=0x%lx\n", pXGI->VBFlags));
++
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL); /* Unlock Registers */
++#endif
++
++ inXGIIDXREG(XGICR, 0x30, CR30);
++ inXGIIDXREG(XGICR, 0x31, CR31);
++ inXGIIDXREG(XGICR, 0x33, CR33);
++
++ inXGIIDXREG(XGICR, 0x3b, CR3B);
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 4,
++ "Before: CR30=0x%02x, CR31=0x%02x, CR33=0x%02x, CR%02x=0x%02x\n",
++ CR30, CR31, CR33, temp, CR38);
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "VBFlags=0x%lx\n",
++ pXGI->VBFlags);
++
++ CR30 = 0x00;
++ CR31 &= ~0x60; /* Clear VB_Drivermode & VB_OutputDisable */
++ CR31 |= 0x04; /* Set VB_NotSimuMode (not for 30xB/1400x1050?) */
++ CR35 = 0x00;
++
++
++ if (!pXGI->AllowHotkey) {
++ CR31 |= 0x80; /* Disable hotkey-switch */
++ }
++ CR79 &= ~0x10; /* Enable Backlight control on 315 series */
++
++
++ if ((vbflag & CRT1_LCDA) && (viewmode == XGI_MODE_CRT1)) {
++
++ CR38 |= 0x02;
++
++ }
++ else {
++
++ switch (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
++
++ case CRT2_TV:
++
++ CR38 &= ~0xC0; /* Clear Pal M/N bits */
++
++ if (vbflag & TV_YPBPR) { /* Video bridge */
++ if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPR) {
++ CR30 |= 0x80;
++ CR38 |= 0x08;
++ if (vbflag & TV_YPBPR525P)
++ CR38 |= 0x10;
++ else if (vbflag & TV_YPBPR750P)
++ CR38 |= 0x20;
++ else if (vbflag & TV_YPBPR1080I)
++ CR38 |= 0x30;
++ CR31 &= ~0x01;
++ if (pXGI->XGI_SD_Flags & XGI_SD_SUPPORTYPBPRAR) {
++ CR3B &= ~0x03;
++ if ((vbflag & TV_YPBPRAR) == TV_YPBPR43LB)
++ CR3B |= 0x00;
++ else if ((vbflag & TV_YPBPRAR) == TV_YPBPR43)
++ CR3B |= 0x03;
++ else if ((vbflag & TV_YPBPRAR) == TV_YPBPR169)
++ CR3B |= 0x01;
++ else
++ CR3B |= 0x03;
++ }
++ }
++ }
++ else { /* All */
++ if (vbflag & TV_SCART)
++ CR30 |= 0x10;
++ if (vbflag & TV_SVIDEO)
++ CR30 |= 0x08;
++ if (vbflag & TV_AVIDEO)
++ CR30 |= 0x04;
++ if (!(CR30 & 0x1C))
++ CR30 |= 0x08; /* default: SVIDEO */
++
++ if (vbflag & TV_PAL) {
++ CR31 |= 0x01;
++ CR35 |= 0x01;
++ if (pXGI->XGI_Pr->VBType & VB_XGIVB) {
++ if (vbflag & TV_PALM) {
++ CR38 |= 0x40;
++ CR35 |= 0x04;
++ }
++ else if (vbflag & TV_PALN) {
++ CR38 |= 0x80;
++ CR35 |= 0x08;
++ }
++ }
++ }
++ else {
++ CR31 &= ~0x01;
++ CR35 &= ~0x01;
++ if (vbflag & TV_NTSCJ) {
++ CR38 |= 0x40; /* TW, not BIOS */
++ CR35 |= 0x02;
++ }
++ }
++ if (vbflag & TV_SCART) {
++ CR31 |= 0x01;
++ CR35 |= 0x01;
++ }
++ }
++
++ CR31 &= ~0x04; /* Clear NotSimuMode */
++#ifdef XGI_CP
++ XGI_CP_DRIVER_CONFIG
++#endif
++ break;
++
++ case CRT2_LCD:
++ CR30 |= 0x20;
++ break;
++
++ case CRT2_VGA:
++ CR30 |= 0x40;
++ break;
++
++ default:
++ CR30 |= 0x00;
++ CR31 |= 0x20; /* VB_OUTPUT_DISABLE */
++ }
++
++ }
++
++ if (vbflag & CRT1_LCDA) {
++ switch (viewmode) {
++ case XGI_MODE_CRT1:
++ CR38 |= 0x01;
++ break;
++ case XGI_MODE_CRT2:
++ if (vbflag & (CRT2_TV | CRT2_VGA)) {
++ CR30 |= 0x02;
++ CR38 |= 0x01;
++ }
++ else {
++ CR38 |= 0x03;
++ }
++ break;
++ case XGI_MODE_SIMU:
++ default:
++ if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
++ CR30 |= 0x01;
++ }
++ break;
++ }
++ }
++ else {
++ if (vbflag & (CRT2_TV | CRT2_LCD | CRT2_VGA)) {
++ CR30 |= 0x01;
++ }
++ }
++
++ CR31 |= 0x40; /* Set Drivermode */
++ CR31 &= ~0x06; /* Disable SlaveMode, disable SimuMode in SlaveMode */
++ crt1rateindex = XGISearchCRT1Rate(pScrn, mymode);
++
++ if (IS_DUAL_HEAD(pXGI)) {
++ if (IS_SECOND_HEAD(pXGI)) {
++ /* CRT1 */
++ CR33 &= 0xf0;
++ if (!(vbflag & CRT1_LCDA)) {
++ CR33 |= (crt1rateindex & 0x0f);
++ }
++ }
++ else {
++ /* CRT2 */
++ CR33 &= 0x0f;
++ if (vbflag & CRT2_VGA) {
++ CR33 |= ((crt1rateindex << 4) & 0xf0);
++ }
++ }
++ }
++ else
++#ifdef XGIMERGED
++ if (pXGI->MergedFB) {
++ CR33 = 0;
++ if (!(vbflag & CRT1_LCDA)) {
++ CR33 |= (crt1rateindex & 0x0f);
++ }
++ if (vbflag & CRT2_VGA) {
++ CR33 |= (XGISearchCRT1Rate(pScrn, mymode2) << 4);
++ }
++ }
++ else
++#endif
++ {
++ CR33 = 0;
++ if (!(vbflag & CRT1_LCDA)) {
++ CR33 |= (crt1rateindex & 0x0f);
++ }
++ if (vbflag & CRT2_VGA) {
++ CR33 |= ((crt1rateindex & 0x0f) << 4);
++ }
++ if (vbflag & CRT2_ENABLE) {
++ if (pXGI->CRT1off)
++ CR33 &= 0xf0;
++ }
++ }
++ outXGIIDXREG(XGICR, 0x30, CR30);
++ outXGIIDXREG(XGICR, 0x31, CR31);
++ outXGIIDXREG(XGICR, 0x33, CR33);
++ if (temp) {
++ outXGIIDXREG(XGICR, temp, CR38);
++ }
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
++ "After: CR30=0x%02x,CR31=0x%02x,CR33=0x%02x,CR%02x=%02x\n",
++ CR30, CR31, CR33, temp, CR38);
++
++ if (pXGI->VBFlags & CRT2_ENABLE) {
++ /* Switch on CRT1 for modes that require the bridge in SlaveMode */
++ andXGIIDXREG(XGISR, 0x1f, 0x3f);
++ inXGIIDXREG(XGICR, 0x17, CR17);
++ if (!(CR17 & 0x80)) {
++ orXGIIDXREG(XGICR, 0x17, 0x80);
++ outXGIIDXREG(XGISR, 0x00, 0x01);
++ usleep(10000);
++ outXGIIDXREG(XGISR, 0x00, 0x03);
++ }
++ }
++}
++
++/* PostSetMode:
++ * -) Disable CRT1 for saving bandwidth. This doesn't work with VESA;
++ * VESA uses the bridge in SlaveMode and switching CRT1 off while
++ * the bridge is in SlaveMode not that clever...
++ * -) Check if overlay can be used (depending on dotclock)
++ * -) Check if Panel Scaler is active on LVDS for overlay re-scaling
++ * -) Save TV registers for further processing
++ * -) Apply TV settings
++ */
++static void
++XGIPostSetMode(ScrnInfoPtr pScrn, XGIRegPtr xgiReg)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++/* unsigned char usScratchCR17;
++ Bool flag = FALSE;
++ Bool doit = TRUE; */
++ int myclock;
++ unsigned char sr2b, sr2c, tmpreg;
++ float num, denum, postscalar, divider;
++ PDEBUG(ErrorF(" XGIPostSetMode(). \n"));
++#ifdef TWDEBUG
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT1off is %d\n", pXGI->CRT1off);
++#endif
++
++#ifdef UNLOCK_ALWAYS
++ xgiSaveUnlockExtRegisterLock(pXGI, NULL, NULL);
++#endif
++
++ /* Determine if the video overlay can be used */
++ if (!pXGI->NoXvideo) {
++ inXGIIDXREG(XGISR, 0x2b, sr2b);
++ inXGIIDXREG(XGISR, 0x2c, sr2c);
++ divider = (sr2b & 0x80) ? 2.0 : 1.0;
++ postscalar = (sr2c & 0x80) ?
++ ((((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) :
++ (((sr2c >> 5) & 0x03) + 1.0);
++ num = (sr2b & 0x7f) + 1.0;
++ denum = (sr2c & 0x1f) + 1.0;
++ myclock =
++ (int) ((14318 * (divider / postscalar) * (num / denum)) / 1000);
++
++ pXGI->MiscFlags &= ~(MISC_CRT1OVERLAY | MISC_CRT1OVERLAYGAMMA);
++/* switch(pXGI->xgi_HwDevExt.jChipType) {
++ break;
++ }
++ */
++ if (!(pXGI->MiscFlags & MISC_CRT1OVERLAY)) {
++ if (!IS_DUAL_HEAD(pXGI) || IS_SECOND_HEAD(pXGI))
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 3,
++ "Current dotclock (%dMhz) too high for video overlay on CRT1\n",
++ myclock);
++ }
++ }
++
++ /* Determine if the Panel Link scaler is active */
++ pXGI->MiscFlags &= ~MISC_PANELLINKSCALER;
++ if (pXGI->VBFlags & (CRT2_LCD | CRT1_LCDA)) {
++ if (pXGI->VBFlags & CRT1_LCDA) {
++ inXGIIDXREG(XGIPART1, 0x35, tmpreg);
++ tmpreg &= 0x04;
++ if (!tmpreg)
++ pXGI->MiscFlags |= MISC_PANELLINKSCALER;
++ }
++ }
++
++ /* Determine if our very special TV mode is active */
++ pXGI->MiscFlags &= ~MISC_TVNTSC1024;
++ if ((pXGI->XGI_Pr->VBType & VB_XGIVB) && (pXGI->VBFlags & CRT2_TV)
++ && (!(pXGI->VBFlags & TV_HIVISION))) {
++ if (((pXGI->VBFlags & TV_YPBPR) && (pXGI->VBFlags & TV_YPBPR525I))
++ || ((!(pXGI->VBFlags & TV_YPBPR))
++ && (pXGI->VBFlags & (TV_NTSC | TV_PALM)))) {
++ inXGIIDXREG(XGICR, 0x34, tmpreg);
++ tmpreg &= 0x7f;
++ if ((tmpreg == 0x64) || (tmpreg == 0x4a) || (tmpreg == 0x38)) {
++ pXGI->MiscFlags |= MISC_TVNTSC1024;
++ }
++ }
++ }
++
++ /* Reset XV gamma correction */
++ if (pXGI->ResetXvGamma) {
++ (pXGI->ResetXvGamma) (pScrn);
++ }
++
++ /* Apply TV settings given by options
++ * Do this even in DualHeadMode:
++ * - if this is called by SetModeCRT1, CRT2 mode has been reset by SetModeCRT1
++ * - if this is called by SetModeCRT2, CRT2 mode has changed (duh!)
++ * -> Hence, in both cases, the settings must be re-applied.
++ */
++}
++
++
++USHORT
++XGI_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode,
++ unsigned long VBFlags)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ UShort i = (pXGI->CurrentLayout.bitsPerPixel + 7) / 8 - 1;
++
++ if ((VBFlags & CRT1_LCDA)) {
++ if ((mode->HDisplay > pXGI->LCDwidth) ||
++ (mode->VDisplay > pXGI->LCDheight)) {
++ return 0;
++ }
++ }
++
++ return XGI_GetModeID(VBFlags, mode->HDisplay, mode->VDisplay,
++ i, pXGI->LCDwidth, pXGI->LCDheight);
++}
++
++/* Calculate the vertical refresh rate from a mode */
++int
++XGICalcVRate(DisplayModePtr mode)
++{
++ float hsync, refresh = 0;
++
++ if (mode->HSync > 0.0)
++ hsync = mode->HSync;
++ else if (mode->HTotal > 0)
++ hsync = (float) mode->Clock / (float) mode->HTotal;
++ else
++ hsync = 0.0;
++
++ if (mode->VTotal > 0)
++ refresh = hsync * 1000.0 / mode->VTotal;
++
++ if (mode->Flags & V_INTERLACE)
++ refresh *= 2.0;
++
++ if (mode->Flags & V_DBLSCAN)
++ refresh /= 2.0;
++
++ if (mode->VScan > 1)
++ refresh /= mode->VScan;
++
++ if (mode->VRefresh > 0.0)
++ refresh = mode->VRefresh;
++
++ if (hsync == 0 || refresh == 0)
++ return (0);
++
++ return ((int) (refresh));
++}
++
++/* Calculate CR33 (rate index) for CRT1.
++ * Calculation is done using currentmode, therefore it is
++ * recommended to set VertRefresh and HorizSync to correct
++ * values in config file.
++ */
++unsigned char
++XGISearchCRT1Rate(ScrnInfoPtr pScrn, DisplayModePtr mode)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ int i = 0;
++ int irefresh;
++ unsigned short xres = mode->HDisplay;
++ unsigned short yres = mode->VDisplay;
++ unsigned char index;
++ BOOLEAN checkxgi730 = FALSE;
++
++ irefresh = XGICalcVRate(mode);
++ if (!irefresh) {
++ if (xres == 800 || xres == 1024 || xres == 1280)
++ return 0x02;
++ else
++ return 0x01;
++ }
++
++#ifdef TWDEBUG
++ xf86DrvMsg(0, X_INFO, "Debug: CalcVRate returned %d\n", irefresh);
++#endif
++
++ /* We need the REAL refresh rate here */
++ if (mode->Flags & V_INTERLACE)
++ irefresh /= 2;
++
++ /* Do not multiply by 2 when DBLSCAN! */
++
++#ifdef TWDEBUG
++ xf86DrvMsg(0, X_INFO, "Debug: Rate after correction = %d\n", irefresh);
++#endif
++
++ index = 0;
++ while ((xgix_vrate[i].idx != 0) && (xgix_vrate[i].xres <= xres)) {
++ if ((xgix_vrate[i].xres == xres) && (xgix_vrate[i].yres == yres)) {
++ if ((checkxgi730 == FALSE)
++ || (xgix_vrate[i].XGI730valid32bpp == TRUE)) {
++ if (xgix_vrate[i].refresh == irefresh) {
++ index = xgix_vrate[i].idx;
++ break;
++ }
++ else if (xgix_vrate[i].refresh > irefresh) {
++ if ((xgix_vrate[i].refresh - irefresh) <= 3) {
++ index = xgix_vrate[i].idx;
++ }
++ else if (((checkxgi730 == FALSE)
++ || (xgix_vrate[i - 1].XGI730valid32bpp == TRUE))
++ && ((irefresh - xgix_vrate[i - 1].refresh) <= 2)
++ && (xgix_vrate[i].idx != 1)) {
++ index = xgix_vrate[i - 1].idx;
++ }
++ break;
++ }
++ else if ((irefresh - xgix_vrate[i].refresh) <= 2) {
++ index = xgix_vrate[i].idx;
++ break;
++ }
++ }
++ }
++ i++;
++ }
++
++ /* Jong 10/19/2007; merge code */
++ /* Adjust to match table of VBIOS */
++ switch(pXGI->Chipset)
++ {
++ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21:
++ if((xres == 640) && (yres == 480))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 4;
++ }
++ }
++
++ if((xres == 800) && (yres == 600))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 5;
++ }
++
++ if (index>0)
++ {
++ index --;
++ }
++ }
++
++ if((xres == 1024) && (yres == 768))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 5;
++ }
++
++ if (index>0)
++ {
++ index --;
++ }
++ }
++
++ if((xres == 1280) && (yres == 1024))
++ {
++ if (index>0)
++ {
++ index --;
++ }
++ }
++
++ if((xres == 1600) && (yres == 1200))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 5;
++ }
++ }
++
++ if((xres >= 1920) && (yres >= 1440))
++ {
++ index = 0;
++ }
++
++ break;
++
++ case PCI_CHIP_XGIXG27:
++
++ if((xres == 640) && (yres == 480))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 4;
++ }
++ }
++
++ if((xres == 800) && (yres == 600))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 5;
++ }
++
++ if (index>0)
++ {
++ index --;
++ }
++ }
++
++ if((xres == 1024) && (yres == 768))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 5;
++ }
++
++ if (index>0)
++ {
++ index --;
++ }
++ }
++
++ if((xres == 1280) && (yres == 1024))
++ {
++ if (index>0)
++ {
++ index --;
++ }
++ }
++
++ if((xres == 1600) && (yres == 1200))
++ {
++ if (xgix_vrate[index].refresh>85)
++ {
++ index = 5;
++ }
++ }
++
++ break;
++
++ default:
++ break;
++ }
++
++ if (index > 0)
++ return index;
++ else {
++ /* Default Rate index */
++ if (xres == 800 || xres == 1024 || xres == 1280)
++ return 0x02;
++ else
++ return 0x01;
++ }
++}
++
++
++#define MODEID_OFF 0x449
++
++unsigned char
++XGI_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id)
++{
++ return (XGI_GetSetBIOSScratch(pScrn, MODEID_OFF, id));
++}
++
++unsigned char
++XGI_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value)
++{
++ unsigned char ret = 0;
++#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
++ unsigned char *base;
++
++ base = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_MMIO, 0, 0x2000);
++ if (!base) {
++ XGIErrorLog(pScrn, "(Could not map BIOS scratch area)\n");
++ return 0;
++ }
++
++ ret = *(base + offset);
++
++ /* value != 0xff means: set register */
++ if (value != 0xff)
++ *(base + offset) = value;
++
++ xf86UnMapVidMem(pScrn->scrnIndex, base, 0x2000);
++#endif
++ return ret;
++}
++
++void
++xgiSaveUnlockExtRegisterLock(XGIPtr pXGI, unsigned char *reg1,
++ unsigned char *reg2)
++{
++ register unsigned char val;
++ unsigned long mylockcalls;
++
++ pXGI->lockcalls++;
++ mylockcalls = pXGI->lockcalls;
++
++ /* check if already unlocked */
++ inXGIIDXREG(XGISR, 0x05, val);
++ if (val != 0xa1) {
++ /* save State */
++ if (reg1)
++ *reg1 = val;
++ /* unlock */
++/*
++ outb (0x3c4, 0x20);
++ val4 = inb (0x3c5);
++ val4 |= 0x20;
++ outb (0x3c5, val4);
++*/
++ outXGIIDXREG(XGISR, 0x05, 0x86);
++ inXGIIDXREG(XGISR, 0x05, val);
++ if (val != 0xA1) {
++#ifdef TWDEBUG
++ unsigned char val1, val2;
++ int i;
++#endif
++ XGIErrorLog(pXGI->pScrn,
++ "Failed to unlock sr registers (%p, %lx, 0x%02x; %ld)\n",
++ (void *) pXGI, (unsigned long) pXGI->RelIO, val,
++ mylockcalls);
++#ifdef TWDEBUG
++ for (i = 0; i <= 0x3f; i++) {
++ inXGIIDXREG(XGISR, i, val1);
++ inXGIIDXREG(0x3c4, i, val2);
++ xf86DrvMsg(pXGI->pScrn->scrnIndex, X_INFO,
++ "SR%02d: RelIO=0x%02x 0x3c4=0x%02x (%d)\n",
++ i, val1, val2, mylockcalls);
++ }
++#endif
++ }
++ }
++}
++
++void
++xgiRestoreExtRegisterLock(XGIPtr pXGI, unsigned char reg1, unsigned char reg2)
++{
++ /* restore lock */
++#ifndef UNLOCK_ALWAYS
++ outXGIIDXREG(XGISR, 0x05, reg1 == 0xA1 ? 0x86 : 0x00);
++#endif
++}
++
++/* Jong 12/03/2007; */
++/*
++void XGICheckModeForMonitor(ScrnInfoPtr pScrn, )
++{
++ DisplayModePtr pCRT1Modes=pScrn->monitor->Modes;
++
++ if ((p = first = pScrn->monitor->Modes)) {
++ do {
++ xf86CheckModeForMonitor(p,
++ n = p->next;
++ p = n;
++ } while (p != NULL && p != first);
++ }
++
++ xf86PruneDriverModes(pXGI->CRT2pScrn);
++}
++*/
++
++/* Jong 12/05/2007; filter mode list by monitor DDC */
++static void XGIFilterModeByDDC(DisplayModePtr pModeList, xf86MonPtr pMonitorDDC)
++{
++ DisplayModePtr first, p;
++
++ if ((p = first = pModeList))
++ {
++ do
++ {
++ if(XGICheckModeByDDC(p, pMonitorDDC) == FALSE)
++ xf86DeleteMode(&pModeList, pModeList);
++
++ p = p->next;
++ } while (p != NULL && p != first);
++ }
++}
++
++/* Jong 12/05/2007; filter mode list by monitor DDC */
++static bool XGICheckModeByDDC(DisplayModePtr pMode, xf86MonPtr pMonitorDDC)
++{
++ int i, j;
++ float VF, HF;
++ struct detailed_timings *pd_timings;
++ struct monitor_ranges *pranges;
++ struct std_timings *pstd_t;
++
++ int VRefresh=pMode->VRefresh;
++
++ if ((pMode == NULL) || (pMonitorDDC == NULL)) {
++ return(FALSE); /* ignore */
++ }
++
++ if( pMode->VRefresh == 0)
++ VRefresh = (int)((float)(pMode->Clock*1000)/(float)(pMode->VTotal*pMode->HTotal)+0.5);
++
++
++ for (i = 0, j = 0; i < 8; i++, j++)
++ {
++ if (establish_timing[j].width == -1)
++ {
++ continue;
++ }
++
++ if (pMonitorDDC->timings1.t1 & (1 << i))
++ {
++ if( (establish_timing[j].width == pMode->HDisplay) &&
++ (establish_timing[j].height == pMode->VDisplay) &&
++ (establish_timing[j].VRefresh == VRefresh) )
++ return(TRUE);
++ }
++ }
++
++ for (i = 0; i < 8; i++, j++)
++ {
++ if (establish_timing[j].width == -1)
++ {
++ continue;
++ }
++
++ if (pMonitorDDC->timings1.t2 & (1 << i))
++ {
++ if( (establish_timing[j].width == pMode->HDisplay) &&
++ (establish_timing[j].height == pMode->VDisplay) &&
++ (establish_timing[j].VRefresh == VRefresh) )
++ return(TRUE);
++ }
++ }
++
++ for (i = 0; i < 8; i++)
++ {
++ if ((pMode->HDisplay == pMonitorDDC->timings2[i].hsize) &&
++ (pMode->VDisplay == pMonitorDDC->timings2[i].vsize) &&
++ (VRefresh == pMonitorDDC->timings2[i].refresh))
++ return(TRUE);
++ }
++
++/* Jong 12/05/2007; Don't know how to do? */
++#if 0
++ for (i = 0; i < 4; i++)
++ {
++ switch (pMonitorDDC->det_mon[i].type)
++ {
++ case DS_RANGES:
++ pranges = &(pMonitorDDC->det_mon[i].section.ranges);
++ PDEBUG5(ErrorF
++ ("min_v = %d max_v = %d min_h = %d max_h = %d max_clock = %d\n",
++ pranges->min_v, pranges->max_v, pranges->min_h,
++ pranges->max_h, pranges->max_clock));
++
++ if (range->loH > pranges->min_h)
++ range->loH = pranges->min_h;
++ if (range->loV > pranges->min_v)
++ range->loV = pranges->min_v;
++ if (range->hiH < pranges->max_h)
++ range->hiH = pranges->max_h;
++ if (range->hiV < pranges->max_v)
++ range->hiV = pranges->max_v;
++ PDEBUG5(ErrorF
++ ("range(%8.3f %8.3f %8.3f %8.3f)\n", range->loH,
++ range->loV, range->hiH, range->hiV));
++ break;
++
++ case DS_STD_TIMINGS:
++ pstd_t = pMonitorDDC->det_mon[i].section.std_t;
++ for (j = 0; j < 5; j++) {
++ int k;
++ PDEBUG5(ErrorF
++ ("std_t[%d] hsize = %d vsize = %d refresh = %d id = %d\n",
++ j, pstd_t[j].hsize, pstd_t[j].vsize,
++ pstd_t[j].refresh, pstd_t[j].id));
++ for (k = 0; StdTiming[k].width != -1; k++) {
++ if ((StdTiming[k].width == pstd_t[j].hsize) &&
++ (StdTiming[k].height == pstd_t[j].vsize) &&
++ (StdTiming[k].VRefresh == pstd_t[j].refresh)) {
++ if (range->loH > StdTiming[k].HSync)
++ range->loH = StdTiming[k].HSync;
++ if (range->hiH < StdTiming[k].HSync)
++ range->hiH = StdTiming[k].HSync;
++ if (range->loV > StdTiming[k].VRefresh)
++ range->loV = StdTiming[k].VRefresh;
++ if (range->hiV < StdTiming[k].VRefresh)
++ range->hiV = StdTiming[k].VRefresh;
++ break;
++ }
++
++ }
++ }
++ break;
++
++ case DT:
++
++ pd_timings = &pMonitorDDC->det_mon[i].section.d_timings;
++
++ HF = pd_timings->clock / (pd_timings->h_active +
++ pd_timings->h_blanking);
++ VF = HF / (pd_timings->v_active + pd_timings->v_blanking);
++ HF /= 1000; /* into KHz Domain */
++ if (range->loH > HF)
++ range->loH = HF;
++ if (range->hiH < HF)
++ range->hiH = HF;
++ if (range->loV > VF)
++ range->loV = VF;
++ if (range->hiV < VF)
++ range->hiV = VF;
++ PDEBUG(ErrorF
++ ("Detailing Timing: HF = %f VF = %f range (%8.3f %8.3f %8.3f %8.3f)\n",
++ HF, VF, range->loH, range->loV, range->hiH, range->hiV));
++ break;
++ }
++ }
++#endif
++
++ return(FALSE);
++}
++
++#ifdef DEBUG
++void
++XGIDumpSR(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("SR xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x40; i += 0x10) {
++ ErrorF("SR[%02X]:", i);
++ for (j = 0; j < 16; j++) {
++ inXGIIDXREG(XGISR, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++ ErrorF("\n");
++}
++
++void
++XGIDumpCR(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("CR xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x100; i += 0x10) {
++ ErrorF("CR[%02X]:", i);
++ for (j = 0; j < 16; j++) {
++ inXGIIDXREG(XGICR, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++
++void
++XGIDumpGR(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("GR xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("GR:");
++ for (i = 0; i < 0x9; i += 0x10) {
++ inXGIIDXREG(XGISR, i, temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++}
++
++#if 0
++void
++XGIDumpPart0(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("PART0 xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x50; i += 0x10) {
++ ErrorF("PART0[%02X]:", i);
++ for (j = 0; j < 0x10; j++) {
++ inXGIIDXREG(XGIPART0, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++
++void
++XGIDumpPart05(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ int i, j;
++ unsigned long temp;
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("PART05 xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x50; i += 0x10) {
++ ErrorF("PART05[%02X]:", i);
++ for (j = 0; j < 0x10; j++) {
++ inXGIIDXREG(XGIPART05, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++
++void
++XGIDumpPart1(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("PART1 xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x100; i += 0x10) {
++ ErrorF("PART1[%02X]:", i);
++ for (j = 0; j < 0x10; j++) {
++ inXGIIDXREG(XGIPART1, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++
++void
++XGIDumpPart2(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("PART2 xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x100; i += 0x10) {
++ ErrorF("PART2[%02X]:", i);
++ for (j = 0; j < 0x10; j++) {
++ inXGIIDXREG(XGIPART2, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++
++void
++XGIDumpPart3(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("PART3 xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++
++ for (i = 0; i < 0x100; i += 0x10) {
++ ErrorF("PART3[%02X]:", i);
++ for (j = 0; j < 0x10; j++) {
++ inXGIIDXREG(XGIPART3, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++
++void
++XGIDumpPart4(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i, j;
++ unsigned long temp;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("PART4 xx\n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0x100; i += 0x10) {
++ ErrorF("PART4[%02X]:", i);
++ for (j = 0; j < 0x10; j++) {
++ inXGIIDXREG(XGIPART4, (i + j), temp);
++ ErrorF(" %02lX", temp);
++ }
++ ErrorF("\n");
++ }
++}
++#endif
++
++void
++XGIDumpMMIO(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ int i;
++ unsigned long temp;
++/*
++ ErrorF("----------------------------------------------------------------------\n") ;
++ ErrorF("MMIO 85xx\n") ;
++ ErrorF("----------------------------------------------------------------------\n") ;
++ for( i = 0x8500 ; i < 0x8600 ; i+=0x10 )
++ {
++ ErrorF("[%04X]: %08lX %08lX %08lX %08lX\n",i,
++ XGIMMIOLONG(i),
++ XGIMMIOLONG(i+4),
++ XGIMMIOLONG(i+8),
++ XGIMMIOLONG(i+12)) ;
++ }
++*/
++}
++#endif /* DEBUG */
++
++void
++XGIDumpRegs(ScrnInfoPtr pScrn)
++{
++#ifdef DEBUG
++
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ XGIDumpSR(pScrn);
++ XGIDumpCR(pScrn);
++// XGIDumpGR(pScrn);
++// XGIDumpPalette(pScrn);
++ XGIDumpMMIO(pScrn);
++
++ /*
++ if (pXGI->Chipset != PCI_CHIP_XGIXG20) {
++ XGIDumpPart0(pScrn);
++ XGIDumpPart05(pScrn);
++ XGIDumpPart1(pScrn);
++ XGIDumpPart2(pScrn);
++ XGIDumpPart3(pScrn);
++ XGIDumpPart4(pScrn);
++ } */
++
++#endif /* DEBUG */
++}
++
++
++void
++XGIDumpPalette(ScrnInfoPtr pScrn)
++{
++#ifdef DEBUG
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned temp[3];
++ int i, j;
++
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ ErrorF("Palette \n");
++ ErrorF
++ ("----------------------------------------------------------------------\n");
++ for (i = 0; i < 0xFF; i += 0x04) {
++ for (j = 0; j < 16; j++) {
++ outb(0x3c7, i + j);
++ temp[0] = inb(0x3c9);
++ temp[1] = inb(0x3c9);
++ temp[2] = inb(0x3c9);
++
++ ErrorF("PA[%02X]: %02X %02X %02X", i + j,
++ temp[0], temp[1], temp[2]);
++ }
++ ErrorF("\n");
++ }
++ ErrorF("\n");
++#endif
++}
+diff --git a/src/xgi_driver.h b/src/xgi_driver.h
+index cce0764..4004ccd 100644
+--- a/src/xgi_driver.h
++++ b/src/xgi_driver.h
+@@ -41,43 +41,81 @@ static const struct _xgi_vrate {
+ {1, 320, 200, 70, TRUE},
+ {1, 320, 240, 60, TRUE},
+ {1, 400, 300, 60, TRUE},
+- {1, 512, 384, 60, TRUE},
++ {1, 512, 384, 60, TRUE},
+ {1, 640, 400, 72, TRUE},
+- {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE},
+- {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE},
+- {7, 640, 480, 160, FALSE}, {8, 640, 480, 200, FALSE},
++ {1, 640, 480, 60, TRUE},
++ {2, 640, 480, 72, TRUE},
++ {3, 640, 480, 75, TRUE},
++ {4, 640, 480, 85, TRUE},
++ {5, 640, 480, 100, TRUE},
++ {6, 640, 480, 120, TRUE},
++ {7, 640, 480, 160, FALSE},
++ {8, 640, 480, 200, FALSE},
+ {1, 720, 480, 60, TRUE},
+ {1, 720, 576, 58, TRUE},
+ {1, 768, 576, 58, TRUE},
+- {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE},
+- {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE},
+- {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE},
+- {7, 800, 600, 120, FALSE}, {8, 800, 600, 160, FALSE},
+- {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
+- {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
+- {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
++ {1, 800, 480, 60, TRUE},
++ {2, 800, 480, 75, TRUE},
++ {3, 800, 480, 85, TRUE},
++ {1, 800, 600, 56, TRUE},
++ {2, 800, 600, 60, TRUE},
++ {3, 800, 600, 72, TRUE},
++ {4, 800, 600, 75, TRUE},
++ {5, 800, 600, 85, TRUE},
++ {6, 800, 600, 105, TRUE},
++ {7, 800, 600, 120, FALSE},
++ {8, 800, 600, 160, FALSE},
++ {1, 848, 480, 39, TRUE},
++ {2, 848, 480, 60, TRUE},
++ {1, 856, 480, 39, TRUE},
++ {2, 856, 480, 60, TRUE},
++ {1, 1024, 576, 60, TRUE},
++ {2, 1024, 576, 75, TRUE},
++ {3, 1024, 576, 85, TRUE},
+ {1, 1024, 600, 60, TRUE},
+- {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
+- {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
++ {1, 1024, 768, 43, TRUE},
++ {2, 1024, 768, 60, TRUE},
++ {3, 1024, 768, 70, FALSE},
++ {4, 1024, 768, 75, FALSE},
++ {5, 1024, 768, 85, TRUE},
++ {6, 1024, 768, 100, TRUE},
+ {7, 1024, 768, 120, TRUE},
+ {1, 1152, 768, 60, TRUE},
+- {1, 1152, 864, 75, TRUE}, {2, 1152, 864, 84, FALSE},
+- {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, FALSE}, {3, 1280, 720, 85, TRUE},
++ {1, 1152, 864, 75, TRUE},
++ {2, 1152, 864, 84, FALSE},
++ {1, 1280, 720, 60, TRUE},
++ {2, 1280, 720, 75, FALSE},
++ {3, 1280, 720, 85, TRUE},
+ {1, 1280, 768, 60, TRUE},
+ {1, 1280, 800, 60, TRUE},
+- {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
+- {1, 1280, 1024, 43, FALSE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, FALSE},
++ {1, 1280, 960, 60, TRUE},
++ {2, 1280, 960, 85, TRUE},
++ {1, 1280, 1024, 43, FALSE},
++ {2, 1280, 1024, 60, TRUE},
++ {3, 1280, 1024, 75, FALSE},
+ {4, 1280, 1024, 85, TRUE},
+ {1, 1360, 768, 60, TRUE},
+- {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE},
+- {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
+- {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
++ {1, 1400, 1050, 60, TRUE},
++ {2, 1400, 1050, 75, TRUE},
++ {1, 1600, 1200, 60, TRUE},
++ {2, 1600, 1200, 65, TRUE},
++ {3, 1600, 1200, 70, TRUE},
++ {4, 1600, 1200, 75, TRUE},
++ {5, 1600, 1200, 85, TRUE},
++ {6, 1600, 1200, 100, TRUE},
+ {7, 1600, 1200, 120, TRUE},
+ {1, 1680, 1050, 60, TRUE},
+- {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
+- {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
+- {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
+- {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE},
++ {1, 1920, 1440, 60, TRUE},
++ {2, 1920, 1440, 65, TRUE},
++ {3, 1920, 1440, 70, TRUE},
++ {4, 1920, 1440, 75, TRUE},
++ {5, 1920, 1440, 85, TRUE},
++ {6, 1920, 1440, 100, TRUE},
++ {1, 2048, 1536, 60, TRUE},
++ {2, 2048, 1536, 65, TRUE},
++ {3, 2048, 1536, 70, TRUE},
++ {4, 2048, 1536, 75, TRUE},
++ {5, 2048, 1536, 85, TRUE},
+ {0, 0, 0, 0, FALSE}
+ };
+
+diff --git a/src/xgi_opt.c b/src/xgi_opt.c
+index cf92655..4aac85e 100644
+--- a/src/xgi_opt.c
++++ b/src/xgi_opt.c
+@@ -276,7 +276,7 @@ xgiOptions(ScrnInfoPtr pScrn)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "2D Acceleration disabled\n");
+ }
+
+- if (PCI_CHIP_XGIXG20 == pXGI->Chipset)
++ if ((pXGI->Chipset== PCI_CHIP_XGIXG20)||(pXGI->Chipset== PCI_CHIP_XGIXG21)||(pXGI->Chipset== PCI_CHIP_XGIXG27))
+ pXGI->NoXvideo = TRUE;
+
+ /* SWCursor
+diff --git a/src/xgi_pci.h b/src/xgi_pci.h
+index 4f9d258..bf8cf61 100644
+--- a/src/xgi_pci.h
++++ b/src/xgi_pci.h
+@@ -1,34 +1,36 @@
+-/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
+- *
+- * All Rights Reserved.
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining
+- * a copy of this software and associated documentation files (the
+- * "Software"), to deal in the Software without restriction, including
+- * without limitation on the rights to use, copy, modify, merge,
+- * publish, distribute, sublicense, and/or sell copies of the Software,
+- * and to permit persons to whom the Software is furnished to do so,
+- * subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice (including the
+- * next paragraph) shall be included in all copies or substantial
+- * portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+- * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
+- * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+- * DEALINGS IN THE SOFTWARE.
+- */
+-
+-/******************************************************************
+- * Define XGI new PCI device ID.
+- ******************************************************************/
+-
+-
+-#define PCI_VENDOR_XGI 0x18CA
+-#define PCI_CHIP_XGIXG40 0x0040
+-#define PCI_CHIP_XGIXG20 0x0020
++/* Copyright (C) 2003-2006 by XGI Technology, Taiwan.
++ *
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining
++ * a copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation on the rights to use, copy, modify, merge,
++ * publish, distribute, sublicense, and/or sell copies of the Software,
++ * and to permit persons to whom the Software is furnished to do so,
++ * subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the
++ * next paragraph) shall be included in all copies or substantial
++ * portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ * NON-INFRINGEMENT. IN NO EVENT SHALL XGI AND/OR
++ * ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
++ * DEALINGS IN THE SOFTWARE.
++ */
++
++/******************************************************************
++ * Define XGI new PCI device ID.
++ ******************************************************************/
++
++
++#define PCI_VENDOR_XGI 0x18CA
++#define PCI_CHIP_XGIXG40 0x0040
++#define PCI_CHIP_XGIXG20 0x0020
++#define PCI_CHIP_XGIXG21 0x0021 /* Jong 01/07/2008; support New XG21 */
++#define PCI_CHIP_XGIXG27 0x0027
+diff --git a/src/xgi_regs.h b/src/xgi_regs.h
+diff --git a/src/xgi_setup.c b/src/xgi_setup.c
+index a06916b..0265d36 100644
+--- a/src/xgi_setup.c
++++ b/src/xgi_setup.c
+@@ -1,421 +1,686 @@
+-/*
+- * Basic hardware and memory detection
+- *
+- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1) Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2) Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3) The name of the author may not be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- * Author: Thomas Winischhofer <thomas@winischhofer.net>
+- *
+- * Ideas and methods for old series based on code by Can-Ru Yeou, XGI Inc.
+- *
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "xf86PciInfo.h"
+-#include "xf86Pci.h"
+-#include "xf86.h"
+-#include "fb.h"
+-#include "xf1bpp.h"
+-#include "xf4bpp.h"
+-#include "xf86_OSproc.h"
+-#include "xf86Resources.h"
+-#include "xf86Version.h"
+-
+-#include "xf86cmap.h"
+-
+-#include "xgi.h"
+-#include "xgi_regs.h"
+-#include "xgi_dac.h"
+-/* #include "valid_mode.h" */
+-
+-#define _XF86DGA_SERVER_
+-#include <X11/extensions/xf86dgastr.h>
+-
+-#include "globals.h"
+-#define DPMS_SERVER
+-#include <X11/extensions/dpms.h>
+-
+-#include "vb_def.h"
+-extern int FbDevExist;
+-
+-static Bool bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset,
+- ULONG ulSet, ULONG *pulValue);
+-static Bool bAccessNBridgePCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo,
+- ULONG ulOffset, ULONG ulSet, ULONG *pulValue);
+-static Bool XGI_IsXG21(ScrnInfoPtr pScrn);
+-
+-static void XGI_InitHwDevInfo(ScrnInfoPtr pScrn);
+-
+-static void
+-xgiXG40_Setup(ScrnInfoPtr pScrn)
+-{
+- static const char *const dramChannelStr[5] = {
+- "<invalid>", "Single", "Dual", "<invalid>", "Quad"
+- };
+-
+- static const char *const dramTypeStr[4] = {
+- "DDR SDRAM",
+- "DDR2 SDRAM",
+- "DDR2x SDRAM",
+- ""
+- };
+-
+-/*********************************************************************
+- * Setup
+- * Decide the following item of execution data:
+- *
+- * pXGI->BusWidth
+- * pXGI->videoRam (with KB unit)
+- * pXGI->CursorOffset (with Byte Unit)
+- * pXGI->cmdQueueSize (with Byte Unit)
+- * pXGI->cmdQueueSizeMask (with Byte Unit)
+- * pXGI->cmdQueueOffset (with Byte Unit)
+- * pXGI->cmdQueueLen = 0 ; // init value
+- * pXGI->cmdQueueLenMin = 0x200 ; // init value
+- * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+- *********************************************************************/
+-
+- XGIPtr pXGI = XGIPTR(pScrn);
+- unsigned int ulMemConfig = 0;
+- unsigned mem_per_channel;
+- unsigned mem_channels = 1;
+- unsigned long ulDramType = 0;
+-
+- PDEBUG4(ErrorF("xgiXG40_Setup()\n")) ;
+-
+- pXGI->MemClock = XG40Mclk(pXGI);
+-
+- /* SR14 DRAM Size Register
+- * Default value: XXh
+- * D[7:4] Memory size per channel {BChMemSize}
+- * 0011: 8 MB
+- * 0100: 16 MB
+- * 0101: 32 MB
+- * 0110: 64 MB
+- * 0111: 128 MB
+- * 1000: 256MB
+- * others: reserved
+- * D[3:2] Number of dram channels [1:0] {BChNum}
+- * 00: uni-channel
+- * 01: reserved
+- * 10: dual-channel
+- * 11: quad-channel
+- * D1 Data width per channel selection {BDataWidth}
+- * 0: 32-bits
+- * 1: 64-bits
+- * D0 Dram channel mapping {BReverseChMapping}
+- * 0: Normal mapping
+- * 1: Reversal mapping
+- * Dual-channel: Logical channel A/B to physical channel B/A
+- * Quad-channel: Logical channel A/B/C/D to physical channel
+- * C/D/A/B
+- */
+-
+- outXGIIDXREG(XGISR, 0x5, 0x86) ;
+- inXGIIDXREG(XGISR, 0x14, ulMemConfig) ;
+-
+- /* FIXME: Is this correct? The SiS driver detects this differently
+- * FIXME: for XG20.
+- */
+- inXGIIDXREG(XGISR, 0x3A, ulDramType) ;
+-
+- PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ;
+- PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ;
+-
+- /* FIXME: Is this correct? The SiS driver detects this differently
+- * FIXME: for XG20.
+- */
+- pXGI->BusWidth = (ulMemConfig & 0x02) ? 64 : 32;
+-
+- mem_per_channel = ((ulMemConfig >> 4) >= 3)
+- ? (1 << (ulMemConfig >> 4)) * 1024
+- : 8 * 1024;
+-
+-
+- /* All XG20 family chips are single channel, so only test the channel
+- * count field on XG40 family chips.
+- */
+- if (pXGI->Chipset == PCI_CHIP_XGIXG40) {
+- /* Check the PCI revision field. For whatever reason, rev. 2 XG40
+- * chips encode the DRAM channel count differently than other
+- * revisions.
+- */
+- if (pXGI->ChipRev == 2) {
+- switch ((ulMemConfig >> 2) & 0x1) {
+- case 1:
+- /* Dual channel */
+- mem_channels = 2;
+- break ;
+- }
+- }
+- else {
+- switch ((ulMemConfig >> 2) & 0x3) {
+- case 2:
+- /* Dual channel */
+- mem_channels = 2;
+- break ;
+- case 3:
+- /* Quad channel */
+- mem_channels = 4;
+- break ;
+- }
+- }
+- }
+-
+- pScrn->videoRam = mem_per_channel * mem_channels;
+-
+- /* SR15 DRAM Address Mapping Register
+- * Default value: XXh
+- * D7 Channel interleaving configuration { BChConfig }
+- * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel
+- * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region
+- * will be channel-interleaved as per BFineGranSize; the high-address region will be channel-
+- * interleaved as per BCoarseGranSize[1:0]
+- * D[6:5] Memory size of tile-mapped region {BTilingSize}
+- * 00: 4 MB
+- * 01: 8 MB
+- * 10: 16 MB
+- * 11: 32 MB
+- * The following bits are effective only when D7=1
+- * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize}
+- * 0: 64 B
+- * 1: 128 B
+- * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize}
+- * 00: 1KB
+- * 01: 2KB
+- * 10: 4KB
+- * 11: 1MB
+- * D[1:0] reserved
+- */
+-
+- /* Accelerator parameter Initialization */
+-
+- pXGI->cmdQueueSize = (pXGI->Chipset == PCI_CHIP_XGIXG20)
+- ? VOLARI_CQSIZEXG20 : VOLARI_CQSIZE;
+- pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
+- pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D);
+-
+-
+- /* If FbDevExist, X.org driver uses 8MB only. The rest of the framebuffer
+- * is used by the fbdev driver.
+- */
+- if (FbDevExist) {
+- /* FIXME: Is it even possible to have less than 8Mb of video memory?
+- */
+- if (pScrn->videoRam < 8*1024) {
+- pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize;
+- }
+- else if (pScrn->videoRam < 16*1024) {
+- pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize;
+- }
+- else {
+- pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize;
+- }
+- }
+- else {
+- pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize;
+- }
+-
+- pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024;
+- PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n",
+- pScrn->videoRam, pXGI->cmdQueueSize)) ;
+- PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n",
+- pXGI->cmdQueueOffset, pXGI->CursorOffset)) ;
+-
+- pXGI->cmdQueueLen = 0 ;
+- pXGI->cmdQueueLenMin = 0x200 ;
+- pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
+-
+- /* Dual Chip support put here
+- */
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "Detected DRAM type : %s channel %s\n",
+- dramChannelStr[mem_channels],
+- dramTypeStr[(ulDramType & 0x02) >> 1]);
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "Detected memory clock : %3.3fMHz\n",
+- pXGI->MemClock/1000.0);
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "Detected VRAM bus width is %d\n", pXGI->BusWidth);
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024);
+- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+- "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ;
+- XGI_InitHwDevInfo(pScrn);
+-}
+-
+-void
+-XGISetup(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- pXGI->Flags = 0;
+- pXGI->VBFlags = 0;
+-
+- switch (pXGI->Chipset) {
+- case PCI_CHIP_XGIXG40:
+- case PCI_CHIP_XGIXG20:
+- default:
+- xgiXG40_Setup(pScrn);
+- break;
+- }
+-}
+-
+-Bool
+-XGI_IsXG21(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- Bool is_XG21 = FALSE;
+-
+- if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
+- int temp;
+-
+- orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
+- inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, temp);
+-
+- is_XG21 = ((temp & GPIOG_READ) != 0);
+- }
+-
+- return is_XG21;
+-}
+-
+-void
+-XGI_InitHwDevInfo(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt;
+- int i;
+-
+- pHwDevInfo->pDevice = pXGI ;
+- pHwDevInfo->pjVirtualRomBase = pXGI->BIOS ;
+- pHwDevInfo->pjCustomizedROMImage = NULL ;
+- pHwDevInfo->pjVideoMemoryAddress = (UCHAR*)(pXGI->FbBase) ;
+- PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n",(ULONG)(pXGI->FbBase))) ;
+- PDEBUG(ErrorF("pHwDevInfo->pjVideoMemoryAddress = 0x%08lx\n",(ULONG)(pHwDevInfo->pjVideoMemoryAddress))) ;
+- pHwDevInfo->ulVideoMemorySize = pXGI->FbMapSize ;
+- pHwDevInfo->pjIOAddress = pXGI->RelIO + 0x30 ;
+-
+- switch (pXGI->Chipset) {
+- case PCI_CHIP_XGIXG40:
+- pHwDevInfo->jChipType = XG40 ;
+- break ;
+- case PCI_CHIP_XGIXG20:
+- pHwDevInfo->jChipType = XGI_IsXG21(pScrn)?XG21:XG20 ;
+- break ;
+- default:
+- pHwDevInfo->jChipType = XG40 ;
+- break ;
+- }
+-
+- pHwDevInfo->jChipRevision = pXGI->ChipRev;
+- pHwDevInfo->ujVBChipID = VB_CHIP_UNKNOWN ;
+- pHwDevInfo->ulExternalChip = 0 ;
+-
+- pHwDevInfo->ulCRT2LCDType = LCD_1024x768 ;
+- pHwDevInfo->bIntegratedMMEnabled = FALSE ;
+- pHwDevInfo->bSkipDramSizing = TRUE ;
+-
+- pHwDevInfo->pSR = pXGI->SRList ;
+- pHwDevInfo->pCR = pXGI->CRList ;
+- pHwDevInfo->pQueryVGAConfigSpace = (PXGI_QUERYSPACE) bAccessVGAPCIInfo;
+-
+- for( i = 0 ; i < ExtRegSize ; i++ ){
+- pHwDevInfo->pSR[i].jIdx = 0xFF ;
+- pHwDevInfo->pSR[i].jVal = 0xFF ;
+- pHwDevInfo->pCR[i].jIdx = 0xFF ;
+- pHwDevInfo->pCR[i].jVal = 0xFF ;
+- }
+-
+- for( i = 0 ; i < VBIOS_VER_MAX_LENGTH ; i++ ){
+- pHwDevInfo -> szVBIOSVer[i] = '\0' ;
+- }
+-
+-
+- XGINew_InitVBIOSData(pHwDevInfo, pXGI->XGI_Pr);
+- PDEBUG(ErrorF("XGINew_InitVBIOSData(pHwDevInfo) done\n")) ;
+-
+- ErrorF("XGI_InitVBIOSData VBType = %x\n", pXGI->XGI_Pr->VBType);
+- XGI_New_GetVBType(pXGI->XGI_Pr, pHwDevInfo); //yilin
+- ErrorF("XGI_New_GetVBType VBType = %x\n", pXGI->XGI_Pr->VBType);
+-
+- // pHwDevInfo->ujVBChipID = VB_CHIP_301 ; //yilin
+- if( pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C))
+- {
+- PDEBUG(ErrorF("VB chip = 301 \n")) ;
+- pHwDevInfo->ujVBChipID = VB_CHIP_301 ;
+- }
+- else if( pXGI->VBFlags & ( VB_XGI302B| VB_XGI302LV ))
+- {
+- pHwDevInfo->ujVBChipID = VB_CHIP_302 ;
+- }
+-/*
+- else if (pXGI->VBFlags & VB_LVDS) {
+- pHwDevInfo->ulExternalChip |= 0x01 ;
+- }
+-*/ //yilin
+-
+-
+- PDEBUG(ErrorF("pHwDevInfo->jChipType = %08lX done\n",pHwDevInfo->jChipType)) ;
+-}
+-
+-Bool
+-bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset, ULONG ulSet, ULONG *pulValue)
+-{
+- XGIPtr pXGI ;
+-#ifdef XSERVER_LIBPCIACCESS
+- int err;
+-#else
+- PCITAG pciDev;
+-#endif
+-
+- if (!pHwDevInfo || !pulValue) {
+- return FALSE;
+- }
+-
+- pXGI = (XGIPtr)pHwDevInfo->pDevice ;
+-#ifdef XSERVER_LIBPCIACCESS
+- if (ulSet) {
+- err = pci_device_cfg_write_u32(pXGI->PciInfo, *pulValue,
+- ulOffset & ~3);
+- } else {
+- err = pci_device_cfg_write_u32(pXGI->PciInfo, pulValue,
+- ulOffset & ~3);
+- }
+-
+- return (err == 0);
+-#else
+- pciDev = pXGI->PciTag ;
+-
+- if (ulSet) {
+- pciWriteLong(pciDev, ulOffset&0xFFFFFFFc, *pulValue);
+- } else {
+- *pulValue = pciReadLong(pciDev, ulOffset&0xFFFFFFFc);
+- }
+-
+- return TRUE ;
+-#endif
+-}
++/*
++ * Basic hardware and memory detection
++ *
++ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1) Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2) Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3) The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Ideas and methods for old series based on code by Can-Ru Yeou, XGI Inc.
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "xf86PciInfo.h"
++#include "xf86Pci.h"
++#include "xf86.h"
++#include "fb.h"
++#include "xf1bpp.h"
++#include "xf4bpp.h"
++#include "xf86_OSproc.h"
++#include "xf86Resources.h"
++#include "xf86Version.h"
++
++#include "xf86cmap.h"
++
++#include "xgi.h"
++#include "xgi_regs.h"
++#include "xgi_dac.h"
++/* #include "valid_mode.h" */
++
++#define _XF86DGA_SERVER_
++#include <X11/extensions/xf86dgastr.h>
++
++#include "globals.h"
++#define DPMS_SERVER
++#include <X11/extensions/dpms.h>
++
++#include "vb_def.h"
++extern int FbDevExist;
++
++static Bool bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset,
++ ULONG ulSet, ULONG *pulValue);
++static Bool bAccessNBridgePCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo,
++ ULONG ulOffset, ULONG ulSet, ULONG *pulValue);
++static Bool XGI_IsXG21(ScrnInfoPtr pScrn);
++
++static void XGI_InitHwDevInfo(ScrnInfoPtr pScrn);
++
++/* Jong 10/16/2007; merge code */
++static void
++xgiXG2X_Setup(ScrnInfoPtr pScrn)
++{
++
++/*********************************************************************
++ * Setup
++ * Decide the following item of execution data:
++ *
++ * pXGI->BusWidth
++ * pXGI->videoRam (with KB unit)
++ * pXGI->CursorOffset (with Byte Unit)
++ * pXGI->cmdQueueSize (with Byte Unit)
++ * pXGI->cmdQueueSizeMask (with Byte Unit)
++ * pXGI->cmdQueueOffset (with Byte Unit)
++ * pXGI->cmdQueueLen = 0 ; // init value
++ * pXGI->cmdQueueLenMin = 0x200 ; // init value
++ * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
++ *********************************************************************/
++
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned int ulMemConfig = 0;
++ unsigned long ulMemSize = 0;
++ unsigned long ulDramType = 0;
++ char *dramTypeStr ;
++ unsigned long ulTemp ;
++
++ /* DumpDDIName("xgiXG2X_Setup()\n") ; */
++
++ inXGIIDXREG(XGICR, 0x48, ulTemp) ;
++ if(ulTemp & (1<<0)) /* GPIOH, CR48 D[0] read */
++ {
++ dramTypeStr = "DDRII DRAM" ;
++ }
++ else
++ {
++ dramTypeStr = "DDR DRAM" ;
++ }
++
++
++ pXGI->MemClock = XG40Mclk(pXGI);
++
++ /*********************************************************************************************************
++ * SR14 DRAM Size Register
++ * Default value: XXh
++ * D[7:4] Memory size per channel {BChMemSize}
++ * 0011: 8 MB
++ * 0100: 16 MB
++ * 0101: 32 MB
++ * 0110: 64 MB
++ * 0111: 128 MB
++ * 1000: 256MB
++ * others: reserved
++ * D[3:2] Number of dram channels [1:0] {BChNum}
++ * 00: uni-channel
++ * 01: reserved
++ * 10: dual-channel.
++ * 11: quad-channel
++ * D1 Data width per channel selection {BDataWidth}
++ * 0: 32-bits
++ * 1: 64-bits
++ * D0 Dram channel mapping {BReverseChMapping}
++ * 0: Normal mapping
++ * 1: Reversal mapping
++ * Dual-channel: Logical channel A/B to physical channel B/A
++ * Quad-channel: Logical channel A/B/C/D to physical channel C/D/A/B
++ *
++ *********************************************************************************************************/
++
++ outXGIIDXREG(XGISR, 0x5, 0x86) ;
++ inXGIIDXREG(XGISR, 0x14, ulMemConfig) ;
++ inXGIIDXREG(XGISR, 0x3A, ulDramType) ;
++
++ PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ;
++ PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ;
++
++ pXGI->BusWidth = (ulMemConfig & (1<<1) )?64:32 ;
++
++ switch(ulMemConfig>>4)
++ {
++ case 8:
++ ulMemSize = 256*1024 ;
++ break ;
++ case 7:
++ ulMemSize = 128*1024 ;
++ break ;
++ case 6:
++ ulMemSize = 64*1024 ;
++ break ;
++ case 5:
++ ulMemSize = 32*1024 ;
++ break ;
++ case 4:
++ ulMemSize = 16*1024 ;
++ break ;
++ case 3:
++ ulMemSize = 8*1024 ;
++ break ;
++ default:
++ ulMemSize = 8*1024 ;
++ }
++
++ if( pXGI->Chipset == PCI_CHIP_XGIXG40)
++ {
++ if ( (pciReadLong(pXGI->PciTag, 0x08) & 0xFF ) == 2 )
++ {
++ switch((ulMemConfig>>2)&0x1)
++ {
++ case 0:
++ /* Uni channel */
++ ulMemSize *= 1 ;
++ break ;
++ case 1:
++ /* Dual channel */
++ ulMemSize *= 2 ;
++ break ;
++ }
++ }
++ else
++ {
++ switch((ulMemConfig>>2)&0x3)
++ {
++ case 2:
++ /* Dual channel */
++ ulMemSize *= 2 ;
++ break ;
++ case 3:
++ /* Quad channel */
++ ulMemSize *= 4 ;
++ break ;
++ }
++ }
++ }
++
++ pScrn->videoRam = ulMemSize ;
++
++ /*********************************************************************************************************
++ * SR15 DRAM Address Mapping Register
++ * Default value: XXh
++ * D7 Channel interleaving configuration { BChConfig }
++ * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel
++ * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region
++ * will be channel-interleaved as per BFineGranSize; the high-address region will be channel-
++ * interleaved as per BCoarseGranSize[1:0]
++ * D[6:5] Memory size of tile-mapped region {BTilingSize}
++ * 00: 4 MB
++ * 01: 8 MB
++ * 10: 16 MB
++ * 11: 32 MB
++ * The following bits are effective only when D7=1
++ * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize}
++ * 0: 64 B
++ * 1: 128 B
++ * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize}
++ * 00: 1KB
++ * 01: 2KB
++ * 10: 4KB
++ * 11: 1MB
++ * D[1:0] reserved
++ *********************************************************************************************************/
++
++ /* Accelerator parameter Initialization */
++ if(( pXGI->Chipset == PCI_CHIP_XGIXG20 )||( pXGI->Chipset == PCI_CHIP_XGIXG21 )||( pXGI->Chipset == PCI_CHIP_XGIXG27 ))
++ {
++ pXGI->cmdQueueSize = VOLARI_CQSIZEXG20;
++ /* XgiMode = XG20_Mode ; */
++ PDEBUG(ErrorF(" ---XG20_Mode \n"));
++ }
++
++
++ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
++ pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D);
++
++
++ /*
++ If FbDevExist, XFree86 driver use the 8MB only. The rest
++ frame buffer is used by other AP.
++ */
++
++ if( FbDevExist && (pXGI->Chipset != PCI_CHIP_XGIXG20 ) && (pXGI->Chipset != PCI_CHIP_XGIXG21 ) && (pXGI->Chipset != PCI_CHIP_XGIXG27 ) )
++ {
++ if( pScrn->videoRam < 8*1024 )
++ {
++ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ else if( pScrn->videoRam < 16*1024 )
++ {
++ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ else
++ {
++ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize ;
++ }
++ }
++ else
++ {
++ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize ;
++ }
++
++ pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024 ;
++ PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n",
++ pScrn->videoRam, pXGI->cmdQueueSize)) ;
++ PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n",
++ pXGI->cmdQueueOffset, pXGI->CursorOffset)) ;
++
++ pXGI->cmdQueueLen = 0 ;
++ pXGI->cmdQueueLenMin = 0x200 ;
++ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
++
++ /*****************************************************************
++ * Dual Chip support put here *
++ *****************************************************************/
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected DRAM type : %s\n", dramTypeStr);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected memory clock : %3.3fMHz\n",
++ pXGI->MemClock/1000.0);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected VRAM bus width is %d\n", pXGI->BusWidth);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ;
++ XGI_InitHwDevInfo(pScrn);
++}
++
++static void
++xgiXG40_Setup(ScrnInfoPtr pScrn)
++{
++ static const char *const dramChannelStr[5] = {
++ "<invalid>", "Single", "Dual", "<invalid>", "Quad"
++ };
++
++ static const char *const dramTypeStr[4] = {
++ "DDR SDRAM",
++ "DDR2 SDRAM",
++ "DDR2x SDRAM",
++ ""
++ };
++
++/*********************************************************************
++ * Setup
++ * Decide the following item of execution data:
++ *
++ * pXGI->BusWidth
++ * pXGI->videoRam (with KB unit)
++ * pXGI->CursorOffset (with Byte Unit)
++ * pXGI->cmdQueueSize (with Byte Unit)
++ * pXGI->cmdQueueSizeMask (with Byte Unit)
++ * pXGI->cmdQueueOffset (with Byte Unit)
++ * pXGI->cmdQueueLen = 0 ; // init value
++ * pXGI->cmdQueueLenMin = 0x200 ; // init value
++ * pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
++ *********************************************************************/
++
++ XGIPtr pXGI = XGIPTR(pScrn);
++ unsigned int ulMemConfig = 0;
++ unsigned mem_per_channel;
++ unsigned mem_channels = 1;
++ unsigned long ulDramType = 0;
++
++ PDEBUG4(ErrorF("xgiXG40_Setup()\n")) ;
++
++ pXGI->MemClock = XG40Mclk(pXGI);
++
++ /* SR14 DRAM Size Register
++ * Default value: XXh
++ * D[7:4] Memory size per channel {BChMemSize}
++ * 0011: 8 MB
++ * 0100: 16 MB
++ * 0101: 32 MB
++ * 0110: 64 MB
++ * 0111: 128 MB
++ * 1000: 256MB
++ * others: reserved
++ * D[3:2] Number of dram channels [1:0] {BChNum}
++ * 00: uni-channel
++ * 01: reserved
++ * 10: dual-channel
++ * 11: quad-channel
++ * D1 Data width per channel selection {BDataWidth}
++ * 0: 32-bits
++ * 1: 64-bits
++ * D0 Dram channel mapping {BReverseChMapping}
++ * 0: Normal mapping
++ * 1: Reversal mapping
++ * Dual-channel: Logical channel A/B to physical channel B/A
++ * Quad-channel: Logical channel A/B/C/D to physical channel
++ * C/D/A/B
++ */
++
++ outXGIIDXREG(XGISR, 0x5, 0x86) ;
++ inXGIIDXREG(XGISR, 0x14, ulMemConfig) ;
++
++ /* FIXME: Is this correct? The SiS driver detects this differently
++ * FIXME: for XG20.
++ */
++ inXGIIDXREG(XGISR, 0x3A, ulDramType) ;
++
++ PDEBUG(ErrorF("xg40_Setup(): ulMemConfig = %02X\n",ulMemConfig)) ;
++ PDEBUG(ErrorF("xg40_Setup(): ulDramType = %02X\n",ulDramType)) ;
++
++ /* FIXME: Is this correct? The SiS driver detects this differently
++ * FIXME: for XG20.
++ */
++ pXGI->BusWidth = (ulMemConfig & 0x02) ? 64 : 32;
++
++ mem_per_channel = ((ulMemConfig >> 4) >= 3)
++ ? (1 << (ulMemConfig >> 4)) * 1024
++ : 8 * 1024;
++
++
++ /* All XG20 family chips are single channel, so only test the channel
++ * count field on XG40 family chips.
++ */
++ if (pXGI->Chipset == PCI_CHIP_XGIXG40) {
++ /* Check the PCI revision field. For whatever reason, rev. 2 XG40
++ * chips encode the DRAM channel count differently than other
++ * revisions.
++ */
++ if (pXGI->ChipRev == 2) {
++ switch ((ulMemConfig >> 2) & 0x1) {
++ case 1:
++ /* Dual channel */
++ mem_channels = 2;
++ break ;
++ }
++ }
++ else {
++ switch ((ulMemConfig >> 2) & 0x3) {
++ case 2:
++ /* Dual channel */
++ mem_channels = 2;
++ break ;
++ case 3:
++ /* Quad channel */
++ mem_channels = 4;
++ break ;
++ }
++ }
++ }
++
++ pScrn->videoRam = mem_per_channel * mem_channels;
++
++ /* SR15 DRAM Address Mapping Register
++ * Default value: XXh
++ * D7 Channel interleaving configuration { BChConfig }
++ * 0: Divide the whole memory into 2/4 equal-sized regions , each mapped to one channel
++ * 1: Divide the whole memory into 2 regions according to BTilingSize[1:0] . The low-address region
++ * will be channel-interleaved as per BFineGranSize; the high-address region will be channel-
++ * interleaved as per BCoarseGranSize[1:0]
++ * D[6:5] Memory size of tile-mapped region {BTilingSize}
++ * 00: 4 MB
++ * 01: 8 MB
++ * 10: 16 MB
++ * 11: 32 MB
++ * The following bits are effective only when D7=1
++ * D4 Channel-interleaving granularity for tile-mapped region {BFineGranSize}
++ * 0: 64 B
++ * 1: 128 B
++ * D[3:2] Channel-interleaving granularity for linearly mapped region {BCoarseGranSize}
++ * 00: 1KB
++ * 01: 2KB
++ * 10: 4KB
++ * 11: 1MB
++ * D[1:0] reserved
++ */
++
++ /* Accelerator parameter Initialization */
++
++ pXGI->cmdQueueSize = ((pXGI->Chipset == PCI_CHIP_XGIXG20)||(pXGI->Chipset == PCI_CHIP_XGIXG21||(pXGI->Chipset == PCI_CHIP_XGIXG27)))
++ ? VOLARI_CQSIZEXG20 : VOLARI_CQSIZE;
++ pXGI->cmdQueueSizeMask = pXGI->cmdQueueSize - 1 ;
++ pXGI->pCQ_shareWritePort = &(pXGI->cmdQueue_shareWP_only2D);
++
++
++ /* If FbDevExist, X.org driver uses 8MB only. The rest of the framebuffer
++ * is used by the fbdev driver.
++ */
++ if (FbDevExist) {
++ /* FIXME: Is it even possible to have less than 8Mb of video memory?
++ */
++ if (pScrn->videoRam < 8*1024) {
++ pXGI->cmdQueueOffset = 4*1024*1024 - pXGI->cmdQueueSize;
++ }
++ else if (pScrn->videoRam < 16*1024) {
++ pXGI->cmdQueueOffset = 8*1024*1024 - pXGI->cmdQueueSize;
++ }
++ else {
++ pXGI->cmdQueueOffset = 13*1024*1024 - pXGI->cmdQueueSize;
++ }
++ }
++ else {
++ pXGI->cmdQueueOffset = (pScrn->videoRam)*1024 - pXGI->cmdQueueSize;
++ }
++
++ pXGI->CursorOffset = pXGI->cmdQueueOffset - 64*1024;
++ PDEBUG4(ErrorF("pScrn->videoRam = %08lX pXGI->cmdQueueSize = %08lX\n",
++ pScrn->videoRam, pXGI->cmdQueueSize)) ;
++ PDEBUG4(ErrorF("pXGI->cmdQueueOffset = %08lX pXGI->CursorOffset = %08lX\n",
++ pXGI->cmdQueueOffset, pXGI->CursorOffset)) ;
++
++ pXGI->cmdQueueLen = 0 ;
++ pXGI->cmdQueueLenMin = 0x200 ;
++ pXGI->cmdQueueLenMax = pXGI->cmdQueueSize - pXGI->cmdQueueLenMin ;
++
++ /* Dual Chip support put here
++ */
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected DRAM type : %s channel %s\n",
++ dramChannelStr[mem_channels],
++ dramTypeStr[(ulDramType & 0x02) >> 1]);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected memory clock : %3.3fMHz\n",
++ pXGI->MemClock/1000.0);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected VRAM bus width is %d\n", pXGI->BusWidth);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected Cmd Queue size is %d KB\n", pXGI->cmdQueueSize / 1024);
++ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
++ "Detected Cmd Queue Offset is %d\n", pXGI->cmdQueueOffset ) ;
++ XGI_InitHwDevInfo(pScrn);
++}
++
++void
++XGISetup(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ pXGI->Flags = 0;
++ pXGI->VBFlags = 0;
++
++ /* Jong 10/16/2007; merge code */
++ switch (pXGI->Chipset) {
++ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21:
++ case PCI_CHIP_XGIXG27:
++ xgiXG2X_Setup(pScrn);
++ break;
++
++ case PCI_CHIP_XGIXG40:
++ default:
++ xgiXG40_Setup(pScrn);
++ break;
++ }
++}
++
++/* Jong 01/07/2008; Force to disable 2D engine by SR3A[6]=1 */
++Bool ForceToDisable2DEngine(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI ;
++ Bool bReturn=FALSE;
++ CARD8 bForce;
++
++ pXGI = XGIPTR(pScrn);
++
++ if(pXGI->Chipset == PCI_CHIP_XGIXG21)
++ {
++ inXGIIDXREG(XGISR, 0x3A, bForce) ;
++ bForce &= 0x40;
++
++ if(bForce == 0)
++ bReturn=FALSE;
++ else
++ bReturn=TRUE;
++ }
++ else
++ {
++ bReturn=FALSE;
++ }
++
++ return(bReturn);
++}
++
++Bool
++XGI_IsXG21(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ Bool is_XG21 = FALSE;
++
++ if (pXGI->Chipset == PCI_CHIP_XGIXG20) {
++ int temp;
++
++ orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
++ inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, temp);
++
++ is_XG21 = ((temp & GPIOG_READ) != 0);
++ }
++
++ return is_XG21;
++}
++
++void
++XGI_InitHwDevInfo(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ PXGI_HW_DEVICE_INFO pHwDevInfo = &pXGI->xgi_HwDevExt;
++ int i;
++
++ pHwDevInfo->pDevice = pXGI ;
++ pHwDevInfo->pjVirtualRomBase = pXGI->BIOS ;
++ pHwDevInfo->pjCustomizedROMImage = NULL ;
++ pHwDevInfo->pjVideoMemoryAddress = (UCHAR*)(pXGI->FbBase) ;
++ PDEBUG(ErrorF("pXGI->FbBase = 0x%08lx\n",(ULONG)(pXGI->FbBase))) ;
++ PDEBUG(ErrorF("pHwDevInfo->pjVideoMemoryAddress = 0x%08lx\n",(ULONG)(pHwDevInfo->pjVideoMemoryAddress))) ;
++ pHwDevInfo->ulVideoMemorySize = pXGI->FbMapSize ;
++ pHwDevInfo->pjIOAddress = pXGI->RelIO + 0x30 ;
++
++ switch (pXGI->Chipset) {
++ case PCI_CHIP_XGIXG40:
++ pHwDevInfo->jChipType = XG40 ;
++ break ;
++ case PCI_CHIP_XGIXG20:
++ pHwDevInfo->jChipType = XGI_IsXG21(pScrn)?XG21:XG20 ;
++ break ;
++ case PCI_CHIP_XGIXG27:
++ pHwDevInfo->jChipType = XG27;
++ break;
++ case PCI_CHIP_XGIXG21:
++ pHwDevInfo->jChipType = XG21;
++ break;
++ default:
++ pHwDevInfo->jChipType = XG40 ;
++ break ;
++ }
++
++ pHwDevInfo->jChipRevision = pXGI->ChipRev;
++ pHwDevInfo->ujVBChipID = VB_CHIP_UNKNOWN ;
++ pHwDevInfo->ulExternalChip = 0 ;
++
++ pHwDevInfo->ulCRT2LCDType = LCD_1024x768 ;
++ pHwDevInfo->bIntegratedMMEnabled = FALSE ;
++ pHwDevInfo->bSkipDramSizing = TRUE ;
++
++ pHwDevInfo->pSR = pXGI->SRList ;
++ pHwDevInfo->pCR = pXGI->CRList ;
++ pHwDevInfo->pQueryVGAConfigSpace = (PXGI_QUERYSPACE) bAccessVGAPCIInfo;
++
++ for( i = 0 ; i < ExtRegSize ; i++ ){
++ pHwDevInfo->pSR[i].jIdx = 0xFF ;
++ pHwDevInfo->pSR[i].jVal = 0xFF ;
++ pHwDevInfo->pCR[i].jIdx = 0xFF ;
++ pHwDevInfo->pCR[i].jVal = 0xFF ;
++ }
++
++ for( i = 0 ; i < VBIOS_VER_MAX_LENGTH ; i++ ){
++ pHwDevInfo -> szVBIOSVer[i] = '\0' ;
++ }
++
++
++ XGINew_InitVBIOSData(pHwDevInfo, pXGI->XGI_Pr);
++ PDEBUG(ErrorF("XGINew_InitVBIOSData(pHwDevInfo) done\n")) ;
++
++ ErrorF("XGI_InitVBIOSData VBType = %x\n", pXGI->XGI_Pr->VBType);
++ XGI_New_GetVBType(pXGI->XGI_Pr, pHwDevInfo); //yilin
++ ErrorF("XGI_New_GetVBType VBType = %x\n", pXGI->XGI_Pr->VBType);
++
++ // pHwDevInfo->ujVBChipID = VB_CHIP_301 ; //yilin
++ if( pXGI->XGI_Pr->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI301C))
++ {
++ PDEBUG(ErrorF("VB chip = 301 \n")) ;
++ pHwDevInfo->ujVBChipID = VB_CHIP_301 ;
++ }
++ else if( pXGI->VBFlags & ( VB_XGI302B| VB_XGI302LV ))
++ {
++ pHwDevInfo->ujVBChipID = VB_CHIP_302 ;
++ }
++/*
++ else if (pXGI->VBFlags & VB_LVDS) {
++ pHwDevInfo->ulExternalChip |= 0x01 ;
++ }
++*/ //yilin
++
++
++ PDEBUG(ErrorF("pHwDevInfo->jChipType = %08lX done\n",pHwDevInfo->jChipType)) ;
++}
++
++Bool
++bAccessVGAPCIInfo(PXGI_HW_DEVICE_INFO pHwDevInfo, ULONG ulOffset, ULONG ulSet, ULONG *pulValue)
++{
++ XGIPtr pXGI ;
++#ifdef XSERVER_LIBPCIACCESS
++ int err;
++#else
++ PCITAG pciDev;
++#endif
++
++ if (!pHwDevInfo || !pulValue) {
++ return FALSE;
++ }
++
++ pXGI = (XGIPtr)pHwDevInfo->pDevice ;
++#ifdef XSERVER_LIBPCIACCESS
++ if (ulSet) {
++ err = pci_device_cfg_write_u32(pXGI->PciInfo, *pulValue,
++ ulOffset & ~3);
++ } else {
++ err = pci_device_cfg_write_u32(pXGI->PciInfo, pulValue,
++ ulOffset & ~3);
++ }
++
++ return (err == 0);
++#else
++ pciDev = pXGI->PciTag ;
++
++ if (ulSet) {
++ pciWriteLong(pciDev, ulOffset&0xFFFFFFFc, *pulValue);
++ } else {
++ *pulValue = pciReadLong(pciDev, ulOffset&0xFFFFFFFc);
++ }
++
++ return TRUE ;
++#endif
++}
+diff --git a/src/xgi_vb.c b/src/xgi_vb.c
+diff --git a/src/xgi_vb.h b/src/xgi_vb.h
+diff --git a/src/xgi_vga.c b/src/xgi_vga.c
+index 8ff0cb0..4639d3e 100644
+--- a/src/xgi_vga.c
++++ b/src/xgi_vga.c
+@@ -1,263 +1,276 @@
+-/*
+- * Mode setup and basic video bridge detection
+- *
+- * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1) Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2) Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- * 3) The name of the author may not be used to endorse or promote products
+- * derived from this software without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
+- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- * Author: Thomas Winischhofer <thomas@winischhofer.net>
+- *
+- * Init() function for old series (except for TV and FIFO calculation)
+- * previously based on code which is Copyright (C) 1998,1999 by Alan
+- * Hourihane, Wigan, England
+- */
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-
+-#include "xf86.h"
+-#include "xf86_OSproc.h"
+-#include "xf86Version.h"
+-#include "xf86PciInfo.h"
+-#include "xf86Pci.h"
+-
+-#include "xgi.h"
+-#include "xgi_regs.h"
+-#include "xgi_dac.h"
+-
+-#include "vb_def.h"
+-
+-Bool XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+-
+-#define Midx 0
+-#define Nidx 1
+-#define VLDidx 2
+-#define Pidx 3
+-
+-Bool
+-XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+- XGIRegPtr pReg = &pXGI->ModeReg;
+- vgaRegPtr vgaReg = &VGAHWPTR(pScrn)->ModeReg;
+- int vgaIOBase;
+- unsigned short temp;
+- int offset;
+- int clock = mode->Clock;
+- unsigned int vclk[5];
+-
+- int num, denum, div, sbit, scale;
+- unsigned short Threshold_Low, Threshold_High;
+-
+-PDEBUG(ErrorF("XG40Init()\n"));
+-
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "XG40Init()\n");
+- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+- "virtualX = %d depth = %d Logical width = %d\n",
+- pScrn->virtualX, pScrn->bitsPerPixel,
+- pScrn->virtualX * pScrn->bitsPerPixel/8);
+-
+- vgaHWGetIOBase(VGAHWPTR(pScrn));
+- vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+-
+- (*pXGI->XGISave)(pScrn, pReg);
+-
+- outw(VGA_SEQ_INDEX, 0x8605);
+-
+- pReg->xgiRegs3C4[6] &= ~GENMASK(4:2);
+-
+- switch (pScrn->bitsPerPixel) {
+- case 8:
+- pXGI->DstColor = 0 ;
+- pReg->xgiRegs3C4[6] |= 0x03;
+- PDEBUG(ErrorF("8: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
+- break;
+- case 16:
+- pXGI->DstColor = 1 << 16 ;
+- PDEBUG(ErrorF("16: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
+- if (pScrn->depth==15) {
+- pReg->xgiRegs3C4[6] |= ((1 << 2) | 0x03);
+- } else {
+- pReg->xgiRegs3C4[6] |= ((2 << 2) | 0x03);
+- }
+- break;
+- case 24:
+- pReg->xgiRegs3C4[6] |= ((3 << 2) | 0x03);
+- break;
+- case 32:
+- PDEBUG(ErrorF("32: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
+- pXGI->DstColor = 2 << 16 ;
+- pReg->xgiRegs3C4[6] |= ((4 << 2) | 0x03);
+- break;
+- }
+-
+- pXGI->scrnOffset = pScrn->displayWidth * ((pScrn->bitsPerPixel+7)/8);
+- pXGI->scrnOffset += 15 ;
+- pXGI->scrnOffset >>= 4 ;
+- pXGI->scrnOffset <<= 4 ;
+-
+- PDEBUG(ErrorF("XG40Init: pScrn->displayWidth = %ld\n",pScrn->displayWidth )) ;
+- PDEBUG(ErrorF("XG40Init: pScrn->bitsPerPixel = %ld\n",pScrn->bitsPerPixel )) ;
+- PDEBUG(ErrorF("XG40Init: pXGI->scrnOffset = %ld\n",pXGI->scrnOffset )) ;
+-
+- pReg->xgiRegs3D4[0x19] = 0;
+- pReg->xgiRegs3D4[0x1A] &= 0xFC;
+-
+- if (mode->Flags & V_INTERLACE) {
+- offset = pXGI->scrnOffset >> 2;
+- pReg->xgiRegs3C4[0x06] |= 0x20;
+-
+- temp = (mode->CrtcHSyncStart >> 3) -
+- (mode->CrtcHTotal >> 3)/2;
+- pReg->xgiRegs3D4[0x19] = GETVAR8(temp);
+- pReg->xgiRegs3D4[0x1A] |= GETBITS(temp, 9:8);
+- } else {
+- offset = pXGI->scrnOffset >> 3;
+- pReg->xgiRegs3C4[0x06] &= ~0x20;
+- }
+-
+- pReg->xgiRegs3C4[0x07] |= 0x10; /* enable High Speed DAC */
+- pReg->xgiRegs3C4[0x07] &= 0xFC;
+- if (clock < 100000)
+- pReg->xgiRegs3C4[0x07] |= 0x03;
+- else if (clock < 200000)
+- pReg->xgiRegs3C4[0x07] |= 0x02;
+- else if (clock < 250000)
+- pReg->xgiRegs3C4[0x07] |= 0x01;
+-
+- /* Extended Vertical Overflow */
+- pReg->xgiRegs3C4[0x0A] =
+- GETBITSTR(mode->CrtcVTotal -2, 10:10, 0:0) |
+- GETBITSTR(mode->CrtcVDisplay -1, 10:10, 1:1) |
+- GETBITSTR(mode->CrtcVBlankStart , 10:10, 2:2) |
+- GETBITSTR(mode->CrtcVSyncStart , 10:10, 3:3) |
+- GETBITSTR(mode->CrtcVBlankEnd , 8:8, 4:4) |
+- GETBITSTR(mode->CrtcVSyncEnd , 4:4, 5:5) ;
+-
+- /* Extended Horizontal Overflow */
+- pReg->xgiRegs3C4[0x0B] =
+- GETBITSTR((mode->CrtcHTotal >> 3) - 5, 9:8, 1:0) |
+- GETBITSTR((mode->CrtcHDisplay >> 3) - 1, 9:8, 3:2) |
+- GETBITSTR((mode->CrtcHBlankStart >> 3) , 9:8, 5:4) |
+- GETBITSTR((mode->CrtcHSyncStart >> 3) , 9:8, 7:6) ;
+-
+- pReg->xgiRegs3C4[0x0C] &= 0xF8;
+- pReg->xgiRegs3C4[0x0C] |=
+- GETBITSTR(mode->CrtcHBlankEnd >> 3, 7:6, 1:0) |
+- GETBITSTR(mode->CrtcHSyncEnd >> 3, 5:5, 2:2) ;
+-
+- /* Screen Offset */
+- vgaReg->CRTC[0x13] = GETVAR8(offset);
+- pReg->xgiRegs3C4[0x0E] &= 0xF0;
+- pReg->xgiRegs3C4[0x0E] |= GETBITS(offset, 11:8);
+-
+- /* line compare */
+- if (mode->CrtcHDisplay > 0)
+- pReg->xgiRegs3C4[0x0F] |= 0x08;
+- else
+- pReg->xgiRegs3C4[0x0F] &= 0xF7;
+-
+- pReg->xgiRegs3C4[0x10] =
+- ((mode->CrtcHDisplay *((pScrn->bitsPerPixel+7)/8) + 63) >> 6)+1;
+-
+- /* Enable Linear */
+- pReg->xgiRegs3C4[0x20] |= 0x81;
+-
+-
+- /* Set vclk */
+- if (compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) {
+- pReg->xgiRegs3C4[0x2B] = (num -1) & 0x7f;
+- if (div == 2)
+- pReg->xgiRegs3C4[0x2B] |= 0x80;
+- pReg->xgiRegs3C4[0x2C] = ((denum -1) & 0x1f);
+- pReg->xgiRegs3C4[0x2C] |= (((scale-1)&3) << 5);
+- if (sbit)
+- pReg->xgiRegs3C4[0x2C] |= 0x80;
+- pReg->xgiRegs3C4[0x2D] = 0x80;
+- }
+- else {
+- /* if compute_vclk cannot handle the request clock try XGICalcClock! */
+- XGICalcClock(pScrn, clock, 2, vclk);
+- pReg->xgiRegs3C4[0x2B] = (vclk[Midx] - 1) & 0x7f ;
+- pReg->xgiRegs3C4[0x2B] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
+-
+- /* bits [4:0] contain denumerator -MC */
+- pReg->xgiRegs3C4[0x2C] = (vclk[Nidx] -1) & 0x1f ;
+-
+- if (vclk[Pidx] <= 4) {
+- /* postscale 1,2,3,4 */
+- pReg->xgiRegs3C4[0x2C] |= (vclk[Pidx] -1 ) << 5 ;
+- pReg->xgiRegs3C4[0x2C] &= 0x7F;
+- } else {
+- /* postscale 6,8 */
+- pReg->xgiRegs3C4[0x2C] |= ((vclk[Pidx] / 2) -1 ) << 5 ;
+- pReg->xgiRegs3C4[0x2C] |= 0x80;
+- }
+- pReg->xgiRegs3C4[0x2D] = 0x80;
+- } /* end of set vclk */
+-
+- if (clock > 150000) { /* enable two-pixel mode */
+- pReg->xgiRegs3C4[0x07] |= 0x80;
+- pReg->xgiRegs3C4[0x32] |= 0x08;
+- } else {
+- pReg->xgiRegs3C4[0x07] &= 0x7F;
+- pReg->xgiRegs3C4[0x32] &= 0xF7;
+- }
+-
+- /*pReg->xgiRegs3C2 = inb(0x3CC) | 0x0C;*/ /* Programmable Clock */
+- pReg->xgiRegs3C2 = inb(pXGI->RelIO+0x4c) | 0x0C; /*Programmable Clock*/
+-
+- if (!pXGI->NoAccel) {
+- /* Enable 2D accelerator.
+- */
+- pReg->xgiRegs3C4[0x1E] |= (SR1E_ENABLE_2D | SR1E_ENABLE_3D);
+- }
+-
+- /* set threshold value */
+- (*pXGI->SetThreshold)(pScrn, mode, &Threshold_Low, &Threshold_High);
+- pReg->xgiRegs3C4[0x08] = GETBITSTR(Threshold_Low, 3:0, 7:4) | 0xF;
+- pReg->xgiRegs3C4[0x0F] &= ~GENMASK(5:5);
+- pReg->xgiRegs3C4[0x0F] |= GETBITSTR(Threshold_Low, 4:4, 5:5);
+- pReg->xgiRegs3C4[0x09] &= ~GENMASK(3:0);
+- pReg->xgiRegs3C4[0x09] |= GETBITS(Threshold_High, 3:0);
+-
+- return(TRUE);
+-}
+-
+-/* Detect video bridge and set VBFlags accordingly */
+-void XGIVGAPreInit(ScrnInfoPtr pScrn)
+-{
+- XGIPtr pXGI = XGIPTR(pScrn);
+-
+- switch (pXGI->Chipset) {
+- case PCI_CHIP_XGIXG40:
+- case PCI_CHIP_XGIXG20:
+- default:
+- pXGI->ModeInit = XG40Init;
+- break;
+- }
+-
+-
+-}
+-
++/*
++ * Mode setup and basic video bridge detection
++ *
++ * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1) Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2) Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3) The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * Author: Thomas Winischhofer <thomas@winischhofer.net>
++ *
++ * Init() function for old series (except for TV and FIFO calculation)
++ * previously based on code which is Copyright (C) 1998,1999 by Alan
++ * Hourihane, Wigan, England
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "xf86.h"
++#include "xf86_OSproc.h"
++#include "xf86Version.h"
++#include "xf86PciInfo.h"
++#include "xf86Pci.h"
++
++#include "xgi.h"
++#include "xgi_regs.h"
++#include "xgi_dac.h"
++
++#include "vb_def.h"
++
++Bool XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
++
++/* Jong 01/07/2008; force to disable 2D */
++extern Bool ForceToDisable2DEngine(ScrnInfoPtr pScrn);
++
++#define Midx 0
++#define Nidx 1
++#define VLDidx 2
++#define Pidx 3
++
++Bool
++XG40Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++ XGIRegPtr pReg = &pXGI->ModeReg;
++ vgaRegPtr vgaReg = &VGAHWPTR(pScrn)->ModeReg;
++ int vgaIOBase;
++ unsigned short temp;
++ int offset;
++ int clock = mode->Clock;
++ unsigned int vclk[5];
++
++ int num, denum, div, sbit, scale;
++ unsigned short Threshold_Low, Threshold_High;
++
++PDEBUG(ErrorF("XG40Init()\n"));
++
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "XG40Init()\n");
++ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
++ "virtualX = %d depth = %d Logical width = %d\n",
++ pScrn->virtualX, pScrn->bitsPerPixel,
++ pScrn->virtualX * pScrn->bitsPerPixel/8);
++
++ vgaHWGetIOBase(VGAHWPTR(pScrn));
++ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
++
++ (*pXGI->XGISave)(pScrn, pReg);
++
++ outw(VGA_SEQ_INDEX, 0x8605);
++
++ pReg->xgiRegs3C4[6] &= ~GENMASK(4:2);
++
++ switch (pScrn->bitsPerPixel) {
++ case 8:
++ pXGI->DstColor = 0 ;
++ pReg->xgiRegs3C4[6] |= 0x03;
++ PDEBUG(ErrorF("8: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
++ break;
++ case 16:
++ pXGI->DstColor = 1 << 16 ;
++ PDEBUG(ErrorF("16: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
++ if (pScrn->depth==15) {
++ pReg->xgiRegs3C4[6] |= ((1 << 2) | 0x03);
++ } else {
++ pReg->xgiRegs3C4[6] |= ((2 << 2) | 0x03);
++ }
++ break;
++ case 24:
++ pReg->xgiRegs3C4[6] |= ((3 << 2) | 0x03);
++ break;
++ case 32:
++ PDEBUG(ErrorF("32: pXGI->DstColor = %08lX\n",pXGI->DstColor)) ;
++ pXGI->DstColor = 2 << 16 ;
++ pReg->xgiRegs3C4[6] |= ((4 << 2) | 0x03);
++ break;
++ }
++
++ pXGI->scrnOffset = pScrn->displayWidth * ((pScrn->bitsPerPixel+7)/8);
++ pXGI->scrnOffset += 15 ;
++ pXGI->scrnOffset >>= 4 ;
++ pXGI->scrnOffset <<= 4 ;
++
++ PDEBUG(ErrorF("XG40Init: pScrn->displayWidth = %ld\n",pScrn->displayWidth )) ;
++ PDEBUG(ErrorF("XG40Init: pScrn->bitsPerPixel = %ld\n",pScrn->bitsPerPixel )) ;
++ PDEBUG(ErrorF("XG40Init: pXGI->scrnOffset = %ld\n",pXGI->scrnOffset )) ;
++
++ pReg->xgiRegs3D4[0x19] = 0;
++ pReg->xgiRegs3D4[0x1A] &= 0xFC;
++
++ if (mode->Flags & V_INTERLACE) {
++ offset = pXGI->scrnOffset >> 2;
++ pReg->xgiRegs3C4[0x06] |= 0x20;
++
++ temp = (mode->CrtcHSyncStart >> 3) -
++ (mode->CrtcHTotal >> 3)/2;
++ pReg->xgiRegs3D4[0x19] = GETVAR8(temp);
++ pReg->xgiRegs3D4[0x1A] |= GETBITS(temp, 9:8);
++ } else {
++ offset = pXGI->scrnOffset >> 3;
++ pReg->xgiRegs3C4[0x06] &= ~0x20;
++ }
++
++ pReg->xgiRegs3C4[0x07] |= 0x10; /* enable High Speed DAC */
++ pReg->xgiRegs3C4[0x07] &= 0xFC;
++ if (clock < 100000)
++ pReg->xgiRegs3C4[0x07] |= 0x03;
++ else if (clock < 200000)
++ pReg->xgiRegs3C4[0x07] |= 0x02;
++ else if (clock < 250000)
++ pReg->xgiRegs3C4[0x07] |= 0x01;
++
++ /* Extended Vertical Overflow */
++ pReg->xgiRegs3C4[0x0A] =
++ GETBITSTR(mode->CrtcVTotal -2, 10:10, 0:0) |
++ GETBITSTR(mode->CrtcVDisplay -1, 10:10, 1:1) |
++ GETBITSTR(mode->CrtcVBlankStart , 10:10, 2:2) |
++ GETBITSTR(mode->CrtcVSyncStart , 10:10, 3:3) |
++ GETBITSTR(mode->CrtcVBlankEnd , 8:8, 4:4) |
++ GETBITSTR(mode->CrtcVSyncEnd , 4:4, 5:5) ;
++
++ /* Extended Horizontal Overflow */
++ pReg->xgiRegs3C4[0x0B] =
++ GETBITSTR((mode->CrtcHTotal >> 3) - 5, 9:8, 1:0) |
++ GETBITSTR((mode->CrtcHDisplay >> 3) - 1, 9:8, 3:2) |
++ GETBITSTR((mode->CrtcHBlankStart >> 3) , 9:8, 5:4) |
++ GETBITSTR((mode->CrtcHSyncStart >> 3) , 9:8, 7:6) ;
++
++ pReg->xgiRegs3C4[0x0C] &= 0xF8;
++ pReg->xgiRegs3C4[0x0C] |=
++ GETBITSTR(mode->CrtcHBlankEnd >> 3, 7:6, 1:0) |
++ GETBITSTR(mode->CrtcHSyncEnd >> 3, 5:5, 2:2) ;
++
++ /* Screen Offset */
++ vgaReg->CRTC[0x13] = GETVAR8(offset);
++ pReg->xgiRegs3C4[0x0E] &= 0xF0;
++ pReg->xgiRegs3C4[0x0E] |= GETBITS(offset, 11:8);
++
++ /* line compare */
++ if (mode->CrtcHDisplay > 0)
++ pReg->xgiRegs3C4[0x0F] |= 0x08;
++ else
++ pReg->xgiRegs3C4[0x0F] &= 0xF7;
++
++ pReg->xgiRegs3C4[0x10] =
++ ((mode->CrtcHDisplay *((pScrn->bitsPerPixel+7)/8) + 63) >> 6)+1;
++
++ /* Enable Linear */
++ pReg->xgiRegs3C4[0x20] |= 0x81;
++
++
++ /* Set vclk */
++ if (compute_vclk(clock, &num, &denum, &div, &sbit, &scale)) {
++ pReg->xgiRegs3C4[0x2B] = (num -1) & 0x7f;
++ if (div == 2)
++ pReg->xgiRegs3C4[0x2B] |= 0x80;
++ pReg->xgiRegs3C4[0x2C] = ((denum -1) & 0x1f);
++ pReg->xgiRegs3C4[0x2C] |= (((scale-1)&3) << 5);
++ if (sbit)
++ pReg->xgiRegs3C4[0x2C] |= 0x80;
++ pReg->xgiRegs3C4[0x2D] = 0x80;
++ }
++ else {
++ /* if compute_vclk cannot handle the request clock try XGICalcClock! */
++ XGICalcClock(pScrn, clock, 2, vclk);
++ pReg->xgiRegs3C4[0x2B] = (vclk[Midx] - 1) & 0x7f ;
++ pReg->xgiRegs3C4[0x2B] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
++
++ /* bits [4:0] contain denumerator -MC */
++ pReg->xgiRegs3C4[0x2C] = (vclk[Nidx] -1) & 0x1f ;
++
++ if (vclk[Pidx] <= 4) {
++ /* postscale 1,2,3,4 */
++ pReg->xgiRegs3C4[0x2C] |= (vclk[Pidx] -1 ) << 5 ;
++ pReg->xgiRegs3C4[0x2C] &= 0x7F;
++ } else {
++ /* postscale 6,8 */
++ pReg->xgiRegs3C4[0x2C] |= ((vclk[Pidx] / 2) -1 ) << 5 ;
++ pReg->xgiRegs3C4[0x2C] |= 0x80;
++ }
++ pReg->xgiRegs3C4[0x2D] = 0x80;
++ } /* end of set vclk */
++
++ if (clock > 150000) { /* enable two-pixel mode */
++ pReg->xgiRegs3C4[0x07] |= 0x80;
++ pReg->xgiRegs3C4[0x32] |= 0x08;
++ } else {
++ pReg->xgiRegs3C4[0x07] &= 0x7F;
++ pReg->xgiRegs3C4[0x32] &= 0xF7;
++ }
++
++ /*pReg->xgiRegs3C2 = inb(0x3CC) | 0x0C;*/ /* Programmable Clock */
++ pReg->xgiRegs3C2 = inb(pXGI->RelIO+0x4c) | 0x0C; /*Programmable Clock*/
++
++ if (!pXGI->NoAccel) {
++ /* Enable 2D accelerator.
++ */
++ /* Jong 01/07/2008; disable 2D engine depend on SR3A[6]:1-> force to siable 2D */
++ if(pXGI->Chipset != PCI_CHIP_XGIXG21)
++ pReg->xgiRegs3C4[0x1E] |= 0x42;
++ else
++ {
++ if(ForceToDisable2DEngine(pScrn))
++ pReg->xgiRegs3C4[0x1E] |= 0x02;
++ }
++
++ }
++
++ /* set threshold value */
++ (*pXGI->SetThreshold)(pScrn, mode, &Threshold_Low, &Threshold_High);
++ pReg->xgiRegs3C4[0x08] = GETBITSTR(Threshold_Low, 3:0, 7:4) | 0xF;
++ pReg->xgiRegs3C4[0x0F] &= ~GENMASK(5:5);
++ pReg->xgiRegs3C4[0x0F] |= GETBITSTR(Threshold_Low, 4:4, 5:5);
++ pReg->xgiRegs3C4[0x09] &= ~GENMASK(3:0);
++ pReg->xgiRegs3C4[0x09] |= GETBITS(Threshold_High, 3:0);
++
++ return(TRUE);
++}
++
++/* Detect video bridge and set VBFlags accordingly */
++void XGIVGAPreInit(ScrnInfoPtr pScrn)
++{
++ XGIPtr pXGI = XGIPTR(pScrn);
++
++ switch (pXGI->Chipset) {
++ case PCI_CHIP_XGIXG40:
++ case PCI_CHIP_XGIXG20:
++ case PCI_CHIP_XGIXG21:
++ case PCI_CHIP_XGIXG27:
++ default:
++ pXGI->ModeInit = XG40Init;
++ break;
++ }
++
++
++}
++
+diff --git a/src/xgi_video.c b/src/xgi_video.c
+diff --git a/src/xgi_video.h b/src/xgi_video.h
+diff --git a/src/xgi_videohw.c b/src/xgi_videohw.c
+diff --git a/src/xgi_videohw.h b/src/xgi_videohw.h