fe9061d37ce8196f033e68d908edccb6b5c78057
[linux-2.6-block.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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9 #include <linux/module.h>
10
11 #ifdef CONFIG_MTRR
12 #include <asm/mtrr.h>
13 #endif
14
15 #include "XGI_main.h"
16 #include "vb_init.h"
17 #include "vb_util.h"
18 #include "vb_setmode.h"
19
20 #define Index_CR_GPIO_Reg1 0x48
21 #define Index_CR_GPIO_Reg3 0x4a
22
23 #define GPIOG_EN    (1<<6)
24 #define GPIOG_READ  (1<<1)
25
26 static char *forcecrt2type;
27 static char *mode;
28 static int vesa = -1;
29 static unsigned int refresh_rate;
30
31 /* -------------------- Macro definitions ---------------------------- */
32
33 #ifdef DEBUG
34 static void dumpVGAReg(void)
35 {
36         u8 i, reg;
37
38         xgifb_reg_set(XGISR, 0x05, 0x86);
39         /*
40         xgifb_reg_set(XGISR, 0x08, 0x4f);
41         xgifb_reg_set(XGISR, 0x0f, 0x20);
42         xgifb_reg_set(XGISR, 0x11, 0x4f);
43         xgifb_reg_set(XGISR, 0x13, 0x45);
44         xgifb_reg_set(XGISR, 0x14, 0x51);
45         xgifb_reg_set(XGISR, 0x1e, 0x41);
46         xgifb_reg_set(XGISR, 0x1f, 0x0);
47         xgifb_reg_set(XGISR, 0x20, 0xa1);
48         xgifb_reg_set(XGISR, 0x22, 0xfb);
49         xgifb_reg_set(XGISR, 0x26, 0x22);
50         xgifb_reg_set(XGISR, 0x3e, 0x07);
51         */
52
53         /* xgifb_reg_set(XGICR, 0x19, 0x00); */
54         /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
55         /* xgifb_reg_set(XGICR, 0x22, 0xff); */
56         /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
57
58         /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
59
60         /* xgifb_reg_set(XGICR, 0x57, 0x0); */
61         /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
62
63         /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
64         /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
65         /*
66         xgifb_reg_set(XGICR, 0x99, 0x1);
67         xgifb_reg_set(XGICR, 0x41, 0x40);
68         */
69
70         for (i = 0; i < 0x4f; i++) {
71                 reg = xgifb_reg_get(XGISR, i);
72                 pr_debug("\no 3c4 %x", i);
73                 pr_debug("\ni 3c5 => %x", reg);
74         }
75
76         for (i = 0; i < 0xF0; i++) {
77                 reg = xgifb_reg_get(XGICR, i);
78                 pr_debug("\no 3d4 %x", i);
79                 pr_debug("\ni 3d5 => %x", reg);
80         }
81         /*
82         xgifb_reg_set(XGIPART1,0x2F,1);
83         for (i=1; i < 0x50; i++) {
84                 reg = xgifb_reg_get(XGIPART1, i);
85                 pr_debug("\no d004 %x", i);
86                 pr_debug("\ni d005 => %x", reg);
87         }
88
89         for (i=0; i < 0x50; i++) {
90                  reg = xgifb_reg_get(XGIPART2, i);
91                  pr_debug("\no d010 %x", i);
92                  pr_debug("\ni d011 => %x", reg);
93         }
94         for (i=0; i < 0x50; i++) {
95                 reg = xgifb_reg_get(XGIPART3, i);
96                 pr_debug("\no d012 %x",i);
97                 pr_debug("\ni d013 => %x",reg);
98         }
99         for (i=0; i < 0x50; i++) {
100                 reg = xgifb_reg_get(XGIPART4, i);
101                 pr_debug("\no d014 %x",i);
102                 pr_debug("\ni d015 => %x",reg);
103         }
104         */
105 }
106 #else
107 static inline void dumpVGAReg(void)
108 {
109 }
110 #endif
111
112 /* --------------- Hardware Access Routines -------------------------- */
113
114 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
115                 struct xgi_hw_device_info *HwDeviceExtension,
116                 unsigned char modeno, unsigned char rateindex)
117 {
118         unsigned short ModeNo = modeno;
119         unsigned short ModeIdIndex = 0, ClockIndex = 0;
120         unsigned short RefreshRateTableIndex = 0;
121         int Clock;
122         InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
123
124         XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
125
126         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
127                         ModeIdIndex, XGI_Pr);
128
129         ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
130
131         Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
132
133         return Clock;
134 }
135
136 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
137                 struct xgi_hw_device_info *HwDeviceExtension,
138                 unsigned char modeno, unsigned char rateindex,
139                 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
140                 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
141                 u32 *vmode)
142 {
143         unsigned short ModeNo = modeno;
144         unsigned short ModeIdIndex, index = 0;
145         unsigned short RefreshRateTableIndex = 0;
146
147         unsigned short VRE, VBE, VRS, VBS, VDE, VT;
148         unsigned short HRE, HBE, HRS, HBS, HDE, HT;
149         unsigned char sr_data, cr_data, cr_data2;
150         unsigned long cr_data3;
151         int A, B, C, D, E, F, temp, j;
152         InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
153         if (!XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr))
154                 return 0;
155         RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
156                         ModeIdIndex, XGI_Pr);
157         index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
158
159         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
160
161         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
162
163         /* Horizontal total */
164         HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
165         A = HT + 5;
166
167         HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
168         E = HDE + 1;
169
170         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
171
172         /* Horizontal retrace (=sync) start */
173         HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
174         F = HRS - E - 3;
175
176         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
177
178         /* Horizontal blank start */
179         HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
180
181         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
182
183         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
184
185         cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
186
187         /* Horizontal blank end */
188         HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
189                         | ((unsigned short) (sr_data & 0x03) << 6);
190
191         /* Horizontal retrace (=sync) end */
192         HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
193
194         temp = HBE - ((E - 1) & 255);
195         B = (temp > 0) ? temp : (temp + 256);
196
197         temp = HRE - ((E + F + 3) & 63);
198         C = (temp > 0) ? temp : (temp + 64);
199
200         D = B - F - C;
201
202         *left_margin = D * 8;
203         *right_margin = F * 8;
204         *hsync_len = C * 8;
205
206         sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
207
208         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
209
210         cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
211
212         /* Vertical total */
213         VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
214                         | ((unsigned short) (cr_data2 & 0x20) << 4)
215                         | ((unsigned short) (sr_data & 0x01) << 10);
216         A = VT + 2;
217
218         /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
219
220         /* Vertical display enable end */
221         /*
222         VDE = (cr_data & 0xff) |
223                 ((unsigned short) (cr_data2 & 0x02) << 7) |
224                 ((unsigned short) (cr_data2 & 0x40) << 3) |
225                 ((unsigned short) (sr_data & 0x02) << 9);
226         */
227         VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
228         E = VDE + 1;
229
230         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
231
232         /* Vertical retrace (=sync) start */
233         VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
234                         | ((unsigned short) (cr_data2 & 0x80) << 2)
235                         | ((unsigned short) (sr_data & 0x08) << 7);
236         F = VRS + 1 - E;
237
238         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
239
240         cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
241
242         /* Vertical blank start */
243         VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
244                         | ((unsigned short) (cr_data3 & 0x20) << 4)
245                         | ((unsigned short) (sr_data & 0x04) << 8);
246
247         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
248
249         /* Vertical blank end */
250         VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
251         temp = VBE - ((E - 1) & 511);
252         B = (temp > 0) ? temp : (temp + 512);
253
254         cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
255
256         /* Vertical retrace (=sync) end */
257         VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
258         temp = VRE - ((E + F - 1) & 31);
259         C = (temp > 0) ? temp : (temp + 32);
260
261         D = B - F - C;
262
263         *upper_margin = D;
264         *lower_margin = F;
265         *vsync_len = C;
266
267         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
268                 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
269         else
270                 *sync |= FB_SYNC_VERT_HIGH_ACT;
271
272         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
273                 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
274         else
275                 *sync |= FB_SYNC_HOR_HIGH_ACT;
276
277         *vmode = FB_VMODE_NONINTERLACED;
278         if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
279                 *vmode = FB_VMODE_INTERLACED;
280         else {
281                 j = 0;
282                 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
283                         if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
284                             XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
285                                 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
286                                     DoubleScanMode) {
287                                         *vmode = FB_VMODE_DOUBLE;
288                                 }
289                                 break;
290                         }
291                         j++;
292                 }
293         }
294
295         return 1;
296 }
297
298 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
299 {
300         XGI_Pr->P3c4 = BaseAddr + 0x14;
301         XGI_Pr->P3d4 = BaseAddr + 0x24;
302         XGI_Pr->P3c0 = BaseAddr + 0x10;
303         XGI_Pr->P3ce = BaseAddr + 0x1e;
304         XGI_Pr->P3c2 = BaseAddr + 0x12;
305         XGI_Pr->P3ca = BaseAddr + 0x1a;
306         XGI_Pr->P3c6 = BaseAddr + 0x16;
307         XGI_Pr->P3c7 = BaseAddr + 0x17;
308         XGI_Pr->P3c8 = BaseAddr + 0x18;
309         XGI_Pr->P3c9 = BaseAddr + 0x19;
310         XGI_Pr->P3da = BaseAddr + 0x2A;
311         /* Digital video interface registers (LCD) */
312         XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04;
313         /* 301 TV Encoder registers */
314         XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10;
315         /* 301 Macrovision registers */
316         XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12;
317         /* 301 VGA2 (and LCD) registers */
318         XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14;
319         /* 301 palette address port registers */
320         XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
321
322 }
323
324 /* ------------------ Internal helper routines ----------------- */
325
326 static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info)
327 {
328
329         int found_mode = 0;
330         int XGIfb_mode_idx = 0;
331
332         found_mode = 0;
333         while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
334                         && (XGIbios_mode[XGIfb_mode_idx].xres
335                                         <= xgifb_info->lvds_data.LVDSHDE)) {
336                 if ((XGIbios_mode[XGIfb_mode_idx].xres
337                                 == xgifb_info->lvds_data.LVDSHDE)
338                                 && (XGIbios_mode[XGIfb_mode_idx].yres
339                                         == xgifb_info->lvds_data.LVDSVDE)
340                                 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
341                         found_mode = 1;
342                         break;
343                 }
344                 XGIfb_mode_idx++;
345         }
346         if (!found_mode)
347                 XGIfb_mode_idx = -1;
348
349         return XGIfb_mode_idx;
350 }
351
352 static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info,
353                               const char *name)
354 {
355         unsigned int xres;
356         unsigned int yres;
357         unsigned int bpp;
358         int i;
359
360         if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3)
361                 goto invalid_mode;
362
363         if (bpp == 24)
364                 bpp = 32; /* That's for people who mix up color and fb depth. */
365
366         for (i = 0; XGIbios_mode[i].mode_no != 0; i++)
367                 if (XGIbios_mode[i].xres == xres &&
368                     XGIbios_mode[i].yres == yres &&
369                     XGIbios_mode[i].bpp == bpp) {
370                         xgifb_info->mode_idx = i;
371                         return;
372                 }
373 invalid_mode:
374         pr_info("Invalid mode '%s'\n", name);
375 }
376
377 static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
378                                   unsigned int vesamode)
379 {
380         int i = 0, j = 0;
381
382         if (vesamode == 0)
383                 goto invalid;
384
385         vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
386
387         while (XGIbios_mode[i].mode_no != 0) {
388                 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
389                     (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
390                         xgifb_info->mode_idx = i;
391                         j = 1;
392                         break;
393                 }
394                 i++;
395         }
396
397 invalid:
398         if (!j)
399                 pr_info("Invalid VESA mode 0x%x'\n", vesamode);
400 }
401
402 static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
403 {
404         u16 xres, yres;
405         struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
406
407         if (xgifb_info->chip == XG21) {
408                 if (xgifb_info->display2 == XGIFB_DISP_LCD) {
409                         xres = xgifb_info->lvds_data.LVDSHDE;
410                         yres = xgifb_info->lvds_data.LVDSVDE;
411                         if (XGIbios_mode[myindex].xres > xres)
412                                 return -1;
413                         if (XGIbios_mode[myindex].yres > yres)
414                                 return -1;
415                         if ((XGIbios_mode[myindex].xres < xres) &&
416                             (XGIbios_mode[myindex].yres < yres)) {
417                                 if (XGIbios_mode[myindex].bpp > 8)
418                                         return -1;
419                         }
420
421                 }
422                 return myindex;
423
424         }
425
426         /* FIXME: for now, all is valid on XG27 */
427         if (xgifb_info->chip == XG27)
428                 return myindex;
429
430         if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
431                 return -1;
432
433         switch (xgifb_info->display2) {
434         case XGIFB_DISP_LCD:
435                 switch (hw_info->ulCRT2LCDType) {
436                 case LCD_640x480:
437                         xres = 640;
438                         yres = 480;
439                         break;
440                 case LCD_800x600:
441                         xres = 800;
442                         yres = 600;
443                         break;
444                 case LCD_1024x600:
445                         xres = 1024;
446                         yres = 600;
447                         break;
448                 case LCD_1024x768:
449                         xres = 1024;
450                         yres = 768;
451                         break;
452                 case LCD_1152x768:
453                         xres = 1152;
454                         yres = 768;
455                         break;
456                 case LCD_1280x960:
457                         xres = 1280;
458                         yres = 960;
459                         break;
460                 case LCD_1280x768:
461                         xres = 1280;
462                         yres = 768;
463                         break;
464                 case LCD_1280x1024:
465                         xres = 1280;
466                         yres = 1024;
467                         break;
468                 case LCD_1400x1050:
469                         xres = 1400;
470                         yres = 1050;
471                         break;
472                 case LCD_1600x1200:
473                         xres = 1600;
474                         yres = 1200;
475                         break;
476                 default:
477                         xres = 0;
478                         yres = 0;
479                         break;
480                 }
481                 if (XGIbios_mode[myindex].xres > xres)
482                         return -1;
483                 if (XGIbios_mode[myindex].yres > yres)
484                         return -1;
485                 if ((hw_info->ulExternalChip == 0x01) || /* LVDS */
486                     (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */
487                         switch (XGIbios_mode[myindex].xres) {
488                         case 512:
489                                 if (XGIbios_mode[myindex].yres != 512)
490                                         return -1;
491                                 if (hw_info->ulCRT2LCDType == LCD_1024x600)
492                                         return -1;
493                                 break;
494                         case 640:
495                                 if ((XGIbios_mode[myindex].yres != 400)
496                                                 && (XGIbios_mode[myindex].yres
497                                                                 != 480))
498                                         return -1;
499                                 break;
500                         case 800:
501                                 if (XGIbios_mode[myindex].yres != 600)
502                                         return -1;
503                                 break;
504                         case 1024:
505                                 if ((XGIbios_mode[myindex].yres != 600) &&
506                                     (XGIbios_mode[myindex].yres != 768))
507                                         return -1;
508                                 if ((XGIbios_mode[myindex].yres == 600) &&
509                                     (hw_info->ulCRT2LCDType != LCD_1024x600))
510                                         return -1;
511                                 break;
512                         case 1152:
513                                 if ((XGIbios_mode[myindex].yres) != 768)
514                                         return -1;
515                                 if (hw_info->ulCRT2LCDType != LCD_1152x768)
516                                         return -1;
517                                 break;
518                         case 1280:
519                                 if ((XGIbios_mode[myindex].yres != 768) &&
520                                     (XGIbios_mode[myindex].yres != 1024))
521                                         return -1;
522                                 if ((XGIbios_mode[myindex].yres == 768) &&
523                                     (hw_info->ulCRT2LCDType != LCD_1280x768))
524                                         return -1;
525                                 break;
526                         case 1400:
527                                 if (XGIbios_mode[myindex].yres != 1050)
528                                         return -1;
529                                 break;
530                         case 1600:
531                                 if (XGIbios_mode[myindex].yres != 1200)
532                                         return -1;
533                                 break;
534                         default:
535                                 return -1;
536                         }
537                 } else {
538                         switch (XGIbios_mode[myindex].xres) {
539                         case 512:
540                                 if (XGIbios_mode[myindex].yres != 512)
541                                         return -1;
542                                 break;
543                         case 640:
544                                 if ((XGIbios_mode[myindex].yres != 400) &&
545                                     (XGIbios_mode[myindex].yres != 480))
546                                         return -1;
547                                 break;
548                         case 800:
549                                 if (XGIbios_mode[myindex].yres != 600)
550                                         return -1;
551                                 break;
552                         case 1024:
553                                 if (XGIbios_mode[myindex].yres != 768)
554                                         return -1;
555                                 break;
556                         case 1280:
557                                 if ((XGIbios_mode[myindex].yres != 960) &&
558                                     (XGIbios_mode[myindex].yres != 1024))
559                                         return -1;
560                                 if (XGIbios_mode[myindex].yres == 960) {
561                                         if (hw_info->ulCRT2LCDType ==
562                                             LCD_1400x1050)
563                                                 return -1;
564                                 }
565                                 break;
566                         case 1400:
567                                 if (XGIbios_mode[myindex].yres != 1050)
568                                         return -1;
569                                 break;
570                         case 1600:
571                                 if (XGIbios_mode[myindex].yres != 1200)
572                                         return -1;
573                                 break;
574                         default:
575                                 return -1;
576                         }
577                 }
578                 break;
579         case XGIFB_DISP_TV:
580                 switch (XGIbios_mode[myindex].xres) {
581                 case 512:
582                 case 640:
583                 case 800:
584                         break;
585                 case 720:
586                         if (xgifb_info->TV_type == TVMODE_NTSC) {
587                                 if (XGIbios_mode[myindex].yres != 480)
588                                         return -1;
589                         } else if (xgifb_info->TV_type == TVMODE_PAL) {
590                                 if (XGIbios_mode[myindex].yres != 576)
591                                         return -1;
592                         }
593                         /*  TW: LVDS/CHRONTEL does not support 720 */
594                         if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL ||
595                             xgifb_info->hasVB == HASVB_CHRONTEL) {
596                                 return -1;
597                         }
598                         break;
599                 case 1024:
600                         if (xgifb_info->TV_type == TVMODE_NTSC) {
601                                 if (XGIbios_mode[myindex].bpp == 32)
602                                         return -1;
603                         }
604                         break;
605                 default:
606                         return -1;
607                 }
608                 break;
609         case XGIFB_DISP_CRT:
610                 if (XGIbios_mode[myindex].xres > 1280)
611                         return -1;
612                 break;
613         case XGIFB_DISP_NONE:
614                 break;
615         }
616         return myindex;
617
618 }
619
620 static void XGIfb_search_crt2type(const char *name)
621 {
622         int i = 0;
623
624         if (name == NULL)
625                 return;
626
627         while (XGI_crt2type[i].type_no != -1) {
628                 if (!strcmp(name, XGI_crt2type[i].name)) {
629                         XGIfb_crt2type = XGI_crt2type[i].type_no;
630                         XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
631                         break;
632                 }
633                 i++;
634         }
635         if (XGIfb_crt2type < 0)
636                 pr_info("Invalid CRT2 type: %s\n", name);
637 }
638
639 static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
640                                     unsigned int rate)
641 {
642         u16 xres, yres;
643         int i = 0;
644
645         xres = XGIbios_mode[xgifb_info->mode_idx].xres;
646         yres = XGIbios_mode[xgifb_info->mode_idx].yres;
647
648         xgifb_info->rate_idx = 0;
649         while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
650                 if ((XGIfb_vrate[i].xres == xres) &&
651                     (XGIfb_vrate[i].yres == yres)) {
652                         if (XGIfb_vrate[i].refresh == rate) {
653                                 xgifb_info->rate_idx = XGIfb_vrate[i].idx;
654                                 break;
655                         } else if (XGIfb_vrate[i].refresh > rate) {
656                                 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
657                                         pr_debug("XGIfb: Adjusting rate from %d up to %d\n",
658                                                  rate, XGIfb_vrate[i].refresh);
659                                         xgifb_info->rate_idx =
660                                                 XGIfb_vrate[i].idx;
661                                         xgifb_info->refresh_rate =
662                                                 XGIfb_vrate[i].refresh;
663                                 } else if (((rate - XGIfb_vrate[i - 1].refresh)
664                                                 <= 2) && (XGIfb_vrate[i].idx
665                                                 != 1)) {
666                                         pr_debug("XGIfb: Adjusting rate from %d down to %d\n",
667                                                  rate, XGIfb_vrate[i-1].refresh);
668                                         xgifb_info->rate_idx =
669                                                 XGIfb_vrate[i - 1].idx;
670                                         xgifb_info->refresh_rate =
671                                                 XGIfb_vrate[i - 1].refresh;
672                                 }
673                                 break;
674                         } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
675                                 pr_debug("XGIfb: Adjusting rate from %d down to %d\n",
676                                          rate, XGIfb_vrate[i].refresh);
677                                 xgifb_info->rate_idx = XGIfb_vrate[i].idx;
678                                 break;
679                         }
680                 }
681                 i++;
682         }
683         if (xgifb_info->rate_idx > 0) {
684                 return xgifb_info->rate_idx;
685         } else {
686                 pr_info("Unsupported rate %d for %dx%d\n",
687                        rate, xres, yres);
688                 return 0;
689         }
690 }
691
692 static void XGIfb_search_tvstd(const char *name)
693 {
694         int i = 0;
695
696         if (name == NULL)
697                 return;
698
699         while (XGI_tvtype[i].type_no != -1) {
700                 if (!strcmp(name, XGI_tvtype[i].name)) {
701                         XGIfb_tvmode = XGI_tvtype[i].type_no;
702                         break;
703                 }
704                 i++;
705         }
706 }
707
708 /* ----------- FBDev related routines for all series ----------- */
709
710 static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info,
711                              struct fb_var_screeninfo *var)
712 {
713         switch (var->bits_per_pixel) {
714         case 8:
715                 var->red.offset = var->green.offset = var->blue.offset = 0;
716                 var->red.length = var->green.length = var->blue.length = 6;
717                 xgifb_info->video_cmap_len = 256;
718                 break;
719         case 16:
720                 var->red.offset = 11;
721                 var->red.length = 5;
722                 var->green.offset = 5;
723                 var->green.length = 6;
724                 var->blue.offset = 0;
725                 var->blue.length = 5;
726                 var->transp.offset = 0;
727                 var->transp.length = 0;
728                 xgifb_info->video_cmap_len = 16;
729                 break;
730         case 32:
731                 var->red.offset = 16;
732                 var->red.length = 8;
733                 var->green.offset = 8;
734                 var->green.length = 8;
735                 var->blue.offset = 0;
736                 var->blue.length = 8;
737                 var->transp.offset = 24;
738                 var->transp.length = 8;
739                 xgifb_info->video_cmap_len = 16;
740                 break;
741         }
742 }
743
744 /* --------------------- SetMode routines ------------------------- */
745
746 static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
747 {
748         u8 cr30 = 0, cr31 = 0;
749
750         cr31 = xgifb_reg_get(XGICR, 0x31);
751         cr31 &= ~0x60;
752
753         switch (xgifb_info->display2) {
754         case XGIFB_DISP_CRT:
755                 cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
756                 cr31 |= SIS_DRIVER_MODE;
757                 break;
758         case XGIFB_DISP_LCD:
759                 cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
760                 cr31 |= SIS_DRIVER_MODE;
761                 break;
762         case XGIFB_DISP_TV:
763                 if (xgifb_info->TV_type == TVMODE_HIVISION)
764                         cr30 = (SIS_VB_OUTPUT_HIVISION
765                                         | SIS_SIMULTANEOUS_VIEW_ENABLE);
766                 else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
767                         cr30 = (SIS_VB_OUTPUT_SVIDEO
768                                         | SIS_SIMULTANEOUS_VIEW_ENABLE);
769                 else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
770                         cr30 = (SIS_VB_OUTPUT_COMPOSITE
771                                         | SIS_SIMULTANEOUS_VIEW_ENABLE);
772                 else if (xgifb_info->TV_plug == TVPLUG_SCART)
773                         cr30 = (SIS_VB_OUTPUT_SCART
774                                         | SIS_SIMULTANEOUS_VIEW_ENABLE);
775                 cr31 |= SIS_DRIVER_MODE;
776
777                 if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
778                         cr31 |= 0x01;
779                 else
780                         cr31 &= ~0x01;
781                 break;
782         default: /* disable CRT2 */
783                 cr30 = 0x00;
784                 cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
785         }
786
787         xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
788         xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
789         xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33,
790                                                 (xgifb_info->rate_idx & 0x0F));
791 }
792
793 static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
794 {
795         u8 reg;
796         unsigned char doit = 1;
797         /*
798         xgifb_reg_set(XGISR,IND_SIS_PASSWORD,SIS_PASSWORD);
799         xgifb_reg_set(XGICR, 0x13, 0x00);
800         xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
801         *test*
802         */
803         if (xgifb_info->video_bpp == 8) {
804                 /* TW: We can't switch off CRT1 on LVDS/Chrontel
805                  * in 8bpp Modes */
806                 if ((xgifb_info->hasVB == HASVB_LVDS) ||
807                     (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) {
808                         doit = 0;
809                 }
810                 /* TW: We can't switch off CRT1 on 301B-DH
811                  * in 8bpp Modes if using LCD */
812                 if (xgifb_info->display2 == XGIFB_DISP_LCD)
813                         doit = 0;
814         }
815
816         /* TW: We can't switch off CRT1 if bridge is in slave mode */
817         if (xgifb_info->hasVB != HASVB_NONE) {
818                 reg = xgifb_reg_get(XGIPART1, 0x00);
819
820                 if ((reg & 0x50) == 0x10)
821                         doit = 0;
822
823         } else {
824                 XGIfb_crt1off = 0;
825         }
826
827         reg = xgifb_reg_get(XGICR, 0x17);
828         if ((XGIfb_crt1off) && (doit))
829                 reg &= ~0x80;
830         else
831                 reg |= 0x80;
832         xgifb_reg_set(XGICR, 0x17, reg);
833
834         xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04);
835
836         if (xgifb_info->display2 == XGIFB_DISP_TV &&
837             xgifb_info->hasVB == HASVB_301) {
838
839                 reg = xgifb_reg_get(XGIPART4, 0x01);
840
841                 if (reg < 0xB0) { /* Set filter for XGI301 */
842                         int filter_tb;
843
844                         switch (xgifb_info->video_width) {
845                         case 320:
846                                 filter_tb = (xgifb_info->TV_type ==
847                                              TVMODE_NTSC) ? 4 : 12;
848                                 break;
849                         case 640:
850                                 filter_tb = (xgifb_info->TV_type ==
851                                              TVMODE_NTSC) ? 5 : 13;
852                                 break;
853                         case 720:
854                                 filter_tb = (xgifb_info->TV_type ==
855                                              TVMODE_NTSC) ? 6 : 14;
856                                 break;
857                         case 800:
858                                 filter_tb = (xgifb_info->TV_type ==
859                                              TVMODE_NTSC) ? 7 : 15;
860                                 break;
861                         default:
862                                 filter_tb = 0;
863                                 filter = -1;
864                                 break;
865                         }
866                         xgifb_reg_or(XGIPART1,
867                                      SIS_CRT2_WENABLE_315,
868                                      0x01);
869
870                         if (xgifb_info->TV_type == TVMODE_NTSC) {
871
872                                 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
873
874                                 if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
875
876                                         xgifb_reg_and(XGIPART2, 0x30, 0xdf);
877
878                                 } else if (xgifb_info->TV_plug
879                                                 == TVPLUG_COMPOSITE) {
880
881                                         xgifb_reg_or(XGIPART2, 0x30, 0x20);
882
883                                         switch (xgifb_info->video_width) {
884                                         case 640:
885                                                 xgifb_reg_set(XGIPART2,
886                                                               0x35,
887                                                               0xEB);
888                                                 xgifb_reg_set(XGIPART2,
889                                                               0x36,
890                                                               0x04);
891                                                 xgifb_reg_set(XGIPART2,
892                                                               0x37,
893                                                               0x25);
894                                                 xgifb_reg_set(XGIPART2,
895                                                               0x38,
896                                                               0x18);
897                                                 break;
898                                         case 720:
899                                                 xgifb_reg_set(XGIPART2,
900                                                               0x35,
901                                                               0xEE);
902                                                 xgifb_reg_set(XGIPART2,
903                                                               0x36,
904                                                               0x0C);
905                                                 xgifb_reg_set(XGIPART2,
906                                                               0x37,
907                                                               0x22);
908                                                 xgifb_reg_set(XGIPART2,
909                                                               0x38,
910                                                               0x08);
911                                                 break;
912                                         case 800:
913                                                 xgifb_reg_set(XGIPART2,
914                                                               0x35,
915                                                               0xEB);
916                                                 xgifb_reg_set(XGIPART2,
917                                                               0x36,
918                                                               0x15);
919                                                 xgifb_reg_set(XGIPART2,
920                                                               0x37,
921                                                               0x25);
922                                                 xgifb_reg_set(XGIPART2,
923                                                               0x38,
924                                                               0xF6);
925                                                 break;
926                                         }
927                                 }
928
929                         } else if (xgifb_info->TV_type == TVMODE_PAL) {
930
931                                 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
932
933                                 if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
934
935                                         xgifb_reg_and(XGIPART2, 0x30, 0xDF);
936
937                                 } else if (xgifb_info->TV_plug
938                                                 == TVPLUG_COMPOSITE) {
939
940                                         xgifb_reg_or(XGIPART2, 0x30, 0x20);
941
942                                         switch (xgifb_info->video_width) {
943                                         case 640:
944                                                 xgifb_reg_set(XGIPART2,
945                                                               0x35,
946                                                               0xF1);
947                                                 xgifb_reg_set(XGIPART2,
948                                                               0x36,
949                                                               0xF7);
950                                                 xgifb_reg_set(XGIPART2,
951                                                               0x37,
952                                                               0x1F);
953                                                 xgifb_reg_set(XGIPART2,
954                                                               0x38,
955                                                               0x32);
956                                                 break;
957                                         case 720:
958                                                 xgifb_reg_set(XGIPART2,
959                                                               0x35,
960                                                               0xF3);
961                                                 xgifb_reg_set(XGIPART2,
962                                                               0x36,
963                                                               0x00);
964                                                 xgifb_reg_set(XGIPART2,
965                                                               0x37,
966                                                               0x1D);
967                                                 xgifb_reg_set(XGIPART2,
968                                                               0x38,
969                                                               0x20);
970                                                 break;
971                                         case 800:
972                                                 xgifb_reg_set(XGIPART2,
973                                                               0x35,
974                                                               0xFC);
975                                                 xgifb_reg_set(XGIPART2,
976                                                               0x36,
977                                                               0xFB);
978                                                 xgifb_reg_set(XGIPART2,
979                                                               0x37,
980                                                               0x14);
981                                                 xgifb_reg_set(XGIPART2,
982                                                               0x38,
983                                                               0x2A);
984                                                 break;
985                                         }
986                                 }
987                         }
988
989                         if ((filter >= 0) && (filter <= 7)) {
990                                 pr_debug("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
991                                          filter_tb, filter,
992                                          XGI_TV_filter[filter_tb].
993                                                 filter[filter][0],
994                                          XGI_TV_filter[filter_tb].
995                                                 filter[filter][1],
996                                          XGI_TV_filter[filter_tb].
997                                                 filter[filter][2],
998                                          XGI_TV_filter[filter_tb].
999                                                 filter[filter][3]
1000                                 );
1001                                 xgifb_reg_set(
1002                                         XGIPART2,
1003                                         0x35,
1004                                         (XGI_TV_filter[filter_tb].
1005                                                 filter[filter][0]));
1006                                 xgifb_reg_set(
1007                                         XGIPART2,
1008                                         0x36,
1009                                         (XGI_TV_filter[filter_tb].
1010                                                 filter[filter][1]));
1011                                 xgifb_reg_set(
1012                                         XGIPART2,
1013                                         0x37,
1014                                         (XGI_TV_filter[filter_tb].
1015                                                 filter[filter][2]));
1016                                 xgifb_reg_set(
1017                                         XGIPART2,
1018                                         0x38,
1019                                         (XGI_TV_filter[filter_tb].
1020                                                 filter[filter][3]));
1021                         }
1022                 }
1023         }
1024 }
1025
1026 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1027                 struct fb_info *info)
1028 {
1029         struct xgifb_video_info *xgifb_info = info->par;
1030         struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
1031         unsigned int htotal = var->left_margin + var->xres + var->right_margin
1032                         + var->hsync_len;
1033         unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1034                         + var->vsync_len;
1035 #if defined(__powerpc__)
1036         u8 cr_data;
1037 #endif
1038         unsigned int drate = 0, hrate = 0;
1039         int found_mode = 0;
1040         int old_mode;
1041         /* unsigned char reg, reg1; */
1042
1043         info->var.xres_virtual = var->xres_virtual;
1044         info->var.yres_virtual = var->yres_virtual;
1045         info->var.bits_per_pixel = var->bits_per_pixel;
1046
1047         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1048                 vtotal <<= 1;
1049         else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1050                 vtotal <<= 2;
1051         else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1052                 /* vtotal <<= 1; */
1053                 /* var->yres <<= 1; */
1054         }
1055
1056         if (!htotal || !vtotal) {
1057                 pr_debug("XGIfb: Invalid 'var' information\n");
1058                 return -EINVAL;
1059         } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
1060                         var->pixclock, htotal, vtotal);
1061
1062         if (var->pixclock && htotal && vtotal) {
1063                 drate = 1000000000 / var->pixclock;
1064                 hrate = (drate * 1000) / htotal;
1065                 xgifb_info->refresh_rate = (unsigned int) (hrate * 2
1066                                 / vtotal);
1067         } else {
1068                 xgifb_info->refresh_rate = 60;
1069         }
1070
1071         pr_debug("Change mode to %dx%dx%d-%dHz\n",
1072                var->xres,
1073                var->yres,
1074                var->bits_per_pixel,
1075                xgifb_info->refresh_rate);
1076
1077         old_mode = xgifb_info->mode_idx;
1078         xgifb_info->mode_idx = 0;
1079
1080         while ((XGIbios_mode[xgifb_info->mode_idx].mode_no != 0) &&
1081                (XGIbios_mode[xgifb_info->mode_idx].xres <= var->xres)) {
1082                 if ((XGIbios_mode[xgifb_info->mode_idx].xres == var->xres) &&
1083                     (XGIbios_mode[xgifb_info->mode_idx].yres == var->yres) &&
1084                     (XGIbios_mode[xgifb_info->mode_idx].bpp
1085                                                 == var->bits_per_pixel)) {
1086                         found_mode = 1;
1087                         break;
1088                 }
1089                 xgifb_info->mode_idx++;
1090         }
1091
1092         if (found_mode)
1093                 xgifb_info->mode_idx = XGIfb_validate_mode(xgifb_info,
1094                                                         xgifb_info->mode_idx);
1095         else
1096                 xgifb_info->mode_idx = -1;
1097
1098         if (xgifb_info->mode_idx < 0) {
1099                 pr_err("Mode %dx%dx%d not supported\n",
1100                        var->xres, var->yres, var->bits_per_pixel);
1101                 xgifb_info->mode_idx = old_mode;
1102                 return -EINVAL;
1103         }
1104
1105         if (XGIfb_search_refresh_rate(xgifb_info,
1106                                       xgifb_info->refresh_rate) == 0) {
1107                 xgifb_info->rate_idx = 1;
1108                 xgifb_info->refresh_rate = 60;
1109         }
1110
1111         if (isactive) {
1112
1113                 XGIfb_pre_setmode(xgifb_info);
1114                 if (XGISetModeNew(xgifb_info, hw_info,
1115                                   XGIbios_mode[xgifb_info->mode_idx].mode_no)
1116                                         == 0) {
1117                         pr_err("Setting mode[0x%x] failed\n",
1118                                XGIbios_mode[xgifb_info->mode_idx].mode_no);
1119                         return -EINVAL;
1120                 }
1121                 info->fix.line_length = ((info->var.xres_virtual
1122                                 * info->var.bits_per_pixel) >> 6);
1123
1124                 xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1125
1126                 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1127                 xgifb_reg_set(XGISR,
1128                               0x0E,
1129                               (info->fix.line_length & 0xff00) >> 8);
1130
1131                 XGIfb_post_setmode(xgifb_info);
1132
1133                 pr_debug("XGIfb: Set new mode: %dx%dx%d-%d\n",
1134                          XGIbios_mode[xgifb_info->mode_idx].xres,
1135                          XGIbios_mode[xgifb_info->mode_idx].yres,
1136                          XGIbios_mode[xgifb_info->mode_idx].bpp,
1137                          xgifb_info->refresh_rate);
1138
1139                 xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
1140                 xgifb_info->video_vwidth = info->var.xres_virtual;
1141                 xgifb_info->video_width =
1142                         XGIbios_mode[xgifb_info->mode_idx].xres;
1143                 xgifb_info->video_vheight = info->var.yres_virtual;
1144                 xgifb_info->video_height =
1145                         XGIbios_mode[xgifb_info->mode_idx].yres;
1146                 xgifb_info->org_x = xgifb_info->org_y = 0;
1147                 xgifb_info->video_linelength = info->var.xres_virtual
1148                                 * (xgifb_info->video_bpp >> 3);
1149                 switch (xgifb_info->video_bpp) {
1150                 case 8:
1151                         xgifb_info->DstColor = 0x0000;
1152                         xgifb_info->XGI310_AccelDepth = 0x00000000;
1153                         xgifb_info->video_cmap_len = 256;
1154 #if defined(__powerpc__)
1155                         cr_data = xgifb_reg_get(XGICR, 0x4D);
1156                         xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1157 #endif
1158                         break;
1159                 case 16:
1160                         xgifb_info->DstColor = 0x8000;
1161                         xgifb_info->XGI310_AccelDepth = 0x00010000;
1162 #if defined(__powerpc__)
1163                         cr_data = xgifb_reg_get(XGICR, 0x4D);
1164                         xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1165 #endif
1166                         xgifb_info->video_cmap_len = 16;
1167                         break;
1168                 case 32:
1169                         xgifb_info->DstColor = 0xC000;
1170                         xgifb_info->XGI310_AccelDepth = 0x00020000;
1171                         xgifb_info->video_cmap_len = 16;
1172 #if defined(__powerpc__)
1173                         cr_data = xgifb_reg_get(XGICR, 0x4D);
1174                         xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1175 #endif
1176                         break;
1177                 default:
1178                         xgifb_info->video_cmap_len = 16;
1179                         pr_err("Unsupported depth %d",
1180                                xgifb_info->video_bpp);
1181                         break;
1182                 }
1183         }
1184         XGIfb_bpp_to_var(xgifb_info, var); /*update ARGB info*/
1185
1186         dumpVGAReg();
1187         return 0;
1188 }
1189
1190 static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1191 {
1192         struct xgifb_video_info *xgifb_info = info->par;
1193         unsigned int base;
1194
1195         base = var->yoffset * info->var.xres_virtual + var->xoffset;
1196
1197         /* calculate base bpp dep. */
1198         switch (info->var.bits_per_pixel) {
1199         case 16:
1200                 base >>= 1;
1201                 break;
1202         case 32:
1203                 break;
1204         case 8:
1205         default:
1206                 base >>= 2;
1207                 break;
1208         }
1209
1210         xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1211
1212         xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1213         xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1214         xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1215         xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1216         xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1217
1218         if (xgifb_info->display2 != XGIFB_DISP_NONE) {
1219                 xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01);
1220                 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1221                 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1222                 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1223                 xgifb_reg_and_or(XGIPART1,
1224                                  0x02,
1225                                  0x7F,
1226                                  ((base >> 24) & 0x01) << 7);
1227         }
1228         return 0;
1229 }
1230
1231 static int XGIfb_open(struct fb_info *info, int user)
1232 {
1233         return 0;
1234 }
1235
1236 static int XGIfb_release(struct fb_info *info, int user)
1237 {
1238         return 0;
1239 }
1240
1241 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1242 {
1243         int rc = 16;
1244
1245         switch (var->bits_per_pixel) {
1246         case 8:
1247                 rc = 256;
1248                 break;
1249         case 16:
1250                 rc = 16;
1251                 break;
1252         case 32:
1253                 rc = 16;
1254                 break;
1255         }
1256         return rc;
1257 }
1258
1259 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1260                 unsigned blue, unsigned transp, struct fb_info *info)
1261 {
1262         struct xgifb_video_info *xgifb_info = info->par;
1263
1264         if (regno >= XGIfb_get_cmap_len(&info->var))
1265                 return 1;
1266
1267         switch (info->var.bits_per_pixel) {
1268         case 8:
1269                 outb(regno, XGIDACA);
1270                 outb((red >> 10), XGIDACD);
1271                 outb((green >> 10), XGIDACD);
1272                 outb((blue >> 10), XGIDACD);
1273                 if (xgifb_info->display2 != XGIFB_DISP_NONE) {
1274                         outb(regno, XGIDAC2A);
1275                         outb((red >> 8), XGIDAC2D);
1276                         outb((green >> 8), XGIDAC2D);
1277                         outb((blue >> 8), XGIDAC2D);
1278                 }
1279                 break;
1280         case 16:
1281                 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1282                                 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1283                                 >> 11);
1284                 break;
1285         case 32:
1286                 red >>= 8;
1287                 green >>= 8;
1288                 blue >>= 8;
1289                 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1290                                 << 8) | (blue);
1291                 break;
1292         }
1293         return 0;
1294 }
1295
1296 /* ----------- FBDev related routines for all series ---------- */
1297
1298 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1299                 struct fb_info *info)
1300 {
1301         struct xgifb_video_info *xgifb_info = info->par;
1302
1303         memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1304
1305         strncpy(fix->id, "XGI", sizeof(fix->id) - 1);
1306
1307         /* if register_framebuffer has been called, we must lock */
1308         if (atomic_read(&info->count))
1309                 mutex_lock(&info->mm_lock);
1310
1311         fix->smem_start = xgifb_info->video_base;
1312         fix->smem_len = xgifb_info->video_size;
1313
1314         /* if register_framebuffer has been called, we can unlock */
1315         if (atomic_read(&info->count))
1316                 mutex_unlock(&info->mm_lock);
1317
1318         fix->type = FB_TYPE_PACKED_PIXELS;
1319         fix->type_aux = 0;
1320         if (xgifb_info->video_bpp == 8)
1321                 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1322         else
1323                 fix->visual = FB_VISUAL_DIRECTCOLOR;
1324         fix->xpanstep = 0;
1325         if (XGIfb_ypan)
1326                 fix->ypanstep = 1;
1327         fix->ywrapstep = 0;
1328         fix->line_length = xgifb_info->video_linelength;
1329         fix->mmio_start = xgifb_info->mmio_base;
1330         fix->mmio_len = xgifb_info->mmio_size;
1331         fix->accel = FB_ACCEL_SIS_XABRE;
1332
1333         return 0;
1334 }
1335
1336 static int XGIfb_set_par(struct fb_info *info)
1337 {
1338         int err;
1339
1340         err = XGIfb_do_set_var(&info->var, 1, info);
1341         if (err)
1342                 return err;
1343         XGIfb_get_fix(&info->fix, -1, info);
1344         return 0;
1345 }
1346
1347 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1348 {
1349         struct xgifb_video_info *xgifb_info = info->par;
1350         unsigned int htotal = var->left_margin + var->xres + var->right_margin
1351                         + var->hsync_len;
1352         unsigned int vtotal = 0;
1353         unsigned int drate = 0, hrate = 0;
1354         int found_mode = 0;
1355         int refresh_rate, search_idx;
1356
1357         if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1358                 vtotal = var->upper_margin + var->yres + var->lower_margin
1359                                 + var->vsync_len;
1360                 vtotal <<= 1;
1361         } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1362                 vtotal = var->upper_margin + var->yres + var->lower_margin
1363                                 + var->vsync_len;
1364                 vtotal <<= 2;
1365         } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1366                 vtotal = var->upper_margin + (var->yres / 2)
1367                                 + var->lower_margin + var->vsync_len;
1368         } else
1369                 vtotal = var->upper_margin + var->yres + var->lower_margin
1370                                 + var->vsync_len;
1371
1372         if (!(htotal) || !(vtotal)) {
1373                 pr_debug("XGIfb: no valid timing data\n");
1374                 return -EINVAL;
1375         }
1376
1377         if (var->pixclock && htotal && vtotal) {
1378                 drate = 1000000000 / var->pixclock;
1379                 hrate = (drate * 1000) / htotal;
1380                 xgifb_info->refresh_rate =
1381                         (unsigned int) (hrate * 2 / vtotal);
1382                 pr_debug(
1383                         "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1384                         "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1385                         __func__, var->pixclock, htotal, vtotal,
1386                         __func__, drate, hrate, xgifb_info->refresh_rate);
1387         } else {
1388                 xgifb_info->refresh_rate = 60;
1389         }
1390
1391         /*
1392         if ((var->pixclock) && (htotal)) {
1393                 drate = 1E12 / var->pixclock;
1394                 hrate = drate / htotal;
1395                 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1396         } else {
1397                 refresh_rate = 60;
1398         }
1399         */
1400         /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1401         if ((var->xres == 1024) && (var->yres == 600))
1402                 refresh_rate = 60;
1403
1404         search_idx = 0;
1405         while ((XGIbios_mode[search_idx].mode_no != 0) &&
1406                 (XGIbios_mode[search_idx].xres <= var->xres)) {
1407                 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1408                         (XGIbios_mode[search_idx].yres == var->yres) &&
1409                         (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1410                         if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) {
1411                                 found_mode = 1;
1412                                 break;
1413                         }
1414                 }
1415                 search_idx++;
1416         }
1417
1418         if (!found_mode) {
1419
1420                 pr_err("%dx%dx%d is no valid mode\n",
1421                         var->xres, var->yres, var->bits_per_pixel);
1422                 search_idx = 0;
1423                 while (XGIbios_mode[search_idx].mode_no != 0) {
1424                         if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1425                             (var->yres <= XGIbios_mode[search_idx].yres) &&
1426                             (var->bits_per_pixel ==
1427                              XGIbios_mode[search_idx].bpp)) {
1428                                 if (XGIfb_validate_mode(xgifb_info,
1429                                                         search_idx) > 0) {
1430                                         found_mode = 1;
1431                                         break;
1432                                 }
1433                         }
1434                         search_idx++;
1435                 }
1436                 if (found_mode) {
1437                         var->xres = XGIbios_mode[search_idx].xres;
1438                         var->yres = XGIbios_mode[search_idx].yres;
1439                         pr_debug("Adapted to mode %dx%dx%d\n",
1440                                 var->xres, var->yres, var->bits_per_pixel);
1441
1442                 } else {
1443                         pr_err("Failed to find similar mode to %dx%dx%d\n",
1444                                 var->xres, var->yres, var->bits_per_pixel);
1445                         return -EINVAL;
1446                 }
1447         }
1448
1449         /* TW: TODO: Check the refresh rate */
1450
1451         /* Adapt RGB settings */
1452         XGIfb_bpp_to_var(xgifb_info, var);
1453
1454         /* Sanity check for offsets */
1455         if (var->xoffset < 0)
1456                 var->xoffset = 0;
1457         if (var->yoffset < 0)
1458                 var->yoffset = 0;
1459
1460         if (!XGIfb_ypan) {
1461                 if (var->xres != var->xres_virtual)
1462                         var->xres_virtual = var->xres;
1463                 if (var->yres != var->yres_virtual)
1464                         var->yres_virtual = var->yres;
1465         } /* else { */
1466                 /* TW: Now patch yres_virtual if we use panning */
1467                 /* May I do this? */
1468                 /* var->yres_virtual = xgifb_info->heapstart /
1469                         (var->xres * (var->bits_per_pixel >> 3)); */
1470                 /* if (var->yres_virtual <= var->yres) { */
1471                 /* TW: Paranoia check */
1472                 /* var->yres_virtual = var->yres; */
1473                 /* } */
1474         /* } */
1475
1476         /* Truncate offsets to maximum if too high */
1477         if (var->xoffset > var->xres_virtual - var->xres)
1478                 var->xoffset = var->xres_virtual - var->xres - 1;
1479
1480         if (var->yoffset > var->yres_virtual - var->yres)
1481                 var->yoffset = var->yres_virtual - var->yres - 1;
1482
1483         /* Set everything else to 0 */
1484         var->red.msb_right =
1485         var->green.msb_right =
1486         var->blue.msb_right =
1487         var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1488
1489         return 0;
1490 }
1491
1492 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1493                 struct fb_info *info)
1494 {
1495         int err;
1496
1497         if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1498                 return -EINVAL;
1499         if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1500                 return -EINVAL;
1501
1502         if (var->vmode & FB_VMODE_YWRAP) {
1503                 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1504                                 || var->xoffset)
1505                         return -EINVAL;
1506         } else {
1507                 if (var->xoffset + info->var.xres > info->var.xres_virtual
1508                                 || var->yoffset + info->var.yres
1509                                                 > info->var.yres_virtual)
1510                         return -EINVAL;
1511         }
1512         err = XGIfb_pan_var(var, info);
1513         if (err < 0)
1514                 return err;
1515
1516         info->var.xoffset = var->xoffset;
1517         info->var.yoffset = var->yoffset;
1518         if (var->vmode & FB_VMODE_YWRAP)
1519                 info->var.vmode |= FB_VMODE_YWRAP;
1520         else
1521                 info->var.vmode &= ~FB_VMODE_YWRAP;
1522
1523         return 0;
1524 }
1525
1526 static int XGIfb_blank(int blank, struct fb_info *info)
1527 {
1528         struct xgifb_video_info *xgifb_info = info->par;
1529         u8 reg;
1530
1531         reg = xgifb_reg_get(XGICR, 0x17);
1532
1533         if (blank > 0)
1534                 reg &= 0x7f;
1535         else
1536                 reg |= 0x80;
1537
1538         xgifb_reg_set(XGICR, 0x17, reg);
1539         xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1540         xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1541         return 0;
1542 }
1543
1544 static struct fb_ops XGIfb_ops = {
1545         .owner = THIS_MODULE,
1546         .fb_open = XGIfb_open,
1547         .fb_release = XGIfb_release,
1548         .fb_check_var = XGIfb_check_var,
1549         .fb_set_par = XGIfb_set_par,
1550         .fb_setcolreg = XGIfb_setcolreg,
1551         .fb_pan_display = XGIfb_pan_display,
1552         .fb_blank = XGIfb_blank,
1553         .fb_fillrect = cfb_fillrect,
1554         .fb_copyarea = cfb_copyarea,
1555         .fb_imageblit = cfb_imageblit,
1556         /* .fb_mmap = XGIfb_mmap, */
1557 };
1558
1559 /* ---------------- Chip generation dependent routines ---------------- */
1560
1561 /* for XGI 315/550/650/740/330 */
1562
1563 static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
1564 {
1565
1566         u8 ChannelNum, tmp;
1567         u8 reg = 0;
1568
1569         /* xorg driver sets 32MB * 1 channel */
1570         if (xgifb_info->chip == XG27)
1571                 xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
1572
1573         reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
1574         switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1575         case XGI_DRAM_SIZE_1MB:
1576                 xgifb_info->video_size = 0x100000;
1577                 break;
1578         case XGI_DRAM_SIZE_2MB:
1579                 xgifb_info->video_size = 0x200000;
1580                 break;
1581         case XGI_DRAM_SIZE_4MB:
1582                 xgifb_info->video_size = 0x400000;
1583                 break;
1584         case XGI_DRAM_SIZE_8MB:
1585                 xgifb_info->video_size = 0x800000;
1586                 break;
1587         case XGI_DRAM_SIZE_16MB:
1588                 xgifb_info->video_size = 0x1000000;
1589                 break;
1590         case XGI_DRAM_SIZE_32MB:
1591                 xgifb_info->video_size = 0x2000000;
1592                 break;
1593         case XGI_DRAM_SIZE_64MB:
1594                 xgifb_info->video_size = 0x4000000;
1595                 break;
1596         case XGI_DRAM_SIZE_128MB:
1597                 xgifb_info->video_size = 0x8000000;
1598                 break;
1599         case XGI_DRAM_SIZE_256MB:
1600                 xgifb_info->video_size = 0x10000000;
1601                 break;
1602         default:
1603                 return -1;
1604         }
1605
1606         tmp = (reg & 0x0c) >> 2;
1607         switch (xgifb_info->chip) {
1608         case XG20:
1609         case XG21:
1610         case XG27:
1611                 ChannelNum = 1;
1612                 break;
1613
1614         case XG42:
1615                 if (reg & 0x04)
1616                         ChannelNum = 2;
1617                 else
1618                         ChannelNum = 1;
1619                 break;
1620
1621         case XG40:
1622         default:
1623                 if (tmp == 2)
1624                         ChannelNum = 2;
1625                 else if (tmp == 3)
1626                         ChannelNum = 3;
1627                 else
1628                         ChannelNum = 1;
1629                 break;
1630         }
1631
1632         xgifb_info->video_size = xgifb_info->video_size * ChannelNum;
1633         /* PLiad fixed for benchmarking and fb set */
1634         /* xgifb_info->video_size = 0x200000; */ /* 1024x768x16 */
1635         /* xgifb_info->video_size = 0x1000000; */ /* benchmark */
1636
1637         pr_info("SR14=%x DramSzie %x ChannelNum %x\n",
1638                reg,
1639                xgifb_info->video_size, ChannelNum);
1640         return 0;
1641
1642 }
1643
1644 static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
1645 {
1646         u8 cr32, temp = 0;
1647
1648         xgifb_info->TV_plug = xgifb_info->TV_type = 0;
1649
1650         switch (xgifb_info->hasVB) {
1651         case HASVB_LVDS_CHRONTEL:
1652         case HASVB_CHRONTEL:
1653                 break;
1654         case HASVB_301:
1655         case HASVB_302:
1656                 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1657                 break;
1658         }
1659
1660         cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1661
1662         if ((cr32 & SIS_CRT1) && !XGIfb_crt1off)
1663                 XGIfb_crt1off = 0;
1664         else {
1665                 if (cr32 & 0x5F)
1666                         XGIfb_crt1off = 1;
1667                 else
1668                         XGIfb_crt1off = 0;
1669         }
1670
1671         if (!xgifb_info->display2_force) {
1672                 if (cr32 & SIS_VB_TV)
1673                         xgifb_info->display2 = XGIFB_DISP_TV;
1674                 else if (cr32 & SIS_VB_LCD)
1675                         xgifb_info->display2 = XGIFB_DISP_LCD;
1676                 else if (cr32 & SIS_VB_CRT2)
1677                         xgifb_info->display2 = XGIFB_DISP_CRT;
1678                 else
1679                         xgifb_info->display2 = XGIFB_DISP_NONE;
1680         }
1681
1682         if (XGIfb_tvplug != -1)
1683                 /* PR/TW: Override with option */
1684                 xgifb_info->TV_plug = XGIfb_tvplug;
1685         else if (cr32 & SIS_VB_HIVISION) {
1686                 xgifb_info->TV_type = TVMODE_HIVISION;
1687                 xgifb_info->TV_plug = TVPLUG_SVIDEO;
1688         } else if (cr32 & SIS_VB_SVIDEO)
1689                 xgifb_info->TV_plug = TVPLUG_SVIDEO;
1690         else if (cr32 & SIS_VB_COMPOSITE)
1691                 xgifb_info->TV_plug = TVPLUG_COMPOSITE;
1692         else if (cr32 & SIS_VB_SCART)
1693                 xgifb_info->TV_plug = TVPLUG_SCART;
1694
1695         if (xgifb_info->TV_type == 0) {
1696                 temp = xgifb_reg_get(XGICR, 0x38);
1697                 if (temp & 0x10)
1698                         xgifb_info->TV_type = TVMODE_PAL;
1699                 else
1700                         xgifb_info->TV_type = TVMODE_NTSC;
1701         }
1702
1703         /* TW: Copy forceCRT1 option to CRT1off if option is given */
1704         if (XGIfb_forcecrt1 != -1) {
1705                 if (XGIfb_forcecrt1)
1706                         XGIfb_crt1off = 0;
1707                 else
1708                         XGIfb_crt1off = 1;
1709         }
1710 }
1711
1712 static int XGIfb_has_VB(struct xgifb_video_info *xgifb_info)
1713 {
1714         u8 vb_chipid;
1715
1716         vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1717         switch (vb_chipid) {
1718         case 0x01:
1719                 xgifb_info->hasVB = HASVB_301;
1720                 break;
1721         case 0x02:
1722                 xgifb_info->hasVB = HASVB_302;
1723                 break;
1724         default:
1725                 xgifb_info->hasVB = HASVB_NONE;
1726                 return 0;
1727         }
1728         return 1;
1729 }
1730
1731 static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
1732 {
1733         u8 reg;
1734
1735         if (!XGIfb_has_VB(xgifb_info)) {
1736                 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1737                 switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
1738                 case SIS_EXTERNAL_CHIP_LVDS:
1739                         xgifb_info->hasVB = HASVB_LVDS;
1740                         break;
1741                 case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
1742                         xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
1743                         break;
1744                 default:
1745                         break;
1746                 }
1747         }
1748 }
1749
1750 static int __init xgifb_optval(char *fullopt, int validx)
1751 {
1752         unsigned long lres;
1753
1754         if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) {
1755                 pr_err("xgifb: invalid value for option: %s\n", fullopt);
1756                 return 0;
1757         }
1758         return lres;
1759 }
1760
1761 static int __init XGIfb_setup(char *options)
1762 {
1763         char *this_opt;
1764
1765         if (!options || !*options)
1766                 return 0;
1767
1768         pr_info("xgifb: options: %s\n", options);
1769
1770         while ((this_opt = strsep(&options, ",")) != NULL) {
1771
1772                 if (!*this_opt)
1773                         continue;
1774
1775                 if (!strncmp(this_opt, "mode:", 5)) {
1776                         mode = this_opt + 5;
1777                 } else if (!strncmp(this_opt, "vesa:", 5)) {
1778                         vesa = xgifb_optval(this_opt, 5);
1779                 } else if (!strncmp(this_opt, "vrate:", 6)) {
1780                         refresh_rate = xgifb_optval(this_opt, 6);
1781                 } else if (!strncmp(this_opt, "rate:", 5)) {
1782                         refresh_rate = xgifb_optval(this_opt, 5);
1783                 } else if (!strncmp(this_opt, "crt1off", 7)) {
1784                         XGIfb_crt1off = 1;
1785                 } else if (!strncmp(this_opt, "filter:", 7)) {
1786                         filter = xgifb_optval(this_opt, 7);
1787                 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1788                         XGIfb_search_crt2type(this_opt + 14);
1789                 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1790                         XGIfb_forcecrt1 = xgifb_optval(this_opt, 10);
1791                 } else if (!strncmp(this_opt, "tvmode:", 7)) {
1792                         XGIfb_search_tvstd(this_opt + 7);
1793                 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1794                         XGIfb_search_tvstd(this_opt + 7);
1795                 } else if (!strncmp(this_opt, "dstn", 4)) {
1796                         enable_dstn = 1;
1797                         /* TW: DSTN overrules forcecrt2type */
1798                         XGIfb_crt2type = XGIFB_DISP_LCD;
1799                 } else if (!strncmp(this_opt, "noypan", 6)) {
1800                         XGIfb_ypan = 0;
1801                 } else {
1802                         mode = this_opt;
1803                 }
1804         }
1805         return 0;
1806 }
1807
1808 static int __devinit xgifb_probe(struct pci_dev *pdev,
1809                 const struct pci_device_id *ent)
1810 {
1811         u8 reg, reg1;
1812         u8 CR48, CR38;
1813         int ret;
1814         struct fb_info *fb_info;
1815         struct xgifb_video_info *xgifb_info;
1816         struct xgi_hw_device_info *hw_info;
1817
1818         fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev);
1819         if (!fb_info)
1820                 return -ENOMEM;
1821
1822         xgifb_info = fb_info->par;
1823         hw_info = &xgifb_info->hw_info;
1824         xgifb_info->fb_info = fb_info;
1825         xgifb_info->chip_id = pdev->device;
1826         pci_read_config_byte(pdev,
1827                              PCI_REVISION_ID,
1828                              &xgifb_info->revision_id);
1829         hw_info->jChipRevision = xgifb_info->revision_id;
1830
1831         xgifb_info->pcibus = pdev->bus->number;
1832         xgifb_info->pcislot = PCI_SLOT(pdev->devfn);
1833         xgifb_info->pcifunc = PCI_FUNC(pdev->devfn);
1834         xgifb_info->subsysvendor = pdev->subsystem_vendor;
1835         xgifb_info->subsysdevice = pdev->subsystem_device;
1836
1837         xgifb_info->video_base = pci_resource_start(pdev, 0);
1838         xgifb_info->mmio_base = pci_resource_start(pdev, 1);
1839         xgifb_info->mmio_size = pci_resource_len(pdev, 1);
1840         xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
1841         dev_info(&pdev->dev, "Relocate IO address: %Lx [%08lx]\n",
1842                  (u64) pci_resource_start(pdev, 2),
1843                  xgifb_info->vga_base);
1844
1845         if (pci_enable_device(pdev)) {
1846                 ret = -EIO;
1847                 goto error;
1848         }
1849
1850         if (XGIfb_crt2type != -1) {
1851                 xgifb_info->display2 = XGIfb_crt2type;
1852                 xgifb_info->display2_force = true;
1853         }
1854
1855         XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base);
1856
1857         xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
1858         reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD);
1859
1860         if (reg1 != 0xa1) { /*I/O error */
1861                 dev_err(&pdev->dev, "I/O error!!!");
1862                 ret = -EIO;
1863                 goto error_disable;
1864         }
1865
1866         switch (xgifb_info->chip_id) {
1867         case PCI_DEVICE_ID_XGI_20:
1868                 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
1869                 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
1870                 if (CR48&GPIOG_READ)
1871                         xgifb_info->chip = XG21;
1872                 else
1873                         xgifb_info->chip = XG20;
1874                 break;
1875         case PCI_DEVICE_ID_XGI_40:
1876                 xgifb_info->chip = XG40;
1877                 break;
1878         case PCI_DEVICE_ID_XGI_42:
1879                 xgifb_info->chip = XG42;
1880                 break;
1881         case PCI_DEVICE_ID_XGI_27:
1882                 xgifb_info->chip = XG27;
1883                 break;
1884         default:
1885                 ret = -ENODEV;
1886                 goto error_disable;
1887         }
1888
1889         dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip);
1890         hw_info->jChipType = xgifb_info->chip;
1891
1892         if (XGIfb_get_dram_size(xgifb_info)) {
1893                 dev_err(&pdev->dev,
1894                         "Fatal error: Unable to determine RAM size.\n");
1895                 ret = -ENODEV;
1896                 goto error_disable;
1897         }
1898
1899         /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
1900         xgifb_reg_or(XGISR,
1901                      IND_SIS_PCI_ADDRESS_SET,
1902                      (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
1903         /* Enable 2D accelerator engine */
1904         xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
1905
1906         hw_info->ulVideoMemorySize = xgifb_info->video_size;
1907
1908         if (!request_mem_region(xgifb_info->video_base,
1909                                 xgifb_info->video_size,
1910                                 "XGIfb FB")) {
1911                 dev_err(&pdev->dev, "unable request memory size %x\n",
1912                        xgifb_info->video_size);
1913                 dev_err(&pdev->dev,
1914                         "Fatal error: Unable to reserve frame buffer memory. "
1915                         "Is there another framebuffer driver active?\n");
1916                 ret = -ENODEV;
1917                 goto error_disable;
1918         }
1919
1920         if (!request_mem_region(xgifb_info->mmio_base,
1921                                 xgifb_info->mmio_size,
1922                                 "XGIfb MMIO")) {
1923                 dev_err(&pdev->dev,
1924                         "Fatal error: Unable to reserve MMIO region\n");
1925                 ret = -ENODEV;
1926                 goto error_0;
1927         }
1928
1929         xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress =
1930         ioremap(xgifb_info->video_base, xgifb_info->video_size);
1931         xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
1932                                             xgifb_info->mmio_size);
1933
1934         dev_info(&pdev->dev,
1935                  "Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n",
1936                  (u64) xgifb_info->video_base,
1937                  xgifb_info->video_vbase,
1938                  xgifb_info->video_size / 1024);
1939
1940         dev_info(&pdev->dev,
1941                  "MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n",
1942                  (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase,
1943                  xgifb_info->mmio_size / 1024);
1944
1945         pci_set_drvdata(pdev, xgifb_info);
1946         if (!XGIInitNew(pdev))
1947                 dev_err(&pdev->dev, "XGIInitNew() failed!\n");
1948
1949         xgifb_info->mtrr = (unsigned int) 0;
1950
1951         xgifb_info->hasVB = HASVB_NONE;
1952         if ((xgifb_info->chip == XG20) ||
1953             (xgifb_info->chip == XG27)) {
1954                 xgifb_info->hasVB = HASVB_NONE;
1955         } else if (xgifb_info->chip == XG21) {
1956                 CR38 = xgifb_reg_get(XGICR, 0x38);
1957                 if ((CR38&0xE0) == 0xC0)
1958                         xgifb_info->display2 = XGIFB_DISP_LCD;
1959                 else if ((CR38&0xE0) == 0x60)
1960                         xgifb_info->hasVB = HASVB_CHRONTEL;
1961                 else
1962                         xgifb_info->hasVB = HASVB_NONE;
1963         } else {
1964                 XGIfb_get_VB_type(xgifb_info);
1965         }
1966
1967         hw_info->ujVBChipID = VB_CHIP_UNKNOWN;
1968
1969         hw_info->ulExternalChip = 0;
1970
1971         switch (xgifb_info->hasVB) {
1972         case HASVB_301:
1973                 reg = xgifb_reg_get(XGIPART4, 0x01);
1974                 if (reg >= 0xE0) {
1975                         hw_info->ujVBChipID = VB_CHIP_302LV;
1976                         dev_info(&pdev->dev,
1977                                  "XGI302LV bridge detected (revision 0x%02x)\n",
1978                                  reg);
1979                 } else if (reg >= 0xD0) {
1980                         hw_info->ujVBChipID = VB_CHIP_301LV;
1981                         dev_info(&pdev->dev,
1982                                  "XGI301LV bridge detected (revision 0x%02x)\n",
1983                                  reg);
1984                 }
1985                 /* else if (reg >= 0xB0) {
1986                         hw_info->ujVBChipID = VB_CHIP_301B;
1987                         reg1 = xgifb_reg_get(XGIPART4, 0x23);
1988                         pr_debug("XGIfb: XGI301B bridge detected\n");
1989                 } */
1990                 else {
1991                         hw_info->ujVBChipID = VB_CHIP_301;
1992                         dev_info(&pdev->dev, "XGI301 bridge detected\n");
1993                 }
1994                 break;
1995         case HASVB_302:
1996                 reg = xgifb_reg_get(XGIPART4, 0x01);
1997                 if (reg >= 0xE0) {
1998                         hw_info->ujVBChipID = VB_CHIP_302LV;
1999                         dev_info(&pdev->dev,
2000                                  "XGI302LV bridge detected (revision 0x%02x)\n",
2001                                  reg);
2002                 } else if (reg >= 0xD0) {
2003                         hw_info->ujVBChipID = VB_CHIP_301LV;
2004                         dev_info(&pdev->dev,
2005                                  "XGI302LV bridge detected (revision 0x%02x)\n",
2006                                  reg);
2007                 } else if (reg >= 0xB0) {
2008                         reg1 = xgifb_reg_get(XGIPART4, 0x23);
2009
2010                         hw_info->ujVBChipID = VB_CHIP_302B;
2011
2012                 } else {
2013                         hw_info->ujVBChipID = VB_CHIP_302;
2014                         dev_info(&pdev->dev, "XGI302 bridge detected\n");
2015                 }
2016                 break;
2017         case HASVB_LVDS:
2018                 hw_info->ulExternalChip = 0x1;
2019                 dev_info(&pdev->dev, "LVDS transmitter detected\n");
2020                 break;
2021         case HASVB_TRUMPION:
2022                 hw_info->ulExternalChip = 0x2;
2023                 dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n");
2024                 break;
2025         case HASVB_CHRONTEL:
2026                 hw_info->ulExternalChip = 0x4;
2027                 dev_info(&pdev->dev, "Chrontel TV encoder detected\n");
2028                 break;
2029         case HASVB_LVDS_CHRONTEL:
2030                 hw_info->ulExternalChip = 0x5;
2031                 dev_info(&pdev->dev,
2032                          "LVDS transmitter and Chrontel TV encoder detected\n");
2033                 break;
2034         default:
2035                 dev_info(&pdev->dev, "No or unknown bridge type detected\n");
2036                 break;
2037         }
2038
2039         if (xgifb_info->hasVB != HASVB_NONE)
2040                 XGIfb_detect_VB(xgifb_info);
2041         else if (xgifb_info->chip != XG21)
2042                 xgifb_info->display2 = XGIFB_DISP_NONE;
2043
2044         if (xgifb_info->display2 == XGIFB_DISP_LCD) {
2045                 if (!enable_dstn) {
2046                         reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2047                         reg &= 0x0f;
2048                         hw_info->ulCRT2LCDType = XGI310paneltype[reg];
2049                 }
2050         }
2051
2052         if ((hw_info->ujVBChipID == VB_CHIP_302B) ||
2053                         (hw_info->ujVBChipID == VB_CHIP_301LV) ||
2054                         (hw_info->ujVBChipID == VB_CHIP_302LV)) {
2055                 int tmp;
2056                 tmp = xgifb_reg_get(XGICR, 0x34);
2057                 if (tmp <= 0x13) {
2058                         /* Currently on LCDA?
2059                          *(Some BIOSes leave CR38) */
2060                         tmp = xgifb_reg_get(XGICR, 0x38);
2061                         if ((tmp & 0x03) == 0x03) {
2062                                 /* XGI_Pr.XGI_UseLCDA = 1; */
2063                         } else {
2064                                 /* Currently on LCDA?
2065                                  *(Some newer BIOSes set D0 in CR35) */
2066                                 tmp = xgifb_reg_get(XGICR, 0x35);
2067                                 if (tmp & 0x01) {
2068                                         /* XGI_Pr.XGI_UseLCDA = 1; */
2069                                 } else {
2070                                         tmp = xgifb_reg_get(XGICR,
2071                                                             0x30);
2072                                         if (tmp & 0x20) {
2073                                                 tmp = xgifb_reg_get(
2074                                                         XGIPART1, 0x13);
2075                                         }
2076                                 }
2077                         }
2078                 }
2079
2080         }
2081
2082         xgifb_info->mode_idx = -1;
2083
2084         if (mode)
2085                 XGIfb_search_mode(xgifb_info, mode);
2086         else if (vesa != -1)
2087                 XGIfb_search_vesamode(xgifb_info, vesa);
2088
2089         if (xgifb_info->mode_idx >= 0)
2090                 xgifb_info->mode_idx =
2091                         XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx);
2092
2093         if (xgifb_info->mode_idx < 0) {
2094                 if (xgifb_info->display2 == XGIFB_DISP_LCD &&
2095                     xgifb_info->chip == XG21)
2096                         xgifb_info->mode_idx =
2097                                 XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info);
2098                 else
2099                         xgifb_info->mode_idx = DEFAULT_MODE;
2100         }
2101
2102         if (xgifb_info->mode_idx < 0) {
2103                 dev_err(&pdev->dev, "no supported video mode found\n");
2104                 goto error_1;
2105         }
2106
2107         /* yilin set default refresh rate */
2108         xgifb_info->refresh_rate = refresh_rate;
2109         if (xgifb_info->refresh_rate == 0)
2110                 xgifb_info->refresh_rate = 60;
2111         if (XGIfb_search_refresh_rate(xgifb_info,
2112                         xgifb_info->refresh_rate) == 0) {
2113                 xgifb_info->rate_idx = 1;
2114                 xgifb_info->refresh_rate = 60;
2115         }
2116
2117         xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
2118         xgifb_info->video_vwidth =
2119                 xgifb_info->video_width =
2120                         XGIbios_mode[xgifb_info->mode_idx].xres;
2121         xgifb_info->video_vheight =
2122                 xgifb_info->video_height =
2123                         XGIbios_mode[xgifb_info->mode_idx].yres;
2124         xgifb_info->org_x = xgifb_info->org_y = 0;
2125         xgifb_info->video_linelength =
2126                 xgifb_info->video_width *
2127                 (xgifb_info->video_bpp >> 3);
2128         switch (xgifb_info->video_bpp) {
2129         case 8:
2130                 xgifb_info->DstColor = 0x0000;
2131                 xgifb_info->XGI310_AccelDepth = 0x00000000;
2132                 xgifb_info->video_cmap_len = 256;
2133                 break;
2134         case 16:
2135                 xgifb_info->DstColor = 0x8000;
2136                 xgifb_info->XGI310_AccelDepth = 0x00010000;
2137                 xgifb_info->video_cmap_len = 16;
2138                 break;
2139         case 32:
2140                 xgifb_info->DstColor = 0xC000;
2141                 xgifb_info->XGI310_AccelDepth = 0x00020000;
2142                 xgifb_info->video_cmap_len = 16;
2143                 break;
2144         default:
2145                 xgifb_info->video_cmap_len = 16;
2146                 pr_info("Unsupported depth %d\n",
2147                        xgifb_info->video_bpp);
2148                 break;
2149         }
2150
2151         pr_info("Default mode is %dx%dx%d (%dHz)\n",
2152                xgifb_info->video_width,
2153                xgifb_info->video_height,
2154                xgifb_info->video_bpp,
2155                xgifb_info->refresh_rate);
2156
2157         fb_info->var.red.length         = 8;
2158         fb_info->var.green.length       = 8;
2159         fb_info->var.blue.length        = 8;
2160         fb_info->var.activate           = FB_ACTIVATE_NOW;
2161         fb_info->var.height             = -1;
2162         fb_info->var.width              = -1;
2163         fb_info->var.vmode              = FB_VMODE_NONINTERLACED;
2164         fb_info->var.xres               = xgifb_info->video_width;
2165         fb_info->var.xres_virtual       = xgifb_info->video_width;
2166         fb_info->var.yres               = xgifb_info->video_height;
2167         fb_info->var.yres_virtual       = xgifb_info->video_height;
2168         fb_info->var.bits_per_pixel     = xgifb_info->video_bpp;
2169
2170         XGIfb_bpp_to_var(xgifb_info, &fb_info->var);
2171
2172         fb_info->var.pixclock = (u32) (1000000000 /
2173                         XGIfb_mode_rate_to_dclock(&xgifb_info->dev_info,
2174                                 hw_info,
2175                                 XGIbios_mode[xgifb_info->mode_idx].mode_no,
2176                                 xgifb_info->rate_idx));
2177
2178         if (XGIfb_mode_rate_to_ddata(&xgifb_info->dev_info, hw_info,
2179                 XGIbios_mode[xgifb_info->mode_idx].mode_no,
2180                 xgifb_info->rate_idx,
2181                 &fb_info->var.left_margin,
2182                 &fb_info->var.right_margin,
2183                 &fb_info->var.upper_margin,
2184                 &fb_info->var.lower_margin,
2185                 &fb_info->var.hsync_len,
2186                 &fb_info->var.vsync_len,
2187                 &fb_info->var.sync,
2188                 &fb_info->var.vmode)) {
2189
2190                 if ((fb_info->var.vmode & FB_VMODE_MASK) ==
2191                     FB_VMODE_INTERLACED) {
2192                         fb_info->var.yres <<= 1;
2193                         fb_info->var.yres_virtual <<= 1;
2194                 } else if ((fb_info->var.vmode & FB_VMODE_MASK) ==
2195                            FB_VMODE_DOUBLE) {
2196                         fb_info->var.pixclock >>= 1;
2197                         fb_info->var.yres >>= 1;
2198                         fb_info->var.yres_virtual >>= 1;
2199                 }
2200
2201         }
2202
2203         fb_info->flags = FBINFO_FLAG_DEFAULT;
2204         fb_info->screen_base = xgifb_info->video_vbase;
2205         fb_info->fbops = &XGIfb_ops;
2206         XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2207         fb_info->pseudo_palette = xgifb_info->pseudo_palette;
2208
2209         fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2210
2211 #ifdef CONFIG_MTRR
2212         xgifb_info->mtrr = mtrr_add(xgifb_info->video_base,
2213                 xgifb_info->video_size, MTRR_TYPE_WRCOMB, 1);
2214         if (xgifb_info->mtrr >= 0)
2215                 dev_info(&pdev->dev, "added MTRR\n");
2216 #endif
2217
2218         if (register_framebuffer(fb_info) < 0) {
2219                 ret = -EINVAL;
2220                 goto error_mtrr;
2221         }
2222
2223         dumpVGAReg();
2224
2225         return 0;
2226
2227 error_mtrr:
2228 #ifdef CONFIG_MTRR
2229         if (xgifb_info->mtrr >= 0)
2230                 mtrr_del(xgifb_info->mtrr, xgifb_info->video_base,
2231                         xgifb_info->video_size);
2232 #endif /* CONFIG_MTRR */
2233 error_1:
2234         iounmap(xgifb_info->mmio_vbase);
2235         iounmap(xgifb_info->video_vbase);
2236         release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2237 error_0:
2238         release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
2239 error_disable:
2240         pci_disable_device(pdev);
2241 error:
2242         framebuffer_release(fb_info);
2243         return ret;
2244 }
2245
2246 /*****************************************************/
2247 /*                PCI DEVICE HANDLING                */
2248 /*****************************************************/
2249
2250 static void __devexit xgifb_remove(struct pci_dev *pdev)
2251 {
2252         struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
2253         struct fb_info *fb_info = xgifb_info->fb_info;
2254
2255         unregister_framebuffer(fb_info);
2256 #ifdef CONFIG_MTRR
2257         if (xgifb_info->mtrr >= 0)
2258                 mtrr_del(xgifb_info->mtrr, xgifb_info->video_base,
2259                         xgifb_info->video_size);
2260 #endif /* CONFIG_MTRR */
2261         iounmap(xgifb_info->mmio_vbase);
2262         iounmap(xgifb_info->video_vbase);
2263         release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2264         release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
2265         pci_disable_device(pdev);
2266         framebuffer_release(fb_info);
2267         pci_set_drvdata(pdev, NULL);
2268 }
2269
2270 static struct pci_driver xgifb_driver = {
2271         .name = "xgifb",
2272         .id_table = xgifb_pci_table,
2273         .probe = xgifb_probe,
2274         .remove = __devexit_p(xgifb_remove)
2275 };
2276
2277
2278
2279 /*****************************************************/
2280 /*                      MODULE                       */
2281 /*****************************************************/
2282
2283 module_param(mode, charp, 0);
2284 MODULE_PARM_DESC(mode,
2285         "Selects the desired default display mode in the format XxYxDepth "
2286         "(eg. 1024x768x16).");
2287
2288 module_param(forcecrt2type, charp, 0);
2289 MODULE_PARM_DESC(forcecrt2type,
2290         "Force the second display output type. Possible values are NONE, "
2291         "LCD, TV, VGA, SVIDEO or COMPOSITE.");
2292
2293 module_param(vesa, int, 0);
2294 MODULE_PARM_DESC(vesa,
2295         "Selects the desired default display mode by VESA mode number "
2296         "(eg. 0x117).");
2297
2298 module_param(filter, int, 0);
2299 MODULE_PARM_DESC(filter,
2300         "Selects TV flicker filter type (only for systems with a SiS301 video bridge). "
2301         "Possible values 0-7. Default: [no filter]).");
2302
2303 static int __init xgifb_init(void)
2304 {
2305         char *option = NULL;
2306
2307         if (forcecrt2type != NULL)
2308                 XGIfb_search_crt2type(forcecrt2type);
2309         if (fb_get_options("xgifb", &option))
2310                 return -ENODEV;
2311         XGIfb_setup(option);
2312
2313         return pci_register_driver(&xgifb_driver);
2314 }
2315
2316 static void __exit xgifb_remove_module(void)
2317 {
2318         pci_unregister_driver(&xgifb_driver);
2319         pr_debug("Module unloaded\n");
2320 }
2321
2322 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2323 MODULE_LICENSE("GPL");
2324 MODULE_AUTHOR("XGITECH , Others");
2325 module_init(xgifb_init);
2326 module_exit(xgifb_remove_module);