1dfe64dd3Smacallan/*
2dfe64dd3Smacallan * Mode initializing code (CRT1 section)
3dfe64dd3Smacallan * (Universal module for Linux kernel framebuffer and XFree86 4.x)
4dfe64dd3Smacallan *
5dfe64dd3Smacallan * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
6dfe64dd3Smacallan *
7dfe64dd3Smacallan * If distributed as part of the Linux kernel, the following license terms
8dfe64dd3Smacallan * apply:
9dfe64dd3Smacallan *
10dfe64dd3Smacallan * * This program is free software; you can redistribute it and/or modify
11dfe64dd3Smacallan * * it under the terms of the GNU General Public License as published by
12dfe64dd3Smacallan * * the Free Software Foundation; either version 2 of the named License,
13dfe64dd3Smacallan * * or any later version.
14dfe64dd3Smacallan * *
15dfe64dd3Smacallan * * This program is distributed in the hope that it will be useful,
16dfe64dd3Smacallan * * but WITHOUT ANY WARRANTY; without even the implied warranty of
17dfe64dd3Smacallan * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18dfe64dd3Smacallan * * GNU General Public License for more details.
19dfe64dd3Smacallan * *
20dfe64dd3Smacallan * * You should have received a copy of the GNU General Public License
21dfe64dd3Smacallan * * along with this program; if not, write to the Free Software
22dfe64dd3Smacallan * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
23dfe64dd3Smacallan *
24dfe64dd3Smacallan * Otherwise, the following license terms apply:
25dfe64dd3Smacallan *
26dfe64dd3Smacallan * * Redistribution and use in source and binary forms, with or without
27dfe64dd3Smacallan * * modification, are permitted provided that the following conditions
28dfe64dd3Smacallan * * are met:
29dfe64dd3Smacallan * * 1) Redistributions of source code must retain the above copyright
30dfe64dd3Smacallan * *    notice, this list of conditions and the following disclaimer.
31dfe64dd3Smacallan * * 2) Redistributions in binary form must reproduce the above copyright
32dfe64dd3Smacallan * *    notice, this list of conditions and the following disclaimer in the
33dfe64dd3Smacallan * *    documentation and/or other materials provided with the distribution.
34dfe64dd3Smacallan * * 3) The name of the author may not be used to endorse or promote products
35dfe64dd3Smacallan * *    derived from this software without specific prior written permission.
36dfe64dd3Smacallan * *
37dfe64dd3Smacallan * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
38dfe64dd3Smacallan * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39dfe64dd3Smacallan * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40dfe64dd3Smacallan * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41dfe64dd3Smacallan * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42dfe64dd3Smacallan * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43dfe64dd3Smacallan * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44dfe64dd3Smacallan * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45dfe64dd3Smacallan * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46dfe64dd3Smacallan * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47dfe64dd3Smacallan *
48dfe64dd3Smacallan * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
49dfe64dd3Smacallan *
50dfe64dd3Smacallan * Formerly based on non-functional code-fragements for 300 series by XGI, Inc.
51dfe64dd3Smacallan * Used by permission.
52dfe64dd3Smacallan *
53dfe64dd3Smacallan * TW says: This code looks awful, I know. But please don't do anything about
54dfe64dd3Smacallan * this otherwise debugging will be hell.
55dfe64dd3Smacallan * The code is extremely fragile as regards the different chipsets, different
56dfe64dd3Smacallan * video bridges and combinations thereof. If anything is changed, extreme
57dfe64dd3Smacallan * care has to be taken that that change doesn't break it for other chipsets,
58dfe64dd3Smacallan * bridges or combinations thereof.
59dfe64dd3Smacallan * All comments in this file are by me, regardless if they are marked TW or not.
60dfe64dd3Smacallan *
61dfe64dd3Smacallan */
62dfe64dd3Smacallan
63dfe64dd3Smacallan#ifdef HAVE_CONFIG_H
64dfe64dd3Smacallan#include "config.h"
65dfe64dd3Smacallan#endif
66dfe64dd3Smacallan
67dfe64dd3Smacallan#include "init.h"
68dfe64dd3Smacallan#include "vgatypes.h"
69dfe64dd3Smacallan#include "vb_def.h"
70dfe64dd3Smacallan#include "vb_setmode.h"
71dfe64dd3Smacallan
72dfe64dd3Smacallan/*********************************************/
73dfe64dd3Smacallan/*            HELPER: Get ModeID             */
74dfe64dd3Smacallan/*********************************************/
75dfe64dd3Smacallan/* Jong 09/18/2007; patch to GIT */
76dfe64dd3Smacallan/* VGAEngine is not used; FSTN is always FALSE */
77dfe64dd3SmacallanUSHORT
78dfe64dd3SmacallanXGI_GetModeID(ULONG VBFlags, int HDisplay, int VDisplay,
79dfe64dd3Smacallan              int Depth, int LCDwidth, int LCDheight)
80dfe64dd3Smacallan{
81dfe64dd3Smacallan   USHORT ModeIndex = 0;
82dfe64dd3Smacallan
83dfe64dd3Smacallan   switch(HDisplay)
84dfe64dd3Smacallan   {
85dfe64dd3Smacallan     case 320:
86dfe64dd3Smacallan       if(VDisplay == 200)
87dfe64dd3Smacallan	   ModeIndex = ModeIndex_320x200[Depth];
88dfe64dd3Smacallan       else if(VDisplay == 240)
89dfe64dd3Smacallan	   {
90dfe64dd3Smacallan	     ModeIndex = ModeIndex_320x240[Depth];
91dfe64dd3Smacallan       }
92dfe64dd3Smacallan       break;
93dfe64dd3Smacallan     case 400:
94dfe64dd3Smacallan          if(VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth];
95dfe64dd3Smacallan          break;
96dfe64dd3Smacallan     case 512:
97dfe64dd3Smacallan          if(VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth];
98dfe64dd3Smacallan          break;
99dfe64dd3Smacallan     case 640:
100dfe64dd3Smacallan          if(VDisplay == 480)      ModeIndex = ModeIndex_640x480[Depth];
101dfe64dd3Smacallan	  else if(VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth];
102dfe64dd3Smacallan          break;
103dfe64dd3Smacallan     case 720:
104dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
105dfe64dd3Smacallan             if(VDisplay == 480)      ModeIndex = ModeIndex_720x480[Depth];
106dfe64dd3Smacallan             else if(VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth];
107dfe64dd3Smacallan          }
108dfe64dd3Smacallan          break;
109dfe64dd3Smacallan     case 768:
110dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
111dfe64dd3Smacallan             if(VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth];
112dfe64dd3Smacallan          }
113dfe64dd3Smacallan	  break;
114dfe64dd3Smacallan     case 800:
115dfe64dd3Smacallan	  if(VDisplay == 600)    ModeIndex = ModeIndex_800x600[Depth];
116dfe64dd3Smacallan	  else if(!(VBFlags & CRT1_LCDA)) {
117dfe64dd3Smacallan	     if(VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth];
118dfe64dd3Smacallan	  }
119dfe64dd3Smacallan          break;
120dfe64dd3Smacallan     case 848:
121dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
122dfe64dd3Smacallan	     if(VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth];
123dfe64dd3Smacallan	  }
124dfe64dd3Smacallan	  break;
125dfe64dd3Smacallan     case 856:
126dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
127dfe64dd3Smacallan	     if(VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth];
128dfe64dd3Smacallan	  }
129dfe64dd3Smacallan	  break;
130dfe64dd3Smacallan     case 1024:
131dfe64dd3Smacallan          if(VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth];
132dfe64dd3Smacallan	  else if(!(VBFlags & CRT1_LCDA)) {
133dfe64dd3Smacallan	     if(VDisplay == 576)    ModeIndex = ModeIndex_1024x576[Depth];
134dfe64dd3Smacallan	  }
135dfe64dd3Smacallan          break;
136dfe64dd3Smacallan     case 1152:
137dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
138dfe64dd3Smacallan             if(VDisplay == 864)    ModeIndex = ModeIndex_1152x864[Depth];
139dfe64dd3Smacallan	  }
140dfe64dd3Smacallan	  break;
141dfe64dd3Smacallan     case 1280:
142dfe64dd3Smacallan          if(VDisplay == 1024) ModeIndex = ModeIndex_1280x1024[Depth];
143dfe64dd3Smacallan	  else if(VDisplay == 720) {
144dfe64dd3Smacallan	     if((VBFlags & CRT1_LCDA) && (LCDwidth == 1280) && (LCDheight == 720)) {
145dfe64dd3Smacallan	        ModeIndex = ModeIndex_1280x720[Depth];
146dfe64dd3Smacallan	     } else if(!(VBFlags & CRT1_LCDA)) {
147dfe64dd3Smacallan	        ModeIndex = ModeIndex_1280x720[Depth];
148dfe64dd3Smacallan	     }
149dfe64dd3Smacallan	  } else if(!(VBFlags & CRT1_LCDA)) {
150dfe64dd3Smacallan             if(VDisplay == 960)      ModeIndex = ModeIndex_1280x960[Depth];
151dfe64dd3Smacallan	     else if(VDisplay == 768) {
152dfe64dd3Smacallan	           ModeIndex = ModeIndex_310_1280x768[Depth];
153dfe64dd3Smacallan	     }
154dfe64dd3Smacallan	  }
155dfe64dd3Smacallan          break;
156dfe64dd3Smacallan     case 1360:
157dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
158dfe64dd3Smacallan	     if(VDisplay == 768)     ModeIndex = ModeIndex_1360x768[Depth];
159dfe64dd3Smacallan	  }
160dfe64dd3Smacallan          break;
161dfe64dd3Smacallan     case 1400:
162dfe64dd3Smacallan          break;
163dfe64dd3Smacallan     case 1440:
164dfe64dd3Smacallan          /* if(VDisplay == 900) ModeIndex = ModeIndex_1440x900[Depth]; */
165dfe64dd3Smacallan          break;
166dfe64dd3Smacallan     case 1600:
167dfe64dd3Smacallan          if(VDisplay == 1200) ModeIndex = ModeIndex_1600x1200[Depth];
168dfe64dd3Smacallan          break;
169dfe64dd3Smacallan     case 1680:
170dfe64dd3Smacallan          break;
171dfe64dd3Smacallan     case 1920:
172dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
173dfe64dd3Smacallan             if(VDisplay == 1440) ModeIndex = ModeIndex_1920x1440[Depth];
174dfe64dd3Smacallan	  }
175dfe64dd3Smacallan          break;
176dfe64dd3Smacallan     case 2048:
177dfe64dd3Smacallan          if(!(VBFlags & CRT1_LCDA)) {
178dfe64dd3Smacallan             if(VDisplay == 1536) {
179dfe64dd3Smacallan	            ModeIndex = ModeIndex_310_2048x1536[Depth];
180dfe64dd3Smacallan	     }
181dfe64dd3Smacallan	  }
182dfe64dd3Smacallan          break;
183dfe64dd3Smacallan   }
184dfe64dd3Smacallan
185dfe64dd3Smacallan   return(ModeIndex);
186dfe64dd3Smacallan}
187dfe64dd3Smacallan
188dfe64dd3Smacallan/*********************************************/
189dfe64dd3Smacallan/*          HELPER: SetReg, GetReg           */
190dfe64dd3Smacallan/*********************************************/
191dfe64dd3Smacallan
192dfe64dd3Smacallanvoid
193dfe64dd3SmacallanXGI_SetReg(XGIIOADDRESS port, USHORT index, USHORT data)
194dfe64dd3Smacallan{
195dfe64dd3Smacallan   outb(port,index);
196dfe64dd3Smacallan   outb(port + 1,data);
197dfe64dd3Smacallan}
198dfe64dd3Smacallan
199dfe64dd3Smacallanvoid
200dfe64dd3SmacallanXGI_SetRegByte(XGIIOADDRESS port, USHORT data)
201dfe64dd3Smacallan{
202dfe64dd3Smacallan   outb(port,data);
203dfe64dd3Smacallan}
204dfe64dd3Smacallan
205dfe64dd3Smacallanvoid
206dfe64dd3SmacallanXGI_SetRegShort(XGIIOADDRESS port, USHORT data)
207dfe64dd3Smacallan{
208dfe64dd3Smacallan   outw(port,data);
209dfe64dd3Smacallan}
210dfe64dd3Smacallan
211dfe64dd3Smacallanvoid
212dfe64dd3SmacallanXGI_SetRegLong(XGIIOADDRESS port, ULONG data)
213dfe64dd3Smacallan{
214dfe64dd3Smacallan    outl(port,data);
215dfe64dd3Smacallan}
216dfe64dd3Smacallan
217dfe64dd3SmacallanUCHAR
218dfe64dd3SmacallanXGI_GetReg(XGIIOADDRESS port, USHORT index)
219dfe64dd3Smacallan{
220dfe64dd3Smacallan   outb(port,index);
221dfe64dd3Smacallan   return inb(port + 1);
222dfe64dd3Smacallan}
223dfe64dd3Smacallan
224dfe64dd3SmacallanUCHAR
225dfe64dd3SmacallanXGI_GetRegByte(XGIIOADDRESS port)
226dfe64dd3Smacallan{
227dfe64dd3Smacallan   return inb(port);
228dfe64dd3Smacallan}
229dfe64dd3Smacallan
230dfe64dd3SmacallanUSHORT
231dfe64dd3SmacallanXGI_GetRegShort(XGIIOADDRESS port)
232dfe64dd3Smacallan{
233dfe64dd3Smacallan   return inw(port);
234dfe64dd3Smacallan}
235dfe64dd3Smacallan
236dfe64dd3SmacallanULONG
237dfe64dd3SmacallanXGI_GetRegLong(XGIIOADDRESS port)
238dfe64dd3Smacallan{
239dfe64dd3Smacallan   return inl(port);
240dfe64dd3Smacallan}
241dfe64dd3Smacallan
242dfe64dd3Smacallanvoid
243dfe64dd3SmacallanXGI_SetRegANDOR(XGIIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
244dfe64dd3Smacallan{
245dfe64dd3Smacallan  USHORT temp;
246dfe64dd3Smacallan
247dfe64dd3Smacallan  temp = XGI_GetReg(Port,Index);
248dfe64dd3Smacallan  temp = (temp & (DataAND)) | DataOR;
249dfe64dd3Smacallan  XGI_SetReg(Port,Index,temp);
250dfe64dd3Smacallan}
251dfe64dd3Smacallan
252dfe64dd3Smacallanvoid
253dfe64dd3SmacallanXGI_SetRegAND(XGIIOADDRESS Port,USHORT Index,USHORT DataAND)
254dfe64dd3Smacallan{
255dfe64dd3Smacallan  USHORT temp;
256dfe64dd3Smacallan
257dfe64dd3Smacallan  temp = XGI_GetReg(Port,Index);
258dfe64dd3Smacallan  temp &= DataAND;
259dfe64dd3Smacallan  XGI_SetReg(Port,Index,temp);
260dfe64dd3Smacallan}
261dfe64dd3Smacallan
262dfe64dd3Smacallanvoid
263dfe64dd3SmacallanXGI_SetRegOR(XGIIOADDRESS Port,USHORT Index,USHORT DataOR)
264dfe64dd3Smacallan{
265dfe64dd3Smacallan  USHORT temp;
266dfe64dd3Smacallan
267dfe64dd3Smacallan  temp = XGI_GetReg(Port,Index);
268dfe64dd3Smacallan  temp |= DataOR;
269dfe64dd3Smacallan  XGI_SetReg(Port,Index,temp);
270dfe64dd3Smacallan}
271dfe64dd3Smacallan
272dfe64dd3Smacallan/*********************************************/
273dfe64dd3Smacallan/*      HELPER: DisplayOn, DisplayOff        */
274dfe64dd3Smacallan/*********************************************/
275dfe64dd3Smacallan
276dfe64dd3Smacallanvoid
277dfe64dd3SmacallanXGI_New_DisplayOn(VB_DEVICE_INFO *XGI_Pr)
278dfe64dd3Smacallan{
279dfe64dd3Smacallan   XGI_SetRegAND(XGI_Pr->P3c4,0x01,0xDF);
280dfe64dd3Smacallan}
281dfe64dd3Smacallan
282dfe64dd3Smacallanvoid
283dfe64dd3SmacallanXGI_New_DisplayOff(VB_DEVICE_INFO *XGI_Pr)
284dfe64dd3Smacallan{
285dfe64dd3Smacallan   XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x20);
286dfe64dd3Smacallan}
287dfe64dd3Smacallan
288dfe64dd3Smacallan/*********************************************/
289dfe64dd3Smacallan/*         HELPER: Init PCI & Engines        */
290dfe64dd3Smacallan/*********************************************/
291dfe64dd3Smacallan
292dfe64dd3Smacallanstatic void
293dfe64dd3SmacallanXGIInitPCIetc(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
294dfe64dd3Smacallan{
295dfe64dd3Smacallan   CARD8  bForce=0x00; /* Jong 01/07/2008; force to disable 2D */
296dfe64dd3Smacallan
297dfe64dd3Smacallan   switch(HwInfo->jChipType) {
298dfe64dd3Smacallan   case XG40:
299dfe64dd3Smacallan   case XG42:
300dfe64dd3Smacallan   case XG20:
301dfe64dd3Smacallan   case XG21:
302dfe64dd3Smacallan      XGI_SetReg(XGI_Pr->P3c4,0x20,0xa1);
303dfe64dd3Smacallan      /*  - Enable 2D (0x40)
304dfe64dd3Smacallan       *  - Enable 3D (0x02)
305dfe64dd3Smacallan       *  - Enable 3D vertex command fetch (0x10)
306dfe64dd3Smacallan       *  - Enable 3D command parser (0x08)
307dfe64dd3Smacallan       *  - Enable 3D G/L transformation engine (0x80)
308dfe64dd3Smacallan       */
309dfe64dd3Smacallan      XGI_SetRegOR(XGI_Pr->P3c4, 0x1E,
310dfe64dd3Smacallan		   SR1E_ENABLE_3D_TRANSFORM_ENGINE
311dfe64dd3Smacallan		   | SR1E_ENABLE_2D
312dfe64dd3Smacallan		   | SR1E_ENABLE_3D_AGP_VERTEX_FETCH
313dfe64dd3Smacallan		   | SR1E_ENABLE_3D_COMMAND_PARSER
314dfe64dd3Smacallan		   | SR1E_ENABLE_3D);
315dfe64dd3Smacallan
316dfe64dd3Smacallan	  /* Jong 01/07/2008; support forcing to disable 2D engine */
317dfe64dd3Smacallan	  if(HwInfo->jChipType == XG21)
318dfe64dd3Smacallan	  {
319dfe64dd3Smacallan  			inXGIIDXREG(XGI_Pr->P3c4, 0x3A, bForce) ;
320dfe64dd3Smacallan			bForce &= 0x40;
321dfe64dd3Smacallan
322dfe64dd3Smacallan			if(bForce != 0x00)
323dfe64dd3Smacallan			  XGI_SetRegAND(XGI_Pr->P3c4,0x1E,0xBF);
324dfe64dd3Smacallan	  }
325dfe64dd3Smacallan
326dfe64dd3Smacallan	  break;
327dfe64dd3Smacallan   }
328dfe64dd3Smacallan}
329dfe64dd3Smacallan
330dfe64dd3Smacallan/*********************************************/
331dfe64dd3Smacallan/*             HELPER: GetVBType             */
332dfe64dd3Smacallan/*********************************************/
333dfe64dd3Smacallan
334dfe64dd3Smacallanvoid
335dfe64dd3SmacallanXGI_New_GetVBType(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
336dfe64dd3Smacallan{
337dfe64dd3Smacallan  USHORT flag=0, rev=0, nolcd=0;
338dfe64dd3Smacallan
339dfe64dd3Smacallan  XGI_Pr->VBType = 0;
340dfe64dd3Smacallan
341dfe64dd3Smacallan  flag = XGI_GetReg(XGI_Pr->Part4Port,0x00);
342dfe64dd3SmacallanPDEBUG(ErrorF("GetVBType: part4_0: %x \n",flag)); //yilin
343dfe64dd3Smacallan  if(flag > 3) return;
344dfe64dd3Smacallan
345dfe64dd3Smacallan  rev = XGI_GetReg(XGI_Pr->Part4Port,0x01);
346dfe64dd3SmacallanPDEBUG(ErrorF("GetVBType: part4_1: %x \n",rev)); //yilin
347dfe64dd3Smacallan
348dfe64dd3Smacallan  if(flag >= 2) {
349dfe64dd3Smacallan     XGI_Pr->VBType = VB_XGI302B;
350dfe64dd3Smacallan  } else if(flag == 1) {
351dfe64dd3Smacallan     if(rev >= 0xC0) {
352dfe64dd3Smacallan       	XGI_Pr->VBType = VB_XGI301C;
353dfe64dd3Smacallan     } else if(rev >= 0xB0) {
354dfe64dd3Smacallan       	XGI_Pr->VBType = VB_XGI301B;
355dfe64dd3Smacallan	/* Check if 30xB DH version (no LCD support, use Panel Link instead) */
356dfe64dd3Smacallan    	nolcd = XGI_GetReg(XGI_Pr->Part4Port,0x23);
357dfe64dd3Smacallan        if(!(nolcd & 0x02)) XGI_Pr->VBType |= VB_NoLCD;
358dfe64dd3Smacallan     } else {
359dfe64dd3Smacallan        XGI_Pr->VBType = VB_XGI301;
360dfe64dd3Smacallan     }
361dfe64dd3Smacallan  }
362dfe64dd3Smacallan  if(XGI_Pr->VBType & (VB_XGI301B | VB_XGI301C | VB_XGI302B)) {
363dfe64dd3Smacallan     if(rev >= 0xE0) {
364dfe64dd3Smacallan	flag = XGI_GetReg(XGI_Pr->Part4Port,0x39);
365dfe64dd3Smacallan	if(flag == 0xff) XGI_Pr->VBType = VB_XGI302LV;
366dfe64dd3Smacallan	else 	 	 XGI_Pr->VBType = VB_XGI302ELV;
367dfe64dd3Smacallan     } else if(rev >= 0xD0) {
368dfe64dd3Smacallan	XGI_Pr->VBType = VB_XGI301LV;
369dfe64dd3Smacallan     }
370dfe64dd3Smacallan  }
371dfe64dd3SmacallanPDEBUG(ErrorF("GetVBType: XGI_Pr->VBType=%x \n",XGI_Pr->VBType)); //yilin
372dfe64dd3Smacallan}
373dfe64dd3Smacallan
374dfe64dd3Smacallan/*********************************************/
375dfe64dd3Smacallan/*           HELPER: SearchModeID            */
376dfe64dd3Smacallan/*********************************************/
377dfe64dd3Smacallan
378dfe64dd3SmacallanBOOLEAN
379dfe64dd3SmacallanXGI_SearchModeID(const XGI_StStruct *SModeIDTable,
380dfe64dd3Smacallan		 const XGI_ExtStruct *EModeIDTable,
381dfe64dd3Smacallan		 unsigned char VGAINFO, USHORT *ModeNo, USHORT *ModeIdIndex)
382dfe64dd3Smacallan{
383dfe64dd3Smacallan    if (*ModeNo <= 0x13) {
384dfe64dd3Smacallan	if ((*ModeNo) <= 0x05)
385dfe64dd3Smacallan	    (*ModeNo) |= 0x01;
386dfe64dd3Smacallan
387dfe64dd3Smacallan	for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
388dfe64dd3Smacallan	    if (SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo))
389dfe64dd3Smacallan		break;
390dfe64dd3Smacallan
391dfe64dd3Smacallan	    if (SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
392dfe64dd3Smacallan		return FALSE;
393dfe64dd3Smacallan	}
394dfe64dd3Smacallan
395dfe64dd3Smacallan	if (*ModeNo == 0x07) {
396dfe64dd3Smacallan	    if (VGAINFO & 0x10)
397dfe64dd3Smacallan		(*ModeIdIndex)++;   /* 400 lines */
398dfe64dd3Smacallan	    /* else 350 lines */
399dfe64dd3Smacallan	}
400dfe64dd3Smacallan
401dfe64dd3Smacallan	if (*ModeNo <= 0x03) {
402dfe64dd3Smacallan	    if (!(VGAINFO & 0x80))
403dfe64dd3Smacallan		(*ModeIdIndex)++;
404dfe64dd3Smacallan
405dfe64dd3Smacallan	    if (VGAINFO & 0x10)
406dfe64dd3Smacallan		(*ModeIdIndex)++; /* 400 lines  */
407dfe64dd3Smacallan	    /* else 350 lines  */
408dfe64dd3Smacallan	}
409dfe64dd3Smacallan	/* else 200 lines  */
410dfe64dd3Smacallan    }
411dfe64dd3Smacallan    else {
412dfe64dd3Smacallan
413dfe64dd3Smacallan	for (*ModeIdIndex = 0; /* emtpy */; (*ModeIdIndex)++) {
414dfe64dd3Smacallan	    if (EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo))
415dfe64dd3Smacallan		break;
416dfe64dd3Smacallan
417dfe64dd3Smacallan	    if (EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
418dfe64dd3Smacallan		return FALSE;
419dfe64dd3Smacallan	}
420dfe64dd3Smacallan    }
421dfe64dd3Smacallan
422dfe64dd3Smacallan    return TRUE;
423dfe64dd3Smacallan}
424dfe64dd3Smacallan
425dfe64dd3Smacallan/*********************************************/
426dfe64dd3Smacallan/*            HELPER: GetModePtr             */
427dfe64dd3Smacallan/*********************************************/
428dfe64dd3Smacallan
429dfe64dd3SmacallanUCHAR
430dfe64dd3SmacallanXGI_GetModePtr(const XGI_StStruct *SModeIDTable, unsigned ModeType,
431dfe64dd3Smacallan	       USHORT ModeNo, USHORT ModeIdIndex)
432dfe64dd3Smacallan{
433dfe64dd3Smacallan    return (ModeNo <= 0x13)
434dfe64dd3Smacallan	? SModeIDTable[ModeIdIndex].St_StTableIndex
435dfe64dd3Smacallan	: ((ModeType <= 0x02) ? 0x1B /* 02 -> ModeEGA  */ : 0x0F);
436dfe64dd3Smacallan}
437dfe64dd3Smacallan
438dfe64dd3Smacallan
439dfe64dd3Smacallan/*********************************************/
440dfe64dd3Smacallan/*           HELPER: LowModeTests            */
441dfe64dd3Smacallan/*********************************************/
442dfe64dd3Smacallan
443dfe64dd3Smacallanstatic BOOLEAN
444dfe64dd3SmacallanXGI_DoLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
445dfe64dd3Smacallan{
446dfe64dd3Smacallan    USHORT temp,temp1,temp2;
447dfe64dd3Smacallan
448dfe64dd3Smacallan    if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
449dfe64dd3Smacallan       return(1);
450dfe64dd3Smacallan    temp = XGI_GetReg(XGI_Pr->P3d4,0x11);
451dfe64dd3Smacallan    XGI_SetRegOR(XGI_Pr->P3d4,0x11,0x80);
452dfe64dd3Smacallan    temp1 = XGI_GetReg(XGI_Pr->P3d4,0x00);
453dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3d4,0x00,0x55);
454dfe64dd3Smacallan    temp2 = XGI_GetReg(XGI_Pr->P3d4,0x00);
455dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3d4,0x00,temp1);
456dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3d4,0x11,temp);
457dfe64dd3Smacallan    if (temp2 == 0x55)
458dfe64dd3Smacallan	return(0);
459dfe64dd3Smacallan    else
460dfe64dd3Smacallan	return(1);
461dfe64dd3Smacallan}
462dfe64dd3Smacallan
463dfe64dd3Smacallanstatic void
464dfe64dd3SmacallanXGI_SetLowModeTest(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, PXGI_HW_DEVICE_INFO HwInfo)
465dfe64dd3Smacallan{
466dfe64dd3Smacallan    if(XGI_DoLowModeTest(XGI_Pr, ModeNo, HwInfo)) {
467dfe64dd3Smacallan       XGI_Pr->SetFlag |= LowModeTests;
468dfe64dd3Smacallan    }
469dfe64dd3Smacallan}
470dfe64dd3Smacallan
471dfe64dd3Smacallanstatic void
472dfe64dd3SmacallanXGI_HandleCRT1(VB_DEVICE_INFO *XGI_Pr)
473dfe64dd3Smacallan{
474dfe64dd3Smacallan    XGI_SetRegAND(XGI_Pr->P3d4, 0x53, 0xbf);
475dfe64dd3Smacallan}
476dfe64dd3Smacallan
477dfe64dd3Smacallan/*********************************************/
478dfe64dd3Smacallan/*             HELPER: GetOffset             */
479dfe64dd3Smacallan/*********************************************/
480dfe64dd3Smacallan
481dfe64dd3SmacallanUSHORT
482dfe64dd3SmacallanXGI_New_GetOffset(VB_DEVICE_INFO *XGI_Pr,USHORT ModeNo,USHORT ModeIdIndex,
483dfe64dd3Smacallan              USHORT RefreshRateTableIndex,PXGI_HW_DEVICE_INFO HwInfo)
484dfe64dd3Smacallan{
485dfe64dd3Smacallan  USHORT xres, temp, colordepth, infoflag;
486dfe64dd3Smacallan
487dfe64dd3Smacallan  infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
488dfe64dd3Smacallan  xres = XGI_Pr->RefIndex[RefreshRateTableIndex].XRes;
489dfe64dd3Smacallan
490dfe64dd3Smacallan  colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex, XGI_Pr);
491dfe64dd3Smacallan
492dfe64dd3Smacallan  temp = xres / 16;
493dfe64dd3Smacallan  if(infoflag & InterlaceMode) temp <<= 1;
494dfe64dd3Smacallan  temp *= colordepth;
495dfe64dd3Smacallan  if(xres % 16) {
496dfe64dd3Smacallan     colordepth >>= 1;
497dfe64dd3Smacallan     temp += colordepth;
498dfe64dd3Smacallan  }
499dfe64dd3Smacallan
500dfe64dd3Smacallan  return(temp);
501dfe64dd3Smacallan}
502dfe64dd3Smacallan
503dfe64dd3Smacallan/*********************************************/
504dfe64dd3Smacallan/*                 RESET VCLK                */
505dfe64dd3Smacallan/*********************************************/
506dfe64dd3Smacallan
507dfe64dd3Smacallanstatic void
508dfe64dd3SmacallanXGI_ResetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo)
509dfe64dd3Smacallan{
510dfe64dd3Smacallan    XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xCF,0x20);
511dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[1].SR2B);
512dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[1].SR2C);
513dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
514dfe64dd3Smacallan    XGI_SetRegANDOR(XGI_Pr->P3c4,0x31,0xcf,0x10);
515dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2B,XGI_Pr->VCLKData[0].SR2B);
516dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2C,XGI_Pr->VCLKData[0].SR2C);
517dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2D,0x80);
518dfe64dd3Smacallan}
519dfe64dd3Smacallan
520dfe64dd3Smacallan/*********************************************/
521dfe64dd3Smacallan/*                  CRTC/2                   */
522dfe64dd3Smacallan/*********************************************/
523dfe64dd3Smacallan
524dfe64dd3Smacallanstatic void
525dfe64dd3SmacallanXGI_New_SetCRT1CRTC(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
526dfe64dd3Smacallan                USHORT RefreshRateTableIndex,
527dfe64dd3Smacallan		PXGI_HW_DEVICE_INFO HwInfo)
528dfe64dd3Smacallan{
529dfe64dd3Smacallan  UCHAR  index;
530dfe64dd3Smacallan  USHORT temp,i,j,modeflag;
531dfe64dd3Smacallan
532dfe64dd3Smacallan  XGI_SetRegAND(XGI_Pr->P3d4,0x11,0x7f);		/* unlock cr0-7 */
533dfe64dd3Smacallan
534dfe64dd3Smacallan     if(ModeNo <= 0x13) {
535dfe64dd3Smacallan        modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
536dfe64dd3Smacallan     } else {
537dfe64dd3Smacallan        modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
538dfe64dd3Smacallan     }
539dfe64dd3Smacallan
540dfe64dd3Smacallan     index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
541dfe64dd3Smacallan
542dfe64dd3Smacallan     for(i=0,j=0;i<=7;i++,j++) {
543dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
544dfe64dd3Smacallan     }
545dfe64dd3Smacallan     for(j=0x10;i<=10;i++,j++) {
546dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
547dfe64dd3Smacallan     }
548dfe64dd3Smacallan     for(j=0x15;i<=12;i++,j++) {
549dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->P3d4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
550dfe64dd3Smacallan     }
551dfe64dd3Smacallan     for(j=0x0A;i<=15;i++,j++) {
552dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->P3c4,j,XGI_Pr->XGINEWUB_CRT1Table[index].CR[i]);
553dfe64dd3Smacallan     }
554dfe64dd3Smacallan
555dfe64dd3Smacallan     temp = XGI_Pr->XGINEWUB_CRT1Table[index].CR[16] & 0xE0;
556dfe64dd3Smacallan     XGI_SetReg(XGI_Pr->P3c4,0x0E,temp);
557dfe64dd3Smacallan
558dfe64dd3Smacallan     temp = ((XGI_Pr->XGINEWUB_CRT1Table[index].CR[16]) & 0x01) << 5;
559dfe64dd3Smacallan     if(modeflag & DoubleScanMode)  temp |= 0x80;
560dfe64dd3Smacallan     XGI_SetRegANDOR(XGI_Pr->P3d4,0x09,0x5F,temp);
561dfe64dd3Smacallan
562dfe64dd3Smacallan  if(XGI_Pr->ModeType > ModeVGA) XGI_SetReg(XGI_Pr->P3d4,0x14,0x4F);
563dfe64dd3Smacallan}
564dfe64dd3Smacallan
565dfe64dd3Smacallan/*********************************************/
566dfe64dd3Smacallan/*               OFFSET & PITCH              */
567dfe64dd3Smacallan/*********************************************/
568dfe64dd3Smacallan/*  (partly overruled by SetPitch() in XF86) */
569dfe64dd3Smacallan/*********************************************/
570dfe64dd3Smacallan
571dfe64dd3Smacallanstatic void
572dfe64dd3SmacallanXGI_New_SetCRT1Offset(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
573dfe64dd3Smacallan                  USHORT RefreshRateTableIndex,
574dfe64dd3Smacallan		  PXGI_HW_DEVICE_INFO HwInfo)
575dfe64dd3Smacallan{
576dfe64dd3Smacallan   USHORT temp, DisplayUnit, infoflag;
577dfe64dd3Smacallan
578dfe64dd3Smacallan   infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
579dfe64dd3Smacallan
580dfe64dd3Smacallan   DisplayUnit = XGI_New_GetOffset(XGI_Pr,ModeNo,ModeIdIndex,
581dfe64dd3Smacallan                     	       RefreshRateTableIndex,HwInfo);
582dfe64dd3Smacallan
583dfe64dd3Smacallan   temp = (DisplayUnit >> 8) & 0x0f;
584dfe64dd3Smacallan   XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,temp);
585dfe64dd3Smacallan
586dfe64dd3Smacallan   temp = DisplayUnit & 0xFF;
587dfe64dd3Smacallan   XGI_SetReg(XGI_Pr->P3d4,0x13,temp);
588dfe64dd3Smacallan
589dfe64dd3Smacallan   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
590dfe64dd3Smacallan
591dfe64dd3Smacallan   DisplayUnit <<= 5;
592dfe64dd3Smacallan   temp = (DisplayUnit & 0xff00) >> 8;
593dfe64dd3Smacallan   if(DisplayUnit & 0xff) temp++;
594dfe64dd3Smacallan   temp++;
595dfe64dd3Smacallan   XGI_SetReg(XGI_Pr->P3c4,0x10,temp);
596dfe64dd3Smacallan}
597dfe64dd3Smacallan
598dfe64dd3Smacallan/*********************************************/
599dfe64dd3Smacallan/*                  VCLK                     */
600dfe64dd3Smacallan/*********************************************/
601dfe64dd3Smacallan
602dfe64dd3Smacallanstatic void
603dfe64dd3SmacallanXGI_New_SetCRT1VCLK(VB_DEVICE_INFO *XGI_Pr, USHORT ModeNo, USHORT ModeIdIndex,
604dfe64dd3Smacallan                PXGI_HW_DEVICE_INFO HwInfo, USHORT RefreshRateTableIndex)
605dfe64dd3Smacallan{
606dfe64dd3Smacallan  USHORT  index=0, clka, clkb;
607dfe64dd3Smacallan
608dfe64dd3Smacallan     if((XGI_Pr->VBType & VB_XGI301BLV302BLV) && (XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
609dfe64dd3Smacallan        clka = XGI_Pr->VBVCLKData[index].Part4_A;
610dfe64dd3Smacallan	clkb = XGI_Pr->VBVCLKData[index].Part4_B;
611dfe64dd3Smacallan     } else {
612dfe64dd3Smacallan        clka = XGI_Pr->VCLKData[index].SR2B;
613dfe64dd3Smacallan	clkb = XGI_Pr->VCLKData[index].SR2C;
614dfe64dd3Smacallan     }
615dfe64dd3Smacallan
616dfe64dd3Smacallan    XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xCF);
617dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2B,clka);
618dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2C,clkb);
619dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3c4,0x2D,0x01);
620dfe64dd3Smacallan}
621dfe64dd3Smacallan
622dfe64dd3Smacallan/*********************************************/
623dfe64dd3Smacallan/*              MODE REGISTERS               */
624dfe64dd3Smacallan/*********************************************/
625dfe64dd3Smacallan
626dfe64dd3Smacallanstatic void
627dfe64dd3SmacallanXGI_New_SetVCLKState(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
628dfe64dd3Smacallan                 USHORT ModeNo, USHORT RefreshRateTableIndex,
629dfe64dd3Smacallan                 USHORT ModeIdIndex)
630dfe64dd3Smacallan{
631dfe64dd3Smacallan  USHORT data=0, VCLK=0, index=0;
632dfe64dd3Smacallan
633dfe64dd3Smacallan  if(ModeNo > 0x13) {
634dfe64dd3Smacallan        VCLK = XGI_Pr->VCLKData[index].CLOCK;
635dfe64dd3Smacallan  }
636dfe64dd3Smacallan
637dfe64dd3Smacallan    if(VCLK >= 166)
638dfe64dd3Smacallan	data |= 0x0c;
639dfe64dd3Smacallan
640dfe64dd3Smacallan    XGI_SetRegANDOR(XGI_Pr->P3c4,0x32,0xf3,data);
641dfe64dd3Smacallan
642dfe64dd3Smacallan    if(VCLK >= 166) {
643dfe64dd3Smacallan	XGI_SetRegAND(XGI_Pr->P3c4,0x1f,0xe7);
644dfe64dd3Smacallan    }
645dfe64dd3Smacallan
646dfe64dd3Smacallan    /* DAC speed */
647dfe64dd3Smacallan    XGI_SetRegANDOR(XGI_Pr->P3c4,0x07,0xE8,0x10);
648dfe64dd3Smacallan}
649dfe64dd3Smacallan
650dfe64dd3Smacallanstatic void
651dfe64dd3SmacallanXGI_New_SetCRT1ModeRegs(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
652dfe64dd3Smacallan                    USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
653dfe64dd3Smacallan{
654dfe64dd3Smacallan  USHORT data,infoflag=0,modeflag;
655dfe64dd3Smacallan  USHORT resindex = 0,xres;
656dfe64dd3Smacallan
657dfe64dd3Smacallan     if(ModeNo > 0x13) {
658dfe64dd3Smacallan    	modeflag = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
659dfe64dd3Smacallan    	infoflag = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
660dfe64dd3Smacallan	xres = XGI_Pr->ModeResInfo[resindex].HTotal;
661dfe64dd3Smacallan     } else {
662dfe64dd3Smacallan    	modeflag = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
663dfe64dd3Smacallan	xres = XGI_Pr->StResInfo[resindex].HTotal;
664dfe64dd3Smacallan     }
665dfe64dd3Smacallan
666dfe64dd3Smacallan  /* Disable DPMS */
667dfe64dd3Smacallan  XGI_SetRegAND(XGI_Pr->P3c4,0x1F,0x3F);
668dfe64dd3Smacallan
669dfe64dd3Smacallan  data = 0;
670dfe64dd3Smacallan  if(ModeNo > 0x13) {
671dfe64dd3Smacallan     if(XGI_Pr->ModeType > 0x02) {
672dfe64dd3Smacallan        data |= 0x02;
673dfe64dd3Smacallan        data |= ((XGI_Pr->ModeType - ModeVGA) << 2);
674dfe64dd3Smacallan     }
675dfe64dd3Smacallan     if(infoflag & InterlaceMode) data |= 0x20;
676dfe64dd3Smacallan  }
677dfe64dd3Smacallan  XGI_SetRegANDOR(XGI_Pr->P3c4,0x06,0xC0,data);
678dfe64dd3Smacallan
679dfe64dd3Smacallan    data = 0;
680dfe64dd3Smacallan    if(infoflag & InterlaceMode) {
681dfe64dd3Smacallan        if(xres <= 800)       data = 0x0020;
682dfe64dd3Smacallan        else if(xres <= 1024) data = 0x0035;
683dfe64dd3Smacallan        else                  data = 0x0048;
684dfe64dd3Smacallan    }
685dfe64dd3Smacallan    XGI_SetReg(XGI_Pr->P3d4,0x19,(data & 0xFF));
686dfe64dd3Smacallan    XGI_SetRegANDOR(XGI_Pr->P3d4,0x1a,0xFC,(data >> 8));
687dfe64dd3Smacallan
688dfe64dd3Smacallan  if(modeflag & HalfDCLK) {
689dfe64dd3Smacallan     XGI_SetRegOR(XGI_Pr->P3c4,0x01,0x08);
690dfe64dd3Smacallan  }
691dfe64dd3Smacallan
692dfe64dd3Smacallan  data = 0;
693dfe64dd3Smacallan  if(modeflag & LineCompareOff) data = 0x08;
694dfe64dd3Smacallan
695dfe64dd3Smacallan     XGI_SetRegANDOR(XGI_Pr->P3c4,0x0F,0xB7,data);
696dfe64dd3Smacallan     if(XGI_Pr->ModeType == ModeEGA) {
697dfe64dd3Smacallan        if(ModeNo > 0x13) {
698dfe64dd3Smacallan  	   XGI_SetRegOR(XGI_Pr->P3c4,0x0F,0x40);
699dfe64dd3Smacallan        }
700dfe64dd3Smacallan     }
701dfe64dd3Smacallan
702dfe64dd3Smacallan    XGI_SetRegAND(XGI_Pr->P3c4,0x31,0xfb);
703dfe64dd3Smacallan
704dfe64dd3Smacallan  data = 0x60;
705dfe64dd3Smacallan  if(XGI_Pr->ModeType != ModeText) {
706dfe64dd3Smacallan     data ^= 0x60;
707dfe64dd3Smacallan     if(XGI_Pr->ModeType != ModeEGA) {
708dfe64dd3Smacallan        data ^= 0xA0;
709dfe64dd3Smacallan     }
710dfe64dd3Smacallan  }
711dfe64dd3Smacallan  XGI_SetRegANDOR(XGI_Pr->P3c4,0x21,0x1F,data);
712dfe64dd3Smacallan
713dfe64dd3Smacallan  XGI_New_SetVCLKState(XGI_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
714dfe64dd3Smacallan}
715dfe64dd3Smacallan
716dfe64dd3Smacallan/*********************************************/
717dfe64dd3Smacallan/*                 LOAD DAC                  */
718dfe64dd3Smacallan/*********************************************/
719dfe64dd3Smacallan
720dfe64dd3Smacallanextern const uint8_t XGI_MDA_DAC[];
721dfe64dd3Smacallanextern const uint8_t XGI_CGA_DAC[];
722dfe64dd3Smacallanextern const uint8_t XGI_EGA_DAC[];
723dfe64dd3Smacallanextern const uint8_t XGI_VGA_DAC[];
724dfe64dd3Smacallan
725dfe64dd3Smacallanvoid
726dfe64dd3SmacallanXGI_New_LoadDAC(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
727dfe64dd3Smacallan            USHORT ModeNo, USHORT ModeIdIndex)
728dfe64dd3Smacallan{
729dfe64dd3Smacallan   USHORT data,data2;
730dfe64dd3Smacallan   USHORT time,i,j,k,m,n,o;
731dfe64dd3Smacallan   USHORT si,di,bx,dl,al,ah,dh;
732dfe64dd3Smacallan   USHORT shiftflag;
733dfe64dd3Smacallan   XGIIOADDRESS DACAddr, DACData;
734dfe64dd3Smacallan   const uint8_t *table = NULL;
735dfe64dd3Smacallan
736dfe64dd3Smacallan   if(ModeNo <= 0x13) {
737dfe64dd3Smacallan      data = XGI_Pr->SModeIDTable[ModeIdIndex].St_ModeFlag;
738dfe64dd3Smacallan   } else {
739dfe64dd3Smacallan      data = XGI_Pr->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
740dfe64dd3Smacallan   }
741dfe64dd3Smacallan
742dfe64dd3Smacallan   data &= DACInfoFlag;
743dfe64dd3Smacallan   time = 64;
744dfe64dd3Smacallan   if(data == 0x00) table = XGI_MDA_DAC;
745dfe64dd3Smacallan   if(data == 0x08) table = XGI_CGA_DAC;
746dfe64dd3Smacallan   if(data == 0x10) table = XGI_EGA_DAC;
747dfe64dd3Smacallan   if(data == 0x18) {
748dfe64dd3Smacallan      time = 256;
749dfe64dd3Smacallan      table = XGI_VGA_DAC;
750dfe64dd3Smacallan   }
751dfe64dd3Smacallan   if(time == 256) j = 16;
752dfe64dd3Smacallan   else            j = time;
753dfe64dd3Smacallan
754dfe64dd3Smacallan   if( ( (XGI_Pr->VBInfo & SetCRT2ToLCD) &&        /* 301B-DH LCD */
755dfe64dd3Smacallan         (XGI_Pr->VBType & VB_NoLCD) )        ||
756dfe64dd3Smacallan       (XGI_Pr->VBInfo & SetCRT2ToLCDA)       ||   /* LCDA */
757dfe64dd3Smacallan       (!(XGI_Pr->SetFlag & ProgrammingCRT2)) ) {  /* Programming CRT1 */
758dfe64dd3Smacallan      DACAddr = XGI_Pr->P3c8;
759dfe64dd3Smacallan      DACData = XGI_Pr->P3c9;
760dfe64dd3Smacallan      shiftflag = 0;
761dfe64dd3Smacallan      XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
762dfe64dd3Smacallan   } else {
763dfe64dd3Smacallan      shiftflag = 1;
764dfe64dd3Smacallan      DACAddr = XGI_Pr->Part5Port;
765dfe64dd3Smacallan      DACData = XGI_Pr->Part5Port + 1;
766dfe64dd3Smacallan   }
767dfe64dd3Smacallan
768dfe64dd3Smacallan   XGI_SetRegByte(DACAddr,0x00);
769dfe64dd3Smacallan
770dfe64dd3Smacallan   for(i=0; i<j; i++) {
771dfe64dd3Smacallan      data = table[i];
772dfe64dd3Smacallan      for(k=0; k<3; k++) {
773dfe64dd3Smacallan	data2 = 0;
774dfe64dd3Smacallan	if(data & 0x01) data2 = 0x2A;
775dfe64dd3Smacallan	if(data & 0x02) data2 += 0x15;
776dfe64dd3Smacallan	if(shiftflag) data2 <<= 2;
777dfe64dd3Smacallan	XGI_SetRegByte(DACData, data2);
778dfe64dd3Smacallan	data >>= 2;
779dfe64dd3Smacallan      }
780dfe64dd3Smacallan   }
781dfe64dd3Smacallan
782dfe64dd3Smacallan   if(time == 256) {
783dfe64dd3Smacallan      for(i = 16; i < 32; i++) {
784dfe64dd3Smacallan   	 data = table[i];
785dfe64dd3Smacallan	 if(shiftflag) data <<= 2;
786dfe64dd3Smacallan	 for(k = 0; k < 3; k++) XGI_SetRegByte(DACData, data);
787dfe64dd3Smacallan      }
788dfe64dd3Smacallan      si = 32;
789dfe64dd3Smacallan      for(m = 0; m < 9; m++) {
790dfe64dd3Smacallan         di = si;
791dfe64dd3Smacallan         bx = si + 4;
792dfe64dd3Smacallan         dl = 0;
793dfe64dd3Smacallan         for(n = 0; n < 3; n++) {
794dfe64dd3Smacallan  	    for(o = 0; o < 5; o++) {
795dfe64dd3Smacallan	       dh = table[si];
796dfe64dd3Smacallan	       ah = table[di];
797dfe64dd3Smacallan	       al = table[bx];
798dfe64dd3Smacallan	       si++;
799dfe64dd3Smacallan	       XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
800dfe64dd3Smacallan	    }
801dfe64dd3Smacallan	    si -= 2;
802dfe64dd3Smacallan	    for(o = 0; o < 3; o++) {
803dfe64dd3Smacallan	       dh = table[bx];
804dfe64dd3Smacallan	       ah = table[di];
805dfe64dd3Smacallan	       al = table[si];
806dfe64dd3Smacallan	       si--;
807dfe64dd3Smacallan	       XGI_WriteDAC(DACData, shiftflag, dl, ah, al, dh);
808dfe64dd3Smacallan	    }
809dfe64dd3Smacallan	    dl++;
810dfe64dd3Smacallan	 }            /* for n < 3 */
811dfe64dd3Smacallan	 si += 5;
812dfe64dd3Smacallan      }               /* for m < 9 */
813dfe64dd3Smacallan   }
814dfe64dd3Smacallan}
815dfe64dd3Smacallan
816dfe64dd3Smacallan/*********************************************/
817dfe64dd3Smacallan/*         SET CRT1 REGISTER GROUP           */
818dfe64dd3Smacallan/*********************************************/
819dfe64dd3Smacallan
820dfe64dd3Smacallanstatic void
821dfe64dd3SmacallanXGI_New_SetCRT1Group(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
822dfe64dd3Smacallan                 USHORT ModeNo, USHORT ModeIdIndex)
823dfe64dd3Smacallan{
824dfe64dd3Smacallan    const USHORT StandTableIndex = XGI_GetModePtr(XGI_Pr->SModeIDTable,
825dfe64dd3Smacallan                                                  XGI_Pr->ModeType,
826dfe64dd3Smacallan                                                  ModeNo, ModeIdIndex);
827dfe64dd3Smacallan    USHORT RefreshRateTableIndex = 0;
828dfe64dd3Smacallan
829dfe64dd3Smacallan
830dfe64dd3Smacallan/*
831dfe64dd3Smacallan  if(XGI_Pr->SetFlag & LowModeTests) {
832dfe64dd3Smacallan     if(XGI_Pr->VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
833dfe64dd3Smacallan        XGI_New_DisableBridge(XGI_Pr, HwInfo);
834dfe64dd3Smacallan     }
835dfe64dd3Smacallan  }
836dfe64dd3Smacallan*/
837dfe64dd3Smacallan  XGI_SetSeqRegs(StandTableIndex, XGI_Pr);
838dfe64dd3Smacallan  XGI_SetMiscRegs(StandTableIndex, XGI_Pr);
839dfe64dd3Smacallan  XGI_SetCRTCRegs(StandTableIndex, XGI_Pr);
840dfe64dd3Smacallan  XGI_SetATTRegs(ModeNo, StandTableIndex, ModeIdIndex, XGI_Pr);
841dfe64dd3Smacallan  XGI_SetGRCRegs(StandTableIndex, XGI_Pr);
842dfe64dd3Smacallan  XGI_ClearExt1Regs(ModeNo, XGI_Pr);
843dfe64dd3Smacallan  XGI_ResetCRT1VCLK(XGI_Pr, HwInfo);
844dfe64dd3Smacallan
845dfe64dd3Smacallan  XGI_Pr->SetFlag &= (~ProgrammingCRT2);
846dfe64dd3Smacallan
847dfe64dd3Smacallan#ifdef LINUX_XF86
848dfe64dd3Smacallan  xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
849dfe64dd3Smacallan                    XGI_Pr->VBType, XGI_Pr->VBInfo);
850dfe64dd3Smacallan#endif
851dfe64dd3Smacallan
852dfe64dd3Smacallan  if(XGI_Pr->VBInfo & SetSimuScanMode) {
853dfe64dd3Smacallan     if(XGI_Pr->VBInfo & SetInSlaveMode) {
854dfe64dd3Smacallan        XGI_Pr->SetFlag |= ProgrammingCRT2;
855dfe64dd3Smacallan     }
856dfe64dd3Smacallan  }
857dfe64dd3Smacallan
858dfe64dd3Smacallan  if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
859dfe64dd3Smacallan     XGI_Pr->SetFlag |= ProgrammingCRT2;
860dfe64dd3Smacallan  }
861dfe64dd3Smacallan
862dfe64dd3Smacallan  if(!(XGI_Pr->VBInfo & SetCRT2ToLCDA)) {
863dfe64dd3Smacallan     XGI_Pr->SetFlag &= ~ProgrammingCRT2;
864dfe64dd3Smacallan  }
865dfe64dd3Smacallan
866dfe64dd3Smacallan  if(RefreshRateTableIndex != 0xFFFF) {
867dfe64dd3Smacallan     XGI_SetSync(RefreshRateTableIndex, XGI_Pr);
868dfe64dd3Smacallan     XGI_New_SetCRT1CRTC(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
869dfe64dd3Smacallan     XGI_New_SetCRT1Offset(XGI_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
870dfe64dd3Smacallan     XGI_New_SetCRT1VCLK(XGI_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
871dfe64dd3Smacallan  }
872dfe64dd3Smacallan
873dfe64dd3Smacallan  XGI_New_SetCRT1ModeRegs(XGI_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
874dfe64dd3Smacallan
875dfe64dd3Smacallan  XGI_New_LoadDAC(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
876dfe64dd3Smacallan}
877dfe64dd3Smacallan
878dfe64dd3Smacallan
879dfe64dd3Smacallan/*********************************************/
880dfe64dd3Smacallan/*         XFree86: SET SCREEN PITCH         */
881dfe64dd3Smacallan/*********************************************/
882dfe64dd3Smacallan
883dfe64dd3Smacallan#ifdef LINUX_XF86
884dfe64dd3Smacallanstatic void
885dfe64dd3SmacallanXGI_SetPitchCRT1(VB_DEVICE_INFO *XGI_Pr, ScrnInfoPtr pScrn)
886dfe64dd3Smacallan{
887dfe64dd3Smacallan   XGIPtr pXGI = XGIPTR(pScrn);
888dfe64dd3Smacallan   UShort HDisplay = pXGI->scrnPitch >> 3;
889dfe64dd3Smacallan
890dfe64dd3Smacallan   XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
891dfe64dd3Smacallan   XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
892dfe64dd3Smacallan}
893dfe64dd3Smacallan#endif
894dfe64dd3Smacallan
895dfe64dd3Smacallan/*********************************************/
896dfe64dd3Smacallan/*          XFree86: XGIBIOSSetMode()        */
897dfe64dd3Smacallan/*           for non-Dual-Head mode          */
898dfe64dd3Smacallan/*********************************************/
899dfe64dd3Smacallan
900dfe64dd3Smacallan#ifdef LINUX_XF86
901dfe64dd3SmacallanBOOLEAN
902dfe64dd3SmacallanXGIBIOSSetMode(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
903dfe64dd3Smacallan	       ScrnInfoPtr pScrn, DisplayModePtr mode)
904dfe64dd3Smacallan{
905dfe64dd3Smacallan    XGIPtr  pXGI = XGIPTR(pScrn);
906dfe64dd3Smacallan    UShort  ModeNo=0;
907dfe64dd3Smacallan    BOOLEAN SetModeRet = FALSE ;
908dfe64dd3Smacallan    UShort  HDisplay = pXGI->scrnOffset >> 3 ;
909dfe64dd3Smacallan
910dfe64dd3Smacallan#if XGI_USING_BIOS_SETMODE
911dfe64dd3Smacallan    PDEBUG(ErrorF("XGI_USING_BIOS_SETMODE \n"));
912dfe64dd3Smacallan    if ((pXGI->pVbe != NULL) && (pXGI->pVbe->pInt10 != NULL)) {
913dfe64dd3Smacallan        xf86Int10InfoPtr pInt = pXGI->pVbe->pInt10;
914dfe64dd3Smacallan
915dfe64dd3Smacallan        if (xf86LoadSubModule(pScrn, "int10")) {
916dfe64dd3Smacallan            pInt->num = 0x10;
917dfe64dd3Smacallan            pInt->ax = 0x80 | ModeNo;
918dfe64dd3Smacallan
919dfe64dd3Smacallan            /* ah = 0, set mode */
920dfe64dd3Smacallan            xf86ExecX86int10(pInt);
921dfe64dd3Smacallan            SetModeRet = ((pInt->ax & 0x7f) == ModeNo);
922dfe64dd3Smacallan        }
923dfe64dd3Smacallan    }
924dfe64dd3Smacallan    else
925dfe64dd3Smacallan#endif
926dfe64dd3Smacallan    {
927dfe64dd3Smacallan        PDEBUG(ErrorF("XGI_USING_C_code_SETMODE \n"));
928dfe64dd3Smacallan		/* Jong 08/21/2007; support external modeline in X configuration file */
929dfe64dd3Smacallan		/* ------------------------------------------------------------------ */
930dfe64dd3Smacallan		HwInfo->BPP = pScrn->bitsPerPixel;
931dfe64dd3Smacallan		HwInfo->Frequency = mode->VRefresh;
932dfe64dd3Smacallan		HwInfo->Horizontal_ACTIVE = mode->HDisplay;
933dfe64dd3Smacallan		HwInfo->Vertical_ACTIVE = mode->VDisplay;
934dfe64dd3Smacallan		HwInfo->Interlace=FALSE;
935dfe64dd3Smacallan
936dfe64dd3Smacallan		if( (mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C) ) /* custom mode */
937dfe64dd3Smacallan		{
938dfe64dd3Smacallan			xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting a customer mode %dx%d\n", mode->HDisplay, mode->VDisplay);
939dfe64dd3Smacallan
940dfe64dd3Smacallan			HwInfo->SpecifyTiming = TRUE;
941dfe64dd3Smacallan			HwInfo->Horizontal_FP = mode->HSyncStart - mode->HDisplay; /* HSyncStart - HDisplay */
942dfe64dd3Smacallan			HwInfo->Horizontal_BP = mode->HTotal - mode->HSyncEnd; /* HTotal - HSyncEnd */
943dfe64dd3Smacallan			HwInfo->Horizontal_SYNC = mode->HSyncEnd - mode->HSyncStart; /* HSyncEnd - HSyncStart */
944dfe64dd3Smacallan			HwInfo->Vertical_FP =  mode->VSyncStart - mode->VDisplay;
945dfe64dd3Smacallan			HwInfo->Vertical_BP = mode->VTotal - mode->VSyncEnd;
946dfe64dd3Smacallan			HwInfo->Vertical_SYNC = mode->VSyncEnd - mode->VSyncStart;
947dfe64dd3Smacallan			HwInfo->DCLK = mode->Clock;
948dfe64dd3Smacallan		}
949dfe64dd3Smacallan		else
950dfe64dd3Smacallan		{
951dfe64dd3Smacallan			HwInfo->SpecifyTiming = FALSE;
952dfe64dd3Smacallan
953dfe64dd3Smacallan			ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
954dfe64dd3Smacallan			if(!ModeNo) return FALSE;
955dfe64dd3Smacallan
956dfe64dd3Smacallan			xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting a standard mode 0x%x\n", ModeNo);
957dfe64dd3Smacallan		}
958dfe64dd3Smacallan		/* ------------------------------------------------------------------ */
959dfe64dd3Smacallan
960dfe64dd3Smacallan        SetModeRet = XGISetModeNew(HwInfo, XGI_Pr, ModeNo);
961dfe64dd3Smacallan        PDEBUG(ErrorF("out_of_C_code_SETMODE \n"));
962dfe64dd3Smacallan    }
963dfe64dd3Smacallan
964dfe64dd3Smacallan
965dfe64dd3Smacallan    /* SetPitch: Adapt to virtual size & position */
966dfe64dd3Smacallan    if ((ModeNo > 0x13) || (mode->type == M_T_USERDEF) || ((mode->type & M_T_CLOCK_CRTC_C) == M_T_CLOCK_CRTC_C)) {
967dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->Part1Port, 0x2f, 1);  //yilin for crt2pitch it shoude modify if not colone mode
968dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->Part1Port, 0x07, (HDisplay & 0xFF));
969dfe64dd3Smacallan        XGI_SetRegANDOR(XGI_Pr->Part1Port, 0x09, 0xF0, (HDisplay>>8));
970dfe64dd3Smacallan
971dfe64dd3Smacallan		/* Jong10052009; Set pitch with HDisplay = pXGI->scrnOffset >> 3 */
972dfe64dd3Smacallan	    PDEBUG(ErrorF("scrnOffset is %d...\n", pXGI->scrnOffset));
973dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
974dfe64dd3Smacallan        XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8));
975dfe64dd3Smacallan		/*
976dfe64dd3Smacallan        XGI_SetReg(XGI_Pr->P3d4,0x13,(HDisplay & 0xFF));
977dfe64dd3Smacallan        XGI_SetRegANDOR(XGI_Pr->P3c4,0x0E,0xF0,(HDisplay>>8)); */
978dfe64dd3Smacallan    }
979dfe64dd3Smacallan
980dfe64dd3Smacallan    return SetModeRet;
981dfe64dd3Smacallan}
982dfe64dd3Smacallan
983dfe64dd3Smacallan/*********************************************/
984dfe64dd3Smacallan/*       XFree86: XGIBIOSSetModeCRT1()       */
985dfe64dd3Smacallan/*           for Dual-Head modes             */
986dfe64dd3Smacallan/*********************************************/
987dfe64dd3Smacallan
988dfe64dd3SmacallanBOOLEAN
989dfe64dd3SmacallanXGIBIOSSetModeCRT1(VB_DEVICE_INFO *XGI_Pr, PXGI_HW_DEVICE_INFO HwInfo,
990dfe64dd3Smacallan		   ScrnInfoPtr pScrn, DisplayModePtr mode)
991dfe64dd3Smacallan{
992dfe64dd3Smacallan    XGIPtr  pXGI = XGIPTR(pScrn);
993dfe64dd3Smacallan    USHORT  ModeIdIndex, ModeNo=0;
994dfe64dd3Smacallan    UCHAR backupreg=0;
995dfe64dd3Smacallan    unsigned vga_info;
996dfe64dd3Smacallan    XGIEntPtr pXGIEnt = ENTITY_PRIVATE(pXGI);
997dfe64dd3Smacallan    UCHAR backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
998dfe64dd3Smacallan
999dfe64dd3Smacallan
1000dfe64dd3Smacallan    ModeNo = XGI_CalcModeIndex(pScrn, mode, pXGI->VBFlags);
1001dfe64dd3Smacallan    if(!ModeNo) return FALSE;
1002dfe64dd3Smacallan
1003dfe64dd3Smacallan    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
1004dfe64dd3Smacallan                   "Setting standard mode 0x%x on CRT1\n", ModeNo);
1005dfe64dd3Smacallan
1006dfe64dd3Smacallan#if (defined(i386) || defined(__i386) || defined(__i386__) || defined(__AMD64__))
1007dfe64dd3Smacallan    vga_info = XGI_GetSetBIOSScratch(pScrn, 0x489, 0xff);
1008dfe64dd3Smacallan#else
1009dfe64dd3Smacallan    vga_info = 0x11;
1010dfe64dd3Smacallan#endif
1011dfe64dd3Smacallan   XGIInitPCIetc(XGI_Pr, HwInfo);
1012dfe64dd3Smacallan
1013dfe64dd3Smacallan   XGI_SetReg(XGI_Pr->P3c4,0x05,0x86);
1014dfe64dd3Smacallan
1015dfe64dd3Smacallan   if (!XGI_SearchModeID(XGI_Pr->SModeIDTable, XGI_Pr->EModeIDTable,
1016dfe64dd3Smacallan                         vga_info, &ModeNo, &ModeIdIndex)) {
1017dfe64dd3Smacallan       return FALSE;
1018dfe64dd3Smacallan   }
1019dfe64dd3Smacallan
1020dfe64dd3Smacallan   /* Determine VBType */
1021dfe64dd3Smacallan   XGI_New_GetVBType(XGI_Pr, HwInfo);
1022dfe64dd3Smacallan
1023dfe64dd3Smacallan    if (XGI_Pr->VBType & VB_XGI301BLV302BLV) {
1024dfe64dd3Smacallan	backupreg = XGI_GetReg(XGI_Pr->P3d4,0x38);
1025dfe64dd3Smacallan    }
1026dfe64dd3Smacallan
1027dfe64dd3Smacallan   /* Get VB information (connectors, connected devices) */
1028dfe64dd3Smacallan   /* (We don't care if the current mode is a CRT2 mode) */
1029dfe64dd3Smacallan   XGI_SetLowModeTest(XGI_Pr, ModeNo, HwInfo);
1030dfe64dd3Smacallan
1031dfe64dd3Smacallan   /* Set mode on CRT1 */
1032dfe64dd3Smacallan   XGI_New_SetCRT1Group(XGI_Pr, HwInfo, ModeNo, ModeIdIndex);
1033dfe64dd3Smacallan   /* SetPitch: Adapt to virtual size & position */
1034dfe64dd3Smacallan   XGI_SetPitchCRT1(XGI_Pr, pScrn);
1035dfe64dd3Smacallan
1036dfe64dd3Smacallan
1037dfe64dd3Smacallan   /* Reset CRT2 if changing mode on CRT1 */
1038dfe64dd3Smacallan   if(IS_DUAL_HEAD(pXGI)) {
1039dfe64dd3Smacallan      if(pXGIEnt->CRT2ModeNo != -1) {
1040dfe64dd3Smacallan         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
1041dfe64dd3Smacallan				"(Re-)Setting mode for CRT2\n");
1042dfe64dd3Smacallan	 backupcr30 = XGI_GetReg(XGI_Pr->P3d4,0x30);
1043dfe64dd3Smacallan	 backupcr31 = XGI_GetReg(XGI_Pr->P3d4,0x31);
1044dfe64dd3Smacallan	 backupcr35 = XGI_GetReg(XGI_Pr->P3d4,0x35);
1045dfe64dd3Smacallan	 backupcr38 = XGI_GetReg(XGI_Pr->P3d4,0x38);
1046dfe64dd3Smacallan	 if(XGI_Pr->VBType & VB_XGIVB) {
1047dfe64dd3Smacallan	    /* Backup LUT-enable */
1048dfe64dd3Smacallan	    if(pXGIEnt->CRT2ModeSet) {
1049dfe64dd3Smacallan	       backupp40d = XGI_GetReg(XGI_Pr->Part4Port,0x0d) & 0x08;
1050dfe64dd3Smacallan	    }
1051dfe64dd3Smacallan	 }
1052dfe64dd3Smacallan	 if(XGI_Pr->VBInfo & SetCRT2ToLCDA) {
1053dfe64dd3Smacallan	    XGI_SetReg(XGI_Pr->P3d4,0x30,pXGIEnt->CRT2CR30);
1054dfe64dd3Smacallan	    XGI_SetReg(XGI_Pr->P3d4,0x31,pXGIEnt->CRT2CR31);
1055dfe64dd3Smacallan	    XGI_SetReg(XGI_Pr->P3d4,0x35,pXGIEnt->CRT2CR35);
1056dfe64dd3Smacallan	    XGI_SetReg(XGI_Pr->P3d4,0x38,pXGIEnt->CRT2CR38);
1057dfe64dd3Smacallan	 }
1058dfe64dd3Smacallan
1059dfe64dd3Smacallan         XGI_SetReg(XGI_Pr->P3d4,0x30,backupcr30);
1060dfe64dd3Smacallan	 XGI_SetReg(XGI_Pr->P3d4,0x31,backupcr31);
1061dfe64dd3Smacallan	 XGI_SetReg(XGI_Pr->P3d4,0x35,backupcr35);
1062dfe64dd3Smacallan	 XGI_SetReg(XGI_Pr->P3d4,0x38,backupcr38);
1063dfe64dd3Smacallan	 if(XGI_Pr->VBType & VB_XGIVB) {
1064dfe64dd3Smacallan	    XGI_SetRegANDOR(XGI_Pr->Part4Port,0x0d, ~0x08, backupp40d);
1065dfe64dd3Smacallan	 }
1066dfe64dd3Smacallan      }
1067dfe64dd3Smacallan   }
1068dfe64dd3Smacallan
1069dfe64dd3Smacallan   /* Warning: From here, the custom mode entries in XGI_Pr are
1070dfe64dd3Smacallan    * possibly overwritten
1071dfe64dd3Smacallan    */
1072dfe64dd3Smacallan
1073dfe64dd3Smacallan   XGI_HandleCRT1(XGI_Pr);
1074dfe64dd3Smacallan
1075dfe64dd3Smacallan   XGI_New_DisplayOn(XGI_Pr);
1076dfe64dd3Smacallan   XGI_SetRegByte(XGI_Pr->P3c6,0xFF);
1077dfe64dd3Smacallan
1078dfe64dd3Smacallan   /* Backup/Set ModeNo in BIOS scratch area */
1079dfe64dd3Smacallan   XGI_GetSetModeID(pScrn,ModeNo);
1080dfe64dd3Smacallan
1081dfe64dd3Smacallan   return TRUE;
1082dfe64dd3Smacallan}
1083dfe64dd3Smacallan#endif /* Linux_XF86 */
1084