Merge remote branch 'alsa/devel' into topic/misc
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / xgifb / XGI_main_26.c
1 /*
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.
5 */
6
7 //#include <linux/config.h>
8 #include <linux/version.h>
9 #include <linux/module.h>
10 #include <linux/moduleparam.h>
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/mm.h>
16 #include <linux/tty.h>
17 #include <linux/slab.h>
18 #include <linux/delay.h>
19 #include <linux/fb.h>
20 #include <linux/console.h>
21 #include <linux/selection.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/pci.h>
25 #include <linux/vmalloc.h>
26 #include <linux/vt_kern.h>
27 #include <linux/capability.h>
28 #include <linux/fs.h>
29 #include <linux/types.h>
30 #include <linux/proc_fs.h>
31
32
33 #ifndef XGIFB_PAN
34 #define XGIFB_PAN
35 #endif
36
37 #include <asm/io.h>
38 #ifdef CONFIG_MTRR
39 #include <asm/mtrr.h>
40 #endif
41
42 #include "XGIfb.h"
43 #include "vgatypes.h"
44 #include "XGI_main.h"
45 #include "vb_util.h"
46
47
48 #define Index_CR_GPIO_Reg1 0x48
49 #define Index_CR_GPIO_Reg2 0x49
50 #define Index_CR_GPIO_Reg3 0x4a
51
52 #define GPIOG_EN (1<<6)
53 #define GPIOG_WRITE (1<<6)
54 #define GPIOG_READ (1<<1)
55 int XGIfb_GetXG21DefaultLVDSModeIdx(void);
56
57 /* -------------------- Macro definitions ---------------------------- */
58
59 #undef XGIFBDEBUG
60
61 #ifdef XGIFBDEBUG
62 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63 #else
64 #define DPRINTK(fmt, args...)
65 #endif
66
67 #ifdef XGIFBDEBUG
68 static void dumpVGAReg(void)
69 {
70 u8 i,reg;
71
72 outXGIIDXREG(XGISR, 0x05, 0x86);
73 /*
74 outXGIIDXREG(XGISR, 0x08, 0x4f);
75 outXGIIDXREG(XGISR, 0x0f, 0x20);
76 outXGIIDXREG(XGISR, 0x11, 0x4f);
77 outXGIIDXREG(XGISR, 0x13, 0x45);
78 outXGIIDXREG(XGISR, 0x14, 0x51);
79 outXGIIDXREG(XGISR, 0x1e, 0x41);
80 outXGIIDXREG(XGISR, 0x1f, 0x0);
81 outXGIIDXREG(XGISR, 0x20, 0xa1);
82 outXGIIDXREG(XGISR, 0x22, 0xfb);
83 outXGIIDXREG(XGISR, 0x26, 0x22);
84 outXGIIDXREG(XGISR, 0x3e, 0x07);
85 */
86
87 //outXGIIDXREG(XGICR, 0x19, 0x00);
88 //outXGIIDXREG(XGICR, 0x1a, 0x3C);
89 //outXGIIDXREG(XGICR, 0x22, 0xff);
90 //outXGIIDXREG(XGICR, 0x3D, 0x10);
91
92 //outXGIIDXREG(XGICR, 0x4a, 0xf3);
93
94 //outXGIIDXREG(XGICR, 0x57, 0x0);
95 //outXGIIDXREG(XGICR, 0x7a, 0x2c);
96
97 //outXGIIDXREG(XGICR, 0x82, 0xcc);
98 //outXGIIDXREG(XGICR, 0x8c, 0x0);
99 /*
100 outXGIIDXREG(XGICR, 0x99, 0x1);
101 outXGIIDXREG(XGICR, 0x41, 0x40);
102 */
103
104 for(i=0; i < 0x4f; i++)
105 {
106 inXGIIDXREG(XGISR, i, reg);
107 printk("\no 3c4 %x",i);
108 printk("\ni 3c5 => %x",reg);
109 }
110
111 for(i=0; i < 0xF0; i++)
112 {
113 inXGIIDXREG(XGICR, i, reg);
114 printk("\no 3d4 %x",i);
115 printk("\ni 3d5 => %x",reg);
116 }
117 /*
118
119 outXGIIDXREG(XGIPART1,0x2F,1);
120 for(i=1; i < 0x50; i++)
121 {
122 inXGIIDXREG(XGIPART1, i, reg);
123 printk("\no d004 %x",i);
124 printk("\ni d005 => %x",reg);
125 }
126
127 for(i=0; i < 0x50; i++)
128 {
129 inXGIIDXREG(XGIPART2, i, reg);
130 printk("\no d010 %x",i);
131 printk("\ni d011 => %x",reg);
132 }
133 for(i=0; i < 0x50; i++)
134 {
135 inXGIIDXREG(XGIPART3, i, reg);
136 printk("\no d012 %x",i);
137 printk("\ni d013 => %x",reg);
138 }
139 for(i=0; i < 0x50; i++)
140 {
141 inXGIIDXREG(XGIPART4, i, reg);
142 printk("\no d014 %x",i);
143 printk("\ni d015 => %x",reg);
144 }
145 */
146 }
147 #else
148 static inline void dumpVGAReg(void) {}
149 #endif
150
151 /* data for XGI components */
152 struct video_info xgi_video_info;
153
154
155 #if 1
156 #define DEBUGPRN(x)
157 #else
158 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
159 #endif
160
161
162 /* --------------- Hardware Access Routines -------------------------- */
163
164 int
165 XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
166 unsigned char modeno, unsigned char rateindex)
167 {
168 unsigned short ModeNo = modeno;
169 unsigned short ModeIdIndex = 0, ClockIndex = 0;
170 unsigned short RefreshRateTableIndex = 0;
171
172 /*unsigned long temp = 0;*/
173 int Clock;
174 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
175 InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
176
177 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, XGI_Pr ) ;
178
179 /*
180 temp = XGI_SearchModeID( ModeNo , &ModeIdIndex, XGI_Pr ) ;
181 if(!temp) {
182 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
183 return 65000;
184 }
185
186 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
187 RefreshRateTableIndex += (rateindex - 1);
188
189 */
190 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
191 if(HwDeviceExtension->jChipType < XGI_315H) {
192 ClockIndex &= 0x3F;
193 }
194 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000 ;
195
196 return(Clock);
197 }
198
199 int
200 XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
201 unsigned char modeno, unsigned char rateindex,
202 u32 *left_margin, u32 *right_margin,
203 u32 *upper_margin, u32 *lower_margin,
204 u32 *hsync_len, u32 *vsync_len,
205 u32 *sync, u32 *vmode)
206 {
207 unsigned short ModeNo = modeno;
208 unsigned short ModeIdIndex = 0, index = 0;
209 unsigned short RefreshRateTableIndex = 0;
210
211 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
212 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
213 unsigned char sr_data, cr_data, cr_data2;
214 unsigned long cr_data3;
215 int A, B, C, D, E, F, temp, j;
216 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
217 InitTo330Pointer( HwDeviceExtension->jChipType, XGI_Pr ) ;
218 RefreshRateTableIndex = XGI_GetRatePtrCRT2( HwDeviceExtension, ModeNo , ModeIdIndex, XGI_Pr ) ;
219 /*
220 temp = XGI_SearchModeID( ModeNo, &ModeIdIndex, XGI_Pr);
221 if(!temp) return 0;
222
223 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
224 RefreshRateTableIndex += (rateindex - 1);
225 */
226 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
227
228 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
229
230 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
231
232 /* Horizontal total */
233 HT = (cr_data & 0xff) |
234 ((unsigned short) (sr_data & 0x03) << 8);
235 A = HT + 5;
236
237 /*cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
238
239 Horizontal display enable end
240 HDE = (cr_data & 0xff) |
241 ((unsigned short) (sr_data & 0x0C) << 6);*/
242 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) -1;
243 E = HDE + 1;
244
245 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
246
247 /* Horizontal retrace (=sync) start */
248 HRS = (cr_data & 0xff) |
249 ((unsigned short) (sr_data & 0xC0) << 2);
250 F = HRS - E - 3;
251
252 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
253
254 /* Horizontal blank start */
255 HBS = (cr_data & 0xff) |
256 ((unsigned short) (sr_data & 0x30) << 4);
257
258 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
259
260 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
261
262 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
263
264 /* Horizontal blank end */
265 HBE = (cr_data & 0x1f) |
266 ((unsigned short) (cr_data2 & 0x80) >> 2) |
267 ((unsigned short) (sr_data & 0x03) << 6);
268
269 /* Horizontal retrace (=sync) end */
270 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
271
272 temp = HBE - ((E - 1) & 255);
273 B = (temp > 0) ? temp : (temp + 256);
274
275 temp = HRE - ((E + F + 3) & 63);
276 C = (temp > 0) ? temp : (temp + 64);
277
278 D = B - F - C;
279
280 *left_margin = D * 8;
281 *right_margin = F * 8;
282 *hsync_len = C * 8;
283
284 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
285
286 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
287
288 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
289
290 /* Vertical total */
291 VT = (cr_data & 0xFF) |
292 ((unsigned short) (cr_data2 & 0x01) << 8) |
293 ((unsigned short)(cr_data2 & 0x20) << 4) |
294 ((unsigned short) (sr_data & 0x01) << 10);
295 A = VT + 2;
296
297 //cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
298
299 /* Vertical display enable end */
300 /* VDE = (cr_data & 0xff) |
301 ((unsigned short) (cr_data2 & 0x02) << 7) |
302 ((unsigned short) (cr_data2 & 0x40) << 3) |
303 ((unsigned short) (sr_data & 0x02) << 9); */
304 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes -1;
305 E = VDE + 1;
306
307 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
308
309 /* Vertical retrace (=sync) start */
310 VRS = (cr_data & 0xff) |
311 ((unsigned short) (cr_data2 & 0x04) << 6) |
312 ((unsigned short) (cr_data2 & 0x80) << 2) |
313 ((unsigned short) (sr_data & 0x08) << 7);
314 F = VRS + 1 - E;
315
316 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
317
318 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
319
320 /* Vertical blank start */
321 VBS = (cr_data & 0xff) |
322 ((unsigned short) (cr_data2 & 0x08) << 5) |
323 ((unsigned short) (cr_data3 & 0x20) << 4) |
324 ((unsigned short) (sr_data & 0x04) << 8);
325
326 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
327
328 /* Vertical blank end */
329 VBE = (cr_data & 0xff) |
330 ((unsigned short) (sr_data & 0x10) << 4);
331 temp = VBE - ((E - 1) & 511);
332 B = (temp > 0) ? temp : (temp + 512);
333
334 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
335
336 /* Vertical retrace (=sync) end */
337 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
338 temp = VRE - ((E + F - 1) & 31);
339 C = (temp > 0) ? temp : (temp + 32);
340
341 D = B - F - C;
342
343 *upper_margin = D;
344 *lower_margin = F;
345 *vsync_len = C;
346
347 if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
348 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
349 else
350 *sync |= FB_SYNC_VERT_HIGH_ACT;
351
352 if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
353 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
354 else
355 *sync |= FB_SYNC_HOR_HIGH_ACT;
356
357 *vmode = FB_VMODE_NONINTERLACED;
358 if(XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
359 *vmode = FB_VMODE_INTERLACED;
360 else {
361 j = 0;
362 while(XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
363 if(XGI_Pr->EModeIDTable[j].Ext_ModeID ==
364 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
365 if(XGI_Pr->EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) {
366 *vmode = FB_VMODE_DOUBLE;
367 }
368 break;
369 }
370 j++;
371 }
372 }
373
374 return 1;
375 }
376
377
378
379
380 void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
381 {
382 XGI_Pr->RelIO = BaseAddr;
383 XGI_Pr->P3c4 = BaseAddr + 0x14;
384 XGI_Pr->P3d4 = BaseAddr + 0x24;
385 XGI_Pr->P3c0 = BaseAddr + 0x10;
386 XGI_Pr->P3ce = BaseAddr + 0x1e;
387 XGI_Pr->P3c2 = BaseAddr + 0x12;
388 XGI_Pr->P3ca = BaseAddr + 0x1a;
389 XGI_Pr->P3c6 = BaseAddr + 0x16;
390 XGI_Pr->P3c7 = BaseAddr + 0x17;
391 XGI_Pr->P3c8 = BaseAddr + 0x18;
392 XGI_Pr->P3c9 = BaseAddr + 0x19;
393 XGI_Pr->P3da = BaseAddr + 0x2A;
394 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
395 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
396 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
397 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
398 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14+2; /* 301 palette address port registers */
399
400 }
401
402
403 void XGIfb_set_reg4(u16 port, unsigned long data)
404 {
405 outl((u32) (data & 0xffffffff), port);
406 }
407
408 u32 XGIfb_get_reg3(u16 port)
409 {
410 u32 data;
411
412 data = inl(port);
413 return (data);
414 }
415
416 /* ------------ Interface for init & mode switching code ------------- */
417
418 unsigned char
419 XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
420 unsigned long offset, unsigned long set, unsigned long *value)
421 {
422 static struct pci_dev *pdev = NULL;
423 static unsigned char init = 0, valid_pdev = 0;
424
425 if (!set)
426 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
427 else
428 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
429
430 if (!init) {
431 init = 1;
432 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id, pdev);
433 if (pdev) {
434 valid_pdev = 1;
435 pci_dev_put(pdev);
436 }
437 }
438
439 if (!valid_pdev) {
440 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
441 xgi_video_info.chip_id);
442 return 0;
443 }
444
445 if (set == 0)
446 pci_read_config_dword(pdev, offset, (u32 *)value);
447 else
448 pci_write_config_dword(pdev, offset, (u32)(*value));
449
450 return 1;
451 }
452
453 /*unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
454 unsigned long offset, unsigned long set, unsigned long *value)
455 {
456 static struct pci_dev *pdev = NULL;
457 static unsigned char init = 0, valid_pdev = 0;
458 u16 nbridge_id = 0;
459
460 if (!init) {
461 init = 1;
462 switch (xgi_video_info.chip) {
463 case XGI_540:
464 nbridge_id = PCI_DEVICE_ID_XG_540;
465 break;
466 case XGI_630:
467 nbridge_id = PCI_DEVICE_ID_XG_630;
468 break;
469 case XGI_730:
470 nbridge_id = PCI_DEVICE_ID_XG_730;
471 break;
472 case XGI_550:
473 nbridge_id = PCI_DEVICE_ID_XG_550;
474 break;
475 case XGI_650:
476 nbridge_id = PCI_DEVICE_ID_XG_650;
477 break;
478 case XGI_740:
479 nbridge_id = PCI_DEVICE_ID_XG_740;
480 break;
481 default:
482 nbridge_id = 0;
483 break;
484 }
485
486 pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
487 if (pdev)
488 valid_pdev = 1;
489 }
490
491 if (!valid_pdev) {
492 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
493 nbridge_id);
494 return 0;
495 }
496
497 if (set == 0)
498 pci_read_config_dword(pdev, offset, (u32 *)value);
499 else
500 pci_write_config_dword(pdev, offset, (u32)(*value));
501
502 return 1;
503 }
504 */
505 /* ------------------ Internal helper routines ----------------- */
506
507 static void XGIfb_search_mode(const char *name)
508 {
509 int i = 0, j = 0, l;
510
511 if(name == NULL) {
512 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
513 xgifb_mode_idx = DEFAULT_MODE;
514 if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
515 {
516 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
517 }
518 return;
519 }
520
521
522 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
523 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
524 xgifb_mode_idx = DEFAULT_MODE;
525 if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
526 {
527 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
528 }
529 return;
530 }
531
532 while(XGIbios_mode[i].mode_no != 0) {
533 l = min(strlen(name), strlen(XGIbios_mode[i].name));
534 if (!strncmp(name, XGIbios_mode[i].name, l)) {
535 xgifb_mode_idx = i;
536 j = 1;
537 break;
538 }
539 i++;
540 }
541 if(!j) printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
542 }
543
544 static void XGIfb_search_vesamode(unsigned int vesamode)
545 {
546 int i = 0, j = 0;
547
548 if(vesamode == 0) {
549
550 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
551 xgifb_mode_idx = DEFAULT_MODE;
552 if ((xgi_video_info.chip == XG21) && ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD))
553 {
554 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
555 }
556 return;
557 }
558
559 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
560
561 while(XGIbios_mode[i].mode_no != 0) {
562 if( (XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
563 (XGIbios_mode[i].vesa_mode_no_2 == vesamode) ) {
564 xgifb_mode_idx = i;
565 j = 1;
566 break;
567 }
568 i++;
569 }
570 if(!j) printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
571 }
572
573 int XGIfb_GetXG21LVDSData(void)
574 {
575 u8 tmp;
576 unsigned char *pData;
577 int i,j,k;
578
579 inXGIIDXREG(XGISR,0x1e,tmp);
580 outXGIIDXREG(XGISR, 0x1e, tmp|4);
581
582 pData = xgi_video_info.mmio_vbase+0x20000;
583 if ((pData[0x0]==0x55) && (pData[0x1]==0xAA) && (pData[0x65] & 0x1))
584 {
585 i = pData[ 0x316 ] | ( pData[ 0x317 ] << 8 );
586 j = pData[ i-1 ] ;
587 if ( j == 0xff )
588 {
589 j = 1;
590 }
591 k = 0;
592 do
593 {
594 XGI21_LCDCapList[k].LVDS_Capability = pData[ i ] | ( pData[ i + 1 ] << 8 );
595 XGI21_LCDCapList[k].LVDSHT = pData[ i + 2 ] | ( pData[ i + 3 ] << 8 ) ;
596 XGI21_LCDCapList[k].LVDSVT = pData[ i + 4 ] | ( pData[ i + 5 ] << 8 );
597 XGI21_LCDCapList[k].LVDSHDE = pData[ i + 6 ] | ( pData[ i + 7 ] << 8 );
598 XGI21_LCDCapList[k].LVDSVDE = pData[ i + 8 ] | ( pData[ i + 9 ] << 8 );
599 XGI21_LCDCapList[k].LVDSHFP = pData[ i + 10 ] | ( pData[ i + 11 ] << 8 );
600 XGI21_LCDCapList[k].LVDSVFP = pData[ i + 12 ] | ( pData[ i + 13 ] << 8 );
601 XGI21_LCDCapList[k].LVDSHSYNC = pData[ i + 14 ] | ( pData[ i + 15 ] << 8 );
602 XGI21_LCDCapList[k].LVDSVSYNC = pData[ i + 16 ] | ( pData[ i + 17 ] << 8 );
603 XGI21_LCDCapList[k].VCLKData1 = pData[ i + 18 ] ;
604 XGI21_LCDCapList[k].VCLKData2 = pData[ i + 19 ] ;
605 XGI21_LCDCapList[k].PSC_S1 = pData[ i + 20 ] ;
606 XGI21_LCDCapList[k].PSC_S2 = pData[ i + 21 ] ;
607 XGI21_LCDCapList[k].PSC_S3 = pData[ i + 22 ] ;
608 XGI21_LCDCapList[k].PSC_S4 = pData[ i + 23 ] ;
609 XGI21_LCDCapList[k].PSC_S5 = pData[ i + 24 ] ;
610 i += 25;
611 j--;
612 k++;
613 } while ((j > 0) &&
614 (k < (sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct))));
615 return 1;
616 }
617 return 0;
618 }
619
620 int XGIfb_GetXG21DefaultLVDSModeIdx(void)
621 {
622
623 int found_mode = 0;
624 int XGIfb_mode_idx = 0;
625
626 found_mode = 0;
627 while( (XGIbios_mode[XGIfb_mode_idx].mode_no != 0) &&
628 (XGIbios_mode[XGIfb_mode_idx].xres <= XGI21_LCDCapList[0].LVDSHDE) )
629 {
630 if( (XGIbios_mode[XGIfb_mode_idx].xres == XGI21_LCDCapList[0].LVDSHDE) &&
631 (XGIbios_mode[XGIfb_mode_idx].yres == XGI21_LCDCapList[0].LVDSVDE) &&
632 (XGIbios_mode[XGIfb_mode_idx].bpp == 8))
633 {
634 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
635 found_mode = 1;
636 break;
637 }
638 XGIfb_mode_idx++;
639 }
640 if (!found_mode)
641 XGIfb_mode_idx = 0;
642
643 return (XGIfb_mode_idx);
644 }
645
646
647 static int XGIfb_validate_mode(int myindex)
648 {
649 u16 xres, yres;
650
651 if (xgi_video_info.chip == XG21)
652 {
653 if ((xgi_video_info.disp_state & DISPTYPE_DISP2) == DISPTYPE_LCD)
654 {
655 xres = XGI21_LCDCapList[0].LVDSHDE;
656 yres = XGI21_LCDCapList[0].LVDSVDE;
657 if(XGIbios_mode[myindex].xres > xres)
658 return(-1);
659 if(XGIbios_mode[myindex].yres > yres)
660 return(-1);
661 if ((XGIbios_mode[myindex].xres < xres) && (XGIbios_mode[myindex].yres < yres) )
662 {
663 if (XGIbios_mode[myindex].bpp > 8)
664 return(-1);
665 }
666
667 }
668 return(myindex);
669
670 }
671
672 /* FIXME: for now, all is valid on XG27 */
673 if (xgi_video_info.chip == XG27)
674 return(myindex);
675
676 if(!(XGIbios_mode[myindex].chipset & MD_XGI315))
677 return(-1);
678
679 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
680 case DISPTYPE_LCD:
681 switch (XGIhw_ext.ulCRT2LCDType) {
682 case LCD_640x480:
683 xres = 640; yres = 480; break;
684 case LCD_800x600:
685 xres = 800; yres = 600; break;
686 case LCD_1024x600:
687 xres = 1024; yres = 600; break;
688 case LCD_1024x768:
689 xres = 1024; yres = 768; break;
690 case LCD_1152x768:
691 xres = 1152; yres = 768; break;
692 case LCD_1280x960:
693 xres = 1280; yres = 960; break;
694 case LCD_1280x768:
695 xres = 1280; yres = 768; break;
696 case LCD_1280x1024:
697 xres = 1280; yres = 1024; break;
698 case LCD_1400x1050:
699 xres = 1400; yres = 1050; break;
700 case LCD_1600x1200:
701 xres = 1600; yres = 1200; break;
702 // case LCD_320x480: // TW: FSTN
703 // xres = 320; yres = 480; break;
704 default:
705 xres = 0; yres = 0; break;
706 }
707 if(XGIbios_mode[myindex].xres > xres) {
708 return(-1);
709 }
710 if(XGIbios_mode[myindex].yres > yres) {
711 return(-1);
712 }
713 if((XGIhw_ext.ulExternalChip == 0x01) || // LVDS
714 (XGIhw_ext.ulExternalChip == 0x05)) // LVDS+Chrontel
715 {
716 switch (XGIbios_mode[myindex].xres) {
717 case 512:
718 if(XGIbios_mode[myindex].yres != 512) return -1;
719 if(XGIhw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
720 break;
721 case 640:
722 if((XGIbios_mode[myindex].yres != 400) &&
723 (XGIbios_mode[myindex].yres != 480))
724 return -1;
725 break;
726 case 800:
727 if(XGIbios_mode[myindex].yres != 600) return -1;
728 break;
729 case 1024:
730 if((XGIbios_mode[myindex].yres != 600) &&
731 (XGIbios_mode[myindex].yres != 768))
732 return -1;
733 if((XGIbios_mode[myindex].yres == 600) &&
734 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
735 return -1;
736 break;
737 case 1152:
738 if((XGIbios_mode[myindex].yres) != 768) return -1;
739 if(XGIhw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
740 break;
741 case 1280:
742 if((XGIbios_mode[myindex].yres != 768) &&
743 (XGIbios_mode[myindex].yres != 1024))
744 return -1;
745 if((XGIbios_mode[myindex].yres == 768) &&
746 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
747 return -1;
748 break;
749 case 1400:
750 if(XGIbios_mode[myindex].yres != 1050) return -1;
751 break;
752 case 1600:
753 if(XGIbios_mode[myindex].yres != 1200) return -1;
754 break;
755 default:
756 return -1;
757 }
758 } else {
759 switch (XGIbios_mode[myindex].xres) {
760 case 512:
761 if(XGIbios_mode[myindex].yres != 512) return -1;
762 break;
763 case 640:
764 if((XGIbios_mode[myindex].yres != 400) &&
765 (XGIbios_mode[myindex].yres != 480))
766 return -1;
767 break;
768 case 800:
769 if(XGIbios_mode[myindex].yres != 600) return -1;
770 break;
771 case 1024:
772 if(XGIbios_mode[myindex].yres != 768) return -1;
773 break;
774 case 1280:
775 if((XGIbios_mode[myindex].yres != 960) &&
776 (XGIbios_mode[myindex].yres != 1024))
777 return -1;
778 if(XGIbios_mode[myindex].yres == 960) {
779 if(XGIhw_ext.ulCRT2LCDType == LCD_1400x1050)
780 return -1;
781 }
782 break;
783 case 1400:
784 if(XGIbios_mode[myindex].yres != 1050) return -1;
785 break;
786 case 1600:
787 if(XGIbios_mode[myindex].yres != 1200) return -1;
788 break;
789 default:
790 return -1;
791 }
792 }
793 break;
794 case DISPTYPE_TV:
795 switch (XGIbios_mode[myindex].xres) {
796 case 512:
797 case 640:
798 case 800:
799 break;
800 case 720:
801 if (xgi_video_info.TV_type == TVMODE_NTSC) {
802 if (XGIbios_mode[myindex].yres != 480) {
803 return(-1);
804 }
805 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
806 if (XGIbios_mode[myindex].yres != 576) {
807 return(-1);
808 }
809 }
810 // TW: LVDS/CHRONTEL does not support 720
811 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
812 xgi_video_info.hasVB == HASVB_CHRONTEL) {
813 return(-1);
814 }
815 break;
816 case 1024:
817 if (xgi_video_info.TV_type == TVMODE_NTSC) {
818 if(XGIbios_mode[myindex].bpp == 32) {
819 return(-1);
820 }
821 }
822 // TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)
823 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
824 xgi_video_info.hasVB == HASVB_CHRONTEL) {
825 if(xgi_video_info.chip < XGI_315H) {
826 return(-1);
827 }
828 }
829 break;
830 default:
831 return(-1);
832 }
833 break;
834 case DISPTYPE_CRT2:
835 if(XGIbios_mode[myindex].xres > 1280) return -1;
836 break;
837 }
838 return(myindex);
839
840 }
841
842 static void XGIfb_search_crt2type(const char *name)
843 {
844 int i = 0;
845
846 if(name == NULL)
847 return;
848
849 while(XGI_crt2type[i].type_no != -1) {
850 if (!strcmp(name, XGI_crt2type[i].name)) {
851 XGIfb_crt2type = XGI_crt2type[i].type_no;
852 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
853 break;
854 }
855 i++;
856 }
857 if(XGIfb_crt2type < 0)
858 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
859 }
860
861 static void XGIfb_search_queuemode(const char *name)
862 {
863 int i = 0;
864
865 if(name == NULL)
866 return;
867
868 while (XGI_queuemode[i].type_no != -1) {
869 if (!strcmp(name, XGI_queuemode[i].name)) {
870 XGIfb_queuemode = XGI_queuemode[i].type_no;
871 break;
872 }
873 i++;
874 }
875 if (XGIfb_queuemode < 0)
876 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
877 }
878
879 static u8 XGIfb_search_refresh_rate(unsigned int rate)
880 {
881 u16 xres, yres;
882 int i = 0;
883
884 xres = XGIbios_mode[xgifb_mode_idx].xres;
885 yres = XGIbios_mode[xgifb_mode_idx].yres;
886
887 XGIfb_rate_idx = 0;
888 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
889 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres == yres)) {
890 if (XGIfb_vrate[i].refresh == rate) {
891 XGIfb_rate_idx = XGIfb_vrate[i].idx;
892 break;
893 } else if (XGIfb_vrate[i].refresh > rate) {
894 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
895 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
896 rate, XGIfb_vrate[i].refresh);
897 XGIfb_rate_idx = XGIfb_vrate[i].idx;
898 xgi_video_info.refresh_rate = XGIfb_vrate[i].refresh;
899 } else if (((rate - XGIfb_vrate[i-1].refresh) <= 2)
900 && (XGIfb_vrate[i].idx != 1)) {
901 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
902 rate, XGIfb_vrate[i-1].refresh);
903 XGIfb_rate_idx = XGIfb_vrate[i-1].idx;
904 xgi_video_info.refresh_rate = XGIfb_vrate[i-1].refresh;
905 }
906 break;
907 } else if((rate - XGIfb_vrate[i].refresh) <= 2) {
908 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
909 rate, XGIfb_vrate[i].refresh);
910 XGIfb_rate_idx = XGIfb_vrate[i].idx;
911 break;
912 }
913 }
914 i++;
915 }
916 if (XGIfb_rate_idx > 0) {
917 return XGIfb_rate_idx;
918 } else {
919 printk(KERN_INFO
920 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
921 return 0;
922 }
923 }
924
925 static void XGIfb_search_tvstd(const char *name)
926 {
927 int i = 0;
928
929 if(name == NULL)
930 return;
931
932 while (XGI_tvtype[i].type_no != -1) {
933 if (!strcmp(name, XGI_tvtype[i].name)) {
934 XGIfb_tvmode = XGI_tvtype[i].type_no;
935 break;
936 }
937 i++;
938 }
939 }
940
941 static unsigned char XGIfb_bridgeisslave(void)
942 {
943 unsigned char usScratchP1_00;
944
945 if (xgi_video_info.hasVB == HASVB_NONE)
946 return 0;
947
948 inXGIIDXREG(XGIPART1,0x00,usScratchP1_00);
949 if ((usScratchP1_00 & 0x50) == 0x10)
950 return 1;
951 else
952 return 0;
953 }
954
955 static unsigned char XGIfbcheckvretracecrt1(void)
956 {
957 unsigned char temp;
958
959 inXGIIDXREG(XGICR,0x17,temp);
960 if (!(temp & 0x80))
961 return 0;
962
963
964 inXGIIDXREG(XGISR,0x1f,temp);
965 if (temp & 0xc0)
966 return 0;
967
968 if (inXGIREG(XGIINPSTAT) & 0x08)
969 return 1;
970 else
971 return 0;
972 }
973
974 static unsigned char XGIfbcheckvretracecrt2(void)
975 {
976 unsigned char temp;
977 if (xgi_video_info.hasVB == HASVB_NONE)
978 return 0;
979 inXGIIDXREG(XGIPART1, 0x30, temp);
980 if (temp & 0x02)
981 return 0;
982 else
983 return 1;
984 }
985
986 static unsigned char XGIfb_CheckVBRetrace(void)
987 {
988 if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
989 if(XGIfb_bridgeisslave()) {
990 return(XGIfbcheckvretracecrt1());
991 } else {
992 return(XGIfbcheckvretracecrt2());
993 }
994 }
995 return(XGIfbcheckvretracecrt1());
996 }
997
998 /* ----------- FBDev related routines for all series ----------- */
999
1000
1001 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1002 {
1003 switch(var->bits_per_pixel) {
1004 case 8:
1005 var->red.offset = var->green.offset = var->blue.offset = 0;
1006 var->red.length = var->green.length = var->blue.length = 6;
1007 xgi_video_info.video_cmap_len = 256;
1008 break;
1009 case 16:
1010 var->red.offset = 11;
1011 var->red.length = 5;
1012 var->green.offset = 5;
1013 var->green.length = 6;
1014 var->blue.offset = 0;
1015 var->blue.length = 5;
1016 var->transp.offset = 0;
1017 var->transp.length = 0;
1018 xgi_video_info.video_cmap_len = 16;
1019 break;
1020 case 32:
1021 var->red.offset = 16;
1022 var->red.length = 8;
1023 var->green.offset = 8;
1024 var->green.length = 8;
1025 var->blue.offset = 0;
1026 var->blue.length = 8;
1027 var->transp.offset = 24;
1028 var->transp.length = 8;
1029 xgi_video_info.video_cmap_len = 16;
1030 break;
1031 }
1032 }
1033
1034
1035
1036 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
1037 struct fb_info *info)
1038 {
1039
1040 unsigned int htotal = var->left_margin + var->xres +
1041 var->right_margin + var->hsync_len;
1042 unsigned int vtotal = var->upper_margin + var->yres +
1043 var->lower_margin + var->vsync_len;
1044 #if defined(__powerpc__)
1045 u8 sr_data, cr_data;
1046 #endif
1047 unsigned int drate = 0, hrate = 0;
1048 int found_mode = 0;
1049 int old_mode;
1050 // unsigned char reg,reg1;
1051
1052 DEBUGPRN("Inside do_set_var");
1053 // 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);
1054
1055 info->var.xres_virtual = var->xres_virtual;
1056 info->var.yres_virtual = var->yres_virtual;
1057 info->var.bits_per_pixel = var->bits_per_pixel;
1058
1059 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1060 vtotal <<= 1;
1061 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1062 vtotal <<= 2;
1063 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
1064 {
1065 // vtotal <<= 1;
1066 // var->yres <<= 1;
1067 }
1068
1069 if(!htotal || !vtotal) {
1070 DPRINTK("XGIfb: Invalid 'var' information\n");
1071 return -EINVAL;
1072 }
1073 printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1074 var->pixclock,htotal,vtotal);
1075
1076
1077
1078 if(var->pixclock && htotal && vtotal) {
1079 drate = 1000000000 / var->pixclock;
1080 hrate = (drate * 1000) / htotal;
1081 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1082 } else {
1083 xgi_video_info.refresh_rate = 60;
1084 }
1085
1086 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1087 var->xres,var->yres,var->bits_per_pixel,xgi_video_info.refresh_rate);
1088
1089 old_mode = xgifb_mode_idx;
1090 xgifb_mode_idx = 0;
1091
1092 while( (XGIbios_mode[xgifb_mode_idx].mode_no != 0) &&
1093 (XGIbios_mode[xgifb_mode_idx].xres <= var->xres) ) {
1094 if( (XGIbios_mode[xgifb_mode_idx].xres == var->xres) &&
1095 (XGIbios_mode[xgifb_mode_idx].yres == var->yres) &&
1096 (XGIbios_mode[xgifb_mode_idx].bpp == var->bits_per_pixel)) {
1097 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1098 found_mode = 1;
1099 break;
1100 }
1101 xgifb_mode_idx++;
1102 }
1103
1104 if(found_mode)
1105 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1106 else
1107 xgifb_mode_idx = -1;
1108
1109 if(xgifb_mode_idx < 0) {
1110 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1111 var->yres, var->bits_per_pixel);
1112 xgifb_mode_idx = old_mode;
1113 return -EINVAL;
1114 }
1115
1116 if(XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1117 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1118 xgi_video_info.refresh_rate = 60;
1119 }
1120
1121 if(isactive) {
1122
1123
1124 XGIfb_pre_setmode();
1125 if(XGISetModeNew( &XGIhw_ext, XGIfb_mode_no) == 0) {
1126 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1127 return -EINVAL;
1128 }
1129 info->fix.line_length = ((info->var.xres_virtual * info->var.bits_per_pixel)>>6);
1130
1131 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1132
1133 outXGIIDXREG(XGICR,0x13,(info->fix.line_length & 0x00ff));
1134 outXGIIDXREG(XGISR,0x0E,(info->fix.line_length & 0xff00)>>8);
1135
1136 XGIfb_post_setmode();
1137
1138 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d \n",
1139 XGIbios_mode[xgifb_mode_idx].xres,
1140 XGIbios_mode[xgifb_mode_idx].yres,
1141 XGIbios_mode[xgifb_mode_idx].bpp,
1142 xgi_video_info.refresh_rate);
1143
1144 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1145 xgi_video_info.video_vwidth = info->var.xres_virtual;
1146 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1147 xgi_video_info.video_vheight = info->var.yres_virtual;
1148 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1149 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1150 xgi_video_info.video_linelength = info->var.xres_virtual * (xgi_video_info.video_bpp >> 3);
1151 xgi_video_info.accel = 0;
1152 if(XGIfb_accel) {
1153 xgi_video_info.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
1154 }
1155 switch(xgi_video_info.video_bpp)
1156 {
1157 case 8:
1158 xgi_video_info.DstColor = 0x0000;
1159 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1160 xgi_video_info.video_cmap_len = 256;
1161 #if defined(__powerpc__)
1162 inXGIIDXREG (XGICR, 0x4D, cr_data);
1163 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1164 #endif
1165 break;
1166 case 16:
1167 xgi_video_info.DstColor = 0x8000;
1168 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1169 #if defined(__powerpc__)
1170 inXGIIDXREG (XGICR, 0x4D, cr_data);
1171 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1172 #endif
1173 xgi_video_info.video_cmap_len = 16;
1174 break;
1175 case 32:
1176 xgi_video_info.DstColor = 0xC000;
1177 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1178 xgi_video_info.video_cmap_len = 16;
1179 #if defined(__powerpc__)
1180 inXGIIDXREG (XGICR, 0x4D, cr_data);
1181 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1182 #endif
1183 break;
1184 default:
1185 xgi_video_info.video_cmap_len = 16;
1186 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1187 xgi_video_info.accel = 0;
1188 break;
1189 }
1190 }
1191 XGIfb_bpp_to_var(var); /*update ARGB info*/
1192 DEBUGPRN("End of do_set_var");
1193
1194 dumpVGAReg();
1195 return 0;
1196 }
1197
1198 #ifdef XGIFB_PAN
1199 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1200 {
1201 unsigned int base;
1202
1203 // printk("Inside pan_var");
1204
1205 if (var->xoffset > (var->xres_virtual - var->xres)) {
1206 // printk( "Pan: xo: %d xv %d xr %d\n",
1207 // var->xoffset, var->xres_virtual, var->xres);
1208 return -EINVAL;
1209 }
1210 if(var->yoffset > (var->yres_virtual - var->yres)) {
1211 // printk( "Pan: yo: %d yv %d yr %d\n",
1212 // var->yoffset, var->yres_virtual, var->yres);
1213 return -EINVAL;
1214 }
1215 base = var->yoffset * var->xres_virtual + var->xoffset;
1216
1217 /* calculate base bpp dep. */
1218 switch(var->bits_per_pixel) {
1219 case 16:
1220 base >>= 1;
1221 break;
1222 case 32:
1223 break;
1224 case 8:
1225 default:
1226 base >>= 2;
1227 break;
1228 }
1229
1230 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1231
1232 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1233 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1234 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1235 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1236 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1237
1238 if(xgi_video_info.disp_state & DISPTYPE_DISP2) {
1239 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1240 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1241 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1242 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1243 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1244 }
1245 // printk("End of pan_var");
1246 return 0;
1247 }
1248 #endif
1249
1250
1251 void XGI_dispinfo(struct ap_data *rec)
1252 {
1253 rec->minfo.bpp = xgi_video_info.video_bpp;
1254 rec->minfo.xres = xgi_video_info.video_width;
1255 rec->minfo.yres = xgi_video_info.video_height;
1256 rec->minfo.v_xres = xgi_video_info.video_vwidth;
1257 rec->minfo.v_yres = xgi_video_info.video_vheight;
1258 rec->minfo.org_x = xgi_video_info.org_x;
1259 rec->minfo.org_y = xgi_video_info.org_y;
1260 rec->minfo.vrate = xgi_video_info.refresh_rate;
1261 rec->iobase = xgi_video_info.vga_base - 0x30;
1262 rec->mem_size = xgi_video_info.video_size;
1263 rec->disp_state = xgi_video_info.disp_state;
1264 rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1265 rec->hasVB = xgi_video_info.hasVB;
1266 rec->TV_type = xgi_video_info.TV_type;
1267 rec->TV_plug = xgi_video_info.TV_plug;
1268 rec->chip = xgi_video_info.chip;
1269 }
1270
1271
1272
1273
1274 static int XGIfb_open(struct fb_info *info, int user)
1275 {
1276 return 0;
1277 }
1278
1279 static int XGIfb_release(struct fb_info *info, int user)
1280 {
1281 return 0;
1282 }
1283
1284 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1285 {
1286 int rc = 16;
1287
1288 switch(var->bits_per_pixel) {
1289 case 8:
1290 rc = 256;
1291 break;
1292 case 16:
1293 rc = 16;
1294 break;
1295 case 32:
1296 rc = 16;
1297 break;
1298 }
1299 return rc;
1300 }
1301
1302 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
1303 unsigned transp, struct fb_info *info)
1304 {
1305 if (regno >= XGIfb_get_cmap_len(&info->var))
1306 return 1;
1307
1308 switch (info->var.bits_per_pixel) {
1309 case 8:
1310 outXGIREG(XGIDACA, regno);
1311 outXGIREG(XGIDACD, (red >> 10));
1312 outXGIREG(XGIDACD, (green >> 10));
1313 outXGIREG(XGIDACD, (blue >> 10));
1314 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1315 outXGIREG(XGIDAC2A, regno);
1316 outXGIREG(XGIDAC2D, (red >> 8));
1317 outXGIREG(XGIDAC2D, (green >> 8));
1318 outXGIREG(XGIDAC2D, (blue >> 8));
1319 }
1320 break;
1321 case 16:
1322 ((u32 *)(info->pseudo_palette))[regno] =
1323 ((red & 0xf800)) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
1324 break;
1325 case 32:
1326 red >>= 8;
1327 green >>= 8;
1328 blue >>= 8;
1329 ((u32 *) (info->pseudo_palette))[regno] =
1330 (red << 16) | (green << 8) | (blue);
1331 break;
1332 }
1333 return 0;
1334 }
1335
1336 static int XGIfb_set_par(struct fb_info *info)
1337 {
1338 int err;
1339
1340 // printk("XGIfb: inside set_par\n");
1341 if((err = XGIfb_do_set_var(&info->var, 1, info)))
1342 return err;
1343 XGIfb_get_fix(&info->fix, -1, info);
1344 // printk("XGIfb:end of set_par\n");
1345 return 0;
1346 }
1347
1348 static int XGIfb_check_var(struct fb_var_screeninfo *var,
1349 struct fb_info *info)
1350 {
1351 unsigned int htotal =
1352 var->left_margin + var->xres + var->right_margin +
1353 var->hsync_len;
1354 unsigned int vtotal = 0;
1355 unsigned int drate = 0, hrate = 0;
1356 int found_mode = 0;
1357 int refresh_rate, search_idx;
1358
1359 DEBUGPRN("Inside check_var");
1360
1361 if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1362 vtotal = var->upper_margin + var->yres + var->lower_margin +
1363 var->vsync_len;
1364 vtotal <<= 1;
1365 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1366 vtotal = var->upper_margin + var->yres + var->lower_margin +
1367 var->vsync_len;
1368 vtotal <<= 2;
1369 } else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1370 vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
1371 var->vsync_len;
1372 } else vtotal = var->upper_margin + var->yres + var->lower_margin +
1373 var->vsync_len;
1374
1375 if(!(htotal) || !(vtotal)) {
1376 XGIFAIL("XGIfb: no valid timing data");
1377 }
1378
1379
1380 if(var->pixclock && htotal && vtotal) {
1381 drate = 1000000000 / var->pixclock;
1382 hrate = (drate * 1000) / htotal;
1383 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1384 printk(KERN_DEBUG \
1385 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n" \
1386 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1387 __func__,var->pixclock, htotal, vtotal,
1388 __func__, drate, hrate, xgi_video_info.refresh_rate);
1389 } else {
1390 xgi_video_info.refresh_rate = 60;
1391 }
1392
1393 /*
1394 if((var->pixclock) && (htotal)) {
1395 drate = 1E12 / var->pixclock;
1396 hrate = drate / htotal;
1397 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1398 } else refresh_rate = 60;
1399 */
1400 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1401 if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
1402
1403 search_idx = 0;
1404 while((XGIbios_mode[search_idx].mode_no != 0) &&
1405 (XGIbios_mode[search_idx].xres <= var->xres) ) {
1406 if((XGIbios_mode[search_idx].xres == var->xres) &&
1407 (XGIbios_mode[search_idx].yres == var->yres) &&
1408 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1409 if(XGIfb_validate_mode(search_idx) > 0) {
1410 found_mode = 1;
1411 break;
1412 }
1413 }
1414 search_idx++;
1415 }
1416
1417 if(!found_mode) {
1418
1419 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1420 var->xres, var->yres, var->bits_per_pixel);
1421
1422 search_idx = 0;
1423 while(XGIbios_mode[search_idx].mode_no != 0) {
1424
1425 if( (var->xres <= XGIbios_mode[search_idx].xres) &&
1426 (var->yres <= XGIbios_mode[search_idx].yres) &&
1427 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp) ) {
1428 if(XGIfb_validate_mode(search_idx) > 0) {
1429 found_mode = 1;
1430 break;
1431 }
1432 }
1433 search_idx++;
1434 }
1435 if(found_mode) {
1436 var->xres = XGIbios_mode[search_idx].xres;
1437 var->yres = XGIbios_mode[search_idx].yres;
1438 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1439 var->xres, var->yres, var->bits_per_pixel);
1440
1441 } else {
1442 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1443 var->xres, var->yres, var->bits_per_pixel);
1444 return -EINVAL;
1445 }
1446 }
1447
1448 /* TW: TODO: Check the refresh rate */
1449
1450 /* Adapt RGB settings */
1451 XGIfb_bpp_to_var(var);
1452
1453 /* Sanity check for offsets */
1454 if (var->xoffset < 0)
1455 var->xoffset = 0;
1456 if (var->yoffset < 0)
1457 var->yoffset = 0;
1458
1459
1460 if(!XGIfb_ypan) {
1461 if(var->xres != var->xres_virtual)
1462 var->xres_virtual = var->xres;
1463 if(var->yres != var->yres_virtual)
1464 var->yres_virtual = var->yres;
1465 }/* else {
1466 // TW: Now patch yres_virtual if we use panning
1467 // May I do this?
1468 var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3));
1469 if(var->yres_virtual <= var->yres) {
1470 // TW: Paranoia check
1471 var->yres_virtual = var->yres;
1472 }
1473 }*/
1474
1475 /* Truncate offsets to maximum if too high */
1476 if (var->xoffset > var->xres_virtual - var->xres)
1477 var->xoffset = var->xres_virtual - var->xres - 1;
1478
1479 if (var->yoffset > var->yres_virtual - var->yres)
1480 var->yoffset = var->yres_virtual - var->yres - 1;
1481
1482 /* Set everything else to 0 */
1483 var->red.msb_right =
1484 var->green.msb_right =
1485 var->blue.msb_right =
1486 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1487
1488 DEBUGPRN("end of check_var");
1489 return 0;
1490 }
1491
1492 #ifdef XGIFB_PAN
1493 static int XGIfb_pan_display( struct fb_var_screeninfo *var,
1494 struct fb_info* info)
1495 {
1496 int err;
1497
1498 // printk("\nInside pan_display:");
1499
1500 if (var->xoffset > (var->xres_virtual - var->xres))
1501 return -EINVAL;
1502 if (var->yoffset > (var->yres_virtual - var->yres))
1503 return -EINVAL;
1504
1505 if (var->vmode & FB_VMODE_YWRAP) {
1506 if (var->yoffset < 0
1507 || var->yoffset >= info->var.yres_virtual
1508 || var->xoffset) return -EINVAL;
1509 } else {
1510 if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1511 var->yoffset + info->var.yres > info->var.yres_virtual)
1512 return -EINVAL;
1513 }
1514
1515 if((err = XGIfb_pan_var(var)) < 0) return err;
1516
1517 info->var.xoffset = var->xoffset;
1518 info->var.yoffset = var->yoffset;
1519 if (var->vmode & FB_VMODE_YWRAP)
1520 info->var.vmode |= FB_VMODE_YWRAP;
1521 else
1522 info->var.vmode &= ~FB_VMODE_YWRAP;
1523
1524 // printk(" End of pan_display");
1525 return 0;
1526 }
1527 #endif
1528
1529
1530 static int XGIfb_blank(int blank, struct fb_info *info)
1531 {
1532 u8 reg;
1533
1534 inXGIIDXREG(XGICR, 0x17, reg);
1535
1536 if(blank > 0)
1537 reg &= 0x7f;
1538 else
1539 reg |= 0x80;
1540
1541 outXGIIDXREG(XGICR, 0x17, reg);
1542 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1543 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1544 return(0);
1545 }
1546
1547
1548 static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
1549 unsigned long arg)
1550 {
1551 DEBUGPRN("inside ioctl");
1552 switch (cmd) {
1553 case FBIO_ALLOC:
1554 if (!capable(CAP_SYS_RAWIO))
1555 return -EPERM;
1556 XGI_malloc((struct XGI_memreq *) arg);
1557 break;
1558 case FBIO_FREE:
1559 if (!capable(CAP_SYS_RAWIO))
1560 return -EPERM;
1561 XGI_free(*(unsigned long *) arg);
1562 break;
1563 case FBIOGET_HWCINFO:
1564 {
1565 unsigned long *hwc_offset = (unsigned long *) arg;
1566
1567 if (XGIfb_caps & HW_CURSOR_CAP)
1568 *hwc_offset = XGIfb_hwcursor_vbase -
1569 (unsigned long) xgi_video_info.video_vbase;
1570 else
1571 *hwc_offset = 0;
1572
1573 break;
1574 }
1575 case FBIOPUT_MODEINFO:
1576 {
1577 struct mode_info *x = (struct mode_info *)arg;
1578
1579 xgi_video_info.video_bpp = x->bpp;
1580 xgi_video_info.video_width = x->xres;
1581 xgi_video_info.video_height = x->yres;
1582 xgi_video_info.video_vwidth = x->v_xres;
1583 xgi_video_info.video_vheight = x->v_yres;
1584 xgi_video_info.org_x = x->org_x;
1585 xgi_video_info.org_y = x->org_y;
1586 xgi_video_info.refresh_rate = x->vrate;
1587 xgi_video_info.video_linelength = xgi_video_info.video_vwidth * (xgi_video_info.video_bpp >> 3);
1588 switch(xgi_video_info.video_bpp) {
1589 case 8:
1590 xgi_video_info.DstColor = 0x0000;
1591 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1592 xgi_video_info.video_cmap_len = 256;
1593 break;
1594 case 16:
1595 xgi_video_info.DstColor = 0x8000;
1596 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1597 xgi_video_info.video_cmap_len = 16;
1598 break;
1599 case 32:
1600 xgi_video_info.DstColor = 0xC000;
1601 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1602 xgi_video_info.video_cmap_len = 16;
1603 break;
1604 default:
1605 xgi_video_info.video_cmap_len = 16;
1606 printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1607 xgi_video_info.accel = 0;
1608 break;
1609 }
1610
1611 break;
1612 }
1613 case FBIOGET_DISPINFO:
1614 XGI_dispinfo((struct ap_data *)arg);
1615 break;
1616 case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1617 {
1618 struct XGIfb_info *x = (struct XGIfb_info *)arg;
1619
1620 //x->XGIfb_id = XGIFB_ID;
1621 x->XGIfb_version = VER_MAJOR;
1622 x->XGIfb_revision = VER_MINOR;
1623 x->XGIfb_patchlevel = VER_LEVEL;
1624 x->chip_id = xgi_video_info.chip_id;
1625 x->memory = xgi_video_info.video_size / 1024;
1626 x->heapstart = xgi_video_info.heapstart / 1024;
1627 x->fbvidmode = XGIfb_mode_no;
1628 x->XGIfb_caps = XGIfb_caps;
1629 x->XGIfb_tqlen = 512; /* yet unused */
1630 x->XGIfb_pcibus = xgi_video_info.pcibus;
1631 x->XGIfb_pcislot = xgi_video_info.pcislot;
1632 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1633 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1634 x->XGIfb_lcda = XGIfb_detectedlcda;
1635 break;
1636 }
1637 case XGIFB_GET_VBRSTATUS:
1638 {
1639 unsigned long *vbrstatus = (unsigned long *) arg;
1640 if(XGIfb_CheckVBRetrace()) *vbrstatus = 1;
1641 else *vbrstatus = 0;
1642 }
1643 default:
1644 return -EINVAL;
1645 }
1646 DEBUGPRN("end of ioctl");
1647 return 0;
1648
1649 }
1650
1651
1652
1653 /* ----------- FBDev related routines for all series ---------- */
1654
1655 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1656 struct fb_info *info)
1657 {
1658 DEBUGPRN("inside get_fix");
1659 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1660
1661 strcpy(fix->id, myid);
1662
1663 fix->smem_start = xgi_video_info.video_base;
1664
1665 fix->smem_len = xgi_video_info.video_size;
1666
1667
1668 /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1669 if (xgi_video_info.video_size > 0x1000000) {
1670 fix->smem_len = 0xD00000;
1671 } else if (xgi_video_info.video_size > 0x800000)
1672 fix->smem_len = 0x800000;
1673 else
1674 fix->smem_len = 0x400000;
1675 } else
1676 fix->smem_len = XGIfb_mem * 1024;
1677 */
1678 fix->type = video_type;
1679 fix->type_aux = 0;
1680 if(xgi_video_info.video_bpp == 8)
1681 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1682 else
1683 fix->visual = FB_VISUAL_DIRECTCOLOR;
1684 fix->xpanstep = 0;
1685 #ifdef XGIFB_PAN
1686 if(XGIfb_ypan) fix->ypanstep = 1;
1687 #endif
1688 fix->ywrapstep = 0;
1689 fix->line_length = xgi_video_info.video_linelength;
1690 fix->mmio_start = xgi_video_info.mmio_base;
1691 fix->mmio_len = XGIfb_mmio_size;
1692 if(xgi_video_info.chip >= XG40)
1693 fix->accel = FB_ACCEL_XGI_XABRE;
1694 else
1695 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
1696
1697
1698 DEBUGPRN("end of get_fix");
1699 return 0;
1700 }
1701
1702
1703 static struct fb_ops XGIfb_ops = {
1704 .owner = THIS_MODULE,
1705 .fb_open = XGIfb_open,
1706 .fb_release = XGIfb_release,
1707 .fb_check_var = XGIfb_check_var,
1708 .fb_set_par = XGIfb_set_par,
1709 .fb_setcolreg = XGIfb_setcolreg,
1710 #ifdef XGIFB_PAN
1711 .fb_pan_display = XGIfb_pan_display,
1712 #endif
1713 .fb_blank = XGIfb_blank,
1714 .fb_fillrect = fbcon_XGI_fillrect,
1715 .fb_copyarea = fbcon_XGI_copyarea,
1716 .fb_imageblit = cfb_imageblit,
1717 .fb_sync = fbcon_XGI_sync,
1718 .fb_ioctl = XGIfb_ioctl,
1719 // .fb_mmap = XGIfb_mmap,
1720 };
1721
1722 /* ---------------- Chip generation dependent routines ---------------- */
1723
1724
1725 /* for XGI 315/550/650/740/330 */
1726
1727 static int XGIfb_get_dram_size(void)
1728 {
1729
1730 u8 ChannelNum,tmp;
1731 u8 reg = 0;
1732
1733 /* xorg driver sets 32MB * 1 channel */
1734 if (xgi_video_info.chip == XG27)
1735 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1736
1737 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1738 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1739 case XGI_DRAM_SIZE_1MB:
1740 xgi_video_info.video_size = 0x100000;
1741 break;
1742 case XGI_DRAM_SIZE_2MB:
1743 xgi_video_info.video_size = 0x200000;
1744 break;
1745 case XGI_DRAM_SIZE_4MB:
1746 xgi_video_info.video_size = 0x400000;
1747 break;
1748 case XGI_DRAM_SIZE_8MB:
1749 xgi_video_info.video_size = 0x800000;
1750 break;
1751 case XGI_DRAM_SIZE_16MB:
1752 xgi_video_info.video_size = 0x1000000;
1753 break;
1754 case XGI_DRAM_SIZE_32MB:
1755 xgi_video_info.video_size = 0x2000000;
1756 break;
1757 case XGI_DRAM_SIZE_64MB:
1758 xgi_video_info.video_size = 0x4000000;
1759 break;
1760 case XGI_DRAM_SIZE_128MB:
1761 xgi_video_info.video_size = 0x8000000;
1762 break;
1763 case XGI_DRAM_SIZE_256MB:
1764 xgi_video_info.video_size = 0x10000000;
1765 break;
1766 default:
1767 return -1;
1768 }
1769
1770 tmp = (reg & 0x0c) >> 2;
1771 switch(xgi_video_info.chip)
1772 {
1773 case XG20:
1774 case XG21:
1775 case XG27:
1776 ChannelNum = 1;
1777 break;
1778
1779 case XG42:
1780 if(reg & 0x04)
1781 ChannelNum = 2;
1782 else
1783 ChannelNum = 1;
1784 break;
1785
1786 case XG45:
1787 if(tmp == 1)
1788 ChannelNum = 2;
1789 else
1790 if(tmp == 2)
1791 ChannelNum = 3;
1792 else
1793 if(tmp == 3)
1794 ChannelNum = 4;
1795 else
1796 ChannelNum = 1;
1797 break;
1798
1799 case XG40:
1800 default:
1801 if(tmp == 2)
1802 ChannelNum = 2;
1803 else
1804 if(tmp == 3)
1805 ChannelNum = 3;
1806 else
1807 ChannelNum = 1;
1808 break;
1809 }
1810
1811
1812 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1813 //PLiad fixed for benchmarking and fb set
1814 //xgi_video_info.video_size = 0x200000;//1024x768x16
1815 //xgi_video_info.video_size = 0x1000000;//benchmark
1816
1817 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",reg,xgi_video_info.video_size ,ChannelNum );
1818 return 0;
1819
1820 }
1821
1822 static void XGIfb_detect_VB(void)
1823 {
1824 u8 cr32, temp=0;
1825
1826 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1827
1828 switch(xgi_video_info.hasVB) {
1829 case HASVB_LVDS_CHRONTEL:
1830 case HASVB_CHRONTEL:
1831 break;
1832 case HASVB_301:
1833 case HASVB_302:
1834 // XGI_Sense30x(); //Yi-Lin TV Sense?
1835 break;
1836 }
1837
1838 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1839
1840 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1841 XGIfb_crt1off = 0;
1842 else {
1843 if (cr32 & 0x5F)
1844 XGIfb_crt1off = 1;
1845 else
1846 XGIfb_crt1off = 0;
1847 }
1848
1849 if (XGIfb_crt2type != -1)
1850 /* TW: Override with option */
1851 xgi_video_info.disp_state = XGIfb_crt2type;
1852 else if (cr32 & XGI_VB_TV)
1853 xgi_video_info.disp_state = DISPTYPE_TV;
1854 else if (cr32 & XGI_VB_LCD)
1855 xgi_video_info.disp_state = DISPTYPE_LCD;
1856 else if (cr32 & XGI_VB_CRT2)
1857 xgi_video_info.disp_state = DISPTYPE_CRT2;
1858 else
1859 xgi_video_info.disp_state = 0;
1860
1861 if(XGIfb_tvplug != -1)
1862 /* PR/TW: Override with option */
1863 xgi_video_info.TV_plug = XGIfb_tvplug;
1864 else if (cr32 & XGI_VB_HIVISION) {
1865 xgi_video_info.TV_type = TVMODE_HIVISION;
1866 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1867 }
1868 else if (cr32 & XGI_VB_SVIDEO)
1869 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1870 else if (cr32 & XGI_VB_COMPOSITE)
1871 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1872 else if (cr32 & XGI_VB_SCART)
1873 xgi_video_info.TV_plug = TVPLUG_SCART;
1874
1875 if(xgi_video_info.TV_type == 0) {
1876 /* TW: PAL/NTSC changed for 650 */
1877 if((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip >= XGI_330)) {
1878
1879 inXGIIDXREG(XGICR, 0x38, temp);
1880 if(temp & 0x10)
1881 xgi_video_info.TV_type = TVMODE_PAL;
1882 else
1883 xgi_video_info.TV_type = TVMODE_NTSC;
1884
1885 } else {
1886
1887 inXGIIDXREG(XGICR, 0x79, temp);
1888 if(temp & 0x20)
1889 xgi_video_info.TV_type = TVMODE_PAL;
1890 else
1891 xgi_video_info.TV_type = TVMODE_NTSC;
1892 }
1893 }
1894
1895 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1896 if (XGIfb_forcecrt1 != -1) {
1897 if (XGIfb_forcecrt1) XGIfb_crt1off = 0;
1898 else XGIfb_crt1off = 1;
1899 }
1900 }
1901
1902 static void XGIfb_get_VB_type(void)
1903 {
1904 u8 reg;
1905
1906 if (!XGIfb_has_VB()) {
1907 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1908 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1909 case XGI310_EXTERNAL_CHIP_LVDS:
1910 xgi_video_info.hasVB = HASVB_LVDS;
1911 break;
1912 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1913 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1914 break;
1915 default:
1916 break;
1917 }
1918 }
1919 }
1920
1921
1922 static int XGIfb_has_VB(void)
1923 {
1924 u8 vb_chipid;
1925
1926 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1927 switch (vb_chipid) {
1928 case 0x01:
1929 xgi_video_info.hasVB = HASVB_301;
1930 break;
1931 case 0x02:
1932 xgi_video_info.hasVB = HASVB_302;
1933 break;
1934 default:
1935 xgi_video_info.hasVB = HASVB_NONE;
1936 return 0;
1937 }
1938 return 1;
1939 }
1940
1941
1942
1943 /* ------------------ Sensing routines ------------------ */
1944
1945 /* TW: Determine and detect attached devices on XGI30x */
1946 int
1947 XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
1948 {
1949 int temp,i;
1950
1951 outXGIIDXREG(XGIPART4,0x11,tempbl);
1952 temp = tempbh | tempcl;
1953 setXGIIDXREG(XGIPART4,0x10,0xe0,temp);
1954 for(i=0; i<10; i++) XGI_LongWait(&XGI_Pr);
1955 tempch &= 0x7f;
1956 inXGIIDXREG(XGIPART4,0x03,temp);
1957 temp ^= 0x0e;
1958 temp &= tempch;
1959 return(temp);
1960 }
1961
1962 void
1963 XGI_Sense30x(void)
1964 {
1965 u8 backupP4_0d;
1966 u8 testsvhs_tempbl, testsvhs_tempbh;
1967 u8 testsvhs_tempcl, testsvhs_tempch;
1968 u8 testcvbs_tempbl, testcvbs_tempbh;
1969 u8 testcvbs_tempcl, testcvbs_tempch;
1970 u8 testvga2_tempbl, testvga2_tempbh;
1971 u8 testvga2_tempcl, testvga2_tempch;
1972 int myflag, result;
1973
1974 inXGIIDXREG(XGIPART4,0x0d,backupP4_0d);
1975 outXGIIDXREG(XGIPART4,0x0d,(backupP4_0d | 0x04));
1976
1977
1978
1979 testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
1980 testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
1981 testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
1982 if((XGIhw_ext.ujVBChipID != VB_CHIP_301) &&
1983 (XGIhw_ext.ujVBChipID != VB_CHIP_302)) {
1984 testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
1985 testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
1986 testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
1987 if(XGIhw_ext.ujVBChipID == VB_CHIP_301LV ||
1988 XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
1989 testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
1990 testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
1991 testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
1992 }
1993 }
1994 if(XGIhw_ext.ujVBChipID != VB_CHIP_301LV &&
1995 XGIhw_ext.ujVBChipID != VB_CHIP_302LV) {
1996 inXGIIDXREG(XGIPART4,0x01,myflag);
1997 if(myflag & 0x04) {
1998 testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
1999 testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
2000 testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
2001 }
2002 }
2003 if((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2004 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV) ) {
2005 testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
2006 testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
2007 testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
2008 testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
2009 } else {
2010 testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
2011 testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
2012 testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
2013 }
2014
2015
2016 if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
2017 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2018 testvga2_tempcl, testvga2_tempch);
2019 if(result) {
2020 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2021 orXGIIDXREG(XGICR, 0x32, 0x10);
2022 }
2023 }
2024
2025 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh,
2026 testsvhs_tempcl, testsvhs_tempch);
2027 if(result) {
2028 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2029 /* TW: So we can be sure that there IS a SVHS output */
2030 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2031 orXGIIDXREG(XGICR, 0x32, 0x02);
2032 }
2033
2034 if(!result) {
2035 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2036 testcvbs_tempcl, testcvbs_tempch);
2037 if(result) {
2038 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2039 /* TW: So we can be sure that there IS a CVBS output */
2040 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2041 orXGIIDXREG(XGICR, 0x32, 0x01);
2042 }
2043 }
2044 XGIDoSense(0, 0, 0, 0);
2045
2046 outXGIIDXREG(XGIPART4,0x0d,backupP4_0d);
2047 }
2048
2049
2050
2051 /* ------------------------ Heap routines -------------------------- */
2052
2053 static int XGIfb_heap_init(void)
2054 {
2055 XGI_OH *poh;
2056 u8 temp=0;
2057
2058 int agp_enabled = 1;
2059 u32 agp_size;
2060 unsigned long *cmdq_baseport = 0;
2061 unsigned long *read_port = 0;
2062 unsigned long *write_port = 0;
2063 XGI_CMDTYPE cmd_type;
2064 #ifndef AGPOFF
2065 struct agp_kern_info *agp_info;
2066 struct agp_memory *agp;
2067 u32 agp_phys;
2068 #endif
2069
2070 /* TW: The heap start is either set manually using the "mem" parameter, or
2071 * defaults as follows:
2072 * -) If more than 16MB videoRAM available, let our heap start at 12MB.
2073 * -) If more than 8MB videoRAM available, let our heap start at 8MB.
2074 * -) If 4MB or less is available, let it start at 4MB.
2075 * This is for avoiding a clash with X driver which uses the beginning
2076 * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2077 * in XF86Config-4.
2078 * The heap start can also be specified by parameter "mem" when starting the XGIfb
2079 * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2080 */
2081 if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
2082 if (xgi_video_info.video_size > 0x1000000) {
2083 xgi_video_info.heapstart = 0xD00000;
2084 } else if (xgi_video_info.video_size > 0x800000) {
2085 xgi_video_info.heapstart = 0x800000;
2086 } else {
2087 xgi_video_info.heapstart = 0x400000;
2088 }
2089 } else {
2090 xgi_video_info.heapstart = XGIfb_mem * 1024;
2091 }
2092 XGIfb_heap_start =
2093 (unsigned long) (xgi_video_info.video_vbase + xgi_video_info.heapstart);
2094 printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2095 (int)(xgi_video_info.heapstart / 1024));
2096
2097 XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase + xgi_video_info.video_size;
2098 XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
2099
2100
2101
2102 /* TW: Now initialize the 310 series' command queue mode.
2103 * On 310/325, there are three queue modes available which
2104 * are chosen by setting bits 7:5 in SR26:
2105 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2106 * track of the queue, the FIFO, command parsing and so
2107 * on. This is the one comparable to the 300 series.
2108 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2109 * have to do queue management himself. Register 0x85c4 will
2110 * hold the location of the next free queue slot, 0x85c8
2111 * is the "queue read pointer" whose way of working is
2112 * unknown to me. Anyway, this mode would require a
2113 * translation of the MMIO commands to some kind of
2114 * accelerator assembly and writing these commands
2115 * to the memory location pointed to by 0x85c4.
2116 * We will not use this, as nobody knows how this
2117 * "assembly" works, and as it would require a complete
2118 * re-write of the accelerator code.
2119 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2120 * queue in AGP memory space.
2121 *
2122 * SR26 bit 4 is called "Bypass H/W queue".
2123 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2124 * SR26 bit 0 resets the queue
2125 * Size of queue memory is encoded in bits 3:2 like this:
2126 * 00 (0x00) 512K
2127 * 01 (0x04) 1M
2128 * 10 (0x08) 2M
2129 * 11 (0x0C) 4M
2130 * The queue location is to be written to 0x85C0.
2131 *
2132 */
2133 cmdq_baseport = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_PHYBASE);
2134 write_port = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_WRITEPORT);
2135 read_port = (unsigned long *)(xgi_video_info.mmio_vbase + MMIO_QUEUE_READPORT);
2136
2137 DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2138
2139 agp_size = COMMAND_QUEUE_AREA_SIZE;
2140
2141 #ifndef AGPOFF
2142 if (XGIfb_queuemode == AGP_CMD_QUEUE) {
2143 agp_info = vmalloc(sizeof(*agp_info));
2144 memset((void*)agp_info, 0x00, sizeof(*agp_info));
2145 agp_copy_info(agp_info);
2146
2147 agp_backend_acquire();
2148
2149 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE/PAGE_SIZE,
2150 AGP_NORMAL_MEMORY);
2151 if (agp == NULL) {
2152 DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2153 agp_enabled = 0;
2154 } else {
2155 if (agp_bind_memory(agp, agp->pg_start) != 0) {
2156 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2157 /* TODO: Free AGP memory here */
2158 agp_enabled = 0;
2159 } else {
2160 agp_enable(0);
2161 }
2162 }
2163 }
2164 #else
2165 agp_enabled = 0;
2166 #endif
2167
2168 /* TW: Now select the queue mode */
2169
2170 if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2171 cmd_type = AGP_CMD_QUEUE;
2172 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
2173 /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
2174 } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
2175 cmd_type = VM_CMD_QUEUE;
2176 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2177 } else {
2178 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2179 cmd_type = MMIO_CMD;
2180 }
2181
2182 switch (agp_size) {
2183 case 0x80000:
2184 temp = XGI_CMD_QUEUE_SIZE_512k;
2185 break;
2186 case 0x100000:
2187 temp = XGI_CMD_QUEUE_SIZE_1M;
2188 break;
2189 case 0x200000:
2190 temp = XGI_CMD_QUEUE_SIZE_2M;
2191 break;
2192 case 0x400000:
2193 temp = XGI_CMD_QUEUE_SIZE_4M;
2194 break;
2195 }
2196
2197 switch (cmd_type) {
2198 case AGP_CMD_QUEUE:
2199 #ifndef AGPOFF
2200 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2201 agp_info->aper_base, agp->physical, agp_size/1024);
2202
2203 agp_phys = agp_info->aper_base + agp->physical;
2204
2205 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2206 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
2207
2208 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2209
2210 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2211
2212 *write_port = *read_port;
2213
2214 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2215 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2216
2217 *cmdq_baseport = agp_phys;
2218
2219 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2220 #endif
2221 break;
2222
2223 case VM_CMD_QUEUE:
2224 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2225 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2226
2227 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2228
2229 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2230
2231 *write_port = *read_port;
2232
2233 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2234 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2235
2236 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2237
2238 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2239
2240 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2241 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2242 break;
2243
2244 default: /* MMIO */
2245
2246 // printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__);
2247 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
2248 * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2249 * enough. Reserve memory in any way.
2250 */
2251 // FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2252 // FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2253 // FIXME
2254 // FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2255 // FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2256 // FIXME
2257 // FIXME *write_port = *read_port;
2258 // FIXME
2259 // FIXME /* TW: Set Auto_Correction bit */
2260 // FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR);
2261 // FIXME // FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2262 // FIXME
2263 // FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2264 // FIXME
2265 // FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP;
2266 // FIXME
2267 // FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n",
2268 // FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2269 break;
2270 }
2271
2272
2273
2274
2275 /* TW: Now reserve memory for the HWCursor. It is always located at the very
2276 top of the videoRAM, right below the TB memory area (if used). */
2277 if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
2278 XGIfb_heap_end -= XGIfb_hwcursor_size;
2279 XGIfb_heap_size -= XGIfb_hwcursor_size;
2280 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2281
2282 XGIfb_caps |= HW_CURSOR_CAP;
2283
2284 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
2285 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2286 }
2287
2288 XGIfb_heap.poha_chain = NULL;
2289 XGIfb_heap.poh_freelist = NULL;
2290
2291 poh = XGIfb_poh_new_node();
2292
2293 if(poh == NULL) return 1;
2294
2295 poh->poh_next = &XGIfb_heap.oh_free;
2296 poh->poh_prev = &XGIfb_heap.oh_free;
2297 poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2298 poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
2299
2300 DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
2301 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2302 (unsigned int) poh->size / 1024);
2303
2304 DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
2305 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2306
2307 XGIfb_heap.oh_free.poh_next = poh;
2308 XGIfb_heap.oh_free.poh_prev = poh;
2309 XGIfb_heap.oh_free.size = 0;
2310 XGIfb_heap.max_freesize = poh->size;
2311
2312 XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2313 XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2314 XGIfb_heap.oh_used.size = SENTINEL;
2315
2316 return 0;
2317 }
2318
2319 static XGI_OH *XGIfb_poh_new_node(void)
2320 {
2321 int i;
2322 unsigned long cOhs;
2323 XGI_OHALLOC *poha;
2324 XGI_OH *poh;
2325
2326 if (XGIfb_heap.poh_freelist == NULL) {
2327 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
2328 if(!poha) return NULL;
2329
2330 poha->poha_next = XGIfb_heap.poha_chain;
2331 XGIfb_heap.poha_chain = poha;
2332
2333 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH) + 1;
2334
2335 poh = &poha->aoh[0];
2336 for (i = cOhs - 1; i != 0; i--) {
2337 poh->poh_next = poh + 1;
2338 poh = poh + 1;
2339 }
2340
2341 poh->poh_next = NULL;
2342 XGIfb_heap.poh_freelist = &poha->aoh[0];
2343 }
2344
2345 poh = XGIfb_heap.poh_freelist;
2346 XGIfb_heap.poh_freelist = poh->poh_next;
2347
2348 return (poh);
2349 }
2350
2351 static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2352 {
2353 XGI_OH *pohThis;
2354 XGI_OH *pohRoot;
2355 int bAllocated = 0;
2356
2357 if (size > XGIfb_heap.max_freesize) {
2358 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2359 (unsigned int) size / 1024);
2360 return (NULL);
2361 }
2362
2363 pohThis = XGIfb_heap.oh_free.poh_next;
2364
2365 while (pohThis != &XGIfb_heap.oh_free) {
2366 if (size <= pohThis->size) {
2367 bAllocated = 1;
2368 break;
2369 }
2370 pohThis = pohThis->poh_next;
2371 }
2372
2373 if (!bAllocated) {
2374 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
2375 (unsigned int) size / 1024);
2376 return (NULL);
2377 }
2378
2379 if (size == pohThis->size) {
2380 pohRoot = pohThis;
2381 XGIfb_delete_node(pohThis);
2382 } else {
2383 pohRoot = XGIfb_poh_new_node();
2384
2385 if (pohRoot == NULL) {
2386 return (NULL);
2387 }
2388
2389 pohRoot->offset = pohThis->offset;
2390 pohRoot->size = size;
2391
2392 pohThis->offset += size;
2393 pohThis->size -= size;
2394 }
2395
2396 XGIfb_heap.max_freesize -= size;
2397
2398 pohThis = &XGIfb_heap.oh_used;
2399 XGIfb_insert_node(pohThis, pohRoot);
2400
2401 return (pohRoot);
2402 }
2403
2404 static void XGIfb_delete_node(XGI_OH *poh)
2405 {
2406 XGI_OH *poh_prev;
2407 XGI_OH *poh_next;
2408
2409 poh_prev = poh->poh_prev;
2410 poh_next = poh->poh_next;
2411
2412 poh_prev->poh_next = poh_next;
2413 poh_next->poh_prev = poh_prev;
2414
2415 }
2416
2417 static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2418 {
2419 XGI_OH *pohTemp;
2420
2421 pohTemp = pohList->poh_next;
2422
2423 pohList->poh_next = poh;
2424 pohTemp->poh_prev = poh;
2425
2426 poh->poh_prev = pohList;
2427 poh->poh_next = pohTemp;
2428 }
2429
2430 static XGI_OH *XGIfb_poh_free(unsigned long base)
2431 {
2432 XGI_OH *pohThis;
2433 XGI_OH *poh_freed;
2434 XGI_OH *poh_prev;
2435 XGI_OH *poh_next;
2436 unsigned long ulUpper;
2437 unsigned long ulLower;
2438 int foundNode = 0;
2439
2440 poh_freed = XGIfb_heap.oh_used.poh_next;
2441
2442 while(poh_freed != &XGIfb_heap.oh_used) {
2443 if(poh_freed->offset == base) {
2444 foundNode = 1;
2445 break;
2446 }
2447
2448 poh_freed = poh_freed->poh_next;
2449 }
2450
2451 if (!foundNode) return (NULL);
2452
2453 XGIfb_heap.max_freesize += poh_freed->size;
2454
2455 poh_prev = poh_next = NULL;
2456 ulUpper = poh_freed->offset + poh_freed->size;
2457 ulLower = poh_freed->offset;
2458
2459 pohThis = XGIfb_heap.oh_free.poh_next;
2460
2461 while (pohThis != &XGIfb_heap.oh_free) {
2462 if (pohThis->offset == ulUpper) {
2463 poh_next = pohThis;
2464 }
2465 else if ((pohThis->offset + pohThis->size) ==
2466 ulLower) {
2467 poh_prev = pohThis;
2468 }
2469 pohThis = pohThis->poh_next;
2470 }
2471
2472 XGIfb_delete_node(poh_freed);
2473
2474 if (poh_prev && poh_next) {
2475 poh_prev->size += (poh_freed->size + poh_next->size);
2476 XGIfb_delete_node(poh_next);
2477 XGIfb_free_node(poh_freed);
2478 XGIfb_free_node(poh_next);
2479 return (poh_prev);
2480 }
2481
2482 if (poh_prev) {
2483 poh_prev->size += poh_freed->size;
2484 XGIfb_free_node(poh_freed);
2485 return (poh_prev);
2486 }
2487
2488 if (poh_next) {
2489 poh_next->size += poh_freed->size;
2490 poh_next->offset = poh_freed->offset;
2491 XGIfb_free_node(poh_freed);
2492 return (poh_next);
2493 }
2494
2495 XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2496
2497 return (poh_freed);
2498 }
2499
2500 static void XGIfb_free_node(XGI_OH *poh)
2501 {
2502 if(poh == NULL) return;
2503
2504 poh->poh_next = XGIfb_heap.poh_freelist;
2505 XGIfb_heap.poh_freelist = poh;
2506
2507 }
2508
2509 void XGI_malloc(struct XGI_memreq *req)
2510 {
2511 XGI_OH *poh;
2512
2513 poh = XGIfb_poh_allocate(req->size);
2514
2515 if(poh == NULL) {
2516 req->offset = 0;
2517 req->size = 0;
2518 DPRINTK("XGIfb: Video RAM allocation failed\n");
2519 } else {
2520 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
2521 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
2522
2523 req->offset = poh->offset;
2524 req->size = poh->size;
2525 }
2526
2527 }
2528
2529 void XGI_free(unsigned long base)
2530 {
2531 XGI_OH *poh;
2532
2533 poh = XGIfb_poh_free(base);
2534
2535 if(poh == NULL) {
2536 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
2537 (unsigned int) base);
2538 }
2539 }
2540
2541 /* --------------------- SetMode routines ------------------------- */
2542
2543 static void XGIfb_pre_setmode(void)
2544 {
2545 u8 cr30 = 0, cr31 = 0;
2546
2547 inXGIIDXREG(XGICR, 0x31, cr31);
2548 cr31 &= ~0x60;
2549
2550 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2551 case DISPTYPE_CRT2:
2552 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2553 cr31 |= XGI_DRIVER_MODE;
2554 break;
2555 case DISPTYPE_LCD:
2556 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
2557 cr31 |= XGI_DRIVER_MODE;
2558 break;
2559 case DISPTYPE_TV:
2560 if (xgi_video_info.TV_type == TVMODE_HIVISION)
2561 cr30 = (XGI_VB_OUTPUT_HIVISION | XGI_SIMULTANEOUS_VIEW_ENABLE);
2562 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
2563 cr30 = (XGI_VB_OUTPUT_SVIDEO | XGI_SIMULTANEOUS_VIEW_ENABLE);
2564 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
2565 cr30 = (XGI_VB_OUTPUT_COMPOSITE | XGI_SIMULTANEOUS_VIEW_ENABLE);
2566 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
2567 cr30 = (XGI_VB_OUTPUT_SCART | XGI_SIMULTANEOUS_VIEW_ENABLE);
2568 cr31 |= XGI_DRIVER_MODE;
2569
2570 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
2571 cr31 |= 0x01;
2572 else
2573 cr31 &= ~0x01;
2574 break;
2575 default: /* disable CRT2 */
2576 cr30 = 0x00;
2577 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2578 }
2579
2580 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2581 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
2582 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
2583
2584 if(xgi_video_info.accel) XGIfb_syncaccel();
2585
2586
2587 }
2588
2589 static void XGIfb_post_setmode(void)
2590 {
2591 u8 reg;
2592 unsigned char doit = 1;
2593 /* outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2594 outXGIIDXREG(XGICR,0x13,0x00);
2595 setXGIIDXREG(XGISR,0x0E,0xF0,0x01);
2596 *test**/
2597 if (xgi_video_info.video_bpp == 8) {
2598 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
2599 if ((xgi_video_info.hasVB == HASVB_LVDS) || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
2600 doit = 0;
2601 }
2602 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
2603 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2604 doit = 0;
2605 }
2606 }
2607
2608 /* TW: We can't switch off CRT1 if bridge is in slave mode */
2609 if(xgi_video_info.hasVB != HASVB_NONE) {
2610 inXGIIDXREG(XGIPART1, 0x00, reg);
2611
2612
2613 if ((reg & 0x50) == 0x10)
2614 doit = 0;
2615
2616
2617 } else
2618 XGIfb_crt1off = 0;
2619
2620 inXGIIDXREG(XGICR, 0x17, reg);
2621 if ((XGIfb_crt1off) && (doit))
2622 reg &= ~0x80;
2623 else
2624 reg |= 0x80;
2625 outXGIIDXREG(XGICR, 0x17, reg);
2626
2627 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
2628
2629 if((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB == HASVB_301)) {
2630
2631 inXGIIDXREG(XGIPART4, 0x01, reg);
2632
2633 if(reg < 0xB0) { /* Set filter for XGI301 */
2634
2635 switch (xgi_video_info.video_width) {
2636 case 320:
2637 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2638 break;
2639 case 640:
2640 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2641 break;
2642 case 720:
2643 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2644 break;
2645 case 800:
2646 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2647 break;
2648 default:
2649 filter = -1;
2650 break;
2651 }
2652
2653 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
2654
2655 if(xgi_video_info.TV_type == TVMODE_NTSC) {
2656
2657 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
2658
2659 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2660
2661 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
2662
2663 } else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE) {
2664
2665 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2666
2667 switch (xgi_video_info.video_width) {
2668 case 640:
2669 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2670 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2671 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2672 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2673 break;
2674 case 720:
2675 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2676 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2677 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2678 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2679 break;
2680 case 800:
2681 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2682 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2683 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2684 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2685 break;
2686 }
2687 }
2688
2689 } else if(xgi_video_info.TV_type == TVMODE_PAL) {
2690
2691 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2692
2693 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2694
2695 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2696
2697 } else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE) {
2698
2699 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2700
2701 switch (xgi_video_info.video_width) {
2702 case 640:
2703 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2704 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2705 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2706 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2707 break;
2708 case 720:
2709 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2710 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2711 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2712 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2713 break;
2714 case 800:
2715 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2716 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2717 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2718 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2719 break;
2720 }
2721 }
2722 }
2723
2724 if ((filter >= 0) && (filter <=7)) {
2725 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2726 XGI_TV_filter[filter_tb].filter[filter][0],
2727 XGI_TV_filter[filter_tb].filter[filter][1],
2728 XGI_TV_filter[filter_tb].filter[filter][2],
2729 XGI_TV_filter[filter_tb].filter[filter][3]
2730 );
2731 outXGIIDXREG(XGIPART2, 0x35, (XGI_TV_filter[filter_tb].filter[filter][0]));
2732 outXGIIDXREG(XGIPART2, 0x36, (XGI_TV_filter[filter_tb].filter[filter][1]));
2733 outXGIIDXREG(XGIPART2, 0x37, (XGI_TV_filter[filter_tb].filter[filter][2]));
2734 outXGIIDXREG(XGIPART2, 0x38, (XGI_TV_filter[filter_tb].filter[filter][3]));
2735 }
2736
2737 }
2738
2739 }
2740
2741 }
2742
2743 #ifndef MODULE
2744 XGIINITSTATIC int __init XGIfb_setup(char *options)
2745 {
2746 char *this_opt;
2747
2748
2749
2750 xgi_video_info.refresh_rate = 0;
2751
2752 printk(KERN_INFO "XGIfb: Options %s\n", options);
2753
2754 if (!options || !*options)
2755 return 0;
2756
2757 while((this_opt = strsep(&options, ",")) != NULL) {
2758
2759 if (!*this_opt) continue;
2760
2761 if (!strncmp(this_opt, "mode:", 5)) {
2762 XGIfb_search_mode(this_opt + 5);
2763 } else if (!strncmp(this_opt, "vesa:", 5)) {
2764 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2765 } else if (!strncmp(this_opt, "mode:", 5)) {
2766 XGIfb_search_mode(this_opt + 5);
2767 } else if (!strncmp(this_opt, "vesa:", 5)) {
2768 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2769 } else if (!strncmp(this_opt, "vrate:", 6)) {
2770 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2771 } else if (!strncmp(this_opt, "rate:", 5)) {
2772 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2773 } else if (!strncmp(this_opt, "off", 3)) {
2774 XGIfb_off = 1;
2775 } else if (!strncmp(this_opt, "crt1off", 7)) {
2776 XGIfb_crt1off = 1;
2777 } else if (!strncmp(this_opt, "filter:", 7)) {
2778 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2779 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2780 XGIfb_search_crt2type(this_opt + 14);
2781 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2782 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2783 } else if (!strncmp(this_opt, "tvmode:",7)) {
2784 XGIfb_search_tvstd(this_opt + 7);
2785 } else if (!strncmp(this_opt, "tvstandard:",11)) {
2786 XGIfb_search_tvstd(this_opt + 7);
2787 } else if (!strncmp(this_opt, "mem:",4)) {
2788 XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2789 } else if (!strncmp(this_opt, "dstn", 4)) {
2790 enable_dstn = 1;
2791 /* TW: DSTN overrules forcecrt2type */
2792 XGIfb_crt2type = DISPTYPE_LCD;
2793 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2794 XGIfb_search_queuemode(this_opt + 10);
2795 } else if (!strncmp(this_opt, "pdc:", 4)) {
2796 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2797 if(XGIfb_pdc & ~0x3c) {
2798 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2799 XGIfb_pdc = 0;
2800 }
2801 } else if (!strncmp(this_opt, "noaccel", 7)) {
2802 XGIfb_accel = 0;
2803 } else if (!strncmp(this_opt, "noypan", 6)) {
2804 XGIfb_ypan = 0;
2805 } else if (!strncmp(this_opt, "userom:", 7)) {
2806 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2807 // } else if (!strncmp(this_opt, "useoem:", 7)) {
2808 // XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
2809 } else {
2810 XGIfb_search_mode(this_opt);
2811 // printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt);
2812 }
2813
2814 /* TW: Acceleration only with MMIO mode */
2815 if((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
2816 XGIfb_ypan = 0;
2817 XGIfb_accel = 0;
2818 }
2819 /* TW: Panning only with acceleration */
2820 if(XGIfb_accel == 0) XGIfb_ypan = 0;
2821
2822 }
2823 printk("\nxgifb: outa xgifb_setup 3450");
2824 return 0;
2825 }
2826 #endif
2827
2828 static unsigned char VBIOS_BUF[65535];
2829
2830 unsigned char *attempt_map_rom(struct pci_dev *dev, void *copy_address)
2831 {
2832 u32 rom_size = 0;
2833 u32 rom_address = 0;
2834 int j;
2835
2836 /* Get the size of the expansion rom */
2837 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0xFFFFFFFF);
2838 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_size);
2839 if ((rom_size & 0x01) == 0)
2840 {
2841 printk("No ROM\n");
2842 return NULL;
2843 }
2844
2845 rom_size &= 0xFFFFF800;
2846 rom_size = (~rom_size)+1;
2847
2848 rom_address = pci_resource_start(dev, 0);
2849 if (rom_address == 0 || rom_address == 0xFFFFFFF0)
2850 {
2851 printk("No suitable rom address found\n"); return NULL;
2852 }
2853
2854 printk("ROM Size is %dK, Address is %x\n", rom_size/1024, rom_address);
2855
2856 /* Map ROM */
2857 pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_address | PCI_ROM_ADDRESS_ENABLE);
2858
2859 /* memcpy(copy_address, rom_address, rom_size); */
2860 {
2861 unsigned char *virt_addr = ioremap(rom_address, 0x8000000);
2862
2863 unsigned char *from = (unsigned char *)virt_addr;
2864 unsigned char *to = (unsigned char *)copy_address;
2865 for (j=0; j<65536 /*rom_size*/; j++) *to++ = *from++;
2866 }
2867
2868 pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
2869
2870 printk("Copy is done\n");
2871
2872 return copy_address;
2873 }
2874
2875 int __devinit xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2876 {
2877 u16 reg16;
2878 u8 reg, reg1;
2879 u8 CR48,CR38;
2880 if (XGIfb_off)
2881 return -ENXIO;
2882
2883 XGIfb_registered = 0;
2884
2885 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2886 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2887 if(!fb_info) return -ENOMEM;
2888
2889 xgi_video_info.chip_id = pdev->device;
2890 pci_read_config_byte(pdev, PCI_REVISION_ID,&xgi_video_info.revision_id);
2891 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
2892 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2893 XGIvga_enabled = reg16 & 0x01;
2894
2895 xgi_video_info.pcibus = pdev->bus->number;
2896 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2897 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2898 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2899 xgi_video_info.subsysdevice = pdev->subsystem_device;
2900
2901 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2902 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2903 XGIfb_mmio_size = pci_resource_len(pdev, 1);
2904 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2905 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2906 //XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30;
2907 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2908 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2909
2910 if (pci_enable_device(pdev))
2911 return -EIO;
2912
2913 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2914
2915 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2916 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
2917
2918 if(reg1 != 0xa1) /*I/O error */
2919 {
2920 printk("\nXGIfb: I/O error!!!");
2921 return -EIO;
2922 }
2923
2924 switch (xgi_video_info.chip_id) {
2925 case PCI_DEVICE_ID_XG_20:
2926 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2927 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2928 if (CR48&GPIOG_READ)
2929 xgi_video_info.chip = XG21;
2930 else
2931 xgi_video_info.chip = XG20;
2932 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2933 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2934 break;
2935 case PCI_DEVICE_ID_XG_40:
2936 xgi_video_info.chip = XG40;
2937 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2938 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2939 break;
2940 case PCI_DEVICE_ID_XG_41:
2941 xgi_video_info.chip = XG41;
2942 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2943 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2944 break;
2945 case PCI_DEVICE_ID_XG_42:
2946 xgi_video_info.chip = XG42;
2947 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2948 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2949 break;
2950 case PCI_DEVICE_ID_XG_27:
2951 xgi_video_info.chip = XG27;
2952 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2953 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2954 break;
2955 default:
2956 return -ENODEV;
2957 }
2958
2959 printk("XGIfb:chipid = %x\n",xgi_video_info.chip);
2960 XGIhw_ext.jChipType = xgi_video_info.chip;
2961
2962 switch (xgi_video_info.chip) {
2963 case XG40:
2964 case XG41:
2965 case XG42:
2966 case XG45:
2967 case XG20:
2968 case XG21:
2969 case XG27:
2970 XGIhw_ext.bIntegratedMMEnabled = 1;
2971 break;
2972
2973 default:
2974 break;
2975 }
2976
2977
2978 XGIhw_ext.pDevice = NULL;
2979 if ((xgi_video_info.chip == XG21) || (XGIfb_userom))
2980 {
2981 XGIhw_ext.pjVirtualRomBase = attempt_map_rom(pdev, VBIOS_BUF);
2982
2983 if(XGIhw_ext.pjVirtualRomBase)
2984 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",XGIhw_ext.pjVirtualRomBase);
2985 else
2986 printk(KERN_INFO "XGIfb: Video ROM not found\n");
2987 } else {
2988 XGIhw_ext.pjVirtualRomBase = NULL;
2989 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2990 }
2991 XGIhw_ext.pjCustomizedROMImage = NULL;
2992 XGIhw_ext.bSkipDramSizing = 0;
2993 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2994 // XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space;
2995 strcpy(XGIhw_ext.szVBIOSVer, "0.84");
2996
2997
2998 XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
2999 if (XGIhw_ext.pSR == NULL)
3000 {
3001 printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
3002 return -ENODEV;
3003 }
3004 XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
3005
3006 XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
3007 if (XGIhw_ext.pCR == NULL)
3008 {
3009 vfree(XGIhw_ext.pSR);
3010 printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
3011 return -ENODEV;
3012 }
3013 XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
3014
3015
3016
3017
3018 if (!XGIvga_enabled)
3019 {
3020 /* Mapping Max FB Size for 315 Init */
3021 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3022 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3023 {
3024 #ifdef LINUXBIOS
3025 printk("XGIfb: XGIInit() ...");
3026 /* XGIInitNewt for LINUXBIOS only */
3027 if(XGIInitNew(&XGIhw_ext))
3028 {
3029 printk("OK\n");
3030 }
3031 else
3032 {
3033 printk("Fail\n");
3034 }
3035 #endif
3036
3037 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3038
3039
3040 }
3041 }
3042 #ifdef LINUXBIOS
3043 else
3044 {
3045 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3046 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3047 {
3048
3049 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3050
3051 // yilin Because no VBIOS DRAM Sizing, Dram size will error.
3052 // Set SR13 ,14 temporarily for UDtech
3053 outXGIIDXREG(XGISR, 0x13, 0x45);
3054 outXGIIDXREG(XGISR, 0x14, 0x51);
3055
3056
3057 }
3058 }
3059 #endif
3060 if (XGIfb_get_dram_size())
3061 {
3062 vfree(XGIhw_ext.pSR);
3063 vfree(XGIhw_ext.pCR);
3064 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
3065 return -ENODEV;
3066 }
3067
3068
3069
3070 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3071 {
3072 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
3073 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3074 /* Enable 2D accelerator engine */
3075 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3076 }
3077
3078 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3079
3080 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB"))
3081 { printk("unable request memory size %x",xgi_video_info.video_size);
3082 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3083 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
3084 vfree(XGIhw_ext.pSR);
3085 vfree(XGIhw_ext.pCR);
3086 return -ENODEV;
3087 }
3088
3089 if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO"))
3090 {
3091 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
3092 release_mem_region(xgi_video_info.video_base, xgi_video_info.video_size);
3093 vfree(XGIhw_ext.pSR);
3094 vfree(XGIhw_ext.pCR);
3095 return -ENODEV;
3096 }
3097
3098 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3099 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
3100 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
3101
3102 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3103 xgi_video_info.video_base, xgi_video_info.video_vbase,xgi_video_info.video_size / 1024);
3104
3105 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
3106 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,XGIfb_mmio_size / 1024);
3107 printk("XGIfb: XGIInitNew() ...");
3108 if(XGIInitNew(&XGIhw_ext))
3109 {
3110 printk("OK\n");
3111 }
3112 else
3113 {
3114 printk("Fail\n");
3115 }
3116
3117 if(XGIfb_heap_init())
3118 {
3119 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
3120 }
3121
3122
3123 xgi_video_info.mtrr = (unsigned int) 0;
3124
3125 if((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF))
3126 {
3127 xgi_video_info.hasVB = HASVB_NONE;
3128 if((xgi_video_info.chip == XG20)||(xgi_video_info.chip == XG27))
3129 xgi_video_info.hasVB = HASVB_NONE;
3130 else if(xgi_video_info.chip == XG21) {
3131 inXGIIDXREG(XGICR,0x38,CR38);
3132 if ((CR38&0xE0) == 0xC0) {
3133 xgi_video_info.disp_state = DISPTYPE_LCD;
3134 if (!XGIfb_GetXG21LVDSData()) {
3135 int m;
3136 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
3137 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3138 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3139 XGINew_SetReg1( XGI_Pr.P3d4 , 0x36, m) ;
3140 }
3141 }
3142 }
3143 }
3144 else if ((CR38&0xE0) == 0x60)
3145 xgi_video_info.hasVB = HASVB_CHRONTEL ;
3146 else
3147 xgi_video_info.hasVB = HASVB_NONE;
3148 }
3149 else
3150 XGIfb_get_VB_type();
3151
3152 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
3153
3154 XGIhw_ext.ulExternalChip = 0;
3155
3156 switch (xgi_video_info.hasVB) {
3157 case HASVB_301:
3158 inXGIIDXREG(XGIPART4, 0x01, reg);
3159 if (reg >= 0xE0) {
3160 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3161 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
3162 } else if (reg >= 0xD0) {
3163 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3164 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n",reg);
3165 }
3166 /* else if (reg >= 0xB0) {
3167 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
3168 inXGIIDXREG(XGIPART4,0x23,reg1);
3169 printk("XGIfb: XGI301B bridge detected\n");
3170 }*/
3171 else {
3172 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3173 printk("XGIfb: XGI301 bridge detected\n");
3174 }
3175 break;
3176 case HASVB_302:
3177 inXGIIDXREG(XGIPART4, 0x01, reg);
3178 if (reg >= 0xE0) {
3179 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
3180 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
3181 } else if (reg >= 0xD0) {
3182 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
3183 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n",reg);
3184 } else if (reg >= 0xB0) {
3185 inXGIIDXREG(XGIPART4,0x23,reg1);
3186
3187 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
3188
3189 } else {
3190 XGIhw_ext.ujVBChipID = VB_CHIP_302;
3191 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3192 }
3193 break;
3194 case HASVB_LVDS:
3195 XGIhw_ext.ulExternalChip = 0x1;
3196 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3197 break;
3198 case HASVB_TRUMPION:
3199 XGIhw_ext.ulExternalChip = 0x2;
3200 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3201 break;
3202 case HASVB_CHRONTEL:
3203 XGIhw_ext.ulExternalChip = 0x4;
3204 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3205 break;
3206 case HASVB_LVDS_CHRONTEL:
3207 XGIhw_ext.ulExternalChip = 0x5;
3208 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3209 break;
3210 default:
3211 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3212 break;
3213 }
3214
3215 if (xgi_video_info.hasVB != HASVB_NONE) {
3216 XGIfb_detect_VB();
3217 }
3218
3219 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3220 if (XGIfb_crt1off)
3221 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3222 else
3223 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3224 } else {
3225 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3226 }
3227
3228 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
3229 if (!enable_dstn) {
3230 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3231 reg &= 0x0f;
3232 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
3233
3234 } else {
3235 // TW: FSTN/DSTN
3236 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3237 }
3238 }
3239
3240 XGIfb_detectedpdc = 0;
3241
3242 XGIfb_detectedlcda = 0xff;
3243 #ifndef LINUXBIOS
3244
3245 /* TW: Try to find about LCDA */
3246
3247 if((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3248 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3249 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV))
3250 {
3251 int tmp;
3252 inXGIIDXREG(XGICR,0x34,tmp);
3253 if(tmp <= 0x13)
3254 {
3255 // Currently on LCDA? (Some BIOSes leave CR38)
3256 inXGIIDXREG(XGICR,0x38,tmp);
3257 if((tmp & 0x03) == 0x03)
3258 {
3259 /* XGI_Pr.XGI_UseLCDA = 1; */
3260 }else
3261 {
3262 // Currently on LCDA? (Some newer BIOSes set D0 in CR35)
3263 inXGIIDXREG(XGICR,0x35,tmp);
3264 if(tmp & 0x01)
3265 {
3266 /* XGI_Pr.XGI_UseLCDA = 1; */
3267 }else
3268 {
3269 inXGIIDXREG(XGICR,0x30,tmp);
3270 if(tmp & 0x20)
3271 {
3272 inXGIIDXREG(XGIPART1,0x13,tmp);
3273 if(tmp & 0x04)
3274 {
3275 /* XGI_Pr.XGI_UseLCDA = 1; */
3276 }
3277 }
3278 }
3279 }
3280 }
3281
3282 }
3283
3284
3285 #endif
3286
3287 if (xgifb_mode_idx >= 0)
3288 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3289
3290 if (xgifb_mode_idx < 0) {
3291 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3292 case DISPTYPE_LCD:
3293 xgifb_mode_idx = DEFAULT_LCDMODE;
3294 if (xgi_video_info.chip == XG21)
3295 {
3296 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
3297 }
3298 break;
3299 case DISPTYPE_TV:
3300 xgifb_mode_idx = DEFAULT_TVMODE;
3301 break;
3302 default:
3303 xgifb_mode_idx = DEFAULT_MODE;
3304 break;
3305 }
3306 }
3307
3308 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3309
3310
3311 if( xgi_video_info.refresh_rate == 0)
3312 xgi_video_info.refresh_rate = 60; /*yilin set default refresh rate */
3313 if(XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0)
3314 {
3315 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3316 xgi_video_info.refresh_rate = 60;
3317 }
3318
3319 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3320 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3321 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3322 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3323 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
3324 switch(xgi_video_info.video_bpp) {
3325 case 8:
3326 xgi_video_info.DstColor = 0x0000;
3327 xgi_video_info.XGI310_AccelDepth = 0x00000000;
3328 xgi_video_info.video_cmap_len = 256;
3329 break;
3330 case 16:
3331 xgi_video_info.DstColor = 0x8000;
3332 xgi_video_info.XGI310_AccelDepth = 0x00010000;
3333 xgi_video_info.video_cmap_len = 16;
3334 break;
3335 case 32:
3336 xgi_video_info.DstColor = 0xC000;
3337 xgi_video_info.XGI310_AccelDepth = 0x00020000;
3338 xgi_video_info.video_cmap_len = 16;
3339 break;
3340 default:
3341 xgi_video_info.video_cmap_len = 16;
3342 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
3343 break;
3344 }
3345
3346
3347
3348 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
3349 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3350 xgi_video_info.refresh_rate);
3351
3352 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3353 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3354 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3355
3356 XGIfb_bpp_to_var(&default_var);
3357
3358 default_var.pixclock = (u32) (1000000000 /
3359 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3360 XGIfb_mode_no, XGIfb_rate_idx));
3361
3362 if(XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3363 XGIfb_mode_no, XGIfb_rate_idx,
3364 &default_var.left_margin, &default_var.right_margin,
3365 &default_var.upper_margin, &default_var.lower_margin,
3366 &default_var.hsync_len, &default_var.vsync_len,
3367 &default_var.sync, &default_var.vmode)) {
3368
3369 if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3370 default_var.yres <<= 1;
3371 default_var.yres_virtual <<= 1;
3372 } else if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3373 default_var.pixclock >>= 1;
3374 default_var.yres >>= 1;
3375 default_var.yres_virtual >>= 1;
3376 }
3377
3378 }
3379
3380 xgi_video_info.accel = 0;
3381 if(XGIfb_accel) {
3382 xgi_video_info.accel = -1;
3383 default_var.accel_flags |= FB_ACCELF_TEXT;
3384 XGIfb_initaccel();
3385 }
3386
3387 fb_info->flags = FBINFO_FLAG_DEFAULT;
3388 fb_info->var = default_var;
3389 fb_info->fix = XGIfb_fix;
3390 fb_info->par = &xgi_video_info;
3391 fb_info->screen_base = xgi_video_info.video_vbase;
3392 fb_info->fbops = &XGIfb_ops;
3393 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3394 fb_info->pseudo_palette = pseudo_palette;
3395
3396 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3397
3398
3399 #ifdef CONFIG_MTRR
3400 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3401 (unsigned int) xgi_video_info.video_size,
3402 MTRR_TYPE_WRCOMB, 1);
3403 if(xgi_video_info.mtrr) {
3404 printk(KERN_INFO "XGIfb: Added MTRRs\n");
3405 }
3406 #endif
3407
3408 if(register_framebuffer(fb_info) < 0)
3409 {
3410 return -EINVAL;
3411 }
3412
3413 XGIfb_registered = 1;
3414
3415 printk(KERN_INFO "XGIfb: Installed XGIFB_GET_INFO ioctl (%lx)\n",
3416 XGIFB_GET_INFO);
3417
3418 /* printk(KERN_INFO "XGIfb: 2D acceleration is %s, scrolling mode %s\n",
3419 XGIfb_accel ? "enabled" : "disabled",
3420 XGIfb_ypan ? "ypan" : "redraw");
3421 */
3422 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
3423 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
3424
3425
3426 }
3427
3428 dumpVGAReg();
3429
3430 return 0;
3431 }
3432
3433
3434 /*****************************************************/
3435 /* PCI DEVICE HANDLING */
3436 /*****************************************************/
3437
3438 static void __devexit xgifb_remove(struct pci_dev *pdev)
3439 {
3440 /* Unregister the framebuffer */
3441 // if(xgi_video_info.registered) {
3442 unregister_framebuffer(fb_info);
3443 framebuffer_release(fb_info);
3444 // }
3445
3446 pci_set_drvdata(pdev, NULL);
3447
3448 };
3449
3450 static struct pci_driver xgifb_driver = {
3451 .name = "xgifb",
3452 .id_table = xgifb_pci_table,
3453 .probe = xgifb_probe,
3454 .remove = __devexit_p(xgifb_remove)
3455 };
3456
3457 XGIINITSTATIC int __init xgifb_init(void)
3458 {
3459 #ifndef MODULE
3460 char *option = NULL;
3461
3462 if (fb_get_options("xgifb", &option))
3463 return -ENODEV;
3464 XGIfb_setup(option);
3465 #endif
3466 return(pci_register_driver(&xgifb_driver));
3467 }
3468
3469
3470 #ifndef MODULE
3471 module_init(xgifb_init);
3472 #endif
3473
3474 /*****************************************************/
3475 /* MODULE */
3476 /*****************************************************/
3477
3478 #ifdef MODULE
3479
3480 static char *mode = NULL;
3481 static int vesa = 0;
3482 static unsigned int rate = 0;
3483 static unsigned int crt1off = 1;
3484 static unsigned int mem = 0;
3485 static char *forcecrt2type = NULL;
3486 static int forcecrt1 = -1;
3487 static int pdc = -1;
3488 static int pdc1 = -1;
3489 static int noaccel = -1;
3490 static int noypan = -1;
3491 static int nomax = -1;
3492 static int userom = -1;
3493 static int useoem = -1;
3494 static char *tvstandard = NULL;
3495 static int nocrt2rate = 0;
3496 static int scalelcd = -1;
3497 static char *specialtiming = NULL;
3498 static int lvdshl = -1;
3499 static int tvxposoffset = 0, tvyposoffset = 0;
3500 #if !defined(__i386__) && !defined(__x86_64__)
3501 static int resetcard = 0;
3502 static int videoram = 0;
3503 #endif
3504
3505 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3506 MODULE_LICENSE("GPL");
3507 MODULE_AUTHOR("XGITECH , Others");
3508
3509
3510
3511 module_param(mem, int, 0);
3512 module_param(noaccel, int, 0);
3513 module_param(noypan, int, 0);
3514 module_param(nomax, int, 0);
3515 module_param(userom, int, 0);
3516 module_param(useoem, int, 0);
3517 module_param(mode, charp, 0);
3518 module_param(vesa, int, 0);
3519 module_param(rate, int, 0);
3520 module_param(forcecrt1, int, 0);
3521 module_param(forcecrt2type, charp, 0);
3522 module_param(scalelcd, int, 0);
3523 module_param(pdc, int, 0);
3524 module_param(pdc1, int, 0);
3525 module_param(specialtiming, charp, 0);
3526 module_param(lvdshl, int, 0);
3527 module_param(tvstandard, charp, 0);
3528 module_param(tvxposoffset, int, 0);
3529 module_param(tvyposoffset, int, 0);
3530 module_param(filter, int, 0);
3531 module_param(nocrt2rate, int, 0);
3532 #if !defined(__i386__) && !defined(__x86_64__)
3533 module_param(resetcard, int, 0);
3534 module_param(videoram, int, 0);
3535 #endif
3536
3537
3538 MODULE_PARM_DESC(mem,
3539 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3540 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3541 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3542 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3543 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3544 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3545 "for XFree86 4.x/X.org 6.7 and later.\n");
3546
3547 MODULE_PARM_DESC(noaccel,
3548 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3549 "(default: 0)\n");
3550
3551 MODULE_PARM_DESC(noypan,
3552 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3553 "will be performed by redrawing the screen. (default: 0)\n");
3554
3555 MODULE_PARM_DESC(nomax,
3556 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3557 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3558 "this is set to anything other than 0, xgifb will not do this and thereby \n"
3559 "enable the user to positively specify a virtual Y size of the screen using\n"
3560 "fbset. (default: 0)\n");
3561
3562
3563
3564 MODULE_PARM_DESC(mode,
3565 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3566 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3567 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3568 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
3569
3570 MODULE_PARM_DESC(vesa,
3571 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3572 "0x117 (default: 0x0103)\n");
3573
3574
3575 MODULE_PARM_DESC(rate,
3576 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3577 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3578 "will be ignored (default: 60)\n");
3579
3580 MODULE_PARM_DESC(forcecrt1,
3581 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
3582 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3583 "0=CRT1 OFF) (default: [autodetected])\n");
3584
3585 MODULE_PARM_DESC(forcecrt2type,
3586 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3587 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3588 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3589 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3590 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3591 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3592 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3593 "depends on the very hardware in use. (default: [autodetected])\n");
3594
3595 MODULE_PARM_DESC(scalelcd,
3596 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3597 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3598 "show black bars around the image, TMDS panels will probably do the scaling\n"
3599 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
3600
3601 MODULE_PARM_DESC(pdc,
3602 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3603 "should detect this correctly in most cases; however, sometimes this is not\n"
3604 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3605 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3606 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3607 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
3608
3609 MODULE_PARM_DESC(pdc1,
3610 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3611 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3612 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3613 "implemented yet.\n");
3614
3615 MODULE_PARM_DESC(specialtiming,
3616 "\nPlease refer to documentation for more information on this option.\n");
3617
3618 MODULE_PARM_DESC(lvdshl,
3619 "\nPlease refer to documentation for more information on this option.\n");
3620
3621 MODULE_PARM_DESC(tvstandard,
3622 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3623 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
3624
3625 MODULE_PARM_DESC(tvxposoffset,
3626 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3627 "Default: 0\n");
3628
3629 MODULE_PARM_DESC(tvyposoffset,
3630 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3631 "Default: 0\n");
3632
3633 MODULE_PARM_DESC(filter,
3634 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3635 "(Possible values 0-7, default: [no filter])\n");
3636
3637 MODULE_PARM_DESC(nocrt2rate,
3638 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3639 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
3640
3641
3642
3643
3644 int __init xgifb_init_module(void)
3645 {
3646 printk("\nXGIfb_init_module");
3647 if(mode)
3648 XGIfb_search_mode(mode);
3649 else if (vesa != -1)
3650 XGIfb_search_vesamode(vesa);
3651
3652 return(xgifb_init());
3653 }
3654
3655 static void __exit xgifb_remove_module(void)
3656 {
3657 pci_unregister_driver(&xgifb_driver);
3658 printk(KERN_DEBUG "xgifb: Module unloaded\n");
3659 }
3660
3661 module_init(xgifb_init_module);
3662 module_exit(xgifb_remove_module);
3663
3664 #endif /* /MODULE */
3665
3666 EXPORT_SYMBOL(XGI_malloc);
3667 EXPORT_SYMBOL(XGI_free);
3668