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>
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)
55 int XGIfb_GetXG21DefaultLVDSModeIdx(void);
57 /* -------------------- Macro definitions ---------------------------- */
62 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
64 #define DPRINTK(fmt, args...)
68 static void dumpVGAReg(void)
72 outXGIIDXREG(XGISR, 0x05, 0x86);
74 outXGIIDXREG(XGISR, 0x08, 0x4f);
75 outXGIIDXREG(XGISR, 0x0f, 0x20);
76 outXGIIDXREG(XGISR, 0x11, 0x4f);
77 outXGIIDXREG(XGISR, 0x13, 0x45);
78 outXGIIDXREG(XGISR, 0x14, 0x51);
79 outXGIIDXREG(XGISR, 0x1e, 0x41);
80 outXGIIDXREG(XGISR, 0x1f, 0x0);
81 outXGIIDXREG(XGISR, 0x20, 0xa1);
82 outXGIIDXREG(XGISR, 0x22, 0xfb);
83 outXGIIDXREG(XGISR, 0x26, 0x22);
84 outXGIIDXREG(XGISR, 0x3e, 0x07);
87 /* outXGIIDXREG(XGICR, 0x19, 0x00); */
88 /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
89 /* outXGIIDXREG(XGICR, 0x22, 0xff); */
90 /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
92 /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
94 /* outXGIIDXREG(XGICR, 0x57, 0x0); */
95 /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
97 /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
98 /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
100 outXGIIDXREG(XGICR, 0x99, 0x1);
101 outXGIIDXREG(XGICR, 0x41, 0x40);
104 for (i = 0; i < 0x4f; i++) {
105 inXGIIDXREG(XGISR, i, reg);
106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
110 for (i = 0; i < 0xF0; i++) {
111 inXGIIDXREG(XGICR, i, reg);
112 printk("\no 3d4 %x", i);
113 printk("\ni 3d5 => %x", reg);
116 outXGIIDXREG(XGIPART1,0x2F,1);
117 for (i=1; i < 0x50; i++) {
118 inXGIIDXREG(XGIPART1, i, reg);
119 printk("\no d004 %x", i);
120 printk("\ni d005 => %x", reg);
123 for (i=0; i < 0x50; i++) {
124 inXGIIDXREG(XGIPART2, i, reg);
125 printk("\no d010 %x", i);
126 printk("\ni d011 => %x", reg);
128 for (i=0; i < 0x50; i++) {
129 inXGIIDXREG(XGIPART3, i, reg);
130 printk("\no d012 %x",i);
131 printk("\ni d013 => %x",reg);
133 for (i=0; i < 0x50; i++) {
134 inXGIIDXREG(XGIPART4, i, reg);
135 printk("\no d014 %x",i);
136 printk("\ni d015 => %x",reg);
141 static inline void dumpVGAReg(void)
146 /* data for XGI components */
147 struct video_info xgi_video_info;
152 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
155 /* --------------- Hardware Access Routines -------------------------- */
157 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 struct xgi_hw_device_info *HwDeviceExtension,
159 unsigned char modeno, unsigned char rateindex)
161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
165 /* unsigned long temp = 0; */
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
174 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
176 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
185 if (HwDeviceExtension->jChipType < XGI_315H)
188 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
193 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
194 struct xgi_hw_device_info *HwDeviceExtension,
195 unsigned char modeno, unsigned char rateindex,
196 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
197 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
200 unsigned short ModeNo = modeno;
201 unsigned short ModeIdIndex = 0, index = 0;
202 unsigned short RefreshRateTableIndex = 0;
204 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
205 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
206 unsigned char sr_data, cr_data, cr_data2;
207 unsigned long cr_data3;
208 int A, B, C, D, E, F, temp, j;
209 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
210 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
211 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
212 ModeIdIndex, XGI_Pr);
214 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
218 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
219 RefreshRateTableIndex += (rateindex - 1);
221 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
223 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
225 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
227 /* Horizontal total */
228 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
232 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
234 Horizontal display enable end
235 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
237 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
240 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
242 /* Horizontal retrace (=sync) start */
243 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
246 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
248 /* Horizontal blank start */
249 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
251 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
253 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
255 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
257 /* Horizontal blank end */
258 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
259 | ((unsigned short) (sr_data & 0x03) << 6);
261 /* Horizontal retrace (=sync) end */
262 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
264 temp = HBE - ((E - 1) & 255);
265 B = (temp > 0) ? temp : (temp + 256);
267 temp = HRE - ((E + F + 3) & 63);
268 C = (temp > 0) ? temp : (temp + 64);
272 *left_margin = D * 8;
273 *right_margin = F * 8;
276 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
278 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
280 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
283 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
284 | ((unsigned short) (cr_data2 & 0x20) << 4)
285 | ((unsigned short) (sr_data & 0x01) << 10);
288 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
290 /* Vertical display enable end */
292 VDE = (cr_data & 0xff) |
293 ((unsigned short) (cr_data2 & 0x02) << 7) |
294 ((unsigned short) (cr_data2 & 0x40) << 3) |
295 ((unsigned short) (sr_data & 0x02) << 9);
297 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
300 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
302 /* Vertical retrace (=sync) start */
303 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
304 | ((unsigned short) (cr_data2 & 0x80) << 2)
305 | ((unsigned short) (sr_data & 0x08) << 7);
308 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
310 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
312 /* Vertical blank start */
313 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
314 | ((unsigned short) (cr_data3 & 0x20) << 4)
315 | ((unsigned short) (sr_data & 0x04) << 8);
317 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
319 /* Vertical blank end */
320 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
321 temp = VBE - ((E - 1) & 511);
322 B = (temp > 0) ? temp : (temp + 512);
324 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
326 /* Vertical retrace (=sync) end */
327 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
328 temp = VRE - ((E + F - 1) & 31);
329 C = (temp > 0) ? temp : (temp + 32);
337 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
338 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
340 *sync |= FB_SYNC_VERT_HIGH_ACT;
342 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
343 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
345 *sync |= FB_SYNC_HOR_HIGH_ACT;
347 *vmode = FB_VMODE_NONINTERLACED;
348 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
349 *vmode = FB_VMODE_INTERLACED;
352 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
354 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
355 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
357 *vmode = FB_VMODE_DOUBLE;
368 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
370 XGI_Pr->RelIO = BaseAddr;
371 XGI_Pr->P3c4 = BaseAddr + 0x14;
372 XGI_Pr->P3d4 = BaseAddr + 0x24;
373 XGI_Pr->P3c0 = BaseAddr + 0x10;
374 XGI_Pr->P3ce = BaseAddr + 0x1e;
375 XGI_Pr->P3c2 = BaseAddr + 0x12;
376 XGI_Pr->P3ca = BaseAddr + 0x1a;
377 XGI_Pr->P3c6 = BaseAddr + 0x16;
378 XGI_Pr->P3c7 = BaseAddr + 0x17;
379 XGI_Pr->P3c8 = BaseAddr + 0x18;
380 XGI_Pr->P3c9 = BaseAddr + 0x19;
381 XGI_Pr->P3da = BaseAddr + 0x2A;
382 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
383 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
384 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
385 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
386 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
390 void XGIfb_set_reg4(u16 port, unsigned long data)
392 outl((u32)(data & 0xffffffff), port);
395 u32 XGIfb_get_reg3(u16 port)
403 /* ------------ Interface for init & mode switching code ------------- */
405 unsigned char XGIfb_query_VGA_config_space(
406 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
407 unsigned long set, unsigned long *value)
409 static struct pci_dev *pdev = NULL;
410 static unsigned char init = 0, valid_pdev = 0;
413 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
415 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
419 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
428 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
429 xgi_video_info.chip_id);
434 pci_read_config_dword(pdev, offset, (u32 *) value);
436 pci_write_config_dword(pdev, offset, (u32)(*value));
442 unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
443 unsigned long offset, unsigned long set, unsigned long *value)
445 static struct pci_dev *pdev = NULL;
446 static unsigned char init = 0, valid_pdev = 0;
451 switch (xgi_video_info.chip) {
453 nbridge_id = PCI_DEVICE_ID_XG_540;
456 nbridge_id = PCI_DEVICE_ID_XG_630;
459 nbridge_id = PCI_DEVICE_ID_XG_730;
462 nbridge_id = PCI_DEVICE_ID_XG_550;
465 nbridge_id = PCI_DEVICE_ID_XG_650;
468 nbridge_id = PCI_DEVICE_ID_XG_740;
475 pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
481 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
487 pci_read_config_dword(pdev, offset, (u32 *)value);
489 pci_write_config_dword(pdev, offset, (u32)(*value));
494 /* ------------------ Internal helper routines ----------------- */
496 static void XGIfb_search_mode(const char *name)
501 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
502 xgifb_mode_idx = DEFAULT_MODE;
503 if ((xgi_video_info.chip == XG21)
504 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
506 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
511 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
512 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
513 xgifb_mode_idx = DEFAULT_MODE;
514 if ((xgi_video_info.chip == XG21)
515 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
517 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
522 while (XGIbios_mode[i].mode_no != 0) {
523 l = min(strlen(name), strlen(XGIbios_mode[i].name));
524 if (!strncmp(name, XGIbios_mode[i].name, l)) {
532 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
535 static void XGIfb_search_vesamode(unsigned int vesamode)
541 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
542 xgifb_mode_idx = DEFAULT_MODE;
543 if ((xgi_video_info.chip == XG21)
544 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
546 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
551 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
553 while (XGIbios_mode[i].mode_no != 0) {
554 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
555 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
563 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
566 static int XGIfb_GetXG21LVDSData(void)
569 unsigned char *pData;
572 inXGIIDXREG(XGISR, 0x1e, tmp);
573 outXGIIDXREG(XGISR, 0x1e, tmp | 4);
575 pData = xgi_video_info.mmio_vbase + 0x20000;
576 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
577 i = pData[0x316] | (pData[0x317] << 8);
584 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
585 | (pData[i + 1] << 8);
586 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
588 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
590 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
592 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
594 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
596 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
598 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
599 | (pData[i + 15] << 8);
600 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
601 | (pData[i + 17] << 8);
602 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
603 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
604 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
605 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
606 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
607 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
608 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
612 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
613 / sizeof(struct XGI21_LVDSCapStruct))));
619 int XGIfb_GetXG21DefaultLVDSModeIdx(void)
623 int XGIfb_mode_idx = 0;
626 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
627 && (XGIbios_mode[XGIfb_mode_idx].xres
628 <= XGI21_LCDCapList[0].LVDSHDE)) {
629 if ((XGIbios_mode[XGIfb_mode_idx].xres
630 == XGI21_LCDCapList[0].LVDSHDE)
631 && (XGIbios_mode[XGIfb_mode_idx].yres
632 == XGI21_LCDCapList[0].LVDSVDE)
633 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
634 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
643 return XGIfb_mode_idx;
646 static int XGIfb_validate_mode(int myindex)
650 if (xgi_video_info.chip == XG21) {
651 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
653 xres = XGI21_LCDCapList[0].LVDSHDE;
654 yres = XGI21_LCDCapList[0].LVDSVDE;
655 if (XGIbios_mode[myindex].xres > xres)
657 if (XGIbios_mode[myindex].yres > yres)
659 if ((XGIbios_mode[myindex].xres < xres)
660 && (XGIbios_mode[myindex].yres < yres)) {
661 if (XGIbios_mode[myindex].bpp > 8)
670 /* FIXME: for now, all is valid on XG27 */
671 if (xgi_video_info.chip == XG27)
674 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
677 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
679 switch (XGIhw_ext.ulCRT2LCDType) {
720 /* case LCD_320x480: */ /* TW: FSTN */
731 if (XGIbios_mode[myindex].xres > xres)
733 if (XGIbios_mode[myindex].yres > yres)
735 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
736 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
737 switch (XGIbios_mode[myindex].xres) {
739 if (XGIbios_mode[myindex].yres != 512)
741 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
745 if ((XGIbios_mode[myindex].yres != 400)
746 && (XGIbios_mode[myindex].yres
751 if (XGIbios_mode[myindex].yres != 600)
755 if ((XGIbios_mode[myindex].yres != 600)
756 && (XGIbios_mode[myindex].yres
759 if ((XGIbios_mode[myindex].yres == 600)
760 && (XGIhw_ext.ulCRT2LCDType
765 if ((XGIbios_mode[myindex].yres) != 768)
767 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
771 if ((XGIbios_mode[myindex].yres != 768)
772 && (XGIbios_mode[myindex].yres
775 if ((XGIbios_mode[myindex].yres == 768)
776 && (XGIhw_ext.ulCRT2LCDType
781 if (XGIbios_mode[myindex].yres != 1050)
785 if (XGIbios_mode[myindex].yres != 1200)
792 switch (XGIbios_mode[myindex].xres) {
794 if (XGIbios_mode[myindex].yres != 512)
798 if ((XGIbios_mode[myindex].yres != 400)
799 && (XGIbios_mode[myindex].yres
804 if (XGIbios_mode[myindex].yres != 600)
808 if (XGIbios_mode[myindex].yres != 768)
812 if ((XGIbios_mode[myindex].yres != 960)
813 && (XGIbios_mode[myindex].yres
816 if (XGIbios_mode[myindex].yres == 960) {
817 if (XGIhw_ext.ulCRT2LCDType
823 if (XGIbios_mode[myindex].yres != 1050)
827 if (XGIbios_mode[myindex].yres != 1200)
836 switch (XGIbios_mode[myindex].xres) {
842 if (xgi_video_info.TV_type == TVMODE_NTSC) {
843 if (XGIbios_mode[myindex].yres != 480)
845 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
846 if (XGIbios_mode[myindex].yres != 576)
849 /* TW: LVDS/CHRONTEL does not support 720 */
850 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
851 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
856 if (xgi_video_info.TV_type == TVMODE_NTSC) {
857 if (XGIbios_mode[myindex].bpp == 32)
860 /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */
861 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
862 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
863 if (xgi_video_info.chip < XGI_315H)
872 if (XGIbios_mode[myindex].xres > 1280)
880 static void XGIfb_search_crt2type(const char *name)
887 while (XGI_crt2type[i].type_no != -1) {
888 if (!strcmp(name, XGI_crt2type[i].name)) {
889 XGIfb_crt2type = XGI_crt2type[i].type_no;
890 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
895 if (XGIfb_crt2type < 0)
896 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
899 static void XGIfb_search_queuemode(const char *name)
906 while (XGI_queuemode[i].type_no != -1) {
907 if (!strcmp(name, XGI_queuemode[i].name)) {
908 XGIfb_queuemode = XGI_queuemode[i].type_no;
913 if (XGIfb_queuemode < 0)
914 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
917 static u8 XGIfb_search_refresh_rate(unsigned int rate)
922 xres = XGIbios_mode[xgifb_mode_idx].xres;
923 yres = XGIbios_mode[xgifb_mode_idx].yres;
926 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
927 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
929 if (XGIfb_vrate[i].refresh == rate) {
930 XGIfb_rate_idx = XGIfb_vrate[i].idx;
932 } else if (XGIfb_vrate[i].refresh > rate) {
933 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
934 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
935 rate, XGIfb_vrate[i].refresh);
936 XGIfb_rate_idx = XGIfb_vrate[i].idx;
937 xgi_video_info.refresh_rate
938 = XGIfb_vrate[i].refresh;
939 } else if (((rate - XGIfb_vrate[i - 1].refresh)
940 <= 2) && (XGIfb_vrate[i].idx
942 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
943 rate, XGIfb_vrate[i-1].refresh);
944 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
945 xgi_video_info.refresh_rate
946 = XGIfb_vrate[i - 1].refresh;
949 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
950 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
951 rate, XGIfb_vrate[i].refresh);
952 XGIfb_rate_idx = XGIfb_vrate[i].idx;
958 if (XGIfb_rate_idx > 0) {
959 return XGIfb_rate_idx;
962 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
967 static void XGIfb_search_tvstd(const char *name)
974 while (XGI_tvtype[i].type_no != -1) {
975 if (!strcmp(name, XGI_tvtype[i].name)) {
976 XGIfb_tvmode = XGI_tvtype[i].type_no;
983 static unsigned char XGIfb_bridgeisslave(void)
985 unsigned char usScratchP1_00;
987 if (xgi_video_info.hasVB == HASVB_NONE)
990 inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00);
991 if ((usScratchP1_00 & 0x50) == 0x10)
997 static unsigned char XGIfbcheckvretracecrt1(void)
1001 inXGIIDXREG(XGICR, 0x17, temp);
1005 inXGIIDXREG(XGISR, 0x1f, temp);
1009 if (inXGIREG(XGIINPSTAT) & 0x08)
1015 static unsigned char XGIfbcheckvretracecrt2(void)
1018 if (xgi_video_info.hasVB == HASVB_NONE)
1020 inXGIIDXREG(XGIPART1, 0x30, temp);
1027 static unsigned char XGIfb_CheckVBRetrace(void)
1029 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1030 if (XGIfb_bridgeisslave())
1031 return XGIfbcheckvretracecrt1();
1033 return XGIfbcheckvretracecrt2();
1035 return XGIfbcheckvretracecrt1();
1038 /* ----------- FBDev related routines for all series ----------- */
1040 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1042 switch (var->bits_per_pixel) {
1044 var->red.offset = var->green.offset = var->blue.offset = 0;
1045 var->red.length = var->green.length = var->blue.length = 6;
1046 xgi_video_info.video_cmap_len = 256;
1049 var->red.offset = 11;
1050 var->red.length = 5;
1051 var->green.offset = 5;
1052 var->green.length = 6;
1053 var->blue.offset = 0;
1054 var->blue.length = 5;
1055 var->transp.offset = 0;
1056 var->transp.length = 0;
1057 xgi_video_info.video_cmap_len = 16;
1060 var->red.offset = 16;
1061 var->red.length = 8;
1062 var->green.offset = 8;
1063 var->green.length = 8;
1064 var->blue.offset = 0;
1065 var->blue.length = 8;
1066 var->transp.offset = 24;
1067 var->transp.length = 8;
1068 xgi_video_info.video_cmap_len = 16;
1073 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1074 struct fb_info *info)
1077 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1079 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1081 #if defined(__powerpc__)
1082 u8 sr_data, cr_data;
1084 unsigned int drate = 0, hrate = 0;
1087 /* unsigned char reg, reg1; */
1089 DEBUGPRN("Inside do_set_var");
1090 /* 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); */
1092 info->var.xres_virtual = var->xres_virtual;
1093 info->var.yres_virtual = var->yres_virtual;
1094 info->var.bits_per_pixel = var->bits_per_pixel;
1096 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1098 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1100 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1102 /* var->yres <<= 1; */
1105 if (!htotal || !vtotal) {
1106 DPRINTK("XGIfb: Invalid 'var' information\n");
1108 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1109 var->pixclock, htotal, vtotal);
1111 if (var->pixclock && htotal && vtotal) {
1112 drate = 1000000000 / var->pixclock;
1113 hrate = (drate * 1000) / htotal;
1114 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1117 xgi_video_info.refresh_rate = 60;
1120 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1121 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
1123 old_mode = xgifb_mode_idx;
1126 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1127 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1128 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1129 && (XGIbios_mode[xgifb_mode_idx].yres
1131 && (XGIbios_mode[xgifb_mode_idx].bpp
1132 == var->bits_per_pixel)) {
1133 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1141 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1143 xgifb_mode_idx = -1;
1145 if (xgifb_mode_idx < 0) {
1146 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1147 var->yres, var->bits_per_pixel);
1148 xgifb_mode_idx = old_mode;
1152 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1153 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1154 xgi_video_info.refresh_rate = 60;
1159 XGIfb_pre_setmode();
1160 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1161 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1164 info->fix.line_length = ((info->var.xres_virtual
1165 * info->var.bits_per_pixel) >> 6);
1167 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1169 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1170 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
1172 XGIfb_post_setmode();
1174 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1175 XGIbios_mode[xgifb_mode_idx].xres,
1176 XGIbios_mode[xgifb_mode_idx].yres,
1177 XGIbios_mode[xgifb_mode_idx].bpp,
1178 xgi_video_info.refresh_rate);
1180 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1181 xgi_video_info.video_vwidth = info->var.xres_virtual;
1182 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1183 xgi_video_info.video_vheight = info->var.yres_virtual;
1184 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1185 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1186 xgi_video_info.video_linelength = info->var.xres_virtual
1187 * (xgi_video_info.video_bpp >> 3);
1188 xgi_video_info.accel = 0;
1190 xgi_video_info.accel = (var->accel_flags
1191 & FB_ACCELF_TEXT) ? -1 : 0;
1193 switch (xgi_video_info.video_bpp) {
1195 xgi_video_info.DstColor = 0x0000;
1196 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1197 xgi_video_info.video_cmap_len = 256;
1198 #if defined(__powerpc__)
1199 inXGIIDXREG(XGICR, 0x4D, cr_data);
1200 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1204 xgi_video_info.DstColor = 0x8000;
1205 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1206 #if defined(__powerpc__)
1207 inXGIIDXREG(XGICR, 0x4D, cr_data);
1208 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1210 xgi_video_info.video_cmap_len = 16;
1213 xgi_video_info.DstColor = 0xC000;
1214 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1215 xgi_video_info.video_cmap_len = 16;
1216 #if defined(__powerpc__)
1217 inXGIIDXREG(XGICR, 0x4D, cr_data);
1218 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1222 xgi_video_info.video_cmap_len = 16;
1223 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1224 xgi_video_info.accel = 0;
1228 XGIfb_bpp_to_var(var); /*update ARGB info*/
1229 DEBUGPRN("End of do_set_var");
1236 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1240 /* printk("Inside pan_var"); */
1242 if (var->xoffset > (var->xres_virtual - var->xres)) {
1243 /* printk("Pan: xo: %d xv %d xr %d\n",
1244 var->xoffset, var->xres_virtual, var->xres); */
1247 if (var->yoffset > (var->yres_virtual - var->yres)) {
1248 /* printk("Pan: yo: %d yv %d yr %d\n",
1249 var->yoffset, var->yres_virtual, var->yres); */
1252 base = var->yoffset * var->xres_virtual + var->xoffset;
1254 /* calculate base bpp dep. */
1255 switch (var->bits_per_pixel) {
1267 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1269 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1270 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1271 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1272 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1273 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1275 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1276 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1277 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1278 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1279 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1280 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1282 /* printk("End of pan_var"); */
1287 void XGI_dispinfo(struct ap_data *rec)
1289 rec->minfo.bpp = xgi_video_info.video_bpp;
1290 rec->minfo.xres = xgi_video_info.video_width;
1291 rec->minfo.yres = xgi_video_info.video_height;
1292 rec->minfo.v_xres = xgi_video_info.video_vwidth;
1293 rec->minfo.v_yres = xgi_video_info.video_vheight;
1294 rec->minfo.org_x = xgi_video_info.org_x;
1295 rec->minfo.org_y = xgi_video_info.org_y;
1296 rec->minfo.vrate = xgi_video_info.refresh_rate;
1297 rec->iobase = xgi_video_info.vga_base - 0x30;
1298 rec->mem_size = xgi_video_info.video_size;
1299 rec->disp_state = xgi_video_info.disp_state;
1300 rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1301 rec->hasVB = xgi_video_info.hasVB;
1302 rec->TV_type = xgi_video_info.TV_type;
1303 rec->TV_plug = xgi_video_info.TV_plug;
1304 rec->chip = xgi_video_info.chip;
1307 static int XGIfb_open(struct fb_info *info, int user)
1312 static int XGIfb_release(struct fb_info *info, int user)
1317 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1321 switch (var->bits_per_pixel) {
1335 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1336 unsigned blue, unsigned transp, struct fb_info *info)
1338 if (regno >= XGIfb_get_cmap_len(&info->var))
1341 switch (info->var.bits_per_pixel) {
1343 outXGIREG(XGIDACA, regno);
1344 outXGIREG(XGIDACD, (red >> 10));
1345 outXGIREG(XGIDACD, (green >> 10));
1346 outXGIREG(XGIDACD, (blue >> 10));
1347 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1348 outXGIREG(XGIDAC2A, regno);
1349 outXGIREG(XGIDAC2D, (red >> 8));
1350 outXGIREG(XGIDAC2D, (green >> 8));
1351 outXGIREG(XGIDAC2D, (blue >> 8));
1355 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1356 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1363 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1370 static int XGIfb_set_par(struct fb_info *info)
1374 /* printk("XGIfb: inside set_par\n"); */
1375 err = XGIfb_do_set_var(&info->var, 1, info);
1378 XGIfb_get_fix(&info->fix, -1, info);
1379 /* printk("XGIfb: end of set_par\n"); */
1383 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1385 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1387 unsigned int vtotal = 0;
1388 unsigned int drate = 0, hrate = 0;
1390 int refresh_rate, search_idx;
1392 DEBUGPRN("Inside check_var");
1394 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1395 vtotal = var->upper_margin + var->yres + var->lower_margin
1398 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1399 vtotal = var->upper_margin + var->yres + var->lower_margin
1402 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1403 vtotal = var->upper_margin + (var->yres / 2)
1404 + var->lower_margin + var->vsync_len;
1406 vtotal = var->upper_margin + var->yres + var->lower_margin
1409 if (!(htotal) || !(vtotal))
1410 XGIFAIL("XGIfb: no valid timing data");
1412 if (var->pixclock && htotal && vtotal) {
1413 drate = 1000000000 / var->pixclock;
1414 hrate = (drate * 1000) / htotal;
1415 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1417 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1418 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1419 __func__, var->pixclock, htotal, vtotal,
1420 __func__, drate, hrate, xgi_video_info.refresh_rate);
1422 xgi_video_info.refresh_rate = 60;
1426 if ((var->pixclock) && (htotal)) {
1427 drate = 1E12 / var->pixclock;
1428 hrate = drate / htotal;
1429 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1434 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1435 if ((var->xres == 1024) && (var->yres == 600))
1439 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1440 (XGIbios_mode[search_idx].xres <= var->xres)) {
1441 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1442 (XGIbios_mode[search_idx].yres == var->yres) &&
1443 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1444 if (XGIfb_validate_mode(search_idx) > 0) {
1454 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1455 var->xres, var->yres, var->bits_per_pixel);
1457 while (XGIbios_mode[search_idx].mode_no != 0) {
1459 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1460 (var->yres <= XGIbios_mode[search_idx].yres) &&
1461 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1462 if (XGIfb_validate_mode(search_idx) > 0) {
1470 var->xres = XGIbios_mode[search_idx].xres;
1471 var->yres = XGIbios_mode[search_idx].yres;
1472 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1473 var->xres, var->yres, var->bits_per_pixel);
1476 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1477 var->xres, var->yres, var->bits_per_pixel);
1482 /* TW: TODO: Check the refresh rate */
1484 /* Adapt RGB settings */
1485 XGIfb_bpp_to_var(var);
1487 /* Sanity check for offsets */
1488 if (var->xoffset < 0)
1490 if (var->yoffset < 0)
1494 if (var->xres != var->xres_virtual)
1495 var->xres_virtual = var->xres;
1496 if (var->yres != var->yres_virtual)
1497 var->yres_virtual = var->yres;
1499 /* TW: Now patch yres_virtual if we use panning */
1500 /* May I do this? */
1501 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1502 /* if (var->yres_virtual <= var->yres) { */
1503 /* TW: Paranoia check */
1504 /* var->yres_virtual = var->yres; */
1508 /* Truncate offsets to maximum if too high */
1509 if (var->xoffset > var->xres_virtual - var->xres)
1510 var->xoffset = var->xres_virtual - var->xres - 1;
1512 if (var->yoffset > var->yres_virtual - var->yres)
1513 var->yoffset = var->yres_virtual - var->yres - 1;
1515 /* Set everything else to 0 */
1516 var->red.msb_right =
1517 var->green.msb_right =
1518 var->blue.msb_right =
1519 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1521 DEBUGPRN("end of check_var");
1526 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1527 struct fb_info *info)
1531 /* printk("\nInside pan_display:\n"); */
1533 if (var->xoffset > (var->xres_virtual - var->xres))
1535 if (var->yoffset > (var->yres_virtual - var->yres))
1538 if (var->vmode & FB_VMODE_YWRAP) {
1539 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1543 if (var->xoffset + info->var.xres > info->var.xres_virtual
1544 || var->yoffset + info->var.yres
1545 > info->var.yres_virtual)
1548 err = XGIfb_pan_var(var);
1552 info->var.xoffset = var->xoffset;
1553 info->var.yoffset = var->yoffset;
1554 if (var->vmode & FB_VMODE_YWRAP)
1555 info->var.vmode |= FB_VMODE_YWRAP;
1557 info->var.vmode &= ~FB_VMODE_YWRAP;
1559 /* printk("End of pan_display\n"); */
1564 static int XGIfb_blank(int blank, struct fb_info *info)
1568 inXGIIDXREG(XGICR, 0x17, reg);
1575 outXGIIDXREG(XGICR, 0x17, reg);
1576 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1577 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1581 static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
1584 DEBUGPRN("inside ioctl");
1587 if (!capable(CAP_SYS_RAWIO))
1589 XGI_malloc((struct XGI_memreq *) arg);
1592 if (!capable(CAP_SYS_RAWIO))
1594 XGI_free(*(unsigned long *) arg);
1596 case FBIOGET_HWCINFO: {
1597 unsigned long *hwc_offset = (unsigned long *) arg;
1599 if (XGIfb_caps & HW_CURSOR_CAP)
1601 = XGIfb_hwcursor_vbase
1602 - (unsigned long) xgi_video_info.video_vbase;
1608 case FBIOPUT_MODEINFO: {
1609 struct mode_info *x = (struct mode_info *) arg;
1611 xgi_video_info.video_bpp = x->bpp;
1612 xgi_video_info.video_width = x->xres;
1613 xgi_video_info.video_height = x->yres;
1614 xgi_video_info.video_vwidth = x->v_xres;
1615 xgi_video_info.video_vheight = x->v_yres;
1616 xgi_video_info.org_x = x->org_x;
1617 xgi_video_info.org_y = x->org_y;
1618 xgi_video_info.refresh_rate = x->vrate;
1619 xgi_video_info.video_linelength = xgi_video_info.video_vwidth
1620 * (xgi_video_info.video_bpp >> 3);
1621 switch (xgi_video_info.video_bpp) {
1623 xgi_video_info.DstColor = 0x0000;
1624 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1625 xgi_video_info.video_cmap_len = 256;
1628 xgi_video_info.DstColor = 0x8000;
1629 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1630 xgi_video_info.video_cmap_len = 16;
1633 xgi_video_info.DstColor = 0xC000;
1634 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1635 xgi_video_info.video_cmap_len = 16;
1638 xgi_video_info.video_cmap_len = 16;
1639 printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1640 xgi_video_info.accel = 0;
1646 case FBIOGET_DISPINFO:
1647 XGI_dispinfo((struct ap_data *) arg);
1649 case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1651 struct XGIfb_info *x = (struct XGIfb_info *) arg;
1653 /* x->XGIfb_id = XGIFB_ID; */
1654 x->XGIfb_version = VER_MAJOR;
1655 x->XGIfb_revision = VER_MINOR;
1656 x->XGIfb_patchlevel = VER_LEVEL;
1657 x->chip_id = xgi_video_info.chip_id;
1658 x->memory = xgi_video_info.video_size / 1024;
1659 x->heapstart = xgi_video_info.heapstart / 1024;
1660 x->fbvidmode = XGIfb_mode_no;
1661 x->XGIfb_caps = XGIfb_caps;
1662 x->XGIfb_tqlen = 512; /* yet unused */
1663 x->XGIfb_pcibus = xgi_video_info.pcibus;
1664 x->XGIfb_pcislot = xgi_video_info.pcislot;
1665 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1666 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1667 x->XGIfb_lcda = XGIfb_detectedlcda;
1670 case XGIFB_GET_VBRSTATUS: {
1671 unsigned long *vbrstatus = (unsigned long *) arg;
1672 if (XGIfb_CheckVBRetrace())
1679 } DEBUGPRN("end of ioctl");
1684 /* ----------- FBDev related routines for all series ---------- */
1686 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1687 struct fb_info *info)
1689 DEBUGPRN("inside get_fix");
1690 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1692 strcpy(fix->id, myid);
1694 fix->smem_start = xgi_video_info.video_base;
1696 fix->smem_len = xgi_video_info.video_size;
1698 /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1699 if (xgi_video_info.video_size > 0x1000000) {
1700 fix->smem_len = 0xD00000;
1701 } else if (xgi_video_info.video_size > 0x800000)
1702 fix->smem_len = 0x800000;
1704 fix->smem_len = 0x400000;
1706 fix->smem_len = XGIfb_mem * 1024;
1708 fix->type = video_type;
1710 if (xgi_video_info.video_bpp == 8)
1711 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1713 fix->visual = FB_VISUAL_DIRECTCOLOR;
1720 fix->line_length = xgi_video_info.video_linelength;
1721 fix->mmio_start = xgi_video_info.mmio_base;
1722 fix->mmio_len = XGIfb_mmio_size;
1723 if (xgi_video_info.chip >= XG40)
1724 fix->accel = FB_ACCEL_XGI_XABRE;
1726 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
1728 DEBUGPRN("end of get_fix");
1732 static struct fb_ops XGIfb_ops = {
1733 .owner = THIS_MODULE,
1734 .fb_open = XGIfb_open,
1735 .fb_release = XGIfb_release,
1736 .fb_check_var = XGIfb_check_var,
1737 .fb_set_par = XGIfb_set_par,
1738 .fb_setcolreg = XGIfb_setcolreg,
1740 .fb_pan_display = XGIfb_pan_display,
1742 .fb_blank = XGIfb_blank,
1743 .fb_fillrect = fbcon_XGI_fillrect,
1744 .fb_copyarea = fbcon_XGI_copyarea,
1745 .fb_imageblit = cfb_imageblit,
1746 .fb_sync = fbcon_XGI_sync,
1747 .fb_ioctl = XGIfb_ioctl,
1748 /* .fb_mmap = XGIfb_mmap, */
1751 /* ---------------- Chip generation dependent routines ---------------- */
1753 /* for XGI 315/550/650/740/330 */
1755 static int XGIfb_get_dram_size(void)
1761 /* xorg driver sets 32MB * 1 channel */
1762 if (xgi_video_info.chip == XG27)
1763 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1765 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1766 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1767 case XGI_DRAM_SIZE_1MB:
1768 xgi_video_info.video_size = 0x100000;
1770 case XGI_DRAM_SIZE_2MB:
1771 xgi_video_info.video_size = 0x200000;
1773 case XGI_DRAM_SIZE_4MB:
1774 xgi_video_info.video_size = 0x400000;
1776 case XGI_DRAM_SIZE_8MB:
1777 xgi_video_info.video_size = 0x800000;
1779 case XGI_DRAM_SIZE_16MB:
1780 xgi_video_info.video_size = 0x1000000;
1782 case XGI_DRAM_SIZE_32MB:
1783 xgi_video_info.video_size = 0x2000000;
1785 case XGI_DRAM_SIZE_64MB:
1786 xgi_video_info.video_size = 0x4000000;
1788 case XGI_DRAM_SIZE_128MB:
1789 xgi_video_info.video_size = 0x8000000;
1791 case XGI_DRAM_SIZE_256MB:
1792 xgi_video_info.video_size = 0x10000000;
1798 tmp = (reg & 0x0c) >> 2;
1799 switch (xgi_video_info.chip) {
1835 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1836 /* PLiad fixed for benchmarking and fb set */
1837 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1838 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1840 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
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 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, 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 /* TW: PAL/NTSC changed for 650 */
1900 if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip
1903 inXGIIDXREG(XGICR, 0x38, temp);
1905 xgi_video_info.TV_type = TVMODE_PAL;
1907 xgi_video_info.TV_type = TVMODE_NTSC;
1911 inXGIIDXREG(XGICR, 0x79, temp);
1913 xgi_video_info.TV_type = TVMODE_PAL;
1915 xgi_video_info.TV_type = TVMODE_NTSC;
1919 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1920 if (XGIfb_forcecrt1 != -1) {
1921 if (XGIfb_forcecrt1)
1928 static void XGIfb_get_VB_type(void)
1932 if (!XGIfb_has_VB()) {
1933 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1934 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1935 case XGI310_EXTERNAL_CHIP_LVDS:
1936 xgi_video_info.hasVB = HASVB_LVDS;
1938 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1939 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1947 static int XGIfb_has_VB(void)
1951 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1952 switch (vb_chipid) {
1954 xgi_video_info.hasVB = HASVB_301;
1957 xgi_video_info.hasVB = HASVB_302;
1960 xgi_video_info.hasVB = HASVB_NONE;
1966 /* ------------------ Sensing routines ------------------ */
1968 /* TW: Determine and detect attached devices on XGI30x */
1969 int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
1973 outXGIIDXREG(XGIPART4, 0x11, tempbl);
1974 temp = tempbh | tempcl;
1975 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1976 for (i = 0; i < 10; i++)
1977 XGI_LongWait(&XGI_Pr);
1979 inXGIIDXREG(XGIPART4, 0x03, temp);
1985 void XGI_Sense30x(void)
1988 u8 testsvhs_tempbl, testsvhs_tempbh;
1989 u8 testsvhs_tempcl, testsvhs_tempch;
1990 u8 testcvbs_tempbl, testcvbs_tempbh;
1991 u8 testcvbs_tempcl, testcvbs_tempch;
1992 u8 testvga2_tempbl, testvga2_tempbh;
1993 u8 testvga2_tempcl, testvga2_tempch;
1996 inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1997 outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
1999 testvga2_tempbh = 0x00;
2000 testvga2_tempbl = 0xd1;
2001 testsvhs_tempbh = 0x00;
2002 testsvhs_tempbl = 0xb9;
2003 testcvbs_tempbh = 0x00;
2004 testcvbs_tempbl = 0xb3;
2005 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
2007 testvga2_tempbh = 0x01;
2008 testvga2_tempbl = 0x90;
2009 testsvhs_tempbh = 0x01;
2010 testsvhs_tempbl = 0x6b;
2011 testcvbs_tempbh = 0x01;
2012 testcvbs_tempbl = 0x74;
2013 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
2014 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
2015 testvga2_tempbh = 0x00;
2016 testvga2_tempbl = 0x00;
2017 testsvhs_tempbh = 0x02;
2018 testsvhs_tempbl = 0x00;
2019 testcvbs_tempbh = 0x01;
2020 testcvbs_tempbl = 0x00;
2023 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
2025 inXGIIDXREG(XGIPART4, 0x01, myflag);
2026 if (myflag & 0x04) {
2027 testvga2_tempbh = 0x00;
2028 testvga2_tempbl = 0xfd;
2029 testsvhs_tempbh = 0x00;
2030 testsvhs_tempbl = 0xdd;
2031 testcvbs_tempbh = 0x00;
2032 testcvbs_tempbl = 0xee;
2035 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
2036 == VB_CHIP_302LV)) {
2037 testvga2_tempbh = 0x00;
2038 testvga2_tempbl = 0x00;
2039 testvga2_tempch = 0x00;
2040 testvga2_tempcl = 0x00;
2041 testsvhs_tempch = 0x04;
2042 testsvhs_tempcl = 0x08;
2043 testcvbs_tempch = 0x08;
2044 testcvbs_tempcl = 0x08;
2046 testvga2_tempch = 0x0e;
2047 testvga2_tempcl = 0x08;
2048 testsvhs_tempch = 0x06;
2049 testsvhs_tempcl = 0x04;
2050 testcvbs_tempch = 0x08;
2051 testcvbs_tempcl = 0x04;
2054 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
2055 || testvga2_tempbl) {
2056 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2057 testvga2_tempcl, testvga2_tempch);
2059 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2060 orXGIIDXREG(XGICR, 0x32, 0x10);
2064 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
2067 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2068 /* TW: So we can be sure that there IS a SVHS output */
2069 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2070 orXGIIDXREG(XGICR, 0x32, 0x02);
2074 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2075 testcvbs_tempcl, testcvbs_tempch);
2077 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2078 /* TW: So we can be sure that there IS a CVBS output */
2079 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2080 orXGIIDXREG(XGICR, 0x32, 0x01);
2083 XGIDoSense(0, 0, 0, 0);
2085 outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
2088 /* ------------------------ Heap routines -------------------------- */
2090 static int XGIfb_heap_init(void)
2095 int agp_enabled = 1;
2097 unsigned long *cmdq_baseport = NULL;
2098 unsigned long *read_port = NULL;
2099 unsigned long *write_port = NULL;
2100 XGI_CMDTYPE cmd_type;
2102 struct agp_kern_info *agp_info;
2103 struct agp_memory *agp;
2107 /* TW: The heap start is either set manually using the "mem" parameter, or
2108 * defaults as follows:
2109 * -) If more than 16MB videoRAM available, let our heap start at 12MB.
2110 * -) If more than 8MB videoRAM available, let our heap start at 8MB.
2111 * -) If 4MB or less is available, let it start at 4MB.
2112 * This is for avoiding a clash with X driver which uses the beginning
2113 * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2115 * The heap start can also be specified by parameter "mem" when starting the XGIfb
2116 * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2118 if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) {
2119 if (xgi_video_info.video_size > 0x1000000)
2120 xgi_video_info.heapstart = 0xD00000;
2121 else if (xgi_video_info.video_size > 0x800000)
2122 xgi_video_info.heapstart = 0x800000;
2124 xgi_video_info.heapstart = 0x400000;
2126 xgi_video_info.heapstart = XGIfb_mem * 1024;
2128 XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase
2129 + xgi_video_info.heapstart);
2130 printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2131 (int)(xgi_video_info.heapstart / 1024));
2133 XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase
2134 + xgi_video_info.video_size;
2135 XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
2137 /* TW: Now initialize the 310 series' command queue mode.
2138 * On 310/325, there are three queue modes available which
2139 * are chosen by setting bits 7:5 in SR26:
2140 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2141 * track of the queue, the FIFO, command parsing and so
2142 * on. This is the one comparable to the 300 series.
2143 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2144 * have to do queue management himself. Register 0x85c4 will
2145 * hold the location of the next free queue slot, 0x85c8
2146 * is the "queue read pointer" whose way of working is
2147 * unknown to me. Anyway, this mode would require a
2148 * translation of the MMIO commands to some kind of
2149 * accelerator assembly and writing these commands
2150 * to the memory location pointed to by 0x85c4.
2151 * We will not use this, as nobody knows how this
2152 * "assembly" works, and as it would require a complete
2153 * re-write of the accelerator code.
2154 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2155 * queue in AGP memory space.
2157 * SR26 bit 4 is called "Bypass H/W queue".
2158 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2159 * SR26 bit 0 resets the queue
2160 * Size of queue memory is encoded in bits 3:2 like this:
2165 * The queue location is to be written to 0x85C0.
2168 cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase
2169 + MMIO_QUEUE_PHYBASE);
2170 write_port = (unsigned long *) (xgi_video_info.mmio_vbase
2171 + MMIO_QUEUE_WRITEPORT);
2172 read_port = (unsigned long *) (xgi_video_info.mmio_vbase
2173 + MMIO_QUEUE_READPORT);
2175 DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2177 agp_size = COMMAND_QUEUE_AREA_SIZE;
2180 if (XGIfb_queuemode == AGP_CMD_QUEUE) {
2181 agp_info = vmalloc(sizeof(*agp_info));
2182 memset((void *)agp_info, 0x00, sizeof(*agp_info));
2183 agp_copy_info(agp_info);
2185 agp_backend_acquire();
2187 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
2190 DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2193 if (agp_bind_memory(agp, agp->pg_start) != 0) {
2194 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2195 /* TODO: Free AGP memory here */
2206 /* TW: Now select the queue mode */
2208 if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2209 cmd_type = AGP_CMD_QUEUE;
2210 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
2211 /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
2212 } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
2213 cmd_type = VM_CMD_QUEUE;
2214 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2216 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2217 cmd_type = MMIO_CMD;
2222 temp = XGI_CMD_QUEUE_SIZE_512k;
2225 temp = XGI_CMD_QUEUE_SIZE_1M;
2228 temp = XGI_CMD_QUEUE_SIZE_2M;
2231 temp = XGI_CMD_QUEUE_SIZE_4M;
2238 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2239 agp_info->aper_base, agp->physical, agp_size/1024);
2241 agp_phys = agp_info->aper_base + agp->physical;
2243 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2244 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
2246 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2248 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2250 *write_port = *read_port;
2252 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2253 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2255 *cmdq_baseport = agp_phys;
2257 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2262 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2263 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2265 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2267 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2269 *write_port = *read_port;
2271 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2272 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2274 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2276 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2278 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2279 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2284 /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */
2285 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
2286 * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2287 * enough. Reserve memory in any way.
2289 /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */
2290 /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */
2292 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */
2293 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */
2295 /* FIXME *write_port = *read_port; */
2297 /* FIXME *//* TW: Set Auto_Correction bit */
2298 /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */
2299 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */
2301 /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */
2303 /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */
2305 /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */
2306 /* FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */
2310 /* TW: Now reserve memory for the HWCursor. It is always located at the very
2311 top of the videoRAM, right below the TB memory area (if used). */
2312 if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
2313 XGIfb_heap_end -= XGIfb_hwcursor_size;
2314 XGIfb_heap_size -= XGIfb_hwcursor_size;
2315 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2317 XGIfb_caps |= HW_CURSOR_CAP;
2319 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
2320 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2323 XGIfb_heap.poha_chain = NULL;
2324 XGIfb_heap.poh_freelist = NULL;
2326 poh = XGIfb_poh_new_node();
2331 poh->poh_next = &XGIfb_heap.oh_free;
2332 poh->poh_prev = &XGIfb_heap.oh_free;
2333 poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2334 poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
2336 DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
2337 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2338 (unsigned int) poh->size / 1024);
2340 DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
2341 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2343 XGIfb_heap.oh_free.poh_next = poh;
2344 XGIfb_heap.oh_free.poh_prev = poh;
2345 XGIfb_heap.oh_free.size = 0;
2346 XGIfb_heap.max_freesize = poh->size;
2348 XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2349 XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2350 XGIfb_heap.oh_used.size = SENTINEL;
2355 static XGI_OH *XGIfb_poh_new_node(void)
2362 if (XGIfb_heap.poh_freelist == NULL) {
2363 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
2367 poha->poha_next = XGIfb_heap.poha_chain;
2368 XGIfb_heap.poha_chain = poha;
2370 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH)
2373 poh = &poha->aoh[0];
2374 for (i = cOhs - 1; i != 0; i--) {
2375 poh->poh_next = poh + 1;
2379 poh->poh_next = NULL;
2380 XGIfb_heap.poh_freelist = &poha->aoh[0];
2383 poh = XGIfb_heap.poh_freelist;
2384 XGIfb_heap.poh_freelist = poh->poh_next;
2389 static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2395 if (size > XGIfb_heap.max_freesize) {
2396 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2397 (unsigned int) size / 1024);
2401 pohThis = XGIfb_heap.oh_free.poh_next;
2403 while (pohThis != &XGIfb_heap.oh_free) {
2404 if (size <= pohThis->size) {
2408 pohThis = pohThis->poh_next;
2412 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2413 (unsigned int) size / 1024);
2417 if (size == pohThis->size) {
2419 XGIfb_delete_node(pohThis);
2421 pohRoot = XGIfb_poh_new_node();
2423 if (pohRoot == NULL)
2426 pohRoot->offset = pohThis->offset;
2427 pohRoot->size = size;
2429 pohThis->offset += size;
2430 pohThis->size -= size;
2433 XGIfb_heap.max_freesize -= size;
2435 pohThis = &XGIfb_heap.oh_used;
2436 XGIfb_insert_node(pohThis, pohRoot);
2441 static void XGIfb_delete_node(XGI_OH *poh)
2446 poh_prev = poh->poh_prev;
2447 poh_next = poh->poh_next;
2449 poh_prev->poh_next = poh_next;
2450 poh_next->poh_prev = poh_prev;
2454 static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2458 pohTemp = pohList->poh_next;
2460 pohList->poh_next = poh;
2461 pohTemp->poh_prev = poh;
2463 poh->poh_prev = pohList;
2464 poh->poh_next = pohTemp;
2467 static XGI_OH *XGIfb_poh_free(unsigned long base)
2473 unsigned long ulUpper;
2474 unsigned long ulLower;
2477 poh_freed = XGIfb_heap.oh_used.poh_next;
2479 while (poh_freed != &XGIfb_heap.oh_used) {
2480 if (poh_freed->offset == base) {
2485 poh_freed = poh_freed->poh_next;
2491 XGIfb_heap.max_freesize += poh_freed->size;
2493 poh_prev = poh_next = NULL;
2494 ulUpper = poh_freed->offset + poh_freed->size;
2495 ulLower = poh_freed->offset;
2497 pohThis = XGIfb_heap.oh_free.poh_next;
2499 while (pohThis != &XGIfb_heap.oh_free) {
2500 if (pohThis->offset == ulUpper)
2502 else if ((pohThis->offset + pohThis->size) == ulLower)
2505 pohThis = pohThis->poh_next;
2508 XGIfb_delete_node(poh_freed);
2510 if (poh_prev && poh_next) {
2511 poh_prev->size += (poh_freed->size + poh_next->size);
2512 XGIfb_delete_node(poh_next);
2513 XGIfb_free_node(poh_freed);
2514 XGIfb_free_node(poh_next);
2519 poh_prev->size += poh_freed->size;
2520 XGIfb_free_node(poh_freed);
2525 poh_next->size += poh_freed->size;
2526 poh_next->offset = poh_freed->offset;
2527 XGIfb_free_node(poh_freed);
2531 XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2536 static void XGIfb_free_node(XGI_OH *poh)
2541 poh->poh_next = XGIfb_heap.poh_freelist;
2542 XGIfb_heap.poh_freelist = poh;
2546 void XGI_malloc(struct XGI_memreq *req)
2550 poh = XGIfb_poh_allocate(req->size);
2555 DPRINTK("XGIfb: Video RAM allocation failed\n");
2557 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
2558 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
2560 req->offset = poh->offset;
2561 req->size = poh->size;
2566 void XGI_free(unsigned long base)
2570 poh = XGIfb_poh_free(base);
2573 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
2574 (unsigned int) base);
2578 /* --------------------- SetMode routines ------------------------- */
2580 static void XGIfb_pre_setmode(void)
2582 u8 cr30 = 0, cr31 = 0;
2584 inXGIIDXREG(XGICR, 0x31, cr31);
2587 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2589 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2590 cr31 |= XGI_DRIVER_MODE;
2593 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
2594 cr31 |= XGI_DRIVER_MODE;
2597 if (xgi_video_info.TV_type == TVMODE_HIVISION)
2598 cr30 = (XGI_VB_OUTPUT_HIVISION
2599 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2600 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
2601 cr30 = (XGI_VB_OUTPUT_SVIDEO
2602 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2603 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
2604 cr30 = (XGI_VB_OUTPUT_COMPOSITE
2605 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2606 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
2607 cr30 = (XGI_VB_OUTPUT_SCART
2608 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2609 cr31 |= XGI_DRIVER_MODE;
2611 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
2616 default: /* disable CRT2 */
2618 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2621 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2622 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
2623 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
2625 if (xgi_video_info.accel)
2630 static void XGIfb_post_setmode(void)
2633 unsigned char doit = 1;
2635 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2636 outXGIIDXREG(XGICR, 0x13, 0x00);
2637 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
2640 if (xgi_video_info.video_bpp == 8) {
2641 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
2642 if ((xgi_video_info.hasVB == HASVB_LVDS)
2643 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
2646 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
2647 if (xgi_video_info.disp_state & DISPTYPE_LCD)
2651 /* TW: We can't switch off CRT1 if bridge is in slave mode */
2652 if (xgi_video_info.hasVB != HASVB_NONE) {
2653 inXGIIDXREG(XGIPART1, 0x00, reg);
2655 if ((reg & 0x50) == 0x10)
2662 inXGIIDXREG(XGICR, 0x17, reg);
2663 if ((XGIfb_crt1off) && (doit))
2667 outXGIIDXREG(XGICR, 0x17, reg);
2669 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
2671 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
2674 inXGIIDXREG(XGIPART4, 0x01, reg);
2676 if (reg < 0xB0) { /* Set filter for XGI301 */
2678 switch (xgi_video_info.video_width) {
2680 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2683 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2686 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2689 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2696 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
2698 if (xgi_video_info.TV_type == TVMODE_NTSC) {
2700 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
2702 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2704 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
2706 } else if (xgi_video_info.TV_plug
2707 == TVPLUG_COMPOSITE) {
2709 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2711 switch (xgi_video_info.video_width) {
2713 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2714 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2715 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2716 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2719 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2720 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2721 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2722 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2725 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2726 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2727 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2728 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2733 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2735 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2737 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2739 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2741 } else if (xgi_video_info.TV_plug
2742 == TVPLUG_COMPOSITE) {
2744 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2746 switch (xgi_video_info.video_width) {
2748 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2749 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2750 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2751 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2754 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2755 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2756 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2757 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2760 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2761 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2762 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2763 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2769 if ((filter >= 0) && (filter <= 7)) {
2770 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2771 XGI_TV_filter[filter_tb].filter[filter][0],
2772 XGI_TV_filter[filter_tb].filter[filter][1],
2773 XGI_TV_filter[filter_tb].filter[filter][2],
2774 XGI_TV_filter[filter_tb].filter[filter][3]
2779 (XGI_TV_filter[filter_tb].filter[filter][0]));
2783 (XGI_TV_filter[filter_tb].filter[filter][1]));
2787 (XGI_TV_filter[filter_tb].filter[filter][2]));
2791 (XGI_TV_filter[filter_tb].filter[filter][3]));
2800 XGIINITSTATIC int __init XGIfb_setup(char *options)
2804 xgi_video_info.refresh_rate = 0;
2806 printk(KERN_INFO "XGIfb: Options %s\n", options);
2808 if (!options || !*options)
2811 while ((this_opt = strsep(&options, ",")) != NULL) {
2816 if (!strncmp(this_opt, "mode:", 5)) {
2817 XGIfb_search_mode(this_opt + 5);
2818 } else if (!strncmp(this_opt, "vesa:", 5)) {
2819 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2820 } else if (!strncmp(this_opt, "mode:", 5)) {
2821 XGIfb_search_mode(this_opt + 5);
2822 } else if (!strncmp(this_opt, "vesa:", 5)) {
2823 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2824 } else if (!strncmp(this_opt, "vrate:", 6)) {
2825 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2826 } else if (!strncmp(this_opt, "rate:", 5)) {
2827 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2828 } else if (!strncmp(this_opt, "off", 3)) {
2830 } else if (!strncmp(this_opt, "crt1off", 7)) {
2832 } else if (!strncmp(this_opt, "filter:", 7)) {
2833 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2834 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2835 XGIfb_search_crt2type(this_opt + 14);
2836 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2837 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2838 } else if (!strncmp(this_opt, "tvmode:", 7)) {
2839 XGIfb_search_tvstd(this_opt + 7);
2840 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2841 XGIfb_search_tvstd(this_opt + 7);
2842 } else if (!strncmp(this_opt, "mem:", 4)) {
2843 XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2844 } else if (!strncmp(this_opt, "dstn", 4)) {
2846 /* TW: DSTN overrules forcecrt2type */
2847 XGIfb_crt2type = DISPTYPE_LCD;
2848 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2849 XGIfb_search_queuemode(this_opt + 10);
2850 } else if (!strncmp(this_opt, "pdc:", 4)) {
2851 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2852 if (XGIfb_pdc & ~0x3c) {
2853 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2856 } else if (!strncmp(this_opt, "noaccel", 7)) {
2858 } else if (!strncmp(this_opt, "noypan", 6)) {
2860 } else if (!strncmp(this_opt, "userom:", 7)) {
2861 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2862 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2863 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
2865 XGIfb_search_mode(this_opt);
2866 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
2869 /* TW: Acceleration only with MMIO mode */
2870 if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
2874 /* TW: Panning only with acceleration */
2875 if (XGIfb_accel == 0)
2879 printk("\nxgifb: outa xgifb_setup 3450");
2883 static unsigned char VBIOS_BUF[65535];
2885 static unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
2888 u32 rom_address = 0;
2891 /* Get the size of the expansion rom */
2892 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
2893 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
2894 if ((rom_size & 0x01) == 0) {
2899 rom_size &= 0xFFFFF800;
2900 rom_size = (~rom_size) + 1;
2902 rom_address = pci_resource_start(dev, 0);
2903 if (rom_address == 0 || rom_address == 0xFFFFFFF0) {
2904 printk("No suitable rom address found\n");
2908 printk("ROM Size is %dK, Address is %x\n", rom_size / 1024, rom_address);
2911 pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address
2912 | PCI_ROM_ADDRESS_ENABLE);
2914 /* memcpy(copy_address, rom_address, rom_size); */
2916 unsigned char *virt_addr = ioremap(rom_address, 0x8000000);
2918 unsigned char *from = (unsigned char *) virt_addr;
2919 unsigned char *to = (unsigned char *) copy_address;
2920 for (j = 0; j < 65536 /*rom_size*/; j++)
2924 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
2926 printk("Copy is done\n");
2928 return copy_address;
2931 static int __devinit xgifb_probe(struct pci_dev *pdev,
2932 const struct pci_device_id *ent)
2940 XGIfb_registered = 0;
2942 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2943 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2947 xgi_video_info.chip_id = pdev->device;
2948 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2949 pci_read_config_word(pdev, PCI_COMMAND, ®16);
2950 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2951 XGIvga_enabled = reg16 & 0x01;
2953 xgi_video_info.pcibus = pdev->bus->number;
2954 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2955 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2956 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2957 xgi_video_info.subsysdevice = pdev->subsystem_device;
2959 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2960 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2961 XGIfb_mmio_size = pci_resource_len(pdev, 1);
2962 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2963 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2964 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2965 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2966 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2968 if (pci_enable_device(pdev))
2971 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2973 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2974 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
2976 if (reg1 != 0xa1) { /*I/O error */
2977 printk("\nXGIfb: I/O error!!!");
2981 switch (xgi_video_info.chip_id) {
2982 case PCI_DEVICE_ID_XG_20:
2983 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2984 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2985 if (CR48&GPIOG_READ)
2986 xgi_video_info.chip = XG21;
2988 xgi_video_info.chip = XG20;
2989 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2990 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2992 case PCI_DEVICE_ID_XG_40:
2993 xgi_video_info.chip = XG40;
2994 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2995 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2997 case PCI_DEVICE_ID_XG_41:
2998 xgi_video_info.chip = XG41;
2999 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3000 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3002 case PCI_DEVICE_ID_XG_42:
3003 xgi_video_info.chip = XG42;
3004 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3005 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3007 case PCI_DEVICE_ID_XG_27:
3008 xgi_video_info.chip = XG27;
3009 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3010 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3016 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
3017 XGIhw_ext.jChipType = xgi_video_info.chip;
3019 switch (xgi_video_info.chip) {
3027 XGIhw_ext.bIntegratedMMEnabled = 1;
3033 XGIhw_ext.pDevice = NULL;
3034 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
3035 XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
3037 if (XGIhw_ext.pjVirtualRomBase)
3038 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
3040 printk(KERN_INFO "XGIfb: Video ROM not found\n");
3042 XGIhw_ext.pjVirtualRomBase = NULL;
3043 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
3045 XGIhw_ext.pjCustomizedROMImage = NULL;
3046 XGIhw_ext.bSkipDramSizing = 0;
3047 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
3048 /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */
3049 strcpy(XGIhw_ext.szVBIOSVer, "0.84");
3051 XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
3052 if (XGIhw_ext.pSR == NULL) {
3053 printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
3056 XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
3058 XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
3059 if (XGIhw_ext.pCR == NULL) {
3060 vfree(XGIhw_ext.pSR);
3061 printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
3064 XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
3066 if (!XGIvga_enabled) {
3067 /* Mapping Max FB Size for 315 Init */
3068 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3069 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3071 printk("XGIfb: XGIInit() ...");
3072 /* XGIInitNewt for LINUXBIOS only */
3073 if (XGIInitNew(&XGIhw_ext))
3079 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3085 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3086 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3088 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3090 /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
3091 /* Set SR13 ,14 temporarily for UDtech */
3092 outXGIIDXREG(XGISR, 0x13, 0x45);
3093 outXGIIDXREG(XGISR, 0x14, 0x51);
3098 if (XGIfb_get_dram_size()) {
3099 vfree(XGIhw_ext.pSR);
3100 vfree(XGIhw_ext.pCR);
3101 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
3105 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3106 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
3107 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3108 /* Enable 2D accelerator engine */
3109 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3112 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3114 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
3115 printk("unable request memory size %x", xgi_video_info.video_size);
3116 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3117 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
3118 vfree(XGIhw_ext.pSR);
3119 vfree(XGIhw_ext.pCR);
3123 if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) {
3124 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
3125 release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
3126 vfree(XGIhw_ext.pSR);
3127 vfree(XGIhw_ext.pCR);
3131 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3132 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
3133 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
3135 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3136 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
3138 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
3139 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, XGIfb_mmio_size / 1024);
3140 printk("XGIfb: XGIInitNew() ...");
3141 if (XGIInitNew(&XGIhw_ext))
3146 if (XGIfb_heap_init())
3147 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
3149 xgi_video_info.mtrr = (unsigned int) 0;
3151 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3152 xgi_video_info.hasVB = HASVB_NONE;
3153 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
3154 xgi_video_info.hasVB = HASVB_NONE;
3155 } else if (xgi_video_info.chip == XG21) {
3156 inXGIIDXREG(XGICR, 0x38, CR38);
3157 if ((CR38&0xE0) == 0xC0) {
3158 xgi_video_info.disp_state = DISPTYPE_LCD;
3159 if (!XGIfb_GetXG21LVDSData()) {
3161 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
3162 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3163 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3164 XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
3168 } else if ((CR38&0xE0) == 0x60) {
3169 xgi_video_info.hasVB = HASVB_CHRONTEL;
3171 xgi_video_info.hasVB = HASVB_NONE;
3174 XGIfb_get_VB_type();
3177 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
3179 XGIhw_ext.ulExternalChip = 0;
3181 switch (xgi_video_info.hasVB) {
3183 inXGIIDXREG(XGIPART4, 0x01, reg);
3185 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3186 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3187 } else if (reg >= 0xD0) {
3188 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3189 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
3191 /* else if (reg >= 0xB0) {
3192 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
3193 inXGIIDXREG(XGIPART4, 0x23, reg1);
3194 printk("XGIfb: XGI301B bridge detected\n");
3197 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3198 printk("XGIfb: XGI301 bridge detected\n");
3202 inXGIIDXREG(XGIPART4, 0x01, reg);
3204 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3205 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3206 } else if (reg >= 0xD0) {
3207 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3208 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3209 } else if (reg >= 0xB0) {
3210 inXGIIDXREG(XGIPART4, 0x23, reg1);
3212 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
3215 XGIhw_ext.ujVBChipID = VB_CHIP_302;
3216 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3220 XGIhw_ext.ulExternalChip = 0x1;
3221 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3223 case HASVB_TRUMPION:
3224 XGIhw_ext.ulExternalChip = 0x2;
3225 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3227 case HASVB_CHRONTEL:
3228 XGIhw_ext.ulExternalChip = 0x4;
3229 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3231 case HASVB_LVDS_CHRONTEL:
3232 XGIhw_ext.ulExternalChip = 0x5;
3233 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3236 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3240 if (xgi_video_info.hasVB != HASVB_NONE)
3243 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3245 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3247 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3249 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3252 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
3254 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3256 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
3260 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3264 XGIfb_detectedpdc = 0;
3266 XGIfb_detectedlcda = 0xff;
3269 /* TW: Try to find about LCDA */
3271 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3272 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3273 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
3275 inXGIIDXREG(XGICR, 0x34, tmp);
3277 /* Currently on LCDA? (Some BIOSes leave CR38) */
3278 inXGIIDXREG(XGICR, 0x38, tmp);
3279 if ((tmp & 0x03) == 0x03) {
3280 /* XGI_Pr.XGI_UseLCDA = 1; */
3282 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
3283 inXGIIDXREG(XGICR, 0x35, tmp);
3285 /* XGI_Pr.XGI_UseLCDA = 1; */
3287 inXGIIDXREG(XGICR, 0x30, tmp);
3289 inXGIIDXREG(XGIPART1, 0x13, tmp);
3291 /* XGI_Pr.XGI_UseLCDA = 1; */
3302 if (xgifb_mode_idx >= 0)
3303 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3305 if (xgifb_mode_idx < 0) {
3306 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3308 xgifb_mode_idx = DEFAULT_LCDMODE;
3309 if (xgi_video_info.chip == XG21)
3310 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
3313 xgifb_mode_idx = DEFAULT_TVMODE;
3316 xgifb_mode_idx = DEFAULT_MODE;
3321 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3323 if (xgi_video_info.refresh_rate == 0)
3324 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
3325 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
3326 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3327 xgi_video_info.refresh_rate = 60;
3330 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3331 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3332 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3333 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3334 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
3335 switch (xgi_video_info.video_bpp) {
3337 xgi_video_info.DstColor = 0x0000;
3338 xgi_video_info.XGI310_AccelDepth = 0x00000000;
3339 xgi_video_info.video_cmap_len = 256;
3342 xgi_video_info.DstColor = 0x8000;
3343 xgi_video_info.XGI310_AccelDepth = 0x00010000;
3344 xgi_video_info.video_cmap_len = 16;
3347 xgi_video_info.DstColor = 0xC000;
3348 xgi_video_info.XGI310_AccelDepth = 0x00020000;
3349 xgi_video_info.video_cmap_len = 16;
3352 xgi_video_info.video_cmap_len = 16;
3353 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
3357 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
3358 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3359 xgi_video_info.refresh_rate);
3361 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3362 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3363 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3365 XGIfb_bpp_to_var(&default_var);
3367 default_var.pixclock = (u32) (1000000000 /
3368 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3369 XGIfb_mode_no, XGIfb_rate_idx));
3371 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3372 XGIfb_mode_no, XGIfb_rate_idx,
3373 &default_var.left_margin, &default_var.right_margin,
3374 &default_var.upper_margin, &default_var.lower_margin,
3375 &default_var.hsync_len, &default_var.vsync_len,
3376 &default_var.sync, &default_var.vmode)) {
3378 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3379 default_var.yres <<= 1;
3380 default_var.yres_virtual <<= 1;
3381 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3382 default_var.pixclock >>= 1;
3383 default_var.yres >>= 1;
3384 default_var.yres_virtual >>= 1;
3389 xgi_video_info.accel = 0;
3391 xgi_video_info.accel = -1;
3392 default_var.accel_flags |= FB_ACCELF_TEXT;
3396 fb_info->flags = FBINFO_FLAG_DEFAULT;
3397 fb_info->var = default_var;
3398 fb_info->fix = XGIfb_fix;
3399 fb_info->par = &xgi_video_info;
3400 fb_info->screen_base = xgi_video_info.video_vbase;
3401 fb_info->fbops = &XGIfb_ops;
3402 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3403 fb_info->pseudo_palette = pseudo_palette;
3405 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3408 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3409 (unsigned int) xgi_video_info.video_size,
3410 MTRR_TYPE_WRCOMB, 1);
3411 if (xgi_video_info.mtrr)
3412 printk(KERN_INFO "XGIfb: Added MTRRs\n");
3415 if (register_framebuffer(fb_info) < 0)
3418 XGIfb_registered = 1;
3420 printk(KERN_INFO "XGIfb: Installed XGIFB_GET_INFO ioctl (%lx)\n",
3423 /* printk(KERN_INFO "XGIfb: 2D acceleration is %s, scrolling mode %s\n",
3424 XGIfb_accel ? "enabled" : "disabled",
3425 XGIfb_ypan ? "ypan" : "redraw");
3427 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
3428 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
3437 /*****************************************************/
3438 /* PCI DEVICE HANDLING */
3439 /*****************************************************/
3441 static void __devexit xgifb_remove(struct pci_dev *pdev)
3443 /* Unregister the framebuffer */
3444 /* if (xgi_video_info.registered) { */
3445 unregister_framebuffer(fb_info);
3446 framebuffer_release(fb_info);
3449 pci_set_drvdata(pdev, NULL);
3453 static struct pci_driver xgifb_driver = {
3455 .id_table = xgifb_pci_table,
3456 .probe = xgifb_probe,
3457 .remove = __devexit_p(xgifb_remove)
3460 XGIINITSTATIC int __init xgifb_init(void)
3462 char *option = NULL;
3464 if (fb_get_options("xgifb", &option))
3466 XGIfb_setup(option);
3468 return pci_register_driver(&xgifb_driver);
3472 module_init(xgifb_init);
3475 /*****************************************************/
3477 /*****************************************************/
3481 static char *mode = NULL;
3482 static int vesa = 0;
3483 static unsigned int rate = 0;
3484 static unsigned int mem = 0;
3485 static char *forcecrt2type = NULL;
3486 static int forcecrt1 = -1;
3487 static int pdc = -1;
3488 static int pdc1 = -1;
3489 static int noaccel = -1;
3490 static int noypan = -1;
3491 static int nomax = -1;
3492 static int userom = -1;
3493 static int useoem = -1;
3494 static char *tvstandard = NULL;
3495 static int nocrt2rate = 0;
3496 static int scalelcd = -1;
3497 static char *specialtiming = NULL;
3498 static int lvdshl = -1;
3499 static int tvxposoffset = 0, tvyposoffset = 0;
3500 #if !defined(__i386__) && !defined(__x86_64__)
3501 static int resetcard = 0;
3502 static int videoram = 0;
3505 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3506 MODULE_LICENSE("GPL");
3507 MODULE_AUTHOR("XGITECH , Others");
3509 module_param(mem, int, 0);
3510 module_param(noaccel, int, 0);
3511 module_param(noypan, int, 0);
3512 module_param(nomax, int, 0);
3513 module_param(userom, int, 0);
3514 module_param(useoem, int, 0);
3515 module_param(mode, charp, 0);
3516 module_param(vesa, int, 0);
3517 module_param(rate, int, 0);
3518 module_param(forcecrt1, int, 0);
3519 module_param(forcecrt2type, charp, 0);
3520 module_param(scalelcd, int, 0);
3521 module_param(pdc, int, 0);
3522 module_param(pdc1, int, 0);
3523 module_param(specialtiming, charp, 0);
3524 module_param(lvdshl, int, 0);
3525 module_param(tvstandard, charp, 0);
3526 module_param(tvxposoffset, int, 0);
3527 module_param(tvyposoffset, int, 0);
3528 module_param(filter, int, 0);
3529 module_param(nocrt2rate, int, 0);
3530 #if !defined(__i386__) && !defined(__x86_64__)
3531 module_param(resetcard, int, 0);
3532 module_param(videoram, int, 0);
3535 MODULE_PARM_DESC(mem,
3536 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3537 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3538 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3539 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3540 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3541 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3542 "for XFree86 4.x/X.org 6.7 and later.\n");
3544 MODULE_PARM_DESC(noaccel,
3545 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3548 MODULE_PARM_DESC(noypan,
3549 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3550 "will be performed by redrawing the screen. (default: 0)\n");
3552 MODULE_PARM_DESC(nomax,
3553 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3554 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3555 "this is set to anything other than 0, xgifb will not do this and thereby\n"
3556 "enable the user to positively specify a virtual Y size of the screen using\n"
3557 "fbset. (default: 0)\n");
3559 MODULE_PARM_DESC(mode,
3560 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3561 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3562 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3563 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
3565 MODULE_PARM_DESC(vesa,
3566 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3567 "0x117 (default: 0x0103)\n");
3569 MODULE_PARM_DESC(rate,
3570 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3571 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3572 "will be ignored (default: 60)\n");
3574 MODULE_PARM_DESC(forcecrt1,
3575 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
3576 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3577 "0=CRT1 OFF) (default: [autodetected])\n");
3579 MODULE_PARM_DESC(forcecrt2type,
3580 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3581 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3582 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3583 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3584 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3585 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3586 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3587 "depends on the very hardware in use. (default: [autodetected])\n");
3589 MODULE_PARM_DESC(scalelcd,
3590 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3591 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3592 "show black bars around the image, TMDS panels will probably do the scaling\n"
3593 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
3595 MODULE_PARM_DESC(pdc,
3596 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3597 "should detect this correctly in most cases; however, sometimes this is not\n"
3598 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3599 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3600 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3601 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
3603 MODULE_PARM_DESC(pdc1,
3604 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3605 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3606 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3607 "implemented yet.\n");
3609 MODULE_PARM_DESC(specialtiming,
3610 "\nPlease refer to documentation for more information on this option.\n");
3612 MODULE_PARM_DESC(lvdshl,
3613 "\nPlease refer to documentation for more information on this option.\n");
3615 MODULE_PARM_DESC(tvstandard,
3616 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3617 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
3619 MODULE_PARM_DESC(tvxposoffset,
3620 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3623 MODULE_PARM_DESC(tvyposoffset,
3624 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3627 MODULE_PARM_DESC(filter,
3628 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3629 "(Possible values 0-7, default: [no filter])\n");
3631 MODULE_PARM_DESC(nocrt2rate,
3632 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3633 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
3635 static int __init xgifb_init_module(void)
3637 printk("\nXGIfb_init_module");
3639 XGIfb_search_mode(mode);
3640 else if (vesa != -1)
3641 XGIfb_search_vesamode(vesa);
3643 return xgifb_init();
3646 static void __exit xgifb_remove_module(void)
3648 pci_unregister_driver(&xgifb_driver);
3649 printk(KERN_DEBUG "xgifb: Module unloaded\n");
3652 module_init(xgifb_init_module);
3653 module_exit(xgifb_remove_module);
3655 #endif /* /MODULE */
3657 EXPORT_SYMBOL(XGI_malloc);
3658 EXPORT_SYMBOL(XGI_free);