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