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_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
483 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
489 pci_read_config_dword(pdev, offset, (u32 *)value);
491 pci_write_config_dword(pdev, offset, (u32)(*value));
496 /* ------------------ Internal helper routines ----------------- */
498 static void XGIfb_search_mode(const char *name)
503 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
504 xgifb_mode_idx = DEFAULT_MODE;
505 if ((xgi_video_info.chip == XG21)
506 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
508 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
513 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
514 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
515 xgifb_mode_idx = DEFAULT_MODE;
516 if ((xgi_video_info.chip == XG21)
517 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
519 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
524 while (XGIbios_mode[i].mode_no != 0) {
525 l = min(strlen(name), strlen(XGIbios_mode[i].name));
526 if (!strncmp(name, XGIbios_mode[i].name, l)) {
534 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
537 static void XGIfb_search_vesamode(unsigned int vesamode)
543 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
544 xgifb_mode_idx = DEFAULT_MODE;
545 if ((xgi_video_info.chip == XG21)
546 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
548 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
553 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
555 while (XGIbios_mode[i].mode_no != 0) {
556 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
557 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
565 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
568 static int XGIfb_GetXG21LVDSData(void)
571 unsigned char *pData;
574 inXGIIDXREG(XGISR, 0x1e, tmp);
575 outXGIIDXREG(XGISR, 0x1e, tmp | 4);
577 pData = xgi_video_info.mmio_vbase + 0x20000;
578 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
579 i = pData[0x316] | (pData[0x317] << 8);
586 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
587 | (pData[i + 1] << 8);
588 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
590 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
592 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
594 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
596 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
598 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
600 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
601 | (pData[i + 15] << 8);
602 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
603 | (pData[i + 17] << 8);
604 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
605 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
606 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
607 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
608 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
609 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
610 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
614 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
615 / sizeof(struct XGI21_LVDSCapStruct))));
621 int XGIfb_GetXG21DefaultLVDSModeIdx(void)
625 int XGIfb_mode_idx = 0;
628 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
629 && (XGIbios_mode[XGIfb_mode_idx].xres
630 <= XGI21_LCDCapList[0].LVDSHDE)) {
631 if ((XGIbios_mode[XGIfb_mode_idx].xres
632 == XGI21_LCDCapList[0].LVDSHDE)
633 && (XGIbios_mode[XGIfb_mode_idx].yres
634 == XGI21_LCDCapList[0].LVDSVDE)
635 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
636 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
645 return XGIfb_mode_idx;
648 static int XGIfb_validate_mode(int myindex)
652 if (xgi_video_info.chip == XG21) {
653 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
655 xres = XGI21_LCDCapList[0].LVDSHDE;
656 yres = XGI21_LCDCapList[0].LVDSVDE;
657 if (XGIbios_mode[myindex].xres > xres)
659 if (XGIbios_mode[myindex].yres > yres)
661 if ((XGIbios_mode[myindex].xres < xres)
662 && (XGIbios_mode[myindex].yres < yres)) {
663 if (XGIbios_mode[myindex].bpp > 8)
672 /* FIXME: for now, all is valid on XG27 */
673 if (xgi_video_info.chip == XG27)
676 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
679 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
681 switch (XGIhw_ext.ulCRT2LCDType) {
722 /* case LCD_320x480: */ /* TW: FSTN */
733 if (XGIbios_mode[myindex].xres > xres)
735 if (XGIbios_mode[myindex].yres > yres)
737 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
738 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
739 switch (XGIbios_mode[myindex].xres) {
741 if (XGIbios_mode[myindex].yres != 512)
743 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
747 if ((XGIbios_mode[myindex].yres != 400)
748 && (XGIbios_mode[myindex].yres
753 if (XGIbios_mode[myindex].yres != 600)
757 if ((XGIbios_mode[myindex].yres != 600)
758 && (XGIbios_mode[myindex].yres
761 if ((XGIbios_mode[myindex].yres == 600)
762 && (XGIhw_ext.ulCRT2LCDType
767 if ((XGIbios_mode[myindex].yres) != 768)
769 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
773 if ((XGIbios_mode[myindex].yres != 768)
774 && (XGIbios_mode[myindex].yres
777 if ((XGIbios_mode[myindex].yres == 768)
778 && (XGIhw_ext.ulCRT2LCDType
783 if (XGIbios_mode[myindex].yres != 1050)
787 if (XGIbios_mode[myindex].yres != 1200)
794 switch (XGIbios_mode[myindex].xres) {
796 if (XGIbios_mode[myindex].yres != 512)
800 if ((XGIbios_mode[myindex].yres != 400)
801 && (XGIbios_mode[myindex].yres
806 if (XGIbios_mode[myindex].yres != 600)
810 if (XGIbios_mode[myindex].yres != 768)
814 if ((XGIbios_mode[myindex].yres != 960)
815 && (XGIbios_mode[myindex].yres
818 if (XGIbios_mode[myindex].yres == 960) {
819 if (XGIhw_ext.ulCRT2LCDType
825 if (XGIbios_mode[myindex].yres != 1050)
829 if (XGIbios_mode[myindex].yres != 1200)
838 switch (XGIbios_mode[myindex].xres) {
844 if (xgi_video_info.TV_type == TVMODE_NTSC) {
845 if (XGIbios_mode[myindex].yres != 480)
847 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
848 if (XGIbios_mode[myindex].yres != 576)
851 /* TW: LVDS/CHRONTEL does not support 720 */
852 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
853 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
858 if (xgi_video_info.TV_type == TVMODE_NTSC) {
859 if (XGIbios_mode[myindex].bpp == 32)
862 /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */
863 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
864 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
865 if (xgi_video_info.chip < XGI_315H)
874 if (XGIbios_mode[myindex].xres > 1280)
882 static void XGIfb_search_crt2type(const char *name)
889 while (XGI_crt2type[i].type_no != -1) {
890 if (!strcmp(name, XGI_crt2type[i].name)) {
891 XGIfb_crt2type = XGI_crt2type[i].type_no;
892 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
897 if (XGIfb_crt2type < 0)
898 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
901 static void XGIfb_search_queuemode(const char *name)
908 while (XGI_queuemode[i].type_no != -1) {
909 if (!strcmp(name, XGI_queuemode[i].name)) {
910 XGIfb_queuemode = XGI_queuemode[i].type_no;
915 if (XGIfb_queuemode < 0)
916 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
919 static u8 XGIfb_search_refresh_rate(unsigned int rate)
924 xres = XGIbios_mode[xgifb_mode_idx].xres;
925 yres = XGIbios_mode[xgifb_mode_idx].yres;
928 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
929 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
931 if (XGIfb_vrate[i].refresh == rate) {
932 XGIfb_rate_idx = XGIfb_vrate[i].idx;
934 } else if (XGIfb_vrate[i].refresh > rate) {
935 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
936 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
937 rate, XGIfb_vrate[i].refresh);
938 XGIfb_rate_idx = XGIfb_vrate[i].idx;
939 xgi_video_info.refresh_rate
940 = XGIfb_vrate[i].refresh;
941 } else if (((rate - XGIfb_vrate[i - 1].refresh)
942 <= 2) && (XGIfb_vrate[i].idx
944 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
945 rate, XGIfb_vrate[i-1].refresh);
946 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
947 xgi_video_info.refresh_rate
948 = XGIfb_vrate[i - 1].refresh;
951 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
952 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
953 rate, XGIfb_vrate[i].refresh);
954 XGIfb_rate_idx = XGIfb_vrate[i].idx;
960 if (XGIfb_rate_idx > 0) {
961 return XGIfb_rate_idx;
964 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
969 static void XGIfb_search_tvstd(const char *name)
976 while (XGI_tvtype[i].type_no != -1) {
977 if (!strcmp(name, XGI_tvtype[i].name)) {
978 XGIfb_tvmode = XGI_tvtype[i].type_no;
985 static unsigned char XGIfb_bridgeisslave(void)
987 unsigned char usScratchP1_00;
989 if (xgi_video_info.hasVB == HASVB_NONE)
992 inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00);
993 if ((usScratchP1_00 & 0x50) == 0x10)
999 static unsigned char XGIfbcheckvretracecrt1(void)
1003 inXGIIDXREG(XGICR, 0x17, temp);
1007 inXGIIDXREG(XGISR, 0x1f, temp);
1011 if (inXGIREG(XGIINPSTAT) & 0x08)
1017 static unsigned char XGIfbcheckvretracecrt2(void)
1020 if (xgi_video_info.hasVB == HASVB_NONE)
1022 inXGIIDXREG(XGIPART1, 0x30, temp);
1029 static unsigned char XGIfb_CheckVBRetrace(void)
1031 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1032 if (XGIfb_bridgeisslave())
1033 return XGIfbcheckvretracecrt1();
1035 return XGIfbcheckvretracecrt2();
1037 return XGIfbcheckvretracecrt1();
1040 /* ----------- FBDev related routines for all series ----------- */
1042 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1044 switch (var->bits_per_pixel) {
1046 var->red.offset = var->green.offset = var->blue.offset = 0;
1047 var->red.length = var->green.length = var->blue.length = 6;
1048 xgi_video_info.video_cmap_len = 256;
1051 var->red.offset = 11;
1052 var->red.length = 5;
1053 var->green.offset = 5;
1054 var->green.length = 6;
1055 var->blue.offset = 0;
1056 var->blue.length = 5;
1057 var->transp.offset = 0;
1058 var->transp.length = 0;
1059 xgi_video_info.video_cmap_len = 16;
1062 var->red.offset = 16;
1063 var->red.length = 8;
1064 var->green.offset = 8;
1065 var->green.length = 8;
1066 var->blue.offset = 0;
1067 var->blue.length = 8;
1068 var->transp.offset = 24;
1069 var->transp.length = 8;
1070 xgi_video_info.video_cmap_len = 16;
1075 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1076 struct fb_info *info)
1079 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1081 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1083 #if defined(__powerpc__)
1084 u8 sr_data, cr_data;
1086 unsigned int drate = 0, hrate = 0;
1089 /* unsigned char reg, reg1; */
1091 DEBUGPRN("Inside do_set_var");
1092 /* 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); */
1094 info->var.xres_virtual = var->xres_virtual;
1095 info->var.yres_virtual = var->yres_virtual;
1096 info->var.bits_per_pixel = var->bits_per_pixel;
1098 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1100 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1102 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1104 /* var->yres <<= 1; */
1107 if (!htotal || !vtotal) {
1108 DPRINTK("XGIfb: Invalid 'var' information\n");
1110 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1111 var->pixclock, htotal, vtotal);
1113 if (var->pixclock && htotal && vtotal) {
1114 drate = 1000000000 / var->pixclock;
1115 hrate = (drate * 1000) / htotal;
1116 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1119 xgi_video_info.refresh_rate = 60;
1122 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1123 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
1125 old_mode = xgifb_mode_idx;
1128 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1129 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1130 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1131 && (XGIbios_mode[xgifb_mode_idx].yres
1133 && (XGIbios_mode[xgifb_mode_idx].bpp
1134 == var->bits_per_pixel)) {
1135 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1143 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1145 xgifb_mode_idx = -1;
1147 if (xgifb_mode_idx < 0) {
1148 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1149 var->yres, var->bits_per_pixel);
1150 xgifb_mode_idx = old_mode;
1154 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1155 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1156 xgi_video_info.refresh_rate = 60;
1161 XGIfb_pre_setmode();
1162 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1163 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1166 info->fix.line_length = ((info->var.xres_virtual
1167 * info->var.bits_per_pixel) >> 6);
1169 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1171 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1172 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
1174 XGIfb_post_setmode();
1176 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1177 XGIbios_mode[xgifb_mode_idx].xres,
1178 XGIbios_mode[xgifb_mode_idx].yres,
1179 XGIbios_mode[xgifb_mode_idx].bpp,
1180 xgi_video_info.refresh_rate);
1182 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1183 xgi_video_info.video_vwidth = info->var.xres_virtual;
1184 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1185 xgi_video_info.video_vheight = info->var.yres_virtual;
1186 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1187 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1188 xgi_video_info.video_linelength = info->var.xres_virtual
1189 * (xgi_video_info.video_bpp >> 3);
1190 xgi_video_info.accel = 0;
1192 xgi_video_info.accel = (var->accel_flags
1193 & FB_ACCELF_TEXT) ? -1 : 0;
1195 switch (xgi_video_info.video_bpp) {
1197 xgi_video_info.DstColor = 0x0000;
1198 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1199 xgi_video_info.video_cmap_len = 256;
1200 #if defined(__powerpc__)
1201 inXGIIDXREG(XGICR, 0x4D, cr_data);
1202 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1206 xgi_video_info.DstColor = 0x8000;
1207 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1208 #if defined(__powerpc__)
1209 inXGIIDXREG(XGICR, 0x4D, cr_data);
1210 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1212 xgi_video_info.video_cmap_len = 16;
1215 xgi_video_info.DstColor = 0xC000;
1216 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1217 xgi_video_info.video_cmap_len = 16;
1218 #if defined(__powerpc__)
1219 inXGIIDXREG(XGICR, 0x4D, cr_data);
1220 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1224 xgi_video_info.video_cmap_len = 16;
1225 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1226 xgi_video_info.accel = 0;
1230 XGIfb_bpp_to_var(var); /*update ARGB info*/
1231 DEBUGPRN("End of do_set_var");
1238 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1242 /* printk("Inside pan_var"); */
1244 if (var->xoffset > (var->xres_virtual - var->xres)) {
1245 /* printk("Pan: xo: %d xv %d xr %d\n",
1246 var->xoffset, var->xres_virtual, var->xres); */
1249 if (var->yoffset > (var->yres_virtual - var->yres)) {
1250 /* printk("Pan: yo: %d yv %d yr %d\n",
1251 var->yoffset, var->yres_virtual, var->yres); */
1254 base = var->yoffset * var->xres_virtual + var->xoffset;
1256 /* calculate base bpp dep. */
1257 switch (var->bits_per_pixel) {
1269 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1271 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1272 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1273 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1274 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1275 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1277 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1278 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1279 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1280 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1281 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1282 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1284 /* printk("End of pan_var"); */
1289 void XGI_dispinfo(struct ap_data *rec)
1291 rec->minfo.bpp = xgi_video_info.video_bpp;
1292 rec->minfo.xres = xgi_video_info.video_width;
1293 rec->minfo.yres = xgi_video_info.video_height;
1294 rec->minfo.v_xres = xgi_video_info.video_vwidth;
1295 rec->minfo.v_yres = xgi_video_info.video_vheight;
1296 rec->minfo.org_x = xgi_video_info.org_x;
1297 rec->minfo.org_y = xgi_video_info.org_y;
1298 rec->minfo.vrate = xgi_video_info.refresh_rate;
1299 rec->iobase = xgi_video_info.vga_base - 0x30;
1300 rec->mem_size = xgi_video_info.video_size;
1301 rec->disp_state = xgi_video_info.disp_state;
1302 rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1303 rec->hasVB = xgi_video_info.hasVB;
1304 rec->TV_type = xgi_video_info.TV_type;
1305 rec->TV_plug = xgi_video_info.TV_plug;
1306 rec->chip = xgi_video_info.chip;
1309 static int XGIfb_open(struct fb_info *info, int user)
1314 static int XGIfb_release(struct fb_info *info, int user)
1319 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1323 switch (var->bits_per_pixel) {
1337 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1338 unsigned blue, unsigned transp, struct fb_info *info)
1340 if (regno >= XGIfb_get_cmap_len(&info->var))
1343 switch (info->var.bits_per_pixel) {
1345 outXGIREG(XGIDACA, regno);
1346 outXGIREG(XGIDACD, (red >> 10));
1347 outXGIREG(XGIDACD, (green >> 10));
1348 outXGIREG(XGIDACD, (blue >> 10));
1349 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1350 outXGIREG(XGIDAC2A, regno);
1351 outXGIREG(XGIDAC2D, (red >> 8));
1352 outXGIREG(XGIDAC2D, (green >> 8));
1353 outXGIREG(XGIDAC2D, (blue >> 8));
1357 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1358 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1365 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1372 static int XGIfb_set_par(struct fb_info *info)
1376 /* printk("XGIfb: inside set_par\n"); */
1377 err = XGIfb_do_set_var(&info->var, 1, info);
1380 XGIfb_get_fix(&info->fix, -1, info);
1381 /* printk("XGIfb: end of set_par\n"); */
1385 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1387 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1389 unsigned int vtotal = 0;
1390 unsigned int drate = 0, hrate = 0;
1392 int refresh_rate, search_idx;
1394 DEBUGPRN("Inside check_var");
1396 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1397 vtotal = var->upper_margin + var->yres + var->lower_margin
1400 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1401 vtotal = var->upper_margin + var->yres + var->lower_margin
1404 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1405 vtotal = var->upper_margin + (var->yres / 2)
1406 + var->lower_margin + var->vsync_len;
1408 vtotal = var->upper_margin + var->yres + var->lower_margin
1411 if (!(htotal) || !(vtotal))
1412 XGIFAIL("XGIfb: no valid timing data");
1414 if (var->pixclock && htotal && vtotal) {
1415 drate = 1000000000 / var->pixclock;
1416 hrate = (drate * 1000) / htotal;
1417 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1419 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1420 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1421 __func__, var->pixclock, htotal, vtotal,
1422 __func__, drate, hrate, xgi_video_info.refresh_rate);
1424 xgi_video_info.refresh_rate = 60;
1428 if ((var->pixclock) && (htotal)) {
1429 drate = 1E12 / var->pixclock;
1430 hrate = drate / htotal;
1431 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1436 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1437 if ((var->xres == 1024) && (var->yres == 600))
1441 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1442 (XGIbios_mode[search_idx].xres <= var->xres)) {
1443 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1444 (XGIbios_mode[search_idx].yres == var->yres) &&
1445 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1446 if (XGIfb_validate_mode(search_idx) > 0) {
1456 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1457 var->xres, var->yres, var->bits_per_pixel);
1459 while (XGIbios_mode[search_idx].mode_no != 0) {
1461 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1462 (var->yres <= XGIbios_mode[search_idx].yres) &&
1463 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1464 if (XGIfb_validate_mode(search_idx) > 0) {
1472 var->xres = XGIbios_mode[search_idx].xres;
1473 var->yres = XGIbios_mode[search_idx].yres;
1474 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1475 var->xres, var->yres, var->bits_per_pixel);
1478 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1479 var->xres, var->yres, var->bits_per_pixel);
1484 /* TW: TODO: Check the refresh rate */
1486 /* Adapt RGB settings */
1487 XGIfb_bpp_to_var(var);
1489 /* Sanity check for offsets */
1490 if (var->xoffset < 0)
1492 if (var->yoffset < 0)
1496 if (var->xres != var->xres_virtual)
1497 var->xres_virtual = var->xres;
1498 if (var->yres != var->yres_virtual)
1499 var->yres_virtual = var->yres;
1501 /* TW: Now patch yres_virtual if we use panning */
1502 /* May I do this? */
1503 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1504 /* if (var->yres_virtual <= var->yres) { */
1505 /* TW: Paranoia check */
1506 /* var->yres_virtual = var->yres; */
1510 /* Truncate offsets to maximum if too high */
1511 if (var->xoffset > var->xres_virtual - var->xres)
1512 var->xoffset = var->xres_virtual - var->xres - 1;
1514 if (var->yoffset > var->yres_virtual - var->yres)
1515 var->yoffset = var->yres_virtual - var->yres - 1;
1517 /* Set everything else to 0 */
1518 var->red.msb_right =
1519 var->green.msb_right =
1520 var->blue.msb_right =
1521 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1523 DEBUGPRN("end of check_var");
1528 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1529 struct fb_info *info)
1533 /* printk("\nInside pan_display:\n"); */
1535 if (var->xoffset > (var->xres_virtual - var->xres))
1537 if (var->yoffset > (var->yres_virtual - var->yres))
1540 if (var->vmode & FB_VMODE_YWRAP) {
1541 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1545 if (var->xoffset + info->var.xres > info->var.xres_virtual
1546 || var->yoffset + info->var.yres
1547 > info->var.yres_virtual)
1550 err = XGIfb_pan_var(var);
1554 info->var.xoffset = var->xoffset;
1555 info->var.yoffset = var->yoffset;
1556 if (var->vmode & FB_VMODE_YWRAP)
1557 info->var.vmode |= FB_VMODE_YWRAP;
1559 info->var.vmode &= ~FB_VMODE_YWRAP;
1561 /* printk("End of pan_display\n"); */
1566 static int XGIfb_blank(int blank, struct fb_info *info)
1570 inXGIIDXREG(XGICR, 0x17, reg);
1577 outXGIIDXREG(XGICR, 0x17, reg);
1578 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1579 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1583 static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
1586 DEBUGPRN("inside ioctl");
1589 if (!capable(CAP_SYS_RAWIO))
1591 XGI_malloc((struct XGI_memreq *) arg);
1594 if (!capable(CAP_SYS_RAWIO))
1596 XGI_free(*(unsigned long *) arg);
1598 case FBIOGET_HWCINFO: {
1599 unsigned long *hwc_offset = (unsigned long *) arg;
1601 if (XGIfb_caps & HW_CURSOR_CAP)
1603 = XGIfb_hwcursor_vbase
1604 - (unsigned long) xgi_video_info.video_vbase;
1610 case FBIOPUT_MODEINFO: {
1611 struct mode_info *x = (struct mode_info *) arg;
1613 xgi_video_info.video_bpp = x->bpp;
1614 xgi_video_info.video_width = x->xres;
1615 xgi_video_info.video_height = x->yres;
1616 xgi_video_info.video_vwidth = x->v_xres;
1617 xgi_video_info.video_vheight = x->v_yres;
1618 xgi_video_info.org_x = x->org_x;
1619 xgi_video_info.org_y = x->org_y;
1620 xgi_video_info.refresh_rate = x->vrate;
1621 xgi_video_info.video_linelength = xgi_video_info.video_vwidth
1622 * (xgi_video_info.video_bpp >> 3);
1623 switch (xgi_video_info.video_bpp) {
1625 xgi_video_info.DstColor = 0x0000;
1626 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1627 xgi_video_info.video_cmap_len = 256;
1630 xgi_video_info.DstColor = 0x8000;
1631 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1632 xgi_video_info.video_cmap_len = 16;
1635 xgi_video_info.DstColor = 0xC000;
1636 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1637 xgi_video_info.video_cmap_len = 16;
1640 xgi_video_info.video_cmap_len = 16;
1641 printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1642 xgi_video_info.accel = 0;
1648 case FBIOGET_DISPINFO:
1649 XGI_dispinfo((struct ap_data *) arg);
1651 case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1653 struct XGIfb_info *x = (struct XGIfb_info *) arg;
1655 /* x->XGIfb_id = XGIFB_ID; */
1656 x->XGIfb_version = VER_MAJOR;
1657 x->XGIfb_revision = VER_MINOR;
1658 x->XGIfb_patchlevel = VER_LEVEL;
1659 x->chip_id = xgi_video_info.chip_id;
1660 x->memory = xgi_video_info.video_size / 1024;
1661 x->heapstart = xgi_video_info.heapstart / 1024;
1662 x->fbvidmode = XGIfb_mode_no;
1663 x->XGIfb_caps = XGIfb_caps;
1664 x->XGIfb_tqlen = 512; /* yet unused */
1665 x->XGIfb_pcibus = xgi_video_info.pcibus;
1666 x->XGIfb_pcislot = xgi_video_info.pcislot;
1667 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1668 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1669 x->XGIfb_lcda = XGIfb_detectedlcda;
1672 case XGIFB_GET_VBRSTATUS: {
1673 unsigned long *vbrstatus = (unsigned long *) arg;
1674 if (XGIfb_CheckVBRetrace())
1681 } DEBUGPRN("end of ioctl");
1686 /* ----------- FBDev related routines for all series ---------- */
1688 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1689 struct fb_info *info)
1691 DEBUGPRN("inside get_fix");
1692 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1694 strcpy(fix->id, myid);
1696 fix->smem_start = xgi_video_info.video_base;
1698 fix->smem_len = xgi_video_info.video_size;
1700 /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1701 if (xgi_video_info.video_size > 0x1000000) {
1702 fix->smem_len = 0xD00000;
1703 } else if (xgi_video_info.video_size > 0x800000)
1704 fix->smem_len = 0x800000;
1706 fix->smem_len = 0x400000;
1708 fix->smem_len = XGIfb_mem * 1024;
1710 fix->type = video_type;
1712 if (xgi_video_info.video_bpp == 8)
1713 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1715 fix->visual = FB_VISUAL_DIRECTCOLOR;
1722 fix->line_length = xgi_video_info.video_linelength;
1723 fix->mmio_start = xgi_video_info.mmio_base;
1724 fix->mmio_len = XGIfb_mmio_size;
1725 if (xgi_video_info.chip >= XG40)
1726 fix->accel = FB_ACCEL_XGI_XABRE;
1728 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
1730 DEBUGPRN("end of get_fix");
1734 static struct fb_ops XGIfb_ops = {
1735 .owner = THIS_MODULE,
1736 .fb_open = XGIfb_open,
1737 .fb_release = XGIfb_release,
1738 .fb_check_var = XGIfb_check_var,
1739 .fb_set_par = XGIfb_set_par,
1740 .fb_setcolreg = XGIfb_setcolreg,
1742 .fb_pan_display = XGIfb_pan_display,
1744 .fb_blank = XGIfb_blank,
1745 .fb_fillrect = fbcon_XGI_fillrect,
1746 .fb_copyarea = fbcon_XGI_copyarea,
1747 .fb_imageblit = cfb_imageblit,
1748 .fb_sync = fbcon_XGI_sync,
1749 .fb_ioctl = XGIfb_ioctl,
1750 /* .fb_mmap = XGIfb_mmap, */
1753 /* ---------------- Chip generation dependent routines ---------------- */
1755 /* for XGI 315/550/650/740/330 */
1757 static int XGIfb_get_dram_size(void)
1763 /* xorg driver sets 32MB * 1 channel */
1764 if (xgi_video_info.chip == XG27)
1765 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1767 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1768 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1769 case XGI_DRAM_SIZE_1MB:
1770 xgi_video_info.video_size = 0x100000;
1772 case XGI_DRAM_SIZE_2MB:
1773 xgi_video_info.video_size = 0x200000;
1775 case XGI_DRAM_SIZE_4MB:
1776 xgi_video_info.video_size = 0x400000;
1778 case XGI_DRAM_SIZE_8MB:
1779 xgi_video_info.video_size = 0x800000;
1781 case XGI_DRAM_SIZE_16MB:
1782 xgi_video_info.video_size = 0x1000000;
1784 case XGI_DRAM_SIZE_32MB:
1785 xgi_video_info.video_size = 0x2000000;
1787 case XGI_DRAM_SIZE_64MB:
1788 xgi_video_info.video_size = 0x4000000;
1790 case XGI_DRAM_SIZE_128MB:
1791 xgi_video_info.video_size = 0x8000000;
1793 case XGI_DRAM_SIZE_256MB:
1794 xgi_video_info.video_size = 0x10000000;
1800 tmp = (reg & 0x0c) >> 2;
1801 switch (xgi_video_info.chip) {
1837 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1838 /* PLiad fixed for benchmarking and fb set */
1839 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1840 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1842 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1843 xgi_video_info.video_size, ChannelNum);
1848 static void XGIfb_detect_VB(void)
1852 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1854 switch (xgi_video_info.hasVB) {
1855 case HASVB_LVDS_CHRONTEL:
1856 case HASVB_CHRONTEL:
1860 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1864 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1866 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1875 if (XGIfb_crt2type != -1)
1876 /* TW: Override with option */
1877 xgi_video_info.disp_state = XGIfb_crt2type;
1878 else if (cr32 & XGI_VB_TV)
1879 xgi_video_info.disp_state = DISPTYPE_TV;
1880 else if (cr32 & XGI_VB_LCD)
1881 xgi_video_info.disp_state = DISPTYPE_LCD;
1882 else if (cr32 & XGI_VB_CRT2)
1883 xgi_video_info.disp_state = DISPTYPE_CRT2;
1885 xgi_video_info.disp_state = 0;
1887 if (XGIfb_tvplug != -1)
1888 /* PR/TW: Override with option */
1889 xgi_video_info.TV_plug = XGIfb_tvplug;
1890 else if (cr32 & XGI_VB_HIVISION) {
1891 xgi_video_info.TV_type = TVMODE_HIVISION;
1892 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1893 } else if (cr32 & XGI_VB_SVIDEO)
1894 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1895 else if (cr32 & XGI_VB_COMPOSITE)
1896 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1897 else if (cr32 & XGI_VB_SCART)
1898 xgi_video_info.TV_plug = TVPLUG_SCART;
1900 if (xgi_video_info.TV_type == 0) {
1901 /* TW: PAL/NTSC changed for 650 */
1902 if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip
1905 inXGIIDXREG(XGICR, 0x38, temp);
1907 xgi_video_info.TV_type = TVMODE_PAL;
1909 xgi_video_info.TV_type = TVMODE_NTSC;
1913 inXGIIDXREG(XGICR, 0x79, temp);
1915 xgi_video_info.TV_type = TVMODE_PAL;
1917 xgi_video_info.TV_type = TVMODE_NTSC;
1921 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1922 if (XGIfb_forcecrt1 != -1) {
1923 if (XGIfb_forcecrt1)
1930 static void XGIfb_get_VB_type(void)
1934 if (!XGIfb_has_VB()) {
1935 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1936 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1937 case XGI310_EXTERNAL_CHIP_LVDS:
1938 xgi_video_info.hasVB = HASVB_LVDS;
1940 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1941 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1949 static int XGIfb_has_VB(void)
1953 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1954 switch (vb_chipid) {
1956 xgi_video_info.hasVB = HASVB_301;
1959 xgi_video_info.hasVB = HASVB_302;
1962 xgi_video_info.hasVB = HASVB_NONE;
1968 /* ------------------ Sensing routines ------------------ */
1970 /* TW: Determine and detect attached devices on XGI30x */
1971 int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
1975 outXGIIDXREG(XGIPART4, 0x11, tempbl);
1976 temp = tempbh | tempcl;
1977 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1978 for (i = 0; i < 10; i++)
1979 XGI_LongWait(&XGI_Pr);
1981 inXGIIDXREG(XGIPART4, 0x03, temp);
1987 void XGI_Sense30x(void)
1990 u8 testsvhs_tempbl, testsvhs_tempbh;
1991 u8 testsvhs_tempcl, testsvhs_tempch;
1992 u8 testcvbs_tempbl, testcvbs_tempbh;
1993 u8 testcvbs_tempcl, testcvbs_tempch;
1994 u8 testvga2_tempbl, testvga2_tempbh;
1995 u8 testvga2_tempcl, testvga2_tempch;
1998 inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1999 outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
2001 testvga2_tempbh = 0x00;
2002 testvga2_tempbl = 0xd1;
2003 testsvhs_tempbh = 0x00;
2004 testsvhs_tempbl = 0xb9;
2005 testcvbs_tempbh = 0x00;
2006 testcvbs_tempbl = 0xb3;
2007 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
2009 testvga2_tempbh = 0x01;
2010 testvga2_tempbl = 0x90;
2011 testsvhs_tempbh = 0x01;
2012 testsvhs_tempbl = 0x6b;
2013 testcvbs_tempbh = 0x01;
2014 testcvbs_tempbl = 0x74;
2015 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
2016 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
2017 testvga2_tempbh = 0x00;
2018 testvga2_tempbl = 0x00;
2019 testsvhs_tempbh = 0x02;
2020 testsvhs_tempbl = 0x00;
2021 testcvbs_tempbh = 0x01;
2022 testcvbs_tempbl = 0x00;
2025 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
2027 inXGIIDXREG(XGIPART4, 0x01, myflag);
2028 if (myflag & 0x04) {
2029 testvga2_tempbh = 0x00;
2030 testvga2_tempbl = 0xfd;
2031 testsvhs_tempbh = 0x00;
2032 testsvhs_tempbl = 0xdd;
2033 testcvbs_tempbh = 0x00;
2034 testcvbs_tempbl = 0xee;
2037 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
2038 == VB_CHIP_302LV)) {
2039 testvga2_tempbh = 0x00;
2040 testvga2_tempbl = 0x00;
2041 testvga2_tempch = 0x00;
2042 testvga2_tempcl = 0x00;
2043 testsvhs_tempch = 0x04;
2044 testsvhs_tempcl = 0x08;
2045 testcvbs_tempch = 0x08;
2046 testcvbs_tempcl = 0x08;
2048 testvga2_tempch = 0x0e;
2049 testvga2_tempcl = 0x08;
2050 testsvhs_tempch = 0x06;
2051 testsvhs_tempcl = 0x04;
2052 testcvbs_tempch = 0x08;
2053 testcvbs_tempcl = 0x04;
2056 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
2057 || testvga2_tempbl) {
2058 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2059 testvga2_tempcl, testvga2_tempch);
2061 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2062 orXGIIDXREG(XGICR, 0x32, 0x10);
2066 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
2069 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2070 /* TW: So we can be sure that there IS a SVHS output */
2071 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2072 orXGIIDXREG(XGICR, 0x32, 0x02);
2076 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2077 testcvbs_tempcl, testcvbs_tempch);
2079 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2080 /* TW: So we can be sure that there IS a CVBS output */
2081 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2082 orXGIIDXREG(XGICR, 0x32, 0x01);
2085 XGIDoSense(0, 0, 0, 0);
2087 outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
2090 /* ------------------------ Heap routines -------------------------- */
2092 static int XGIfb_heap_init(void)
2097 int agp_enabled = 1;
2099 unsigned long *cmdq_baseport = NULL;
2100 unsigned long *read_port = NULL;
2101 unsigned long *write_port = NULL;
2102 XGI_CMDTYPE cmd_type;
2104 struct agp_kern_info *agp_info;
2105 struct agp_memory *agp;
2109 /* TW: The heap start is either set manually using the "mem" parameter, or
2110 * defaults as follows:
2111 * -) If more than 16MB videoRAM available, let our heap start at 12MB.
2112 * -) If more than 8MB videoRAM available, let our heap start at 8MB.
2113 * -) If 4MB or less is available, let it start at 4MB.
2114 * This is for avoiding a clash with X driver which uses the beginning
2115 * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2117 * The heap start can also be specified by parameter "mem" when starting the XGIfb
2118 * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2120 if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) {
2121 if (xgi_video_info.video_size > 0x1000000)
2122 xgi_video_info.heapstart = 0xD00000;
2123 else if (xgi_video_info.video_size > 0x800000)
2124 xgi_video_info.heapstart = 0x800000;
2126 xgi_video_info.heapstart = 0x400000;
2128 xgi_video_info.heapstart = XGIfb_mem * 1024;
2130 XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase
2131 + xgi_video_info.heapstart);
2132 printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2133 (int)(xgi_video_info.heapstart / 1024));
2135 XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase
2136 + xgi_video_info.video_size;
2137 XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
2139 /* TW: Now initialize the 310 series' command queue mode.
2140 * On 310/325, there are three queue modes available which
2141 * are chosen by setting bits 7:5 in SR26:
2142 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2143 * track of the queue, the FIFO, command parsing and so
2144 * on. This is the one comparable to the 300 series.
2145 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2146 * have to do queue management himself. Register 0x85c4 will
2147 * hold the location of the next free queue slot, 0x85c8
2148 * is the "queue read pointer" whose way of working is
2149 * unknown to me. Anyway, this mode would require a
2150 * translation of the MMIO commands to some kind of
2151 * accelerator assembly and writing these commands
2152 * to the memory location pointed to by 0x85c4.
2153 * We will not use this, as nobody knows how this
2154 * "assembly" works, and as it would require a complete
2155 * re-write of the accelerator code.
2156 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2157 * queue in AGP memory space.
2159 * SR26 bit 4 is called "Bypass H/W queue".
2160 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2161 * SR26 bit 0 resets the queue
2162 * Size of queue memory is encoded in bits 3:2 like this:
2167 * The queue location is to be written to 0x85C0.
2170 cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase
2171 + MMIO_QUEUE_PHYBASE);
2172 write_port = (unsigned long *) (xgi_video_info.mmio_vbase
2173 + MMIO_QUEUE_WRITEPORT);
2174 read_port = (unsigned long *) (xgi_video_info.mmio_vbase
2175 + MMIO_QUEUE_READPORT);
2177 DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2179 agp_size = COMMAND_QUEUE_AREA_SIZE;
2182 if (XGIfb_queuemode == AGP_CMD_QUEUE) {
2183 agp_info = vzalloc(sizeof(*agp_info));
2184 agp_copy_info(agp_info);
2186 agp_backend_acquire();
2188 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
2191 DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2194 if (agp_bind_memory(agp, agp->pg_start) != 0) {
2195 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2196 /* TODO: Free AGP memory here */
2207 /* TW: Now select the queue mode */
2209 if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2210 cmd_type = AGP_CMD_QUEUE;
2211 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
2212 /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
2213 } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
2214 cmd_type = VM_CMD_QUEUE;
2215 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2217 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2218 cmd_type = MMIO_CMD;
2223 temp = XGI_CMD_QUEUE_SIZE_512k;
2226 temp = XGI_CMD_QUEUE_SIZE_1M;
2229 temp = XGI_CMD_QUEUE_SIZE_2M;
2232 temp = XGI_CMD_QUEUE_SIZE_4M;
2239 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2240 agp_info->aper_base, agp->physical, agp_size/1024);
2242 agp_phys = agp_info->aper_base + agp->physical;
2244 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2245 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
2247 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2249 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2251 *write_port = *read_port;
2253 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2254 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2256 *cmdq_baseport = agp_phys;
2258 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2263 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2264 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2266 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2268 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2270 *write_port = *read_port;
2272 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2273 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2275 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2277 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2279 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2280 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2285 /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */
2286 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
2287 * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2288 * enough. Reserve memory in any way.
2290 /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */
2291 /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */
2293 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */
2294 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */
2296 /* FIXME *write_port = *read_port; */
2298 /* FIXME *//* TW: Set Auto_Correction bit */
2299 /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */
2300 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */
2302 /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */
2304 /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */
2306 /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */
2307 /* FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */
2311 /* TW: Now reserve memory for the HWCursor. It is always located at the very
2312 top of the videoRAM, right below the TB memory area (if used). */
2313 if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
2314 XGIfb_heap_end -= XGIfb_hwcursor_size;
2315 XGIfb_heap_size -= XGIfb_hwcursor_size;
2316 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2318 XGIfb_caps |= HW_CURSOR_CAP;
2320 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
2321 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2324 XGIfb_heap.poha_chain = NULL;
2325 XGIfb_heap.poh_freelist = NULL;
2327 poh = XGIfb_poh_new_node();
2332 poh->poh_next = &XGIfb_heap.oh_free;
2333 poh->poh_prev = &XGIfb_heap.oh_free;
2334 poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2335 poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
2337 DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
2338 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2339 (unsigned int) poh->size / 1024);
2341 DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
2342 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2344 XGIfb_heap.oh_free.poh_next = poh;
2345 XGIfb_heap.oh_free.poh_prev = poh;
2346 XGIfb_heap.oh_free.size = 0;
2347 XGIfb_heap.max_freesize = poh->size;
2349 XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2350 XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2351 XGIfb_heap.oh_used.size = SENTINEL;
2356 static XGI_OH *XGIfb_poh_new_node(void)
2363 if (XGIfb_heap.poh_freelist == NULL) {
2364 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
2368 poha->poha_next = XGIfb_heap.poha_chain;
2369 XGIfb_heap.poha_chain = poha;
2371 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH)
2374 poh = &poha->aoh[0];
2375 for (i = cOhs - 1; i != 0; i--) {
2376 poh->poh_next = poh + 1;
2380 poh->poh_next = NULL;
2381 XGIfb_heap.poh_freelist = &poha->aoh[0];
2384 poh = XGIfb_heap.poh_freelist;
2385 XGIfb_heap.poh_freelist = poh->poh_next;
2390 static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2396 if (size > XGIfb_heap.max_freesize) {
2397 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2398 (unsigned int) size / 1024);
2402 pohThis = XGIfb_heap.oh_free.poh_next;
2404 while (pohThis != &XGIfb_heap.oh_free) {
2405 if (size <= pohThis->size) {
2409 pohThis = pohThis->poh_next;
2413 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2414 (unsigned int) size / 1024);
2418 if (size == pohThis->size) {
2420 XGIfb_delete_node(pohThis);
2422 pohRoot = XGIfb_poh_new_node();
2424 if (pohRoot == NULL)
2427 pohRoot->offset = pohThis->offset;
2428 pohRoot->size = size;
2430 pohThis->offset += size;
2431 pohThis->size -= size;
2434 XGIfb_heap.max_freesize -= size;
2436 pohThis = &XGIfb_heap.oh_used;
2437 XGIfb_insert_node(pohThis, pohRoot);
2442 static void XGIfb_delete_node(XGI_OH *poh)
2447 poh_prev = poh->poh_prev;
2448 poh_next = poh->poh_next;
2450 poh_prev->poh_next = poh_next;
2451 poh_next->poh_prev = poh_prev;
2455 static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2459 pohTemp = pohList->poh_next;
2461 pohList->poh_next = poh;
2462 pohTemp->poh_prev = poh;
2464 poh->poh_prev = pohList;
2465 poh->poh_next = pohTemp;
2468 static XGI_OH *XGIfb_poh_free(unsigned long base)
2474 unsigned long ulUpper;
2475 unsigned long ulLower;
2478 poh_freed = XGIfb_heap.oh_used.poh_next;
2480 while (poh_freed != &XGIfb_heap.oh_used) {
2481 if (poh_freed->offset == base) {
2486 poh_freed = poh_freed->poh_next;
2492 XGIfb_heap.max_freesize += poh_freed->size;
2494 poh_prev = poh_next = NULL;
2495 ulUpper = poh_freed->offset + poh_freed->size;
2496 ulLower = poh_freed->offset;
2498 pohThis = XGIfb_heap.oh_free.poh_next;
2500 while (pohThis != &XGIfb_heap.oh_free) {
2501 if (pohThis->offset == ulUpper)
2503 else if ((pohThis->offset + pohThis->size) == ulLower)
2506 pohThis = pohThis->poh_next;
2509 XGIfb_delete_node(poh_freed);
2511 if (poh_prev && poh_next) {
2512 poh_prev->size += (poh_freed->size + poh_next->size);
2513 XGIfb_delete_node(poh_next);
2514 XGIfb_free_node(poh_freed);
2515 XGIfb_free_node(poh_next);
2520 poh_prev->size += poh_freed->size;
2521 XGIfb_free_node(poh_freed);
2526 poh_next->size += poh_freed->size;
2527 poh_next->offset = poh_freed->offset;
2528 XGIfb_free_node(poh_freed);
2532 XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2537 static void XGIfb_free_node(XGI_OH *poh)
2542 poh->poh_next = XGIfb_heap.poh_freelist;
2543 XGIfb_heap.poh_freelist = poh;
2547 void XGI_malloc(struct XGI_memreq *req)
2551 poh = XGIfb_poh_allocate(req->size);
2556 DPRINTK("XGIfb: Video RAM allocation failed\n");
2558 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
2559 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
2561 req->offset = poh->offset;
2562 req->size = poh->size;
2567 void XGI_free(unsigned long base)
2571 poh = XGIfb_poh_free(base);
2574 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
2575 (unsigned int) base);
2579 /* --------------------- SetMode routines ------------------------- */
2581 static void XGIfb_pre_setmode(void)
2583 u8 cr30 = 0, cr31 = 0;
2585 inXGIIDXREG(XGICR, 0x31, cr31);
2588 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2590 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2591 cr31 |= XGI_DRIVER_MODE;
2594 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
2595 cr31 |= XGI_DRIVER_MODE;
2598 if (xgi_video_info.TV_type == TVMODE_HIVISION)
2599 cr30 = (XGI_VB_OUTPUT_HIVISION
2600 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2601 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
2602 cr30 = (XGI_VB_OUTPUT_SVIDEO
2603 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2604 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
2605 cr30 = (XGI_VB_OUTPUT_COMPOSITE
2606 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2607 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
2608 cr30 = (XGI_VB_OUTPUT_SCART
2609 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2610 cr31 |= XGI_DRIVER_MODE;
2612 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
2617 default: /* disable CRT2 */
2619 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2622 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2623 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
2624 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
2626 if (xgi_video_info.accel)
2631 static void XGIfb_post_setmode(void)
2634 unsigned char doit = 1;
2636 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2637 outXGIIDXREG(XGICR, 0x13, 0x00);
2638 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
2641 if (xgi_video_info.video_bpp == 8) {
2642 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
2643 if ((xgi_video_info.hasVB == HASVB_LVDS)
2644 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
2647 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
2648 if (xgi_video_info.disp_state & DISPTYPE_LCD)
2652 /* TW: We can't switch off CRT1 if bridge is in slave mode */
2653 if (xgi_video_info.hasVB != HASVB_NONE) {
2654 inXGIIDXREG(XGIPART1, 0x00, reg);
2656 if ((reg & 0x50) == 0x10)
2663 inXGIIDXREG(XGICR, 0x17, reg);
2664 if ((XGIfb_crt1off) && (doit))
2668 outXGIIDXREG(XGICR, 0x17, reg);
2670 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
2672 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
2675 inXGIIDXREG(XGIPART4, 0x01, reg);
2677 if (reg < 0xB0) { /* Set filter for XGI301 */
2679 switch (xgi_video_info.video_width) {
2681 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2684 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2687 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2690 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2697 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
2699 if (xgi_video_info.TV_type == TVMODE_NTSC) {
2701 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
2703 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2705 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
2707 } else if (xgi_video_info.TV_plug
2708 == TVPLUG_COMPOSITE) {
2710 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2712 switch (xgi_video_info.video_width) {
2714 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2715 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2716 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2717 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2720 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2721 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2722 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2723 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2726 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2727 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2728 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2729 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2734 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2736 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2738 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2740 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2742 } else if (xgi_video_info.TV_plug
2743 == TVPLUG_COMPOSITE) {
2745 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2747 switch (xgi_video_info.video_width) {
2749 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2750 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2751 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2752 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2755 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2756 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2757 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2758 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2761 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2762 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2763 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2764 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2770 if ((filter >= 0) && (filter <= 7)) {
2771 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2772 XGI_TV_filter[filter_tb].filter[filter][0],
2773 XGI_TV_filter[filter_tb].filter[filter][1],
2774 XGI_TV_filter[filter_tb].filter[filter][2],
2775 XGI_TV_filter[filter_tb].filter[filter][3]
2780 (XGI_TV_filter[filter_tb].filter[filter][0]));
2784 (XGI_TV_filter[filter_tb].filter[filter][1]));
2788 (XGI_TV_filter[filter_tb].filter[filter][2]));
2792 (XGI_TV_filter[filter_tb].filter[filter][3]));
2801 XGIINITSTATIC int __init XGIfb_setup(char *options)
2805 xgi_video_info.refresh_rate = 0;
2807 printk(KERN_INFO "XGIfb: Options %s\n", options);
2809 if (!options || !*options)
2812 while ((this_opt = strsep(&options, ",")) != NULL) {
2817 if (!strncmp(this_opt, "mode:", 5)) {
2818 XGIfb_search_mode(this_opt + 5);
2819 } else if (!strncmp(this_opt, "vesa:", 5)) {
2820 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2821 } else if (!strncmp(this_opt, "mode:", 5)) {
2822 XGIfb_search_mode(this_opt + 5);
2823 } else if (!strncmp(this_opt, "vesa:", 5)) {
2824 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2825 } else if (!strncmp(this_opt, "vrate:", 6)) {
2826 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2827 } else if (!strncmp(this_opt, "rate:", 5)) {
2828 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2829 } else if (!strncmp(this_opt, "off", 3)) {
2831 } else if (!strncmp(this_opt, "crt1off", 7)) {
2833 } else if (!strncmp(this_opt, "filter:", 7)) {
2834 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2835 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2836 XGIfb_search_crt2type(this_opt + 14);
2837 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2838 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2839 } else if (!strncmp(this_opt, "tvmode:", 7)) {
2840 XGIfb_search_tvstd(this_opt + 7);
2841 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2842 XGIfb_search_tvstd(this_opt + 7);
2843 } else if (!strncmp(this_opt, "mem:", 4)) {
2844 XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2845 } else if (!strncmp(this_opt, "dstn", 4)) {
2847 /* TW: DSTN overrules forcecrt2type */
2848 XGIfb_crt2type = DISPTYPE_LCD;
2849 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2850 XGIfb_search_queuemode(this_opt + 10);
2851 } else if (!strncmp(this_opt, "pdc:", 4)) {
2852 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2853 if (XGIfb_pdc & ~0x3c) {
2854 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2857 } else if (!strncmp(this_opt, "noaccel", 7)) {
2859 } else if (!strncmp(this_opt, "noypan", 6)) {
2861 } else if (!strncmp(this_opt, "userom:", 7)) {
2862 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2863 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2864 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
2866 XGIfb_search_mode(this_opt);
2867 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
2870 /* TW: Acceleration only with MMIO mode */
2871 if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
2875 /* TW: Panning only with acceleration */
2876 if (XGIfb_accel == 0)
2880 printk("\nxgifb: outa xgifb_setup 3450");
2884 static unsigned char VBIOS_BUF[65535];
2886 static unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
2889 u32 rom_address = 0;
2892 /* Get the size of the expansion rom */
2893 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
2894 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
2895 if ((rom_size & 0x01) == 0) {
2900 rom_size &= 0xFFFFF800;
2901 rom_size = (~rom_size) + 1;
2903 rom_address = pci_resource_start(dev, 0);
2904 if (rom_address == 0 || rom_address == 0xFFFFFFF0) {
2905 printk("No suitable rom address found\n");
2909 printk("ROM Size is %dK, Address is %x\n", rom_size / 1024, rom_address);
2912 pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address
2913 | PCI_ROM_ADDRESS_ENABLE);
2915 /* memcpy(copy_address, rom_address, rom_size); */
2917 unsigned char *virt_addr = ioremap(rom_address, 0x8000000);
2919 unsigned char *from = (unsigned char *) virt_addr;
2920 unsigned char *to = (unsigned char *) copy_address;
2921 for (j = 0; j < 65536 /*rom_size*/; j++)
2925 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
2927 printk("Copy is done\n");
2929 return copy_address;
2932 static int __devinit xgifb_probe(struct pci_dev *pdev,
2933 const struct pci_device_id *ent)
2941 XGIfb_registered = 0;
2943 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2944 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2948 xgi_video_info.chip_id = pdev->device;
2949 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2950 pci_read_config_word(pdev, PCI_COMMAND, ®16);
2951 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2952 XGIvga_enabled = reg16 & 0x01;
2954 xgi_video_info.pcibus = pdev->bus->number;
2955 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2956 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2957 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2958 xgi_video_info.subsysdevice = pdev->subsystem_device;
2960 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2961 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2962 XGIfb_mmio_size = pci_resource_len(pdev, 1);
2963 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2964 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2965 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2966 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2967 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2969 if (pci_enable_device(pdev))
2972 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2974 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2975 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
2977 if (reg1 != 0xa1) { /*I/O error */
2978 printk("\nXGIfb: I/O error!!!");
2982 switch (xgi_video_info.chip_id) {
2983 case PCI_DEVICE_ID_XG_20:
2984 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2985 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2986 if (CR48&GPIOG_READ)
2987 xgi_video_info.chip = XG21;
2989 xgi_video_info.chip = XG20;
2990 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2991 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2993 case PCI_DEVICE_ID_XG_40:
2994 xgi_video_info.chip = XG40;
2995 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2996 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2998 case PCI_DEVICE_ID_XG_41:
2999 xgi_video_info.chip = XG41;
3000 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3001 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3003 case PCI_DEVICE_ID_XG_42:
3004 xgi_video_info.chip = XG42;
3005 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3006 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3008 case PCI_DEVICE_ID_XG_27:
3009 xgi_video_info.chip = XG27;
3010 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
3011 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
3017 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
3018 XGIhw_ext.jChipType = xgi_video_info.chip;
3020 switch (xgi_video_info.chip) {
3028 XGIhw_ext.bIntegratedMMEnabled = 1;
3034 XGIhw_ext.pDevice = NULL;
3035 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
3036 XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
3038 if (XGIhw_ext.pjVirtualRomBase)
3039 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
3041 printk(KERN_INFO "XGIfb: Video ROM not found\n");
3043 XGIhw_ext.pjVirtualRomBase = NULL;
3044 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
3046 XGIhw_ext.pjCustomizedROMImage = NULL;
3047 XGIhw_ext.bSkipDramSizing = 0;
3048 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
3049 /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */
3050 strcpy(XGIhw_ext.szVBIOSVer, "0.84");
3052 XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
3053 if (XGIhw_ext.pSR == NULL) {
3054 printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
3057 XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
3059 XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
3060 if (XGIhw_ext.pCR == NULL) {
3061 vfree(XGIhw_ext.pSR);
3062 printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
3065 XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
3067 if (!XGIvga_enabled) {
3068 /* Mapping Max FB Size for 315 Init */
3069 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3070 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3072 printk("XGIfb: XGIInit() ...");
3073 /* XGIInitNewt for LINUXBIOS only */
3074 if (XGIInitNew(&XGIhw_ext))
3080 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3086 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3087 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3089 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3091 /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
3092 /* Set SR13 ,14 temporarily for UDtech */
3093 outXGIIDXREG(XGISR, 0x13, 0x45);
3094 outXGIIDXREG(XGISR, 0x14, 0x51);
3099 if (XGIfb_get_dram_size()) {
3100 vfree(XGIhw_ext.pSR);
3101 vfree(XGIhw_ext.pCR);
3102 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
3106 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3107 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
3108 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3109 /* Enable 2D accelerator engine */
3110 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3113 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3115 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
3116 printk("unable request memory size %x", xgi_video_info.video_size);
3117 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3118 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
3119 vfree(XGIhw_ext.pSR);
3120 vfree(XGIhw_ext.pCR);
3124 if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) {
3125 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
3126 release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
3127 vfree(XGIhw_ext.pSR);
3128 vfree(XGIhw_ext.pCR);
3132 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3133 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
3134 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
3136 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3137 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
3139 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
3140 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, XGIfb_mmio_size / 1024);
3141 printk("XGIfb: XGIInitNew() ...");
3142 if (XGIInitNew(&XGIhw_ext))
3147 if (XGIfb_heap_init())
3148 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
3150 xgi_video_info.mtrr = (unsigned int) 0;
3152 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3153 xgi_video_info.hasVB = HASVB_NONE;
3154 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
3155 xgi_video_info.hasVB = HASVB_NONE;
3156 } else if (xgi_video_info.chip == XG21) {
3157 inXGIIDXREG(XGICR, 0x38, CR38);
3158 if ((CR38&0xE0) == 0xC0) {
3159 xgi_video_info.disp_state = DISPTYPE_LCD;
3160 if (!XGIfb_GetXG21LVDSData()) {
3162 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
3163 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3164 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3165 XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
3169 } else if ((CR38&0xE0) == 0x60) {
3170 xgi_video_info.hasVB = HASVB_CHRONTEL;
3172 xgi_video_info.hasVB = HASVB_NONE;
3175 XGIfb_get_VB_type();
3178 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
3180 XGIhw_ext.ulExternalChip = 0;
3182 switch (xgi_video_info.hasVB) {
3184 inXGIIDXREG(XGIPART4, 0x01, reg);
3186 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3187 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3188 } else if (reg >= 0xD0) {
3189 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3190 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
3192 /* else if (reg >= 0xB0) {
3193 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
3194 inXGIIDXREG(XGIPART4, 0x23, reg1);
3195 printk("XGIfb: XGI301B bridge detected\n");
3198 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3199 printk("XGIfb: XGI301 bridge detected\n");
3203 inXGIIDXREG(XGIPART4, 0x01, reg);
3205 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3206 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3207 } else if (reg >= 0xD0) {
3208 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3209 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3210 } else if (reg >= 0xB0) {
3211 inXGIIDXREG(XGIPART4, 0x23, reg1);
3213 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
3216 XGIhw_ext.ujVBChipID = VB_CHIP_302;
3217 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3221 XGIhw_ext.ulExternalChip = 0x1;
3222 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3224 case HASVB_TRUMPION:
3225 XGIhw_ext.ulExternalChip = 0x2;
3226 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3228 case HASVB_CHRONTEL:
3229 XGIhw_ext.ulExternalChip = 0x4;
3230 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3232 case HASVB_LVDS_CHRONTEL:
3233 XGIhw_ext.ulExternalChip = 0x5;
3234 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3237 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3241 if (xgi_video_info.hasVB != HASVB_NONE)
3244 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3246 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3248 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3250 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3253 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
3255 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3257 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
3261 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3265 XGIfb_detectedpdc = 0;
3267 XGIfb_detectedlcda = 0xff;
3270 /* TW: Try to find about LCDA */
3272 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3273 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3274 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
3276 inXGIIDXREG(XGICR, 0x34, tmp);
3278 /* Currently on LCDA? (Some BIOSes leave CR38) */
3279 inXGIIDXREG(XGICR, 0x38, tmp);
3280 if ((tmp & 0x03) == 0x03) {
3281 /* XGI_Pr.XGI_UseLCDA = 1; */
3283 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
3284 inXGIIDXREG(XGICR, 0x35, tmp);
3286 /* XGI_Pr.XGI_UseLCDA = 1; */
3288 inXGIIDXREG(XGICR, 0x30, tmp);
3290 inXGIIDXREG(XGIPART1, 0x13, tmp);
3292 /* XGI_Pr.XGI_UseLCDA = 1; */
3303 if (xgifb_mode_idx >= 0)
3304 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3306 if (xgifb_mode_idx < 0) {
3307 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3309 xgifb_mode_idx = DEFAULT_LCDMODE;
3310 if (xgi_video_info.chip == XG21)
3311 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
3314 xgifb_mode_idx = DEFAULT_TVMODE;
3317 xgifb_mode_idx = DEFAULT_MODE;
3322 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3324 if (xgi_video_info.refresh_rate == 0)
3325 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
3326 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
3327 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3328 xgi_video_info.refresh_rate = 60;
3331 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3332 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3333 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3334 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3335 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
3336 switch (xgi_video_info.video_bpp) {
3338 xgi_video_info.DstColor = 0x0000;
3339 xgi_video_info.XGI310_AccelDepth = 0x00000000;
3340 xgi_video_info.video_cmap_len = 256;
3343 xgi_video_info.DstColor = 0x8000;
3344 xgi_video_info.XGI310_AccelDepth = 0x00010000;
3345 xgi_video_info.video_cmap_len = 16;
3348 xgi_video_info.DstColor = 0xC000;
3349 xgi_video_info.XGI310_AccelDepth = 0x00020000;
3350 xgi_video_info.video_cmap_len = 16;
3353 xgi_video_info.video_cmap_len = 16;
3354 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
3358 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
3359 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3360 xgi_video_info.refresh_rate);
3362 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3363 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3364 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3366 XGIfb_bpp_to_var(&default_var);
3368 default_var.pixclock = (u32) (1000000000 /
3369 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3370 XGIfb_mode_no, XGIfb_rate_idx));
3372 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3373 XGIfb_mode_no, XGIfb_rate_idx,
3374 &default_var.left_margin, &default_var.right_margin,
3375 &default_var.upper_margin, &default_var.lower_margin,
3376 &default_var.hsync_len, &default_var.vsync_len,
3377 &default_var.sync, &default_var.vmode)) {
3379 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3380 default_var.yres <<= 1;
3381 default_var.yres_virtual <<= 1;
3382 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3383 default_var.pixclock >>= 1;
3384 default_var.yres >>= 1;
3385 default_var.yres_virtual >>= 1;
3390 xgi_video_info.accel = 0;
3392 xgi_video_info.accel = -1;
3393 default_var.accel_flags |= FB_ACCELF_TEXT;
3397 fb_info->flags = FBINFO_FLAG_DEFAULT;
3398 fb_info->var = default_var;
3399 fb_info->fix = XGIfb_fix;
3400 fb_info->par = &xgi_video_info;
3401 fb_info->screen_base = xgi_video_info.video_vbase;
3402 fb_info->fbops = &XGIfb_ops;
3403 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3404 fb_info->pseudo_palette = pseudo_palette;
3406 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3409 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3410 (unsigned int) xgi_video_info.video_size,
3411 MTRR_TYPE_WRCOMB, 1);
3412 if (xgi_video_info.mtrr)
3413 printk(KERN_INFO "XGIfb: Added MTRRs\n");
3416 if (register_framebuffer(fb_info) < 0)
3419 XGIfb_registered = 1;
3421 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
3422 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
3431 /*****************************************************/
3432 /* PCI DEVICE HANDLING */
3433 /*****************************************************/
3435 static void __devexit xgifb_remove(struct pci_dev *pdev)
3437 /* Unregister the framebuffer */
3438 /* if (xgi_video_info.registered) { */
3439 unregister_framebuffer(fb_info);
3440 framebuffer_release(fb_info);
3443 pci_set_drvdata(pdev, NULL);
3447 static struct pci_driver xgifb_driver = {
3449 .id_table = xgifb_pci_table,
3450 .probe = xgifb_probe,
3451 .remove = __devexit_p(xgifb_remove)
3454 XGIINITSTATIC int __init xgifb_init(void)
3456 char *option = NULL;
3458 if (fb_get_options("xgifb", &option))
3460 XGIfb_setup(option);
3462 return pci_register_driver(&xgifb_driver);
3466 module_init(xgifb_init);
3469 /*****************************************************/
3471 /*****************************************************/
3475 static char *mode = NULL;
3476 static int vesa = 0;
3477 static unsigned int rate = 0;
3478 static unsigned int mem = 0;
3479 static char *forcecrt2type = NULL;
3480 static int forcecrt1 = -1;
3481 static int pdc = -1;
3482 static int pdc1 = -1;
3483 static int noaccel = -1;
3484 static int noypan = -1;
3485 static int nomax = -1;
3486 static int userom = -1;
3487 static int useoem = -1;
3488 static char *tvstandard = NULL;
3489 static int nocrt2rate = 0;
3490 static int scalelcd = -1;
3491 static char *specialtiming = NULL;
3492 static int lvdshl = -1;
3493 static int tvxposoffset = 0, tvyposoffset = 0;
3494 #if !defined(__i386__) && !defined(__x86_64__)
3495 static int resetcard = 0;
3496 static int videoram = 0;
3499 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3500 MODULE_LICENSE("GPL");
3501 MODULE_AUTHOR("XGITECH , Others");
3503 module_param(mem, int, 0);
3504 module_param(noaccel, int, 0);
3505 module_param(noypan, int, 0);
3506 module_param(nomax, int, 0);
3507 module_param(userom, int, 0);
3508 module_param(useoem, int, 0);
3509 module_param(mode, charp, 0);
3510 module_param(vesa, int, 0);
3511 module_param(rate, int, 0);
3512 module_param(forcecrt1, int, 0);
3513 module_param(forcecrt2type, charp, 0);
3514 module_param(scalelcd, int, 0);
3515 module_param(pdc, int, 0);
3516 module_param(pdc1, int, 0);
3517 module_param(specialtiming, charp, 0);
3518 module_param(lvdshl, int, 0);
3519 module_param(tvstandard, charp, 0);
3520 module_param(tvxposoffset, int, 0);
3521 module_param(tvyposoffset, int, 0);
3522 module_param(filter, int, 0);
3523 module_param(nocrt2rate, int, 0);
3524 #if !defined(__i386__) && !defined(__x86_64__)
3525 module_param(resetcard, int, 0);
3526 module_param(videoram, int, 0);
3529 MODULE_PARM_DESC(mem,
3530 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3531 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3532 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3533 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3534 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3535 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3536 "for XFree86 4.x/X.org 6.7 and later.\n");
3538 MODULE_PARM_DESC(noaccel,
3539 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3542 MODULE_PARM_DESC(noypan,
3543 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3544 "will be performed by redrawing the screen. (default: 0)\n");
3546 MODULE_PARM_DESC(nomax,
3547 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3548 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3549 "this is set to anything other than 0, xgifb will not do this and thereby\n"
3550 "enable the user to positively specify a virtual Y size of the screen using\n"
3551 "fbset. (default: 0)\n");
3553 MODULE_PARM_DESC(mode,
3554 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3555 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3556 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3557 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
3559 MODULE_PARM_DESC(vesa,
3560 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3561 "0x117 (default: 0x0103)\n");
3563 MODULE_PARM_DESC(rate,
3564 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3565 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3566 "will be ignored (default: 60)\n");
3568 MODULE_PARM_DESC(forcecrt1,
3569 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
3570 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3571 "0=CRT1 OFF) (default: [autodetected])\n");
3573 MODULE_PARM_DESC(forcecrt2type,
3574 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3575 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3576 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3577 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3578 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3579 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3580 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3581 "depends on the very hardware in use. (default: [autodetected])\n");
3583 MODULE_PARM_DESC(scalelcd,
3584 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3585 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3586 "show black bars around the image, TMDS panels will probably do the scaling\n"
3587 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
3589 MODULE_PARM_DESC(pdc,
3590 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3591 "should detect this correctly in most cases; however, sometimes this is not\n"
3592 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3593 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3594 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3595 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
3597 MODULE_PARM_DESC(pdc1,
3598 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3599 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3600 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3601 "implemented yet.\n");
3603 MODULE_PARM_DESC(specialtiming,
3604 "\nPlease refer to documentation for more information on this option.\n");
3606 MODULE_PARM_DESC(lvdshl,
3607 "\nPlease refer to documentation for more information on this option.\n");
3609 MODULE_PARM_DESC(tvstandard,
3610 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3611 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
3613 MODULE_PARM_DESC(tvxposoffset,
3614 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3617 MODULE_PARM_DESC(tvyposoffset,
3618 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3621 MODULE_PARM_DESC(filter,
3622 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3623 "(Possible values 0-7, default: [no filter])\n");
3625 MODULE_PARM_DESC(nocrt2rate,
3626 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3627 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
3629 static int __init xgifb_init_module(void)
3631 printk("\nXGIfb_init_module");
3633 XGIfb_search_mode(mode);
3634 else if (vesa != -1)
3635 XGIfb_search_vesamode(vesa);
3637 return xgifb_init();
3640 static void __exit xgifb_remove_module(void)
3642 pci_unregister_driver(&xgifb_driver);
3643 printk(KERN_DEBUG "xgifb: Module unloaded\n");
3646 module_init(xgifb_init_module);
3647 module_exit(xgifb_remove_module);
3649 #endif /* /MODULE */
3651 EXPORT_SYMBOL(XGI_malloc);
3652 EXPORT_SYMBOL(XGI_free);