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