diff options
author | root <root@linux.site> | 2008-04-28 10:46:29 +0800 |
---|---|---|
committer | root <root@linux.site> | 2008-04-28 10:46:29 +0800 |
commit | f9f7b2a7457744f9abc99626ee992a6886a6fbe5 (patch) | |
tree | 07ce9357cb2965e24d03b888fac25c9582f5168f | |
parent | 0b28672591001e1448cfc65f928d0b5f0ec79138 (diff) |
XGI:Add support for XG21/27
-rw-r--r-- | src/init.c | 2105 | ||||
-rw-r--r-- | src/init.h | 1 | ||||
-rw-r--r-- | src/vb_def.h | 18 | ||||
-rw-r--r-- | src/vb_ext.c | 19 | ||||
-rw-r--r-- | src/vb_ext.h | 27 | ||||
-rw-r--r-- | src/vb_init.c | 6702 | ||||
-rw-r--r-- | src/vb_init.h | 3 | ||||
-rw-r--r-- | src/vb_setmode.c | 17902 | ||||
-rw-r--r-- | src/vb_setmode.h | 18 | ||||
-rw-r--r-- | src/vb_struct.h | 1073 | ||||
-rw-r--r-- | src/vb_table.h | 205 | ||||
-rw-r--r-- | src/vgatypes.h | 20 | ||||
-rw-r--r-- | src/xgi.h | 1794 | ||||
-rw-r--r-- | src/xgi_accel.c | 1729 | ||||
-rw-r--r-- | src/xgi_accel.h | 48 | ||||
-rw-r--r-- | src/xgi_cursor.c | 89 | ||||
-rw-r--r-- | src/xgi_cursor.h | 23 | ||||
-rw-r--r-- | src/xgi_dac.c | 45 | ||||
-rw-r--r-- | src/xgi_dri.c | 6 | ||||
-rw-r--r-- | src/xgi_driver.c | 12494 | ||||
-rw-r--r-- | src/xgi_driver.h | 86 | ||||
-rw-r--r-- | src/xgi_opt.c | 2 | ||||
-rw-r--r-- | src/xgi_pci.h | 70 | ||||
-rw-r--r-- | src/xgi_setup.c | 1107 | ||||
-rw-r--r-- | src/xgi_vga.c | 539 | ||||
-rw-r--r-- | xgi-xg20-21-27.patch | 46676 |
26 files changed, 71740 insertions, 21061 deletions
@@ -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 */
@@ -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 @@ -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 |