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.
7 /* #include <linux/config.h> */
8 #include <linux/version.h>
9 #include <linux/module.h>
10 #include <linux/moduleparam.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
16 #include <linux/tty.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
20 #include <linux/console.h>
21 #include <linux/selection.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/pci.h>
25 #include <linux/vmalloc.h>
26 #include <linux/vt_kern.h>
27 #include <linux/capability.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
46 #include "vb_setmode.h"
48 #define Index_CR_GPIO_Reg1 0x48
49 #define Index_CR_GPIO_Reg2 0x49
50 #define Index_CR_GPIO_Reg3 0x4a
52 #define GPIOG_EN (1<<6)
53 #define GPIOG_WRITE (1<<6)
54 #define GPIOG_READ (1<<1)
56 #define XGIFB_ROM_SIZE 65536
58 /* -------------------- Macro definitions ---------------------------- */
63 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
65 #define DPRINTK(fmt, args...)
69 static void dumpVGAReg(void)
73 xgifb_reg_set(XGISR, 0x05, 0x86);
75 xgifb_reg_set(XGISR, 0x08, 0x4f);
76 xgifb_reg_set(XGISR, 0x0f, 0x20);
77 xgifb_reg_set(XGISR, 0x11, 0x4f);
78 xgifb_reg_set(XGISR, 0x13, 0x45);
79 xgifb_reg_set(XGISR, 0x14, 0x51);
80 xgifb_reg_set(XGISR, 0x1e, 0x41);
81 xgifb_reg_set(XGISR, 0x1f, 0x0);
82 xgifb_reg_set(XGISR, 0x20, 0xa1);
83 xgifb_reg_set(XGISR, 0x22, 0xfb);
84 xgifb_reg_set(XGISR, 0x26, 0x22);
85 xgifb_reg_set(XGISR, 0x3e, 0x07);
88 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
89 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
90 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
91 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
93 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
95 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
96 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
98 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
99 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
101 xgifb_reg_set(XGICR, 0x99, 0x1);
102 xgifb_reg_set(XGICR, 0x41, 0x40);
105 for (i = 0; i < 0x4f; i++) {
106 reg = xgifb_reg_get(XGISR, i);
107 printk("\no 3c4 %x", i);
108 printk("\ni 3c5 => %x", reg);
111 for (i = 0; i < 0xF0; i++) {
112 reg = xgifb_reg_get(XGICR, i);
113 printk("\no 3d4 %x", i);
114 printk("\ni 3d5 => %x", reg);
117 xgifb_reg_set(XGIPART1,0x2F,1);
118 for (i=1; i < 0x50; i++) {
119 reg = xgifb_reg_get(XGIPART1, i);
120 printk("\no d004 %x", i);
121 printk("\ni d005 => %x", reg);
124 for (i=0; i < 0x50; i++) {
125 reg = xgifb_reg_get(XGIPART2, i);
126 printk("\no d010 %x", i);
127 printk("\ni d011 => %x", reg);
129 for (i=0; i < 0x50; i++) {
130 reg = xgifb_reg_get(XGIPART3, i);
131 printk("\no d012 %x",i);
132 printk("\ni d013 => %x",reg);
134 for (i=0; i < 0x50; i++) {
135 reg = xgifb_reg_get(XGIPART4, i);
136 printk("\no d014 %x",i);
137 printk("\ni d015 => %x",reg);
142 static inline void dumpVGAReg(void)
147 /* data for XGI components */
148 struct video_info xgi_video_info;
153 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
156 /* --------------- Hardware Access Routines -------------------------- */
158 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
159 struct xgi_hw_device_info *HwDeviceExtension,
160 unsigned char modeno, unsigned char rateindex)
162 unsigned short ModeNo = modeno;
163 unsigned short ModeIdIndex = 0, ClockIndex = 0;
164 unsigned short RefreshRateTableIndex = 0;
166 /* unsigned long temp = 0; */
168 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
169 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
171 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
172 ModeIdIndex, XGI_Pr);
175 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
177 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
181 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
182 RefreshRateTableIndex += (rateindex - 1);
185 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
187 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
192 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
193 struct xgi_hw_device_info *HwDeviceExtension,
194 unsigned char modeno, unsigned char rateindex,
195 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
196 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
199 unsigned short ModeNo = modeno;
200 unsigned short ModeIdIndex = 0, index = 0;
201 unsigned short RefreshRateTableIndex = 0;
203 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
204 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
205 unsigned char sr_data, cr_data, cr_data2;
206 unsigned long cr_data3;
207 int A, B, C, D, E, F, temp, j;
208 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
209 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
210 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
211 ModeIdIndex, XGI_Pr);
213 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
217 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
218 RefreshRateTableIndex += (rateindex - 1);
220 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
222 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
224 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
226 /* Horizontal total */
227 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
231 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
233 Horizontal display enable end
234 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
236 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
239 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
241 /* Horizontal retrace (=sync) start */
242 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
245 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
247 /* Horizontal blank start */
248 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
250 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
252 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
254 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
256 /* Horizontal blank end */
257 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
258 | ((unsigned short) (sr_data & 0x03) << 6);
260 /* Horizontal retrace (=sync) end */
261 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
263 temp = HBE - ((E - 1) & 255);
264 B = (temp > 0) ? temp : (temp + 256);
266 temp = HRE - ((E + F + 3) & 63);
267 C = (temp > 0) ? temp : (temp + 64);
271 *left_margin = D * 8;
272 *right_margin = F * 8;
275 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
277 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
279 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
282 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
283 | ((unsigned short) (cr_data2 & 0x20) << 4)
284 | ((unsigned short) (sr_data & 0x01) << 10);
287 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
289 /* Vertical display enable end */
291 VDE = (cr_data & 0xff) |
292 ((unsigned short) (cr_data2 & 0x02) << 7) |
293 ((unsigned short) (cr_data2 & 0x40) << 3) |
294 ((unsigned short) (sr_data & 0x02) << 9);
296 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
299 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
301 /* Vertical retrace (=sync) start */
302 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
303 | ((unsigned short) (cr_data2 & 0x80) << 2)
304 | ((unsigned short) (sr_data & 0x08) << 7);
307 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
309 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
311 /* Vertical blank start */
312 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
313 | ((unsigned short) (cr_data3 & 0x20) << 4)
314 | ((unsigned short) (sr_data & 0x04) << 8);
316 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
318 /* Vertical blank end */
319 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
320 temp = VBE - ((E - 1) & 511);
321 B = (temp > 0) ? temp : (temp + 512);
323 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
325 /* Vertical retrace (=sync) end */
326 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
327 temp = VRE - ((E + F - 1) & 31);
328 C = (temp > 0) ? temp : (temp + 32);
336 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
337 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
339 *sync |= FB_SYNC_VERT_HIGH_ACT;
341 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
342 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
344 *sync |= FB_SYNC_HOR_HIGH_ACT;
346 *vmode = FB_VMODE_NONINTERLACED;
347 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
348 *vmode = FB_VMODE_INTERLACED;
351 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
352 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
353 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
354 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
356 *vmode = FB_VMODE_DOUBLE;
367 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
369 XGI_Pr->RelIO = BaseAddr;
370 XGI_Pr->P3c4 = BaseAddr + 0x14;
371 XGI_Pr->P3d4 = BaseAddr + 0x24;
372 XGI_Pr->P3c0 = BaseAddr + 0x10;
373 XGI_Pr->P3ce = BaseAddr + 0x1e;
374 XGI_Pr->P3c2 = BaseAddr + 0x12;
375 XGI_Pr->P3ca = BaseAddr + 0x1a;
376 XGI_Pr->P3c6 = BaseAddr + 0x16;
377 XGI_Pr->P3c7 = BaseAddr + 0x17;
378 XGI_Pr->P3c8 = BaseAddr + 0x18;
379 XGI_Pr->P3c9 = BaseAddr + 0x19;
380 XGI_Pr->P3da = BaseAddr + 0x2A;
381 /* Digital video interface registers (LCD) */
382 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
383 /* 301 TV Encoder registers */
384 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
385 /* 301 Macrovision registers */
386 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
387 /* 301 VGA2 (and LCD) registers */
388 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
389 /* 301 palette address port registers */
390 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
394 /* ------------ Interface for init & mode switching code ------------- */
396 static unsigned char XGIfb_query_VGA_config_space(
397 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
398 unsigned long set, unsigned long *value)
400 static struct pci_dev *pdev = NULL;
401 static unsigned char init = 0, valid_pdev = 0;
404 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
406 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
410 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
419 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
420 xgi_video_info.chip_id);
425 pci_read_config_dword(pdev, offset, (u32 *) value);
427 pci_write_config_dword(pdev, offset, (u32)(*value));
432 /* ------------------ Internal helper routines ----------------- */
434 static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
438 int XGIfb_mode_idx = 0;
441 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
442 && (XGIbios_mode[XGIfb_mode_idx].xres
443 <= XGI21_LCDCapList[0].LVDSHDE)) {
444 if ((XGIbios_mode[XGIfb_mode_idx].xres
445 == XGI21_LCDCapList[0].LVDSHDE)
446 && (XGIbios_mode[XGIfb_mode_idx].yres
447 == XGI21_LCDCapList[0].LVDSVDE)
448 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
449 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
458 return XGIfb_mode_idx;
461 static void XGIfb_search_mode(const char *name)
466 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
467 xgifb_mode_idx = DEFAULT_MODE;
468 if ((xgi_video_info.chip == XG21)
469 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
471 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
476 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
477 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
478 xgifb_mode_idx = DEFAULT_MODE;
479 if ((xgi_video_info.chip == XG21)
480 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
482 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
487 while (XGIbios_mode[i].mode_no != 0) {
488 l = min(strlen(name), strlen(XGIbios_mode[i].name));
489 if (!strncmp(name, XGIbios_mode[i].name, l)) {
497 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
500 static void XGIfb_search_vesamode(unsigned int vesamode)
506 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
507 xgifb_mode_idx = DEFAULT_MODE;
508 if ((xgi_video_info.chip == XG21)
509 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
511 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
516 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
518 while (XGIbios_mode[i].mode_no != 0) {
519 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
520 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
528 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
531 static int XGIfb_GetXG21LVDSData(void)
534 unsigned char *pData;
537 tmp = xgifb_reg_get(XGISR, 0x1e);
538 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
540 pData = xgi_video_info.mmio_vbase + 0x20000;
541 if ((pData[0x0] == 0x55) &&
542 (pData[0x1] == 0xAA) &&
543 (pData[0x65] & 0x1)) {
544 i = pData[0x316] | (pData[0x317] << 8);
551 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
552 | (pData[i + 1] << 8);
553 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
555 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
557 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
559 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
561 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
563 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
565 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
566 | (pData[i + 15] << 8);
567 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
568 | (pData[i + 17] << 8);
569 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
570 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
571 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
572 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
573 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
574 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
575 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
579 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
580 / sizeof(struct XGI21_LVDSCapStruct))));
586 static int XGIfb_validate_mode(int myindex)
590 if (xgi_video_info.chip == XG21) {
591 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
593 xres = XGI21_LCDCapList[0].LVDSHDE;
594 yres = XGI21_LCDCapList[0].LVDSVDE;
595 if (XGIbios_mode[myindex].xres > xres)
597 if (XGIbios_mode[myindex].yres > yres)
599 if ((XGIbios_mode[myindex].xres < xres) &&
600 (XGIbios_mode[myindex].yres < yres)) {
601 if (XGIbios_mode[myindex].bpp > 8)
610 /* FIXME: for now, all is valid on XG27 */
611 if (xgi_video_info.chip == XG27)
614 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
617 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
619 switch (XGIhw_ext.ulCRT2LCDType) {
660 /* case LCD_320x480: */ /* TW: FSTN */
671 if (XGIbios_mode[myindex].xres > xres)
673 if (XGIbios_mode[myindex].yres > yres)
675 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
676 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
677 switch (XGIbios_mode[myindex].xres) {
679 if (XGIbios_mode[myindex].yres != 512)
681 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
685 if ((XGIbios_mode[myindex].yres != 400)
686 && (XGIbios_mode[myindex].yres
691 if (XGIbios_mode[myindex].yres != 600)
695 if ((XGIbios_mode[myindex].yres != 600) &&
696 (XGIbios_mode[myindex].yres != 768))
698 if ((XGIbios_mode[myindex].yres == 600) &&
699 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
703 if ((XGIbios_mode[myindex].yres) != 768)
705 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
709 if ((XGIbios_mode[myindex].yres != 768) &&
710 (XGIbios_mode[myindex].yres != 1024))
712 if ((XGIbios_mode[myindex].yres == 768) &&
713 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
717 if (XGIbios_mode[myindex].yres != 1050)
721 if (XGIbios_mode[myindex].yres != 1200)
728 switch (XGIbios_mode[myindex].xres) {
730 if (XGIbios_mode[myindex].yres != 512)
734 if ((XGIbios_mode[myindex].yres != 400) &&
735 (XGIbios_mode[myindex].yres != 480))
739 if (XGIbios_mode[myindex].yres != 600)
743 if (XGIbios_mode[myindex].yres != 768)
747 if ((XGIbios_mode[myindex].yres != 960) &&
748 (XGIbios_mode[myindex].yres != 1024))
750 if (XGIbios_mode[myindex].yres == 960) {
751 if (XGIhw_ext.ulCRT2LCDType ==
757 if (XGIbios_mode[myindex].yres != 1050)
761 if (XGIbios_mode[myindex].yres != 1200)
770 switch (XGIbios_mode[myindex].xres) {
776 if (xgi_video_info.TV_type == TVMODE_NTSC) {
777 if (XGIbios_mode[myindex].yres != 480)
779 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
780 if (XGIbios_mode[myindex].yres != 576)
783 /* TW: LVDS/CHRONTEL does not support 720 */
784 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
785 xgi_video_info.hasVB == HASVB_CHRONTEL) {
790 if (xgi_video_info.TV_type == TVMODE_NTSC) {
791 if (XGIbios_mode[myindex].bpp == 32)
800 if (XGIbios_mode[myindex].xres > 1280)
808 static void XGIfb_search_crt2type(const char *name)
815 while (XGI_crt2type[i].type_no != -1) {
816 if (!strcmp(name, XGI_crt2type[i].name)) {
817 XGIfb_crt2type = XGI_crt2type[i].type_no;
818 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
823 if (XGIfb_crt2type < 0)
824 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
827 static u8 XGIfb_search_refresh_rate(unsigned int rate)
832 xres = XGIbios_mode[xgifb_mode_idx].xres;
833 yres = XGIbios_mode[xgifb_mode_idx].yres;
836 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
837 if ((XGIfb_vrate[i].xres == xres) &&
838 (XGIfb_vrate[i].yres == yres)) {
839 if (XGIfb_vrate[i].refresh == rate) {
840 XGIfb_rate_idx = XGIfb_vrate[i].idx;
842 } else if (XGIfb_vrate[i].refresh > rate) {
843 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
844 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
845 rate, XGIfb_vrate[i].refresh);
846 XGIfb_rate_idx = XGIfb_vrate[i].idx;
847 xgi_video_info.refresh_rate =
848 XGIfb_vrate[i].refresh;
849 } else if (((rate - XGIfb_vrate[i - 1].refresh)
850 <= 2) && (XGIfb_vrate[i].idx
852 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
853 rate, XGIfb_vrate[i-1].refresh);
854 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
855 xgi_video_info.refresh_rate =
856 XGIfb_vrate[i - 1].refresh;
859 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
860 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
861 rate, XGIfb_vrate[i].refresh);
862 XGIfb_rate_idx = XGIfb_vrate[i].idx;
868 if (XGIfb_rate_idx > 0) {
869 return XGIfb_rate_idx;
871 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
877 static void XGIfb_search_tvstd(const char *name)
884 while (XGI_tvtype[i].type_no != -1) {
885 if (!strcmp(name, XGI_tvtype[i].name)) {
886 XGIfb_tvmode = XGI_tvtype[i].type_no;
893 /* ----------- FBDev related routines for all series ----------- */
895 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
897 switch (var->bits_per_pixel) {
899 var->red.offset = var->green.offset = var->blue.offset = 0;
900 var->red.length = var->green.length = var->blue.length = 6;
901 xgi_video_info.video_cmap_len = 256;
904 var->red.offset = 11;
906 var->green.offset = 5;
907 var->green.length = 6;
908 var->blue.offset = 0;
909 var->blue.length = 5;
910 var->transp.offset = 0;
911 var->transp.length = 0;
912 xgi_video_info.video_cmap_len = 16;
915 var->red.offset = 16;
917 var->green.offset = 8;
918 var->green.length = 8;
919 var->blue.offset = 0;
920 var->blue.length = 8;
921 var->transp.offset = 24;
922 var->transp.length = 8;
923 xgi_video_info.video_cmap_len = 16;
928 /* --------------------- SetMode routines ------------------------- */
930 static void XGIfb_pre_setmode(void)
932 u8 cr30 = 0, cr31 = 0;
934 cr31 = xgifb_reg_get(XGICR, 0x31);
937 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
939 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
940 cr31 |= XGI_DRIVER_MODE;
943 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
944 cr31 |= XGI_DRIVER_MODE;
947 if (xgi_video_info.TV_type == TVMODE_HIVISION)
948 cr30 = (XGI_VB_OUTPUT_HIVISION
949 | XGI_SIMULTANEOUS_VIEW_ENABLE);
950 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
951 cr30 = (XGI_VB_OUTPUT_SVIDEO
952 | XGI_SIMULTANEOUS_VIEW_ENABLE);
953 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
954 cr30 = (XGI_VB_OUTPUT_COMPOSITE
955 | XGI_SIMULTANEOUS_VIEW_ENABLE);
956 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
957 cr30 = (XGI_VB_OUTPUT_SCART
958 | XGI_SIMULTANEOUS_VIEW_ENABLE);
959 cr31 |= XGI_DRIVER_MODE;
961 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
966 default: /* disable CRT2 */
968 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
971 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
972 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
973 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
976 static void XGIfb_post_setmode(void)
979 unsigned char doit = 1;
981 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
982 xgifb_reg_set(XGICR, 0x13, 0x00);
983 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
986 if (xgi_video_info.video_bpp == 8) {
987 /* TW: We can't switch off CRT1 on LVDS/Chrontel
989 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
990 (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
993 /* TW: We can't switch off CRT1 on 301B-DH
994 * in 8bpp Modes if using LCD */
995 if (xgi_video_info.disp_state & DISPTYPE_LCD)
999 /* TW: We can't switch off CRT1 if bridge is in slave mode */
1000 if (xgi_video_info.hasVB != HASVB_NONE) {
1001 reg = xgifb_reg_get(XGIPART1, 0x00);
1003 if ((reg & 0x50) == 0x10)
1010 reg = xgifb_reg_get(XGICR, 0x17);
1011 if ((XGIfb_crt1off) && (doit))
1015 xgifb_reg_set(XGICR, 0x17, reg);
1017 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1019 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1022 reg = xgifb_reg_get(XGIPART4, 0x01);
1024 if (reg < 0xB0) { /* Set filter for XGI301 */
1025 switch (xgi_video_info.video_width) {
1027 filter_tb = (xgi_video_info.TV_type ==
1028 TVMODE_NTSC) ? 4 : 12;
1031 filter_tb = (xgi_video_info.TV_type ==
1032 TVMODE_NTSC) ? 5 : 13;
1035 filter_tb = (xgi_video_info.TV_type ==
1036 TVMODE_NTSC) ? 6 : 14;
1039 filter_tb = (xgi_video_info.TV_type ==
1040 TVMODE_NTSC) ? 7 : 15;
1046 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1048 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1050 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1052 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1054 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1056 } else if (xgi_video_info.TV_plug
1057 == TVPLUG_COMPOSITE) {
1059 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1061 switch (xgi_video_info.video_width) {
1063 xgifb_reg_set(XGIPART2,
1066 xgifb_reg_set(XGIPART2,
1069 xgifb_reg_set(XGIPART2,
1072 xgifb_reg_set(XGIPART2,
1077 xgifb_reg_set(XGIPART2,
1080 xgifb_reg_set(XGIPART2,
1083 xgifb_reg_set(XGIPART2,
1086 xgifb_reg_set(XGIPART2,
1091 xgifb_reg_set(XGIPART2,
1094 xgifb_reg_set(XGIPART2,
1097 xgifb_reg_set(XGIPART2,
1100 xgifb_reg_set(XGIPART2,
1107 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1109 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1111 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1113 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1115 } else if (xgi_video_info.TV_plug
1116 == TVPLUG_COMPOSITE) {
1118 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1120 switch (xgi_video_info.video_width) {
1122 xgifb_reg_set(XGIPART2,
1125 xgifb_reg_set(XGIPART2,
1128 xgifb_reg_set(XGIPART2,
1131 xgifb_reg_set(XGIPART2,
1136 xgifb_reg_set(XGIPART2,
1139 xgifb_reg_set(XGIPART2,
1142 xgifb_reg_set(XGIPART2,
1145 xgifb_reg_set(XGIPART2,
1150 xgifb_reg_set(XGIPART2,
1153 xgifb_reg_set(XGIPART2,
1156 xgifb_reg_set(XGIPART2,
1159 xgifb_reg_set(XGIPART2,
1167 if ((filter >= 0) && (filter <= 7)) {
1168 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1170 XGI_TV_filter[filter_tb].
1172 XGI_TV_filter[filter_tb].
1174 XGI_TV_filter[filter_tb].
1176 XGI_TV_filter[filter_tb].
1182 (XGI_TV_filter[filter_tb].
1183 filter[filter][0]));
1187 (XGI_TV_filter[filter_tb].
1188 filter[filter][1]));
1192 (XGI_TV_filter[filter_tb].
1193 filter[filter][2]));
1197 (XGI_TV_filter[filter_tb].
1198 filter[filter][3]));
1204 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1205 struct fb_info *info)
1208 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1210 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1212 #if defined(__powerpc__)
1213 u8 sr_data, cr_data;
1215 unsigned int drate = 0, hrate = 0;
1218 /* unsigned char reg, reg1; */
1220 DEBUGPRN("Inside do_set_var");
1221 /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */
1223 info->var.xres_virtual = var->xres_virtual;
1224 info->var.yres_virtual = var->yres_virtual;
1225 info->var.bits_per_pixel = var->bits_per_pixel;
1227 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1229 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1231 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1233 /* var->yres <<= 1; */
1236 if (!htotal || !vtotal) {
1237 DPRINTK("XGIfb: Invalid 'var' information\n");
1239 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1240 var->pixclock, htotal, vtotal);
1242 if (var->pixclock && htotal && vtotal) {
1243 drate = 1000000000 / var->pixclock;
1244 hrate = (drate * 1000) / htotal;
1245 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1248 xgi_video_info.refresh_rate = 60;
1251 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1254 var->bits_per_pixel,
1255 xgi_video_info.refresh_rate);
1257 old_mode = xgifb_mode_idx;
1260 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1261 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1262 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1263 && (XGIbios_mode[xgifb_mode_idx].yres
1265 && (XGIbios_mode[xgifb_mode_idx].bpp
1266 == var->bits_per_pixel)) {
1267 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1275 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1277 xgifb_mode_idx = -1;
1279 if (xgifb_mode_idx < 0) {
1280 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1281 var->xres, var->yres, var->bits_per_pixel);
1282 xgifb_mode_idx = old_mode;
1286 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1287 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1288 xgi_video_info.refresh_rate = 60;
1293 XGIfb_pre_setmode();
1294 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1295 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1299 info->fix.line_length = ((info->var.xres_virtual
1300 * info->var.bits_per_pixel) >> 6);
1302 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1304 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1305 xgifb_reg_set(XGISR,
1307 (info->fix.line_length & 0xff00) >> 8);
1309 XGIfb_post_setmode();
1311 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1312 XGIbios_mode[xgifb_mode_idx].xres,
1313 XGIbios_mode[xgifb_mode_idx].yres,
1314 XGIbios_mode[xgifb_mode_idx].bpp,
1315 xgi_video_info.refresh_rate);
1317 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1318 xgi_video_info.video_vwidth = info->var.xres_virtual;
1319 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1320 xgi_video_info.video_vheight = info->var.yres_virtual;
1321 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1322 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1323 xgi_video_info.video_linelength = info->var.xres_virtual
1324 * (xgi_video_info.video_bpp >> 3);
1325 switch (xgi_video_info.video_bpp) {
1327 xgi_video_info.DstColor = 0x0000;
1328 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1329 xgi_video_info.video_cmap_len = 256;
1330 #if defined(__powerpc__)
1331 cr_data = xgifb_reg_get(XGICR, 0x4D);
1332 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1336 xgi_video_info.DstColor = 0x8000;
1337 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1338 #if defined(__powerpc__)
1339 cr_data = xgifb_reg_get(XGICR, 0x4D);
1340 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1342 xgi_video_info.video_cmap_len = 16;
1345 xgi_video_info.DstColor = 0xC000;
1346 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1347 xgi_video_info.video_cmap_len = 16;
1348 #if defined(__powerpc__)
1349 cr_data = xgifb_reg_get(XGICR, 0x4D);
1350 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1354 xgi_video_info.video_cmap_len = 16;
1355 printk(KERN_ERR "XGIfb: Unsupported depth %d",
1356 xgi_video_info.video_bpp);
1360 XGIfb_bpp_to_var(var); /*update ARGB info*/
1361 DEBUGPRN("End of do_set_var");
1368 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1372 /* printk("Inside pan_var"); */
1374 if (var->xoffset > (var->xres_virtual - var->xres)) {
1375 /* printk("Pan: xo: %d xv %d xr %d\n",
1376 var->xoffset, var->xres_virtual, var->xres); */
1379 if (var->yoffset > (var->yres_virtual - var->yres)) {
1380 /* printk("Pan: yo: %d yv %d yr %d\n",
1381 var->yoffset, var->yres_virtual, var->yres); */
1384 base = var->yoffset * var->xres_virtual + var->xoffset;
1386 /* calculate base bpp dep. */
1387 switch (var->bits_per_pixel) {
1399 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1401 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1402 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1403 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1404 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1405 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1407 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1408 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1409 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1410 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1411 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1412 xgifb_reg_and_or(XGIPART1,
1415 ((base >> 24) & 0x01) << 7);
1417 /* printk("End of pan_var"); */
1422 static int XGIfb_open(struct fb_info *info, int user)
1427 static int XGIfb_release(struct fb_info *info, int user)
1432 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1436 switch (var->bits_per_pixel) {
1450 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1451 unsigned blue, unsigned transp, struct fb_info *info)
1453 if (regno >= XGIfb_get_cmap_len(&info->var))
1456 switch (info->var.bits_per_pixel) {
1458 outb(regno, XGIDACA);
1459 outb((red >> 10), XGIDACD);
1460 outb((green >> 10), XGIDACD);
1461 outb((blue >> 10), XGIDACD);
1462 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1463 outb(regno, XGIDAC2A);
1464 outb((red >> 8), XGIDAC2D);
1465 outb((green >> 8), XGIDAC2D);
1466 outb((blue >> 8), XGIDAC2D);
1470 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1471 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1478 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1485 /* ----------- FBDev related routines for all series ---------- */
1487 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1488 struct fb_info *info)
1490 DEBUGPRN("inside get_fix");
1491 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1493 strcpy(fix->id, myid);
1495 fix->smem_start = xgi_video_info.video_base;
1497 fix->smem_len = xgi_video_info.video_size;
1499 fix->type = video_type;
1501 if (xgi_video_info.video_bpp == 8)
1502 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1504 fix->visual = FB_VISUAL_DIRECTCOLOR;
1511 fix->line_length = xgi_video_info.video_linelength;
1512 fix->mmio_start = xgi_video_info.mmio_base;
1513 fix->mmio_len = xgi_video_info.mmio_size;
1514 fix->accel = FB_ACCEL_XGI_XABRE;
1516 DEBUGPRN("end of get_fix");
1520 static int XGIfb_set_par(struct fb_info *info)
1524 /* printk("XGIfb: inside set_par\n"); */
1525 err = XGIfb_do_set_var(&info->var, 1, info);
1528 XGIfb_get_fix(&info->fix, -1, info);
1529 /* printk("XGIfb: end of set_par\n"); */
1533 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1535 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1537 unsigned int vtotal = 0;
1538 unsigned int drate = 0, hrate = 0;
1540 int refresh_rate, search_idx;
1542 DEBUGPRN("Inside check_var");
1544 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1545 vtotal = var->upper_margin + var->yres + var->lower_margin
1548 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1549 vtotal = var->upper_margin + var->yres + var->lower_margin
1552 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1553 vtotal = var->upper_margin + (var->yres / 2)
1554 + var->lower_margin + var->vsync_len;
1556 vtotal = var->upper_margin + var->yres + var->lower_margin
1559 if (!(htotal) || !(vtotal))
1560 XGIFAIL("XGIfb: no valid timing data");
1562 if (var->pixclock && htotal && vtotal) {
1563 drate = 1000000000 / var->pixclock;
1564 hrate = (drate * 1000) / htotal;
1565 xgi_video_info.refresh_rate =
1566 (unsigned int) (hrate * 2 / vtotal);
1568 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1569 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1570 __func__, var->pixclock, htotal, vtotal,
1571 __func__, drate, hrate, xgi_video_info.refresh_rate);
1573 xgi_video_info.refresh_rate = 60;
1577 if ((var->pixclock) && (htotal)) {
1578 drate = 1E12 / var->pixclock;
1579 hrate = drate / htotal;
1580 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1585 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1586 if ((var->xres == 1024) && (var->yres == 600))
1590 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1591 (XGIbios_mode[search_idx].xres <= var->xres)) {
1592 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1593 (XGIbios_mode[search_idx].yres == var->yres) &&
1594 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1595 if (XGIfb_validate_mode(search_idx) > 0) {
1605 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1606 var->xres, var->yres, var->bits_per_pixel);
1608 while (XGIbios_mode[search_idx].mode_no != 0) {
1609 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1610 (var->yres <= XGIbios_mode[search_idx].yres) &&
1611 (var->bits_per_pixel ==
1612 XGIbios_mode[search_idx].bpp)) {
1613 if (XGIfb_validate_mode(search_idx) > 0) {
1621 var->xres = XGIbios_mode[search_idx].xres;
1622 var->yres = XGIbios_mode[search_idx].yres;
1623 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1624 var->xres, var->yres, var->bits_per_pixel);
1627 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1628 var->xres, var->yres, var->bits_per_pixel);
1633 /* TW: TODO: Check the refresh rate */
1635 /* Adapt RGB settings */
1636 XGIfb_bpp_to_var(var);
1638 /* Sanity check for offsets */
1639 if (var->xoffset < 0)
1641 if (var->yoffset < 0)
1645 if (var->xres != var->xres_virtual)
1646 var->xres_virtual = var->xres;
1647 if (var->yres != var->yres_virtual)
1648 var->yres_virtual = var->yres;
1650 /* TW: Now patch yres_virtual if we use panning */
1651 /* May I do this? */
1652 /* var->yres_virtual = xgi_video_info.heapstart /
1653 (var->xres * (var->bits_per_pixel >> 3)); */
1654 /* if (var->yres_virtual <= var->yres) { */
1655 /* TW: Paranoia check */
1656 /* var->yres_virtual = var->yres; */
1660 /* Truncate offsets to maximum if too high */
1661 if (var->xoffset > var->xres_virtual - var->xres)
1662 var->xoffset = var->xres_virtual - var->xres - 1;
1664 if (var->yoffset > var->yres_virtual - var->yres)
1665 var->yoffset = var->yres_virtual - var->yres - 1;
1667 /* Set everything else to 0 */
1668 var->red.msb_right =
1669 var->green.msb_right =
1670 var->blue.msb_right =
1671 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1673 DEBUGPRN("end of check_var");
1678 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1679 struct fb_info *info)
1683 /* printk("\nInside pan_display:\n"); */
1685 if (var->xoffset > (var->xres_virtual - var->xres))
1687 if (var->yoffset > (var->yres_virtual - var->yres))
1690 if (var->vmode & FB_VMODE_YWRAP) {
1691 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1695 if (var->xoffset + info->var.xres > info->var.xres_virtual
1696 || var->yoffset + info->var.yres
1697 > info->var.yres_virtual)
1700 err = XGIfb_pan_var(var);
1704 info->var.xoffset = var->xoffset;
1705 info->var.yoffset = var->yoffset;
1706 if (var->vmode & FB_VMODE_YWRAP)
1707 info->var.vmode |= FB_VMODE_YWRAP;
1709 info->var.vmode &= ~FB_VMODE_YWRAP;
1711 /* printk("End of pan_display\n"); */
1716 static int XGIfb_blank(int blank, struct fb_info *info)
1720 reg = xgifb_reg_get(XGICR, 0x17);
1727 xgifb_reg_set(XGICR, 0x17, reg);
1728 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1729 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1733 static struct fb_ops XGIfb_ops = {
1734 .owner = THIS_MODULE,
1735 .fb_open = XGIfb_open,
1736 .fb_release = XGIfb_release,
1737 .fb_check_var = XGIfb_check_var,
1738 .fb_set_par = XGIfb_set_par,
1739 .fb_setcolreg = XGIfb_setcolreg,
1741 .fb_pan_display = XGIfb_pan_display,
1743 .fb_blank = XGIfb_blank,
1744 .fb_fillrect = cfb_fillrect,
1745 .fb_copyarea = cfb_copyarea,
1746 .fb_imageblit = cfb_imageblit,
1747 /* .fb_mmap = XGIfb_mmap, */
1750 /* ---------------- Chip generation dependent routines ---------------- */
1752 /* for XGI 315/550/650/740/330 */
1754 static int XGIfb_get_dram_size(void)
1760 /* xorg driver sets 32MB * 1 channel */
1761 if (xgi_video_info.chip == XG27)
1762 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1764 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
1765 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1766 case XGI_DRAM_SIZE_1MB:
1767 xgi_video_info.video_size = 0x100000;
1769 case XGI_DRAM_SIZE_2MB:
1770 xgi_video_info.video_size = 0x200000;
1772 case XGI_DRAM_SIZE_4MB:
1773 xgi_video_info.video_size = 0x400000;
1775 case XGI_DRAM_SIZE_8MB:
1776 xgi_video_info.video_size = 0x800000;
1778 case XGI_DRAM_SIZE_16MB:
1779 xgi_video_info.video_size = 0x1000000;
1781 case XGI_DRAM_SIZE_32MB:
1782 xgi_video_info.video_size = 0x2000000;
1784 case XGI_DRAM_SIZE_64MB:
1785 xgi_video_info.video_size = 0x4000000;
1787 case XGI_DRAM_SIZE_128MB:
1788 xgi_video_info.video_size = 0x8000000;
1790 case XGI_DRAM_SIZE_256MB:
1791 xgi_video_info.video_size = 0x10000000;
1797 tmp = (reg & 0x0c) >> 2;
1798 switch (xgi_video_info.chip) {
1834 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1835 /* PLiad fixed for benchmarking and fb set */
1836 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1837 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1839 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1841 xgi_video_info.video_size, ChannelNum);
1846 static void XGIfb_detect_VB(void)
1850 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1852 switch (xgi_video_info.hasVB) {
1853 case HASVB_LVDS_CHRONTEL:
1854 case HASVB_CHRONTEL:
1858 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1862 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1864 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1873 if (XGIfb_crt2type != -1)
1874 /* TW: Override with option */
1875 xgi_video_info.disp_state = XGIfb_crt2type;
1876 else if (cr32 & XGI_VB_TV)
1877 xgi_video_info.disp_state = DISPTYPE_TV;
1878 else if (cr32 & XGI_VB_LCD)
1879 xgi_video_info.disp_state = DISPTYPE_LCD;
1880 else if (cr32 & XGI_VB_CRT2)
1881 xgi_video_info.disp_state = DISPTYPE_CRT2;
1883 xgi_video_info.disp_state = 0;
1885 if (XGIfb_tvplug != -1)
1886 /* PR/TW: Override with option */
1887 xgi_video_info.TV_plug = XGIfb_tvplug;
1888 else if (cr32 & XGI_VB_HIVISION) {
1889 xgi_video_info.TV_type = TVMODE_HIVISION;
1890 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1891 } else if (cr32 & XGI_VB_SVIDEO)
1892 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1893 else if (cr32 & XGI_VB_COMPOSITE)
1894 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1895 else if (cr32 & XGI_VB_SCART)
1896 xgi_video_info.TV_plug = TVPLUG_SCART;
1898 if (xgi_video_info.TV_type == 0) {
1899 temp = xgifb_reg_get(XGICR, 0x38);
1901 xgi_video_info.TV_type = TVMODE_PAL;
1903 xgi_video_info.TV_type = TVMODE_NTSC;
1906 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1907 if (XGIfb_forcecrt1 != -1) {
1908 if (XGIfb_forcecrt1)
1915 static int XGIfb_has_VB(void)
1919 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1920 switch (vb_chipid) {
1922 xgi_video_info.hasVB = HASVB_301;
1925 xgi_video_info.hasVB = HASVB_302;
1928 xgi_video_info.hasVB = HASVB_NONE;
1934 static void XGIfb_get_VB_type(void)
1938 if (!XGIfb_has_VB()) {
1939 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1940 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1941 case XGI310_EXTERNAL_CHIP_LVDS:
1942 xgi_video_info.hasVB = HASVB_LVDS;
1944 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1945 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1953 XGIINITSTATIC int __init XGIfb_setup(char *options)
1957 xgi_video_info.refresh_rate = 0;
1959 printk(KERN_INFO "XGIfb: Options %s\n", options);
1961 if (!options || !*options)
1964 while ((this_opt = strsep(&options, ",")) != NULL) {
1969 if (!strncmp(this_opt, "mode:", 5)) {
1970 XGIfb_search_mode(this_opt + 5);
1971 } else if (!strncmp(this_opt, "vesa:", 5)) {
1972 XGIfb_search_vesamode(simple_strtoul(
1973 this_opt + 5, NULL, 0));
1974 } else if (!strncmp(this_opt, "mode:", 5)) {
1975 XGIfb_search_mode(this_opt + 5);
1976 } else if (!strncmp(this_opt, "vesa:", 5)) {
1977 XGIfb_search_vesamode(simple_strtoul(
1978 this_opt + 5, NULL, 0));
1979 } else if (!strncmp(this_opt, "vrate:", 6)) {
1980 xgi_video_info.refresh_rate = simple_strtoul(
1981 this_opt + 6, NULL, 0);
1982 } else if (!strncmp(this_opt, "rate:", 5)) {
1983 xgi_video_info.refresh_rate = simple_strtoul(
1984 this_opt + 5, NULL, 0);
1985 } else if (!strncmp(this_opt, "off", 3)) {
1987 } else if (!strncmp(this_opt, "crt1off", 7)) {
1989 } else if (!strncmp(this_opt, "filter:", 7)) {
1990 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1991 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1992 XGIfb_search_crt2type(this_opt + 14);
1993 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1994 XGIfb_forcecrt1 = (int)simple_strtoul(
1995 this_opt + 10, NULL, 0);
1996 } else if (!strncmp(this_opt, "tvmode:", 7)) {
1997 XGIfb_search_tvstd(this_opt + 7);
1998 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1999 XGIfb_search_tvstd(this_opt + 7);
2000 } else if (!strncmp(this_opt, "dstn", 4)) {
2002 /* TW: DSTN overrules forcecrt2type */
2003 XGIfb_crt2type = DISPTYPE_LCD;
2004 } else if (!strncmp(this_opt, "pdc:", 4)) {
2005 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2006 if (XGIfb_pdc & ~0x3c) {
2007 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2010 } else if (!strncmp(this_opt, "noypan", 6)) {
2012 } else if (!strncmp(this_opt, "userom:", 7)) {
2013 XGIfb_userom = (int)simple_strtoul(
2014 this_opt + 7, NULL, 0);
2015 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2016 /* XGIfb_useoem = (int)simple_strtoul(
2017 this_opt + 7, NULL, 0); */
2019 XGIfb_search_mode(this_opt);
2020 /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
2024 /* TW: Panning only with acceleration */
2028 printk("\nxgifb: outa xgifb_setup 3450");
2032 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2034 void __iomem *rom_address;
2035 unsigned char *rom_copy;
2038 rom_address = pci_map_rom(dev, &rom_size);
2039 if (rom_address == NULL)
2042 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2043 if (rom_copy == NULL)
2046 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2047 memcpy_fromio(rom_copy, rom_address, rom_size);
2050 pci_unmap_rom(dev, rom_address);
2054 static int __devinit xgifb_probe(struct pci_dev *pdev,
2055 const struct pci_device_id *ent)
2064 XGIfb_registered = 0;
2066 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2067 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2071 xgi_video_info.chip_id = pdev->device;
2072 pci_read_config_byte(pdev,
2074 &xgi_video_info.revision_id);
2075 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2077 xgi_video_info.pcibus = pdev->bus->number;
2078 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2079 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2080 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2081 xgi_video_info.subsysdevice = pdev->subsystem_device;
2083 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2084 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2085 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2086 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2087 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2088 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2089 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2090 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2092 if (pci_enable_device(pdev)) {
2097 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2099 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2100 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
2102 if (reg1 != 0xa1) { /*I/O error */
2103 printk("\nXGIfb: I/O error!!!");
2108 switch (xgi_video_info.chip_id) {
2109 case PCI_DEVICE_ID_XG_20:
2110 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2111 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
2112 if (CR48&GPIOG_READ)
2113 xgi_video_info.chip = XG21;
2115 xgi_video_info.chip = XG20;
2116 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2118 case PCI_DEVICE_ID_XG_40:
2119 xgi_video_info.chip = XG40;
2120 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2122 case PCI_DEVICE_ID_XG_41:
2123 xgi_video_info.chip = XG41;
2124 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2126 case PCI_DEVICE_ID_XG_42:
2127 xgi_video_info.chip = XG42;
2128 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2130 case PCI_DEVICE_ID_XG_27:
2131 xgi_video_info.chip = XG27;
2132 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2139 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2140 XGIhw_ext.jChipType = xgi_video_info.chip;
2142 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2143 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2144 if (XGIhw_ext.pjVirtualRomBase)
2145 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2146 XGIhw_ext.pjVirtualRomBase);
2148 printk(KERN_INFO "XGIfb: Video ROM not found\n");
2150 XGIhw_ext.pjVirtualRomBase = NULL;
2151 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2153 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2155 if (XGIfb_get_dram_size()) {
2156 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2161 if ((xgifb_mode_idx < 0) ||
2162 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2163 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2165 IND_XGI_PCI_ADDRESS_SET,
2166 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2167 /* Enable 2D accelerator engine */
2168 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2171 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2173 if (!request_mem_region(xgi_video_info.video_base,
2174 xgi_video_info.video_size,
2176 printk("unable request memory size %x",
2177 xgi_video_info.video_size);
2178 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2179 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2184 if (!request_mem_region(xgi_video_info.mmio_base,
2185 xgi_video_info.mmio_size,
2187 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2192 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2193 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2194 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2195 xgi_video_info.mmio_size);
2197 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2198 xgi_video_info.video_base,
2199 xgi_video_info.video_vbase,
2200 xgi_video_info.video_size / 1024);
2202 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2203 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2204 xgi_video_info.mmio_size / 1024);
2205 printk("XGIfb: XGIInitNew() ...");
2206 if (XGIInitNew(&XGIhw_ext))
2211 xgi_video_info.mtrr = (unsigned int) 0;
2213 if ((xgifb_mode_idx < 0) ||
2214 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2215 xgi_video_info.hasVB = HASVB_NONE;
2216 if ((xgi_video_info.chip == XG20) ||
2217 (xgi_video_info.chip == XG27)) {
2218 xgi_video_info.hasVB = HASVB_NONE;
2219 } else if (xgi_video_info.chip == XG21) {
2220 CR38 = xgifb_reg_get(XGICR, 0x38);
2221 if ((CR38&0xE0) == 0xC0) {
2222 xgi_video_info.disp_state = DISPTYPE_LCD;
2223 if (!XGIfb_GetXG21LVDSData()) {
2225 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2226 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2227 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2228 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2232 } else if ((CR38&0xE0) == 0x60) {
2233 xgi_video_info.hasVB = HASVB_CHRONTEL;
2235 xgi_video_info.hasVB = HASVB_NONE;
2238 XGIfb_get_VB_type();
2241 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2243 XGIhw_ext.ulExternalChip = 0;
2245 switch (xgi_video_info.hasVB) {
2247 reg = xgifb_reg_get(XGIPART4, 0x01);
2249 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2250 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2251 } else if (reg >= 0xD0) {
2252 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2253 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2255 /* else if (reg >= 0xB0) {
2256 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2257 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2258 printk("XGIfb: XGI301B bridge detected\n");
2261 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2262 printk("XGIfb: XGI301 bridge detected\n");
2266 reg = xgifb_reg_get(XGIPART4, 0x01);
2268 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2269 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2270 } else if (reg >= 0xD0) {
2271 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2272 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2273 } else if (reg >= 0xB0) {
2274 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2276 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2279 XGIhw_ext.ujVBChipID = VB_CHIP_302;
2280 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2284 XGIhw_ext.ulExternalChip = 0x1;
2285 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2287 case HASVB_TRUMPION:
2288 XGIhw_ext.ulExternalChip = 0x2;
2289 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2291 case HASVB_CHRONTEL:
2292 XGIhw_ext.ulExternalChip = 0x4;
2293 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2295 case HASVB_LVDS_CHRONTEL:
2296 XGIhw_ext.ulExternalChip = 0x5;
2297 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2300 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2304 if (xgi_video_info.hasVB != HASVB_NONE)
2307 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2309 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2311 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2314 xgi_video_info.disp_state = DISPMODE_SINGLE |
2318 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2320 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2322 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2326 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2330 XGIfb_detectedpdc = 0;
2332 XGIfb_detectedlcda = 0xff;
2334 /* TW: Try to find about LCDA */
2336 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2337 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2338 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2340 tmp = xgifb_reg_get(XGICR, 0x34);
2342 /* Currently on LCDA?
2343 *(Some BIOSes leave CR38) */
2344 tmp = xgifb_reg_get(XGICR, 0x38);
2345 if ((tmp & 0x03) == 0x03) {
2346 /* XGI_Pr.XGI_UseLCDA = 1; */
2348 /* Currently on LCDA?
2349 *(Some newer BIOSes set D0 in CR35) */
2350 tmp = xgifb_reg_get(XGICR, 0x35);
2352 /* XGI_Pr.XGI_UseLCDA = 1; */
2354 tmp = xgifb_reg_get(XGICR,
2357 tmp = xgifb_reg_get(
2360 /* XGI_Pr.XGI_UseLCDA = 1; */
2369 if (xgifb_mode_idx >= 0)
2370 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2372 if (xgifb_mode_idx < 0) {
2373 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2375 xgifb_mode_idx = DEFAULT_LCDMODE;
2376 if (xgi_video_info.chip == XG21)
2378 XGIfb_GetXG21DefaultLVDSModeIdx();
2381 xgifb_mode_idx = DEFAULT_TVMODE;
2384 xgifb_mode_idx = DEFAULT_MODE;
2389 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2391 /* yilin set default refresh rate */
2392 if (xgi_video_info.refresh_rate == 0)
2393 xgi_video_info.refresh_rate = 60;
2394 if (XGIfb_search_refresh_rate(
2395 xgi_video_info.refresh_rate) == 0) {
2396 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2397 xgi_video_info.refresh_rate = 60;
2400 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2401 xgi_video_info.video_vwidth =
2402 xgi_video_info.video_width =
2403 XGIbios_mode[xgifb_mode_idx].xres;
2404 xgi_video_info.video_vheight =
2405 xgi_video_info.video_height =
2406 XGIbios_mode[xgifb_mode_idx].yres;
2407 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2408 xgi_video_info.video_linelength =
2409 xgi_video_info.video_width *
2410 (xgi_video_info.video_bpp >> 3);
2411 switch (xgi_video_info.video_bpp) {
2413 xgi_video_info.DstColor = 0x0000;
2414 xgi_video_info.XGI310_AccelDepth = 0x00000000;
2415 xgi_video_info.video_cmap_len = 256;
2418 xgi_video_info.DstColor = 0x8000;
2419 xgi_video_info.XGI310_AccelDepth = 0x00010000;
2420 xgi_video_info.video_cmap_len = 16;
2423 xgi_video_info.DstColor = 0xC000;
2424 xgi_video_info.XGI310_AccelDepth = 0x00020000;
2425 xgi_video_info.video_cmap_len = 16;
2428 xgi_video_info.video_cmap_len = 16;
2429 printk(KERN_INFO "XGIfb: Unsupported depth %d",
2430 xgi_video_info.video_bpp);
2434 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2435 xgi_video_info.video_width,
2436 xgi_video_info.video_height,
2437 xgi_video_info.video_bpp,
2438 xgi_video_info.refresh_rate);
2441 default_var.xres_virtual =
2442 xgi_video_info.video_width;
2444 default_var.yres_virtual =
2445 xgi_video_info.video_height;
2446 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2448 XGIfb_bpp_to_var(&default_var);
2450 default_var.pixclock = (u32) (1000000000 /
2451 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2452 XGIfb_mode_no, XGIfb_rate_idx));
2454 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2455 XGIfb_mode_no, XGIfb_rate_idx,
2456 &default_var.left_margin, &default_var.right_margin,
2457 &default_var.upper_margin, &default_var.lower_margin,
2458 &default_var.hsync_len, &default_var.vsync_len,
2459 &default_var.sync, &default_var.vmode)) {
2461 if ((default_var.vmode & FB_VMODE_MASK) ==
2462 FB_VMODE_INTERLACED) {
2463 default_var.yres <<= 1;
2464 default_var.yres_virtual <<= 1;
2465 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2467 default_var.pixclock >>= 1;
2468 default_var.yres >>= 1;
2469 default_var.yres_virtual >>= 1;
2474 fb_info->flags = FBINFO_FLAG_DEFAULT;
2475 fb_info->var = default_var;
2476 fb_info->fix = XGIfb_fix;
2477 fb_info->par = &xgi_video_info;
2478 fb_info->screen_base = xgi_video_info.video_vbase;
2479 fb_info->fbops = &XGIfb_ops;
2480 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2481 fb_info->pseudo_palette = pseudo_palette;
2483 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2486 xgi_video_info.mtrr = mtrr_add(
2487 (unsigned int) xgi_video_info.video_base,
2488 (unsigned int) xgi_video_info.video_size,
2489 MTRR_TYPE_WRCOMB, 1);
2490 if (xgi_video_info.mtrr)
2491 printk(KERN_INFO "XGIfb: Added MTRRs\n");
2494 if (register_framebuffer(fb_info) < 0) {
2499 XGIfb_registered = 1;
2501 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2502 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2511 iounmap(xgi_video_info.mmio_vbase);
2512 iounmap(xgi_video_info.video_vbase);
2513 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2515 release_mem_region(xgi_video_info.video_base,
2516 xgi_video_info.video_size);
2518 vfree(XGIhw_ext.pjVirtualRomBase);
2519 framebuffer_release(fb_info);
2523 /*****************************************************/
2524 /* PCI DEVICE HANDLING */
2525 /*****************************************************/
2527 static void __devexit xgifb_remove(struct pci_dev *pdev)
2529 unregister_framebuffer(fb_info);
2530 iounmap(xgi_video_info.mmio_vbase);
2531 iounmap(xgi_video_info.video_vbase);
2532 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2533 release_mem_region(xgi_video_info.video_base,
2534 xgi_video_info.video_size);
2535 vfree(XGIhw_ext.pjVirtualRomBase);
2536 framebuffer_release(fb_info);
2537 pci_set_drvdata(pdev, NULL);
2540 static struct pci_driver xgifb_driver = {
2542 .id_table = xgifb_pci_table,
2543 .probe = xgifb_probe,
2544 .remove = __devexit_p(xgifb_remove)
2547 XGIINITSTATIC int __init xgifb_init(void)
2549 char *option = NULL;
2551 if (fb_get_options("xgifb", &option))
2553 XGIfb_setup(option);
2555 return pci_register_driver(&xgifb_driver);
2559 module_init(xgifb_init);
2562 /*****************************************************/
2564 /*****************************************************/
2568 static char *mode = NULL;
2569 static int vesa = 0;
2570 static unsigned int rate = 0;
2571 static unsigned int mem = 0;
2572 static char *forcecrt2type = NULL;
2573 static int forcecrt1 = -1;
2574 static int pdc = -1;
2575 static int pdc1 = -1;
2576 static int noypan = -1;
2577 static int userom = -1;
2578 static int useoem = -1;
2579 static char *tvstandard = NULL;
2580 static int nocrt2rate = 0;
2581 static int scalelcd = -1;
2582 static char *specialtiming = NULL;
2583 static int lvdshl = -1;
2584 static int tvxposoffset = 0, tvyposoffset = 0;
2585 #if !defined(__i386__) && !defined(__x86_64__)
2586 static int resetcard = 0;
2587 static int videoram = 0;
2590 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2591 MODULE_LICENSE("GPL");
2592 MODULE_AUTHOR("XGITECH , Others");
2594 module_param(mem, int, 0);
2595 module_param(noypan, int, 0);
2596 module_param(userom, int, 0);
2597 module_param(useoem, int, 0);
2598 module_param(mode, charp, 0);
2599 module_param(vesa, int, 0);
2600 module_param(rate, int, 0);
2601 module_param(forcecrt1, int, 0);
2602 module_param(forcecrt2type, charp, 0);
2603 module_param(scalelcd, int, 0);
2604 module_param(pdc, int, 0);
2605 module_param(pdc1, int, 0);
2606 module_param(specialtiming, charp, 0);
2607 module_param(lvdshl, int, 0);
2608 module_param(tvstandard, charp, 0);
2609 module_param(tvxposoffset, int, 0);
2610 module_param(tvyposoffset, int, 0);
2611 module_param(filter, int, 0);
2612 module_param(nocrt2rate, int, 0);
2613 #if !defined(__i386__) && !defined(__x86_64__)
2614 module_param(resetcard, int, 0);
2615 module_param(videoram, int, 0);
2618 MODULE_PARM_DESC(noypan,
2619 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2620 "will be performed by redrawing the screen. (default: 0)\n");
2622 MODULE_PARM_DESC(mode,
2623 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2624 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2625 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2626 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2628 MODULE_PARM_DESC(vesa,
2629 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2630 "0x117 (default: 0x0103)\n");
2632 MODULE_PARM_DESC(rate,
2633 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2634 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2635 "will be ignored (default: 60)\n");
2637 MODULE_PARM_DESC(forcecrt1,
2638 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2639 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2640 "0=CRT1 OFF) (default: [autodetected])\n");
2642 MODULE_PARM_DESC(forcecrt2type,
2643 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2644 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2645 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2646 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2647 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2648 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2649 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2650 "depends on the very hardware in use. (default: [autodetected])\n");
2652 MODULE_PARM_DESC(scalelcd,
2653 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2654 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2655 "show black bars around the image, TMDS panels will probably do the scaling\n"
2656 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2658 MODULE_PARM_DESC(pdc,
2659 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2660 "should detect this correctly in most cases; however, sometimes this is not\n"
2661 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2662 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2663 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2664 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2666 MODULE_PARM_DESC(pdc1,
2667 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2668 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2669 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2670 "implemented yet.\n");
2672 MODULE_PARM_DESC(specialtiming,
2673 "\nPlease refer to documentation for more information on this option.\n");
2675 MODULE_PARM_DESC(lvdshl,
2676 "\nPlease refer to documentation for more information on this option.\n");
2678 MODULE_PARM_DESC(tvstandard,
2679 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2680 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2682 MODULE_PARM_DESC(tvxposoffset,
2683 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2686 MODULE_PARM_DESC(tvyposoffset,
2687 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2690 MODULE_PARM_DESC(filter,
2691 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2692 "(Possible values 0-7, default: [no filter])\n");
2694 MODULE_PARM_DESC(nocrt2rate,
2695 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2696 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2698 static int __init xgifb_init_module(void)
2700 printk("\nXGIfb_init_module");
2702 XGIfb_search_mode(mode);
2703 else if (vesa != -1)
2704 XGIfb_search_vesamode(vesa);
2706 return xgifb_init();
2709 static void __exit xgifb_remove_module(void)
2711 pci_unregister_driver(&xgifb_driver);
2712 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2715 module_init(xgifb_init_module);
2716 module_exit(xgifb_remove_module);
2718 #endif /* /MODULE */