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