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