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