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/module.h>
9 #include <linux/moduleparam.h>
10 #include <linux/kernel.h>
11 #include <linux/spinlock.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
15 #include <linux/tty.h>
16 #include <linux/slab.h>
17 #include <linux/delay.h>
19 #include <linux/console.h>
20 #include <linux/selection.h>
21 #include <linux/ioport.h>
22 #include <linux/init.h>
23 #include <linux/pci.h>
24 #include <linux/vmalloc.h>
25 #include <linux/vt_kern.h>
26 #include <linux/capability.h>
28 #include <linux/types.h>
29 #include <linux/proc_fs.h>
41 #include "vb_setmode.h"
43 #define Index_CR_GPIO_Reg1 0x48
44 #define Index_CR_GPIO_Reg3 0x4a
46 #define GPIOG_EN (1<<6)
47 #define GPIOG_READ (1<<1)
49 #define XGIFB_ROM_SIZE 65536
51 /* -------------------- Macro definitions ---------------------------- */
56 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
58 #define DPRINTK(fmt, args...)
62 static void dumpVGAReg(void)
66 xgifb_reg_set(XGISR, 0x05, 0x86);
68 xgifb_reg_set(XGISR, 0x08, 0x4f);
69 xgifb_reg_set(XGISR, 0x0f, 0x20);
70 xgifb_reg_set(XGISR, 0x11, 0x4f);
71 xgifb_reg_set(XGISR, 0x13, 0x45);
72 xgifb_reg_set(XGISR, 0x14, 0x51);
73 xgifb_reg_set(XGISR, 0x1e, 0x41);
74 xgifb_reg_set(XGISR, 0x1f, 0x0);
75 xgifb_reg_set(XGISR, 0x20, 0xa1);
76 xgifb_reg_set(XGISR, 0x22, 0xfb);
77 xgifb_reg_set(XGISR, 0x26, 0x22);
78 xgifb_reg_set(XGISR, 0x3e, 0x07);
81 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
82 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
83 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
84 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
86 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
88 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
89 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
91 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
92 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
94 xgifb_reg_set(XGICR, 0x99, 0x1);
95 xgifb_reg_set(XGICR, 0x41, 0x40);
98 for (i = 0; i < 0x4f; i++) {
99 reg = xgifb_reg_get(XGISR, i);
100 printk("\no 3c4 %x", i);
101 printk("\ni 3c5 => %x", reg);
104 for (i = 0; i < 0xF0; i++) {
105 reg = xgifb_reg_get(XGICR, i);
106 printk("\no 3d4 %x", i);
107 printk("\ni 3d5 => %x", reg);
110 xgifb_reg_set(XGIPART1,0x2F,1);
111 for (i=1; i < 0x50; i++) {
112 reg = xgifb_reg_get(XGIPART1, i);
113 printk("\no d004 %x", i);
114 printk("\ni d005 => %x", reg);
117 for (i=0; i < 0x50; i++) {
118 reg = xgifb_reg_get(XGIPART2, i);
119 printk("\no d010 %x", i);
120 printk("\ni d011 => %x", reg);
122 for (i=0; i < 0x50; i++) {
123 reg = xgifb_reg_get(XGIPART3, i);
124 printk("\no d012 %x",i);
125 printk("\ni d013 => %x",reg);
127 for (i=0; i < 0x50; i++) {
128 reg = xgifb_reg_get(XGIPART4, i);
129 printk("\no d014 %x",i);
130 printk("\ni d015 => %x",reg);
135 static inline void dumpVGAReg(void)
140 /* data for XGI components */
141 struct video_info xgi_video_info;
146 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
149 /* --------------- Hardware Access Routines -------------------------- */
151 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
152 struct xgi_hw_device_info *HwDeviceExtension,
153 unsigned char modeno, unsigned char rateindex)
155 unsigned short ModeNo = modeno;
156 unsigned short ModeIdIndex = 0, ClockIndex = 0;
157 unsigned short RefreshRateTableIndex = 0;
159 /* unsigned long temp = 0; */
161 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
162 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
164 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
165 ModeIdIndex, XGI_Pr);
168 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
170 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
174 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
175 RefreshRateTableIndex += (rateindex - 1);
178 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
180 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
185 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
186 struct xgi_hw_device_info *HwDeviceExtension,
187 unsigned char modeno, unsigned char rateindex,
188 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
189 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
192 unsigned short ModeNo = modeno;
193 unsigned short ModeIdIndex = 0, index = 0;
194 unsigned short RefreshRateTableIndex = 0;
196 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
197 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
198 unsigned char sr_data, cr_data, cr_data2;
199 unsigned long cr_data3;
200 int A, B, C, D, E, F, temp, j;
201 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
202 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
203 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
204 ModeIdIndex, XGI_Pr);
206 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
210 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
211 RefreshRateTableIndex += (rateindex - 1);
213 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
215 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
217 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
219 /* Horizontal total */
220 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
224 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
226 Horizontal display enable end
227 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
229 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
232 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
234 /* Horizontal retrace (=sync) start */
235 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
238 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
240 /* Horizontal blank start */
241 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
243 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
245 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
247 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
249 /* Horizontal blank end */
250 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
251 | ((unsigned short) (sr_data & 0x03) << 6);
253 /* Horizontal retrace (=sync) end */
254 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
256 temp = HBE - ((E - 1) & 255);
257 B = (temp > 0) ? temp : (temp + 256);
259 temp = HRE - ((E + F + 3) & 63);
260 C = (temp > 0) ? temp : (temp + 64);
264 *left_margin = D * 8;
265 *right_margin = F * 8;
268 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
270 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
272 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
275 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
276 | ((unsigned short) (cr_data2 & 0x20) << 4)
277 | ((unsigned short) (sr_data & 0x01) << 10);
280 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
282 /* Vertical display enable end */
284 VDE = (cr_data & 0xff) |
285 ((unsigned short) (cr_data2 & 0x02) << 7) |
286 ((unsigned short) (cr_data2 & 0x40) << 3) |
287 ((unsigned short) (sr_data & 0x02) << 9);
289 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
292 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
294 /* Vertical retrace (=sync) start */
295 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
296 | ((unsigned short) (cr_data2 & 0x80) << 2)
297 | ((unsigned short) (sr_data & 0x08) << 7);
300 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
302 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
304 /* Vertical blank start */
305 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
306 | ((unsigned short) (cr_data3 & 0x20) << 4)
307 | ((unsigned short) (sr_data & 0x04) << 8);
309 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
311 /* Vertical blank end */
312 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
313 temp = VBE - ((E - 1) & 511);
314 B = (temp > 0) ? temp : (temp + 512);
316 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
318 /* Vertical retrace (=sync) end */
319 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
320 temp = VRE - ((E + F - 1) & 31);
321 C = (temp > 0) ? temp : (temp + 32);
329 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
330 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
332 *sync |= FB_SYNC_VERT_HIGH_ACT;
334 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
335 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
337 *sync |= FB_SYNC_HOR_HIGH_ACT;
339 *vmode = FB_VMODE_NONINTERLACED;
340 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
341 *vmode = FB_VMODE_INTERLACED;
344 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
345 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
346 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
347 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
349 *vmode = FB_VMODE_DOUBLE;
360 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
362 XGI_Pr->RelIO = BaseAddr;
363 XGI_Pr->P3c4 = BaseAddr + 0x14;
364 XGI_Pr->P3d4 = BaseAddr + 0x24;
365 XGI_Pr->P3c0 = BaseAddr + 0x10;
366 XGI_Pr->P3ce = BaseAddr + 0x1e;
367 XGI_Pr->P3c2 = BaseAddr + 0x12;
368 XGI_Pr->P3ca = BaseAddr + 0x1a;
369 XGI_Pr->P3c6 = BaseAddr + 0x16;
370 XGI_Pr->P3c7 = BaseAddr + 0x17;
371 XGI_Pr->P3c8 = BaseAddr + 0x18;
372 XGI_Pr->P3c9 = BaseAddr + 0x19;
373 XGI_Pr->P3da = BaseAddr + 0x2A;
374 /* Digital video interface registers (LCD) */
375 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
376 /* 301 TV Encoder registers */
377 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
378 /* 301 Macrovision registers */
379 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
380 /* 301 VGA2 (and LCD) registers */
381 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
382 /* 301 palette address port registers */
383 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
387 /* ------------ Interface for init & mode switching code ------------- */
389 static unsigned char XGIfb_query_VGA_config_space(
390 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
391 unsigned long set, unsigned long *value)
393 static struct pci_dev *pdev;
394 static unsigned char init, valid_pdev;
397 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
399 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
403 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
412 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
413 xgi_video_info.chip_id);
418 pci_read_config_dword(pdev, offset, (u32 *) value);
420 pci_write_config_dword(pdev, offset, (u32)(*value));
425 /* ------------------ Internal helper routines ----------------- */
427 static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
431 int XGIfb_mode_idx = 0;
434 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
435 && (XGIbios_mode[XGIfb_mode_idx].xres
436 <= XGI21_LCDCapList[0].LVDSHDE)) {
437 if ((XGIbios_mode[XGIfb_mode_idx].xres
438 == XGI21_LCDCapList[0].LVDSHDE)
439 && (XGIbios_mode[XGIfb_mode_idx].yres
440 == XGI21_LCDCapList[0].LVDSVDE)
441 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
442 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
451 return XGIfb_mode_idx;
454 static void XGIfb_search_mode(const char *name)
459 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
460 xgifb_mode_idx = DEFAULT_MODE;
461 if ((xgi_video_info.chip == XG21)
462 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
464 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
469 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
470 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
471 xgifb_mode_idx = DEFAULT_MODE;
472 if ((xgi_video_info.chip == XG21)
473 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
475 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
480 while (XGIbios_mode[i].mode_no != 0) {
481 l = min(strlen(name), strlen(XGIbios_mode[i].name));
482 if (!strncmp(name, XGIbios_mode[i].name, l)) {
490 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
493 static void XGIfb_search_vesamode(unsigned int vesamode)
499 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
500 xgifb_mode_idx = DEFAULT_MODE;
501 if ((xgi_video_info.chip == XG21)
502 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
504 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
509 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
511 while (XGIbios_mode[i].mode_no != 0) {
512 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
513 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
521 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
524 static int XGIfb_GetXG21LVDSData(void)
527 unsigned char *pData;
530 tmp = xgifb_reg_get(XGISR, 0x1e);
531 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
533 pData = xgi_video_info.mmio_vbase + 0x20000;
534 if ((pData[0x0] == 0x55) &&
535 (pData[0x1] == 0xAA) &&
536 (pData[0x65] & 0x1)) {
537 i = pData[0x316] | (pData[0x317] << 8);
544 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
545 | (pData[i + 1] << 8);
546 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
548 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
550 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
552 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
554 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
556 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
558 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
559 | (pData[i + 15] << 8);
560 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
561 | (pData[i + 17] << 8);
562 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
563 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
564 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
565 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
566 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
567 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
568 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
572 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
573 / sizeof(struct XGI21_LVDSCapStruct))));
579 static int XGIfb_validate_mode(int myindex)
583 if (xgi_video_info.chip == XG21) {
584 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
586 xres = XGI21_LCDCapList[0].LVDSHDE;
587 yres = XGI21_LCDCapList[0].LVDSVDE;
588 if (XGIbios_mode[myindex].xres > xres)
590 if (XGIbios_mode[myindex].yres > yres)
592 if ((XGIbios_mode[myindex].xres < xres) &&
593 (XGIbios_mode[myindex].yres < yres)) {
594 if (XGIbios_mode[myindex].bpp > 8)
603 /* FIXME: for now, all is valid on XG27 */
604 if (xgi_video_info.chip == XG27)
607 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
610 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
612 switch (XGIhw_ext.ulCRT2LCDType) {
653 /* case LCD_320x480: */ /* TW: FSTN */
664 if (XGIbios_mode[myindex].xres > xres)
666 if (XGIbios_mode[myindex].yres > yres)
668 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
669 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
670 switch (XGIbios_mode[myindex].xres) {
672 if (XGIbios_mode[myindex].yres != 512)
674 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
678 if ((XGIbios_mode[myindex].yres != 400)
679 && (XGIbios_mode[myindex].yres
684 if (XGIbios_mode[myindex].yres != 600)
688 if ((XGIbios_mode[myindex].yres != 600) &&
689 (XGIbios_mode[myindex].yres != 768))
691 if ((XGIbios_mode[myindex].yres == 600) &&
692 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
696 if ((XGIbios_mode[myindex].yres) != 768)
698 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
702 if ((XGIbios_mode[myindex].yres != 768) &&
703 (XGIbios_mode[myindex].yres != 1024))
705 if ((XGIbios_mode[myindex].yres == 768) &&
706 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
710 if (XGIbios_mode[myindex].yres != 1050)
714 if (XGIbios_mode[myindex].yres != 1200)
721 switch (XGIbios_mode[myindex].xres) {
723 if (XGIbios_mode[myindex].yres != 512)
727 if ((XGIbios_mode[myindex].yres != 400) &&
728 (XGIbios_mode[myindex].yres != 480))
732 if (XGIbios_mode[myindex].yres != 600)
736 if (XGIbios_mode[myindex].yres != 768)
740 if ((XGIbios_mode[myindex].yres != 960) &&
741 (XGIbios_mode[myindex].yres != 1024))
743 if (XGIbios_mode[myindex].yres == 960) {
744 if (XGIhw_ext.ulCRT2LCDType ==
750 if (XGIbios_mode[myindex].yres != 1050)
754 if (XGIbios_mode[myindex].yres != 1200)
763 switch (XGIbios_mode[myindex].xres) {
769 if (xgi_video_info.TV_type == TVMODE_NTSC) {
770 if (XGIbios_mode[myindex].yres != 480)
772 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
773 if (XGIbios_mode[myindex].yres != 576)
776 /* TW: LVDS/CHRONTEL does not support 720 */
777 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
778 xgi_video_info.hasVB == HASVB_CHRONTEL) {
783 if (xgi_video_info.TV_type == TVMODE_NTSC) {
784 if (XGIbios_mode[myindex].bpp == 32)
793 if (XGIbios_mode[myindex].xres > 1280)
801 static void XGIfb_search_crt2type(const char *name)
808 while (XGI_crt2type[i].type_no != -1) {
809 if (!strcmp(name, XGI_crt2type[i].name)) {
810 XGIfb_crt2type = XGI_crt2type[i].type_no;
811 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
816 if (XGIfb_crt2type < 0)
817 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
820 static u8 XGIfb_search_refresh_rate(unsigned int rate)
825 xres = XGIbios_mode[xgifb_mode_idx].xres;
826 yres = XGIbios_mode[xgifb_mode_idx].yres;
829 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
830 if ((XGIfb_vrate[i].xres == xres) &&
831 (XGIfb_vrate[i].yres == yres)) {
832 if (XGIfb_vrate[i].refresh == rate) {
833 XGIfb_rate_idx = XGIfb_vrate[i].idx;
835 } else if (XGIfb_vrate[i].refresh > rate) {
836 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
837 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
838 rate, XGIfb_vrate[i].refresh);
839 XGIfb_rate_idx = XGIfb_vrate[i].idx;
840 xgi_video_info.refresh_rate =
841 XGIfb_vrate[i].refresh;
842 } else if (((rate - XGIfb_vrate[i - 1].refresh)
843 <= 2) && (XGIfb_vrate[i].idx
845 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
846 rate, XGIfb_vrate[i-1].refresh);
847 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
848 xgi_video_info.refresh_rate =
849 XGIfb_vrate[i - 1].refresh;
852 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
853 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
854 rate, XGIfb_vrate[i].refresh);
855 XGIfb_rate_idx = XGIfb_vrate[i].idx;
861 if (XGIfb_rate_idx > 0) {
862 return XGIfb_rate_idx;
864 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
870 static void XGIfb_search_tvstd(const char *name)
877 while (XGI_tvtype[i].type_no != -1) {
878 if (!strcmp(name, XGI_tvtype[i].name)) {
879 XGIfb_tvmode = XGI_tvtype[i].type_no;
886 /* ----------- FBDev related routines for all series ----------- */
888 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
890 switch (var->bits_per_pixel) {
892 var->red.offset = var->green.offset = var->blue.offset = 0;
893 var->red.length = var->green.length = var->blue.length = 6;
894 xgi_video_info.video_cmap_len = 256;
897 var->red.offset = 11;
899 var->green.offset = 5;
900 var->green.length = 6;
901 var->blue.offset = 0;
902 var->blue.length = 5;
903 var->transp.offset = 0;
904 var->transp.length = 0;
905 xgi_video_info.video_cmap_len = 16;
908 var->red.offset = 16;
910 var->green.offset = 8;
911 var->green.length = 8;
912 var->blue.offset = 0;
913 var->blue.length = 8;
914 var->transp.offset = 24;
915 var->transp.length = 8;
916 xgi_video_info.video_cmap_len = 16;
921 /* --------------------- SetMode routines ------------------------- */
923 static void XGIfb_pre_setmode(void)
925 u8 cr30 = 0, cr31 = 0;
927 cr31 = xgifb_reg_get(XGICR, 0x31);
930 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
932 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
933 cr31 |= XGI_DRIVER_MODE;
936 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
937 cr31 |= XGI_DRIVER_MODE;
940 if (xgi_video_info.TV_type == TVMODE_HIVISION)
941 cr30 = (XGI_VB_OUTPUT_HIVISION
942 | XGI_SIMULTANEOUS_VIEW_ENABLE);
943 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
944 cr30 = (XGI_VB_OUTPUT_SVIDEO
945 | XGI_SIMULTANEOUS_VIEW_ENABLE);
946 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
947 cr30 = (XGI_VB_OUTPUT_COMPOSITE
948 | XGI_SIMULTANEOUS_VIEW_ENABLE);
949 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
950 cr30 = (XGI_VB_OUTPUT_SCART
951 | XGI_SIMULTANEOUS_VIEW_ENABLE);
952 cr31 |= XGI_DRIVER_MODE;
954 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
959 default: /* disable CRT2 */
961 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
964 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
965 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
966 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
969 static void XGIfb_post_setmode(void)
972 unsigned char doit = 1;
974 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
975 xgifb_reg_set(XGICR, 0x13, 0x00);
976 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
979 if (xgi_video_info.video_bpp == 8) {
980 /* TW: We can't switch off CRT1 on LVDS/Chrontel
982 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
983 (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
986 /* TW: We can't switch off CRT1 on 301B-DH
987 * in 8bpp Modes if using LCD */
988 if (xgi_video_info.disp_state & DISPTYPE_LCD)
992 /* TW: We can't switch off CRT1 if bridge is in slave mode */
993 if (xgi_video_info.hasVB != HASVB_NONE) {
994 reg = xgifb_reg_get(XGIPART1, 0x00);
996 if ((reg & 0x50) == 0x10)
1003 reg = xgifb_reg_get(XGICR, 0x17);
1004 if ((XGIfb_crt1off) && (doit))
1008 xgifb_reg_set(XGICR, 0x17, reg);
1010 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1012 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1015 reg = xgifb_reg_get(XGIPART4, 0x01);
1017 if (reg < 0xB0) { /* Set filter for XGI301 */
1018 switch (xgi_video_info.video_width) {
1020 filter_tb = (xgi_video_info.TV_type ==
1021 TVMODE_NTSC) ? 4 : 12;
1024 filter_tb = (xgi_video_info.TV_type ==
1025 TVMODE_NTSC) ? 5 : 13;
1028 filter_tb = (xgi_video_info.TV_type ==
1029 TVMODE_NTSC) ? 6 : 14;
1032 filter_tb = (xgi_video_info.TV_type ==
1033 TVMODE_NTSC) ? 7 : 15;
1039 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1041 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1043 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1045 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1047 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1049 } else if (xgi_video_info.TV_plug
1050 == TVPLUG_COMPOSITE) {
1052 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1054 switch (xgi_video_info.video_width) {
1056 xgifb_reg_set(XGIPART2,
1059 xgifb_reg_set(XGIPART2,
1062 xgifb_reg_set(XGIPART2,
1065 xgifb_reg_set(XGIPART2,
1070 xgifb_reg_set(XGIPART2,
1073 xgifb_reg_set(XGIPART2,
1076 xgifb_reg_set(XGIPART2,
1079 xgifb_reg_set(XGIPART2,
1084 xgifb_reg_set(XGIPART2,
1087 xgifb_reg_set(XGIPART2,
1090 xgifb_reg_set(XGIPART2,
1093 xgifb_reg_set(XGIPART2,
1100 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1102 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1104 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1106 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1108 } else if (xgi_video_info.TV_plug
1109 == TVPLUG_COMPOSITE) {
1111 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1113 switch (xgi_video_info.video_width) {
1115 xgifb_reg_set(XGIPART2,
1118 xgifb_reg_set(XGIPART2,
1121 xgifb_reg_set(XGIPART2,
1124 xgifb_reg_set(XGIPART2,
1129 xgifb_reg_set(XGIPART2,
1132 xgifb_reg_set(XGIPART2,
1135 xgifb_reg_set(XGIPART2,
1138 xgifb_reg_set(XGIPART2,
1143 xgifb_reg_set(XGIPART2,
1146 xgifb_reg_set(XGIPART2,
1149 xgifb_reg_set(XGIPART2,
1152 xgifb_reg_set(XGIPART2,
1160 if ((filter >= 0) && (filter <= 7)) {
1161 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1163 XGI_TV_filter[filter_tb].
1165 XGI_TV_filter[filter_tb].
1167 XGI_TV_filter[filter_tb].
1169 XGI_TV_filter[filter_tb].
1175 (XGI_TV_filter[filter_tb].
1176 filter[filter][0]));
1180 (XGI_TV_filter[filter_tb].
1181 filter[filter][1]));
1185 (XGI_TV_filter[filter_tb].
1186 filter[filter][2]));
1190 (XGI_TV_filter[filter_tb].
1191 filter[filter][3]));
1197 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1198 struct fb_info *info)
1201 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1203 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1205 #if defined(__powerpc__)
1206 u8 sr_data, cr_data;
1208 unsigned int drate = 0, hrate = 0;
1211 /* unsigned char reg, reg1; */
1213 DEBUGPRN("Inside do_set_var");
1214 /* 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); */
1216 info->var.xres_virtual = var->xres_virtual;
1217 info->var.yres_virtual = var->yres_virtual;
1218 info->var.bits_per_pixel = var->bits_per_pixel;
1220 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1222 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1224 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1226 /* var->yres <<= 1; */
1229 if (!htotal || !vtotal) {
1230 DPRINTK("XGIfb: Invalid 'var' information\n");
1232 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1233 var->pixclock, htotal, vtotal);
1235 if (var->pixclock && htotal && vtotal) {
1236 drate = 1000000000 / var->pixclock;
1237 hrate = (drate * 1000) / htotal;
1238 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1241 xgi_video_info.refresh_rate = 60;
1244 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1247 var->bits_per_pixel,
1248 xgi_video_info.refresh_rate);
1250 old_mode = xgifb_mode_idx;
1253 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1254 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1255 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1256 && (XGIbios_mode[xgifb_mode_idx].yres
1258 && (XGIbios_mode[xgifb_mode_idx].bpp
1259 == var->bits_per_pixel)) {
1260 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1268 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1270 xgifb_mode_idx = -1;
1272 if (xgifb_mode_idx < 0) {
1273 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1274 var->xres, var->yres, var->bits_per_pixel);
1275 xgifb_mode_idx = old_mode;
1279 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1280 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1281 xgi_video_info.refresh_rate = 60;
1286 XGIfb_pre_setmode();
1287 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1288 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1292 info->fix.line_length = ((info->var.xres_virtual
1293 * info->var.bits_per_pixel) >> 6);
1295 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1297 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1298 xgifb_reg_set(XGISR,
1300 (info->fix.line_length & 0xff00) >> 8);
1302 XGIfb_post_setmode();
1304 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1305 XGIbios_mode[xgifb_mode_idx].xres,
1306 XGIbios_mode[xgifb_mode_idx].yres,
1307 XGIbios_mode[xgifb_mode_idx].bpp,
1308 xgi_video_info.refresh_rate);
1310 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1311 xgi_video_info.video_vwidth = info->var.xres_virtual;
1312 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1313 xgi_video_info.video_vheight = info->var.yres_virtual;
1314 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1315 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1316 xgi_video_info.video_linelength = info->var.xres_virtual
1317 * (xgi_video_info.video_bpp >> 3);
1318 switch (xgi_video_info.video_bpp) {
1320 xgi_video_info.DstColor = 0x0000;
1321 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1322 xgi_video_info.video_cmap_len = 256;
1323 #if defined(__powerpc__)
1324 cr_data = xgifb_reg_get(XGICR, 0x4D);
1325 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1329 xgi_video_info.DstColor = 0x8000;
1330 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1331 #if defined(__powerpc__)
1332 cr_data = xgifb_reg_get(XGICR, 0x4D);
1333 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1335 xgi_video_info.video_cmap_len = 16;
1338 xgi_video_info.DstColor = 0xC000;
1339 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1340 xgi_video_info.video_cmap_len = 16;
1341 #if defined(__powerpc__)
1342 cr_data = xgifb_reg_get(XGICR, 0x4D);
1343 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1347 xgi_video_info.video_cmap_len = 16;
1348 printk(KERN_ERR "XGIfb: Unsupported depth %d",
1349 xgi_video_info.video_bpp);
1353 XGIfb_bpp_to_var(var); /*update ARGB info*/
1354 DEBUGPRN("End of do_set_var");
1360 static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1364 /* printk("Inside pan_var"); */
1366 base = var->yoffset * info->var.xres_virtual + var->xoffset;
1368 /* calculate base bpp dep. */
1369 switch (info->var.bits_per_pixel) {
1381 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1383 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1384 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1385 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1386 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1387 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1389 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1390 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1391 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1392 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1393 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1394 xgifb_reg_and_or(XGIPART1,
1397 ((base >> 24) & 0x01) << 7);
1399 /* printk("End of pan_var"); */
1403 static int XGIfb_open(struct fb_info *info, int user)
1408 static int XGIfb_release(struct fb_info *info, int user)
1413 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1417 switch (var->bits_per_pixel) {
1431 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1432 unsigned blue, unsigned transp, struct fb_info *info)
1434 if (regno >= XGIfb_get_cmap_len(&info->var))
1437 switch (info->var.bits_per_pixel) {
1439 outb(regno, XGIDACA);
1440 outb((red >> 10), XGIDACD);
1441 outb((green >> 10), XGIDACD);
1442 outb((blue >> 10), XGIDACD);
1443 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1444 outb(regno, XGIDAC2A);
1445 outb((red >> 8), XGIDAC2D);
1446 outb((green >> 8), XGIDAC2D);
1447 outb((blue >> 8), XGIDAC2D);
1451 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1452 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1459 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1466 /* ----------- FBDev related routines for all series ---------- */
1468 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1469 struct fb_info *info)
1471 DEBUGPRN("inside get_fix");
1472 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1474 strcpy(fix->id, myid);
1476 fix->smem_start = xgi_video_info.video_base;
1478 fix->smem_len = xgi_video_info.video_size;
1480 fix->type = FB_TYPE_PACKED_PIXELS;
1482 if (xgi_video_info.video_bpp == 8)
1483 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1485 fix->visual = FB_VISUAL_DIRECTCOLOR;
1490 fix->line_length = xgi_video_info.video_linelength;
1491 fix->mmio_start = xgi_video_info.mmio_base;
1492 fix->mmio_len = xgi_video_info.mmio_size;
1493 fix->accel = FB_ACCEL_XGI_XABRE;
1495 DEBUGPRN("end of get_fix");
1499 static int XGIfb_set_par(struct fb_info *info)
1503 /* printk("XGIfb: inside set_par\n"); */
1504 err = XGIfb_do_set_var(&info->var, 1, info);
1507 XGIfb_get_fix(&info->fix, -1, info);
1508 /* printk("XGIfb: end of set_par\n"); */
1512 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1514 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1516 unsigned int vtotal = 0;
1517 unsigned int drate = 0, hrate = 0;
1519 int refresh_rate, search_idx;
1521 DEBUGPRN("Inside check_var");
1523 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1524 vtotal = var->upper_margin + var->yres + var->lower_margin
1527 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1528 vtotal = var->upper_margin + var->yres + var->lower_margin
1531 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1532 vtotal = var->upper_margin + (var->yres / 2)
1533 + var->lower_margin + var->vsync_len;
1535 vtotal = var->upper_margin + var->yres + var->lower_margin
1538 if (!(htotal) || !(vtotal))
1539 XGIFAIL("XGIfb: no valid timing data");
1541 if (var->pixclock && htotal && vtotal) {
1542 drate = 1000000000 / var->pixclock;
1543 hrate = (drate * 1000) / htotal;
1544 xgi_video_info.refresh_rate =
1545 (unsigned int) (hrate * 2 / vtotal);
1547 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1548 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1549 __func__, var->pixclock, htotal, vtotal,
1550 __func__, drate, hrate, xgi_video_info.refresh_rate);
1552 xgi_video_info.refresh_rate = 60;
1556 if ((var->pixclock) && (htotal)) {
1557 drate = 1E12 / var->pixclock;
1558 hrate = drate / htotal;
1559 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1564 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1565 if ((var->xres == 1024) && (var->yres == 600))
1569 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1570 (XGIbios_mode[search_idx].xres <= var->xres)) {
1571 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1572 (XGIbios_mode[search_idx].yres == var->yres) &&
1573 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1574 if (XGIfb_validate_mode(search_idx) > 0) {
1584 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1585 var->xres, var->yres, var->bits_per_pixel);
1587 while (XGIbios_mode[search_idx].mode_no != 0) {
1588 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1589 (var->yres <= XGIbios_mode[search_idx].yres) &&
1590 (var->bits_per_pixel ==
1591 XGIbios_mode[search_idx].bpp)) {
1592 if (XGIfb_validate_mode(search_idx) > 0) {
1600 var->xres = XGIbios_mode[search_idx].xres;
1601 var->yres = XGIbios_mode[search_idx].yres;
1602 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1603 var->xres, var->yres, var->bits_per_pixel);
1606 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1607 var->xres, var->yres, var->bits_per_pixel);
1612 /* TW: TODO: Check the refresh rate */
1614 /* Adapt RGB settings */
1615 XGIfb_bpp_to_var(var);
1617 /* Sanity check for offsets */
1618 if (var->xoffset < 0)
1620 if (var->yoffset < 0)
1624 if (var->xres != var->xres_virtual)
1625 var->xres_virtual = var->xres;
1626 if (var->yres != var->yres_virtual)
1627 var->yres_virtual = var->yres;
1629 /* TW: Now patch yres_virtual if we use panning */
1630 /* May I do this? */
1631 /* var->yres_virtual = xgi_video_info.heapstart /
1632 (var->xres * (var->bits_per_pixel >> 3)); */
1633 /* if (var->yres_virtual <= var->yres) { */
1634 /* TW: Paranoia check */
1635 /* var->yres_virtual = var->yres; */
1639 /* Truncate offsets to maximum if too high */
1640 if (var->xoffset > var->xres_virtual - var->xres)
1641 var->xoffset = var->xres_virtual - var->xres - 1;
1643 if (var->yoffset > var->yres_virtual - var->yres)
1644 var->yoffset = var->yres_virtual - var->yres - 1;
1646 /* Set everything else to 0 */
1647 var->red.msb_right =
1648 var->green.msb_right =
1649 var->blue.msb_right =
1650 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1652 DEBUGPRN("end of check_var");
1656 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1657 struct fb_info *info)
1661 /* printk("\nInside pan_display:\n"); */
1663 if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1665 if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1668 if (var->vmode & FB_VMODE_YWRAP) {
1669 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1673 if (var->xoffset + info->var.xres > info->var.xres_virtual
1674 || var->yoffset + info->var.yres
1675 > info->var.yres_virtual)
1678 err = XGIfb_pan_var(var, info);
1682 info->var.xoffset = var->xoffset;
1683 info->var.yoffset = var->yoffset;
1684 if (var->vmode & FB_VMODE_YWRAP)
1685 info->var.vmode |= FB_VMODE_YWRAP;
1687 info->var.vmode &= ~FB_VMODE_YWRAP;
1689 /* printk("End of pan_display\n"); */
1693 static int XGIfb_blank(int blank, struct fb_info *info)
1697 reg = xgifb_reg_get(XGICR, 0x17);
1704 xgifb_reg_set(XGICR, 0x17, reg);
1705 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1706 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1710 static struct fb_ops XGIfb_ops = {
1711 .owner = THIS_MODULE,
1712 .fb_open = XGIfb_open,
1713 .fb_release = XGIfb_release,
1714 .fb_check_var = XGIfb_check_var,
1715 .fb_set_par = XGIfb_set_par,
1716 .fb_setcolreg = XGIfb_setcolreg,
1717 .fb_pan_display = XGIfb_pan_display,
1718 .fb_blank = XGIfb_blank,
1719 .fb_fillrect = cfb_fillrect,
1720 .fb_copyarea = cfb_copyarea,
1721 .fb_imageblit = cfb_imageblit,
1722 /* .fb_mmap = XGIfb_mmap, */
1725 /* ---------------- Chip generation dependent routines ---------------- */
1727 /* for XGI 315/550/650/740/330 */
1729 static int XGIfb_get_dram_size(void)
1735 /* xorg driver sets 32MB * 1 channel */
1736 if (xgi_video_info.chip == XG27)
1737 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1739 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
1740 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1741 case XGI_DRAM_SIZE_1MB:
1742 xgi_video_info.video_size = 0x100000;
1744 case XGI_DRAM_SIZE_2MB:
1745 xgi_video_info.video_size = 0x200000;
1747 case XGI_DRAM_SIZE_4MB:
1748 xgi_video_info.video_size = 0x400000;
1750 case XGI_DRAM_SIZE_8MB:
1751 xgi_video_info.video_size = 0x800000;
1753 case XGI_DRAM_SIZE_16MB:
1754 xgi_video_info.video_size = 0x1000000;
1756 case XGI_DRAM_SIZE_32MB:
1757 xgi_video_info.video_size = 0x2000000;
1759 case XGI_DRAM_SIZE_64MB:
1760 xgi_video_info.video_size = 0x4000000;
1762 case XGI_DRAM_SIZE_128MB:
1763 xgi_video_info.video_size = 0x8000000;
1765 case XGI_DRAM_SIZE_256MB:
1766 xgi_video_info.video_size = 0x10000000;
1772 tmp = (reg & 0x0c) >> 2;
1773 switch (xgi_video_info.chip) {
1809 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1810 /* PLiad fixed for benchmarking and fb set */
1811 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1812 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1814 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1816 xgi_video_info.video_size, ChannelNum);
1821 static void XGIfb_detect_VB(void)
1825 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1827 switch (xgi_video_info.hasVB) {
1828 case HASVB_LVDS_CHRONTEL:
1829 case HASVB_CHRONTEL:
1833 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1837 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1839 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1848 if (XGIfb_crt2type != -1)
1849 /* TW: Override with option */
1850 xgi_video_info.disp_state = XGIfb_crt2type;
1851 else if (cr32 & XGI_VB_TV)
1852 xgi_video_info.disp_state = DISPTYPE_TV;
1853 else if (cr32 & XGI_VB_LCD)
1854 xgi_video_info.disp_state = DISPTYPE_LCD;
1855 else if (cr32 & XGI_VB_CRT2)
1856 xgi_video_info.disp_state = DISPTYPE_CRT2;
1858 xgi_video_info.disp_state = 0;
1860 if (XGIfb_tvplug != -1)
1861 /* PR/TW: Override with option */
1862 xgi_video_info.TV_plug = XGIfb_tvplug;
1863 else if (cr32 & XGI_VB_HIVISION) {
1864 xgi_video_info.TV_type = TVMODE_HIVISION;
1865 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1866 } else if (cr32 & XGI_VB_SVIDEO)
1867 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1868 else if (cr32 & XGI_VB_COMPOSITE)
1869 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1870 else if (cr32 & XGI_VB_SCART)
1871 xgi_video_info.TV_plug = TVPLUG_SCART;
1873 if (xgi_video_info.TV_type == 0) {
1874 temp = xgifb_reg_get(XGICR, 0x38);
1876 xgi_video_info.TV_type = TVMODE_PAL;
1878 xgi_video_info.TV_type = TVMODE_NTSC;
1881 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1882 if (XGIfb_forcecrt1 != -1) {
1883 if (XGIfb_forcecrt1)
1890 static int XGIfb_has_VB(void)
1894 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1895 switch (vb_chipid) {
1897 xgi_video_info.hasVB = HASVB_301;
1900 xgi_video_info.hasVB = HASVB_302;
1903 xgi_video_info.hasVB = HASVB_NONE;
1909 static void XGIfb_get_VB_type(void)
1913 if (!XGIfb_has_VB()) {
1914 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1915 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1916 case XGI310_EXTERNAL_CHIP_LVDS:
1917 xgi_video_info.hasVB = HASVB_LVDS;
1919 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1920 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1928 static int __init XGIfb_setup(char *options)
1932 xgi_video_info.refresh_rate = 0;
1934 printk(KERN_INFO "XGIfb: Options %s\n", options);
1936 if (!options || !*options)
1939 while ((this_opt = strsep(&options, ",")) != NULL) {
1944 if (!strncmp(this_opt, "mode:", 5)) {
1945 XGIfb_search_mode(this_opt + 5);
1946 } else if (!strncmp(this_opt, "vesa:", 5)) {
1947 XGIfb_search_vesamode(simple_strtoul(
1948 this_opt + 5, NULL, 0));
1949 } else if (!strncmp(this_opt, "mode:", 5)) {
1950 XGIfb_search_mode(this_opt + 5);
1951 } else if (!strncmp(this_opt, "vesa:", 5)) {
1952 XGIfb_search_vesamode(simple_strtoul(
1953 this_opt + 5, NULL, 0));
1954 } else if (!strncmp(this_opt, "vrate:", 6)) {
1955 xgi_video_info.refresh_rate = simple_strtoul(
1956 this_opt + 6, NULL, 0);
1957 } else if (!strncmp(this_opt, "rate:", 5)) {
1958 xgi_video_info.refresh_rate = simple_strtoul(
1959 this_opt + 5, NULL, 0);
1960 } else if (!strncmp(this_opt, "off", 3)) {
1962 } else if (!strncmp(this_opt, "crt1off", 7)) {
1964 } else if (!strncmp(this_opt, "filter:", 7)) {
1965 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1966 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1967 XGIfb_search_crt2type(this_opt + 14);
1968 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1969 XGIfb_forcecrt1 = (int)simple_strtoul(
1970 this_opt + 10, NULL, 0);
1971 } else if (!strncmp(this_opt, "tvmode:", 7)) {
1972 XGIfb_search_tvstd(this_opt + 7);
1973 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1974 XGIfb_search_tvstd(this_opt + 7);
1975 } else if (!strncmp(this_opt, "dstn", 4)) {
1977 /* TW: DSTN overrules forcecrt2type */
1978 XGIfb_crt2type = DISPTYPE_LCD;
1979 } else if (!strncmp(this_opt, "pdc:", 4)) {
1980 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
1981 if (XGIfb_pdc & ~0x3c) {
1982 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
1985 } else if (!strncmp(this_opt, "noypan", 6)) {
1987 } else if (!strncmp(this_opt, "userom:", 7)) {
1988 XGIfb_userom = (int)simple_strtoul(
1989 this_opt + 7, NULL, 0);
1990 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
1991 /* XGIfb_useoem = (int)simple_strtoul(
1992 this_opt + 7, NULL, 0); */
1994 XGIfb_search_mode(this_opt);
1995 /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
1999 /* TW: Panning only with acceleration */
2003 printk("\nxgifb: outa xgifb_setup 3450");
2007 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2009 void __iomem *rom_address;
2010 unsigned char *rom_copy;
2013 rom_address = pci_map_rom(dev, &rom_size);
2014 if (rom_address == NULL)
2017 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2018 if (rom_copy == NULL)
2021 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2022 memcpy_fromio(rom_copy, rom_address, rom_size);
2025 pci_unmap_rom(dev, rom_address);
2029 static int __devinit xgifb_probe(struct pci_dev *pdev,
2030 const struct pci_device_id *ent)
2039 XGIfb_registered = 0;
2041 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2042 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2046 xgi_video_info.chip_id = pdev->device;
2047 pci_read_config_byte(pdev,
2049 &xgi_video_info.revision_id);
2050 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2052 xgi_video_info.pcibus = pdev->bus->number;
2053 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2054 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2055 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2056 xgi_video_info.subsysdevice = pdev->subsystem_device;
2058 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2059 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2060 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2061 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2062 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2063 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2064 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2065 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2067 if (pci_enable_device(pdev)) {
2072 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2074 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2075 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
2077 if (reg1 != 0xa1) { /*I/O error */
2078 printk("\nXGIfb: I/O error!!!");
2083 switch (xgi_video_info.chip_id) {
2084 case PCI_DEVICE_ID_XG_20:
2085 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2086 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
2087 if (CR48&GPIOG_READ)
2088 xgi_video_info.chip = XG21;
2090 xgi_video_info.chip = XG20;
2091 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2093 case PCI_DEVICE_ID_XG_40:
2094 xgi_video_info.chip = XG40;
2095 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2097 case PCI_DEVICE_ID_XG_41:
2098 xgi_video_info.chip = XG41;
2099 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2101 case PCI_DEVICE_ID_XG_42:
2102 xgi_video_info.chip = XG42;
2103 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2105 case PCI_DEVICE_ID_XG_27:
2106 xgi_video_info.chip = XG27;
2107 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2114 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2115 XGIhw_ext.jChipType = xgi_video_info.chip;
2117 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2118 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2119 if (XGIhw_ext.pjVirtualRomBase)
2120 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2121 XGIhw_ext.pjVirtualRomBase);
2123 printk(KERN_INFO "XGIfb: Video ROM not found\n");
2125 XGIhw_ext.pjVirtualRomBase = NULL;
2126 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2128 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2130 if (XGIfb_get_dram_size()) {
2131 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2136 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2138 IND_XGI_PCI_ADDRESS_SET,
2139 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2140 /* Enable 2D accelerator engine */
2141 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2143 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2145 if (!request_mem_region(xgi_video_info.video_base,
2146 xgi_video_info.video_size,
2148 printk("unable request memory size %x",
2149 xgi_video_info.video_size);
2150 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2151 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2156 if (!request_mem_region(xgi_video_info.mmio_base,
2157 xgi_video_info.mmio_size,
2159 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2164 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2165 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2166 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2167 xgi_video_info.mmio_size);
2169 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2170 xgi_video_info.video_base,
2171 xgi_video_info.video_vbase,
2172 xgi_video_info.video_size / 1024);
2174 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2175 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2176 xgi_video_info.mmio_size / 1024);
2177 printk("XGIfb: XGIInitNew() ...");
2178 if (XGIInitNew(&XGIhw_ext))
2183 xgi_video_info.mtrr = (unsigned int) 0;
2185 xgi_video_info.hasVB = HASVB_NONE;
2186 if ((xgi_video_info.chip == XG20) ||
2187 (xgi_video_info.chip == XG27)) {
2188 xgi_video_info.hasVB = HASVB_NONE;
2189 } else if (xgi_video_info.chip == XG21) {
2190 CR38 = xgifb_reg_get(XGICR, 0x38);
2191 if ((CR38&0xE0) == 0xC0) {
2192 xgi_video_info.disp_state = DISPTYPE_LCD;
2193 if (!XGIfb_GetXG21LVDSData()) {
2195 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2196 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2197 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2198 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2202 } else if ((CR38&0xE0) == 0x60) {
2203 xgi_video_info.hasVB = HASVB_CHRONTEL;
2205 xgi_video_info.hasVB = HASVB_NONE;
2208 XGIfb_get_VB_type();
2211 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2213 XGIhw_ext.ulExternalChip = 0;
2215 switch (xgi_video_info.hasVB) {
2217 reg = xgifb_reg_get(XGIPART4, 0x01);
2219 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2220 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2221 } else if (reg >= 0xD0) {
2222 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2223 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2225 /* else if (reg >= 0xB0) {
2226 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2227 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2228 printk("XGIfb: XGI301B bridge detected\n");
2231 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2232 printk("XGIfb: XGI301 bridge detected\n");
2236 reg = xgifb_reg_get(XGIPART4, 0x01);
2238 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2239 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2240 } else if (reg >= 0xD0) {
2241 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2242 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2243 } else if (reg >= 0xB0) {
2244 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2246 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2249 XGIhw_ext.ujVBChipID = VB_CHIP_302;
2250 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2254 XGIhw_ext.ulExternalChip = 0x1;
2255 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2257 case HASVB_TRUMPION:
2258 XGIhw_ext.ulExternalChip = 0x2;
2259 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2261 case HASVB_CHRONTEL:
2262 XGIhw_ext.ulExternalChip = 0x4;
2263 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2265 case HASVB_LVDS_CHRONTEL:
2266 XGIhw_ext.ulExternalChip = 0x5;
2267 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2270 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2274 if (xgi_video_info.hasVB != HASVB_NONE)
2277 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2279 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2281 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2284 xgi_video_info.disp_state = DISPMODE_SINGLE |
2288 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2290 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2292 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2296 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2300 XGIfb_detectedpdc = 0;
2302 XGIfb_detectedlcda = 0xff;
2304 /* TW: Try to find about LCDA */
2306 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2307 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2308 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2310 tmp = xgifb_reg_get(XGICR, 0x34);
2312 /* Currently on LCDA?
2313 *(Some BIOSes leave CR38) */
2314 tmp = xgifb_reg_get(XGICR, 0x38);
2315 if ((tmp & 0x03) == 0x03) {
2316 /* XGI_Pr.XGI_UseLCDA = 1; */
2318 /* Currently on LCDA?
2319 *(Some newer BIOSes set D0 in CR35) */
2320 tmp = xgifb_reg_get(XGICR, 0x35);
2322 /* XGI_Pr.XGI_UseLCDA = 1; */
2324 tmp = xgifb_reg_get(XGICR,
2327 tmp = xgifb_reg_get(
2330 /* XGI_Pr.XGI_UseLCDA = 1; */
2339 if (xgifb_mode_idx >= 0)
2340 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2342 if (xgifb_mode_idx < 0) {
2343 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2345 xgifb_mode_idx = DEFAULT_LCDMODE;
2346 if (xgi_video_info.chip == XG21)
2348 XGIfb_GetXG21DefaultLVDSModeIdx();
2351 xgifb_mode_idx = DEFAULT_TVMODE;
2354 xgifb_mode_idx = DEFAULT_MODE;
2359 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2361 /* yilin set default refresh rate */
2362 if (xgi_video_info.refresh_rate == 0)
2363 xgi_video_info.refresh_rate = 60;
2364 if (XGIfb_search_refresh_rate(
2365 xgi_video_info.refresh_rate) == 0) {
2366 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2367 xgi_video_info.refresh_rate = 60;
2370 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2371 xgi_video_info.video_vwidth =
2372 xgi_video_info.video_width =
2373 XGIbios_mode[xgifb_mode_idx].xres;
2374 xgi_video_info.video_vheight =
2375 xgi_video_info.video_height =
2376 XGIbios_mode[xgifb_mode_idx].yres;
2377 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2378 xgi_video_info.video_linelength =
2379 xgi_video_info.video_width *
2380 (xgi_video_info.video_bpp >> 3);
2381 switch (xgi_video_info.video_bpp) {
2383 xgi_video_info.DstColor = 0x0000;
2384 xgi_video_info.XGI310_AccelDepth = 0x00000000;
2385 xgi_video_info.video_cmap_len = 256;
2388 xgi_video_info.DstColor = 0x8000;
2389 xgi_video_info.XGI310_AccelDepth = 0x00010000;
2390 xgi_video_info.video_cmap_len = 16;
2393 xgi_video_info.DstColor = 0xC000;
2394 xgi_video_info.XGI310_AccelDepth = 0x00020000;
2395 xgi_video_info.video_cmap_len = 16;
2398 xgi_video_info.video_cmap_len = 16;
2399 printk(KERN_INFO "XGIfb: Unsupported depth %d",
2400 xgi_video_info.video_bpp);
2404 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2405 xgi_video_info.video_width,
2406 xgi_video_info.video_height,
2407 xgi_video_info.video_bpp,
2408 xgi_video_info.refresh_rate);
2411 default_var.xres_virtual =
2412 xgi_video_info.video_width;
2414 default_var.yres_virtual =
2415 xgi_video_info.video_height;
2416 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2418 XGIfb_bpp_to_var(&default_var);
2420 default_var.pixclock = (u32) (1000000000 /
2421 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2422 XGIfb_mode_no, XGIfb_rate_idx));
2424 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2425 XGIfb_mode_no, XGIfb_rate_idx,
2426 &default_var.left_margin, &default_var.right_margin,
2427 &default_var.upper_margin, &default_var.lower_margin,
2428 &default_var.hsync_len, &default_var.vsync_len,
2429 &default_var.sync, &default_var.vmode)) {
2431 if ((default_var.vmode & FB_VMODE_MASK) ==
2432 FB_VMODE_INTERLACED) {
2433 default_var.yres <<= 1;
2434 default_var.yres_virtual <<= 1;
2435 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2437 default_var.pixclock >>= 1;
2438 default_var.yres >>= 1;
2439 default_var.yres_virtual >>= 1;
2444 fb_info->flags = FBINFO_FLAG_DEFAULT;
2445 fb_info->var = default_var;
2446 fb_info->fix = XGIfb_fix;
2447 fb_info->par = &xgi_video_info;
2448 fb_info->screen_base = xgi_video_info.video_vbase;
2449 fb_info->fbops = &XGIfb_ops;
2450 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2451 fb_info->pseudo_palette = pseudo_palette;
2453 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2456 xgi_video_info.mtrr = mtrr_add(
2457 (unsigned int) xgi_video_info.video_base,
2458 (unsigned int) xgi_video_info.video_size,
2459 MTRR_TYPE_WRCOMB, 1);
2460 if (xgi_video_info.mtrr)
2461 printk(KERN_INFO "XGIfb: Added MTRRs\n");
2464 if (register_framebuffer(fb_info) < 0) {
2469 XGIfb_registered = 1;
2471 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2472 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2479 iounmap(xgi_video_info.mmio_vbase);
2480 iounmap(xgi_video_info.video_vbase);
2481 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2483 release_mem_region(xgi_video_info.video_base,
2484 xgi_video_info.video_size);
2486 vfree(XGIhw_ext.pjVirtualRomBase);
2487 framebuffer_release(fb_info);
2491 /*****************************************************/
2492 /* PCI DEVICE HANDLING */
2493 /*****************************************************/
2495 static void __devexit xgifb_remove(struct pci_dev *pdev)
2497 unregister_framebuffer(fb_info);
2498 iounmap(xgi_video_info.mmio_vbase);
2499 iounmap(xgi_video_info.video_vbase);
2500 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2501 release_mem_region(xgi_video_info.video_base,
2502 xgi_video_info.video_size);
2503 vfree(XGIhw_ext.pjVirtualRomBase);
2504 framebuffer_release(fb_info);
2505 pci_set_drvdata(pdev, NULL);
2508 static struct pci_driver xgifb_driver = {
2510 .id_table = xgifb_pci_table,
2511 .probe = xgifb_probe,
2512 .remove = __devexit_p(xgifb_remove)
2515 static int __init xgifb_init(void)
2517 char *option = NULL;
2519 if (fb_get_options("xgifb", &option))
2521 XGIfb_setup(option);
2523 return pci_register_driver(&xgifb_driver);
2527 module_init(xgifb_init);
2530 /*****************************************************/
2532 /*****************************************************/
2538 static unsigned int rate;
2539 static unsigned int mem;
2540 static char *forcecrt2type;
2541 static int forcecrt1 = -1;
2542 static int pdc = -1;
2543 static int pdc1 = -1;
2544 static int noypan = -1;
2545 static int userom = -1;
2546 static int useoem = -1;
2547 static char *tvstandard;
2548 static int nocrt2rate;
2549 static int scalelcd = -1;
2550 static char *specialtiming;
2551 static int lvdshl = -1;
2552 static int tvxposoffset, tvyposoffset;
2553 #if !defined(__i386__) && !defined(__x86_64__)
2554 static int resetcard;
2555 static int videoram;
2558 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2559 MODULE_LICENSE("GPL");
2560 MODULE_AUTHOR("XGITECH , Others");
2562 module_param(mem, int, 0);
2563 module_param(noypan, int, 0);
2564 module_param(userom, int, 0);
2565 module_param(useoem, int, 0);
2566 module_param(mode, charp, 0);
2567 module_param(vesa, int, 0);
2568 module_param(rate, int, 0);
2569 module_param(forcecrt1, int, 0);
2570 module_param(forcecrt2type, charp, 0);
2571 module_param(scalelcd, int, 0);
2572 module_param(pdc, int, 0);
2573 module_param(pdc1, int, 0);
2574 module_param(specialtiming, charp, 0);
2575 module_param(lvdshl, int, 0);
2576 module_param(tvstandard, charp, 0);
2577 module_param(tvxposoffset, int, 0);
2578 module_param(tvyposoffset, int, 0);
2579 module_param(filter, int, 0);
2580 module_param(nocrt2rate, int, 0);
2581 #if !defined(__i386__) && !defined(__x86_64__)
2582 module_param(resetcard, int, 0);
2583 module_param(videoram, int, 0);
2586 MODULE_PARM_DESC(noypan,
2587 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2588 "will be performed by redrawing the screen. (default: 0)\n");
2590 MODULE_PARM_DESC(mode,
2591 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2592 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2593 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2594 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2596 MODULE_PARM_DESC(vesa,
2597 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2598 "0x117 (default: 0x0103)\n");
2600 MODULE_PARM_DESC(rate,
2601 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2602 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2603 "will be ignored (default: 60)\n");
2605 MODULE_PARM_DESC(forcecrt1,
2606 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2607 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2608 "0=CRT1 OFF) (default: [autodetected])\n");
2610 MODULE_PARM_DESC(forcecrt2type,
2611 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2612 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2613 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2614 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2615 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2616 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2617 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2618 "depends on the very hardware in use. (default: [autodetected])\n");
2620 MODULE_PARM_DESC(scalelcd,
2621 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2622 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2623 "show black bars around the image, TMDS panels will probably do the scaling\n"
2624 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2626 MODULE_PARM_DESC(pdc,
2627 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2628 "should detect this correctly in most cases; however, sometimes this is not\n"
2629 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2630 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2631 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2632 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2634 MODULE_PARM_DESC(pdc1,
2635 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2636 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2637 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2638 "implemented yet.\n");
2640 MODULE_PARM_DESC(specialtiming,
2641 "\nPlease refer to documentation for more information on this option.\n");
2643 MODULE_PARM_DESC(lvdshl,
2644 "\nPlease refer to documentation for more information on this option.\n");
2646 MODULE_PARM_DESC(tvstandard,
2647 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2648 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2650 MODULE_PARM_DESC(tvxposoffset,
2651 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2654 MODULE_PARM_DESC(tvyposoffset,
2655 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2658 MODULE_PARM_DESC(filter,
2659 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2660 "(Possible values 0-7, default: [no filter])\n");
2662 MODULE_PARM_DESC(nocrt2rate,
2663 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2664 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2666 static int __init xgifb_init_module(void)
2668 printk("\nXGIfb_init_module");
2670 XGIfb_search_mode(mode);
2671 else if (vesa != -1)
2672 XGIfb_search_vesamode(vesa);
2674 return xgifb_init();
2677 static void __exit xgifb_remove_module(void)
2679 pci_unregister_driver(&xgifb_driver);
2680 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2683 module_init(xgifb_init_module);
2684 module_exit(xgifb_remove_module);
2686 #endif /* /MODULE */