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