blob: a6e9c60faf5acfa14950564cd8ba84e5297d8378 [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"
Aaro Koskinend542af52011-04-18 22:14:06 +030044#include "vb_init.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020045#include "vb_util.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030046#include "vb_setmode.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020047
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020048#define Index_CR_GPIO_Reg1 0x48
49#define Index_CR_GPIO_Reg2 0x49
50#define Index_CR_GPIO_Reg3 0x4a
51
52#define GPIOG_EN (1<<6)
53#define GPIOG_WRITE (1<<6)
54#define GPIOG_READ (1<<1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020055
Aaro Koskinen0f07d942011-02-17 23:29:13 +020056#define XGIFB_ROM_SIZE 65536
57
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020058/* -------------------- Macro definitions ---------------------------- */
59
60#undef XGIFBDEBUG
61
62#ifdef XGIFBDEBUG
63#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
64#else
65#define DPRINTK(fmt, args...)
66#endif
67
68#ifdef XGIFBDEBUG
69static void dumpVGAReg(void)
70{
Prashant P. Shahb654f872010-09-06 17:34:26 +053071 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020072
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030073 xgifb_reg_set(XGISR, 0x05, 0x86);
Prashant P. Shahb654f872010-09-06 17:34:26 +053074 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030075 xgifb_reg_set(XGISR, 0x08, 0x4f);
76 xgifb_reg_set(XGISR, 0x0f, 0x20);
77 xgifb_reg_set(XGISR, 0x11, 0x4f);
78 xgifb_reg_set(XGISR, 0x13, 0x45);
79 xgifb_reg_set(XGISR, 0x14, 0x51);
80 xgifb_reg_set(XGISR, 0x1e, 0x41);
81 xgifb_reg_set(XGISR, 0x1f, 0x0);
82 xgifb_reg_set(XGISR, 0x20, 0xa1);
83 xgifb_reg_set(XGISR, 0x22, 0xfb);
84 xgifb_reg_set(XGISR, 0x26, 0x22);
85 xgifb_reg_set(XGISR, 0x3e, 0x07);
Prashant P. Shahb654f872010-09-06 17:34:26 +053086 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020087
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030088 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
89 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
90 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
91 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020092
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030093 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020094
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030095 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
96 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020097
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030098 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
99 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530100 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300101 xgifb_reg_set(XGICR, 0x99, 0x1);
102 xgifb_reg_set(XGICR, 0x41, 0x40);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530103 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200104
Prashant P. Shahb654f872010-09-06 17:34:26 +0530105 for (i = 0; i < 0x4f; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300106 reg = xgifb_reg_get(XGISR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530107 printk("\no 3c4 %x", i);
108 printk("\ni 3c5 => %x", reg);
109 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200110
Prashant P. Shahb654f872010-09-06 17:34:26 +0530111 for (i = 0; i < 0xF0; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300112 reg = xgifb_reg_get(XGICR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530113 printk("\no 3d4 %x", i);
114 printk("\ni 3d5 => %x", reg);
115 }
116 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300117 xgifb_reg_set(XGIPART1,0x2F,1);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530118 for (i=1; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300119 reg = xgifb_reg_get(XGIPART1, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530120 printk("\no d004 %x", i);
121 printk("\ni d005 => %x", reg);
122 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200123
Prashant P. Shahb654f872010-09-06 17:34:26 +0530124 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300125 reg = xgifb_reg_get(XGIPART2, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530126 printk("\no d010 %x", i);
127 printk("\ni d011 => %x", reg);
128 }
129 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300130 reg = xgifb_reg_get(XGIPART3, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530131 printk("\no d012 %x",i);
132 printk("\ni d013 => %x",reg);
133 }
134 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300135 reg = xgifb_reg_get(XGIPART4, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530136 printk("\no d014 %x",i);
137 printk("\ni d015 => %x",reg);
138 }
139 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200140}
141#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530142static inline void dumpVGAReg(void)
143{
144}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200145#endif
146
147/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530148struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200149
150#if 1
151#define DEBUGPRN(x)
152#else
153#define DEBUGPRN(x) printk(KERN_INFO x "\n");
154#endif
155
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200156/* --------------- Hardware Access Routines -------------------------- */
157
Prashant P. Shahb654f872010-09-06 17:34:26 +0530158static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
159 struct xgi_hw_device_info *HwDeviceExtension,
160 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200161{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530162 unsigned short ModeNo = modeno;
163 unsigned short ModeIdIndex = 0, ClockIndex = 0;
164 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200165
Prashant P. Shahb654f872010-09-06 17:34:26 +0530166 /* unsigned long temp = 0; */
167 int Clock;
168 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
169 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200170
Prashant P. Shahb654f872010-09-06 17:34:26 +0530171 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
172 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200173
Prashant P. Shahb654f872010-09-06 17:34:26 +0530174 /*
175 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
176 if (!temp) {
177 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
178 return 65000;
179 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200180
Prashant P. Shahb654f872010-09-06 17:34:26 +0530181 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
182 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200183
Prashant P. Shahb654f872010-09-06 17:34:26 +0530184 */
185 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200186
Prashant P. Shahb654f872010-09-06 17:34:26 +0530187 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
188
189 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200190}
191
Prashant P. Shahb654f872010-09-06 17:34:26 +0530192static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
193 struct xgi_hw_device_info *HwDeviceExtension,
194 unsigned char modeno, unsigned char rateindex,
195 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
196 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
197 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200198{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530199 unsigned short ModeNo = modeno;
200 unsigned short ModeIdIndex = 0, index = 0;
201 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200202
Prashant P. Shahb654f872010-09-06 17:34:26 +0530203 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
204 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
205 unsigned char sr_data, cr_data, cr_data2;
206 unsigned long cr_data3;
207 int A, B, C, D, E, F, temp, j;
208 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
209 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
210 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
211 ModeIdIndex, XGI_Pr);
212 /*
213 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
214 if (!temp)
215 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200216
Prashant P. Shahb654f872010-09-06 17:34:26 +0530217 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
218 RefreshRateTableIndex += (rateindex - 1);
219 */
220 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200221
Prashant P. Shahb654f872010-09-06 17:34:26 +0530222 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200223
Prashant P. Shahb654f872010-09-06 17:34:26 +0530224 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200225
Prashant P. Shahb654f872010-09-06 17:34:26 +0530226 /* Horizontal total */
227 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
228 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200229
Prashant P. Shahb654f872010-09-06 17:34:26 +0530230 /*
231 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200232
Prashant P. Shahb654f872010-09-06 17:34:26 +0530233 Horizontal display enable end
234 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
235 */
236 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
237 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200238
Prashant P. Shahb654f872010-09-06 17:34:26 +0530239 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200240
Prashant P. Shahb654f872010-09-06 17:34:26 +0530241 /* Horizontal retrace (=sync) start */
242 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
243 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200244
Prashant P. Shahb654f872010-09-06 17:34:26 +0530245 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200246
Prashant P. Shahb654f872010-09-06 17:34:26 +0530247 /* Horizontal blank start */
248 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200249
Prashant P. Shahb654f872010-09-06 17:34:26 +0530250 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200251
Prashant P. Shahb654f872010-09-06 17:34:26 +0530252 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200253
Prashant P. Shahb654f872010-09-06 17:34:26 +0530254 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200255
Prashant P. Shahb654f872010-09-06 17:34:26 +0530256 /* Horizontal blank end */
257 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
258 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200259
Prashant P. Shahb654f872010-09-06 17:34:26 +0530260 /* Horizontal retrace (=sync) end */
261 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200262
Prashant P. Shahb654f872010-09-06 17:34:26 +0530263 temp = HBE - ((E - 1) & 255);
264 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200265
Prashant P. Shahb654f872010-09-06 17:34:26 +0530266 temp = HRE - ((E + F + 3) & 63);
267 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200268
Prashant P. Shahb654f872010-09-06 17:34:26 +0530269 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200270
Prashant P. Shahb654f872010-09-06 17:34:26 +0530271 *left_margin = D * 8;
272 *right_margin = F * 8;
273 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200274
Prashant P. Shahb654f872010-09-06 17:34:26 +0530275 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200276
Prashant P. Shahb654f872010-09-06 17:34:26 +0530277 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200278
Prashant P. Shahb654f872010-09-06 17:34:26 +0530279 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200280
Prashant P. Shahb654f872010-09-06 17:34:26 +0530281 /* Vertical total */
282 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
283 | ((unsigned short) (cr_data2 & 0x20) << 4)
284 | ((unsigned short) (sr_data & 0x01) << 10);
285 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200286
Prashant P. Shahb654f872010-09-06 17:34:26 +0530287 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200288
Prashant P. Shahb654f872010-09-06 17:34:26 +0530289 /* Vertical display enable end */
290 /*
291 VDE = (cr_data & 0xff) |
292 ((unsigned short) (cr_data2 & 0x02) << 7) |
293 ((unsigned short) (cr_data2 & 0x40) << 3) |
294 ((unsigned short) (sr_data & 0x02) << 9);
295 */
296 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
297 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200298
Prashant P. Shahb654f872010-09-06 17:34:26 +0530299 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200300
Prashant P. Shahb654f872010-09-06 17:34:26 +0530301 /* Vertical retrace (=sync) start */
302 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
303 | ((unsigned short) (cr_data2 & 0x80) << 2)
304 | ((unsigned short) (sr_data & 0x08) << 7);
305 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200306
Prashant P. Shahb654f872010-09-06 17:34:26 +0530307 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200308
Prashant P. Shahb654f872010-09-06 17:34:26 +0530309 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200310
Prashant P. Shahb654f872010-09-06 17:34:26 +0530311 /* Vertical blank start */
312 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
313 | ((unsigned short) (cr_data3 & 0x20) << 4)
314 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200315
Prashant P. Shahb654f872010-09-06 17:34:26 +0530316 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200317
Prashant P. Shahb654f872010-09-06 17:34:26 +0530318 /* Vertical blank end */
319 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
320 temp = VBE - ((E - 1) & 511);
321 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200322
Prashant P. Shahb654f872010-09-06 17:34:26 +0530323 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200324
Prashant P. Shahb654f872010-09-06 17:34:26 +0530325 /* Vertical retrace (=sync) end */
326 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
327 temp = VRE - ((E + F - 1) & 31);
328 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200329
Prashant P. Shahb654f872010-09-06 17:34:26 +0530330 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200331
Prashant P. Shahb654f872010-09-06 17:34:26 +0530332 *upper_margin = D;
333 *lower_margin = F;
334 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200335
Prashant P. Shahb654f872010-09-06 17:34:26 +0530336 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
337 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
338 else
339 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200340
Prashant P. Shahb654f872010-09-06 17:34:26 +0530341 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
342 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
343 else
344 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200345
Prashant P. Shahb654f872010-09-06 17:34:26 +0530346 *vmode = FB_VMODE_NONINTERLACED;
347 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
348 *vmode = FB_VMODE_INTERLACED;
349 else {
350 j = 0;
351 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
352 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
353 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
354 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
355 & DoubleScanMode) {
356 *vmode = FB_VMODE_DOUBLE;
357 }
358 break;
359 }
360 j++;
361 }
362 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200363
Prashant P. Shahb654f872010-09-06 17:34:26 +0530364 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200365}
366
Randy Dunlap89229672010-08-10 08:46:44 -0700367static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200368{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530369 XGI_Pr->RelIO = BaseAddr;
370 XGI_Pr->P3c4 = BaseAddr + 0x14;
371 XGI_Pr->P3d4 = BaseAddr + 0x24;
372 XGI_Pr->P3c0 = BaseAddr + 0x10;
373 XGI_Pr->P3ce = BaseAddr + 0x1e;
374 XGI_Pr->P3c2 = BaseAddr + 0x12;
375 XGI_Pr->P3ca = BaseAddr + 0x1a;
376 XGI_Pr->P3c6 = BaseAddr + 0x16;
377 XGI_Pr->P3c7 = BaseAddr + 0x17;
378 XGI_Pr->P3c8 = BaseAddr + 0x18;
379 XGI_Pr->P3c9 = BaseAddr + 0x19;
380 XGI_Pr->P3da = BaseAddr + 0x2A;
381 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
382 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
383 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
384 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
385 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200386
387}
388
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200389/* ------------ Interface for init & mode switching code ------------- */
390
Prashant P. Shahb654f872010-09-06 17:34:26 +0530391unsigned char XGIfb_query_VGA_config_space(
392 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
393 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200394{
395 static struct pci_dev *pdev = NULL;
396 static unsigned char init = 0, valid_pdev = 0;
397
398 if (!set)
399 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
400 else
401 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
402
403 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400404 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530405 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
406 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200407 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400408 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200409 pci_dev_put(pdev);
410 }
411 }
412
413 if (!valid_pdev) {
414 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
415 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400416 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200417 }
418
419 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530420 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200421 else
422 pci_write_config_dword(pdev, offset, (u32)(*value));
423
Bill Pembertondda08c52010-06-17 13:10:42 -0400424 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200425}
426
Prashant P. Shahb654f872010-09-06 17:34:26 +0530427/*
428unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200429 unsigned long offset, unsigned long set, unsigned long *value)
430{
431 static struct pci_dev *pdev = NULL;
432 static unsigned char init = 0, valid_pdev = 0;
433 u16 nbridge_id = 0;
434
435 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400436 init = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200437 switch (xgi_video_info.chip) {
438 case XGI_540:
439 nbridge_id = PCI_DEVICE_ID_XG_540;
440 break;
441 case XGI_630:
442 nbridge_id = PCI_DEVICE_ID_XG_630;
443 break;
444 case XGI_730:
445 nbridge_id = PCI_DEVICE_ID_XG_730;
446 break;
447 case XGI_550:
448 nbridge_id = PCI_DEVICE_ID_XG_550;
449 break;
450 case XGI_650:
451 nbridge_id = PCI_DEVICE_ID_XG_650;
452 break;
453 case XGI_740:
454 nbridge_id = PCI_DEVICE_ID_XG_740;
455 break;
456 default:
457 nbridge_id = 0;
458 break;
459 }
460
Atul Sowanifc2347e2010-11-03 18:40:56 +0530461 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
462 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400463 valid_pdev = 1;
Atul Sowanifc2347e2010-11-03 18:40:56 +0530464 pci_dev_put(pdev);
465 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200466 }
467
468 if (!valid_pdev) {
469 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530470 nbridge_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400471 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200472 }
473
474 if (set == 0)
475 pci_read_config_dword(pdev, offset, (u32 *)value);
476 else
477 pci_write_config_dword(pdev, offset, (u32)(*value));
478
Bill Pembertondda08c52010-06-17 13:10:42 -0400479 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200480}
481*/
482/* ------------------ Internal helper routines ----------------- */
483
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300484int XGIfb_GetXG21DefaultLVDSModeIdx(void)
485{
486
487 int found_mode = 0;
488 int XGIfb_mode_idx = 0;
489
490 found_mode = 0;
491 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
492 && (XGIbios_mode[XGIfb_mode_idx].xres
493 <= XGI21_LCDCapList[0].LVDSHDE)) {
494 if ((XGIbios_mode[XGIfb_mode_idx].xres
495 == XGI21_LCDCapList[0].LVDSHDE)
496 && (XGIbios_mode[XGIfb_mode_idx].yres
497 == XGI21_LCDCapList[0].LVDSVDE)
498 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
499 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
500 found_mode = 1;
501 break;
502 }
503 XGIfb_mode_idx++;
504 }
505 if (!found_mode)
506 XGIfb_mode_idx = 0;
507
508 return XGIfb_mode_idx;
509}
510
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200511static void XGIfb_search_mode(const char *name)
512{
513 int i = 0, j = 0, l;
514
Prashant P. Shahb654f872010-09-06 17:34:26 +0530515 if (name == NULL) {
516 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
517 xgifb_mode_idx = DEFAULT_MODE;
518 if ((xgi_video_info.chip == XG21)
519 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
520 == DISPTYPE_LCD)) {
521 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
522 }
523 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200524 }
525
Prashant P. Shahb654f872010-09-06 17:34:26 +0530526 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
527 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
528 xgifb_mode_idx = DEFAULT_MODE;
529 if ((xgi_video_info.chip == XG21)
530 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
531 == DISPTYPE_LCD)) {
532 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
533 }
534 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200535 }
536
Prashant P. Shahb654f872010-09-06 17:34:26 +0530537 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200538 l = min(strlen(name), strlen(XGIbios_mode[i].name));
539 if (!strncmp(name, XGIbios_mode[i].name, l)) {
540 xgifb_mode_idx = i;
541 j = 1;
542 break;
543 }
544 i++;
545 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530546 if (!j)
547 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200548}
549
550static void XGIfb_search_vesamode(unsigned int vesamode)
551{
552 int i = 0, j = 0;
553
Prashant P. Shahb654f872010-09-06 17:34:26 +0530554 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200555
556 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
557 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530558 if ((xgi_video_info.chip == XG21)
559 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
560 == DISPTYPE_LCD)) {
561 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200562 }
563 return;
564 }
565
Prashant P. Shahb654f872010-09-06 17:34:26 +0530566 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200567
Prashant P. Shahb654f872010-09-06 17:34:26 +0530568 while (XGIbios_mode[i].mode_no != 0) {
569 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
570 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200571 xgifb_mode_idx = i;
572 j = 1;
573 break;
574 }
575 i++;
576 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530577 if (!j)
578 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200579}
580
Randy Dunlap89229672010-08-10 08:46:44 -0700581static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200582{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530583 u8 tmp;
584 unsigned char *pData;
585 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200586
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300587 tmp = xgifb_reg_get(XGISR, 0x1e);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300588 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200589
Prashant P. Shahb654f872010-09-06 17:34:26 +0530590 pData = xgi_video_info.mmio_vbase + 0x20000;
591 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
592 i = pData[0x316] | (pData[0x317] << 8);
593 j = pData[i - 1];
594 if (j == 0xff)
595 j = 1;
596
597 k = 0;
598 do {
599 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
600 | (pData[i + 1] << 8);
601 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
602 + 3] << 8);
603 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
604 + 5] << 8);
605 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
606 + 7] << 8);
607 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
608 + 9] << 8);
609 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
610 + 11] << 8);
611 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
612 + 13] << 8);
613 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
614 | (pData[i + 15] << 8);
615 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
616 | (pData[i + 17] << 8);
617 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
618 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
619 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
620 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
621 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
622 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
623 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
624 i += 25;
625 j--;
626 k++;
627 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
628 / sizeof(struct XGI21_LVDSCapStruct))));
629 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200630 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530631 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200632}
633
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200634static int XGIfb_validate_mode(int myindex)
635{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530636 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200637
Prashant P. Shahb654f872010-09-06 17:34:26 +0530638 if (xgi_video_info.chip == XG21) {
639 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
640 == DISPTYPE_LCD) {
641 xres = XGI21_LCDCapList[0].LVDSHDE;
642 yres = XGI21_LCDCapList[0].LVDSVDE;
643 if (XGIbios_mode[myindex].xres > xres)
644 return -1;
645 if (XGIbios_mode[myindex].yres > yres)
646 return -1;
647 if ((XGIbios_mode[myindex].xres < xres)
648 && (XGIbios_mode[myindex].yres < yres)) {
649 if (XGIbios_mode[myindex].bpp > 8)
650 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200651 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530652
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200653 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530654 return myindex;
655
656 }
657
658 /* FIXME: for now, all is valid on XG27 */
659 if (xgi_video_info.chip == XG27)
660 return myindex;
661
662 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
663 return -1;
664
665 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
666 case DISPTYPE_LCD:
667 switch (XGIhw_ext.ulCRT2LCDType) {
668 case LCD_640x480:
669 xres = 640;
670 yres = 480;
671 break;
672 case LCD_800x600:
673 xres = 800;
674 yres = 600;
675 break;
676 case LCD_1024x600:
677 xres = 1024;
678 yres = 600;
679 break;
680 case LCD_1024x768:
681 xres = 1024;
682 yres = 768;
683 break;
684 case LCD_1152x768:
685 xres = 1152;
686 yres = 768;
687 break;
688 case LCD_1280x960:
689 xres = 1280;
690 yres = 960;
691 break;
692 case LCD_1280x768:
693 xres = 1280;
694 yres = 768;
695 break;
696 case LCD_1280x1024:
697 xres = 1280;
698 yres = 1024;
699 break;
700 case LCD_1400x1050:
701 xres = 1400;
702 yres = 1050;
703 break;
704 case LCD_1600x1200:
705 xres = 1600;
706 yres = 1200;
707 break;
708 /* case LCD_320x480: */ /* TW: FSTN */
709 /*
710 xres = 320;
711 yres = 480;
712 break;
713 */
714 default:
715 xres = 0;
716 yres = 0;
717 break;
718 }
719 if (XGIbios_mode[myindex].xres > xres)
720 return -1;
721 if (XGIbios_mode[myindex].yres > yres)
722 return -1;
723 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
724 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
725 switch (XGIbios_mode[myindex].xres) {
726 case 512:
727 if (XGIbios_mode[myindex].yres != 512)
728 return -1;
729 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
730 return -1;
731 break;
732 case 640:
733 if ((XGIbios_mode[myindex].yres != 400)
734 && (XGIbios_mode[myindex].yres
735 != 480))
736 return -1;
737 break;
738 case 800:
739 if (XGIbios_mode[myindex].yres != 600)
740 return -1;
741 break;
742 case 1024:
743 if ((XGIbios_mode[myindex].yres != 600)
744 && (XGIbios_mode[myindex].yres
745 != 768))
746 return -1;
747 if ((XGIbios_mode[myindex].yres == 600)
748 && (XGIhw_ext.ulCRT2LCDType
749 != LCD_1024x600))
750 return -1;
751 break;
752 case 1152:
753 if ((XGIbios_mode[myindex].yres) != 768)
754 return -1;
755 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
756 return -1;
757 break;
758 case 1280:
759 if ((XGIbios_mode[myindex].yres != 768)
760 && (XGIbios_mode[myindex].yres
761 != 1024))
762 return -1;
763 if ((XGIbios_mode[myindex].yres == 768)
764 && (XGIhw_ext.ulCRT2LCDType
765 != LCD_1280x768))
766 return -1;
767 break;
768 case 1400:
769 if (XGIbios_mode[myindex].yres != 1050)
770 return -1;
771 break;
772 case 1600:
773 if (XGIbios_mode[myindex].yres != 1200)
774 return -1;
775 break;
776 default:
777 return -1;
778 }
779 } else {
780 switch (XGIbios_mode[myindex].xres) {
781 case 512:
782 if (XGIbios_mode[myindex].yres != 512)
783 return -1;
784 break;
785 case 640:
786 if ((XGIbios_mode[myindex].yres != 400)
787 && (XGIbios_mode[myindex].yres
788 != 480))
789 return -1;
790 break;
791 case 800:
792 if (XGIbios_mode[myindex].yres != 600)
793 return -1;
794 break;
795 case 1024:
796 if (XGIbios_mode[myindex].yres != 768)
797 return -1;
798 break;
799 case 1280:
800 if ((XGIbios_mode[myindex].yres != 960)
801 && (XGIbios_mode[myindex].yres
802 != 1024))
803 return -1;
804 if (XGIbios_mode[myindex].yres == 960) {
805 if (XGIhw_ext.ulCRT2LCDType
806 == LCD_1400x1050)
807 return -1;
808 }
809 break;
810 case 1400:
811 if (XGIbios_mode[myindex].yres != 1050)
812 return -1;
813 break;
814 case 1600:
815 if (XGIbios_mode[myindex].yres != 1200)
816 return -1;
817 break;
818 default:
819 return -1;
820 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200821 }
822 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530823 case DISPTYPE_TV:
824 switch (XGIbios_mode[myindex].xres) {
825 case 512:
826 case 640:
827 case 800:
828 break;
829 case 720:
830 if (xgi_video_info.TV_type == TVMODE_NTSC) {
831 if (XGIbios_mode[myindex].yres != 480)
832 return -1;
833 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
834 if (XGIbios_mode[myindex].yres != 576)
835 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200836 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530837 /* TW: LVDS/CHRONTEL does not support 720 */
838 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
839 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
840 return -1;
841 }
842 break;
843 case 1024:
844 if (xgi_video_info.TV_type == TVMODE_NTSC) {
845 if (XGIbios_mode[myindex].bpp == 32)
846 return -1;
847 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530848 break;
849 default:
850 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200851 }
852 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530853 case DISPTYPE_CRT2:
854 if (XGIbios_mode[myindex].xres > 1280)
855 return -1;
856 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200857 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530858 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200859
860}
861
862static void XGIfb_search_crt2type(const char *name)
863{
864 int i = 0;
865
Prashant P. Shahb654f872010-09-06 17:34:26 +0530866 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200867 return;
868
Prashant P. Shahb654f872010-09-06 17:34:26 +0530869 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200870 if (!strcmp(name, XGI_crt2type[i].name)) {
871 XGIfb_crt2type = XGI_crt2type[i].type_no;
872 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
873 break;
874 }
875 i++;
876 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530877 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200878 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
879}
880
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200881static u8 XGIfb_search_refresh_rate(unsigned int rate)
882{
883 u16 xres, yres;
884 int i = 0;
885
886 xres = XGIbios_mode[xgifb_mode_idx].xres;
887 yres = XGIbios_mode[xgifb_mode_idx].yres;
888
889 XGIfb_rate_idx = 0;
890 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530891 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
892 == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200893 if (XGIfb_vrate[i].refresh == rate) {
894 XGIfb_rate_idx = XGIfb_vrate[i].idx;
895 break;
896 } else if (XGIfb_vrate[i].refresh > rate) {
897 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
898 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530899 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200900 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530901 xgi_video_info.refresh_rate
902 = XGIfb_vrate[i].refresh;
903 } else if (((rate - XGIfb_vrate[i - 1].refresh)
904 <= 2) && (XGIfb_vrate[i].idx
905 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200906 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530907 rate, XGIfb_vrate[i-1].refresh);
908 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
909 xgi_video_info.refresh_rate
910 = XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200911 }
912 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530913 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200914 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
915 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530916 XGIfb_rate_idx = XGIfb_vrate[i].idx;
917 break;
918 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200919 }
920 i++;
921 }
922 if (XGIfb_rate_idx > 0) {
923 return XGIfb_rate_idx;
924 } else {
925 printk(KERN_INFO
Prashant P. Shahb654f872010-09-06 17:34:26 +0530926 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200927 return 0;
928 }
929}
930
931static void XGIfb_search_tvstd(const char *name)
932{
933 int i = 0;
934
Prashant P. Shahb654f872010-09-06 17:34:26 +0530935 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200936 return;
937
938 while (XGI_tvtype[i].type_no != -1) {
939 if (!strcmp(name, XGI_tvtype[i].name)) {
940 XGIfb_tvmode = XGI_tvtype[i].type_no;
941 break;
942 }
943 i++;
944 }
945}
946
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200947/* ----------- FBDev related routines for all series ----------- */
948
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200949static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
950{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530951 switch (var->bits_per_pixel) {
952 case 8:
953 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200954 var->red.length = var->green.length = var->blue.length = 6;
955 xgi_video_info.video_cmap_len = 256;
956 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530957 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200958 var->red.offset = 11;
959 var->red.length = 5;
960 var->green.offset = 5;
961 var->green.length = 6;
962 var->blue.offset = 0;
963 var->blue.length = 5;
964 var->transp.offset = 0;
965 var->transp.length = 0;
966 xgi_video_info.video_cmap_len = 16;
967 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530968 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200969 var->red.offset = 16;
970 var->red.length = 8;
971 var->green.offset = 8;
972 var->green.length = 8;
973 var->blue.offset = 0;
974 var->blue.length = 8;
975 var->transp.offset = 24;
976 var->transp.length = 8;
977 xgi_video_info.video_cmap_len = 16;
978 break;
979 }
980}
981
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300982/* --------------------- SetMode routines ------------------------- */
983
984static void XGIfb_pre_setmode(void)
985{
986 u8 cr30 = 0, cr31 = 0;
987
988 cr31 = xgifb_reg_get(XGICR, 0x31);
989 cr31 &= ~0x60;
990
991 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
992 case DISPTYPE_CRT2:
993 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
994 cr31 |= XGI_DRIVER_MODE;
995 break;
996 case DISPTYPE_LCD:
997 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
998 cr31 |= XGI_DRIVER_MODE;
999 break;
1000 case DISPTYPE_TV:
1001 if (xgi_video_info.TV_type == TVMODE_HIVISION)
1002 cr30 = (XGI_VB_OUTPUT_HIVISION
1003 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1004 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
1005 cr30 = (XGI_VB_OUTPUT_SVIDEO
1006 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1007 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
1008 cr30 = (XGI_VB_OUTPUT_COMPOSITE
1009 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1010 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
1011 cr30 = (XGI_VB_OUTPUT_SCART
1012 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1013 cr31 |= XGI_DRIVER_MODE;
1014
1015 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
1016 cr31 |= 0x01;
1017 else
1018 cr31 &= ~0x01;
1019 break;
1020 default: /* disable CRT2 */
1021 cr30 = 0x00;
1022 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
1023 }
1024
1025 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
1026 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
1027 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
1028}
1029
1030static void XGIfb_post_setmode(void)
1031{
1032 u8 reg;
1033 unsigned char doit = 1;
1034 /*
1035 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1036 xgifb_reg_set(XGICR, 0x13, 0x00);
1037 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
1038 *test*
1039 */
1040 if (xgi_video_info.video_bpp == 8) {
1041 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
1042 if ((xgi_video_info.hasVB == HASVB_LVDS)
1043 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
1044 doit = 0;
1045 }
1046 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
1047 if (xgi_video_info.disp_state & DISPTYPE_LCD)
1048 doit = 0;
1049 }
1050
1051 /* TW: We can't switch off CRT1 if bridge is in slave mode */
1052 if (xgi_video_info.hasVB != HASVB_NONE) {
1053 reg = xgifb_reg_get(XGIPART1, 0x00);
1054
1055 if ((reg & 0x50) == 0x10)
1056 doit = 0;
1057
1058 } else {
1059 XGIfb_crt1off = 0;
1060 }
1061
1062 reg = xgifb_reg_get(XGICR, 0x17);
1063 if ((XGIfb_crt1off) && (doit))
1064 reg &= ~0x80;
1065 else
1066 reg |= 0x80;
1067 xgifb_reg_set(XGICR, 0x17, reg);
1068
1069 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1070
1071 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1072 == HASVB_301)) {
1073
1074 reg = xgifb_reg_get(XGIPART4, 0x01);
1075
1076 if (reg < 0xB0) { /* Set filter for XGI301 */
1077
1078 switch (xgi_video_info.video_width) {
1079 case 320:
1080 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
1081 break;
1082 case 640:
1083 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
1084 break;
1085 case 720:
1086 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
1087 break;
1088 case 800:
1089 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
1090 break;
1091 default:
1092 filter = -1;
1093 break;
1094 }
1095
1096 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1097
1098 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1099
1100 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1101
1102 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1103
1104 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1105
1106 } else if (xgi_video_info.TV_plug
1107 == TVPLUG_COMPOSITE) {
1108
1109 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1110
1111 switch (xgi_video_info.video_width) {
1112 case 640:
1113 xgifb_reg_set(XGIPART2, 0x35, 0xEB);
1114 xgifb_reg_set(XGIPART2, 0x36, 0x04);
1115 xgifb_reg_set(XGIPART2, 0x37, 0x25);
1116 xgifb_reg_set(XGIPART2, 0x38, 0x18);
1117 break;
1118 case 720:
1119 xgifb_reg_set(XGIPART2, 0x35, 0xEE);
1120 xgifb_reg_set(XGIPART2, 0x36, 0x0C);
1121 xgifb_reg_set(XGIPART2, 0x37, 0x22);
1122 xgifb_reg_set(XGIPART2, 0x38, 0x08);
1123 break;
1124 case 800:
1125 xgifb_reg_set(XGIPART2, 0x35, 0xEB);
1126 xgifb_reg_set(XGIPART2, 0x36, 0x15);
1127 xgifb_reg_set(XGIPART2, 0x37, 0x25);
1128 xgifb_reg_set(XGIPART2, 0x38, 0xF6);
1129 break;
1130 }
1131 }
1132
1133 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1134
1135 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1136
1137 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1138
1139 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1140
1141 } else if (xgi_video_info.TV_plug
1142 == TVPLUG_COMPOSITE) {
1143
1144 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1145
1146 switch (xgi_video_info.video_width) {
1147 case 640:
1148 xgifb_reg_set(XGIPART2, 0x35, 0xF1);
1149 xgifb_reg_set(XGIPART2, 0x36, 0xF7);
1150 xgifb_reg_set(XGIPART2, 0x37, 0x1F);
1151 xgifb_reg_set(XGIPART2, 0x38, 0x32);
1152 break;
1153 case 720:
1154 xgifb_reg_set(XGIPART2, 0x35, 0xF3);
1155 xgifb_reg_set(XGIPART2, 0x36, 0x00);
1156 xgifb_reg_set(XGIPART2, 0x37, 0x1D);
1157 xgifb_reg_set(XGIPART2, 0x38, 0x20);
1158 break;
1159 case 800:
1160 xgifb_reg_set(XGIPART2, 0x35, 0xFC);
1161 xgifb_reg_set(XGIPART2, 0x36, 0xFB);
1162 xgifb_reg_set(XGIPART2, 0x37, 0x14);
1163 xgifb_reg_set(XGIPART2, 0x38, 0x2A);
1164 break;
1165 }
1166 }
1167 }
1168
1169 if ((filter >= 0) && (filter <= 7)) {
1170 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
1171 XGI_TV_filter[filter_tb].filter[filter][0],
1172 XGI_TV_filter[filter_tb].filter[filter][1],
1173 XGI_TV_filter[filter_tb].filter[filter][2],
1174 XGI_TV_filter[filter_tb].filter[filter][3]
1175 );
1176 xgifb_reg_set(
1177 XGIPART2,
1178 0x35,
1179 (XGI_TV_filter[filter_tb].filter[filter][0]));
1180 xgifb_reg_set(
1181 XGIPART2,
1182 0x36,
1183 (XGI_TV_filter[filter_tb].filter[filter][1]));
1184 xgifb_reg_set(
1185 XGIPART2,
1186 0x37,
1187 (XGI_TV_filter[filter_tb].filter[filter][2]));
1188 xgifb_reg_set(
1189 XGIPART2,
1190 0x38,
1191 (XGI_TV_filter[filter_tb].filter[filter][3]));
1192 }
1193
1194 }
1195
1196 }
1197
1198}
1199
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001200static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301201 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001202{
1203
Prashant P. Shahb654f872010-09-06 17:34:26 +05301204 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1205 + var->hsync_len;
1206 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1207 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001208#if defined(__powerpc__)
1209 u8 sr_data, cr_data;
1210#endif
1211 unsigned int drate = 0, hrate = 0;
1212 int found_mode = 0;
1213 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301214 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001215
1216 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301217 /* 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 +02001218
Prashant P. Shahb654f872010-09-06 17:34:26 +05301219 info->var.xres_virtual = var->xres_virtual;
1220 info->var.yres_virtual = var->yres_virtual;
1221 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001222
1223 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1224 vtotal <<= 1;
1225 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1226 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301227 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1228 /* vtotal <<= 1; */
1229 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001230 }
1231
Prashant P. Shahb654f872010-09-06 17:34:26 +05301232 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001233 DPRINTK("XGIfb: Invalid 'var' information\n");
1234 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301235 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1236 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001237
Prashant P. Shahb654f872010-09-06 17:34:26 +05301238 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001239 drate = 1000000000 / var->pixclock;
1240 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301241 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1242 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001243 } else {
1244 xgi_video_info.refresh_rate = 60;
1245 }
1246
1247 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05301248 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001249
1250 old_mode = xgifb_mode_idx;
1251 xgifb_mode_idx = 0;
1252
Prashant P. Shahb654f872010-09-06 17:34:26 +05301253 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1254 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1255 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1256 && (XGIbios_mode[xgifb_mode_idx].yres
1257 == var->yres)
1258 && (XGIbios_mode[xgifb_mode_idx].bpp
1259 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001260 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1261 found_mode = 1;
1262 break;
1263 }
1264 xgifb_mode_idx++;
1265 }
1266
Prashant P. Shahb654f872010-09-06 17:34:26 +05301267 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001268 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1269 else
1270 xgifb_mode_idx = -1;
1271
Prashant P. Shahb654f872010-09-06 17:34:26 +05301272 if (xgifb_mode_idx < 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001273 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301274 var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001275 xgifb_mode_idx = old_mode;
1276 return -EINVAL;
1277 }
1278
Prashant P. Shahb654f872010-09-06 17:34:26 +05301279 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001280 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1281 xgi_video_info.refresh_rate = 60;
1282 }
1283
Prashant P. Shahb654f872010-09-06 17:34:26 +05301284 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001285
1286 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301287 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001288 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1289 return -EINVAL;
1290 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301291 info->fix.line_length = ((info->var.xres_virtual
1292 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001293
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001294 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001295
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001296 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1297 xgifb_reg_set(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001298
1299 XGIfb_post_setmode();
1300
Prashant P. Shahb654f872010-09-06 17:34:26 +05301301 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1302 XGIbios_mode[xgifb_mode_idx].xres,
1303 XGIbios_mode[xgifb_mode_idx].yres,
1304 XGIbios_mode[xgifb_mode_idx].bpp,
1305 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001306
1307 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1308 xgi_video_info.video_vwidth = info->var.xres_virtual;
1309 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1310 xgi_video_info.video_vheight = info->var.yres_virtual;
1311 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1312 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301313 xgi_video_info.video_linelength = info->var.xres_virtual
1314 * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301315 switch (xgi_video_info.video_bpp) {
1316 case 8:
1317 xgi_video_info.DstColor = 0x0000;
1318 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1319 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001320#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001321 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001322 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001323#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301324 break;
1325 case 16:
1326 xgi_video_info.DstColor = 0x8000;
1327 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001328#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001329 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001330 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001331#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301332 xgi_video_info.video_cmap_len = 16;
1333 break;
1334 case 32:
1335 xgi_video_info.DstColor = 0xC000;
1336 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1337 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001338#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001339 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001340 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001341#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301342 break;
1343 default:
1344 xgi_video_info.video_cmap_len = 16;
1345 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301346 break;
1347 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001348 }
1349 XGIfb_bpp_to_var(var); /*update ARGB info*/
1350 DEBUGPRN("End of do_set_var");
1351
1352 dumpVGAReg();
1353 return 0;
1354}
1355
1356#ifdef XGIFB_PAN
1357static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1358{
1359 unsigned int base;
1360
Prashant P. Shahb654f872010-09-06 17:34:26 +05301361 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001362
1363 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301364 /* printk("Pan: xo: %d xv %d xr %d\n",
1365 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001366 return -EINVAL;
1367 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301368 if (var->yoffset > (var->yres_virtual - var->yres)) {
1369 /* printk("Pan: yo: %d yv %d yr %d\n",
1370 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001371 return -EINVAL;
1372 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301373 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001374
Prashant P. Shahb654f872010-09-06 17:34:26 +05301375 /* calculate base bpp dep. */
1376 switch (var->bits_per_pixel) {
1377 case 16:
1378 base >>= 1;
1379 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001380 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301381 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001382 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301383 default:
1384 base >>= 2;
1385 break;
1386 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001387
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001388 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001389
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001390 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1391 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1392 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1393 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
Aaro Koskinen65283d42011-04-18 22:14:02 +03001394 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001395
Prashant P. Shahb654f872010-09-06 17:34:26 +05301396 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene67f4d42011-04-18 22:14:00 +03001397 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001398 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1399 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1400 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
Aaro Koskinen65283d42011-04-18 22:14:02 +03001401 xgifb_reg_and_or(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301402 }
1403 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001404 return 0;
1405}
1406#endif
1407
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001408static int XGIfb_open(struct fb_info *info, int user)
1409{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301410 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001411}
1412
1413static int XGIfb_release(struct fb_info *info, int user)
1414{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301415 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001416}
1417
1418static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1419{
1420 int rc = 16;
1421
Prashant P. Shahb654f872010-09-06 17:34:26 +05301422 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001423 case 8:
1424 rc = 256;
1425 break;
1426 case 16:
1427 rc = 16;
1428 break;
1429 case 32:
1430 rc = 16;
1431 break;
1432 }
1433 return rc;
1434}
1435
Prashant P. Shahb654f872010-09-06 17:34:26 +05301436static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1437 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001438{
1439 if (regno >= XGIfb_get_cmap_len(&info->var))
1440 return 1;
1441
1442 switch (info->var.bits_per_pixel) {
1443 case 8:
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001444 outb(regno, XGIDACA);
1445 outb((red >> 10), XGIDACD);
1446 outb((green >> 10), XGIDACD);
1447 outb((blue >> 10), XGIDACD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001448 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001449 outb(regno, XGIDAC2A);
1450 outb((red >> 8), XGIDAC2D);
1451 outb((green >> 8), XGIDAC2D);
1452 outb((blue >> 8), XGIDAC2D);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001453 }
1454 break;
1455 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301456 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1457 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1458 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001459 break;
1460 case 32:
1461 red >>= 8;
1462 green >>= 8;
1463 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301464 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1465 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001466 break;
1467 }
1468 return 0;
1469}
1470
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001471/* ----------- FBDev related routines for all series ---------- */
1472
1473static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1474 struct fb_info *info)
1475{
1476 DEBUGPRN("inside get_fix");
1477 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1478
1479 strcpy(fix->id, myid);
1480
1481 fix->smem_start = xgi_video_info.video_base;
1482
1483 fix->smem_len = xgi_video_info.video_size;
1484
1485 fix->type = video_type;
1486 fix->type_aux = 0;
1487 if (xgi_video_info.video_bpp == 8)
1488 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1489 else
1490 fix->visual = FB_VISUAL_DIRECTCOLOR;
1491 fix->xpanstep = 0;
1492#ifdef XGIFB_PAN
1493 if (XGIfb_ypan)
1494 fix->ypanstep = 1;
1495#endif
1496 fix->ywrapstep = 0;
1497 fix->line_length = xgi_video_info.video_linelength;
1498 fix->mmio_start = xgi_video_info.mmio_base;
1499 fix->mmio_len = xgi_video_info.mmio_size;
1500 fix->accel = FB_ACCEL_XGI_XABRE;
1501
1502 DEBUGPRN("end of get_fix");
1503 return 0;
1504}
1505
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001506static int XGIfb_set_par(struct fb_info *info)
1507{
1508 int err;
1509
Prashant P. Shahb654f872010-09-06 17:34:26 +05301510 /* printk("XGIfb: inside set_par\n"); */
1511 err = XGIfb_do_set_var(&info->var, 1, info);
1512 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001513 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001514 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301515 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001516 return 0;
1517}
1518
Prashant P. Shahb654f872010-09-06 17:34:26 +05301519static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001520{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301521 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1522 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001523 unsigned int vtotal = 0;
1524 unsigned int drate = 0, hrate = 0;
1525 int found_mode = 0;
1526 int refresh_rate, search_idx;
1527
1528 DEBUGPRN("Inside check_var");
1529
Prashant P. Shahb654f872010-09-06 17:34:26 +05301530 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1531 vtotal = var->upper_margin + var->yres + var->lower_margin
1532 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001533 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301534 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1535 vtotal = var->upper_margin + var->yres + var->lower_margin
1536 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001537 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301538 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1539 vtotal = var->upper_margin + (var->yres / 2)
1540 + var->lower_margin + var->vsync_len;
1541 } else
1542 vtotal = var->upper_margin + var->yres + var->lower_margin
1543 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001544
Prashant P. Shahb654f872010-09-06 17:34:26 +05301545 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001546 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301547
1548 if (var->pixclock && htotal && vtotal) {
1549 drate = 1000000000 / var->pixclock;
1550 hrate = (drate * 1000) / htotal;
1551 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1552 printk(KERN_DEBUG
1553 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1554 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1555 __func__, var->pixclock, htotal, vtotal,
1556 __func__, drate, hrate, xgi_video_info.refresh_rate);
1557 } else {
1558 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001559 }
1560
Prashant P. Shahb654f872010-09-06 17:34:26 +05301561 /*
1562 if ((var->pixclock) && (htotal)) {
1563 drate = 1E12 / var->pixclock;
1564 hrate = drate / htotal;
1565 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1566 } else {
1567 refresh_rate = 60;
1568 }
1569 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001570 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301571 if ((var->xres == 1024) && (var->yres == 600))
1572 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001573
1574 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301575 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1576 (XGIbios_mode[search_idx].xres <= var->xres)) {
1577 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1578 (XGIbios_mode[search_idx].yres == var->yres) &&
1579 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1580 if (XGIfb_validate_mode(search_idx) > 0) {
1581 found_mode = 1;
1582 break;
1583 }
1584 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001585 search_idx++;
1586 }
1587
Prashant P. Shahb654f872010-09-06 17:34:26 +05301588 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001589
1590 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1591 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301592 search_idx = 0;
1593 while (XGIbios_mode[search_idx].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001594
Prashant P. Shahb654f872010-09-06 17:34:26 +05301595 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1596 (var->yres <= XGIbios_mode[search_idx].yres) &&
1597 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1598 if (XGIfb_validate_mode(search_idx) > 0) {
1599 found_mode = 1;
1600 break;
1601 }
1602 }
1603 search_idx++;
1604 }
1605 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001606 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301607 var->yres = XGIbios_mode[search_idx].yres;
1608 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1609 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001610
1611 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301612 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001613 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301614 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001615 }
1616 }
1617
1618 /* TW: TODO: Check the refresh rate */
1619
1620 /* Adapt RGB settings */
1621 XGIfb_bpp_to_var(var);
1622
1623 /* Sanity check for offsets */
1624 if (var->xoffset < 0)
1625 var->xoffset = 0;
1626 if (var->yoffset < 0)
1627 var->yoffset = 0;
1628
Prashant P. Shahb654f872010-09-06 17:34:26 +05301629 if (!XGIfb_ypan) {
1630 if (var->xres != var->xres_virtual)
1631 var->xres_virtual = var->xres;
1632 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001633 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301634 } /* else { */
1635 /* TW: Now patch yres_virtual if we use panning */
1636 /* May I do this? */
1637 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1638 /* if (var->yres_virtual <= var->yres) { */
1639 /* TW: Paranoia check */
1640 /* var->yres_virtual = var->yres; */
1641 /* } */
1642 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001643
1644 /* Truncate offsets to maximum if too high */
1645 if (var->xoffset > var->xres_virtual - var->xres)
1646 var->xoffset = var->xres_virtual - var->xres - 1;
1647
1648 if (var->yoffset > var->yres_virtual - var->yres)
1649 var->yoffset = var->yres_virtual - var->yres - 1;
1650
1651 /* Set everything else to 0 */
1652 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301653 var->green.msb_right =
1654 var->blue.msb_right =
1655 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001656
1657 DEBUGPRN("end of check_var");
1658 return 0;
1659}
1660
1661#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301662static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1663 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001664{
1665 int err;
1666
Prashant P. Shahb654f872010-09-06 17:34:26 +05301667 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001668
1669 if (var->xoffset > (var->xres_virtual - var->xres))
1670 return -EINVAL;
1671 if (var->yoffset > (var->yres_virtual - var->yres))
1672 return -EINVAL;
1673
1674 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301675 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1676 || var->xoffset)
1677 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001678 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301679 if (var->xoffset + info->var.xres > info->var.xres_virtual
1680 || var->yoffset + info->var.yres
1681 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001682 return -EINVAL;
1683 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301684 err = XGIfb_pan_var(var);
1685 if (err < 0)
1686 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001687
1688 info->var.xoffset = var->xoffset;
1689 info->var.yoffset = var->yoffset;
1690 if (var->vmode & FB_VMODE_YWRAP)
1691 info->var.vmode |= FB_VMODE_YWRAP;
1692 else
1693 info->var.vmode &= ~FB_VMODE_YWRAP;
1694
Prashant P. Shahb654f872010-09-06 17:34:26 +05301695 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001696 return 0;
1697}
1698#endif
1699
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001700static int XGIfb_blank(int blank, struct fb_info *info)
1701{
1702 u8 reg;
1703
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001704 reg = xgifb_reg_get(XGICR, 0x17);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001705
Prashant P. Shahb654f872010-09-06 17:34:26 +05301706 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001707 reg &= 0x7f;
1708 else
1709 reg |= 0x80;
1710
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001711 xgifb_reg_set(XGICR, 0x17, reg);
1712 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1713 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301714 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001715}
1716
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001717static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301718 .owner = THIS_MODULE,
1719 .fb_open = XGIfb_open,
1720 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001721 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301722 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001723 .fb_setcolreg = XGIfb_setcolreg,
1724#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301725 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001726#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301727 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001728 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001729 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001730 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301731 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001732};
1733
1734/* ---------------- Chip generation dependent routines ---------------- */
1735
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001736/* for XGI 315/550/650/740/330 */
1737
1738static int XGIfb_get_dram_size(void)
1739{
1740
Prashant P. Shahb654f872010-09-06 17:34:26 +05301741 u8 ChannelNum, tmp;
1742 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001743
1744 /* xorg driver sets 32MB * 1 channel */
1745 if (xgi_video_info.chip == XG27)
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001746 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001747
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001748 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301749 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1750 case XGI_DRAM_SIZE_1MB:
1751 xgi_video_info.video_size = 0x100000;
1752 break;
1753 case XGI_DRAM_SIZE_2MB:
1754 xgi_video_info.video_size = 0x200000;
1755 break;
1756 case XGI_DRAM_SIZE_4MB:
1757 xgi_video_info.video_size = 0x400000;
1758 break;
1759 case XGI_DRAM_SIZE_8MB:
1760 xgi_video_info.video_size = 0x800000;
1761 break;
1762 case XGI_DRAM_SIZE_16MB:
1763 xgi_video_info.video_size = 0x1000000;
1764 break;
1765 case XGI_DRAM_SIZE_32MB:
1766 xgi_video_info.video_size = 0x2000000;
1767 break;
1768 case XGI_DRAM_SIZE_64MB:
1769 xgi_video_info.video_size = 0x4000000;
1770 break;
1771 case XGI_DRAM_SIZE_128MB:
1772 xgi_video_info.video_size = 0x8000000;
1773 break;
1774 case XGI_DRAM_SIZE_256MB:
1775 xgi_video_info.video_size = 0x10000000;
1776 break;
1777 default:
1778 return -1;
1779 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001780
Prashant P. Shahb654f872010-09-06 17:34:26 +05301781 tmp = (reg & 0x0c) >> 2;
1782 switch (xgi_video_info.chip) {
1783 case XG20:
1784 case XG21:
1785 case XG27:
1786 ChannelNum = 1;
1787 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001788
Prashant P. Shahb654f872010-09-06 17:34:26 +05301789 case XG42:
1790 if (reg & 0x04)
1791 ChannelNum = 2;
1792 else
1793 ChannelNum = 1;
1794 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001795
Prashant P. Shahb654f872010-09-06 17:34:26 +05301796 case XG45:
1797 if (tmp == 1)
1798 ChannelNum = 2;
1799 else if (tmp == 2)
1800 ChannelNum = 3;
1801 else if (tmp == 3)
1802 ChannelNum = 4;
1803 else
1804 ChannelNum = 1;
1805 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001806
Prashant P. Shahb654f872010-09-06 17:34:26 +05301807 case XG40:
1808 default:
1809 if (tmp == 2)
1810 ChannelNum = 2;
1811 else if (tmp == 3)
1812 ChannelNum = 3;
1813 else
1814 ChannelNum = 1;
1815 break;
1816 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001817
Prashant P. Shahb654f872010-09-06 17:34:26 +05301818 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1819 /* PLiad fixed for benchmarking and fb set */
1820 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1821 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001822
Prashant P. Shahb654f872010-09-06 17:34:26 +05301823 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1824 xgi_video_info.video_size, ChannelNum);
1825 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001826
1827}
1828
1829static void XGIfb_detect_VB(void)
1830{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301831 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001832
1833 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1834
Prashant P. Shahb654f872010-09-06 17:34:26 +05301835 switch (xgi_video_info.hasVB) {
1836 case HASVB_LVDS_CHRONTEL:
1837 case HASVB_CHRONTEL:
1838 break;
1839 case HASVB_301:
1840 case HASVB_302:
1841 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1842 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001843 }
1844
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001845 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001846
1847 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1848 XGIfb_crt1off = 0;
1849 else {
1850 if (cr32 & 0x5F)
1851 XGIfb_crt1off = 1;
1852 else
1853 XGIfb_crt1off = 0;
1854 }
1855
1856 if (XGIfb_crt2type != -1)
1857 /* TW: Override with option */
1858 xgi_video_info.disp_state = XGIfb_crt2type;
1859 else if (cr32 & XGI_VB_TV)
1860 xgi_video_info.disp_state = DISPTYPE_TV;
1861 else if (cr32 & XGI_VB_LCD)
1862 xgi_video_info.disp_state = DISPTYPE_LCD;
1863 else if (cr32 & XGI_VB_CRT2)
1864 xgi_video_info.disp_state = DISPTYPE_CRT2;
1865 else
1866 xgi_video_info.disp_state = 0;
1867
Prashant P. Shahb654f872010-09-06 17:34:26 +05301868 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001869 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301870 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001871 else if (cr32 & XGI_VB_HIVISION) {
1872 xgi_video_info.TV_type = TVMODE_HIVISION;
1873 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301874 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001875 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1876 else if (cr32 & XGI_VB_COMPOSITE)
1877 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1878 else if (cr32 & XGI_VB_SCART)
1879 xgi_video_info.TV_plug = TVPLUG_SCART;
1880
Prashant P. Shahb654f872010-09-06 17:34:26 +05301881 if (xgi_video_info.TV_type == 0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001882 temp = xgifb_reg_get(XGICR, 0x38);
Aaro Koskinenebe78462011-03-13 12:26:08 +02001883 if (temp & 0x10)
1884 xgi_video_info.TV_type = TVMODE_PAL;
1885 else
1886 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001887 }
1888
1889 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301890 if (XGIfb_forcecrt1 != -1) {
1891 if (XGIfb_forcecrt1)
1892 XGIfb_crt1off = 0;
1893 else
1894 XGIfb_crt1off = 1;
1895 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001896}
1897
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001898static int XGIfb_has_VB(void)
1899{
1900 u8 vb_chipid;
1901
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001902 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001903 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301904 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001905 xgi_video_info.hasVB = HASVB_301;
1906 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301907 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001908 xgi_video_info.hasVB = HASVB_302;
1909 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301910 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001911 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001912 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001913 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001914 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001915}
1916
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001917static void XGIfb_get_VB_type(void)
1918{
1919 u8 reg;
1920
1921 if (!XGIfb_has_VB()) {
1922 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1923 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1924 case XGI310_EXTERNAL_CHIP_LVDS:
1925 xgi_video_info.hasVB = HASVB_LVDS;
1926 break;
1927 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1928 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1929 break;
1930 default:
1931 break;
1932 }
1933 }
1934}
1935
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001936/* ------------------ Sensing routines ------------------ */
1937
1938/* TW: Determine and detect attached devices on XGI30x */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301939int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001940{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301941 int temp, i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001942
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001943 xgifb_reg_set(XGIPART4, 0x11, tempbl);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301944 temp = tempbh | tempcl;
Aaro Koskinen65283d42011-04-18 22:14:02 +03001945 xgifb_reg_and_or(XGIPART4, 0x10, 0xe0, temp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301946 for (i = 0; i < 10; i++)
1947 XGI_LongWait(&XGI_Pr);
1948 tempch &= 0x7f;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001949 temp = xgifb_reg_get(XGIPART4, 0x03);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301950 temp ^= 0x0e;
1951 temp &= tempch;
1952 return temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001953}
1954
Prashant P. Shahb654f872010-09-06 17:34:26 +05301955void XGI_Sense30x(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001956{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301957 u8 backupP4_0d;
1958 u8 testsvhs_tempbl, testsvhs_tempbh;
1959 u8 testsvhs_tempcl, testsvhs_tempch;
1960 u8 testcvbs_tempbl, testcvbs_tempbh;
1961 u8 testcvbs_tempcl, testcvbs_tempch;
1962 u8 testvga2_tempbl, testvga2_tempbh;
1963 u8 testvga2_tempcl, testvga2_tempch;
1964 int myflag, result;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001965
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001966 backupP4_0d = xgifb_reg_get(XGIPART4, 0x0d);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001967 xgifb_reg_set(XGIPART4, 0x0d, (backupP4_0d | 0x04));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001968
Prashant P. Shahb654f872010-09-06 17:34:26 +05301969 testvga2_tempbh = 0x00;
1970 testvga2_tempbl = 0xd1;
1971 testsvhs_tempbh = 0x00;
1972 testsvhs_tempbl = 0xb9;
1973 testcvbs_tempbh = 0x00;
1974 testcvbs_tempbl = 0xb3;
1975 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
1976 != VB_CHIP_302)) {
1977 testvga2_tempbh = 0x01;
1978 testvga2_tempbl = 0x90;
1979 testsvhs_tempbh = 0x01;
1980 testsvhs_tempbl = 0x6b;
1981 testcvbs_tempbh = 0x01;
1982 testcvbs_tempbl = 0x74;
1983 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
1984 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
1985 testvga2_tempbh = 0x00;
1986 testvga2_tempbl = 0x00;
1987 testsvhs_tempbh = 0x02;
1988 testsvhs_tempbl = 0x00;
1989 testcvbs_tempbh = 0x01;
1990 testcvbs_tempbl = 0x00;
1991 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001992 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301993 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
1994 != VB_CHIP_302LV) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001995 myflag = xgifb_reg_get(XGIPART4, 0x01);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301996 if (myflag & 0x04) {
1997 testvga2_tempbh = 0x00;
1998 testvga2_tempbl = 0xfd;
1999 testsvhs_tempbh = 0x00;
2000 testsvhs_tempbl = 0xdd;
2001 testcvbs_tempbh = 0x00;
2002 testcvbs_tempbl = 0xee;
2003 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002004 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302005 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
2006 == VB_CHIP_302LV)) {
2007 testvga2_tempbh = 0x00;
2008 testvga2_tempbl = 0x00;
2009 testvga2_tempch = 0x00;
2010 testvga2_tempcl = 0x00;
2011 testsvhs_tempch = 0x04;
2012 testsvhs_tempcl = 0x08;
2013 testcvbs_tempch = 0x08;
2014 testcvbs_tempcl = 0x08;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002015 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302016 testvga2_tempch = 0x0e;
2017 testvga2_tempcl = 0x08;
2018 testsvhs_tempch = 0x06;
2019 testsvhs_tempcl = 0x04;
2020 testcvbs_tempch = 0x08;
2021 testcvbs_tempcl = 0x04;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002022 }
2023
Prashant P. Shahb654f872010-09-06 17:34:26 +05302024 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
2025 || testvga2_tempbl) {
2026 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
2027 testvga2_tempcl, testvga2_tempch);
2028 if (result) {
2029 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002030 xgifb_reg_or(XGICR, 0x32, 0x10);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302031 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002032 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002033
Prashant P. Shahb654f872010-09-06 17:34:26 +05302034 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
2035 testsvhs_tempch);
2036 if (result) {
2037 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
2038 /* TW: So we can be sure that there IS a SVHS output */
2039 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002040 xgifb_reg_or(XGICR, 0x32, 0x02);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002041 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002042
Prashant P. Shahb654f872010-09-06 17:34:26 +05302043 if (!result) {
2044 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
2045 testcvbs_tempcl, testcvbs_tempch);
2046 if (result) {
2047 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
2048 /* TW: So we can be sure that there IS a CVBS output */
2049 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002050 xgifb_reg_or(XGICR, 0x32, 0x01);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302051 }
2052 }
2053 XGIDoSense(0, 0, 0, 0);
2054
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002055 xgifb_reg_set(XGIPART4, 0x0d, backupP4_0d);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002056}
2057
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002058XGIINITSTATIC int __init XGIfb_setup(char *options)
2059{
2060 char *this_opt;
2061
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002062 xgi_video_info.refresh_rate = 0;
2063
Prashant P. Shahb654f872010-09-06 17:34:26 +05302064 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002065
2066 if (!options || !*options)
2067 return 0;
2068
Prashant P. Shahb654f872010-09-06 17:34:26 +05302069 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002070
Prashant P. Shahb654f872010-09-06 17:34:26 +05302071 if (!*this_opt)
2072 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002073
2074 if (!strncmp(this_opt, "mode:", 5)) {
2075 XGIfb_search_mode(this_opt + 5);
2076 } else if (!strncmp(this_opt, "vesa:", 5)) {
2077 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2078 } else if (!strncmp(this_opt, "mode:", 5)) {
2079 XGIfb_search_mode(this_opt + 5);
2080 } else if (!strncmp(this_opt, "vesa:", 5)) {
2081 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2082 } else if (!strncmp(this_opt, "vrate:", 6)) {
2083 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2084 } else if (!strncmp(this_opt, "rate:", 5)) {
2085 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2086 } else if (!strncmp(this_opt, "off", 3)) {
2087 XGIfb_off = 1;
2088 } else if (!strncmp(this_opt, "crt1off", 7)) {
2089 XGIfb_crt1off = 1;
2090 } else if (!strncmp(this_opt, "filter:", 7)) {
2091 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2092 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2093 XGIfb_search_crt2type(this_opt + 14);
2094 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2095 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302096 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002097 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302098 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2099 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302100 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002101 enable_dstn = 1;
2102 /* TW: DSTN overrules forcecrt2type */
2103 XGIfb_crt2type = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002104 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302105 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2106 if (XGIfb_pdc & ~0x3c) {
2107 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2108 XGIfb_pdc = 0;
2109 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002110 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302111 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002112 } else if (!strncmp(this_opt, "userom:", 7)) {
2113 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302114 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2115 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002116 } else {
2117 XGIfb_search_mode(this_opt);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302118 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002119 }
2120
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002121 /* TW: Panning only with acceleration */
Javier Martinez Canillas0089bf12011-02-21 18:16:43 +01002122 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002123
2124 }
2125 printk("\nxgifb: outa xgifb_setup 3450");
2126 return 0;
2127}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002128
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002129static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002130{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002131 void __iomem *rom_address;
2132 unsigned char *rom_copy;
2133 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002134
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002135 rom_address = pci_map_rom(dev, &rom_size);
2136 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002137 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002138
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002139 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2140 if (rom_copy == NULL)
2141 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002142
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002143 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2144 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002145
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002146done:
2147 pci_unmap_rom(dev, rom_address);
2148 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002149}
2150
Randy Dunlap89229672010-08-10 08:46:44 -07002151static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302152 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002153{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302154 u8 reg, reg1;
2155 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002156 int ret;
2157
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002158 if (XGIfb_off)
2159 return -ENXIO;
2160
2161 XGIfb_registered = 0;
2162
Bill Pembertone4147ab2010-06-17 13:10:50 -04002163 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302164 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2165 if (!fb_info)
2166 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002167
Prashant P. Shahb654f872010-09-06 17:34:26 +05302168 xgi_video_info.chip_id = pdev->device;
2169 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302170 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002171
Prashant P. Shahb654f872010-09-06 17:34:26 +05302172 xgi_video_info.pcibus = pdev->bus->number;
2173 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2174 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2175 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2176 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002177
Prashant P. Shahb654f872010-09-06 17:34:26 +05302178 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2179 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002180 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302181 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2182 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2183 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2184 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2185 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002186
Aaro Koskinenbb292232011-02-17 23:29:11 +02002187 if (pci_enable_device(pdev)) {
2188 ret = -EIO;
2189 goto error;
2190 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002191
Prashant P. Shahb654f872010-09-06 17:34:26 +05302192 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002193
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002194 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002195 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002196
Prashant P. Shahb654f872010-09-06 17:34:26 +05302197 if (reg1 != 0xa1) { /*I/O error */
2198 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002199 ret = -EIO;
2200 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302201 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002202
2203 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302204 case PCI_DEVICE_ID_XG_20:
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002205 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002206 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002207 if (CR48&GPIOG_READ)
2208 xgi_video_info.chip = XG21;
2209 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302210 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002211 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2212 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302213 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002214 xgi_video_info.chip = XG40;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002215 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2216 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302217 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002218 xgi_video_info.chip = XG41;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002219 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2220 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302221 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002222 xgi_video_info.chip = XG42;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002223 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2224 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302225 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002226 xgi_video_info.chip = XG27;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002227 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2228 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302229 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002230 ret = -ENODEV;
2231 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002232 }
2233
Prashant P. Shahb654f872010-09-06 17:34:26 +05302234 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2235 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002236
Prashant P. Shahb654f872010-09-06 17:34:26 +05302237 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002238 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302239 if (XGIhw_ext.pjVirtualRomBase)
2240 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002241 else
2242 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302243 } else {
2244 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002245 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302246 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302247 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002248
Prashant P. Shahb654f872010-09-06 17:34:26 +05302249 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302250 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002251 ret = -ENODEV;
2252 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302253 }
2254
2255 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2256 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002257 xgifb_reg_or(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302258 /* Enable 2D accelerator engine */
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002259 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302260 }
2261
2262 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2263
2264 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
2265 printk("unable request memory size %x", xgi_video_info.video_size);
2266 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2267 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002268 ret = -ENODEV;
2269 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302270 }
2271
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002272 if (!request_mem_region(xgi_video_info.mmio_base,
2273 xgi_video_info.mmio_size,
2274 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302275 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002276 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002277 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302278 }
2279
2280 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2281 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002282 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2283 xgi_video_info.mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302284
2285 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2286 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
2287
2288 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002289 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2290 xgi_video_info.mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302291 printk("XGIfb: XGIInitNew() ...");
2292 if (XGIInitNew(&XGIhw_ext))
2293 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002294 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002295 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002296
Prashant P. Shahb654f872010-09-06 17:34:26 +05302297 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002298
Prashant P. Shahb654f872010-09-06 17:34:26 +05302299 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002300 xgi_video_info.hasVB = HASVB_NONE;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302301 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
2302 xgi_video_info.hasVB = HASVB_NONE;
2303 } else if (xgi_video_info.chip == XG21) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002304 CR38 = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302305 if ((CR38&0xE0) == 0xC0) {
2306 xgi_video_info.disp_state = DISPTYPE_LCD;
2307 if (!XGIfb_GetXG21LVDSData()) {
2308 int m;
2309 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2310 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2311 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
Aaro Koskinen8104e322011-03-13 12:26:22 +02002312 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302313 }
2314 }
2315 }
2316 } else if ((CR38&0xE0) == 0x60) {
2317 xgi_video_info.hasVB = HASVB_CHRONTEL;
2318 } else {
2319 xgi_video_info.hasVB = HASVB_NONE;
2320 }
2321 } else {
2322 XGIfb_get_VB_type();
2323 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002324
Prashant P. Shahb654f872010-09-06 17:34:26 +05302325 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002326
Prashant P. Shahb654f872010-09-06 17:34:26 +05302327 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002328
2329 switch (xgi_video_info.hasVB) {
2330 case HASVB_301:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002331 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002332 if (reg >= 0xE0) {
2333 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302334 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2335 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002336 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302337 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2338 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002339 /* else if (reg >= 0xB0) {
2340 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002341 reg1 = xgifb_reg_get(XGIPART4, 0x23);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302342 printk("XGIfb: XGI301B bridge detected\n");
2343 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002344 else {
2345 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2346 printk("XGIfb: XGI301 bridge detected\n");
2347 }
2348 break;
2349 case HASVB_302:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002350 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002351 if (reg >= 0xE0) {
2352 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302353 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2354 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002355 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302356 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2357 } else if (reg >= 0xB0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002358 reg1 = xgifb_reg_get(XGIPART4, 0x23);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002359
Prashant P. Shahb654f872010-09-06 17:34:26 +05302360 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002361
2362 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302363 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002364 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2365 }
2366 break;
2367 case HASVB_LVDS:
2368 XGIhw_ext.ulExternalChip = 0x1;
2369 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2370 break;
2371 case HASVB_TRUMPION:
2372 XGIhw_ext.ulExternalChip = 0x2;
2373 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2374 break;
2375 case HASVB_CHRONTEL:
2376 XGIhw_ext.ulExternalChip = 0x4;
2377 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2378 break;
2379 case HASVB_LVDS_CHRONTEL:
2380 XGIhw_ext.ulExternalChip = 0x5;
2381 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2382 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302383 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002384 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2385 break;
2386 }
2387
Prashant P. Shahb654f872010-09-06 17:34:26 +05302388 if (xgi_video_info.hasVB != HASVB_NONE)
2389 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002390
2391 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2392 if (XGIfb_crt1off)
2393 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2394 else
2395 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
2396 } else {
2397 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
2398 }
2399
2400 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302401 if (!enable_dstn) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002402 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302403 reg &= 0x0f;
2404 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002405
Prashant P. Shahb654f872010-09-06 17:34:26 +05302406 } else {
2407 /* TW: FSTN/DSTN */
2408 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2409 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002410 }
2411
2412 XGIfb_detectedpdc = 0;
2413
Prashant P. Shahb654f872010-09-06 17:34:26 +05302414 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002415
Prashant P. Shahb654f872010-09-06 17:34:26 +05302416 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002417
Prashant P. Shahb654f872010-09-06 17:34:26 +05302418 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2419 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2420 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2421 int tmp;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002422 tmp = xgifb_reg_get(XGICR, 0x34);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302423 if (tmp <= 0x13) {
2424 /* Currently on LCDA? (Some BIOSes leave CR38) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002425 tmp = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302426 if ((tmp & 0x03) == 0x03) {
2427 /* XGI_Pr.XGI_UseLCDA = 1; */
2428 } else {
2429 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002430 tmp = xgifb_reg_get(XGICR, 0x35);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302431 if (tmp & 0x01) {
2432 /* XGI_Pr.XGI_UseLCDA = 1; */
2433 } else {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002434 tmp = xgifb_reg_get(XGICR, 0x30);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302435 if (tmp & 0x20) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002436 tmp = xgifb_reg_get(XGIPART1, 0x13);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302437 if (tmp & 0x04) {
2438 /* XGI_Pr.XGI_UseLCDA = 1; */
2439 }
2440 }
2441 }
2442 }
2443 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002444
Prashant P. Shahb654f872010-09-06 17:34:26 +05302445 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002446
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002447 if (xgifb_mode_idx >= 0)
2448 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2449
2450 if (xgifb_mode_idx < 0) {
2451 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302452 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002453 xgifb_mode_idx = DEFAULT_LCDMODE;
2454 if (xgi_video_info.chip == XG21)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302455 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002456 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302457 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002458 xgifb_mode_idx = DEFAULT_TVMODE;
2459 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302460 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002461 xgifb_mode_idx = DEFAULT_MODE;
2462 break;
2463 }
2464 }
2465
2466 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2467
Prashant P. Shahb654f872010-09-06 17:34:26 +05302468 if (xgi_video_info.refresh_rate == 0)
2469 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
2470 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
2471 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2472 xgi_video_info.refresh_rate = 60;
2473 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002474
2475 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2476 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
2477 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
2478 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2479 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302480 switch (xgi_video_info.video_bpp) {
2481 case 8:
2482 xgi_video_info.DstColor = 0x0000;
2483 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002484 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302485 break;
2486 case 16:
2487 xgi_video_info.DstColor = 0x8000;
2488 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002489 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302490 break;
2491 case 32:
2492 xgi_video_info.DstColor = 0xC000;
2493 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002494 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302495 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002496 default:
2497 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302498 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002499 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302500 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002501
2502 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302503 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
2504 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002505
2506 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
2507 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
2508 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2509
2510 XGIfb_bpp_to_var(&default_var);
2511
2512 default_var.pixclock = (u32) (1000000000 /
2513 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2514 XGIfb_mode_no, XGIfb_rate_idx));
2515
Prashant P. Shahb654f872010-09-06 17:34:26 +05302516 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2517 XGIfb_mode_no, XGIfb_rate_idx,
2518 &default_var.left_margin, &default_var.right_margin,
2519 &default_var.upper_margin, &default_var.lower_margin,
2520 &default_var.hsync_len, &default_var.vsync_len,
2521 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002522
Prashant P. Shahb654f872010-09-06 17:34:26 +05302523 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
2524 default_var.yres <<= 1;
2525 default_var.yres_virtual <<= 1;
2526 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
2527 default_var.pixclock >>= 1;
2528 default_var.yres >>= 1;
2529 default_var.yres_virtual >>= 1;
2530 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002531
Prashant P. Shahb654f872010-09-06 17:34:26 +05302532 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002533
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002534 fb_info->flags = FBINFO_FLAG_DEFAULT;
2535 fb_info->var = default_var;
2536 fb_info->fix = XGIfb_fix;
2537 fb_info->par = &xgi_video_info;
2538 fb_info->screen_base = xgi_video_info.video_vbase;
2539 fb_info->fbops = &XGIfb_ops;
2540 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2541 fb_info->pseudo_palette = pseudo_palette;
2542
2543 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2544
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002545#ifdef CONFIG_MTRR
2546 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
2547 (unsigned int) xgi_video_info.video_size,
2548 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302549 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002550 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002551#endif
2552
Aaro Koskinenbb292232011-02-17 23:29:11 +02002553 if (register_framebuffer(fb_info) < 0) {
2554 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002555 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002556 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002557
2558 XGIfb_registered = 1;
2559
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002560 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302561 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002562
2563 }
2564
2565 dumpVGAReg();
2566
2567 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002568
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002569error_1:
2570 iounmap(xgi_video_info.mmio_vbase);
2571 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002572 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002573error_0:
2574 release_mem_region(xgi_video_info.video_base,
2575 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002576error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002577 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002578 framebuffer_release(fb_info);
2579 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002580}
2581
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002582/*****************************************************/
2583/* PCI DEVICE HANDLING */
2584/*****************************************************/
2585
2586static void __devexit xgifb_remove(struct pci_dev *pdev)
2587{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302588 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002589 iounmap(xgi_video_info.mmio_vbase);
2590 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002591 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002592 release_mem_region(xgi_video_info.video_base,
2593 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002594 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302595 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002596 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02002597}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002598
2599static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302600 .name = "xgifb",
2601 .id_table = xgifb_pci_table,
2602 .probe = xgifb_probe,
2603 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002604};
2605
2606XGIINITSTATIC int __init xgifb_init(void)
2607{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002608 char *option = NULL;
2609
2610 if (fb_get_options("xgifb", &option))
2611 return -ENODEV;
2612 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04002613
Prashant P. Shahb654f872010-09-06 17:34:26 +05302614 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002615}
2616
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002617#ifndef MODULE
2618module_init(xgifb_init);
2619#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002620
2621/*****************************************************/
2622/* MODULE */
2623/*****************************************************/
2624
2625#ifdef MODULE
2626
Prashant P. Shahb654f872010-09-06 17:34:26 +05302627static char *mode = NULL;
2628static int vesa = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002629static unsigned int rate = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002630static unsigned int mem = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302631static char *forcecrt2type = NULL;
2632static int forcecrt1 = -1;
2633static int pdc = -1;
2634static int pdc1 = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302635static int noypan = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302636static int userom = -1;
2637static int useoem = -1;
2638static char *tvstandard = NULL;
2639static int nocrt2rate = 0;
2640static int scalelcd = -1;
2641static char *specialtiming = NULL;
2642static int lvdshl = -1;
2643static int tvxposoffset = 0, tvyposoffset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002644#if !defined(__i386__) && !defined(__x86_64__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302645static int resetcard = 0;
2646static int videoram = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002647#endif
2648
2649MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2650MODULE_LICENSE("GPL");
2651MODULE_AUTHOR("XGITECH , Others");
2652
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002653module_param(mem, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002654module_param(noypan, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002655module_param(userom, int, 0);
2656module_param(useoem, int, 0);
2657module_param(mode, charp, 0);
2658module_param(vesa, int, 0);
2659module_param(rate, int, 0);
2660module_param(forcecrt1, int, 0);
2661module_param(forcecrt2type, charp, 0);
2662module_param(scalelcd, int, 0);
2663module_param(pdc, int, 0);
2664module_param(pdc1, int, 0);
2665module_param(specialtiming, charp, 0);
2666module_param(lvdshl, int, 0);
2667module_param(tvstandard, charp, 0);
2668module_param(tvxposoffset, int, 0);
2669module_param(tvyposoffset, int, 0);
2670module_param(filter, int, 0);
2671module_param(nocrt2rate, int, 0);
2672#if !defined(__i386__) && !defined(__x86_64__)
2673module_param(resetcard, int, 0);
2674module_param(videoram, int, 0);
2675#endif
2676
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002677MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302678 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2679 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002680
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002681MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302682 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2683 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2684 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2685 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002686
2687MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302688 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2689 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002690
2691MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302692 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2693 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2694 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002695
2696MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302697 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2698 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2699 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002700
2701MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302702 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2703 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2704 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2705 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2706 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2707 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2708 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2709 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002710
2711MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302712 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2713 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2714 "show black bars around the image, TMDS panels will probably do the scaling\n"
2715 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002716
2717MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302718 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2719 "should detect this correctly in most cases; however, sometimes this is not\n"
2720 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2721 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2722 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2723 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002724
2725MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302726 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2727 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2728 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2729 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002730
2731MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302732 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002733
2734MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302735 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002736
2737MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302738 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2739 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002740
2741MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302742 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2743 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002744
2745MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302746 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2747 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002748
2749MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302750 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2751 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002752
2753MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302754 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2755 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002756
Randy Dunlap89229672010-08-10 08:46:44 -07002757static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002758{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302759 printk("\nXGIfb_init_module");
2760 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002761 XGIfb_search_mode(mode);
2762 else if (vesa != -1)
2763 XGIfb_search_vesamode(vesa);
2764
Prashant P. Shahb654f872010-09-06 17:34:26 +05302765 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002766}
2767
2768static void __exit xgifb_remove_module(void)
2769{
2770 pci_unregister_driver(&xgifb_driver);
2771 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2772}
2773
2774module_init(xgifb_init_module);
2775module_exit(xgifb_remove_module);
2776
Prashant P. Shahb654f872010-09-06 17:34:26 +05302777#endif /* /MODULE */