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