blob: f69ff574767e3520f887166d4438438d969cdcce [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
Randy Dunlap89229672010-08-10 08:46:44 -070046int XGIfb_accel = 0;
47
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020048#define Index_CR_GPIO_Reg1 0x48
49#define Index_CR_GPIO_Reg2 0x49
50#define Index_CR_GPIO_Reg3 0x4a
51
52#define GPIOG_EN (1<<6)
53#define GPIOG_WRITE (1<<6)
54#define GPIOG_READ (1<<1)
55int XGIfb_GetXG21DefaultLVDSModeIdx(void);
56
Aaro Koskinen0f07d942011-02-17 23:29:13 +020057#define XGIFB_ROM_SIZE 65536
58
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020059/* -------------------- Macro definitions ---------------------------- */
60
61#undef XGIFBDEBUG
62
63#ifdef XGIFBDEBUG
64#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
65#else
66#define DPRINTK(fmt, args...)
67#endif
68
69#ifdef XGIFBDEBUG
70static void dumpVGAReg(void)
71{
Prashant P. Shahb654f872010-09-06 17:34:26 +053072 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020073
Prashant P. Shahb654f872010-09-06 17:34:26 +053074 outXGIIDXREG(XGISR, 0x05, 0x86);
75 /*
76 outXGIIDXREG(XGISR, 0x08, 0x4f);
77 outXGIIDXREG(XGISR, 0x0f, 0x20);
78 outXGIIDXREG(XGISR, 0x11, 0x4f);
79 outXGIIDXREG(XGISR, 0x13, 0x45);
80 outXGIIDXREG(XGISR, 0x14, 0x51);
81 outXGIIDXREG(XGISR, 0x1e, 0x41);
82 outXGIIDXREG(XGISR, 0x1f, 0x0);
83 outXGIIDXREG(XGISR, 0x20, 0xa1);
84 outXGIIDXREG(XGISR, 0x22, 0xfb);
85 outXGIIDXREG(XGISR, 0x26, 0x22);
86 outXGIIDXREG(XGISR, 0x3e, 0x07);
87 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020088
Prashant P. Shahb654f872010-09-06 17:34:26 +053089 /* outXGIIDXREG(XGICR, 0x19, 0x00); */
90 /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
91 /* outXGIIDXREG(XGICR, 0x22, 0xff); */
92 /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020093
Prashant P. Shahb654f872010-09-06 17:34:26 +053094 /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020095
Prashant P. Shahb654f872010-09-06 17:34:26 +053096 /* outXGIIDXREG(XGICR, 0x57, 0x0); */
97 /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020098
Prashant P. Shahb654f872010-09-06 17:34:26 +053099 /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
100 /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
101 /*
102 outXGIIDXREG(XGICR, 0x99, 0x1);
103 outXGIIDXREG(XGICR, 0x41, 0x40);
104 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200105
Prashant P. Shahb654f872010-09-06 17:34:26 +0530106 for (i = 0; i < 0x4f; i++) {
107 inXGIIDXREG(XGISR, i, reg);
108 printk("\no 3c4 %x", i);
109 printk("\ni 3c5 => %x", reg);
110 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200111
Prashant P. Shahb654f872010-09-06 17:34:26 +0530112 for (i = 0; i < 0xF0; i++) {
113 inXGIIDXREG(XGICR, i, reg);
114 printk("\no 3d4 %x", i);
115 printk("\ni 3d5 => %x", reg);
116 }
117 /*
118 outXGIIDXREG(XGIPART1,0x2F,1);
119 for (i=1; i < 0x50; i++) {
120 inXGIIDXREG(XGIPART1, i, reg);
121 printk("\no d004 %x", i);
122 printk("\ni d005 => %x", reg);
123 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200124
Prashant P. Shahb654f872010-09-06 17:34:26 +0530125 for (i=0; i < 0x50; i++) {
126 inXGIIDXREG(XGIPART2, i, reg);
127 printk("\no d010 %x", i);
128 printk("\ni d011 => %x", reg);
129 }
130 for (i=0; i < 0x50; i++) {
131 inXGIIDXREG(XGIPART3, i, reg);
132 printk("\no d012 %x",i);
133 printk("\ni d013 => %x",reg);
134 }
135 for (i=0; i < 0x50; i++) {
136 inXGIIDXREG(XGIPART4, i, reg);
137 printk("\no d014 %x",i);
138 printk("\ni d015 => %x",reg);
139 }
140 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200141}
142#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530143static inline void dumpVGAReg(void)
144{
145}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200146#endif
147
148/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530149struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200150
151#if 1
152#define DEBUGPRN(x)
153#else
154#define DEBUGPRN(x) printk(KERN_INFO x "\n");
155#endif
156
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200157/* --------------- Hardware Access Routines -------------------------- */
158
Prashant P. Shahb654f872010-09-06 17:34:26 +0530159static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
160 struct xgi_hw_device_info *HwDeviceExtension,
161 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200162{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530163 unsigned short ModeNo = modeno;
164 unsigned short ModeIdIndex = 0, ClockIndex = 0;
165 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200166
Prashant P. Shahb654f872010-09-06 17:34:26 +0530167 /* unsigned long temp = 0; */
168 int Clock;
169 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
170 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200171
Prashant P. Shahb654f872010-09-06 17:34:26 +0530172 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
173 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200174
Prashant P. Shahb654f872010-09-06 17:34:26 +0530175 /*
176 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
177 if (!temp) {
178 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
179 return 65000;
180 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200181
Prashant P. Shahb654f872010-09-06 17:34:26 +0530182 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
183 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200184
Prashant P. Shahb654f872010-09-06 17:34:26 +0530185 */
186 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
187 if (HwDeviceExtension->jChipType < XGI_315H)
188 ClockIndex &= 0x3F;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200189
Prashant P. Shahb654f872010-09-06 17:34:26 +0530190 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
191
192 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200193}
194
Prashant P. Shahb654f872010-09-06 17:34:26 +0530195static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
196 struct xgi_hw_device_info *HwDeviceExtension,
197 unsigned char modeno, unsigned char rateindex,
198 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
199 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
200 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200201{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530202 unsigned short ModeNo = modeno;
203 unsigned short ModeIdIndex = 0, index = 0;
204 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200205
Prashant P. Shahb654f872010-09-06 17:34:26 +0530206 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
207 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
208 unsigned char sr_data, cr_data, cr_data2;
209 unsigned long cr_data3;
210 int A, B, C, D, E, F, temp, j;
211 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
212 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
213 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
214 ModeIdIndex, XGI_Pr);
215 /*
216 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
217 if (!temp)
218 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200219
Prashant P. Shahb654f872010-09-06 17:34:26 +0530220 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
221 RefreshRateTableIndex += (rateindex - 1);
222 */
223 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200224
Prashant P. Shahb654f872010-09-06 17:34:26 +0530225 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200226
Prashant P. Shahb654f872010-09-06 17:34:26 +0530227 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200228
Prashant P. Shahb654f872010-09-06 17:34:26 +0530229 /* Horizontal total */
230 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
231 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200232
Prashant P. Shahb654f872010-09-06 17:34:26 +0530233 /*
234 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200235
Prashant P. Shahb654f872010-09-06 17:34:26 +0530236 Horizontal display enable end
237 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
238 */
239 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
240 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200241
Prashant P. Shahb654f872010-09-06 17:34:26 +0530242 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200243
Prashant P. Shahb654f872010-09-06 17:34:26 +0530244 /* Horizontal retrace (=sync) start */
245 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
246 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200247
Prashant P. Shahb654f872010-09-06 17:34:26 +0530248 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200249
Prashant P. Shahb654f872010-09-06 17:34:26 +0530250 /* Horizontal blank start */
251 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200252
Prashant P. Shahb654f872010-09-06 17:34:26 +0530253 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200254
Prashant P. Shahb654f872010-09-06 17:34:26 +0530255 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200256
Prashant P. Shahb654f872010-09-06 17:34:26 +0530257 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200258
Prashant P. Shahb654f872010-09-06 17:34:26 +0530259 /* Horizontal blank end */
260 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
261 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200262
Prashant P. Shahb654f872010-09-06 17:34:26 +0530263 /* Horizontal retrace (=sync) end */
264 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200265
Prashant P. Shahb654f872010-09-06 17:34:26 +0530266 temp = HBE - ((E - 1) & 255);
267 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200268
Prashant P. Shahb654f872010-09-06 17:34:26 +0530269 temp = HRE - ((E + F + 3) & 63);
270 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200271
Prashant P. Shahb654f872010-09-06 17:34:26 +0530272 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200273
Prashant P. Shahb654f872010-09-06 17:34:26 +0530274 *left_margin = D * 8;
275 *right_margin = F * 8;
276 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200277
Prashant P. Shahb654f872010-09-06 17:34:26 +0530278 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200279
Prashant P. Shahb654f872010-09-06 17:34:26 +0530280 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200281
Prashant P. Shahb654f872010-09-06 17:34:26 +0530282 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200283
Prashant P. Shahb654f872010-09-06 17:34:26 +0530284 /* Vertical total */
285 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
286 | ((unsigned short) (cr_data2 & 0x20) << 4)
287 | ((unsigned short) (sr_data & 0x01) << 10);
288 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200289
Prashant P. Shahb654f872010-09-06 17:34:26 +0530290 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200291
Prashant P. Shahb654f872010-09-06 17:34:26 +0530292 /* Vertical display enable end */
293 /*
294 VDE = (cr_data & 0xff) |
295 ((unsigned short) (cr_data2 & 0x02) << 7) |
296 ((unsigned short) (cr_data2 & 0x40) << 3) |
297 ((unsigned short) (sr_data & 0x02) << 9);
298 */
299 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
300 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200301
Prashant P. Shahb654f872010-09-06 17:34:26 +0530302 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200303
Prashant P. Shahb654f872010-09-06 17:34:26 +0530304 /* Vertical retrace (=sync) start */
305 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
306 | ((unsigned short) (cr_data2 & 0x80) << 2)
307 | ((unsigned short) (sr_data & 0x08) << 7);
308 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200309
Prashant P. Shahb654f872010-09-06 17:34:26 +0530310 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200311
Prashant P. Shahb654f872010-09-06 17:34:26 +0530312 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200313
Prashant P. Shahb654f872010-09-06 17:34:26 +0530314 /* Vertical blank start */
315 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
316 | ((unsigned short) (cr_data3 & 0x20) << 4)
317 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200318
Prashant P. Shahb654f872010-09-06 17:34:26 +0530319 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200320
Prashant P. Shahb654f872010-09-06 17:34:26 +0530321 /* Vertical blank end */
322 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
323 temp = VBE - ((E - 1) & 511);
324 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200325
Prashant P. Shahb654f872010-09-06 17:34:26 +0530326 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200327
Prashant P. Shahb654f872010-09-06 17:34:26 +0530328 /* Vertical retrace (=sync) end */
329 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
330 temp = VRE - ((E + F - 1) & 31);
331 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200332
Prashant P. Shahb654f872010-09-06 17:34:26 +0530333 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200334
Prashant P. Shahb654f872010-09-06 17:34:26 +0530335 *upper_margin = D;
336 *lower_margin = F;
337 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200338
Prashant P. Shahb654f872010-09-06 17:34:26 +0530339 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
340 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
341 else
342 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200343
Prashant P. Shahb654f872010-09-06 17:34:26 +0530344 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
345 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
346 else
347 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200348
Prashant P. Shahb654f872010-09-06 17:34:26 +0530349 *vmode = FB_VMODE_NONINTERLACED;
350 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
351 *vmode = FB_VMODE_INTERLACED;
352 else {
353 j = 0;
354 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
355 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
356 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
357 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
358 & DoubleScanMode) {
359 *vmode = FB_VMODE_DOUBLE;
360 }
361 break;
362 }
363 j++;
364 }
365 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200366
Prashant P. Shahb654f872010-09-06 17:34:26 +0530367 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200368}
369
Randy Dunlap89229672010-08-10 08:46:44 -0700370static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200371{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530372 XGI_Pr->RelIO = BaseAddr;
373 XGI_Pr->P3c4 = BaseAddr + 0x14;
374 XGI_Pr->P3d4 = BaseAddr + 0x24;
375 XGI_Pr->P3c0 = BaseAddr + 0x10;
376 XGI_Pr->P3ce = BaseAddr + 0x1e;
377 XGI_Pr->P3c2 = BaseAddr + 0x12;
378 XGI_Pr->P3ca = BaseAddr + 0x1a;
379 XGI_Pr->P3c6 = BaseAddr + 0x16;
380 XGI_Pr->P3c7 = BaseAddr + 0x17;
381 XGI_Pr->P3c8 = BaseAddr + 0x18;
382 XGI_Pr->P3c9 = BaseAddr + 0x19;
383 XGI_Pr->P3da = BaseAddr + 0x2A;
384 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
385 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
386 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
387 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
388 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200389
390}
391
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200392void XGIfb_set_reg4(u16 port, unsigned long data)
393{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530394 outl((u32)(data & 0xffffffff), port);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200395}
396
397u32 XGIfb_get_reg3(u16 port)
398{
399 u32 data;
400
401 data = inl(port);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530402 return data;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200403}
404
405/* ------------ Interface for init & mode switching code ------------- */
406
Prashant P. Shahb654f872010-09-06 17:34:26 +0530407unsigned char XGIfb_query_VGA_config_space(
408 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
409 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200410{
411 static struct pci_dev *pdev = NULL;
412 static unsigned char init = 0, valid_pdev = 0;
413
414 if (!set)
415 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
416 else
417 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
418
419 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400420 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530421 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
422 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200423 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400424 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200425 pci_dev_put(pdev);
426 }
427 }
428
429 if (!valid_pdev) {
430 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
431 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400432 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200433 }
434
435 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530436 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200437 else
438 pci_write_config_dword(pdev, offset, (u32)(*value));
439
Bill Pembertondda08c52010-06-17 13:10:42 -0400440 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200441}
442
Prashant P. Shahb654f872010-09-06 17:34:26 +0530443/*
444unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200445 unsigned long offset, unsigned long set, unsigned long *value)
446{
447 static struct pci_dev *pdev = NULL;
448 static unsigned char init = 0, valid_pdev = 0;
449 u16 nbridge_id = 0;
450
451 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400452 init = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200453 switch (xgi_video_info.chip) {
454 case XGI_540:
455 nbridge_id = PCI_DEVICE_ID_XG_540;
456 break;
457 case XGI_630:
458 nbridge_id = PCI_DEVICE_ID_XG_630;
459 break;
460 case XGI_730:
461 nbridge_id = PCI_DEVICE_ID_XG_730;
462 break;
463 case XGI_550:
464 nbridge_id = PCI_DEVICE_ID_XG_550;
465 break;
466 case XGI_650:
467 nbridge_id = PCI_DEVICE_ID_XG_650;
468 break;
469 case XGI_740:
470 nbridge_id = PCI_DEVICE_ID_XG_740;
471 break;
472 default:
473 nbridge_id = 0;
474 break;
475 }
476
Atul Sowanifc2347e2010-11-03 18:40:56 +0530477 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
478 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400479 valid_pdev = 1;
Atul Sowanifc2347e2010-11-03 18:40:56 +0530480 pci_dev_put(pdev);
481 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200482 }
483
484 if (!valid_pdev) {
485 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530486 nbridge_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400487 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200488 }
489
490 if (set == 0)
491 pci_read_config_dword(pdev, offset, (u32 *)value);
492 else
493 pci_write_config_dword(pdev, offset, (u32)(*value));
494
Bill Pembertondda08c52010-06-17 13:10:42 -0400495 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200496}
497*/
498/* ------------------ Internal helper routines ----------------- */
499
500static void XGIfb_search_mode(const char *name)
501{
502 int i = 0, j = 0, l;
503
Prashant P. Shahb654f872010-09-06 17:34:26 +0530504 if (name == NULL) {
505 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
506 xgifb_mode_idx = DEFAULT_MODE;
507 if ((xgi_video_info.chip == XG21)
508 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
509 == DISPTYPE_LCD)) {
510 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
511 }
512 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200513 }
514
Prashant P. Shahb654f872010-09-06 17:34:26 +0530515 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
516 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
517 xgifb_mode_idx = DEFAULT_MODE;
518 if ((xgi_video_info.chip == XG21)
519 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
520 == DISPTYPE_LCD)) {
521 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
522 }
523 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200524 }
525
Prashant P. Shahb654f872010-09-06 17:34:26 +0530526 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200527 l = min(strlen(name), strlen(XGIbios_mode[i].name));
528 if (!strncmp(name, XGIbios_mode[i].name, l)) {
529 xgifb_mode_idx = i;
530 j = 1;
531 break;
532 }
533 i++;
534 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530535 if (!j)
536 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200537}
538
539static void XGIfb_search_vesamode(unsigned int vesamode)
540{
541 int i = 0, j = 0;
542
Prashant P. Shahb654f872010-09-06 17:34:26 +0530543 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200544
545 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
546 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530547 if ((xgi_video_info.chip == XG21)
548 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
549 == DISPTYPE_LCD)) {
550 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200551 }
552 return;
553 }
554
Prashant P. Shahb654f872010-09-06 17:34:26 +0530555 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200556
Prashant P. Shahb654f872010-09-06 17:34:26 +0530557 while (XGIbios_mode[i].mode_no != 0) {
558 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
559 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200560 xgifb_mode_idx = i;
561 j = 1;
562 break;
563 }
564 i++;
565 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530566 if (!j)
567 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200568}
569
Randy Dunlap89229672010-08-10 08:46:44 -0700570static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200571{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530572 u8 tmp;
573 unsigned char *pData;
574 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200575
Prashant P. Shahb654f872010-09-06 17:34:26 +0530576 inXGIIDXREG(XGISR, 0x1e, tmp);
577 outXGIIDXREG(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200578
Prashant P. Shahb654f872010-09-06 17:34:26 +0530579 pData = xgi_video_info.mmio_vbase + 0x20000;
580 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
581 i = pData[0x316] | (pData[0x317] << 8);
582 j = pData[i - 1];
583 if (j == 0xff)
584 j = 1;
585
586 k = 0;
587 do {
588 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
589 | (pData[i + 1] << 8);
590 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
591 + 3] << 8);
592 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
593 + 5] << 8);
594 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
595 + 7] << 8);
596 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
597 + 9] << 8);
598 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
599 + 11] << 8);
600 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
601 + 13] << 8);
602 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
603 | (pData[i + 15] << 8);
604 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
605 | (pData[i + 17] << 8);
606 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
607 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
608 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
609 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
610 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
611 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
612 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
613 i += 25;
614 j--;
615 k++;
616 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
617 / sizeof(struct XGI21_LVDSCapStruct))));
618 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200619 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530620 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200621}
622
623int XGIfb_GetXG21DefaultLVDSModeIdx(void)
624{
625
626 int found_mode = 0;
627 int XGIfb_mode_idx = 0;
628
629 found_mode = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530630 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
631 && (XGIbios_mode[XGIfb_mode_idx].xres
632 <= XGI21_LCDCapList[0].LVDSHDE)) {
633 if ((XGIbios_mode[XGIfb_mode_idx].xres
634 == XGI21_LCDCapList[0].LVDSHDE)
635 && (XGIbios_mode[XGIfb_mode_idx].yres
636 == XGI21_LCDCapList[0].LVDSVDE)
637 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200638 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
639 found_mode = 1;
640 break;
641 }
642 XGIfb_mode_idx++;
643 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530644 if (!found_mode)
645 XGIfb_mode_idx = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200646
Prashant P. Shahb654f872010-09-06 17:34:26 +0530647 return XGIfb_mode_idx;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200648}
649
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200650static int XGIfb_validate_mode(int myindex)
651{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530652 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200653
Prashant P. Shahb654f872010-09-06 17:34:26 +0530654 if (xgi_video_info.chip == XG21) {
655 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
656 == DISPTYPE_LCD) {
657 xres = XGI21_LCDCapList[0].LVDSHDE;
658 yres = XGI21_LCDCapList[0].LVDSVDE;
659 if (XGIbios_mode[myindex].xres > xres)
660 return -1;
661 if (XGIbios_mode[myindex].yres > yres)
662 return -1;
663 if ((XGIbios_mode[myindex].xres < xres)
664 && (XGIbios_mode[myindex].yres < yres)) {
665 if (XGIbios_mode[myindex].bpp > 8)
666 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200667 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530668
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200669 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530670 return myindex;
671
672 }
673
674 /* FIXME: for now, all is valid on XG27 */
675 if (xgi_video_info.chip == XG27)
676 return myindex;
677
678 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
679 return -1;
680
681 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
682 case DISPTYPE_LCD:
683 switch (XGIhw_ext.ulCRT2LCDType) {
684 case LCD_640x480:
685 xres = 640;
686 yres = 480;
687 break;
688 case LCD_800x600:
689 xres = 800;
690 yres = 600;
691 break;
692 case LCD_1024x600:
693 xres = 1024;
694 yres = 600;
695 break;
696 case LCD_1024x768:
697 xres = 1024;
698 yres = 768;
699 break;
700 case LCD_1152x768:
701 xres = 1152;
702 yres = 768;
703 break;
704 case LCD_1280x960:
705 xres = 1280;
706 yres = 960;
707 break;
708 case LCD_1280x768:
709 xres = 1280;
710 yres = 768;
711 break;
712 case LCD_1280x1024:
713 xres = 1280;
714 yres = 1024;
715 break;
716 case LCD_1400x1050:
717 xres = 1400;
718 yres = 1050;
719 break;
720 case LCD_1600x1200:
721 xres = 1600;
722 yres = 1200;
723 break;
724 /* case LCD_320x480: */ /* TW: FSTN */
725 /*
726 xres = 320;
727 yres = 480;
728 break;
729 */
730 default:
731 xres = 0;
732 yres = 0;
733 break;
734 }
735 if (XGIbios_mode[myindex].xres > xres)
736 return -1;
737 if (XGIbios_mode[myindex].yres > yres)
738 return -1;
739 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
740 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
741 switch (XGIbios_mode[myindex].xres) {
742 case 512:
743 if (XGIbios_mode[myindex].yres != 512)
744 return -1;
745 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
746 return -1;
747 break;
748 case 640:
749 if ((XGIbios_mode[myindex].yres != 400)
750 && (XGIbios_mode[myindex].yres
751 != 480))
752 return -1;
753 break;
754 case 800:
755 if (XGIbios_mode[myindex].yres != 600)
756 return -1;
757 break;
758 case 1024:
759 if ((XGIbios_mode[myindex].yres != 600)
760 && (XGIbios_mode[myindex].yres
761 != 768))
762 return -1;
763 if ((XGIbios_mode[myindex].yres == 600)
764 && (XGIhw_ext.ulCRT2LCDType
765 != LCD_1024x600))
766 return -1;
767 break;
768 case 1152:
769 if ((XGIbios_mode[myindex].yres) != 768)
770 return -1;
771 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
772 return -1;
773 break;
774 case 1280:
775 if ((XGIbios_mode[myindex].yres != 768)
776 && (XGIbios_mode[myindex].yres
777 != 1024))
778 return -1;
779 if ((XGIbios_mode[myindex].yres == 768)
780 && (XGIhw_ext.ulCRT2LCDType
781 != LCD_1280x768))
782 return -1;
783 break;
784 case 1400:
785 if (XGIbios_mode[myindex].yres != 1050)
786 return -1;
787 break;
788 case 1600:
789 if (XGIbios_mode[myindex].yres != 1200)
790 return -1;
791 break;
792 default:
793 return -1;
794 }
795 } else {
796 switch (XGIbios_mode[myindex].xres) {
797 case 512:
798 if (XGIbios_mode[myindex].yres != 512)
799 return -1;
800 break;
801 case 640:
802 if ((XGIbios_mode[myindex].yres != 400)
803 && (XGIbios_mode[myindex].yres
804 != 480))
805 return -1;
806 break;
807 case 800:
808 if (XGIbios_mode[myindex].yres != 600)
809 return -1;
810 break;
811 case 1024:
812 if (XGIbios_mode[myindex].yres != 768)
813 return -1;
814 break;
815 case 1280:
816 if ((XGIbios_mode[myindex].yres != 960)
817 && (XGIbios_mode[myindex].yres
818 != 1024))
819 return -1;
820 if (XGIbios_mode[myindex].yres == 960) {
821 if (XGIhw_ext.ulCRT2LCDType
822 == LCD_1400x1050)
823 return -1;
824 }
825 break;
826 case 1400:
827 if (XGIbios_mode[myindex].yres != 1050)
828 return -1;
829 break;
830 case 1600:
831 if (XGIbios_mode[myindex].yres != 1200)
832 return -1;
833 break;
834 default:
835 return -1;
836 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200837 }
838 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530839 case DISPTYPE_TV:
840 switch (XGIbios_mode[myindex].xres) {
841 case 512:
842 case 640:
843 case 800:
844 break;
845 case 720:
846 if (xgi_video_info.TV_type == TVMODE_NTSC) {
847 if (XGIbios_mode[myindex].yres != 480)
848 return -1;
849 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
850 if (XGIbios_mode[myindex].yres != 576)
851 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200852 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530853 /* TW: LVDS/CHRONTEL does not support 720 */
854 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
855 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
856 return -1;
857 }
858 break;
859 case 1024:
860 if (xgi_video_info.TV_type == TVMODE_NTSC) {
861 if (XGIbios_mode[myindex].bpp == 32)
862 return -1;
863 }
864 /* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019) */
865 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
866 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
867 if (xgi_video_info.chip < XGI_315H)
868 return -1;
869 }
870 break;
871 default:
872 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200873 }
874 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530875 case DISPTYPE_CRT2:
876 if (XGIbios_mode[myindex].xres > 1280)
877 return -1;
878 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200879 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530880 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200881
882}
883
884static void XGIfb_search_crt2type(const char *name)
885{
886 int i = 0;
887
Prashant P. Shahb654f872010-09-06 17:34:26 +0530888 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200889 return;
890
Prashant P. Shahb654f872010-09-06 17:34:26 +0530891 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200892 if (!strcmp(name, XGI_crt2type[i].name)) {
893 XGIfb_crt2type = XGI_crt2type[i].type_no;
894 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
895 break;
896 }
897 i++;
898 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530899 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200900 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
901}
902
903static void XGIfb_search_queuemode(const char *name)
904{
905 int i = 0;
906
Prashant P. Shahb654f872010-09-06 17:34:26 +0530907 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200908 return;
909
910 while (XGI_queuemode[i].type_no != -1) {
911 if (!strcmp(name, XGI_queuemode[i].name)) {
912 XGIfb_queuemode = XGI_queuemode[i].type_no;
913 break;
914 }
915 i++;
916 }
917 if (XGIfb_queuemode < 0)
918 printk(KERN_INFO "XGIfb: Invalid queuemode type: %s\n", name);
919}
920
921static u8 XGIfb_search_refresh_rate(unsigned int rate)
922{
923 u16 xres, yres;
924 int i = 0;
925
926 xres = XGIbios_mode[xgifb_mode_idx].xres;
927 yres = XGIbios_mode[xgifb_mode_idx].yres;
928
929 XGIfb_rate_idx = 0;
930 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530931 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
932 == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200933 if (XGIfb_vrate[i].refresh == rate) {
934 XGIfb_rate_idx = XGIfb_vrate[i].idx;
935 break;
936 } else if (XGIfb_vrate[i].refresh > rate) {
937 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
938 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530939 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200940 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530941 xgi_video_info.refresh_rate
942 = XGIfb_vrate[i].refresh;
943 } else if (((rate - XGIfb_vrate[i - 1].refresh)
944 <= 2) && (XGIfb_vrate[i].idx
945 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200946 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530947 rate, XGIfb_vrate[i-1].refresh);
948 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
949 xgi_video_info.refresh_rate
950 = XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200951 }
952 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530953 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200954 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
955 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530956 XGIfb_rate_idx = XGIfb_vrate[i].idx;
957 break;
958 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200959 }
960 i++;
961 }
962 if (XGIfb_rate_idx > 0) {
963 return XGIfb_rate_idx;
964 } else {
965 printk(KERN_INFO
Prashant P. Shahb654f872010-09-06 17:34:26 +0530966 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200967 return 0;
968 }
969}
970
971static void XGIfb_search_tvstd(const char *name)
972{
973 int i = 0;
974
Prashant P. Shahb654f872010-09-06 17:34:26 +0530975 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200976 return;
977
978 while (XGI_tvtype[i].type_no != -1) {
979 if (!strcmp(name, XGI_tvtype[i].name)) {
980 XGIfb_tvmode = XGI_tvtype[i].type_no;
981 break;
982 }
983 i++;
984 }
985}
986
Bill Pemberton82d6eb52010-06-17 13:10:46 -0400987static unsigned char XGIfb_bridgeisslave(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200988{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530989 unsigned char usScratchP1_00;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200990
Prashant P. Shahb654f872010-09-06 17:34:26 +0530991 if (xgi_video_info.hasVB == HASVB_NONE)
992 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200993
Prashant P. Shahb654f872010-09-06 17:34:26 +0530994 inXGIIDXREG(XGIPART1, 0x00, usScratchP1_00);
995 if ((usScratchP1_00 & 0x50) == 0x10)
996 return 1;
997 else
998 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200999}
1000
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001001static unsigned char XGIfbcheckvretracecrt1(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001002{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301003 unsigned char temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001004
Prashant P. Shahb654f872010-09-06 17:34:26 +05301005 inXGIIDXREG(XGICR, 0x17, temp);
1006 if (!(temp & 0x80))
1007 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001008
Prashant P. Shahb654f872010-09-06 17:34:26 +05301009 inXGIIDXREG(XGISR, 0x1f, temp);
1010 if (temp & 0xc0)
1011 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001012
Prashant P. Shahb654f872010-09-06 17:34:26 +05301013 if (inXGIREG(XGIINPSTAT) & 0x08)
1014 return 1;
1015 else
1016 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001017}
1018
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001019static unsigned char XGIfbcheckvretracecrt2(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001020{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301021 unsigned char temp;
1022 if (xgi_video_info.hasVB == HASVB_NONE)
1023 return 0;
1024 inXGIIDXREG(XGIPART1, 0x30, temp);
1025 if (temp & 0x02)
1026 return 0;
1027 else
1028 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001029}
1030
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001031static unsigned char XGIfb_CheckVBRetrace(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001032{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301033 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
1034 if (XGIfb_bridgeisslave())
1035 return XGIfbcheckvretracecrt1();
1036 else
1037 return XGIfbcheckvretracecrt2();
1038 }
1039 return XGIfbcheckvretracecrt1();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001040}
1041
1042/* ----------- FBDev related routines for all series ----------- */
1043
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001044static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
1045{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301046 switch (var->bits_per_pixel) {
1047 case 8:
1048 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001049 var->red.length = var->green.length = var->blue.length = 6;
1050 xgi_video_info.video_cmap_len = 256;
1051 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301052 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001053 var->red.offset = 11;
1054 var->red.length = 5;
1055 var->green.offset = 5;
1056 var->green.length = 6;
1057 var->blue.offset = 0;
1058 var->blue.length = 5;
1059 var->transp.offset = 0;
1060 var->transp.length = 0;
1061 xgi_video_info.video_cmap_len = 16;
1062 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301063 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001064 var->red.offset = 16;
1065 var->red.length = 8;
1066 var->green.offset = 8;
1067 var->green.length = 8;
1068 var->blue.offset = 0;
1069 var->blue.length = 8;
1070 var->transp.offset = 24;
1071 var->transp.length = 8;
1072 xgi_video_info.video_cmap_len = 16;
1073 break;
1074 }
1075}
1076
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001077static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301078 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001079{
1080
Prashant P. Shahb654f872010-09-06 17:34:26 +05301081 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1082 + var->hsync_len;
1083 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1084 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001085#if defined(__powerpc__)
1086 u8 sr_data, cr_data;
1087#endif
1088 unsigned int drate = 0, hrate = 0;
1089 int found_mode = 0;
1090 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301091 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001092
1093 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301094 /* 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 +02001095
Prashant P. Shahb654f872010-09-06 17:34:26 +05301096 info->var.xres_virtual = var->xres_virtual;
1097 info->var.yres_virtual = var->yres_virtual;
1098 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001099
1100 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1101 vtotal <<= 1;
1102 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1103 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301104 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1105 /* vtotal <<= 1; */
1106 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001107 }
1108
Prashant P. Shahb654f872010-09-06 17:34:26 +05301109 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001110 DPRINTK("XGIfb: Invalid 'var' information\n");
1111 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301112 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1113 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001114
Prashant P. Shahb654f872010-09-06 17:34:26 +05301115 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001116 drate = 1000000000 / var->pixclock;
1117 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301118 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1119 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001120 } else {
1121 xgi_video_info.refresh_rate = 60;
1122 }
1123
1124 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05301125 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001126
1127 old_mode = xgifb_mode_idx;
1128 xgifb_mode_idx = 0;
1129
Prashant P. Shahb654f872010-09-06 17:34:26 +05301130 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1131 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1132 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1133 && (XGIbios_mode[xgifb_mode_idx].yres
1134 == var->yres)
1135 && (XGIbios_mode[xgifb_mode_idx].bpp
1136 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001137 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1138 found_mode = 1;
1139 break;
1140 }
1141 xgifb_mode_idx++;
1142 }
1143
Prashant P. Shahb654f872010-09-06 17:34:26 +05301144 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001145 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1146 else
1147 xgifb_mode_idx = -1;
1148
Prashant P. Shahb654f872010-09-06 17:34:26 +05301149 if (xgifb_mode_idx < 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001150 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301151 var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001152 xgifb_mode_idx = old_mode;
1153 return -EINVAL;
1154 }
1155
Prashant P. Shahb654f872010-09-06 17:34:26 +05301156 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001157 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1158 xgi_video_info.refresh_rate = 60;
1159 }
1160
Prashant P. Shahb654f872010-09-06 17:34:26 +05301161 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001162
1163 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301164 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001165 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1166 return -EINVAL;
1167 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301168 info->fix.line_length = ((info->var.xres_virtual
1169 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001170
Prashant P. Shahb654f872010-09-06 17:34:26 +05301171 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001172
Prashant P. Shahb654f872010-09-06 17:34:26 +05301173 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1174 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001175
1176 XGIfb_post_setmode();
1177
Prashant P. Shahb654f872010-09-06 17:34:26 +05301178 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1179 XGIbios_mode[xgifb_mode_idx].xres,
1180 XGIbios_mode[xgifb_mode_idx].yres,
1181 XGIbios_mode[xgifb_mode_idx].bpp,
1182 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001183
1184 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1185 xgi_video_info.video_vwidth = info->var.xres_virtual;
1186 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1187 xgi_video_info.video_vheight = info->var.yres_virtual;
1188 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1189 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301190 xgi_video_info.video_linelength = info->var.xres_virtual
1191 * (xgi_video_info.video_bpp >> 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001192 xgi_video_info.accel = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301193 if (XGIfb_accel) {
1194 xgi_video_info.accel = (var->accel_flags
1195 & FB_ACCELF_TEXT) ? -1 : 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001196 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301197 switch (xgi_video_info.video_bpp) {
1198 case 8:
1199 xgi_video_info.DstColor = 0x0000;
1200 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1201 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001202#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301203 inXGIIDXREG(XGICR, 0x4D, cr_data);
1204 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001205#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301206 break;
1207 case 16:
1208 xgi_video_info.DstColor = 0x8000;
1209 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001210#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301211 inXGIIDXREG(XGICR, 0x4D, cr_data);
1212 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001213#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301214 xgi_video_info.video_cmap_len = 16;
1215 break;
1216 case 32:
1217 xgi_video_info.DstColor = 0xC000;
1218 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1219 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001220#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301221 inXGIIDXREG(XGICR, 0x4D, cr_data);
1222 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001223#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301224 break;
1225 default:
1226 xgi_video_info.video_cmap_len = 16;
1227 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
1228 xgi_video_info.accel = 0;
1229 break;
1230 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001231 }
1232 XGIfb_bpp_to_var(var); /*update ARGB info*/
1233 DEBUGPRN("End of do_set_var");
1234
1235 dumpVGAReg();
1236 return 0;
1237}
1238
1239#ifdef XGIFB_PAN
1240static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1241{
1242 unsigned int base;
1243
Prashant P. Shahb654f872010-09-06 17:34:26 +05301244 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001245
1246 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301247 /* printk("Pan: xo: %d xv %d xr %d\n",
1248 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001249 return -EINVAL;
1250 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301251 if (var->yoffset > (var->yres_virtual - var->yres)) {
1252 /* printk("Pan: yo: %d yv %d yr %d\n",
1253 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001254 return -EINVAL;
1255 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301256 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001257
Prashant P. Shahb654f872010-09-06 17:34:26 +05301258 /* calculate base bpp dep. */
1259 switch (var->bits_per_pixel) {
1260 case 16:
1261 base >>= 1;
1262 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001263 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301264 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001265 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301266 default:
1267 base >>= 2;
1268 break;
1269 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001270
1271 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1272
Prashant P. Shahb654f872010-09-06 17:34:26 +05301273 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001274 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1275 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301276 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001277 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1278
Prashant P. Shahb654f872010-09-06 17:34:26 +05301279 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001280 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301281 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1282 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1283 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001284 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301285 }
1286 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001287 return 0;
1288}
1289#endif
1290
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001291void XGI_dispinfo(struct ap_data *rec)
1292{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301293 rec->minfo.bpp = xgi_video_info.video_bpp;
1294 rec->minfo.xres = xgi_video_info.video_width;
1295 rec->minfo.yres = xgi_video_info.video_height;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001296 rec->minfo.v_xres = xgi_video_info.video_vwidth;
1297 rec->minfo.v_yres = xgi_video_info.video_vheight;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301298 rec->minfo.org_x = xgi_video_info.org_x;
1299 rec->minfo.org_y = xgi_video_info.org_y;
1300 rec->minfo.vrate = xgi_video_info.refresh_rate;
1301 rec->iobase = xgi_video_info.vga_base - 0x30;
1302 rec->mem_size = xgi_video_info.video_size;
1303 rec->disp_state = xgi_video_info.disp_state;
1304 rec->version = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
1305 rec->hasVB = xgi_video_info.hasVB;
1306 rec->TV_type = xgi_video_info.TV_type;
1307 rec->TV_plug = xgi_video_info.TV_plug;
1308 rec->chip = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001309}
1310
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001311static int XGIfb_open(struct fb_info *info, int user)
1312{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301313 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001314}
1315
1316static int XGIfb_release(struct fb_info *info, int user)
1317{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301318 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001319}
1320
1321static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1322{
1323 int rc = 16;
1324
Prashant P. Shahb654f872010-09-06 17:34:26 +05301325 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001326 case 8:
1327 rc = 256;
1328 break;
1329 case 16:
1330 rc = 16;
1331 break;
1332 case 32:
1333 rc = 16;
1334 break;
1335 }
1336 return rc;
1337}
1338
Prashant P. Shahb654f872010-09-06 17:34:26 +05301339static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1340 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001341{
1342 if (regno >= XGIfb_get_cmap_len(&info->var))
1343 return 1;
1344
1345 switch (info->var.bits_per_pixel) {
1346 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301347 outXGIREG(XGIDACA, regno);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001348 outXGIREG(XGIDACD, (red >> 10));
1349 outXGIREG(XGIDACD, (green >> 10));
1350 outXGIREG(XGIDACD, (blue >> 10));
1351 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301352 outXGIREG(XGIDAC2A, regno);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001353 outXGIREG(XGIDAC2D, (red >> 8));
1354 outXGIREG(XGIDAC2D, (green >> 8));
1355 outXGIREG(XGIDAC2D, (blue >> 8));
1356 }
1357 break;
1358 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301359 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1360 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1361 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001362 break;
1363 case 32:
1364 red >>= 8;
1365 green >>= 8;
1366 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301367 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1368 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001369 break;
1370 }
1371 return 0;
1372}
1373
1374static int XGIfb_set_par(struct fb_info *info)
1375{
1376 int err;
1377
Prashant P. Shahb654f872010-09-06 17:34:26 +05301378 /* printk("XGIfb: inside set_par\n"); */
1379 err = XGIfb_do_set_var(&info->var, 1, info);
1380 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001381 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001382 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301383 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001384 return 0;
1385}
1386
Prashant P. Shahb654f872010-09-06 17:34:26 +05301387static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001388{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301389 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1390 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001391 unsigned int vtotal = 0;
1392 unsigned int drate = 0, hrate = 0;
1393 int found_mode = 0;
1394 int refresh_rate, search_idx;
1395
1396 DEBUGPRN("Inside check_var");
1397
Prashant P. Shahb654f872010-09-06 17:34:26 +05301398 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1399 vtotal = var->upper_margin + var->yres + var->lower_margin
1400 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001401 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301402 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1403 vtotal = var->upper_margin + var->yres + var->lower_margin
1404 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001405 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301406 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1407 vtotal = var->upper_margin + (var->yres / 2)
1408 + var->lower_margin + var->vsync_len;
1409 } else
1410 vtotal = var->upper_margin + var->yres + var->lower_margin
1411 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001412
Prashant P. Shahb654f872010-09-06 17:34:26 +05301413 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001414 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301415
1416 if (var->pixclock && htotal && vtotal) {
1417 drate = 1000000000 / var->pixclock;
1418 hrate = (drate * 1000) / htotal;
1419 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1420 printk(KERN_DEBUG
1421 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1422 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1423 __func__, var->pixclock, htotal, vtotal,
1424 __func__, drate, hrate, xgi_video_info.refresh_rate);
1425 } else {
1426 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001427 }
1428
Prashant P. Shahb654f872010-09-06 17:34:26 +05301429 /*
1430 if ((var->pixclock) && (htotal)) {
1431 drate = 1E12 / var->pixclock;
1432 hrate = drate / htotal;
1433 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1434 } else {
1435 refresh_rate = 60;
1436 }
1437 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001438 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301439 if ((var->xres == 1024) && (var->yres == 600))
1440 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001441
1442 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301443 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1444 (XGIbios_mode[search_idx].xres <= var->xres)) {
1445 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1446 (XGIbios_mode[search_idx].yres == var->yres) &&
1447 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1448 if (XGIfb_validate_mode(search_idx) > 0) {
1449 found_mode = 1;
1450 break;
1451 }
1452 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001453 search_idx++;
1454 }
1455
Prashant P. Shahb654f872010-09-06 17:34:26 +05301456 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001457
1458 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1459 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301460 search_idx = 0;
1461 while (XGIbios_mode[search_idx].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001462
Prashant P. Shahb654f872010-09-06 17:34:26 +05301463 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1464 (var->yres <= XGIbios_mode[search_idx].yres) &&
1465 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1466 if (XGIfb_validate_mode(search_idx) > 0) {
1467 found_mode = 1;
1468 break;
1469 }
1470 }
1471 search_idx++;
1472 }
1473 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001474 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301475 var->yres = XGIbios_mode[search_idx].yres;
1476 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1477 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001478
1479 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301480 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001481 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301482 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001483 }
1484 }
1485
1486 /* TW: TODO: Check the refresh rate */
1487
1488 /* Adapt RGB settings */
1489 XGIfb_bpp_to_var(var);
1490
1491 /* Sanity check for offsets */
1492 if (var->xoffset < 0)
1493 var->xoffset = 0;
1494 if (var->yoffset < 0)
1495 var->yoffset = 0;
1496
Prashant P. Shahb654f872010-09-06 17:34:26 +05301497 if (!XGIfb_ypan) {
1498 if (var->xres != var->xres_virtual)
1499 var->xres_virtual = var->xres;
1500 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001501 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301502 } /* else { */
1503 /* TW: Now patch yres_virtual if we use panning */
1504 /* May I do this? */
1505 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1506 /* if (var->yres_virtual <= var->yres) { */
1507 /* TW: Paranoia check */
1508 /* var->yres_virtual = var->yres; */
1509 /* } */
1510 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001511
1512 /* Truncate offsets to maximum if too high */
1513 if (var->xoffset > var->xres_virtual - var->xres)
1514 var->xoffset = var->xres_virtual - var->xres - 1;
1515
1516 if (var->yoffset > var->yres_virtual - var->yres)
1517 var->yoffset = var->yres_virtual - var->yres - 1;
1518
1519 /* Set everything else to 0 */
1520 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301521 var->green.msb_right =
1522 var->blue.msb_right =
1523 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001524
1525 DEBUGPRN("end of check_var");
1526 return 0;
1527}
1528
1529#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301530static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1531 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001532{
1533 int err;
1534
Prashant P. Shahb654f872010-09-06 17:34:26 +05301535 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001536
1537 if (var->xoffset > (var->xres_virtual - var->xres))
1538 return -EINVAL;
1539 if (var->yoffset > (var->yres_virtual - var->yres))
1540 return -EINVAL;
1541
1542 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301543 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1544 || var->xoffset)
1545 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001546 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301547 if (var->xoffset + info->var.xres > info->var.xres_virtual
1548 || var->yoffset + info->var.yres
1549 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001550 return -EINVAL;
1551 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301552 err = XGIfb_pan_var(var);
1553 if (err < 0)
1554 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001555
1556 info->var.xoffset = var->xoffset;
1557 info->var.yoffset = var->yoffset;
1558 if (var->vmode & FB_VMODE_YWRAP)
1559 info->var.vmode |= FB_VMODE_YWRAP;
1560 else
1561 info->var.vmode &= ~FB_VMODE_YWRAP;
1562
Prashant P. Shahb654f872010-09-06 17:34:26 +05301563 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001564 return 0;
1565}
1566#endif
1567
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001568static int XGIfb_blank(int blank, struct fb_info *info)
1569{
1570 u8 reg;
1571
1572 inXGIIDXREG(XGICR, 0x17, reg);
1573
Prashant P. Shahb654f872010-09-06 17:34:26 +05301574 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001575 reg &= 0x7f;
1576 else
1577 reg |= 0x80;
1578
Prashant P. Shahb654f872010-09-06 17:34:26 +05301579 outXGIIDXREG(XGICR, 0x17, reg);
1580 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1581 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1582 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001583}
1584
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001585static int XGIfb_ioctl(struct fb_info *info, unsigned int cmd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301586 unsigned long arg)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001587{
1588 DEBUGPRN("inside ioctl");
1589 switch (cmd) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301590 case FBIO_ALLOC:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001591 if (!capable(CAP_SYS_RAWIO))
1592 return -EPERM;
1593 XGI_malloc((struct XGI_memreq *) arg);
1594 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301595 case FBIO_FREE:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001596 if (!capable(CAP_SYS_RAWIO))
1597 return -EPERM;
1598 XGI_free(*(unsigned long *) arg);
1599 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301600 case FBIOGET_HWCINFO: {
1601 unsigned long *hwc_offset = (unsigned long *) arg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001602
Prashant P. Shahb654f872010-09-06 17:34:26 +05301603 if (XGIfb_caps & HW_CURSOR_CAP)
1604 *hwc_offset
1605 = XGIfb_hwcursor_vbase
1606 - (unsigned long) xgi_video_info.video_vbase;
1607 else
1608 *hwc_offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001609
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001610 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001611 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301612 case FBIOPUT_MODEINFO: {
1613 struct mode_info *x = (struct mode_info *) arg;
1614
1615 xgi_video_info.video_bpp = x->bpp;
1616 xgi_video_info.video_width = x->xres;
1617 xgi_video_info.video_height = x->yres;
1618 xgi_video_info.video_vwidth = x->v_xres;
1619 xgi_video_info.video_vheight = x->v_yres;
1620 xgi_video_info.org_x = x->org_x;
1621 xgi_video_info.org_y = x->org_y;
1622 xgi_video_info.refresh_rate = x->vrate;
1623 xgi_video_info.video_linelength = xgi_video_info.video_vwidth
1624 * (xgi_video_info.video_bpp >> 3);
1625 switch (xgi_video_info.video_bpp) {
1626 case 8:
1627 xgi_video_info.DstColor = 0x0000;
1628 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1629 xgi_video_info.video_cmap_len = 256;
1630 break;
1631 case 16:
1632 xgi_video_info.DstColor = 0x8000;
1633 xgi_video_info.XGI310_AccelDepth = 0x00010000;
1634 xgi_video_info.video_cmap_len = 16;
1635 break;
1636 case 32:
1637 xgi_video_info.DstColor = 0xC000;
1638 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1639 xgi_video_info.video_cmap_len = 16;
1640 break;
1641 default:
1642 xgi_video_info.video_cmap_len = 16;
1643 printk(KERN_ERR "XGIfb: Unsupported accel depth %d", xgi_video_info.video_bpp);
1644 xgi_video_info.accel = 0;
1645 break;
1646 }
1647
1648 break;
1649 }
1650 case FBIOGET_DISPINFO:
1651 XGI_dispinfo((struct ap_data *) arg);
1652 break;
1653 case XGIFB_GET_INFO: /* TW: New for communication with X driver */
1654 {
1655 struct XGIfb_info *x = (struct XGIfb_info *) arg;
1656
1657 /* x->XGIfb_id = XGIFB_ID; */
1658 x->XGIfb_version = VER_MAJOR;
1659 x->XGIfb_revision = VER_MINOR;
1660 x->XGIfb_patchlevel = VER_LEVEL;
1661 x->chip_id = xgi_video_info.chip_id;
1662 x->memory = xgi_video_info.video_size / 1024;
1663 x->heapstart = xgi_video_info.heapstart / 1024;
1664 x->fbvidmode = XGIfb_mode_no;
1665 x->XGIfb_caps = XGIfb_caps;
1666 x->XGIfb_tqlen = 512; /* yet unused */
1667 x->XGIfb_pcibus = xgi_video_info.pcibus;
1668 x->XGIfb_pcislot = xgi_video_info.pcislot;
1669 x->XGIfb_pcifunc = xgi_video_info.pcifunc;
1670 x->XGIfb_lcdpdc = XGIfb_detectedpdc;
1671 x->XGIfb_lcda = XGIfb_detectedlcda;
1672 break;
1673 }
1674 case XGIFB_GET_VBRSTATUS: {
1675 unsigned long *vbrstatus = (unsigned long *) arg;
1676 if (XGIfb_CheckVBRetrace())
1677 *vbrstatus = 1;
1678 else
1679 *vbrstatus = 0;
1680 }
1681 default:
1682 return -EINVAL;
1683 } DEBUGPRN("end of ioctl");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001684 return 0;
1685
1686}
1687
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001688/* ----------- FBDev related routines for all series ---------- */
1689
1690static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301691 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001692{
1693 DEBUGPRN("inside get_fix");
1694 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1695
1696 strcpy(fix->id, myid);
1697
1698 fix->smem_start = xgi_video_info.video_base;
1699
1700 fix->smem_len = xgi_video_info.video_size;
1701
Prashant P. Shahb654f872010-09-06 17:34:26 +05301702 /* if((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size/1024))) {
1703 if (xgi_video_info.video_size > 0x1000000) {
1704 fix->smem_len = 0xD00000;
1705 } else if (xgi_video_info.video_size > 0x800000)
1706 fix->smem_len = 0x800000;
1707 else
1708 fix->smem_len = 0x400000;
1709 } else
1710 fix->smem_len = XGIfb_mem * 1024;
1711 */
1712 fix->type = video_type;
1713 fix->type_aux = 0;
1714 if (xgi_video_info.video_bpp == 8)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001715 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1716 else
1717 fix->visual = FB_VISUAL_DIRECTCOLOR;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301718 fix->xpanstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001719#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301720 if (XGIfb_ypan)
1721 fix->ypanstep = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001722#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301723 fix->ywrapstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001724 fix->line_length = xgi_video_info.video_linelength;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301725 fix->mmio_start = xgi_video_info.mmio_base;
1726 fix->mmio_len = XGIfb_mmio_size;
1727 if (xgi_video_info.chip >= XG40)
1728 fix->accel = FB_ACCEL_XGI_XABRE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001729 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05301730 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001731
1732 DEBUGPRN("end of get_fix");
1733 return 0;
1734}
1735
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001736static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301737 .owner = THIS_MODULE,
1738 .fb_open = XGIfb_open,
1739 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001740 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301741 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001742 .fb_setcolreg = XGIfb_setcolreg,
1743#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301744 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001745#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301746 .fb_blank = XGIfb_blank,
1747 .fb_fillrect = fbcon_XGI_fillrect,
1748 .fb_copyarea = fbcon_XGI_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001749 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301750 .fb_sync = fbcon_XGI_sync,
1751 .fb_ioctl = XGIfb_ioctl,
1752 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001753};
1754
1755/* ---------------- Chip generation dependent routines ---------------- */
1756
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001757/* for XGI 315/550/650/740/330 */
1758
1759static int XGIfb_get_dram_size(void)
1760{
1761
Prashant P. Shahb654f872010-09-06 17:34:26 +05301762 u8 ChannelNum, tmp;
1763 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001764
1765 /* xorg driver sets 32MB * 1 channel */
1766 if (xgi_video_info.chip == XG27)
1767 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1768
Prashant P. Shahb654f872010-09-06 17:34:26 +05301769 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1770 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1771 case XGI_DRAM_SIZE_1MB:
1772 xgi_video_info.video_size = 0x100000;
1773 break;
1774 case XGI_DRAM_SIZE_2MB:
1775 xgi_video_info.video_size = 0x200000;
1776 break;
1777 case XGI_DRAM_SIZE_4MB:
1778 xgi_video_info.video_size = 0x400000;
1779 break;
1780 case XGI_DRAM_SIZE_8MB:
1781 xgi_video_info.video_size = 0x800000;
1782 break;
1783 case XGI_DRAM_SIZE_16MB:
1784 xgi_video_info.video_size = 0x1000000;
1785 break;
1786 case XGI_DRAM_SIZE_32MB:
1787 xgi_video_info.video_size = 0x2000000;
1788 break;
1789 case XGI_DRAM_SIZE_64MB:
1790 xgi_video_info.video_size = 0x4000000;
1791 break;
1792 case XGI_DRAM_SIZE_128MB:
1793 xgi_video_info.video_size = 0x8000000;
1794 break;
1795 case XGI_DRAM_SIZE_256MB:
1796 xgi_video_info.video_size = 0x10000000;
1797 break;
1798 default:
1799 return -1;
1800 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001801
Prashant P. Shahb654f872010-09-06 17:34:26 +05301802 tmp = (reg & 0x0c) >> 2;
1803 switch (xgi_video_info.chip) {
1804 case XG20:
1805 case XG21:
1806 case XG27:
1807 ChannelNum = 1;
1808 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001809
Prashant P. Shahb654f872010-09-06 17:34:26 +05301810 case XG42:
1811 if (reg & 0x04)
1812 ChannelNum = 2;
1813 else
1814 ChannelNum = 1;
1815 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001816
Prashant P. Shahb654f872010-09-06 17:34:26 +05301817 case XG45:
1818 if (tmp == 1)
1819 ChannelNum = 2;
1820 else if (tmp == 2)
1821 ChannelNum = 3;
1822 else if (tmp == 3)
1823 ChannelNum = 4;
1824 else
1825 ChannelNum = 1;
1826 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001827
Prashant P. Shahb654f872010-09-06 17:34:26 +05301828 case XG40:
1829 default:
1830 if (tmp == 2)
1831 ChannelNum = 2;
1832 else if (tmp == 3)
1833 ChannelNum = 3;
1834 else
1835 ChannelNum = 1;
1836 break;
1837 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001838
Prashant P. Shahb654f872010-09-06 17:34:26 +05301839 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1840 /* PLiad fixed for benchmarking and fb set */
1841 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1842 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001843
Prashant P. Shahb654f872010-09-06 17:34:26 +05301844 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1845 xgi_video_info.video_size, ChannelNum);
1846 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001847
1848}
1849
1850static void XGIfb_detect_VB(void)
1851{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301852 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001853
1854 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1855
Prashant P. Shahb654f872010-09-06 17:34:26 +05301856 switch (xgi_video_info.hasVB) {
1857 case HASVB_LVDS_CHRONTEL:
1858 case HASVB_CHRONTEL:
1859 break;
1860 case HASVB_301:
1861 case HASVB_302:
1862 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1863 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001864 }
1865
1866 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1867
1868 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1869 XGIfb_crt1off = 0;
1870 else {
1871 if (cr32 & 0x5F)
1872 XGIfb_crt1off = 1;
1873 else
1874 XGIfb_crt1off = 0;
1875 }
1876
1877 if (XGIfb_crt2type != -1)
1878 /* TW: Override with option */
1879 xgi_video_info.disp_state = XGIfb_crt2type;
1880 else if (cr32 & XGI_VB_TV)
1881 xgi_video_info.disp_state = DISPTYPE_TV;
1882 else if (cr32 & XGI_VB_LCD)
1883 xgi_video_info.disp_state = DISPTYPE_LCD;
1884 else if (cr32 & XGI_VB_CRT2)
1885 xgi_video_info.disp_state = DISPTYPE_CRT2;
1886 else
1887 xgi_video_info.disp_state = 0;
1888
Prashant P. Shahb654f872010-09-06 17:34:26 +05301889 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001890 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301891 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001892 else if (cr32 & XGI_VB_HIVISION) {
1893 xgi_video_info.TV_type = TVMODE_HIVISION;
1894 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301895 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001896 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1897 else if (cr32 & XGI_VB_COMPOSITE)
1898 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1899 else if (cr32 & XGI_VB_SCART)
1900 xgi_video_info.TV_plug = TVPLUG_SCART;
1901
Prashant P. Shahb654f872010-09-06 17:34:26 +05301902 if (xgi_video_info.TV_type == 0) {
1903 /* TW: PAL/NTSC changed for 650 */
1904 if ((xgi_video_info.chip <= XGI_315PRO) || (xgi_video_info.chip
1905 >= XGI_330)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001906
Prashant P. Shahb654f872010-09-06 17:34:26 +05301907 inXGIIDXREG(XGICR, 0x38, temp);
1908 if (temp & 0x10)
1909 xgi_video_info.TV_type = TVMODE_PAL;
1910 else
1911 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001912
Prashant P. Shahb654f872010-09-06 17:34:26 +05301913 } else {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001914
Prashant P. Shahb654f872010-09-06 17:34:26 +05301915 inXGIIDXREG(XGICR, 0x79, temp);
1916 if (temp & 0x20)
1917 xgi_video_info.TV_type = TVMODE_PAL;
1918 else
1919 xgi_video_info.TV_type = TVMODE_NTSC;
1920 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001921 }
1922
1923 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301924 if (XGIfb_forcecrt1 != -1) {
1925 if (XGIfb_forcecrt1)
1926 XGIfb_crt1off = 0;
1927 else
1928 XGIfb_crt1off = 1;
1929 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001930}
1931
1932static void XGIfb_get_VB_type(void)
1933{
1934 u8 reg;
1935
1936 if (!XGIfb_has_VB()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301937 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001938 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301939 case XGI310_EXTERNAL_CHIP_LVDS:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001940 xgi_video_info.hasVB = HASVB_LVDS;
1941 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301942 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001943 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1944 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301945 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001946 break;
1947 }
1948 }
1949}
1950
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001951static int XGIfb_has_VB(void)
1952{
1953 u8 vb_chipid;
1954
1955 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1956 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301957 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001958 xgi_video_info.hasVB = HASVB_301;
1959 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301960 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001961 xgi_video_info.hasVB = HASVB_302;
1962 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301963 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001964 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001965 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001966 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001967 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001968}
1969
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001970/* ------------------ Sensing routines ------------------ */
1971
1972/* TW: Determine and detect attached devices on XGI30x */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301973int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001974{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301975 int temp, i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001976
Prashant P. Shahb654f872010-09-06 17:34:26 +05301977 outXGIIDXREG(XGIPART4, 0x11, tempbl);
1978 temp = tempbh | tempcl;
1979 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1980 for (i = 0; i < 10; i++)
1981 XGI_LongWait(&XGI_Pr);
1982 tempch &= 0x7f;
1983 inXGIIDXREG(XGIPART4, 0x03, temp);
1984 temp ^= 0x0e;
1985 temp &= tempch;
1986 return temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001987}
1988
Prashant P. Shahb654f872010-09-06 17:34:26 +05301989void XGI_Sense30x(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001990{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301991 u8 backupP4_0d;
1992 u8 testsvhs_tempbl, testsvhs_tempbh;
1993 u8 testsvhs_tempcl, testsvhs_tempch;
1994 u8 testcvbs_tempbl, testcvbs_tempbh;
1995 u8 testcvbs_tempcl, testcvbs_tempch;
1996 u8 testvga2_tempbl, testvga2_tempbh;
1997 u8 testvga2_tempcl, testvga2_tempch;
1998 int myflag, result;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001999
Prashant P. Shahb654f872010-09-06 17:34:26 +05302000 inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
2001 outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002002
Prashant P. Shahb654f872010-09-06 17:34:26 +05302003 testvga2_tempbh = 0x00;
2004 testvga2_tempbl = 0xd1;
2005 testsvhs_tempbh = 0x00;
2006 testsvhs_tempbl = 0xb9;
2007 testcvbs_tempbh = 0x00;
2008 testcvbs_tempbl = 0xb3;
2009 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
2010 != VB_CHIP_302)) {
2011 testvga2_tempbh = 0x01;
2012 testvga2_tempbl = 0x90;
2013 testsvhs_tempbh = 0x01;
2014 testsvhs_tempbl = 0x6b;
2015 testcvbs_tempbh = 0x01;
2016 testcvbs_tempbl = 0x74;
2017 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
2018 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
2019 testvga2_tempbh = 0x00;
2020 testvga2_tempbl = 0x00;
2021 testsvhs_tempbh = 0x02;
2022 testsvhs_tempbl = 0x00;
2023 testcvbs_tempbh = 0x01;
2024 testcvbs_tempbl = 0x00;
2025 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002026 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302027 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
2028 != VB_CHIP_302LV) {
2029 inXGIIDXREG(XGIPART4, 0x01, myflag);
2030 if (myflag & 0x04) {
2031 testvga2_tempbh = 0x00;
2032 testvga2_tempbl = 0xfd;
2033 testsvhs_tempbh = 0x00;
2034 testsvhs_tempbl = 0xdd;
2035 testcvbs_tempbh = 0x00;
2036 testcvbs_tempbl = 0xee;
2037 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002038 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302039 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
2040 == VB_CHIP_302LV)) {
2041 testvga2_tempbh = 0x00;
2042 testvga2_tempbl = 0x00;
2043 testvga2_tempch = 0x00;
2044 testvga2_tempcl = 0x00;
2045 testsvhs_tempch = 0x04;
2046 testsvhs_tempcl = 0x08;
2047 testcvbs_tempch = 0x08;
2048 testcvbs_tempcl = 0x08;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002049 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302050 testvga2_tempch = 0x0e;
2051 testvga2_tempcl = 0x08;
2052 testsvhs_tempch = 0x06;
2053 testsvhs_tempcl = 0x04;
2054 testcvbs_tempch = 0x08;
2055 testcvbs_tempcl = 0x04;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002056 }
2057
Prashant P. Shahb654f872010-09-06 17:34:26 +05302058 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
2059 || testvga2_tempbl) {
2060 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2061 testvga2_tempcl, testvga2_tempch);
2062 if (result) {
2063 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
2064 orXGIIDXREG(XGICR, 0x32, 0x10);
2065 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002066 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002067
Prashant P. Shahb654f872010-09-06 17:34:26 +05302068 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
2069 testsvhs_tempch);
2070 if (result) {
2071 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2072 /* TW: So we can be sure that there IS a SVHS output */
2073 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
2074 orXGIIDXREG(XGICR, 0x32, 0x02);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002075 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002076
Prashant P. Shahb654f872010-09-06 17:34:26 +05302077 if (!result) {
2078 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2079 testcvbs_tempcl, testcvbs_tempch);
2080 if (result) {
2081 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2082 /* TW: So we can be sure that there IS a CVBS output */
2083 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
2084 orXGIIDXREG(XGICR, 0x32, 0x01);
2085 }
2086 }
2087 XGIDoSense(0, 0, 0, 0);
2088
2089 outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002090}
2091
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002092/* ------------------------ Heap routines -------------------------- */
2093
2094static int XGIfb_heap_init(void)
2095{
2096 XGI_OH *poh;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302097 u8 temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002098
Prashant P. Shahb654f872010-09-06 17:34:26 +05302099 int agp_enabled = 1;
2100 u32 agp_size;
Randy Dunlap89229672010-08-10 08:46:44 -07002101 unsigned long *cmdq_baseport = NULL;
2102 unsigned long *read_port = NULL;
2103 unsigned long *write_port = NULL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302104 XGI_CMDTYPE cmd_type;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002105#ifndef AGPOFF
Prashant P. Shahb654f872010-09-06 17:34:26 +05302106 struct agp_kern_info *agp_info;
2107 struct agp_memory *agp;
2108 u32 agp_phys;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002109#endif
2110
Prashant P. Shahb654f872010-09-06 17:34:26 +05302111 /* TW: The heap start is either set manually using the "mem" parameter, or
2112 * defaults as follows:
2113 * -) If more than 16MB videoRAM available, let our heap start at 12MB.
2114 * -) If more than 8MB videoRAM available, let our heap start at 8MB.
2115 * -) If 4MB or less is available, let it start at 4MB.
2116 * This is for avoiding a clash with X driver which uses the beginning
2117 * of the videoRAM. To limit size of X framebuffer, use Option MaxXFBMem
2118 * in XF86Config-4.
2119 * The heap start can also be specified by parameter "mem" when starting the XGIfb
2120 * driver. XGIfb mem=1024 lets heap starts at 1MB, etc.
2121 */
2122 if ((!XGIfb_mem) || (XGIfb_mem > (xgi_video_info.video_size / 1024))) {
2123 if (xgi_video_info.video_size > 0x1000000)
2124 xgi_video_info.heapstart = 0xD00000;
2125 else if (xgi_video_info.video_size > 0x800000)
2126 xgi_video_info.heapstart = 0x800000;
2127 else
2128 xgi_video_info.heapstart = 0x400000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002129 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302130 xgi_video_info.heapstart = XGIfb_mem * 1024;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002131 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302132 XGIfb_heap_start = (unsigned long) (xgi_video_info.video_vbase
2133 + xgi_video_info.heapstart);
2134 printk(KERN_INFO "XGIfb: Memory heap starting at %dK\n",
2135 (int)(xgi_video_info.heapstart / 1024));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002136
Prashant P. Shahb654f872010-09-06 17:34:26 +05302137 XGIfb_heap_end = (unsigned long) xgi_video_info.video_vbase
2138 + xgi_video_info.video_size;
2139 XGIfb_heap_size = XGIfb_heap_end - XGIfb_heap_start;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002140
Prashant P. Shahb654f872010-09-06 17:34:26 +05302141 /* TW: Now initialize the 310 series' command queue mode.
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002142 * On 310/325, there are three queue modes available which
2143 * are chosen by setting bits 7:5 in SR26:
2144 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
2145 * track of the queue, the FIFO, command parsing and so
2146 * on. This is the one comparable to the 300 series.
2147 * 2. VRAM queue mode (bit 6, 0x40). In this case, one will
2148 * have to do queue management himself. Register 0x85c4 will
2149 * hold the location of the next free queue slot, 0x85c8
2150 * is the "queue read pointer" whose way of working is
2151 * unknown to me. Anyway, this mode would require a
2152 * translation of the MMIO commands to some kind of
2153 * accelerator assembly and writing these commands
2154 * to the memory location pointed to by 0x85c4.
2155 * We will not use this, as nobody knows how this
2156 * "assembly" works, and as it would require a complete
2157 * re-write of the accelerator code.
2158 * 3. AGP queue mode (bit 7, 0x80). Works as 2., but keeps the
2159 * queue in AGP memory space.
2160 *
2161 * SR26 bit 4 is called "Bypass H/W queue".
2162 * SR26 bit 1 is called "Enable Command Queue Auto Correction"
2163 * SR26 bit 0 resets the queue
2164 * Size of queue memory is encoded in bits 3:2 like this:
2165 * 00 (0x00) 512K
2166 * 01 (0x04) 1M
2167 * 10 (0x08) 2M
2168 * 11 (0x0C) 4M
2169 * The queue location is to be written to 0x85C0.
2170 *
Prashant P. Shahb654f872010-09-06 17:34:26 +05302171 */
2172 cmdq_baseport = (unsigned long *) (xgi_video_info.mmio_vbase
2173 + MMIO_QUEUE_PHYBASE);
2174 write_port = (unsigned long *) (xgi_video_info.mmio_vbase
2175 + MMIO_QUEUE_WRITEPORT);
2176 read_port = (unsigned long *) (xgi_video_info.mmio_vbase
2177 + MMIO_QUEUE_READPORT);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002178
2179 DPRINTK("AGP base: 0x%p, read: 0x%p, write: 0x%p\n", cmdq_baseport, read_port, write_port);
2180
Prashant P. Shahb654f872010-09-06 17:34:26 +05302181 agp_size = COMMAND_QUEUE_AREA_SIZE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002182
2183#ifndef AGPOFF
2184 if (XGIfb_queuemode == AGP_CMD_QUEUE) {
Joe Perches5b84cc72010-11-04 20:07:59 -07002185 agp_info = vzalloc(sizeof(*agp_info));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002186 agp_copy_info(agp_info);
2187
2188 agp_backend_acquire();
2189
Prashant P. Shahb654f872010-09-06 17:34:26 +05302190 agp = agp_allocate_memory(COMMAND_QUEUE_AREA_SIZE / PAGE_SIZE,
2191 AGP_NORMAL_MEMORY);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002192 if (agp == NULL) {
2193 DPRINTK("XGIfb: Allocating AGP buffer failed.\n");
2194 agp_enabled = 0;
2195 } else {
2196 if (agp_bind_memory(agp, agp->pg_start) != 0) {
2197 DPRINTK("XGIfb: AGP: Failed to bind memory\n");
2198 /* TODO: Free AGP memory here */
2199 agp_enabled = 0;
2200 } else {
2201 agp_enable(0);
2202 }
2203 }
2204 }
2205#else
2206 agp_enabled = 0;
2207#endif
2208
2209 /* TW: Now select the queue mode */
2210
2211 if ((agp_enabled) && (XGIfb_queuemode == AGP_CMD_QUEUE)) {
2212 cmd_type = AGP_CMD_QUEUE;
2213 printk(KERN_INFO "XGIfb: Using AGP queue mode\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302214 /* } else if (XGIfb_heap_size >= COMMAND_QUEUE_AREA_SIZE) */
2215 } else if (XGIfb_queuemode == VM_CMD_QUEUE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002216 cmd_type = VM_CMD_QUEUE;
2217 printk(KERN_INFO "XGIfb: Using VRAM queue mode\n");
2218 } else {
2219 printk(KERN_INFO "XGIfb: Using MMIO queue mode\n");
2220 cmd_type = MMIO_CMD;
2221 }
2222
2223 switch (agp_size) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302224 case 0x80000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002225 temp = XGI_CMD_QUEUE_SIZE_512k;
2226 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302227 case 0x100000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002228 temp = XGI_CMD_QUEUE_SIZE_1M;
2229 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302230 case 0x200000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002231 temp = XGI_CMD_QUEUE_SIZE_2M;
2232 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302233 case 0x400000:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002234 temp = XGI_CMD_QUEUE_SIZE_4M;
2235 break;
2236 }
2237
2238 switch (cmd_type) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302239 case AGP_CMD_QUEUE:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002240#ifndef AGPOFF
2241 DPRINTK("XGIfb: AGP buffer base = 0x%lx, offset = 0x%x, size = %dK\n",
2242 agp_info->aper_base, agp->physical, agp_size/1024);
2243
2244 agp_phys = agp_info->aper_base + agp->physical;
2245
Prashant P. Shahb654f872010-09-06 17:34:26 +05302246 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, 0);
2247 outXGIIDXREG(XGICR, IND_XGI_AGP_IO_PAD, XGI_AGP_2X);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002248
Prashant P. Shahb654f872010-09-06 17:34:26 +05302249 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002250
2251 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2252
2253 *write_port = *read_port;
2254
2255 temp |= XGI_AGP_CMDQUEUE_ENABLE;
2256 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2257
2258 *cmdq_baseport = agp_phys;
2259
2260 XGIfb_caps |= AGP_CMD_QUEUE_CAP;
2261#endif
2262 break;
2263
Prashant P. Shahb654f872010-09-06 17:34:26 +05302264 case VM_CMD_QUEUE:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002265 XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
2266 XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
2267
2268 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD);
2269
2270 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET);
2271
2272 *write_port = *read_port;
2273
2274 temp |= XGI_VRAM_CMDQUEUE_ENABLE;
2275 outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp);
2276
2277 *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE;
2278
2279 XGIfb_caps |= VM_CMD_QUEUE_CAP;
2280
2281 DPRINTK("XGIfb: VM Cmd Queue offset = 0x%lx, size is %dK\n",
2282 *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024);
2283 break;
2284
Prashant P. Shahb654f872010-09-06 17:34:26 +05302285 default: /* MMIO */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002286
Prashant P. Shahb654f872010-09-06 17:34:26 +05302287 /* printk("%s:%d - I'm here\n", __FUNCTION__, __LINE__); */
2288 /* TW: This previously only wrote XGI_MMIO_CMD_ENABLE
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002289 * to IND_XGI_CMDQUEUE_SET. I doubt that this is
2290 * enough. Reserve memory in any way.
2291 */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302292 /* FIXME XGIfb_heap_end -= COMMAND_QUEUE_AREA_SIZE; */
2293 /* FIXME XGIfb_heap_size -= COMMAND_QUEUE_AREA_SIZE; */
2294 /* FIXME */
2295 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_THRESHOLD, COMMAND_QUEUE_THRESHOLD); */
2296 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, XGI_CMD_QUEUE_RESET); */
2297 /* FIXME */
2298 /* FIXME *write_port = *read_port; */
2299 /* FIXME */
2300 /* FIXME *//* TW: Set Auto_Correction bit */
2301 /* FIXME temp |= (XGI_MMIO_CMD_ENABLE | XGI_CMD_AUTO_CORR); */
2302 /* FIXME outXGIIDXREG(XGISR, IND_XGI_CMDQUEUE_SET, temp); */
2303 /* FIXME */
2304 /* FIXME *cmdq_baseport = xgi_video_info.video_size - COMMAND_QUEUE_AREA_SIZE; */
2305 /* FIXME */
2306 /* FIXME XGIfb_caps |= MMIO_CMD_QUEUE_CAP; */
2307 /* FIXME */
2308 /* FIXME DPRINTK("XGIfb: MMIO Cmd Queue offset = 0x%lx, size is %dK\n", */
2309 /* FIXME *cmdq_baseport, COMMAND_QUEUE_AREA_SIZE/1024); */
2310 break;
2311}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002312
Prashant P. Shahb654f872010-09-06 17:34:26 +05302313 /* TW: Now reserve memory for the HWCursor. It is always located at the very
2314 top of the videoRAM, right below the TB memory area (if used). */
2315 if (XGIfb_heap_size >= XGIfb_hwcursor_size) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002316 XGIfb_heap_end -= XGIfb_hwcursor_size;
2317 XGIfb_heap_size -= XGIfb_hwcursor_size;
2318 XGIfb_hwcursor_vbase = XGIfb_heap_end;
2319
2320 XGIfb_caps |= HW_CURSOR_CAP;
2321
2322 DPRINTK("XGIfb: Hardware Cursor start at 0x%lx, size is %dK\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302323 XGIfb_heap_end, XGIfb_hwcursor_size/1024);
2324 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002325
Prashant P. Shahb654f872010-09-06 17:34:26 +05302326 XGIfb_heap.poha_chain = NULL;
2327 XGIfb_heap.poh_freelist = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002328
Prashant P. Shahb654f872010-09-06 17:34:26 +05302329 poh = XGIfb_poh_new_node();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002330
Prashant P. Shahb654f872010-09-06 17:34:26 +05302331 if (poh == NULL)
2332 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002333
Prashant P. Shahb654f872010-09-06 17:34:26 +05302334 poh->poh_next = &XGIfb_heap.oh_free;
2335 poh->poh_prev = &XGIfb_heap.oh_free;
2336 poh->size = XGIfb_heap_end - XGIfb_heap_start + 1;
2337 poh->offset = XGIfb_heap_start - (unsigned long) xgi_video_info.video_vbase;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002338
Prashant P. Shahb654f872010-09-06 17:34:26 +05302339 DPRINTK("XGIfb: Heap start:0x%p, end:0x%p, len=%dk\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002340 (char *) XGIfb_heap_start, (char *) XGIfb_heap_end,
2341 (unsigned int) poh->size / 1024);
2342
Prashant P. Shahb654f872010-09-06 17:34:26 +05302343 DPRINTK("XGIfb: First Node offset:0x%x, size:%dk\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002344 (unsigned int) poh->offset, (unsigned int) poh->size / 1024);
2345
Prashant P. Shahb654f872010-09-06 17:34:26 +05302346 XGIfb_heap.oh_free.poh_next = poh;
2347 XGIfb_heap.oh_free.poh_prev = poh;
2348 XGIfb_heap.oh_free.size = 0;
2349 XGIfb_heap.max_freesize = poh->size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002350
Prashant P. Shahb654f872010-09-06 17:34:26 +05302351 XGIfb_heap.oh_used.poh_next = &XGIfb_heap.oh_used;
2352 XGIfb_heap.oh_used.poh_prev = &XGIfb_heap.oh_used;
2353 XGIfb_heap.oh_used.size = SENTINEL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002354
Prashant P. Shahb654f872010-09-06 17:34:26 +05302355 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002356}
2357
2358static XGI_OH *XGIfb_poh_new_node(void)
2359{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302360 int i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002361 unsigned long cOhs;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302362 XGI_OHALLOC *poha;
2363 XGI_OH *poh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002364
2365 if (XGIfb_heap.poh_freelist == NULL) {
2366 poha = kmalloc(OH_ALLOC_SIZE, GFP_KERNEL);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302367 if (!poha)
2368 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002369
2370 poha->poha_next = XGIfb_heap.poha_chain;
2371 XGIfb_heap.poha_chain = poha;
2372
Prashant P. Shahb654f872010-09-06 17:34:26 +05302373 cOhs = (OH_ALLOC_SIZE - sizeof(XGI_OHALLOC)) / sizeof(XGI_OH)
2374 + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002375
2376 poh = &poha->aoh[0];
2377 for (i = cOhs - 1; i != 0; i--) {
2378 poh->poh_next = poh + 1;
2379 poh = poh + 1;
2380 }
2381
2382 poh->poh_next = NULL;
2383 XGIfb_heap.poh_freelist = &poha->aoh[0];
2384 }
2385
2386 poh = XGIfb_heap.poh_freelist;
2387 XGIfb_heap.poh_freelist = poh->poh_next;
2388
Prashant P. Shahb654f872010-09-06 17:34:26 +05302389 return poh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002390}
2391
2392static XGI_OH *XGIfb_poh_allocate(unsigned long size)
2393{
2394 XGI_OH *pohThis;
2395 XGI_OH *pohRoot;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302396 int bAllocated = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002397
2398 if (size > XGIfb_heap.max_freesize) {
2399 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302400 (unsigned int) size / 1024);
2401 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002402 }
2403
2404 pohThis = XGIfb_heap.oh_free.poh_next;
2405
2406 while (pohThis != &XGIfb_heap.oh_free) {
2407 if (size <= pohThis->size) {
2408 bAllocated = 1;
2409 break;
2410 }
2411 pohThis = pohThis->poh_next;
2412 }
2413
2414 if (!bAllocated) {
2415 DPRINTK("XGIfb: Can't allocate %dk size on offscreen\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302416 (unsigned int) size / 1024);
2417 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002418 }
2419
2420 if (size == pohThis->size) {
2421 pohRoot = pohThis;
2422 XGIfb_delete_node(pohThis);
2423 } else {
2424 pohRoot = XGIfb_poh_new_node();
2425
Prashant P. Shahb654f872010-09-06 17:34:26 +05302426 if (pohRoot == NULL)
2427 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002428
2429 pohRoot->offset = pohThis->offset;
2430 pohRoot->size = size;
2431
2432 pohThis->offset += size;
2433 pohThis->size -= size;
2434 }
2435
2436 XGIfb_heap.max_freesize -= size;
2437
2438 pohThis = &XGIfb_heap.oh_used;
2439 XGIfb_insert_node(pohThis, pohRoot);
2440
Prashant P. Shahb654f872010-09-06 17:34:26 +05302441 return pohRoot;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002442}
2443
2444static void XGIfb_delete_node(XGI_OH *poh)
2445{
2446 XGI_OH *poh_prev;
2447 XGI_OH *poh_next;
2448
2449 poh_prev = poh->poh_prev;
2450 poh_next = poh->poh_next;
2451
2452 poh_prev->poh_next = poh_next;
2453 poh_next->poh_prev = poh_prev;
2454
2455}
2456
2457static void XGIfb_insert_node(XGI_OH *pohList, XGI_OH *poh)
2458{
2459 XGI_OH *pohTemp;
2460
2461 pohTemp = pohList->poh_next;
2462
2463 pohList->poh_next = poh;
2464 pohTemp->poh_prev = poh;
2465
2466 poh->poh_prev = pohList;
2467 poh->poh_next = pohTemp;
2468}
2469
2470static XGI_OH *XGIfb_poh_free(unsigned long base)
2471{
2472 XGI_OH *pohThis;
2473 XGI_OH *poh_freed;
2474 XGI_OH *poh_prev;
2475 XGI_OH *poh_next;
2476 unsigned long ulUpper;
2477 unsigned long ulLower;
2478 int foundNode = 0;
2479
2480 poh_freed = XGIfb_heap.oh_used.poh_next;
2481
Prashant P. Shahb654f872010-09-06 17:34:26 +05302482 while (poh_freed != &XGIfb_heap.oh_used) {
2483 if (poh_freed->offset == base) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002484 foundNode = 1;
2485 break;
2486 }
2487
2488 poh_freed = poh_freed->poh_next;
2489 }
2490
Prashant P. Shahb654f872010-09-06 17:34:26 +05302491 if (!foundNode)
2492 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002493
2494 XGIfb_heap.max_freesize += poh_freed->size;
2495
2496 poh_prev = poh_next = NULL;
2497 ulUpper = poh_freed->offset + poh_freed->size;
2498 ulLower = poh_freed->offset;
2499
2500 pohThis = XGIfb_heap.oh_free.poh_next;
2501
2502 while (pohThis != &XGIfb_heap.oh_free) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302503 if (pohThis->offset == ulUpper)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002504 poh_next = pohThis;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302505 else if ((pohThis->offset + pohThis->size) == ulLower)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002506 poh_prev = pohThis;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302507
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002508 pohThis = pohThis->poh_next;
2509 }
2510
2511 XGIfb_delete_node(poh_freed);
2512
2513 if (poh_prev && poh_next) {
2514 poh_prev->size += (poh_freed->size + poh_next->size);
2515 XGIfb_delete_node(poh_next);
2516 XGIfb_free_node(poh_freed);
2517 XGIfb_free_node(poh_next);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302518 return poh_prev;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002519 }
2520
2521 if (poh_prev) {
2522 poh_prev->size += poh_freed->size;
2523 XGIfb_free_node(poh_freed);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302524 return poh_prev;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002525 }
2526
2527 if (poh_next) {
2528 poh_next->size += poh_freed->size;
2529 poh_next->offset = poh_freed->offset;
2530 XGIfb_free_node(poh_freed);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302531 return poh_next;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002532 }
2533
2534 XGIfb_insert_node(&XGIfb_heap.oh_free, poh_freed);
2535
Prashant P. Shahb654f872010-09-06 17:34:26 +05302536 return poh_freed;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002537}
2538
2539static void XGIfb_free_node(XGI_OH *poh)
2540{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302541 if (poh == NULL)
2542 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002543
2544 poh->poh_next = XGIfb_heap.poh_freelist;
2545 XGIfb_heap.poh_freelist = poh;
2546
2547}
2548
2549void XGI_malloc(struct XGI_memreq *req)
2550{
2551 XGI_OH *poh;
2552
2553 poh = XGIfb_poh_allocate(req->size);
2554
Prashant P. Shahb654f872010-09-06 17:34:26 +05302555 if (poh == NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002556 req->offset = 0;
2557 req->size = 0;
2558 DPRINTK("XGIfb: Video RAM allocation failed\n");
2559 } else {
2560 DPRINTK("XGIfb: Video RAM allocation succeeded: 0x%p\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302561 (char *) (poh->offset + (unsigned long) xgi_video_info.video_vbase));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002562
2563 req->offset = poh->offset;
2564 req->size = poh->size;
2565 }
2566
2567}
2568
2569void XGI_free(unsigned long base)
2570{
2571 XGI_OH *poh;
2572
2573 poh = XGIfb_poh_free(base);
2574
Prashant P. Shahb654f872010-09-06 17:34:26 +05302575 if (poh == NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002576 DPRINTK("XGIfb: XGIfb_poh_free() failed at base 0x%x\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302577 (unsigned int) base);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002578 }
2579}
2580
2581/* --------------------- SetMode routines ------------------------- */
2582
2583static void XGIfb_pre_setmode(void)
2584{
2585 u8 cr30 = 0, cr31 = 0;
2586
2587 inXGIIDXREG(XGICR, 0x31, cr31);
2588 cr31 &= ~0x60;
2589
2590 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302591 case DISPTYPE_CRT2:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002592 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
2593 cr31 |= XGI_DRIVER_MODE;
2594 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302595 case DISPTYPE_LCD:
2596 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002597 cr31 |= XGI_DRIVER_MODE;
2598 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302599 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002600 if (xgi_video_info.TV_type == TVMODE_HIVISION)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302601 cr30 = (XGI_VB_OUTPUT_HIVISION
2602 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002603 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302604 cr30 = (XGI_VB_OUTPUT_SVIDEO
2605 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002606 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302607 cr30 = (XGI_VB_OUTPUT_COMPOSITE
2608 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002609 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302610 cr30 = (XGI_VB_OUTPUT_SCART
2611 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002612 cr31 |= XGI_DRIVER_MODE;
2613
Prashant P. Shahb654f872010-09-06 17:34:26 +05302614 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002615 cr31 |= 0x01;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302616 else
2617 cr31 &= ~0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002618 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302619 default: /* disable CRT2 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002620 cr30 = 0x00;
2621 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
2622 }
2623
2624 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
2625 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302626 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002627
Prashant P. Shahb654f872010-09-06 17:34:26 +05302628 if (xgi_video_info.accel)
2629 XGIfb_syncaccel();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002630
2631}
2632
2633static void XGIfb_post_setmode(void)
2634{
2635 u8 reg;
Bill Pemberton82d6eb52010-06-17 13:10:46 -04002636 unsigned char doit = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302637 /*
2638 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
2639 outXGIIDXREG(XGICR, 0x13, 0x00);
2640 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
2641 *test*
2642 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002643 if (xgi_video_info.video_bpp == 8) {
2644 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302645 if ((xgi_video_info.hasVB == HASVB_LVDS)
2646 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
Bill Pembertondda08c52010-06-17 13:10:42 -04002647 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002648 }
2649 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302650 if (xgi_video_info.disp_state & DISPTYPE_LCD)
Bill Pembertondda08c52010-06-17 13:10:42 -04002651 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002652 }
2653
2654 /* TW: We can't switch off CRT1 if bridge is in slave mode */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302655 if (xgi_video_info.hasVB != HASVB_NONE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002656 inXGIIDXREG(XGIPART1, 0x00, reg);
2657
Bill Pembertondda08c52010-06-17 13:10:42 -04002658 if ((reg & 0x50) == 0x10)
2659 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002660
Prashant P. Shahb654f872010-09-06 17:34:26 +05302661 } else {
Bill Pembertondda08c52010-06-17 13:10:42 -04002662 XGIfb_crt1off = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302663 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002664
2665 inXGIIDXREG(XGICR, 0x17, reg);
Bill Pembertondda08c52010-06-17 13:10:42 -04002666 if ((XGIfb_crt1off) && (doit))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002667 reg &= ~0x80;
2668 else
2669 reg |= 0x80;
2670 outXGIIDXREG(XGICR, 0x17, reg);
2671
Prashant P. Shahb654f872010-09-06 17:34:26 +05302672 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002673
Prashant P. Shahb654f872010-09-06 17:34:26 +05302674 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
2675 == HASVB_301)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002676
Prashant P. Shahb654f872010-09-06 17:34:26 +05302677 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002678
Prashant P. Shahb654f872010-09-06 17:34:26 +05302679 if (reg < 0xB0) { /* Set filter for XGI301 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002680
Prashant P. Shahb654f872010-09-06 17:34:26 +05302681 switch (xgi_video_info.video_width) {
2682 case 320:
2683 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
2684 break;
2685 case 640:
2686 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
2687 break;
2688 case 720:
2689 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
2690 break;
2691 case 800:
2692 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
2693 break;
2694 default:
2695 filter = -1;
2696 break;
2697 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002698
Prashant P. Shahb654f872010-09-06 17:34:26 +05302699 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002700
Prashant P. Shahb654f872010-09-06 17:34:26 +05302701 if (xgi_video_info.TV_type == TVMODE_NTSC) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002702
Prashant P. Shahb654f872010-09-06 17:34:26 +05302703 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002704
Prashant P. Shahb654f872010-09-06 17:34:26 +05302705 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002706
Prashant P. Shahb654f872010-09-06 17:34:26 +05302707 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002708
Prashant P. Shahb654f872010-09-06 17:34:26 +05302709 } else if (xgi_video_info.TV_plug
2710 == TVPLUG_COMPOSITE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002711
Prashant P. Shahb654f872010-09-06 17:34:26 +05302712 orXGIIDXREG(XGIPART2, 0x30, 0x20);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002713
Prashant P. Shahb654f872010-09-06 17:34:26 +05302714 switch (xgi_video_info.video_width) {
2715 case 640:
2716 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2717 outXGIIDXREG(XGIPART2, 0x36, 0x04);
2718 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2719 outXGIIDXREG(XGIPART2, 0x38, 0x18);
2720 break;
2721 case 720:
2722 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
2723 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
2724 outXGIIDXREG(XGIPART2, 0x37, 0x22);
2725 outXGIIDXREG(XGIPART2, 0x38, 0x08);
2726 break;
2727 case 800:
2728 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
2729 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2730 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2731 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2732 break;
2733 }
2734 }
2735
2736 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2737
2738 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2739
2740 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2741
2742 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2743
2744 } else if (xgi_video_info.TV_plug
2745 == TVPLUG_COMPOSITE) {
2746
2747 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2748
2749 switch (xgi_video_info.video_width) {
2750 case 640:
2751 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2752 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2753 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2754 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2755 break;
2756 case 720:
2757 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2758 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2759 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2760 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2761 break;
2762 case 800:
2763 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2764 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2765 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2766 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2767 break;
2768 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002769 }
2770 }
2771
Prashant P. Shahb654f872010-09-06 17:34:26 +05302772 if ((filter >= 0) && (filter <= 7)) {
2773 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2774 XGI_TV_filter[filter_tb].filter[filter][0],
2775 XGI_TV_filter[filter_tb].filter[filter][1],
2776 XGI_TV_filter[filter_tb].filter[filter][2],
2777 XGI_TV_filter[filter_tb].filter[filter][3]
2778 );
2779 outXGIIDXREG(
2780 XGIPART2,
2781 0x35,
2782 (XGI_TV_filter[filter_tb].filter[filter][0]));
2783 outXGIIDXREG(
2784 XGIPART2,
2785 0x36,
2786 (XGI_TV_filter[filter_tb].filter[filter][1]));
2787 outXGIIDXREG(
2788 XGIPART2,
2789 0x37,
2790 (XGI_TV_filter[filter_tb].filter[filter][2]));
2791 outXGIIDXREG(
2792 XGIPART2,
2793 0x38,
2794 (XGI_TV_filter[filter_tb].filter[filter][3]));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002795 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002796
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002797 }
2798
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002799 }
2800
2801}
2802
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002803XGIINITSTATIC int __init XGIfb_setup(char *options)
2804{
2805 char *this_opt;
2806
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002807 xgi_video_info.refresh_rate = 0;
2808
Prashant P. Shahb654f872010-09-06 17:34:26 +05302809 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002810
2811 if (!options || !*options)
2812 return 0;
2813
Prashant P. Shahb654f872010-09-06 17:34:26 +05302814 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002815
Prashant P. Shahb654f872010-09-06 17:34:26 +05302816 if (!*this_opt)
2817 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002818
2819 if (!strncmp(this_opt, "mode:", 5)) {
2820 XGIfb_search_mode(this_opt + 5);
2821 } else if (!strncmp(this_opt, "vesa:", 5)) {
2822 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2823 } else if (!strncmp(this_opt, "mode:", 5)) {
2824 XGIfb_search_mode(this_opt + 5);
2825 } else if (!strncmp(this_opt, "vesa:", 5)) {
2826 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2827 } else if (!strncmp(this_opt, "vrate:", 6)) {
2828 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2829 } else if (!strncmp(this_opt, "rate:", 5)) {
2830 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2831 } else if (!strncmp(this_opt, "off", 3)) {
2832 XGIfb_off = 1;
2833 } else if (!strncmp(this_opt, "crt1off", 7)) {
2834 XGIfb_crt1off = 1;
2835 } else if (!strncmp(this_opt, "filter:", 7)) {
2836 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2837 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2838 XGIfb_search_crt2type(this_opt + 14);
2839 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2840 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302841 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002842 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302843 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2844 XGIfb_search_tvstd(this_opt + 7);
2845 } else if (!strncmp(this_opt, "mem:", 4)) {
2846 XGIfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
2847 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002848 enable_dstn = 1;
2849 /* TW: DSTN overrules forcecrt2type */
2850 XGIfb_crt2type = DISPTYPE_LCD;
2851 } else if (!strncmp(this_opt, "queuemode:", 10)) {
2852 XGIfb_search_queuemode(this_opt + 10);
2853 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302854 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2855 if (XGIfb_pdc & ~0x3c) {
2856 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2857 XGIfb_pdc = 0;
2858 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002859 } else if (!strncmp(this_opt, "noaccel", 7)) {
2860 XGIfb_accel = 0;
2861 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302862 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002863 } else if (!strncmp(this_opt, "userom:", 7)) {
2864 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302865 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2866 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002867 } else {
2868 XGIfb_search_mode(this_opt);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302869 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002870 }
2871
2872 /* TW: Acceleration only with MMIO mode */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302873 if ((XGIfb_queuemode != -1) && (XGIfb_queuemode != MMIO_CMD)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002874 XGIfb_ypan = 0;
2875 XGIfb_accel = 0;
2876 }
2877 /* TW: Panning only with acceleration */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302878 if (XGIfb_accel == 0)
2879 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002880
2881 }
2882 printk("\nxgifb: outa xgifb_setup 3450");
2883 return 0;
2884}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002885
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002886static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002887{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002888 void __iomem *rom_address;
2889 unsigned char *rom_copy;
2890 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002891
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002892 rom_address = pci_map_rom(dev, &rom_size);
2893 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002894 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002895
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002896 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2897 if (rom_copy == NULL)
2898 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002899
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002900 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2901 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002902
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002903done:
2904 pci_unmap_rom(dev, rom_address);
2905 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002906}
2907
Randy Dunlap89229672010-08-10 08:46:44 -07002908static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302909 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002910{
2911 u16 reg16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302912 u8 reg, reg1;
2913 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002914 int ret;
2915
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002916 if (XGIfb_off)
2917 return -ENXIO;
2918
2919 XGIfb_registered = 0;
2920
Bill Pembertone4147ab2010-06-17 13:10:50 -04002921 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302922 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2923 if (!fb_info)
2924 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002925
Prashant P. Shahb654f872010-09-06 17:34:26 +05302926 xgi_video_info.chip_id = pdev->device;
2927 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2928 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
2929 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2930 XGIvga_enabled = reg16 & 0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002931
Prashant P. Shahb654f872010-09-06 17:34:26 +05302932 xgi_video_info.pcibus = pdev->bus->number;
2933 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2934 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2935 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2936 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002937
Prashant P. Shahb654f872010-09-06 17:34:26 +05302938 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2939 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
2940 XGIfb_mmio_size = pci_resource_len(pdev, 1);
2941 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2942 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2943 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2944 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2945 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002946
Aaro Koskinenbb292232011-02-17 23:29:11 +02002947 if (pci_enable_device(pdev)) {
2948 ret = -EIO;
2949 goto error;
2950 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002951
Prashant P. Shahb654f872010-09-06 17:34:26 +05302952 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002953
Prashant P. Shahb654f872010-09-06 17:34:26 +05302954 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2955 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002956
Prashant P. Shahb654f872010-09-06 17:34:26 +05302957 if (reg1 != 0xa1) { /*I/O error */
2958 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002959 ret = -EIO;
2960 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302961 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002962
2963 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302964 case PCI_DEVICE_ID_XG_20:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002965 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2966 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2967 if (CR48&GPIOG_READ)
2968 xgi_video_info.chip = XG21;
2969 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302970 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002971 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2972 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2973 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302974 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002975 xgi_video_info.chip = XG40;
2976 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2977 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2978 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302979 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002980 xgi_video_info.chip = XG41;
2981 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2982 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2983 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302984 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002985 xgi_video_info.chip = XG42;
2986 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2987 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2988 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302989 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002990 xgi_video_info.chip = XG27;
2991 XGIfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
2992 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2993 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302994 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002995 ret = -ENODEV;
2996 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002997 }
2998
Prashant P. Shahb654f872010-09-06 17:34:26 +05302999 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
3000 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003001
Prashant P. Shahb654f872010-09-06 17:34:26 +05303002 switch (xgi_video_info.chip) {
3003 case XG40:
3004 case XG41:
3005 case XG42:
3006 case XG45:
3007 case XG20:
3008 case XG21:
3009 case XG27:
3010 XGIhw_ext.bIntegratedMMEnabled = 1;
3011 break;
3012 default:
3013 break;
3014 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003015
Prashant P. Shahb654f872010-09-06 17:34:26 +05303016 XGIhw_ext.pDevice = NULL;
3017 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02003018 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303019 if (XGIhw_ext.pjVirtualRomBase)
3020 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003021 else
3022 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05303023 } else {
3024 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003025 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05303026 }
3027 XGIhw_ext.pjCustomizedROMImage = NULL;
3028 XGIhw_ext.bSkipDramSizing = 0;
3029 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
3030 /* XGIhw_ext.pQueryNorthBridgeSpace = &XGIfb_query_north_bridge_space; */
3031 strcpy(XGIhw_ext.szVBIOSVer, "0.84");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003032
Prashant P. Shahb654f872010-09-06 17:34:26 +05303033 XGIhw_ext.pSR = vmalloc(sizeof(struct XGI_DSReg) * SR_BUFFER_SIZE);
3034 if (XGIhw_ext.pSR == NULL) {
3035 printk(KERN_ERR "XGIfb: Fatal error: Allocating SRReg space failed.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003036 ret = -ENODEV;
3037 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303038 }
3039 XGIhw_ext.pSR[0].jIdx = XGIhw_ext.pSR[0].jVal = 0xFF;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003040
Prashant P. Shahb654f872010-09-06 17:34:26 +05303041 XGIhw_ext.pCR = vmalloc(sizeof(struct XGI_DSReg) * CR_BUFFER_SIZE);
3042 if (XGIhw_ext.pCR == NULL) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303043 printk(KERN_ERR "XGIfb: Fatal error: Allocating CRReg space failed.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003044 ret = -ENODEV;
3045 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303046 }
3047 XGIhw_ext.pCR[0].jIdx = XGIhw_ext.pCR[0].jVal = 0xFF;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003048
Prashant P. Shahb654f872010-09-06 17:34:26 +05303049 if (!XGIvga_enabled) {
3050 /* Mapping Max FB Size for 315 Init */
3051 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3052 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003053#ifdef LINUXBIOS
Prashant P. Shahb654f872010-09-06 17:34:26 +05303054 printk("XGIfb: XGIInit() ...");
3055 /* XGIInitNewt for LINUXBIOS only */
3056 if (XGIInitNew(&XGIhw_ext))
3057 printk("OK\n");
3058 else
3059 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003060#endif
3061
Prashant P. Shahb654f872010-09-06 17:34:26 +05303062 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003063
Prashant P. Shahb654f872010-09-06 17:34:26 +05303064 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003065 }
3066#ifdef LINUXBIOS
Prashant P. Shahb654f872010-09-06 17:34:26 +05303067 else {
3068 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
3069 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3070
3071 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
3072
3073 /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
3074 /* Set SR13 ,14 temporarily for UDtech */
3075 outXGIIDXREG(XGISR, 0x13, 0x45);
3076 outXGIIDXREG(XGISR, 0x14, 0x51);
3077
3078 }
3079 }
3080#endif
3081 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303082 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003083 ret = -ENODEV;
3084 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303085 }
3086
3087 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
3088 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
3089 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
3090 /* Enable 2D accelerator engine */
3091 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
3092 }
3093
3094 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
3095
3096 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
3097 printk("unable request memory size %x", xgi_video_info.video_size);
3098 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
3099 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003100 ret = -ENODEV;
3101 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303102 }
3103
3104 if (!request_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size, "XGIfb MMIO")) {
3105 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02003106 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003107 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303108 }
3109
3110 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
3111 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
3112 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base, XGIfb_mmio_size);
3113
3114 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
3115 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
3116
3117 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
3118 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase, XGIfb_mmio_size / 1024);
3119 printk("XGIfb: XGIInitNew() ...");
3120 if (XGIInitNew(&XGIhw_ext))
3121 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003122 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003123 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003124
Prashant P. Shahb654f872010-09-06 17:34:26 +05303125 if (XGIfb_heap_init())
3126 printk(KERN_WARNING "XGIfb: Failed to initialize offscreen memory heap\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003127
Prashant P. Shahb654f872010-09-06 17:34:26 +05303128 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003129
Prashant P. Shahb654f872010-09-06 17:34:26 +05303130 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003131 xgi_video_info.hasVB = HASVB_NONE;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303132 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
3133 xgi_video_info.hasVB = HASVB_NONE;
3134 } else if (xgi_video_info.chip == XG21) {
3135 inXGIIDXREG(XGICR, 0x38, CR38);
3136 if ((CR38&0xE0) == 0xC0) {
3137 xgi_video_info.disp_state = DISPTYPE_LCD;
3138 if (!XGIfb_GetXG21LVDSData()) {
3139 int m;
3140 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
3141 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
3142 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
3143 XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
3144 }
3145 }
3146 }
3147 } else if ((CR38&0xE0) == 0x60) {
3148 xgi_video_info.hasVB = HASVB_CHRONTEL;
3149 } else {
3150 xgi_video_info.hasVB = HASVB_NONE;
3151 }
3152 } else {
3153 XGIfb_get_VB_type();
3154 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003155
Prashant P. Shahb654f872010-09-06 17:34:26 +05303156 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003157
Prashant P. Shahb654f872010-09-06 17:34:26 +05303158 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003159
3160 switch (xgi_video_info.hasVB) {
3161 case HASVB_301:
Prashant P. Shahb654f872010-09-06 17:34:26 +05303162 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003163 if (reg >= 0xE0) {
3164 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303165 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3166 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003167 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303168 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
3169 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003170 /* else if (reg >= 0xB0) {
3171 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303172 inXGIIDXREG(XGIPART4, 0x23, reg1);
3173 printk("XGIfb: XGI301B bridge detected\n");
3174 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003175 else {
3176 XGIhw_ext.ujVBChipID = VB_CHIP_301;
3177 printk("XGIfb: XGI301 bridge detected\n");
3178 }
3179 break;
3180 case HASVB_302:
Prashant P. Shahb654f872010-09-06 17:34:26 +05303181 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003182 if (reg >= 0xE0) {
3183 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303184 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3185 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003186 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303187 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
3188 } else if (reg >= 0xB0) {
3189 inXGIIDXREG(XGIPART4, 0x23, reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003190
Prashant P. Shahb654f872010-09-06 17:34:26 +05303191 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003192
3193 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303194 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003195 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
3196 }
3197 break;
3198 case HASVB_LVDS:
3199 XGIhw_ext.ulExternalChip = 0x1;
3200 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
3201 break;
3202 case HASVB_TRUMPION:
3203 XGIhw_ext.ulExternalChip = 0x2;
3204 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
3205 break;
3206 case HASVB_CHRONTEL:
3207 XGIhw_ext.ulExternalChip = 0x4;
3208 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
3209 break;
3210 case HASVB_LVDS_CHRONTEL:
3211 XGIhw_ext.ulExternalChip = 0x5;
3212 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
3213 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303214 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003215 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
3216 break;
3217 }
3218
Prashant P. Shahb654f872010-09-06 17:34:26 +05303219 if (xgi_video_info.hasVB != HASVB_NONE)
3220 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003221
3222 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
3223 if (XGIfb_crt1off)
3224 xgi_video_info.disp_state |= DISPMODE_SINGLE;
3225 else
3226 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
3227 } else {
3228 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
3229 }
3230
3231 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303232 if (!enable_dstn) {
3233 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
3234 reg &= 0x0f;
3235 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003236
Prashant P. Shahb654f872010-09-06 17:34:26 +05303237 } else {
3238 /* TW: FSTN/DSTN */
3239 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
3240 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003241 }
3242
3243 XGIfb_detectedpdc = 0;
3244
Prashant P. Shahb654f872010-09-06 17:34:26 +05303245 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003246#ifndef LINUXBIOS
3247
Prashant P. Shahb654f872010-09-06 17:34:26 +05303248 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003249
Prashant P. Shahb654f872010-09-06 17:34:26 +05303250 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
3251 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
3252 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
3253 int tmp;
3254 inXGIIDXREG(XGICR, 0x34, tmp);
3255 if (tmp <= 0x13) {
3256 /* Currently on LCDA? (Some BIOSes leave CR38) */
3257 inXGIIDXREG(XGICR, 0x38, tmp);
3258 if ((tmp & 0x03) == 0x03) {
3259 /* XGI_Pr.XGI_UseLCDA = 1; */
3260 } else {
3261 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
3262 inXGIIDXREG(XGICR, 0x35, tmp);
3263 if (tmp & 0x01) {
3264 /* XGI_Pr.XGI_UseLCDA = 1; */
3265 } else {
3266 inXGIIDXREG(XGICR, 0x30, tmp);
3267 if (tmp & 0x20) {
3268 inXGIIDXREG(XGIPART1, 0x13, tmp);
3269 if (tmp & 0x04) {
3270 /* XGI_Pr.XGI_UseLCDA = 1; */
3271 }
3272 }
3273 }
3274 }
3275 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003276
Prashant P. Shahb654f872010-09-06 17:34:26 +05303277 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003278
3279#endif
3280
3281 if (xgifb_mode_idx >= 0)
3282 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
3283
3284 if (xgifb_mode_idx < 0) {
3285 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303286 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003287 xgifb_mode_idx = DEFAULT_LCDMODE;
3288 if (xgi_video_info.chip == XG21)
Prashant P. Shahb654f872010-09-06 17:34:26 +05303289 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003290 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303291 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003292 xgifb_mode_idx = DEFAULT_TVMODE;
3293 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303294 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003295 xgifb_mode_idx = DEFAULT_MODE;
3296 break;
3297 }
3298 }
3299
3300 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
3301
Prashant P. Shahb654f872010-09-06 17:34:26 +05303302 if (xgi_video_info.refresh_rate == 0)
3303 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
3304 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
3305 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
3306 xgi_video_info.refresh_rate = 60;
3307 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003308
3309 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
3310 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
3311 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
3312 xgi_video_info.org_x = xgi_video_info.org_y = 0;
3313 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303314 switch (xgi_video_info.video_bpp) {
3315 case 8:
3316 xgi_video_info.DstColor = 0x0000;
3317 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003318 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303319 break;
3320 case 16:
3321 xgi_video_info.DstColor = 0x8000;
3322 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003323 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303324 break;
3325 case 32:
3326 xgi_video_info.DstColor = 0xC000;
3327 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003328 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303329 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003330 default:
3331 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303332 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003333 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303334 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003335
3336 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05303337 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
3338 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003339
3340 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
3341 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
3342 default_var.bits_per_pixel = xgi_video_info.video_bpp;
3343
3344 XGIfb_bpp_to_var(&default_var);
3345
3346 default_var.pixclock = (u32) (1000000000 /
3347 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
3348 XGIfb_mode_no, XGIfb_rate_idx));
3349
Prashant P. Shahb654f872010-09-06 17:34:26 +05303350 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
3351 XGIfb_mode_no, XGIfb_rate_idx,
3352 &default_var.left_margin, &default_var.right_margin,
3353 &default_var.upper_margin, &default_var.lower_margin,
3354 &default_var.hsync_len, &default_var.vsync_len,
3355 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003356
Prashant P. Shahb654f872010-09-06 17:34:26 +05303357 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
3358 default_var.yres <<= 1;
3359 default_var.yres_virtual <<= 1;
3360 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
3361 default_var.pixclock >>= 1;
3362 default_var.yres >>= 1;
3363 default_var.yres_virtual >>= 1;
3364 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003365
Prashant P. Shahb654f872010-09-06 17:34:26 +05303366 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003367
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003368 xgi_video_info.accel = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303369 if (XGIfb_accel) {
3370 xgi_video_info.accel = -1;
3371 default_var.accel_flags |= FB_ACCELF_TEXT;
3372 XGIfb_initaccel();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003373 }
3374
3375 fb_info->flags = FBINFO_FLAG_DEFAULT;
3376 fb_info->var = default_var;
3377 fb_info->fix = XGIfb_fix;
3378 fb_info->par = &xgi_video_info;
3379 fb_info->screen_base = xgi_video_info.video_vbase;
3380 fb_info->fbops = &XGIfb_ops;
3381 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
3382 fb_info->pseudo_palette = pseudo_palette;
3383
3384 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
3385
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003386#ifdef CONFIG_MTRR
3387 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
3388 (unsigned int) xgi_video_info.video_size,
3389 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303390 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003391 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003392#endif
3393
Aaro Koskinenbb292232011-02-17 23:29:11 +02003394 if (register_framebuffer(fb_info) < 0) {
3395 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003396 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02003397 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003398
3399 XGIfb_registered = 1;
3400
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003401 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05303402 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003403
3404 }
3405
3406 dumpVGAReg();
3407
3408 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02003409
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003410error_1:
3411 iounmap(xgi_video_info.mmio_vbase);
3412 iounmap(xgi_video_info.video_vbase);
3413 release_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size);
3414error_0:
3415 release_mem_region(xgi_video_info.video_base,
3416 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02003417error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02003418 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinen6af81722011-02-17 23:29:12 +02003419 vfree(XGIhw_ext.pSR);
3420 vfree(XGIhw_ext.pCR);
Aaro Koskinenbb292232011-02-17 23:29:11 +02003421 framebuffer_release(fb_info);
3422 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003423}
3424
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003425/*****************************************************/
3426/* PCI DEVICE HANDLING */
3427/*****************************************************/
3428
3429static void __devexit xgifb_remove(struct pci_dev *pdev)
3430{
3431 /* Unregister the framebuffer */
Prashant P. Shahb654f872010-09-06 17:34:26 +05303432 /* if (xgi_video_info.registered) { */
3433 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02003434 iounmap(xgi_video_info.mmio_vbase);
3435 iounmap(xgi_video_info.video_vbase);
3436 release_mem_region(xgi_video_info.mmio_base, XGIfb_mmio_size);
3437 release_mem_region(xgi_video_info.video_base,
3438 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02003439 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05303440 framebuffer_release(fb_info);
3441 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003442
3443 pci_set_drvdata(pdev, NULL);
3444
3445};
3446
3447static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05303448 .name = "xgifb",
3449 .id_table = xgifb_pci_table,
3450 .probe = xgifb_probe,
3451 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003452};
3453
3454XGIINITSTATIC int __init xgifb_init(void)
3455{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003456 char *option = NULL;
3457
3458 if (fb_get_options("xgifb", &option))
3459 return -ENODEV;
3460 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04003461
Prashant P. Shahb654f872010-09-06 17:34:26 +05303462 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003463}
3464
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003465#ifndef MODULE
3466module_init(xgifb_init);
3467#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003468
3469/*****************************************************/
3470/* MODULE */
3471/*****************************************************/
3472
3473#ifdef MODULE
3474
Prashant P. Shahb654f872010-09-06 17:34:26 +05303475static char *mode = NULL;
3476static int vesa = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003477static unsigned int rate = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003478static unsigned int mem = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05303479static char *forcecrt2type = NULL;
3480static int forcecrt1 = -1;
3481static int pdc = -1;
3482static int pdc1 = -1;
3483static int noaccel = -1;
3484static int noypan = -1;
3485static int nomax = -1;
3486static int userom = -1;
3487static int useoem = -1;
3488static char *tvstandard = NULL;
3489static int nocrt2rate = 0;
3490static int scalelcd = -1;
3491static char *specialtiming = NULL;
3492static int lvdshl = -1;
3493static int tvxposoffset = 0, tvyposoffset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003494#if !defined(__i386__) && !defined(__x86_64__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05303495static int resetcard = 0;
3496static int videoram = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003497#endif
3498
3499MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
3500MODULE_LICENSE("GPL");
3501MODULE_AUTHOR("XGITECH , Others");
3502
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003503module_param(mem, int, 0);
3504module_param(noaccel, int, 0);
3505module_param(noypan, int, 0);
3506module_param(nomax, int, 0);
3507module_param(userom, int, 0);
3508module_param(useoem, int, 0);
3509module_param(mode, charp, 0);
3510module_param(vesa, int, 0);
3511module_param(rate, int, 0);
3512module_param(forcecrt1, int, 0);
3513module_param(forcecrt2type, charp, 0);
3514module_param(scalelcd, int, 0);
3515module_param(pdc, int, 0);
3516module_param(pdc1, int, 0);
3517module_param(specialtiming, charp, 0);
3518module_param(lvdshl, int, 0);
3519module_param(tvstandard, charp, 0);
3520module_param(tvxposoffset, int, 0);
3521module_param(tvyposoffset, int, 0);
3522module_param(filter, int, 0);
3523module_param(nocrt2rate, int, 0);
3524#if !defined(__i386__) && !defined(__x86_64__)
3525module_param(resetcard, int, 0);
3526module_param(videoram, int, 0);
3527#endif
3528
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003529MODULE_PARM_DESC(mem,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303530 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
3531 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
3532 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
3533 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
3534 "otherwise at 12288KB. On 315 and Xabre series, the heap size is 32KB by default.\n"
3535 "The value is to be specified without 'KB' and must match the MaxXFBMem setting\n"
3536 "for XFree86 4.x/X.org 6.7 and later.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003537
3538MODULE_PARM_DESC(noaccel,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303539 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
3540 "(default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003541
3542MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303543 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
3544 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003545
3546MODULE_PARM_DESC(nomax,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303547 "\nIf y-panning is enabled, xgifb will by default use the entire available video\n"
3548 "memory for the virtual screen in order to optimize scrolling performance. If\n"
3549 "this is set to anything other than 0, xgifb will not do this and thereby\n"
3550 "enable the user to positively specify a virtual Y size of the screen using\n"
3551 "fbset. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003552
3553MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303554 "\nSelects the desired default display mode in the format XxYxDepth,\n"
3555 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
3556 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
3557 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003558
3559MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303560 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
3561 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003562
3563MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303564 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
3565 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
3566 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003567
3568MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303569 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
3570 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
3571 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003572
3573MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303574 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
3575 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
3576 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
3577 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
3578 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
3579 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
3580 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
3581 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003582
3583MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303584 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
3585 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
3586 "show black bars around the image, TMDS panels will probably do the scaling\n"
3587 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003588
3589MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303590 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
3591 "should detect this correctly in most cases; however, sometimes this is not\n"
3592 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
3593 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
3594 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
3595 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003596
3597MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303598 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
3599 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
3600 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
3601 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003602
3603MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303604 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003605
3606MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303607 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003608
3609MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303610 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
3611 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003612
3613MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303614 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
3615 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003616
3617MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303618 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
3619 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003620
3621MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303622 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
3623 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003624
3625MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05303626 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
3627 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003628
Randy Dunlap89229672010-08-10 08:46:44 -07003629static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003630{
Prashant P. Shahb654f872010-09-06 17:34:26 +05303631 printk("\nXGIfb_init_module");
3632 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003633 XGIfb_search_mode(mode);
3634 else if (vesa != -1)
3635 XGIfb_search_vesamode(vesa);
3636
Prashant P. Shahb654f872010-09-06 17:34:26 +05303637 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003638}
3639
3640static void __exit xgifb_remove_module(void)
3641{
3642 pci_unregister_driver(&xgifb_driver);
3643 printk(KERN_DEBUG "xgifb: Module unloaded\n");
3644}
3645
3646module_init(xgifb_init_module);
3647module_exit(xgifb_remove_module);
3648
Prashant P. Shahb654f872010-09-06 17:34:26 +05303649#endif /* /MODULE */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02003650
3651EXPORT_SYMBOL(XGI_malloc);
3652EXPORT_SYMBOL(XGI_free);
3653