blob: b2cb7a3889a21ea1b0b0cb9cdf1bee7084f2a36c [file] [log] [blame]
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001/*
2 * XG20, XG21, XG40, XG42 frame buffer device
3 * for Linux kernels 2.5.x, 2.6.x
4 * Base on TW's sis fbdev code.
5 */
6
Prashant P. Shahb654f872010-09-06 17:34:26 +05307/* #include <linux/config.h> */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02008#include <linux/version.h>
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/tty.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/fb.h>
20#include <linux/console.h>
21#include <linux/selection.h>
22#include <linux/ioport.h>
23#include <linux/init.h>
24#include <linux/pci.h>
25#include <linux/vmalloc.h>
26#include <linux/vt_kern.h>
27#include <linux/capability.h>
28#include <linux/fs.h>
29#include <linux/types.h>
30#include <linux/proc_fs.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020031
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020032#ifndef XGIFB_PAN
33#define XGIFB_PAN
34#endif
35
36#include <asm/io.h>
37#ifdef CONFIG_MTRR
38#include <asm/mtrr.h>
39#endif
40
41#include "XGIfb.h"
42#include "vgatypes.h"
43#include "XGI_main.h"
44#include "vb_util.h"
45
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020046#define Index_CR_GPIO_Reg1 0x48
47#define Index_CR_GPIO_Reg2 0x49
48#define Index_CR_GPIO_Reg3 0x4a
49
50#define GPIOG_EN (1<<6)
51#define GPIOG_WRITE (1<<6)
52#define GPIOG_READ (1<<1)
53int XGIfb_GetXG21DefaultLVDSModeIdx(void);
54
Aaro Koskinen0f07d942011-02-17 23:29:13 +020055#define XGIFB_ROM_SIZE 65536
56
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020057/* -------------------- Macro definitions ---------------------------- */
58
59#undef XGIFBDEBUG
60
61#ifdef XGIFBDEBUG
62#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63#else
64#define DPRINTK(fmt, args...)
65#endif
66
67#ifdef XGIFBDEBUG
68static void dumpVGAReg(void)
69{
Prashant P. Shahb654f872010-09-06 17:34:26 +053070 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020071
Prashant P. Shahb654f872010-09-06 17:34:26 +053072 outXGIIDXREG(XGISR, 0x05, 0x86);
73 /*
74 outXGIIDXREG(XGISR, 0x08, 0x4f);
75 outXGIIDXREG(XGISR, 0x0f, 0x20);
76 outXGIIDXREG(XGISR, 0x11, 0x4f);
77 outXGIIDXREG(XGISR, 0x13, 0x45);
78 outXGIIDXREG(XGISR, 0x14, 0x51);
79 outXGIIDXREG(XGISR, 0x1e, 0x41);
80 outXGIIDXREG(XGISR, 0x1f, 0x0);
81 outXGIIDXREG(XGISR, 0x20, 0xa1);
82 outXGIIDXREG(XGISR, 0x22, 0xfb);
83 outXGIIDXREG(XGISR, 0x26, 0x22);
84 outXGIIDXREG(XGISR, 0x3e, 0x07);
85 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020086
Prashant P. Shahb654f872010-09-06 17:34:26 +053087 /* outXGIIDXREG(XGICR, 0x19, 0x00); */
88 /* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
89 /* outXGIIDXREG(XGICR, 0x22, 0xff); */
90 /* outXGIIDXREG(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020091
Prashant P. Shahb654f872010-09-06 17:34:26 +053092 /* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020093
Prashant P. Shahb654f872010-09-06 17:34:26 +053094 /* outXGIIDXREG(XGICR, 0x57, 0x0); */
95 /* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020096
Prashant P. Shahb654f872010-09-06 17:34:26 +053097 /* outXGIIDXREG(XGICR, 0x82, 0xcc); */
98 /* outXGIIDXREG(XGICR, 0x8c, 0x0); */
99 /*
100 outXGIIDXREG(XGICR, 0x99, 0x1);
101 outXGIIDXREG(XGICR, 0x41, 0x40);
102 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200103
Prashant P. Shahb654f872010-09-06 17:34:26 +0530104 for (i = 0; i < 0x4f; i++) {
105 inXGIIDXREG(XGISR, i, reg);
106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
108 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200109
Prashant P. Shahb654f872010-09-06 17:34:26 +0530110 for (i = 0; i < 0xF0; i++) {
111 inXGIIDXREG(XGICR, i, reg);
112 printk("\no 3d4 %x", i);
113 printk("\ni 3d5 => %x", reg);
114 }
115 /*
116 outXGIIDXREG(XGIPART1,0x2F,1);
117 for (i=1; i < 0x50; i++) {
118 inXGIIDXREG(XGIPART1, i, reg);
119 printk("\no d004 %x", i);
120 printk("\ni d005 => %x", reg);
121 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200122
Prashant P. Shahb654f872010-09-06 17:34:26 +0530123 for (i=0; i < 0x50; i++) {
124 inXGIIDXREG(XGIPART2, i, reg);
125 printk("\no d010 %x", i);
126 printk("\ni d011 => %x", reg);
127 }
128 for (i=0; i < 0x50; i++) {
129 inXGIIDXREG(XGIPART3, i, reg);
130 printk("\no d012 %x",i);
131 printk("\ni d013 => %x",reg);
132 }
133 for (i=0; i < 0x50; i++) {
134 inXGIIDXREG(XGIPART4, i, reg);
135 printk("\no d014 %x",i);
136 printk("\ni d015 => %x",reg);
137 }
138 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200139}
140#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530141static inline void dumpVGAReg(void)
142{
143}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200144#endif
145
146/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530147struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200148
149#if 1
150#define DEBUGPRN(x)
151#else
152#define DEBUGPRN(x) printk(KERN_INFO x "\n");
153#endif
154
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200155/* --------------- Hardware Access Routines -------------------------- */
156
Prashant P. Shahb654f872010-09-06 17:34:26 +0530157static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 struct xgi_hw_device_info *HwDeviceExtension,
159 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200160{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200164
Prashant P. Shahb654f872010-09-06 17:34:26 +0530165 /* unsigned long temp = 0; */
166 int Clock;
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200169
Prashant P. Shahb654f872010-09-06 17:34:26 +0530170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200172
Prashant P. Shahb654f872010-09-06 17:34:26 +0530173 /*
174 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
175 if (!temp) {
176 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
177 return 65000;
178 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200179
Prashant P. Shahb654f872010-09-06 17:34:26 +0530180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200182
Prashant P. Shahb654f872010-09-06 17:34:26 +0530183 */
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200185
Prashant P. Shahb654f872010-09-06 17:34:26 +0530186 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
187
188 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200189}
190
Prashant P. Shahb654f872010-09-06 17:34:26 +0530191static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192 struct xgi_hw_device_info *HwDeviceExtension,
193 unsigned char modeno, unsigned char rateindex,
194 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
196 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200197{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530198 unsigned short ModeNo = modeno;
199 unsigned short ModeIdIndex = 0, index = 0;
200 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200201
Prashant P. Shahb654f872010-09-06 17:34:26 +0530202 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204 unsigned char sr_data, cr_data, cr_data2;
205 unsigned long cr_data3;
206 int A, B, C, D, E, F, temp, j;
207 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210 ModeIdIndex, XGI_Pr);
211 /*
212 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
213 if (!temp)
214 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200215
Prashant P. Shahb654f872010-09-06 17:34:26 +0530216 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217 RefreshRateTableIndex += (rateindex - 1);
218 */
219 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200220
Prashant P. Shahb654f872010-09-06 17:34:26 +0530221 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200222
Prashant P. Shahb654f872010-09-06 17:34:26 +0530223 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200224
Prashant P. Shahb654f872010-09-06 17:34:26 +0530225 /* Horizontal total */
226 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
227 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200228
Prashant P. Shahb654f872010-09-06 17:34:26 +0530229 /*
230 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200231
Prashant P. Shahb654f872010-09-06 17:34:26 +0530232 Horizontal display enable end
233 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
234 */
235 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
236 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200237
Prashant P. Shahb654f872010-09-06 17:34:26 +0530238 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200239
Prashant P. Shahb654f872010-09-06 17:34:26 +0530240 /* Horizontal retrace (=sync) start */
241 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
242 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200243
Prashant P. Shahb654f872010-09-06 17:34:26 +0530244 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200245
Prashant P. Shahb654f872010-09-06 17:34:26 +0530246 /* Horizontal blank start */
247 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200248
Prashant P. Shahb654f872010-09-06 17:34:26 +0530249 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200250
Prashant P. Shahb654f872010-09-06 17:34:26 +0530251 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200252
Prashant P. Shahb654f872010-09-06 17:34:26 +0530253 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200254
Prashant P. Shahb654f872010-09-06 17:34:26 +0530255 /* Horizontal blank end */
256 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200258
Prashant P. Shahb654f872010-09-06 17:34:26 +0530259 /* Horizontal retrace (=sync) end */
260 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200261
Prashant P. Shahb654f872010-09-06 17:34:26 +0530262 temp = HBE - ((E - 1) & 255);
263 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200264
Prashant P. Shahb654f872010-09-06 17:34:26 +0530265 temp = HRE - ((E + F + 3) & 63);
266 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200267
Prashant P. Shahb654f872010-09-06 17:34:26 +0530268 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200269
Prashant P. Shahb654f872010-09-06 17:34:26 +0530270 *left_margin = D * 8;
271 *right_margin = F * 8;
272 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200273
Prashant P. Shahb654f872010-09-06 17:34:26 +0530274 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200275
Prashant P. Shahb654f872010-09-06 17:34:26 +0530276 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200277
Prashant P. Shahb654f872010-09-06 17:34:26 +0530278 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200279
Prashant P. Shahb654f872010-09-06 17:34:26 +0530280 /* Vertical total */
281 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282 | ((unsigned short) (cr_data2 & 0x20) << 4)
283 | ((unsigned short) (sr_data & 0x01) << 10);
284 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200285
Prashant P. Shahb654f872010-09-06 17:34:26 +0530286 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200287
Prashant P. Shahb654f872010-09-06 17:34:26 +0530288 /* Vertical display enable end */
289 /*
290 VDE = (cr_data & 0xff) |
291 ((unsigned short) (cr_data2 & 0x02) << 7) |
292 ((unsigned short) (cr_data2 & 0x40) << 3) |
293 ((unsigned short) (sr_data & 0x02) << 9);
294 */
295 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
296 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200297
Prashant P. Shahb654f872010-09-06 17:34:26 +0530298 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200299
Prashant P. Shahb654f872010-09-06 17:34:26 +0530300 /* Vertical retrace (=sync) start */
301 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302 | ((unsigned short) (cr_data2 & 0x80) << 2)
303 | ((unsigned short) (sr_data & 0x08) << 7);
304 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200305
Prashant P. Shahb654f872010-09-06 17:34:26 +0530306 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200307
Prashant P. Shahb654f872010-09-06 17:34:26 +0530308 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200309
Prashant P. Shahb654f872010-09-06 17:34:26 +0530310 /* Vertical blank start */
311 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312 | ((unsigned short) (cr_data3 & 0x20) << 4)
313 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200314
Prashant P. Shahb654f872010-09-06 17:34:26 +0530315 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200316
Prashant P. Shahb654f872010-09-06 17:34:26 +0530317 /* Vertical blank end */
318 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319 temp = VBE - ((E - 1) & 511);
320 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200321
Prashant P. Shahb654f872010-09-06 17:34:26 +0530322 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200323
Prashant P. Shahb654f872010-09-06 17:34:26 +0530324 /* Vertical retrace (=sync) end */
325 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326 temp = VRE - ((E + F - 1) & 31);
327 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200328
Prashant P. Shahb654f872010-09-06 17:34:26 +0530329 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200330
Prashant P. Shahb654f872010-09-06 17:34:26 +0530331 *upper_margin = D;
332 *lower_margin = F;
333 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200334
Prashant P. Shahb654f872010-09-06 17:34:26 +0530335 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
337 else
338 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200339
Prashant P. Shahb654f872010-09-06 17:34:26 +0530340 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
342 else
343 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200344
Prashant P. Shahb654f872010-09-06 17:34:26 +0530345 *vmode = FB_VMODE_NONINTERLACED;
346 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347 *vmode = FB_VMODE_INTERLACED;
348 else {
349 j = 0;
350 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
351 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
352 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
354 & DoubleScanMode) {
355 *vmode = FB_VMODE_DOUBLE;
356 }
357 break;
358 }
359 j++;
360 }
361 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200362
Prashant P. Shahb654f872010-09-06 17:34:26 +0530363 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200364}
365
Randy Dunlap89229672010-08-10 08:46:44 -0700366static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200367{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530368 XGI_Pr->RelIO = BaseAddr;
369 XGI_Pr->P3c4 = BaseAddr + 0x14;
370 XGI_Pr->P3d4 = BaseAddr + 0x24;
371 XGI_Pr->P3c0 = BaseAddr + 0x10;
372 XGI_Pr->P3ce = BaseAddr + 0x1e;
373 XGI_Pr->P3c2 = BaseAddr + 0x12;
374 XGI_Pr->P3ca = BaseAddr + 0x1a;
375 XGI_Pr->P3c6 = BaseAddr + 0x16;
376 XGI_Pr->P3c7 = BaseAddr + 0x17;
377 XGI_Pr->P3c8 = BaseAddr + 0x18;
378 XGI_Pr->P3c9 = BaseAddr + 0x19;
379 XGI_Pr->P3da = BaseAddr + 0x2A;
380 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
381 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
382 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
383 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
384 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200385
386}
387
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200388void XGIfb_set_reg4(u16 port, unsigned long data)
389{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530390 outl((u32)(data & 0xffffffff), port);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200391}
392
393u32 XGIfb_get_reg3(u16 port)
394{
395 u32 data;
396
397 data = inl(port);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530398 return data;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200399}
400
401/* ------------ Interface for init & mode switching code ------------- */
402
Prashant P. Shahb654f872010-09-06 17:34:26 +0530403unsigned char XGIfb_query_VGA_config_space(
404 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
405 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200406{
407 static struct pci_dev *pdev = NULL;
408 static unsigned char init = 0, valid_pdev = 0;
409
410 if (!set)
411 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
412 else
413 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
414
415 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400416 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530417 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
418 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200419 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400420 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200421 pci_dev_put(pdev);
422 }
423 }
424
425 if (!valid_pdev) {
426 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
427 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400428 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200429 }
430
431 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530432 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200433 else
434 pci_write_config_dword(pdev, offset, (u32)(*value));
435
Bill Pembertondda08c52010-06-17 13:10:42 -0400436 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200437}
438
Prashant P. Shahb654f872010-09-06 17:34:26 +0530439/*
440unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200441 unsigned long offset, unsigned long set, unsigned long *value)
442{
443 static struct pci_dev *pdev = NULL;
444 static unsigned char init = 0, valid_pdev = 0;
445 u16 nbridge_id = 0;
446
447 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400448 init = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200449 switch (xgi_video_info.chip) {
450 case XGI_540:
451 nbridge_id = PCI_DEVICE_ID_XG_540;
452 break;
453 case XGI_630:
454 nbridge_id = PCI_DEVICE_ID_XG_630;
455 break;
456 case XGI_730:
457 nbridge_id = PCI_DEVICE_ID_XG_730;
458 break;
459 case XGI_550:
460 nbridge_id = PCI_DEVICE_ID_XG_550;
461 break;
462 case XGI_650:
463 nbridge_id = PCI_DEVICE_ID_XG_650;
464 break;
465 case XGI_740:
466 nbridge_id = PCI_DEVICE_ID_XG_740;
467 break;
468 default:
469 nbridge_id = 0;
470 break;
471 }
472
Atul Sowanifc2347e2010-11-03 18:40:56 +0530473 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
474 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400475 valid_pdev = 1;
Atul Sowanifc2347e2010-11-03 18:40:56 +0530476 pci_dev_put(pdev);
477 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200478 }
479
480 if (!valid_pdev) {
481 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530482 nbridge_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400483 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200484 }
485
486 if (set == 0)
487 pci_read_config_dword(pdev, offset, (u32 *)value);
488 else
489 pci_write_config_dword(pdev, offset, (u32)(*value));
490
Bill Pembertondda08c52010-06-17 13:10:42 -0400491 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200492}
493*/
494/* ------------------ Internal helper routines ----------------- */
495
496static void XGIfb_search_mode(const char *name)
497{
498 int i = 0, j = 0, l;
499
Prashant P. Shahb654f872010-09-06 17:34:26 +0530500 if (name == NULL) {
501 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
502 xgifb_mode_idx = DEFAULT_MODE;
503 if ((xgi_video_info.chip == XG21)
504 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
505 == DISPTYPE_LCD)) {
506 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
507 }
508 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200509 }
510
Prashant P. Shahb654f872010-09-06 17:34:26 +0530511 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
512 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
513 xgifb_mode_idx = DEFAULT_MODE;
514 if ((xgi_video_info.chip == XG21)
515 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
516 == DISPTYPE_LCD)) {
517 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
518 }
519 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200520 }
521
Prashant P. Shahb654f872010-09-06 17:34:26 +0530522 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200523 l = min(strlen(name), strlen(XGIbios_mode[i].name));
524 if (!strncmp(name, XGIbios_mode[i].name, l)) {
525 xgifb_mode_idx = i;
526 j = 1;
527 break;
528 }
529 i++;
530 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530531 if (!j)
532 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200533}
534
535static void XGIfb_search_vesamode(unsigned int vesamode)
536{
537 int i = 0, j = 0;
538
Prashant P. Shahb654f872010-09-06 17:34:26 +0530539 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200540
541 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
542 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530543 if ((xgi_video_info.chip == XG21)
544 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
545 == DISPTYPE_LCD)) {
546 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200547 }
548 return;
549 }
550
Prashant P. Shahb654f872010-09-06 17:34:26 +0530551 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200552
Prashant P. Shahb654f872010-09-06 17:34:26 +0530553 while (XGIbios_mode[i].mode_no != 0) {
554 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
555 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200556 xgifb_mode_idx = i;
557 j = 1;
558 break;
559 }
560 i++;
561 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530562 if (!j)
563 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200564}
565
Randy Dunlap89229672010-08-10 08:46:44 -0700566static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200567{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530568 u8 tmp;
569 unsigned char *pData;
570 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200571
Prashant P. Shahb654f872010-09-06 17:34:26 +0530572 inXGIIDXREG(XGISR, 0x1e, tmp);
573 outXGIIDXREG(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200574
Prashant P. Shahb654f872010-09-06 17:34:26 +0530575 pData = xgi_video_info.mmio_vbase + 0x20000;
576 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
577 i = pData[0x316] | (pData[0x317] << 8);
578 j = pData[i - 1];
579 if (j == 0xff)
580 j = 1;
581
582 k = 0;
583 do {
584 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
585 | (pData[i + 1] << 8);
586 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
587 + 3] << 8);
588 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
589 + 5] << 8);
590 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
591 + 7] << 8);
592 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
593 + 9] << 8);
594 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
595 + 11] << 8);
596 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
597 + 13] << 8);
598 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
599 | (pData[i + 15] << 8);
600 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
601 | (pData[i + 17] << 8);
602 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
603 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
604 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
605 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
606 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
607 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
608 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
609 i += 25;
610 j--;
611 k++;
612 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
613 / sizeof(struct XGI21_LVDSCapStruct))));
614 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200615 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530616 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200617}
618
619int XGIfb_GetXG21DefaultLVDSModeIdx(void)
620{
621
622 int found_mode = 0;
623 int XGIfb_mode_idx = 0;
624
625 found_mode = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530626 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
627 && (XGIbios_mode[XGIfb_mode_idx].xres
628 <= XGI21_LCDCapList[0].LVDSHDE)) {
629 if ((XGIbios_mode[XGIfb_mode_idx].xres
630 == XGI21_LCDCapList[0].LVDSHDE)
631 && (XGIbios_mode[XGIfb_mode_idx].yres
632 == XGI21_LCDCapList[0].LVDSVDE)
633 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200634 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
635 found_mode = 1;
636 break;
637 }
638 XGIfb_mode_idx++;
639 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530640 if (!found_mode)
641 XGIfb_mode_idx = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200642
Prashant P. Shahb654f872010-09-06 17:34:26 +0530643 return XGIfb_mode_idx;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200644}
645
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200646static int XGIfb_validate_mode(int myindex)
647{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530648 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200649
Prashant P. Shahb654f872010-09-06 17:34:26 +0530650 if (xgi_video_info.chip == XG21) {
651 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
652 == DISPTYPE_LCD) {
653 xres = XGI21_LCDCapList[0].LVDSHDE;
654 yres = XGI21_LCDCapList[0].LVDSVDE;
655 if (XGIbios_mode[myindex].xres > xres)
656 return -1;
657 if (XGIbios_mode[myindex].yres > yres)
658 return -1;
659 if ((XGIbios_mode[myindex].xres < xres)
660 && (XGIbios_mode[myindex].yres < yres)) {
661 if (XGIbios_mode[myindex].bpp > 8)
662 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200663 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530664
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200665 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530666 return myindex;
667
668 }
669
670 /* FIXME: for now, all is valid on XG27 */
671 if (xgi_video_info.chip == XG27)
672 return myindex;
673
674 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
675 return -1;
676
677 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
678 case DISPTYPE_LCD:
679 switch (XGIhw_ext.ulCRT2LCDType) {
680 case LCD_640x480:
681 xres = 640;
682 yres = 480;
683 break;
684 case LCD_800x600:
685 xres = 800;
686 yres = 600;
687 break;
688 case LCD_1024x600:
689 xres = 1024;
690 yres = 600;
691 break;
692 case LCD_1024x768:
693 xres = 1024;
694 yres = 768;
695 break;
696 case LCD_1152x768:
697 xres = 1152;
698 yres = 768;
699 break;
700 case LCD_1280x960:
701 xres = 1280;
702 yres = 960;
703 break;
704 case LCD_1280x768:
705 xres = 1280;
706 yres = 768;
707 break;
708 case LCD_1280x1024:
709 xres = 1280;
710 yres = 1024;
711 break;
712 case LCD_1400x1050:
713 xres = 1400;
714 yres = 1050;
715 break;
716 case LCD_1600x1200:
717 xres = 1600;
718 yres = 1200;
719 break;
720 /* case LCD_320x480: */ /* TW: FSTN */
721 /*
722 xres = 320;
723 yres = 480;
724 break;
725 */
726 default:
727 xres = 0;
728 yres = 0;
729 break;
730 }
731 if (XGIbios_mode[myindex].xres > xres)
732 return -1;
733 if (XGIbios_mode[myindex].yres > yres)
734 return -1;
735 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
736 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
737 switch (XGIbios_mode[myindex].xres) {
738 case 512:
739 if (XGIbios_mode[myindex].yres != 512)
740 return -1;
741 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
742 return -1;
743 break;
744 case 640:
745 if ((XGIbios_mode[myindex].yres != 400)
746 && (XGIbios_mode[myindex].yres
747 != 480))
748 return -1;
749 break;
750 case 800:
751 if (XGIbios_mode[myindex].yres != 600)
752 return -1;
753 break;
754 case 1024:
755 if ((XGIbios_mode[myindex].yres != 600)
756 && (XGIbios_mode[myindex].yres
757 != 768))
758 return -1;
759 if ((XGIbios_mode[myindex].yres == 600)
760 && (XGIhw_ext.ulCRT2LCDType
761 != LCD_1024x600))
762 return -1;
763 break;
764 case 1152:
765 if ((XGIbios_mode[myindex].yres) != 768)
766 return -1;
767 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
768 return -1;
769 break;
770 case 1280:
771 if ((XGIbios_mode[myindex].yres != 768)
772 && (XGIbios_mode[myindex].yres
773 != 1024))
774 return -1;
775 if ((XGIbios_mode[myindex].yres == 768)
776 && (XGIhw_ext.ulCRT2LCDType
777 != LCD_1280x768))
778 return -1;
779 break;
780 case 1400:
781 if (XGIbios_mode[myindex].yres != 1050)
782 return -1;
783 break;
784 case 1600:
785 if (XGIbios_mode[myindex].yres != 1200)
786 return -1;
787 break;
788 default:
789 return -1;
790 }
791 } else {
792 switch (XGIbios_mode[myindex].xres) {
793 case 512:
794 if (XGIbios_mode[myindex].yres != 512)
795 return -1;
796 break;
797 case 640:
798 if ((XGIbios_mode[myindex].yres != 400)
799 && (XGIbios_mode[myindex].yres
800 != 480))
801 return -1;
802 break;
803 case 800:
804 if (XGIbios_mode[myindex].yres != 600)
805 return -1;
806 break;
807 case 1024:
808 if (XGIbios_mode[myindex].yres != 768)
809 return -1;
810 break;
811 case 1280:
812 if ((XGIbios_mode[myindex].yres != 960)
813 && (XGIbios_mode[myindex].yres
814 != 1024))
815 return -1;
816 if (XGIbios_mode[myindex].yres == 960) {
817 if (XGIhw_ext.ulCRT2LCDType
818 == LCD_1400x1050)
819 return -1;
820 }
821 break;
822 case 1400:
823 if (XGIbios_mode[myindex].yres != 1050)
824 return -1;
825 break;
826 case 1600:
827 if (XGIbios_mode[myindex].yres != 1200)
828 return -1;
829 break;
830 default:
831 return -1;
832 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200833 }
834 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530835 case DISPTYPE_TV:
836 switch (XGIbios_mode[myindex].xres) {
837 case 512:
838 case 640:
839 case 800:
840 break;
841 case 720:
842 if (xgi_video_info.TV_type == TVMODE_NTSC) {
843 if (XGIbios_mode[myindex].yres != 480)
844 return -1;
845 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
846 if (XGIbios_mode[myindex].yres != 576)
847 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200848 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530849 /* TW: LVDS/CHRONTEL does not support 720 */
850 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
851 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
852 return -1;
853 }
854 break;
855 case 1024:
856 if (xgi_video_info.TV_type == TVMODE_NTSC) {
857 if (XGIbios_mode[myindex].bpp == 32)
858 return -1;
859 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530860 break;
861 default:
862 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200863 }
864 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530865 case DISPTYPE_CRT2:
866 if (XGIbios_mode[myindex].xres > 1280)
867 return -1;
868 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200869 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530870 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200871
872}
873
874static void XGIfb_search_crt2type(const char *name)
875{
876 int i = 0;
877
Prashant P. Shahb654f872010-09-06 17:34:26 +0530878 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200879 return;
880
Prashant P. Shahb654f872010-09-06 17:34:26 +0530881 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200882 if (!strcmp(name, XGI_crt2type[i].name)) {
883 XGIfb_crt2type = XGI_crt2type[i].type_no;
884 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
885 break;
886 }
887 i++;
888 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530889 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200890 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
891}
892
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200893static u8 XGIfb_search_refresh_rate(unsigned int rate)
894{
895 u16 xres, yres;
896 int i = 0;
897
898 xres = XGIbios_mode[xgifb_mode_idx].xres;
899 yres = XGIbios_mode[xgifb_mode_idx].yres;
900
901 XGIfb_rate_idx = 0;
902 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530903 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
904 == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200905 if (XGIfb_vrate[i].refresh == rate) {
906 XGIfb_rate_idx = XGIfb_vrate[i].idx;
907 break;
908 } else if (XGIfb_vrate[i].refresh > rate) {
909 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
910 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530911 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200912 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530913 xgi_video_info.refresh_rate
914 = XGIfb_vrate[i].refresh;
915 } else if (((rate - XGIfb_vrate[i - 1].refresh)
916 <= 2) && (XGIfb_vrate[i].idx
917 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200918 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530919 rate, XGIfb_vrate[i-1].refresh);
920 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
921 xgi_video_info.refresh_rate
922 = XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200923 }
924 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530925 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200926 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
927 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530928 XGIfb_rate_idx = XGIfb_vrate[i].idx;
929 break;
930 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200931 }
932 i++;
933 }
934 if (XGIfb_rate_idx > 0) {
935 return XGIfb_rate_idx;
936 } else {
937 printk(KERN_INFO
Prashant P. Shahb654f872010-09-06 17:34:26 +0530938 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200939 return 0;
940 }
941}
942
943static void XGIfb_search_tvstd(const char *name)
944{
945 int i = 0;
946
Prashant P. Shahb654f872010-09-06 17:34:26 +0530947 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200948 return;
949
950 while (XGI_tvtype[i].type_no != -1) {
951 if (!strcmp(name, XGI_tvtype[i].name)) {
952 XGIfb_tvmode = XGI_tvtype[i].type_no;
953 break;
954 }
955 i++;
956 }
957}
958
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200959/* ----------- FBDev related routines for all series ----------- */
960
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200961static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
962{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530963 switch (var->bits_per_pixel) {
964 case 8:
965 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200966 var->red.length = var->green.length = var->blue.length = 6;
967 xgi_video_info.video_cmap_len = 256;
968 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530969 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200970 var->red.offset = 11;
971 var->red.length = 5;
972 var->green.offset = 5;
973 var->green.length = 6;
974 var->blue.offset = 0;
975 var->blue.length = 5;
976 var->transp.offset = 0;
977 var->transp.length = 0;
978 xgi_video_info.video_cmap_len = 16;
979 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530980 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200981 var->red.offset = 16;
982 var->red.length = 8;
983 var->green.offset = 8;
984 var->green.length = 8;
985 var->blue.offset = 0;
986 var->blue.length = 8;
987 var->transp.offset = 24;
988 var->transp.length = 8;
989 xgi_video_info.video_cmap_len = 16;
990 break;
991 }
992}
993
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200994static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +0530995 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200996{
997
Prashant P. Shahb654f872010-09-06 17:34:26 +0530998 unsigned int htotal = var->left_margin + var->xres + var->right_margin
999 + var->hsync_len;
1000 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1001 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001002#if defined(__powerpc__)
1003 u8 sr_data, cr_data;
1004#endif
1005 unsigned int drate = 0, hrate = 0;
1006 int found_mode = 0;
1007 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301008 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001009
1010 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301011 /* 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 +02001012
Prashant P. Shahb654f872010-09-06 17:34:26 +05301013 info->var.xres_virtual = var->xres_virtual;
1014 info->var.yres_virtual = var->yres_virtual;
1015 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001016
1017 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1018 vtotal <<= 1;
1019 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1020 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301021 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1022 /* vtotal <<= 1; */
1023 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001024 }
1025
Prashant P. Shahb654f872010-09-06 17:34:26 +05301026 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001027 DPRINTK("XGIfb: Invalid 'var' information\n");
1028 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301029 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1030 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001031
Prashant P. Shahb654f872010-09-06 17:34:26 +05301032 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001033 drate = 1000000000 / var->pixclock;
1034 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301035 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1036 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001037 } else {
1038 xgi_video_info.refresh_rate = 60;
1039 }
1040
1041 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05301042 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001043
1044 old_mode = xgifb_mode_idx;
1045 xgifb_mode_idx = 0;
1046
Prashant P. Shahb654f872010-09-06 17:34:26 +05301047 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1048 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1049 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1050 && (XGIbios_mode[xgifb_mode_idx].yres
1051 == var->yres)
1052 && (XGIbios_mode[xgifb_mode_idx].bpp
1053 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001054 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1055 found_mode = 1;
1056 break;
1057 }
1058 xgifb_mode_idx++;
1059 }
1060
Prashant P. Shahb654f872010-09-06 17:34:26 +05301061 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001062 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1063 else
1064 xgifb_mode_idx = -1;
1065
Prashant P. Shahb654f872010-09-06 17:34:26 +05301066 if (xgifb_mode_idx < 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001067 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301068 var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001069 xgifb_mode_idx = old_mode;
1070 return -EINVAL;
1071 }
1072
Prashant P. Shahb654f872010-09-06 17:34:26 +05301073 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001074 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1075 xgi_video_info.refresh_rate = 60;
1076 }
1077
Prashant P. Shahb654f872010-09-06 17:34:26 +05301078 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001079
1080 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301081 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001082 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1083 return -EINVAL;
1084 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301085 info->fix.line_length = ((info->var.xres_virtual
1086 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001087
Prashant P. Shahb654f872010-09-06 17:34:26 +05301088 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001089
Prashant P. Shahb654f872010-09-06 17:34:26 +05301090 outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1091 outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001092
1093 XGIfb_post_setmode();
1094
Prashant P. Shahb654f872010-09-06 17:34:26 +05301095 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1096 XGIbios_mode[xgifb_mode_idx].xres,
1097 XGIbios_mode[xgifb_mode_idx].yres,
1098 XGIbios_mode[xgifb_mode_idx].bpp,
1099 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001100
1101 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1102 xgi_video_info.video_vwidth = info->var.xres_virtual;
1103 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1104 xgi_video_info.video_vheight = info->var.yres_virtual;
1105 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1106 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301107 xgi_video_info.video_linelength = info->var.xres_virtual
1108 * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301109 switch (xgi_video_info.video_bpp) {
1110 case 8:
1111 xgi_video_info.DstColor = 0x0000;
1112 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1113 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001114#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301115 inXGIIDXREG(XGICR, 0x4D, cr_data);
1116 outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001117#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301118 break;
1119 case 16:
1120 xgi_video_info.DstColor = 0x8000;
1121 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001122#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301123 inXGIIDXREG(XGICR, 0x4D, cr_data);
1124 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001125#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301126 xgi_video_info.video_cmap_len = 16;
1127 break;
1128 case 32:
1129 xgi_video_info.DstColor = 0xC000;
1130 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1131 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001132#if defined(__powerpc__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301133 inXGIIDXREG(XGICR, 0x4D, cr_data);
1134 outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001135#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301136 break;
1137 default:
1138 xgi_video_info.video_cmap_len = 16;
1139 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301140 break;
1141 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001142 }
1143 XGIfb_bpp_to_var(var); /*update ARGB info*/
1144 DEBUGPRN("End of do_set_var");
1145
1146 dumpVGAReg();
1147 return 0;
1148}
1149
1150#ifdef XGIFB_PAN
1151static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1152{
1153 unsigned int base;
1154
Prashant P. Shahb654f872010-09-06 17:34:26 +05301155 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001156
1157 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301158 /* printk("Pan: xo: %d xv %d xr %d\n",
1159 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001160 return -EINVAL;
1161 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301162 if (var->yoffset > (var->yres_virtual - var->yres)) {
1163 /* printk("Pan: yo: %d yv %d yr %d\n",
1164 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001165 return -EINVAL;
1166 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301167 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001168
Prashant P. Shahb654f872010-09-06 17:34:26 +05301169 /* calculate base bpp dep. */
1170 switch (var->bits_per_pixel) {
1171 case 16:
1172 base >>= 1;
1173 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001174 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301175 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001176 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301177 default:
1178 base >>= 2;
1179 break;
1180 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001181
1182 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
1183
Prashant P. Shahb654f872010-09-06 17:34:26 +05301184 outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001185 outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
1186 outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301187 outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001188 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1189
Prashant P. Shahb654f872010-09-06 17:34:26 +05301190 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001191 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301192 outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
1193 outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1194 outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001195 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301196 }
1197 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001198 return 0;
1199}
1200#endif
1201
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001202static int XGIfb_open(struct fb_info *info, int user)
1203{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301204 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001205}
1206
1207static int XGIfb_release(struct fb_info *info, int user)
1208{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301209 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001210}
1211
1212static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1213{
1214 int rc = 16;
1215
Prashant P. Shahb654f872010-09-06 17:34:26 +05301216 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001217 case 8:
1218 rc = 256;
1219 break;
1220 case 16:
1221 rc = 16;
1222 break;
1223 case 32:
1224 rc = 16;
1225 break;
1226 }
1227 return rc;
1228}
1229
Prashant P. Shahb654f872010-09-06 17:34:26 +05301230static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1231 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001232{
1233 if (regno >= XGIfb_get_cmap_len(&info->var))
1234 return 1;
1235
1236 switch (info->var.bits_per_pixel) {
1237 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301238 outXGIREG(XGIDACA, regno);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001239 outXGIREG(XGIDACD, (red >> 10));
1240 outXGIREG(XGIDACD, (green >> 10));
1241 outXGIREG(XGIDACD, (blue >> 10));
1242 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301243 outXGIREG(XGIDAC2A, regno);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001244 outXGIREG(XGIDAC2D, (red >> 8));
1245 outXGIREG(XGIDAC2D, (green >> 8));
1246 outXGIREG(XGIDAC2D, (blue >> 8));
1247 }
1248 break;
1249 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301250 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1251 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1252 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001253 break;
1254 case 32:
1255 red >>= 8;
1256 green >>= 8;
1257 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301258 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1259 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001260 break;
1261 }
1262 return 0;
1263}
1264
1265static int XGIfb_set_par(struct fb_info *info)
1266{
1267 int err;
1268
Prashant P. Shahb654f872010-09-06 17:34:26 +05301269 /* printk("XGIfb: inside set_par\n"); */
1270 err = XGIfb_do_set_var(&info->var, 1, info);
1271 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001272 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001273 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301274 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001275 return 0;
1276}
1277
Prashant P. Shahb654f872010-09-06 17:34:26 +05301278static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001279{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301280 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1281 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001282 unsigned int vtotal = 0;
1283 unsigned int drate = 0, hrate = 0;
1284 int found_mode = 0;
1285 int refresh_rate, search_idx;
1286
1287 DEBUGPRN("Inside check_var");
1288
Prashant P. Shahb654f872010-09-06 17:34:26 +05301289 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1290 vtotal = var->upper_margin + var->yres + var->lower_margin
1291 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001292 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301293 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1294 vtotal = var->upper_margin + var->yres + var->lower_margin
1295 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001296 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301297 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1298 vtotal = var->upper_margin + (var->yres / 2)
1299 + var->lower_margin + var->vsync_len;
1300 } else
1301 vtotal = var->upper_margin + var->yres + var->lower_margin
1302 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001303
Prashant P. Shahb654f872010-09-06 17:34:26 +05301304 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001305 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301306
1307 if (var->pixclock && htotal && vtotal) {
1308 drate = 1000000000 / var->pixclock;
1309 hrate = (drate * 1000) / htotal;
1310 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1311 printk(KERN_DEBUG
1312 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1313 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1314 __func__, var->pixclock, htotal, vtotal,
1315 __func__, drate, hrate, xgi_video_info.refresh_rate);
1316 } else {
1317 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001318 }
1319
Prashant P. Shahb654f872010-09-06 17:34:26 +05301320 /*
1321 if ((var->pixclock) && (htotal)) {
1322 drate = 1E12 / var->pixclock;
1323 hrate = drate / htotal;
1324 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1325 } else {
1326 refresh_rate = 60;
1327 }
1328 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001329 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301330 if ((var->xres == 1024) && (var->yres == 600))
1331 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001332
1333 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301334 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1335 (XGIbios_mode[search_idx].xres <= var->xres)) {
1336 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1337 (XGIbios_mode[search_idx].yres == var->yres) &&
1338 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1339 if (XGIfb_validate_mode(search_idx) > 0) {
1340 found_mode = 1;
1341 break;
1342 }
1343 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001344 search_idx++;
1345 }
1346
Prashant P. Shahb654f872010-09-06 17:34:26 +05301347 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001348
1349 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1350 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301351 search_idx = 0;
1352 while (XGIbios_mode[search_idx].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001353
Prashant P. Shahb654f872010-09-06 17:34:26 +05301354 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1355 (var->yres <= XGIbios_mode[search_idx].yres) &&
1356 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1357 if (XGIfb_validate_mode(search_idx) > 0) {
1358 found_mode = 1;
1359 break;
1360 }
1361 }
1362 search_idx++;
1363 }
1364 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001365 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301366 var->yres = XGIbios_mode[search_idx].yres;
1367 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1368 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001369
1370 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301371 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001372 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301373 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001374 }
1375 }
1376
1377 /* TW: TODO: Check the refresh rate */
1378
1379 /* Adapt RGB settings */
1380 XGIfb_bpp_to_var(var);
1381
1382 /* Sanity check for offsets */
1383 if (var->xoffset < 0)
1384 var->xoffset = 0;
1385 if (var->yoffset < 0)
1386 var->yoffset = 0;
1387
Prashant P. Shahb654f872010-09-06 17:34:26 +05301388 if (!XGIfb_ypan) {
1389 if (var->xres != var->xres_virtual)
1390 var->xres_virtual = var->xres;
1391 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001392 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301393 } /* else { */
1394 /* TW: Now patch yres_virtual if we use panning */
1395 /* May I do this? */
1396 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1397 /* if (var->yres_virtual <= var->yres) { */
1398 /* TW: Paranoia check */
1399 /* var->yres_virtual = var->yres; */
1400 /* } */
1401 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001402
1403 /* Truncate offsets to maximum if too high */
1404 if (var->xoffset > var->xres_virtual - var->xres)
1405 var->xoffset = var->xres_virtual - var->xres - 1;
1406
1407 if (var->yoffset > var->yres_virtual - var->yres)
1408 var->yoffset = var->yres_virtual - var->yres - 1;
1409
1410 /* Set everything else to 0 */
1411 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301412 var->green.msb_right =
1413 var->blue.msb_right =
1414 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001415
1416 DEBUGPRN("end of check_var");
1417 return 0;
1418}
1419
1420#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301421static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1422 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001423{
1424 int err;
1425
Prashant P. Shahb654f872010-09-06 17:34:26 +05301426 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001427
1428 if (var->xoffset > (var->xres_virtual - var->xres))
1429 return -EINVAL;
1430 if (var->yoffset > (var->yres_virtual - var->yres))
1431 return -EINVAL;
1432
1433 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301434 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1435 || var->xoffset)
1436 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001437 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301438 if (var->xoffset + info->var.xres > info->var.xres_virtual
1439 || var->yoffset + info->var.yres
1440 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001441 return -EINVAL;
1442 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301443 err = XGIfb_pan_var(var);
1444 if (err < 0)
1445 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001446
1447 info->var.xoffset = var->xoffset;
1448 info->var.yoffset = var->yoffset;
1449 if (var->vmode & FB_VMODE_YWRAP)
1450 info->var.vmode |= FB_VMODE_YWRAP;
1451 else
1452 info->var.vmode &= ~FB_VMODE_YWRAP;
1453
Prashant P. Shahb654f872010-09-06 17:34:26 +05301454 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001455 return 0;
1456}
1457#endif
1458
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001459static int XGIfb_blank(int blank, struct fb_info *info)
1460{
1461 u8 reg;
1462
1463 inXGIIDXREG(XGICR, 0x17, reg);
1464
Prashant P. Shahb654f872010-09-06 17:34:26 +05301465 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001466 reg &= 0x7f;
1467 else
1468 reg |= 0x80;
1469
Prashant P. Shahb654f872010-09-06 17:34:26 +05301470 outXGIIDXREG(XGICR, 0x17, reg);
1471 outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
1472 outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
1473 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001474}
1475
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001476/* ----------- FBDev related routines for all series ---------- */
1477
1478static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301479 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001480{
1481 DEBUGPRN("inside get_fix");
1482 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1483
1484 strcpy(fix->id, myid);
1485
1486 fix->smem_start = xgi_video_info.video_base;
1487
1488 fix->smem_len = xgi_video_info.video_size;
1489
Prashant P. Shahb654f872010-09-06 17:34:26 +05301490 fix->type = video_type;
1491 fix->type_aux = 0;
1492 if (xgi_video_info.video_bpp == 8)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001493 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1494 else
1495 fix->visual = FB_VISUAL_DIRECTCOLOR;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301496 fix->xpanstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001497#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301498 if (XGIfb_ypan)
1499 fix->ypanstep = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001500#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301501 fix->ywrapstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001502 fix->line_length = xgi_video_info.video_linelength;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301503 fix->mmio_start = xgi_video_info.mmio_base;
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02001504 fix->mmio_len = xgi_video_info.mmio_size;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301505 if (xgi_video_info.chip >= XG40)
1506 fix->accel = FB_ACCEL_XGI_XABRE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001507 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05301508 fix->accel = FB_ACCEL_XGI_GLAMOUR_2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001509
1510 DEBUGPRN("end of get_fix");
1511 return 0;
1512}
1513
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001514static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301515 .owner = THIS_MODULE,
1516 .fb_open = XGIfb_open,
1517 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001518 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301519 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001520 .fb_setcolreg = XGIfb_setcolreg,
1521#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301522 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001523#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301524 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001525 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001526 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001527 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301528 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001529};
1530
1531/* ---------------- Chip generation dependent routines ---------------- */
1532
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001533/* for XGI 315/550/650/740/330 */
1534
1535static int XGIfb_get_dram_size(void)
1536{
1537
Prashant P. Shahb654f872010-09-06 17:34:26 +05301538 u8 ChannelNum, tmp;
1539 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001540
1541 /* xorg driver sets 32MB * 1 channel */
1542 if (xgi_video_info.chip == XG27)
1543 outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
1544
Prashant P. Shahb654f872010-09-06 17:34:26 +05301545 inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
1546 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1547 case XGI_DRAM_SIZE_1MB:
1548 xgi_video_info.video_size = 0x100000;
1549 break;
1550 case XGI_DRAM_SIZE_2MB:
1551 xgi_video_info.video_size = 0x200000;
1552 break;
1553 case XGI_DRAM_SIZE_4MB:
1554 xgi_video_info.video_size = 0x400000;
1555 break;
1556 case XGI_DRAM_SIZE_8MB:
1557 xgi_video_info.video_size = 0x800000;
1558 break;
1559 case XGI_DRAM_SIZE_16MB:
1560 xgi_video_info.video_size = 0x1000000;
1561 break;
1562 case XGI_DRAM_SIZE_32MB:
1563 xgi_video_info.video_size = 0x2000000;
1564 break;
1565 case XGI_DRAM_SIZE_64MB:
1566 xgi_video_info.video_size = 0x4000000;
1567 break;
1568 case XGI_DRAM_SIZE_128MB:
1569 xgi_video_info.video_size = 0x8000000;
1570 break;
1571 case XGI_DRAM_SIZE_256MB:
1572 xgi_video_info.video_size = 0x10000000;
1573 break;
1574 default:
1575 return -1;
1576 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001577
Prashant P. Shahb654f872010-09-06 17:34:26 +05301578 tmp = (reg & 0x0c) >> 2;
1579 switch (xgi_video_info.chip) {
1580 case XG20:
1581 case XG21:
1582 case XG27:
1583 ChannelNum = 1;
1584 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001585
Prashant P. Shahb654f872010-09-06 17:34:26 +05301586 case XG42:
1587 if (reg & 0x04)
1588 ChannelNum = 2;
1589 else
1590 ChannelNum = 1;
1591 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001592
Prashant P. Shahb654f872010-09-06 17:34:26 +05301593 case XG45:
1594 if (tmp == 1)
1595 ChannelNum = 2;
1596 else if (tmp == 2)
1597 ChannelNum = 3;
1598 else if (tmp == 3)
1599 ChannelNum = 4;
1600 else
1601 ChannelNum = 1;
1602 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001603
Prashant P. Shahb654f872010-09-06 17:34:26 +05301604 case XG40:
1605 default:
1606 if (tmp == 2)
1607 ChannelNum = 2;
1608 else if (tmp == 3)
1609 ChannelNum = 3;
1610 else
1611 ChannelNum = 1;
1612 break;
1613 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001614
Prashant P. Shahb654f872010-09-06 17:34:26 +05301615 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1616 /* PLiad fixed for benchmarking and fb set */
1617 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1618 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001619
Prashant P. Shahb654f872010-09-06 17:34:26 +05301620 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1621 xgi_video_info.video_size, ChannelNum);
1622 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001623
1624}
1625
1626static void XGIfb_detect_VB(void)
1627{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301628 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001629
1630 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1631
Prashant P. Shahb654f872010-09-06 17:34:26 +05301632 switch (xgi_video_info.hasVB) {
1633 case HASVB_LVDS_CHRONTEL:
1634 case HASVB_CHRONTEL:
1635 break;
1636 case HASVB_301:
1637 case HASVB_302:
1638 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1639 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001640 }
1641
1642 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
1643
1644 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1645 XGIfb_crt1off = 0;
1646 else {
1647 if (cr32 & 0x5F)
1648 XGIfb_crt1off = 1;
1649 else
1650 XGIfb_crt1off = 0;
1651 }
1652
1653 if (XGIfb_crt2type != -1)
1654 /* TW: Override with option */
1655 xgi_video_info.disp_state = XGIfb_crt2type;
1656 else if (cr32 & XGI_VB_TV)
1657 xgi_video_info.disp_state = DISPTYPE_TV;
1658 else if (cr32 & XGI_VB_LCD)
1659 xgi_video_info.disp_state = DISPTYPE_LCD;
1660 else if (cr32 & XGI_VB_CRT2)
1661 xgi_video_info.disp_state = DISPTYPE_CRT2;
1662 else
1663 xgi_video_info.disp_state = 0;
1664
Prashant P. Shahb654f872010-09-06 17:34:26 +05301665 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001666 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301667 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001668 else if (cr32 & XGI_VB_HIVISION) {
1669 xgi_video_info.TV_type = TVMODE_HIVISION;
1670 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301671 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001672 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1673 else if (cr32 & XGI_VB_COMPOSITE)
1674 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1675 else if (cr32 & XGI_VB_SCART)
1676 xgi_video_info.TV_plug = TVPLUG_SCART;
1677
Prashant P. Shahb654f872010-09-06 17:34:26 +05301678 if (xgi_video_info.TV_type == 0) {
Aaro Koskinenebe78462011-03-13 12:26:08 +02001679 inXGIIDXREG(XGICR, 0x38, temp);
1680 if (temp & 0x10)
1681 xgi_video_info.TV_type = TVMODE_PAL;
1682 else
1683 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001684 }
1685
1686 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301687 if (XGIfb_forcecrt1 != -1) {
1688 if (XGIfb_forcecrt1)
1689 XGIfb_crt1off = 0;
1690 else
1691 XGIfb_crt1off = 1;
1692 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001693}
1694
1695static void XGIfb_get_VB_type(void)
1696{
1697 u8 reg;
1698
1699 if (!XGIfb_has_VB()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301700 inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001701 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301702 case XGI310_EXTERNAL_CHIP_LVDS:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001703 xgi_video_info.hasVB = HASVB_LVDS;
1704 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301705 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001706 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1707 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301708 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001709 break;
1710 }
1711 }
1712}
1713
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001714static int XGIfb_has_VB(void)
1715{
1716 u8 vb_chipid;
1717
1718 inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
1719 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301720 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001721 xgi_video_info.hasVB = HASVB_301;
1722 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301723 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001724 xgi_video_info.hasVB = HASVB_302;
1725 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301726 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001727 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001728 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001729 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001730 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001731}
1732
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001733/* ------------------ Sensing routines ------------------ */
1734
1735/* TW: Determine and detect attached devices on XGI30x */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301736int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001737{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301738 int temp, i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001739
Prashant P. Shahb654f872010-09-06 17:34:26 +05301740 outXGIIDXREG(XGIPART4, 0x11, tempbl);
1741 temp = tempbh | tempcl;
1742 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1743 for (i = 0; i < 10; i++)
1744 XGI_LongWait(&XGI_Pr);
1745 tempch &= 0x7f;
1746 inXGIIDXREG(XGIPART4, 0x03, temp);
1747 temp ^= 0x0e;
1748 temp &= tempch;
1749 return temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001750}
1751
Prashant P. Shahb654f872010-09-06 17:34:26 +05301752void XGI_Sense30x(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001753{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301754 u8 backupP4_0d;
1755 u8 testsvhs_tempbl, testsvhs_tempbh;
1756 u8 testsvhs_tempcl, testsvhs_tempch;
1757 u8 testcvbs_tempbl, testcvbs_tempbh;
1758 u8 testcvbs_tempcl, testcvbs_tempch;
1759 u8 testvga2_tempbl, testvga2_tempbh;
1760 u8 testvga2_tempcl, testvga2_tempch;
1761 int myflag, result;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001762
Prashant P. Shahb654f872010-09-06 17:34:26 +05301763 inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
1764 outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001765
Prashant P. Shahb654f872010-09-06 17:34:26 +05301766 testvga2_tempbh = 0x00;
1767 testvga2_tempbl = 0xd1;
1768 testsvhs_tempbh = 0x00;
1769 testsvhs_tempbl = 0xb9;
1770 testcvbs_tempbh = 0x00;
1771 testcvbs_tempbl = 0xb3;
1772 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
1773 != VB_CHIP_302)) {
1774 testvga2_tempbh = 0x01;
1775 testvga2_tempbl = 0x90;
1776 testsvhs_tempbh = 0x01;
1777 testsvhs_tempbl = 0x6b;
1778 testcvbs_tempbh = 0x01;
1779 testcvbs_tempbl = 0x74;
1780 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
1781 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
1782 testvga2_tempbh = 0x00;
1783 testvga2_tempbl = 0x00;
1784 testsvhs_tempbh = 0x02;
1785 testsvhs_tempbl = 0x00;
1786 testcvbs_tempbh = 0x01;
1787 testcvbs_tempbl = 0x00;
1788 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001789 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301790 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
1791 != VB_CHIP_302LV) {
1792 inXGIIDXREG(XGIPART4, 0x01, myflag);
1793 if (myflag & 0x04) {
1794 testvga2_tempbh = 0x00;
1795 testvga2_tempbl = 0xfd;
1796 testsvhs_tempbh = 0x00;
1797 testsvhs_tempbl = 0xdd;
1798 testcvbs_tempbh = 0x00;
1799 testcvbs_tempbl = 0xee;
1800 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001801 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301802 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
1803 == VB_CHIP_302LV)) {
1804 testvga2_tempbh = 0x00;
1805 testvga2_tempbl = 0x00;
1806 testvga2_tempch = 0x00;
1807 testvga2_tempcl = 0x00;
1808 testsvhs_tempch = 0x04;
1809 testsvhs_tempcl = 0x08;
1810 testcvbs_tempch = 0x08;
1811 testcvbs_tempcl = 0x08;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001812 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301813 testvga2_tempch = 0x0e;
1814 testvga2_tempcl = 0x08;
1815 testsvhs_tempch = 0x06;
1816 testsvhs_tempcl = 0x04;
1817 testcvbs_tempch = 0x08;
1818 testcvbs_tempcl = 0x04;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001819 }
1820
Prashant P. Shahb654f872010-09-06 17:34:26 +05301821 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
1822 || testvga2_tempbl) {
1823 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
1824 testvga2_tempcl, testvga2_tempch);
1825 if (result) {
1826 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
1827 orXGIIDXREG(XGICR, 0x32, 0x10);
1828 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001829 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001830
Prashant P. Shahb654f872010-09-06 17:34:26 +05301831 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
1832 testsvhs_tempch);
1833 if (result) {
1834 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
1835 /* TW: So we can be sure that there IS a SVHS output */
1836 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1837 orXGIIDXREG(XGICR, 0x32, 0x02);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001838 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001839
Prashant P. Shahb654f872010-09-06 17:34:26 +05301840 if (!result) {
1841 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
1842 testcvbs_tempcl, testcvbs_tempch);
1843 if (result) {
1844 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
1845 /* TW: So we can be sure that there IS a CVBS output */
1846 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1847 orXGIIDXREG(XGICR, 0x32, 0x01);
1848 }
1849 }
1850 XGIDoSense(0, 0, 0, 0);
1851
1852 outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001853}
1854
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001855/* --------------------- SetMode routines ------------------------- */
1856
1857static void XGIfb_pre_setmode(void)
1858{
1859 u8 cr30 = 0, cr31 = 0;
1860
1861 inXGIIDXREG(XGICR, 0x31, cr31);
1862 cr31 &= ~0x60;
1863
1864 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301865 case DISPTYPE_CRT2:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001866 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1867 cr31 |= XGI_DRIVER_MODE;
1868 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301869 case DISPTYPE_LCD:
1870 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001871 cr31 |= XGI_DRIVER_MODE;
1872 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301873 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001874 if (xgi_video_info.TV_type == TVMODE_HIVISION)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301875 cr30 = (XGI_VB_OUTPUT_HIVISION
1876 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001877 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301878 cr30 = (XGI_VB_OUTPUT_SVIDEO
1879 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001880 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301881 cr30 = (XGI_VB_OUTPUT_COMPOSITE
1882 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001883 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301884 cr30 = (XGI_VB_OUTPUT_SCART
1885 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001886 cr31 |= XGI_DRIVER_MODE;
1887
Prashant P. Shahb654f872010-09-06 17:34:26 +05301888 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001889 cr31 |= 0x01;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301890 else
1891 cr31 &= ~0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001892 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301893 default: /* disable CRT2 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001894 cr30 = 0x00;
1895 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
1896 }
1897
1898 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
1899 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301900 outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001901}
1902
1903static void XGIfb_post_setmode(void)
1904{
1905 u8 reg;
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001906 unsigned char doit = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301907 /*
1908 outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1909 outXGIIDXREG(XGICR, 0x13, 0x00);
1910 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
1911 *test*
1912 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001913 if (xgi_video_info.video_bpp == 8) {
1914 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301915 if ((xgi_video_info.hasVB == HASVB_LVDS)
1916 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
Bill Pembertondda08c52010-06-17 13:10:42 -04001917 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001918 }
1919 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301920 if (xgi_video_info.disp_state & DISPTYPE_LCD)
Bill Pembertondda08c52010-06-17 13:10:42 -04001921 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001922 }
1923
1924 /* TW: We can't switch off CRT1 if bridge is in slave mode */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301925 if (xgi_video_info.hasVB != HASVB_NONE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001926 inXGIIDXREG(XGIPART1, 0x00, reg);
1927
Bill Pembertondda08c52010-06-17 13:10:42 -04001928 if ((reg & 0x50) == 0x10)
1929 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001930
Prashant P. Shahb654f872010-09-06 17:34:26 +05301931 } else {
Bill Pembertondda08c52010-06-17 13:10:42 -04001932 XGIfb_crt1off = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301933 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001934
1935 inXGIIDXREG(XGICR, 0x17, reg);
Bill Pembertondda08c52010-06-17 13:10:42 -04001936 if ((XGIfb_crt1off) && (doit))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001937 reg &= ~0x80;
1938 else
1939 reg |= 0x80;
1940 outXGIIDXREG(XGICR, 0x17, reg);
1941
Prashant P. Shahb654f872010-09-06 17:34:26 +05301942 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001943
Prashant P. Shahb654f872010-09-06 17:34:26 +05301944 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1945 == HASVB_301)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001946
Prashant P. Shahb654f872010-09-06 17:34:26 +05301947 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001948
Prashant P. Shahb654f872010-09-06 17:34:26 +05301949 if (reg < 0xB0) { /* Set filter for XGI301 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001950
Prashant P. Shahb654f872010-09-06 17:34:26 +05301951 switch (xgi_video_info.video_width) {
1952 case 320:
1953 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
1954 break;
1955 case 640:
1956 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
1957 break;
1958 case 720:
1959 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
1960 break;
1961 case 800:
1962 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
1963 break;
1964 default:
1965 filter = -1;
1966 break;
1967 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001968
Prashant P. Shahb654f872010-09-06 17:34:26 +05301969 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001970
Prashant P. Shahb654f872010-09-06 17:34:26 +05301971 if (xgi_video_info.TV_type == TVMODE_NTSC) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001972
Prashant P. Shahb654f872010-09-06 17:34:26 +05301973 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001974
Prashant P. Shahb654f872010-09-06 17:34:26 +05301975 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001976
Prashant P. Shahb654f872010-09-06 17:34:26 +05301977 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001978
Prashant P. Shahb654f872010-09-06 17:34:26 +05301979 } else if (xgi_video_info.TV_plug
1980 == TVPLUG_COMPOSITE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001981
Prashant P. Shahb654f872010-09-06 17:34:26 +05301982 orXGIIDXREG(XGIPART2, 0x30, 0x20);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001983
Prashant P. Shahb654f872010-09-06 17:34:26 +05301984 switch (xgi_video_info.video_width) {
1985 case 640:
1986 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
1987 outXGIIDXREG(XGIPART2, 0x36, 0x04);
1988 outXGIIDXREG(XGIPART2, 0x37, 0x25);
1989 outXGIIDXREG(XGIPART2, 0x38, 0x18);
1990 break;
1991 case 720:
1992 outXGIIDXREG(XGIPART2, 0x35, 0xEE);
1993 outXGIIDXREG(XGIPART2, 0x36, 0x0C);
1994 outXGIIDXREG(XGIPART2, 0x37, 0x22);
1995 outXGIIDXREG(XGIPART2, 0x38, 0x08);
1996 break;
1997 case 800:
1998 outXGIIDXREG(XGIPART2, 0x35, 0xEB);
1999 outXGIIDXREG(XGIPART2, 0x36, 0x15);
2000 outXGIIDXREG(XGIPART2, 0x37, 0x25);
2001 outXGIIDXREG(XGIPART2, 0x38, 0xF6);
2002 break;
2003 }
2004 }
2005
2006 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2007
2008 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2009
2010 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2011
2012 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2013
2014 } else if (xgi_video_info.TV_plug
2015 == TVPLUG_COMPOSITE) {
2016
2017 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2018
2019 switch (xgi_video_info.video_width) {
2020 case 640:
2021 outXGIIDXREG(XGIPART2, 0x35, 0xF1);
2022 outXGIIDXREG(XGIPART2, 0x36, 0xF7);
2023 outXGIIDXREG(XGIPART2, 0x37, 0x1F);
2024 outXGIIDXREG(XGIPART2, 0x38, 0x32);
2025 break;
2026 case 720:
2027 outXGIIDXREG(XGIPART2, 0x35, 0xF3);
2028 outXGIIDXREG(XGIPART2, 0x36, 0x00);
2029 outXGIIDXREG(XGIPART2, 0x37, 0x1D);
2030 outXGIIDXREG(XGIPART2, 0x38, 0x20);
2031 break;
2032 case 800:
2033 outXGIIDXREG(XGIPART2, 0x35, 0xFC);
2034 outXGIIDXREG(XGIPART2, 0x36, 0xFB);
2035 outXGIIDXREG(XGIPART2, 0x37, 0x14);
2036 outXGIIDXREG(XGIPART2, 0x38, 0x2A);
2037 break;
2038 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002039 }
2040 }
2041
Prashant P. Shahb654f872010-09-06 17:34:26 +05302042 if ((filter >= 0) && (filter <= 7)) {
2043 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2044 XGI_TV_filter[filter_tb].filter[filter][0],
2045 XGI_TV_filter[filter_tb].filter[filter][1],
2046 XGI_TV_filter[filter_tb].filter[filter][2],
2047 XGI_TV_filter[filter_tb].filter[filter][3]
2048 );
2049 outXGIIDXREG(
2050 XGIPART2,
2051 0x35,
2052 (XGI_TV_filter[filter_tb].filter[filter][0]));
2053 outXGIIDXREG(
2054 XGIPART2,
2055 0x36,
2056 (XGI_TV_filter[filter_tb].filter[filter][1]));
2057 outXGIIDXREG(
2058 XGIPART2,
2059 0x37,
2060 (XGI_TV_filter[filter_tb].filter[filter][2]));
2061 outXGIIDXREG(
2062 XGIPART2,
2063 0x38,
2064 (XGI_TV_filter[filter_tb].filter[filter][3]));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002065 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002066
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002067 }
2068
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002069 }
2070
2071}
2072
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002073XGIINITSTATIC int __init XGIfb_setup(char *options)
2074{
2075 char *this_opt;
2076
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002077 xgi_video_info.refresh_rate = 0;
2078
Prashant P. Shahb654f872010-09-06 17:34:26 +05302079 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002080
2081 if (!options || !*options)
2082 return 0;
2083
Prashant P. Shahb654f872010-09-06 17:34:26 +05302084 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002085
Prashant P. Shahb654f872010-09-06 17:34:26 +05302086 if (!*this_opt)
2087 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002088
2089 if (!strncmp(this_opt, "mode:", 5)) {
2090 XGIfb_search_mode(this_opt + 5);
2091 } else if (!strncmp(this_opt, "vesa:", 5)) {
2092 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2093 } else if (!strncmp(this_opt, "mode:", 5)) {
2094 XGIfb_search_mode(this_opt + 5);
2095 } else if (!strncmp(this_opt, "vesa:", 5)) {
2096 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2097 } else if (!strncmp(this_opt, "vrate:", 6)) {
2098 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2099 } else if (!strncmp(this_opt, "rate:", 5)) {
2100 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2101 } else if (!strncmp(this_opt, "off", 3)) {
2102 XGIfb_off = 1;
2103 } else if (!strncmp(this_opt, "crt1off", 7)) {
2104 XGIfb_crt1off = 1;
2105 } else if (!strncmp(this_opt, "filter:", 7)) {
2106 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2107 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2108 XGIfb_search_crt2type(this_opt + 14);
2109 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2110 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302111 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002112 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302113 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2114 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302115 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002116 enable_dstn = 1;
2117 /* TW: DSTN overrules forcecrt2type */
2118 XGIfb_crt2type = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002119 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302120 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2121 if (XGIfb_pdc & ~0x3c) {
2122 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2123 XGIfb_pdc = 0;
2124 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002125 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302126 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002127 } else if (!strncmp(this_opt, "userom:", 7)) {
2128 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302129 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2130 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002131 } else {
2132 XGIfb_search_mode(this_opt);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302133 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002134 }
2135
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002136 /* TW: Panning only with acceleration */
Javier Martinez Canillas0089bf12011-02-21 18:16:43 +01002137 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002138
2139 }
2140 printk("\nxgifb: outa xgifb_setup 3450");
2141 return 0;
2142}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002143
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002144static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002145{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002146 void __iomem *rom_address;
2147 unsigned char *rom_copy;
2148 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002149
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002150 rom_address = pci_map_rom(dev, &rom_size);
2151 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002152 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002153
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002154 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2155 if (rom_copy == NULL)
2156 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002157
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002158 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2159 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002160
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002161done:
2162 pci_unmap_rom(dev, rom_address);
2163 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002164}
2165
Randy Dunlap89229672010-08-10 08:46:44 -07002166static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302167 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002168{
2169 u16 reg16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302170 u8 reg, reg1;
2171 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002172 int ret;
2173
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002174 if (XGIfb_off)
2175 return -ENXIO;
2176
2177 XGIfb_registered = 0;
2178
Bill Pembertone4147ab2010-06-17 13:10:50 -04002179 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302180 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2181 if (!fb_info)
2182 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002183
Prashant P. Shahb654f872010-09-06 17:34:26 +05302184 xgi_video_info.chip_id = pdev->device;
2185 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
2186 pci_read_config_word(pdev, PCI_COMMAND, &reg16);
2187 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
2188 XGIvga_enabled = reg16 & 0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002189
Prashant P. Shahb654f872010-09-06 17:34:26 +05302190 xgi_video_info.pcibus = pdev->bus->number;
2191 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2192 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2193 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2194 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002195
Prashant P. Shahb654f872010-09-06 17:34:26 +05302196 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2197 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002198 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302199 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2200 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2201 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2202 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2203 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002204
Aaro Koskinenbb292232011-02-17 23:29:11 +02002205 if (pci_enable_device(pdev)) {
2206 ret = -EIO;
2207 goto error;
2208 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002209
Prashant P. Shahb654f872010-09-06 17:34:26 +05302210 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002211
Prashant P. Shahb654f872010-09-06 17:34:26 +05302212 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2213 inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002214
Prashant P. Shahb654f872010-09-06 17:34:26 +05302215 if (reg1 != 0xa1) { /*I/O error */
2216 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002217 ret = -EIO;
2218 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302219 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002220
2221 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302222 case PCI_DEVICE_ID_XG_20:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002223 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
2224 inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
2225 if (CR48&GPIOG_READ)
2226 xgi_video_info.chip = XG21;
2227 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302228 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002229 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2230 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302231 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002232 xgi_video_info.chip = XG40;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002233 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2234 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302235 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002236 xgi_video_info.chip = XG41;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002237 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2238 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302239 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002240 xgi_video_info.chip = XG42;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002241 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2242 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302243 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002244 xgi_video_info.chip = XG27;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002245 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2246 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302247 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002248 ret = -ENODEV;
2249 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002250 }
2251
Prashant P. Shahb654f872010-09-06 17:34:26 +05302252 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2253 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002254
Prashant P. Shahb654f872010-09-06 17:34:26 +05302255 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002256 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302257 if (XGIhw_ext.pjVirtualRomBase)
2258 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002259 else
2260 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302261 } else {
2262 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002263 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302264 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302265 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002266
Prashant P. Shahb654f872010-09-06 17:34:26 +05302267 if (!XGIvga_enabled) {
2268 /* Mapping Max FB Size for 315 Init */
2269 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
2270 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002271#ifdef LINUXBIOS
Prashant P. Shahb654f872010-09-06 17:34:26 +05302272 printk("XGIfb: XGIInit() ...");
2273 /* XGIInitNewt for LINUXBIOS only */
2274 if (XGIInitNew(&XGIhw_ext))
2275 printk("OK\n");
2276 else
2277 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002278#endif
2279
Prashant P. Shahb654f872010-09-06 17:34:26 +05302280 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002281
Prashant P. Shahb654f872010-09-06 17:34:26 +05302282 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002283 }
2284#ifdef LINUXBIOS
Prashant P. Shahb654f872010-09-06 17:34:26 +05302285 else {
2286 XGIhw_ext.pjVideoMemoryAddress = ioremap(xgi_video_info.video_base, 0x10000000);
2287 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2288
2289 outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
2290
2291 /* yilin Because no VBIOS DRAM Sizing, Dram size will error. */
2292 /* Set SR13 ,14 temporarily for UDtech */
2293 outXGIIDXREG(XGISR, 0x13, 0x45);
2294 outXGIIDXREG(XGISR, 0x14, 0x51);
2295
2296 }
2297 }
2298#endif
2299 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302300 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002301 ret = -ENODEV;
2302 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302303 }
2304
2305 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2306 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2307 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2308 /* Enable 2D accelerator engine */
2309 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2310 }
2311
2312 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2313
2314 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
2315 printk("unable request memory size %x", xgi_video_info.video_size);
2316 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2317 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002318 ret = -ENODEV;
2319 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302320 }
2321
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002322 if (!request_mem_region(xgi_video_info.mmio_base,
2323 xgi_video_info.mmio_size,
2324 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302325 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002326 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002327 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302328 }
2329
2330 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2331 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002332 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2333 xgi_video_info.mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302334
2335 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2336 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
2337
2338 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002339 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2340 xgi_video_info.mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302341 printk("XGIfb: XGIInitNew() ...");
2342 if (XGIInitNew(&XGIhw_ext))
2343 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002344 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002345 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002346
Prashant P. Shahb654f872010-09-06 17:34:26 +05302347 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002348
Prashant P. Shahb654f872010-09-06 17:34:26 +05302349 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002350 xgi_video_info.hasVB = HASVB_NONE;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302351 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
2352 xgi_video_info.hasVB = HASVB_NONE;
2353 } else if (xgi_video_info.chip == XG21) {
2354 inXGIIDXREG(XGICR, 0x38, CR38);
2355 if ((CR38&0xE0) == 0xC0) {
2356 xgi_video_info.disp_state = DISPTYPE_LCD;
2357 if (!XGIfb_GetXG21LVDSData()) {
2358 int m;
2359 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2360 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2361 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
2362 XGINew_SetReg1(XGI_Pr.P3d4, 0x36, m);
2363 }
2364 }
2365 }
2366 } else if ((CR38&0xE0) == 0x60) {
2367 xgi_video_info.hasVB = HASVB_CHRONTEL;
2368 } else {
2369 xgi_video_info.hasVB = HASVB_NONE;
2370 }
2371 } else {
2372 XGIfb_get_VB_type();
2373 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002374
Prashant P. Shahb654f872010-09-06 17:34:26 +05302375 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002376
Prashant P. Shahb654f872010-09-06 17:34:26 +05302377 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002378
2379 switch (xgi_video_info.hasVB) {
2380 case HASVB_301:
Prashant P. Shahb654f872010-09-06 17:34:26 +05302381 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002382 if (reg >= 0xE0) {
2383 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302384 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2385 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002386 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302387 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2388 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002389 /* else if (reg >= 0xB0) {
2390 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302391 inXGIIDXREG(XGIPART4, 0x23, reg1);
2392 printk("XGIfb: XGI301B bridge detected\n");
2393 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002394 else {
2395 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2396 printk("XGIfb: XGI301 bridge detected\n");
2397 }
2398 break;
2399 case HASVB_302:
Prashant P. Shahb654f872010-09-06 17:34:26 +05302400 inXGIIDXREG(XGIPART4, 0x01, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002401 if (reg >= 0xE0) {
2402 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302403 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2404 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002405 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302406 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2407 } else if (reg >= 0xB0) {
2408 inXGIIDXREG(XGIPART4, 0x23, reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002409
Prashant P. Shahb654f872010-09-06 17:34:26 +05302410 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002411
2412 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302413 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002414 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2415 }
2416 break;
2417 case HASVB_LVDS:
2418 XGIhw_ext.ulExternalChip = 0x1;
2419 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2420 break;
2421 case HASVB_TRUMPION:
2422 XGIhw_ext.ulExternalChip = 0x2;
2423 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2424 break;
2425 case HASVB_CHRONTEL:
2426 XGIhw_ext.ulExternalChip = 0x4;
2427 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2428 break;
2429 case HASVB_LVDS_CHRONTEL:
2430 XGIhw_ext.ulExternalChip = 0x5;
2431 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2432 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302433 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002434 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2435 break;
2436 }
2437
Prashant P. Shahb654f872010-09-06 17:34:26 +05302438 if (xgi_video_info.hasVB != HASVB_NONE)
2439 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002440
2441 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2442 if (XGIfb_crt1off)
2443 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2444 else
2445 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
2446 } else {
2447 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
2448 }
2449
2450 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302451 if (!enable_dstn) {
2452 inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
2453 reg &= 0x0f;
2454 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002455
Prashant P. Shahb654f872010-09-06 17:34:26 +05302456 } else {
2457 /* TW: FSTN/DSTN */
2458 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2459 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002460 }
2461
2462 XGIfb_detectedpdc = 0;
2463
Prashant P. Shahb654f872010-09-06 17:34:26 +05302464 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002465#ifndef LINUXBIOS
2466
Prashant P. Shahb654f872010-09-06 17:34:26 +05302467 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002468
Prashant P. Shahb654f872010-09-06 17:34:26 +05302469 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2470 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2471 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2472 int tmp;
2473 inXGIIDXREG(XGICR, 0x34, tmp);
2474 if (tmp <= 0x13) {
2475 /* Currently on LCDA? (Some BIOSes leave CR38) */
2476 inXGIIDXREG(XGICR, 0x38, tmp);
2477 if ((tmp & 0x03) == 0x03) {
2478 /* XGI_Pr.XGI_UseLCDA = 1; */
2479 } else {
2480 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
2481 inXGIIDXREG(XGICR, 0x35, tmp);
2482 if (tmp & 0x01) {
2483 /* XGI_Pr.XGI_UseLCDA = 1; */
2484 } else {
2485 inXGIIDXREG(XGICR, 0x30, tmp);
2486 if (tmp & 0x20) {
2487 inXGIIDXREG(XGIPART1, 0x13, tmp);
2488 if (tmp & 0x04) {
2489 /* XGI_Pr.XGI_UseLCDA = 1; */
2490 }
2491 }
2492 }
2493 }
2494 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002495
Prashant P. Shahb654f872010-09-06 17:34:26 +05302496 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002497
2498#endif
2499
2500 if (xgifb_mode_idx >= 0)
2501 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2502
2503 if (xgifb_mode_idx < 0) {
2504 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302505 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002506 xgifb_mode_idx = DEFAULT_LCDMODE;
2507 if (xgi_video_info.chip == XG21)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302508 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002509 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302510 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002511 xgifb_mode_idx = DEFAULT_TVMODE;
2512 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302513 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002514 xgifb_mode_idx = DEFAULT_MODE;
2515 break;
2516 }
2517 }
2518
2519 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2520
Prashant P. Shahb654f872010-09-06 17:34:26 +05302521 if (xgi_video_info.refresh_rate == 0)
2522 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
2523 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
2524 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2525 xgi_video_info.refresh_rate = 60;
2526 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002527
2528 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2529 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
2530 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
2531 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2532 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302533 switch (xgi_video_info.video_bpp) {
2534 case 8:
2535 xgi_video_info.DstColor = 0x0000;
2536 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002537 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302538 break;
2539 case 16:
2540 xgi_video_info.DstColor = 0x8000;
2541 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002542 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302543 break;
2544 case 32:
2545 xgi_video_info.DstColor = 0xC000;
2546 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002547 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302548 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002549 default:
2550 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302551 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002552 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302553 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002554
2555 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302556 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
2557 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002558
2559 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
2560 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
2561 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2562
2563 XGIfb_bpp_to_var(&default_var);
2564
2565 default_var.pixclock = (u32) (1000000000 /
2566 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2567 XGIfb_mode_no, XGIfb_rate_idx));
2568
Prashant P. Shahb654f872010-09-06 17:34:26 +05302569 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2570 XGIfb_mode_no, XGIfb_rate_idx,
2571 &default_var.left_margin, &default_var.right_margin,
2572 &default_var.upper_margin, &default_var.lower_margin,
2573 &default_var.hsync_len, &default_var.vsync_len,
2574 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002575
Prashant P. Shahb654f872010-09-06 17:34:26 +05302576 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
2577 default_var.yres <<= 1;
2578 default_var.yres_virtual <<= 1;
2579 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
2580 default_var.pixclock >>= 1;
2581 default_var.yres >>= 1;
2582 default_var.yres_virtual >>= 1;
2583 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002584
Prashant P. Shahb654f872010-09-06 17:34:26 +05302585 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002586
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002587 fb_info->flags = FBINFO_FLAG_DEFAULT;
2588 fb_info->var = default_var;
2589 fb_info->fix = XGIfb_fix;
2590 fb_info->par = &xgi_video_info;
2591 fb_info->screen_base = xgi_video_info.video_vbase;
2592 fb_info->fbops = &XGIfb_ops;
2593 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2594 fb_info->pseudo_palette = pseudo_palette;
2595
2596 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2597
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002598#ifdef CONFIG_MTRR
2599 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
2600 (unsigned int) xgi_video_info.video_size,
2601 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302602 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002603 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002604#endif
2605
Aaro Koskinenbb292232011-02-17 23:29:11 +02002606 if (register_framebuffer(fb_info) < 0) {
2607 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002608 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002609 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002610
2611 XGIfb_registered = 1;
2612
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002613 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302614 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002615
2616 }
2617
2618 dumpVGAReg();
2619
2620 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002621
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002622error_1:
2623 iounmap(xgi_video_info.mmio_vbase);
2624 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002625 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002626error_0:
2627 release_mem_region(xgi_video_info.video_base,
2628 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002629error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002630 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002631 framebuffer_release(fb_info);
2632 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002633}
2634
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002635/*****************************************************/
2636/* PCI DEVICE HANDLING */
2637/*****************************************************/
2638
2639static void __devexit xgifb_remove(struct pci_dev *pdev)
2640{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302641 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002642 iounmap(xgi_video_info.mmio_vbase);
2643 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002644 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002645 release_mem_region(xgi_video_info.video_base,
2646 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002647 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302648 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002649 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02002650}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002651
2652static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302653 .name = "xgifb",
2654 .id_table = xgifb_pci_table,
2655 .probe = xgifb_probe,
2656 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002657};
2658
2659XGIINITSTATIC int __init xgifb_init(void)
2660{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002661 char *option = NULL;
2662
2663 if (fb_get_options("xgifb", &option))
2664 return -ENODEV;
2665 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04002666
Prashant P. Shahb654f872010-09-06 17:34:26 +05302667 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002668}
2669
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002670#ifndef MODULE
2671module_init(xgifb_init);
2672#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002673
2674/*****************************************************/
2675/* MODULE */
2676/*****************************************************/
2677
2678#ifdef MODULE
2679
Prashant P. Shahb654f872010-09-06 17:34:26 +05302680static char *mode = NULL;
2681static int vesa = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002682static unsigned int rate = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002683static unsigned int mem = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302684static char *forcecrt2type = NULL;
2685static int forcecrt1 = -1;
2686static int pdc = -1;
2687static int pdc1 = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302688static int noypan = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302689static int userom = -1;
2690static int useoem = -1;
2691static char *tvstandard = NULL;
2692static int nocrt2rate = 0;
2693static int scalelcd = -1;
2694static char *specialtiming = NULL;
2695static int lvdshl = -1;
2696static int tvxposoffset = 0, tvyposoffset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002697#if !defined(__i386__) && !defined(__x86_64__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302698static int resetcard = 0;
2699static int videoram = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002700#endif
2701
2702MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2703MODULE_LICENSE("GPL");
2704MODULE_AUTHOR("XGITECH , Others");
2705
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002706module_param(mem, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002707module_param(noypan, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002708module_param(userom, int, 0);
2709module_param(useoem, int, 0);
2710module_param(mode, charp, 0);
2711module_param(vesa, int, 0);
2712module_param(rate, int, 0);
2713module_param(forcecrt1, int, 0);
2714module_param(forcecrt2type, charp, 0);
2715module_param(scalelcd, int, 0);
2716module_param(pdc, int, 0);
2717module_param(pdc1, int, 0);
2718module_param(specialtiming, charp, 0);
2719module_param(lvdshl, int, 0);
2720module_param(tvstandard, charp, 0);
2721module_param(tvxposoffset, int, 0);
2722module_param(tvyposoffset, int, 0);
2723module_param(filter, int, 0);
2724module_param(nocrt2rate, int, 0);
2725#if !defined(__i386__) && !defined(__x86_64__)
2726module_param(resetcard, int, 0);
2727module_param(videoram, int, 0);
2728#endif
2729
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002730MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302731 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2732 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002733
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002734MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302735 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2736 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2737 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2738 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002739
2740MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302741 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2742 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002743
2744MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302745 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2746 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2747 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002748
2749MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302750 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2751 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2752 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002753
2754MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302755 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2756 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2757 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2758 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2759 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2760 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2761 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2762 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002763
2764MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302765 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2766 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2767 "show black bars around the image, TMDS panels will probably do the scaling\n"
2768 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002769
2770MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302771 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2772 "should detect this correctly in most cases; however, sometimes this is not\n"
2773 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2774 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2775 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2776 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002777
2778MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302779 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2780 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2781 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2782 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002783
2784MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302785 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002786
2787MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302788 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002789
2790MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302791 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2792 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002793
2794MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302795 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2796 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002797
2798MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302799 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2800 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002801
2802MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302803 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2804 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002805
2806MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302807 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2808 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002809
Randy Dunlap89229672010-08-10 08:46:44 -07002810static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002811{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302812 printk("\nXGIfb_init_module");
2813 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002814 XGIfb_search_mode(mode);
2815 else if (vesa != -1)
2816 XGIfb_search_vesamode(vesa);
2817
Prashant P. Shahb654f872010-09-06 17:34:26 +05302818 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002819}
2820
2821static void __exit xgifb_remove_module(void)
2822{
2823 pci_unregister_driver(&xgifb_driver);
2824 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2825}
2826
2827module_init(xgifb_init_module);
2828module_exit(xgifb_remove_module);
2829
Prashant P. Shahb654f872010-09-06 17:34:26 +05302830#endif /* /MODULE */