2 * XG20, XG21, XG40, XG42 frame buffer device
3 * for Linux kernels 2.5.x, 2.6.x
4 * Base on TW's sis fbdev code.
7 /* #include <linux/config.h> */
8 #include <linux/version.h>
9 #include <linux/module.h>
10 #include <linux/moduleparam.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
16 #include <linux/tty.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
20 #include <linux/console.h>
21 #include <linux/selection.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/pci.h>
25 #include <linux/vmalloc.h>
26 #include <linux/vt_kern.h>
27 #include <linux/capability.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
46 #include "vb_setmode.h"
48 #define Index_CR_GPIO_Reg1 0x48
49 #define Index_CR_GPIO_Reg2 0x49
50 #define Index_CR_GPIO_Reg3 0x4a
52 #define GPIOG_EN (1<<6)
53 #define GPIOG_WRITE (1<<6)
54 #define GPIOG_READ (1<<1)
56 #define XGIFB_ROM_SIZE 65536
58 /* -------------------- Macro definitions ---------------------------- */
63 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
65 #define DPRINTK(fmt, args...)
69 static void dumpVGAReg(void)
73 xgifb_reg_set(XGISR, 0x05, 0x86);
75 xgifb_reg_set(XGISR, 0x08, 0x4f);
76 xgifb_reg_set(XGISR, 0x0f, 0x20);
77 xgifb_reg_set(XGISR, 0x11, 0x4f);
78 xgifb_reg_set(XGISR, 0x13, 0x45);
79 xgifb_reg_set(XGISR, 0x14, 0x51);
80 xgifb_reg_set(XGISR, 0x1e, 0x41);
81 xgifb_reg_set(XGISR, 0x1f, 0x0);
82 xgifb_reg_set(XGISR, 0x20, 0xa1);
83 xgifb_reg_set(XGISR, 0x22, 0xfb);
84 xgifb_reg_set(XGISR, 0x26, 0x22);
85 xgifb_reg_set(XGISR, 0x3e, 0x07);
88 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
89 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
90 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
91 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
93 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
95 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
96 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
98 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
99 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
101 xgifb_reg_set(XGICR, 0x99, 0x1);
102 xgifb_reg_set(XGICR, 0x41, 0x40);
105 for (i = 0; i < 0x4f; i++) {
106 reg = xgifb_reg_get(XGISR, i);
107 printk("\no 3c4 %x", i);
108 printk("\ni 3c5 => %x", reg);
111 for (i = 0; i < 0xF0; i++) {
112 reg = xgifb_reg_get(XGICR, i);
113 printk("\no 3d4 %x", i);
114 printk("\ni 3d5 => %x", reg);
117 xgifb_reg_set(XGIPART1,0x2F,1);
118 for (i=1; i < 0x50; i++) {
119 reg = xgifb_reg_get(XGIPART1, i);
120 printk("\no d004 %x", i);
121 printk("\ni d005 => %x", reg);
124 for (i=0; i < 0x50; i++) {
125 reg = xgifb_reg_get(XGIPART2, i);
126 printk("\no d010 %x", i);
127 printk("\ni d011 => %x", reg);
129 for (i=0; i < 0x50; i++) {
130 reg = xgifb_reg_get(XGIPART3, i);
131 printk("\no d012 %x",i);
132 printk("\ni d013 => %x",reg);
134 for (i=0; i < 0x50; i++) {
135 reg = xgifb_reg_get(XGIPART4, i);
136 printk("\no d014 %x",i);
137 printk("\ni d015 => %x",reg);
142 static inline void dumpVGAReg(void)
147 /* data for XGI components */
148 struct video_info xgi_video_info;
153 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
156 /* --------------- Hardware Access Routines -------------------------- */
158 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
159 struct xgi_hw_device_info *HwDeviceExtension,
160 unsigned char modeno, unsigned char rateindex)
162 unsigned short ModeNo = modeno;
163 unsigned short ModeIdIndex = 0, ClockIndex = 0;
164 unsigned short RefreshRateTableIndex = 0;
166 /* unsigned long temp = 0; */
168 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
169 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
171 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
172 ModeIdIndex, XGI_Pr);
175 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
177 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
181 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
182 RefreshRateTableIndex += (rateindex - 1);
185 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
187 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
192 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
193 struct xgi_hw_device_info *HwDeviceExtension,
194 unsigned char modeno, unsigned char rateindex,
195 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
196 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
199 unsigned short ModeNo = modeno;
200 unsigned short ModeIdIndex = 0, index = 0;
201 unsigned short RefreshRateTableIndex = 0;
203 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
204 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
205 unsigned char sr_data, cr_data, cr_data2;
206 unsigned long cr_data3;
207 int A, B, C, D, E, F, temp, j;
208 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
209 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
210 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
211 ModeIdIndex, XGI_Pr);
213 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
217 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
218 RefreshRateTableIndex += (rateindex - 1);
220 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
222 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
224 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
226 /* Horizontal total */
227 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
231 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
233 Horizontal display enable end
234 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
236 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
239 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
241 /* Horizontal retrace (=sync) start */
242 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
245 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
247 /* Horizontal blank start */
248 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
250 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
252 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
254 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
256 /* Horizontal blank end */
257 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
258 | ((unsigned short) (sr_data & 0x03) << 6);
260 /* Horizontal retrace (=sync) end */
261 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
263 temp = HBE - ((E - 1) & 255);
264 B = (temp > 0) ? temp : (temp + 256);
266 temp = HRE - ((E + F + 3) & 63);
267 C = (temp > 0) ? temp : (temp + 64);
271 *left_margin = D * 8;
272 *right_margin = F * 8;
275 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
277 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
279 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
282 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
283 | ((unsigned short) (cr_data2 & 0x20) << 4)
284 | ((unsigned short) (sr_data & 0x01) << 10);
287 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
289 /* Vertical display enable end */
291 VDE = (cr_data & 0xff) |
292 ((unsigned short) (cr_data2 & 0x02) << 7) |
293 ((unsigned short) (cr_data2 & 0x40) << 3) |
294 ((unsigned short) (sr_data & 0x02) << 9);
296 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
299 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
301 /* Vertical retrace (=sync) start */
302 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
303 | ((unsigned short) (cr_data2 & 0x80) << 2)
304 | ((unsigned short) (sr_data & 0x08) << 7);
307 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
309 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
311 /* Vertical blank start */
312 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
313 | ((unsigned short) (cr_data3 & 0x20) << 4)
314 | ((unsigned short) (sr_data & 0x04) << 8);
316 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
318 /* Vertical blank end */
319 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
320 temp = VBE - ((E - 1) & 511);
321 B = (temp > 0) ? temp : (temp + 512);
323 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
325 /* Vertical retrace (=sync) end */
326 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
327 temp = VRE - ((E + F - 1) & 31);
328 C = (temp > 0) ? temp : (temp + 32);
336 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
337 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
339 *sync |= FB_SYNC_VERT_HIGH_ACT;
341 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
342 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
344 *sync |= FB_SYNC_HOR_HIGH_ACT;
346 *vmode = FB_VMODE_NONINTERLACED;
347 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
348 *vmode = FB_VMODE_INTERLACED;
351 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
352 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
353 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
354 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
356 *vmode = FB_VMODE_DOUBLE;
367 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
369 XGI_Pr->RelIO = BaseAddr;
370 XGI_Pr->P3c4 = BaseAddr + 0x14;
371 XGI_Pr->P3d4 = BaseAddr + 0x24;
372 XGI_Pr->P3c0 = BaseAddr + 0x10;
373 XGI_Pr->P3ce = BaseAddr + 0x1e;
374 XGI_Pr->P3c2 = BaseAddr + 0x12;
375 XGI_Pr->P3ca = BaseAddr + 0x1a;
376 XGI_Pr->P3c6 = BaseAddr + 0x16;
377 XGI_Pr->P3c7 = BaseAddr + 0x17;
378 XGI_Pr->P3c8 = BaseAddr + 0x18;
379 XGI_Pr->P3c9 = BaseAddr + 0x19;
380 XGI_Pr->P3da = BaseAddr + 0x2A;
381 /* Digital video interface registers (LCD) */
382 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
383 /* 301 TV Encoder registers */
384 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
385 /* 301 Macrovision registers */
386 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
387 /* 301 VGA2 (and LCD) registers */
388 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
389 /* 301 palette address port registers */
390 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
394 /* ------------ Interface for init & mode switching code ------------- */
396 static unsigned char XGIfb_query_VGA_config_space(
397 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
398 unsigned long set, unsigned long *value)
400 static struct pci_dev *pdev = NULL;
401 static unsigned char init = 0, valid_pdev = 0;
404 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
406 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
410 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
419 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
420 xgi_video_info.chip_id);
425 pci_read_config_dword(pdev, offset, (u32 *) value);
427 pci_write_config_dword(pdev, offset, (u32)(*value));
432 /* ------------------ Internal helper routines ----------------- */
434 static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
438 int XGIfb_mode_idx = 0;
441 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
442 && (XGIbios_mode[XGIfb_mode_idx].xres
443 <= XGI21_LCDCapList[0].LVDSHDE)) {
444 if ((XGIbios_mode[XGIfb_mode_idx].xres
445 == XGI21_LCDCapList[0].LVDSHDE)
446 && (XGIbios_mode[XGIfb_mode_idx].yres
447 == XGI21_LCDCapList[0].LVDSVDE)
448 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
449 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
458 return XGIfb_mode_idx;
461 static void XGIfb_search_mode(const char *name)
466 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
467 xgifb_mode_idx = DEFAULT_MODE;
468 if ((xgi_video_info.chip == XG21)
469 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
471 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
476 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
477 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
478 xgifb_mode_idx = DEFAULT_MODE;
479 if ((xgi_video_info.chip == XG21)
480 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
482 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
487 while (XGIbios_mode[i].mode_no != 0) {
488 l = min(strlen(name), strlen(XGIbios_mode[i].name));
489 if (!strncmp(name, XGIbios_mode[i].name, l)) {
497 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
500 static void XGIfb_search_vesamode(unsigned int vesamode)
506 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
507 xgifb_mode_idx = DEFAULT_MODE;
508 if ((xgi_video_info.chip == XG21)
509 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
511 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
516 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
518 while (XGIbios_mode[i].mode_no != 0) {
519 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
520 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
528 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
531 static int XGIfb_GetXG21LVDSData(void)
534 unsigned char *pData;
537 tmp = xgifb_reg_get(XGISR, 0x1e);
538 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
540 pData = xgi_video_info.mmio_vbase + 0x20000;
541 if ((pData[0x0] == 0x55) &&
542 (pData[0x1] == 0xAA) &&
543 (pData[0x65] & 0x1)) {
544 i = pData[0x316] | (pData[0x317] << 8);
551 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
552 | (pData[i + 1] << 8);
553 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
555 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
557 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
559 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
561 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
563 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
565 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
566 | (pData[i + 15] << 8);
567 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
568 | (pData[i + 17] << 8);
569 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
570 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
571 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
572 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
573 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
574 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
575 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
579 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
580 / sizeof(struct XGI21_LVDSCapStruct))));
586 static int XGIfb_validate_mode(int myindex)
590 if (xgi_video_info.chip == XG21) {
591 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
593 xres = XGI21_LCDCapList[0].LVDSHDE;
594 yres = XGI21_LCDCapList[0].LVDSVDE;
595 if (XGIbios_mode[myindex].xres > xres)
597 if (XGIbios_mode[myindex].yres > yres)
599 if ((XGIbios_mode[myindex].xres < xres) &&
600 (XGIbios_mode[myindex].yres < yres)) {
601 if (XGIbios_mode[myindex].bpp > 8)
610 /* FIXME: for now, all is valid on XG27 */
611 if (xgi_video_info.chip == XG27)
614 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
617 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
619 switch (XGIhw_ext.ulCRT2LCDType) {
660 /* case LCD_320x480: */ /* TW: FSTN */
671 if (XGIbios_mode[myindex].xres > xres)
673 if (XGIbios_mode[myindex].yres > yres)
675 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
676 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
677 switch (XGIbios_mode[myindex].xres) {
679 if (XGIbios_mode[myindex].yres != 512)
681 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
685 if ((XGIbios_mode[myindex].yres != 400)
686 && (XGIbios_mode[myindex].yres
691 if (XGIbios_mode[myindex].yres != 600)
695 if ((XGIbios_mode[myindex].yres != 600) &&
696 (XGIbios_mode[myindex].yres != 768))
698 if ((XGIbios_mode[myindex].yres == 600) &&
699 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
703 if ((XGIbios_mode[myindex].yres) != 768)
705 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
709 if ((XGIbios_mode[myindex].yres != 768) &&
710 (XGIbios_mode[myindex].yres != 1024))
712 if ((XGIbios_mode[myindex].yres == 768) &&
713 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
717 if (XGIbios_mode[myindex].yres != 1050)
721 if (XGIbios_mode[myindex].yres != 1200)
728 switch (XGIbios_mode[myindex].xres) {
730 if (XGIbios_mode[myindex].yres != 512)
734 if ((XGIbios_mode[myindex].yres != 400) &&
735 (XGIbios_mode[myindex].yres != 480))
739 if (XGIbios_mode[myindex].yres != 600)
743 if (XGIbios_mode[myindex].yres != 768)
747 if ((XGIbios_mode[myindex].yres != 960) &&
748 (XGIbios_mode[myindex].yres != 1024))
750 if (XGIbios_mode[myindex].yres == 960) {
751 if (XGIhw_ext.ulCRT2LCDType ==
757 if (XGIbios_mode[myindex].yres != 1050)
761 if (XGIbios_mode[myindex].yres != 1200)
770 switch (XGIbios_mode[myindex].xres) {
776 if (xgi_video_info.TV_type == TVMODE_NTSC) {
777 if (XGIbios_mode[myindex].yres != 480)
779 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
780 if (XGIbios_mode[myindex].yres != 576)
783 /* TW: LVDS/CHRONTEL does not support 720 */
784 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
785 xgi_video_info.hasVB == HASVB_CHRONTEL) {
790 if (xgi_video_info.TV_type == TVMODE_NTSC) {
791 if (XGIbios_mode[myindex].bpp == 32)
800 if (XGIbios_mode[myindex].xres > 1280)
808 static void XGIfb_search_crt2type(const char *name)
815 while (XGI_crt2type[i].type_no != -1) {
816 if (!strcmp(name, XGI_crt2type[i].name)) {
817 XGIfb_crt2type = XGI_crt2type[i].type_no;
818 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
823 if (XGIfb_crt2type < 0)
824 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
827 static u8 XGIfb_search_refresh_rate(unsigned int rate)
832 xres = XGIbios_mode[xgifb_mode_idx].xres;
833 yres = XGIbios_mode[xgifb_mode_idx].yres;
836 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
837 if ((XGIfb_vrate[i].xres == xres) &&
838 (XGIfb_vrate[i].yres == yres)) {
839 if (XGIfb_vrate[i].refresh == rate) {
840 XGIfb_rate_idx = XGIfb_vrate[i].idx;
842 } else if (XGIfb_vrate[i].refresh > rate) {
843 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
844 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
845 rate, XGIfb_vrate[i].refresh);
846 XGIfb_rate_idx = XGIfb_vrate[i].idx;
847 xgi_video_info.refresh_rate =
848 XGIfb_vrate[i].refresh;
849 } else if (((rate - XGIfb_vrate[i - 1].refresh)
850 <= 2) && (XGIfb_vrate[i].idx
852 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
853 rate, XGIfb_vrate[i-1].refresh);
854 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
855 xgi_video_info.refresh_rate =
856 XGIfb_vrate[i - 1].refresh;
859 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
860 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
861 rate, XGIfb_vrate[i].refresh);
862 XGIfb_rate_idx = XGIfb_vrate[i].idx;
868 if (XGIfb_rate_idx > 0) {
869 return XGIfb_rate_idx;
871 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
877 static void XGIfb_search_tvstd(const char *name)
884 while (XGI_tvtype[i].type_no != -1) {
885 if (!strcmp(name, XGI_tvtype[i].name)) {
886 XGIfb_tvmode = XGI_tvtype[i].type_no;
893 /* ----------- FBDev related routines for all series ----------- */
895 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
897 switch (var->bits_per_pixel) {
899 var->red.offset = var->green.offset = var->blue.offset = 0;
900 var->red.length = var->green.length = var->blue.length = 6;
901 xgi_video_info.video_cmap_len = 256;
904 var->red.offset = 11;
906 var->green.offset = 5;
907 var->green.length = 6;
908 var->blue.offset = 0;
909 var->blue.length = 5;
910 var->transp.offset = 0;
911 var->transp.length = 0;
912 xgi_video_info.video_cmap_len = 16;
915 var->red.offset = 16;
917 var->green.offset = 8;
918 var->green.length = 8;
919 var->blue.offset = 0;
920 var->blue.length = 8;
921 var->transp.offset = 24;
922 var->transp.length = 8;
923 xgi_video_info.video_cmap_len = 16;
928 /* --------------------- SetMode routines ------------------------- */
930 static void XGIfb_pre_setmode(void)
932 u8 cr30 = 0, cr31 = 0;
934 cr31 = xgifb_reg_get(XGICR, 0x31);
937 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
939 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
940 cr31 |= XGI_DRIVER_MODE;
943 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
944 cr31 |= XGI_DRIVER_MODE;
947 if (xgi_video_info.TV_type == TVMODE_HIVISION)
948 cr30 = (XGI_VB_OUTPUT_HIVISION
949 | XGI_SIMULTANEOUS_VIEW_ENABLE);
950 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
951 cr30 = (XGI_VB_OUTPUT_SVIDEO
952 | XGI_SIMULTANEOUS_VIEW_ENABLE);
953 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
954 cr30 = (XGI_VB_OUTPUT_COMPOSITE
955 | XGI_SIMULTANEOUS_VIEW_ENABLE);
956 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
957 cr30 = (XGI_VB_OUTPUT_SCART
958 | XGI_SIMULTANEOUS_VIEW_ENABLE);
959 cr31 |= XGI_DRIVER_MODE;
961 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
966 default: /* disable CRT2 */
968 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
971 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
972 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
973 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
976 static void XGIfb_post_setmode(void)
979 unsigned char doit = 1;
981 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
982 xgifb_reg_set(XGICR, 0x13, 0x00);
983 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
986 if (xgi_video_info.video_bpp == 8) {
987 /* TW: We can't switch off CRT1 on LVDS/Chrontel
989 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
990 (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
993 /* TW: We can't switch off CRT1 on 301B-DH
994 * in 8bpp Modes if using LCD */
995 if (xgi_video_info.disp_state & DISPTYPE_LCD)
999 /* TW: We can't switch off CRT1 if bridge is in slave mode */
1000 if (xgi_video_info.hasVB != HASVB_NONE) {
1001 reg = xgifb_reg_get(XGIPART1, 0x00);
1003 if ((reg & 0x50) == 0x10)
1010 reg = xgifb_reg_get(XGICR, 0x17);
1011 if ((XGIfb_crt1off) && (doit))
1015 xgifb_reg_set(XGICR, 0x17, reg);
1017 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1019 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1022 reg = xgifb_reg_get(XGIPART4, 0x01);
1024 if (reg < 0xB0) { /* Set filter for XGI301 */
1025 switch (xgi_video_info.video_width) {
1027 filter_tb = (xgi_video_info.TV_type ==
1028 TVMODE_NTSC) ? 4 : 12;
1031 filter_tb = (xgi_video_info.TV_type ==
1032 TVMODE_NTSC) ? 5 : 13;
1035 filter_tb = (xgi_video_info.TV_type ==
1036 TVMODE_NTSC) ? 6 : 14;
1039 filter_tb = (xgi_video_info.TV_type ==
1040 TVMODE_NTSC) ? 7 : 15;
1046 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1048 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1050 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1052 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1054 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1056 } else if (xgi_video_info.TV_plug
1057 == TVPLUG_COMPOSITE) {
1059 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1061 switch (xgi_video_info.video_width) {
1063 xgifb_reg_set(XGIPART2,
1066 xgifb_reg_set(XGIPART2,
1069 xgifb_reg_set(XGIPART2,
1072 xgifb_reg_set(XGIPART2,
1077 xgifb_reg_set(XGIPART2,
1080 xgifb_reg_set(XGIPART2,
1083 xgifb_reg_set(XGIPART2,
1086 xgifb_reg_set(XGIPART2,
1091 xgifb_reg_set(XGIPART2,
1094 xgifb_reg_set(XGIPART2,
1097 xgifb_reg_set(XGIPART2,
1100 xgifb_reg_set(XGIPART2,
1107 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1109 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1111 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1113 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1115 } else if (xgi_video_info.TV_plug
1116 == TVPLUG_COMPOSITE) {
1118 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1120 switch (xgi_video_info.video_width) {
1122 xgifb_reg_set(XGIPART2,
1125 xgifb_reg_set(XGIPART2,
1128 xgifb_reg_set(XGIPART2,
1131 xgifb_reg_set(XGIPART2,
1136 xgifb_reg_set(XGIPART2,
1139 xgifb_reg_set(XGIPART2,
1142 xgifb_reg_set(XGIPART2,
1145 xgifb_reg_set(XGIPART2,
1150 xgifb_reg_set(XGIPART2,
1153 xgifb_reg_set(XGIPART2,
1156 xgifb_reg_set(XGIPART2,
1159 xgifb_reg_set(XGIPART2,
1167 if ((filter >= 0) && (filter <= 7)) {
1168 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1170 XGI_TV_filter[filter_tb].
1172 XGI_TV_filter[filter_tb].
1174 XGI_TV_filter[filter_tb].
1176 XGI_TV_filter[filter_tb].
1182 (XGI_TV_filter[filter_tb].
1183 filter[filter][0]));
1187 (XGI_TV_filter[filter_tb].
1188 filter[filter][1]));
1192 (XGI_TV_filter[filter_tb].
1193 filter[filter][2]));
1197 (XGI_TV_filter[filter_tb].
1198 filter[filter][3]));
1204 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1205 struct fb_info *info)
1208 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1210 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1212 #if defined(__powerpc__)
1213 u8 sr_data, cr_data;
1215 unsigned int drate = 0, hrate = 0;
1218 /* unsigned char reg, reg1; */
1220 DEBUGPRN("Inside do_set_var");
1221 /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */
1223 info->var.xres_virtual = var->xres_virtual;
1224 info->var.yres_virtual = var->yres_virtual;
1225 info->var.bits_per_pixel = var->bits_per_pixel;
1227 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1229 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1231 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1233 /* var->yres <<= 1; */
1236 if (!htotal || !vtotal) {
1237 DPRINTK("XGIfb: Invalid 'var' information\n");
1239 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1240 var->pixclock, htotal, vtotal);
1242 if (var->pixclock && htotal && vtotal) {
1243 drate = 1000000000 / var->pixclock;
1244 hrate = (drate * 1000) / htotal;
1245 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1248 xgi_video_info.refresh_rate = 60;
1251 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1254 var->bits_per_pixel,
1255 xgi_video_info.refresh_rate);
1257 old_mode = xgifb_mode_idx;
1260 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1261 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1262 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1263 && (XGIbios_mode[xgifb_mode_idx].yres
1265 && (XGIbios_mode[xgifb_mode_idx].bpp
1266 == var->bits_per_pixel)) {
1267 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1275 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1277 xgifb_mode_idx = -1;
1279 if (xgifb_mode_idx < 0) {
1280 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1281 var->xres, var->yres, var->bits_per_pixel);
1282 xgifb_mode_idx = old_mode;
1286 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1287 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1288 xgi_video_info.refresh_rate = 60;
1293 XGIfb_pre_setmode();
1294 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1295 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1299 info->fix.line_length = ((info->var.xres_virtual
1300 * info->var.bits_per_pixel) >> 6);
1302 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1304 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1305 xgifb_reg_set(XGISR,
1307 (info->fix.line_length & 0xff00) >> 8);
1309 XGIfb_post_setmode();
1311 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1312 XGIbios_mode[xgifb_mode_idx].xres,
1313 XGIbios_mode[xgifb_mode_idx].yres,
1314 XGIbios_mode[xgifb_mode_idx].bpp,
1315 xgi_video_info.refresh_rate);
1317 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1318 xgi_video_info.video_vwidth = info->var.xres_virtual;
1319 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1320 xgi_video_info.video_vheight = info->var.yres_virtual;
1321 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1322 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1323 xgi_video_info.video_linelength = info->var.xres_virtual
1324 * (xgi_video_info.video_bpp >> 3);
1325 switch (xgi_video_info.video_bpp) {
1327 xgi_video_info.DstColor = 0x0000;
1328 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1329 xgi_video_info.video_cmap_len = 256;
1330 #if defined(__powerpc__)
1331 cr_data = xgifb_reg_get(XGICR, 0x4D);
1332 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1336 xgi_video_info.DstColor = 0x8000;
1337 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1338 #if defined(__powerpc__)
1339 cr_data = xgifb_reg_get(XGICR, 0x4D);
1340 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1342 xgi_video_info.video_cmap_len = 16;
1345 xgi_video_info.DstColor = 0xC000;
1346 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1347 xgi_video_info.video_cmap_len = 16;
1348 #if defined(__powerpc__)
1349 cr_data = xgifb_reg_get(XGICR, 0x4D);
1350 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1354 xgi_video_info.video_cmap_len = 16;
1355 printk(KERN_ERR "XGIfb: Unsupported depth %d",
1356 xgi_video_info.video_bpp);
1360 XGIfb_bpp_to_var(var); /*update ARGB info*/
1361 DEBUGPRN("End of do_set_var");
1368 static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1372 /* printk("Inside pan_var"); */
1374 base = var->yoffset * info->var.xres_virtual + var->xoffset;
1376 /* calculate base bpp dep. */
1377 switch (info->var.bits_per_pixel) {
1389 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1391 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1392 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1393 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1394 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1395 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1397 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1398 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1399 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1400 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1401 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1402 xgifb_reg_and_or(XGIPART1,
1405 ((base >> 24) & 0x01) << 7);
1407 /* printk("End of pan_var"); */
1412 static int XGIfb_open(struct fb_info *info, int user)
1417 static int XGIfb_release(struct fb_info *info, int user)
1422 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1426 switch (var->bits_per_pixel) {
1440 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1441 unsigned blue, unsigned transp, struct fb_info *info)
1443 if (regno >= XGIfb_get_cmap_len(&info->var))
1446 switch (info->var.bits_per_pixel) {
1448 outb(regno, XGIDACA);
1449 outb((red >> 10), XGIDACD);
1450 outb((green >> 10), XGIDACD);
1451 outb((blue >> 10), XGIDACD);
1452 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1453 outb(regno, XGIDAC2A);
1454 outb((red >> 8), XGIDAC2D);
1455 outb((green >> 8), XGIDAC2D);
1456 outb((blue >> 8), XGIDAC2D);
1460 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1461 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1468 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1475 /* ----------- FBDev related routines for all series ---------- */
1477 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1478 struct fb_info *info)
1480 DEBUGPRN("inside get_fix");
1481 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1483 strcpy(fix->id, myid);
1485 fix->smem_start = xgi_video_info.video_base;
1487 fix->smem_len = xgi_video_info.video_size;
1489 fix->type = video_type;
1491 if (xgi_video_info.video_bpp == 8)
1492 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1494 fix->visual = FB_VISUAL_DIRECTCOLOR;
1501 fix->line_length = xgi_video_info.video_linelength;
1502 fix->mmio_start = xgi_video_info.mmio_base;
1503 fix->mmio_len = xgi_video_info.mmio_size;
1504 fix->accel = FB_ACCEL_XGI_XABRE;
1506 DEBUGPRN("end of get_fix");
1510 static int XGIfb_set_par(struct fb_info *info)
1514 /* printk("XGIfb: inside set_par\n"); */
1515 err = XGIfb_do_set_var(&info->var, 1, info);
1518 XGIfb_get_fix(&info->fix, -1, info);
1519 /* printk("XGIfb: end of set_par\n"); */
1523 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1525 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1527 unsigned int vtotal = 0;
1528 unsigned int drate = 0, hrate = 0;
1530 int refresh_rate, search_idx;
1532 DEBUGPRN("Inside check_var");
1534 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1535 vtotal = var->upper_margin + var->yres + var->lower_margin
1538 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1539 vtotal = var->upper_margin + var->yres + var->lower_margin
1542 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1543 vtotal = var->upper_margin + (var->yres / 2)
1544 + var->lower_margin + var->vsync_len;
1546 vtotal = var->upper_margin + var->yres + var->lower_margin
1549 if (!(htotal) || !(vtotal))
1550 XGIFAIL("XGIfb: no valid timing data");
1552 if (var->pixclock && htotal && vtotal) {
1553 drate = 1000000000 / var->pixclock;
1554 hrate = (drate * 1000) / htotal;
1555 xgi_video_info.refresh_rate =
1556 (unsigned int) (hrate * 2 / vtotal);
1558 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1559 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1560 __func__, var->pixclock, htotal, vtotal,
1561 __func__, drate, hrate, xgi_video_info.refresh_rate);
1563 xgi_video_info.refresh_rate = 60;
1567 if ((var->pixclock) && (htotal)) {
1568 drate = 1E12 / var->pixclock;
1569 hrate = drate / htotal;
1570 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1575 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1576 if ((var->xres == 1024) && (var->yres == 600))
1580 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1581 (XGIbios_mode[search_idx].xres <= var->xres)) {
1582 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1583 (XGIbios_mode[search_idx].yres == var->yres) &&
1584 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1585 if (XGIfb_validate_mode(search_idx) > 0) {
1595 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1596 var->xres, var->yres, var->bits_per_pixel);
1598 while (XGIbios_mode[search_idx].mode_no != 0) {
1599 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1600 (var->yres <= XGIbios_mode[search_idx].yres) &&
1601 (var->bits_per_pixel ==
1602 XGIbios_mode[search_idx].bpp)) {
1603 if (XGIfb_validate_mode(search_idx) > 0) {
1611 var->xres = XGIbios_mode[search_idx].xres;
1612 var->yres = XGIbios_mode[search_idx].yres;
1613 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1614 var->xres, var->yres, var->bits_per_pixel);
1617 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1618 var->xres, var->yres, var->bits_per_pixel);
1623 /* TW: TODO: Check the refresh rate */
1625 /* Adapt RGB settings */
1626 XGIfb_bpp_to_var(var);
1628 /* Sanity check for offsets */
1629 if (var->xoffset < 0)
1631 if (var->yoffset < 0)
1635 if (var->xres != var->xres_virtual)
1636 var->xres_virtual = var->xres;
1637 if (var->yres != var->yres_virtual)
1638 var->yres_virtual = var->yres;
1640 /* TW: Now patch yres_virtual if we use panning */
1641 /* May I do this? */
1642 /* var->yres_virtual = xgi_video_info.heapstart /
1643 (var->xres * (var->bits_per_pixel >> 3)); */
1644 /* if (var->yres_virtual <= var->yres) { */
1645 /* TW: Paranoia check */
1646 /* var->yres_virtual = var->yres; */
1650 /* Truncate offsets to maximum if too high */
1651 if (var->xoffset > var->xres_virtual - var->xres)
1652 var->xoffset = var->xres_virtual - var->xres - 1;
1654 if (var->yoffset > var->yres_virtual - var->yres)
1655 var->yoffset = var->yres_virtual - var->yres - 1;
1657 /* Set everything else to 0 */
1658 var->red.msb_right =
1659 var->green.msb_right =
1660 var->blue.msb_right =
1661 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1663 DEBUGPRN("end of check_var");
1668 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1669 struct fb_info *info)
1673 /* printk("\nInside pan_display:\n"); */
1675 if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1677 if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1680 if (var->vmode & FB_VMODE_YWRAP) {
1681 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1685 if (var->xoffset + info->var.xres > info->var.xres_virtual
1686 || var->yoffset + info->var.yres
1687 > info->var.yres_virtual)
1690 err = XGIfb_pan_var(var, info);
1694 info->var.xoffset = var->xoffset;
1695 info->var.yoffset = var->yoffset;
1696 if (var->vmode & FB_VMODE_YWRAP)
1697 info->var.vmode |= FB_VMODE_YWRAP;
1699 info->var.vmode &= ~FB_VMODE_YWRAP;
1701 /* printk("End of pan_display\n"); */
1706 static int XGIfb_blank(int blank, struct fb_info *info)
1710 reg = xgifb_reg_get(XGICR, 0x17);
1717 xgifb_reg_set(XGICR, 0x17, reg);
1718 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1719 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1723 static struct fb_ops XGIfb_ops = {
1724 .owner = THIS_MODULE,
1725 .fb_open = XGIfb_open,
1726 .fb_release = XGIfb_release,
1727 .fb_check_var = XGIfb_check_var,
1728 .fb_set_par = XGIfb_set_par,
1729 .fb_setcolreg = XGIfb_setcolreg,
1731 .fb_pan_display = XGIfb_pan_display,
1733 .fb_blank = XGIfb_blank,
1734 .fb_fillrect = cfb_fillrect,
1735 .fb_copyarea = cfb_copyarea,
1736 .fb_imageblit = cfb_imageblit,
1737 /* .fb_mmap = XGIfb_mmap, */
1740 /* ---------------- Chip generation dependent routines ---------------- */
1742 /* for XGI 315/550/650/740/330 */
1744 static int XGIfb_get_dram_size(void)
1750 /* xorg driver sets 32MB * 1 channel */
1751 if (xgi_video_info.chip == XG27)
1752 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1754 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
1755 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1756 case XGI_DRAM_SIZE_1MB:
1757 xgi_video_info.video_size = 0x100000;
1759 case XGI_DRAM_SIZE_2MB:
1760 xgi_video_info.video_size = 0x200000;
1762 case XGI_DRAM_SIZE_4MB:
1763 xgi_video_info.video_size = 0x400000;
1765 case XGI_DRAM_SIZE_8MB:
1766 xgi_video_info.video_size = 0x800000;
1768 case XGI_DRAM_SIZE_16MB:
1769 xgi_video_info.video_size = 0x1000000;
1771 case XGI_DRAM_SIZE_32MB:
1772 xgi_video_info.video_size = 0x2000000;
1774 case XGI_DRAM_SIZE_64MB:
1775 xgi_video_info.video_size = 0x4000000;
1777 case XGI_DRAM_SIZE_128MB:
1778 xgi_video_info.video_size = 0x8000000;
1780 case XGI_DRAM_SIZE_256MB:
1781 xgi_video_info.video_size = 0x10000000;
1787 tmp = (reg & 0x0c) >> 2;
1788 switch (xgi_video_info.chip) {
1824 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1825 /* PLiad fixed for benchmarking and fb set */
1826 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1827 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1829 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1831 xgi_video_info.video_size, ChannelNum);
1836 static void XGIfb_detect_VB(void)
1840 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1842 switch (xgi_video_info.hasVB) {
1843 case HASVB_LVDS_CHRONTEL:
1844 case HASVB_CHRONTEL:
1848 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1852 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1854 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1863 if (XGIfb_crt2type != -1)
1864 /* TW: Override with option */
1865 xgi_video_info.disp_state = XGIfb_crt2type;
1866 else if (cr32 & XGI_VB_TV)
1867 xgi_video_info.disp_state = DISPTYPE_TV;
1868 else if (cr32 & XGI_VB_LCD)
1869 xgi_video_info.disp_state = DISPTYPE_LCD;
1870 else if (cr32 & XGI_VB_CRT2)
1871 xgi_video_info.disp_state = DISPTYPE_CRT2;
1873 xgi_video_info.disp_state = 0;
1875 if (XGIfb_tvplug != -1)
1876 /* PR/TW: Override with option */
1877 xgi_video_info.TV_plug = XGIfb_tvplug;
1878 else if (cr32 & XGI_VB_HIVISION) {
1879 xgi_video_info.TV_type = TVMODE_HIVISION;
1880 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1881 } else if (cr32 & XGI_VB_SVIDEO)
1882 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1883 else if (cr32 & XGI_VB_COMPOSITE)
1884 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1885 else if (cr32 & XGI_VB_SCART)
1886 xgi_video_info.TV_plug = TVPLUG_SCART;
1888 if (xgi_video_info.TV_type == 0) {
1889 temp = xgifb_reg_get(XGICR, 0x38);
1891 xgi_video_info.TV_type = TVMODE_PAL;
1893 xgi_video_info.TV_type = TVMODE_NTSC;
1896 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1897 if (XGIfb_forcecrt1 != -1) {
1898 if (XGIfb_forcecrt1)
1905 static int XGIfb_has_VB(void)
1909 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1910 switch (vb_chipid) {
1912 xgi_video_info.hasVB = HASVB_301;
1915 xgi_video_info.hasVB = HASVB_302;
1918 xgi_video_info.hasVB = HASVB_NONE;
1924 static void XGIfb_get_VB_type(void)
1928 if (!XGIfb_has_VB()) {
1929 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1930 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1931 case XGI310_EXTERNAL_CHIP_LVDS:
1932 xgi_video_info.hasVB = HASVB_LVDS;
1934 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1935 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1943 XGIINITSTATIC int __init XGIfb_setup(char *options)
1947 xgi_video_info.refresh_rate = 0;
1949 printk(KERN_INFO "XGIfb: Options %s\n", options);
1951 if (!options || !*options)
1954 while ((this_opt = strsep(&options, ",")) != NULL) {
1959 if (!strncmp(this_opt, "mode:", 5)) {
1960 XGIfb_search_mode(this_opt + 5);
1961 } else if (!strncmp(this_opt, "vesa:", 5)) {
1962 XGIfb_search_vesamode(simple_strtoul(
1963 this_opt + 5, NULL, 0));
1964 } else if (!strncmp(this_opt, "mode:", 5)) {
1965 XGIfb_search_mode(this_opt + 5);
1966 } else if (!strncmp(this_opt, "vesa:", 5)) {
1967 XGIfb_search_vesamode(simple_strtoul(
1968 this_opt + 5, NULL, 0));
1969 } else if (!strncmp(this_opt, "vrate:", 6)) {
1970 xgi_video_info.refresh_rate = simple_strtoul(
1971 this_opt + 6, NULL, 0);
1972 } else if (!strncmp(this_opt, "rate:", 5)) {
1973 xgi_video_info.refresh_rate = simple_strtoul(
1974 this_opt + 5, NULL, 0);
1975 } else if (!strncmp(this_opt, "off", 3)) {
1977 } else if (!strncmp(this_opt, "crt1off", 7)) {
1979 } else if (!strncmp(this_opt, "filter:", 7)) {
1980 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1981 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1982 XGIfb_search_crt2type(this_opt + 14);
1983 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1984 XGIfb_forcecrt1 = (int)simple_strtoul(
1985 this_opt + 10, NULL, 0);
1986 } else if (!strncmp(this_opt, "tvmode:", 7)) {
1987 XGIfb_search_tvstd(this_opt + 7);
1988 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1989 XGIfb_search_tvstd(this_opt + 7);
1990 } else if (!strncmp(this_opt, "dstn", 4)) {
1992 /* TW: DSTN overrules forcecrt2type */
1993 XGIfb_crt2type = DISPTYPE_LCD;
1994 } else if (!strncmp(this_opt, "pdc:", 4)) {
1995 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
1996 if (XGIfb_pdc & ~0x3c) {
1997 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2000 } else if (!strncmp(this_opt, "noypan", 6)) {
2002 } else if (!strncmp(this_opt, "userom:", 7)) {
2003 XGIfb_userom = (int)simple_strtoul(
2004 this_opt + 7, NULL, 0);
2005 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2006 /* XGIfb_useoem = (int)simple_strtoul(
2007 this_opt + 7, NULL, 0); */
2009 XGIfb_search_mode(this_opt);
2010 /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
2014 /* TW: Panning only with acceleration */
2018 printk("\nxgifb: outa xgifb_setup 3450");
2022 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2024 void __iomem *rom_address;
2025 unsigned char *rom_copy;
2028 rom_address = pci_map_rom(dev, &rom_size);
2029 if (rom_address == NULL)
2032 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2033 if (rom_copy == NULL)
2036 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2037 memcpy_fromio(rom_copy, rom_address, rom_size);
2040 pci_unmap_rom(dev, rom_address);
2044 static int __devinit xgifb_probe(struct pci_dev *pdev,
2045 const struct pci_device_id *ent)
2054 XGIfb_registered = 0;
2056 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2057 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2061 xgi_video_info.chip_id = pdev->device;
2062 pci_read_config_byte(pdev,
2064 &xgi_video_info.revision_id);
2065 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2067 xgi_video_info.pcibus = pdev->bus->number;
2068 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2069 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2070 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2071 xgi_video_info.subsysdevice = pdev->subsystem_device;
2073 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2074 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2075 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2076 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2077 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2078 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2079 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2080 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2082 if (pci_enable_device(pdev)) {
2087 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2089 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2090 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
2092 if (reg1 != 0xa1) { /*I/O error */
2093 printk("\nXGIfb: I/O error!!!");
2098 switch (xgi_video_info.chip_id) {
2099 case PCI_DEVICE_ID_XG_20:
2100 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2101 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
2102 if (CR48&GPIOG_READ)
2103 xgi_video_info.chip = XG21;
2105 xgi_video_info.chip = XG20;
2106 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2108 case PCI_DEVICE_ID_XG_40:
2109 xgi_video_info.chip = XG40;
2110 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2112 case PCI_DEVICE_ID_XG_41:
2113 xgi_video_info.chip = XG41;
2114 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2116 case PCI_DEVICE_ID_XG_42:
2117 xgi_video_info.chip = XG42;
2118 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2120 case PCI_DEVICE_ID_XG_27:
2121 xgi_video_info.chip = XG27;
2122 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2129 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2130 XGIhw_ext.jChipType = xgi_video_info.chip;
2132 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2133 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2134 if (XGIhw_ext.pjVirtualRomBase)
2135 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2136 XGIhw_ext.pjVirtualRomBase);
2138 printk(KERN_INFO "XGIfb: Video ROM not found\n");
2140 XGIhw_ext.pjVirtualRomBase = NULL;
2141 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2143 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2145 if (XGIfb_get_dram_size()) {
2146 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2151 if ((xgifb_mode_idx < 0) ||
2152 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2153 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2155 IND_XGI_PCI_ADDRESS_SET,
2156 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2157 /* Enable 2D accelerator engine */
2158 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2161 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2163 if (!request_mem_region(xgi_video_info.video_base,
2164 xgi_video_info.video_size,
2166 printk("unable request memory size %x",
2167 xgi_video_info.video_size);
2168 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2169 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2174 if (!request_mem_region(xgi_video_info.mmio_base,
2175 xgi_video_info.mmio_size,
2177 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2182 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2183 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2184 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2185 xgi_video_info.mmio_size);
2187 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2188 xgi_video_info.video_base,
2189 xgi_video_info.video_vbase,
2190 xgi_video_info.video_size / 1024);
2192 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2193 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2194 xgi_video_info.mmio_size / 1024);
2195 printk("XGIfb: XGIInitNew() ...");
2196 if (XGIInitNew(&XGIhw_ext))
2201 xgi_video_info.mtrr = (unsigned int) 0;
2203 if ((xgifb_mode_idx < 0) ||
2204 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2205 xgi_video_info.hasVB = HASVB_NONE;
2206 if ((xgi_video_info.chip == XG20) ||
2207 (xgi_video_info.chip == XG27)) {
2208 xgi_video_info.hasVB = HASVB_NONE;
2209 } else if (xgi_video_info.chip == XG21) {
2210 CR38 = xgifb_reg_get(XGICR, 0x38);
2211 if ((CR38&0xE0) == 0xC0) {
2212 xgi_video_info.disp_state = DISPTYPE_LCD;
2213 if (!XGIfb_GetXG21LVDSData()) {
2215 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2216 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2217 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2218 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2222 } else if ((CR38&0xE0) == 0x60) {
2223 xgi_video_info.hasVB = HASVB_CHRONTEL;
2225 xgi_video_info.hasVB = HASVB_NONE;
2228 XGIfb_get_VB_type();
2231 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2233 XGIhw_ext.ulExternalChip = 0;
2235 switch (xgi_video_info.hasVB) {
2237 reg = xgifb_reg_get(XGIPART4, 0x01);
2239 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2240 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2241 } else if (reg >= 0xD0) {
2242 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2243 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2245 /* else if (reg >= 0xB0) {
2246 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2247 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2248 printk("XGIfb: XGI301B bridge detected\n");
2251 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2252 printk("XGIfb: XGI301 bridge detected\n");
2256 reg = xgifb_reg_get(XGIPART4, 0x01);
2258 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2259 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2260 } else if (reg >= 0xD0) {
2261 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2262 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2263 } else if (reg >= 0xB0) {
2264 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2266 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2269 XGIhw_ext.ujVBChipID = VB_CHIP_302;
2270 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2274 XGIhw_ext.ulExternalChip = 0x1;
2275 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2277 case HASVB_TRUMPION:
2278 XGIhw_ext.ulExternalChip = 0x2;
2279 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2281 case HASVB_CHRONTEL:
2282 XGIhw_ext.ulExternalChip = 0x4;
2283 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2285 case HASVB_LVDS_CHRONTEL:
2286 XGIhw_ext.ulExternalChip = 0x5;
2287 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2290 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2294 if (xgi_video_info.hasVB != HASVB_NONE)
2297 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2299 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2301 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2304 xgi_video_info.disp_state = DISPMODE_SINGLE |
2308 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2310 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2312 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2316 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2320 XGIfb_detectedpdc = 0;
2322 XGIfb_detectedlcda = 0xff;
2324 /* TW: Try to find about LCDA */
2326 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2327 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2328 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2330 tmp = xgifb_reg_get(XGICR, 0x34);
2332 /* Currently on LCDA?
2333 *(Some BIOSes leave CR38) */
2334 tmp = xgifb_reg_get(XGICR, 0x38);
2335 if ((tmp & 0x03) == 0x03) {
2336 /* XGI_Pr.XGI_UseLCDA = 1; */
2338 /* Currently on LCDA?
2339 *(Some newer BIOSes set D0 in CR35) */
2340 tmp = xgifb_reg_get(XGICR, 0x35);
2342 /* XGI_Pr.XGI_UseLCDA = 1; */
2344 tmp = xgifb_reg_get(XGICR,
2347 tmp = xgifb_reg_get(
2350 /* XGI_Pr.XGI_UseLCDA = 1; */
2359 if (xgifb_mode_idx >= 0)
2360 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2362 if (xgifb_mode_idx < 0) {
2363 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2365 xgifb_mode_idx = DEFAULT_LCDMODE;
2366 if (xgi_video_info.chip == XG21)
2368 XGIfb_GetXG21DefaultLVDSModeIdx();
2371 xgifb_mode_idx = DEFAULT_TVMODE;
2374 xgifb_mode_idx = DEFAULT_MODE;
2379 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2381 /* yilin set default refresh rate */
2382 if (xgi_video_info.refresh_rate == 0)
2383 xgi_video_info.refresh_rate = 60;
2384 if (XGIfb_search_refresh_rate(
2385 xgi_video_info.refresh_rate) == 0) {
2386 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2387 xgi_video_info.refresh_rate = 60;
2390 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2391 xgi_video_info.video_vwidth =
2392 xgi_video_info.video_width =
2393 XGIbios_mode[xgifb_mode_idx].xres;
2394 xgi_video_info.video_vheight =
2395 xgi_video_info.video_height =
2396 XGIbios_mode[xgifb_mode_idx].yres;
2397 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2398 xgi_video_info.video_linelength =
2399 xgi_video_info.video_width *
2400 (xgi_video_info.video_bpp >> 3);
2401 switch (xgi_video_info.video_bpp) {
2403 xgi_video_info.DstColor = 0x0000;
2404 xgi_video_info.XGI310_AccelDepth = 0x00000000;
2405 xgi_video_info.video_cmap_len = 256;
2408 xgi_video_info.DstColor = 0x8000;
2409 xgi_video_info.XGI310_AccelDepth = 0x00010000;
2410 xgi_video_info.video_cmap_len = 16;
2413 xgi_video_info.DstColor = 0xC000;
2414 xgi_video_info.XGI310_AccelDepth = 0x00020000;
2415 xgi_video_info.video_cmap_len = 16;
2418 xgi_video_info.video_cmap_len = 16;
2419 printk(KERN_INFO "XGIfb: Unsupported depth %d",
2420 xgi_video_info.video_bpp);
2424 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2425 xgi_video_info.video_width,
2426 xgi_video_info.video_height,
2427 xgi_video_info.video_bpp,
2428 xgi_video_info.refresh_rate);
2431 default_var.xres_virtual =
2432 xgi_video_info.video_width;
2434 default_var.yres_virtual =
2435 xgi_video_info.video_height;
2436 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2438 XGIfb_bpp_to_var(&default_var);
2440 default_var.pixclock = (u32) (1000000000 /
2441 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2442 XGIfb_mode_no, XGIfb_rate_idx));
2444 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2445 XGIfb_mode_no, XGIfb_rate_idx,
2446 &default_var.left_margin, &default_var.right_margin,
2447 &default_var.upper_margin, &default_var.lower_margin,
2448 &default_var.hsync_len, &default_var.vsync_len,
2449 &default_var.sync, &default_var.vmode)) {
2451 if ((default_var.vmode & FB_VMODE_MASK) ==
2452 FB_VMODE_INTERLACED) {
2453 default_var.yres <<= 1;
2454 default_var.yres_virtual <<= 1;
2455 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2457 default_var.pixclock >>= 1;
2458 default_var.yres >>= 1;
2459 default_var.yres_virtual >>= 1;
2464 fb_info->flags = FBINFO_FLAG_DEFAULT;
2465 fb_info->var = default_var;
2466 fb_info->fix = XGIfb_fix;
2467 fb_info->par = &xgi_video_info;
2468 fb_info->screen_base = xgi_video_info.video_vbase;
2469 fb_info->fbops = &XGIfb_ops;
2470 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2471 fb_info->pseudo_palette = pseudo_palette;
2473 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2476 xgi_video_info.mtrr = mtrr_add(
2477 (unsigned int) xgi_video_info.video_base,
2478 (unsigned int) xgi_video_info.video_size,
2479 MTRR_TYPE_WRCOMB, 1);
2480 if (xgi_video_info.mtrr)
2481 printk(KERN_INFO "XGIfb: Added MTRRs\n");
2484 if (register_framebuffer(fb_info) < 0) {
2489 XGIfb_registered = 1;
2491 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2492 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2501 iounmap(xgi_video_info.mmio_vbase);
2502 iounmap(xgi_video_info.video_vbase);
2503 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2505 release_mem_region(xgi_video_info.video_base,
2506 xgi_video_info.video_size);
2508 vfree(XGIhw_ext.pjVirtualRomBase);
2509 framebuffer_release(fb_info);
2513 /*****************************************************/
2514 /* PCI DEVICE HANDLING */
2515 /*****************************************************/
2517 static void __devexit xgifb_remove(struct pci_dev *pdev)
2519 unregister_framebuffer(fb_info);
2520 iounmap(xgi_video_info.mmio_vbase);
2521 iounmap(xgi_video_info.video_vbase);
2522 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2523 release_mem_region(xgi_video_info.video_base,
2524 xgi_video_info.video_size);
2525 vfree(XGIhw_ext.pjVirtualRomBase);
2526 framebuffer_release(fb_info);
2527 pci_set_drvdata(pdev, NULL);
2530 static struct pci_driver xgifb_driver = {
2532 .id_table = xgifb_pci_table,
2533 .probe = xgifb_probe,
2534 .remove = __devexit_p(xgifb_remove)
2537 XGIINITSTATIC int __init xgifb_init(void)
2539 char *option = NULL;
2541 if (fb_get_options("xgifb", &option))
2543 XGIfb_setup(option);
2545 return pci_register_driver(&xgifb_driver);
2549 module_init(xgifb_init);
2552 /*****************************************************/
2554 /*****************************************************/
2558 static char *mode = NULL;
2559 static int vesa = 0;
2560 static unsigned int rate = 0;
2561 static unsigned int mem = 0;
2562 static char *forcecrt2type = NULL;
2563 static int forcecrt1 = -1;
2564 static int pdc = -1;
2565 static int pdc1 = -1;
2566 static int noypan = -1;
2567 static int userom = -1;
2568 static int useoem = -1;
2569 static char *tvstandard = NULL;
2570 static int nocrt2rate = 0;
2571 static int scalelcd = -1;
2572 static char *specialtiming = NULL;
2573 static int lvdshl = -1;
2574 static int tvxposoffset = 0, tvyposoffset = 0;
2575 #if !defined(__i386__) && !defined(__x86_64__)
2576 static int resetcard = 0;
2577 static int videoram = 0;
2580 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2581 MODULE_LICENSE("GPL");
2582 MODULE_AUTHOR("XGITECH , Others");
2584 module_param(mem, int, 0);
2585 module_param(noypan, int, 0);
2586 module_param(userom, int, 0);
2587 module_param(useoem, int, 0);
2588 module_param(mode, charp, 0);
2589 module_param(vesa, int, 0);
2590 module_param(rate, int, 0);
2591 module_param(forcecrt1, int, 0);
2592 module_param(forcecrt2type, charp, 0);
2593 module_param(scalelcd, int, 0);
2594 module_param(pdc, int, 0);
2595 module_param(pdc1, int, 0);
2596 module_param(specialtiming, charp, 0);
2597 module_param(lvdshl, int, 0);
2598 module_param(tvstandard, charp, 0);
2599 module_param(tvxposoffset, int, 0);
2600 module_param(tvyposoffset, int, 0);
2601 module_param(filter, int, 0);
2602 module_param(nocrt2rate, int, 0);
2603 #if !defined(__i386__) && !defined(__x86_64__)
2604 module_param(resetcard, int, 0);
2605 module_param(videoram, int, 0);
2608 MODULE_PARM_DESC(noypan,
2609 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2610 "will be performed by redrawing the screen. (default: 0)\n");
2612 MODULE_PARM_DESC(mode,
2613 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2614 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2615 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2616 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2618 MODULE_PARM_DESC(vesa,
2619 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2620 "0x117 (default: 0x0103)\n");
2622 MODULE_PARM_DESC(rate,
2623 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2624 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2625 "will be ignored (default: 60)\n");
2627 MODULE_PARM_DESC(forcecrt1,
2628 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2629 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2630 "0=CRT1 OFF) (default: [autodetected])\n");
2632 MODULE_PARM_DESC(forcecrt2type,
2633 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2634 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2635 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2636 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2637 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2638 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2639 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2640 "depends on the very hardware in use. (default: [autodetected])\n");
2642 MODULE_PARM_DESC(scalelcd,
2643 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2644 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2645 "show black bars around the image, TMDS panels will probably do the scaling\n"
2646 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2648 MODULE_PARM_DESC(pdc,
2649 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2650 "should detect this correctly in most cases; however, sometimes this is not\n"
2651 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2652 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2653 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2654 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2656 MODULE_PARM_DESC(pdc1,
2657 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2658 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2659 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2660 "implemented yet.\n");
2662 MODULE_PARM_DESC(specialtiming,
2663 "\nPlease refer to documentation for more information on this option.\n");
2665 MODULE_PARM_DESC(lvdshl,
2666 "\nPlease refer to documentation for more information on this option.\n");
2668 MODULE_PARM_DESC(tvstandard,
2669 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2670 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2672 MODULE_PARM_DESC(tvxposoffset,
2673 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2676 MODULE_PARM_DESC(tvyposoffset,
2677 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2680 MODULE_PARM_DESC(filter,
2681 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2682 "(Possible values 0-7, default: [no filter])\n");
2684 MODULE_PARM_DESC(nocrt2rate,
2685 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2686 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2688 static int __init xgifb_init_module(void)
2690 printk("\nXGIfb_init_module");
2692 XGIfb_search_mode(mode);
2693 else if (vesa != -1)
2694 XGIfb_search_vesamode(vesa);
2696 return xgifb_init();
2699 static void __exit xgifb_remove_module(void)
2701 pci_unregister_driver(&xgifb_driver);
2702 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2705 module_init(xgifb_init_module);
2706 module_exit(xgifb_remove_module);
2708 #endif /* /MODULE */