blob: fa97c3796a012a6aedfe1cd5257ba063aaa8a459 [file] [log] [blame]
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001/*
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
Prashant P. Shahb654f872010-09-06 17:34:26 +05307/* #include <linux/config.h> */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02008#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>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020031
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020032#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
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020046#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)
53int XGIfb_GetXG21DefaultLVDSModeIdx(void);
54
Aaro Koskinen0f07d942011-02-17 23:29:13 +020055#define XGIFB_ROM_SIZE 65536
56
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020057/* -------------------- 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
68static void dumpVGAReg(void)
69{
Prashant P. Shahb654f872010-09-06 17:34:26 +053070 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020071
Prashant P. Shahb654f872010-09-06 17:34:26 +053072 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 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020086
Prashant P. Shahb654f872010-09-06 17:34:26 +053087 /* outXGIIDXREG(XGICR, 0x19, 0x00); */
88 /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
89 /* outXGIIDXREG(XGICR, 0x22, 0xff); */
90 /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020091
Prashant P. Shahb654f872010-09-06 17:34:26 +053092 /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020093
Prashant P. Shahb654f872010-09-06 17:34:26 +053094 /* outXGIIDXREG(XGICR, 0x57, 0x0); */
95 /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020096
Prashant P. Shahb654f872010-09-06 17:34:26 +053097 /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
98 /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
99 /*
100 outXGIIDXREG(XGICR, 0x99, 0x1);
101 outXGIIDXREG(XGICR, 0x41, 0x40);
102 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200103
Prashant P. Shahb654f872010-09-06 17:34:26 +0530104 for (i = 0; i < 0x4f; i++) {
105 inXGIIDXREG(XGISR, i, reg);
106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
108 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200109
Prashant P. Shahb654f872010-09-06 17:34:26 +0530110 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 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200122
Prashant P. Shahb654f872010-09-06 17:34:26 +0530123 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 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200139}
140#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530141static inline void dumpVGAReg(void)
142{
143}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200144#endif
145
146/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530147struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200148
149#if 1
150#define DEBUGPRN(x)
151#else
152#define DEBUGPRN(x) printk(KERN_INFO x "\n");
153#endif
154
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200155/* --------------- Hardware Access Routines -------------------------- */
156
Prashant P. Shahb654f872010-09-06 17:34:26 +0530157static 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)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200160{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200164
Prashant P. Shahb654f872010-09-06 17:34:26 +0530165 /* unsigned long temp = 0; */
166 int Clock;
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200169
Prashant P. Shahb654f872010-09-06 17:34:26 +0530170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200172
Prashant P. Shahb654f872010-09-06 17:34:26 +0530173 /*
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 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200179
Prashant P. Shahb654f872010-09-06 17:34:26 +0530180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200182
Prashant P. Shahb654f872010-09-06 17:34:26 +0530183 */
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
185 if (HwDeviceExtension->jChipType < XGI_315H)
186 ClockIndex &= 0x3F;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200187
Prashant P. Shahb654f872010-09-06 17:34:26 +0530188 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
189
190 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200191}
192
Prashant P. Shahb654f872010-09-06 17:34:26 +0530193static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
194 struct xgi_hw_device_info *HwDeviceExtension,
195 unsigned char modeno, unsigned char rateindex,
196 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
197 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
198 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200199{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530200 unsigned short ModeNo = modeno;
201 unsigned short ModeIdIndex = 0, index = 0;
202 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200203
Prashant P. Shahb654f872010-09-06 17:34:26 +0530204 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
205 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
206 unsigned char sr_data, cr_data, cr_data2;
207 unsigned long cr_data3;
208 int A, B, C, D, E, F, temp, j;
209 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
210 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
211 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
212 ModeIdIndex, XGI_Pr);
213 /*
214 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
215 if (!temp)
216 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200217
Prashant P. Shahb654f872010-09-06 17:34:26 +0530218 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
219 RefreshRateTableIndex += (rateindex - 1);
220 */
221 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200222
Prashant P. Shahb654f872010-09-06 17:34:26 +0530223 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200224
Prashant P. Shahb654f872010-09-06 17:34:26 +0530225 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200226
Prashant P. Shahb654f872010-09-06 17:34:26 +0530227 /* Horizontal total */
228 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
229 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200230
Prashant P. Shahb654f872010-09-06 17:34:26 +0530231 /*
232 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200233
Prashant P. Shahb654f872010-09-06 17:34:26 +0530234 Horizontal display enable end
235 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
236 */
237 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
238 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200239
Prashant P. Shahb654f872010-09-06 17:34:26 +0530240 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200241
Prashant P. Shahb654f872010-09-06 17:34:26 +0530242 /* Horizontal retrace (=sync) start */
243 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
244 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200245
Prashant P. Shahb654f872010-09-06 17:34:26 +0530246 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200247
Prashant P. Shahb654f872010-09-06 17:34:26 +0530248 /* Horizontal blank start */
249 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200250
Prashant P. Shahb654f872010-09-06 17:34:26 +0530251 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200252
Prashant P. Shahb654f872010-09-06 17:34:26 +0530253 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200254
Prashant P. Shahb654f872010-09-06 17:34:26 +0530255 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200256
Prashant P. Shahb654f872010-09-06 17:34:26 +0530257 /* Horizontal blank end */
258 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
259 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200260
Prashant P. Shahb654f872010-09-06 17:34:26 +0530261 /* Horizontal retrace (=sync) end */
262 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200263
Prashant P. Shahb654f872010-09-06 17:34:26 +0530264 temp = HBE - ((E - 1) & 255);
265 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200266
Prashant P. Shahb654f872010-09-06 17:34:26 +0530267 temp = HRE - ((E + F + 3) & 63);
268 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200269
Prashant P. Shahb654f872010-09-06 17:34:26 +0530270 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200271
Prashant P. Shahb654f872010-09-06 17:34:26 +0530272 *left_margin = D * 8;
273 *right_margin = F * 8;
274 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200275
Prashant P. Shahb654f872010-09-06 17:34:26 +0530276 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200277
Prashant P. Shahb654f872010-09-06 17:34:26 +0530278 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200279
Prashant P. Shahb654f872010-09-06 17:34:26 +0530280 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200281
Prashant P. Shahb654f872010-09-06 17:34:26 +0530282 /* Vertical total */
283 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
284 | ((unsigned short) (cr_data2 & 0x20) << 4)
285 | ((unsigned short) (sr_data & 0x01) << 10);
286 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200287
Prashant P. Shahb654f872010-09-06 17:34:26 +0530288 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200289
Prashant P. Shahb654f872010-09-06 17:34:26 +0530290 /* Vertical display enable end */
291 /*
292 VDE = (cr_data & 0xff) |
293 ((unsigned short) (cr_data2 & 0x02) << 7) |
294 ((unsigned short) (cr_data2 & 0x40) << 3) |
295 ((unsigned short) (sr_data & 0x02) << 9);
296 */
297 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
298 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200299
Prashant P. Shahb654f872010-09-06 17:34:26 +0530300 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200301
Prashant P. Shahb654f872010-09-06 17:34:26 +0530302 /* Vertical retrace (=sync) start */
303 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
304 | ((unsigned short) (cr_data2 & 0x80) << 2)
305 | ((unsigned short) (sr_data & 0x08) << 7);
306 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200307
Prashant P. Shahb654f872010-09-06 17:34:26 +0530308 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200309
Prashant P. Shahb654f872010-09-06 17:34:26 +0530310 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200311
Prashant P. Shahb654f872010-09-06 17:34:26 +0530312 /* Vertical blank start */
313 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
314 | ((unsigned short) (cr_data3 & 0x20) << 4)
315 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200316
Prashant P. Shahb654f872010-09-06 17:34:26 +0530317 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200318
Prashant P. Shahb654f872010-09-06 17:34:26 +0530319 /* Vertical blank end */
320 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
321 temp = VBE - ((E - 1) & 511);
322 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200323
Prashant P. Shahb654f872010-09-06 17:34:26 +0530324 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200325
Prashant P. Shahb654f872010-09-06 17:34:26 +0530326 /* Vertical retrace (=sync) end */
327 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
328 temp = VRE - ((E + F - 1) & 31);
329 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200330
Prashant P. Shahb654f872010-09-06 17:34:26 +0530331 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200332
Prashant P. Shahb654f872010-09-06 17:34:26 +0530333 *upper_margin = D;
334 *lower_margin = F;
335 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200336
Prashant P. Shahb654f872010-09-06 17:34:26 +0530337 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
338 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
339 else
340 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200341
Prashant P. Shahb654f872010-09-06 17:34:26 +0530342 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
343 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
344 else
345 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200346
Prashant P. Shahb654f872010-09-06 17:34:26 +0530347 *vmode = FB_VMODE_NONINTERLACED;
348 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
349 *vmode = FB_VMODE_INTERLACED;
350 else {
351 j = 0;
352 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
354 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
355 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
356 & DoubleScanMode) {
357 *vmode = FB_VMODE_DOUBLE;
358 }
359 break;
360 }
361 j++;
362 }
363 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200364
Prashant P. Shahb654f872010-09-06 17:34:26 +0530365 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200366}
367
Randy Dunlap89229672010-08-10 08:46:44 -0700368static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200369{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530370 XGI_Pr->RelIO = BaseAddr;
371 XGI_Pr->P3c4 = BaseAddr + 0x14;
372 XGI_Pr->P3d4 = BaseAddr + 0x24;
373 XGI_Pr->P3c0 = BaseAddr + 0x10;
374 XGI_Pr->P3ce = BaseAddr + 0x1e;
375 XGI_Pr->P3c2 = BaseAddr + 0x12;
376 XGI_Pr->P3ca = BaseAddr + 0x1a;
377 XGI_Pr->P3c6 = BaseAddr + 0x16;
378 XGI_Pr->P3c7 = BaseAddr + 0x17;
379 XGI_Pr->P3c8 = BaseAddr + 0x18;
380 XGI_Pr->P3c9 = BaseAddr + 0x19;
381 XGI_Pr->P3da = BaseAddr + 0x2A;
382 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
383 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
384 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
385 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
386 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200387
388}
389
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200390void XGIfb_set_reg4(u16 port, unsigned long data)
391{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530392 outl((u32)(data & 0xffffffff), port);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200393}
394
395u32 XGIfb_get_reg3(u16 port)
396{
397 u32 data;
398
399 data = inl(port);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530400 return data;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200401}
402
403/* ------------ Interface for init & mode switching code ------------- */
404
Prashant P. Shahb654f872010-09-06 17:34:26 +0530405unsigned char XGIfb_query_VGA_config_space(
406 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
407 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200408{
409 static struct pci_dev *pdev = NULL;
410 static unsigned char init = 0, valid_pdev = 0;
411
412 if (!set)
413 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
414 else
415 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
416
417 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400418 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530419 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
420 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200421 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400422 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200423 pci_dev_put(pdev);
424 }
425 }
426
427 if (!valid_pdev) {
428 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
429 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400430 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200431 }
432
433 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530434 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200435 else
436 pci_write_config_dword(pdev, offset, (u32)(*value));
437
Bill Pembertondda08c52010-06-17 13:10:42 -0400438 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200439}
440
Prashant P. Shahb654f872010-09-06 17:34:26 +0530441/*
442unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200443 unsigned long offset, unsigned long set, unsigned long *value)
444{
445 static struct pci_dev *pdev = NULL;
446 static unsigned char init = 0, valid_pdev = 0;
447 u16 nbridge_id = 0;
448
449 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400450 init = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200451 switch (xgi_video_info.chip) {
452 case XGI_540:
453 nbridge_id = PCI_DEVICE_ID_XG_540;
454 break;
455 case XGI_630:
456 nbridge_id = PCI_DEVICE_ID_XG_630;
457 break;
458 case XGI_730:
459 nbridge_id = PCI_DEVICE_ID_XG_730;
460 break;
461 case XGI_550:
462 nbridge_id = PCI_DEVICE_ID_XG_550;
463 break;
464 case XGI_650:
465 nbridge_id = PCI_DEVICE_ID_XG_650;
466 break;
467 case XGI_740:
468 nbridge_id = PCI_DEVICE_ID_XG_740;
469 break;
470 default:
471 nbridge_id = 0;
472 break;
473 }
474
Atul Sowanifc2347e2010-11-03 18:40:56 +0530475 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
476 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400477 valid_pdev = 1;
Atul Sowanifc2347e2010-11-03 18:40:56 +0530478 pci_dev_put(pdev);
479 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200480 }
481
482 if (!valid_pdev) {
483 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530484 nbridge_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400485 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200486 }
487
488 if (set == 0)
489 pci_read_config_dword(pdev, offset, (u32 *)value);
490 else
491 pci_write_config_dword(pdev, offset, (u32)(*value));
492
Bill Pembertondda08c52010-06-17 13:10:42 -0400493 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200494}
495*/
496/* ------------------ Internal helper routines ----------------- */
497
498static void XGIfb_search_mode(const char *name)
499{
500 int i = 0, j = 0, l;
501
Prashant P. Shahb654f872010-09-06 17:34:26 +0530502 if (name == NULL) {
503 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
504 xgifb_mode_idx = DEFAULT_MODE;
505 if ((xgi_video_info.chip == XG21)
506 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
507 == DISPTYPE_LCD)) {
508 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
509 }
510 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200511 }
512
Prashant P. Shahb654f872010-09-06 17:34:26 +0530513 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
514 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
515 xgifb_mode_idx = DEFAULT_MODE;
516 if ((xgi_video_info.chip == XG21)
517 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
518 == DISPTYPE_LCD)) {
519 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
520 }
521 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200522 }
523
Prashant P. Shahb654f872010-09-06 17:34:26 +0530524 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200525 l = min(strlen(name), strlen(XGIbios_mode[i].name));
526 if (!strncmp(name, XGIbios_mode[i].name, l)) {
527 xgifb_mode_idx = i;
528 j = 1;
529 break;
530 }
531 i++;
532 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530533 if (!j)
534 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200535}
536
537static void XGIfb_search_vesamode(unsigned int vesamode)
538{
539 int i = 0, j = 0;
540
Prashant P. Shahb654f872010-09-06 17:34:26 +0530541 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200542
543 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
544 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530545 if ((xgi_video_info.chip == XG21)
546 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
547 == DISPTYPE_LCD)) {
548 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200549 }
550 return;
551 }
552
Prashant P. Shahb654f872010-09-06 17:34:26 +0530553 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200554
Prashant P. Shahb654f872010-09-06 17:34:26 +0530555 while (XGIbios_mode[i].mode_no != 0) {
556 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
557 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200558 xgifb_mode_idx = i;
559 j = 1;
560 break;
561 }
562 i++;
563 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530564 if (!j)
565 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200566}
567
Randy Dunlap89229672010-08-10 08:46:44 -0700568static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200569{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530570 u8 tmp;
571 unsigned char *pData;
572 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200573
Prashant P. Shahb654f872010-09-06 17:34:26 +0530574 inXGIIDXREG(XGISR, 0x1e, tmp);
575 outXGIIDXREG(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200576
Prashant P. Shahb654f872010-09-06 17:34:26 +0530577 pData = xgi_video_info.mmio_vbase + 0x20000;
578 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
579 i = pData[0x316] | (pData[0x317] << 8);
580 j = pData[i - 1];
581 if (j == 0xff)
582 j = 1;
583
584 k = 0;
585 do {
586 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
587 | (pData[i + 1] << 8);
588 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
589 + 3] << 8);
590 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
591 + 5] << 8);
592 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
593 + 7] << 8);
594 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
595 + 9] << 8);
596 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
597 + 11] << 8);
598 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
599 + 13] << 8);
600 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
601 | (pData[i + 15] << 8);
602 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
603 | (pData[i + 17] << 8);
604 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
605 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
606 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
607 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
608 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
609 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
610 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
611 i += 25;
612 j--;
613 k++;
614 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
615 / sizeof(struct XGI21_LVDSCapStruct))));
616 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200617 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530618 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200619}
620
621int XGIfb_GetXG21DefaultLVDSModeIdx(void)
622{
623
624 int found_mode = 0;
625 int XGIfb_mode_idx = 0;
626
627 found_mode = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530628 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
629 && (XGIbios_mode[XGIfb_mode_idx].xres
630 <= XGI21_LCDCapList[0].LVDSHDE)) {
631 if ((XGIbios_mode[XGIfb_mode_idx].xres
632 == XGI21_LCDCapList[0].LVDSHDE)
633 && (XGIbios_mode[XGIfb_mode_idx].yres
634 == XGI21_LCDCapList[0].LVDSVDE)
635 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200636 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
637 found_mode = 1;
638 break;
639 }
640 XGIfb_mode_idx++;
641 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530642 if (!found_mode)
643 XGIfb_mode_idx = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200644
Prashant P. Shahb654f872010-09-06 17:34:26 +0530645 return XGIfb_mode_idx;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200646}
647
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200648static int XGIfb_validate_mode(int myindex)
649{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530650 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200651
Prashant P. Shahb654f872010-09-06 17:34:26 +0530652 if (xgi_video_info.chip == XG21) {
653 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
654 == DISPTYPE_LCD) {
655 xres = XGI21_LCDCapList[0].LVDSHDE;
656 yres = XGI21_LCDCapList[0].LVDSVDE;
657 if (XGIbios_mode[myindex].xres > xres)
658 return -1;
659 if (XGIbios_mode[myindex].yres > yres)
660 return -1;
661 if ((XGIbios_mode[myindex].xres < xres)
662 && (XGIbios_mode[myindex].yres < yres)) {
663 if (XGIbios_mode[myindex].bpp > 8)
664 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200665 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530666
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200667 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530668 return myindex;
669
670 }
671
672 /* FIXME: for now, all is valid on XG27 */
673 if (xgi_video_info.chip == XG27)
674 return myindex;
675
676 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
677 return -1;
678
679 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
680 case DISPTYPE_LCD:
681 switch (XGIhw_ext.ulCRT2LCDType) {
682 case LCD_640x480:
683 xres = 640;
684 yres = 480;
685 break;
686 case LCD_800x600:
687 xres = 800;
688 yres = 600;
689 break;
690 case LCD_1024x600:
691 xres = 1024;
692 yres = 600;
693 break;
694 case LCD_1024x768:
695 xres = 1024;
696 yres = 768;
697 break;
698 case LCD_1152x768:
699 xres = 1152;
700 yres = 768;
701 break;
702 case LCD_1280x960:
703 xres = 1280;
704 yres = 960;
705 break;
706 case LCD_1280x768:
707 xres = 1280;
708 yres = 768;
709 break;
710 case LCD_1280x1024:
711 xres = 1280;
712 yres = 1024;
713 break;
714 case LCD_1400x1050:
715 xres = 1400;
716 yres = 1050;
717 break;
718 case LCD_1600x1200:
719 xres = 1600;
720 yres = 1200;
721 break;
722 /* case LCD_320x480: */ /* TW: FSTN */
723 /*
724 xres = 320;
725 yres = 480;
726 break;
727 */
728 default:
729 xres = 0;
730 yres = 0;
731 break;
732 }
733 if (XGIbios_mode[myindex].xres > xres)
734 return -1;
735 if (XGIbios_mode[myindex].yres > yres)
736 return -1;
737 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
738 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
739 switch (XGIbios_mode[myindex].xres) {
740 case 512:
741 if (XGIbios_mode[myindex].yres != 512)
742 return -1;
743 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
744 return -1;
745 break;
746 case 640:
747 if ((XGIbios_mode[myindex].yres != 400)
748 && (XGIbios_mode[myindex].yres
749 != 480))
750 return -1;
751 break;
752 case 800:
753 if (XGIbios_mode[myindex].yres != 600)
754 return -1;
755 break;
756 case 1024:
757 if ((XGIbios_mode[myindex].yres != 600)
758 && (XGIbios_mode[myindex].yres
759 != 768))
760 return -1;
761 if ((XGIbios_mode[myindex].yres == 600)
762 && (XGIhw_ext.ulCRT2LCDType
763 != LCD_1024x600))
764 return -1;
765 break;
766 case 1152:
767 if ((XGIbios_mode[myindex].yres) != 768)
768 return -1;
769 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
770 return -1;
771 break;
772 case 1280:
773 if ((XGIbios_mode[myindex].yres != 768)
774 && (XGIbios_mode[myindex].yres
775 != 1024))
776 return -1;
777 if ((XGIbios_mode[myindex].yres == 768)
778 && (XGIhw_ext.ulCRT2LCDType
779 != LCD_1280x768))
780 return -1;
781 break;
782 case 1400:
783 if (XGIbios_mode[myindex].yres != 1050)
784 return -1;
785 break;
786 case 1600:
787 if (XGIbios_mode[myindex].yres != 1200)
788 return -1;
789 break;
790 default:
791 return -1;
792 }
793 } else {
794 switch (XGIbios_mode[myindex].xres) {
795 case 512:
796 if (XGIbios_mode[myindex].yres != 512)
797 return -1;
798 break;
799 case 640:
800 if ((XGIbios_mode[myindex].yres != 400)
801 && (XGIbios_mode[myindex].yres
802 != 480))
803 return -1;
804 break;
805 case 800:
806 if (XGIbios_mode[myindex].yres != 600)
807 return -1;
808 break;
809 case 1024:
810 if (XGIbios_mode[myindex].yres != 768)
811 return -1;
812 break;
813 case 1280:
814 if ((XGIbios_mode[myindex].yres != 960)
815 && (XGIbios_mode[myindex].yres
816 != 1024))
817 return -1;
818 if (XGIbios_mode[myindex].yres == 960) {
819 if (XGIhw_ext.ulCRT2LCDType
820 == LCD_1400x1050)
821 return -1;
822 }
823 break;
824 case 1400:
825 if (XGIbios_mode[myindex].yres != 1050)
826 return -1;
827 break;
828 case 1600:
829 if (XGIbios_mode[myindex].yres != 1200)
830 return -1;
831 break;
832 default:
833 return -1;
834 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200835 }
836 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530837 case DISPTYPE_TV:
838 switch (XGIbios_mode[myindex].xres) {
839 case 512:
840 case 640:
841 case 800:
842 break;
843 case 720:
844 if (xgi_video_info.TV_type == TVMODE_NTSC) {
845 if (XGIbios_mode[myindex].yres != 480)
846 return -1;
847 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
848 if (XGIbios_mode[myindex].yres != 576)
849 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200850 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530851 /* TW: LVDS/CHRONTEL does not support 720 */
852 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
853 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
854 return -1;
855 }
856 break;
857 case 1024:
858 if (xgi_video_info.TV_type == TVMODE_NTSC) {
859 if (XGIbios_mode[myindex].bpp == 32)
860 return -1;
861 }
862 /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */
863 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
864 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
865 if (xgi_video_info.chip < XGI_315H)
866 return -1;
867 }
868 break;
869 default:
870 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200871 }
872 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530873 case DISPTYPE_CRT2:
874 if (XGIbios_mode[myindex].xres > 1280)
875 return -1;
876 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200877 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530878 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200879
880}
881
882static void XGIfb_search_crt2type(const char *name)
883{
884 int i = 0;
885
Prashant P. Shahb654f872010-09-06 17:34:26 +0530886 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200887 return;
888
Prashant P. Shahb654f872010-09-06 17:34:26 +0530889 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200890 if (!strcmp(name, XGI_crt2type[i].name)) {
891 XGIfb_crt2type = XGI_crt2type[i].type_no;
892 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
893 break;
894 }
895 i++;
896 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530897 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200898 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
899}
900
901static void XGIfb_search_queuemode(const char *name)
902{
903 int i = 0;
904
Prashant P. Shahb654f872010-09-06 17:34:26 +0530905 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200906 return;
907
908 while (XGI_queuemode[i].type_no != -1) {
909 if (!strcmp(name, XGI_queuemode[i].name)) {
910 XGIfb_queuemode = XGI_queuemode[i].type_no;
911 break;
912 }
913 i++;
914 }
915 if (XGIfb_queuemode < 0)
916 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
917}
918
919static u8 XGIfb_search_refresh_rate(unsigned int rate)
920{
921 u16 xres, yres;
922 int i = 0;
923
924 xres = XGIbios_mode[xgifb_mode_idx].xres;
925 yres = XGIbios_mode[xgifb_mode_idx].yres;
926
927 XGIfb_rate_idx = 0;
928 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530929 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
930 == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200931 if (XGIfb_vrate[i].refresh == rate) {
932 XGIfb_rate_idx = XGIfb_vrate[i].idx;
933 break;
934 } else if (XGIfb_vrate[i].refresh > rate) {
935 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
936 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530937 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200938 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530939 xgi_video_info.refresh_rate
940 = XGIfb_vrate[i].refresh;
941 } else if (((rate - XGIfb_vrate[i - 1].refresh)
942 <= 2) && (XGIfb_vrate[i].idx
943 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200944 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530945 rate, XGIfb_vrate[i-1].refresh);
946 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
947 xgi_video_info.refresh_rate
948 = XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200949 }
950 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530951 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200952 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
953 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530954 XGIfb_rate_idx = XGIfb_vrate[i].idx;
955 break;
956 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200957 }
958 i++;
959 }
960 if (XGIfb_rate_idx > 0) {
961 return XGIfb_rate_idx;
962 } else {
963 printk(KERN_INFO
Prashant P. Shahb654f872010-09-06 17:34:26 +0530964 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200965 return 0;
966 }
967}
968
969static void XGIfb_search_tvstd(const char *name)
970{
971 int i = 0;
972
Prashant P. Shahb654f872010-09-06 17:34:26 +0530973 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200974 return;
975
976 while (XGI_tvtype[i].type_no != -1) {
977 if (!strcmp(name, XGI_tvtype[i].name)) {
978 XGIfb_tvmode = XGI_tvtype[i].type_no;
979 break;
980 }
981 i++;
982 }
983}
984
Bill Pemberton82d6eb52010-06-17 13:10:46 -0400985static unsigned char XGIfb_bridgeisslave(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200986{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530987 unsigned char usScratchP1_00;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200988
Prashant P. Shahb654f872010-09-06 17:34:26 +0530989 if (xgi_video_info.hasVB == HASVB_NONE)
990 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200991
Prashant P. Shahb654f872010-09-06 17:34:26 +0530992 inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00);
993 if ((usScratchP1_00 & 0x50) == 0x10)
994 return 1;
995 else
996 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200997}
998
Bill Pemberton82d6eb52010-06-17 13:10:46 -0400999static unsigned char XGIfbcheckvretracecrt1(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001000{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301001 unsigned char temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001002
Prashant P. Shahb654f872010-09-06 17:34:26 +05301003 inXGIIDXREG(XGICR, 0x17, temp);
1004 if (!(temp & 0x80))
1005 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001006
Prashant P. Shahb654f872010-09-06 17:34:26 +05301007 inXGIIDXREG(XGISR, 0x1f, temp);
1008 if (temp & 0xc0)
1009 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001010
Prashant P. Shahb654f872010-09-06 17:34:26 +05301011 if (inXGIREG(XGIINPSTAT) & 0x08)
1012 return 1;
1013 else
1014 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001015}
1016
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001017static unsigned char XGIfbcheckvretracecrt2(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001018{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301019 unsigned char temp;
1020 if (xgi_video_info.hasVB == HASVB_NONE)
1021 return 0;
1022 inXGIIDXREG(XGIPART1, 0x30, temp);
1023 if (temp & 0x02)
1024 return 0;
1025 else
1026 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001027}
1028
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001029static unsigned char XGIfb_CheckVBRetrace(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001030{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301031 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1032 if (XGIfb_bridgeisslave())
1033 return XGIfbcheckvretracecrt1();
1034 else
1035 return XGIfbcheckvretracecrt2();
1036 }
1037 return XGIfbcheckvretracecrt1();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001038}
1039
1040/* ----------- FBDev related routines for all series ----------- */
1041
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001042static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1043{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301044 switch (var->bits_per_pixel) {
1045 case 8:
1046 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001047 var->red.length = var->green.length = var->blue.length = 6;
1048 xgi_video_info.video_cmap_len = 256;
1049 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301050 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001051 var->red.offset = 11;
1052 var->red.length = 5;
1053 var->green.offset = 5;
1054 var->green.length = 6;
1055 var->blue.offset = 0;
1056 var->blue.length = 5;
1057 var->transp.offset = 0;
1058 var->transp.length = 0;
1059 xgi_video_info.video_cmap_len = 16;
1060 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301061 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001062 var->red.offset = 16;
1063 var->red.length = 8;
1064 var->green.offset = 8;
1065 var->green.length = 8;
1066 var->blue.offset = 0;
1067 var->blue.length = 8;
1068 var->transp.offset = 24;
1069 var->transp.length = 8;
1070 xgi_video_info.video_cmap_len = 16;
1071 break;
1072 }
1073}
1074
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001075static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301076 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001077{
1078
Prashant P. Shahb654f872010-09-06 17:34:26 +05301079 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1080 + var->hsync_len;
1081 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1082 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001083#if defined(__powerpc__)
1084 u8 sr_data, cr_data;
1085#endif
1086 unsigned int drate = 0, hrate = 0;
1087 int found_mode = 0;
1088 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301089 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001090
1091 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301092 /* 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); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001093
Prashant P. Shahb654f872010-09-06 17:34:26 +05301094 info->var.xres_virtual = var->xres_virtual;
1095 info->var.yres_virtual = var->yres_virtual;
1096 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001097
1098 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1099 vtotal <<= 1;
1100 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1101 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301102 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1103 /* vtotal <<= 1; */
1104 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001105 }
1106
Prashant P. Shahb654f872010-09-06 17:34:26 +05301107 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001108 DPRINTK("XGIfb: Invalid 'var' information\n");
1109 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301110 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1111 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001112
Prashant P. Shahb654f872010-09-06 17:34:26 +05301113 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001114 drate = 1000000000 / var->pixclock;
1115 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301116 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1117 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001118 } else {
1119 xgi_video_info.refresh_rate = 60;
1120 }
1121
1122 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05301123 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001124
1125 old_mode = xgifb_mode_idx;
1126 xgifb_mode_idx = 0;
1127
Prashant P. Shahb654f872010-09-06 17:34:26 +05301128 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1129 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1130 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1131 && (XGIbios_mode[xgifb_mode_idx].yres
1132 == var->yres)
1133 && (XGIbios_mode[xgifb_mode_idx].bpp
1134 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001135 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1136 found_mode = 1;
1137 break;
1138 }
1139 xgifb_mode_idx++;
1140 }
1141
Prashant P. Shahb654f872010-09-06 17:34:26 +05301142 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001143 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1144 else
1145 xgifb_mode_idx = -1;
1146
Prashant P. Shahb654f872010-09-06 17:34:26 +05301147 if (xgifb_mode_idx < 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001148 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301149 var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001150 xgifb_mode_idx = old_mode;
1151 return -EINVAL;
1152 }
1153
Prashant P. Shahb654f872010-09-06 17:34:26 +05301154 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001155 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1156 xgi_video_info.refresh_rate = 60;
1157 }
1158
Prashant P. Shahb654f872010-09-06 17:34:26 +05301159 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001160
1161 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301162 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001163 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1164 return -EINVAL;
1165 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301166 info->fix.line_length = ((info->var.xres_virtual
1167 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001168
Prashant P. Shahb654f872010-09-06 17:34:26 +05301169 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001170
Prashant P. Shahb654f872010-09-06 17:34:26 +05301171 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1172 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001173
1174 XGIfb_post_setmode();
1175
Prashant P. Shahb654f872010-09-06 17:34:26 +05301176 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1177 XGIbios_mode[xgifb_mode_idx].xres,
1178 XGIbios_mode[xgifb_mode_idx].yres,
1179 XGIbios_mode[xgifb_mode_idx].bpp,
1180 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001181
1182 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1183 xgi_video_info.video_vwidth = info->var.xres_virtual;
1184 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1185 xgi_video_info.video_vheight = info->var.yres_virtual;
1186 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1187 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301188 xgi_video_info.video_linelength = info->var.xres_virtual
1189 * (xgi_video_info.video_bpp >> 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001190 xgi_video_info.accel = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301191 switch (xgi_video_info.video_bpp) {
1192 case 8:
1193 xgi_video_info.DstColor = 0x0000;
1194 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1195 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001196#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301197 inXGIIDXREG(XGICR, 0x4D, cr_data);
1198 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001199#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301200 break;
1201 case 16:
1202 xgi_video_info.DstColor = 0x8000;
1203 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001204#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301205 inXGIIDXREG(XGICR, 0x4D, cr_data);
1206 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001207#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301208 xgi_video_info.video_cmap_len = 16;
1209 break;
1210 case 32:
1211 xgi_video_info.DstColor = 0xC000;
1212 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1213 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001214#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301215 inXGIIDXREG(XGICR, 0x4D, cr_data);
1216 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001217#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301218 break;
1219 default:
1220 xgi_video_info.video_cmap_len = 16;
1221 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1222 xgi_video_info.accel = 0;
1223 break;
1224 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001225 }
1226 XGIfb_bpp_to_var(var); /*update ARGB info*/
1227 DEBUGPRN("End of do_set_var");
1228
1229 dumpVGAReg();
1230 return 0;
1231}
1232
1233#ifdef XGIFB_PAN
1234static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1235{
1236 unsigned int base;
1237
Prashant P. Shahb654f872010-09-06 17:34:26 +05301238 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001239
1240 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301241 /* printk("Pan: xo: %d xv %d xr %d\n",
1242 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001243 return -EINVAL;
1244 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301245 if (var->yoffset > (var->yres_virtual - var->yres)) {
1246 /* printk("Pan: yo: %d yv %d yr %d\n",
1247 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001248 return -EINVAL;
1249 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301250 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001251
Prashant P. Shahb654f872010-09-06 17:34:26 +05301252 /* calculate base bpp dep. */
1253 switch (var->bits_per_pixel) {
1254 case 16:
1255 base >>= 1;
1256 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001257 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301258 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001259 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301260 default:
1261 base >>= 2;
1262 break;
1263 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001264
1265 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1266
Prashant P. Shahb654f872010-09-06 17:34:26 +05301267 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001268 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1269 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301270 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001271 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1272
Prashant P. Shahb654f872010-09-06 17:34:26 +05301273 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001274 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301275 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1276 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1277 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001278 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301279 }
1280 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001281 return 0;
1282}
1283#endif
1284
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001285void XGI_dispinfo(struct ap_data *rec)
1286{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301287 rec->minfo.bpp = xgi_video_info.video_bpp;
1288 rec->minfo.xres = xgi_video_info.video_width;
1289 rec->minfo.yres = xgi_video_info.video_height;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001290 rec->minfo.v_xres = xgi_video_info.video_vwidth;
1291 rec->minfo.v_yres = xgi_video_info.video_vheight;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301292 rec->minfo.org_x = xgi_video_info.org_x;
1293 rec->minfo.org_y = xgi_video_info.org_y;
1294 rec->minfo.vrate = xgi_video_info.refresh_rate;
1295 rec->iobase = xgi_video_info.vga_base - 0x30;
1296 rec->mem_size = xgi_video_info.video_size;
1297 rec->disp_state = xgi_video_info.disp_state;
1298 rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1299 rec->hasVB = xgi_video_info.hasVB;
1300 rec->TV_type = xgi_video_info.TV_type;
1301 rec->TV_plug = xgi_video_info.TV_plug;
1302 rec->chip = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001303}
1304
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001305static int XGIfb_open(struct fb_info *info, int user)
1306{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301307 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001308}
1309
1310static int XGIfb_release(struct fb_info *info, int user)
1311{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301312 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001313}
1314
1315static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1316{
1317 int rc = 16;
1318
Prashant P. Shahb654f872010-09-06 17:34:26 +05301319 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001320 case 8:
1321 rc = 256;
1322 break;
1323 case 16:
1324 rc = 16;
1325 break;
1326 case 32:
1327 rc = 16;
1328 break;
1329 }
1330 return rc;
1331}
1332
Prashant P. Shahb654f872010-09-06 17:34:26 +05301333static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1334 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001335{
1336 if (regno >= XGIfb_get_cmap_len(&info->var))
1337 return 1;
1338
1339 switch (info->var.bits_per_pixel) {
1340 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301341 outXGIREG(XGIDACA, regno);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001342 outXGIREG(XGIDACD, (red >> 10));
1343 outXGIREG(XGIDACD, (green >> 10));
1344 outXGIREG(XGIDACD, (blue >> 10));
1345 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301346 outXGIREG(XGIDAC2A, regno);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001347 outXGIREG(XGIDAC2D, (red >> 8));
1348 outXGIREG(XGIDAC2D, (green >> 8));
1349 outXGIREG(XGIDAC2D, (blue >> 8));
1350 }
1351 break;
1352 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301353 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1354 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1355 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001356 break;
1357 case 32:
1358 red >>= 8;
1359 green >>= 8;
1360 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301361 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1362 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001363 break;
1364 }
1365 return 0;
1366}
1367
1368static int XGIfb_set_par(struct fb_info *info)
1369{
1370 int err;
1371
Prashant P. Shahb654f872010-09-06 17:34:26 +05301372 /* printk("XGIfb: inside set_par\n"); */
1373 err = XGIfb_do_set_var(&info->var, 1, info);
1374 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001375 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001376 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301377 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001378 return 0;
1379}
1380
Prashant P. Shahb654f872010-09-06 17:34:26 +05301381static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001382{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301383 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1384 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001385 unsigned int vtotal = 0;
1386 unsigned int drate = 0, hrate = 0;
1387 int found_mode = 0;
1388 int refresh_rate, search_idx;
1389
1390 DEBUGPRN("Inside check_var");
1391
Prashant P. Shahb654f872010-09-06 17:34:26 +05301392 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1393 vtotal = var->upper_margin + var->yres + var->lower_margin
1394 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001395 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301396 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1397 vtotal = var->upper_margin + var->yres + var->lower_margin
1398 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001399 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301400 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1401 vtotal = var->upper_margin + (var->yres / 2)
1402 + var->lower_margin + var->vsync_len;
1403 } else
1404 vtotal = var->upper_margin + var->yres + var->lower_margin
1405 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001406
Prashant P. Shahb654f872010-09-06 17:34:26 +05301407 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001408 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301409
1410 if (var->pixclock && htotal && vtotal) {
1411 drate = 1000000000 / var->pixclock;
1412 hrate = (drate * 1000) / htotal;
1413 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1414 printk(KERN_DEBUG
1415 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1416 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1417 __func__, var->pixclock, htotal, vtotal,
1418 __func__, drate, hrate, xgi_video_info.refresh_rate);
1419 } else {
1420 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001421 }
1422
Prashant P. Shahb654f872010-09-06 17:34:26 +05301423 /*
1424 if ((var->pixclock) && (htotal)) {
1425 drate = 1E12 / var->pixclock;
1426 hrate = drate / htotal;
1427 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1428 } else {
1429 refresh_rate = 60;
1430 }
1431 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001432 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301433 if ((var->xres == 1024) && (var->yres == 600))
1434 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001435
1436 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301437 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1438 (XGIbios_mode[search_idx].xres <= var->xres)) {
1439 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1440 (XGIbios_mode[search_idx].yres == var->yres) &&
1441 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1442 if (XGIfb_validate_mode(search_idx) > 0) {
1443 found_mode = 1;
1444 break;
1445 }
1446 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001447 search_idx++;
1448 }
1449
Prashant P. Shahb654f872010-09-06 17:34:26 +05301450 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001451
1452 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1453 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301454 search_idx = 0;
1455 while (XGIbios_mode[search_idx].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001456
Prashant P. Shahb654f872010-09-06 17:34:26 +05301457 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1458 (var->yres <= XGIbios_mode[search_idx].yres) &&
1459 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1460 if (XGIfb_validate_mode(search_idx) > 0) {
1461 found_mode = 1;
1462 break;
1463 }
1464 }
1465 search_idx++;
1466 }
1467 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001468 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301469 var->yres = XGIbios_mode[search_idx].yres;
1470 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1471 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001472
1473 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301474 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001475 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301476 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001477 }
1478 }
1479
1480 /* TW: TODO: Check the refresh rate */
1481
1482 /* Adapt RGB settings */
1483 XGIfb_bpp_to_var(var);
1484
1485 /* Sanity check for offsets */
1486 if (var->xoffset < 0)
1487 var->xoffset = 0;
1488 if (var->yoffset < 0)
1489 var->yoffset = 0;
1490
Prashant P. Shahb654f872010-09-06 17:34:26 +05301491 if (!XGIfb_ypan) {
1492 if (var->xres != var->xres_virtual)
1493 var->xres_virtual = var->xres;
1494 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001495 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301496 } /* else { */
1497 /* TW: Now patch yres_virtual if we use panning */
1498 /* May I do this? */
1499 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1500 /* if (var->yres_virtual <= var->yres) { */
1501 /* TW: Paranoia check */
1502 /* var->yres_virtual = var->yres; */
1503 /* } */
1504 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001505
1506 /* Truncate offsets to maximum if too high */
1507 if (var->xoffset > var->xres_virtual - var->xres)
1508 var->xoffset = var->xres_virtual - var->xres - 1;
1509
1510 if (var->yoffset > var->yres_virtual - var->yres)
1511 var->yoffset = var->yres_virtual - var->yres - 1;
1512
1513 /* Set everything else to 0 */
1514 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301515 var->green.msb_right =
1516 var->blue.msb_right =
1517 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001518
1519 DEBUGPRN("end of check_var");
1520 return 0;
1521}
1522
1523#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301524static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1525 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001526{
1527 int err;
1528
Prashant P. Shahb654f872010-09-06 17:34:26 +05301529 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001530
1531 if (var->xoffset > (var->xres_virtual - var->xres))
1532 return -EINVAL;
1533 if (var->yoffset > (var->yres_virtual - var->yres))
1534 return -EINVAL;
1535
1536 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301537 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1538 || var->xoffset)
1539 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001540 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301541 if (var->xoffset + info->var.xres > info->var.xres_virtual
1542 || var->yoffset + info->var.yres
1543 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001544 return -EINVAL;
1545 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301546 err = XGIfb_pan_var(var);
1547 if (err < 0)
1548 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001549
1550 info->var.xoffset = var->xoffset;
1551 info->var.yoffset = var->yoffset;
1552 if (var->vmode & FB_VMODE_YWRAP)
1553 info->var.vmode |= FB_VMODE_YWRAP;
1554 else
1555 info->var.vmode &= ~FB_VMODE_YWRAP;
1556
Prashant P. Shahb654f872010-09-06 17:34:26 +05301557 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001558 return 0;
1559}
1560#endif
1561
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001562static int XGIfb_blank(int blank, struct fb_info *info)
1563{
1564 u8 reg;
1565
1566 inXGIIDXREG(XGICR, 0x17, reg);
1567
Prashant P. Shahb654f872010-09-06 17:34:26 +05301568 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001569 reg &= 0x7f;
1570 else
1571 reg |= 0x80;
1572
Prashant P. Shahb654f872010-09-06 17:34:26 +05301573 outXGIIDXREG(XGICR, 0x17, reg);
1574 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1575 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1576 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001577}
1578
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001579static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301580 unsigned long arg)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001581{
1582 DEBUGPRN("inside ioctl");
1583 switch (cmd) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301584 case FBIO_ALLOC:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001585 if (!capable(CAP_SYS_RAWIO))
1586 return -EPERM;
1587 XGI_malloc((struct XGI_memreq *) arg);
1588 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301589 case FBIO_FREE:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001590 if (!capable(CAP_SYS_RAWIO))
1591 return -EPERM;
1592 XGI_free(*(unsigned long *) arg);
1593 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301594 case FBIOGET_HWCINFO: {
1595 unsigned long *hwc_offset = (unsigned long *) arg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001596
Prashant P. Shahb654f872010-09-06 17:34:26 +05301597 if (XGIfb_caps & HW_CURSOR_CAP)
1598 *hwc_offset
1599 = XGIfb_hwcursor_vbase
1600 - (unsigned long) xgi_video_info.video_vbase;
1601 else
1602 *hwc_offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001603
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001604 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001605 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301606 case FBIOPUT_MODEINFO: {
1607 struct mode_info *x = (struct mode_info *) arg;
1608
1609 xgi_video_info.video_bpp = x->bpp;
1610 xgi_video_info.video_width = x->xres;
1611 xgi_video_info.video_height = x->yres;
1612 xgi_video_info.video_vwidth = x->v_xres;
1613 xgi_video_info.video_vheight = x->v_yres;
1614 xgi_video_info.org_x = x->org_x;
1615 xgi_video_info.org_y = x->org_y;
1616 xgi_video_info.refresh_rate = x->vrate;
1617 xgi_video_info.video_linelength = xgi_video_info.video_vwidth
1618 * (xgi_video_info.video_bpp >> 3);
1619 switch (xgi_video_info.video_bpp) {
1620 case 8:
1621 xgi_video_info.DstColor = 0x0000;
1622 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1623 xgi_video_info.video_cmap_len = 256;
1624 break;
1625 case 16:
1626 xgi_video_info.DstColor = 0x8000;
1627 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1628 xgi_video_info.video_cmap_len = 16;
1629 break;
1630 case 32:
1631 xgi_video_info.DstColor = 0xC000;
1632 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1633 xgi_video_info.video_cmap_len = 16;
1634 break;
1635 default:
1636 xgi_video_info.video_cmap_len = 16;
1637 printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1638 xgi_video_info.accel = 0;
1639 break;
1640 }
1641
1642 break;
1643 }
1644 case FBIOGET_DISPINFO:
1645 XGI_dispinfo((struct ap_data *) arg);
1646 break;
1647 case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1648 {
1649 struct XGIfb_info *x = (struct XGIfb_info *) arg;
1650
1651 /* x->XGIfb_id = XGIFB_ID; */
1652 x->XGIfb_version = VER_MAJOR;
1653 x->XGIfb_revision = VER_MINOR;
1654 x->XGIfb_patchlevel = VER_LEVEL;
1655 x->chip_id = xgi_video_info.chip_id;
1656 x->memory = xgi_video_info.video_size / 1024;
1657 x->heapstart = xgi_video_info.heapstart / 1024;
1658 x->fbvidmode = XGIfb_mode_no;
1659 x->XGIfb_caps = XGIfb_caps;
1660 x->XGIfb_tqlen = 512; /* yet unused */
1661 x->XGIfb_pcibus = xgi_video_info.pcibus;
1662 x->XGIfb_pcislot = xgi_video_info.pcislot;
1663 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1664 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1665 x->XGIfb_lcda = XGIfb_detectedlcda;
1666 break;
1667 }
1668 case XGIFB_GET_VBRSTATUS: {
1669 unsigned long *vbrstatus = (unsigned long *) arg;
1670 if (XGIfb_CheckVBRetrace())
1671 *vbrstatus = 1;
1672 else
1673 *vbrstatus = 0;
1674 }
1675 default:
1676 return -EINVAL;
1677 } DEBUGPRN("end of ioctl");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001678 return 0;
1679
1680}
1681
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001682/* ----------- FBDev related routines for all series ---------- */
1683
1684static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301685 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001686{
1687 DEBUGPRN("inside get_fix");
1688 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1689
1690 strcpy(fix->id, myid);
1691
1692 fix->smem_start = xgi_video_info.video_base;
1693
1694 fix->smem_len = xgi_video_info.video_size;
1695
Prashant P. Shahb654f872010-09-06 17:34:26 +05301696 /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1697 if (xgi_video_info.video_size > 0x1000000) {
1698 fix->smem_len = 0xD00000;
1699 } else if (xgi_video_info.video_size > 0x800000)
1700 fix->smem_len = 0x800000;
1701 else
1702 fix->smem_len = 0x400000;
1703 } else
1704 fix->smem_len = XGIfb_mem * 1024;
1705 */
1706 fix->type = video_type;
1707 fix->type_aux = 0;
1708 if (xgi_video_info.video_bpp == 8)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001709 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1710 else
1711 fix->visual = FB_VISUAL_DIRECTCOLOR;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301712 fix->xpanstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001713#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301714 if (XGIfb_ypan)
1715 fix->ypanstep = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001716#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301717 fix->ywrapstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001718 fix->line_length = xgi_video_info.video_linelength;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301719 fix->mmio_start = xgi_video_info.mmio_base;
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02001720 fix->mmio_len = xgi_video_info.mmio_size;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301721 if (xgi_video_info.chip >= XG40)
1722 fix->accel = FB_ACCEL_XGI_XABRE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001723 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05301724 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001725
1726 DEBUGPRN("end of get_fix");
1727 return 0;
1728}
1729
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001730static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301731 .owner = THIS_MODULE,
1732 .fb_open = XGIfb_open,
1733 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001734 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301735 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001736 .fb_setcolreg = XGIfb_setcolreg,
1737#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301738 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001739#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301740 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001741 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001742 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001743 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301744 .fb_ioctl = XGIfb_ioctl,
1745 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001746};
1747
1748/* ---------------- Chip generation dependent routines ---------------- */
1749
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001750/* for XGI 315/550/650/740/330 */
1751
1752static int XGIfb_get_dram_size(void)
1753{
1754
Prashant P. Shahb654f872010-09-06 17:34:26 +05301755 u8 ChannelNum, tmp;
1756 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001757
1758 /* xorg driver sets 32MB * 1 channel */
1759 if (xgi_video_info.chip == XG27)
1760 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1761
Prashant P. Shahb654f872010-09-06 17:34:26 +05301762 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1763 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1764 case XGI_DRAM_SIZE_1MB:
1765 xgi_video_info.video_size = 0x100000;
1766 break;
1767 case XGI_DRAM_SIZE_2MB:
1768 xgi_video_info.video_size = 0x200000;
1769 break;
1770 case XGI_DRAM_SIZE_4MB:
1771 xgi_video_info.video_size = 0x400000;
1772 break;
1773 case XGI_DRAM_SIZE_8MB:
1774 xgi_video_info.video_size = 0x800000;
1775 break;
1776 case XGI_DRAM_SIZE_16MB:
1777 xgi_video_info.video_size = 0x1000000;
1778 break;
1779 case XGI_DRAM_SIZE_32MB:
1780 xgi_video_info.video_size = 0x2000000;
1781 break;
1782 case XGI_DRAM_SIZE_64MB:
1783 xgi_video_info.video_size = 0x4000000;
1784 break;
1785 case XGI_DRAM_SIZE_128MB:
1786 xgi_video_info.video_size = 0x8000000;
1787 break;
1788 case XGI_DRAM_SIZE_256MB:
1789 xgi_video_info.video_size = 0x10000000;
1790 break;
1791 default:
1792 return -1;
1793 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001794
Prashant P. Shahb654f872010-09-06 17:34:26 +05301795 tmp = (reg & 0x0c) >> 2;
1796 switch (xgi_video_info.chip) {
1797 case XG20:
1798 case XG21:
1799 case XG27:
1800 ChannelNum = 1;
1801 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001802
Prashant P. Shahb654f872010-09-06 17:34:26 +05301803 case XG42:
1804 if (reg & 0x04)
1805 ChannelNum = 2;
1806 else
1807 ChannelNum = 1;
1808 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001809
Prashant P. Shahb654f872010-09-06 17:34:26 +05301810 case XG45:
1811 if (tmp == 1)
1812 ChannelNum = 2;
1813 else if (tmp == 2)
1814 ChannelNum = 3;
1815 else if (tmp == 3)
1816 ChannelNum = 4;
1817 else
1818 ChannelNum = 1;
1819 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001820
Prashant P. Shahb654f872010-09-06 17:34:26 +05301821 case XG40:
1822 default:
1823 if (tmp == 2)
1824 ChannelNum = 2;
1825 else if (tmp == 3)
1826 ChannelNum = 3;
1827 else
1828 ChannelNum = 1;
1829 break;
1830 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001831
Prashant P. Shahb654f872010-09-06 17:34:26 +05301832 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1833 /* PLiad fixed for benchmarking and fb set */
1834 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1835 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001836
Prashant P. Shahb654f872010-09-06 17:34:26 +05301837 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1838 xgi_video_info.video_size, ChannelNum);
1839 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001840
1841}
1842
1843static void XGIfb_detect_VB(void)
1844{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301845 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001846
1847 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1848
Prashant P. Shahb654f872010-09-06 17:34:26 +05301849 switch (xgi_video_info.hasVB) {
1850 case HASVB_LVDS_CHRONTEL:
1851 case HASVB_CHRONTEL:
1852 break;
1853 case HASVB_301:
1854 case HASVB_302:
1855 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1856 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001857 }
1858
1859 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1860
1861 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1862 XGIfb_crt1off = 0;
1863 else {
1864 if (cr32 & 0x5F)
1865 XGIfb_crt1off = 1;
1866 else
1867 XGIfb_crt1off = 0;
1868 }
1869
1870 if (XGIfb_crt2type != -1)
1871 /* TW: Override with option */
1872 xgi_video_info.disp_state = XGIfb_crt2type;
1873 else if (cr32 & XGI_VB_TV)
1874 xgi_video_info.disp_state = DISPTYPE_TV;
1875 else if (cr32 & XGI_VB_LCD)
1876 xgi_video_info.disp_state = DISPTYPE_LCD;
1877 else if (cr32 & XGI_VB_CRT2)
1878 xgi_video_info.disp_state = DISPTYPE_CRT2;
1879 else
1880 xgi_video_info.disp_state = 0;
1881
Prashant P. Shahb654f872010-09-06 17:34:26 +05301882 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001883 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301884 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001885 else if (cr32 & XGI_VB_HIVISION) {
1886 xgi_video_info.TV_type = TVMODE_HIVISION;
1887 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301888 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001889 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1890 else if (cr32 & XGI_VB_COMPOSITE)
1891 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1892 else if (cr32 & XGI_VB_SCART)
1893 xgi_video_info.TV_plug = TVPLUG_SCART;
1894
Prashant P. Shahb654f872010-09-06 17:34:26 +05301895 if (xgi_video_info.TV_type == 0) {
1896 /* TW: PAL/NTSC changed for 650 */
1897 if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip
1898 >= XGI_330)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001899
Prashant P. Shahb654f872010-09-06 17:34:26 +05301900 inXGIIDXREG(XGICR, 0x38, temp);
1901 if (temp & 0x10)
1902 xgi_video_info.TV_type = TVMODE_PAL;
1903 else
1904 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001905
Prashant P. Shahb654f872010-09-06 17:34:26 +05301906 } else {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001907
Prashant P. Shahb654f872010-09-06 17:34:26 +05301908 inXGIIDXREG(XGICR, 0x79, temp);
1909 if (temp & 0x20)
1910 xgi_video_info.TV_type = TVMODE_PAL;
1911 else
1912 xgi_video_info.TV_type = TVMODE_NTSC;
1913 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001914 }
1915
1916 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301917 if (XGIfb_forcecrt1 != -1) {
1918 if (XGIfb_forcecrt1)
1919 XGIfb_crt1off = 0;
1920 else
1921 XGIfb_crt1off = 1;
1922 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001923}
1924
1925static void XGIfb_get_VB_type(void)
1926{
1927 u8 reg;
1928
1929 if (!XGIfb_has_VB()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301930 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001931 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301932 case XGI310_EXTERNAL_CHIP_LVDS:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001933 xgi_video_info.hasVB = HASVB_LVDS;
1934 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301935 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001936 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1937 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301938 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001939 break;
1940 }
1941 }
1942}
1943
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001944static int XGIfb_has_VB(void)
1945{
1946 u8 vb_chipid;
1947
1948 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1949 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301950 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001951 xgi_video_info.hasVB = HASVB_301;
1952 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301953 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001954 xgi_video_info.hasVB = HASVB_302;
1955 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301956 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001957 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001958 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001959 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001960 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001961}
1962
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001963/* ------------------ Sensing routines ------------------ */
1964
1965/* TW: Determine and detect attached devices on XGI30x */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301966int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001967{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301968 int temp, i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001969
Prashant P. Shahb654f872010-09-06 17:34:26 +05301970 outXGIIDXREG(XGIPART4, 0x11, tempbl);
1971 temp = tempbh | tempcl;
1972 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1973 for (i = 0; i < 10; i++)
1974 XGI_LongWait(&XGI_Pr);
1975 tempch &= 0x7f;
1976 inXGIIDXREG(XGIPART4, 0x03, temp);
1977 temp ^= 0x0e;
1978 temp &= tempch;
1979 return temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001980}
1981
Prashant P. Shahb654f872010-09-06 17:34:26 +05301982void XGI_Sense30x(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001983{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301984 u8 backupP4_0d;
1985 u8 testsvhs_tempbl, testsvhs_tempbh;
1986 u8 testsvhs_tempcl, testsvhs_tempch;
1987 u8 testcvbs_tempbl, testcvbs_tempbh;
1988 u8 testcvbs_tempcl, testcvbs_tempch;
1989 u8 testvga2_tempbl, testvga2_tempbh;
1990 u8 testvga2_tempcl, testvga2_tempch;
1991 int myflag, result;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001992
Prashant P. Shahb654f872010-09-06 17:34:26 +05301993 inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1994 outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001995
Prashant P. Shahb654f872010-09-06 17:34:26 +05301996 testvga2_tempbh = 0x00;
1997 testvga2_tempbl = 0xd1;
1998 testsvhs_tempbh = 0x00;
1999 testsvhs_tempbl = 0xb9;
2000 testcvbs_tempbh = 0x00;
2001 testcvbs_tempbl = 0xb3;
2002 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
2003 != VB_CHIP_302)) {
2004 testvga2_tempbh = 0x01;
2005 testvga2_tempbl = 0x90;
2006 testsvhs_tempbh = 0x01;
2007 testsvhs_tempbl = 0x6b;
2008 testcvbs_tempbh = 0x01;
2009 testcvbs_tempbl = 0x74;
2010 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
2011 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
2012 testvga2_tempbh = 0x00;
2013 testvga2_tempbl = 0x00;
2014 testsvhs_tempbh = 0x02;
2015 testsvhs_tempbl = 0x00;
2016 testcvbs_tempbh = 0x01;
2017 testcvbs_tempbl = 0x00;
2018 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002019 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302020 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
2021 != VB_CHIP_302LV) {
2022 inXGIIDXREG(XGIPART4, 0x01, myflag);
2023 if (myflag & 0x04) {
2024 testvga2_tempbh = 0x00;
2025 testvga2_tempbl = 0xfd;
2026 testsvhs_tempbh = 0x00;
2027 testsvhs_tempbl = 0xdd;
2028 testcvbs_tempbh = 0x00;
2029 testcvbs_tempbl = 0xee;
2030 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002031 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302032 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
2033 == VB_CHIP_302LV)) {
2034 testvga2_tempbh = 0x00;
2035 testvga2_tempbl = 0x00;
2036 testvga2_tempch = 0x00;
2037 testvga2_tempcl = 0x00;
2038 testsvhs_tempch = 0x04;
2039 testsvhs_tempcl = 0x08;
2040 testcvbs_tempch = 0x08;
2041 testcvbs_tempcl = 0x08;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002042 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302043 testvga2_tempch = 0x0e;
2044 testvga2_tempcl = 0x08;
2045 testsvhs_tempch = 0x06;
2046 testsvhs_tempcl = 0x04;
2047 testcvbs_tempch = 0x08;
2048 testcvbs_tempcl = 0x04;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002049 }
2050
Prashant P. Shahb654f872010-09-06 17:34:26 +05302051 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
2052 || testvga2_tempbl) {
2053 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2054 testvga2_tempcl, testvga2_tempch);
2055 if (result) {
2056 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2057 orXGIIDXREG(XGICR, 0x32, 0x10);
2058 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002059 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002060
Prashant P. Shahb654f872010-09-06 17:34:26 +05302061 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
2062 testsvhs_tempch);
2063 if (result) {
2064 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2065 /* TW: So we can be sure that there IS a SVHS output */
2066 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2067 orXGIIDXREG(XGICR, 0x32, 0x02);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002068 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002069
Prashant P. Shahb654f872010-09-06 17:34:26 +05302070 if (!result) {
2071 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2072 testcvbs_tempcl, testcvbs_tempch);
2073 if (result) {
2074 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2075 /* TW: So we can be sure that there IS a CVBS output */
2076 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2077 orXGIIDXREG(XGICR, 0x32, 0x01);
2078 }
2079 }
2080 XGIDoSense(0, 0, 0, 0);
2081
2082 outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002083}
2084
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002085/* ------------------------ Heap routines -------------------------- */
2086
2087static int XGIfb_heap_init(void)
2088{
2089 XGI_OH *poh;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302090 u8 temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002091
Prashant P. Shahb654f872010-09-06 17:34:26 +05302092 int agp_enabled = 1;
2093 u32 agp_size;
Randy Dunlap89229672010-08-10 08:46:44 -07002094 unsigned long *cmdq_baseport = NULL;
2095 unsigned long *read_port = NULL;
2096 unsigned long *write_port = NULL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302097 XGI_CMDTYPE cmd_type;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002098#ifndef AGPOFF
Prashant P. Shahb654f872010-09-06 17:34:26 +05302099 struct agp_kern_info *agp_info;
2100 struct agp_memory *agp;
2101 u32 agp_phys;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002102#endif
2103
Prashant P. Shahb654f872010-09-06 17:34:26 +05302104 /* TW: The heap start is either set manually using the "mem" parameter, or
2105 * defaults as follows:
2106 * -) If more than 16MB videoRAM available, let our heap start at 12MB.
2107 * -) If more than 8MB videoRAM available, let our heap start at 8MB.
2108 * -) If 4MB or less is available, let it start at 4MB.
2109 * This is for avoiding a clash with X driver which uses the beginning
2110 * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2111 * in XF86Config-4.
2112 * The heap start can also be specified by parameter "mem" when starting the XGIfb
2113 * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2114 */
2115 if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) {
2116 if (xgi_video_info.video_size > 0x1000000)
2117 xgi_video_info.heapstart = 0xD00000;
2118 else if (xgi_video_info.video_size > 0x800000)
2119 xgi_video_info.heapstart = 0x800000;
2120 else
2121 xgi_video_info.heapstart = 0x400000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002122 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302123 xgi_video_info.heapstart = XGIfb_mem * 1024;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002124 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302125 XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase
2126 + xgi_video_info.heapstart);
2127 printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2128 (int)(xgi_video_info.heapstart / 1024));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002129
Prashant P. Shahb654f872010-09-06 17:34:26 +05302130 XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase
2131 + xgi_video_info.video_size;
2132 XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002133
Prashant P. Shahb654f872010-09-06 17:34:26 +05302134 /* TW: Now initialize the 310 series' command queue mode.
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002135 * On 310/325, there are three queue modes available which
2136 * are chosen by setting bits 7:5 in SR26:
2137 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2138 * track of the queue, the FIFO, command parsing and so
2139 * on. This is the one comparable to the 300 series.
2140 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2141 * have to do queue management himself. Register 0x85c4 will
2142 * hold the location of the next free queue slot, 0x85c8
2143 * is the "queue read pointer" whose way of working is
2144 * unknown to me. Anyway, this mode would require a
2145 * translation of the MMIO commands to some kind of
2146 * accelerator assembly and writing these commands
2147 * to the memory location pointed to by 0x85c4.
2148 * We will not use this, as nobody knows how this
2149 * "assembly" works, and as it would require a complete
2150 * re-write of the accelerator code.
2151 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2152 * queue in AGP memory space.
2153 *
2154 * SR26 bit 4 is called "Bypass H/W queue".
2155 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2156 * SR26 bit 0 resets the queue
2157 * Size of queue memory is encoded in bits 3:2 like this:
2158 * 00 (0x00) 512K
2159 * 01 (0x04) 1M
2160 * 10 (0x08) 2M
2161 * 11 (0x0C) 4M
2162 * The queue location is to be written to 0x85C0.
2163 *
Prashant P. Shahb654f872010-09-06 17:34:26 +05302164 */
2165 cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase
2166 + MMIO_QUEUE_PHYBASE);
2167 write_port = (unsigned long *) (xgi_video_info.mmio_vbase
2168 + MMIO_QUEUE_WRITEPORT);
2169 read_port = (unsigned long *) (xgi_video_info.mmio_vbase
2170 + MMIO_QUEUE_READPORT);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002171
2172 DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2173
Prashant P. Shahb654f872010-09-06 17:34:26 +05302174 agp_size = COMMAND_QUEUE_AREA_SIZE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002175
2176#ifndef AGPOFF
2177 if (XGIfb_queuemode == AGP_CMD_QUEUE) {
Joe Perches5b84cc72010-11-04 20:07:59 -07002178 agp_info = vzalloc(sizeof(*agp_info));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002179 agp_copy_info(agp_info);
2180
2181 agp_backend_acquire();
2182
Prashant P. Shahb654f872010-09-06 17:34:26 +05302183 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
2184 AGP_NORMAL_MEMORY);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002185 if (agp == NULL) {
2186 DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2187 agp_enabled = 0;
2188 } else {
2189 if (agp_bind_memory(agp, agp->pg_start) != 0) {
2190 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2191 /* TODO: Free AGP memory here */
2192 agp_enabled = 0;
2193 } else {
2194 agp_enable(0);
2195 }
2196 }
2197 }
2198#else
2199 agp_enabled = 0;
2200#endif
2201
2202 /* TW: Now select the queue mode */
2203
2204 if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2205 cmd_type = AGP_CMD_QUEUE;
2206 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302207 /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
2208 } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002209 cmd_type = VM_CMD_QUEUE;
2210 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2211 } else {
2212 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2213 cmd_type = MMIO_CMD;
2214 }
2215
2216 switch (agp_size) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302217 case 0x80000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002218 temp = XGI_CMD_QUEUE_SIZE_512k;
2219 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302220 case 0x100000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002221 temp = XGI_CMD_QUEUE_SIZE_1M;
2222 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302223 case 0x200000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002224 temp = XGI_CMD_QUEUE_SIZE_2M;
2225 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302226 case 0x400000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002227 temp = XGI_CMD_QUEUE_SIZE_4M;
2228 break;
2229 }
2230
2231 switch (cmd_type) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302232 case AGP_CMD_QUEUE:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002233#ifndef AGPOFF
2234 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2235 agp_info->aper_base, agp->physical, agp_size/1024);
2236
2237 agp_phys = agp_info->aper_base + agp->physical;
2238
Prashant P. Shahb654f872010-09-06 17:34:26 +05302239 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2240 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002241
Prashant P. Shahb654f872010-09-06 17:34:26 +05302242 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002243
2244 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2245
2246 *write_port = *read_port;
2247
2248 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2249 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2250
2251 *cmdq_baseport = agp_phys;
2252
2253 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2254#endif
2255 break;
2256
Prashant P. Shahb654f872010-09-06 17:34:26 +05302257 case VM_CMD_QUEUE:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002258 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2259 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2260
2261 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2262
2263 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2264
2265 *write_port = *read_port;
2266
2267 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2268 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2269
2270 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2271
2272 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2273
2274 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2275 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2276 break;
2277
Prashant P. Shahb654f872010-09-06 17:34:26 +05302278 default: /* MMIO */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002279
Prashant P. Shahb654f872010-09-06 17:34:26 +05302280 /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */
2281 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002282 * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2283 * enough. Reserve memory in any way.
2284 */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302285 /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */
2286 /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */
2287 /* FIXME */
2288 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */
2289 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */
2290 /* FIXME */
2291 /* FIXME *write_port = *read_port; */
2292 /* FIXME */
2293 /* FIXME *//* TW: Set Auto_Correction bit */
2294 /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */
2295 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */
2296 /* FIXME */
2297 /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */
2298 /* FIXME */
2299 /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */
2300 /* FIXME */
2301 /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */
2302 /* FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */
2303 break;
2304}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002305
Prashant P. Shahb654f872010-09-06 17:34:26 +05302306 /* TW: Now reserve memory for the HWCursor. It is always located at the very
2307 top of the videoRAM, right below the TB memory area (if used). */
2308 if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002309 XGIfb_heap_end -= XGIfb_hwcursor_size;
2310 XGIfb_heap_size -= XGIfb_hwcursor_size;
2311 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2312
2313 XGIfb_caps |= HW_CURSOR_CAP;
2314
2315 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302316 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2317 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002318
Prashant P. Shahb654f872010-09-06 17:34:26 +05302319 XGIfb_heap.poha_chain = NULL;
2320 XGIfb_heap.poh_freelist = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002321
Prashant P. Shahb654f872010-09-06 17:34:26 +05302322 poh = XGIfb_poh_new_node();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002323
Prashant P. Shahb654f872010-09-06 17:34:26 +05302324 if (poh == NULL)
2325 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002326
Prashant P. Shahb654f872010-09-06 17:34:26 +05302327 poh->poh_next = &XGIfb_heap.oh_free;
2328 poh->poh_prev = &XGIfb_heap.oh_free;
2329 poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2330 poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002331
Prashant P. Shahb654f872010-09-06 17:34:26 +05302332 DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002333 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2334 (unsigned int) poh->size / 1024);
2335
Prashant P. Shahb654f872010-09-06 17:34:26 +05302336 DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002337 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2338
Prashant P. Shahb654f872010-09-06 17:34:26 +05302339 XGIfb_heap.oh_free.poh_next = poh;
2340 XGIfb_heap.oh_free.poh_prev = poh;
2341 XGIfb_heap.oh_free.size = 0;
2342 XGIfb_heap.max_freesize = poh->size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002343
Prashant P. Shahb654f872010-09-06 17:34:26 +05302344 XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2345 XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2346 XGIfb_heap.oh_used.size = SENTINEL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002347
Prashant P. Shahb654f872010-09-06 17:34:26 +05302348 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002349}
2350
2351static XGI_OH *XGIfb_poh_new_node(void)
2352{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302353 int i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002354 unsigned long cOhs;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302355 XGI_OHALLOC *poha;
2356 XGI_OH *poh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002357
2358 if (XGIfb_heap.poh_freelist == NULL) {
2359 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302360 if (!poha)
2361 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002362
2363 poha->poha_next = XGIfb_heap.poha_chain;
2364 XGIfb_heap.poha_chain = poha;
2365
Prashant P. Shahb654f872010-09-06 17:34:26 +05302366 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH)
2367 + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002368
2369 poh = &poha->aoh[0];
2370 for (i = cOhs - 1; i != 0; i--) {
2371 poh->poh_next = poh + 1;
2372 poh = poh + 1;
2373 }
2374
2375 poh->poh_next = NULL;
2376 XGIfb_heap.poh_freelist = &poha->aoh[0];
2377 }
2378
2379 poh = XGIfb_heap.poh_freelist;
2380 XGIfb_heap.poh_freelist = poh->poh_next;
2381
Prashant P. Shahb654f872010-09-06 17:34:26 +05302382 return poh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002383}
2384
2385static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2386{
2387 XGI_OH *pohThis;
2388 XGI_OH *pohRoot;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302389 int bAllocated = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002390
2391 if (size > XGIfb_heap.max_freesize) {
2392 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302393 (unsigned int) size / 1024);
2394 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002395 }
2396
2397 pohThis = XGIfb_heap.oh_free.poh_next;
2398
2399 while (pohThis != &XGIfb_heap.oh_free) {
2400 if (size <= pohThis->size) {
2401 bAllocated = 1;
2402 break;
2403 }
2404 pohThis = pohThis->poh_next;
2405 }
2406
2407 if (!bAllocated) {
2408 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302409 (unsigned int) size / 1024);
2410 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002411 }
2412
2413 if (size == pohThis->size) {
2414 pohRoot = pohThis;
2415 XGIfb_delete_node(pohThis);
2416 } else {
2417 pohRoot = XGIfb_poh_new_node();
2418
Prashant P. Shahb654f872010-09-06 17:34:26 +05302419 if (pohRoot == NULL)
2420 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002421
2422 pohRoot->offset = pohThis->offset;
2423 pohRoot->size = size;
2424
2425 pohThis->offset += size;
2426 pohThis->size -= size;
2427 }
2428
2429 XGIfb_heap.max_freesize -= size;
2430
2431 pohThis = &XGIfb_heap.oh_used;
2432 XGIfb_insert_node(pohThis, pohRoot);
2433
Prashant P. Shahb654f872010-09-06 17:34:26 +05302434 return pohRoot;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002435}
2436
2437static void XGIfb_delete_node(XGI_OH *poh)
2438{
2439 XGI_OH *poh_prev;
2440 XGI_OH *poh_next;
2441
2442 poh_prev = poh->poh_prev;
2443 poh_next = poh->poh_next;
2444
2445 poh_prev->poh_next = poh_next;
2446 poh_next->poh_prev = poh_prev;
2447
2448}
2449
2450static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2451{
2452 XGI_OH *pohTemp;
2453
2454 pohTemp = pohList->poh_next;
2455
2456 pohList->poh_next = poh;
2457 pohTemp->poh_prev = poh;
2458
2459 poh->poh_prev = pohList;
2460 poh->poh_next = pohTemp;
2461}
2462
2463static XGI_OH *XGIfb_poh_free(unsigned long base)
2464{
2465 XGI_OH *pohThis;
2466 XGI_OH *poh_freed;
2467 XGI_OH *poh_prev;
2468 XGI_OH *poh_next;
2469 unsigned long ulUpper;
2470 unsigned long ulLower;
2471 int foundNode = 0;
2472
2473 poh_freed = XGIfb_heap.oh_used.poh_next;
2474
Prashant P. Shahb654f872010-09-06 17:34:26 +05302475 while (poh_freed != &XGIfb_heap.oh_used) {
2476 if (poh_freed->offset == base) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002477 foundNode = 1;
2478 break;
2479 }
2480
2481 poh_freed = poh_freed->poh_next;
2482 }
2483
Prashant P. Shahb654f872010-09-06 17:34:26 +05302484 if (!foundNode)
2485 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002486
2487 XGIfb_heap.max_freesize += poh_freed->size;
2488
2489 poh_prev = poh_next = NULL;
2490 ulUpper = poh_freed->offset + poh_freed->size;
2491 ulLower = poh_freed->offset;
2492
2493 pohThis = XGIfb_heap.oh_free.poh_next;
2494
2495 while (pohThis != &XGIfb_heap.oh_free) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302496 if (pohThis->offset == ulUpper)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002497 poh_next = pohThis;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302498 else if ((pohThis->offset + pohThis->size) == ulLower)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002499 poh_prev = pohThis;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302500
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002501 pohThis = pohThis->poh_next;
2502 }
2503
2504 XGIfb_delete_node(poh_freed);
2505
2506 if (poh_prev && poh_next) {
2507 poh_prev->size += (poh_freed->size + poh_next->size);
2508 XGIfb_delete_node(poh_next);
2509 XGIfb_free_node(poh_freed);
2510 XGIfb_free_node(poh_next);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302511 return poh_prev;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002512 }
2513
2514 if (poh_prev) {
2515 poh_prev->size += poh_freed->size;
2516 XGIfb_free_node(poh_freed);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302517 return poh_prev;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002518 }
2519
2520 if (poh_next) {
2521 poh_next->size += poh_freed->size;
2522 poh_next->offset = poh_freed->offset;
2523 XGIfb_free_node(poh_freed);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302524 return poh_next;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002525 }
2526
2527 XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2528
Prashant P. Shahb654f872010-09-06 17:34:26 +05302529 return poh_freed;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002530}
2531
2532static void XGIfb_free_node(XGI_OH *poh)
2533{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302534 if (poh == NULL)
2535 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002536
2537 poh->poh_next = XGIfb_heap.poh_freelist;
2538 XGIfb_heap.poh_freelist = poh;
2539
2540}
2541
2542void XGI_malloc(struct XGI_memreq *req)
2543{
2544 XGI_OH *poh;
2545
2546 poh = XGIfb_poh_allocate(req->size);
2547
Prashant P. Shahb654f872010-09-06 17:34:26 +05302548 if (poh == NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002549 req->offset = 0;
2550 req->size = 0;
2551 DPRINTK("XGIfb: Video RAM allocation failed\n");
2552 } else {
2553 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302554 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002555
2556 req->offset = poh->offset;
2557 req->size = poh->size;
2558 }
2559
2560}
2561
2562void XGI_free(unsigned long base)
2563{
2564 XGI_OH *poh;
2565
2566 poh = XGIfb_poh_free(base);
2567
Prashant P. Shahb654f872010-09-06 17:34:26 +05302568 if (poh == NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002569 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302570 (unsigned int) base);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002571 }
2572}
2573
2574/* --------------------- SetMode routines ------------------------- */
2575
2576static void XGIfb_pre_setmode(void)
2577{
2578 u8 cr30 = 0, cr31 = 0;
2579
2580 inXGIIDXREG(XGICR, 0x31, cr31);
2581 cr31 &= ~0x60;
2582
2583 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302584 case DISPTYPE_CRT2:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002585 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2586 cr31 |= XGI_DRIVER_MODE;
2587 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302588 case DISPTYPE_LCD:
2589 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002590 cr31 |= XGI_DRIVER_MODE;
2591 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302592 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002593 if (xgi_video_info.TV_type == TVMODE_HIVISION)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302594 cr30 = (XGI_VB_OUTPUT_HIVISION
2595 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002596 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302597 cr30 = (XGI_VB_OUTPUT_SVIDEO
2598 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002599 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302600 cr30 = (XGI_VB_OUTPUT_COMPOSITE
2601 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002602 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302603 cr30 = (XGI_VB_OUTPUT_SCART
2604 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002605 cr31 |= XGI_DRIVER_MODE;
2606
Prashant P. Shahb654f872010-09-06 17:34:26 +05302607 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002608 cr31 |= 0x01;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302609 else
2610 cr31 &= ~0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002611 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302612 default: /* disable CRT2 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002613 cr30 = 0x00;
2614 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2615 }
2616
2617 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2618 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302619 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002620
Prashant P. Shahb654f872010-09-06 17:34:26 +05302621 if (xgi_video_info.accel)
2622 XGIfb_syncaccel();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002623
2624}
2625
2626static void XGIfb_post_setmode(void)
2627{
2628 u8 reg;
Bill Pemberton82d6eb52010-06-17 13:10:46 -04002629 unsigned char doit = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302630 /*
2631 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2632 outXGIIDXREG(XGICR, 0x13, 0x00);
2633 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
2634 *test*
2635 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002636 if (xgi_video_info.video_bpp == 8) {
2637 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302638 if ((xgi_video_info.hasVB == HASVB_LVDS)
2639 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
Bill Pembertondda08c52010-06-17 13:10:42 -04002640 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002641 }
2642 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302643 if (xgi_video_info.disp_state & DISPTYPE_LCD)
Bill Pembertondda08c52010-06-17 13:10:42 -04002644 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002645 }
2646
2647 /* TW: We can't switch off CRT1 if bridge is in slave mode */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302648 if (xgi_video_info.hasVB != HASVB_NONE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002649 inXGIIDXREG(XGIPART1, 0x00, reg);
2650
Bill Pembertondda08c52010-06-17 13:10:42 -04002651 if ((reg & 0x50) == 0x10)
2652 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002653
Prashant P. Shahb654f872010-09-06 17:34:26 +05302654 } else {
Bill Pembertondda08c52010-06-17 13:10:42 -04002655 XGIfb_crt1off = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302656 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002657
2658 inXGIIDXREG(XGICR, 0x17, reg);
Bill Pembertondda08c52010-06-17 13:10:42 -04002659 if ((XGIfb_crt1off) && (doit))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002660 reg &= ~0x80;
2661 else
2662 reg |= 0x80;
2663 outXGIIDXREG(XGICR, 0x17, reg);
2664
Prashant P. Shahb654f872010-09-06 17:34:26 +05302665 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002666
Prashant P. Shahb654f872010-09-06 17:34:26 +05302667 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
2668 == HASVB_301)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002669
Prashant P. Shahb654f872010-09-06 17:34:26 +05302670 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002671
Prashant P. Shahb654f872010-09-06 17:34:26 +05302672 if (reg < 0xB0) { /* Set filter for XGI301 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002673
Prashant P. Shahb654f872010-09-06 17:34:26 +05302674 switch (xgi_video_info.video_width) {
2675 case 320:
2676 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2677 break;
2678 case 640:
2679 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2680 break;
2681 case 720:
2682 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2683 break;
2684 case 800:
2685 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2686 break;
2687 default:
2688 filter = -1;
2689 break;
2690 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002691
Prashant P. Shahb654f872010-09-06 17:34:26 +05302692 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002693
Prashant P. Shahb654f872010-09-06 17:34:26 +05302694 if (xgi_video_info.TV_type == TVMODE_NTSC) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002695
Prashant P. Shahb654f872010-09-06 17:34:26 +05302696 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002697
Prashant P. Shahb654f872010-09-06 17:34:26 +05302698 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002699
Prashant P. Shahb654f872010-09-06 17:34:26 +05302700 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002701
Prashant P. Shahb654f872010-09-06 17:34:26 +05302702 } else if (xgi_video_info.TV_plug
2703 == TVPLUG_COMPOSITE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002704
Prashant P. Shahb654f872010-09-06 17:34:26 +05302705 orXGIIDXREG(XGIPART2, 0x30, 0x20);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002706
Prashant P. Shahb654f872010-09-06 17:34:26 +05302707 switch (xgi_video_info.video_width) {
2708 case 640:
2709 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2710 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2711 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2712 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2713 break;
2714 case 720:
2715 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2716 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2717 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2718 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2719 break;
2720 case 800:
2721 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2722 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2723 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2724 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2725 break;
2726 }
2727 }
2728
2729 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2730
2731 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2732
2733 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2734
2735 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2736
2737 } else if (xgi_video_info.TV_plug
2738 == TVPLUG_COMPOSITE) {
2739
2740 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2741
2742 switch (xgi_video_info.video_width) {
2743 case 640:
2744 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2745 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2746 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2747 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2748 break;
2749 case 720:
2750 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2751 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2752 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2753 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2754 break;
2755 case 800:
2756 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2757 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2758 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2759 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2760 break;
2761 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002762 }
2763 }
2764
Prashant P. Shahb654f872010-09-06 17:34:26 +05302765 if ((filter >= 0) && (filter <= 7)) {
2766 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2767 XGI_TV_filter[filter_tb].filter[filter][0],
2768 XGI_TV_filter[filter_tb].filter[filter][1],
2769 XGI_TV_filter[filter_tb].filter[filter][2],
2770 XGI_TV_filter[filter_tb].filter[filter][3]
2771 );
2772 outXGIIDXREG(
2773 XGIPART2,
2774 0x35,
2775 (XGI_TV_filter[filter_tb].filter[filter][0]));
2776 outXGIIDXREG(
2777 XGIPART2,
2778 0x36,
2779 (XGI_TV_filter[filter_tb].filter[filter][1]));
2780 outXGIIDXREG(
2781 XGIPART2,
2782 0x37,
2783 (XGI_TV_filter[filter_tb].filter[filter][2]));
2784 outXGIIDXREG(
2785 XGIPART2,
2786 0x38,
2787 (XGI_TV_filter[filter_tb].filter[filter][3]));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002788 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002789
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002790 }
2791
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002792 }
2793
2794}
2795
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002796XGIINITSTATIC int __init XGIfb_setup(char *options)
2797{
2798 char *this_opt;
2799
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002800 xgi_video_info.refresh_rate = 0;
2801
Prashant P. Shahb654f872010-09-06 17:34:26 +05302802 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002803
2804 if (!options || !*options)
2805 return 0;
2806
Prashant P. Shahb654f872010-09-06 17:34:26 +05302807 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002808
Prashant P. Shahb654f872010-09-06 17:34:26 +05302809 if (!*this_opt)
2810 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002811
2812 if (!strncmp(this_opt, "mode:", 5)) {
2813 XGIfb_search_mode(this_opt + 5);
2814 } else if (!strncmp(this_opt, "vesa:", 5)) {
2815 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2816 } else if (!strncmp(this_opt, "mode:", 5)) {
2817 XGIfb_search_mode(this_opt + 5);
2818 } else if (!strncmp(this_opt, "vesa:", 5)) {
2819 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2820 } else if (!strncmp(this_opt, "vrate:", 6)) {
2821 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2822 } else if (!strncmp(this_opt, "rate:", 5)) {
2823 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2824 } else if (!strncmp(this_opt, "off", 3)) {
2825 XGIfb_off = 1;
2826 } else if (!strncmp(this_opt, "crt1off", 7)) {
2827 XGIfb_crt1off = 1;
2828 } else if (!strncmp(this_opt, "filter:", 7)) {
2829 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2830 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2831 XGIfb_search_crt2type(this_opt + 14);
2832 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2833 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302834 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002835 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302836 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2837 XGIfb_search_tvstd(this_opt + 7);
2838 } else if (!strncmp(this_opt, "mem:", 4)) {
2839 XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2840 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002841 enable_dstn = 1;
2842 /* TW: DSTN overrules forcecrt2type */
2843 XGIfb_crt2type = DISPTYPE_LCD;
2844 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2845 XGIfb_search_queuemode(this_opt + 10);
2846 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302847 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2848 if (XGIfb_pdc & ~0x3c) {
2849 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2850 XGIfb_pdc = 0;
2851 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002852 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302853 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002854 } else if (!strncmp(this_opt, "userom:", 7)) {
2855 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302856 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2857 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002858 } else {
2859 XGIfb_search_mode(this_opt);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302860 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002861 }
2862
2863 /* TW: Acceleration only with MMIO mode */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302864 if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002865 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002866 }
2867 /* TW: Panning only with acceleration */
Javier Martinez Canillas0089bf12011-02-21 18:16:43 +01002868 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002869
2870 }
2871 printk("\nxgifb: outa xgifb_setup 3450");
2872 return 0;
2873}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002874
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002875static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002876{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002877 void __iomem *rom_address;
2878 unsigned char *rom_copy;
2879 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002880
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002881 rom_address = pci_map_rom(dev, &rom_size);
2882 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002883 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002884
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002885 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2886 if (rom_copy == NULL)
2887 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002888
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002889 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2890 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002891
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002892done:
2893 pci_unmap_rom(dev, rom_address);
2894 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002895}
2896
Randy Dunlap89229672010-08-10 08:46:44 -07002897static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302898 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002899{
2900 u16 reg16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302901 u8 reg, reg1;
2902 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002903 int ret;
2904
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002905 if (XGIfb_off)
2906 return -ENXIO;
2907
2908 XGIfb_registered = 0;
2909
Bill Pembertone4147ab2010-06-17 13:10:50 -04002910 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302911 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2912 if (!fb_info)
2913 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002914
Prashant P. Shahb654f872010-09-06 17:34:26 +05302915 xgi_video_info.chip_id = pdev->device;
2916 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2917 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
2918 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2919 XGIvga_enabled = reg16 & 0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002920
Prashant P. Shahb654f872010-09-06 17:34:26 +05302921 xgi_video_info.pcibus = pdev->bus->number;
2922 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2923 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2924 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2925 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002926
Prashant P. Shahb654f872010-09-06 17:34:26 +05302927 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2928 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002929 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302930 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2931 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2932 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2933 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2934 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002935
Aaro Koskinenbb292232011-02-17 23:29:11 +02002936 if (pci_enable_device(pdev)) {
2937 ret = -EIO;
2938 goto error;
2939 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002940
Prashant P. Shahb654f872010-09-06 17:34:26 +05302941 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002942
Prashant P. Shahb654f872010-09-06 17:34:26 +05302943 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2944 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002945
Prashant P. Shahb654f872010-09-06 17:34:26 +05302946 if (reg1 != 0xa1) { /*I/O error */
2947 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002948 ret = -EIO;
2949 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302950 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002951
2952 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302953 case PCI_DEVICE_ID_XG_20:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002954 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2955 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2956 if (CR48&GPIOG_READ)
2957 xgi_video_info.chip = XG21;
2958 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302959 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002960 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2961 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2962 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302963 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002964 xgi_video_info.chip = XG40;
2965 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2966 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2967 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302968 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002969 xgi_video_info.chip = XG41;
2970 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2971 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2972 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302973 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002974 xgi_video_info.chip = XG42;
2975 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2976 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2977 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302978 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002979 xgi_video_info.chip = XG27;
2980 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2981 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2982 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302983 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002984 ret = -ENODEV;
2985 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002986 }
2987
Prashant P. Shahb654f872010-09-06 17:34:26 +05302988 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2989 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002990
Prashant P. Shahb654f872010-09-06 17:34:26 +05302991 switch (xgi_video_info.chip) {
2992 case XG40:
2993 case XG41:
2994 case XG42:
2995 case XG45:
2996 case XG20:
2997 case XG21:
2998 case XG27:
2999 XGIhw_ext.bIntegratedMMEnabled = 1;
3000 break;
3001 default:
3002 break;
3003 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003004
Prashant P. Shahb654f872010-09-06 17:34:26 +05303005 XGIhw_ext.pDevice = NULL;
3006 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02003007 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303008 if (XGIhw_ext.pjVirtualRomBase)
3009 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003010 else
3011 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05303012 } else {
3013 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003014 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05303015 }
3016 XGIhw_ext.pjCustomizedROMImage = NULL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303017 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
3018 /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */
3019 strcpy(XGIhw_ext.szVBIOSVer, "0.84");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003020
Prashant P. Shahb654f872010-09-06 17:34:26 +05303021 if (!XGIvga_enabled) {
3022 /* Mapping Max FB Size for 315 Init */
3023 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3024 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003025#ifdef LINUXBIOS
Prashant P. Shahb654f872010-09-06 17:34:26 +05303026 printk("XGIfb: XGIInit() ...");
3027 /* XGIInitNewt for LINUXBIOS only */
3028 if (XGIInitNew(&XGIhw_ext))
3029 printk("OK\n");
3030 else
3031 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003032#endif
3033
Prashant P. Shahb654f872010-09-06 17:34:26 +05303034 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003035
Prashant P. Shahb654f872010-09-06 17:34:26 +05303036 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003037 }
3038#ifdef LINUXBIOS
Prashant P. Shahb654f872010-09-06 17:34:26 +05303039 else {
3040 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3041 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3042
3043 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3044
3045 /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
3046 /* Set SR13 ,14 temporarily for UDtech */
3047 outXGIIDXREG(XGISR, 0x13, 0x45);
3048 outXGIIDXREG(XGISR, 0x14, 0x51);
3049
3050 }
3051 }
3052#endif
3053 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303054 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003055 ret = -ENODEV;
3056 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303057 }
3058
3059 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3060 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
3061 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3062 /* Enable 2D accelerator engine */
3063 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3064 }
3065
3066 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3067
3068 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
3069 printk("unable request memory size %x", xgi_video_info.video_size);
3070 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3071 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003072 ret = -ENODEV;
3073 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303074 }
3075
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02003076 if (!request_mem_region(xgi_video_info.mmio_base,
3077 xgi_video_info.mmio_size,
3078 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303079 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003080 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003081 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303082 }
3083
3084 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3085 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02003086 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
3087 xgi_video_info.mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303088
3089 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3090 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
3091
3092 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02003093 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
3094 xgi_video_info.mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303095 printk("XGIfb: XGIInitNew() ...");
3096 if (XGIInitNew(&XGIhw_ext))
3097 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003098 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003099 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003100
Prashant P. Shahb654f872010-09-06 17:34:26 +05303101 if (XGIfb_heap_init())
3102 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003103
Prashant P. Shahb654f872010-09-06 17:34:26 +05303104 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003105
Prashant P. Shahb654f872010-09-06 17:34:26 +05303106 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003107 xgi_video_info.hasVB = HASVB_NONE;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303108 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
3109 xgi_video_info.hasVB = HASVB_NONE;
3110 } else if (xgi_video_info.chip == XG21) {
3111 inXGIIDXREG(XGICR, 0x38, CR38);
3112 if ((CR38&0xE0) == 0xC0) {
3113 xgi_video_info.disp_state = DISPTYPE_LCD;
3114 if (!XGIfb_GetXG21LVDSData()) {
3115 int m;
3116 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
3117 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3118 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3119 XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
3120 }
3121 }
3122 }
3123 } else if ((CR38&0xE0) == 0x60) {
3124 xgi_video_info.hasVB = HASVB_CHRONTEL;
3125 } else {
3126 xgi_video_info.hasVB = HASVB_NONE;
3127 }
3128 } else {
3129 XGIfb_get_VB_type();
3130 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003131
Prashant P. Shahb654f872010-09-06 17:34:26 +05303132 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003133
Prashant P. Shahb654f872010-09-06 17:34:26 +05303134 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003135
3136 switch (xgi_video_info.hasVB) {
3137 case HASVB_301:
Prashant P. Shahb654f872010-09-06 17:34:26 +05303138 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003139 if (reg >= 0xE0) {
3140 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303141 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3142 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003143 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303144 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
3145 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003146 /* else if (reg >= 0xB0) {
3147 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303148 inXGIIDXREG(XGIPART4, 0x23, reg1);
3149 printk("XGIfb: XGI301B bridge detected\n");
3150 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003151 else {
3152 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3153 printk("XGIfb: XGI301 bridge detected\n");
3154 }
3155 break;
3156 case HASVB_302:
Prashant P. Shahb654f872010-09-06 17:34:26 +05303157 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003158 if (reg >= 0xE0) {
3159 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303160 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3161 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003162 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303163 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3164 } else if (reg >= 0xB0) {
3165 inXGIIDXREG(XGIPART4, 0x23, reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003166
Prashant P. Shahb654f872010-09-06 17:34:26 +05303167 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003168
3169 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303170 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003171 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3172 }
3173 break;
3174 case HASVB_LVDS:
3175 XGIhw_ext.ulExternalChip = 0x1;
3176 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3177 break;
3178 case HASVB_TRUMPION:
3179 XGIhw_ext.ulExternalChip = 0x2;
3180 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3181 break;
3182 case HASVB_CHRONTEL:
3183 XGIhw_ext.ulExternalChip = 0x4;
3184 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3185 break;
3186 case HASVB_LVDS_CHRONTEL:
3187 XGIhw_ext.ulExternalChip = 0x5;
3188 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3189 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303190 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003191 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3192 break;
3193 }
3194
Prashant P. Shahb654f872010-09-06 17:34:26 +05303195 if (xgi_video_info.hasVB != HASVB_NONE)
3196 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003197
3198 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3199 if (XGIfb_crt1off)
3200 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3201 else
3202 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3203 } else {
3204 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3205 }
3206
3207 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303208 if (!enable_dstn) {
3209 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3210 reg &= 0x0f;
3211 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003212
Prashant P. Shahb654f872010-09-06 17:34:26 +05303213 } else {
3214 /* TW: FSTN/DSTN */
3215 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3216 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003217 }
3218
3219 XGIfb_detectedpdc = 0;
3220
Prashant P. Shahb654f872010-09-06 17:34:26 +05303221 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003222#ifndef LINUXBIOS
3223
Prashant P. Shahb654f872010-09-06 17:34:26 +05303224 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003225
Prashant P. Shahb654f872010-09-06 17:34:26 +05303226 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3227 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3228 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
3229 int tmp;
3230 inXGIIDXREG(XGICR, 0x34, tmp);
3231 if (tmp <= 0x13) {
3232 /* Currently on LCDA? (Some BIOSes leave CR38) */
3233 inXGIIDXREG(XGICR, 0x38, tmp);
3234 if ((tmp & 0x03) == 0x03) {
3235 /* XGI_Pr.XGI_UseLCDA = 1; */
3236 } else {
3237 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
3238 inXGIIDXREG(XGICR, 0x35, tmp);
3239 if (tmp & 0x01) {
3240 /* XGI_Pr.XGI_UseLCDA = 1; */
3241 } else {
3242 inXGIIDXREG(XGICR, 0x30, tmp);
3243 if (tmp & 0x20) {
3244 inXGIIDXREG(XGIPART1, 0x13, tmp);
3245 if (tmp & 0x04) {
3246 /* XGI_Pr.XGI_UseLCDA = 1; */
3247 }
3248 }
3249 }
3250 }
3251 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003252
Prashant P. Shahb654f872010-09-06 17:34:26 +05303253 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003254
3255#endif
3256
3257 if (xgifb_mode_idx >= 0)
3258 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3259
3260 if (xgifb_mode_idx < 0) {
3261 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303262 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003263 xgifb_mode_idx = DEFAULT_LCDMODE;
3264 if (xgi_video_info.chip == XG21)
Prashant P. Shahb654f872010-09-06 17:34:26 +05303265 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003266 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303267 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003268 xgifb_mode_idx = DEFAULT_TVMODE;
3269 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303270 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003271 xgifb_mode_idx = DEFAULT_MODE;
3272 break;
3273 }
3274 }
3275
3276 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3277
Prashant P. Shahb654f872010-09-06 17:34:26 +05303278 if (xgi_video_info.refresh_rate == 0)
3279 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
3280 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
3281 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3282 xgi_video_info.refresh_rate = 60;
3283 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003284
3285 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3286 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3287 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3288 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3289 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303290 switch (xgi_video_info.video_bpp) {
3291 case 8:
3292 xgi_video_info.DstColor = 0x0000;
3293 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003294 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303295 break;
3296 case 16:
3297 xgi_video_info.DstColor = 0x8000;
3298 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003299 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303300 break;
3301 case 32:
3302 xgi_video_info.DstColor = 0xC000;
3303 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003304 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303305 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003306 default:
3307 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303308 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003309 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303310 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003311
3312 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05303313 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3314 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003315
3316 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3317 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3318 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3319
3320 XGIfb_bpp_to_var(&default_var);
3321
3322 default_var.pixclock = (u32) (1000000000 /
3323 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3324 XGIfb_mode_no, XGIfb_rate_idx));
3325
Prashant P. Shahb654f872010-09-06 17:34:26 +05303326 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3327 XGIfb_mode_no, XGIfb_rate_idx,
3328 &default_var.left_margin, &default_var.right_margin,
3329 &default_var.upper_margin, &default_var.lower_margin,
3330 &default_var.hsync_len, &default_var.vsync_len,
3331 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003332
Prashant P. Shahb654f872010-09-06 17:34:26 +05303333 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3334 default_var.yres <<= 1;
3335 default_var.yres_virtual <<= 1;
3336 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3337 default_var.pixclock >>= 1;
3338 default_var.yres >>= 1;
3339 default_var.yres_virtual >>= 1;
3340 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003341
Prashant P. Shahb654f872010-09-06 17:34:26 +05303342 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003343
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003344 xgi_video_info.accel = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003345
3346 fb_info->flags = FBINFO_FLAG_DEFAULT;
3347 fb_info->var = default_var;
3348 fb_info->fix = XGIfb_fix;
3349 fb_info->par = &xgi_video_info;
3350 fb_info->screen_base = xgi_video_info.video_vbase;
3351 fb_info->fbops = &XGIfb_ops;
3352 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3353 fb_info->pseudo_palette = pseudo_palette;
3354
3355 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3356
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003357#ifdef CONFIG_MTRR
3358 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3359 (unsigned int) xgi_video_info.video_size,
3360 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303361 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003362 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003363#endif
3364
Aaro Koskinenbb292232011-02-17 23:29:11 +02003365 if (register_framebuffer(fb_info) < 0) {
3366 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003367 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02003368 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003369
3370 XGIfb_registered = 1;
3371
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003372 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05303373 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003374
3375 }
3376
3377 dumpVGAReg();
3378
3379 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02003380
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003381error_1:
3382 iounmap(xgi_video_info.mmio_vbase);
3383 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02003384 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003385error_0:
3386 release_mem_region(xgi_video_info.video_base,
3387 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02003388error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02003389 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02003390 framebuffer_release(fb_info);
3391 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003392}
3393
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003394/*****************************************************/
3395/* PCI DEVICE HANDLING */
3396/*****************************************************/
3397
3398static void __devexit xgifb_remove(struct pci_dev *pdev)
3399{
Prashant P. Shahb654f872010-09-06 17:34:26 +05303400 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003401 iounmap(xgi_video_info.mmio_vbase);
3402 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02003403 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003404 release_mem_region(xgi_video_info.video_base,
3405 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02003406 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303407 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003408 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02003409}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003410
3411static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303412 .name = "xgifb",
3413 .id_table = xgifb_pci_table,
3414 .probe = xgifb_probe,
3415 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003416};
3417
3418XGIINITSTATIC int __init xgifb_init(void)
3419{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003420 char *option = NULL;
3421
3422 if (fb_get_options("xgifb", &option))
3423 return -ENODEV;
3424 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04003425
Prashant P. Shahb654f872010-09-06 17:34:26 +05303426 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003427}
3428
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003429#ifndef MODULE
3430module_init(xgifb_init);
3431#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003432
3433/*****************************************************/
3434/* MODULE */
3435/*****************************************************/
3436
3437#ifdef MODULE
3438
Prashant P. Shahb654f872010-09-06 17:34:26 +05303439static char *mode = NULL;
3440static int vesa = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003441static unsigned int rate = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003442static unsigned int mem = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303443static char *forcecrt2type = NULL;
3444static int forcecrt1 = -1;
3445static int pdc = -1;
3446static int pdc1 = -1;
3447static int noaccel = -1;
3448static int noypan = -1;
3449static int nomax = -1;
3450static int userom = -1;
3451static int useoem = -1;
3452static char *tvstandard = NULL;
3453static int nocrt2rate = 0;
3454static int scalelcd = -1;
3455static char *specialtiming = NULL;
3456static int lvdshl = -1;
3457static int tvxposoffset = 0, tvyposoffset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003458#if !defined(__i386__) && !defined(__x86_64__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05303459static int resetcard = 0;
3460static int videoram = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003461#endif
3462
3463MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3464MODULE_LICENSE("GPL");
3465MODULE_AUTHOR("XGITECH , Others");
3466
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003467module_param(mem, int, 0);
3468module_param(noaccel, int, 0);
3469module_param(noypan, int, 0);
3470module_param(nomax, int, 0);
3471module_param(userom, int, 0);
3472module_param(useoem, int, 0);
3473module_param(mode, charp, 0);
3474module_param(vesa, int, 0);
3475module_param(rate, int, 0);
3476module_param(forcecrt1, int, 0);
3477module_param(forcecrt2type, charp, 0);
3478module_param(scalelcd, int, 0);
3479module_param(pdc, int, 0);
3480module_param(pdc1, int, 0);
3481module_param(specialtiming, charp, 0);
3482module_param(lvdshl, int, 0);
3483module_param(tvstandard, charp, 0);
3484module_param(tvxposoffset, int, 0);
3485module_param(tvyposoffset, int, 0);
3486module_param(filter, int, 0);
3487module_param(nocrt2rate, int, 0);
3488#if !defined(__i386__) && !defined(__x86_64__)
3489module_param(resetcard, int, 0);
3490module_param(videoram, int, 0);
3491#endif
3492
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003493MODULE_PARM_DESC(mem,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303494 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3495 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3496 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3497 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3498 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3499 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3500 "for XFree86 4.x/X.org 6.7 and later.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003501
3502MODULE_PARM_DESC(noaccel,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303503 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3504 "(default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003505
3506MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303507 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3508 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003509
3510MODULE_PARM_DESC(nomax,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303511 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3512 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3513 "this is set to anything other than 0, xgifb will not do this and thereby\n"
3514 "enable the user to positively specify a virtual Y size of the screen using\n"
3515 "fbset. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003516
3517MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303518 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3519 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3520 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3521 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003522
3523MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303524 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3525 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003526
3527MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303528 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3529 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3530 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003531
3532MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303533 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
3534 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3535 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003536
3537MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303538 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3539 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3540 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3541 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3542 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3543 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3544 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3545 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003546
3547MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303548 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3549 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3550 "show black bars around the image, TMDS panels will probably do the scaling\n"
3551 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003552
3553MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303554 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3555 "should detect this correctly in most cases; however, sometimes this is not\n"
3556 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3557 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3558 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3559 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003560
3561MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303562 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3563 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3564 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3565 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003566
3567MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303568 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003569
3570MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303571 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003572
3573MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303574 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3575 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003576
3577MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303578 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3579 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003580
3581MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303582 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3583 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003584
3585MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303586 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3587 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003588
3589MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303590 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3591 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003592
Randy Dunlap89229672010-08-10 08:46:44 -07003593static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003594{
Prashant P. Shahb654f872010-09-06 17:34:26 +05303595 printk("\nXGIfb_init_module");
3596 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003597 XGIfb_search_mode(mode);
3598 else if (vesa != -1)
3599 XGIfb_search_vesamode(vesa);
3600
Prashant P. Shahb654f872010-09-06 17:34:26 +05303601 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003602}
3603
3604static void __exit xgifb_remove_module(void)
3605{
3606 pci_unregister_driver(&xgifb_driver);
3607 printk(KERN_DEBUG "xgifb: Module unloaded\n");
3608}
3609
3610module_init(xgifb_init_module);
3611module_exit(xgifb_remove_module);
3612
Prashant P. Shahb654f872010-09-06 17:34:26 +05303613#endif /* /MODULE */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003614
3615EXPORT_SYMBOL(XGI_malloc);
3616EXPORT_SYMBOL(XGI_free);
3617