]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/xgifb/XGI_main_26.c
Merge branch 'for-linus' of git://neil.brown.name/md
[mv-sheeva.git] / drivers / staging / xgifb / XGI_main_26.c
1 /*
2  * XG20, XG21, XG40, XG42 frame buffer device
3  * for Linux kernels  2.5.x, 2.6.x
4  * Base on TW's sis fbdev code.
5  */
6
7 /* #include <linux/config.h> */
8 #include <linux/version.h>
9 #include <linux/module.h>
10 #include <linux/moduleparam.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/mm.h>
16 #include <linux/tty.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/fb.h>
20 #include <linux/console.h>
21 #include <linux/selection.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/pci.h>
25 #include <linux/vmalloc.h>
26 #include <linux/vt_kern.h>
27 #include <linux/capability.h>
28 #include <linux/fs.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31
32 #ifndef XGIFB_PAN
33 #define XGIFB_PAN
34 #endif
35
36 #include <asm/io.h>
37 #ifdef CONFIG_MTRR
38 #include <asm/mtrr.h>
39 #endif
40
41 #include "XGIfb.h"
42 #include "vgatypes.h"
43 #include "XGI_main.h"
44 #include "vb_util.h"
45
46 int XGIfb_accel = 0;
47
48 #define Index_CR_GPIO_Reg1 0x48
49 #define Index_CR_GPIO_Reg2 0x49
50 #define Index_CR_GPIO_Reg3 0x4a
51
52 #define GPIOG_EN    (1<<6)
53 #define GPIOG_WRITE (1<<6)
54 #define GPIOG_READ  (1<<1)
55 int XGIfb_GetXG21DefaultLVDSModeIdx(void);
56
57 /* -------------------- Macro definitions ---------------------------- */
58
59 #undef XGIFBDEBUG
60
61 #ifdef XGIFBDEBUG
62 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63 #else
64 #define DPRINTK(fmt, args...)
65 #endif
66
67 #ifdef XGIFBDEBUG
68 static void dumpVGAReg(void)
69 {
70         u8 i, reg;
71
72         outXGIIDXREG(XGISR, 0x05, 0x86);
73         /*
74         outXGIIDXREG(XGISR, 0x08, 0x4f);
75         outXGIIDXREG(XGISR, 0x0f, 0x20);
76         outXGIIDXREG(XGISR, 0x11, 0x4f);
77         outXGIIDXREG(XGISR, 0x13, 0x45);
78         outXGIIDXREG(XGISR, 0x14, 0x51);
79         outXGIIDXREG(XGISR, 0x1e, 0x41);
80         outXGIIDXREG(XGISR, 0x1f, 0x0);
81         outXGIIDXREG(XGISR, 0x20, 0xa1);
82         outXGIIDXREG(XGISR, 0x22, 0xfb);
83         outXGIIDXREG(XGISR, 0x26, 0x22);
84         outXGIIDXREG(XGISR, 0x3e, 0x07);
85         */
86
87         /* outXGIIDXREG(XGICR, 0x19, 0x00); */
88         /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
89         /* outXGIIDXREG(XGICR, 0x22, 0xff); */
90         /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
91
92         /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
93
94         /* outXGIIDXREG(XGICR, 0x57, 0x0); */
95         /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
96
97         /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
98         /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
99         /*
100         outXGIIDXREG(XGICR, 0x99, 0x1);
101         outXGIIDXREG(XGICR, 0x41, 0x40);
102         */
103
104         for (i = 0; i < 0x4f; i++) {
105                 inXGIIDXREG(XGISR, i, reg);
106                 printk("\no 3c4 %x", i);
107                 printk("\ni 3c5 => %x", reg);
108         }
109
110         for (i = 0; i < 0xF0; i++) {
111                 inXGIIDXREG(XGICR, i, reg);
112                 printk("\no 3d4 %x", i);
113                 printk("\ni 3d5 => %x", reg);
114         }
115         /*
116         outXGIIDXREG(XGIPART1,0x2F,1);
117         for (i=1; i < 0x50; i++) {
118                 inXGIIDXREG(XGIPART1, i, reg);
119                 printk("\no d004 %x", i);
120                 printk("\ni d005 => %x", reg);
121         }
122
123         for (i=0; i < 0x50; i++) {
124                  inXGIIDXREG(XGIPART2, i, reg);
125                  printk("\no d010 %x", i);
126                  printk("\ni d011 => %x", reg);
127         }
128         for (i=0; i < 0x50; i++) {
129                 inXGIIDXREG(XGIPART3, i, reg);
130                 printk("\no d012 %x",i);
131                 printk("\ni d013 => %x",reg);
132         }
133         for (i=0; i < 0x50; i++) {
134                 inXGIIDXREG(XGIPART4, i, reg);
135                 printk("\no d014 %x",i);
136                 printk("\ni d015 => %x",reg);
137         }
138         */
139 }
140 #else
141 static inline void dumpVGAReg(void)
142 {
143 }
144 #endif
145
146 /* data for XGI components */
147 struct video_info xgi_video_info;
148
149 #if 1
150 #define DEBUGPRN(x)
151 #else
152 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
153 #endif
154
155 /* --------------- Hardware Access Routines -------------------------- */
156
157 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158                 struct xgi_hw_device_info *HwDeviceExtension,
159                 unsigned char modeno, unsigned char rateindex)
160 {
161         unsigned short ModeNo = modeno;
162         unsigned short ModeIdIndex = 0, ClockIndex = 0;
163         unsigned short RefreshRateTableIndex = 0;
164
165         /* unsigned long  temp = 0; */
166         int Clock;
167         XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168         InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
169
170         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171                         ModeIdIndex, XGI_Pr);
172
173         /*
174         temp = XGI_SearchModeID(ModeNo , &ModeIdIndex,  XGI_Pr) ;
175         if (!temp) {
176                 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
177                 return 65000;
178         }
179
180         RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181         RefreshRateTableIndex += (rateindex - 1);
182
183         */
184         ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
185         if (HwDeviceExtension->jChipType < XGI_315H)
186                 ClockIndex &= 0x3F;
187
188         Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
189
190         return Clock;
191 }
192
193 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
194                 struct xgi_hw_device_info *HwDeviceExtension,
195                 unsigned char modeno, unsigned char rateindex,
196                 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
197                 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
198                 u32 *vmode)
199 {
200         unsigned short ModeNo = modeno;
201         unsigned short ModeIdIndex = 0, index = 0;
202         unsigned short RefreshRateTableIndex = 0;
203
204         unsigned short VRE, VBE, VRS, VBS, VDE, VT;
205         unsigned short HRE, HBE, HRS, HBS, HDE, HT;
206         unsigned char sr_data, cr_data, cr_data2;
207         unsigned long cr_data3;
208         int A, B, C, D, E, F, temp, j;
209         XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
210         InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
211         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
212                         ModeIdIndex, XGI_Pr);
213         /*
214         temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
215         if (!temp)
216                 return 0;
217
218         RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
219         RefreshRateTableIndex += (rateindex - 1);
220         */
221         index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
222
223         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
224
225         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
226
227         /* Horizontal total */
228         HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
229         A = HT + 5;
230
231         /*
232         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
233
234         Horizontal display enable end
235         HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
236         */
237         HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
238         E = HDE + 1;
239
240         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
241
242         /* Horizontal retrace (=sync) start */
243         HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
244         F = HRS - E - 3;
245
246         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
247
248         /* Horizontal blank start */
249         HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
250
251         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
252
253         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
254
255         cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
256
257         /* Horizontal blank end */
258         HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
259                         | ((unsigned short) (sr_data & 0x03) << 6);
260
261         /* Horizontal retrace (=sync) end */
262         HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
263
264         temp = HBE - ((E - 1) & 255);
265         B = (temp > 0) ? temp : (temp + 256);
266
267         temp = HRE - ((E + F + 3) & 63);
268         C = (temp > 0) ? temp : (temp + 64);
269
270         D = B - F - C;
271
272         *left_margin = D * 8;
273         *right_margin = F * 8;
274         *hsync_len = C * 8;
275
276         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
277
278         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
279
280         cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
281
282         /* Vertical total */
283         VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
284                         | ((unsigned short) (cr_data2 & 0x20) << 4)
285                         | ((unsigned short) (sr_data & 0x01) << 10);
286         A = VT + 2;
287
288         /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
289
290         /* Vertical display enable end */
291         /*
292         VDE = (cr_data & 0xff) |
293                 ((unsigned short) (cr_data2 & 0x02) << 7) |
294                 ((unsigned short) (cr_data2 & 0x40) << 3) |
295                 ((unsigned short) (sr_data & 0x02) << 9);
296         */
297         VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
298         E = VDE + 1;
299
300         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
301
302         /* Vertical retrace (=sync) start */
303         VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
304                         | ((unsigned short) (cr_data2 & 0x80) << 2)
305                         | ((unsigned short) (sr_data & 0x08) << 7);
306         F = VRS + 1 - E;
307
308         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
309
310         cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
311
312         /* Vertical blank start */
313         VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
314                         | ((unsigned short) (cr_data3 & 0x20) << 4)
315                         | ((unsigned short) (sr_data & 0x04) << 8);
316
317         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
318
319         /* Vertical blank end */
320         VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
321         temp = VBE - ((E - 1) & 511);
322         B = (temp > 0) ? temp : (temp + 512);
323
324         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
325
326         /* Vertical retrace (=sync) end */
327         VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
328         temp = VRE - ((E + F - 1) & 31);
329         C = (temp > 0) ? temp : (temp + 32);
330
331         D = B - F - C;
332
333         *upper_margin = D;
334         *lower_margin = F;
335         *vsync_len = C;
336
337         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
338                 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
339         else
340                 *sync |= FB_SYNC_VERT_HIGH_ACT;
341
342         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
343                 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
344         else
345                 *sync |= FB_SYNC_HOR_HIGH_ACT;
346
347         *vmode = FB_VMODE_NONINTERLACED;
348         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
349                 *vmode = FB_VMODE_INTERLACED;
350         else {
351                 j = 0;
352                 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
353                         if (XGI_Pr->EModeIDTable[j].Ext_ModeID
354                                         == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
355                                 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
356                                                 & DoubleScanMode) {
357                                         *vmode = FB_VMODE_DOUBLE;
358                                 }
359                                 break;
360                         }
361                         j++;
362                 }
363         }
364
365         return 1;
366 }
367
368 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
369 {
370         XGI_Pr->RelIO = BaseAddr;
371         XGI_Pr->P3c4 = BaseAddr + 0x14;
372         XGI_Pr->P3d4 = BaseAddr + 0x24;
373         XGI_Pr->P3c0 = BaseAddr + 0x10;
374         XGI_Pr->P3ce = BaseAddr + 0x1e;
375         XGI_Pr->P3c2 = BaseAddr + 0x12;
376         XGI_Pr->P3ca = BaseAddr + 0x1a;
377         XGI_Pr->P3c6 = BaseAddr + 0x16;
378         XGI_Pr->P3c7 = BaseAddr + 0x17;
379         XGI_Pr->P3c8 = BaseAddr + 0x18;
380         XGI_Pr->P3c9 = BaseAddr + 0x19;
381         XGI_Pr->P3da = BaseAddr + 0x2A;
382         XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
383         XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
384         XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
385         XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
386         XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
387
388 }
389
390 void XGIfb_set_reg4(u16 port, unsigned long data)
391 {
392         outl((u32)(data & 0xffffffff), port);
393 }
394
395 u32 XGIfb_get_reg3(u16 port)
396 {
397         u32 data;
398
399         data = inl(port);
400         return data;
401 }
402
403 /* ------------ Interface for init & mode switching code ------------- */
404
405 unsigned char XGIfb_query_VGA_config_space(
406                 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
407                 unsigned long set, unsigned long *value)
408 {
409         static struct pci_dev *pdev = NULL;
410         static unsigned char init = 0, valid_pdev = 0;
411
412         if (!set)
413                 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
414         else
415                 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
416
417         if (!init) {
418                 init = 1;
419                 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
420                                 pdev);
421                 if (pdev) {
422                         valid_pdev = 1;
423                         pci_dev_put(pdev);
424                 }
425         }
426
427         if (!valid_pdev) {
428                 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
429                                 xgi_video_info.chip_id);
430                 return 0;
431         }
432
433         if (set == 0)
434                 pci_read_config_dword(pdev, offset, (u32 *) value);
435         else
436                 pci_write_config_dword(pdev, offset, (u32)(*value));
437
438         return 1;
439 }
440
441 /*
442 unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
443         unsigned long offset, unsigned long set, unsigned long *value)
444 {
445         static struct pci_dev *pdev = NULL;
446         static unsigned char init = 0, valid_pdev = 0;
447         u16 nbridge_id = 0;
448
449         if (!init) {
450                 init = 1;
451                 switch (xgi_video_info.chip) {
452                 case XGI_540:
453                         nbridge_id = PCI_DEVICE_ID_XG_540;
454                         break;
455                 case XGI_630:
456                         nbridge_id = PCI_DEVICE_ID_XG_630;
457                         break;
458                 case XGI_730:
459                         nbridge_id = PCI_DEVICE_ID_XG_730;
460                         break;
461                 case XGI_550:
462                         nbridge_id = PCI_DEVICE_ID_XG_550;
463                         break;
464                 case XGI_650:
465                         nbridge_id = PCI_DEVICE_ID_XG_650;
466                         break;
467                 case XGI_740:
468                         nbridge_id = PCI_DEVICE_ID_XG_740;
469                         break;
470                 default:
471                         nbridge_id = 0;
472                         break;
473                 }
474
475                 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
476                 if (pdev) {
477                         valid_pdev = 1;
478                         pci_dev_put(pdev);
479                 }
480         }
481
482         if (!valid_pdev) {
483                 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
484                         nbridge_id);
485                 return 0;
486         }
487
488         if (set == 0)
489                 pci_read_config_dword(pdev, offset, (u32 *)value);
490         else
491                 pci_write_config_dword(pdev, offset, (u32)(*value));
492
493         return 1;
494 }
495 */
496 /* ------------------ Internal helper routines ----------------- */
497
498 static void XGIfb_search_mode(const char *name)
499 {
500         int i = 0, j = 0, l;
501
502         if (name == NULL) {
503                 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
504                 xgifb_mode_idx = DEFAULT_MODE;
505                 if ((xgi_video_info.chip == XG21)
506                                 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
507                                                 == DISPTYPE_LCD)) {
508                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
509                 }
510                 return;
511         }
512
513         if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
514                 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
515                 xgifb_mode_idx = DEFAULT_MODE;
516                 if ((xgi_video_info.chip == XG21)
517                                 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
518                                                 == DISPTYPE_LCD)) {
519                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
520                 }
521                 return;
522         }
523
524         while (XGIbios_mode[i].mode_no != 0) {
525                 l = min(strlen(name), strlen(XGIbios_mode[i].name));
526                 if (!strncmp(name, XGIbios_mode[i].name, l)) {
527                         xgifb_mode_idx = i;
528                         j = 1;
529                         break;
530                 }
531                 i++;
532         }
533         if (!j)
534                 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
535 }
536
537 static void XGIfb_search_vesamode(unsigned int vesamode)
538 {
539         int i = 0, j = 0;
540
541         if (vesamode == 0) {
542
543                 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
544                 xgifb_mode_idx = DEFAULT_MODE;
545                 if ((xgi_video_info.chip == XG21)
546                                 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
547                                                 == DISPTYPE_LCD)) {
548                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
549                 }
550                 return;
551         }
552
553         vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
554
555         while (XGIbios_mode[i].mode_no != 0) {
556                 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
557                                 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
558                         xgifb_mode_idx = i;
559                         j = 1;
560                         break;
561                 }
562                 i++;
563         }
564         if (!j)
565                 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
566 }
567
568 static int XGIfb_GetXG21LVDSData(void)
569 {
570         u8 tmp;
571         unsigned char *pData;
572         int i, j, k;
573
574         inXGIIDXREG(XGISR, 0x1e, tmp);
575         outXGIIDXREG(XGISR, 0x1e, tmp | 4);
576
577         pData = xgi_video_info.mmio_vbase + 0x20000;
578         if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
579                 i = pData[0x316] | (pData[0x317] << 8);
580                 j = pData[i - 1];
581                 if (j == 0xff)
582                         j = 1;
583
584                 k = 0;
585                 do {
586                         XGI21_LCDCapList[k].LVDS_Capability = pData[i]
587                                         | (pData[i + 1] << 8);
588                         XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
589                                         + 3] << 8);
590                         XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
591                                         + 5] << 8);
592                         XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
593                                         + 7] << 8);
594                         XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
595                                         + 9] << 8);
596                         XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
597                                         + 11] << 8);
598                         XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
599                                         + 13] << 8);
600                         XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
601                                         | (pData[i + 15] << 8);
602                         XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
603                                         | (pData[i + 17] << 8);
604                         XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
605                         XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
606                         XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
607                         XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
608                         XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
609                         XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
610                         XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
611                         i += 25;
612                         j--;
613                         k++;
614                 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
615                                 / sizeof(struct XGI21_LVDSCapStruct))));
616                 return 1;
617         }
618         return 0;
619 }
620
621 int XGIfb_GetXG21DefaultLVDSModeIdx(void)
622 {
623
624         int found_mode = 0;
625         int XGIfb_mode_idx = 0;
626
627         found_mode = 0;
628         while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
629                         && (XGIbios_mode[XGIfb_mode_idx].xres
630                                         <= XGI21_LCDCapList[0].LVDSHDE)) {
631                 if ((XGIbios_mode[XGIfb_mode_idx].xres
632                                 == XGI21_LCDCapList[0].LVDSHDE)
633                                 && (XGIbios_mode[XGIfb_mode_idx].yres
634                                                 == XGI21_LCDCapList[0].LVDSVDE)
635                                 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
636                         XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
637                         found_mode = 1;
638                         break;
639                 }
640                 XGIfb_mode_idx++;
641         }
642         if (!found_mode)
643                 XGIfb_mode_idx = 0;
644
645         return XGIfb_mode_idx;
646 }
647
648 static int XGIfb_validate_mode(int myindex)
649 {
650         u16 xres, yres;
651
652         if (xgi_video_info.chip == XG21) {
653                 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
654                                 == DISPTYPE_LCD) {
655                         xres = XGI21_LCDCapList[0].LVDSHDE;
656                         yres = XGI21_LCDCapList[0].LVDSVDE;
657                         if (XGIbios_mode[myindex].xres > xres)
658                                 return -1;
659                         if (XGIbios_mode[myindex].yres > yres)
660                                 return -1;
661                         if ((XGIbios_mode[myindex].xres < xres)
662                                         && (XGIbios_mode[myindex].yres < yres)) {
663                                 if (XGIbios_mode[myindex].bpp > 8)
664                                         return -1;
665                         }
666
667                 }
668                 return myindex;
669
670         }
671
672         /* FIXME: for now, all is valid on XG27 */
673         if (xgi_video_info.chip == XG27)
674                 return myindex;
675
676         if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
677                 return -1;
678
679         switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
680         case DISPTYPE_LCD:
681                 switch (XGIhw_ext.ulCRT2LCDType) {
682                 case LCD_640x480:
683                         xres = 640;
684                         yres = 480;
685                         break;
686                 case LCD_800x600:
687                         xres = 800;
688                         yres = 600;
689                         break;
690                 case LCD_1024x600:
691                         xres = 1024;
692                         yres = 600;
693                         break;
694                 case LCD_1024x768:
695                         xres = 1024;
696                         yres = 768;
697                         break;
698                 case LCD_1152x768:
699                         xres = 1152;
700                         yres = 768;
701                         break;
702                 case LCD_1280x960:
703                         xres = 1280;
704                         yres = 960;
705                         break;
706                 case LCD_1280x768:
707                         xres = 1280;
708                         yres = 768;
709                         break;
710                 case LCD_1280x1024:
711                         xres = 1280;
712                         yres = 1024;
713                         break;
714                 case LCD_1400x1050:
715                         xres = 1400;
716                         yres = 1050;
717                         break;
718                 case LCD_1600x1200:
719                         xres = 1600;
720                         yres = 1200;
721                         break;
722                 /* case LCD_320x480: */ /* TW: FSTN */
723                         /*
724                         xres =  320;
725                         yres =  480;
726                         break;
727                         */
728                 default:
729                         xres = 0;
730                         yres = 0;
731                         break;
732                 }
733                 if (XGIbios_mode[myindex].xres > xres)
734                         return -1;
735                 if (XGIbios_mode[myindex].yres > yres)
736                         return -1;
737                 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
738                                 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
739                         switch (XGIbios_mode[myindex].xres) {
740                         case 512:
741                                 if (XGIbios_mode[myindex].yres != 512)
742                                         return -1;
743                                 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
744                                         return -1;
745                                 break;
746                         case 640:
747                                 if ((XGIbios_mode[myindex].yres != 400)
748                                                 && (XGIbios_mode[myindex].yres
749                                                                 != 480))
750                                         return -1;
751                                 break;
752                         case 800:
753                                 if (XGIbios_mode[myindex].yres != 600)
754                                         return -1;
755                                 break;
756                         case 1024:
757                                 if ((XGIbios_mode[myindex].yres != 600)
758                                                 && (XGIbios_mode[myindex].yres
759                                                                 != 768))
760                                         return -1;
761                                 if ((XGIbios_mode[myindex].yres == 600)
762                                                 && (XGIhw_ext.ulCRT2LCDType
763                                                                 != LCD_1024x600))
764                                         return -1;
765                                 break;
766                         case 1152:
767                                 if ((XGIbios_mode[myindex].yres) != 768)
768                                         return -1;
769                                 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
770                                         return -1;
771                                 break;
772                         case 1280:
773                                 if ((XGIbios_mode[myindex].yres != 768)
774                                                 && (XGIbios_mode[myindex].yres
775                                                                 != 1024))
776                                         return -1;
777                                 if ((XGIbios_mode[myindex].yres == 768)
778                                                 && (XGIhw_ext.ulCRT2LCDType
779                                                                 != LCD_1280x768))
780                                         return -1;
781                                 break;
782                         case 1400:
783                                 if (XGIbios_mode[myindex].yres != 1050)
784                                         return -1;
785                                 break;
786                         case 1600:
787                                 if (XGIbios_mode[myindex].yres != 1200)
788                                         return -1;
789                                 break;
790                         default:
791                                 return -1;
792                         }
793                 } else {
794                         switch (XGIbios_mode[myindex].xres) {
795                         case 512:
796                                 if (XGIbios_mode[myindex].yres != 512)
797                                         return -1;
798                                 break;
799                         case 640:
800                                 if ((XGIbios_mode[myindex].yres != 400)
801                                                 && (XGIbios_mode[myindex].yres
802                                                                 != 480))
803                                         return -1;
804                                 break;
805                         case 800:
806                                 if (XGIbios_mode[myindex].yres != 600)
807                                         return -1;
808                                 break;
809                         case 1024:
810                                 if (XGIbios_mode[myindex].yres != 768)
811                                         return -1;
812                                 break;
813                         case 1280:
814                                 if ((XGIbios_mode[myindex].yres != 960)
815                                                 && (XGIbios_mode[myindex].yres
816                                                                 != 1024))
817                                         return -1;
818                                 if (XGIbios_mode[myindex].yres == 960) {
819                                         if (XGIhw_ext.ulCRT2LCDType
820                                                         == LCD_1400x1050)
821                                                 return -1;
822                                 }
823                                 break;
824                         case 1400:
825                                 if (XGIbios_mode[myindex].yres != 1050)
826                                         return -1;
827                                 break;
828                         case 1600:
829                                 if (XGIbios_mode[myindex].yres != 1200)
830                                         return -1;
831                                 break;
832                         default:
833                                 return -1;
834                         }
835                 }
836                 break;
837         case DISPTYPE_TV:
838                 switch (XGIbios_mode[myindex].xres) {
839                 case 512:
840                 case 640:
841                 case 800:
842                         break;
843                 case 720:
844                         if (xgi_video_info.TV_type == TVMODE_NTSC) {
845                                 if (XGIbios_mode[myindex].yres != 480)
846                                         return -1;
847                         } else if (xgi_video_info.TV_type == TVMODE_PAL) {
848                                 if (XGIbios_mode[myindex].yres != 576)
849                                         return -1;
850                         }
851                         /*  TW: LVDS/CHRONTEL does not support 720 */
852                         if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
853                                         || xgi_video_info.hasVB == HASVB_CHRONTEL) {
854                                 return -1;
855                         }
856                         break;
857                 case 1024:
858                         if (xgi_video_info.TV_type == TVMODE_NTSC) {
859                                 if (XGIbios_mode[myindex].bpp == 32)
860                                         return -1;
861                         }
862                         /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */
863                         if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
864                                         || xgi_video_info.hasVB == HASVB_CHRONTEL) {
865                                 if (xgi_video_info.chip < XGI_315H)
866                                         return -1;
867                         }
868                         break;
869                 default:
870                         return -1;
871                 }
872                 break;
873         case DISPTYPE_CRT2:
874                 if (XGIbios_mode[myindex].xres > 1280)
875                         return -1;
876                 break;
877         }
878         return myindex;
879
880 }
881
882 static void XGIfb_search_crt2type(const char *name)
883 {
884         int i = 0;
885
886         if (name == NULL)
887                 return;
888
889         while (XGI_crt2type[i].type_no != -1) {
890                 if (!strcmp(name, XGI_crt2type[i].name)) {
891                         XGIfb_crt2type = XGI_crt2type[i].type_no;
892                         XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
893                         break;
894                 }
895                 i++;
896         }
897         if (XGIfb_crt2type < 0)
898                 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
899 }
900
901 static void XGIfb_search_queuemode(const char *name)
902 {
903         int i = 0;
904
905         if (name == NULL)
906                 return;
907
908         while (XGI_queuemode[i].type_no != -1) {
909                 if (!strcmp(name, XGI_queuemode[i].name)) {
910                         XGIfb_queuemode = XGI_queuemode[i].type_no;
911                         break;
912                 }
913                 i++;
914         }
915         if (XGIfb_queuemode < 0)
916                 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
917 }
918
919 static u8 XGIfb_search_refresh_rate(unsigned int rate)
920 {
921         u16 xres, yres;
922         int i = 0;
923
924         xres = XGIbios_mode[xgifb_mode_idx].xres;
925         yres = XGIbios_mode[xgifb_mode_idx].yres;
926
927         XGIfb_rate_idx = 0;
928         while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
929                 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
930                                 == yres)) {
931                         if (XGIfb_vrate[i].refresh == rate) {
932                                 XGIfb_rate_idx = XGIfb_vrate[i].idx;
933                                 break;
934                         } else if (XGIfb_vrate[i].refresh > rate) {
935                                 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
936                                         DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
937                                                         rate, XGIfb_vrate[i].refresh);
938                                         XGIfb_rate_idx = XGIfb_vrate[i].idx;
939                                         xgi_video_info.refresh_rate
940                                                         = XGIfb_vrate[i].refresh;
941                                 } else if (((rate - XGIfb_vrate[i - 1].refresh)
942                                                 <= 2) && (XGIfb_vrate[i].idx
943                                                 != 1)) {
944                                         DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
945                                                         rate, XGIfb_vrate[i-1].refresh);
946                                         XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
947                                         xgi_video_info.refresh_rate
948                                                         = XGIfb_vrate[i - 1].refresh;
949                                 }
950                                 break;
951                         } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
952                                 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
953                                                 rate, XGIfb_vrate[i].refresh);
954                                 XGIfb_rate_idx = XGIfb_vrate[i].idx;
955                                 break;
956                         }
957                 }
958                 i++;
959         }
960         if (XGIfb_rate_idx > 0) {
961                 return XGIfb_rate_idx;
962         } else {
963                 printk(KERN_INFO
964                                 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
965                 return 0;
966         }
967 }
968
969 static void XGIfb_search_tvstd(const char *name)
970 {
971         int i = 0;
972
973         if (name == NULL)
974                 return;
975
976         while (XGI_tvtype[i].type_no != -1) {
977                 if (!strcmp(name, XGI_tvtype[i].name)) {
978                         XGIfb_tvmode = XGI_tvtype[i].type_no;
979                         break;
980                 }
981                 i++;
982         }
983 }
984
985 static unsigned char XGIfb_bridgeisslave(void)
986 {
987         unsigned char usScratchP1_00;
988
989         if (xgi_video_info.hasVB == HASVB_NONE)
990                 return 0;
991
992         inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00);
993         if ((usScratchP1_00 & 0x50) == 0x10)
994                 return 1;
995         else
996                 return 0;
997 }
998
999 static unsigned char XGIfbcheckvretracecrt1(void)
1000 {
1001         unsigned char temp;
1002
1003         inXGIIDXREG(XGICR, 0x17, temp);
1004         if (!(temp & 0x80))
1005                 return 0;
1006
1007         inXGIIDXREG(XGISR, 0x1f, temp);
1008         if (temp & 0xc0)
1009                 return 0;
1010
1011         if (inXGIREG(XGIINPSTAT) & 0x08)
1012                 return 1;
1013         else
1014                 return 0;
1015 }
1016
1017 static unsigned char XGIfbcheckvretracecrt2(void)
1018 {
1019         unsigned char temp;
1020         if (xgi_video_info.hasVB == HASVB_NONE)
1021                 return 0;
1022         inXGIIDXREG(XGIPART1, 0x30, temp);
1023         if (temp & 0x02)
1024                 return 0;
1025         else
1026                 return 1;
1027 }
1028
1029 static unsigned char XGIfb_CheckVBRetrace(void)
1030 {
1031         if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1032                 if (XGIfb_bridgeisslave())
1033                         return XGIfbcheckvretracecrt1();
1034                 else
1035                         return XGIfbcheckvretracecrt2();
1036         }
1037         return XGIfbcheckvretracecrt1();
1038 }
1039
1040 /* ----------- FBDev related routines for all series ----------- */
1041
1042 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1043 {
1044         switch (var->bits_per_pixel) {
1045         case 8:
1046                 var->red.offset = var->green.offset = var->blue.offset = 0;
1047                 var->red.length = var->green.length = var->blue.length = 6;
1048                 xgi_video_info.video_cmap_len = 256;
1049                 break;
1050         case 16:
1051                 var->red.offset = 11;
1052                 var->red.length = 5;
1053                 var->green.offset = 5;
1054                 var->green.length = 6;
1055                 var->blue.offset = 0;
1056                 var->blue.length = 5;
1057                 var->transp.offset = 0;
1058                 var->transp.length = 0;
1059                 xgi_video_info.video_cmap_len = 16;
1060                 break;
1061         case 32:
1062                 var->red.offset = 16;
1063                 var->red.length = 8;
1064                 var->green.offset = 8;
1065                 var->green.length = 8;
1066                 var->blue.offset = 0;
1067                 var->blue.length = 8;
1068                 var->transp.offset = 24;
1069                 var->transp.length = 8;
1070                 xgi_video_info.video_cmap_len = 16;
1071                 break;
1072         }
1073 }
1074
1075 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1076                 struct fb_info *info)
1077 {
1078
1079         unsigned int htotal = var->left_margin + var->xres + var->right_margin
1080                         + var->hsync_len;
1081         unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1082                         + var->vsync_len;
1083 #if defined(__powerpc__)
1084         u8 sr_data, cr_data;
1085 #endif
1086         unsigned int drate = 0, hrate = 0;
1087         int found_mode = 0;
1088         int old_mode;
1089         /* unsigned char reg, reg1; */
1090
1091         DEBUGPRN("Inside do_set_var");
1092         /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */
1093
1094         info->var.xres_virtual = var->xres_virtual;
1095         info->var.yres_virtual = var->yres_virtual;
1096         info->var.bits_per_pixel = var->bits_per_pixel;
1097
1098         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1099                 vtotal <<= 1;
1100         else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1101                 vtotal <<= 2;
1102         else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1103                 /* vtotal <<= 1; */
1104                 /* var->yres <<= 1; */
1105         }
1106
1107         if (!htotal || !vtotal) {
1108                 DPRINTK("XGIfb: Invalid 'var' information\n");
1109                 return -EINVAL;
1110         } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1111                         var->pixclock, htotal, vtotal);
1112
1113         if (var->pixclock && htotal && vtotal) {
1114                 drate = 1000000000 / var->pixclock;
1115                 hrate = (drate * 1000) / htotal;
1116                 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1117                                 / vtotal);
1118         } else {
1119                 xgi_video_info.refresh_rate = 60;
1120         }
1121
1122         printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1123                         var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
1124
1125         old_mode = xgifb_mode_idx;
1126         xgifb_mode_idx = 0;
1127
1128         while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1129                         && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1130                 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1131                                 && (XGIbios_mode[xgifb_mode_idx].yres
1132                                                 == var->yres)
1133                                 && (XGIbios_mode[xgifb_mode_idx].bpp
1134                                                 == var->bits_per_pixel)) {
1135                         XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1136                         found_mode = 1;
1137                         break;
1138                 }
1139                 xgifb_mode_idx++;
1140         }
1141
1142         if (found_mode)
1143                 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1144         else
1145                 xgifb_mode_idx = -1;
1146
1147         if (xgifb_mode_idx < 0) {
1148                 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1149                                 var->yres, var->bits_per_pixel);
1150                 xgifb_mode_idx = old_mode;
1151                 return -EINVAL;
1152         }
1153
1154         if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1155                 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1156                 xgi_video_info.refresh_rate = 60;
1157         }
1158
1159         if (isactive) {
1160
1161                 XGIfb_pre_setmode();
1162                 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1163                         printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1164                         return -EINVAL;
1165                 }
1166                 info->fix.line_length = ((info->var.xres_virtual
1167                                 * info->var.bits_per_pixel) >> 6);
1168
1169                 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1170
1171                 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1172                 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
1173
1174                 XGIfb_post_setmode();
1175
1176                 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1177                                 XGIbios_mode[xgifb_mode_idx].xres,
1178                                 XGIbios_mode[xgifb_mode_idx].yres,
1179                                 XGIbios_mode[xgifb_mode_idx].bpp,
1180                                 xgi_video_info.refresh_rate);
1181
1182                 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1183                 xgi_video_info.video_vwidth = info->var.xres_virtual;
1184                 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1185                 xgi_video_info.video_vheight = info->var.yres_virtual;
1186                 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1187                 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1188                 xgi_video_info.video_linelength = info->var.xres_virtual
1189                                 * (xgi_video_info.video_bpp >> 3);
1190                 xgi_video_info.accel = 0;
1191                 if (XGIfb_accel) {
1192                         xgi_video_info.accel = (var->accel_flags
1193                                         & FB_ACCELF_TEXT) ? -1 : 0;
1194                 }
1195                 switch (xgi_video_info.video_bpp) {
1196                 case 8:
1197                         xgi_video_info.DstColor = 0x0000;
1198                         xgi_video_info.XGI310_AccelDepth = 0x00000000;
1199                         xgi_video_info.video_cmap_len = 256;
1200 #if defined(__powerpc__)
1201                         inXGIIDXREG(XGICR, 0x4D, cr_data);
1202                         outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1203 #endif
1204                         break;
1205                 case 16:
1206                         xgi_video_info.DstColor = 0x8000;
1207                         xgi_video_info.XGI310_AccelDepth = 0x00010000;
1208 #if defined(__powerpc__)
1209                         inXGIIDXREG(XGICR, 0x4D, cr_data);
1210                         outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1211 #endif
1212                         xgi_video_info.video_cmap_len = 16;
1213                         break;
1214                 case 32:
1215                         xgi_video_info.DstColor = 0xC000;
1216                         xgi_video_info.XGI310_AccelDepth = 0x00020000;
1217                         xgi_video_info.video_cmap_len = 16;
1218 #if defined(__powerpc__)
1219                         inXGIIDXREG(XGICR, 0x4D, cr_data);
1220                         outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1221 #endif
1222                         break;
1223                 default:
1224                         xgi_video_info.video_cmap_len = 16;
1225                         printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1226                         xgi_video_info.accel = 0;
1227                         break;
1228                 }
1229         }
1230         XGIfb_bpp_to_var(var); /*update ARGB info*/
1231         DEBUGPRN("End of do_set_var");
1232
1233         dumpVGAReg();
1234         return 0;
1235 }
1236
1237 #ifdef XGIFB_PAN
1238 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1239 {
1240         unsigned int base;
1241
1242         /* printk("Inside pan_var"); */
1243
1244         if (var->xoffset > (var->xres_virtual - var->xres)) {
1245                 /* printk("Pan: xo: %d xv %d xr %d\n",
1246                         var->xoffset, var->xres_virtual, var->xres); */
1247                 return -EINVAL;
1248         }
1249         if (var->yoffset > (var->yres_virtual - var->yres)) {
1250                 /* printk("Pan: yo: %d yv %d yr %d\n",
1251                         var->yoffset, var->yres_virtual, var->yres); */
1252                 return -EINVAL;
1253         }
1254         base = var->yoffset * var->xres_virtual + var->xoffset;
1255
1256         /* calculate base bpp dep. */
1257         switch (var->bits_per_pixel) {
1258         case 16:
1259                 base >>= 1;
1260                 break;
1261         case 32:
1262                 break;
1263         case 8:
1264         default:
1265                 base >>= 2;
1266                 break;
1267         }
1268
1269         outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1270
1271         outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1272         outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1273         outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1274         outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1275         setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1276
1277         if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1278                 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1279                 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1280                 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1281                 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1282                 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1283         }
1284         /* printk("End of pan_var"); */
1285         return 0;
1286 }
1287 #endif
1288
1289 void XGI_dispinfo(struct ap_data *rec)
1290 {
1291         rec->minfo.bpp = xgi_video_info.video_bpp;
1292         rec->minfo.xres = xgi_video_info.video_width;
1293         rec->minfo.yres = xgi_video_info.video_height;
1294         rec->minfo.v_xres = xgi_video_info.video_vwidth;
1295         rec->minfo.v_yres = xgi_video_info.video_vheight;
1296         rec->minfo.org_x = xgi_video_info.org_x;
1297         rec->minfo.org_y = xgi_video_info.org_y;
1298         rec->minfo.vrate = xgi_video_info.refresh_rate;
1299         rec->iobase = xgi_video_info.vga_base - 0x30;
1300         rec->mem_size = xgi_video_info.video_size;
1301         rec->disp_state = xgi_video_info.disp_state;
1302         rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1303         rec->hasVB = xgi_video_info.hasVB;
1304         rec->TV_type = xgi_video_info.TV_type;
1305         rec->TV_plug = xgi_video_info.TV_plug;
1306         rec->chip = xgi_video_info.chip;
1307 }
1308
1309 static int XGIfb_open(struct fb_info *info, int user)
1310 {
1311         return 0;
1312 }
1313
1314 static int XGIfb_release(struct fb_info *info, int user)
1315 {
1316         return 0;
1317 }
1318
1319 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1320 {
1321         int rc = 16;
1322
1323         switch (var->bits_per_pixel) {
1324         case 8:
1325                 rc = 256;
1326                 break;
1327         case 16:
1328                 rc = 16;
1329                 break;
1330         case 32:
1331                 rc = 16;
1332                 break;
1333         }
1334         return rc;
1335 }
1336
1337 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1338                 unsigned blue, unsigned transp, struct fb_info *info)
1339 {
1340         if (regno >= XGIfb_get_cmap_len(&info->var))
1341                 return 1;
1342
1343         switch (info->var.bits_per_pixel) {
1344         case 8:
1345                 outXGIREG(XGIDACA, regno);
1346                 outXGIREG(XGIDACD, (red >> 10));
1347                 outXGIREG(XGIDACD, (green >> 10));
1348                 outXGIREG(XGIDACD, (blue >> 10));
1349                 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1350                         outXGIREG(XGIDAC2A, regno);
1351                         outXGIREG(XGIDAC2D, (red >> 8));
1352                         outXGIREG(XGIDAC2D, (green >> 8));
1353                         outXGIREG(XGIDAC2D, (blue >> 8));
1354                 }
1355                 break;
1356         case 16:
1357                 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1358                                 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1359                                 >> 11);
1360                 break;
1361         case 32:
1362                 red >>= 8;
1363                 green >>= 8;
1364                 blue >>= 8;
1365                 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1366                                 << 8) | (blue);
1367                 break;
1368         }
1369         return 0;
1370 }
1371
1372 static int XGIfb_set_par(struct fb_info *info)
1373 {
1374         int err;
1375
1376         /* printk("XGIfb: inside set_par\n"); */
1377         err = XGIfb_do_set_var(&info->var, 1, info);
1378         if (err)
1379                 return err;
1380         XGIfb_get_fix(&info->fix, -1, info);
1381         /* printk("XGIfb: end of set_par\n"); */
1382         return 0;
1383 }
1384
1385 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1386 {
1387         unsigned int htotal = var->left_margin + var->xres + var->right_margin
1388                         + var->hsync_len;
1389         unsigned int vtotal = 0;
1390         unsigned int drate = 0, hrate = 0;
1391         int found_mode = 0;
1392         int refresh_rate, search_idx;
1393
1394         DEBUGPRN("Inside check_var");
1395
1396         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1397                 vtotal = var->upper_margin + var->yres + var->lower_margin
1398                                 + var->vsync_len;
1399                 vtotal <<= 1;
1400         } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1401                 vtotal = var->upper_margin + var->yres + var->lower_margin
1402                                 + var->vsync_len;
1403                 vtotal <<= 2;
1404         } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1405                 vtotal = var->upper_margin + (var->yres / 2)
1406                                 + var->lower_margin + var->vsync_len;
1407         } else
1408                 vtotal = var->upper_margin + var->yres + var->lower_margin
1409                                 + var->vsync_len;
1410
1411         if (!(htotal) || !(vtotal))
1412                 XGIFAIL("XGIfb: no valid timing data");
1413
1414         if (var->pixclock && htotal && vtotal) {
1415                 drate = 1000000000 / var->pixclock;
1416                 hrate = (drate * 1000) / htotal;
1417                 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1418                 printk(KERN_DEBUG
1419                         "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1420                         "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1421                         __func__, var->pixclock, htotal, vtotal,
1422                         __func__, drate, hrate, xgi_video_info.refresh_rate);
1423         } else {
1424                 xgi_video_info.refresh_rate = 60;
1425         }
1426
1427         /*
1428         if ((var->pixclock) && (htotal)) {
1429                 drate = 1E12 / var->pixclock;
1430                 hrate = drate / htotal;
1431                 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1432         } else {
1433                 refresh_rate = 60;
1434         }
1435         */
1436         /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1437         if ((var->xres == 1024) && (var->yres == 600))
1438                 refresh_rate = 60;
1439
1440         search_idx = 0;
1441         while ((XGIbios_mode[search_idx].mode_no != 0) &&
1442                 (XGIbios_mode[search_idx].xres <= var->xres)) {
1443                 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1444                         (XGIbios_mode[search_idx].yres == var->yres) &&
1445                         (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1446                         if (XGIfb_validate_mode(search_idx) > 0) {
1447                                 found_mode = 1;
1448                                 break;
1449                         }
1450                 }
1451                 search_idx++;
1452         }
1453
1454         if (!found_mode) {
1455
1456                 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1457                         var->xres, var->yres, var->bits_per_pixel);
1458                 search_idx = 0;
1459                 while (XGIbios_mode[search_idx].mode_no != 0) {
1460
1461                         if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1462                                 (var->yres <= XGIbios_mode[search_idx].yres) &&
1463                                 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1464                                 if (XGIfb_validate_mode(search_idx) > 0) {
1465                                         found_mode = 1;
1466                                         break;
1467                                 }
1468                         }
1469                         search_idx++;
1470                 }
1471                 if (found_mode) {
1472                         var->xres = XGIbios_mode[search_idx].xres;
1473                         var->yres = XGIbios_mode[search_idx].yres;
1474                         printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1475                                 var->xres, var->yres, var->bits_per_pixel);
1476
1477                 } else {
1478                         printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1479                                 var->xres, var->yres, var->bits_per_pixel);
1480                         return -EINVAL;
1481                 }
1482         }
1483
1484         /* TW: TODO: Check the refresh rate */
1485
1486         /* Adapt RGB settings */
1487         XGIfb_bpp_to_var(var);
1488
1489         /* Sanity check for offsets */
1490         if (var->xoffset < 0)
1491                 var->xoffset = 0;
1492         if (var->yoffset < 0)
1493                 var->yoffset = 0;
1494
1495         if (!XGIfb_ypan) {
1496                 if (var->xres != var->xres_virtual)
1497                         var->xres_virtual = var->xres;
1498                 if (var->yres != var->yres_virtual)
1499                         var->yres_virtual = var->yres;
1500         } /* else { */
1501                 /* TW: Now patch yres_virtual if we use panning */
1502                 /* May I do this? */
1503                 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1504                 /* if (var->yres_virtual <= var->yres) { */
1505                 /* TW: Paranoia check */
1506                 /* var->yres_virtual = var->yres; */
1507                 /* } */
1508         /* } */
1509
1510         /* Truncate offsets to maximum if too high */
1511         if (var->xoffset > var->xres_virtual - var->xres)
1512                 var->xoffset = var->xres_virtual - var->xres - 1;
1513
1514         if (var->yoffset > var->yres_virtual - var->yres)
1515                 var->yoffset = var->yres_virtual - var->yres - 1;
1516
1517         /* Set everything else to 0 */
1518         var->red.msb_right =
1519         var->green.msb_right =
1520         var->blue.msb_right =
1521         var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1522
1523         DEBUGPRN("end of check_var");
1524         return 0;
1525 }
1526
1527 #ifdef XGIFB_PAN
1528 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1529                 struct fb_info *info)
1530 {
1531         int err;
1532
1533         /* printk("\nInside pan_display:\n"); */
1534
1535         if (var->xoffset > (var->xres_virtual - var->xres))
1536                 return -EINVAL;
1537         if (var->yoffset > (var->yres_virtual - var->yres))
1538                 return -EINVAL;
1539
1540         if (var->vmode & FB_VMODE_YWRAP) {
1541                 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1542                                 || var->xoffset)
1543                         return -EINVAL;
1544         } else {
1545                 if (var->xoffset + info->var.xres > info->var.xres_virtual
1546                                 || var->yoffset + info->var.yres
1547                                                 > info->var.yres_virtual)
1548                         return -EINVAL;
1549         }
1550         err = XGIfb_pan_var(var);
1551         if (err < 0)
1552                 return err;
1553
1554         info->var.xoffset = var->xoffset;
1555         info->var.yoffset = var->yoffset;
1556         if (var->vmode & FB_VMODE_YWRAP)
1557                 info->var.vmode |= FB_VMODE_YWRAP;
1558         else
1559                 info->var.vmode &= ~FB_VMODE_YWRAP;
1560
1561         /* printk("End of pan_display\n"); */
1562         return 0;
1563 }
1564 #endif
1565
1566 static int XGIfb_blank(int blank, struct fb_info *info)
1567 {
1568         u8 reg;
1569
1570         inXGIIDXREG(XGICR, 0x17, reg);
1571
1572         if (blank > 0)
1573                 reg &= 0x7f;
1574         else
1575                 reg |= 0x80;
1576
1577         outXGIIDXREG(XGICR, 0x17, reg);
1578         outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1579         outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1580         return 0;
1581 }
1582
1583 static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
1584                 unsigned long arg)
1585 {
1586         DEBUGPRN("inside ioctl");
1587         switch (cmd) {
1588         case FBIO_ALLOC:
1589                 if (!capable(CAP_SYS_RAWIO))
1590                         return -EPERM;
1591                 XGI_malloc((struct XGI_memreq *) arg);
1592                 break;
1593         case FBIO_FREE:
1594                 if (!capable(CAP_SYS_RAWIO))
1595                         return -EPERM;
1596                 XGI_free(*(unsigned long *) arg);
1597                 break;
1598         case FBIOGET_HWCINFO: {
1599                 unsigned long *hwc_offset = (unsigned long *) arg;
1600
1601                 if (XGIfb_caps & HW_CURSOR_CAP)
1602                         *hwc_offset
1603                                         = XGIfb_hwcursor_vbase
1604                                                         - (unsigned long) xgi_video_info.video_vbase;
1605                 else
1606                         *hwc_offset = 0;
1607
1608                 break;
1609         }
1610         case FBIOPUT_MODEINFO: {
1611                 struct mode_info *x = (struct mode_info *) arg;
1612
1613                 xgi_video_info.video_bpp = x->bpp;
1614                 xgi_video_info.video_width = x->xres;
1615                 xgi_video_info.video_height = x->yres;
1616                 xgi_video_info.video_vwidth = x->v_xres;
1617                 xgi_video_info.video_vheight = x->v_yres;
1618                 xgi_video_info.org_x = x->org_x;
1619                 xgi_video_info.org_y = x->org_y;
1620                 xgi_video_info.refresh_rate = x->vrate;
1621                 xgi_video_info.video_linelength = xgi_video_info.video_vwidth
1622                                 * (xgi_video_info.video_bpp >> 3);
1623                 switch (xgi_video_info.video_bpp) {
1624                 case 8:
1625                         xgi_video_info.DstColor = 0x0000;
1626                         xgi_video_info.XGI310_AccelDepth = 0x00000000;
1627                         xgi_video_info.video_cmap_len = 256;
1628                         break;
1629                 case 16:
1630                         xgi_video_info.DstColor = 0x8000;
1631                         xgi_video_info.XGI310_AccelDepth = 0x00010000;
1632                         xgi_video_info.video_cmap_len = 16;
1633                         break;
1634                 case 32:
1635                         xgi_video_info.DstColor = 0xC000;
1636                         xgi_video_info.XGI310_AccelDepth = 0x00020000;
1637                         xgi_video_info.video_cmap_len = 16;
1638                         break;
1639                 default:
1640                         xgi_video_info.video_cmap_len = 16;
1641                         printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1642                         xgi_video_info.accel = 0;
1643                         break;
1644                 }
1645
1646                 break;
1647         }
1648         case FBIOGET_DISPINFO:
1649                 XGI_dispinfo((struct ap_data *) arg);
1650                 break;
1651         case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1652         {
1653                 struct XGIfb_info *x = (struct XGIfb_info *) arg;
1654
1655                 /* x->XGIfb_id = XGIFB_ID; */
1656                 x->XGIfb_version = VER_MAJOR;
1657                 x->XGIfb_revision = VER_MINOR;
1658                 x->XGIfb_patchlevel = VER_LEVEL;
1659                 x->chip_id = xgi_video_info.chip_id;
1660                 x->memory = xgi_video_info.video_size / 1024;
1661                 x->heapstart = xgi_video_info.heapstart / 1024;
1662                 x->fbvidmode = XGIfb_mode_no;
1663                 x->XGIfb_caps = XGIfb_caps;
1664                 x->XGIfb_tqlen = 512; /* yet unused */
1665                 x->XGIfb_pcibus = xgi_video_info.pcibus;
1666                 x->XGIfb_pcislot = xgi_video_info.pcislot;
1667                 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1668                 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1669                 x->XGIfb_lcda = XGIfb_detectedlcda;
1670                 break;
1671         }
1672         case XGIFB_GET_VBRSTATUS: {
1673                 unsigned long *vbrstatus = (unsigned long *) arg;
1674                 if (XGIfb_CheckVBRetrace())
1675                         *vbrstatus = 1;
1676                 else
1677                         *vbrstatus = 0;
1678         }
1679         default:
1680                 return -EINVAL;
1681         } DEBUGPRN("end of ioctl");
1682         return 0;
1683
1684 }
1685
1686 /* ----------- FBDev related routines for all series ---------- */
1687
1688 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1689                 struct fb_info *info)
1690 {
1691         DEBUGPRN("inside get_fix");
1692         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1693
1694         strcpy(fix->id, myid);
1695
1696         fix->smem_start = xgi_video_info.video_base;
1697
1698         fix->smem_len = xgi_video_info.video_size;
1699
1700         /*        if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1701          if (xgi_video_info.video_size > 0x1000000) {
1702          fix->smem_len = 0xD00000;
1703          } else if (xgi_video_info.video_size > 0x800000)
1704          fix->smem_len = 0x800000;
1705          else
1706          fix->smem_len = 0x400000;
1707          } else
1708          fix->smem_len = XGIfb_mem * 1024;
1709          */
1710         fix->type = video_type;
1711         fix->type_aux = 0;
1712         if (xgi_video_info.video_bpp == 8)
1713                 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1714         else
1715                 fix->visual = FB_VISUAL_DIRECTCOLOR;
1716         fix->xpanstep = 0;
1717 #ifdef XGIFB_PAN
1718         if (XGIfb_ypan)
1719                 fix->ypanstep = 1;
1720 #endif
1721         fix->ywrapstep = 0;
1722         fix->line_length = xgi_video_info.video_linelength;
1723         fix->mmio_start = xgi_video_info.mmio_base;
1724         fix->mmio_len = XGIfb_mmio_size;
1725         if (xgi_video_info.chip >= XG40)
1726                 fix->accel = FB_ACCEL_XGI_XABRE;
1727         else
1728                 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
1729
1730         DEBUGPRN("end of get_fix");
1731         return 0;
1732 }
1733
1734 static struct fb_ops XGIfb_ops = {
1735         .owner = THIS_MODULE,
1736         .fb_open = XGIfb_open,
1737         .fb_release = XGIfb_release,
1738         .fb_check_var = XGIfb_check_var,
1739         .fb_set_par = XGIfb_set_par,
1740         .fb_setcolreg = XGIfb_setcolreg,
1741 #ifdef XGIFB_PAN
1742         .fb_pan_display = XGIfb_pan_display,
1743 #endif
1744         .fb_blank = XGIfb_blank,
1745         .fb_fillrect = fbcon_XGI_fillrect,
1746         .fb_copyarea = fbcon_XGI_copyarea,
1747         .fb_imageblit = cfb_imageblit,
1748         .fb_sync = fbcon_XGI_sync,
1749         .fb_ioctl = XGIfb_ioctl,
1750         /* .fb_mmap = XGIfb_mmap, */
1751 };
1752
1753 /* ---------------- Chip generation dependent routines ---------------- */
1754
1755 /* for XGI 315/550/650/740/330 */
1756
1757 static int XGIfb_get_dram_size(void)
1758 {
1759
1760         u8 ChannelNum, tmp;
1761         u8 reg = 0;
1762
1763         /* xorg driver sets 32MB * 1 channel */
1764         if (xgi_video_info.chip == XG27)
1765                 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1766
1767         inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1768         switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1769         case XGI_DRAM_SIZE_1MB:
1770                 xgi_video_info.video_size = 0x100000;
1771                 break;
1772         case XGI_DRAM_SIZE_2MB:
1773                 xgi_video_info.video_size = 0x200000;
1774                 break;
1775         case XGI_DRAM_SIZE_4MB:
1776                 xgi_video_info.video_size = 0x400000;
1777                 break;
1778         case XGI_DRAM_SIZE_8MB:
1779                 xgi_video_info.video_size = 0x800000;
1780                 break;
1781         case XGI_DRAM_SIZE_16MB:
1782                 xgi_video_info.video_size = 0x1000000;
1783                 break;
1784         case XGI_DRAM_SIZE_32MB:
1785                 xgi_video_info.video_size = 0x2000000;
1786                 break;
1787         case XGI_DRAM_SIZE_64MB:
1788                 xgi_video_info.video_size = 0x4000000;
1789                 break;
1790         case XGI_DRAM_SIZE_128MB:
1791                 xgi_video_info.video_size = 0x8000000;
1792                 break;
1793         case XGI_DRAM_SIZE_256MB:
1794                 xgi_video_info.video_size = 0x10000000;
1795                 break;
1796         default:
1797                 return -1;
1798         }
1799
1800         tmp = (reg & 0x0c) >> 2;
1801         switch (xgi_video_info.chip) {
1802         case XG20:
1803         case XG21:
1804         case XG27:
1805                 ChannelNum = 1;
1806                 break;
1807
1808         case XG42:
1809                 if (reg & 0x04)
1810                         ChannelNum = 2;
1811                 else
1812                         ChannelNum = 1;
1813                 break;
1814
1815         case XG45:
1816                 if (tmp == 1)
1817                         ChannelNum = 2;
1818                 else if (tmp == 2)
1819                         ChannelNum = 3;
1820                 else if (tmp == 3)
1821                         ChannelNum = 4;
1822                 else
1823                         ChannelNum = 1;
1824                 break;
1825
1826         case XG40:
1827         default:
1828                 if (tmp == 2)
1829                         ChannelNum = 2;
1830                 else if (tmp == 3)
1831                         ChannelNum = 3;
1832                 else
1833                         ChannelNum = 1;
1834                 break;
1835         }
1836
1837         xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1838         /* PLiad fixed for benchmarking and fb set */
1839         /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1840         /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1841
1842         printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1843                         xgi_video_info.video_size, ChannelNum);
1844         return 0;
1845
1846 }
1847
1848 static void XGIfb_detect_VB(void)
1849 {
1850         u8 cr32, temp = 0;
1851
1852         xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1853
1854         switch (xgi_video_info.hasVB) {
1855         case HASVB_LVDS_CHRONTEL:
1856         case HASVB_CHRONTEL:
1857                 break;
1858         case HASVB_301:
1859         case HASVB_302:
1860                 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1861                 break;
1862         }
1863
1864         inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1865
1866         if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1867                 XGIfb_crt1off = 0;
1868         else {
1869                 if (cr32 & 0x5F)
1870                         XGIfb_crt1off = 1;
1871                 else
1872                         XGIfb_crt1off = 0;
1873         }
1874
1875         if (XGIfb_crt2type != -1)
1876                 /* TW: Override with option */
1877                 xgi_video_info.disp_state = XGIfb_crt2type;
1878         else if (cr32 & XGI_VB_TV)
1879                 xgi_video_info.disp_state = DISPTYPE_TV;
1880         else if (cr32 & XGI_VB_LCD)
1881                 xgi_video_info.disp_state = DISPTYPE_LCD;
1882         else if (cr32 & XGI_VB_CRT2)
1883                 xgi_video_info.disp_state = DISPTYPE_CRT2;
1884         else
1885                 xgi_video_info.disp_state = 0;
1886
1887         if (XGIfb_tvplug != -1)
1888                 /* PR/TW: Override with option */
1889                 xgi_video_info.TV_plug = XGIfb_tvplug;
1890         else if (cr32 & XGI_VB_HIVISION) {
1891                 xgi_video_info.TV_type = TVMODE_HIVISION;
1892                 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1893         } else if (cr32 & XGI_VB_SVIDEO)
1894                 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1895         else if (cr32 & XGI_VB_COMPOSITE)
1896                 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1897         else if (cr32 & XGI_VB_SCART)
1898                 xgi_video_info.TV_plug = TVPLUG_SCART;
1899
1900         if (xgi_video_info.TV_type == 0) {
1901                 /* TW: PAL/NTSC changed for 650 */
1902                 if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip
1903                                 >= XGI_330)) {
1904
1905                         inXGIIDXREG(XGICR, 0x38, temp);
1906                         if (temp & 0x10)
1907                                 xgi_video_info.TV_type = TVMODE_PAL;
1908                         else
1909                                 xgi_video_info.TV_type = TVMODE_NTSC;
1910
1911                 } else {
1912
1913                         inXGIIDXREG(XGICR, 0x79, temp);
1914                         if (temp & 0x20)
1915                                 xgi_video_info.TV_type = TVMODE_PAL;
1916                         else
1917                                 xgi_video_info.TV_type = TVMODE_NTSC;
1918                 }
1919         }
1920
1921         /* TW: Copy forceCRT1 option to CRT1off if option is given */
1922         if (XGIfb_forcecrt1 != -1) {
1923                 if (XGIfb_forcecrt1)
1924                         XGIfb_crt1off = 0;
1925                 else
1926                         XGIfb_crt1off = 1;
1927         }
1928 }
1929
1930 static void XGIfb_get_VB_type(void)
1931 {
1932         u8 reg;
1933
1934         if (!XGIfb_has_VB()) {
1935                 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1936                 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1937                 case XGI310_EXTERNAL_CHIP_LVDS:
1938                         xgi_video_info.hasVB = HASVB_LVDS;
1939                         break;
1940                 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1941                         xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1942                         break;
1943                 default:
1944                         break;
1945                 }
1946         }
1947 }
1948
1949 static int XGIfb_has_VB(void)
1950 {
1951         u8 vb_chipid;
1952
1953         inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1954         switch (vb_chipid) {
1955         case 0x01:
1956                 xgi_video_info.hasVB = HASVB_301;
1957                 break;
1958         case 0x02:
1959                 xgi_video_info.hasVB = HASVB_302;
1960                 break;
1961         default:
1962                 xgi_video_info.hasVB = HASVB_NONE;
1963                 return 0;
1964         }
1965         return 1;
1966 }
1967
1968 /* ------------------ Sensing routines ------------------ */
1969
1970 /* TW: Determine and detect attached devices on XGI30x */
1971 int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
1972 {
1973         int temp, i;
1974
1975         outXGIIDXREG(XGIPART4, 0x11, tempbl);
1976         temp = tempbh | tempcl;
1977         setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1978         for (i = 0; i < 10; i++)
1979                 XGI_LongWait(&XGI_Pr);
1980         tempch &= 0x7f;
1981         inXGIIDXREG(XGIPART4, 0x03, temp);
1982         temp ^= 0x0e;
1983         temp &= tempch;
1984         return temp;
1985 }
1986
1987 void XGI_Sense30x(void)
1988 {
1989         u8 backupP4_0d;
1990         u8 testsvhs_tempbl, testsvhs_tempbh;
1991         u8 testsvhs_tempcl, testsvhs_tempch;
1992         u8 testcvbs_tempbl, testcvbs_tempbh;
1993         u8 testcvbs_tempcl, testcvbs_tempch;
1994         u8 testvga2_tempbl, testvga2_tempbh;
1995         u8 testvga2_tempcl, testvga2_tempch;
1996         int myflag, result;
1997
1998         inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1999         outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
2000
2001         testvga2_tempbh = 0x00;
2002         testvga2_tempbl = 0xd1;
2003         testsvhs_tempbh = 0x00;
2004         testsvhs_tempbl = 0xb9;
2005         testcvbs_tempbh = 0x00;
2006         testcvbs_tempbl = 0xb3;
2007         if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
2008                         != VB_CHIP_302)) {
2009                 testvga2_tempbh = 0x01;
2010                 testvga2_tempbl = 0x90;
2011                 testsvhs_tempbh = 0x01;
2012                 testsvhs_tempbl = 0x6b;
2013                 testcvbs_tempbh = 0x01;
2014                 testcvbs_tempbl = 0x74;
2015                 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
2016                                 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
2017                         testvga2_tempbh = 0x00;
2018                         testvga2_tempbl = 0x00;
2019                         testsvhs_tempbh = 0x02;
2020                         testsvhs_tempbl = 0x00;
2021                         testcvbs_tempbh = 0x01;
2022                         testcvbs_tempbl = 0x00;
2023                 }
2024         }
2025         if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
2026                         != VB_CHIP_302LV) {
2027                 inXGIIDXREG(XGIPART4, 0x01, myflag);
2028                 if (myflag & 0x04) {
2029                         testvga2_tempbh = 0x00;
2030                         testvga2_tempbl = 0xfd;
2031                         testsvhs_tempbh = 0x00;
2032                         testsvhs_tempbl = 0xdd;
2033                         testcvbs_tempbh = 0x00;
2034                         testcvbs_tempbl = 0xee;
2035                 }
2036         }
2037         if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
2038                         == VB_CHIP_302LV)) {
2039                 testvga2_tempbh = 0x00;
2040                 testvga2_tempbl = 0x00;
2041                 testvga2_tempch = 0x00;
2042                 testvga2_tempcl = 0x00;
2043                 testsvhs_tempch = 0x04;
2044                 testsvhs_tempcl = 0x08;
2045                 testcvbs_tempch = 0x08;
2046                 testcvbs_tempcl = 0x08;
2047         } else {
2048                 testvga2_tempch = 0x0e;
2049                 testvga2_tempcl = 0x08;
2050                 testsvhs_tempch = 0x06;
2051                 testsvhs_tempcl = 0x04;
2052                 testcvbs_tempch = 0x08;
2053                 testcvbs_tempcl = 0x04;
2054         }
2055
2056         if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
2057                         || testvga2_tempbl) {
2058                 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2059                                 testvga2_tempcl, testvga2_tempch);
2060                 if (result) {
2061                         printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2062                         orXGIIDXREG(XGICR, 0x32, 0x10);
2063                 }
2064         }
2065
2066         result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
2067                         testsvhs_tempch);
2068         if (result) {
2069                 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2070                 /* TW: So we can be sure that there IS a SVHS output */
2071                 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2072                 orXGIIDXREG(XGICR, 0x32, 0x02);
2073         }
2074
2075         if (!result) {
2076                 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2077                                 testcvbs_tempcl, testcvbs_tempch);
2078                 if (result) {
2079                         printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2080                         /* TW: So we can be sure that there IS a CVBS output */
2081                         xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2082                         orXGIIDXREG(XGICR, 0x32, 0x01);
2083                 }
2084         }
2085         XGIDoSense(0, 0, 0, 0);
2086
2087         outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
2088 }
2089
2090 /* ------------------------ Heap routines -------------------------- */
2091
2092 static int XGIfb_heap_init(void)
2093 {
2094         XGI_OH *poh;
2095         u8 temp = 0;
2096
2097         int agp_enabled = 1;
2098         u32 agp_size;
2099         unsigned long *cmdq_baseport = NULL;
2100         unsigned long *read_port = NULL;
2101         unsigned long *write_port = NULL;
2102         XGI_CMDTYPE cmd_type;
2103 #ifndef AGPOFF
2104         struct agp_kern_info *agp_info;
2105         struct agp_memory *agp;
2106         u32 agp_phys;
2107 #endif
2108
2109         /* TW: The heap start is either set manually using the "mem" parameter, or
2110          *     defaults as follows:
2111          *     -) If more than 16MB videoRAM available, let our heap start at 12MB.
2112          *     -) If more than  8MB videoRAM available, let our heap start at  8MB.
2113          *     -) If 4MB or less is available, let it start at 4MB.
2114          *     This is for avoiding a clash with X driver which uses the beginning
2115          *     of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2116          *     in XF86Config-4.
2117          *     The heap start can also be specified by parameter "mem" when starting the XGIfb
2118          *     driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2119          */
2120         if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) {
2121                 if (xgi_video_info.video_size > 0x1000000)
2122                         xgi_video_info.heapstart = 0xD00000;
2123                 else if (xgi_video_info.video_size > 0x800000)
2124                         xgi_video_info.heapstart = 0x800000;
2125                 else
2126                         xgi_video_info.heapstart = 0x400000;
2127         } else {
2128                 xgi_video_info.heapstart = XGIfb_mem * 1024;
2129         }
2130         XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase
2131                         + xgi_video_info.heapstart);
2132         printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2133                         (int)(xgi_video_info.heapstart / 1024));
2134
2135         XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase
2136                         + xgi_video_info.video_size;
2137         XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
2138
2139         /* TW: Now initialize the 310 series' command queue mode.
2140          * On 310/325, there are three queue modes available which
2141          * are chosen by setting bits 7:5 in SR26:
2142          * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2143          *    track of the queue, the FIFO, command parsing and so
2144          *    on. This is the one comparable to the 300 series.
2145          * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2146          *    have to do queue management himself. Register 0x85c4 will
2147          *    hold the location of the next free queue slot, 0x85c8
2148          *    is the "queue read pointer" whose way of working is
2149          *    unknown to me. Anyway, this mode would require a
2150          *    translation of the MMIO commands to some kind of
2151          *    accelerator assembly and writing these commands
2152          *    to the memory location pointed to by 0x85c4.
2153          *    We will not use this, as nobody knows how this
2154          *    "assembly" works, and as it would require a complete
2155          *    re-write of the accelerator code.
2156          * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2157          *    queue in AGP memory space.
2158          *
2159          * SR26 bit 4 is called "Bypass H/W queue".
2160          * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2161          * SR26 bit 0 resets the queue
2162          * Size of queue memory is encoded in bits 3:2 like this:
2163          *    00  (0x00)  512K
2164          *    01  (0x04)  1M
2165          *    10  (0x08)  2M
2166          *    11  (0x0C)  4M
2167          * The queue location is to be written to 0x85C0.
2168          *
2169          */
2170         cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase
2171                         + MMIO_QUEUE_PHYBASE);
2172         write_port = (unsigned long *) (xgi_video_info.mmio_vbase
2173                         + MMIO_QUEUE_WRITEPORT);
2174         read_port = (unsigned long *) (xgi_video_info.mmio_vbase
2175                         + MMIO_QUEUE_READPORT);
2176
2177         DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2178
2179         agp_size = COMMAND_QUEUE_AREA_SIZE;
2180
2181 #ifndef AGPOFF
2182         if (XGIfb_queuemode == AGP_CMD_QUEUE) {
2183                 agp_info = vzalloc(sizeof(*agp_info));
2184                 agp_copy_info(agp_info);
2185
2186                 agp_backend_acquire();
2187
2188                 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
2189                                 AGP_NORMAL_MEMORY);
2190                 if (agp == NULL) {
2191                         DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2192                         agp_enabled = 0;
2193                 } else {
2194                         if (agp_bind_memory(agp, agp->pg_start) != 0) {
2195                                 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2196                                 /* TODO: Free AGP memory here */
2197                                 agp_enabled = 0;
2198                         } else {
2199                                 agp_enable(0);
2200                         }
2201                 }
2202         }
2203 #else
2204         agp_enabled = 0;
2205 #endif
2206
2207         /* TW: Now select the queue mode */
2208
2209         if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2210                 cmd_type = AGP_CMD_QUEUE;
2211                 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
2212         /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE)  */
2213         } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
2214                 cmd_type = VM_CMD_QUEUE;
2215                 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2216         } else {
2217                 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2218                 cmd_type = MMIO_CMD;
2219         }
2220
2221         switch (agp_size) {
2222         case 0x80000:
2223                 temp = XGI_CMD_QUEUE_SIZE_512k;
2224                 break;
2225         case 0x100000:
2226                 temp = XGI_CMD_QUEUE_SIZE_1M;
2227                 break;
2228         case 0x200000:
2229                 temp = XGI_CMD_QUEUE_SIZE_2M;
2230                 break;
2231         case 0x400000:
2232                 temp = XGI_CMD_QUEUE_SIZE_4M;
2233                 break;
2234         }
2235
2236         switch (cmd_type) {
2237         case AGP_CMD_QUEUE:
2238 #ifndef AGPOFF
2239                 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2240                         agp_info->aper_base, agp->physical, agp_size/1024);
2241
2242                 agp_phys = agp_info->aper_base + agp->physical;
2243
2244                 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2245                 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
2246
2247                 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2248
2249                 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2250
2251                 *write_port = *read_port;
2252
2253                 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2254                 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2255
2256                 *cmdq_baseport = agp_phys;
2257
2258                 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2259 #endif
2260                 break;
2261
2262         case VM_CMD_QUEUE:
2263                 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2264                 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2265
2266                 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2267
2268                 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2269
2270                 *write_port = *read_port;
2271
2272                 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2273                 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2274
2275                 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2276
2277                 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2278
2279                 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2280                         *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2281                 break;
2282
2283         default: /* MMIO */
2284
2285                 /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */
2286                 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
2287                  * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2288                  * enough. Reserve memory in any way.
2289                  */
2290                 /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */
2291                 /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */
2292                 /* FIXME */
2293                 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */
2294                 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */
2295                 /* FIXME */
2296                 /* FIXME *write_port = *read_port; */
2297                 /* FIXME */
2298                 /* FIXME *//* TW: Set Auto_Correction bit */
2299                 /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */
2300                 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */
2301                 /* FIXME */
2302                 /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */
2303                 /* FIXME */
2304                 /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */
2305                 /* FIXME */
2306                 /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */
2307                 /* FIXME        *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */
2308         break;
2309 }
2310
2311         /* TW: Now reserve memory for the HWCursor. It is always located at the very
2312         top of the videoRAM, right below the TB memory area (if used). */
2313         if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
2314                 XGIfb_heap_end -= XGIfb_hwcursor_size;
2315                 XGIfb_heap_size -= XGIfb_hwcursor_size;
2316                 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2317
2318                 XGIfb_caps |= HW_CURSOR_CAP;
2319
2320                 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
2321                                 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2322         }
2323
2324         XGIfb_heap.poha_chain = NULL;
2325         XGIfb_heap.poh_freelist = NULL;
2326
2327         poh = XGIfb_poh_new_node();
2328
2329         if (poh == NULL)
2330                 return 1;
2331
2332         poh->poh_next = &XGIfb_heap.oh_free;
2333         poh->poh_prev = &XGIfb_heap.oh_free;
2334         poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2335         poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
2336
2337         DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
2338                 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2339                 (unsigned int) poh->size / 1024);
2340
2341         DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
2342                 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2343
2344         XGIfb_heap.oh_free.poh_next = poh;
2345         XGIfb_heap.oh_free.poh_prev = poh;
2346         XGIfb_heap.oh_free.size = 0;
2347         XGIfb_heap.max_freesize = poh->size;
2348
2349         XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2350         XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2351         XGIfb_heap.oh_used.size = SENTINEL;
2352
2353         return 0;
2354 }
2355
2356 static XGI_OH *XGIfb_poh_new_node(void)
2357 {
2358         int i;
2359         unsigned long cOhs;
2360         XGI_OHALLOC *poha;
2361         XGI_OH *poh;
2362
2363         if (XGIfb_heap.poh_freelist == NULL) {
2364                 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
2365                 if (!poha)
2366                         return NULL;
2367
2368                 poha->poha_next = XGIfb_heap.poha_chain;
2369                 XGIfb_heap.poha_chain = poha;
2370
2371                 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH)
2372                                 + 1;
2373
2374                 poh = &poha->aoh[0];
2375                 for (i = cOhs - 1; i != 0; i--) {
2376                         poh->poh_next = poh + 1;
2377                         poh = poh + 1;
2378                 }
2379
2380                 poh->poh_next = NULL;
2381                 XGIfb_heap.poh_freelist = &poha->aoh[0];
2382         }
2383
2384         poh = XGIfb_heap.poh_freelist;
2385         XGIfb_heap.poh_freelist = poh->poh_next;
2386
2387         return poh;
2388 }
2389
2390 static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2391 {
2392         XGI_OH *pohThis;
2393         XGI_OH *pohRoot;
2394         int bAllocated = 0;
2395
2396         if (size > XGIfb_heap.max_freesize) {
2397                 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2398                                 (unsigned int) size / 1024);
2399                 return NULL;
2400         }
2401
2402         pohThis = XGIfb_heap.oh_free.poh_next;
2403
2404         while (pohThis != &XGIfb_heap.oh_free) {
2405                 if (size <= pohThis->size) {
2406                         bAllocated = 1;
2407                         break;
2408                 }
2409                 pohThis = pohThis->poh_next;
2410         }
2411
2412         if (!bAllocated) {
2413                 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2414                                 (unsigned int) size / 1024);
2415                 return NULL;
2416         }
2417
2418         if (size == pohThis->size) {
2419                 pohRoot = pohThis;
2420                 XGIfb_delete_node(pohThis);
2421         } else {
2422                 pohRoot = XGIfb_poh_new_node();
2423
2424                 if (pohRoot == NULL)
2425                         return NULL;
2426
2427                 pohRoot->offset = pohThis->offset;
2428                 pohRoot->size = size;
2429
2430                 pohThis->offset += size;
2431                 pohThis->size -= size;
2432         }
2433
2434         XGIfb_heap.max_freesize -= size;
2435
2436         pohThis = &XGIfb_heap.oh_used;
2437         XGIfb_insert_node(pohThis, pohRoot);
2438
2439         return pohRoot;
2440 }
2441
2442 static void XGIfb_delete_node(XGI_OH *poh)
2443 {
2444         XGI_OH *poh_prev;
2445         XGI_OH *poh_next;
2446
2447         poh_prev = poh->poh_prev;
2448         poh_next = poh->poh_next;
2449
2450         poh_prev->poh_next = poh_next;
2451         poh_next->poh_prev = poh_prev;
2452
2453 }
2454
2455 static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2456 {
2457         XGI_OH *pohTemp;
2458
2459         pohTemp = pohList->poh_next;
2460
2461         pohList->poh_next = poh;
2462         pohTemp->poh_prev = poh;
2463
2464         poh->poh_prev = pohList;
2465         poh->poh_next = pohTemp;
2466 }
2467
2468 static XGI_OH *XGIfb_poh_free(unsigned long base)
2469 {
2470         XGI_OH *pohThis;
2471         XGI_OH *poh_freed;
2472         XGI_OH *poh_prev;
2473         XGI_OH *poh_next;
2474         unsigned long ulUpper;
2475         unsigned long ulLower;
2476         int foundNode = 0;
2477
2478         poh_freed = XGIfb_heap.oh_used.poh_next;
2479
2480         while (poh_freed != &XGIfb_heap.oh_used) {
2481                 if (poh_freed->offset == base) {
2482                         foundNode = 1;
2483                         break;
2484                 }
2485
2486                 poh_freed = poh_freed->poh_next;
2487         }
2488
2489         if (!foundNode)
2490                 return NULL;
2491
2492         XGIfb_heap.max_freesize += poh_freed->size;
2493
2494         poh_prev = poh_next = NULL;
2495         ulUpper = poh_freed->offset + poh_freed->size;
2496         ulLower = poh_freed->offset;
2497
2498         pohThis = XGIfb_heap.oh_free.poh_next;
2499
2500         while (pohThis != &XGIfb_heap.oh_free) {
2501                 if (pohThis->offset == ulUpper)
2502                         poh_next = pohThis;
2503                 else if ((pohThis->offset + pohThis->size) == ulLower)
2504                         poh_prev = pohThis;
2505
2506                 pohThis = pohThis->poh_next;
2507         }
2508
2509         XGIfb_delete_node(poh_freed);
2510
2511         if (poh_prev && poh_next) {
2512                 poh_prev->size += (poh_freed->size + poh_next->size);
2513                 XGIfb_delete_node(poh_next);
2514                 XGIfb_free_node(poh_freed);
2515                 XGIfb_free_node(poh_next);
2516                 return poh_prev;
2517         }
2518
2519         if (poh_prev) {
2520                 poh_prev->size += poh_freed->size;
2521                 XGIfb_free_node(poh_freed);
2522                 return poh_prev;
2523         }
2524
2525         if (poh_next) {
2526                 poh_next->size += poh_freed->size;
2527                 poh_next->offset = poh_freed->offset;
2528                 XGIfb_free_node(poh_freed);
2529                 return poh_next;
2530         }
2531
2532         XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2533
2534         return poh_freed;
2535 }
2536
2537 static void XGIfb_free_node(XGI_OH *poh)
2538 {
2539         if (poh == NULL)
2540                 return;
2541
2542         poh->poh_next = XGIfb_heap.poh_freelist;
2543         XGIfb_heap.poh_freelist = poh;
2544
2545 }
2546
2547 void XGI_malloc(struct XGI_memreq *req)
2548 {
2549         XGI_OH *poh;
2550
2551         poh = XGIfb_poh_allocate(req->size);
2552
2553         if (poh == NULL) {
2554                 req->offset = 0;
2555                 req->size = 0;
2556                 DPRINTK("XGIfb: Video RAM allocation failed\n");
2557         } else {
2558                 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
2559                                 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
2560
2561                 req->offset = poh->offset;
2562                 req->size = poh->size;
2563         }
2564
2565 }
2566
2567 void XGI_free(unsigned long base)
2568 {
2569         XGI_OH *poh;
2570
2571         poh = XGIfb_poh_free(base);
2572
2573         if (poh == NULL) {
2574                 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
2575                                 (unsigned int) base);
2576         }
2577 }
2578
2579 /* --------------------- SetMode routines ------------------------- */
2580
2581 static void XGIfb_pre_setmode(void)
2582 {
2583         u8 cr30 = 0, cr31 = 0;
2584
2585         inXGIIDXREG(XGICR, 0x31, cr31);
2586         cr31 &= ~0x60;
2587
2588         switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2589         case DISPTYPE_CRT2:
2590                 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2591                 cr31 |= XGI_DRIVER_MODE;
2592                 break;
2593         case DISPTYPE_LCD:
2594                 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
2595                 cr31 |= XGI_DRIVER_MODE;
2596                 break;
2597         case DISPTYPE_TV:
2598                 if (xgi_video_info.TV_type == TVMODE_HIVISION)
2599                         cr30 = (XGI_VB_OUTPUT_HIVISION
2600                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
2601                 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
2602                         cr30 = (XGI_VB_OUTPUT_SVIDEO
2603                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
2604                 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
2605                         cr30 = (XGI_VB_OUTPUT_COMPOSITE
2606                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
2607                 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
2608                         cr30 = (XGI_VB_OUTPUT_SCART
2609                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
2610                 cr31 |= XGI_DRIVER_MODE;
2611
2612                 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
2613                         cr31 |= 0x01;
2614                 else
2615                         cr31 &= ~0x01;
2616                 break;
2617         default: /* disable CRT2 */
2618                 cr30 = 0x00;
2619                 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2620         }
2621
2622         outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2623         outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
2624         outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
2625
2626         if (xgi_video_info.accel)
2627                 XGIfb_syncaccel();
2628
2629 }
2630
2631 static void XGIfb_post_setmode(void)
2632 {
2633         u8 reg;
2634         unsigned char doit = 1;
2635         /*
2636         outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2637         outXGIIDXREG(XGICR, 0x13, 0x00);
2638         setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
2639         *test*
2640         */
2641         if (xgi_video_info.video_bpp == 8) {
2642                 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
2643                 if ((xgi_video_info.hasVB == HASVB_LVDS)
2644                                 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
2645                         doit = 0;
2646                 }
2647                 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
2648                 if (xgi_video_info.disp_state & DISPTYPE_LCD)
2649                         doit = 0;
2650         }
2651
2652         /* TW: We can't switch off CRT1 if bridge is in slave mode */
2653         if (xgi_video_info.hasVB != HASVB_NONE) {
2654                 inXGIIDXREG(XGIPART1, 0x00, reg);
2655
2656                 if ((reg & 0x50) == 0x10)
2657                         doit = 0;
2658
2659         } else {
2660                 XGIfb_crt1off = 0;
2661         }
2662
2663         inXGIIDXREG(XGICR, 0x17, reg);
2664         if ((XGIfb_crt1off) && (doit))
2665                 reg &= ~0x80;
2666         else
2667                 reg |= 0x80;
2668         outXGIIDXREG(XGICR, 0x17, reg);
2669
2670         andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
2671
2672         if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
2673                         == HASVB_301)) {
2674
2675                 inXGIIDXREG(XGIPART4, 0x01, reg);
2676
2677                 if (reg < 0xB0) { /* Set filter for XGI301 */
2678
2679                         switch (xgi_video_info.video_width) {
2680                         case 320:
2681                                 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2682                                 break;
2683                         case 640:
2684                                 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2685                                 break;
2686                         case 720:
2687                                 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2688                                 break;
2689                         case 800:
2690                                 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2691                                 break;
2692                         default:
2693                                 filter = -1;
2694                                 break;
2695                         }
2696
2697                         orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
2698
2699                         if (xgi_video_info.TV_type == TVMODE_NTSC) {
2700
2701                                 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
2702
2703                                 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2704
2705                                         andXGIIDXREG(XGIPART2, 0x30, 0xdf);
2706
2707                                 } else if (xgi_video_info.TV_plug
2708                                                 == TVPLUG_COMPOSITE) {
2709
2710                                         orXGIIDXREG(XGIPART2, 0x30, 0x20);
2711
2712                                         switch (xgi_video_info.video_width) {
2713                                         case 640:
2714                                                 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2715                                                 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2716                                                 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2717                                                 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2718                                                 break;
2719                                         case 720:
2720                                                 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2721                                                 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2722                                                 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2723                                                 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2724                                                 break;
2725                                         case 800:
2726                                                 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2727                                                 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2728                                                 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2729                                                 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2730                                                 break;
2731                                         }
2732                                 }
2733
2734                         } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2735
2736                                 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2737
2738                                 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2739
2740                                         andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2741
2742                                 } else if (xgi_video_info.TV_plug
2743                                                 == TVPLUG_COMPOSITE) {
2744
2745                                         orXGIIDXREG(XGIPART2, 0x30, 0x20);
2746
2747                                         switch (xgi_video_info.video_width) {
2748                                         case 640:
2749                                                 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2750                                                 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2751                                                 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2752                                                 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2753                                                 break;
2754                                         case 720:
2755                                                 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2756                                                 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2757                                                 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2758                                                 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2759                                                 break;
2760                                         case 800:
2761                                                 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2762                                                 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2763                                                 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2764                                                 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2765                                                 break;
2766                                         }
2767                                 }
2768                         }
2769
2770                         if ((filter >= 0) && (filter <= 7)) {
2771                                 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2772                                                 XGI_TV_filter[filter_tb].filter[filter][0],
2773                                                 XGI_TV_filter[filter_tb].filter[filter][1],
2774                                                 XGI_TV_filter[filter_tb].filter[filter][2],
2775                                                 XGI_TV_filter[filter_tb].filter[filter][3]
2776                                 );
2777                                 outXGIIDXREG(
2778                                                 XGIPART2,
2779                                                 0x35,
2780                                                 (XGI_TV_filter[filter_tb].filter[filter][0]));
2781                                 outXGIIDXREG(
2782                                                 XGIPART2,
2783                                                 0x36,
2784                                                 (XGI_TV_filter[filter_tb].filter[filter][1]));
2785                                 outXGIIDXREG(
2786                                                 XGIPART2,
2787                                                 0x37,
2788                                                 (XGI_TV_filter[filter_tb].filter[filter][2]));
2789                                 outXGIIDXREG(
2790                                                 XGIPART2,
2791                                                 0x38,
2792                                                 (XGI_TV_filter[filter_tb].filter[filter][3]));
2793                         }
2794
2795                 }
2796
2797         }
2798
2799 }
2800
2801 XGIINITSTATIC int __init XGIfb_setup(char *options)
2802 {
2803         char *this_opt;
2804
2805         xgi_video_info.refresh_rate = 0;
2806
2807         printk(KERN_INFO "XGIfb: Options %s\n", options);
2808
2809         if (!options || !*options)
2810                 return 0;
2811
2812         while ((this_opt = strsep(&options, ",")) != NULL) {
2813
2814                 if (!*this_opt)
2815                         continue;
2816
2817                 if (!strncmp(this_opt, "mode:", 5)) {
2818                         XGIfb_search_mode(this_opt + 5);
2819                 } else if (!strncmp(this_opt, "vesa:", 5)) {
2820                         XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2821                 } else if (!strncmp(this_opt, "mode:", 5)) {
2822                         XGIfb_search_mode(this_opt + 5);
2823                 } else if (!strncmp(this_opt, "vesa:", 5)) {
2824                         XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2825                 } else if (!strncmp(this_opt, "vrate:", 6)) {
2826                         xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2827                 } else if (!strncmp(this_opt, "rate:", 5)) {
2828                         xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2829                 } else if (!strncmp(this_opt, "off", 3)) {
2830                         XGIfb_off = 1;
2831                 } else if (!strncmp(this_opt, "crt1off", 7)) {
2832                         XGIfb_crt1off = 1;
2833                 } else if (!strncmp(this_opt, "filter:", 7)) {
2834                         filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2835                 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2836                         XGIfb_search_crt2type(this_opt + 14);
2837                 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2838                         XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2839                 } else if (!strncmp(this_opt, "tvmode:", 7)) {
2840                         XGIfb_search_tvstd(this_opt + 7);
2841                 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2842                         XGIfb_search_tvstd(this_opt + 7);
2843                 } else if (!strncmp(this_opt, "mem:", 4)) {
2844                         XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2845                 } else if (!strncmp(this_opt, "dstn", 4)) {
2846                         enable_dstn = 1;
2847                         /* TW: DSTN overrules forcecrt2type */
2848                         XGIfb_crt2type = DISPTYPE_LCD;
2849                 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2850                         XGIfb_search_queuemode(this_opt + 10);
2851                 } else if (!strncmp(this_opt, "pdc:", 4)) {
2852                         XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2853                         if (XGIfb_pdc & ~0x3c) {
2854                                 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2855                                 XGIfb_pdc = 0;
2856                         }
2857                 } else if (!strncmp(this_opt, "noaccel", 7)) {
2858                         XGIfb_accel = 0;
2859                 } else if (!strncmp(this_opt, "noypan", 6)) {
2860                         XGIfb_ypan = 0;
2861                 } else if (!strncmp(this_opt, "userom:", 7)) {
2862                         XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2863                         /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2864                         /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
2865                 } else {
2866                         XGIfb_search_mode(this_opt);
2867                         /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
2868                 }
2869
2870                 /* TW: Acceleration only with MMIO mode */
2871                 if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
2872                         XGIfb_ypan = 0;
2873                         XGIfb_accel = 0;
2874                 }
2875                 /* TW: Panning only with acceleration */
2876                 if (XGIfb_accel == 0)
2877                         XGIfb_ypan = 0;
2878
2879         }
2880         printk("\nxgifb: outa xgifb_setup 3450");
2881         return 0;
2882 }
2883
2884 static unsigned char VBIOS_BUF[65535];
2885
2886 static unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
2887 {
2888         u32 rom_size = 0;
2889         u32 rom_address = 0;
2890         int j;
2891
2892         /*  Get the size of the expansion rom */
2893         pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
2894         pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
2895         if ((rom_size & 0x01) == 0) {
2896                 printk("No ROM\n");
2897                 return NULL;
2898         }
2899
2900         rom_size &= 0xFFFFF800;
2901         rom_size = (~rom_size) + 1;
2902
2903         rom_address = pci_resource_start(dev, 0);
2904         if (rom_address == 0 || rom_address == 0xFFFFFFF0) {
2905                 printk("No suitable rom address found\n");
2906                 return NULL;
2907         }
2908
2909         printk("ROM Size is %dK, Address is %x\n", rom_size / 1024, rom_address);
2910
2911         /*  Map ROM */
2912         pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address
2913                         | PCI_ROM_ADDRESS_ENABLE);
2914
2915         /* memcpy(copy_address, rom_address, rom_size); */
2916         {
2917                 unsigned char *virt_addr = ioremap(rom_address, 0x8000000);
2918
2919                 unsigned char *from = (unsigned char *) virt_addr;
2920                 unsigned char *to = (unsigned char *) copy_address;
2921                 for (j = 0; j < 65536 /*rom_size*/; j++)
2922                         *to++ = *from++;
2923         }
2924
2925         pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
2926
2927         printk("Copy is done\n");
2928
2929         return copy_address;
2930 }
2931
2932 static int __devinit xgifb_probe(struct pci_dev *pdev,
2933                 const struct pci_device_id *ent)
2934 {
2935         u16 reg16;
2936         u8 reg, reg1;
2937         u8 CR48, CR38;
2938         if (XGIfb_off)
2939                 return -ENXIO;
2940
2941         XGIfb_registered = 0;
2942
2943         memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2944         fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2945         if (!fb_info)
2946                 return -ENOMEM;
2947
2948         xgi_video_info.chip_id = pdev->device;
2949         pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2950         pci_read_config_word(pdev, PCI_COMMAND, &reg16);
2951         XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2952         XGIvga_enabled = reg16 & 0x01;
2953
2954         xgi_video_info.pcibus = pdev->bus->number;
2955         xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2956         xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2957         xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2958         xgi_video_info.subsysdevice = pdev->subsystem_device;
2959
2960         xgi_video_info.video_base = pci_resource_start(pdev, 0);
2961         xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2962         XGIfb_mmio_size = pci_resource_len(pdev, 1);
2963         xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2964         XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2965         /* XGI_Pr.RelIO  = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2966         printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2967                         (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2968
2969         if (pci_enable_device(pdev))
2970                 return -EIO;
2971
2972         XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2973
2974         outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2975         inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
2976
2977         if (reg1 != 0xa1) { /*I/O error */
2978                 printk("\nXGIfb: I/O error!!!");
2979                 return -EIO;
2980         }
2981
2982         switch (xgi_video_info.chip_id) {
2983         case PCI_DEVICE_ID_XG_20:
2984                 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2985                 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2986                 if (CR48&GPIOG_READ)
2987                         xgi_video_info.chip = XG21;
2988                 else
2989                         xgi_video_info.chip = XG20;
2990                 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2991                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2992                 break;
2993         case PCI_DEVICE_ID_XG_40:
2994                 xgi_video_info.chip = XG40;
2995                 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2996                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2997                 break;
2998         case PCI_DEVICE_ID_XG_41:
2999                 xgi_video_info.chip = XG41;
3000                 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3001                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3002                 break;
3003         case PCI_DEVICE_ID_XG_42:
3004                 xgi_video_info.chip = XG42;
3005                 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3006                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3007                 break;
3008         case PCI_DEVICE_ID_XG_27:
3009                 xgi_video_info.chip = XG27;
3010                 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3011                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3012                 break;
3013         default:
3014                 return -ENODEV;
3015         }
3016
3017         printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
3018         XGIhw_ext.jChipType = xgi_video_info.chip;
3019
3020         switch (xgi_video_info.chip) {
3021         case XG40:
3022         case XG41:
3023         case XG42:
3024         case XG45:
3025         case XG20:
3026         case XG21:
3027         case XG27:
3028                 XGIhw_ext.bIntegratedMMEnabled = 1;
3029                 break;
3030         default:
3031                 break;
3032         }
3033
3034         XGIhw_ext.pDevice = NULL;
3035         if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
3036                 XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
3037
3038                 if (XGIhw_ext.pjVirtualRomBase)
3039                         printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
3040                 else
3041                         printk(KERN_INFO "XGIfb: Video ROM not found\n");
3042         } else {
3043                 XGIhw_ext.pjVirtualRomBase = NULL;
3044                 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
3045         }
3046         XGIhw_ext.pjCustomizedROMImage = NULL;
3047         XGIhw_ext.bSkipDramSizing = 0;
3048         XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
3049         /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */
3050         strcpy(XGIhw_ext.szVBIOSVer, "0.84");
3051
3052         XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
3053         if (XGIhw_ext.pSR == NULL) {
3054                 printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
3055                 return -ENODEV;
3056         }
3057         XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
3058
3059         XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
3060         if (XGIhw_ext.pCR == NULL) {
3061                 vfree(XGIhw_ext.pSR);
3062                 printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
3063                 return -ENODEV;
3064         }
3065         XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
3066
3067         if (!XGIvga_enabled) {
3068                 /* Mapping Max FB Size for 315 Init */
3069                 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3070                 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3071 #ifdef LINUXBIOS
3072                         printk("XGIfb: XGIInit() ...");
3073                         /* XGIInitNewt for LINUXBIOS only */
3074                         if (XGIInitNew(&XGIhw_ext))
3075                                 printk("OK\n");
3076                         else
3077                                 printk("Fail\n");
3078 #endif
3079
3080                         outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3081
3082                 }
3083         }
3084 #ifdef LINUXBIOS
3085         else {
3086                 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3087                 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3088
3089                         outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3090
3091                         /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
3092                         /* Set SR13 ,14 temporarily for UDtech */
3093                         outXGIIDXREG(XGISR, 0x13, 0x45);
3094                         outXGIIDXREG(XGISR, 0x14, 0x51);
3095
3096                 }
3097         }
3098 #endif
3099         if (XGIfb_get_dram_size()) {
3100                 vfree(XGIhw_ext.pSR);
3101                 vfree(XGIhw_ext.pCR);
3102                 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
3103                 return -ENODEV;
3104         }
3105
3106         if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3107                 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
3108                 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3109                 /* Enable 2D accelerator engine */
3110                 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3111         }
3112
3113         XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3114
3115         if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
3116                 printk("unable request memory size %x", xgi_video_info.video_size);
3117                 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3118                 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
3119                 vfree(XGIhw_ext.pSR);
3120                 vfree(XGIhw_ext.pCR);
3121                 return -ENODEV;
3122         }
3123
3124         if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) {
3125                 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
3126                 release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
3127                 vfree(XGIhw_ext.pSR);
3128                 vfree(XGIhw_ext.pCR);
3129                 return -ENODEV;
3130         }
3131
3132         xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3133         ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
3134         xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
3135
3136         printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3137                         xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
3138
3139         printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
3140                         xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, XGIfb_mmio_size / 1024);
3141         printk("XGIfb: XGIInitNew() ...");
3142         if (XGIInitNew(&XGIhw_ext))
3143                 printk("OK\n");
3144         else
3145                 printk("Fail\n");
3146
3147         if (XGIfb_heap_init())
3148                 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
3149
3150         xgi_video_info.mtrr = (unsigned int) 0;
3151
3152         if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3153                 xgi_video_info.hasVB = HASVB_NONE;
3154                 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
3155                         xgi_video_info.hasVB = HASVB_NONE;
3156                 } else if (xgi_video_info.chip == XG21) {
3157                         inXGIIDXREG(XGICR, 0x38, CR38);
3158                         if ((CR38&0xE0) == 0xC0) {
3159                                 xgi_video_info.disp_state = DISPTYPE_LCD;
3160                                 if (!XGIfb_GetXG21LVDSData()) {
3161                                         int m;
3162                                         for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
3163                                                 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3164                                                                 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3165                                                         XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
3166                                                 }
3167                                         }
3168                                 }
3169                         } else if ((CR38&0xE0) == 0x60) {
3170                                 xgi_video_info.hasVB = HASVB_CHRONTEL;
3171                         } else {
3172                                 xgi_video_info.hasVB = HASVB_NONE;
3173                         }
3174                 } else {
3175                         XGIfb_get_VB_type();
3176                 }
3177
3178                 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
3179
3180                 XGIhw_ext.ulExternalChip = 0;
3181
3182                 switch (xgi_video_info.hasVB) {
3183                 case HASVB_301:
3184                         inXGIIDXREG(XGIPART4, 0x01, reg);
3185                         if (reg >= 0xE0) {
3186                                 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3187                                 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3188                         } else if (reg >= 0xD0) {
3189                                 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3190                                 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
3191                         }
3192                         /* else if (reg >= 0xB0) {
3193                                 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
3194                                 inXGIIDXREG(XGIPART4, 0x23, reg1);
3195                                 printk("XGIfb: XGI301B bridge detected\n");
3196                         } */
3197                         else {
3198                                 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3199                                 printk("XGIfb: XGI301 bridge detected\n");
3200                         }
3201                         break;
3202                 case HASVB_302:
3203                         inXGIIDXREG(XGIPART4, 0x01, reg);
3204                         if (reg >= 0xE0) {
3205                                 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3206                                 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3207                         } else if (reg >= 0xD0) {
3208                                 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3209                                 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3210                         } else if (reg >= 0xB0) {
3211                                 inXGIIDXREG(XGIPART4, 0x23, reg1);
3212
3213                                 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
3214
3215                         } else {
3216                                 XGIhw_ext.ujVBChipID = VB_CHIP_302;
3217                                 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3218                         }
3219                         break;
3220                 case HASVB_LVDS:
3221                         XGIhw_ext.ulExternalChip = 0x1;
3222                         printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3223                         break;
3224                 case HASVB_TRUMPION:
3225                         XGIhw_ext.ulExternalChip = 0x2;
3226                         printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3227                         break;
3228                 case HASVB_CHRONTEL:
3229                         XGIhw_ext.ulExternalChip = 0x4;
3230                         printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3231                         break;
3232                 case HASVB_LVDS_CHRONTEL:
3233                         XGIhw_ext.ulExternalChip = 0x5;
3234                         printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3235                         break;
3236                 default:
3237                         printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3238                         break;
3239                 }
3240
3241                 if (xgi_video_info.hasVB != HASVB_NONE)
3242                         XGIfb_detect_VB();
3243
3244                 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3245                         if (XGIfb_crt1off)
3246                                 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3247                         else
3248                                 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3249                 } else {
3250                         xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3251                 }
3252
3253                 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
3254                         if (!enable_dstn) {
3255                                 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3256                                 reg &= 0x0f;
3257                                 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
3258
3259                         } else {
3260                                 /* TW: FSTN/DSTN */
3261                                 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3262                         }
3263                 }
3264
3265                 XGIfb_detectedpdc = 0;
3266
3267                 XGIfb_detectedlcda = 0xff;
3268 #ifndef LINUXBIOS
3269
3270                 /* TW: Try to find about LCDA */
3271
3272                 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3273                                 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3274                                 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
3275                         int tmp;
3276                         inXGIIDXREG(XGICR, 0x34, tmp);
3277                         if (tmp <= 0x13) {
3278                                 /* Currently on LCDA? (Some BIOSes leave CR38) */
3279                                 inXGIIDXREG(XGICR, 0x38, tmp);
3280                                 if ((tmp & 0x03) == 0x03) {
3281                                         /* XGI_Pr.XGI_UseLCDA = 1; */
3282                                 } else {
3283                                         /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
3284                                         inXGIIDXREG(XGICR, 0x35, tmp);
3285                                         if (tmp & 0x01) {
3286                                                 /* XGI_Pr.XGI_UseLCDA = 1; */
3287                                         } else {
3288                                                 inXGIIDXREG(XGICR, 0x30, tmp);
3289                                                 if (tmp & 0x20) {
3290                                                         inXGIIDXREG(XGIPART1, 0x13, tmp);
3291                                                         if (tmp & 0x04) {
3292                                                                 /* XGI_Pr.XGI_UseLCDA = 1; */
3293                                                         }
3294                                                 }
3295                                         }
3296                                 }
3297                         }
3298
3299                 }
3300
3301 #endif
3302
3303                 if (xgifb_mode_idx >= 0)
3304                         xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3305
3306                 if (xgifb_mode_idx < 0) {
3307                         switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3308                         case DISPTYPE_LCD:
3309                                 xgifb_mode_idx = DEFAULT_LCDMODE;
3310                                 if (xgi_video_info.chip == XG21)
3311                                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
3312                                 break;
3313                         case DISPTYPE_TV:
3314                                 xgifb_mode_idx = DEFAULT_TVMODE;
3315                                 break;
3316                         default:
3317                                 xgifb_mode_idx = DEFAULT_MODE;
3318                                 break;
3319                         }
3320                 }
3321
3322                 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3323
3324                 if (xgi_video_info.refresh_rate == 0)
3325                         xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
3326                 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
3327                         XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3328                         xgi_video_info.refresh_rate = 60;
3329                 }
3330
3331                 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3332                 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3333                 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3334                 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3335                 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
3336                 switch (xgi_video_info.video_bpp) {
3337                 case 8:
3338                         xgi_video_info.DstColor = 0x0000;
3339                         xgi_video_info.XGI310_AccelDepth = 0x00000000;
3340                         xgi_video_info.video_cmap_len = 256;
3341                         break;
3342                 case 16:
3343                         xgi_video_info.DstColor = 0x8000;
3344                         xgi_video_info.XGI310_AccelDepth = 0x00010000;
3345                         xgi_video_info.video_cmap_len = 16;
3346                         break;
3347                 case 32:
3348                         xgi_video_info.DstColor = 0xC000;
3349                         xgi_video_info.XGI310_AccelDepth = 0x00020000;
3350                         xgi_video_info.video_cmap_len = 16;
3351                         break;
3352                 default:
3353                         xgi_video_info.video_cmap_len = 16;
3354                         printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
3355                         break;
3356                 }
3357
3358                 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
3359                                 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3360                                 xgi_video_info.refresh_rate);
3361
3362                 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3363                 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3364                 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3365
3366                 XGIfb_bpp_to_var(&default_var);
3367
3368                 default_var.pixclock = (u32) (1000000000 /
3369                                 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3370                                                 XGIfb_mode_no, XGIfb_rate_idx));
3371
3372                 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3373                         XGIfb_mode_no, XGIfb_rate_idx,
3374                         &default_var.left_margin, &default_var.right_margin,
3375                         &default_var.upper_margin, &default_var.lower_margin,
3376                         &default_var.hsync_len, &default_var.vsync_len,
3377                         &default_var.sync, &default_var.vmode)) {
3378
3379                         if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3380                                 default_var.yres <<= 1;
3381                                 default_var.yres_virtual <<= 1;
3382                         } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3383                                 default_var.pixclock >>= 1;
3384                                 default_var.yres >>= 1;
3385                                 default_var.yres_virtual >>= 1;
3386                         }
3387
3388                 }
3389
3390                 xgi_video_info.accel = 0;
3391                 if (XGIfb_accel) {
3392                         xgi_video_info.accel = -1;
3393                         default_var.accel_flags |= FB_ACCELF_TEXT;
3394                         XGIfb_initaccel();
3395                 }
3396
3397                 fb_info->flags = FBINFO_FLAG_DEFAULT;
3398                 fb_info->var = default_var;
3399                 fb_info->fix = XGIfb_fix;
3400                 fb_info->par = &xgi_video_info;
3401                 fb_info->screen_base = xgi_video_info.video_vbase;
3402                 fb_info->fbops = &XGIfb_ops;
3403                 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3404                 fb_info->pseudo_palette = pseudo_palette;
3405
3406                 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3407
3408 #ifdef CONFIG_MTRR
3409                 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3410                                 (unsigned int) xgi_video_info.video_size,
3411                                 MTRR_TYPE_WRCOMB, 1);
3412                 if (xgi_video_info.mtrr)
3413                         printk(KERN_INFO "XGIfb: Added MTRRs\n");
3414 #endif
3415
3416                 if (register_framebuffer(fb_info) < 0)
3417                         return -EINVAL;
3418
3419                 XGIfb_registered = 1;
3420
3421                 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
3422                                 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
3423
3424         }
3425
3426         dumpVGAReg();
3427
3428         return 0;
3429 }
3430
3431 /*****************************************************/
3432 /*                PCI DEVICE HANDLING                */
3433 /*****************************************************/
3434
3435 static void __devexit xgifb_remove(struct pci_dev *pdev)
3436 {
3437         /* Unregister the framebuffer */
3438         /* if (xgi_video_info.registered) { */
3439         unregister_framebuffer(fb_info);
3440         framebuffer_release(fb_info);
3441         /* } */
3442
3443         pci_set_drvdata(pdev, NULL);
3444
3445 };
3446
3447 static struct pci_driver xgifb_driver = {
3448         .name = "xgifb",
3449         .id_table = xgifb_pci_table,
3450         .probe = xgifb_probe,
3451         .remove = __devexit_p(xgifb_remove)
3452 };
3453
3454 XGIINITSTATIC int __init xgifb_init(void)
3455 {
3456         char *option = NULL;
3457
3458         if (fb_get_options("xgifb", &option))
3459                 return -ENODEV;
3460         XGIfb_setup(option);
3461
3462         return pci_register_driver(&xgifb_driver);
3463 }
3464
3465 #ifndef MODULE
3466 module_init(xgifb_init);
3467 #endif
3468
3469 /*****************************************************/
3470 /*                      MODULE                       */
3471 /*****************************************************/
3472
3473 #ifdef MODULE
3474
3475 static char *mode = NULL;
3476 static int vesa = 0;
3477 static unsigned int rate = 0;
3478 static unsigned int mem = 0;
3479 static char *forcecrt2type = NULL;
3480 static int forcecrt1 = -1;
3481 static int pdc = -1;
3482 static int pdc1 = -1;
3483 static int noaccel = -1;
3484 static int noypan = -1;
3485 static int nomax = -1;
3486 static int userom = -1;
3487 static int useoem = -1;
3488 static char *tvstandard = NULL;
3489 static int nocrt2rate = 0;
3490 static int scalelcd = -1;
3491 static char *specialtiming = NULL;
3492 static int lvdshl = -1;
3493 static int tvxposoffset = 0, tvyposoffset = 0;
3494 #if !defined(__i386__) && !defined(__x86_64__)
3495 static int resetcard = 0;
3496 static int videoram = 0;
3497 #endif
3498
3499 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3500 MODULE_LICENSE("GPL");
3501 MODULE_AUTHOR("XGITECH , Others");
3502
3503 module_param(mem, int, 0);
3504 module_param(noaccel, int, 0);
3505 module_param(noypan, int, 0);
3506 module_param(nomax, int, 0);
3507 module_param(userom, int, 0);
3508 module_param(useoem, int, 0);
3509 module_param(mode, charp, 0);
3510 module_param(vesa, int, 0);
3511 module_param(rate, int, 0);
3512 module_param(forcecrt1, int, 0);
3513 module_param(forcecrt2type, charp, 0);
3514 module_param(scalelcd, int, 0);
3515 module_param(pdc, int, 0);
3516 module_param(pdc1, int, 0);
3517 module_param(specialtiming, charp, 0);
3518 module_param(lvdshl, int, 0);
3519 module_param(tvstandard, charp, 0);
3520 module_param(tvxposoffset, int, 0);
3521 module_param(tvyposoffset, int, 0);
3522 module_param(filter, int, 0);
3523 module_param(nocrt2rate, int, 0);
3524 #if !defined(__i386__) && !defined(__x86_64__)
3525 module_param(resetcard, int, 0);
3526 module_param(videoram, int, 0);
3527 #endif
3528
3529 MODULE_PARM_DESC(mem,
3530                 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3531                 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3532                 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3533                 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3534                 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3535                 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3536                 "for XFree86 4.x/X.org 6.7 and later.\n");
3537
3538 MODULE_PARM_DESC(noaccel,
3539                 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3540                 "(default: 0)\n");
3541
3542 MODULE_PARM_DESC(noypan,
3543                 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3544                 "will be performed by redrawing the screen. (default: 0)\n");
3545
3546 MODULE_PARM_DESC(nomax,
3547                 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3548                 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3549                 "this is set to anything other than 0, xgifb will not do this and thereby\n"
3550                 "enable the user to positively specify a virtual Y size of the screen using\n"
3551                 "fbset. (default: 0)\n");
3552
3553 MODULE_PARM_DESC(mode,
3554                 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3555                 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3556                 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3557                 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
3558
3559 MODULE_PARM_DESC(vesa,
3560                 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3561                 "0x117 (default: 0x0103)\n");
3562
3563 MODULE_PARM_DESC(rate,
3564                 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3565                 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3566                 "will be ignored (default: 60)\n");
3567
3568 MODULE_PARM_DESC(forcecrt1,
3569                 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
3570                 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3571                 "0=CRT1 OFF) (default: [autodetected])\n");
3572
3573 MODULE_PARM_DESC(forcecrt2type,
3574                 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3575                 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3576                 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3577                 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3578                 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3579                 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3580                 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3581                 "depends on the very hardware in use. (default: [autodetected])\n");
3582
3583 MODULE_PARM_DESC(scalelcd,
3584                 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3585                 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3586                 "show black bars around the image, TMDS panels will probably do the scaling\n"
3587                 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
3588
3589 MODULE_PARM_DESC(pdc,
3590                 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3591                 "should detect this correctly in most cases; however, sometimes this is not\n"
3592                 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3593                 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3594                 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3595                 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
3596
3597 MODULE_PARM_DESC(pdc1,
3598                 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3599                 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3600                 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3601                 "implemented yet.\n");
3602
3603 MODULE_PARM_DESC(specialtiming,
3604                 "\nPlease refer to documentation for more information on this option.\n");
3605
3606 MODULE_PARM_DESC(lvdshl,
3607                 "\nPlease refer to documentation for more information on this option.\n");
3608
3609 MODULE_PARM_DESC(tvstandard,
3610                 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3611                 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
3612
3613 MODULE_PARM_DESC(tvxposoffset,
3614                 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3615                 "Default: 0\n");
3616
3617 MODULE_PARM_DESC(tvyposoffset,
3618                 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3619                 "Default: 0\n");
3620
3621 MODULE_PARM_DESC(filter,
3622                 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3623                 "(Possible values 0-7, default: [no filter])\n");
3624
3625 MODULE_PARM_DESC(nocrt2rate,
3626                 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3627                 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
3628
3629 static int __init xgifb_init_module(void)
3630 {
3631         printk("\nXGIfb_init_module");
3632         if (mode)
3633                 XGIfb_search_mode(mode);
3634         else if (vesa != -1)
3635                 XGIfb_search_vesamode(vesa);
3636
3637         return xgifb_init();
3638 }
3639
3640 static void __exit xgifb_remove_module(void)
3641 {
3642         pci_unregister_driver(&xgifb_driver);
3643         printk(KERN_DEBUG "xgifb: Module unloaded\n");
3644 }
3645
3646 module_init(xgifb_init_module);
3647 module_exit(xgifb_remove_module);
3648
3649 #endif  /*  /MODULE  */
3650
3651 EXPORT_SYMBOL(XGI_malloc);
3652 EXPORT_SYMBOL(XGI_free);
3653