video: platinumfb: Add __devexit_p at necessary place
[pandora-kernel.git] / drivers / staging / xgifb / XGI_main_26.c
1 /*
2  * XG20, XG21, XG40, XG42 frame buffer device
3  * for Linux kernels  2.5.x, 2.6.x
4  * Base on TW's sis fbdev code.
5  */
6
7 /* #include <linux/config.h> */
8 #include <linux/module.h>
9 #include <linux/moduleparam.h>
10 #include <linux/kernel.h>
11 #include <linux/spinlock.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/mm.h>
15 #include <linux/tty.h>
16 #include <linux/slab.h>
17 #include <linux/delay.h>
18 #include <linux/fb.h>
19 #include <linux/console.h>
20 #include <linux/selection.h>
21 #include <linux/ioport.h>
22 #include <linux/init.h>
23 #include <linux/pci.h>
24 #include <linux/vmalloc.h>
25 #include <linux/vt_kern.h>
26 #include <linux/capability.h>
27 #include <linux/fs.h>
28 #include <linux/types.h>
29 #include <linux/proc_fs.h>
30
31 #ifndef XGIFB_PAN
32 #define XGIFB_PAN
33 #endif
34
35 #include <linux/io.h>
36 #ifdef CONFIG_MTRR
37 #include <asm/mtrr.h>
38 #endif
39
40 #include "XGIfb.h"
41 #include "vgatypes.h"
42 #include "XGI_main.h"
43 #include "vb_init.h"
44 #include "vb_util.h"
45 #include "vb_setmode.h"
46
47 #define Index_CR_GPIO_Reg1 0x48
48 #define Index_CR_GPIO_Reg2 0x49
49 #define Index_CR_GPIO_Reg3 0x4a
50
51 #define GPIOG_EN    (1<<6)
52 #define GPIOG_WRITE (1<<6)
53 #define GPIOG_READ  (1<<1)
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         xgifb_reg_set(XGISR, 0x05, 0x86);
73         /*
74         xgifb_reg_set(XGISR, 0x08, 0x4f);
75         xgifb_reg_set(XGISR, 0x0f, 0x20);
76         xgifb_reg_set(XGISR, 0x11, 0x4f);
77         xgifb_reg_set(XGISR, 0x13, 0x45);
78         xgifb_reg_set(XGISR, 0x14, 0x51);
79         xgifb_reg_set(XGISR, 0x1e, 0x41);
80         xgifb_reg_set(XGISR, 0x1f, 0x0);
81         xgifb_reg_set(XGISR, 0x20, 0xa1);
82         xgifb_reg_set(XGISR, 0x22, 0xfb);
83         xgifb_reg_set(XGISR, 0x26, 0x22);
84         xgifb_reg_set(XGISR, 0x3e, 0x07);
85         */
86
87         /* xgifb_reg_set(XGICR, 0x19, 0x00); */
88         /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
89         /* xgifb_reg_set(XGICR, 0x22, 0xff); */
90         /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
91
92         /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
93
94         /* xgifb_reg_set(XGICR, 0x57, 0x0); */
95         /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
96
97         /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
98         /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
99         /*
100         xgifb_reg_set(XGICR, 0x99, 0x1);
101         xgifb_reg_set(XGICR, 0x41, 0x40);
102         */
103
104         for (i = 0; i < 0x4f; i++) {
105                 reg = xgifb_reg_get(XGISR, i);
106                 printk("\no 3c4 %x", i);
107                 printk("\ni 3c5 => %x", reg);
108         }
109
110         for (i = 0; i < 0xF0; i++) {
111                 reg = xgifb_reg_get(XGICR, i);
112                 printk("\no 3d4 %x", i);
113                 printk("\ni 3d5 => %x", reg);
114         }
115         /*
116         xgifb_reg_set(XGIPART1,0x2F,1);
117         for (i=1; i < 0x50; i++) {
118                 reg = xgifb_reg_get(XGIPART1, i);
119                 printk("\no d004 %x", i);
120                 printk("\ni d005 => %x", reg);
121         }
122
123         for (i=0; i < 0x50; i++) {
124                  reg = xgifb_reg_get(XGIPART2, i);
125                  printk("\no d010 %x", i);
126                  printk("\ni d011 => %x", reg);
127         }
128         for (i=0; i < 0x50; i++) {
129                 reg = xgifb_reg_get(XGIPART3, i);
130                 printk("\no d012 %x",i);
131                 printk("\ni d013 => %x",reg);
132         }
133         for (i=0; i < 0x50; i++) {
134                 reg = xgifb_reg_get(XGIPART4, i);
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
186         Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
187
188         return Clock;
189 }
190
191 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192                 struct xgi_hw_device_info *HwDeviceExtension,
193                 unsigned char modeno, unsigned char rateindex,
194                 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195                 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
196                 u32 *vmode)
197 {
198         unsigned short ModeNo = modeno;
199         unsigned short ModeIdIndex = 0, index = 0;
200         unsigned short RefreshRateTableIndex = 0;
201
202         unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203         unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204         unsigned char sr_data, cr_data, cr_data2;
205         unsigned long cr_data3;
206         int A, B, C, D, E, F, temp, j;
207         XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208         InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210                         ModeIdIndex, XGI_Pr);
211         /*
212         temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
213         if (!temp)
214                 return 0;
215
216         RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217         RefreshRateTableIndex += (rateindex - 1);
218         */
219         index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
220
221         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
222
223         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
224
225         /* Horizontal total */
226         HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
227         A = HT + 5;
228
229         /*
230         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
231
232         Horizontal display enable end
233         HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
234         */
235         HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
236         E = HDE + 1;
237
238         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
239
240         /* Horizontal retrace (=sync) start */
241         HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
242         F = HRS - E - 3;
243
244         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
245
246         /* Horizontal blank start */
247         HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
248
249         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
250
251         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
252
253         cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
254
255         /* Horizontal blank end */
256         HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257                         | ((unsigned short) (sr_data & 0x03) << 6);
258
259         /* Horizontal retrace (=sync) end */
260         HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
261
262         temp = HBE - ((E - 1) & 255);
263         B = (temp > 0) ? temp : (temp + 256);
264
265         temp = HRE - ((E + F + 3) & 63);
266         C = (temp > 0) ? temp : (temp + 64);
267
268         D = B - F - C;
269
270         *left_margin = D * 8;
271         *right_margin = F * 8;
272         *hsync_len = C * 8;
273
274         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
275
276         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
277
278         cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
279
280         /* Vertical total */
281         VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282                         | ((unsigned short) (cr_data2 & 0x20) << 4)
283                         | ((unsigned short) (sr_data & 0x01) << 10);
284         A = VT + 2;
285
286         /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
287
288         /* Vertical display enable end */
289         /*
290         VDE = (cr_data & 0xff) |
291                 ((unsigned short) (cr_data2 & 0x02) << 7) |
292                 ((unsigned short) (cr_data2 & 0x40) << 3) |
293                 ((unsigned short) (sr_data & 0x02) << 9);
294         */
295         VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
296         E = VDE + 1;
297
298         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
299
300         /* Vertical retrace (=sync) start */
301         VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302                         | ((unsigned short) (cr_data2 & 0x80) << 2)
303                         | ((unsigned short) (sr_data & 0x08) << 7);
304         F = VRS + 1 - E;
305
306         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
307
308         cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
309
310         /* Vertical blank start */
311         VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312                         | ((unsigned short) (cr_data3 & 0x20) << 4)
313                         | ((unsigned short) (sr_data & 0x04) << 8);
314
315         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
316
317         /* Vertical blank end */
318         VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319         temp = VBE - ((E - 1) & 511);
320         B = (temp > 0) ? temp : (temp + 512);
321
322         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
323
324         /* Vertical retrace (=sync) end */
325         VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326         temp = VRE - ((E + F - 1) & 31);
327         C = (temp > 0) ? temp : (temp + 32);
328
329         D = B - F - C;
330
331         *upper_margin = D;
332         *lower_margin = F;
333         *vsync_len = C;
334
335         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336                 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
337         else
338                 *sync |= FB_SYNC_VERT_HIGH_ACT;
339
340         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341                 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
342         else
343                 *sync |= FB_SYNC_HOR_HIGH_ACT;
344
345         *vmode = FB_VMODE_NONINTERLACED;
346         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347                 *vmode = FB_VMODE_INTERLACED;
348         else {
349                 j = 0;
350                 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
351                         if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
352                             XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353                                 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
354                                     DoubleScanMode) {
355                                         *vmode = FB_VMODE_DOUBLE;
356                                 }
357                                 break;
358                         }
359                         j++;
360                 }
361         }
362
363         return 1;
364 }
365
366 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
367 {
368         XGI_Pr->RelIO = BaseAddr;
369         XGI_Pr->P3c4 = BaseAddr + 0x14;
370         XGI_Pr->P3d4 = BaseAddr + 0x24;
371         XGI_Pr->P3c0 = BaseAddr + 0x10;
372         XGI_Pr->P3ce = BaseAddr + 0x1e;
373         XGI_Pr->P3c2 = BaseAddr + 0x12;
374         XGI_Pr->P3ca = BaseAddr + 0x1a;
375         XGI_Pr->P3c6 = BaseAddr + 0x16;
376         XGI_Pr->P3c7 = BaseAddr + 0x17;
377         XGI_Pr->P3c8 = BaseAddr + 0x18;
378         XGI_Pr->P3c9 = BaseAddr + 0x19;
379         XGI_Pr->P3da = BaseAddr + 0x2A;
380         /* Digital video interface registers (LCD) */
381         XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
382         /* 301 TV Encoder registers */
383         XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
384         /* 301 Macrovision registers */
385         XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
386         /* 301 VGA2 (and LCD) registers */
387         XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
388         /* 301 palette address port registers */
389         XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
390
391 }
392
393 /* ------------ Interface for init & mode switching code ------------- */
394
395 static unsigned char XGIfb_query_VGA_config_space(
396                 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
397                 unsigned long set, unsigned long *value)
398 {
399         static struct pci_dev *pdev = NULL;
400         static unsigned char init = 0, valid_pdev = 0;
401
402         if (!set)
403                 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
404         else
405                 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
406
407         if (!init) {
408                 init = 1;
409                 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
410                                 pdev);
411                 if (pdev) {
412                         valid_pdev = 1;
413                         pci_dev_put(pdev);
414                 }
415         }
416
417         if (!valid_pdev) {
418                 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
419                                 xgi_video_info.chip_id);
420                 return 0;
421         }
422
423         if (set == 0)
424                 pci_read_config_dword(pdev, offset, (u32 *) value);
425         else
426                 pci_write_config_dword(pdev, offset, (u32)(*value));
427
428         return 1;
429 }
430
431 /* ------------------ Internal helper routines ----------------- */
432
433 static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
434 {
435
436         int found_mode = 0;
437         int XGIfb_mode_idx = 0;
438
439         found_mode = 0;
440         while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
441                         && (XGIbios_mode[XGIfb_mode_idx].xres
442                                         <= XGI21_LCDCapList[0].LVDSHDE)) {
443                 if ((XGIbios_mode[XGIfb_mode_idx].xres
444                                 == XGI21_LCDCapList[0].LVDSHDE)
445                                 && (XGIbios_mode[XGIfb_mode_idx].yres
446                                                 == XGI21_LCDCapList[0].LVDSVDE)
447                                 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
448                         XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
449                         found_mode = 1;
450                         break;
451                 }
452                 XGIfb_mode_idx++;
453         }
454         if (!found_mode)
455                 XGIfb_mode_idx = 0;
456
457         return XGIfb_mode_idx;
458 }
459
460 static void XGIfb_search_mode(const char *name)
461 {
462         int i = 0, j = 0, l;
463
464         if (name == NULL) {
465                 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
466                 xgifb_mode_idx = DEFAULT_MODE;
467                 if ((xgi_video_info.chip == XG21)
468                                 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
469                                                 == DISPTYPE_LCD)) {
470                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
471                 }
472                 return;
473         }
474
475         if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
476                 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
477                 xgifb_mode_idx = DEFAULT_MODE;
478                 if ((xgi_video_info.chip == XG21)
479                                 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
480                                                 == DISPTYPE_LCD)) {
481                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
482                 }
483                 return;
484         }
485
486         while (XGIbios_mode[i].mode_no != 0) {
487                 l = min(strlen(name), strlen(XGIbios_mode[i].name));
488                 if (!strncmp(name, XGIbios_mode[i].name, l)) {
489                         xgifb_mode_idx = i;
490                         j = 1;
491                         break;
492                 }
493                 i++;
494         }
495         if (!j)
496                 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
497 }
498
499 static void XGIfb_search_vesamode(unsigned int vesamode)
500 {
501         int i = 0, j = 0;
502
503         if (vesamode == 0) {
504
505                 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
506                 xgifb_mode_idx = DEFAULT_MODE;
507                 if ((xgi_video_info.chip == XG21)
508                                 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
509                                                 == DISPTYPE_LCD)) {
510                         xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
511                 }
512                 return;
513         }
514
515         vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
516
517         while (XGIbios_mode[i].mode_no != 0) {
518                 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
519                     (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
520                         xgifb_mode_idx = i;
521                         j = 1;
522                         break;
523                 }
524                 i++;
525         }
526         if (!j)
527                 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
528 }
529
530 static int XGIfb_GetXG21LVDSData(void)
531 {
532         u8 tmp;
533         unsigned char *pData;
534         int i, j, k;
535
536         tmp = xgifb_reg_get(XGISR, 0x1e);
537         xgifb_reg_set(XGISR, 0x1e, tmp | 4);
538
539         pData = xgi_video_info.mmio_vbase + 0x20000;
540         if ((pData[0x0] == 0x55) &&
541             (pData[0x1] == 0xAA) &&
542             (pData[0x65] & 0x1)) {
543                 i = pData[0x316] | (pData[0x317] << 8);
544                 j = pData[i - 1];
545                 if (j == 0xff)
546                         j = 1;
547
548                 k = 0;
549                 do {
550                         XGI21_LCDCapList[k].LVDS_Capability = pData[i]
551                                         | (pData[i + 1] << 8);
552                         XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
553                                         + 3] << 8);
554                         XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
555                                         + 5] << 8);
556                         XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
557                                         + 7] << 8);
558                         XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
559                                         + 9] << 8);
560                         XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
561                                         + 11] << 8);
562                         XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
563                                         + 13] << 8);
564                         XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
565                                         | (pData[i + 15] << 8);
566                         XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
567                                         | (pData[i + 17] << 8);
568                         XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
569                         XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
570                         XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
571                         XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
572                         XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
573                         XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
574                         XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
575                         i += 25;
576                         j--;
577                         k++;
578                 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
579                                 / sizeof(struct XGI21_LVDSCapStruct))));
580                 return 1;
581         }
582         return 0;
583 }
584
585 static int XGIfb_validate_mode(int myindex)
586 {
587         u16 xres, yres;
588
589         if (xgi_video_info.chip == XG21) {
590                 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
591                                 == DISPTYPE_LCD) {
592                         xres = XGI21_LCDCapList[0].LVDSHDE;
593                         yres = XGI21_LCDCapList[0].LVDSVDE;
594                         if (XGIbios_mode[myindex].xres > xres)
595                                 return -1;
596                         if (XGIbios_mode[myindex].yres > yres)
597                                 return -1;
598                         if ((XGIbios_mode[myindex].xres < xres) &&
599                             (XGIbios_mode[myindex].yres < yres)) {
600                                 if (XGIbios_mode[myindex].bpp > 8)
601                                         return -1;
602                         }
603
604                 }
605                 return myindex;
606
607         }
608
609         /* FIXME: for now, all is valid on XG27 */
610         if (xgi_video_info.chip == XG27)
611                 return myindex;
612
613         if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
614                 return -1;
615
616         switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
617         case DISPTYPE_LCD:
618                 switch (XGIhw_ext.ulCRT2LCDType) {
619                 case LCD_640x480:
620                         xres = 640;
621                         yres = 480;
622                         break;
623                 case LCD_800x600:
624                         xres = 800;
625                         yres = 600;
626                         break;
627                 case LCD_1024x600:
628                         xres = 1024;
629                         yres = 600;
630                         break;
631                 case LCD_1024x768:
632                         xres = 1024;
633                         yres = 768;
634                         break;
635                 case LCD_1152x768:
636                         xres = 1152;
637                         yres = 768;
638                         break;
639                 case LCD_1280x960:
640                         xres = 1280;
641                         yres = 960;
642                         break;
643                 case LCD_1280x768:
644                         xres = 1280;
645                         yres = 768;
646                         break;
647                 case LCD_1280x1024:
648                         xres = 1280;
649                         yres = 1024;
650                         break;
651                 case LCD_1400x1050:
652                         xres = 1400;
653                         yres = 1050;
654                         break;
655                 case LCD_1600x1200:
656                         xres = 1600;
657                         yres = 1200;
658                         break;
659                 /* case LCD_320x480: */ /* TW: FSTN */
660                         /*
661                         xres =  320;
662                         yres =  480;
663                         break;
664                         */
665                 default:
666                         xres = 0;
667                         yres = 0;
668                         break;
669                 }
670                 if (XGIbios_mode[myindex].xres > xres)
671                         return -1;
672                 if (XGIbios_mode[myindex].yres > yres)
673                         return -1;
674                 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
675                     (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
676                         switch (XGIbios_mode[myindex].xres) {
677                         case 512:
678                                 if (XGIbios_mode[myindex].yres != 512)
679                                         return -1;
680                                 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
681                                         return -1;
682                                 break;
683                         case 640:
684                                 if ((XGIbios_mode[myindex].yres != 400)
685                                                 && (XGIbios_mode[myindex].yres
686                                                                 != 480))
687                                         return -1;
688                                 break;
689                         case 800:
690                                 if (XGIbios_mode[myindex].yres != 600)
691                                         return -1;
692                                 break;
693                         case 1024:
694                                 if ((XGIbios_mode[myindex].yres != 600) &&
695                                     (XGIbios_mode[myindex].yres != 768))
696                                         return -1;
697                                 if ((XGIbios_mode[myindex].yres == 600) &&
698                                     (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
699                                         return -1;
700                                 break;
701                         case 1152:
702                                 if ((XGIbios_mode[myindex].yres) != 768)
703                                         return -1;
704                                 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
705                                         return -1;
706                                 break;
707                         case 1280:
708                                 if ((XGIbios_mode[myindex].yres != 768) &&
709                                     (XGIbios_mode[myindex].yres != 1024))
710                                         return -1;
711                                 if ((XGIbios_mode[myindex].yres == 768) &&
712                                     (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
713                                         return -1;
714                                 break;
715                         case 1400:
716                                 if (XGIbios_mode[myindex].yres != 1050)
717                                         return -1;
718                                 break;
719                         case 1600:
720                                 if (XGIbios_mode[myindex].yres != 1200)
721                                         return -1;
722                                 break;
723                         default:
724                                 return -1;
725                         }
726                 } else {
727                         switch (XGIbios_mode[myindex].xres) {
728                         case 512:
729                                 if (XGIbios_mode[myindex].yres != 512)
730                                         return -1;
731                                 break;
732                         case 640:
733                                 if ((XGIbios_mode[myindex].yres != 400) &&
734                                     (XGIbios_mode[myindex].yres != 480))
735                                         return -1;
736                                 break;
737                         case 800:
738                                 if (XGIbios_mode[myindex].yres != 600)
739                                         return -1;
740                                 break;
741                         case 1024:
742                                 if (XGIbios_mode[myindex].yres != 768)
743                                         return -1;
744                                 break;
745                         case 1280:
746                                 if ((XGIbios_mode[myindex].yres != 960) &&
747                                     (XGIbios_mode[myindex].yres != 1024))
748                                         return -1;
749                                 if (XGIbios_mode[myindex].yres == 960) {
750                                         if (XGIhw_ext.ulCRT2LCDType ==
751                                             LCD_1400x1050)
752                                                 return -1;
753                                 }
754                                 break;
755                         case 1400:
756                                 if (XGIbios_mode[myindex].yres != 1050)
757                                         return -1;
758                                 break;
759                         case 1600:
760                                 if (XGIbios_mode[myindex].yres != 1200)
761                                         return -1;
762                                 break;
763                         default:
764                                 return -1;
765                         }
766                 }
767                 break;
768         case DISPTYPE_TV:
769                 switch (XGIbios_mode[myindex].xres) {
770                 case 512:
771                 case 640:
772                 case 800:
773                         break;
774                 case 720:
775                         if (xgi_video_info.TV_type == TVMODE_NTSC) {
776                                 if (XGIbios_mode[myindex].yres != 480)
777                                         return -1;
778                         } else if (xgi_video_info.TV_type == TVMODE_PAL) {
779                                 if (XGIbios_mode[myindex].yres != 576)
780                                         return -1;
781                         }
782                         /*  TW: LVDS/CHRONTEL does not support 720 */
783                         if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
784                             xgi_video_info.hasVB == HASVB_CHRONTEL) {
785                                 return -1;
786                         }
787                         break;
788                 case 1024:
789                         if (xgi_video_info.TV_type == TVMODE_NTSC) {
790                                 if (XGIbios_mode[myindex].bpp == 32)
791                                         return -1;
792                         }
793                         break;
794                 default:
795                         return -1;
796                 }
797                 break;
798         case DISPTYPE_CRT2:
799                 if (XGIbios_mode[myindex].xres > 1280)
800                         return -1;
801                 break;
802         }
803         return myindex;
804
805 }
806
807 static void XGIfb_search_crt2type(const char *name)
808 {
809         int i = 0;
810
811         if (name == NULL)
812                 return;
813
814         while (XGI_crt2type[i].type_no != -1) {
815                 if (!strcmp(name, XGI_crt2type[i].name)) {
816                         XGIfb_crt2type = XGI_crt2type[i].type_no;
817                         XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
818                         break;
819                 }
820                 i++;
821         }
822         if (XGIfb_crt2type < 0)
823                 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
824 }
825
826 static u8 XGIfb_search_refresh_rate(unsigned int rate)
827 {
828         u16 xres, yres;
829         int i = 0;
830
831         xres = XGIbios_mode[xgifb_mode_idx].xres;
832         yres = XGIbios_mode[xgifb_mode_idx].yres;
833
834         XGIfb_rate_idx = 0;
835         while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
836                 if ((XGIfb_vrate[i].xres == xres) &&
837                     (XGIfb_vrate[i].yres == yres)) {
838                         if (XGIfb_vrate[i].refresh == rate) {
839                                 XGIfb_rate_idx = XGIfb_vrate[i].idx;
840                                 break;
841                         } else if (XGIfb_vrate[i].refresh > rate) {
842                                 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
843                                         DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
844                                                 rate, XGIfb_vrate[i].refresh);
845                                         XGIfb_rate_idx = XGIfb_vrate[i].idx;
846                                         xgi_video_info.refresh_rate =
847                                                 XGIfb_vrate[i].refresh;
848                                 } else if (((rate - XGIfb_vrate[i - 1].refresh)
849                                                 <= 2) && (XGIfb_vrate[i].idx
850                                                 != 1)) {
851                                         DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
852                                                 rate, XGIfb_vrate[i-1].refresh);
853                                         XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
854                                         xgi_video_info.refresh_rate =
855                                                 XGIfb_vrate[i - 1].refresh;
856                                 }
857                                 break;
858                         } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
859                                 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
860                                         rate, XGIfb_vrate[i].refresh);
861                                 XGIfb_rate_idx = XGIfb_vrate[i].idx;
862                                 break;
863                         }
864                 }
865                 i++;
866         }
867         if (XGIfb_rate_idx > 0) {
868                 return XGIfb_rate_idx;
869         } else {
870                 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
871                        rate, xres, yres);
872                 return 0;
873         }
874 }
875
876 static void XGIfb_search_tvstd(const char *name)
877 {
878         int i = 0;
879
880         if (name == NULL)
881                 return;
882
883         while (XGI_tvtype[i].type_no != -1) {
884                 if (!strcmp(name, XGI_tvtype[i].name)) {
885                         XGIfb_tvmode = XGI_tvtype[i].type_no;
886                         break;
887                 }
888                 i++;
889         }
890 }
891
892 /* ----------- FBDev related routines for all series ----------- */
893
894 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
895 {
896         switch (var->bits_per_pixel) {
897         case 8:
898                 var->red.offset = var->green.offset = var->blue.offset = 0;
899                 var->red.length = var->green.length = var->blue.length = 6;
900                 xgi_video_info.video_cmap_len = 256;
901                 break;
902         case 16:
903                 var->red.offset = 11;
904                 var->red.length = 5;
905                 var->green.offset = 5;
906                 var->green.length = 6;
907                 var->blue.offset = 0;
908                 var->blue.length = 5;
909                 var->transp.offset = 0;
910                 var->transp.length = 0;
911                 xgi_video_info.video_cmap_len = 16;
912                 break;
913         case 32:
914                 var->red.offset = 16;
915                 var->red.length = 8;
916                 var->green.offset = 8;
917                 var->green.length = 8;
918                 var->blue.offset = 0;
919                 var->blue.length = 8;
920                 var->transp.offset = 24;
921                 var->transp.length = 8;
922                 xgi_video_info.video_cmap_len = 16;
923                 break;
924         }
925 }
926
927 /* --------------------- SetMode routines ------------------------- */
928
929 static void XGIfb_pre_setmode(void)
930 {
931         u8 cr30 = 0, cr31 = 0;
932
933         cr31 = xgifb_reg_get(XGICR, 0x31);
934         cr31 &= ~0x60;
935
936         switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
937         case DISPTYPE_CRT2:
938                 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
939                 cr31 |= XGI_DRIVER_MODE;
940                 break;
941         case DISPTYPE_LCD:
942                 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
943                 cr31 |= XGI_DRIVER_MODE;
944                 break;
945         case DISPTYPE_TV:
946                 if (xgi_video_info.TV_type == TVMODE_HIVISION)
947                         cr30 = (XGI_VB_OUTPUT_HIVISION
948                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
949                 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
950                         cr30 = (XGI_VB_OUTPUT_SVIDEO
951                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
952                 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
953                         cr30 = (XGI_VB_OUTPUT_COMPOSITE
954                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
955                 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
956                         cr30 = (XGI_VB_OUTPUT_SCART
957                                         | XGI_SIMULTANEOUS_VIEW_ENABLE);
958                 cr31 |= XGI_DRIVER_MODE;
959
960                 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
961                         cr31 |= 0x01;
962                 else
963                         cr31 &= ~0x01;
964                 break;
965         default: /* disable CRT2 */
966                 cr30 = 0x00;
967                 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
968         }
969
970         xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
971         xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
972         xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
973 }
974
975 static void XGIfb_post_setmode(void)
976 {
977         u8 reg;
978         unsigned char doit = 1;
979         /*
980         xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
981         xgifb_reg_set(XGICR, 0x13, 0x00);
982         xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
983         *test*
984         */
985         if (xgi_video_info.video_bpp == 8) {
986                 /* TW: We can't switch off CRT1 on LVDS/Chrontel
987                  * in 8bpp Modes */
988                 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
989                     (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
990                         doit = 0;
991                 }
992                 /* TW: We can't switch off CRT1 on 301B-DH
993                  * in 8bpp Modes if using LCD */
994                 if (xgi_video_info.disp_state & DISPTYPE_LCD)
995                         doit = 0;
996         }
997
998         /* TW: We can't switch off CRT1 if bridge is in slave mode */
999         if (xgi_video_info.hasVB != HASVB_NONE) {
1000                 reg = xgifb_reg_get(XGIPART1, 0x00);
1001
1002                 if ((reg & 0x50) == 0x10)
1003                         doit = 0;
1004
1005         } else {
1006                 XGIfb_crt1off = 0;
1007         }
1008
1009         reg = xgifb_reg_get(XGICR, 0x17);
1010         if ((XGIfb_crt1off) && (doit))
1011                 reg &= ~0x80;
1012         else
1013                 reg |= 0x80;
1014         xgifb_reg_set(XGICR, 0x17, reg);
1015
1016         xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1017
1018         if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1019                         == HASVB_301)) {
1020
1021                 reg = xgifb_reg_get(XGIPART4, 0x01);
1022
1023                 if (reg < 0xB0) { /* Set filter for XGI301 */
1024                         switch (xgi_video_info.video_width) {
1025                         case 320:
1026                                 filter_tb = (xgi_video_info.TV_type ==
1027                                              TVMODE_NTSC) ? 4 : 12;
1028                                 break;
1029                         case 640:
1030                                 filter_tb = (xgi_video_info.TV_type ==
1031                                              TVMODE_NTSC) ? 5 : 13;
1032                                 break;
1033                         case 720:
1034                                 filter_tb = (xgi_video_info.TV_type ==
1035                                              TVMODE_NTSC) ? 6 : 14;
1036                                 break;
1037                         case 800:
1038                                 filter_tb = (xgi_video_info.TV_type ==
1039                                              TVMODE_NTSC) ? 7 : 15;
1040                                 break;
1041                         default:
1042                                 filter = -1;
1043                                 break;
1044                         }
1045                         xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1046
1047                         if (xgi_video_info.TV_type == TVMODE_NTSC) {
1048
1049                                 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1050
1051                                 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1052
1053                                         xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1054
1055                                 } else if (xgi_video_info.TV_plug
1056                                                 == TVPLUG_COMPOSITE) {
1057
1058                                         xgifb_reg_or(XGIPART2, 0x30, 0x20);
1059
1060                                         switch (xgi_video_info.video_width) {
1061                                         case 640:
1062                                                 xgifb_reg_set(XGIPART2,
1063                                                               0x35,
1064                                                               0xEB);
1065                                                 xgifb_reg_set(XGIPART2,
1066                                                               0x36,
1067                                                               0x04);
1068                                                 xgifb_reg_set(XGIPART2,
1069                                                               0x37,
1070                                                               0x25);
1071                                                 xgifb_reg_set(XGIPART2,
1072                                                               0x38,
1073                                                               0x18);
1074                                                 break;
1075                                         case 720:
1076                                                 xgifb_reg_set(XGIPART2,
1077                                                               0x35,
1078                                                               0xEE);
1079                                                 xgifb_reg_set(XGIPART2,
1080                                                               0x36,
1081                                                               0x0C);
1082                                                 xgifb_reg_set(XGIPART2,
1083                                                               0x37,
1084                                                               0x22);
1085                                                 xgifb_reg_set(XGIPART2,
1086                                                               0x38,
1087                                                               0x08);
1088                                                 break;
1089                                         case 800:
1090                                                 xgifb_reg_set(XGIPART2,
1091                                                               0x35,
1092                                                               0xEB);
1093                                                 xgifb_reg_set(XGIPART2,
1094                                                               0x36,
1095                                                               0x15);
1096                                                 xgifb_reg_set(XGIPART2,
1097                                                               0x37,
1098                                                               0x25);
1099                                                 xgifb_reg_set(XGIPART2,
1100                                                               0x38,
1101                                                               0xF6);
1102                                                 break;
1103                                         }
1104                                 }
1105
1106                         } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1107
1108                                 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1109
1110                                 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1111
1112                                         xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1113
1114                                 } else if (xgi_video_info.TV_plug
1115                                                 == TVPLUG_COMPOSITE) {
1116
1117                                         xgifb_reg_or(XGIPART2, 0x30, 0x20);
1118
1119                                         switch (xgi_video_info.video_width) {
1120                                         case 640:
1121                                                 xgifb_reg_set(XGIPART2,
1122                                                               0x35,
1123                                                               0xF1);
1124                                                 xgifb_reg_set(XGIPART2,
1125                                                               0x36,
1126                                                               0xF7);
1127                                                 xgifb_reg_set(XGIPART2,
1128                                                               0x37,
1129                                                               0x1F);
1130                                                 xgifb_reg_set(XGIPART2,
1131                                                               0x38,
1132                                                               0x32);
1133                                                 break;
1134                                         case 720:
1135                                                 xgifb_reg_set(XGIPART2,
1136                                                               0x35,
1137                                                               0xF3);
1138                                                 xgifb_reg_set(XGIPART2,
1139                                                               0x36,
1140                                                               0x00);
1141                                                 xgifb_reg_set(XGIPART2,
1142                                                               0x37,
1143                                                               0x1D);
1144                                                 xgifb_reg_set(XGIPART2,
1145                                                               0x38,
1146                                                               0x20);
1147                                                 break;
1148                                         case 800:
1149                                                 xgifb_reg_set(XGIPART2,
1150                                                               0x35,
1151                                                               0xFC);
1152                                                 xgifb_reg_set(XGIPART2,
1153                                                               0x36,
1154                                                               0xFB);
1155                                                 xgifb_reg_set(XGIPART2,
1156                                                               0x37,
1157                                                               0x14);
1158                                                 xgifb_reg_set(XGIPART2,
1159                                                               0x38,
1160                                                               0x2A);
1161                                                 break;
1162                                         }
1163                                 }
1164                         }
1165
1166                         if ((filter >= 0) && (filter <= 7)) {
1167                                 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1168                                         filter_tb, filter,
1169                                         XGI_TV_filter[filter_tb].
1170                                                 filter[filter][0],
1171                                         XGI_TV_filter[filter_tb].
1172                                                 filter[filter][1],
1173                                         XGI_TV_filter[filter_tb].
1174                                                 filter[filter][2],
1175                                         XGI_TV_filter[filter_tb].
1176                                                 filter[filter][3]
1177                                 );
1178                                 xgifb_reg_set(
1179                                         XGIPART2,
1180                                         0x35,
1181                                         (XGI_TV_filter[filter_tb].
1182                                                 filter[filter][0]));
1183                                 xgifb_reg_set(
1184                                         XGIPART2,
1185                                         0x36,
1186                                         (XGI_TV_filter[filter_tb].
1187                                                 filter[filter][1]));
1188                                 xgifb_reg_set(
1189                                         XGIPART2,
1190                                         0x37,
1191                                         (XGI_TV_filter[filter_tb].
1192                                                 filter[filter][2]));
1193                                 xgifb_reg_set(
1194                                         XGIPART2,
1195                                         0x38,
1196                                         (XGI_TV_filter[filter_tb].
1197                                                 filter[filter][3]));
1198                         }
1199                 }
1200         }
1201 }
1202
1203 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1204                 struct fb_info *info)
1205 {
1206
1207         unsigned int htotal = var->left_margin + var->xres + var->right_margin
1208                         + var->hsync_len;
1209         unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1210                         + var->vsync_len;
1211 #if defined(__powerpc__)
1212         u8 sr_data, cr_data;
1213 #endif
1214         unsigned int drate = 0, hrate = 0;
1215         int found_mode = 0;
1216         int old_mode;
1217         /* unsigned char reg, reg1; */
1218
1219         DEBUGPRN("Inside do_set_var");
1220         /* 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); */
1221
1222         info->var.xres_virtual = var->xres_virtual;
1223         info->var.yres_virtual = var->yres_virtual;
1224         info->var.bits_per_pixel = var->bits_per_pixel;
1225
1226         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1227                 vtotal <<= 1;
1228         else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1229                 vtotal <<= 2;
1230         else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1231                 /* vtotal <<= 1; */
1232                 /* var->yres <<= 1; */
1233         }
1234
1235         if (!htotal || !vtotal) {
1236                 DPRINTK("XGIfb: Invalid 'var' information\n");
1237                 return -EINVAL;
1238         } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1239                         var->pixclock, htotal, vtotal);
1240
1241         if (var->pixclock && htotal && vtotal) {
1242                 drate = 1000000000 / var->pixclock;
1243                 hrate = (drate * 1000) / htotal;
1244                 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1245                                 / vtotal);
1246         } else {
1247                 xgi_video_info.refresh_rate = 60;
1248         }
1249
1250         printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1251                var->xres,
1252                var->yres,
1253                var->bits_per_pixel,
1254                xgi_video_info.refresh_rate);
1255
1256         old_mode = xgifb_mode_idx;
1257         xgifb_mode_idx = 0;
1258
1259         while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1260                         && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1261                 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1262                                 && (XGIbios_mode[xgifb_mode_idx].yres
1263                                                 == var->yres)
1264                                 && (XGIbios_mode[xgifb_mode_idx].bpp
1265                                                 == var->bits_per_pixel)) {
1266                         XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1267                         found_mode = 1;
1268                         break;
1269                 }
1270                 xgifb_mode_idx++;
1271         }
1272
1273         if (found_mode)
1274                 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1275         else
1276                 xgifb_mode_idx = -1;
1277
1278         if (xgifb_mode_idx < 0) {
1279                 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1280                        var->xres, var->yres, var->bits_per_pixel);
1281                 xgifb_mode_idx = old_mode;
1282                 return -EINVAL;
1283         }
1284
1285         if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1286                 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1287                 xgi_video_info.refresh_rate = 60;
1288         }
1289
1290         if (isactive) {
1291
1292                 XGIfb_pre_setmode();
1293                 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1294                         printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1295                                XGIfb_mode_no);
1296                         return -EINVAL;
1297                 }
1298                 info->fix.line_length = ((info->var.xres_virtual
1299                                 * info->var.bits_per_pixel) >> 6);
1300
1301                 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1302
1303                 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1304                 xgifb_reg_set(XGISR,
1305                               0x0E,
1306                               (info->fix.line_length & 0xff00) >> 8);
1307
1308                 XGIfb_post_setmode();
1309
1310                 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1311                                 XGIbios_mode[xgifb_mode_idx].xres,
1312                                 XGIbios_mode[xgifb_mode_idx].yres,
1313                                 XGIbios_mode[xgifb_mode_idx].bpp,
1314                                 xgi_video_info.refresh_rate);
1315
1316                 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1317                 xgi_video_info.video_vwidth = info->var.xres_virtual;
1318                 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1319                 xgi_video_info.video_vheight = info->var.yres_virtual;
1320                 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1321                 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1322                 xgi_video_info.video_linelength = info->var.xres_virtual
1323                                 * (xgi_video_info.video_bpp >> 3);
1324                 switch (xgi_video_info.video_bpp) {
1325                 case 8:
1326                         xgi_video_info.DstColor = 0x0000;
1327                         xgi_video_info.XGI310_AccelDepth = 0x00000000;
1328                         xgi_video_info.video_cmap_len = 256;
1329 #if defined(__powerpc__)
1330                         cr_data = xgifb_reg_get(XGICR, 0x4D);
1331                         xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1332 #endif
1333                         break;
1334                 case 16:
1335                         xgi_video_info.DstColor = 0x8000;
1336                         xgi_video_info.XGI310_AccelDepth = 0x00010000;
1337 #if defined(__powerpc__)
1338                         cr_data = xgifb_reg_get(XGICR, 0x4D);
1339                         xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1340 #endif
1341                         xgi_video_info.video_cmap_len = 16;
1342                         break;
1343                 case 32:
1344                         xgi_video_info.DstColor = 0xC000;
1345                         xgi_video_info.XGI310_AccelDepth = 0x00020000;
1346                         xgi_video_info.video_cmap_len = 16;
1347 #if defined(__powerpc__)
1348                         cr_data = xgifb_reg_get(XGICR, 0x4D);
1349                         xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1350 #endif
1351                         break;
1352                 default:
1353                         xgi_video_info.video_cmap_len = 16;
1354                         printk(KERN_ERR "XGIfb: Unsupported depth %d",
1355                                xgi_video_info.video_bpp);
1356                         break;
1357                 }
1358         }
1359         XGIfb_bpp_to_var(var); /*update ARGB info*/
1360         DEBUGPRN("End of do_set_var");
1361
1362         dumpVGAReg();
1363         return 0;
1364 }
1365
1366 #ifdef XGIFB_PAN
1367 static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1368 {
1369         unsigned int base;
1370
1371         /* printk("Inside pan_var"); */
1372
1373         base = var->yoffset * info->var.xres_virtual + var->xoffset;
1374
1375         /* calculate base bpp dep. */
1376         switch (info->var.bits_per_pixel) {
1377         case 16:
1378                 base >>= 1;
1379                 break;
1380         case 32:
1381                 break;
1382         case 8:
1383         default:
1384                 base >>= 2;
1385                 break;
1386         }
1387
1388         xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1389
1390         xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1391         xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1392         xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1393         xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1394         xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1395
1396         if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1397                 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1398                 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1399                 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1400                 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1401                 xgifb_reg_and_or(XGIPART1,
1402                                  0x02,
1403                                  0x7F,
1404                                  ((base >> 24) & 0x01) << 7);
1405         }
1406         /* printk("End of pan_var"); */
1407         return 0;
1408 }
1409 #endif
1410
1411 static int XGIfb_open(struct fb_info *info, int user)
1412 {
1413         return 0;
1414 }
1415
1416 static int XGIfb_release(struct fb_info *info, int user)
1417 {
1418         return 0;
1419 }
1420
1421 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1422 {
1423         int rc = 16;
1424
1425         switch (var->bits_per_pixel) {
1426         case 8:
1427                 rc = 256;
1428                 break;
1429         case 16:
1430                 rc = 16;
1431                 break;
1432         case 32:
1433                 rc = 16;
1434                 break;
1435         }
1436         return rc;
1437 }
1438
1439 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1440                 unsigned blue, unsigned transp, struct fb_info *info)
1441 {
1442         if (regno >= XGIfb_get_cmap_len(&info->var))
1443                 return 1;
1444
1445         switch (info->var.bits_per_pixel) {
1446         case 8:
1447                 outb(regno, XGIDACA);
1448                 outb((red >> 10), XGIDACD);
1449                 outb((green >> 10), XGIDACD);
1450                 outb((blue >> 10), XGIDACD);
1451                 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1452                         outb(regno, XGIDAC2A);
1453                         outb((red >> 8), XGIDAC2D);
1454                         outb((green >> 8), XGIDAC2D);
1455                         outb((blue >> 8), XGIDAC2D);
1456                 }
1457                 break;
1458         case 16:
1459                 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1460                                 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1461                                 >> 11);
1462                 break;
1463         case 32:
1464                 red >>= 8;
1465                 green >>= 8;
1466                 blue >>= 8;
1467                 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1468                                 << 8) | (blue);
1469                 break;
1470         }
1471         return 0;
1472 }
1473
1474 /* ----------- FBDev related routines for all series ---------- */
1475
1476 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1477                 struct fb_info *info)
1478 {
1479         DEBUGPRN("inside get_fix");
1480         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1481
1482         strcpy(fix->id, myid);
1483
1484         fix->smem_start = xgi_video_info.video_base;
1485
1486         fix->smem_len = xgi_video_info.video_size;
1487
1488         fix->type = video_type;
1489         fix->type_aux = 0;
1490         if (xgi_video_info.video_bpp == 8)
1491                 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1492         else
1493                 fix->visual = FB_VISUAL_DIRECTCOLOR;
1494         fix->xpanstep = 0;
1495 #ifdef XGIFB_PAN
1496         if (XGIfb_ypan)
1497                 fix->ypanstep = 1;
1498 #endif
1499         fix->ywrapstep = 0;
1500         fix->line_length = xgi_video_info.video_linelength;
1501         fix->mmio_start = xgi_video_info.mmio_base;
1502         fix->mmio_len = xgi_video_info.mmio_size;
1503         fix->accel = FB_ACCEL_XGI_XABRE;
1504
1505         DEBUGPRN("end of get_fix");
1506         return 0;
1507 }
1508
1509 static int XGIfb_set_par(struct fb_info *info)
1510 {
1511         int err;
1512
1513         /* printk("XGIfb: inside set_par\n"); */
1514         err = XGIfb_do_set_var(&info->var, 1, info);
1515         if (err)
1516                 return err;
1517         XGIfb_get_fix(&info->fix, -1, info);
1518         /* printk("XGIfb: end of set_par\n"); */
1519         return 0;
1520 }
1521
1522 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1523 {
1524         unsigned int htotal = var->left_margin + var->xres + var->right_margin
1525                         + var->hsync_len;
1526         unsigned int vtotal = 0;
1527         unsigned int drate = 0, hrate = 0;
1528         int found_mode = 0;
1529         int refresh_rate, search_idx;
1530
1531         DEBUGPRN("Inside check_var");
1532
1533         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1534                 vtotal = var->upper_margin + var->yres + var->lower_margin
1535                                 + var->vsync_len;
1536                 vtotal <<= 1;
1537         } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1538                 vtotal = var->upper_margin + var->yres + var->lower_margin
1539                                 + var->vsync_len;
1540                 vtotal <<= 2;
1541         } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1542                 vtotal = var->upper_margin + (var->yres / 2)
1543                                 + var->lower_margin + var->vsync_len;
1544         } else
1545                 vtotal = var->upper_margin + var->yres + var->lower_margin
1546                                 + var->vsync_len;
1547
1548         if (!(htotal) || !(vtotal))
1549                 XGIFAIL("XGIfb: no valid timing data");
1550
1551         if (var->pixclock && htotal && vtotal) {
1552                 drate = 1000000000 / var->pixclock;
1553                 hrate = (drate * 1000) / htotal;
1554                 xgi_video_info.refresh_rate =
1555                         (unsigned int) (hrate * 2 / vtotal);
1556                 printk(KERN_DEBUG
1557                         "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1558                         "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1559                         __func__, var->pixclock, htotal, vtotal,
1560                         __func__, drate, hrate, xgi_video_info.refresh_rate);
1561         } else {
1562                 xgi_video_info.refresh_rate = 60;
1563         }
1564
1565         /*
1566         if ((var->pixclock) && (htotal)) {
1567                 drate = 1E12 / var->pixclock;
1568                 hrate = drate / htotal;
1569                 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1570         } else {
1571                 refresh_rate = 60;
1572         }
1573         */
1574         /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1575         if ((var->xres == 1024) && (var->yres == 600))
1576                 refresh_rate = 60;
1577
1578         search_idx = 0;
1579         while ((XGIbios_mode[search_idx].mode_no != 0) &&
1580                 (XGIbios_mode[search_idx].xres <= var->xres)) {
1581                 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1582                         (XGIbios_mode[search_idx].yres == var->yres) &&
1583                         (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1584                         if (XGIfb_validate_mode(search_idx) > 0) {
1585                                 found_mode = 1;
1586                                 break;
1587                         }
1588                 }
1589                 search_idx++;
1590         }
1591
1592         if (!found_mode) {
1593
1594                 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1595                         var->xres, var->yres, var->bits_per_pixel);
1596                 search_idx = 0;
1597                 while (XGIbios_mode[search_idx].mode_no != 0) {
1598                         if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1599                             (var->yres <= XGIbios_mode[search_idx].yres) &&
1600                             (var->bits_per_pixel ==
1601                              XGIbios_mode[search_idx].bpp)) {
1602                                 if (XGIfb_validate_mode(search_idx) > 0) {
1603                                         found_mode = 1;
1604                                         break;
1605                                 }
1606                         }
1607                         search_idx++;
1608                 }
1609                 if (found_mode) {
1610                         var->xres = XGIbios_mode[search_idx].xres;
1611                         var->yres = XGIbios_mode[search_idx].yres;
1612                         printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1613                                 var->xres, var->yres, var->bits_per_pixel);
1614
1615                 } else {
1616                         printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1617                                 var->xres, var->yres, var->bits_per_pixel);
1618                         return -EINVAL;
1619                 }
1620         }
1621
1622         /* TW: TODO: Check the refresh rate */
1623
1624         /* Adapt RGB settings */
1625         XGIfb_bpp_to_var(var);
1626
1627         /* Sanity check for offsets */
1628         if (var->xoffset < 0)
1629                 var->xoffset = 0;
1630         if (var->yoffset < 0)
1631                 var->yoffset = 0;
1632
1633         if (!XGIfb_ypan) {
1634                 if (var->xres != var->xres_virtual)
1635                         var->xres_virtual = var->xres;
1636                 if (var->yres != var->yres_virtual)
1637                         var->yres_virtual = var->yres;
1638         } /* else { */
1639                 /* TW: Now patch yres_virtual if we use panning */
1640                 /* May I do this? */
1641                 /* var->yres_virtual = xgi_video_info.heapstart /
1642                         (var->xres * (var->bits_per_pixel >> 3)); */
1643                 /* if (var->yres_virtual <= var->yres) { */
1644                 /* TW: Paranoia check */
1645                 /* var->yres_virtual = var->yres; */
1646                 /* } */
1647         /* } */
1648
1649         /* Truncate offsets to maximum if too high */
1650         if (var->xoffset > var->xres_virtual - var->xres)
1651                 var->xoffset = var->xres_virtual - var->xres - 1;
1652
1653         if (var->yoffset > var->yres_virtual - var->yres)
1654                 var->yoffset = var->yres_virtual - var->yres - 1;
1655
1656         /* Set everything else to 0 */
1657         var->red.msb_right =
1658         var->green.msb_right =
1659         var->blue.msb_right =
1660         var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1661
1662         DEBUGPRN("end of check_var");
1663         return 0;
1664 }
1665
1666 #ifdef XGIFB_PAN
1667 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1668                 struct fb_info *info)
1669 {
1670         int err;
1671
1672         /* printk("\nInside pan_display:\n"); */
1673
1674         if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1675                 return -EINVAL;
1676         if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1677                 return -EINVAL;
1678
1679         if (var->vmode & FB_VMODE_YWRAP) {
1680                 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1681                                 || var->xoffset)
1682                         return -EINVAL;
1683         } else {
1684                 if (var->xoffset + info->var.xres > info->var.xres_virtual
1685                                 || var->yoffset + info->var.yres
1686                                                 > info->var.yres_virtual)
1687                         return -EINVAL;
1688         }
1689         err = XGIfb_pan_var(var, info);
1690         if (err < 0)
1691                 return err;
1692
1693         info->var.xoffset = var->xoffset;
1694         info->var.yoffset = var->yoffset;
1695         if (var->vmode & FB_VMODE_YWRAP)
1696                 info->var.vmode |= FB_VMODE_YWRAP;
1697         else
1698                 info->var.vmode &= ~FB_VMODE_YWRAP;
1699
1700         /* printk("End of pan_display\n"); */
1701         return 0;
1702 }
1703 #endif
1704
1705 static int XGIfb_blank(int blank, struct fb_info *info)
1706 {
1707         u8 reg;
1708
1709         reg = xgifb_reg_get(XGICR, 0x17);
1710
1711         if (blank > 0)
1712                 reg &= 0x7f;
1713         else
1714                 reg |= 0x80;
1715
1716         xgifb_reg_set(XGICR, 0x17, reg);
1717         xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1718         xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1719         return 0;
1720 }
1721
1722 static struct fb_ops XGIfb_ops = {
1723         .owner = THIS_MODULE,
1724         .fb_open = XGIfb_open,
1725         .fb_release = XGIfb_release,
1726         .fb_check_var = XGIfb_check_var,
1727         .fb_set_par = XGIfb_set_par,
1728         .fb_setcolreg = XGIfb_setcolreg,
1729 #ifdef XGIFB_PAN
1730         .fb_pan_display = XGIfb_pan_display,
1731 #endif
1732         .fb_blank = XGIfb_blank,
1733         .fb_fillrect = cfb_fillrect,
1734         .fb_copyarea = cfb_copyarea,
1735         .fb_imageblit = cfb_imageblit,
1736         /* .fb_mmap = XGIfb_mmap, */
1737 };
1738
1739 /* ---------------- Chip generation dependent routines ---------------- */
1740
1741 /* for XGI 315/550/650/740/330 */
1742
1743 static int XGIfb_get_dram_size(void)
1744 {
1745
1746         u8 ChannelNum, tmp;
1747         u8 reg = 0;
1748
1749         /* xorg driver sets 32MB * 1 channel */
1750         if (xgi_video_info.chip == XG27)
1751                 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1752
1753         reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
1754         switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1755         case XGI_DRAM_SIZE_1MB:
1756                 xgi_video_info.video_size = 0x100000;
1757                 break;
1758         case XGI_DRAM_SIZE_2MB:
1759                 xgi_video_info.video_size = 0x200000;
1760                 break;
1761         case XGI_DRAM_SIZE_4MB:
1762                 xgi_video_info.video_size = 0x400000;
1763                 break;
1764         case XGI_DRAM_SIZE_8MB:
1765                 xgi_video_info.video_size = 0x800000;
1766                 break;
1767         case XGI_DRAM_SIZE_16MB:
1768                 xgi_video_info.video_size = 0x1000000;
1769                 break;
1770         case XGI_DRAM_SIZE_32MB:
1771                 xgi_video_info.video_size = 0x2000000;
1772                 break;
1773         case XGI_DRAM_SIZE_64MB:
1774                 xgi_video_info.video_size = 0x4000000;
1775                 break;
1776         case XGI_DRAM_SIZE_128MB:
1777                 xgi_video_info.video_size = 0x8000000;
1778                 break;
1779         case XGI_DRAM_SIZE_256MB:
1780                 xgi_video_info.video_size = 0x10000000;
1781                 break;
1782         default:
1783                 return -1;
1784         }
1785
1786         tmp = (reg & 0x0c) >> 2;
1787         switch (xgi_video_info.chip) {
1788         case XG20:
1789         case XG21:
1790         case XG27:
1791                 ChannelNum = 1;
1792                 break;
1793
1794         case XG42:
1795                 if (reg & 0x04)
1796                         ChannelNum = 2;
1797                 else
1798                         ChannelNum = 1;
1799                 break;
1800
1801         case XG45:
1802                 if (tmp == 1)
1803                         ChannelNum = 2;
1804                 else if (tmp == 2)
1805                         ChannelNum = 3;
1806                 else if (tmp == 3)
1807                         ChannelNum = 4;
1808                 else
1809                         ChannelNum = 1;
1810                 break;
1811
1812         case XG40:
1813         default:
1814                 if (tmp == 2)
1815                         ChannelNum = 2;
1816                 else if (tmp == 3)
1817                         ChannelNum = 3;
1818                 else
1819                         ChannelNum = 1;
1820                 break;
1821         }
1822
1823         xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1824         /* PLiad fixed for benchmarking and fb set */
1825         /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1826         /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1827
1828         printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1829                reg,
1830                xgi_video_info.video_size, ChannelNum);
1831         return 0;
1832
1833 }
1834
1835 static void XGIfb_detect_VB(void)
1836 {
1837         u8 cr32, temp = 0;
1838
1839         xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1840
1841         switch (xgi_video_info.hasVB) {
1842         case HASVB_LVDS_CHRONTEL:
1843         case HASVB_CHRONTEL:
1844                 break;
1845         case HASVB_301:
1846         case HASVB_302:
1847                 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1848                 break;
1849         }
1850
1851         cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1852
1853         if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1854                 XGIfb_crt1off = 0;
1855         else {
1856                 if (cr32 & 0x5F)
1857                         XGIfb_crt1off = 1;
1858                 else
1859                         XGIfb_crt1off = 0;
1860         }
1861
1862         if (XGIfb_crt2type != -1)
1863                 /* TW: Override with option */
1864                 xgi_video_info.disp_state = XGIfb_crt2type;
1865         else if (cr32 & XGI_VB_TV)
1866                 xgi_video_info.disp_state = DISPTYPE_TV;
1867         else if (cr32 & XGI_VB_LCD)
1868                 xgi_video_info.disp_state = DISPTYPE_LCD;
1869         else if (cr32 & XGI_VB_CRT2)
1870                 xgi_video_info.disp_state = DISPTYPE_CRT2;
1871         else
1872                 xgi_video_info.disp_state = 0;
1873
1874         if (XGIfb_tvplug != -1)
1875                 /* PR/TW: Override with option */
1876                 xgi_video_info.TV_plug = XGIfb_tvplug;
1877         else if (cr32 & XGI_VB_HIVISION) {
1878                 xgi_video_info.TV_type = TVMODE_HIVISION;
1879                 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1880         } else if (cr32 & XGI_VB_SVIDEO)
1881                 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1882         else if (cr32 & XGI_VB_COMPOSITE)
1883                 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1884         else if (cr32 & XGI_VB_SCART)
1885                 xgi_video_info.TV_plug = TVPLUG_SCART;
1886
1887         if (xgi_video_info.TV_type == 0) {
1888                 temp = xgifb_reg_get(XGICR, 0x38);
1889                 if (temp & 0x10)
1890                         xgi_video_info.TV_type = TVMODE_PAL;
1891                 else
1892                         xgi_video_info.TV_type = TVMODE_NTSC;
1893         }
1894
1895         /* TW: Copy forceCRT1 option to CRT1off if option is given */
1896         if (XGIfb_forcecrt1 != -1) {
1897                 if (XGIfb_forcecrt1)
1898                         XGIfb_crt1off = 0;
1899                 else
1900                         XGIfb_crt1off = 1;
1901         }
1902 }
1903
1904 static int XGIfb_has_VB(void)
1905 {
1906         u8 vb_chipid;
1907
1908         vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1909         switch (vb_chipid) {
1910         case 0x01:
1911                 xgi_video_info.hasVB = HASVB_301;
1912                 break;
1913         case 0x02:
1914                 xgi_video_info.hasVB = HASVB_302;
1915                 break;
1916         default:
1917                 xgi_video_info.hasVB = HASVB_NONE;
1918                 return 0;
1919         }
1920         return 1;
1921 }
1922
1923 static void XGIfb_get_VB_type(void)
1924 {
1925         u8 reg;
1926
1927         if (!XGIfb_has_VB()) {
1928                 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1929                 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1930                 case XGI310_EXTERNAL_CHIP_LVDS:
1931                         xgi_video_info.hasVB = HASVB_LVDS;
1932                         break;
1933                 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1934                         xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1935                         break;
1936                 default:
1937                         break;
1938                 }
1939         }
1940 }
1941
1942 XGIINITSTATIC int __init XGIfb_setup(char *options)
1943 {
1944         char *this_opt;
1945
1946         xgi_video_info.refresh_rate = 0;
1947
1948         printk(KERN_INFO "XGIfb: Options %s\n", options);
1949
1950         if (!options || !*options)
1951                 return 0;
1952
1953         while ((this_opt = strsep(&options, ",")) != NULL) {
1954
1955                 if (!*this_opt)
1956                         continue;
1957
1958                 if (!strncmp(this_opt, "mode:", 5)) {
1959                         XGIfb_search_mode(this_opt + 5);
1960                 } else if (!strncmp(this_opt, "vesa:", 5)) {
1961                         XGIfb_search_vesamode(simple_strtoul(
1962                                                 this_opt + 5, NULL, 0));
1963                 } else if (!strncmp(this_opt, "mode:", 5)) {
1964                         XGIfb_search_mode(this_opt + 5);
1965                 } else if (!strncmp(this_opt, "vesa:", 5)) {
1966                         XGIfb_search_vesamode(simple_strtoul(
1967                                                 this_opt + 5, NULL, 0));
1968                 } else if (!strncmp(this_opt, "vrate:", 6)) {
1969                         xgi_video_info.refresh_rate = simple_strtoul(
1970                                                 this_opt + 6, NULL, 0);
1971                 } else if (!strncmp(this_opt, "rate:", 5)) {
1972                         xgi_video_info.refresh_rate = simple_strtoul(
1973                                                 this_opt + 5, NULL, 0);
1974                 } else if (!strncmp(this_opt, "off", 3)) {
1975                         XGIfb_off = 1;
1976                 } else if (!strncmp(this_opt, "crt1off", 7)) {
1977                         XGIfb_crt1off = 1;
1978                 } else if (!strncmp(this_opt, "filter:", 7)) {
1979                         filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1980                 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1981                         XGIfb_search_crt2type(this_opt + 14);
1982                 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1983                         XGIfb_forcecrt1 = (int)simple_strtoul(
1984                                                 this_opt + 10, NULL, 0);
1985                 } else if (!strncmp(this_opt, "tvmode:", 7)) {
1986                         XGIfb_search_tvstd(this_opt + 7);
1987                 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1988                         XGIfb_search_tvstd(this_opt + 7);
1989                 } else if (!strncmp(this_opt, "dstn", 4)) {
1990                         enable_dstn = 1;
1991                         /* TW: DSTN overrules forcecrt2type */
1992                         XGIfb_crt2type = DISPTYPE_LCD;
1993                 } else if (!strncmp(this_opt, "pdc:", 4)) {
1994                         XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
1995                         if (XGIfb_pdc & ~0x3c) {
1996                                 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
1997                                 XGIfb_pdc = 0;
1998                         }
1999                 } else if (!strncmp(this_opt, "noypan", 6)) {
2000                         XGIfb_ypan = 0;
2001                 } else if (!strncmp(this_opt, "userom:", 7)) {
2002                         XGIfb_userom = (int)simple_strtoul(
2003                                                 this_opt + 7, NULL, 0);
2004                         /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2005                         /* XGIfb_useoem = (int)simple_strtoul(
2006                                                 this_opt + 7, NULL, 0); */
2007                 } else {
2008                         XGIfb_search_mode(this_opt);
2009                         /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
2010                                   this_opt); */
2011                 }
2012
2013                 /* TW: Panning only with acceleration */
2014                 XGIfb_ypan = 0;
2015
2016         }
2017         printk("\nxgifb: outa xgifb_setup 3450");
2018         return 0;
2019 }
2020
2021 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2022 {
2023         void __iomem *rom_address;
2024         unsigned char *rom_copy;
2025         size_t rom_size;
2026
2027         rom_address = pci_map_rom(dev, &rom_size);
2028         if (rom_address == NULL)
2029                 return NULL;
2030
2031         rom_copy = vzalloc(XGIFB_ROM_SIZE);
2032         if (rom_copy == NULL)
2033                 goto done;
2034
2035         rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2036         memcpy_fromio(rom_copy, rom_address, rom_size);
2037
2038 done:
2039         pci_unmap_rom(dev, rom_address);
2040         return rom_copy;
2041 }
2042
2043 static int __devinit xgifb_probe(struct pci_dev *pdev,
2044                 const struct pci_device_id *ent)
2045 {
2046         u8 reg, reg1;
2047         u8 CR48, CR38;
2048         int ret;
2049
2050         if (XGIfb_off)
2051                 return -ENXIO;
2052
2053         XGIfb_registered = 0;
2054
2055         memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2056         fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2057         if (!fb_info)
2058                 return -ENOMEM;
2059
2060         xgi_video_info.chip_id = pdev->device;
2061         pci_read_config_byte(pdev,
2062                              PCI_REVISION_ID,
2063                              &xgi_video_info.revision_id);
2064         XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2065
2066         xgi_video_info.pcibus = pdev->bus->number;
2067         xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2068         xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2069         xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2070         xgi_video_info.subsysdevice = pdev->subsystem_device;
2071
2072         xgi_video_info.video_base = pci_resource_start(pdev, 0);
2073         xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2074         xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2075         xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2076         XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2077         /* XGI_Pr.RelIO  = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2078         printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2079                (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2080
2081         if (pci_enable_device(pdev)) {
2082                 ret = -EIO;
2083                 goto error;
2084         }
2085
2086         XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2087
2088         xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2089         reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
2090
2091         if (reg1 != 0xa1) { /*I/O error */
2092                 printk("\nXGIfb: I/O error!!!");
2093                 ret = -EIO;
2094                 goto error;
2095         }
2096
2097         switch (xgi_video_info.chip_id) {
2098         case PCI_DEVICE_ID_XG_20:
2099                 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2100                 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
2101                 if (CR48&GPIOG_READ)
2102                         xgi_video_info.chip = XG21;
2103                 else
2104                         xgi_video_info.chip = XG20;
2105                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2106                 break;
2107         case PCI_DEVICE_ID_XG_40:
2108                 xgi_video_info.chip = XG40;
2109                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2110                 break;
2111         case PCI_DEVICE_ID_XG_41:
2112                 xgi_video_info.chip = XG41;
2113                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2114                 break;
2115         case PCI_DEVICE_ID_XG_42:
2116                 xgi_video_info.chip = XG42;
2117                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2118                 break;
2119         case PCI_DEVICE_ID_XG_27:
2120                 xgi_video_info.chip = XG27;
2121                 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2122                 break;
2123         default:
2124                 ret = -ENODEV;
2125                 goto error;
2126         }
2127
2128         printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2129         XGIhw_ext.jChipType = xgi_video_info.chip;
2130
2131         if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2132                 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2133                 if (XGIhw_ext.pjVirtualRomBase)
2134                         printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2135                                XGIhw_ext.pjVirtualRomBase);
2136                 else
2137                         printk(KERN_INFO "XGIfb: Video ROM not found\n");
2138         } else {
2139                 XGIhw_ext.pjVirtualRomBase = NULL;
2140                 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2141         }
2142         XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2143
2144         if (XGIfb_get_dram_size()) {
2145                 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2146                 ret = -ENODEV;
2147                 goto error;
2148         }
2149
2150         if ((xgifb_mode_idx < 0) ||
2151             ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2152                 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
2153                 xgifb_reg_or(XGISR,
2154                              IND_XGI_PCI_ADDRESS_SET,
2155                              (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2156                 /* Enable 2D accelerator engine */
2157                 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2158         }
2159
2160         XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2161
2162         if (!request_mem_region(xgi_video_info.video_base,
2163                                 xgi_video_info.video_size,
2164                                 "XGIfb FB")) {
2165                 printk("unable request memory size %x",
2166                        xgi_video_info.video_size);
2167                 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2168                 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2169                 ret = -ENODEV;
2170                 goto error;
2171         }
2172
2173         if (!request_mem_region(xgi_video_info.mmio_base,
2174                                 xgi_video_info.mmio_size,
2175                                 "XGIfb MMIO")) {
2176                 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2177                 ret = -ENODEV;
2178                 goto error_0;
2179         }
2180
2181         xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2182         ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2183         xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2184                                             xgi_video_info.mmio_size);
2185
2186         printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2187                xgi_video_info.video_base,
2188                xgi_video_info.video_vbase,
2189                xgi_video_info.video_size / 1024);
2190
2191         printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2192                xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2193                xgi_video_info.mmio_size / 1024);
2194         printk("XGIfb: XGIInitNew() ...");
2195         if (XGIInitNew(&XGIhw_ext))
2196                 printk("OK\n");
2197         else
2198                 printk("Fail\n");
2199
2200         xgi_video_info.mtrr = (unsigned int) 0;
2201
2202         if ((xgifb_mode_idx < 0) ||
2203             ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2204                 xgi_video_info.hasVB = HASVB_NONE;
2205                 if ((xgi_video_info.chip == XG20) ||
2206                     (xgi_video_info.chip == XG27)) {
2207                         xgi_video_info.hasVB = HASVB_NONE;
2208                 } else if (xgi_video_info.chip == XG21) {
2209                         CR38 = xgifb_reg_get(XGICR, 0x38);
2210                         if ((CR38&0xE0) == 0xC0) {
2211                                 xgi_video_info.disp_state = DISPTYPE_LCD;
2212                                 if (!XGIfb_GetXG21LVDSData()) {
2213                                         int m;
2214                                         for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2215                                                 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2216                                                     (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2217                                                         xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2218                                                 }
2219                                         }
2220                                 }
2221                         } else if ((CR38&0xE0) == 0x60) {
2222                                 xgi_video_info.hasVB = HASVB_CHRONTEL;
2223                         } else {
2224                                 xgi_video_info.hasVB = HASVB_NONE;
2225                         }
2226                 } else {
2227                         XGIfb_get_VB_type();
2228                 }
2229
2230                 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2231
2232                 XGIhw_ext.ulExternalChip = 0;
2233
2234                 switch (xgi_video_info.hasVB) {
2235                 case HASVB_301:
2236                         reg = xgifb_reg_get(XGIPART4, 0x01);
2237                         if (reg >= 0xE0) {
2238                                 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2239                                 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2240                         } else if (reg >= 0xD0) {
2241                                 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2242                                 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2243                         }
2244                         /* else if (reg >= 0xB0) {
2245                                 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2246                                 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2247                                 printk("XGIfb: XGI301B bridge detected\n");
2248                         } */
2249                         else {
2250                                 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2251                                 printk("XGIfb: XGI301 bridge detected\n");
2252                         }
2253                         break;
2254                 case HASVB_302:
2255                         reg = xgifb_reg_get(XGIPART4, 0x01);
2256                         if (reg >= 0xE0) {
2257                                 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2258                                 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2259                         } else if (reg >= 0xD0) {
2260                                 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2261                                 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2262                         } else if (reg >= 0xB0) {
2263                                 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2264
2265                                 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2266
2267                         } else {
2268                                 XGIhw_ext.ujVBChipID = VB_CHIP_302;
2269                                 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2270                         }
2271                         break;
2272                 case HASVB_LVDS:
2273                         XGIhw_ext.ulExternalChip = 0x1;
2274                         printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2275                         break;
2276                 case HASVB_TRUMPION:
2277                         XGIhw_ext.ulExternalChip = 0x2;
2278                         printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2279                         break;
2280                 case HASVB_CHRONTEL:
2281                         XGIhw_ext.ulExternalChip = 0x4;
2282                         printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2283                         break;
2284                 case HASVB_LVDS_CHRONTEL:
2285                         XGIhw_ext.ulExternalChip = 0x5;
2286                         printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2287                         break;
2288                 default:
2289                         printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2290                         break;
2291                 }
2292
2293                 if (xgi_video_info.hasVB != HASVB_NONE)
2294                         XGIfb_detect_VB();
2295
2296                 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2297                         if (XGIfb_crt1off)
2298                                 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2299                         else
2300                                 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2301                                                               DISPTYPE_CRT1);
2302                 } else {
2303                         xgi_video_info.disp_state = DISPMODE_SINGLE |
2304                                                     DISPTYPE_CRT1;
2305                 }
2306
2307                 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2308                         if (!enable_dstn) {
2309                                 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2310                                 reg &= 0x0f;
2311                                 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2312
2313                         } else {
2314                                 /* TW: FSTN/DSTN */
2315                                 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2316                         }
2317                 }
2318
2319                 XGIfb_detectedpdc = 0;
2320
2321                 XGIfb_detectedlcda = 0xff;
2322
2323                 /* TW: Try to find about LCDA */
2324
2325                 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2326                                 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2327                                 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2328                         int tmp;
2329                         tmp = xgifb_reg_get(XGICR, 0x34);
2330                         if (tmp <= 0x13) {
2331                                 /* Currently on LCDA?
2332                                  *(Some BIOSes leave CR38) */
2333                                 tmp = xgifb_reg_get(XGICR, 0x38);
2334                                 if ((tmp & 0x03) == 0x03) {
2335                                         /* XGI_Pr.XGI_UseLCDA = 1; */
2336                                 } else {
2337                                         /* Currently on LCDA?
2338                                          *(Some newer BIOSes set D0 in CR35) */
2339                                         tmp = xgifb_reg_get(XGICR, 0x35);
2340                                         if (tmp & 0x01) {
2341                                                 /* XGI_Pr.XGI_UseLCDA = 1; */
2342                                         } else {
2343                                                 tmp = xgifb_reg_get(XGICR,
2344                                                                     0x30);
2345                                                 if (tmp & 0x20) {
2346                                                         tmp = xgifb_reg_get(
2347                                                                 XGIPART1, 0x13);
2348                                                         if (tmp & 0x04) {
2349                                                                 /* XGI_Pr.XGI_UseLCDA = 1; */
2350                                                         }
2351                                                 }
2352                                         }
2353                                 }
2354                         }
2355
2356                 }
2357
2358                 if (xgifb_mode_idx >= 0)
2359                         xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2360
2361                 if (xgifb_mode_idx < 0) {
2362                         switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2363                         case DISPTYPE_LCD:
2364                                 xgifb_mode_idx = DEFAULT_LCDMODE;
2365                                 if (xgi_video_info.chip == XG21)
2366                                         xgifb_mode_idx =
2367                                             XGIfb_GetXG21DefaultLVDSModeIdx();
2368                                 break;
2369                         case DISPTYPE_TV:
2370                                 xgifb_mode_idx = DEFAULT_TVMODE;
2371                                 break;
2372                         default:
2373                                 xgifb_mode_idx = DEFAULT_MODE;
2374                                 break;
2375                         }
2376                 }
2377
2378                 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2379
2380                 /* yilin set default refresh rate */
2381                 if (xgi_video_info.refresh_rate == 0)
2382                         xgi_video_info.refresh_rate = 60;
2383                 if (XGIfb_search_refresh_rate(
2384                                 xgi_video_info.refresh_rate) == 0) {
2385                         XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2386                         xgi_video_info.refresh_rate = 60;
2387                 }
2388
2389                 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2390                 xgi_video_info.video_vwidth =
2391                         xgi_video_info.video_width =
2392                                 XGIbios_mode[xgifb_mode_idx].xres;
2393                 xgi_video_info.video_vheight =
2394                         xgi_video_info.video_height =
2395                                 XGIbios_mode[xgifb_mode_idx].yres;
2396                 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2397                 xgi_video_info.video_linelength =
2398                         xgi_video_info.video_width *
2399                         (xgi_video_info.video_bpp >> 3);
2400                 switch (xgi_video_info.video_bpp) {
2401                 case 8:
2402                         xgi_video_info.DstColor = 0x0000;
2403                         xgi_video_info.XGI310_AccelDepth = 0x00000000;
2404                         xgi_video_info.video_cmap_len = 256;
2405                         break;
2406                 case 16:
2407                         xgi_video_info.DstColor = 0x8000;
2408                         xgi_video_info.XGI310_AccelDepth = 0x00010000;
2409                         xgi_video_info.video_cmap_len = 16;
2410                         break;
2411                 case 32:
2412                         xgi_video_info.DstColor = 0xC000;
2413                         xgi_video_info.XGI310_AccelDepth = 0x00020000;
2414                         xgi_video_info.video_cmap_len = 16;
2415                         break;
2416                 default:
2417                         xgi_video_info.video_cmap_len = 16;
2418                         printk(KERN_INFO "XGIfb: Unsupported depth %d",
2419                                xgi_video_info.video_bpp);
2420                         break;
2421                 }
2422
2423                 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2424                        xgi_video_info.video_width,
2425                        xgi_video_info.video_height,
2426                        xgi_video_info.video_bpp,
2427                        xgi_video_info.refresh_rate);
2428
2429                 default_var.xres =
2430                         default_var.xres_virtual =
2431                                 xgi_video_info.video_width;
2432                 default_var.yres =
2433                         default_var.yres_virtual =
2434                                 xgi_video_info.video_height;
2435                 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2436
2437                 XGIfb_bpp_to_var(&default_var);
2438
2439                 default_var.pixclock = (u32) (1000000000 /
2440                                 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2441                                                 XGIfb_mode_no, XGIfb_rate_idx));
2442
2443                 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2444                         XGIfb_mode_no, XGIfb_rate_idx,
2445                         &default_var.left_margin, &default_var.right_margin,
2446                         &default_var.upper_margin, &default_var.lower_margin,
2447                         &default_var.hsync_len, &default_var.vsync_len,
2448                         &default_var.sync, &default_var.vmode)) {
2449
2450                         if ((default_var.vmode & FB_VMODE_MASK) ==
2451                             FB_VMODE_INTERLACED) {
2452                                 default_var.yres <<= 1;
2453                                 default_var.yres_virtual <<= 1;
2454                         } else if ((default_var.vmode & FB_VMODE_MASK) ==
2455                                    FB_VMODE_DOUBLE) {
2456                                 default_var.pixclock >>= 1;
2457                                 default_var.yres >>= 1;
2458                                 default_var.yres_virtual >>= 1;
2459                         }
2460
2461                 }
2462
2463                 fb_info->flags = FBINFO_FLAG_DEFAULT;
2464                 fb_info->var = default_var;
2465                 fb_info->fix = XGIfb_fix;
2466                 fb_info->par = &xgi_video_info;
2467                 fb_info->screen_base = xgi_video_info.video_vbase;
2468                 fb_info->fbops = &XGIfb_ops;
2469                 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2470                 fb_info->pseudo_palette = pseudo_palette;
2471
2472                 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2473
2474 #ifdef CONFIG_MTRR
2475                 xgi_video_info.mtrr = mtrr_add(
2476                         (unsigned int) xgi_video_info.video_base,
2477                         (unsigned int) xgi_video_info.video_size,
2478                         MTRR_TYPE_WRCOMB, 1);
2479                 if (xgi_video_info.mtrr)
2480                         printk(KERN_INFO "XGIfb: Added MTRRs\n");
2481 #endif
2482
2483                 if (register_framebuffer(fb_info) < 0) {
2484                         ret = -EINVAL;
2485                         goto error_1;
2486                 }
2487
2488                 XGIfb_registered = 1;
2489
2490                 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2491                        fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2492
2493         }
2494
2495         dumpVGAReg();
2496
2497         return 0;
2498
2499 error_1:
2500         iounmap(xgi_video_info.mmio_vbase);
2501         iounmap(xgi_video_info.video_vbase);
2502         release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2503 error_0:
2504         release_mem_region(xgi_video_info.video_base,
2505                            xgi_video_info.video_size);
2506 error:
2507         vfree(XGIhw_ext.pjVirtualRomBase);
2508         framebuffer_release(fb_info);
2509         return ret;
2510 }
2511
2512 /*****************************************************/
2513 /*                PCI DEVICE HANDLING                */
2514 /*****************************************************/
2515
2516 static void __devexit xgifb_remove(struct pci_dev *pdev)
2517 {
2518         unregister_framebuffer(fb_info);
2519         iounmap(xgi_video_info.mmio_vbase);
2520         iounmap(xgi_video_info.video_vbase);
2521         release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2522         release_mem_region(xgi_video_info.video_base,
2523                            xgi_video_info.video_size);
2524         vfree(XGIhw_ext.pjVirtualRomBase);
2525         framebuffer_release(fb_info);
2526         pci_set_drvdata(pdev, NULL);
2527 }
2528
2529 static struct pci_driver xgifb_driver = {
2530         .name = "xgifb",
2531         .id_table = xgifb_pci_table,
2532         .probe = xgifb_probe,
2533         .remove = __devexit_p(xgifb_remove)
2534 };
2535
2536 XGIINITSTATIC int __init xgifb_init(void)
2537 {
2538         char *option = NULL;
2539
2540         if (fb_get_options("xgifb", &option))
2541                 return -ENODEV;
2542         XGIfb_setup(option);
2543
2544         return pci_register_driver(&xgifb_driver);
2545 }
2546
2547 #ifndef MODULE
2548 module_init(xgifb_init);
2549 #endif
2550
2551 /*****************************************************/
2552 /*                      MODULE                       */
2553 /*****************************************************/
2554
2555 #ifdef MODULE
2556
2557 static char *mode = NULL;
2558 static int vesa = 0;
2559 static unsigned int rate = 0;
2560 static unsigned int mem = 0;
2561 static char *forcecrt2type = NULL;
2562 static int forcecrt1 = -1;
2563 static int pdc = -1;
2564 static int pdc1 = -1;
2565 static int noypan = -1;
2566 static int userom = -1;
2567 static int useoem = -1;
2568 static char *tvstandard = NULL;
2569 static int nocrt2rate = 0;
2570 static int scalelcd = -1;
2571 static char *specialtiming = NULL;
2572 static int lvdshl = -1;
2573 static int tvxposoffset = 0, tvyposoffset = 0;
2574 #if !defined(__i386__) && !defined(__x86_64__)
2575 static int resetcard = 0;
2576 static int videoram = 0;
2577 #endif
2578
2579 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2580 MODULE_LICENSE("GPL");
2581 MODULE_AUTHOR("XGITECH , Others");
2582
2583 module_param(mem, int, 0);
2584 module_param(noypan, int, 0);
2585 module_param(userom, int, 0);
2586 module_param(useoem, int, 0);
2587 module_param(mode, charp, 0);
2588 module_param(vesa, int, 0);
2589 module_param(rate, int, 0);
2590 module_param(forcecrt1, int, 0);
2591 module_param(forcecrt2type, charp, 0);
2592 module_param(scalelcd, int, 0);
2593 module_param(pdc, int, 0);
2594 module_param(pdc1, int, 0);
2595 module_param(specialtiming, charp, 0);
2596 module_param(lvdshl, int, 0);
2597 module_param(tvstandard, charp, 0);
2598 module_param(tvxposoffset, int, 0);
2599 module_param(tvyposoffset, int, 0);
2600 module_param(filter, int, 0);
2601 module_param(nocrt2rate, int, 0);
2602 #if !defined(__i386__) && !defined(__x86_64__)
2603 module_param(resetcard, int, 0);
2604 module_param(videoram, int, 0);
2605 #endif
2606
2607 MODULE_PARM_DESC(noypan,
2608                 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2609                 "will be performed by redrawing the screen. (default: 0)\n");
2610
2611 MODULE_PARM_DESC(mode,
2612                 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2613                 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2614                 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2615                 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2616
2617 MODULE_PARM_DESC(vesa,
2618                 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2619                 "0x117 (default: 0x0103)\n");
2620
2621 MODULE_PARM_DESC(rate,
2622                 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2623                 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2624                 "will be ignored (default: 60)\n");
2625
2626 MODULE_PARM_DESC(forcecrt1,
2627                 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2628                 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2629                 "0=CRT1 OFF) (default: [autodetected])\n");
2630
2631 MODULE_PARM_DESC(forcecrt2type,
2632                 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2633                 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2634                 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2635                 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2636                 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2637                 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2638                 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2639                 "depends on the very hardware in use. (default: [autodetected])\n");
2640
2641 MODULE_PARM_DESC(scalelcd,
2642                 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2643                 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2644                 "show black bars around the image, TMDS panels will probably do the scaling\n"
2645                 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2646
2647 MODULE_PARM_DESC(pdc,
2648                 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2649                 "should detect this correctly in most cases; however, sometimes this is not\n"
2650                 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2651                 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2652                 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2653                 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2654
2655 MODULE_PARM_DESC(pdc1,
2656                 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2657                 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2658                 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2659                 "implemented yet.\n");
2660
2661 MODULE_PARM_DESC(specialtiming,
2662                 "\nPlease refer to documentation for more information on this option.\n");
2663
2664 MODULE_PARM_DESC(lvdshl,
2665                 "\nPlease refer to documentation for more information on this option.\n");
2666
2667 MODULE_PARM_DESC(tvstandard,
2668                 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2669                 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2670
2671 MODULE_PARM_DESC(tvxposoffset,
2672                 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2673                 "Default: 0\n");
2674
2675 MODULE_PARM_DESC(tvyposoffset,
2676                 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2677                 "Default: 0\n");
2678
2679 MODULE_PARM_DESC(filter,
2680                 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2681                 "(Possible values 0-7, default: [no filter])\n");
2682
2683 MODULE_PARM_DESC(nocrt2rate,
2684                 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2685                 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2686
2687 static int __init xgifb_init_module(void)
2688 {
2689         printk("\nXGIfb_init_module");
2690         if (mode)
2691                 XGIfb_search_mode(mode);
2692         else if (vesa != -1)
2693                 XGIfb_search_vesamode(vesa);
2694
2695         return xgifb_init();
2696 }
2697
2698 static void __exit xgifb_remove_module(void)
2699 {
2700         pci_unregister_driver(&xgifb_driver);
2701         printk(KERN_DEBUG "xgifb: Module unloaded\n");
2702 }
2703
2704 module_init(xgifb_init_module);
2705 module_exit(xgifb_remove_module);
2706
2707 #endif  /*  /MODULE  */