blob: df27dfed7560456343d638bddace64a73aa192f0 [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/module.h>
9#include <linux/moduleparam.h>
10#include <linux/kernel.h>
11#include <linux/spinlock.h>
12#include <linux/errno.h>
13#include <linux/string.h>
14#include <linux/mm.h>
15#include <linux/tty.h>
16#include <linux/slab.h>
17#include <linux/delay.h>
18#include <linux/fb.h>
19#include <linux/console.h>
20#include <linux/selection.h>
21#include <linux/ioport.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/vmalloc.h>
25#include <linux/vt_kern.h>
26#include <linux/capability.h>
27#include <linux/fs.h>
28#include <linux/types.h>
29#include <linux/proc_fs.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020030
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020031#ifndef XGIFB_PAN
32#define XGIFB_PAN
33#endif
34
Kenji Toyamaa12c27c2011-04-26 12:13:43 +080035#include <linux/io.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020036#ifdef CONFIG_MTRR
37#include <asm/mtrr.h>
38#endif
39
40#include "XGIfb.h"
41#include "vgatypes.h"
42#include "XGI_main.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030043#include "vb_init.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020044#include "vb_util.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030045#include "vb_setmode.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020046
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020047#define Index_CR_GPIO_Reg1 0x48
48#define Index_CR_GPIO_Reg2 0x49
49#define Index_CR_GPIO_Reg3 0x4a
50
51#define GPIOG_EN (1<<6)
52#define GPIOG_WRITE (1<<6)
53#define GPIOG_READ (1<<1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020054
Aaro Koskinen0f07d942011-02-17 23:29:13 +020055#define XGIFB_ROM_SIZE 65536
56
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020057/* -------------------- Macro definitions ---------------------------- */
58
59#undef XGIFBDEBUG
60
61#ifdef XGIFBDEBUG
62#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63#else
64#define DPRINTK(fmt, args...)
65#endif
66
67#ifdef XGIFBDEBUG
68static void dumpVGAReg(void)
69{
Prashant P. Shahb654f872010-09-06 17:34:26 +053070 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020071
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030072 xgifb_reg_set(XGISR, 0x05, 0x86);
Prashant P. Shahb654f872010-09-06 17:34:26 +053073 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030074 xgifb_reg_set(XGISR, 0x08, 0x4f);
75 xgifb_reg_set(XGISR, 0x0f, 0x20);
76 xgifb_reg_set(XGISR, 0x11, 0x4f);
77 xgifb_reg_set(XGISR, 0x13, 0x45);
78 xgifb_reg_set(XGISR, 0x14, 0x51);
79 xgifb_reg_set(XGISR, 0x1e, 0x41);
80 xgifb_reg_set(XGISR, 0x1f, 0x0);
81 xgifb_reg_set(XGISR, 0x20, 0xa1);
82 xgifb_reg_set(XGISR, 0x22, 0xfb);
83 xgifb_reg_set(XGISR, 0x26, 0x22);
84 xgifb_reg_set(XGISR, 0x3e, 0x07);
Prashant P. Shahb654f872010-09-06 17:34:26 +053085 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020086
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030087 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
88 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
89 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
90 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020091
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030092 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020093
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030094 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
95 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020096
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030097 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
98 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
Prashant P. Shahb654f872010-09-06 17:34:26 +053099 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300100 xgifb_reg_set(XGICR, 0x99, 0x1);
101 xgifb_reg_set(XGICR, 0x41, 0x40);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530102 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200103
Prashant P. Shahb654f872010-09-06 17:34:26 +0530104 for (i = 0; i < 0x4f; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300105 reg = xgifb_reg_get(XGISR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
108 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200109
Prashant P. Shahb654f872010-09-06 17:34:26 +0530110 for (i = 0; i < 0xF0; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300111 reg = xgifb_reg_get(XGICR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530112 printk("\no 3d4 %x", i);
113 printk("\ni 3d5 => %x", reg);
114 }
115 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300116 xgifb_reg_set(XGIPART1,0x2F,1);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530117 for (i=1; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300118 reg = xgifb_reg_get(XGIPART1, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530119 printk("\no d004 %x", i);
120 printk("\ni d005 => %x", reg);
121 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200122
Prashant P. Shahb654f872010-09-06 17:34:26 +0530123 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300124 reg = xgifb_reg_get(XGIPART2, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530125 printk("\no d010 %x", i);
126 printk("\ni d011 => %x", reg);
127 }
128 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300129 reg = xgifb_reg_get(XGIPART3, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530130 printk("\no d012 %x",i);
131 printk("\ni d013 => %x",reg);
132 }
133 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300134 reg = xgifb_reg_get(XGIPART4, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530135 printk("\no d014 %x",i);
136 printk("\ni d015 => %x",reg);
137 }
138 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200139}
140#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530141static inline void dumpVGAReg(void)
142{
143}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200144#endif
145
146/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530147struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200148
149#if 1
150#define DEBUGPRN(x)
151#else
152#define DEBUGPRN(x) printk(KERN_INFO x "\n");
153#endif
154
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200155/* --------------- Hardware Access Routines -------------------------- */
156
Prashant P. Shahb654f872010-09-06 17:34:26 +0530157static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 struct xgi_hw_device_info *HwDeviceExtension,
159 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200160{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200164
Prashant P. Shahb654f872010-09-06 17:34:26 +0530165 /* unsigned long temp = 0; */
166 int Clock;
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200169
Prashant P. Shahb654f872010-09-06 17:34:26 +0530170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200172
Prashant P. Shahb654f872010-09-06 17:34:26 +0530173 /*
174 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
175 if (!temp) {
176 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
177 return 65000;
178 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200179
Prashant P. Shahb654f872010-09-06 17:34:26 +0530180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200182
Prashant P. Shahb654f872010-09-06 17:34:26 +0530183 */
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200185
Prashant P. Shahb654f872010-09-06 17:34:26 +0530186 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
187
188 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200189}
190
Prashant P. Shahb654f872010-09-06 17:34:26 +0530191static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192 struct xgi_hw_device_info *HwDeviceExtension,
193 unsigned char modeno, unsigned char rateindex,
194 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
196 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200197{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530198 unsigned short ModeNo = modeno;
199 unsigned short ModeIdIndex = 0, index = 0;
200 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200201
Prashant P. Shahb654f872010-09-06 17:34:26 +0530202 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204 unsigned char sr_data, cr_data, cr_data2;
205 unsigned long cr_data3;
206 int A, B, C, D, E, F, temp, j;
207 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210 ModeIdIndex, XGI_Pr);
211 /*
212 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
213 if (!temp)
214 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200215
Prashant P. Shahb654f872010-09-06 17:34:26 +0530216 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217 RefreshRateTableIndex += (rateindex - 1);
218 */
219 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200220
Prashant P. Shahb654f872010-09-06 17:34:26 +0530221 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200222
Prashant P. Shahb654f872010-09-06 17:34:26 +0530223 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200224
Prashant P. Shahb654f872010-09-06 17:34:26 +0530225 /* Horizontal total */
226 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
227 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200228
Prashant P. Shahb654f872010-09-06 17:34:26 +0530229 /*
230 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200231
Prashant P. Shahb654f872010-09-06 17:34:26 +0530232 Horizontal display enable end
233 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
234 */
235 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
236 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200237
Prashant P. Shahb654f872010-09-06 17:34:26 +0530238 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200239
Prashant P. Shahb654f872010-09-06 17:34:26 +0530240 /* Horizontal retrace (=sync) start */
241 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
242 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200243
Prashant P. Shahb654f872010-09-06 17:34:26 +0530244 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200245
Prashant P. Shahb654f872010-09-06 17:34:26 +0530246 /* Horizontal blank start */
247 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200248
Prashant P. Shahb654f872010-09-06 17:34:26 +0530249 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200250
Prashant P. Shahb654f872010-09-06 17:34:26 +0530251 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200252
Prashant P. Shahb654f872010-09-06 17:34:26 +0530253 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200254
Prashant P. Shahb654f872010-09-06 17:34:26 +0530255 /* Horizontal blank end */
256 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200258
Prashant P. Shahb654f872010-09-06 17:34:26 +0530259 /* Horizontal retrace (=sync) end */
260 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200261
Prashant P. Shahb654f872010-09-06 17:34:26 +0530262 temp = HBE - ((E - 1) & 255);
263 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200264
Prashant P. Shahb654f872010-09-06 17:34:26 +0530265 temp = HRE - ((E + F + 3) & 63);
266 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200267
Prashant P. Shahb654f872010-09-06 17:34:26 +0530268 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200269
Prashant P. Shahb654f872010-09-06 17:34:26 +0530270 *left_margin = D * 8;
271 *right_margin = F * 8;
272 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200273
Prashant P. Shahb654f872010-09-06 17:34:26 +0530274 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200275
Prashant P. Shahb654f872010-09-06 17:34:26 +0530276 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200277
Prashant P. Shahb654f872010-09-06 17:34:26 +0530278 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200279
Prashant P. Shahb654f872010-09-06 17:34:26 +0530280 /* Vertical total */
281 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282 | ((unsigned short) (cr_data2 & 0x20) << 4)
283 | ((unsigned short) (sr_data & 0x01) << 10);
284 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200285
Prashant P. Shahb654f872010-09-06 17:34:26 +0530286 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200287
Prashant P. Shahb654f872010-09-06 17:34:26 +0530288 /* Vertical display enable end */
289 /*
290 VDE = (cr_data & 0xff) |
291 ((unsigned short) (cr_data2 & 0x02) << 7) |
292 ((unsigned short) (cr_data2 & 0x40) << 3) |
293 ((unsigned short) (sr_data & 0x02) << 9);
294 */
295 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
296 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200297
Prashant P. Shahb654f872010-09-06 17:34:26 +0530298 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200299
Prashant P. Shahb654f872010-09-06 17:34:26 +0530300 /* Vertical retrace (=sync) start */
301 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302 | ((unsigned short) (cr_data2 & 0x80) << 2)
303 | ((unsigned short) (sr_data & 0x08) << 7);
304 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200305
Prashant P. Shahb654f872010-09-06 17:34:26 +0530306 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200307
Prashant P. Shahb654f872010-09-06 17:34:26 +0530308 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200309
Prashant P. Shahb654f872010-09-06 17:34:26 +0530310 /* Vertical blank start */
311 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312 | ((unsigned short) (cr_data3 & 0x20) << 4)
313 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200314
Prashant P. Shahb654f872010-09-06 17:34:26 +0530315 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200316
Prashant P. Shahb654f872010-09-06 17:34:26 +0530317 /* Vertical blank end */
318 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319 temp = VBE - ((E - 1) & 511);
320 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200321
Prashant P. Shahb654f872010-09-06 17:34:26 +0530322 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200323
Prashant P. Shahb654f872010-09-06 17:34:26 +0530324 /* Vertical retrace (=sync) end */
325 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326 temp = VRE - ((E + F - 1) & 31);
327 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200328
Prashant P. Shahb654f872010-09-06 17:34:26 +0530329 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200330
Prashant P. Shahb654f872010-09-06 17:34:26 +0530331 *upper_margin = D;
332 *lower_margin = F;
333 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200334
Prashant P. Shahb654f872010-09-06 17:34:26 +0530335 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
337 else
338 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200339
Prashant P. Shahb654f872010-09-06 17:34:26 +0530340 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
342 else
343 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200344
Prashant P. Shahb654f872010-09-06 17:34:26 +0530345 *vmode = FB_VMODE_NONINTERLACED;
346 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347 *vmode = FB_VMODE_INTERLACED;
348 else {
349 j = 0;
350 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800351 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
352 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
354 DoubleScanMode) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530355 *vmode = FB_VMODE_DOUBLE;
356 }
357 break;
358 }
359 j++;
360 }
361 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200362
Prashant P. Shahb654f872010-09-06 17:34:26 +0530363 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200364}
365
Randy Dunlap89229672010-08-10 08:46:44 -0700366static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200367{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530368 XGI_Pr->RelIO = BaseAddr;
369 XGI_Pr->P3c4 = BaseAddr + 0x14;
370 XGI_Pr->P3d4 = BaseAddr + 0x24;
371 XGI_Pr->P3c0 = BaseAddr + 0x10;
372 XGI_Pr->P3ce = BaseAddr + 0x1e;
373 XGI_Pr->P3c2 = BaseAddr + 0x12;
374 XGI_Pr->P3ca = BaseAddr + 0x1a;
375 XGI_Pr->P3c6 = BaseAddr + 0x16;
376 XGI_Pr->P3c7 = BaseAddr + 0x17;
377 XGI_Pr->P3c8 = BaseAddr + 0x18;
378 XGI_Pr->P3c9 = BaseAddr + 0x19;
379 XGI_Pr->P3da = BaseAddr + 0x2A;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800380 /* Digital video interface registers (LCD) */
381 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
382 /* 301 TV Encoder registers */
383 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
384 /* 301 Macrovision registers */
385 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
386 /* 301 VGA2 (and LCD) registers */
387 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
388 /* 301 palette address port registers */
389 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200390
391}
392
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200393/* ------------ Interface for init & mode switching code ------------- */
394
Aaro Koskinen8a94d1a2011-04-18 22:14:08 +0300395static unsigned char XGIfb_query_VGA_config_space(
Prashant P. Shahb654f872010-09-06 17:34:26 +0530396 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
397 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200398{
Ruslan Pisareve684f462011-07-21 11:58:53 +0300399 static struct pci_dev *pdev;
400 static unsigned char init, valid_pdev;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200401
402 if (!set)
403 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
404 else
405 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
406
407 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400408 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530409 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
410 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200411 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400412 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200413 pci_dev_put(pdev);
414 }
415 }
416
417 if (!valid_pdev) {
418 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
419 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400420 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200421 }
422
423 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530424 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200425 else
426 pci_write_config_dword(pdev, offset, (u32)(*value));
427
Bill Pembertondda08c52010-06-17 13:10:42 -0400428 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200429}
430
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200431/* ------------------ Internal helper routines ----------------- */
432
Aaro Koskinen8a94d1a2011-04-18 22:14:08 +0300433static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300434{
435
436 int found_mode = 0;
437 int XGIfb_mode_idx = 0;
438
439 found_mode = 0;
440 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
441 && (XGIbios_mode[XGIfb_mode_idx].xres
442 <= XGI21_LCDCapList[0].LVDSHDE)) {
443 if ((XGIbios_mode[XGIfb_mode_idx].xres
444 == XGI21_LCDCapList[0].LVDSHDE)
445 && (XGIbios_mode[XGIfb_mode_idx].yres
446 == XGI21_LCDCapList[0].LVDSVDE)
447 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
448 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
449 found_mode = 1;
450 break;
451 }
452 XGIfb_mode_idx++;
453 }
454 if (!found_mode)
455 XGIfb_mode_idx = 0;
456
457 return XGIfb_mode_idx;
458}
459
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200460static void XGIfb_search_mode(const char *name)
461{
462 int i = 0, j = 0, l;
463
Prashant P. Shahb654f872010-09-06 17:34:26 +0530464 if (name == NULL) {
465 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
466 xgifb_mode_idx = DEFAULT_MODE;
467 if ((xgi_video_info.chip == XG21)
468 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
469 == DISPTYPE_LCD)) {
470 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
471 }
472 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200473 }
474
Prashant P. Shahb654f872010-09-06 17:34:26 +0530475 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
476 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
477 xgifb_mode_idx = DEFAULT_MODE;
478 if ((xgi_video_info.chip == XG21)
479 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
480 == DISPTYPE_LCD)) {
481 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
482 }
483 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200484 }
485
Prashant P. Shahb654f872010-09-06 17:34:26 +0530486 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200487 l = min(strlen(name), strlen(XGIbios_mode[i].name));
488 if (!strncmp(name, XGIbios_mode[i].name, l)) {
489 xgifb_mode_idx = i;
490 j = 1;
491 break;
492 }
493 i++;
494 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530495 if (!j)
496 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200497}
498
499static void XGIfb_search_vesamode(unsigned int vesamode)
500{
501 int i = 0, j = 0;
502
Prashant P. Shahb654f872010-09-06 17:34:26 +0530503 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200504
505 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
506 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530507 if ((xgi_video_info.chip == XG21)
508 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
509 == DISPTYPE_LCD)) {
510 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200511 }
512 return;
513 }
514
Prashant P. Shahb654f872010-09-06 17:34:26 +0530515 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200516
Prashant P. Shahb654f872010-09-06 17:34:26 +0530517 while (XGIbios_mode[i].mode_no != 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800518 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
519 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200520 xgifb_mode_idx = i;
521 j = 1;
522 break;
523 }
524 i++;
525 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530526 if (!j)
527 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200528}
529
Randy Dunlap89229672010-08-10 08:46:44 -0700530static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200531{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530532 u8 tmp;
533 unsigned char *pData;
534 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200535
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300536 tmp = xgifb_reg_get(XGISR, 0x1e);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300537 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200538
Prashant P. Shahb654f872010-09-06 17:34:26 +0530539 pData = xgi_video_info.mmio_vbase + 0x20000;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800540 if ((pData[0x0] == 0x55) &&
541 (pData[0x1] == 0xAA) &&
542 (pData[0x65] & 0x1)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530543 i = pData[0x316] | (pData[0x317] << 8);
544 j = pData[i - 1];
545 if (j == 0xff)
546 j = 1;
547
548 k = 0;
549 do {
550 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
551 | (pData[i + 1] << 8);
552 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
553 + 3] << 8);
554 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
555 + 5] << 8);
556 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
557 + 7] << 8);
558 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
559 + 9] << 8);
560 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
561 + 11] << 8);
562 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
563 + 13] << 8);
564 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
565 | (pData[i + 15] << 8);
566 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
567 | (pData[i + 17] << 8);
568 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
569 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
570 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
571 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
572 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
573 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
574 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
575 i += 25;
576 j--;
577 k++;
578 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
579 / sizeof(struct XGI21_LVDSCapStruct))));
580 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200581 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530582 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200583}
584
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200585static int XGIfb_validate_mode(int myindex)
586{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530587 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200588
Prashant P. Shahb654f872010-09-06 17:34:26 +0530589 if (xgi_video_info.chip == XG21) {
590 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
591 == DISPTYPE_LCD) {
592 xres = XGI21_LCDCapList[0].LVDSHDE;
593 yres = XGI21_LCDCapList[0].LVDSVDE;
594 if (XGIbios_mode[myindex].xres > xres)
595 return -1;
596 if (XGIbios_mode[myindex].yres > yres)
597 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800598 if ((XGIbios_mode[myindex].xres < xres) &&
599 (XGIbios_mode[myindex].yres < yres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530600 if (XGIbios_mode[myindex].bpp > 8)
601 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200602 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530603
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200604 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530605 return myindex;
606
607 }
608
609 /* FIXME: for now, all is valid on XG27 */
610 if (xgi_video_info.chip == XG27)
611 return myindex;
612
613 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
614 return -1;
615
616 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
617 case DISPTYPE_LCD:
618 switch (XGIhw_ext.ulCRT2LCDType) {
619 case LCD_640x480:
620 xres = 640;
621 yres = 480;
622 break;
623 case LCD_800x600:
624 xres = 800;
625 yres = 600;
626 break;
627 case LCD_1024x600:
628 xres = 1024;
629 yres = 600;
630 break;
631 case LCD_1024x768:
632 xres = 1024;
633 yres = 768;
634 break;
635 case LCD_1152x768:
636 xres = 1152;
637 yres = 768;
638 break;
639 case LCD_1280x960:
640 xres = 1280;
641 yres = 960;
642 break;
643 case LCD_1280x768:
644 xres = 1280;
645 yres = 768;
646 break;
647 case LCD_1280x1024:
648 xres = 1280;
649 yres = 1024;
650 break;
651 case LCD_1400x1050:
652 xres = 1400;
653 yres = 1050;
654 break;
655 case LCD_1600x1200:
656 xres = 1600;
657 yres = 1200;
658 break;
659 /* case LCD_320x480: */ /* TW: FSTN */
660 /*
661 xres = 320;
662 yres = 480;
663 break;
664 */
665 default:
666 xres = 0;
667 yres = 0;
668 break;
669 }
670 if (XGIbios_mode[myindex].xres > xres)
671 return -1;
672 if (XGIbios_mode[myindex].yres > yres)
673 return -1;
674 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800675 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530676 switch (XGIbios_mode[myindex].xres) {
677 case 512:
678 if (XGIbios_mode[myindex].yres != 512)
679 return -1;
680 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
681 return -1;
682 break;
683 case 640:
684 if ((XGIbios_mode[myindex].yres != 400)
685 && (XGIbios_mode[myindex].yres
686 != 480))
687 return -1;
688 break;
689 case 800:
690 if (XGIbios_mode[myindex].yres != 600)
691 return -1;
692 break;
693 case 1024:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800694 if ((XGIbios_mode[myindex].yres != 600) &&
695 (XGIbios_mode[myindex].yres != 768))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530696 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800697 if ((XGIbios_mode[myindex].yres == 600) &&
698 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530699 return -1;
700 break;
701 case 1152:
702 if ((XGIbios_mode[myindex].yres) != 768)
703 return -1;
704 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
705 return -1;
706 break;
707 case 1280:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800708 if ((XGIbios_mode[myindex].yres != 768) &&
709 (XGIbios_mode[myindex].yres != 1024))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530710 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800711 if ((XGIbios_mode[myindex].yres == 768) &&
712 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530713 return -1;
714 break;
715 case 1400:
716 if (XGIbios_mode[myindex].yres != 1050)
717 return -1;
718 break;
719 case 1600:
720 if (XGIbios_mode[myindex].yres != 1200)
721 return -1;
722 break;
723 default:
724 return -1;
725 }
726 } else {
727 switch (XGIbios_mode[myindex].xres) {
728 case 512:
729 if (XGIbios_mode[myindex].yres != 512)
730 return -1;
731 break;
732 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800733 if ((XGIbios_mode[myindex].yres != 400) &&
734 (XGIbios_mode[myindex].yres != 480))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530735 return -1;
736 break;
737 case 800:
738 if (XGIbios_mode[myindex].yres != 600)
739 return -1;
740 break;
741 case 1024:
742 if (XGIbios_mode[myindex].yres != 768)
743 return -1;
744 break;
745 case 1280:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800746 if ((XGIbios_mode[myindex].yres != 960) &&
747 (XGIbios_mode[myindex].yres != 1024))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530748 return -1;
749 if (XGIbios_mode[myindex].yres == 960) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800750 if (XGIhw_ext.ulCRT2LCDType ==
751 LCD_1400x1050)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530752 return -1;
753 }
754 break;
755 case 1400:
756 if (XGIbios_mode[myindex].yres != 1050)
757 return -1;
758 break;
759 case 1600:
760 if (XGIbios_mode[myindex].yres != 1200)
761 return -1;
762 break;
763 default:
764 return -1;
765 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200766 }
767 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530768 case DISPTYPE_TV:
769 switch (XGIbios_mode[myindex].xres) {
770 case 512:
771 case 640:
772 case 800:
773 break;
774 case 720:
775 if (xgi_video_info.TV_type == TVMODE_NTSC) {
776 if (XGIbios_mode[myindex].yres != 480)
777 return -1;
778 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
779 if (XGIbios_mode[myindex].yres != 576)
780 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200781 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530782 /* TW: LVDS/CHRONTEL does not support 720 */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800783 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
784 xgi_video_info.hasVB == HASVB_CHRONTEL) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530785 return -1;
786 }
787 break;
788 case 1024:
789 if (xgi_video_info.TV_type == TVMODE_NTSC) {
790 if (XGIbios_mode[myindex].bpp == 32)
791 return -1;
792 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530793 break;
794 default:
795 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200796 }
797 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530798 case DISPTYPE_CRT2:
799 if (XGIbios_mode[myindex].xres > 1280)
800 return -1;
801 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200802 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530803 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200804
805}
806
807static void XGIfb_search_crt2type(const char *name)
808{
809 int i = 0;
810
Prashant P. Shahb654f872010-09-06 17:34:26 +0530811 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200812 return;
813
Prashant P. Shahb654f872010-09-06 17:34:26 +0530814 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200815 if (!strcmp(name, XGI_crt2type[i].name)) {
816 XGIfb_crt2type = XGI_crt2type[i].type_no;
817 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
818 break;
819 }
820 i++;
821 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530822 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200823 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
824}
825
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200826static u8 XGIfb_search_refresh_rate(unsigned int rate)
827{
828 u16 xres, yres;
829 int i = 0;
830
831 xres = XGIbios_mode[xgifb_mode_idx].xres;
832 yres = XGIbios_mode[xgifb_mode_idx].yres;
833
834 XGIfb_rate_idx = 0;
835 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800836 if ((XGIfb_vrate[i].xres == xres) &&
837 (XGIfb_vrate[i].yres == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200838 if (XGIfb_vrate[i].refresh == rate) {
839 XGIfb_rate_idx = XGIfb_vrate[i].idx;
840 break;
841 } else if (XGIfb_vrate[i].refresh > rate) {
842 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
843 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800844 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200845 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800846 xgi_video_info.refresh_rate =
847 XGIfb_vrate[i].refresh;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530848 } else if (((rate - XGIfb_vrate[i - 1].refresh)
849 <= 2) && (XGIfb_vrate[i].idx
850 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200851 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800852 rate, XGIfb_vrate[i-1].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530853 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800854 xgi_video_info.refresh_rate =
855 XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200856 }
857 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530858 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200859 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800860 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530861 XGIfb_rate_idx = XGIfb_vrate[i].idx;
862 break;
863 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200864 }
865 i++;
866 }
867 if (XGIfb_rate_idx > 0) {
868 return XGIfb_rate_idx;
869 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800870 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
871 rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200872 return 0;
873 }
874}
875
876static void XGIfb_search_tvstd(const char *name)
877{
878 int i = 0;
879
Prashant P. Shahb654f872010-09-06 17:34:26 +0530880 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200881 return;
882
883 while (XGI_tvtype[i].type_no != -1) {
884 if (!strcmp(name, XGI_tvtype[i].name)) {
885 XGIfb_tvmode = XGI_tvtype[i].type_no;
886 break;
887 }
888 i++;
889 }
890}
891
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200892/* ----------- FBDev related routines for all series ----------- */
893
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200894static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
895{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530896 switch (var->bits_per_pixel) {
897 case 8:
898 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200899 var->red.length = var->green.length = var->blue.length = 6;
900 xgi_video_info.video_cmap_len = 256;
901 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530902 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200903 var->red.offset = 11;
904 var->red.length = 5;
905 var->green.offset = 5;
906 var->green.length = 6;
907 var->blue.offset = 0;
908 var->blue.length = 5;
909 var->transp.offset = 0;
910 var->transp.length = 0;
911 xgi_video_info.video_cmap_len = 16;
912 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530913 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200914 var->red.offset = 16;
915 var->red.length = 8;
916 var->green.offset = 8;
917 var->green.length = 8;
918 var->blue.offset = 0;
919 var->blue.length = 8;
920 var->transp.offset = 24;
921 var->transp.length = 8;
922 xgi_video_info.video_cmap_len = 16;
923 break;
924 }
925}
926
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300927/* --------------------- SetMode routines ------------------------- */
928
929static void XGIfb_pre_setmode(void)
930{
931 u8 cr30 = 0, cr31 = 0;
932
933 cr31 = xgifb_reg_get(XGICR, 0x31);
934 cr31 &= ~0x60;
935
936 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
937 case DISPTYPE_CRT2:
938 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
939 cr31 |= XGI_DRIVER_MODE;
940 break;
941 case DISPTYPE_LCD:
942 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
943 cr31 |= XGI_DRIVER_MODE;
944 break;
945 case DISPTYPE_TV:
946 if (xgi_video_info.TV_type == TVMODE_HIVISION)
947 cr30 = (XGI_VB_OUTPUT_HIVISION
948 | XGI_SIMULTANEOUS_VIEW_ENABLE);
949 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
950 cr30 = (XGI_VB_OUTPUT_SVIDEO
951 | XGI_SIMULTANEOUS_VIEW_ENABLE);
952 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
953 cr30 = (XGI_VB_OUTPUT_COMPOSITE
954 | XGI_SIMULTANEOUS_VIEW_ENABLE);
955 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
956 cr30 = (XGI_VB_OUTPUT_SCART
957 | XGI_SIMULTANEOUS_VIEW_ENABLE);
958 cr31 |= XGI_DRIVER_MODE;
959
960 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
961 cr31 |= 0x01;
962 else
963 cr31 &= ~0x01;
964 break;
965 default: /* disable CRT2 */
966 cr30 = 0x00;
967 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
968 }
969
970 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
971 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
972 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
973}
974
975static void XGIfb_post_setmode(void)
976{
977 u8 reg;
978 unsigned char doit = 1;
979 /*
980 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
981 xgifb_reg_set(XGICR, 0x13, 0x00);
982 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
983 *test*
984 */
985 if (xgi_video_info.video_bpp == 8) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800986 /* TW: We can't switch off CRT1 on LVDS/Chrontel
987 * in 8bpp Modes */
988 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
989 (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300990 doit = 0;
991 }
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800992 /* TW: We can't switch off CRT1 on 301B-DH
993 * in 8bpp Modes if using LCD */
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300994 if (xgi_video_info.disp_state & DISPTYPE_LCD)
995 doit = 0;
996 }
997
998 /* TW: We can't switch off CRT1 if bridge is in slave mode */
999 if (xgi_video_info.hasVB != HASVB_NONE) {
1000 reg = xgifb_reg_get(XGIPART1, 0x00);
1001
1002 if ((reg & 0x50) == 0x10)
1003 doit = 0;
1004
1005 } else {
1006 XGIfb_crt1off = 0;
1007 }
1008
1009 reg = xgifb_reg_get(XGICR, 0x17);
1010 if ((XGIfb_crt1off) && (doit))
1011 reg &= ~0x80;
1012 else
1013 reg |= 0x80;
1014 xgifb_reg_set(XGICR, 0x17, reg);
1015
1016 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1017
1018 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1019 == HASVB_301)) {
1020
1021 reg = xgifb_reg_get(XGIPART4, 0x01);
1022
1023 if (reg < 0xB0) { /* Set filter for XGI301 */
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001024 switch (xgi_video_info.video_width) {
1025 case 320:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001026 filter_tb = (xgi_video_info.TV_type ==
1027 TVMODE_NTSC) ? 4 : 12;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001028 break;
1029 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001030 filter_tb = (xgi_video_info.TV_type ==
1031 TVMODE_NTSC) ? 5 : 13;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001032 break;
1033 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001034 filter_tb = (xgi_video_info.TV_type ==
1035 TVMODE_NTSC) ? 6 : 14;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001036 break;
1037 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001038 filter_tb = (xgi_video_info.TV_type ==
1039 TVMODE_NTSC) ? 7 : 15;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001040 break;
1041 default:
1042 filter = -1;
1043 break;
1044 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001045 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1046
1047 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1048
1049 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1050
1051 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1052
1053 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1054
1055 } else if (xgi_video_info.TV_plug
1056 == TVPLUG_COMPOSITE) {
1057
1058 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1059
1060 switch (xgi_video_info.video_width) {
1061 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001062 xgifb_reg_set(XGIPART2,
1063 0x35,
1064 0xEB);
1065 xgifb_reg_set(XGIPART2,
1066 0x36,
1067 0x04);
1068 xgifb_reg_set(XGIPART2,
1069 0x37,
1070 0x25);
1071 xgifb_reg_set(XGIPART2,
1072 0x38,
1073 0x18);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001074 break;
1075 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001076 xgifb_reg_set(XGIPART2,
1077 0x35,
1078 0xEE);
1079 xgifb_reg_set(XGIPART2,
1080 0x36,
1081 0x0C);
1082 xgifb_reg_set(XGIPART2,
1083 0x37,
1084 0x22);
1085 xgifb_reg_set(XGIPART2,
1086 0x38,
1087 0x08);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001088 break;
1089 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001090 xgifb_reg_set(XGIPART2,
1091 0x35,
1092 0xEB);
1093 xgifb_reg_set(XGIPART2,
1094 0x36,
1095 0x15);
1096 xgifb_reg_set(XGIPART2,
1097 0x37,
1098 0x25);
1099 xgifb_reg_set(XGIPART2,
1100 0x38,
1101 0xF6);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001102 break;
1103 }
1104 }
1105
1106 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1107
1108 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1109
1110 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1111
1112 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1113
1114 } else if (xgi_video_info.TV_plug
1115 == TVPLUG_COMPOSITE) {
1116
1117 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1118
1119 switch (xgi_video_info.video_width) {
1120 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001121 xgifb_reg_set(XGIPART2,
1122 0x35,
1123 0xF1);
1124 xgifb_reg_set(XGIPART2,
1125 0x36,
1126 0xF7);
1127 xgifb_reg_set(XGIPART2,
1128 0x37,
1129 0x1F);
1130 xgifb_reg_set(XGIPART2,
1131 0x38,
1132 0x32);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001133 break;
1134 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001135 xgifb_reg_set(XGIPART2,
1136 0x35,
1137 0xF3);
1138 xgifb_reg_set(XGIPART2,
1139 0x36,
1140 0x00);
1141 xgifb_reg_set(XGIPART2,
1142 0x37,
1143 0x1D);
1144 xgifb_reg_set(XGIPART2,
1145 0x38,
1146 0x20);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001147 break;
1148 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001149 xgifb_reg_set(XGIPART2,
1150 0x35,
1151 0xFC);
1152 xgifb_reg_set(XGIPART2,
1153 0x36,
1154 0xFB);
1155 xgifb_reg_set(XGIPART2,
1156 0x37,
1157 0x14);
1158 xgifb_reg_set(XGIPART2,
1159 0x38,
1160 0x2A);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001161 break;
1162 }
1163 }
1164 }
1165
1166 if ((filter >= 0) && (filter <= 7)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001167 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1168 filter_tb, filter,
1169 XGI_TV_filter[filter_tb].
1170 filter[filter][0],
1171 XGI_TV_filter[filter_tb].
1172 filter[filter][1],
1173 XGI_TV_filter[filter_tb].
1174 filter[filter][2],
1175 XGI_TV_filter[filter_tb].
1176 filter[filter][3]
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001177 );
1178 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001179 XGIPART2,
1180 0x35,
1181 (XGI_TV_filter[filter_tb].
1182 filter[filter][0]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001183 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001184 XGIPART2,
1185 0x36,
1186 (XGI_TV_filter[filter_tb].
1187 filter[filter][1]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001188 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001189 XGIPART2,
1190 0x37,
1191 (XGI_TV_filter[filter_tb].
1192 filter[filter][2]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001193 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001194 XGIPART2,
1195 0x38,
1196 (XGI_TV_filter[filter_tb].
1197 filter[filter][3]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001198 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001199 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001200 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001201}
1202
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001203static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301204 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001205{
1206
Prashant P. Shahb654f872010-09-06 17:34:26 +05301207 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1208 + var->hsync_len;
1209 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1210 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001211#if defined(__powerpc__)
1212 u8 sr_data, cr_data;
1213#endif
1214 unsigned int drate = 0, hrate = 0;
1215 int found_mode = 0;
1216 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301217 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001218
1219 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301220 /* 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 +02001221
Prashant P. Shahb654f872010-09-06 17:34:26 +05301222 info->var.xres_virtual = var->xres_virtual;
1223 info->var.yres_virtual = var->yres_virtual;
1224 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001225
1226 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1227 vtotal <<= 1;
1228 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1229 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301230 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1231 /* vtotal <<= 1; */
1232 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001233 }
1234
Prashant P. Shahb654f872010-09-06 17:34:26 +05301235 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001236 DPRINTK("XGIfb: Invalid 'var' information\n");
1237 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301238 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1239 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001240
Prashant P. Shahb654f872010-09-06 17:34:26 +05301241 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001242 drate = 1000000000 / var->pixclock;
1243 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301244 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1245 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001246 } else {
1247 xgi_video_info.refresh_rate = 60;
1248 }
1249
1250 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001251 var->xres,
1252 var->yres,
1253 var->bits_per_pixel,
1254 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001255
1256 old_mode = xgifb_mode_idx;
1257 xgifb_mode_idx = 0;
1258
Prashant P. Shahb654f872010-09-06 17:34:26 +05301259 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1260 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1261 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1262 && (XGIbios_mode[xgifb_mode_idx].yres
1263 == var->yres)
1264 && (XGIbios_mode[xgifb_mode_idx].bpp
1265 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001266 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1267 found_mode = 1;
1268 break;
1269 }
1270 xgifb_mode_idx++;
1271 }
1272
Prashant P. Shahb654f872010-09-06 17:34:26 +05301273 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001274 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1275 else
1276 xgifb_mode_idx = -1;
1277
Prashant P. Shahb654f872010-09-06 17:34:26 +05301278 if (xgifb_mode_idx < 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001279 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1280 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001281 xgifb_mode_idx = old_mode;
1282 return -EINVAL;
1283 }
1284
Prashant P. Shahb654f872010-09-06 17:34:26 +05301285 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001286 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1287 xgi_video_info.refresh_rate = 60;
1288 }
1289
Prashant P. Shahb654f872010-09-06 17:34:26 +05301290 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001291
1292 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301293 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001294 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1295 XGIfb_mode_no);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001296 return -EINVAL;
1297 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301298 info->fix.line_length = ((info->var.xres_virtual
1299 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001300
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001301 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001302
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001303 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001304 xgifb_reg_set(XGISR,
1305 0x0E,
1306 (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001307
1308 XGIfb_post_setmode();
1309
Prashant P. Shahb654f872010-09-06 17:34:26 +05301310 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1311 XGIbios_mode[xgifb_mode_idx].xres,
1312 XGIbios_mode[xgifb_mode_idx].yres,
1313 XGIbios_mode[xgifb_mode_idx].bpp,
1314 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001315
1316 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1317 xgi_video_info.video_vwidth = info->var.xres_virtual;
1318 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1319 xgi_video_info.video_vheight = info->var.yres_virtual;
1320 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1321 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301322 xgi_video_info.video_linelength = info->var.xres_virtual
1323 * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301324 switch (xgi_video_info.video_bpp) {
1325 case 8:
1326 xgi_video_info.DstColor = 0x0000;
1327 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1328 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001329#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001330 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001331 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001332#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301333 break;
1334 case 16:
1335 xgi_video_info.DstColor = 0x8000;
1336 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001337#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001338 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001339 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001340#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301341 xgi_video_info.video_cmap_len = 16;
1342 break;
1343 case 32:
1344 xgi_video_info.DstColor = 0xC000;
1345 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1346 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001347#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001348 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001349 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001350#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301351 break;
1352 default:
1353 xgi_video_info.video_cmap_len = 16;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001354 printk(KERN_ERR "XGIfb: Unsupported depth %d",
1355 xgi_video_info.video_bpp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301356 break;
1357 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001358 }
1359 XGIfb_bpp_to_var(var); /*update ARGB info*/
1360 DEBUGPRN("End of do_set_var");
1361
1362 dumpVGAReg();
1363 return 0;
1364}
1365
1366#ifdef XGIFB_PAN
1367static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1368{
1369 unsigned int base;
1370
Prashant P. Shahb654f872010-09-06 17:34:26 +05301371 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001372
1373 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301374 /* printk("Pan: xo: %d xv %d xr %d\n",
1375 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001376 return -EINVAL;
1377 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301378 if (var->yoffset > (var->yres_virtual - var->yres)) {
1379 /* printk("Pan: yo: %d yv %d yr %d\n",
1380 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001381 return -EINVAL;
1382 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301383 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001384
Prashant P. Shahb654f872010-09-06 17:34:26 +05301385 /* calculate base bpp dep. */
1386 switch (var->bits_per_pixel) {
1387 case 16:
1388 base >>= 1;
1389 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001390 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301391 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001392 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301393 default:
1394 base >>= 2;
1395 break;
1396 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001397
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001398 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001399
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001400 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1401 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1402 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1403 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
Aaro Koskinen65283d42011-04-18 22:14:02 +03001404 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001405
Prashant P. Shahb654f872010-09-06 17:34:26 +05301406 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene67f4d42011-04-18 22:14:00 +03001407 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001408 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1409 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1410 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001411 xgifb_reg_and_or(XGIPART1,
1412 0x02,
1413 0x7F,
1414 ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301415 }
1416 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001417 return 0;
1418}
1419#endif
1420
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001421static int XGIfb_open(struct fb_info *info, int user)
1422{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301423 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001424}
1425
1426static int XGIfb_release(struct fb_info *info, int user)
1427{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301428 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001429}
1430
1431static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1432{
1433 int rc = 16;
1434
Prashant P. Shahb654f872010-09-06 17:34:26 +05301435 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001436 case 8:
1437 rc = 256;
1438 break;
1439 case 16:
1440 rc = 16;
1441 break;
1442 case 32:
1443 rc = 16;
1444 break;
1445 }
1446 return rc;
1447}
1448
Prashant P. Shahb654f872010-09-06 17:34:26 +05301449static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1450 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001451{
1452 if (regno >= XGIfb_get_cmap_len(&info->var))
1453 return 1;
1454
1455 switch (info->var.bits_per_pixel) {
1456 case 8:
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001457 outb(regno, XGIDACA);
1458 outb((red >> 10), XGIDACD);
1459 outb((green >> 10), XGIDACD);
1460 outb((blue >> 10), XGIDACD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001461 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001462 outb(regno, XGIDAC2A);
1463 outb((red >> 8), XGIDAC2D);
1464 outb((green >> 8), XGIDAC2D);
1465 outb((blue >> 8), XGIDAC2D);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001466 }
1467 break;
1468 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301469 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1470 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1471 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001472 break;
1473 case 32:
1474 red >>= 8;
1475 green >>= 8;
1476 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301477 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1478 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001479 break;
1480 }
1481 return 0;
1482}
1483
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001484/* ----------- FBDev related routines for all series ---------- */
1485
1486static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1487 struct fb_info *info)
1488{
1489 DEBUGPRN("inside get_fix");
1490 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1491
1492 strcpy(fix->id, myid);
1493
1494 fix->smem_start = xgi_video_info.video_base;
1495
1496 fix->smem_len = xgi_video_info.video_size;
1497
1498 fix->type = video_type;
1499 fix->type_aux = 0;
1500 if (xgi_video_info.video_bpp == 8)
1501 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1502 else
1503 fix->visual = FB_VISUAL_DIRECTCOLOR;
1504 fix->xpanstep = 0;
1505#ifdef XGIFB_PAN
1506 if (XGIfb_ypan)
1507 fix->ypanstep = 1;
1508#endif
1509 fix->ywrapstep = 0;
1510 fix->line_length = xgi_video_info.video_linelength;
1511 fix->mmio_start = xgi_video_info.mmio_base;
1512 fix->mmio_len = xgi_video_info.mmio_size;
1513 fix->accel = FB_ACCEL_XGI_XABRE;
1514
1515 DEBUGPRN("end of get_fix");
1516 return 0;
1517}
1518
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001519static int XGIfb_set_par(struct fb_info *info)
1520{
1521 int err;
1522
Prashant P. Shahb654f872010-09-06 17:34:26 +05301523 /* printk("XGIfb: inside set_par\n"); */
1524 err = XGIfb_do_set_var(&info->var, 1, info);
1525 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001526 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001527 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301528 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001529 return 0;
1530}
1531
Prashant P. Shahb654f872010-09-06 17:34:26 +05301532static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001533{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301534 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1535 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001536 unsigned int vtotal = 0;
1537 unsigned int drate = 0, hrate = 0;
1538 int found_mode = 0;
1539 int refresh_rate, search_idx;
1540
1541 DEBUGPRN("Inside check_var");
1542
Prashant P. Shahb654f872010-09-06 17:34:26 +05301543 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1544 vtotal = var->upper_margin + var->yres + var->lower_margin
1545 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001546 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301547 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1548 vtotal = var->upper_margin + var->yres + var->lower_margin
1549 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001550 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301551 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1552 vtotal = var->upper_margin + (var->yres / 2)
1553 + var->lower_margin + var->vsync_len;
1554 } else
1555 vtotal = var->upper_margin + var->yres + var->lower_margin
1556 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001557
Prashant P. Shahb654f872010-09-06 17:34:26 +05301558 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001559 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301560
1561 if (var->pixclock && htotal && vtotal) {
1562 drate = 1000000000 / var->pixclock;
1563 hrate = (drate * 1000) / htotal;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001564 xgi_video_info.refresh_rate =
1565 (unsigned int) (hrate * 2 / vtotal);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301566 printk(KERN_DEBUG
1567 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1568 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1569 __func__, var->pixclock, htotal, vtotal,
1570 __func__, drate, hrate, xgi_video_info.refresh_rate);
1571 } else {
1572 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001573 }
1574
Prashant P. Shahb654f872010-09-06 17:34:26 +05301575 /*
1576 if ((var->pixclock) && (htotal)) {
1577 drate = 1E12 / var->pixclock;
1578 hrate = drate / htotal;
1579 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1580 } else {
1581 refresh_rate = 60;
1582 }
1583 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001584 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301585 if ((var->xres == 1024) && (var->yres == 600))
1586 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001587
1588 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301589 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1590 (XGIbios_mode[search_idx].xres <= var->xres)) {
1591 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1592 (XGIbios_mode[search_idx].yres == var->yres) &&
1593 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1594 if (XGIfb_validate_mode(search_idx) > 0) {
1595 found_mode = 1;
1596 break;
1597 }
1598 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001599 search_idx++;
1600 }
1601
Prashant P. Shahb654f872010-09-06 17:34:26 +05301602 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001603
1604 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1605 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301606 search_idx = 0;
1607 while (XGIbios_mode[search_idx].mode_no != 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301608 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001609 (var->yres <= XGIbios_mode[search_idx].yres) &&
1610 (var->bits_per_pixel ==
1611 XGIbios_mode[search_idx].bpp)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301612 if (XGIfb_validate_mode(search_idx) > 0) {
1613 found_mode = 1;
1614 break;
1615 }
1616 }
1617 search_idx++;
1618 }
1619 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001620 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301621 var->yres = XGIbios_mode[search_idx].yres;
1622 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1623 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001624
1625 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301626 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001627 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301628 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001629 }
1630 }
1631
1632 /* TW: TODO: Check the refresh rate */
1633
1634 /* Adapt RGB settings */
1635 XGIfb_bpp_to_var(var);
1636
1637 /* Sanity check for offsets */
1638 if (var->xoffset < 0)
1639 var->xoffset = 0;
1640 if (var->yoffset < 0)
1641 var->yoffset = 0;
1642
Prashant P. Shahb654f872010-09-06 17:34:26 +05301643 if (!XGIfb_ypan) {
1644 if (var->xres != var->xres_virtual)
1645 var->xres_virtual = var->xres;
1646 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001647 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301648 } /* else { */
1649 /* TW: Now patch yres_virtual if we use panning */
1650 /* May I do this? */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001651 /* var->yres_virtual = xgi_video_info.heapstart /
1652 (var->xres * (var->bits_per_pixel >> 3)); */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301653 /* if (var->yres_virtual <= var->yres) { */
1654 /* TW: Paranoia check */
1655 /* var->yres_virtual = var->yres; */
1656 /* } */
1657 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001658
1659 /* Truncate offsets to maximum if too high */
1660 if (var->xoffset > var->xres_virtual - var->xres)
1661 var->xoffset = var->xres_virtual - var->xres - 1;
1662
1663 if (var->yoffset > var->yres_virtual - var->yres)
1664 var->yoffset = var->yres_virtual - var->yres - 1;
1665
1666 /* Set everything else to 0 */
1667 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301668 var->green.msb_right =
1669 var->blue.msb_right =
1670 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001671
1672 DEBUGPRN("end of check_var");
1673 return 0;
1674}
1675
1676#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301677static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1678 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001679{
1680 int err;
1681
Prashant P. Shahb654f872010-09-06 17:34:26 +05301682 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001683
1684 if (var->xoffset > (var->xres_virtual - var->xres))
1685 return -EINVAL;
1686 if (var->yoffset > (var->yres_virtual - var->yres))
1687 return -EINVAL;
1688
1689 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301690 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1691 || var->xoffset)
1692 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001693 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301694 if (var->xoffset + info->var.xres > info->var.xres_virtual
1695 || var->yoffset + info->var.yres
1696 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001697 return -EINVAL;
1698 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301699 err = XGIfb_pan_var(var);
1700 if (err < 0)
1701 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001702
1703 info->var.xoffset = var->xoffset;
1704 info->var.yoffset = var->yoffset;
1705 if (var->vmode & FB_VMODE_YWRAP)
1706 info->var.vmode |= FB_VMODE_YWRAP;
1707 else
1708 info->var.vmode &= ~FB_VMODE_YWRAP;
1709
Prashant P. Shahb654f872010-09-06 17:34:26 +05301710 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001711 return 0;
1712}
1713#endif
1714
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001715static int XGIfb_blank(int blank, struct fb_info *info)
1716{
1717 u8 reg;
1718
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001719 reg = xgifb_reg_get(XGICR, 0x17);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001720
Prashant P. Shahb654f872010-09-06 17:34:26 +05301721 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001722 reg &= 0x7f;
1723 else
1724 reg |= 0x80;
1725
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001726 xgifb_reg_set(XGICR, 0x17, reg);
1727 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1728 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301729 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001730}
1731
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001732static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301733 .owner = THIS_MODULE,
1734 .fb_open = XGIfb_open,
1735 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001736 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301737 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001738 .fb_setcolreg = XGIfb_setcolreg,
1739#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301740 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001741#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301742 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001743 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001744 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001745 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301746 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001747};
1748
1749/* ---------------- Chip generation dependent routines ---------------- */
1750
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001751/* for XGI 315/550/650/740/330 */
1752
1753static int XGIfb_get_dram_size(void)
1754{
1755
Prashant P. Shahb654f872010-09-06 17:34:26 +05301756 u8 ChannelNum, tmp;
1757 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001758
1759 /* xorg driver sets 32MB * 1 channel */
1760 if (xgi_video_info.chip == XG27)
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001761 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001762
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001763 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301764 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1765 case XGI_DRAM_SIZE_1MB:
1766 xgi_video_info.video_size = 0x100000;
1767 break;
1768 case XGI_DRAM_SIZE_2MB:
1769 xgi_video_info.video_size = 0x200000;
1770 break;
1771 case XGI_DRAM_SIZE_4MB:
1772 xgi_video_info.video_size = 0x400000;
1773 break;
1774 case XGI_DRAM_SIZE_8MB:
1775 xgi_video_info.video_size = 0x800000;
1776 break;
1777 case XGI_DRAM_SIZE_16MB:
1778 xgi_video_info.video_size = 0x1000000;
1779 break;
1780 case XGI_DRAM_SIZE_32MB:
1781 xgi_video_info.video_size = 0x2000000;
1782 break;
1783 case XGI_DRAM_SIZE_64MB:
1784 xgi_video_info.video_size = 0x4000000;
1785 break;
1786 case XGI_DRAM_SIZE_128MB:
1787 xgi_video_info.video_size = 0x8000000;
1788 break;
1789 case XGI_DRAM_SIZE_256MB:
1790 xgi_video_info.video_size = 0x10000000;
1791 break;
1792 default:
1793 return -1;
1794 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001795
Prashant P. Shahb654f872010-09-06 17:34:26 +05301796 tmp = (reg & 0x0c) >> 2;
1797 switch (xgi_video_info.chip) {
1798 case XG20:
1799 case XG21:
1800 case XG27:
1801 ChannelNum = 1;
1802 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001803
Prashant P. Shahb654f872010-09-06 17:34:26 +05301804 case XG42:
1805 if (reg & 0x04)
1806 ChannelNum = 2;
1807 else
1808 ChannelNum = 1;
1809 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001810
Prashant P. Shahb654f872010-09-06 17:34:26 +05301811 case XG45:
1812 if (tmp == 1)
1813 ChannelNum = 2;
1814 else if (tmp == 2)
1815 ChannelNum = 3;
1816 else if (tmp == 3)
1817 ChannelNum = 4;
1818 else
1819 ChannelNum = 1;
1820 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001821
Prashant P. Shahb654f872010-09-06 17:34:26 +05301822 case XG40:
1823 default:
1824 if (tmp == 2)
1825 ChannelNum = 2;
1826 else if (tmp == 3)
1827 ChannelNum = 3;
1828 else
1829 ChannelNum = 1;
1830 break;
1831 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001832
Prashant P. Shahb654f872010-09-06 17:34:26 +05301833 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1834 /* PLiad fixed for benchmarking and fb set */
1835 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1836 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001837
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001838 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1839 reg,
1840 xgi_video_info.video_size, ChannelNum);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301841 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001842
1843}
1844
1845static void XGIfb_detect_VB(void)
1846{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301847 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001848
1849 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1850
Prashant P. Shahb654f872010-09-06 17:34:26 +05301851 switch (xgi_video_info.hasVB) {
1852 case HASVB_LVDS_CHRONTEL:
1853 case HASVB_CHRONTEL:
1854 break;
1855 case HASVB_301:
1856 case HASVB_302:
1857 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1858 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001859 }
1860
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001861 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001862
1863 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1864 XGIfb_crt1off = 0;
1865 else {
1866 if (cr32 & 0x5F)
1867 XGIfb_crt1off = 1;
1868 else
1869 XGIfb_crt1off = 0;
1870 }
1871
1872 if (XGIfb_crt2type != -1)
1873 /* TW: Override with option */
1874 xgi_video_info.disp_state = XGIfb_crt2type;
1875 else if (cr32 & XGI_VB_TV)
1876 xgi_video_info.disp_state = DISPTYPE_TV;
1877 else if (cr32 & XGI_VB_LCD)
1878 xgi_video_info.disp_state = DISPTYPE_LCD;
1879 else if (cr32 & XGI_VB_CRT2)
1880 xgi_video_info.disp_state = DISPTYPE_CRT2;
1881 else
1882 xgi_video_info.disp_state = 0;
1883
Prashant P. Shahb654f872010-09-06 17:34:26 +05301884 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001885 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301886 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001887 else if (cr32 & XGI_VB_HIVISION) {
1888 xgi_video_info.TV_type = TVMODE_HIVISION;
1889 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301890 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001891 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1892 else if (cr32 & XGI_VB_COMPOSITE)
1893 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1894 else if (cr32 & XGI_VB_SCART)
1895 xgi_video_info.TV_plug = TVPLUG_SCART;
1896
Prashant P. Shahb654f872010-09-06 17:34:26 +05301897 if (xgi_video_info.TV_type == 0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001898 temp = xgifb_reg_get(XGICR, 0x38);
Aaro Koskinenebe78462011-03-13 12:26:08 +02001899 if (temp & 0x10)
1900 xgi_video_info.TV_type = TVMODE_PAL;
1901 else
1902 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001903 }
1904
1905 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301906 if (XGIfb_forcecrt1 != -1) {
1907 if (XGIfb_forcecrt1)
1908 XGIfb_crt1off = 0;
1909 else
1910 XGIfb_crt1off = 1;
1911 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001912}
1913
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001914static int XGIfb_has_VB(void)
1915{
1916 u8 vb_chipid;
1917
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001918 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001919 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301920 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001921 xgi_video_info.hasVB = HASVB_301;
1922 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301923 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001924 xgi_video_info.hasVB = HASVB_302;
1925 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301926 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001927 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001928 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001929 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001930 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001931}
1932
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001933static void XGIfb_get_VB_type(void)
1934{
1935 u8 reg;
1936
1937 if (!XGIfb_has_VB()) {
1938 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1939 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1940 case XGI310_EXTERNAL_CHIP_LVDS:
1941 xgi_video_info.hasVB = HASVB_LVDS;
1942 break;
1943 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1944 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1945 break;
1946 default:
1947 break;
1948 }
1949 }
1950}
1951
Ruslan Pisarev032abf72011-07-21 11:59:11 +03001952static int __init XGIfb_setup(char *options)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001953{
1954 char *this_opt;
1955
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001956 xgi_video_info.refresh_rate = 0;
1957
Prashant P. Shahb654f872010-09-06 17:34:26 +05301958 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001959
1960 if (!options || !*options)
1961 return 0;
1962
Prashant P. Shahb654f872010-09-06 17:34:26 +05301963 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001964
Prashant P. Shahb654f872010-09-06 17:34:26 +05301965 if (!*this_opt)
1966 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001967
1968 if (!strncmp(this_opt, "mode:", 5)) {
1969 XGIfb_search_mode(this_opt + 5);
1970 } else if (!strncmp(this_opt, "vesa:", 5)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001971 XGIfb_search_vesamode(simple_strtoul(
1972 this_opt + 5, NULL, 0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001973 } else if (!strncmp(this_opt, "mode:", 5)) {
1974 XGIfb_search_mode(this_opt + 5);
1975 } else if (!strncmp(this_opt, "vesa:", 5)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001976 XGIfb_search_vesamode(simple_strtoul(
1977 this_opt + 5, NULL, 0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001978 } else if (!strncmp(this_opt, "vrate:", 6)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001979 xgi_video_info.refresh_rate = simple_strtoul(
1980 this_opt + 6, NULL, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001981 } else if (!strncmp(this_opt, "rate:", 5)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001982 xgi_video_info.refresh_rate = simple_strtoul(
1983 this_opt + 5, NULL, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001984 } else if (!strncmp(this_opt, "off", 3)) {
1985 XGIfb_off = 1;
1986 } else if (!strncmp(this_opt, "crt1off", 7)) {
1987 XGIfb_crt1off = 1;
1988 } else if (!strncmp(this_opt, "filter:", 7)) {
1989 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1990 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1991 XGIfb_search_crt2type(this_opt + 14);
1992 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001993 XGIfb_forcecrt1 = (int)simple_strtoul(
1994 this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301995 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001996 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301997 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1998 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301999 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002000 enable_dstn = 1;
2001 /* TW: DSTN overrules forcecrt2type */
2002 XGIfb_crt2type = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002003 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302004 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2005 if (XGIfb_pdc & ~0x3c) {
2006 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2007 XGIfb_pdc = 0;
2008 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002009 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302010 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002011 } else if (!strncmp(this_opt, "userom:", 7)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002012 XGIfb_userom = (int)simple_strtoul(
2013 this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302014 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002015 /* XGIfb_useoem = (int)simple_strtoul(
2016 this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002017 } else {
2018 XGIfb_search_mode(this_opt);
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002019 /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
2020 this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002021 }
2022
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002023 /* TW: Panning only with acceleration */
Javier Martinez Canillas0089bf12011-02-21 18:16:43 +01002024 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002025
2026 }
2027 printk("\nxgifb: outa xgifb_setup 3450");
2028 return 0;
2029}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002030
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002031static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002032{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002033 void __iomem *rom_address;
2034 unsigned char *rom_copy;
2035 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002036
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002037 rom_address = pci_map_rom(dev, &rom_size);
2038 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002039 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002040
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002041 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2042 if (rom_copy == NULL)
2043 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002044
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002045 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2046 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002047
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002048done:
2049 pci_unmap_rom(dev, rom_address);
2050 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002051}
2052
Randy Dunlap89229672010-08-10 08:46:44 -07002053static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302054 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002055{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302056 u8 reg, reg1;
2057 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002058 int ret;
2059
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002060 if (XGIfb_off)
2061 return -ENXIO;
2062
2063 XGIfb_registered = 0;
2064
Bill Pembertone4147ab2010-06-17 13:10:50 -04002065 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302066 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2067 if (!fb_info)
2068 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002069
Prashant P. Shahb654f872010-09-06 17:34:26 +05302070 xgi_video_info.chip_id = pdev->device;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002071 pci_read_config_byte(pdev,
2072 PCI_REVISION_ID,
2073 &xgi_video_info.revision_id);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302074 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002075
Prashant P. Shahb654f872010-09-06 17:34:26 +05302076 xgi_video_info.pcibus = pdev->bus->number;
2077 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2078 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2079 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2080 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002081
Prashant P. Shahb654f872010-09-06 17:34:26 +05302082 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2083 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002084 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302085 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2086 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2087 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2088 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002089 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002090
Aaro Koskinenbb292232011-02-17 23:29:11 +02002091 if (pci_enable_device(pdev)) {
2092 ret = -EIO;
2093 goto error;
2094 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002095
Prashant P. Shahb654f872010-09-06 17:34:26 +05302096 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002097
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002098 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002099 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002100
Prashant P. Shahb654f872010-09-06 17:34:26 +05302101 if (reg1 != 0xa1) { /*I/O error */
2102 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002103 ret = -EIO;
2104 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302105 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002106
2107 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302108 case PCI_DEVICE_ID_XG_20:
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002109 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002110 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002111 if (CR48&GPIOG_READ)
2112 xgi_video_info.chip = XG21;
2113 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302114 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002115 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2116 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302117 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002118 xgi_video_info.chip = XG40;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002119 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2120 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302121 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002122 xgi_video_info.chip = XG41;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002123 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2124 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302125 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002126 xgi_video_info.chip = XG42;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002127 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2128 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302129 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002130 xgi_video_info.chip = XG27;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002131 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2132 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302133 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002134 ret = -ENODEV;
2135 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002136 }
2137
Prashant P. Shahb654f872010-09-06 17:34:26 +05302138 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2139 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002140
Prashant P. Shahb654f872010-09-06 17:34:26 +05302141 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002142 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302143 if (XGIhw_ext.pjVirtualRomBase)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002144 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2145 XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002146 else
2147 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302148 } else {
2149 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002150 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302151 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302152 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002153
Prashant P. Shahb654f872010-09-06 17:34:26 +05302154 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302155 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002156 ret = -ENODEV;
2157 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302158 }
2159
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002160 if ((xgifb_mode_idx < 0) ||
2161 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302162 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002163 xgifb_reg_or(XGISR,
2164 IND_XGI_PCI_ADDRESS_SET,
2165 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302166 /* Enable 2D accelerator engine */
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002167 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302168 }
2169
2170 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2171
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002172 if (!request_mem_region(xgi_video_info.video_base,
2173 xgi_video_info.video_size,
2174 "XGIfb FB")) {
2175 printk("unable request memory size %x",
2176 xgi_video_info.video_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302177 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2178 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002179 ret = -ENODEV;
2180 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302181 }
2182
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002183 if (!request_mem_region(xgi_video_info.mmio_base,
2184 xgi_video_info.mmio_size,
2185 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302186 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002187 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002188 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302189 }
2190
2191 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2192 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002193 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2194 xgi_video_info.mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302195
2196 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002197 xgi_video_info.video_base,
2198 xgi_video_info.video_vbase,
2199 xgi_video_info.video_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302200
2201 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002202 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2203 xgi_video_info.mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302204 printk("XGIfb: XGIInitNew() ...");
2205 if (XGIInitNew(&XGIhw_ext))
2206 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002207 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002208 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002209
Prashant P. Shahb654f872010-09-06 17:34:26 +05302210 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002211
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002212 if ((xgifb_mode_idx < 0) ||
2213 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002214 xgi_video_info.hasVB = HASVB_NONE;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002215 if ((xgi_video_info.chip == XG20) ||
2216 (xgi_video_info.chip == XG27)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302217 xgi_video_info.hasVB = HASVB_NONE;
2218 } else if (xgi_video_info.chip == XG21) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002219 CR38 = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302220 if ((CR38&0xE0) == 0xC0) {
2221 xgi_video_info.disp_state = DISPTYPE_LCD;
2222 if (!XGIfb_GetXG21LVDSData()) {
2223 int m;
2224 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2225 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002226 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
Aaro Koskinen8104e322011-03-13 12:26:22 +02002227 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302228 }
2229 }
2230 }
2231 } else if ((CR38&0xE0) == 0x60) {
2232 xgi_video_info.hasVB = HASVB_CHRONTEL;
2233 } else {
2234 xgi_video_info.hasVB = HASVB_NONE;
2235 }
2236 } else {
2237 XGIfb_get_VB_type();
2238 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002239
Prashant P. Shahb654f872010-09-06 17:34:26 +05302240 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002241
Prashant P. Shahb654f872010-09-06 17:34:26 +05302242 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002243
2244 switch (xgi_video_info.hasVB) {
2245 case HASVB_301:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002246 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002247 if (reg >= 0xE0) {
2248 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302249 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2250 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002251 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302252 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2253 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002254 /* else if (reg >= 0xB0) {
2255 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002256 reg1 = xgifb_reg_get(XGIPART4, 0x23);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302257 printk("XGIfb: XGI301B bridge detected\n");
2258 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002259 else {
2260 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2261 printk("XGIfb: XGI301 bridge detected\n");
2262 }
2263 break;
2264 case HASVB_302:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002265 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002266 if (reg >= 0xE0) {
2267 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302268 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2269 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002270 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302271 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2272 } else if (reg >= 0xB0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002273 reg1 = xgifb_reg_get(XGIPART4, 0x23);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002274
Prashant P. Shahb654f872010-09-06 17:34:26 +05302275 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002276
2277 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302278 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002279 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2280 }
2281 break;
2282 case HASVB_LVDS:
2283 XGIhw_ext.ulExternalChip = 0x1;
2284 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2285 break;
2286 case HASVB_TRUMPION:
2287 XGIhw_ext.ulExternalChip = 0x2;
2288 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2289 break;
2290 case HASVB_CHRONTEL:
2291 XGIhw_ext.ulExternalChip = 0x4;
2292 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2293 break;
2294 case HASVB_LVDS_CHRONTEL:
2295 XGIhw_ext.ulExternalChip = 0x5;
2296 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2297 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302298 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002299 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2300 break;
2301 }
2302
Prashant P. Shahb654f872010-09-06 17:34:26 +05302303 if (xgi_video_info.hasVB != HASVB_NONE)
2304 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002305
2306 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2307 if (XGIfb_crt1off)
2308 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2309 else
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002310 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2311 DISPTYPE_CRT1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002312 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002313 xgi_video_info.disp_state = DISPMODE_SINGLE |
2314 DISPTYPE_CRT1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002315 }
2316
2317 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302318 if (!enable_dstn) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002319 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302320 reg &= 0x0f;
2321 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002322
Prashant P. Shahb654f872010-09-06 17:34:26 +05302323 } else {
2324 /* TW: FSTN/DSTN */
2325 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2326 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002327 }
2328
2329 XGIfb_detectedpdc = 0;
2330
Prashant P. Shahb654f872010-09-06 17:34:26 +05302331 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002332
Prashant P. Shahb654f872010-09-06 17:34:26 +05302333 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002334
Prashant P. Shahb654f872010-09-06 17:34:26 +05302335 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2336 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2337 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2338 int tmp;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002339 tmp = xgifb_reg_get(XGICR, 0x34);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302340 if (tmp <= 0x13) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002341 /* Currently on LCDA?
2342 *(Some BIOSes leave CR38) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002343 tmp = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302344 if ((tmp & 0x03) == 0x03) {
2345 /* XGI_Pr.XGI_UseLCDA = 1; */
2346 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002347 /* Currently on LCDA?
2348 *(Some newer BIOSes set D0 in CR35) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002349 tmp = xgifb_reg_get(XGICR, 0x35);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302350 if (tmp & 0x01) {
2351 /* XGI_Pr.XGI_UseLCDA = 1; */
2352 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002353 tmp = xgifb_reg_get(XGICR,
2354 0x30);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302355 if (tmp & 0x20) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002356 tmp = xgifb_reg_get(
2357 XGIPART1, 0x13);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302358 if (tmp & 0x04) {
2359 /* XGI_Pr.XGI_UseLCDA = 1; */
2360 }
2361 }
2362 }
2363 }
2364 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002365
Prashant P. Shahb654f872010-09-06 17:34:26 +05302366 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002367
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002368 if (xgifb_mode_idx >= 0)
2369 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2370
2371 if (xgifb_mode_idx < 0) {
2372 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302373 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002374 xgifb_mode_idx = DEFAULT_LCDMODE;
2375 if (xgi_video_info.chip == XG21)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002376 xgifb_mode_idx =
2377 XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002378 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302379 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002380 xgifb_mode_idx = DEFAULT_TVMODE;
2381 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302382 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002383 xgifb_mode_idx = DEFAULT_MODE;
2384 break;
2385 }
2386 }
2387
2388 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2389
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002390 /* yilin set default refresh rate */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302391 if (xgi_video_info.refresh_rate == 0)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002392 xgi_video_info.refresh_rate = 60;
2393 if (XGIfb_search_refresh_rate(
2394 xgi_video_info.refresh_rate) == 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302395 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2396 xgi_video_info.refresh_rate = 60;
2397 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002398
2399 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002400 xgi_video_info.video_vwidth =
2401 xgi_video_info.video_width =
2402 XGIbios_mode[xgifb_mode_idx].xres;
2403 xgi_video_info.video_vheight =
2404 xgi_video_info.video_height =
2405 XGIbios_mode[xgifb_mode_idx].yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002406 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002407 xgi_video_info.video_linelength =
2408 xgi_video_info.video_width *
2409 (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302410 switch (xgi_video_info.video_bpp) {
2411 case 8:
2412 xgi_video_info.DstColor = 0x0000;
2413 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002414 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302415 break;
2416 case 16:
2417 xgi_video_info.DstColor = 0x8000;
2418 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002419 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302420 break;
2421 case 32:
2422 xgi_video_info.DstColor = 0xC000;
2423 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002424 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302425 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002426 default:
2427 xgi_video_info.video_cmap_len = 16;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002428 printk(KERN_INFO "XGIfb: Unsupported depth %d",
2429 xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002430 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302431 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002432
2433 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002434 xgi_video_info.video_width,
2435 xgi_video_info.video_height,
2436 xgi_video_info.video_bpp,
2437 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002438
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002439 default_var.xres =
2440 default_var.xres_virtual =
2441 xgi_video_info.video_width;
2442 default_var.yres =
2443 default_var.yres_virtual =
2444 xgi_video_info.video_height;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002445 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2446
2447 XGIfb_bpp_to_var(&default_var);
2448
2449 default_var.pixclock = (u32) (1000000000 /
2450 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2451 XGIfb_mode_no, XGIfb_rate_idx));
2452
Prashant P. Shahb654f872010-09-06 17:34:26 +05302453 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2454 XGIfb_mode_no, XGIfb_rate_idx,
2455 &default_var.left_margin, &default_var.right_margin,
2456 &default_var.upper_margin, &default_var.lower_margin,
2457 &default_var.hsync_len, &default_var.vsync_len,
2458 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002459
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002460 if ((default_var.vmode & FB_VMODE_MASK) ==
2461 FB_VMODE_INTERLACED) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302462 default_var.yres <<= 1;
2463 default_var.yres_virtual <<= 1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002464 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2465 FB_VMODE_DOUBLE) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302466 default_var.pixclock >>= 1;
2467 default_var.yres >>= 1;
2468 default_var.yres_virtual >>= 1;
2469 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002470
Prashant P. Shahb654f872010-09-06 17:34:26 +05302471 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002472
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002473 fb_info->flags = FBINFO_FLAG_DEFAULT;
2474 fb_info->var = default_var;
2475 fb_info->fix = XGIfb_fix;
2476 fb_info->par = &xgi_video_info;
2477 fb_info->screen_base = xgi_video_info.video_vbase;
2478 fb_info->fbops = &XGIfb_ops;
2479 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2480 fb_info->pseudo_palette = pseudo_palette;
2481
2482 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2483
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002484#ifdef CONFIG_MTRR
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002485 xgi_video_info.mtrr = mtrr_add(
2486 (unsigned int) xgi_video_info.video_base,
2487 (unsigned int) xgi_video_info.video_size,
2488 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302489 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002490 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002491#endif
2492
Aaro Koskinenbb292232011-02-17 23:29:11 +02002493 if (register_framebuffer(fb_info) < 0) {
2494 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002495 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002496 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002497
2498 XGIfb_registered = 1;
2499
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002500 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002501 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002502
2503 }
2504
2505 dumpVGAReg();
2506
2507 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002508
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002509error_1:
2510 iounmap(xgi_video_info.mmio_vbase);
2511 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002512 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002513error_0:
2514 release_mem_region(xgi_video_info.video_base,
2515 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002516error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002517 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002518 framebuffer_release(fb_info);
2519 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002520}
2521
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002522/*****************************************************/
2523/* PCI DEVICE HANDLING */
2524/*****************************************************/
2525
2526static void __devexit xgifb_remove(struct pci_dev *pdev)
2527{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302528 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002529 iounmap(xgi_video_info.mmio_vbase);
2530 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002531 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002532 release_mem_region(xgi_video_info.video_base,
2533 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002534 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302535 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002536 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02002537}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002538
2539static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302540 .name = "xgifb",
2541 .id_table = xgifb_pci_table,
2542 .probe = xgifb_probe,
2543 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002544};
2545
Ruslan Pisarev032abf72011-07-21 11:59:11 +03002546static int __init xgifb_init(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002547{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002548 char *option = NULL;
2549
2550 if (fb_get_options("xgifb", &option))
2551 return -ENODEV;
2552 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04002553
Prashant P. Shahb654f872010-09-06 17:34:26 +05302554 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002555}
2556
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002557#ifndef MODULE
2558module_init(xgifb_init);
2559#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002560
2561/*****************************************************/
2562/* MODULE */
2563/*****************************************************/
2564
2565#ifdef MODULE
2566
Ruslan Pisareve684f462011-07-21 11:58:53 +03002567static char *mode;
2568static int vesa;
2569static unsigned int rate;
2570static unsigned int mem;
2571static char *forcecrt2type;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302572static int forcecrt1 = -1;
2573static int pdc = -1;
2574static int pdc1 = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302575static int noypan = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302576static int userom = -1;
2577static int useoem = -1;
Ruslan Pisareve684f462011-07-21 11:58:53 +03002578static char *tvstandard;
2579static int nocrt2rate;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302580static int scalelcd = -1;
Ruslan Pisareve684f462011-07-21 11:58:53 +03002581static char *specialtiming;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302582static int lvdshl = -1;
Ruslan Pisareve684f462011-07-21 11:58:53 +03002583static int tvxposoffset, tvyposoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002584#if !defined(__i386__) && !defined(__x86_64__)
Ruslan Pisareve684f462011-07-21 11:58:53 +03002585static int resetcard;
2586static int videoram;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002587#endif
2588
2589MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2590MODULE_LICENSE("GPL");
2591MODULE_AUTHOR("XGITECH , Others");
2592
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002593module_param(mem, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002594module_param(noypan, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002595module_param(userom, int, 0);
2596module_param(useoem, int, 0);
2597module_param(mode, charp, 0);
2598module_param(vesa, int, 0);
2599module_param(rate, int, 0);
2600module_param(forcecrt1, int, 0);
2601module_param(forcecrt2type, charp, 0);
2602module_param(scalelcd, int, 0);
2603module_param(pdc, int, 0);
2604module_param(pdc1, int, 0);
2605module_param(specialtiming, charp, 0);
2606module_param(lvdshl, int, 0);
2607module_param(tvstandard, charp, 0);
2608module_param(tvxposoffset, int, 0);
2609module_param(tvyposoffset, int, 0);
2610module_param(filter, int, 0);
2611module_param(nocrt2rate, int, 0);
2612#if !defined(__i386__) && !defined(__x86_64__)
2613module_param(resetcard, int, 0);
2614module_param(videoram, int, 0);
2615#endif
2616
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002617MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302618 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2619 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002620
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002621MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302622 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2623 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2624 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2625 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002626
2627MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302628 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2629 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002630
2631MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302632 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2633 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2634 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002635
2636MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302637 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2638 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2639 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002640
2641MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302642 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2643 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2644 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2645 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2646 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2647 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2648 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2649 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002650
2651MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302652 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2653 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2654 "show black bars around the image, TMDS panels will probably do the scaling\n"
2655 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002656
2657MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302658 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2659 "should detect this correctly in most cases; however, sometimes this is not\n"
2660 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2661 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2662 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2663 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002664
2665MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302666 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2667 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2668 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2669 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002670
2671MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302672 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002673
2674MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302675 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002676
2677MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302678 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2679 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002680
2681MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302682 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2683 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002684
2685MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302686 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2687 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002688
2689MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302690 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2691 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002692
2693MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302694 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2695 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002696
Randy Dunlap89229672010-08-10 08:46:44 -07002697static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002698{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302699 printk("\nXGIfb_init_module");
2700 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002701 XGIfb_search_mode(mode);
2702 else if (vesa != -1)
2703 XGIfb_search_vesamode(vesa);
2704
Prashant P. Shahb654f872010-09-06 17:34:26 +05302705 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002706}
2707
2708static void __exit xgifb_remove_module(void)
2709{
2710 pci_unregister_driver(&xgifb_driver);
2711 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2712}
2713
2714module_init(xgifb_init_module);
2715module_exit(xgifb_remove_module);
2716
Prashant P. Shahb654f872010-09-06 17:34:26 +05302717#endif /* /MODULE */