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