]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/xgifb/vb_init.c
8d591828cee5a341e0d530d7def6c4aaaff79f50
[mv-sheeva.git] / drivers / staging / xgifb / vb_init.c
1 #include "vgatypes.h"
2
3 #include <linux/version.h>
4 #include <linux/types.h>
5 #include <linux/delay.h> /* udelay */
6 #include "XGIfb.h"
7
8 #include "vb_def.h"
9 #include "vb_struct.h"
10 #include "vb_util.h"
11 #include "vb_setmode.h"
12 #include "vb_init.h"
13 #include "vb_ext.h"
14
15
16 #include <asm/io.h>
17
18 static unsigned char XGINew_ChannelAB, XGINew_DataBusWidth;
19
20 unsigned short XGINew_DRAMType[17][5] = {
21         {0x0C, 0x0A, 0x02, 0x40, 0x39}, {0x0D, 0x0A, 0x01, 0x40, 0x48},
22         {0x0C, 0x09, 0x02, 0x20, 0x35}, {0x0D, 0x09, 0x01, 0x20, 0x44},
23         {0x0C, 0x08, 0x02, 0x10, 0x31}, {0x0D, 0x08, 0x01, 0x10, 0x40},
24         {0x0C, 0x0A, 0x01, 0x20, 0x34}, {0x0C, 0x09, 0x01, 0x08, 0x32},
25         {0x0B, 0x08, 0x02, 0x08, 0x21}, {0x0C, 0x08, 0x01, 0x08, 0x30},
26         {0x0A, 0x08, 0x02, 0x04, 0x11}, {0x0B, 0x0A, 0x01, 0x10, 0x28},
27         {0x09, 0x08, 0x02, 0x02, 0x01}, {0x0B, 0x09, 0x01, 0x08, 0x24},
28         {0x0B, 0x08, 0x01, 0x04, 0x20}, {0x0A, 0x08, 0x01, 0x02, 0x10},
29         {0x09, 0x08, 0x01, 0x01, 0x00} };
30
31 static unsigned short XGINew_SDRDRAM_TYPE[13][5] = {
32         { 2, 12, 9, 64, 0x35},
33         { 1, 13, 9, 64, 0x44},
34         { 2, 12, 8, 32, 0x31},
35         { 2, 11, 9, 32, 0x25},
36         { 1, 12, 9, 32, 0x34},
37         { 1, 13, 8, 32, 0x40},
38         { 2, 11, 8, 16, 0x21},
39         { 1, 12, 8, 16, 0x30},
40         { 1, 11, 9, 16, 0x24},
41         { 1, 11, 8,  8, 0x20},
42         { 2,  9, 8,  4, 0x01},
43         { 1, 10, 8,  4, 0x10},
44         { 1,  9, 8,  2, 0x00} };
45
46 static unsigned short XGINew_DDRDRAM_TYPE[4][5] = {
47         { 2, 12, 9, 64, 0x35},
48         { 2, 12, 8, 32, 0x31},
49         { 2, 11, 8, 16, 0x21},
50         { 2,  9, 8,  4, 0x01} };
51
52 static unsigned short XGINew_DDRDRAM_TYPE340[4][5] = {
53         { 2, 13, 9, 64, 0x45},
54         { 2, 12, 9, 32, 0x35},
55         { 2, 12, 8, 16, 0x31},
56         { 2, 11, 8,  8, 0x21} };
57
58 static unsigned short XGINew_DDRDRAM_TYPE20[12][5] = {
59         { 2, 14, 11, 128, 0x5D},
60         { 2, 14, 10, 64, 0x59},
61         { 2, 13, 11, 64, 0x4D},
62         { 2, 14,  9, 32, 0x55},
63         { 2, 13, 10, 32, 0x49},
64         { 2, 12, 11, 32, 0x3D},
65         { 2, 14,  8, 16, 0x51},
66         { 2, 13,  9, 16, 0x45},
67         { 2, 12, 10, 16, 0x39},
68         { 2, 13,  8,  8, 0x41},
69         { 2, 12,  9,  8, 0x35},
70         { 2, 12,  8,  4, 0x31} };
71
72 void     XGINew_SetDRAMSize_340(struct xgi_hw_device_info *, struct vb_device_info *);
73 void     XGINew_SetDRAMSize_310(struct xgi_hw_device_info *, struct vb_device_info *);
74 void     XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
75 void     XGINew_SetDRAMModeRegister(struct vb_device_info *);
76 void     XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension);
77 void XGINew_SetDRAMDefaultRegister340(struct xgi_hw_device_info *HwDeviceExtension,
78                                       unsigned long, struct vb_device_info *);
79 unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
80                                      struct vb_device_info *pVBInfo);
81 unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension);
82
83 int      XGINew_DDRSizing340(struct xgi_hw_device_info *, struct vb_device_info *);
84 void     XGINew_DisableRefresh(struct xgi_hw_device_info *, struct vb_device_info *) ;
85 void     XGINew_CheckBusWidth_310(struct vb_device_info *) ;
86 int      XGINew_SDRSizing(struct vb_device_info *);
87 int      XGINew_DDRSizing(struct vb_device_info *);
88 void     XGINew_EnableRefresh(struct xgi_hw_device_info *, struct vb_device_info *);
89 static int      XGINew_RAMType;         /*int      ModeIDOffset,StandTable,CRT1Table,ScreenOffset,REFIndex;*/
90 #if 0
91 static unsigned long     UNIROM;
92 #endif
93 unsigned char  ChkLFB(struct vb_device_info *);
94 void     XGINew_Delay15us(unsigned long);
95 void     SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension,
96                          unsigned long XGI_P3d4Port);
97 void     ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo);
98 void     XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo);
99 void     XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension);
100 void     XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension);
101 void     XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
102 void     XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
103 void     XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
104 unsigned char    GetXG21FPBits(struct vb_device_info *pVBInfo);
105 void     XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo) ;
106 unsigned char    GetXG27FPBits(struct vb_device_info *pVBInfo);
107
108 static void DelayUS(unsigned long MicroSeconds)
109 {
110         udelay(MicroSeconds);
111 }
112
113 unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension)
114 {
115         struct vb_device_info VBINF;
116         struct vb_device_info *pVBInfo = &VBINF;
117         unsigned char i, temp = 0, temp1;
118         /* VBIOSVersion[5]; */
119         volatile unsigned char *pVideoMemory;
120
121         /* unsigned long j, k; */
122
123         struct XGI_DSReg *pSR;
124
125         unsigned long Temp;
126
127         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
128
129         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
130
131         pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
132
133         pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
134
135         /* Newdebugcode(0x99); */
136
137
138         /* if (pVBInfo->ROMAddr == 0) */
139         /* return(0); */
140
141         if (pVBInfo->FBAddr == NULL) {
142                 printk("\n pVBInfo->FBAddr == 0 ");
143                 return 0;
144         }
145         printk("1");
146         if (pVBInfo->BaseAddr == 0) {
147                 printk("\npVBInfo->BaseAddr == 0 ");
148                 return 0;
149         }
150         printk("2");
151
152         XGINew_SetReg3((pVBInfo->BaseAddr + 0x12), 0x67); /* 3c2 <- 67 ,ynlai */
153
154         pVBInfo->ISXPDOS = 0;
155         printk("3");
156
157         if (!HwDeviceExtension->bIntegratedMMEnabled)
158                 return 0; /* alan */
159
160         printk("4");
161
162         /* VBIOSVersion[4] = 0x0; */
163
164         /* 09/07/99 modify by domao */
165
166         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
167         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
168         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
169         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
170         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
171         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
172         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
173         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
174         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
175         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
176         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
177         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
178         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
179         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
180         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
181         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
182         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
183         printk("5");
184
185         if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
186                 XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
187
188         InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
189
190         /* ReadVBIOSData */
191         ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
192
193         /* 1.Openkey */
194         XGINew_SetReg1(pVBInfo->P3c4, 0x05, 0x86);
195         printk("6");
196
197         /* GetXG21Sense (GPIO) */
198         if (HwDeviceExtension->jChipType == XG21)
199                 XGINew_GetXG21Sense(HwDeviceExtension, pVBInfo);
200
201         if (HwDeviceExtension->jChipType == XG27)
202                 XGINew_GetXG27Sense(HwDeviceExtension, pVBInfo);
203
204         printk("7");
205
206         /* 2.Reset Extended register */
207
208         for (i = 0x06; i < 0x20; i++)
209                 XGINew_SetReg1(pVBInfo->P3c4, i, 0);
210
211         for (i = 0x21; i <= 0x27; i++)
212                 XGINew_SetReg1(pVBInfo->P3c4, i, 0);
213
214         /* for(i = 0x06; i <= 0x27; i++) */
215         /* XGINew_SetReg1(pVBInfo->P3c4, i, 0); */
216
217         printk("8");
218
219         if ((HwDeviceExtension->jChipType >= XG20) || (HwDeviceExtension->jChipType >= XG40)) {
220                 for (i = 0x31; i <= 0x3B; i++)
221                         XGINew_SetReg1(pVBInfo->P3c4, i, 0);
222         } else {
223                 for (i = 0x31; i <= 0x3D; i++)
224                         XGINew_SetReg1(pVBInfo->P3c4, i, 0);
225         }
226         printk("9");
227
228         if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
229                 XGINew_SetReg1(pVBInfo->P3c4, 0x3B, 0xC0);
230
231         /* for (i = 0x30; i <= 0x3F; i++) */
232         /* XGINew_SetReg1(pVBInfo->P3d4, i, 0); */
233
234         for (i = 0x79; i <= 0x7C; i++)
235                 XGINew_SetReg1(pVBInfo->P3d4, i, 0); /* shampoo 0208 */
236
237         printk("10");
238
239         if (HwDeviceExtension->jChipType >= XG20)
240                 XGINew_SetReg1(pVBInfo->P3d4, 0x97, *pVBInfo->pXGINew_CR97);
241
242         /* 3.SetMemoryClock
243
244          if (HwDeviceExtension->jChipType >= XG40)
245          XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
246
247          if (HwDeviceExtension->jChipType < XG40)
248          XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);  */
249
250         printk("11");
251
252         /* 4.SetDefExt1Regs begin */
253         XGINew_SetReg1(pVBInfo->P3c4, 0x07, *pVBInfo->pSR07);
254         if (HwDeviceExtension->jChipType == XG27) {
255                 XGINew_SetReg1(pVBInfo->P3c4, 0x40, *pVBInfo->pSR40);
256                 XGINew_SetReg1(pVBInfo->P3c4, 0x41, *pVBInfo->pSR41);
257         }
258         XGINew_SetReg1(pVBInfo->P3c4, 0x11, 0x0F);
259         XGINew_SetReg1(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F);
260         /* XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0x20); */
261         XGINew_SetReg1(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
262         XGINew_SetReg1(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */
263         if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */
264                 XGINew_SetReg1(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36);
265
266         /* SR11 = 0x0F; */
267         /* XGINew_SetReg1(pVBInfo->P3c4, 0x11, SR11); */
268
269         printk("12");
270
271         if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
272                 /* Set AGP Rate */
273                 /*
274                 temp1 = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
275                 temp1 &= 0x02;
276                 if (temp1 == 0x02) {
277                         XGINew_SetReg4(0xcf8, 0x80000000);
278                         ChipsetID = XGINew_GetReg3(0x0cfc);
279                         XGINew_SetReg4(0xcf8, 0x8000002C);
280                         VendorID = XGINew_GetReg3(0x0cfc);
281                         VendorID &= 0x0000FFFF;
282                         XGINew_SetReg4(0xcf8, 0x8001002C);
283                         GraphicVendorID = XGINew_GetReg3(0x0cfc);
284                         GraphicVendorID &= 0x0000FFFF;
285
286                         if (ChipsetID == 0x7301039)
287                                 XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x09);
288
289                         ChipsetID &= 0x0000FFFF;
290
291                         if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) {
292                                 if (ChipsetID == 0x1106) {
293                                         if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019))
294                                                 XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0D);
295                                         else
296                                                 XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
297                                 } else {
298                                         XGINew_SetReg1(pVBInfo->P3d4, 0x5F, 0x0B);
299                                 }
300                         }
301                 }
302                 */
303
304                 printk("13");
305
306                 if (HwDeviceExtension->jChipType >= XG40) {
307                         /* Set AGP customize registers (in SetDefAGPRegs) Start */
308                         for (i = 0x47; i <= 0x4C; i++)
309                                 XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]);
310
311                         for (i = 0x70; i <= 0x71; i++)
312                                 XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]);
313
314                         for (i = 0x74; i <= 0x77; i++)
315                                 XGINew_SetReg1(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]);
316                         /* Set AGP customize registers (in SetDefAGPRegs) End */
317                         /* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
318                         /*        XGINew_SetReg4(0xcf8 , 0x80000000); */
319                         /*        ChipsetID = XGINew_GetReg3(0x0cfc); */
320                         /*        if (ChipsetID == 0x25308086) */
321                         /*            XGINew_SetReg1(pVBInfo->P3d4, 0x77, 0xF0); */
322
323                         HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */
324                         Temp >>= 20;
325                         Temp &= 0xF;
326
327                         if (Temp == 1)
328                                 XGINew_SetReg1(pVBInfo->P3d4, 0x48, 0x20); /* CR48 */
329                 }
330                 printk("14");
331
332                 if (HwDeviceExtension->jChipType < XG40)
333                         XGINew_SetReg1(pVBInfo->P3d4, 0x49, pVBInfo->CR49[0]);
334         } /* != XG20 */
335
336         /* Set PCI */
337         XGINew_SetReg1(pVBInfo->P3c4, 0x23, *pVBInfo->pSR23);
338         XGINew_SetReg1(pVBInfo->P3c4, 0x24, *pVBInfo->pSR24);
339         XGINew_SetReg1(pVBInfo->P3c4, 0x25, pVBInfo->SR25[0]);
340         printk("15");
341
342         if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
343                 /* Set VB */
344                 XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
345                 XGINew_SetRegANDOR(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */
346                 XGINew_SetReg1(pVBInfo->Part1Port, 0x00, 0x00);
347                 temp1 = (unsigned char) XGINew_GetReg1(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */
348                 temp = (unsigned char) ((temp1 >> 4) & 0x0F);
349
350                 XGINew_SetReg1(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2));
351
352                 printk("16");
353
354                 XGINew_SetReg1(pVBInfo->Part1Port, 0x2E, 0x08); /* use VB */
355         } /* != XG20 */
356
357         XGINew_SetReg1(pVBInfo->P3c4, 0x27, 0x1F);
358
359         if ((HwDeviceExtension->jChipType == XG42)
360                         && XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */
361                 XGINew_SetReg1(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40);
362                 XGINew_SetReg1(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01);
363         } else {
364                 XGINew_SetReg1(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31);
365                 XGINew_SetReg1(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32);
366         }
367         XGINew_SetReg1(pVBInfo->P3c4, 0x33, *pVBInfo->pSR33);
368         printk("17");
369
370         /*
371          if (HwDeviceExtension->jChipType >= XG40)
372          SetPowerConsume (HwDeviceExtension, pVBInfo->P3c4);    */
373
374         if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
375                 if (XGI_BridgeIsOn(pVBInfo) == 1) {
376                         if (pVBInfo->IF_DEF_LVDS == 0) {
377                                 XGINew_SetReg1(pVBInfo->Part2Port, 0x00, 0x1C);
378                                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D);
379                                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E);
380                                 XGINew_SetReg1(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10);
381                                 XGINew_SetReg1(pVBInfo->Part4Port, 0x0F, 0x3F);
382                         }
383
384                         XGI_LockCRT2(HwDeviceExtension, pVBInfo);
385                 }
386         } /* != XG20 */
387         printk("18");
388
389         if (HwDeviceExtension->jChipType < XG40)
390                 XGINew_SetReg1(pVBInfo->P3d4, 0x83, 0x00);
391         printk("181");
392
393         if (HwDeviceExtension->bSkipSense == 0) {
394                 printk("182");
395
396                 XGI_SenseCRT1(pVBInfo);
397
398                 printk("183");
399                 /* XGINew_DetectMonitor(HwDeviceExtension); */
400                 pVBInfo->IF_DEF_CH7007 = 0;
401                 if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) {
402                         printk("184");
403                         XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */
404                         printk("185");
405
406                 }
407                 if (HwDeviceExtension->jChipType == XG21) {
408                         printk("186");
409
410                         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
411                         temp = GetXG21FPBits(pVBInfo);
412                         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x01, temp);
413                         printk("187");
414
415                 }
416                 if (HwDeviceExtension->jChipType == XG27) {
417                         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
418                         temp = GetXG27FPBits(pVBInfo);
419                         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x37, ~0x03, temp);
420                 }
421         }
422         printk("19");
423
424         if (HwDeviceExtension->jChipType >= XG40) {
425                 if (HwDeviceExtension->jChipType >= XG40)
426                         XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
427
428                 XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo);
429
430                 if (HwDeviceExtension->bSkipDramSizing == 1) {
431                         pSR = HwDeviceExtension->pSR;
432                         if (pSR != NULL) {
433                                 while (pSR->jIdx != 0xFF) {
434                                         XGINew_SetReg1(pVBInfo->P3c4, pSR->jIdx, pSR->jVal);
435                                         pSR++;
436                                 }
437                         }
438                         /* XGINew_SetDRAMModeRegister340(pVBInfo); */
439                 } /* SkipDramSizing */
440                 else {
441                         {
442                                 printk("20");
443                                 XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo);
444                         }
445                         printk("21");
446
447                 }
448         } /* XG40 */
449
450         printk("22");
451
452         /* SetDefExt2Regs begin */
453         /*
454         AGP = 1;
455         temp = (unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x3A);
456         temp &= 0x30;
457         if (temp == 0x30)
458                 AGP = 0;
459
460         if (AGP == 0)
461                 *pVBInfo->pSR21 &= 0xEF;
462
463         XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
464         if (AGP == 1)
465                 *pVBInfo->pSR22 &= 0x20;
466         XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22);
467         */
468         /* base = 0x80000000; */
469         /* OutPortLong(0xcf8, base); */
470         /* Temp = (InPortLong(0xcfc) & 0xFFFF); */
471         /* if (Temp == 0x1039) { */
472         XGINew_SetReg1(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE));
473         /* } else { */
474         /*      XGINew_SetReg1(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */
475         /* } */
476
477         XGINew_SetReg1(pVBInfo->P3c4, 0x21, *pVBInfo->pSR21);
478
479         printk("23");
480
481         XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo);
482         XGINew_SetModeScratch(HwDeviceExtension, pVBInfo);
483
484         printk("24");
485
486         XGINew_SetReg1(pVBInfo->P3d4, 0x8c, 0x87);
487         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31);
488         printk("25");
489
490         return 1;
491 } /* end of init */
492
493 /* ============== alan ====================== */
494
495 unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
496                                         struct vb_device_info *pVBInfo)
497 {
498         unsigned char data, temp;
499
500         if (HwDeviceExtension->jChipType < XG20) {
501                 if (*pVBInfo->pSoftSetting & SoftDRAMType) {
502                         data = *pVBInfo->pSoftSetting & 0x07;
503                         return data;
504                 } else {
505                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02;
506
507                         if (data == 0)
508                                 data = (XGINew_GetReg1(pVBInfo->P3c4, 0x3A) & 0x02) >> 1;
509
510                         return data;
511                 }
512         } else if (HwDeviceExtension->jChipType == XG27) {
513                 if (*pVBInfo->pSoftSetting & SoftDRAMType) {
514                         data = *pVBInfo->pSoftSetting & 0x07;
515                         return data;
516                 }
517                 temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3B);
518
519                 if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
520                         data = 0; /* DDR */
521                 else
522                         data = 1; /* DDRII */
523                 return data;
524         } else if (HwDeviceExtension->jChipType == XG21) {
525                 XGINew_SetRegAND(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */
526                 DelayUS(800);
527                 XGINew_SetRegOR(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
528                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */
529                 /* HOTPLUG_SUPPORT */
530                 /* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
531                 if (temp & 0x01) /* DVI read GPIOH */
532                         data = 1; /* DDRII */
533                 else
534                         data = 0; /* DDR */
535                 /* ~HOTPLUG_SUPPORT */
536                 XGINew_SetRegOR(pVBInfo->P3d4, 0xB4, 0x02);
537                 return data;
538         } else {
539                 data = XGINew_GetReg1(pVBInfo->P3d4, 0x97) & 0x01;
540
541                 if (data == 1)
542                         data++;
543
544                 return data;
545         }
546 }
547
548 static unsigned char XGINew_Get310DRAMType(struct vb_device_info *pVBInfo)
549 {
550         unsigned char data;
551
552         /* index = XGINew_GetReg1(pVBInfo->P3c4, 0x1A); */
553         /* index &= 07; */
554
555         if (*pVBInfo->pSoftSetting & SoftDRAMType)
556                 data = *pVBInfo->pSoftSetting & 0x03;
557         else
558                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x3a) & 0x03;
559
560         return data;
561 }
562
563 /*
564 void XGINew_Delay15us(unsigned long ulMicrsoSec)
565 {
566 }
567 */
568
569 static void XGINew_SDR_MRS(struct vb_device_info *pVBInfo)
570 {
571         unsigned short data;
572
573         data = XGINew_GetReg1(pVBInfo->P3c4, 0x16);
574         data &= 0x3F; /* SR16 D7=0,D6=0 */
575         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); /* enable mode register set(MRS) low */
576         /* XGINew_Delay15us(0x100); */
577         data |= 0x80; /* SR16 D7=1,D6=0 */
578         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data); /* enable mode register set(MRS) high */
579         /* XGINew_Delay15us(0x100); */
580 }
581
582 static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
583 {
584         XGINew_SetReg1(P3c4, 0x18, 0x01);
585         XGINew_SetReg1(P3c4, 0x19, 0x20);
586         XGINew_SetReg1(P3c4, 0x16, 0x00);
587         XGINew_SetReg1(P3c4, 0x16, 0x80);
588
589         if (*pVBInfo->pXGINew_DRAMTypeDefinition != 0x0C) { /* Samsung F Die */
590                 DelayUS(3000); /* Delay 67 x 3 Delay15us */
591                 XGINew_SetReg1(P3c4, 0x18, 0x00);
592                 XGINew_SetReg1(P3c4, 0x19, 0x20);
593                 XGINew_SetReg1(P3c4, 0x16, 0x00);
594                 XGINew_SetReg1(P3c4, 0x16, 0x80);
595         }
596
597         DelayUS(60);
598         XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
599         XGINew_SetReg1(P3c4, 0x19, 0x01);
600         XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[0]);
601         XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[1]);
602         DelayUS(1000);
603         XGINew_SetReg1(P3c4, 0x1B, 0x03);
604         DelayUS(500);
605         XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
606         XGINew_SetReg1(P3c4, 0x19, 0x00);
607         XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[2]);
608         XGINew_SetReg1(P3c4, 0x16, pVBInfo->SR16[3]);
609         XGINew_SetReg1(P3c4, 0x1B, 0x00);
610 }
611
612 static void XGINew_DDR2x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
613 {
614         XGINew_SetReg1(P3c4, 0x18, 0x00);
615         XGINew_SetReg1(P3c4, 0x19, 0x20);
616         XGINew_SetReg1(P3c4, 0x16, 0x00);
617         XGINew_SetReg1(P3c4, 0x16, 0x80);
618         DelayUS(60);
619         XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
620         /* XGINew_SetReg1(P3c4 ,0x18 ,0x31); */
621         XGINew_SetReg1(P3c4, 0x19, 0x01);
622         XGINew_SetReg1(P3c4, 0x16, 0x05);
623         XGINew_SetReg1(P3c4, 0x16, 0x85);
624         DelayUS(1000);
625         XGINew_SetReg1(P3c4, 0x1B, 0x03);
626         DelayUS(500);
627         /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
628         XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
629         XGINew_SetReg1(P3c4, 0x19, 0x00);
630         XGINew_SetReg1(P3c4, 0x16, 0x05);
631         XGINew_SetReg1(P3c4, 0x16, 0x85);
632         XGINew_SetReg1(P3c4, 0x1B, 0x00);
633 }
634
635 static void XGINew_DDRII_Bootup_XG27(
636                         struct xgi_hw_device_info *HwDeviceExtension,
637                         unsigned long P3c4, struct vb_device_info *pVBInfo)
638 {
639         unsigned long P3d4 = P3c4 + 0x10;
640         XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
641         XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
642
643         /* Set Double Frequency */
644         /* XGINew_SetReg1(P3d4, 0x97, 0x11); *//* CR97 */
645         XGINew_SetReg1(P3d4, 0x97, *pVBInfo->pXGINew_CR97); /* CR97 */
646
647         DelayUS(200);
648
649         XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS2 */
650         XGINew_SetReg1(P3c4, 0x19, 0x80); /* Set SR19 */
651         XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
652         DelayUS(15);
653         XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
654         DelayUS(15);
655
656         XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS3 */
657         XGINew_SetReg1(P3c4, 0x19, 0xC0); /* Set SR19 */
658         XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
659         DelayUS(15);
660         XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
661         DelayUS(15);
662
663         XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS1 */
664         XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
665         XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
666         DelayUS(30);
667         XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
668         DelayUS(15);
669
670         XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Enable */
671         XGINew_SetReg1(P3c4, 0x19, 0x0A); /* Set SR19 */
672         XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
673         DelayUS(30);
674         XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
675         XGINew_SetReg1(P3c4, 0x16, 0x80); /* Set SR16 */
676         /* DelayUS(15); */
677
678         XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B */
679         DelayUS(60);
680         XGINew_SetReg1(P3c4, 0x1B, 0x00); /* Set SR1B */
681
682         XGINew_SetReg1(P3c4, 0x18, 0x42); /* Set SR18 */ /* MRS, DLL Reset */
683         XGINew_SetReg1(P3c4, 0x19, 0x08); /* Set SR19 */
684         XGINew_SetReg1(P3c4, 0x16, 0x00); /* Set SR16 */
685
686         DelayUS(30);
687         XGINew_SetReg1(P3c4, 0x16, 0x83); /* Set SR16 */
688         DelayUS(15);
689
690         XGINew_SetReg1(P3c4, 0x18, 0x80); /* Set SR18 */ /* MRS, ODT */
691         XGINew_SetReg1(P3c4, 0x19, 0x46); /* Set SR19 */
692         XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
693         DelayUS(30);
694         XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
695         DelayUS(15);
696
697         XGINew_SetReg1(P3c4, 0x18, 0x00); /* Set SR18 */ /* EMRS */
698         XGINew_SetReg1(P3c4, 0x19, 0x40); /* Set SR19 */
699         XGINew_SetReg1(P3c4, 0x16, 0x20); /* Set SR16 */
700         DelayUS(30);
701         XGINew_SetReg1(P3c4, 0x16, 0xA0); /* Set SR16 */
702         DelayUS(15);
703
704         XGINew_SetReg1(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */
705         DelayUS(200);
706
707 }
708
709 static void XGINew_DDR2_MRS_XG20(struct xgi_hw_device_info *HwDeviceExtension,
710                 unsigned long P3c4, struct vb_device_info *pVBInfo)
711 {
712         unsigned long P3d4 = P3c4 + 0x10;
713
714         XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
715         XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
716
717         XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */
718
719         DelayUS(200);
720         XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */
721         XGINew_SetReg1(P3c4, 0x19, 0x80);
722         XGINew_SetReg1(P3c4, 0x16, 0x05);
723         XGINew_SetReg1(P3c4, 0x16, 0x85);
724
725         XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */
726         XGINew_SetReg1(P3c4, 0x19, 0xC0);
727         XGINew_SetReg1(P3c4, 0x16, 0x05);
728         XGINew_SetReg1(P3c4, 0x16, 0x85);
729
730         XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */
731         XGINew_SetReg1(P3c4, 0x19, 0x40);
732         XGINew_SetReg1(P3c4, 0x16, 0x05);
733         XGINew_SetReg1(P3c4, 0x16, 0x85);
734
735         /* XGINew_SetReg1(P3c4, 0x18, 0x52); */ /* MRS1 */
736         XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
737         XGINew_SetReg1(P3c4, 0x19, 0x02);
738         XGINew_SetReg1(P3c4, 0x16, 0x05);
739         XGINew_SetReg1(P3c4, 0x16, 0x85);
740
741         DelayUS(15);
742         XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
743         DelayUS(30);
744         XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */
745         DelayUS(100);
746
747         /* XGINew_SetReg1(P3c4 ,0x18, 0x52); */ /* MRS2 */
748         XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
749         XGINew_SetReg1(P3c4, 0x19, 0x00);
750         XGINew_SetReg1(P3c4, 0x16, 0x05);
751         XGINew_SetReg1(P3c4, 0x16, 0x85);
752
753         DelayUS(200);
754 }
755
756 #if 0
757 static void XGINew_DDR2_MRS_XG27(struct xgi_hw_device_info *HwDeviceExtension,
758                 unsigned long P3c4, struct vb_device_info *pVBInfo)
759 {
760         unsigned long P3d4 = P3c4 + 0x10;
761
762         XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
763         XGINew_SetMemoryClock(HwDeviceExtension , pVBInfo);
764
765         XGINew_SetReg1(P3d4, 0x97, 0x11); /* CR97 */
766         DelayUS(200);
767         XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS2 */
768         XGINew_SetReg1(P3c4, 0x19, 0x80);
769
770         XGINew_SetReg1(P3c4, 0x16, 0x10);
771         DelayUS(15); /* 06/11/23 XG27 A0 for CKE enable */
772         XGINew_SetReg1(P3c4, 0x16, 0x90);
773
774         XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS3 */
775         XGINew_SetReg1(P3c4, 0x19, 0xC0);
776
777         XGINew_SetReg1(P3c4, 0x16, 0x00);
778         DelayUS(15); /* 06/11/22 XG27 A0 */
779         XGINew_SetReg1(P3c4, 0x16, 0x80);
780
781         XGINew_SetReg1(P3c4, 0x18, 0x00); /* EMRS1 */
782         XGINew_SetReg1(P3c4, 0x19, 0x40);
783
784         XGINew_SetReg1(P3c4, 0x16, 0x00);
785         DelayUS(15); /* 06/11/22 XG27 A0 */
786         XGINew_SetReg1(P3c4, 0x16, 0x80);
787
788         XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
789         XGINew_SetReg1(P3c4, 0x19, 0x06); /* [Billy]06/11/22 DLL Reset for XG27 Hynix DRAM */
790
791         XGINew_SetReg1(P3c4, 0x16, 0x00);
792         DelayUS(15); /* 06/11/23 XG27 A0 */
793         XGINew_SetReg1(P3c4, 0x16, 0x80);
794
795         DelayUS(30); /* 06/11/23 XG27 A0 Start Auto-PreCharge */
796         XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
797         DelayUS(60);
798         XGINew_SetReg1(P3c4, 0x1B, 0x00); /* SR1B */
799
800         XGINew_SetReg1(P3c4, 0x18, 0x42); /* MRS1 */
801         XGINew_SetReg1(P3c4, 0x19, 0x04); /* DLL without Reset for XG27 Hynix DRAM */
802
803         XGINew_SetReg1(P3c4, 0x16, 0x00);
804         DelayUS(30);
805         XGINew_SetReg1(P3c4, 0x16, 0x80);
806
807         XGINew_SetReg1(P3c4, 0x18, 0x80); /* XG27 OCD ON */
808         XGINew_SetReg1(P3c4, 0x19, 0x46);
809
810         XGINew_SetReg1(P3c4, 0x16, 0x00);
811         DelayUS(30);
812         XGINew_SetReg1(P3c4, 0x16, 0x80);
813
814         XGINew_SetReg1(P3c4, 0x18, 0x00);
815         XGINew_SetReg1(P3c4, 0x19, 0x40);
816
817         XGINew_SetReg1(P3c4, 0x16, 0x00);
818         DelayUS(30);
819         XGINew_SetReg1(P3c4, 0x16, 0x80);
820
821         DelayUS(15); /* Start Auto-PreCharge */
822         XGINew_SetReg1(P3c4, 0x1B, 0x04); /* SR1B */
823         DelayUS(200);
824         XGINew_SetReg1(P3c4, 0x1B, 0x03); /* SR1B */
825
826 }
827 #endif
828
829 static void XGINew_DDR1x_DefaultRegister(
830                 struct xgi_hw_device_info *HwDeviceExtension,
831                 unsigned long Port, struct vb_device_info *pVBInfo)
832 {
833         unsigned long P3d4 = Port, P3c4 = Port - 0x10;
834
835         if (HwDeviceExtension->jChipType >= XG20) {
836                 XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
837                 XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
838                 XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
839                 XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
840
841                 XGINew_SetReg1(P3d4, 0x98, 0x01);
842                 XGINew_SetReg1(P3d4, 0x9A, 0x02);
843
844                 XGINew_DDR1x_MRS_XG20(P3c4, pVBInfo);
845         } else {
846                 XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
847
848                 switch (HwDeviceExtension->jChipType) {
849                 case XG41:
850                 case XG42:
851                         XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
852                         XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
853                         XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
854                         break;
855                 default:
856                         XGINew_SetReg1(P3d4, 0x82, 0x88);
857                         XGINew_SetReg1(P3d4, 0x86, 0x00);
858                         XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
859                         XGINew_SetReg1(P3d4, 0x86, 0x88);
860                         XGINew_GetReg1(P3d4, 0x86);
861                         XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]);
862                         XGINew_SetReg1(P3d4, 0x82, 0x77);
863                         XGINew_SetReg1(P3d4, 0x85, 0x00);
864                         XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
865                         XGINew_SetReg1(P3d4, 0x85, 0x88);
866                         XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
867                         XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
868                         XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
869                         break;
870                 }
871
872                 XGINew_SetReg1(P3d4, 0x97, 0x00);
873                 XGINew_SetReg1(P3d4, 0x98, 0x01);
874                 XGINew_SetReg1(P3d4, 0x9A, 0x02);
875                 XGINew_DDR1x_MRS_340(P3c4, pVBInfo);
876         }
877 }
878
879 #if 0
880
881 static void XGINew_DDR2x_DefaultRegister(
882                 struct xgi_hw_device_info *HwDeviceExtension,
883                 unsigned long Port, struct vb_device_info *pVBInfo)
884 {
885         unsigned long P3d4 = Port ,
886         P3c4 = Port - 0x10;
887
888         XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
889
890         /* 20040906 Hsuan modify CR82, CR85, CR86 for XG42 */
891         switch (HwDeviceExtension->jChipType) {
892         case XG41:
893         case XG42:
894                 XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
895                 XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
896                 XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
897                 break;
898         default:
899                 /* keep following setting sequence, each setting in the same reg insert idle */
900                 XGINew_SetReg1(P3d4, 0x82, 0x88);
901                 XGINew_SetReg1(P3d4, 0x86, 0x00);
902                 XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
903                 XGINew_SetReg1(P3d4, 0x86, 0x88);
904                 XGINew_SetReg1(P3d4, 0x82, 0x77);
905                 XGINew_SetReg1(P3d4, 0x85, 0x00);
906                 XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
907                 XGINew_SetReg1(P3d4, 0x85, 0x88);
908                 XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
909                 XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
910                 XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
911         }
912         XGINew_SetReg1(P3d4, 0x97, 0x11);
913         if (HwDeviceExtension->jChipType == XG42)
914                 XGINew_SetReg1(P3d4, 0x98, 0x01);
915         else
916                 XGINew_SetReg1(P3d4, 0x98, 0x03);
917
918         XGINew_SetReg1(P3d4, 0x9A, 0x02);
919
920         XGINew_DDR2x_MRS_340(P3c4, pVBInfo);
921 }
922 #endif
923
924 static void XGINew_DDR2_DefaultRegister(
925                 struct xgi_hw_device_info *HwDeviceExtension,
926                 unsigned long Port, struct vb_device_info *pVBInfo)
927 {
928         unsigned long P3d4 = Port, P3c4 = Port - 0x10;
929
930         /* keep following setting sequence, each setting in the same reg insert idle */
931         XGINew_SetReg1(P3d4, 0x82, 0x77);
932         XGINew_SetReg1(P3d4, 0x86, 0x00);
933         XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
934         XGINew_SetReg1(P3d4, 0x86, 0x88);
935         XGINew_GetReg1(P3d4, 0x86); /* Insert read command for delay */
936         XGINew_SetReg1(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
937         XGINew_SetReg1(P3d4, 0x82, 0x77);
938         XGINew_SetReg1(P3d4, 0x85, 0x00);
939         XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
940         XGINew_SetReg1(P3d4, 0x85, 0x88);
941         XGINew_GetReg1(P3d4, 0x85); /* Insert read command for delay */
942         XGINew_SetReg1(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
943         if (HwDeviceExtension->jChipType == XG27)
944                 XGINew_SetReg1(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
945         else
946                 XGINew_SetReg1(P3d4, 0x82, 0xA8); /* CR82 */
947
948         XGINew_SetReg1(P3d4, 0x98, 0x01);
949         XGINew_SetReg1(P3d4, 0x9A, 0x02);
950         if (HwDeviceExtension->jChipType == XG27)
951                 XGINew_DDRII_Bootup_XG27(HwDeviceExtension, P3c4, pVBInfo);
952         else
953                 XGINew_DDR2_MRS_XG20(HwDeviceExtension, P3c4, pVBInfo);
954 }
955
956 void XGINew_SetDRAMDefaultRegister340(
957                 struct xgi_hw_device_info *HwDeviceExtension,
958                 unsigned long Port, struct vb_device_info *pVBInfo)
959 {
960         unsigned char temp, temp1, temp2, temp3, i, j, k;
961
962         unsigned long P3d4 = Port, P3c4 = Port - 0x10;
963
964         XGINew_SetReg1(P3d4, 0x6D, pVBInfo->CR40[8][XGINew_RAMType]);
965         XGINew_SetReg1(P3d4, 0x68, pVBInfo->CR40[5][XGINew_RAMType]);
966         XGINew_SetReg1(P3d4, 0x69, pVBInfo->CR40[6][XGINew_RAMType]);
967         XGINew_SetReg1(P3d4, 0x6A, pVBInfo->CR40[7][XGINew_RAMType]);
968
969         temp2 = 0;
970         for (i = 0; i < 4; i++) {
971                 temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */
972                 for (j = 0; j < 4; j++) {
973                         temp1 = ((temp >> (2 * j)) & 0x03) << 2;
974                         temp2 |= temp1;
975                         XGINew_SetReg1(P3d4, 0x6B, temp2);
976                         XGINew_GetReg1(P3d4, 0x6B); /* Insert read command for delay */
977                         temp2 &= 0xF0;
978                         temp2 += 0x10;
979                 }
980         }
981
982         temp2 = 0;
983         for (i = 0; i < 4; i++) {
984                 temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */
985                 for (j = 0; j < 4; j++) {
986                         temp1 = ((temp >> (2 * j)) & 0x03) << 2;
987                         temp2 |= temp1;
988                         XGINew_SetReg1(P3d4, 0x6E, temp2);
989                         XGINew_GetReg1(P3d4, 0x6E); /* Insert read command for delay */
990                         temp2 &= 0xF0;
991                         temp2 += 0x10;
992                 }
993         }
994
995         temp3 = 0;
996         for (k = 0; k < 4; k++) {
997                 XGINew_SetRegANDOR(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */
998                 temp2 = 0;
999                 for (i = 0; i < 8; i++) {
1000                         temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */
1001                         for (j = 0; j < 4; j++) {
1002                                 temp1 = (temp >> (2 * j)) & 0x03;
1003                                 temp2 |= temp1;
1004                                 XGINew_SetReg1(P3d4, 0x6F, temp2);
1005                                 XGINew_GetReg1(P3d4, 0x6F); /* Insert read command for delay */
1006                                 temp2 &= 0xF8;
1007                                 temp2 += 0x08;
1008                         }
1009                 }
1010                 temp3 += 0x01;
1011         }
1012
1013         XGINew_SetReg1(P3d4, 0x80, pVBInfo->CR40[9][XGINew_RAMType]); /* CR80 */
1014         XGINew_SetReg1(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */
1015
1016         temp2 = 0x80;
1017         temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */
1018         for (j = 0; j < 4; j++) {
1019                 temp1 = (temp >> (2 * j)) & 0x03;
1020                 temp2 |= temp1;
1021                 XGINew_SetReg1(P3d4, 0x89, temp2);
1022                 XGINew_GetReg1(P3d4, 0x89); /* Insert read command for delay */
1023                 temp2 &= 0xF0;
1024                 temp2 += 0x10;
1025         }
1026
1027         temp = pVBInfo->CR89[XGINew_RAMType][1];
1028         temp1 = temp & 0x03;
1029         temp2 |= temp1;
1030         XGINew_SetReg1(P3d4, 0x89, temp2);
1031
1032         temp = pVBInfo->CR40[3][XGINew_RAMType];
1033         temp1 = temp & 0x0F;
1034         temp2 = (temp >> 4) & 0x07;
1035         temp3 = temp & 0x80;
1036         XGINew_SetReg1(P3d4, 0x45, temp1); /* CR45 */
1037         XGINew_SetReg1(P3d4, 0x99, temp2); /* CR99 */
1038         XGINew_SetRegOR(P3d4, 0x40, temp3); /* CR40_D[7] */
1039         XGINew_SetReg1(P3d4, 0x41, pVBInfo->CR40[0][XGINew_RAMType]); /* CR41 */
1040
1041         if (HwDeviceExtension->jChipType == XG27)
1042                 XGINew_SetReg1(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */
1043
1044         for (j = 0; j <= 6; j++)
1045                 XGINew_SetReg1(P3d4, (0x90 + j),
1046                                 pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */
1047
1048         for (j = 0; j <= 2; j++)
1049                 XGINew_SetReg1(P3d4, (0xC3 + j),
1050                                 pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */
1051
1052         for (j = 0; j < 2; j++)
1053                 XGINew_SetReg1(P3d4, (0x8A + j),
1054                                 pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */
1055
1056         if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42))
1057                 XGINew_SetReg1(P3d4, 0x8C, 0x87);
1058
1059         XGINew_SetReg1(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */
1060
1061         XGINew_SetReg1(P3d4, 0x83, 0x09); /* CR83 */
1062         XGINew_SetReg1(P3d4, 0x87, 0x00); /* CR87 */
1063         XGINew_SetReg1(P3d4, 0xCF, *pVBInfo->pCRCF); /* CRCF */
1064         if (XGINew_RAMType) {
1065                 /* XGINew_SetReg1(P3c4, 0x17, 0xC0); */ /* SR17 DDRII */
1066                 XGINew_SetReg1(P3c4, 0x17, 0x80); /* SR17 DDRII */
1067                 if (HwDeviceExtension->jChipType == XG27)
1068                         XGINew_SetReg1(P3c4, 0x17, 0x02); /* SR17 DDRII */
1069
1070         } else {
1071                 XGINew_SetReg1(P3c4, 0x17, 0x00); /* SR17 DDR */
1072         }
1073         XGINew_SetReg1(P3c4, 0x1A, 0x87); /* SR1A */
1074
1075         temp = XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
1076         if (temp == 0) {
1077                 XGINew_DDR1x_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
1078         } else {
1079                 XGINew_SetReg1(P3d4, 0xB0, 0x80); /* DDRII Dual frequency mode */
1080                 XGINew_DDR2_DefaultRegister(HwDeviceExtension, P3d4, pVBInfo);
1081         }
1082         XGINew_SetReg1(P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
1083 }
1084
1085 static void XGINew_DDR_MRS(struct vb_device_info *pVBInfo)
1086 {
1087         unsigned short data;
1088
1089         volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
1090
1091         /* SR16 <- 1F,DF,2F,AF */
1092         /* yriver modified SR16 <- 0F,DF,0F,AF */
1093         /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
1094         data = pVideoMemory[0xFB];
1095         /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x16); */
1096
1097         data &= 0x0F;
1098         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1099         data |= 0xC0;
1100         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1101         data &= 0x0F;
1102         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1103         data |= 0x80;
1104         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1105         data &= 0x0F;
1106         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1107         data |= 0xD0;
1108         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1109         data &= 0x0F;
1110         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1111         data |= 0xA0;
1112         XGINew_SetReg1(pVBInfo->P3c4, 0x16, data);
1113         /*
1114         else {
1115                 data &= 0x0F;
1116                 data |= 0x10;
1117                 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1118
1119                 if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10)) {
1120                         data &= 0x0F;
1121                 }
1122
1123                 data |= 0xC0;
1124                 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1125
1126                 data &= 0x0F;
1127                 data |= 0x20;
1128                 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1129                 if (!(pVBInfo->SR15[1][XGINew_RAMType] & 0x10)) {
1130                         data &= 0x0F;
1131                 }
1132
1133                 data |= 0x80;
1134                 XGINew_SetReg1(pVBInfo->P3c4,0x16,data);
1135         }
1136         */
1137 }
1138
1139 /* check if read cache pointer is correct */
1140
1141 static void XGINew_VerifyMclk(struct xgi_hw_device_info *HwDeviceExtension,
1142                 struct vb_device_info *pVBInfo)
1143 {
1144         unsigned char *pVideoMemory = pVBInfo->FBAddr;
1145         unsigned char i, j;
1146         unsigned short Temp, SR21;
1147
1148         pVideoMemory[0] = 0xaa; /* alan */
1149         pVideoMemory[16] = 0x55; /* note: PCI read cache is off */
1150
1151         if ((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
1152                 for (i = 0, j = 16; i < 2; i++, j += 16) {
1153                         SR21 = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
1154                         Temp = SR21 & 0xFB; /* disable PCI post write buffer empty gating */
1155                         XGINew_SetReg1(pVBInfo->P3c4, 0x21, Temp);
1156
1157                         Temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3C);
1158                         Temp |= 0x01; /* MCLK reset */
1159
1160                         Temp = XGINew_GetReg1(pVBInfo->P3c4, 0x3C);
1161                         Temp &= 0xFE; /* MCLK normal operation */
1162
1163                         XGINew_SetReg1(pVBInfo->P3c4, 0x21, SR21);
1164
1165                         pVideoMemory[16 + j] = j;
1166                         if (pVideoMemory[16 + j] == j) {
1167                                 pVideoMemory[j] = j;
1168                                 break;
1169                         }
1170                 }
1171         }
1172 }
1173
1174 void XGINew_SetDRAMSize_340(struct xgi_hw_device_info *HwDeviceExtension,
1175                 struct vb_device_info *pVBInfo)
1176 {
1177         unsigned short data;
1178
1179         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
1180         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
1181
1182         XGISetModeNew(HwDeviceExtension, 0x2e);
1183
1184         data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
1185         XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
1186         XGI_DisplayOff(HwDeviceExtension, pVBInfo);
1187
1188         /* data = XGINew_GetReg1(pVBInfo->P3c4, 0x1); */
1189         /* data |= 0x20 ; */
1190         /* XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */
1191         XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
1192         data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
1193         XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
1194 }
1195
1196 void XGINew_SetDRAMSize_310(struct xgi_hw_device_info *HwDeviceExtension,
1197                 struct vb_device_info *pVBInfo)
1198 {
1199         unsigned short data;
1200         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase, pVBInfo->FBAddr
1201                         = HwDeviceExtension->pjVideoMemoryAddress;
1202 #ifdef XGI301
1203         /* XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x40); */
1204 #endif
1205
1206 #ifdef XGI302   /* alan,should change value */
1207         XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x4D);
1208         XGINew_SetReg1(pVBInfo->P3d4, 0x31, 0xc0);
1209         XGINew_SetReg1(pVBInfo->P3d4, 0x34, 0x3F);
1210 #endif
1211
1212         XGISetModeNew(HwDeviceExtension, 0x2e);
1213
1214         data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
1215         XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
1216
1217         data = XGINew_GetReg1(pVBInfo->P3c4, 0x1);
1218         data |= 0x20;
1219         XGINew_SetReg1(pVBInfo->P3c4, 0x01, data); /* Turn OFF Display */
1220
1221         data = XGINew_GetReg1(pVBInfo->P3c4, 0x16);
1222
1223         XGINew_SetReg1(pVBInfo->P3c4, 0x16, (unsigned short) (data | 0x0F)); /* assume lowest speed DRAM */
1224
1225         XGINew_SetDRAMModeRegister(pVBInfo);
1226         XGINew_DisableRefresh(HwDeviceExtension, pVBInfo);
1227         XGINew_CheckBusWidth_310(pVBInfo);
1228         XGINew_VerifyMclk(HwDeviceExtension, pVBInfo); /* alan 2000/7/3 */
1229
1230         if (XGINew_Get310DRAMType(pVBInfo) < 2)
1231                 XGINew_SDRSizing(pVBInfo);
1232         else
1233                 XGINew_DDRSizing(pVBInfo);
1234
1235         XGINew_SetReg1(pVBInfo->P3c4, 0x16, pVBInfo->SR15[1][XGINew_RAMType]); /* restore SR16 */
1236
1237         XGINew_EnableRefresh(HwDeviceExtension, pVBInfo);
1238         data = XGINew_GetReg1(pVBInfo->P3c4, 0x21);
1239         XGINew_SetReg1(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
1240 }
1241
1242 void XGINew_SetDRAMModeRegister340(struct xgi_hw_device_info *HwDeviceExtension)
1243 {
1244         unsigned char data;
1245         struct vb_device_info VBINF;
1246         struct vb_device_info *pVBInfo = &VBINF;
1247         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
1248         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
1249         pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
1250         pVBInfo->ISXPDOS = 0;
1251
1252         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
1253         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
1254         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
1255         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
1256         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
1257         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
1258         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
1259         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
1260         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
1261         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
1262         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
1263         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
1264         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
1265         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
1266         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
1267         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
1268         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
1269         if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
1270                 XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
1271
1272         InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
1273
1274         ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
1275
1276         if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0) {
1277                 data = (XGINew_GetReg1(pVBInfo->P3c4, 0x39) & 0x02) >> 1;
1278                 if (data == 0x01)
1279                         XGINew_DDR2x_MRS_340(pVBInfo->P3c4, pVBInfo);
1280                 else
1281                         XGINew_DDR1x_MRS_340(pVBInfo->P3c4, pVBInfo);
1282         } else {
1283                 XGINew_DDR2_MRS_XG20(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
1284         }
1285         XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03);
1286 }
1287
1288 void XGINew_SetDRAMModeRegister(struct vb_device_info *pVBInfo)
1289 {
1290         if (XGINew_Get310DRAMType(pVBInfo) < 2) {
1291                 XGINew_SDR_MRS(pVBInfo);
1292         } else {
1293                 /* SR16 <- 0F,CF,0F,8F */
1294                 XGINew_DDR_MRS(pVBInfo);
1295         }
1296 }
1297
1298 void XGINew_DisableRefresh(struct xgi_hw_device_info *HwDeviceExtension,
1299                 struct vb_device_info *pVBInfo)
1300 {
1301         unsigned short data;
1302
1303         data = XGINew_GetReg1(pVBInfo->P3c4, 0x1B);
1304         data &= 0xF8;
1305         XGINew_SetReg1(pVBInfo->P3c4, 0x1B, data);
1306
1307 }
1308
1309 void XGINew_EnableRefresh(struct xgi_hw_device_info *HwDeviceExtension,
1310                 struct vb_device_info *pVBInfo)
1311 {
1312
1313         XGINew_SetReg1(pVBInfo->P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
1314
1315 }
1316
1317 static void XGINew_DisableChannelInterleaving(int index,
1318                 unsigned short XGINew_DDRDRAM_TYPE[][5],
1319                 struct vb_device_info *pVBInfo)
1320 {
1321         unsigned short data;
1322
1323         data = XGINew_GetReg1(pVBInfo->P3c4, 0x15);
1324         data &= 0x1F;
1325
1326         switch (XGINew_DDRDRAM_TYPE[index][3]) {
1327         case 64:
1328                 data |= 0;
1329                 break;
1330         case 32:
1331                 data |= 0x20;
1332                 break;
1333         case 16:
1334                 data |= 0x40;
1335                 break;
1336         case 4:
1337                 data |= 0x60;
1338                 break;
1339         default:
1340                 break;
1341         }
1342         XGINew_SetReg1(pVBInfo->P3c4, 0x15, data);
1343 }
1344
1345 static void XGINew_SetDRAMSizingType(int index,
1346                 unsigned short DRAMTYPE_TABLE[][5],
1347                 struct vb_device_info *pVBInfo)
1348 {
1349         unsigned short data;
1350
1351         data = DRAMTYPE_TABLE[index][4];
1352         XGINew_SetRegANDOR(pVBInfo->P3c4, 0x13, 0x80, data);
1353         DelayUS(15);
1354         /* should delay 50 ns */
1355 }
1356
1357 void XGINew_CheckBusWidth_310(struct vb_device_info *pVBInfo)
1358 {
1359         unsigned short data;
1360         volatile unsigned long *pVideoMemory;
1361
1362         pVideoMemory = (unsigned long *) pVBInfo->FBAddr;
1363
1364         if (XGINew_Get310DRAMType(pVBInfo) < 2) {
1365                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x00);
1366                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x12);
1367                 /* should delay */
1368                 XGINew_SDR_MRS(pVBInfo);
1369
1370                 XGINew_ChannelAB = 0;
1371                 XGINew_DataBusWidth = 128;
1372                 pVideoMemory[0] = 0x01234567L;
1373                 pVideoMemory[1] = 0x456789ABL;
1374                 pVideoMemory[2] = 0x89ABCDEFL;
1375                 pVideoMemory[3] = 0xCDEF0123L;
1376                 pVideoMemory[4] = 0x55555555L;
1377                 pVideoMemory[5] = 0x55555555L;
1378                 pVideoMemory[6] = 0xFFFFFFFFL;
1379                 pVideoMemory[7] = 0xFFFFFFFFL;
1380
1381                 if ((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2]
1382                                 != 0x89ABCDEFL)) {
1383                         /* ChannelA64Bit */
1384                         XGINew_DataBusWidth = 64;
1385                         XGINew_ChannelAB = 0;
1386                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x14);
1387                         XGINew_SetReg1(pVBInfo->P3c4, 0x14,
1388                                         (unsigned short) (data & 0xFD));
1389                 }
1390
1391                 if ((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0]
1392                                 != 0x01234567L)) {
1393                         /* ChannelB64Bit */
1394                         XGINew_DataBusWidth = 64;
1395                         XGINew_ChannelAB = 1;
1396                         data = XGINew_GetReg1(pVBInfo->P3c4, 0x14);
1397                         XGINew_SetReg1(pVBInfo->P3c4, 0x14,
1398                                         (unsigned short) ((data & 0xFD) | 0x01));
1399                 }
1400
1401                 return;
1402         } else {
1403                 /* DDR Dual channel */
1404                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x00);
1405                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x02); /* Channel A, 64bit */
1406                 /* should delay */
1407                 XGINew_DDR_MRS(pVBInfo);
1408
1409                 XGINew_ChannelAB = 0;
1410                 XGINew_DataBusWidth = 64;
1411                 pVideoMemory[0] = 0x01234567L;
1412                 pVideoMemory[1] = 0x456789ABL;
1413                 pVideoMemory[2] = 0x89ABCDEFL;
1414                 pVideoMemory[3] = 0xCDEF0123L;
1415                 pVideoMemory[4] = 0x55555555L;
1416                 pVideoMemory[5] = 0x55555555L;
1417                 pVideoMemory[6] = 0xAAAAAAAAL;
1418                 pVideoMemory[7] = 0xAAAAAAAAL;
1419
1420                 if (pVideoMemory[1] == 0x456789ABL) {
1421                         if (pVideoMemory[0] == 0x01234567L) {
1422                                 /* Channel A 64bit */
1423                                 return;
1424                         }
1425                 } else {
1426                         if (pVideoMemory[0] == 0x01234567L) {
1427                                 /* Channel A 32bit */
1428                                 XGINew_DataBusWidth = 32;
1429                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x00);
1430                                 return;
1431                         }
1432                 }
1433
1434                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x03); /* Channel B, 64bit */
1435                 XGINew_DDR_MRS(pVBInfo);
1436
1437                 XGINew_ChannelAB = 1;
1438                 XGINew_DataBusWidth = 64;
1439                 pVideoMemory[0] = 0x01234567L;
1440                 pVideoMemory[1] = 0x456789ABL;
1441                 pVideoMemory[2] = 0x89ABCDEFL;
1442                 pVideoMemory[3] = 0xCDEF0123L;
1443                 pVideoMemory[4] = 0x55555555L;
1444                 pVideoMemory[5] = 0x55555555L;
1445                 pVideoMemory[6] = 0xAAAAAAAAL;
1446                 pVideoMemory[7] = 0xAAAAAAAAL;
1447
1448                 if (pVideoMemory[1] == 0x456789ABL) {
1449                         /* Channel B 64 */
1450                         if (pVideoMemory[0] == 0x01234567L) {
1451                                 /* Channel B 64bit */
1452                                 return;
1453                         } else {
1454                                 /* error */
1455                         }
1456                 } else {
1457                         if (pVideoMemory[0] == 0x01234567L) {
1458                                 /* Channel B 32 */
1459                                 XGINew_DataBusWidth = 32;
1460                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x01);
1461                         } else {
1462                                 /* error */
1463                         }
1464                 }
1465         }
1466 }
1467
1468 static int XGINew_SetRank(int index, unsigned char RankNo,
1469                 unsigned char XGINew_ChannelAB,
1470                 unsigned short DRAMTYPE_TABLE[][5],
1471                 struct vb_device_info *pVBInfo)
1472 {
1473         unsigned short data;
1474         int RankSize;
1475
1476         if ((RankNo == 2) && (DRAMTYPE_TABLE[index][0] == 2))
1477                 return 0;
1478
1479         RankSize = DRAMTYPE_TABLE[index][3] / 2 * XGINew_DataBusWidth / 32;
1480
1481         if ((RankNo * RankSize) <= 128) {
1482                 data = 0;
1483
1484                 while ((RankSize >>= 1) > 0)
1485                         data += 0x10;
1486
1487                 data |= (RankNo - 1) << 2;
1488                 data |= (XGINew_DataBusWidth / 64) & 2;
1489                 data |= XGINew_ChannelAB;
1490                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, data);
1491                 /* should delay */
1492                 XGINew_SDR_MRS(pVBInfo);
1493                 return 1;
1494         } else {
1495                 return 0;
1496         }
1497 }
1498
1499 static int XGINew_SetDDRChannel(int index, unsigned char ChannelNo,
1500                 unsigned char XGINew_ChannelAB,
1501                 unsigned short DRAMTYPE_TABLE[][5],
1502                 struct vb_device_info *pVBInfo)
1503 {
1504         unsigned short data;
1505         int RankSize;
1506
1507         RankSize = DRAMTYPE_TABLE[index][3] / 2 * XGINew_DataBusWidth / 32;
1508         /* RankSize = DRAMTYPE_TABLE[index][3]; */
1509         if (ChannelNo * RankSize <= 128) {
1510                 data = 0;
1511                 while ((RankSize >>= 1) > 0)
1512                         data += 0x10;
1513
1514                 if (ChannelNo == 2)
1515                         data |= 0x0C;
1516
1517                 data |= (XGINew_DataBusWidth / 32) & 2;
1518                 data |= XGINew_ChannelAB;
1519                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, data);
1520                 /* should delay */
1521                 XGINew_DDR_MRS(pVBInfo);
1522                 return 1;
1523         } else {
1524                 return 0;
1525         }
1526 }
1527
1528 static int XGINew_CheckColumn(int index, unsigned short DRAMTYPE_TABLE[][5],
1529                 struct vb_device_info *pVBInfo)
1530 {
1531         int i;
1532         unsigned long Increment, Position;
1533
1534         /* Increment = 1 << (DRAMTYPE_TABLE[index][2] + XGINew_DataBusWidth / 64 + 1); */
1535         Increment = 1 << (10 + XGINew_DataBusWidth / 64);
1536
1537         for (i = 0, Position = 0; i < 2; i++) {
1538                 *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
1539                 Position += Increment;
1540         }
1541
1542         for (i = 0, Position = 0; i < 2; i++) {
1543                 /* if ( pVBInfo->FBAddr[ Position ] != Position ) */
1544                 if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
1545                         return 0;
1546                 Position += Increment;
1547         }
1548         return 1;
1549 }
1550
1551 static int XGINew_CheckBanks(int index, unsigned short DRAMTYPE_TABLE[][5],
1552                 struct vb_device_info *pVBInfo)
1553 {
1554         int i;
1555         unsigned long Increment, Position;
1556
1557         Increment = 1 << (DRAMTYPE_TABLE[index][2] + XGINew_DataBusWidth / 64 + 2);
1558
1559         for (i = 0, Position = 0; i < 4; i++) {
1560                 /* pVBInfo->FBAddr[Position] = Position; */
1561                 *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
1562                 Position += Increment;
1563         }
1564
1565         for (i = 0, Position = 0; i < 4; i++) {
1566                 /* if (pVBInfo->FBAddr[Position] != Position) */
1567                 if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
1568                         return 0;
1569                 Position += Increment;
1570         }
1571         return 1;
1572 }
1573
1574 static int XGINew_CheckRank(int RankNo, int index,
1575                 unsigned short DRAMTYPE_TABLE[][5],
1576                 struct vb_device_info *pVBInfo)
1577 {
1578         int i;
1579         unsigned long Increment, Position;
1580
1581         Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1]
1582                         + DRAMTYPE_TABLE[index][0] + XGINew_DataBusWidth / 64
1583                         + RankNo);
1584
1585         for (i = 0, Position = 0; i < 2; i++) {
1586                 /* pVBInfo->FBAddr[Position] = Position; */
1587                 /* *((unsigned long *)(pVBInfo->FBAddr)) = Position; */
1588                 *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
1589                 Position += Increment;
1590         }
1591
1592         for (i = 0, Position = 0; i < 2; i++) {
1593                 /* if (pVBInfo->FBAddr[Position] != Position) */
1594                 /* if ((*(unsigned long *)(pVBInfo->FBAddr)) != Position) */
1595                 if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
1596                         return 0;
1597                 Position += Increment;
1598         }
1599         return 1;
1600 }
1601
1602 static int XGINew_CheckDDRRank(int RankNo, int index,
1603                 unsigned short DRAMTYPE_TABLE[][5],
1604                 struct vb_device_info *pVBInfo)
1605 {
1606         unsigned long Increment, Position;
1607         unsigned short data;
1608
1609         Increment = 1 << (DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1]
1610                         + DRAMTYPE_TABLE[index][0] + XGINew_DataBusWidth / 64
1611                         + RankNo);
1612
1613         Increment += Increment / 2;
1614
1615         Position = 0;
1616         *((unsigned long *) (pVBInfo->FBAddr + Position + 0)) = 0x01234567;
1617         *((unsigned long *) (pVBInfo->FBAddr + Position + 1)) = 0x456789AB;
1618         *((unsigned long *) (pVBInfo->FBAddr + Position + 2)) = 0x55555555;
1619         *((unsigned long *) (pVBInfo->FBAddr + Position + 3)) = 0x55555555;
1620         *((unsigned long *) (pVBInfo->FBAddr + Position + 4)) = 0xAAAAAAAA;
1621         *((unsigned long *) (pVBInfo->FBAddr + Position + 5)) = 0xAAAAAAAA;
1622
1623         if ((*(unsigned long *) (pVBInfo->FBAddr + 1)) == 0x456789AB)
1624                 return 1;
1625
1626         if ((*(unsigned long *) (pVBInfo->FBAddr + 0)) == 0x01234567)
1627                 return 0;
1628
1629         data = XGINew_GetReg1(pVBInfo->P3c4, 0x14);
1630         data &= 0xF3;
1631         data |= 0x0E;
1632         XGINew_SetReg1(pVBInfo->P3c4, 0x14, data);
1633         data = XGINew_GetReg1(pVBInfo->P3c4, 0x15);
1634         data += 0x20;
1635         XGINew_SetReg1(pVBInfo->P3c4, 0x15, data);
1636
1637         return 1;
1638 }
1639
1640 static int XGINew_CheckRanks(int RankNo, int index,
1641                 unsigned short DRAMTYPE_TABLE[][5],
1642                 struct vb_device_info *pVBInfo)
1643 {
1644         int r;
1645
1646         for (r = RankNo; r >= 1; r--) {
1647                 if (!XGINew_CheckRank(r, index, DRAMTYPE_TABLE, pVBInfo))
1648                         return 0;
1649         }
1650
1651         if (!XGINew_CheckBanks(index, DRAMTYPE_TABLE, pVBInfo))
1652                 return 0;
1653
1654         if (!XGINew_CheckColumn(index, DRAMTYPE_TABLE, pVBInfo))
1655                 return 0;
1656
1657         return 1;
1658 }
1659
1660 static int XGINew_CheckDDRRanks(int RankNo, int index,
1661                 unsigned short DRAMTYPE_TABLE[][5],
1662                 struct vb_device_info *pVBInfo)
1663 {
1664         int r;
1665
1666         for (r = RankNo; r >= 1; r--) {
1667                 if (!XGINew_CheckDDRRank(r, index, DRAMTYPE_TABLE, pVBInfo))
1668                         return 0;
1669         }
1670
1671         if (!XGINew_CheckBanks(index, DRAMTYPE_TABLE, pVBInfo))
1672                 return 0;
1673
1674         if (!XGINew_CheckColumn(index, DRAMTYPE_TABLE, pVBInfo))
1675                 return 0;
1676
1677         return 1;
1678 }
1679
1680 int XGINew_SDRSizing(struct vb_device_info *pVBInfo)
1681 {
1682         int i;
1683         unsigned char j;
1684
1685         for (i = 0; i < 13; i++) {
1686                 XGINew_SetDRAMSizingType(i, XGINew_SDRDRAM_TYPE, pVBInfo);
1687
1688                 for (j = 2; j > 0; j--) {
1689                         if (!XGINew_SetRank(i, (unsigned char) j, XGINew_ChannelAB, XGINew_SDRDRAM_TYPE, pVBInfo)) {
1690                                 continue;
1691                         } else {
1692                                 if (XGINew_CheckRanks(j, i, XGINew_SDRDRAM_TYPE, pVBInfo))
1693                                         return 1;
1694                         }
1695                 }
1696         }
1697         return 0;
1698 }
1699
1700 static unsigned short XGINew_SetDRAMSizeReg(int index,
1701                 unsigned short DRAMTYPE_TABLE[][5],
1702                 struct vb_device_info *pVBInfo)
1703 {
1704         unsigned short data = 0, memsize = 0;
1705         int RankSize;
1706         unsigned char ChannelNo;
1707
1708         RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 32;
1709         data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
1710         data &= 0x80;
1711
1712         if (data == 0x80)
1713                 RankSize *= 2;
1714
1715         data = 0;
1716
1717         if (XGINew_ChannelAB == 3)
1718                 ChannelNo = 4;
1719         else
1720                 ChannelNo = XGINew_ChannelAB;
1721
1722         if (ChannelNo * RankSize <= 256) {
1723                 while ((RankSize >>= 1) > 0)
1724                         data += 0x10;
1725
1726                 memsize = data >> 4;
1727
1728                 /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
1729                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
1730
1731                 /* data |= XGINew_ChannelAB << 2; */
1732                 /* data |= (XGINew_DataBusWidth / 64) << 1; */
1733                 /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
1734
1735                 /* should delay */
1736                 /* XGINew_SetDRAMModeRegister340(pVBInfo); */
1737         }
1738         return memsize;
1739 }
1740
1741 static unsigned short XGINew_SetDRAMSize20Reg(int index,
1742                 unsigned short DRAMTYPE_TABLE[][5],
1743                 struct vb_device_info *pVBInfo)
1744 {
1745         unsigned short data = 0, memsize = 0;
1746         int RankSize;
1747         unsigned char ChannelNo;
1748
1749         RankSize = DRAMTYPE_TABLE[index][3] * XGINew_DataBusWidth / 8;
1750         data = XGINew_GetReg1(pVBInfo->P3c4, 0x13);
1751         data &= 0x80;
1752
1753         if (data == 0x80)
1754                 RankSize *= 2;
1755
1756         data = 0;
1757
1758         if (XGINew_ChannelAB == 3)
1759                 ChannelNo = 4;
1760         else
1761                 ChannelNo = XGINew_ChannelAB;
1762
1763         if (ChannelNo * RankSize <= 256) {
1764                 while ((RankSize >>= 1) > 0)
1765                         data += 0x10;
1766
1767                 memsize = data >> 4;
1768
1769                 /* [2004/03/25] Vicent, Fix DRAM Sizing Error */
1770                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, (XGINew_GetReg1(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
1771                 DelayUS(15);
1772
1773                 /* data |= XGINew_ChannelAB << 2; */
1774                 /* data |= (XGINew_DataBusWidth / 64) << 1; */
1775                 /* XGINew_SetReg1(pVBInfo->P3c4, 0x14, data); */
1776
1777                 /* should delay */
1778                 /* XGINew_SetDRAMModeRegister340(pVBInfo); */
1779         }
1780         return memsize;
1781 }
1782
1783 static int XGINew_ReadWriteRest(unsigned short StopAddr,
1784                 unsigned short StartAddr, struct vb_device_info *pVBInfo)
1785 {
1786         int i;
1787         unsigned long Position = 0;
1788
1789         *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
1790
1791         for (i = StartAddr; i <= StopAddr; i++) {
1792                 Position = 1 << i;
1793                 *((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
1794         }
1795
1796         DelayUS(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
1797
1798         Position = 0;
1799
1800         if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
1801                 return 0;
1802
1803         for (i = StartAddr; i <= StopAddr; i++) {
1804                 Position = 1 << i;
1805                 if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
1806                         return 0;
1807         }
1808         return 1;
1809 }
1810
1811 static unsigned char XGINew_CheckFrequence(struct vb_device_info *pVBInfo)
1812 {
1813         unsigned char data;
1814
1815         data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
1816
1817         if ((data & 0x10) == 0) {
1818                 data = XGINew_GetReg1(pVBInfo->P3c4, 0x39);
1819                 data = (data & 0x02) >> 1;
1820                 return data;
1821         } else {
1822                 return data & 0x01;
1823         }
1824 }
1825
1826 static void XGINew_CheckChannel(struct xgi_hw_device_info *HwDeviceExtension,
1827                 struct vb_device_info *pVBInfo)
1828 {
1829         unsigned char data;
1830
1831         switch (HwDeviceExtension->jChipType) {
1832         case XG20:
1833         case XG21:
1834                 data = XGINew_GetReg1(pVBInfo->P3d4, 0x97);
1835                 data = data & 0x01;
1836                 XGINew_ChannelAB = 1; /* XG20 "JUST" one channel */
1837
1838                 if (data == 0) { /* Single_32_16 */
1839
1840                         if ((HwDeviceExtension->ulVideoMemorySize - 1)
1841                                         > 0x1000000) {
1842
1843                                 XGINew_DataBusWidth = 32; /* 32 bits */
1844                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */
1845                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
1846                                 DelayUS(15);
1847
1848                                 if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1849                                         return;
1850
1851                                 if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
1852                                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */
1853                                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
1854                                         DelayUS(15);
1855
1856                                         if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1)
1857                                                 return;
1858                                 }
1859                         }
1860
1861                         if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
1862                                 XGINew_DataBusWidth = 16; /* 16 bits */
1863                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */
1864                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41);
1865                                 DelayUS(15);
1866
1867                                 if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
1868                                         return;
1869                                 else
1870                                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31);
1871                                 DelayUS(15);
1872                         }
1873
1874                 } else { /* Dual_16_8 */
1875                         if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
1876
1877                                 XGINew_DataBusWidth = 16; /* 16 bits */
1878                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
1879                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/
1880                                 DelayUS(15);
1881
1882                                 if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
1883                                         return;
1884
1885                                 if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
1886                                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
1887                                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/
1888                                         DelayUS(15);
1889
1890                                         if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1)
1891                                                 return;
1892                                 }
1893                         }
1894
1895                         if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
1896                                 XGINew_DataBusWidth = 8; /* 8 bits */
1897                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
1898                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/
1899                                 DelayUS(15);
1900
1901                                 if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
1902                                         return;
1903                                 else
1904                                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
1905                                 DelayUS(15);
1906                         }
1907                 }
1908                 break;
1909
1910         case XG27:
1911                 XGINew_DataBusWidth = 16; /* 16 bits */
1912                 XGINew_ChannelAB = 1; /* Single channel */
1913                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x51); /* 32Mx16 bit*/
1914                 break;
1915         case XG41:
1916                 if (XGINew_CheckFrequence(pVBInfo) == 1) {
1917                         XGINew_DataBusWidth = 32; /* 32 bits */
1918                         XGINew_ChannelAB = 3; /* Quad Channel */
1919                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
1920                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
1921
1922                         if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
1923                                 return;
1924
1925                         XGINew_ChannelAB = 2; /* Dual channels */
1926                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
1927
1928                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1929                                 return;
1930
1931                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x49);
1932
1933                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1934                                 return;
1935
1936                         XGINew_ChannelAB = 3;
1937                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
1938                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
1939
1940                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1941                                 return;
1942
1943                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
1944
1945                         if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
1946                                 return;
1947                         else
1948                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x39);
1949                 } else { /* DDR */
1950                         XGINew_DataBusWidth = 64; /* 64 bits */
1951                         XGINew_ChannelAB = 2; /* Dual channels */
1952                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
1953                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
1954
1955                         if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1)
1956                                 return;
1957
1958                         XGINew_ChannelAB = 1; /* Single channels */
1959                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
1960
1961                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1962                                 return;
1963
1964                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x53);
1965
1966                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1967                                 return;
1968
1969                         XGINew_ChannelAB = 2; /* Dual channels */
1970                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
1971                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
1972
1973                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
1974                                 return;
1975
1976                         XGINew_ChannelAB = 1; /* Single channels */
1977                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
1978
1979                         if (XGINew_ReadWriteRest(8, 4, pVBInfo) == 1)
1980                                 return;
1981                         else
1982                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x43);
1983                 }
1984
1985                 break;
1986
1987         case XG42:
1988                 /*
1989                  XG42 SR14 D[3] Reserve
1990                  D[2] = 1, Dual Channel
1991                  = 0, Single Channel
1992
1993                  It's Different from Other XG40 Series.
1994                  */
1995                 if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII, DDR2x */
1996                         XGINew_DataBusWidth = 32; /* 32 bits */
1997                         XGINew_ChannelAB = 2; /* 2 Channel */
1998                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
1999                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x44);
2000
2001                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
2002                                 return;
2003
2004                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
2005                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x34);
2006                         if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
2007                                 return;
2008
2009                         XGINew_ChannelAB = 1; /* Single Channel */
2010                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
2011                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x40);
2012
2013                         if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
2014                                 return;
2015                         else {
2016                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
2017                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x30);
2018                         }
2019                 } else { /* DDR */
2020                         XGINew_DataBusWidth = 64; /* 64 bits */
2021                         XGINew_ChannelAB = 1; /* 1 channels */
2022                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
2023                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x52);
2024
2025                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
2026                                 return;
2027                         else {
2028                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
2029                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x42);
2030                         }
2031                 }
2032
2033                 break;
2034
2035         default: /* XG40 */
2036
2037                 if (XGINew_CheckFrequence(pVBInfo) == 1) { /* DDRII */
2038                         XGINew_DataBusWidth = 32; /* 32 bits */
2039                         XGINew_ChannelAB = 3;
2040                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
2041                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4C);
2042
2043                         if (XGINew_ReadWriteRest(25, 23, pVBInfo) == 1)
2044                                 return;
2045
2046                         XGINew_ChannelAB = 2; /* 2 channels */
2047                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x48);
2048
2049                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
2050                                 return;
2051
2052                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
2053                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x3C);
2054
2055                         if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1) {
2056                                 XGINew_ChannelAB = 3; /* 4 channels */
2057                         } else {
2058                                 XGINew_ChannelAB = 2; /* 2 channels */
2059                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x38);
2060                         }
2061                 } else { /* DDR */
2062                         XGINew_DataBusWidth = 64; /* 64 bits */
2063                         XGINew_ChannelAB = 2; /* 2 channels */
2064                         XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0xA1);
2065                         XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x5A);
2066
2067                         if (XGINew_ReadWriteRest(25, 24, pVBInfo) == 1) {
2068                                 return;
2069                         } else {
2070                                 XGINew_SetReg1(pVBInfo->P3c4, 0x13, 0x21);
2071                                 XGINew_SetReg1(pVBInfo->P3c4, 0x14, 0x4A);
2072                         }
2073                 }
2074                 break;
2075         }
2076 }
2077
2078 int XGINew_DDRSizing340(struct xgi_hw_device_info *HwDeviceExtension,
2079                 struct vb_device_info *pVBInfo)
2080 {
2081         int i;
2082         unsigned short memsize, addr;
2083
2084         XGINew_SetReg1(pVBInfo->P3c4, 0x15, 0x00); /* noninterleaving */
2085         XGINew_SetReg1(pVBInfo->P3c4, 0x1C, 0x00); /* nontiling */
2086         XGINew_CheckChannel(HwDeviceExtension, pVBInfo);
2087
2088         if (HwDeviceExtension->jChipType >= XG20) {
2089                 for (i = 0; i < 12; i++) {
2090                         XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
2091                         memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
2092                         if (memsize == 0)
2093                                 continue;
2094
2095                         addr = memsize + (XGINew_ChannelAB - 2) + 20;
2096                         if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
2097                                 continue;
2098
2099                         if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1)
2100                                 return 1;
2101                 }
2102         } else {
2103                 for (i = 0; i < 4; i++) {
2104                         XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
2105                         memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
2106
2107                         if (memsize == 0)
2108                                 continue;
2109
2110                         addr = memsize + (XGINew_ChannelAB - 2) + 20;
2111                         if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
2112                                 continue;
2113
2114                         if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1)
2115                                 return 1;
2116                 }
2117         }
2118         return 0;
2119 }
2120
2121 int XGINew_DDRSizing(struct vb_device_info *pVBInfo)
2122 {
2123         int i;
2124         unsigned char j;
2125
2126         for (i = 0; i < 4; i++) {
2127                 XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE, pVBInfo);
2128                 XGINew_DisableChannelInterleaving(i, XGINew_DDRDRAM_TYPE, pVBInfo);
2129                 for (j = 2; j > 0; j--) {
2130                         XGINew_SetDDRChannel(i, j, XGINew_ChannelAB, XGINew_DDRDRAM_TYPE, pVBInfo);
2131                         if (!XGINew_SetRank(i, (unsigned char) j, XGINew_ChannelAB, XGINew_DDRDRAM_TYPE, pVBInfo)) {
2132                                 continue;
2133                         } else {
2134                                 if (XGINew_CheckDDRRanks(j, i, XGINew_DDRDRAM_TYPE, pVBInfo))
2135                                         return 1;
2136                         }
2137                 }
2138         }
2139         return 0;
2140 }
2141
2142 void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension,
2143                 struct vb_device_info *pVBInfo)
2144 {
2145
2146         XGINew_SetReg1(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28);
2147         XGINew_SetReg1(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29);
2148         XGINew_SetReg1(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A);
2149
2150         XGINew_SetReg1(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E);
2151         XGINew_SetReg1(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F);
2152         XGINew_SetReg1(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30);
2153
2154         /* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
2155         /* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
2156         if (HwDeviceExtension->jChipType == XG42) {
2157                 if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C)
2158                                 && (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01)
2159                                 && (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C)
2160                                                 && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))
2161                                         || ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22)
2162                                                 && (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))))
2163                         XGINew_SetReg1(pVBInfo->P3c4, 0x32, ((unsigned char) XGINew_GetReg1(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
2164         }
2165 }
2166
2167 unsigned char ChkLFB(struct vb_device_info *pVBInfo)
2168 {
2169         if (LFBDRAMTrap & XGINew_GetReg1(pVBInfo->P3d4, 0x78))
2170                 return 1;
2171         else
2172                 return 0;
2173 }
2174
2175 /* --------------------------------------------------------------------- */
2176 /* input : dx ,valid value : CR or second chip's CR */
2177 /*  */
2178 /* SetPowerConsume : */
2179 /* Description: reduce 40/43 power consumption in first chip or */
2180 /* in second chip, assume CR A1 D[6]="1" in this case */
2181 /* output : none */
2182 /* --------------------------------------------------------------------- */
2183 void SetPowerConsume(struct xgi_hw_device_info *HwDeviceExtension,
2184                 unsigned long XGI_P3d4Port)
2185 {
2186         unsigned long lTemp;
2187         unsigned char bTemp;
2188
2189         HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x08, 0, &lTemp); /* Get */
2190         if ((lTemp & 0xFF) == 0) {
2191                 /* set CR58 D[5]=0 D[3]=0 */
2192                 XGINew_SetRegAND(XGI_P3d4Port, 0x58, 0xD7);
2193                 bTemp = (unsigned char) XGINew_GetReg1(XGI_P3d4Port, 0xCB);
2194                 if (bTemp & 0x20) {
2195                         if (!(bTemp & 0x10))
2196                                 XGINew_SetRegANDOR(XGI_P3d4Port, 0x58, 0xD7, 0x20); /* CR58 D[5]=1 D[3]=0 */
2197                         else
2198                                 XGINew_SetRegANDOR(XGI_P3d4Port, 0x58, 0xD7, 0x08); /* CR58 D[5]=0 D[3]=1 */
2199
2200                 }
2201
2202         }
2203 }
2204
2205 #if 0
2206 static void XGINew_InitVBIOSData(struct xgi_hw_device_info *HwDeviceExtension,
2207                 struct vb_device_info *pVBInfo)
2208 {
2209
2210         /* unsigned long ROMAddr = (unsigned long) HwDeviceExtension->pjVirtualRomBase; */
2211         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
2212         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
2213         pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
2214         pVBInfo->ISXPDOS = 0;
2215
2216         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
2217         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
2218         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
2219         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
2220         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
2221         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
2222         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
2223         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
2224         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
2225         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
2226         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
2227         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
2228         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
2229         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
2230         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
2231         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
2232         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
2233         if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
2234         XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
2235
2236         switch (HwDeviceExtension->jChipType) {
2237         case XG40:
2238         case XG41:
2239         case XG42:
2240         case XG20:
2241         case XG21:
2242         default:
2243                 InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
2244                 return;
2245         }
2246
2247 }
2248 #endif
2249
2250 void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo)
2251 {
2252         volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
2253         unsigned long i;
2254         unsigned char j, k;
2255         /* Volari customize data area end */
2256
2257         if (ChipType == XG21) {
2258                 pVBInfo->IF_DEF_LVDS = 0;
2259                 if (pVideoMemory[0x65] & 0x1) {
2260                         pVBInfo->IF_DEF_LVDS = 1;
2261                         i = pVideoMemory[0x316] | (pVideoMemory[0x317] << 8);
2262                         j = pVideoMemory[i - 1];
2263                         if (j != 0xff) {
2264                                 k = 0;
2265                                 do {
2266                                         pVBInfo->XG21_LVDSCapList[k].LVDS_Capability
2267                                                 = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
2268                                         pVBInfo->XG21_LVDSCapList[k].LVDSHT
2269                                                 = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
2270                                         pVBInfo->XG21_LVDSCapList[k].LVDSVT
2271                                                 = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
2272                                         pVBInfo->XG21_LVDSCapList[k].LVDSHDE
2273                                                 = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
2274                                         pVBInfo->XG21_LVDSCapList[k].LVDSVDE
2275                                                 = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
2276                                         pVBInfo->XG21_LVDSCapList[k].LVDSHFP
2277                                                 = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
2278                                         pVBInfo->XG21_LVDSCapList[k].LVDSVFP
2279                                                 = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
2280                                         pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC
2281                                                 = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
2282                                         pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC
2283                                                 = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
2284                                         pVBInfo->XG21_LVDSCapList[k].VCLKData1
2285                                                 = pVideoMemory[i + 18];
2286                                         pVBInfo->XG21_LVDSCapList[k].VCLKData2
2287                                                 = pVideoMemory[i + 19];
2288                                         pVBInfo->XG21_LVDSCapList[k].PSC_S1
2289                                                 = pVideoMemory[i + 20];
2290                                         pVBInfo->XG21_LVDSCapList[k].PSC_S2
2291                                                 = pVideoMemory[i + 21];
2292                                         pVBInfo->XG21_LVDSCapList[k].PSC_S3
2293                                                 = pVideoMemory[i + 22];
2294                                         pVBInfo->XG21_LVDSCapList[k].PSC_S4
2295                                                 = pVideoMemory[i + 23];
2296                                         pVBInfo->XG21_LVDSCapList[k].PSC_S5
2297                                                 = pVideoMemory[i + 24];
2298                                         i += 25;
2299                                         j--;
2300                                         k++;
2301                                 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct))));
2302                         } else {
2303                                 pVBInfo->XG21_LVDSCapList[0].LVDS_Capability
2304                                                 = pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
2305                                 pVBInfo->XG21_LVDSCapList[0].LVDSHT
2306                                                 = pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
2307                                 pVBInfo->XG21_LVDSCapList[0].LVDSVT
2308                                                 = pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
2309                                 pVBInfo->XG21_LVDSCapList[0].LVDSHDE
2310                                                 = pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
2311                                 pVBInfo->XG21_LVDSCapList[0].LVDSVDE
2312                                                 = pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
2313                                 pVBInfo->XG21_LVDSCapList[0].LVDSHFP
2314                                                 = pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
2315                                 pVBInfo->XG21_LVDSCapList[0].LVDSVFP
2316                                                 = pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
2317                                 pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC
2318                                                 = pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
2319                                 pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC
2320                                                 = pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
2321                                 pVBInfo->XG21_LVDSCapList[0].VCLKData1
2322                                                 = pVideoMemory[i + 18];
2323                                 pVBInfo->XG21_LVDSCapList[0].VCLKData2
2324                                                 = pVideoMemory[i + 19];
2325                                 pVBInfo->XG21_LVDSCapList[0].PSC_S1
2326                                                 = pVideoMemory[i + 20];
2327                                 pVBInfo->XG21_LVDSCapList[0].PSC_S2
2328                                                 = pVideoMemory[i + 21];
2329                                 pVBInfo->XG21_LVDSCapList[0].PSC_S3
2330                                                 = pVideoMemory[i + 22];
2331                                 pVBInfo->XG21_LVDSCapList[0].PSC_S4
2332                                                 = pVideoMemory[i + 23];
2333                                 pVBInfo->XG21_LVDSCapList[0].PSC_S5
2334                                                 = pVideoMemory[i + 24];
2335                         }
2336                 }
2337         }
2338 }
2339
2340 void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo)
2341 {
2342
2343         XGINew_SetReg1(P3c4, 0x18, 0x01);
2344         XGINew_SetReg1(P3c4, 0x19, 0x40);
2345         XGINew_SetReg1(P3c4, 0x16, 0x00);
2346         XGINew_SetReg1(P3c4, 0x16, 0x80);
2347         DelayUS(60);
2348
2349         XGINew_SetReg1(P3c4, 0x18, 0x00);
2350         XGINew_SetReg1(P3c4, 0x19, 0x40);
2351         XGINew_SetReg1(P3c4, 0x16, 0x00);
2352         XGINew_SetReg1(P3c4, 0x16, 0x80);
2353         DelayUS(60);
2354         XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
2355         /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
2356         XGINew_SetReg1(P3c4, 0x19, 0x01);
2357         XGINew_SetReg1(P3c4, 0x16, 0x03);
2358         XGINew_SetReg1(P3c4, 0x16, 0x83);
2359         DelayUS(1000);
2360         XGINew_SetReg1(P3c4, 0x1B, 0x03);
2361         DelayUS(500);
2362         /* XGINew_SetReg1(P3c4, 0x18, 0x31); */
2363         XGINew_SetReg1(P3c4, 0x18, pVBInfo->SR15[2][XGINew_RAMType]); /* SR18 */
2364         XGINew_SetReg1(P3c4, 0x19, 0x00);
2365         XGINew_SetReg1(P3c4, 0x16, 0x03);
2366         XGINew_SetReg1(P3c4, 0x16, 0x83);
2367         XGINew_SetReg1(P3c4, 0x1B, 0x00);
2368 }
2369
2370 void XGINew_SetDRAMModeRegister_XG20(struct xgi_hw_device_info *HwDeviceExtension)
2371 {
2372         struct vb_device_info VBINF;
2373         struct vb_device_info *pVBInfo = &VBINF;
2374         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
2375         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
2376         pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
2377         pVBInfo->ISXPDOS = 0;
2378
2379         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
2380         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
2381         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
2382         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
2383         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
2384         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
2385         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
2386         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
2387         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
2388         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
2389         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
2390         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
2391         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
2392         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
2393         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
2394         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
2395         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
2396
2397         InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
2398
2399         ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
2400
2401         if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0)
2402                 XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo);
2403         else
2404                 XGINew_DDR2_MRS_XG20(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
2405
2406         XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03);
2407 }
2408
2409 void XGINew_SetDRAMModeRegister_XG27(
2410                 struct xgi_hw_device_info *HwDeviceExtension)
2411 {
2412         struct vb_device_info VBINF;
2413         struct vb_device_info *pVBInfo = &VBINF;
2414         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
2415         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
2416         pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
2417         pVBInfo->ISXPDOS = 0;
2418
2419         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
2420         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
2421         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
2422         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
2423         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
2424         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
2425         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
2426         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
2427         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
2428         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
2429         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
2430         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
2431         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
2432         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
2433         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
2434         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
2435         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
2436
2437         InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
2438
2439         ReadVBIOSTablData(HwDeviceExtension->jChipType, pVBInfo);
2440
2441         if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0)
2442                 XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo);
2443         else
2444                 /* XGINew_DDR2_MRS_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo); */
2445                 XGINew_DDRII_Bootup_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
2446
2447         /* XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03); */
2448         XGINew_SetReg1(pVBInfo->P3c4, 0x1B, pVBInfo->SR15[3][XGINew_RAMType]); /* SR1B */
2449
2450 }
2451
2452 /*
2453 void XGINew_SetDRAMModeRegister_XG27(struct xgi_hw_device_info *HwDeviceExtension)
2454 {
2455         unsigned char data;
2456         struct vb_device_info VBINF;
2457         struct vb_device_info *pVBInfo = &VBINF;
2458         pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
2459         pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress;
2460         pVBInfo->BaseAddr = HwDeviceExtension->pjIOAddress;
2461         pVBInfo->ISXPDOS = 0;
2462
2463         pVBInfo->P3c4 = pVBInfo->BaseAddr + 0x14;
2464         pVBInfo->P3d4 = pVBInfo->BaseAddr + 0x24;
2465         pVBInfo->P3c0 = pVBInfo->BaseAddr + 0x10;
2466         pVBInfo->P3ce = pVBInfo->BaseAddr + 0x1e;
2467         pVBInfo->P3c2 = pVBInfo->BaseAddr + 0x12;
2468         pVBInfo->P3ca = pVBInfo->BaseAddr + 0x1a;
2469         pVBInfo->P3c6 = pVBInfo->BaseAddr + 0x16;
2470         pVBInfo->P3c7 = pVBInfo->BaseAddr + 0x17;
2471         pVBInfo->P3c8 = pVBInfo->BaseAddr + 0x18;
2472         pVBInfo->P3c9 = pVBInfo->BaseAddr + 0x19;
2473         pVBInfo->P3da = pVBInfo->BaseAddr + 0x2A;
2474         pVBInfo->Part0Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_00;
2475         pVBInfo->Part1Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_04;
2476         pVBInfo->Part2Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_10;
2477         pVBInfo->Part3Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_12;
2478         pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
2479         pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
2480
2481         InitTo330Pointer(HwDeviceExtension->jChipType,pVBInfo);
2482
2483         ReadVBIOSTablData(HwDeviceExtension->jChipType , pVBInfo);
2484
2485         if (XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) == 0)
2486                 XGINew_DDR1x_MRS_XG20(pVBInfo->P3c4, pVBInfo);
2487         else
2488                 XGINew_DDR2_MRS_XG27(HwDeviceExtension, pVBInfo->P3c4, pVBInfo);
2489
2490         XGINew_SetReg1(pVBInfo->P3c4, 0x1B, 0x03);
2491 }
2492 */
2493
2494 void XGINew_ChkSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
2495                 struct vb_device_info *pVBInfo)
2496 {
2497         unsigned short tempbx = 0, temp, tempcx, CR3CData;
2498
2499         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x32);
2500
2501         if (temp & Monitor1Sense)
2502                 tempbx |= ActiveCRT1;
2503         if (temp & LCDSense)
2504                 tempbx |= ActiveLCD;
2505         if (temp & Monitor2Sense)
2506                 tempbx |= ActiveCRT2;
2507         if (temp & TVSense) {
2508                 tempbx |= ActiveTV;
2509                 if (temp & AVIDEOSense)
2510                         tempbx |= (ActiveAVideo << 8);
2511                 if (temp & SVIDEOSense)
2512                         tempbx |= (ActiveSVideo << 8);
2513                 if (temp & SCARTSense)
2514                         tempbx |= (ActiveSCART << 8);
2515                 if (temp & HiTVSense)
2516                         tempbx |= (ActiveHiTV << 8);
2517                 if (temp & YPbPrSense)
2518                         tempbx |= (ActiveYPbPr << 8);
2519         }
2520
2521         tempcx = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
2522         tempcx |= (XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8);
2523
2524         if (tempbx & tempcx) {
2525                 CR3CData = XGINew_GetReg1(pVBInfo->P3d4, 0x3c);
2526                 if (!(CR3CData & DisplayDeviceFromCMOS)) {
2527                         tempcx = 0x1FF0;
2528                         if (*pVBInfo->pSoftSetting & ModeSoftSetting)
2529                                 tempbx = 0x1FF0;
2530                 }
2531         } else {
2532                 tempcx = 0x1FF0;
2533                 if (*pVBInfo->pSoftSetting & ModeSoftSetting)
2534                         tempbx = 0x1FF0;
2535         }
2536
2537         tempbx &= tempcx;
2538         XGINew_SetReg1(pVBInfo->P3d4, 0x3d, (tempbx & 0x00FF));
2539         XGINew_SetReg1(pVBInfo->P3d4, 0x3e, ((tempbx & 0xFF00) >> 8));
2540 }
2541
2542 void XGINew_SetModeScratch(struct xgi_hw_device_info *HwDeviceExtension,
2543                 struct vb_device_info *pVBInfo)
2544 {
2545         unsigned short temp, tempcl = 0, tempch = 0, CR31Data, CR38Data;
2546
2547         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x3d);
2548         temp |= XGINew_GetReg1(pVBInfo->P3d4, 0x3e) << 8;
2549         temp |= (XGINew_GetReg1(pVBInfo->P3d4, 0x31) & (DriverMode >> 8)) << 8;
2550
2551         if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
2552                 if (temp & ActiveCRT2)
2553                         tempcl = SetCRT2ToRAMDAC;
2554         }
2555
2556         if (temp & ActiveLCD) {
2557                 tempcl |= SetCRT2ToLCD;
2558                 if (temp & DriverMode) {
2559                         if (temp & ActiveTV) {
2560                                 tempch = SetToLCDA | EnableDualEdge;
2561                                 temp ^= SetCRT2ToLCD;
2562
2563                                 if ((temp >> 8) & ActiveAVideo)
2564                                         tempcl |= SetCRT2ToAVIDEO;
2565                                 if ((temp >> 8) & ActiveSVideo)
2566                                         tempcl |= SetCRT2ToSVIDEO;
2567                                 if ((temp >> 8) & ActiveSCART)
2568                                         tempcl |= SetCRT2ToSCART;
2569
2570                                 if (pVBInfo->IF_DEF_HiVision == 1) {
2571                                         if ((temp >> 8) & ActiveHiTV)
2572                                                 tempcl |= SetCRT2ToHiVisionTV;
2573                                 }
2574
2575                                 if (pVBInfo->IF_DEF_YPbPr == 1) {
2576                                         if ((temp >> 8) & ActiveYPbPr)
2577                                                 tempch |= SetYPbPr;
2578                                 }
2579                         }
2580                 }
2581         } else {
2582                 if ((temp >> 8) & ActiveAVideo)
2583                         tempcl |= SetCRT2ToAVIDEO;
2584                 if ((temp >> 8) & ActiveSVideo)
2585                         tempcl |= SetCRT2ToSVIDEO;
2586                 if ((temp >> 8) & ActiveSCART)
2587                         tempcl |= SetCRT2ToSCART;
2588
2589                 if (pVBInfo->IF_DEF_HiVision == 1) {
2590                         if ((temp >> 8) & ActiveHiTV)
2591                                 tempcl |= SetCRT2ToHiVisionTV;
2592                 }
2593
2594                 if (pVBInfo->IF_DEF_YPbPr == 1) {
2595                         if ((temp >> 8) & ActiveYPbPr)
2596                                 tempch |= SetYPbPr;
2597                 }
2598         }
2599
2600         tempcl |= SetSimuScanMode;
2601         if ((!(temp & ActiveCRT1)) && ((temp & ActiveLCD) || (temp & ActiveTV)
2602                         || (temp & ActiveCRT2)))
2603                 tempcl ^= (SetSimuScanMode | SwitchToCRT2);
2604         if ((temp & ActiveLCD) && (temp & ActiveTV))
2605                 tempcl ^= (SetSimuScanMode | SwitchToCRT2);
2606         XGINew_SetReg1(pVBInfo->P3d4, 0x30, tempcl);
2607
2608         CR31Data = XGINew_GetReg1(pVBInfo->P3d4, 0x31);
2609         CR31Data &= ~(SetNotSimuMode >> 8);
2610         if (!(temp & ActiveCRT1))
2611                 CR31Data |= (SetNotSimuMode >> 8);
2612         CR31Data &= ~(DisableCRT2Display >> 8);
2613         if (!((temp & ActiveLCD) || (temp & ActiveTV) || (temp & ActiveCRT2)))
2614                 CR31Data |= (DisableCRT2Display >> 8);
2615         XGINew_SetReg1(pVBInfo->P3d4, 0x31, CR31Data);
2616
2617         CR38Data = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
2618         CR38Data &= ~SetYPbPr;
2619         CR38Data |= tempch;
2620         XGINew_SetReg1(pVBInfo->P3d4, 0x38, CR38Data);
2621
2622 }
2623
2624 void XGINew_GetXG21Sense(struct xgi_hw_device_info *HwDeviceExtension,
2625                 struct vb_device_info *pVBInfo)
2626 {
2627         unsigned char Temp;
2628         volatile unsigned char *pVideoMemory =
2629                         (unsigned char *) pVBInfo->ROMAddr;
2630
2631         pVBInfo->IF_DEF_LVDS = 0;
2632
2633 #if 1
2634         if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */
2635                 pVBInfo->IF_DEF_LVDS = 1;
2636                 XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
2637                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */
2638         } else {
2639 #endif
2640                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read  */
2641                 Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0xC0;
2642                 if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
2643                         XGINew_SenseLCD(HwDeviceExtension, pVBInfo);
2644                         XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
2645                         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */
2646                         Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x04;
2647                         if (!Temp)
2648                                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */
2649                         else
2650                                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */
2651                         XGINew_SetRegAND(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */
2652                 }
2653 #if 1
2654         }
2655 #endif
2656 }
2657
2658 void XGINew_GetXG27Sense(struct xgi_hw_device_info *HwDeviceExtension,
2659                 struct vb_device_info *pVBInfo)
2660 {
2661         unsigned char Temp, bCR4A;
2662
2663         pVBInfo->IF_DEF_LVDS = 0;
2664         bCR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
2665         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read  */
2666         Temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48) & 0x07;
2667         XGINew_SetReg1(pVBInfo->P3d4, 0x4A, bCR4A);
2668
2669         if (Temp <= 0x02) {
2670                 pVBInfo->IF_DEF_LVDS = 1;
2671                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */
2672                 XGINew_SetReg1(pVBInfo->P3d4, 0x30, 0x21);
2673         } else {
2674                 XGINew_SetRegANDOR(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */
2675         }
2676         XGINew_SetRegOR(pVBInfo->P3d4, 0x32, LCDSense);
2677
2678 }
2679
2680 unsigned char GetXG21FPBits(struct vb_device_info *pVBInfo)
2681 {
2682         unsigned char CR38, CR4A, temp;
2683
2684         CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
2685         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */
2686         CR38 = XGINew_GetReg1(pVBInfo->P3d4, 0x38);
2687         temp = 0;
2688         if ((CR38 & 0xE0) > 0x80) {
2689                 temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
2690                 temp &= 0x08;
2691                 temp >>= 3;
2692         }
2693
2694         XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
2695
2696         return temp;
2697 }
2698
2699 unsigned char GetXG27FPBits(struct vb_device_info *pVBInfo)
2700 {
2701         unsigned char CR4A, temp;
2702
2703         CR4A = XGINew_GetReg1(pVBInfo->P3d4, 0x4A);
2704         XGINew_SetRegANDOR(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */
2705         temp = XGINew_GetReg1(pVBInfo->P3d4, 0x48);
2706         if (temp <= 2)
2707                 temp &= 0x03;
2708         else
2709                 temp = ((temp & 0x04) >> 1) || ((~temp) & 0x01);
2710
2711         XGINew_SetReg1(pVBInfo->P3d4, 0x4A, CR4A);
2712
2713         return temp;
2714 }
2715