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