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>
45 #include "vb_setmode.h"
47 #define Index_CR_GPIO_Reg1 0x48
48 #define Index_CR_GPIO_Reg2 0x49
49 #define Index_CR_GPIO_Reg3 0x4a
51 #define GPIOG_EN (1<<6)
52 #define GPIOG_WRITE (1<<6)
53 #define GPIOG_READ (1<<1)
55 #define XGIFB_ROM_SIZE 65536
57 /* -------------------- Macro definitions ---------------------------- */
62 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
64 #define DPRINTK(fmt, args...)
68 static void dumpVGAReg(void)
72 xgifb_reg_set(XGISR, 0x05, 0x86);
74 xgifb_reg_set(XGISR, 0x08, 0x4f);
75 xgifb_reg_set(XGISR, 0x0f, 0x20);
76 xgifb_reg_set(XGISR, 0x11, 0x4f);
77 xgifb_reg_set(XGISR, 0x13, 0x45);
78 xgifb_reg_set(XGISR, 0x14, 0x51);
79 xgifb_reg_set(XGISR, 0x1e, 0x41);
80 xgifb_reg_set(XGISR, 0x1f, 0x0);
81 xgifb_reg_set(XGISR, 0x20, 0xa1);
82 xgifb_reg_set(XGISR, 0x22, 0xfb);
83 xgifb_reg_set(XGISR, 0x26, 0x22);
84 xgifb_reg_set(XGISR, 0x3e, 0x07);
87 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
88 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
89 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
90 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
92 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
94 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
95 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
97 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
98 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
100 xgifb_reg_set(XGICR, 0x99, 0x1);
101 xgifb_reg_set(XGICR, 0x41, 0x40);
104 for (i = 0; i < 0x4f; i++) {
105 reg = xgifb_reg_get(XGISR, i);
106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
110 for (i = 0; i < 0xF0; i++) {
111 reg = xgifb_reg_get(XGICR, i);
112 printk("\no 3d4 %x", i);
113 printk("\ni 3d5 => %x", reg);
116 xgifb_reg_set(XGIPART1,0x2F,1);
117 for (i=1; i < 0x50; i++) {
118 reg = xgifb_reg_get(XGIPART1, i);
119 printk("\no d004 %x", i);
120 printk("\ni d005 => %x", reg);
123 for (i=0; i < 0x50; i++) {
124 reg = xgifb_reg_get(XGIPART2, i);
125 printk("\no d010 %x", i);
126 printk("\ni d011 => %x", reg);
128 for (i=0; i < 0x50; i++) {
129 reg = xgifb_reg_get(XGIPART3, i);
130 printk("\no d012 %x",i);
131 printk("\ni d013 => %x",reg);
133 for (i=0; i < 0x50; i++) {
134 reg = xgifb_reg_get(XGIPART4, i);
135 printk("\no d014 %x",i);
136 printk("\ni d015 => %x",reg);
141 static inline void dumpVGAReg(void)
146 /* data for XGI components */
147 struct video_info xgi_video_info;
152 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
155 /* --------------- Hardware Access Routines -------------------------- */
157 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 struct xgi_hw_device_info *HwDeviceExtension,
159 unsigned char modeno, unsigned char rateindex)
161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
165 /* unsigned long temp = 0; */
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
174 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
176 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
186 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
191 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192 struct xgi_hw_device_info *HwDeviceExtension,
193 unsigned char modeno, unsigned char rateindex,
194 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
198 unsigned short ModeNo = modeno;
199 unsigned short ModeIdIndex = 0, index = 0;
200 unsigned short RefreshRateTableIndex = 0;
202 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204 unsigned char sr_data, cr_data, cr_data2;
205 unsigned long cr_data3;
206 int A, B, C, D, E, F, temp, j;
207 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210 ModeIdIndex, XGI_Pr);
212 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
216 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217 RefreshRateTableIndex += (rateindex - 1);
219 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
221 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
223 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
225 /* Horizontal total */
226 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
230 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
232 Horizontal display enable end
233 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
235 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
238 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
240 /* Horizontal retrace (=sync) start */
241 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
244 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
246 /* Horizontal blank start */
247 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
249 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
251 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
253 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
255 /* Horizontal blank end */
256 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257 | ((unsigned short) (sr_data & 0x03) << 6);
259 /* Horizontal retrace (=sync) end */
260 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
262 temp = HBE - ((E - 1) & 255);
263 B = (temp > 0) ? temp : (temp + 256);
265 temp = HRE - ((E + F + 3) & 63);
266 C = (temp > 0) ? temp : (temp + 64);
270 *left_margin = D * 8;
271 *right_margin = F * 8;
274 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
276 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
278 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
281 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282 | ((unsigned short) (cr_data2 & 0x20) << 4)
283 | ((unsigned short) (sr_data & 0x01) << 10);
286 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
288 /* Vertical display enable end */
290 VDE = (cr_data & 0xff) |
291 ((unsigned short) (cr_data2 & 0x02) << 7) |
292 ((unsigned short) (cr_data2 & 0x40) << 3) |
293 ((unsigned short) (sr_data & 0x02) << 9);
295 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
298 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
300 /* Vertical retrace (=sync) start */
301 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302 | ((unsigned short) (cr_data2 & 0x80) << 2)
303 | ((unsigned short) (sr_data & 0x08) << 7);
306 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
308 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
310 /* Vertical blank start */
311 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312 | ((unsigned short) (cr_data3 & 0x20) << 4)
313 | ((unsigned short) (sr_data & 0x04) << 8);
315 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
317 /* Vertical blank end */
318 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319 temp = VBE - ((E - 1) & 511);
320 B = (temp > 0) ? temp : (temp + 512);
322 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
324 /* Vertical retrace (=sync) end */
325 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326 temp = VRE - ((E + F - 1) & 31);
327 C = (temp > 0) ? temp : (temp + 32);
335 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
338 *sync |= FB_SYNC_VERT_HIGH_ACT;
340 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
343 *sync |= FB_SYNC_HOR_HIGH_ACT;
345 *vmode = FB_VMODE_NONINTERLACED;
346 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347 *vmode = FB_VMODE_INTERLACED;
350 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
351 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
352 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
355 *vmode = FB_VMODE_DOUBLE;
366 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
368 XGI_Pr->RelIO = BaseAddr;
369 XGI_Pr->P3c4 = BaseAddr + 0x14;
370 XGI_Pr->P3d4 = BaseAddr + 0x24;
371 XGI_Pr->P3c0 = BaseAddr + 0x10;
372 XGI_Pr->P3ce = BaseAddr + 0x1e;
373 XGI_Pr->P3c2 = BaseAddr + 0x12;
374 XGI_Pr->P3ca = BaseAddr + 0x1a;
375 XGI_Pr->P3c6 = BaseAddr + 0x16;
376 XGI_Pr->P3c7 = BaseAddr + 0x17;
377 XGI_Pr->P3c8 = BaseAddr + 0x18;
378 XGI_Pr->P3c9 = BaseAddr + 0x19;
379 XGI_Pr->P3da = BaseAddr + 0x2A;
380 /* Digital video interface registers (LCD) */
381 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
382 /* 301 TV Encoder registers */
383 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
384 /* 301 Macrovision registers */
385 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
386 /* 301 VGA2 (and LCD) registers */
387 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
388 /* 301 palette address port registers */
389 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
393 /* ------------ Interface for init & mode switching code ------------- */
395 static unsigned char XGIfb_query_VGA_config_space(
396 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
397 unsigned long set, unsigned long *value)
399 static struct pci_dev *pdev = NULL;
400 static unsigned char init = 0, valid_pdev = 0;
403 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
405 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
409 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
418 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
419 xgi_video_info.chip_id);
424 pci_read_config_dword(pdev, offset, (u32 *) value);
426 pci_write_config_dword(pdev, offset, (u32)(*value));
431 /* ------------------ Internal helper routines ----------------- */
433 static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
437 int XGIfb_mode_idx = 0;
440 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
441 && (XGIbios_mode[XGIfb_mode_idx].xres
442 <= XGI21_LCDCapList[0].LVDSHDE)) {
443 if ((XGIbios_mode[XGIfb_mode_idx].xres
444 == XGI21_LCDCapList[0].LVDSHDE)
445 && (XGIbios_mode[XGIfb_mode_idx].yres
446 == XGI21_LCDCapList[0].LVDSVDE)
447 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
448 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
457 return XGIfb_mode_idx;
460 static void XGIfb_search_mode(const char *name)
465 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
466 xgifb_mode_idx = DEFAULT_MODE;
467 if ((xgi_video_info.chip == XG21)
468 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
470 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
475 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
476 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
477 xgifb_mode_idx = DEFAULT_MODE;
478 if ((xgi_video_info.chip == XG21)
479 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
481 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
486 while (XGIbios_mode[i].mode_no != 0) {
487 l = min(strlen(name), strlen(XGIbios_mode[i].name));
488 if (!strncmp(name, XGIbios_mode[i].name, l)) {
496 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
499 static void XGIfb_search_vesamode(unsigned int vesamode)
505 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
506 xgifb_mode_idx = DEFAULT_MODE;
507 if ((xgi_video_info.chip == XG21)
508 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
510 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
515 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
517 while (XGIbios_mode[i].mode_no != 0) {
518 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
519 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
527 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
530 static int XGIfb_GetXG21LVDSData(void)
533 unsigned char *pData;
536 tmp = xgifb_reg_get(XGISR, 0x1e);
537 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
539 pData = xgi_video_info.mmio_vbase + 0x20000;
540 if ((pData[0x0] == 0x55) &&
541 (pData[0x1] == 0xAA) &&
542 (pData[0x65] & 0x1)) {
543 i = pData[0x316] | (pData[0x317] << 8);
550 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
551 | (pData[i + 1] << 8);
552 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
554 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
556 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
558 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
560 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
562 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
564 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
565 | (pData[i + 15] << 8);
566 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
567 | (pData[i + 17] << 8);
568 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
569 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
570 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
571 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
572 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
573 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
574 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
578 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
579 / sizeof(struct XGI21_LVDSCapStruct))));
585 static int XGIfb_validate_mode(int myindex)
589 if (xgi_video_info.chip == XG21) {
590 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
592 xres = XGI21_LCDCapList[0].LVDSHDE;
593 yres = XGI21_LCDCapList[0].LVDSVDE;
594 if (XGIbios_mode[myindex].xres > xres)
596 if (XGIbios_mode[myindex].yres > yres)
598 if ((XGIbios_mode[myindex].xres < xres) &&
599 (XGIbios_mode[myindex].yres < yres)) {
600 if (XGIbios_mode[myindex].bpp > 8)
609 /* FIXME: for now, all is valid on XG27 */
610 if (xgi_video_info.chip == XG27)
613 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
616 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
618 switch (XGIhw_ext.ulCRT2LCDType) {
659 /* case LCD_320x480: */ /* TW: FSTN */
670 if (XGIbios_mode[myindex].xres > xres)
672 if (XGIbios_mode[myindex].yres > yres)
674 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
675 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
676 switch (XGIbios_mode[myindex].xres) {
678 if (XGIbios_mode[myindex].yres != 512)
680 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
684 if ((XGIbios_mode[myindex].yres != 400)
685 && (XGIbios_mode[myindex].yres
690 if (XGIbios_mode[myindex].yres != 600)
694 if ((XGIbios_mode[myindex].yres != 600) &&
695 (XGIbios_mode[myindex].yres != 768))
697 if ((XGIbios_mode[myindex].yres == 600) &&
698 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
702 if ((XGIbios_mode[myindex].yres) != 768)
704 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
708 if ((XGIbios_mode[myindex].yres != 768) &&
709 (XGIbios_mode[myindex].yres != 1024))
711 if ((XGIbios_mode[myindex].yres == 768) &&
712 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
716 if (XGIbios_mode[myindex].yres != 1050)
720 if (XGIbios_mode[myindex].yres != 1200)
727 switch (XGIbios_mode[myindex].xres) {
729 if (XGIbios_mode[myindex].yres != 512)
733 if ((XGIbios_mode[myindex].yres != 400) &&
734 (XGIbios_mode[myindex].yres != 480))
738 if (XGIbios_mode[myindex].yres != 600)
742 if (XGIbios_mode[myindex].yres != 768)
746 if ((XGIbios_mode[myindex].yres != 960) &&
747 (XGIbios_mode[myindex].yres != 1024))
749 if (XGIbios_mode[myindex].yres == 960) {
750 if (XGIhw_ext.ulCRT2LCDType ==
756 if (XGIbios_mode[myindex].yres != 1050)
760 if (XGIbios_mode[myindex].yres != 1200)
769 switch (XGIbios_mode[myindex].xres) {
775 if (xgi_video_info.TV_type == TVMODE_NTSC) {
776 if (XGIbios_mode[myindex].yres != 480)
778 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
779 if (XGIbios_mode[myindex].yres != 576)
782 /* TW: LVDS/CHRONTEL does not support 720 */
783 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
784 xgi_video_info.hasVB == HASVB_CHRONTEL) {
789 if (xgi_video_info.TV_type == TVMODE_NTSC) {
790 if (XGIbios_mode[myindex].bpp == 32)
799 if (XGIbios_mode[myindex].xres > 1280)
807 static void XGIfb_search_crt2type(const char *name)
814 while (XGI_crt2type[i].type_no != -1) {
815 if (!strcmp(name, XGI_crt2type[i].name)) {
816 XGIfb_crt2type = XGI_crt2type[i].type_no;
817 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
822 if (XGIfb_crt2type < 0)
823 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
826 static u8 XGIfb_search_refresh_rate(unsigned int rate)
831 xres = XGIbios_mode[xgifb_mode_idx].xres;
832 yres = XGIbios_mode[xgifb_mode_idx].yres;
835 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
836 if ((XGIfb_vrate[i].xres == xres) &&
837 (XGIfb_vrate[i].yres == yres)) {
838 if (XGIfb_vrate[i].refresh == rate) {
839 XGIfb_rate_idx = XGIfb_vrate[i].idx;
841 } else if (XGIfb_vrate[i].refresh > rate) {
842 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
843 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
844 rate, XGIfb_vrate[i].refresh);
845 XGIfb_rate_idx = XGIfb_vrate[i].idx;
846 xgi_video_info.refresh_rate =
847 XGIfb_vrate[i].refresh;
848 } else if (((rate - XGIfb_vrate[i - 1].refresh)
849 <= 2) && (XGIfb_vrate[i].idx
851 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
852 rate, XGIfb_vrate[i-1].refresh);
853 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
854 xgi_video_info.refresh_rate =
855 XGIfb_vrate[i - 1].refresh;
858 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
859 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
860 rate, XGIfb_vrate[i].refresh);
861 XGIfb_rate_idx = XGIfb_vrate[i].idx;
867 if (XGIfb_rate_idx > 0) {
868 return XGIfb_rate_idx;
870 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
876 static void XGIfb_search_tvstd(const char *name)
883 while (XGI_tvtype[i].type_no != -1) {
884 if (!strcmp(name, XGI_tvtype[i].name)) {
885 XGIfb_tvmode = XGI_tvtype[i].type_no;
892 /* ----------- FBDev related routines for all series ----------- */
894 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
896 switch (var->bits_per_pixel) {
898 var->red.offset = var->green.offset = var->blue.offset = 0;
899 var->red.length = var->green.length = var->blue.length = 6;
900 xgi_video_info.video_cmap_len = 256;
903 var->red.offset = 11;
905 var->green.offset = 5;
906 var->green.length = 6;
907 var->blue.offset = 0;
908 var->blue.length = 5;
909 var->transp.offset = 0;
910 var->transp.length = 0;
911 xgi_video_info.video_cmap_len = 16;
914 var->red.offset = 16;
916 var->green.offset = 8;
917 var->green.length = 8;
918 var->blue.offset = 0;
919 var->blue.length = 8;
920 var->transp.offset = 24;
921 var->transp.length = 8;
922 xgi_video_info.video_cmap_len = 16;
927 /* --------------------- SetMode routines ------------------------- */
929 static void XGIfb_pre_setmode(void)
931 u8 cr30 = 0, cr31 = 0;
933 cr31 = xgifb_reg_get(XGICR, 0x31);
936 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
938 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
939 cr31 |= XGI_DRIVER_MODE;
942 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
943 cr31 |= XGI_DRIVER_MODE;
946 if (xgi_video_info.TV_type == TVMODE_HIVISION)
947 cr30 = (XGI_VB_OUTPUT_HIVISION
948 | XGI_SIMULTANEOUS_VIEW_ENABLE);
949 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
950 cr30 = (XGI_VB_OUTPUT_SVIDEO
951 | XGI_SIMULTANEOUS_VIEW_ENABLE);
952 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
953 cr30 = (XGI_VB_OUTPUT_COMPOSITE
954 | XGI_SIMULTANEOUS_VIEW_ENABLE);
955 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
956 cr30 = (XGI_VB_OUTPUT_SCART
957 | XGI_SIMULTANEOUS_VIEW_ENABLE);
958 cr31 |= XGI_DRIVER_MODE;
960 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
965 default: /* disable CRT2 */
967 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
970 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
971 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
972 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
975 static void XGIfb_post_setmode(void)
978 unsigned char doit = 1;
980 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
981 xgifb_reg_set(XGICR, 0x13, 0x00);
982 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
985 if (xgi_video_info.video_bpp == 8) {
986 /* TW: We can't switch off CRT1 on LVDS/Chrontel
988 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
989 (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
992 /* TW: We can't switch off CRT1 on 301B-DH
993 * in 8bpp Modes if using LCD */
994 if (xgi_video_info.disp_state & DISPTYPE_LCD)
998 /* TW: We can't switch off CRT1 if bridge is in slave mode */
999 if (xgi_video_info.hasVB != HASVB_NONE) {
1000 reg = xgifb_reg_get(XGIPART1, 0x00);
1002 if ((reg & 0x50) == 0x10)
1009 reg = xgifb_reg_get(XGICR, 0x17);
1010 if ((XGIfb_crt1off) && (doit))
1014 xgifb_reg_set(XGICR, 0x17, reg);
1016 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1018 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1021 reg = xgifb_reg_get(XGIPART4, 0x01);
1023 if (reg < 0xB0) { /* Set filter for XGI301 */
1024 switch (xgi_video_info.video_width) {
1026 filter_tb = (xgi_video_info.TV_type ==
1027 TVMODE_NTSC) ? 4 : 12;
1030 filter_tb = (xgi_video_info.TV_type ==
1031 TVMODE_NTSC) ? 5 : 13;
1034 filter_tb = (xgi_video_info.TV_type ==
1035 TVMODE_NTSC) ? 6 : 14;
1038 filter_tb = (xgi_video_info.TV_type ==
1039 TVMODE_NTSC) ? 7 : 15;
1045 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1047 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1049 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1051 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1053 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1055 } else if (xgi_video_info.TV_plug
1056 == TVPLUG_COMPOSITE) {
1058 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1060 switch (xgi_video_info.video_width) {
1062 xgifb_reg_set(XGIPART2,
1065 xgifb_reg_set(XGIPART2,
1068 xgifb_reg_set(XGIPART2,
1071 xgifb_reg_set(XGIPART2,
1076 xgifb_reg_set(XGIPART2,
1079 xgifb_reg_set(XGIPART2,
1082 xgifb_reg_set(XGIPART2,
1085 xgifb_reg_set(XGIPART2,
1090 xgifb_reg_set(XGIPART2,
1093 xgifb_reg_set(XGIPART2,
1096 xgifb_reg_set(XGIPART2,
1099 xgifb_reg_set(XGIPART2,
1106 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1108 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1110 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1112 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1114 } else if (xgi_video_info.TV_plug
1115 == TVPLUG_COMPOSITE) {
1117 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1119 switch (xgi_video_info.video_width) {
1121 xgifb_reg_set(XGIPART2,
1124 xgifb_reg_set(XGIPART2,
1127 xgifb_reg_set(XGIPART2,
1130 xgifb_reg_set(XGIPART2,
1135 xgifb_reg_set(XGIPART2,
1138 xgifb_reg_set(XGIPART2,
1141 xgifb_reg_set(XGIPART2,
1144 xgifb_reg_set(XGIPART2,
1149 xgifb_reg_set(XGIPART2,
1152 xgifb_reg_set(XGIPART2,
1155 xgifb_reg_set(XGIPART2,
1158 xgifb_reg_set(XGIPART2,
1166 if ((filter >= 0) && (filter <= 7)) {
1167 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1169 XGI_TV_filter[filter_tb].
1171 XGI_TV_filter[filter_tb].
1173 XGI_TV_filter[filter_tb].
1175 XGI_TV_filter[filter_tb].
1181 (XGI_TV_filter[filter_tb].
1182 filter[filter][0]));
1186 (XGI_TV_filter[filter_tb].
1187 filter[filter][1]));
1191 (XGI_TV_filter[filter_tb].
1192 filter[filter][2]));
1196 (XGI_TV_filter[filter_tb].
1197 filter[filter][3]));
1203 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1204 struct fb_info *info)
1207 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1209 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1211 #if defined(__powerpc__)
1212 u8 sr_data, cr_data;
1214 unsigned int drate = 0, hrate = 0;
1217 /* unsigned char reg, reg1; */
1219 DEBUGPRN("Inside do_set_var");
1220 /* 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); */
1222 info->var.xres_virtual = var->xres_virtual;
1223 info->var.yres_virtual = var->yres_virtual;
1224 info->var.bits_per_pixel = var->bits_per_pixel;
1226 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1228 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1230 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1232 /* var->yres <<= 1; */
1235 if (!htotal || !vtotal) {
1236 DPRINTK("XGIfb: Invalid 'var' information\n");
1238 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1239 var->pixclock, htotal, vtotal);
1241 if (var->pixclock && htotal && vtotal) {
1242 drate = 1000000000 / var->pixclock;
1243 hrate = (drate * 1000) / htotal;
1244 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1247 xgi_video_info.refresh_rate = 60;
1250 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1253 var->bits_per_pixel,
1254 xgi_video_info.refresh_rate);
1256 old_mode = xgifb_mode_idx;
1259 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1260 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1261 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1262 && (XGIbios_mode[xgifb_mode_idx].yres
1264 && (XGIbios_mode[xgifb_mode_idx].bpp
1265 == var->bits_per_pixel)) {
1266 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1274 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1276 xgifb_mode_idx = -1;
1278 if (xgifb_mode_idx < 0) {
1279 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1280 var->xres, var->yres, var->bits_per_pixel);
1281 xgifb_mode_idx = old_mode;
1285 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1286 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1287 xgi_video_info.refresh_rate = 60;
1292 XGIfb_pre_setmode();
1293 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1294 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1298 info->fix.line_length = ((info->var.xres_virtual
1299 * info->var.bits_per_pixel) >> 6);
1301 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1303 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1304 xgifb_reg_set(XGISR,
1306 (info->fix.line_length & 0xff00) >> 8);
1308 XGIfb_post_setmode();
1310 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1311 XGIbios_mode[xgifb_mode_idx].xres,
1312 XGIbios_mode[xgifb_mode_idx].yres,
1313 XGIbios_mode[xgifb_mode_idx].bpp,
1314 xgi_video_info.refresh_rate);
1316 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1317 xgi_video_info.video_vwidth = info->var.xres_virtual;
1318 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1319 xgi_video_info.video_vheight = info->var.yres_virtual;
1320 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1321 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1322 xgi_video_info.video_linelength = info->var.xres_virtual
1323 * (xgi_video_info.video_bpp >> 3);
1324 switch (xgi_video_info.video_bpp) {
1326 xgi_video_info.DstColor = 0x0000;
1327 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1328 xgi_video_info.video_cmap_len = 256;
1329 #if defined(__powerpc__)
1330 cr_data = xgifb_reg_get(XGICR, 0x4D);
1331 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
1335 xgi_video_info.DstColor = 0x8000;
1336 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1337 #if defined(__powerpc__)
1338 cr_data = xgifb_reg_get(XGICR, 0x4D);
1339 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1341 xgi_video_info.video_cmap_len = 16;
1344 xgi_video_info.DstColor = 0xC000;
1345 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1346 xgi_video_info.video_cmap_len = 16;
1347 #if defined(__powerpc__)
1348 cr_data = xgifb_reg_get(XGICR, 0x4D);
1349 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1353 xgi_video_info.video_cmap_len = 16;
1354 printk(KERN_ERR "XGIfb: Unsupported depth %d",
1355 xgi_video_info.video_bpp);
1359 XGIfb_bpp_to_var(var); /*update ARGB info*/
1360 DEBUGPRN("End of do_set_var");
1367 static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
1371 /* printk("Inside pan_var"); */
1373 base = var->yoffset * info->var.xres_virtual + var->xoffset;
1375 /* calculate base bpp dep. */
1376 switch (info->var.bits_per_pixel) {
1388 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1390 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1391 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1392 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1393 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
1394 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1396 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1397 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1398 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1399 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1400 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1401 xgifb_reg_and_or(XGIPART1,
1404 ((base >> 24) & 0x01) << 7);
1406 /* printk("End of pan_var"); */
1411 static int XGIfb_open(struct fb_info *info, int user)
1416 static int XGIfb_release(struct fb_info *info, int user)
1421 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1425 switch (var->bits_per_pixel) {
1439 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1440 unsigned blue, unsigned transp, struct fb_info *info)
1442 if (regno >= XGIfb_get_cmap_len(&info->var))
1445 switch (info->var.bits_per_pixel) {
1447 outb(regno, XGIDACA);
1448 outb((red >> 10), XGIDACD);
1449 outb((green >> 10), XGIDACD);
1450 outb((blue >> 10), XGIDACD);
1451 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1452 outb(regno, XGIDAC2A);
1453 outb((red >> 8), XGIDAC2D);
1454 outb((green >> 8), XGIDAC2D);
1455 outb((blue >> 8), XGIDAC2D);
1459 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1460 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1467 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1474 /* ----------- FBDev related routines for all series ---------- */
1476 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1477 struct fb_info *info)
1479 DEBUGPRN("inside get_fix");
1480 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1482 strcpy(fix->id, myid);
1484 fix->smem_start = xgi_video_info.video_base;
1486 fix->smem_len = xgi_video_info.video_size;
1488 fix->type = video_type;
1490 if (xgi_video_info.video_bpp == 8)
1491 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1493 fix->visual = FB_VISUAL_DIRECTCOLOR;
1500 fix->line_length = xgi_video_info.video_linelength;
1501 fix->mmio_start = xgi_video_info.mmio_base;
1502 fix->mmio_len = xgi_video_info.mmio_size;
1503 fix->accel = FB_ACCEL_XGI_XABRE;
1505 DEBUGPRN("end of get_fix");
1509 static int XGIfb_set_par(struct fb_info *info)
1513 /* printk("XGIfb: inside set_par\n"); */
1514 err = XGIfb_do_set_var(&info->var, 1, info);
1517 XGIfb_get_fix(&info->fix, -1, info);
1518 /* printk("XGIfb: end of set_par\n"); */
1522 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1524 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1526 unsigned int vtotal = 0;
1527 unsigned int drate = 0, hrate = 0;
1529 int refresh_rate, search_idx;
1531 DEBUGPRN("Inside check_var");
1533 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1534 vtotal = var->upper_margin + var->yres + var->lower_margin
1537 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1538 vtotal = var->upper_margin + var->yres + var->lower_margin
1541 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1542 vtotal = var->upper_margin + (var->yres / 2)
1543 + var->lower_margin + var->vsync_len;
1545 vtotal = var->upper_margin + var->yres + var->lower_margin
1548 if (!(htotal) || !(vtotal))
1549 XGIFAIL("XGIfb: no valid timing data");
1551 if (var->pixclock && htotal && vtotal) {
1552 drate = 1000000000 / var->pixclock;
1553 hrate = (drate * 1000) / htotal;
1554 xgi_video_info.refresh_rate =
1555 (unsigned int) (hrate * 2 / vtotal);
1557 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1558 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1559 __func__, var->pixclock, htotal, vtotal,
1560 __func__, drate, hrate, xgi_video_info.refresh_rate);
1562 xgi_video_info.refresh_rate = 60;
1566 if ((var->pixclock) && (htotal)) {
1567 drate = 1E12 / var->pixclock;
1568 hrate = drate / htotal;
1569 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1574 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1575 if ((var->xres == 1024) && (var->yres == 600))
1579 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1580 (XGIbios_mode[search_idx].xres <= var->xres)) {
1581 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1582 (XGIbios_mode[search_idx].yres == var->yres) &&
1583 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1584 if (XGIfb_validate_mode(search_idx) > 0) {
1594 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1595 var->xres, var->yres, var->bits_per_pixel);
1597 while (XGIbios_mode[search_idx].mode_no != 0) {
1598 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1599 (var->yres <= XGIbios_mode[search_idx].yres) &&
1600 (var->bits_per_pixel ==
1601 XGIbios_mode[search_idx].bpp)) {
1602 if (XGIfb_validate_mode(search_idx) > 0) {
1610 var->xres = XGIbios_mode[search_idx].xres;
1611 var->yres = XGIbios_mode[search_idx].yres;
1612 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1613 var->xres, var->yres, var->bits_per_pixel);
1616 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1617 var->xres, var->yres, var->bits_per_pixel);
1622 /* TW: TODO: Check the refresh rate */
1624 /* Adapt RGB settings */
1625 XGIfb_bpp_to_var(var);
1627 /* Sanity check for offsets */
1628 if (var->xoffset < 0)
1630 if (var->yoffset < 0)
1634 if (var->xres != var->xres_virtual)
1635 var->xres_virtual = var->xres;
1636 if (var->yres != var->yres_virtual)
1637 var->yres_virtual = var->yres;
1639 /* TW: Now patch yres_virtual if we use panning */
1640 /* May I do this? */
1641 /* var->yres_virtual = xgi_video_info.heapstart /
1642 (var->xres * (var->bits_per_pixel >> 3)); */
1643 /* if (var->yres_virtual <= var->yres) { */
1644 /* TW: Paranoia check */
1645 /* var->yres_virtual = var->yres; */
1649 /* Truncate offsets to maximum if too high */
1650 if (var->xoffset > var->xres_virtual - var->xres)
1651 var->xoffset = var->xres_virtual - var->xres - 1;
1653 if (var->yoffset > var->yres_virtual - var->yres)
1654 var->yoffset = var->yres_virtual - var->yres - 1;
1656 /* Set everything else to 0 */
1657 var->red.msb_right =
1658 var->green.msb_right =
1659 var->blue.msb_right =
1660 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1662 DEBUGPRN("end of check_var");
1667 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1668 struct fb_info *info)
1672 /* printk("\nInside pan_display:\n"); */
1674 if (var->xoffset > (info->var.xres_virtual - info->var.xres))
1676 if (var->yoffset > (info->var.yres_virtual - info->var.yres))
1679 if (var->vmode & FB_VMODE_YWRAP) {
1680 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1684 if (var->xoffset + info->var.xres > info->var.xres_virtual
1685 || var->yoffset + info->var.yres
1686 > info->var.yres_virtual)
1689 err = XGIfb_pan_var(var, info);
1693 info->var.xoffset = var->xoffset;
1694 info->var.yoffset = var->yoffset;
1695 if (var->vmode & FB_VMODE_YWRAP)
1696 info->var.vmode |= FB_VMODE_YWRAP;
1698 info->var.vmode &= ~FB_VMODE_YWRAP;
1700 /* printk("End of pan_display\n"); */
1705 static int XGIfb_blank(int blank, struct fb_info *info)
1709 reg = xgifb_reg_get(XGICR, 0x17);
1716 xgifb_reg_set(XGICR, 0x17, reg);
1717 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1718 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
1722 static struct fb_ops XGIfb_ops = {
1723 .owner = THIS_MODULE,
1724 .fb_open = XGIfb_open,
1725 .fb_release = XGIfb_release,
1726 .fb_check_var = XGIfb_check_var,
1727 .fb_set_par = XGIfb_set_par,
1728 .fb_setcolreg = XGIfb_setcolreg,
1730 .fb_pan_display = XGIfb_pan_display,
1732 .fb_blank = XGIfb_blank,
1733 .fb_fillrect = cfb_fillrect,
1734 .fb_copyarea = cfb_copyarea,
1735 .fb_imageblit = cfb_imageblit,
1736 /* .fb_mmap = XGIfb_mmap, */
1739 /* ---------------- Chip generation dependent routines ---------------- */
1741 /* for XGI 315/550/650/740/330 */
1743 static int XGIfb_get_dram_size(void)
1749 /* xorg driver sets 32MB * 1 channel */
1750 if (xgi_video_info.chip == XG27)
1751 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1753 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
1754 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1755 case XGI_DRAM_SIZE_1MB:
1756 xgi_video_info.video_size = 0x100000;
1758 case XGI_DRAM_SIZE_2MB:
1759 xgi_video_info.video_size = 0x200000;
1761 case XGI_DRAM_SIZE_4MB:
1762 xgi_video_info.video_size = 0x400000;
1764 case XGI_DRAM_SIZE_8MB:
1765 xgi_video_info.video_size = 0x800000;
1767 case XGI_DRAM_SIZE_16MB:
1768 xgi_video_info.video_size = 0x1000000;
1770 case XGI_DRAM_SIZE_32MB:
1771 xgi_video_info.video_size = 0x2000000;
1773 case XGI_DRAM_SIZE_64MB:
1774 xgi_video_info.video_size = 0x4000000;
1776 case XGI_DRAM_SIZE_128MB:
1777 xgi_video_info.video_size = 0x8000000;
1779 case XGI_DRAM_SIZE_256MB:
1780 xgi_video_info.video_size = 0x10000000;
1786 tmp = (reg & 0x0c) >> 2;
1787 switch (xgi_video_info.chip) {
1823 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1824 /* PLiad fixed for benchmarking and fb set */
1825 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1826 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1828 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1830 xgi_video_info.video_size, ChannelNum);
1835 static void XGIfb_detect_VB(void)
1839 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1841 switch (xgi_video_info.hasVB) {
1842 case HASVB_LVDS_CHRONTEL:
1843 case HASVB_CHRONTEL:
1847 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1851 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
1853 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1862 if (XGIfb_crt2type != -1)
1863 /* TW: Override with option */
1864 xgi_video_info.disp_state = XGIfb_crt2type;
1865 else if (cr32 & XGI_VB_TV)
1866 xgi_video_info.disp_state = DISPTYPE_TV;
1867 else if (cr32 & XGI_VB_LCD)
1868 xgi_video_info.disp_state = DISPTYPE_LCD;
1869 else if (cr32 & XGI_VB_CRT2)
1870 xgi_video_info.disp_state = DISPTYPE_CRT2;
1872 xgi_video_info.disp_state = 0;
1874 if (XGIfb_tvplug != -1)
1875 /* PR/TW: Override with option */
1876 xgi_video_info.TV_plug = XGIfb_tvplug;
1877 else if (cr32 & XGI_VB_HIVISION) {
1878 xgi_video_info.TV_type = TVMODE_HIVISION;
1879 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1880 } else if (cr32 & XGI_VB_SVIDEO)
1881 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1882 else if (cr32 & XGI_VB_COMPOSITE)
1883 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1884 else if (cr32 & XGI_VB_SCART)
1885 xgi_video_info.TV_plug = TVPLUG_SCART;
1887 if (xgi_video_info.TV_type == 0) {
1888 temp = xgifb_reg_get(XGICR, 0x38);
1890 xgi_video_info.TV_type = TVMODE_PAL;
1892 xgi_video_info.TV_type = TVMODE_NTSC;
1895 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1896 if (XGIfb_forcecrt1 != -1) {
1897 if (XGIfb_forcecrt1)
1904 static int XGIfb_has_VB(void)
1908 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
1909 switch (vb_chipid) {
1911 xgi_video_info.hasVB = HASVB_301;
1914 xgi_video_info.hasVB = HASVB_302;
1917 xgi_video_info.hasVB = HASVB_NONE;
1923 static void XGIfb_get_VB_type(void)
1927 if (!XGIfb_has_VB()) {
1928 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1929 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1930 case XGI310_EXTERNAL_CHIP_LVDS:
1931 xgi_video_info.hasVB = HASVB_LVDS;
1933 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1934 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1942 XGIINITSTATIC int __init XGIfb_setup(char *options)
1946 xgi_video_info.refresh_rate = 0;
1948 printk(KERN_INFO "XGIfb: Options %s\n", options);
1950 if (!options || !*options)
1953 while ((this_opt = strsep(&options, ",")) != NULL) {
1958 if (!strncmp(this_opt, "mode:", 5)) {
1959 XGIfb_search_mode(this_opt + 5);
1960 } else if (!strncmp(this_opt, "vesa:", 5)) {
1961 XGIfb_search_vesamode(simple_strtoul(
1962 this_opt + 5, NULL, 0));
1963 } else if (!strncmp(this_opt, "mode:", 5)) {
1964 XGIfb_search_mode(this_opt + 5);
1965 } else if (!strncmp(this_opt, "vesa:", 5)) {
1966 XGIfb_search_vesamode(simple_strtoul(
1967 this_opt + 5, NULL, 0));
1968 } else if (!strncmp(this_opt, "vrate:", 6)) {
1969 xgi_video_info.refresh_rate = simple_strtoul(
1970 this_opt + 6, NULL, 0);
1971 } else if (!strncmp(this_opt, "rate:", 5)) {
1972 xgi_video_info.refresh_rate = simple_strtoul(
1973 this_opt + 5, NULL, 0);
1974 } else if (!strncmp(this_opt, "off", 3)) {
1976 } else if (!strncmp(this_opt, "crt1off", 7)) {
1978 } else if (!strncmp(this_opt, "filter:", 7)) {
1979 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1980 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1981 XGIfb_search_crt2type(this_opt + 14);
1982 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
1983 XGIfb_forcecrt1 = (int)simple_strtoul(
1984 this_opt + 10, NULL, 0);
1985 } else if (!strncmp(this_opt, "tvmode:", 7)) {
1986 XGIfb_search_tvstd(this_opt + 7);
1987 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1988 XGIfb_search_tvstd(this_opt + 7);
1989 } else if (!strncmp(this_opt, "dstn", 4)) {
1991 /* TW: DSTN overrules forcecrt2type */
1992 XGIfb_crt2type = DISPTYPE_LCD;
1993 } else if (!strncmp(this_opt, "pdc:", 4)) {
1994 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
1995 if (XGIfb_pdc & ~0x3c) {
1996 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
1999 } else if (!strncmp(this_opt, "noypan", 6)) {
2001 } else if (!strncmp(this_opt, "userom:", 7)) {
2002 XGIfb_userom = (int)simple_strtoul(
2003 this_opt + 7, NULL, 0);
2004 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2005 /* XGIfb_useoem = (int)simple_strtoul(
2006 this_opt + 7, NULL, 0); */
2008 XGIfb_search_mode(this_opt);
2009 /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
2013 /* TW: Panning only with acceleration */
2017 printk("\nxgifb: outa xgifb_setup 3450");
2021 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2023 void __iomem *rom_address;
2024 unsigned char *rom_copy;
2027 rom_address = pci_map_rom(dev, &rom_size);
2028 if (rom_address == NULL)
2031 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2032 if (rom_copy == NULL)
2035 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2036 memcpy_fromio(rom_copy, rom_address, rom_size);
2039 pci_unmap_rom(dev, rom_address);
2043 static int __devinit xgifb_probe(struct pci_dev *pdev,
2044 const struct pci_device_id *ent)
2053 XGIfb_registered = 0;
2055 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2056 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2060 xgi_video_info.chip_id = pdev->device;
2061 pci_read_config_byte(pdev,
2063 &xgi_video_info.revision_id);
2064 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2066 xgi_video_info.pcibus = pdev->bus->number;
2067 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2068 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2069 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2070 xgi_video_info.subsysdevice = pdev->subsystem_device;
2072 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2073 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2074 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2075 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2076 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2077 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2078 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2079 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2081 if (pci_enable_device(pdev)) {
2086 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2088 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2089 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
2091 if (reg1 != 0xa1) { /*I/O error */
2092 printk("\nXGIfb: I/O error!!!");
2097 switch (xgi_video_info.chip_id) {
2098 case PCI_DEVICE_ID_XG_20:
2099 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2100 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
2101 if (CR48&GPIOG_READ)
2102 xgi_video_info.chip = XG21;
2104 xgi_video_info.chip = XG20;
2105 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2107 case PCI_DEVICE_ID_XG_40:
2108 xgi_video_info.chip = XG40;
2109 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2111 case PCI_DEVICE_ID_XG_41:
2112 xgi_video_info.chip = XG41;
2113 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2115 case PCI_DEVICE_ID_XG_42:
2116 xgi_video_info.chip = XG42;
2117 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2119 case PCI_DEVICE_ID_XG_27:
2120 xgi_video_info.chip = XG27;
2121 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2128 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2129 XGIhw_ext.jChipType = xgi_video_info.chip;
2131 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2132 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2133 if (XGIhw_ext.pjVirtualRomBase)
2134 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2135 XGIhw_ext.pjVirtualRomBase);
2137 printk(KERN_INFO "XGIfb: Video ROM not found\n");
2139 XGIhw_ext.pjVirtualRomBase = NULL;
2140 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2142 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2144 if (XGIfb_get_dram_size()) {
2145 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2150 if ((xgifb_mode_idx < 0) ||
2151 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2152 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2154 IND_XGI_PCI_ADDRESS_SET,
2155 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2156 /* Enable 2D accelerator engine */
2157 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2160 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2162 if (!request_mem_region(xgi_video_info.video_base,
2163 xgi_video_info.video_size,
2165 printk("unable request memory size %x",
2166 xgi_video_info.video_size);
2167 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2168 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2173 if (!request_mem_region(xgi_video_info.mmio_base,
2174 xgi_video_info.mmio_size,
2176 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2181 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2182 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2183 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2184 xgi_video_info.mmio_size);
2186 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2187 xgi_video_info.video_base,
2188 xgi_video_info.video_vbase,
2189 xgi_video_info.video_size / 1024);
2191 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2192 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2193 xgi_video_info.mmio_size / 1024);
2194 printk("XGIfb: XGIInitNew() ...");
2195 if (XGIInitNew(&XGIhw_ext))
2200 xgi_video_info.mtrr = (unsigned int) 0;
2202 if ((xgifb_mode_idx < 0) ||
2203 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2204 xgi_video_info.hasVB = HASVB_NONE;
2205 if ((xgi_video_info.chip == XG20) ||
2206 (xgi_video_info.chip == XG27)) {
2207 xgi_video_info.hasVB = HASVB_NONE;
2208 } else if (xgi_video_info.chip == XG21) {
2209 CR38 = xgifb_reg_get(XGICR, 0x38);
2210 if ((CR38&0xE0) == 0xC0) {
2211 xgi_video_info.disp_state = DISPTYPE_LCD;
2212 if (!XGIfb_GetXG21LVDSData()) {
2214 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2215 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2216 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2217 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2221 } else if ((CR38&0xE0) == 0x60) {
2222 xgi_video_info.hasVB = HASVB_CHRONTEL;
2224 xgi_video_info.hasVB = HASVB_NONE;
2227 XGIfb_get_VB_type();
2230 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2232 XGIhw_ext.ulExternalChip = 0;
2234 switch (xgi_video_info.hasVB) {
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: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2244 /* else if (reg >= 0xB0) {
2245 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2246 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2247 printk("XGIfb: XGI301B bridge detected\n");
2250 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2251 printk("XGIfb: XGI301 bridge detected\n");
2255 reg = xgifb_reg_get(XGIPART4, 0x01);
2257 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2258 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2259 } else if (reg >= 0xD0) {
2260 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2261 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2262 } else if (reg >= 0xB0) {
2263 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2265 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2268 XGIhw_ext.ujVBChipID = VB_CHIP_302;
2269 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2273 XGIhw_ext.ulExternalChip = 0x1;
2274 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2276 case HASVB_TRUMPION:
2277 XGIhw_ext.ulExternalChip = 0x2;
2278 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2280 case HASVB_CHRONTEL:
2281 XGIhw_ext.ulExternalChip = 0x4;
2282 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2284 case HASVB_LVDS_CHRONTEL:
2285 XGIhw_ext.ulExternalChip = 0x5;
2286 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2289 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2293 if (xgi_video_info.hasVB != HASVB_NONE)
2296 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2298 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2300 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2303 xgi_video_info.disp_state = DISPMODE_SINGLE |
2307 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2309 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2311 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2315 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2319 XGIfb_detectedpdc = 0;
2321 XGIfb_detectedlcda = 0xff;
2323 /* TW: Try to find about LCDA */
2325 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2326 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2327 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2329 tmp = xgifb_reg_get(XGICR, 0x34);
2331 /* Currently on LCDA?
2332 *(Some BIOSes leave CR38) */
2333 tmp = xgifb_reg_get(XGICR, 0x38);
2334 if ((tmp & 0x03) == 0x03) {
2335 /* XGI_Pr.XGI_UseLCDA = 1; */
2337 /* Currently on LCDA?
2338 *(Some newer BIOSes set D0 in CR35) */
2339 tmp = xgifb_reg_get(XGICR, 0x35);
2341 /* XGI_Pr.XGI_UseLCDA = 1; */
2343 tmp = xgifb_reg_get(XGICR,
2346 tmp = xgifb_reg_get(
2349 /* XGI_Pr.XGI_UseLCDA = 1; */
2358 if (xgifb_mode_idx >= 0)
2359 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2361 if (xgifb_mode_idx < 0) {
2362 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2364 xgifb_mode_idx = DEFAULT_LCDMODE;
2365 if (xgi_video_info.chip == XG21)
2367 XGIfb_GetXG21DefaultLVDSModeIdx();
2370 xgifb_mode_idx = DEFAULT_TVMODE;
2373 xgifb_mode_idx = DEFAULT_MODE;
2378 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2380 /* yilin set default refresh rate */
2381 if (xgi_video_info.refresh_rate == 0)
2382 xgi_video_info.refresh_rate = 60;
2383 if (XGIfb_search_refresh_rate(
2384 xgi_video_info.refresh_rate) == 0) {
2385 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2386 xgi_video_info.refresh_rate = 60;
2389 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2390 xgi_video_info.video_vwidth =
2391 xgi_video_info.video_width =
2392 XGIbios_mode[xgifb_mode_idx].xres;
2393 xgi_video_info.video_vheight =
2394 xgi_video_info.video_height =
2395 XGIbios_mode[xgifb_mode_idx].yres;
2396 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2397 xgi_video_info.video_linelength =
2398 xgi_video_info.video_width *
2399 (xgi_video_info.video_bpp >> 3);
2400 switch (xgi_video_info.video_bpp) {
2402 xgi_video_info.DstColor = 0x0000;
2403 xgi_video_info.XGI310_AccelDepth = 0x00000000;
2404 xgi_video_info.video_cmap_len = 256;
2407 xgi_video_info.DstColor = 0x8000;
2408 xgi_video_info.XGI310_AccelDepth = 0x00010000;
2409 xgi_video_info.video_cmap_len = 16;
2412 xgi_video_info.DstColor = 0xC000;
2413 xgi_video_info.XGI310_AccelDepth = 0x00020000;
2414 xgi_video_info.video_cmap_len = 16;
2417 xgi_video_info.video_cmap_len = 16;
2418 printk(KERN_INFO "XGIfb: Unsupported depth %d",
2419 xgi_video_info.video_bpp);
2423 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2424 xgi_video_info.video_width,
2425 xgi_video_info.video_height,
2426 xgi_video_info.video_bpp,
2427 xgi_video_info.refresh_rate);
2430 default_var.xres_virtual =
2431 xgi_video_info.video_width;
2433 default_var.yres_virtual =
2434 xgi_video_info.video_height;
2435 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2437 XGIfb_bpp_to_var(&default_var);
2439 default_var.pixclock = (u32) (1000000000 /
2440 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2441 XGIfb_mode_no, XGIfb_rate_idx));
2443 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2444 XGIfb_mode_no, XGIfb_rate_idx,
2445 &default_var.left_margin, &default_var.right_margin,
2446 &default_var.upper_margin, &default_var.lower_margin,
2447 &default_var.hsync_len, &default_var.vsync_len,
2448 &default_var.sync, &default_var.vmode)) {
2450 if ((default_var.vmode & FB_VMODE_MASK) ==
2451 FB_VMODE_INTERLACED) {
2452 default_var.yres <<= 1;
2453 default_var.yres_virtual <<= 1;
2454 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2456 default_var.pixclock >>= 1;
2457 default_var.yres >>= 1;
2458 default_var.yres_virtual >>= 1;
2463 fb_info->flags = FBINFO_FLAG_DEFAULT;
2464 fb_info->var = default_var;
2465 fb_info->fix = XGIfb_fix;
2466 fb_info->par = &xgi_video_info;
2467 fb_info->screen_base = xgi_video_info.video_vbase;
2468 fb_info->fbops = &XGIfb_ops;
2469 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2470 fb_info->pseudo_palette = pseudo_palette;
2472 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2475 xgi_video_info.mtrr = mtrr_add(
2476 (unsigned int) xgi_video_info.video_base,
2477 (unsigned int) xgi_video_info.video_size,
2478 MTRR_TYPE_WRCOMB, 1);
2479 if (xgi_video_info.mtrr)
2480 printk(KERN_INFO "XGIfb: Added MTRRs\n");
2483 if (register_framebuffer(fb_info) < 0) {
2488 XGIfb_registered = 1;
2490 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2491 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2500 iounmap(xgi_video_info.mmio_vbase);
2501 iounmap(xgi_video_info.video_vbase);
2502 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2504 release_mem_region(xgi_video_info.video_base,
2505 xgi_video_info.video_size);
2507 vfree(XGIhw_ext.pjVirtualRomBase);
2508 framebuffer_release(fb_info);
2512 /*****************************************************/
2513 /* PCI DEVICE HANDLING */
2514 /*****************************************************/
2516 static void __devexit xgifb_remove(struct pci_dev *pdev)
2518 unregister_framebuffer(fb_info);
2519 iounmap(xgi_video_info.mmio_vbase);
2520 iounmap(xgi_video_info.video_vbase);
2521 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2522 release_mem_region(xgi_video_info.video_base,
2523 xgi_video_info.video_size);
2524 vfree(XGIhw_ext.pjVirtualRomBase);
2525 framebuffer_release(fb_info);
2526 pci_set_drvdata(pdev, NULL);
2529 static struct pci_driver xgifb_driver = {
2531 .id_table = xgifb_pci_table,
2532 .probe = xgifb_probe,
2533 .remove = __devexit_p(xgifb_remove)
2536 XGIINITSTATIC int __init xgifb_init(void)
2538 char *option = NULL;
2540 if (fb_get_options("xgifb", &option))
2542 XGIfb_setup(option);
2544 return pci_register_driver(&xgifb_driver);
2548 module_init(xgifb_init);
2551 /*****************************************************/
2553 /*****************************************************/
2557 static char *mode = NULL;
2558 static int vesa = 0;
2559 static unsigned int rate = 0;
2560 static unsigned int mem = 0;
2561 static char *forcecrt2type = NULL;
2562 static int forcecrt1 = -1;
2563 static int pdc = -1;
2564 static int pdc1 = -1;
2565 static int noypan = -1;
2566 static int userom = -1;
2567 static int useoem = -1;
2568 static char *tvstandard = NULL;
2569 static int nocrt2rate = 0;
2570 static int scalelcd = -1;
2571 static char *specialtiming = NULL;
2572 static int lvdshl = -1;
2573 static int tvxposoffset = 0, tvyposoffset = 0;
2574 #if !defined(__i386__) && !defined(__x86_64__)
2575 static int resetcard = 0;
2576 static int videoram = 0;
2579 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2580 MODULE_LICENSE("GPL");
2581 MODULE_AUTHOR("XGITECH , Others");
2583 module_param(mem, int, 0);
2584 module_param(noypan, int, 0);
2585 module_param(userom, int, 0);
2586 module_param(useoem, int, 0);
2587 module_param(mode, charp, 0);
2588 module_param(vesa, int, 0);
2589 module_param(rate, int, 0);
2590 module_param(forcecrt1, int, 0);
2591 module_param(forcecrt2type, charp, 0);
2592 module_param(scalelcd, int, 0);
2593 module_param(pdc, int, 0);
2594 module_param(pdc1, int, 0);
2595 module_param(specialtiming, charp, 0);
2596 module_param(lvdshl, int, 0);
2597 module_param(tvstandard, charp, 0);
2598 module_param(tvxposoffset, int, 0);
2599 module_param(tvyposoffset, int, 0);
2600 module_param(filter, int, 0);
2601 module_param(nocrt2rate, int, 0);
2602 #if !defined(__i386__) && !defined(__x86_64__)
2603 module_param(resetcard, int, 0);
2604 module_param(videoram, int, 0);
2607 MODULE_PARM_DESC(noypan,
2608 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2609 "will be performed by redrawing the screen. (default: 0)\n");
2611 MODULE_PARM_DESC(mode,
2612 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2613 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2614 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2615 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2617 MODULE_PARM_DESC(vesa,
2618 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2619 "0x117 (default: 0x0103)\n");
2621 MODULE_PARM_DESC(rate,
2622 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2623 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2624 "will be ignored (default: 60)\n");
2626 MODULE_PARM_DESC(forcecrt1,
2627 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2628 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2629 "0=CRT1 OFF) (default: [autodetected])\n");
2631 MODULE_PARM_DESC(forcecrt2type,
2632 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2633 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2634 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2635 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2636 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2637 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2638 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2639 "depends on the very hardware in use. (default: [autodetected])\n");
2641 MODULE_PARM_DESC(scalelcd,
2642 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2643 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2644 "show black bars around the image, TMDS panels will probably do the scaling\n"
2645 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2647 MODULE_PARM_DESC(pdc,
2648 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2649 "should detect this correctly in most cases; however, sometimes this is not\n"
2650 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2651 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2652 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2653 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2655 MODULE_PARM_DESC(pdc1,
2656 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2657 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2658 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2659 "implemented yet.\n");
2661 MODULE_PARM_DESC(specialtiming,
2662 "\nPlease refer to documentation for more information on this option.\n");
2664 MODULE_PARM_DESC(lvdshl,
2665 "\nPlease refer to documentation for more information on this option.\n");
2667 MODULE_PARM_DESC(tvstandard,
2668 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2669 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2671 MODULE_PARM_DESC(tvxposoffset,
2672 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2675 MODULE_PARM_DESC(tvyposoffset,
2676 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2679 MODULE_PARM_DESC(filter,
2680 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2681 "(Possible values 0-7, default: [no filter])\n");
2683 MODULE_PARM_DESC(nocrt2rate,
2684 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2685 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2687 static int __init xgifb_init_module(void)
2689 printk("\nXGIfb_init_module");
2691 XGIfb_search_mode(mode);
2692 else if (vesa != -1)
2693 XGIfb_search_vesamode(vesa);
2695 return xgifb_init();
2698 static void __exit xgifb_remove_module(void)
2700 pci_unregister_driver(&xgifb_driver);
2701 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2704 module_init(xgifb_init_module);
2705 module_exit(xgifb_remove_module);
2707 #endif /* /MODULE */