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 #define Index_CR_GPIO_Reg1 0x48
47 #define Index_CR_GPIO_Reg2 0x49
48 #define Index_CR_GPIO_Reg3 0x4a
49
50 #define GPIOG_EN (1<<6)
51 #define GPIOG_WRITE (1<<6)
52 #define GPIOG_READ (1<<1)
53 int XGIfb_GetXG21DefaultLVDSModeIdx(void);
54
55 #define XGIFB_ROM_SIZE 65536
56
57 /* -------------------- Macro definitions ---------------------------- */
58
59 #undef XGIFBDEBUG
60
61 #ifdef XGIFBDEBUG
62 #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63 #else
64 #define DPRINTK(fmt, args...)
65 #endif
66
67 #ifdef XGIFBDEBUG
dumpVGAReg(void)68 static void dumpVGAReg(void)
69 {
70 u8 i, reg;
71
72 outXGIIDXREG(XGISR, 0x05, 0x86);
73 /*
74 outXGIIDXREG(XGISR, 0x08, 0x4f);
75 outXGIIDXREG(XGISR, 0x0f, 0x20);
76 outXGIIDXREG(XGISR, 0x11, 0x4f);
77 outXGIIDXREG(XGISR, 0x13, 0x45);
78 outXGIIDXREG(XGISR, 0x14, 0x51);
79 outXGIIDXREG(XGISR, 0x1e, 0x41);
80 outXGIIDXREG(XGISR, 0x1f, 0x0);
81 outXGIIDXREG(XGISR, 0x20, 0xa1);
82 outXGIIDXREG(XGISR, 0x22, 0xfb);
83 outXGIIDXREG(XGISR, 0x26, 0x22);
84 outXGIIDXREG(XGISR, 0x3e, 0x07);
85 */
86
87 /* outXGIIDXREG(XGICR, 0x19, 0x00); */
88 /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
89 /* outXGIIDXREG(XGICR, 0x22, 0xff); */
90 /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
91
92 /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
93
94 /* outXGIIDXREG(XGICR, 0x57, 0x0); */
95 /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
96
97 /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
98 /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
99 /*
100 outXGIIDXREG(XGICR, 0x99, 0x1);
101 outXGIIDXREG(XGICR, 0x41, 0x40);
102 */
103
104 for (i = 0; i < 0x4f; i++) {
105 inXGIIDXREG(XGISR, i, reg);
106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
108 }
109
110 for (i = 0; i < 0xF0; i++) {
111 inXGIIDXREG(XGICR, i, reg);
112 printk("\no 3d4 %x", i);
113 printk("\ni 3d5 => %x", reg);
114 }
115 /*
116 outXGIIDXREG(XGIPART1,0x2F,1);
117 for (i=1; i < 0x50; i++) {
118 inXGIIDXREG(XGIPART1, i, reg);
119 printk("\no d004 %x", i);
120 printk("\ni d005 => %x", reg);
121 }
122
123 for (i=0; i < 0x50; i++) {
124 inXGIIDXREG(XGIPART2, i, reg);
125 printk("\no d010 %x", i);
126 printk("\ni d011 => %x", reg);
127 }
128 for (i=0; i < 0x50; i++) {
129 inXGIIDXREG(XGIPART3, i, reg);
130 printk("\no d012 %x",i);
131 printk("\ni d013 => %x",reg);
132 }
133 for (i=0; i < 0x50; i++) {
134 inXGIIDXREG(XGIPART4, i, reg);
135 printk("\no d014 %x",i);
136 printk("\ni d015 => %x",reg);
137 }
138 */
139 }
140 #else
dumpVGAReg(void)141 static inline void dumpVGAReg(void)
142 {
143 }
144 #endif
145
146 /* data for XGI components */
147 struct video_info xgi_video_info;
148
149 #if 1
150 #define DEBUGPRN(x)
151 #else
152 #define DEBUGPRN(x) printk(KERN_INFO x "\n");
153 #endif
154
155 /* --------------- Hardware Access Routines -------------------------- */
156
XGIfb_mode_rate_to_dclock(struct vb_device_info * XGI_Pr,struct xgi_hw_device_info * HwDeviceExtension,unsigned char modeno,unsigned char rateindex)157 static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 struct xgi_hw_device_info *HwDeviceExtension,
159 unsigned char modeno, unsigned char rateindex)
160 {
161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
164
165 /* unsigned long temp = 0; */
166 int Clock;
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
169
170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
172
173 /*
174 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
175 if (!temp) {
176 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
177 return 65000;
178 }
179
180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
182
183 */
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
185
186 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
187
188 return Clock;
189 }
190
XGIfb_mode_rate_to_ddata(struct vb_device_info * XGI_Pr,struct xgi_hw_device_info * HwDeviceExtension,unsigned char modeno,unsigned char rateindex,u32 * left_margin,u32 * right_margin,u32 * upper_margin,u32 * lower_margin,u32 * hsync_len,u32 * vsync_len,u32 * sync,u32 * vmode)191 static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192 struct xgi_hw_device_info *HwDeviceExtension,
193 unsigned char modeno, unsigned char rateindex,
194 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
196 u32 *vmode)
197 {
198 unsigned short ModeNo = modeno;
199 unsigned short ModeIdIndex = 0, index = 0;
200 unsigned short RefreshRateTableIndex = 0;
201
202 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204 unsigned char sr_data, cr_data, cr_data2;
205 unsigned long cr_data3;
206 int A, B, C, D, E, F, temp, j;
207 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210 ModeIdIndex, XGI_Pr);
211 /*
212 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
213 if (!temp)
214 return 0;
215
216 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217 RefreshRateTableIndex += (rateindex - 1);
218 */
219 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
220
221 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
222
223 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
224
225 /* Horizontal total */
226 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
227 A = HT + 5;
228
229 /*
230 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
231
232 Horizontal display enable end
233 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
234 */
235 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
236 E = HDE + 1;
237
238 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
239
240 /* Horizontal retrace (=sync) start */
241 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
242 F = HRS - E - 3;
243
244 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
245
246 /* Horizontal blank start */
247 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
248
249 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
250
251 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
252
253 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
254
255 /* Horizontal blank end */
256 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257 | ((unsigned short) (sr_data & 0x03) << 6);
258
259 /* Horizontal retrace (=sync) end */
260 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
261
262 temp = HBE - ((E - 1) & 255);
263 B = (temp > 0) ? temp : (temp + 256);
264
265 temp = HRE - ((E + F + 3) & 63);
266 C = (temp > 0) ? temp : (temp + 64);
267
268 D = B - F - C;
269
270 *left_margin = D * 8;
271 *right_margin = F * 8;
272 *hsync_len = C * 8;
273
274 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
275
276 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
277
278 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
279
280 /* Vertical total */
281 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282 | ((unsigned short) (cr_data2 & 0x20) << 4)
283 | ((unsigned short) (sr_data & 0x01) << 10);
284 A = VT + 2;
285
286 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
287
288 /* Vertical display enable end */
289 /*
290 VDE = (cr_data & 0xff) |
291 ((unsigned short) (cr_data2 & 0x02) << 7) |
292 ((unsigned short) (cr_data2 & 0x40) << 3) |
293 ((unsigned short) (sr_data & 0x02) << 9);
294 */
295 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
296 E = VDE + 1;
297
298 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
299
300 /* Vertical retrace (=sync) start */
301 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302 | ((unsigned short) (cr_data2 & 0x80) << 2)
303 | ((unsigned short) (sr_data & 0x08) << 7);
304 F = VRS + 1 - E;
305
306 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
307
308 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
309
310 /* Vertical blank start */
311 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312 | ((unsigned short) (cr_data3 & 0x20) << 4)
313 | ((unsigned short) (sr_data & 0x04) << 8);
314
315 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
316
317 /* Vertical blank end */
318 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319 temp = VBE - ((E - 1) & 511);
320 B = (temp > 0) ? temp : (temp + 512);
321
322 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
323
324 /* Vertical retrace (=sync) end */
325 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326 temp = VRE - ((E + F - 1) & 31);
327 C = (temp > 0) ? temp : (temp + 32);
328
329 D = B - F - C;
330
331 *upper_margin = D;
332 *lower_margin = F;
333 *vsync_len = C;
334
335 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
337 else
338 *sync |= FB_SYNC_VERT_HIGH_ACT;
339
340 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
342 else
343 *sync |= FB_SYNC_HOR_HIGH_ACT;
344
345 *vmode = FB_VMODE_NONINTERLACED;
346 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347 *vmode = FB_VMODE_INTERLACED;
348 else {
349 j = 0;
350 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
351 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
352 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
354 & DoubleScanMode) {
355 *vmode = FB_VMODE_DOUBLE;
356 }
357 break;
358 }
359 j++;
360 }
361 }
362
363 return 1;
364 }
365
XGIRegInit(struct vb_device_info * XGI_Pr,unsigned long BaseAddr)366 static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
367 {
368 XGI_Pr->RelIO = BaseAddr;
369 XGI_Pr->P3c4 = BaseAddr + 0x14;
370 XGI_Pr->P3d4 = BaseAddr + 0x24;
371 XGI_Pr->P3c0 = BaseAddr + 0x10;
372 XGI_Pr->P3ce = BaseAddr + 0x1e;
373 XGI_Pr->P3c2 = BaseAddr + 0x12;
374 XGI_Pr->P3ca = BaseAddr + 0x1a;
375 XGI_Pr->P3c6 = BaseAddr + 0x16;
376 XGI_Pr->P3c7 = BaseAddr + 0x17;
377 XGI_Pr->P3c8 = BaseAddr + 0x18;
378 XGI_Pr->P3c9 = BaseAddr + 0x19;
379 XGI_Pr->P3da = BaseAddr + 0x2A;
380 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
381 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
382 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
383 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
384 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
385
386 }
387
XGIfb_set_reg4(u16 port,unsigned long data)388 void XGIfb_set_reg4(u16 port, unsigned long data)
389 {
390 outl((u32)(data & 0xffffffff), port);
391 }
392
XGIfb_get_reg3(u16 port)393 u32 XGIfb_get_reg3(u16 port)
394 {
395 u32 data;
396
397 data = inl(port);
398 return data;
399 }
400
401 /* ------------ Interface for init & mode switching code ------------- */
402
XGIfb_query_VGA_config_space(struct xgi_hw_device_info * pXGIhw_ext,unsigned long offset,unsigned long set,unsigned long * value)403 unsigned char XGIfb_query_VGA_config_space(
404 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
405 unsigned long set, unsigned long *value)
406 {
407 static struct pci_dev *pdev = NULL;
408 static unsigned char init = 0, valid_pdev = 0;
409
410 if (!set)
411 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
412 else
413 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
414
415 if (!init) {
416 init = 1;
417 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
418 pdev);
419 if (pdev) {
420 valid_pdev = 1;
421 pci_dev_put(pdev);
422 }
423 }
424
425 if (!valid_pdev) {
426 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
427 xgi_video_info.chip_id);
428 return 0;
429 }
430
431 if (set == 0)
432 pci_read_config_dword(pdev, offset, (u32 *) value);
433 else
434 pci_write_config_dword(pdev, offset, (u32)(*value));
435
436 return 1;
437 }
438
439 /*
440 unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
441 unsigned long offset, unsigned long set, unsigned long *value)
442 {
443 static struct pci_dev *pdev = NULL;
444 static unsigned char init = 0, valid_pdev = 0;
445 u16 nbridge_id = 0;
446
447 if (!init) {
448 init = 1;
449 switch (xgi_video_info.chip) {
450 case XGI_540:
451 nbridge_id = PCI_DEVICE_ID_XG_540;
452 break;
453 case XGI_630:
454 nbridge_id = PCI_DEVICE_ID_XG_630;
455 break;
456 case XGI_730:
457 nbridge_id = PCI_DEVICE_ID_XG_730;
458 break;
459 case XGI_550:
460 nbridge_id = PCI_DEVICE_ID_XG_550;
461 break;
462 case XGI_650:
463 nbridge_id = PCI_DEVICE_ID_XG_650;
464 break;
465 case XGI_740:
466 nbridge_id = PCI_DEVICE_ID_XG_740;
467 break;
468 default:
469 nbridge_id = 0;
470 break;
471 }
472
473 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
474 if (pdev) {
475 valid_pdev = 1;
476 pci_dev_put(pdev);
477 }
478 }
479
480 if (!valid_pdev) {
481 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
482 nbridge_id);
483 return 0;
484 }
485
486 if (set == 0)
487 pci_read_config_dword(pdev, offset, (u32 *)value);
488 else
489 pci_write_config_dword(pdev, offset, (u32)(*value));
490
491 return 1;
492 }
493 */
494 /* ------------------ Internal helper routines ----------------- */
495
XGIfb_search_mode(const char * name)496 static void XGIfb_search_mode(const char *name)
497 {
498 int i = 0, j = 0, l;
499
500 if (name == NULL) {
501 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
502 xgifb_mode_idx = DEFAULT_MODE;
503 if ((xgi_video_info.chip == XG21)
504 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
505 == DISPTYPE_LCD)) {
506 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
507 }
508 return;
509 }
510
511 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
512 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
513 xgifb_mode_idx = DEFAULT_MODE;
514 if ((xgi_video_info.chip == XG21)
515 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
516 == DISPTYPE_LCD)) {
517 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
518 }
519 return;
520 }
521
522 while (XGIbios_mode[i].mode_no != 0) {
523 l = min(strlen(name), strlen(XGIbios_mode[i].name));
524 if (!strncmp(name, XGIbios_mode[i].name, l)) {
525 xgifb_mode_idx = i;
526 j = 1;
527 break;
528 }
529 i++;
530 }
531 if (!j)
532 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
533 }
534
XGIfb_search_vesamode(unsigned int vesamode)535 static void XGIfb_search_vesamode(unsigned int vesamode)
536 {
537 int i = 0, j = 0;
538
539 if (vesamode == 0) {
540
541 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
542 xgifb_mode_idx = DEFAULT_MODE;
543 if ((xgi_video_info.chip == XG21)
544 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
545 == DISPTYPE_LCD)) {
546 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
547 }
548 return;
549 }
550
551 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
552
553 while (XGIbios_mode[i].mode_no != 0) {
554 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
555 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
556 xgifb_mode_idx = i;
557 j = 1;
558 break;
559 }
560 i++;
561 }
562 if (!j)
563 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
564 }
565
XGIfb_GetXG21LVDSData(void)566 static int XGIfb_GetXG21LVDSData(void)
567 {
568 u8 tmp;
569 unsigned char *pData;
570 int i, j, k;
571
572 inXGIIDXREG(XGISR, 0x1e, tmp);
573 outXGIIDXREG(XGISR, 0x1e, tmp | 4);
574
575 pData = xgi_video_info.mmio_vbase + 0x20000;
576 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
577 i = pData[0x316] | (pData[0x317] << 8);
578 j = pData[i - 1];
579 if (j == 0xff)
580 j = 1;
581
582 k = 0;
583 do {
584 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
585 | (pData[i + 1] << 8);
586 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
587 + 3] << 8);
588 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
589 + 5] << 8);
590 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
591 + 7] << 8);
592 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
593 + 9] << 8);
594 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
595 + 11] << 8);
596 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
597 + 13] << 8);
598 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
599 | (pData[i + 15] << 8);
600 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
601 | (pData[i + 17] << 8);
602 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
603 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
604 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
605 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
606 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
607 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
608 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
609 i += 25;
610 j--;
611 k++;
612 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
613 / sizeof(struct XGI21_LVDSCapStruct))));
614 return 1;
615 }
616 return 0;
617 }
618
XGIfb_GetXG21DefaultLVDSModeIdx(void)619 int XGIfb_GetXG21DefaultLVDSModeIdx(void)
620 {
621
622 int found_mode = 0;
623 int XGIfb_mode_idx = 0;
624
625 found_mode = 0;
626 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
627 && (XGIbios_mode[XGIfb_mode_idx].xres
628 <= XGI21_LCDCapList[0].LVDSHDE)) {
629 if ((XGIbios_mode[XGIfb_mode_idx].xres
630 == XGI21_LCDCapList[0].LVDSHDE)
631 && (XGIbios_mode[XGIfb_mode_idx].yres
632 == XGI21_LCDCapList[0].LVDSVDE)
633 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
634 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
635 found_mode = 1;
636 break;
637 }
638 XGIfb_mode_idx++;
639 }
640 if (!found_mode)
641 XGIfb_mode_idx = 0;
642
643 return XGIfb_mode_idx;
644 }
645
XGIfb_validate_mode(int myindex)646 static int XGIfb_validate_mode(int myindex)
647 {
648 u16 xres, yres;
649
650 if (xgi_video_info.chip == XG21) {
651 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
652 == DISPTYPE_LCD) {
653 xres = XGI21_LCDCapList[0].LVDSHDE;
654 yres = XGI21_LCDCapList[0].LVDSVDE;
655 if (XGIbios_mode[myindex].xres > xres)
656 return -1;
657 if (XGIbios_mode[myindex].yres > yres)
658 return -1;
659 if ((XGIbios_mode[myindex].xres < xres)
660 && (XGIbios_mode[myindex].yres < yres)) {
661 if (XGIbios_mode[myindex].bpp > 8)
662 return -1;
663 }
664
665 }
666 return myindex;
667
668 }
669
670 /* FIXME: for now, all is valid on XG27 */
671 if (xgi_video_info.chip == XG27)
672 return myindex;
673
674 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
675 return -1;
676
677 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
678 case DISPTYPE_LCD:
679 switch (XGIhw_ext.ulCRT2LCDType) {
680 case LCD_640x480:
681 xres = 640;
682 yres = 480;
683 break;
684 case LCD_800x600:
685 xres = 800;
686 yres = 600;
687 break;
688 case LCD_1024x600:
689 xres = 1024;
690 yres = 600;
691 break;
692 case LCD_1024x768:
693 xres = 1024;
694 yres = 768;
695 break;
696 case LCD_1152x768:
697 xres = 1152;
698 yres = 768;
699 break;
700 case LCD_1280x960:
701 xres = 1280;
702 yres = 960;
703 break;
704 case LCD_1280x768:
705 xres = 1280;
706 yres = 768;
707 break;
708 case LCD_1280x1024:
709 xres = 1280;
710 yres = 1024;
711 break;
712 case LCD_1400x1050:
713 xres = 1400;
714 yres = 1050;
715 break;
716 case LCD_1600x1200:
717 xres = 1600;
718 yres = 1200;
719 break;
720 /* case LCD_320x480: */ /* TW: FSTN */
721 /*
722 xres = 320;
723 yres = 480;
724 break;
725 */
726 default:
727 xres = 0;
728 yres = 0;
729 break;
730 }
731 if (XGIbios_mode[myindex].xres > xres)
732 return -1;
733 if (XGIbios_mode[myindex].yres > yres)
734 return -1;
735 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
736 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
737 switch (XGIbios_mode[myindex].xres) {
738 case 512:
739 if (XGIbios_mode[myindex].yres != 512)
740 return -1;
741 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
742 return -1;
743 break;
744 case 640:
745 if ((XGIbios_mode[myindex].yres != 400)
746 && (XGIbios_mode[myindex].yres
747 != 480))
748 return -1;
749 break;
750 case 800:
751 if (XGIbios_mode[myindex].yres != 600)
752 return -1;
753 break;
754 case 1024:
755 if ((XGIbios_mode[myindex].yres != 600)
756 && (XGIbios_mode[myindex].yres
757 != 768))
758 return -1;
759 if ((XGIbios_mode[myindex].yres == 600)
760 && (XGIhw_ext.ulCRT2LCDType
761 != LCD_1024x600))
762 return -1;
763 break;
764 case 1152:
765 if ((XGIbios_mode[myindex].yres) != 768)
766 return -1;
767 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
768 return -1;
769 break;
770 case 1280:
771 if ((XGIbios_mode[myindex].yres != 768)
772 && (XGIbios_mode[myindex].yres
773 != 1024))
774 return -1;
775 if ((XGIbios_mode[myindex].yres == 768)
776 && (XGIhw_ext.ulCRT2LCDType
777 != LCD_1280x768))
778 return -1;
779 break;
780 case 1400:
781 if (XGIbios_mode[myindex].yres != 1050)
782 return -1;
783 break;
784 case 1600:
785 if (XGIbios_mode[myindex].yres != 1200)
786 return -1;
787 break;
788 default:
789 return -1;
790 }
791 } else {
792 switch (XGIbios_mode[myindex].xres) {
793 case 512:
794 if (XGIbios_mode[myindex].yres != 512)
795 return -1;
796 break;
797 case 640:
798 if ((XGIbios_mode[myindex].yres != 400)
799 && (XGIbios_mode[myindex].yres
800 != 480))
801 return -1;
802 break;
803 case 800:
804 if (XGIbios_mode[myindex].yres != 600)
805 return -1;
806 break;
807 case 1024:
808 if (XGIbios_mode[myindex].yres != 768)
809 return -1;
810 break;
811 case 1280:
812 if ((XGIbios_mode[myindex].yres != 960)
813 && (XGIbios_mode[myindex].yres
814 != 1024))
815 return -1;
816 if (XGIbios_mode[myindex].yres == 960) {
817 if (XGIhw_ext.ulCRT2LCDType
818 == LCD_1400x1050)
819 return -1;
820 }
821 break;
822 case 1400:
823 if (XGIbios_mode[myindex].yres != 1050)
824 return -1;
825 break;
826 case 1600:
827 if (XGIbios_mode[myindex].yres != 1200)
828 return -1;
829 break;
830 default:
831 return -1;
832 }
833 }
834 break;
835 case DISPTYPE_TV:
836 switch (XGIbios_mode[myindex].xres) {
837 case 512:
838 case 640:
839 case 800:
840 break;
841 case 720:
842 if (xgi_video_info.TV_type == TVMODE_NTSC) {
843 if (XGIbios_mode[myindex].yres != 480)
844 return -1;
845 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
846 if (XGIbios_mode[myindex].yres != 576)
847 return -1;
848 }
849 /* TW: LVDS/CHRONTEL does not support 720 */
850 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
851 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
852 return -1;
853 }
854 break;
855 case 1024:
856 if (xgi_video_info.TV_type == TVMODE_NTSC) {
857 if (XGIbios_mode[myindex].bpp == 32)
858 return -1;
859 }
860 break;
861 default:
862 return -1;
863 }
864 break;
865 case DISPTYPE_CRT2:
866 if (XGIbios_mode[myindex].xres > 1280)
867 return -1;
868 break;
869 }
870 return myindex;
871
872 }
873
XGIfb_search_crt2type(const char * name)874 static void XGIfb_search_crt2type(const char *name)
875 {
876 int i = 0;
877
878 if (name == NULL)
879 return;
880
881 while (XGI_crt2type[i].type_no != -1) {
882 if (!strcmp(name, XGI_crt2type[i].name)) {
883 XGIfb_crt2type = XGI_crt2type[i].type_no;
884 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
885 break;
886 }
887 i++;
888 }
889 if (XGIfb_crt2type < 0)
890 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
891 }
892
XGIfb_search_refresh_rate(unsigned int rate)893 static u8 XGIfb_search_refresh_rate(unsigned int rate)
894 {
895 u16 xres, yres;
896 int i = 0;
897
898 xres = XGIbios_mode[xgifb_mode_idx].xres;
899 yres = XGIbios_mode[xgifb_mode_idx].yres;
900
901 XGIfb_rate_idx = 0;
902 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
903 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
904 == yres)) {
905 if (XGIfb_vrate[i].refresh == rate) {
906 XGIfb_rate_idx = XGIfb_vrate[i].idx;
907 break;
908 } else if (XGIfb_vrate[i].refresh > rate) {
909 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
910 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
911 rate, XGIfb_vrate[i].refresh);
912 XGIfb_rate_idx = XGIfb_vrate[i].idx;
913 xgi_video_info.refresh_rate
914 = XGIfb_vrate[i].refresh;
915 } else if (((rate - XGIfb_vrate[i - 1].refresh)
916 <= 2) && (XGIfb_vrate[i].idx
917 != 1)) {
918 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
919 rate, XGIfb_vrate[i-1].refresh);
920 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
921 xgi_video_info.refresh_rate
922 = XGIfb_vrate[i - 1].refresh;
923 }
924 break;
925 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
926 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
927 rate, XGIfb_vrate[i].refresh);
928 XGIfb_rate_idx = XGIfb_vrate[i].idx;
929 break;
930 }
931 }
932 i++;
933 }
934 if (XGIfb_rate_idx > 0) {
935 return XGIfb_rate_idx;
936 } else {
937 printk(KERN_INFO
938 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
939 return 0;
940 }
941 }
942
XGIfb_search_tvstd(const char * name)943 static void XGIfb_search_tvstd(const char *name)
944 {
945 int i = 0;
946
947 if (name == NULL)
948 return;
949
950 while (XGI_tvtype[i].type_no != -1) {
951 if (!strcmp(name, XGI_tvtype[i].name)) {
952 XGIfb_tvmode = XGI_tvtype[i].type_no;
953 break;
954 }
955 i++;
956 }
957 }
958
959 /* ----------- FBDev related routines for all series ----------- */
960
XGIfb_bpp_to_var(struct fb_var_screeninfo * var)961 static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
962 {
963 switch (var->bits_per_pixel) {
964 case 8:
965 var->red.offset = var->green.offset = var->blue.offset = 0;
966 var->red.length = var->green.length = var->blue.length = 6;
967 xgi_video_info.video_cmap_len = 256;
968 break;
969 case 16:
970 var->red.offset = 11;
971 var->red.length = 5;
972 var->green.offset = 5;
973 var->green.length = 6;
974 var->blue.offset = 0;
975 var->blue.length = 5;
976 var->transp.offset = 0;
977 var->transp.length = 0;
978 xgi_video_info.video_cmap_len = 16;
979 break;
980 case 32:
981 var->red.offset = 16;
982 var->red.length = 8;
983 var->green.offset = 8;
984 var->green.length = 8;
985 var->blue.offset = 0;
986 var->blue.length = 8;
987 var->transp.offset = 24;
988 var->transp.length = 8;
989 xgi_video_info.video_cmap_len = 16;
990 break;
991 }
992 }
993
XGIfb_do_set_var(struct fb_var_screeninfo * var,int isactive,struct fb_info * info)994 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
995 struct fb_info *info)
996 {
997
998 unsigned int htotal = var->left_margin + var->xres + var->right_margin
999 + var->hsync_len;
1000 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1001 + var->vsync_len;
1002 #if defined(__powerpc__)
1003 u8 sr_data, cr_data;
1004 #endif
1005 unsigned int drate = 0, hrate = 0;
1006 int found_mode = 0;
1007 int old_mode;
1008 /* unsigned char reg, reg1; */
1009
1010 DEBUGPRN("Inside do_set_var");
1011 /* 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); */
1012
1013 info->var.xres_virtual = var->xres_virtual;
1014 info->var.yres_virtual = var->yres_virtual;
1015 info->var.bits_per_pixel = var->bits_per_pixel;
1016
1017 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1018 vtotal <<= 1;
1019 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1020 vtotal <<= 2;
1021 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1022 /* vtotal <<= 1; */
1023 /* var->yres <<= 1; */
1024 }
1025
1026 if (!htotal || !vtotal) {
1027 DPRINTK("XGIfb: Invalid 'var' information\n");
1028 return -EINVAL;
1029 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1030 var->pixclock, htotal, vtotal);
1031
1032 if (var->pixclock && htotal && vtotal) {
1033 drate = 1000000000 / var->pixclock;
1034 hrate = (drate * 1000) / htotal;
1035 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1036 / vtotal);
1037 } else {
1038 xgi_video_info.refresh_rate = 60;
1039 }
1040
1041 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
1042 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
1043
1044 old_mode = xgifb_mode_idx;
1045 xgifb_mode_idx = 0;
1046
1047 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1048 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1049 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1050 && (XGIbios_mode[xgifb_mode_idx].yres
1051 == var->yres)
1052 && (XGIbios_mode[xgifb_mode_idx].bpp
1053 == var->bits_per_pixel)) {
1054 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1055 found_mode = 1;
1056 break;
1057 }
1058 xgifb_mode_idx++;
1059 }
1060
1061 if (found_mode)
1062 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1063 else
1064 xgifb_mode_idx = -1;
1065
1066 if (xgifb_mode_idx < 0) {
1067 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
1068 var->yres, var->bits_per_pixel);
1069 xgifb_mode_idx = old_mode;
1070 return -EINVAL;
1071 }
1072
1073 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
1074 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1075 xgi_video_info.refresh_rate = 60;
1076 }
1077
1078 if (isactive) {
1079
1080 XGIfb_pre_setmode();
1081 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
1082 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1083 return -EINVAL;
1084 }
1085 info->fix.line_length = ((info->var.xres_virtual
1086 * info->var.bits_per_pixel) >> 6);
1087
1088 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1089
1090 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1091 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
1092
1093 XGIfb_post_setmode();
1094
1095 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1096 XGIbios_mode[xgifb_mode_idx].xres,
1097 XGIbios_mode[xgifb_mode_idx].yres,
1098 XGIbios_mode[xgifb_mode_idx].bpp,
1099 xgi_video_info.refresh_rate);
1100
1101 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1102 xgi_video_info.video_vwidth = info->var.xres_virtual;
1103 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1104 xgi_video_info.video_vheight = info->var.yres_virtual;
1105 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1106 xgi_video_info.org_x = xgi_video_info.org_y = 0;
1107 xgi_video_info.video_linelength = info->var.xres_virtual
1108 * (xgi_video_info.video_bpp >> 3);
1109 switch (xgi_video_info.video_bpp) {
1110 case 8:
1111 xgi_video_info.DstColor = 0x0000;
1112 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1113 xgi_video_info.video_cmap_len = 256;
1114 #if defined(__powerpc__)
1115 inXGIIDXREG(XGICR, 0x4D, cr_data);
1116 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
1117 #endif
1118 break;
1119 case 16:
1120 xgi_video_info.DstColor = 0x8000;
1121 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1122 #if defined(__powerpc__)
1123 inXGIIDXREG(XGICR, 0x4D, cr_data);
1124 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
1125 #endif
1126 xgi_video_info.video_cmap_len = 16;
1127 break;
1128 case 32:
1129 xgi_video_info.DstColor = 0xC000;
1130 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1131 xgi_video_info.video_cmap_len = 16;
1132 #if defined(__powerpc__)
1133 inXGIIDXREG(XGICR, 0x4D, cr_data);
1134 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
1135 #endif
1136 break;
1137 default:
1138 xgi_video_info.video_cmap_len = 16;
1139 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1140 break;
1141 }
1142 }
1143 XGIfb_bpp_to_var(var); /*update ARGB info*/
1144 DEBUGPRN("End of do_set_var");
1145
1146 dumpVGAReg();
1147 return 0;
1148 }
1149
1150 #ifdef XGIFB_PAN
XGIfb_pan_var(struct fb_var_screeninfo * var)1151 static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1152 {
1153 unsigned int base;
1154
1155 /* printk("Inside pan_var"); */
1156
1157 if (var->xoffset > (var->xres_virtual - var->xres)) {
1158 /* printk("Pan: xo: %d xv %d xr %d\n",
1159 var->xoffset, var->xres_virtual, var->xres); */
1160 return -EINVAL;
1161 }
1162 if (var->yoffset > (var->yres_virtual - var->yres)) {
1163 /* printk("Pan: yo: %d yv %d yr %d\n",
1164 var->yoffset, var->yres_virtual, var->yres); */
1165 return -EINVAL;
1166 }
1167 base = var->yoffset * var->xres_virtual + var->xoffset;
1168
1169 /* calculate base bpp dep. */
1170 switch (var->bits_per_pixel) {
1171 case 16:
1172 base >>= 1;
1173 break;
1174 case 32:
1175 break;
1176 case 8:
1177 default:
1178 base >>= 2;
1179 break;
1180 }
1181
1182 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1183
1184 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
1185 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1186 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
1187 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
1188 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1189
1190 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1191 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1192 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1193 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1194 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
1195 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
1196 }
1197 /* printk("End of pan_var"); */
1198 return 0;
1199 }
1200 #endif
1201
XGIfb_open(struct fb_info * info,int user)1202 static int XGIfb_open(struct fb_info *info, int user)
1203 {
1204 return 0;
1205 }
1206
XGIfb_release(struct fb_info * info,int user)1207 static int XGIfb_release(struct fb_info *info, int user)
1208 {
1209 return 0;
1210 }
1211
XGIfb_get_cmap_len(const struct fb_var_screeninfo * var)1212 static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1213 {
1214 int rc = 16;
1215
1216 switch (var->bits_per_pixel) {
1217 case 8:
1218 rc = 256;
1219 break;
1220 case 16:
1221 rc = 16;
1222 break;
1223 case 32:
1224 rc = 16;
1225 break;
1226 }
1227 return rc;
1228 }
1229
XGIfb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * info)1230 static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1231 unsigned blue, unsigned transp, struct fb_info *info)
1232 {
1233 if (regno >= XGIfb_get_cmap_len(&info->var))
1234 return 1;
1235
1236 switch (info->var.bits_per_pixel) {
1237 case 8:
1238 outXGIREG(XGIDACA, regno);
1239 outXGIREG(XGIDACD, (red >> 10));
1240 outXGIREG(XGIDACD, (green >> 10));
1241 outXGIREG(XGIDACD, (blue >> 10));
1242 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1243 outXGIREG(XGIDAC2A, regno);
1244 outXGIREG(XGIDAC2D, (red >> 8));
1245 outXGIREG(XGIDAC2D, (green >> 8));
1246 outXGIREG(XGIDAC2D, (blue >> 8));
1247 }
1248 break;
1249 case 16:
1250 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1251 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1252 >> 11);
1253 break;
1254 case 32:
1255 red >>= 8;
1256 green >>= 8;
1257 blue >>= 8;
1258 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1259 << 8) | (blue);
1260 break;
1261 }
1262 return 0;
1263 }
1264
XGIfb_set_par(struct fb_info * info)1265 static int XGIfb_set_par(struct fb_info *info)
1266 {
1267 int err;
1268
1269 /* printk("XGIfb: inside set_par\n"); */
1270 err = XGIfb_do_set_var(&info->var, 1, info);
1271 if (err)
1272 return err;
1273 XGIfb_get_fix(&info->fix, -1, info);
1274 /* printk("XGIfb: end of set_par\n"); */
1275 return 0;
1276 }
1277
XGIfb_check_var(struct fb_var_screeninfo * var,struct fb_info * info)1278 static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1279 {
1280 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1281 + var->hsync_len;
1282 unsigned int vtotal = 0;
1283 unsigned int drate = 0, hrate = 0;
1284 int found_mode = 0;
1285 int refresh_rate, search_idx;
1286
1287 DEBUGPRN("Inside check_var");
1288
1289 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1290 vtotal = var->upper_margin + var->yres + var->lower_margin
1291 + var->vsync_len;
1292 vtotal <<= 1;
1293 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1294 vtotal = var->upper_margin + var->yres + var->lower_margin
1295 + var->vsync_len;
1296 vtotal <<= 2;
1297 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1298 vtotal = var->upper_margin + (var->yres / 2)
1299 + var->lower_margin + var->vsync_len;
1300 } else
1301 vtotal = var->upper_margin + var->yres + var->lower_margin
1302 + var->vsync_len;
1303
1304 if (!(htotal) || !(vtotal))
1305 XGIFAIL("XGIfb: no valid timing data");
1306
1307 if (var->pixclock && htotal && vtotal) {
1308 drate = 1000000000 / var->pixclock;
1309 hrate = (drate * 1000) / htotal;
1310 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1311 printk(KERN_DEBUG
1312 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1313 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1314 __func__, var->pixclock, htotal, vtotal,
1315 __func__, drate, hrate, xgi_video_info.refresh_rate);
1316 } else {
1317 xgi_video_info.refresh_rate = 60;
1318 }
1319
1320 /*
1321 if ((var->pixclock) && (htotal)) {
1322 drate = 1E12 / var->pixclock;
1323 hrate = drate / htotal;
1324 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1325 } else {
1326 refresh_rate = 60;
1327 }
1328 */
1329 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
1330 if ((var->xres == 1024) && (var->yres == 600))
1331 refresh_rate = 60;
1332
1333 search_idx = 0;
1334 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1335 (XGIbios_mode[search_idx].xres <= var->xres)) {
1336 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1337 (XGIbios_mode[search_idx].yres == var->yres) &&
1338 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1339 if (XGIfb_validate_mode(search_idx) > 0) {
1340 found_mode = 1;
1341 break;
1342 }
1343 }
1344 search_idx++;
1345 }
1346
1347 if (!found_mode) {
1348
1349 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1350 var->xres, var->yres, var->bits_per_pixel);
1351 search_idx = 0;
1352 while (XGIbios_mode[search_idx].mode_no != 0) {
1353
1354 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1355 (var->yres <= XGIbios_mode[search_idx].yres) &&
1356 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1357 if (XGIfb_validate_mode(search_idx) > 0) {
1358 found_mode = 1;
1359 break;
1360 }
1361 }
1362 search_idx++;
1363 }
1364 if (found_mode) {
1365 var->xres = XGIbios_mode[search_idx].xres;
1366 var->yres = XGIbios_mode[search_idx].yres;
1367 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1368 var->xres, var->yres, var->bits_per_pixel);
1369
1370 } else {
1371 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
1372 var->xres, var->yres, var->bits_per_pixel);
1373 return -EINVAL;
1374 }
1375 }
1376
1377 /* TW: TODO: Check the refresh rate */
1378
1379 /* Adapt RGB settings */
1380 XGIfb_bpp_to_var(var);
1381
1382 /* Sanity check for offsets */
1383 if (var->xoffset < 0)
1384 var->xoffset = 0;
1385 if (var->yoffset < 0)
1386 var->yoffset = 0;
1387
1388 if (!XGIfb_ypan) {
1389 if (var->xres != var->xres_virtual)
1390 var->xres_virtual = var->xres;
1391 if (var->yres != var->yres_virtual)
1392 var->yres_virtual = var->yres;
1393 } /* else { */
1394 /* TW: Now patch yres_virtual if we use panning */
1395 /* May I do this? */
1396 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1397 /* if (var->yres_virtual <= var->yres) { */
1398 /* TW: Paranoia check */
1399 /* var->yres_virtual = var->yres; */
1400 /* } */
1401 /* } */
1402
1403 /* Truncate offsets to maximum if too high */
1404 if (var->xoffset > var->xres_virtual - var->xres)
1405 var->xoffset = var->xres_virtual - var->xres - 1;
1406
1407 if (var->yoffset > var->yres_virtual - var->yres)
1408 var->yoffset = var->yres_virtual - var->yres - 1;
1409
1410 /* Set everything else to 0 */
1411 var->red.msb_right =
1412 var->green.msb_right =
1413 var->blue.msb_right =
1414 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1415
1416 DEBUGPRN("end of check_var");
1417 return 0;
1418 }
1419
1420 #ifdef XGIFB_PAN
XGIfb_pan_display(struct fb_var_screeninfo * var,struct fb_info * info)1421 static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1422 struct fb_info *info)
1423 {
1424 int err;
1425
1426 /* printk("\nInside pan_display:\n"); */
1427
1428 if (var->xoffset > (var->xres_virtual - var->xres))
1429 return -EINVAL;
1430 if (var->yoffset > (var->yres_virtual - var->yres))
1431 return -EINVAL;
1432
1433 if (var->vmode & FB_VMODE_YWRAP) {
1434 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1435 || var->xoffset)
1436 return -EINVAL;
1437 } else {
1438 if (var->xoffset + info->var.xres > info->var.xres_virtual
1439 || var->yoffset + info->var.yres
1440 > info->var.yres_virtual)
1441 return -EINVAL;
1442 }
1443 err = XGIfb_pan_var(var);
1444 if (err < 0)
1445 return err;
1446
1447 info->var.xoffset = var->xoffset;
1448 info->var.yoffset = var->yoffset;
1449 if (var->vmode & FB_VMODE_YWRAP)
1450 info->var.vmode |= FB_VMODE_YWRAP;
1451 else
1452 info->var.vmode &= ~FB_VMODE_YWRAP;
1453
1454 /* printk("End of pan_display\n"); */
1455 return 0;
1456 }
1457 #endif
1458
XGIfb_blank(int blank,struct fb_info * info)1459 static int XGIfb_blank(int blank, struct fb_info *info)
1460 {
1461 u8 reg;
1462
1463 inXGIIDXREG(XGICR, 0x17, reg);
1464
1465 if (blank > 0)
1466 reg &= 0x7f;
1467 else
1468 reg |= 0x80;
1469
1470 outXGIIDXREG(XGICR, 0x17, reg);
1471 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1472 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1473 return 0;
1474 }
1475
1476 /* ----------- FBDev related routines for all series ---------- */
1477
XGIfb_get_fix(struct fb_fix_screeninfo * fix,int con,struct fb_info * info)1478 static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1479 struct fb_info *info)
1480 {
1481 DEBUGPRN("inside get_fix");
1482 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1483
1484 strcpy(fix->id, myid);
1485
1486 fix->smem_start = xgi_video_info.video_base;
1487
1488 fix->smem_len = xgi_video_info.video_size;
1489
1490 fix->type = video_type;
1491 fix->type_aux = 0;
1492 if (xgi_video_info.video_bpp == 8)
1493 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1494 else
1495 fix->visual = FB_VISUAL_DIRECTCOLOR;
1496 fix->xpanstep = 0;
1497 #ifdef XGIFB_PAN
1498 if (XGIfb_ypan)
1499 fix->ypanstep = 1;
1500 #endif
1501 fix->ywrapstep = 0;
1502 fix->line_length = xgi_video_info.video_linelength;
1503 fix->mmio_start = xgi_video_info.mmio_base;
1504 fix->mmio_len = xgi_video_info.mmio_size;
1505 fix->accel = FB_ACCEL_XGI_XABRE;
1506
1507 DEBUGPRN("end of get_fix");
1508 return 0;
1509 }
1510
1511 static struct fb_ops XGIfb_ops = {
1512 .owner = THIS_MODULE,
1513 .fb_open = XGIfb_open,
1514 .fb_release = XGIfb_release,
1515 .fb_check_var = XGIfb_check_var,
1516 .fb_set_par = XGIfb_set_par,
1517 .fb_setcolreg = XGIfb_setcolreg,
1518 #ifdef XGIFB_PAN
1519 .fb_pan_display = XGIfb_pan_display,
1520 #endif
1521 .fb_blank = XGIfb_blank,
1522 .fb_fillrect = cfb_fillrect,
1523 .fb_copyarea = cfb_copyarea,
1524 .fb_imageblit = cfb_imageblit,
1525 /* .fb_mmap = XGIfb_mmap, */
1526 };
1527
1528 /* ---------------- Chip generation dependent routines ---------------- */
1529
1530 /* for XGI 315/550/650/740/330 */
1531
XGIfb_get_dram_size(void)1532 static int XGIfb_get_dram_size(void)
1533 {
1534
1535 u8 ChannelNum, tmp;
1536 u8 reg = 0;
1537
1538 /* xorg driver sets 32MB * 1 channel */
1539 if (xgi_video_info.chip == XG27)
1540 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1541
1542 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1543 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1544 case XGI_DRAM_SIZE_1MB:
1545 xgi_video_info.video_size = 0x100000;
1546 break;
1547 case XGI_DRAM_SIZE_2MB:
1548 xgi_video_info.video_size = 0x200000;
1549 break;
1550 case XGI_DRAM_SIZE_4MB:
1551 xgi_video_info.video_size = 0x400000;
1552 break;
1553 case XGI_DRAM_SIZE_8MB:
1554 xgi_video_info.video_size = 0x800000;
1555 break;
1556 case XGI_DRAM_SIZE_16MB:
1557 xgi_video_info.video_size = 0x1000000;
1558 break;
1559 case XGI_DRAM_SIZE_32MB:
1560 xgi_video_info.video_size = 0x2000000;
1561 break;
1562 case XGI_DRAM_SIZE_64MB:
1563 xgi_video_info.video_size = 0x4000000;
1564 break;
1565 case XGI_DRAM_SIZE_128MB:
1566 xgi_video_info.video_size = 0x8000000;
1567 break;
1568 case XGI_DRAM_SIZE_256MB:
1569 xgi_video_info.video_size = 0x10000000;
1570 break;
1571 default:
1572 return -1;
1573 }
1574
1575 tmp = (reg & 0x0c) >> 2;
1576 switch (xgi_video_info.chip) {
1577 case XG20:
1578 case XG21:
1579 case XG27:
1580 ChannelNum = 1;
1581 break;
1582
1583 case XG42:
1584 if (reg & 0x04)
1585 ChannelNum = 2;
1586 else
1587 ChannelNum = 1;
1588 break;
1589
1590 case XG45:
1591 if (tmp == 1)
1592 ChannelNum = 2;
1593 else if (tmp == 2)
1594 ChannelNum = 3;
1595 else if (tmp == 3)
1596 ChannelNum = 4;
1597 else
1598 ChannelNum = 1;
1599 break;
1600
1601 case XG40:
1602 default:
1603 if (tmp == 2)
1604 ChannelNum = 2;
1605 else if (tmp == 3)
1606 ChannelNum = 3;
1607 else
1608 ChannelNum = 1;
1609 break;
1610 }
1611
1612 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1613 /* PLiad fixed for benchmarking and fb set */
1614 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1615 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
1616
1617 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1618 xgi_video_info.video_size, ChannelNum);
1619 return 0;
1620
1621 }
1622
XGIfb_detect_VB(void)1623 static void XGIfb_detect_VB(void)
1624 {
1625 u8 cr32, temp = 0;
1626
1627 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1628
1629 switch (xgi_video_info.hasVB) {
1630 case HASVB_LVDS_CHRONTEL:
1631 case HASVB_CHRONTEL:
1632 break;
1633 case HASVB_301:
1634 case HASVB_302:
1635 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1636 break;
1637 }
1638
1639 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1640
1641 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1642 XGIfb_crt1off = 0;
1643 else {
1644 if (cr32 & 0x5F)
1645 XGIfb_crt1off = 1;
1646 else
1647 XGIfb_crt1off = 0;
1648 }
1649
1650 if (XGIfb_crt2type != -1)
1651 /* TW: Override with option */
1652 xgi_video_info.disp_state = XGIfb_crt2type;
1653 else if (cr32 & XGI_VB_TV)
1654 xgi_video_info.disp_state = DISPTYPE_TV;
1655 else if (cr32 & XGI_VB_LCD)
1656 xgi_video_info.disp_state = DISPTYPE_LCD;
1657 else if (cr32 & XGI_VB_CRT2)
1658 xgi_video_info.disp_state = DISPTYPE_CRT2;
1659 else
1660 xgi_video_info.disp_state = 0;
1661
1662 if (XGIfb_tvplug != -1)
1663 /* PR/TW: Override with option */
1664 xgi_video_info.TV_plug = XGIfb_tvplug;
1665 else if (cr32 & XGI_VB_HIVISION) {
1666 xgi_video_info.TV_type = TVMODE_HIVISION;
1667 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1668 } else if (cr32 & XGI_VB_SVIDEO)
1669 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1670 else if (cr32 & XGI_VB_COMPOSITE)
1671 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1672 else if (cr32 & XGI_VB_SCART)
1673 xgi_video_info.TV_plug = TVPLUG_SCART;
1674
1675 if (xgi_video_info.TV_type == 0) {
1676 inXGIIDXREG(XGICR, 0x38, temp);
1677 if (temp & 0x10)
1678 xgi_video_info.TV_type = TVMODE_PAL;
1679 else
1680 xgi_video_info.TV_type = TVMODE_NTSC;
1681 }
1682
1683 /* TW: Copy forceCRT1 option to CRT1off if option is given */
1684 if (XGIfb_forcecrt1 != -1) {
1685 if (XGIfb_forcecrt1)
1686 XGIfb_crt1off = 0;
1687 else
1688 XGIfb_crt1off = 1;
1689 }
1690 }
1691
XGIfb_get_VB_type(void)1692 static void XGIfb_get_VB_type(void)
1693 {
1694 u8 reg;
1695
1696 if (!XGIfb_has_VB()) {
1697 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
1698 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1699 case XGI310_EXTERNAL_CHIP_LVDS:
1700 xgi_video_info.hasVB = HASVB_LVDS;
1701 break;
1702 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1703 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1704 break;
1705 default:
1706 break;
1707 }
1708 }
1709 }
1710
XGIfb_has_VB(void)1711 static int XGIfb_has_VB(void)
1712 {
1713 u8 vb_chipid;
1714
1715 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1716 switch (vb_chipid) {
1717 case 0x01:
1718 xgi_video_info.hasVB = HASVB_301;
1719 break;
1720 case 0x02:
1721 xgi_video_info.hasVB = HASVB_302;
1722 break;
1723 default:
1724 xgi_video_info.hasVB = HASVB_NONE;
1725 return 0;
1726 }
1727 return 1;
1728 }
1729
1730 /* ------------------ Sensing routines ------------------ */
1731
1732 /* TW: Determine and detect attached devices on XGI30x */
XGIDoSense(int tempbl,int tempbh,int tempcl,int tempch)1733 int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
1734 {
1735 int temp, i;
1736
1737 outXGIIDXREG(XGIPART4, 0x11, tempbl);
1738 temp = tempbh | tempcl;
1739 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1740 for (i = 0; i < 10; i++)
1741 XGI_LongWait(&XGI_Pr);
1742 tempch &= 0x7f;
1743 inXGIIDXREG(XGIPART4, 0x03, temp);
1744 temp ^= 0x0e;
1745 temp &= tempch;
1746 return temp;
1747 }
1748
XGI_Sense30x(void)1749 void XGI_Sense30x(void)
1750 {
1751 u8 backupP4_0d;
1752 u8 testsvhs_tempbl, testsvhs_tempbh;
1753 u8 testsvhs_tempcl, testsvhs_tempch;
1754 u8 testcvbs_tempbl, testcvbs_tempbh;
1755 u8 testcvbs_tempcl, testcvbs_tempch;
1756 u8 testvga2_tempbl, testvga2_tempbh;
1757 u8 testvga2_tempcl, testvga2_tempch;
1758 int myflag, result;
1759
1760 inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1761 outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
1762
1763 testvga2_tempbh = 0x00;
1764 testvga2_tempbl = 0xd1;
1765 testsvhs_tempbh = 0x00;
1766 testsvhs_tempbl = 0xb9;
1767 testcvbs_tempbh = 0x00;
1768 testcvbs_tempbl = 0xb3;
1769 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
1770 != VB_CHIP_302)) {
1771 testvga2_tempbh = 0x01;
1772 testvga2_tempbl = 0x90;
1773 testsvhs_tempbh = 0x01;
1774 testsvhs_tempbl = 0x6b;
1775 testcvbs_tempbh = 0x01;
1776 testcvbs_tempbl = 0x74;
1777 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
1778 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
1779 testvga2_tempbh = 0x00;
1780 testvga2_tempbl = 0x00;
1781 testsvhs_tempbh = 0x02;
1782 testsvhs_tempbl = 0x00;
1783 testcvbs_tempbh = 0x01;
1784 testcvbs_tempbl = 0x00;
1785 }
1786 }
1787 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
1788 != VB_CHIP_302LV) {
1789 inXGIIDXREG(XGIPART4, 0x01, myflag);
1790 if (myflag & 0x04) {
1791 testvga2_tempbh = 0x00;
1792 testvga2_tempbl = 0xfd;
1793 testsvhs_tempbh = 0x00;
1794 testsvhs_tempbl = 0xdd;
1795 testcvbs_tempbh = 0x00;
1796 testcvbs_tempbl = 0xee;
1797 }
1798 }
1799 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
1800 == VB_CHIP_302LV)) {
1801 testvga2_tempbh = 0x00;
1802 testvga2_tempbl = 0x00;
1803 testvga2_tempch = 0x00;
1804 testvga2_tempcl = 0x00;
1805 testsvhs_tempch = 0x04;
1806 testsvhs_tempcl = 0x08;
1807 testcvbs_tempch = 0x08;
1808 testcvbs_tempcl = 0x08;
1809 } else {
1810 testvga2_tempch = 0x0e;
1811 testvga2_tempcl = 0x08;
1812 testsvhs_tempch = 0x06;
1813 testsvhs_tempcl = 0x04;
1814 testcvbs_tempch = 0x08;
1815 testcvbs_tempcl = 0x04;
1816 }
1817
1818 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
1819 || testvga2_tempbl) {
1820 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
1821 testvga2_tempcl, testvga2_tempch);
1822 if (result) {
1823 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
1824 orXGIIDXREG(XGICR, 0x32, 0x10);
1825 }
1826 }
1827
1828 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
1829 testsvhs_tempch);
1830 if (result) {
1831 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
1832 /* TW: So we can be sure that there IS a SVHS output */
1833 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1834 orXGIIDXREG(XGICR, 0x32, 0x02);
1835 }
1836
1837 if (!result) {
1838 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
1839 testcvbs_tempcl, testcvbs_tempch);
1840 if (result) {
1841 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
1842 /* TW: So we can be sure that there IS a CVBS output */
1843 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1844 orXGIIDXREG(XGICR, 0x32, 0x01);
1845 }
1846 }
1847 XGIDoSense(0, 0, 0, 0);
1848
1849 outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1850 }
1851
1852 /* --------------------- SetMode routines ------------------------- */
1853
XGIfb_pre_setmode(void)1854 static void XGIfb_pre_setmode(void)
1855 {
1856 u8 cr30 = 0, cr31 = 0;
1857
1858 inXGIIDXREG(XGICR, 0x31, cr31);
1859 cr31 &= ~0x60;
1860
1861 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1862 case DISPTYPE_CRT2:
1863 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1864 cr31 |= XGI_DRIVER_MODE;
1865 break;
1866 case DISPTYPE_LCD:
1867 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
1868 cr31 |= XGI_DRIVER_MODE;
1869 break;
1870 case DISPTYPE_TV:
1871 if (xgi_video_info.TV_type == TVMODE_HIVISION)
1872 cr30 = (XGI_VB_OUTPUT_HIVISION
1873 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1874 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
1875 cr30 = (XGI_VB_OUTPUT_SVIDEO
1876 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1877 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
1878 cr30 = (XGI_VB_OUTPUT_COMPOSITE
1879 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1880 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
1881 cr30 = (XGI_VB_OUTPUT_SCART
1882 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1883 cr31 |= XGI_DRIVER_MODE;
1884
1885 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
1886 cr31 |= 0x01;
1887 else
1888 cr31 &= ~0x01;
1889 break;
1890 default: /* disable CRT2 */
1891 cr30 = 0x00;
1892 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
1893 }
1894
1895 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
1896 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
1897 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
1898 }
1899
XGIfb_post_setmode(void)1900 static void XGIfb_post_setmode(void)
1901 {
1902 u8 reg;
1903 unsigned char doit = 1;
1904 /*
1905 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1906 outXGIIDXREG(XGICR, 0x13, 0x00);
1907 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
1908 *test*
1909 */
1910 if (xgi_video_info.video_bpp == 8) {
1911 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
1912 if ((xgi_video_info.hasVB == HASVB_LVDS)
1913 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
1914 doit = 0;
1915 }
1916 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
1917 if (xgi_video_info.disp_state & DISPTYPE_LCD)
1918 doit = 0;
1919 }
1920
1921 /* TW: We can't switch off CRT1 if bridge is in slave mode */
1922 if (xgi_video_info.hasVB != HASVB_NONE) {
1923 inXGIIDXREG(XGIPART1, 0x00, reg);
1924
1925 if ((reg & 0x50) == 0x10)
1926 doit = 0;
1927
1928 } else {
1929 XGIfb_crt1off = 0;
1930 }
1931
1932 inXGIIDXREG(XGICR, 0x17, reg);
1933 if ((XGIfb_crt1off) && (doit))
1934 reg &= ~0x80;
1935 else
1936 reg |= 0x80;
1937 outXGIIDXREG(XGICR, 0x17, reg);
1938
1939 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1940
1941 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1942 == HASVB_301)) {
1943
1944 inXGIIDXREG(XGIPART4, 0x01, reg);
1945
1946 if (reg < 0xB0) { /* Set filter for XGI301 */
1947
1948 switch (xgi_video_info.video_width) {
1949 case 320:
1950 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
1951 break;
1952 case 640:
1953 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
1954 break;
1955 case 720:
1956 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
1957 break;
1958 case 800:
1959 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
1960 break;
1961 default:
1962 filter = -1;
1963 break;
1964 }
1965
1966 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1967
1968 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1969
1970 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
1971
1972 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1973
1974 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
1975
1976 } else if (xgi_video_info.TV_plug
1977 == TVPLUG_COMPOSITE) {
1978
1979 orXGIIDXREG(XGIPART2, 0x30, 0x20);
1980
1981 switch (xgi_video_info.video_width) {
1982 case 640:
1983 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
1984 outXGIIDXREG(XGIPART2, 0x36, 0x04);
1985 outXGIIDXREG(XGIPART2, 0x37, 0x25);
1986 outXGIIDXREG(XGIPART2, 0x38, 0x18);
1987 break;
1988 case 720:
1989 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
1990 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
1991 outXGIIDXREG(XGIPART2, 0x37, 0x22);
1992 outXGIIDXREG(XGIPART2, 0x38, 0x08);
1993 break;
1994 case 800:
1995 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
1996 outXGIIDXREG(XGIPART2, 0x36, 0x15);
1997 outXGIIDXREG(XGIPART2, 0x37, 0x25);
1998 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
1999 break;
2000 }
2001 }
2002
2003 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2004
2005 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2006
2007 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2008
2009 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2010
2011 } else if (xgi_video_info.TV_plug
2012 == TVPLUG_COMPOSITE) {
2013
2014 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2015
2016 switch (xgi_video_info.video_width) {
2017 case 640:
2018 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2019 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2020 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2021 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2022 break;
2023 case 720:
2024 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2025 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2026 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2027 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2028 break;
2029 case 800:
2030 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2031 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2032 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2033 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2034 break;
2035 }
2036 }
2037 }
2038
2039 if ((filter >= 0) && (filter <= 7)) {
2040 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2041 XGI_TV_filter[filter_tb].filter[filter][0],
2042 XGI_TV_filter[filter_tb].filter[filter][1],
2043 XGI_TV_filter[filter_tb].filter[filter][2],
2044 XGI_TV_filter[filter_tb].filter[filter][3]
2045 );
2046 outXGIIDXREG(
2047 XGIPART2,
2048 0x35,
2049 (XGI_TV_filter[filter_tb].filter[filter][0]));
2050 outXGIIDXREG(
2051 XGIPART2,
2052 0x36,
2053 (XGI_TV_filter[filter_tb].filter[filter][1]));
2054 outXGIIDXREG(
2055 XGIPART2,
2056 0x37,
2057 (XGI_TV_filter[filter_tb].filter[filter][2]));
2058 outXGIIDXREG(
2059 XGIPART2,
2060 0x38,
2061 (XGI_TV_filter[filter_tb].filter[filter][3]));
2062 }
2063
2064 }
2065
2066 }
2067
2068 }
2069
XGIfb_setup(char * options)2070 XGIINITSTATIC int __init XGIfb_setup(char *options)
2071 {
2072 char *this_opt;
2073
2074 xgi_video_info.refresh_rate = 0;
2075
2076 printk(KERN_INFO "XGIfb: Options %s\n", options);
2077
2078 if (!options || !*options)
2079 return 0;
2080
2081 while ((this_opt = strsep(&options, ",")) != NULL) {
2082
2083 if (!*this_opt)
2084 continue;
2085
2086 if (!strncmp(this_opt, "mode:", 5)) {
2087 XGIfb_search_mode(this_opt + 5);
2088 } else if (!strncmp(this_opt, "vesa:", 5)) {
2089 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2090 } else if (!strncmp(this_opt, "mode:", 5)) {
2091 XGIfb_search_mode(this_opt + 5);
2092 } else if (!strncmp(this_opt, "vesa:", 5)) {
2093 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2094 } else if (!strncmp(this_opt, "vrate:", 6)) {
2095 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2096 } else if (!strncmp(this_opt, "rate:", 5)) {
2097 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2098 } else if (!strncmp(this_opt, "off", 3)) {
2099 XGIfb_off = 1;
2100 } else if (!strncmp(this_opt, "crt1off", 7)) {
2101 XGIfb_crt1off = 1;
2102 } else if (!strncmp(this_opt, "filter:", 7)) {
2103 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2104 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2105 XGIfb_search_crt2type(this_opt + 14);
2106 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2107 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
2108 } else if (!strncmp(this_opt, "tvmode:", 7)) {
2109 XGIfb_search_tvstd(this_opt + 7);
2110 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2111 XGIfb_search_tvstd(this_opt + 7);
2112 } else if (!strncmp(this_opt, "dstn", 4)) {
2113 enable_dstn = 1;
2114 /* TW: DSTN overrules forcecrt2type */
2115 XGIfb_crt2type = DISPTYPE_LCD;
2116 } else if (!strncmp(this_opt, "pdc:", 4)) {
2117 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2118 if (XGIfb_pdc & ~0x3c) {
2119 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2120 XGIfb_pdc = 0;
2121 }
2122 } else if (!strncmp(this_opt, "noypan", 6)) {
2123 XGIfb_ypan = 0;
2124 } else if (!strncmp(this_opt, "userom:", 7)) {
2125 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
2126 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2127 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
2128 } else {
2129 XGIfb_search_mode(this_opt);
2130 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
2131 }
2132
2133 /* TW: Panning only with acceleration */
2134 XGIfb_ypan = 0;
2135
2136 }
2137 printk("\nxgifb: outa xgifb_setup 3450");
2138 return 0;
2139 }
2140
xgifb_copy_rom(struct pci_dev * dev)2141 static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
2142 {
2143 void __iomem *rom_address;
2144 unsigned char *rom_copy;
2145 size_t rom_size;
2146
2147 rom_address = pci_map_rom(dev, &rom_size);
2148 if (rom_address == NULL)
2149 return NULL;
2150
2151 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2152 if (rom_copy == NULL)
2153 goto done;
2154
2155 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2156 memcpy_fromio(rom_copy, rom_address, rom_size);
2157
2158 done:
2159 pci_unmap_rom(dev, rom_address);
2160 return rom_copy;
2161 }
2162
xgifb_probe(struct pci_dev * pdev,const struct pci_device_id * ent)2163 static int __devinit xgifb_probe(struct pci_dev *pdev,
2164 const struct pci_device_id *ent)
2165 {
2166 u8 reg, reg1;
2167 u8 CR48, CR38;
2168 int ret;
2169
2170 if (XGIfb_off)
2171 return -ENXIO;
2172
2173 XGIfb_registered = 0;
2174
2175 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
2176 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2177 if (!fb_info)
2178 return -ENOMEM;
2179
2180 xgi_video_info.chip_id = pdev->device;
2181 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2182 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2183
2184 xgi_video_info.pcibus = pdev->bus->number;
2185 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2186 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2187 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2188 xgi_video_info.subsysdevice = pdev->subsystem_device;
2189
2190 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2191 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2192 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
2193 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2194 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2195 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2196 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2197 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
2198
2199 if (pci_enable_device(pdev)) {
2200 ret = -EIO;
2201 goto error;
2202 }
2203
2204 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
2205
2206 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2207 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
2208
2209 if (reg1 != 0xa1) { /*I/O error */
2210 printk("\nXGIfb: I/O error!!!");
2211 ret = -EIO;
2212 goto error;
2213 }
2214
2215 switch (xgi_video_info.chip_id) {
2216 case PCI_DEVICE_ID_XG_20:
2217 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2218 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2219 if (CR48&GPIOG_READ)
2220 xgi_video_info.chip = XG21;
2221 else
2222 xgi_video_info.chip = XG20;
2223 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2224 break;
2225 case PCI_DEVICE_ID_XG_40:
2226 xgi_video_info.chip = XG40;
2227 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2228 break;
2229 case PCI_DEVICE_ID_XG_41:
2230 xgi_video_info.chip = XG41;
2231 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2232 break;
2233 case PCI_DEVICE_ID_XG_42:
2234 xgi_video_info.chip = XG42;
2235 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2236 break;
2237 case PCI_DEVICE_ID_XG_27:
2238 xgi_video_info.chip = XG27;
2239 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2240 break;
2241 default:
2242 ret = -ENODEV;
2243 goto error;
2244 }
2245
2246 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2247 XGIhw_ext.jChipType = xgi_video_info.chip;
2248
2249 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
2250 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
2251 if (XGIhw_ext.pjVirtualRomBase)
2252 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
2253 else
2254 printk(KERN_INFO "XGIfb: Video ROM not found\n");
2255 } else {
2256 XGIhw_ext.pjVirtualRomBase = NULL;
2257 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
2258 }
2259 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
2260
2261 if (XGIfb_get_dram_size()) {
2262 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
2263 ret = -ENODEV;
2264 goto error;
2265 }
2266
2267 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2268 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2269 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2270 /* Enable 2D accelerator engine */
2271 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2272 }
2273
2274 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2275
2276 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
2277 printk("unable request memory size %x", xgi_video_info.video_size);
2278 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2279 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
2280 ret = -ENODEV;
2281 goto error;
2282 }
2283
2284 if (!request_mem_region(xgi_video_info.mmio_base,
2285 xgi_video_info.mmio_size,
2286 "XGIfb MMIO")) {
2287 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
2288 ret = -ENODEV;
2289 goto error_0;
2290 }
2291
2292 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2293 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
2294 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2295 xgi_video_info.mmio_size);
2296
2297 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2298 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
2299
2300 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
2301 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2302 xgi_video_info.mmio_size / 1024);
2303 printk("XGIfb: XGIInitNew() ...");
2304 if (XGIInitNew(&XGIhw_ext))
2305 printk("OK\n");
2306 else
2307 printk("Fail\n");
2308
2309 xgi_video_info.mtrr = (unsigned int) 0;
2310
2311 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2312 xgi_video_info.hasVB = HASVB_NONE;
2313 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
2314 xgi_video_info.hasVB = HASVB_NONE;
2315 } else if (xgi_video_info.chip == XG21) {
2316 inXGIIDXREG(XGICR, 0x38, CR38);
2317 if ((CR38&0xE0) == 0xC0) {
2318 xgi_video_info.disp_state = DISPTYPE_LCD;
2319 if (!XGIfb_GetXG21LVDSData()) {
2320 int m;
2321 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2322 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2323 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2324 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2325 }
2326 }
2327 }
2328 } else if ((CR38&0xE0) == 0x60) {
2329 xgi_video_info.hasVB = HASVB_CHRONTEL;
2330 } else {
2331 xgi_video_info.hasVB = HASVB_NONE;
2332 }
2333 } else {
2334 XGIfb_get_VB_type();
2335 }
2336
2337 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
2338
2339 XGIhw_ext.ulExternalChip = 0;
2340
2341 switch (xgi_video_info.hasVB) {
2342 case HASVB_301:
2343 inXGIIDXREG(XGIPART4, 0x01, reg);
2344 if (reg >= 0xE0) {
2345 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2346 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2347 } else if (reg >= 0xD0) {
2348 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2349 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2350 }
2351 /* else if (reg >= 0xB0) {
2352 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
2353 inXGIIDXREG(XGIPART4, 0x23, reg1);
2354 printk("XGIfb: XGI301B bridge detected\n");
2355 } */
2356 else {
2357 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2358 printk("XGIfb: XGI301 bridge detected\n");
2359 }
2360 break;
2361 case HASVB_302:
2362 inXGIIDXREG(XGIPART4, 0x01, reg);
2363 if (reg >= 0xE0) {
2364 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
2365 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2366 } else if (reg >= 0xD0) {
2367 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
2368 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2369 } else if (reg >= 0xB0) {
2370 inXGIIDXREG(XGIPART4, 0x23, reg1);
2371
2372 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
2373
2374 } else {
2375 XGIhw_ext.ujVBChipID = VB_CHIP_302;
2376 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2377 }
2378 break;
2379 case HASVB_LVDS:
2380 XGIhw_ext.ulExternalChip = 0x1;
2381 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2382 break;
2383 case HASVB_TRUMPION:
2384 XGIhw_ext.ulExternalChip = 0x2;
2385 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2386 break;
2387 case HASVB_CHRONTEL:
2388 XGIhw_ext.ulExternalChip = 0x4;
2389 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2390 break;
2391 case HASVB_LVDS_CHRONTEL:
2392 XGIhw_ext.ulExternalChip = 0x5;
2393 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2394 break;
2395 default:
2396 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2397 break;
2398 }
2399
2400 if (xgi_video_info.hasVB != HASVB_NONE)
2401 XGIfb_detect_VB();
2402
2403 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2404 if (XGIfb_crt1off)
2405 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2406 else
2407 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
2408 } else {
2409 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
2410 }
2411
2412 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
2413 if (!enable_dstn) {
2414 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
2415 reg &= 0x0f;
2416 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
2417
2418 } else {
2419 /* TW: FSTN/DSTN */
2420 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2421 }
2422 }
2423
2424 XGIfb_detectedpdc = 0;
2425
2426 XGIfb_detectedlcda = 0xff;
2427
2428 /* TW: Try to find about LCDA */
2429
2430 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2431 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2432 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2433 int tmp;
2434 inXGIIDXREG(XGICR, 0x34, tmp);
2435 if (tmp <= 0x13) {
2436 /* Currently on LCDA? (Some BIOSes leave CR38) */
2437 inXGIIDXREG(XGICR, 0x38, tmp);
2438 if ((tmp & 0x03) == 0x03) {
2439 /* XGI_Pr.XGI_UseLCDA = 1; */
2440 } else {
2441 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
2442 inXGIIDXREG(XGICR, 0x35, tmp);
2443 if (tmp & 0x01) {
2444 /* XGI_Pr.XGI_UseLCDA = 1; */
2445 } else {
2446 inXGIIDXREG(XGICR, 0x30, tmp);
2447 if (tmp & 0x20) {
2448 inXGIIDXREG(XGIPART1, 0x13, tmp);
2449 if (tmp & 0x04) {
2450 /* XGI_Pr.XGI_UseLCDA = 1; */
2451 }
2452 }
2453 }
2454 }
2455 }
2456
2457 }
2458
2459 if (xgifb_mode_idx >= 0)
2460 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2461
2462 if (xgifb_mode_idx < 0) {
2463 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2464 case DISPTYPE_LCD:
2465 xgifb_mode_idx = DEFAULT_LCDMODE;
2466 if (xgi_video_info.chip == XG21)
2467 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
2468 break;
2469 case DISPTYPE_TV:
2470 xgifb_mode_idx = DEFAULT_TVMODE;
2471 break;
2472 default:
2473 xgifb_mode_idx = DEFAULT_MODE;
2474 break;
2475 }
2476 }
2477
2478 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2479
2480 if (xgi_video_info.refresh_rate == 0)
2481 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
2482 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
2483 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2484 xgi_video_info.refresh_rate = 60;
2485 }
2486
2487 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2488 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
2489 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
2490 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2491 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
2492 switch (xgi_video_info.video_bpp) {
2493 case 8:
2494 xgi_video_info.DstColor = 0x0000;
2495 xgi_video_info.XGI310_AccelDepth = 0x00000000;
2496 xgi_video_info.video_cmap_len = 256;
2497 break;
2498 case 16:
2499 xgi_video_info.DstColor = 0x8000;
2500 xgi_video_info.XGI310_AccelDepth = 0x00010000;
2501 xgi_video_info.video_cmap_len = 16;
2502 break;
2503 case 32:
2504 xgi_video_info.DstColor = 0xC000;
2505 xgi_video_info.XGI310_AccelDepth = 0x00020000;
2506 xgi_video_info.video_cmap_len = 16;
2507 break;
2508 default:
2509 xgi_video_info.video_cmap_len = 16;
2510 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
2511 break;
2512 }
2513
2514 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
2515 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
2516 xgi_video_info.refresh_rate);
2517
2518 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
2519 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
2520 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2521
2522 XGIfb_bpp_to_var(&default_var);
2523
2524 default_var.pixclock = (u32) (1000000000 /
2525 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2526 XGIfb_mode_no, XGIfb_rate_idx));
2527
2528 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2529 XGIfb_mode_no, XGIfb_rate_idx,
2530 &default_var.left_margin, &default_var.right_margin,
2531 &default_var.upper_margin, &default_var.lower_margin,
2532 &default_var.hsync_len, &default_var.vsync_len,
2533 &default_var.sync, &default_var.vmode)) {
2534
2535 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
2536 default_var.yres <<= 1;
2537 default_var.yres_virtual <<= 1;
2538 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
2539 default_var.pixclock >>= 1;
2540 default_var.yres >>= 1;
2541 default_var.yres_virtual >>= 1;
2542 }
2543
2544 }
2545
2546 fb_info->flags = FBINFO_FLAG_DEFAULT;
2547 fb_info->var = default_var;
2548 fb_info->fix = XGIfb_fix;
2549 fb_info->par = &xgi_video_info;
2550 fb_info->screen_base = xgi_video_info.video_vbase;
2551 fb_info->fbops = &XGIfb_ops;
2552 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2553 fb_info->pseudo_palette = pseudo_palette;
2554
2555 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2556
2557 #ifdef CONFIG_MTRR
2558 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
2559 (unsigned int) xgi_video_info.video_size,
2560 MTRR_TYPE_WRCOMB, 1);
2561 if (xgi_video_info.mtrr)
2562 printk(KERN_INFO "XGIfb: Added MTRRs\n");
2563 #endif
2564
2565 if (register_framebuffer(fb_info) < 0) {
2566 ret = -EINVAL;
2567 goto error_1;
2568 }
2569
2570 XGIfb_registered = 1;
2571
2572 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
2573 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
2574
2575 }
2576
2577 dumpVGAReg();
2578
2579 return 0;
2580
2581 error_1:
2582 iounmap(xgi_video_info.mmio_vbase);
2583 iounmap(xgi_video_info.video_vbase);
2584 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2585 error_0:
2586 release_mem_region(xgi_video_info.video_base,
2587 xgi_video_info.video_size);
2588 error:
2589 vfree(XGIhw_ext.pjVirtualRomBase);
2590 framebuffer_release(fb_info);
2591 return ret;
2592 }
2593
2594 /*****************************************************/
2595 /* PCI DEVICE HANDLING */
2596 /*****************************************************/
2597
xgifb_remove(struct pci_dev * pdev)2598 static void __devexit xgifb_remove(struct pci_dev *pdev)
2599 {
2600 unregister_framebuffer(fb_info);
2601 iounmap(xgi_video_info.mmio_vbase);
2602 iounmap(xgi_video_info.video_vbase);
2603 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
2604 release_mem_region(xgi_video_info.video_base,
2605 xgi_video_info.video_size);
2606 vfree(XGIhw_ext.pjVirtualRomBase);
2607 framebuffer_release(fb_info);
2608 pci_set_drvdata(pdev, NULL);
2609 }
2610
2611 static struct pci_driver xgifb_driver = {
2612 .name = "xgifb",
2613 .id_table = xgifb_pci_table,
2614 .probe = xgifb_probe,
2615 .remove = __devexit_p(xgifb_remove)
2616 };
2617
xgifb_init(void)2618 XGIINITSTATIC int __init xgifb_init(void)
2619 {
2620 char *option = NULL;
2621
2622 if (fb_get_options("xgifb", &option))
2623 return -ENODEV;
2624 XGIfb_setup(option);
2625
2626 return pci_register_driver(&xgifb_driver);
2627 }
2628
2629 #ifndef MODULE
2630 module_init(xgifb_init);
2631 #endif
2632
2633 /*****************************************************/
2634 /* MODULE */
2635 /*****************************************************/
2636
2637 #ifdef MODULE
2638
2639 static char *mode = NULL;
2640 static int vesa = 0;
2641 static unsigned int rate = 0;
2642 static unsigned int mem = 0;
2643 static char *forcecrt2type = NULL;
2644 static int forcecrt1 = -1;
2645 static int pdc = -1;
2646 static int pdc1 = -1;
2647 static int noypan = -1;
2648 static int userom = -1;
2649 static int useoem = -1;
2650 static char *tvstandard = NULL;
2651 static int nocrt2rate = 0;
2652 static int scalelcd = -1;
2653 static char *specialtiming = NULL;
2654 static int lvdshl = -1;
2655 static int tvxposoffset = 0, tvyposoffset = 0;
2656 #if !defined(__i386__) && !defined(__x86_64__)
2657 static int resetcard = 0;
2658 static int videoram = 0;
2659 #endif
2660
2661 MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2662 MODULE_LICENSE("GPL");
2663 MODULE_AUTHOR("XGITECH , Others");
2664
2665 module_param(mem, int, 0);
2666 module_param(noypan, int, 0);
2667 module_param(userom, int, 0);
2668 module_param(useoem, int, 0);
2669 module_param(mode, charp, 0);
2670 module_param(vesa, int, 0);
2671 module_param(rate, int, 0);
2672 module_param(forcecrt1, int, 0);
2673 module_param(forcecrt2type, charp, 0);
2674 module_param(scalelcd, int, 0);
2675 module_param(pdc, int, 0);
2676 module_param(pdc1, int, 0);
2677 module_param(specialtiming, charp, 0);
2678 module_param(lvdshl, int, 0);
2679 module_param(tvstandard, charp, 0);
2680 module_param(tvxposoffset, int, 0);
2681 module_param(tvyposoffset, int, 0);
2682 module_param(filter, int, 0);
2683 module_param(nocrt2rate, int, 0);
2684 #if !defined(__i386__) && !defined(__x86_64__)
2685 module_param(resetcard, int, 0);
2686 module_param(videoram, int, 0);
2687 #endif
2688
2689 MODULE_PARM_DESC(noypan,
2690 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2691 "will be performed by redrawing the screen. (default: 0)\n");
2692
2693 MODULE_PARM_DESC(mode,
2694 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2695 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2696 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2697 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
2698
2699 MODULE_PARM_DESC(vesa,
2700 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2701 "0x117 (default: 0x0103)\n");
2702
2703 MODULE_PARM_DESC(rate,
2704 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2705 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2706 "will be ignored (default: 60)\n");
2707
2708 MODULE_PARM_DESC(forcecrt1,
2709 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2710 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2711 "0=CRT1 OFF) (default: [autodetected])\n");
2712
2713 MODULE_PARM_DESC(forcecrt2type,
2714 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2715 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2716 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2717 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2718 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2719 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2720 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2721 "depends on the very hardware in use. (default: [autodetected])\n");
2722
2723 MODULE_PARM_DESC(scalelcd,
2724 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2725 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2726 "show black bars around the image, TMDS panels will probably do the scaling\n"
2727 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
2728
2729 MODULE_PARM_DESC(pdc,
2730 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2731 "should detect this correctly in most cases; however, sometimes this is not\n"
2732 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2733 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2734 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2735 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
2736
2737 MODULE_PARM_DESC(pdc1,
2738 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2739 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2740 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2741 "implemented yet.\n");
2742
2743 MODULE_PARM_DESC(specialtiming,
2744 "\nPlease refer to documentation for more information on this option.\n");
2745
2746 MODULE_PARM_DESC(lvdshl,
2747 "\nPlease refer to documentation for more information on this option.\n");
2748
2749 MODULE_PARM_DESC(tvstandard,
2750 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2751 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
2752
2753 MODULE_PARM_DESC(tvxposoffset,
2754 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2755 "Default: 0\n");
2756
2757 MODULE_PARM_DESC(tvyposoffset,
2758 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2759 "Default: 0\n");
2760
2761 MODULE_PARM_DESC(filter,
2762 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2763 "(Possible values 0-7, default: [no filter])\n");
2764
2765 MODULE_PARM_DESC(nocrt2rate,
2766 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2767 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
2768
xgifb_init_module(void)2769 static int __init xgifb_init_module(void)
2770 {
2771 printk("\nXGIfb_init_module");
2772 if (mode)
2773 XGIfb_search_mode(mode);
2774 else if (vesa != -1)
2775 XGIfb_search_vesamode(vesa);
2776
2777 return xgifb_init();
2778 }
2779
xgifb_remove_module(void)2780 static void __exit xgifb_remove_module(void)
2781 {
2782 pci_unregister_driver(&xgifb_driver);
2783 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2784 }
2785
2786 module_init(xgifb_init_module);
2787 module_exit(xgifb_remove_module);
2788
2789 #endif /* /MODULE */
2790