blob: cadec2ad0d3240ca858b1822ab50733d425b51fa [file] [log] [blame]
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001/*
2 * XG20, XG21, XG40, XG42 frame buffer device
3 * for Linux kernels 2.5.x, 2.6.x
4 * Base on TW's sis fbdev code.
5 */
6
Prashant P. Shahb654f872010-09-06 17:34:26 +05307/* #include <linux/config.h> */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02008#include <linux/version.h>
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/tty.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/fb.h>
20#include <linux/console.h>
21#include <linux/selection.h>
22#include <linux/ioport.h>
23#include <linux/init.h>
24#include <linux/pci.h>
25#include <linux/vmalloc.h>
26#include <linux/vt_kern.h>
27#include <linux/capability.h>
28#include <linux/fs.h>
29#include <linux/types.h>
30#include <linux/proc_fs.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020031
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020032#ifndef XGIFB_PAN
33#define XGIFB_PAN
34#endif
35
Kenji Toyamaa12c27c2011-04-26 12:13:43 +080036#include <linux/io.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020037#ifdef CONFIG_MTRR
38#include <asm/mtrr.h>
39#endif
40
41#include "XGIfb.h"
42#include "vgatypes.h"
43#include "XGI_main.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030044#include "vb_init.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020045#include "vb_util.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030046#include "vb_setmode.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020047
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020048#define Index_CR_GPIO_Reg1 0x48
49#define Index_CR_GPIO_Reg2 0x49
50#define Index_CR_GPIO_Reg3 0x4a
51
52#define GPIOG_EN (1<<6)
53#define GPIOG_WRITE (1<<6)
54#define GPIOG_READ (1<<1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020055
Aaro Koskinen0f07d942011-02-17 23:29:13 +020056#define XGIFB_ROM_SIZE 65536
57
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020058/* -------------------- Macro definitions ---------------------------- */
59
60#undef XGIFBDEBUG
61
62#ifdef XGIFBDEBUG
63#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
64#else
65#define DPRINTK(fmt, args...)
66#endif
67
68#ifdef XGIFBDEBUG
69static void dumpVGAReg(void)
70{
Prashant P. Shahb654f872010-09-06 17:34:26 +053071 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020072
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030073 xgifb_reg_set(XGISR, 0x05, 0x86);
Prashant P. Shahb654f872010-09-06 17:34:26 +053074 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030075 xgifb_reg_set(XGISR, 0x08, 0x4f);
76 xgifb_reg_set(XGISR, 0x0f, 0x20);
77 xgifb_reg_set(XGISR, 0x11, 0x4f);
78 xgifb_reg_set(XGISR, 0x13, 0x45);
79 xgifb_reg_set(XGISR, 0x14, 0x51);
80 xgifb_reg_set(XGISR, 0x1e, 0x41);
81 xgifb_reg_set(XGISR, 0x1f, 0x0);
82 xgifb_reg_set(XGISR, 0x20, 0xa1);
83 xgifb_reg_set(XGISR, 0x22, 0xfb);
84 xgifb_reg_set(XGISR, 0x26, 0x22);
85 xgifb_reg_set(XGISR, 0x3e, 0x07);
Prashant P. Shahb654f872010-09-06 17:34:26 +053086 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020087
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030088 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
89 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
90 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
91 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020092
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030093 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020094
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030095 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
96 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020097
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030098 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
99 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530100 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300101 xgifb_reg_set(XGICR, 0x99, 0x1);
102 xgifb_reg_set(XGICR, 0x41, 0x40);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530103 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200104
Prashant P. Shahb654f872010-09-06 17:34:26 +0530105 for (i = 0; i < 0x4f; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300106 reg = xgifb_reg_get(XGISR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530107 printk("\no 3c4 %x", i);
108 printk("\ni 3c5 => %x", reg);
109 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200110
Prashant P. Shahb654f872010-09-06 17:34:26 +0530111 for (i = 0; i < 0xF0; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300112 reg = xgifb_reg_get(XGICR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530113 printk("\no 3d4 %x", i);
114 printk("\ni 3d5 => %x", reg);
115 }
116 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300117 xgifb_reg_set(XGIPART1,0x2F,1);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530118 for (i=1; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300119 reg = xgifb_reg_get(XGIPART1, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530120 printk("\no d004 %x", i);
121 printk("\ni d005 => %x", reg);
122 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200123
Prashant P. Shahb654f872010-09-06 17:34:26 +0530124 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300125 reg = xgifb_reg_get(XGIPART2, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530126 printk("\no d010 %x", i);
127 printk("\ni d011 => %x", reg);
128 }
129 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300130 reg = xgifb_reg_get(XGIPART3, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530131 printk("\no d012 %x",i);
132 printk("\ni d013 => %x",reg);
133 }
134 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300135 reg = xgifb_reg_get(XGIPART4, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530136 printk("\no d014 %x",i);
137 printk("\ni d015 => %x",reg);
138 }
139 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200140}
141#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530142static inline void dumpVGAReg(void)
143{
144}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200145#endif
146
147/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530148struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200149
150#if 1
151#define DEBUGPRN(x)
152#else
153#define DEBUGPRN(x) printk(KERN_INFO x "\n");
154#endif
155
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200156/* --------------- Hardware Access Routines -------------------------- */
157
Prashant P. Shahb654f872010-09-06 17:34:26 +0530158static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
159 struct xgi_hw_device_info *HwDeviceExtension,
160 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200161{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530162 unsigned short ModeNo = modeno;
163 unsigned short ModeIdIndex = 0, ClockIndex = 0;
164 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200165
Prashant P. Shahb654f872010-09-06 17:34:26 +0530166 /* unsigned long temp = 0; */
167 int Clock;
168 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
169 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200170
Prashant P. Shahb654f872010-09-06 17:34:26 +0530171 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
172 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200173
Prashant P. Shahb654f872010-09-06 17:34:26 +0530174 /*
175 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
176 if (!temp) {
177 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
178 return 65000;
179 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200180
Prashant P. Shahb654f872010-09-06 17:34:26 +0530181 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
182 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200183
Prashant P. Shahb654f872010-09-06 17:34:26 +0530184 */
185 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200186
Prashant P. Shahb654f872010-09-06 17:34:26 +0530187 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
188
189 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200190}
191
Prashant P. Shahb654f872010-09-06 17:34:26 +0530192static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
193 struct xgi_hw_device_info *HwDeviceExtension,
194 unsigned char modeno, unsigned char rateindex,
195 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
196 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
197 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200198{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530199 unsigned short ModeNo = modeno;
200 unsigned short ModeIdIndex = 0, index = 0;
201 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200202
Prashant P. Shahb654f872010-09-06 17:34:26 +0530203 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
204 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
205 unsigned char sr_data, cr_data, cr_data2;
206 unsigned long cr_data3;
207 int A, B, C, D, E, F, temp, j;
208 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
209 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
210 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
211 ModeIdIndex, XGI_Pr);
212 /*
213 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
214 if (!temp)
215 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200216
Prashant P. Shahb654f872010-09-06 17:34:26 +0530217 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
218 RefreshRateTableIndex += (rateindex - 1);
219 */
220 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200221
Prashant P. Shahb654f872010-09-06 17:34:26 +0530222 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200223
Prashant P. Shahb654f872010-09-06 17:34:26 +0530224 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200225
Prashant P. Shahb654f872010-09-06 17:34:26 +0530226 /* Horizontal total */
227 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
228 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200229
Prashant P. Shahb654f872010-09-06 17:34:26 +0530230 /*
231 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200232
Prashant P. Shahb654f872010-09-06 17:34:26 +0530233 Horizontal display enable end
234 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
235 */
236 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
237 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200238
Prashant P. Shahb654f872010-09-06 17:34:26 +0530239 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200240
Prashant P. Shahb654f872010-09-06 17:34:26 +0530241 /* Horizontal retrace (=sync) start */
242 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
243 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200244
Prashant P. Shahb654f872010-09-06 17:34:26 +0530245 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200246
Prashant P. Shahb654f872010-09-06 17:34:26 +0530247 /* Horizontal blank start */
248 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200249
Prashant P. Shahb654f872010-09-06 17:34:26 +0530250 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200251
Prashant P. Shahb654f872010-09-06 17:34:26 +0530252 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200253
Prashant P. Shahb654f872010-09-06 17:34:26 +0530254 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200255
Prashant P. Shahb654f872010-09-06 17:34:26 +0530256 /* Horizontal blank end */
257 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
258 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200259
Prashant P. Shahb654f872010-09-06 17:34:26 +0530260 /* Horizontal retrace (=sync) end */
261 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200262
Prashant P. Shahb654f872010-09-06 17:34:26 +0530263 temp = HBE - ((E - 1) & 255);
264 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200265
Prashant P. Shahb654f872010-09-06 17:34:26 +0530266 temp = HRE - ((E + F + 3) & 63);
267 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200268
Prashant P. Shahb654f872010-09-06 17:34:26 +0530269 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200270
Prashant P. Shahb654f872010-09-06 17:34:26 +0530271 *left_margin = D * 8;
272 *right_margin = F * 8;
273 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200274
Prashant P. Shahb654f872010-09-06 17:34:26 +0530275 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200276
Prashant P. Shahb654f872010-09-06 17:34:26 +0530277 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200278
Prashant P. Shahb654f872010-09-06 17:34:26 +0530279 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200280
Prashant P. Shahb654f872010-09-06 17:34:26 +0530281 /* Vertical total */
282 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
283 | ((unsigned short) (cr_data2 & 0x20) << 4)
284 | ((unsigned short) (sr_data & 0x01) << 10);
285 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200286
Prashant P. Shahb654f872010-09-06 17:34:26 +0530287 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200288
Prashant P. Shahb654f872010-09-06 17:34:26 +0530289 /* Vertical display enable end */
290 /*
291 VDE = (cr_data & 0xff) |
292 ((unsigned short) (cr_data2 & 0x02) << 7) |
293 ((unsigned short) (cr_data2 & 0x40) << 3) |
294 ((unsigned short) (sr_data & 0x02) << 9);
295 */
296 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
297 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200298
Prashant P. Shahb654f872010-09-06 17:34:26 +0530299 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200300
Prashant P. Shahb654f872010-09-06 17:34:26 +0530301 /* Vertical retrace (=sync) start */
302 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
303 | ((unsigned short) (cr_data2 & 0x80) << 2)
304 | ((unsigned short) (sr_data & 0x08) << 7);
305 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200306
Prashant P. Shahb654f872010-09-06 17:34:26 +0530307 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200308
Prashant P. Shahb654f872010-09-06 17:34:26 +0530309 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200310
Prashant P. Shahb654f872010-09-06 17:34:26 +0530311 /* Vertical blank start */
312 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
313 | ((unsigned short) (cr_data3 & 0x20) << 4)
314 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200315
Prashant P. Shahb654f872010-09-06 17:34:26 +0530316 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200317
Prashant P. Shahb654f872010-09-06 17:34:26 +0530318 /* Vertical blank end */
319 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
320 temp = VBE - ((E - 1) & 511);
321 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200322
Prashant P. Shahb654f872010-09-06 17:34:26 +0530323 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200324
Prashant P. Shahb654f872010-09-06 17:34:26 +0530325 /* Vertical retrace (=sync) end */
326 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
327 temp = VRE - ((E + F - 1) & 31);
328 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200329
Prashant P. Shahb654f872010-09-06 17:34:26 +0530330 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200331
Prashant P. Shahb654f872010-09-06 17:34:26 +0530332 *upper_margin = D;
333 *lower_margin = F;
334 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200335
Prashant P. Shahb654f872010-09-06 17:34:26 +0530336 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
337 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
338 else
339 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200340
Prashant P. Shahb654f872010-09-06 17:34:26 +0530341 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
342 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
343 else
344 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200345
Prashant P. Shahb654f872010-09-06 17:34:26 +0530346 *vmode = FB_VMODE_NONINTERLACED;
347 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
348 *vmode = FB_VMODE_INTERLACED;
349 else {
350 j = 0;
351 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800352 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
353 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
354 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
355 DoubleScanMode) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530356 *vmode = FB_VMODE_DOUBLE;
357 }
358 break;
359 }
360 j++;
361 }
362 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200363
Prashant P. Shahb654f872010-09-06 17:34:26 +0530364 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200365}
366
Randy Dunlap89229672010-08-10 08:46:44 -0700367static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200368{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530369 XGI_Pr->RelIO = BaseAddr;
370 XGI_Pr->P3c4 = BaseAddr + 0x14;
371 XGI_Pr->P3d4 = BaseAddr + 0x24;
372 XGI_Pr->P3c0 = BaseAddr + 0x10;
373 XGI_Pr->P3ce = BaseAddr + 0x1e;
374 XGI_Pr->P3c2 = BaseAddr + 0x12;
375 XGI_Pr->P3ca = BaseAddr + 0x1a;
376 XGI_Pr->P3c6 = BaseAddr + 0x16;
377 XGI_Pr->P3c7 = BaseAddr + 0x17;
378 XGI_Pr->P3c8 = BaseAddr + 0x18;
379 XGI_Pr->P3c9 = BaseAddr + 0x19;
380 XGI_Pr->P3da = BaseAddr + 0x2A;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800381 /* Digital video interface registers (LCD) */
382 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
383 /* 301 TV Encoder registers */
384 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
385 /* 301 Macrovision registers */
386 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
387 /* 301 VGA2 (and LCD) registers */
388 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
389 /* 301 palette address port registers */
390 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200391
392}
393
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200394/* ------------ Interface for init & mode switching code ------------- */
395
Aaro Koskinen8a94d1a2011-04-18 22:14:08 +0300396static unsigned char XGIfb_query_VGA_config_space(
Prashant P. Shahb654f872010-09-06 17:34:26 +0530397 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
398 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200399{
400 static struct pci_dev *pdev = NULL;
401 static unsigned char init = 0, valid_pdev = 0;
402
403 if (!set)
404 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
405 else
406 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
407
408 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400409 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530410 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
411 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200412 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400413 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200414 pci_dev_put(pdev);
415 }
416 }
417
418 if (!valid_pdev) {
419 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
420 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400421 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200422 }
423
424 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530425 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200426 else
427 pci_write_config_dword(pdev, offset, (u32)(*value));
428
Bill Pembertondda08c52010-06-17 13:10:42 -0400429 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200430}
431
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200432/* ------------------ Internal helper routines ----------------- */
433
Aaro Koskinen8a94d1a2011-04-18 22:14:08 +0300434static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300435{
436
437 int found_mode = 0;
438 int XGIfb_mode_idx = 0;
439
440 found_mode = 0;
441 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
442 && (XGIbios_mode[XGIfb_mode_idx].xres
443 <= XGI21_LCDCapList[0].LVDSHDE)) {
444 if ((XGIbios_mode[XGIfb_mode_idx].xres
445 == XGI21_LCDCapList[0].LVDSHDE)
446 && (XGIbios_mode[XGIfb_mode_idx].yres
447 == XGI21_LCDCapList[0].LVDSVDE)
448 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
449 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
450 found_mode = 1;
451 break;
452 }
453 XGIfb_mode_idx++;
454 }
455 if (!found_mode)
456 XGIfb_mode_idx = 0;
457
458 return XGIfb_mode_idx;
459}
460
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200461static void XGIfb_search_mode(const char *name)
462{
463 int i = 0, j = 0, l;
464
Prashant P. Shahb654f872010-09-06 17:34:26 +0530465 if (name == NULL) {
466 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
467 xgifb_mode_idx = DEFAULT_MODE;
468 if ((xgi_video_info.chip == XG21)
469 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
470 == DISPTYPE_LCD)) {
471 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
472 }
473 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200474 }
475
Prashant P. Shahb654f872010-09-06 17:34:26 +0530476 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
477 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
478 xgifb_mode_idx = DEFAULT_MODE;
479 if ((xgi_video_info.chip == XG21)
480 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
481 == DISPTYPE_LCD)) {
482 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
483 }
484 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200485 }
486
Prashant P. Shahb654f872010-09-06 17:34:26 +0530487 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200488 l = min(strlen(name), strlen(XGIbios_mode[i].name));
489 if (!strncmp(name, XGIbios_mode[i].name, l)) {
490 xgifb_mode_idx = i;
491 j = 1;
492 break;
493 }
494 i++;
495 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530496 if (!j)
497 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200498}
499
500static void XGIfb_search_vesamode(unsigned int vesamode)
501{
502 int i = 0, j = 0;
503
Prashant P. Shahb654f872010-09-06 17:34:26 +0530504 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200505
506 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
507 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530508 if ((xgi_video_info.chip == XG21)
509 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
510 == DISPTYPE_LCD)) {
511 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200512 }
513 return;
514 }
515
Prashant P. Shahb654f872010-09-06 17:34:26 +0530516 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200517
Prashant P. Shahb654f872010-09-06 17:34:26 +0530518 while (XGIbios_mode[i].mode_no != 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800519 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
520 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200521 xgifb_mode_idx = i;
522 j = 1;
523 break;
524 }
525 i++;
526 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530527 if (!j)
528 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200529}
530
Randy Dunlap89229672010-08-10 08:46:44 -0700531static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200532{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530533 u8 tmp;
534 unsigned char *pData;
535 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200536
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300537 tmp = xgifb_reg_get(XGISR, 0x1e);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300538 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200539
Prashant P. Shahb654f872010-09-06 17:34:26 +0530540 pData = xgi_video_info.mmio_vbase + 0x20000;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800541 if ((pData[0x0] == 0x55) &&
542 (pData[0x1] == 0xAA) &&
543 (pData[0x65] & 0x1)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530544 i = pData[0x316] | (pData[0x317] << 8);
545 j = pData[i - 1];
546 if (j == 0xff)
547 j = 1;
548
549 k = 0;
550 do {
551 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
552 | (pData[i + 1] << 8);
553 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
554 + 3] << 8);
555 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
556 + 5] << 8);
557 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
558 + 7] << 8);
559 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
560 + 9] << 8);
561 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
562 + 11] << 8);
563 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
564 + 13] << 8);
565 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
566 | (pData[i + 15] << 8);
567 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
568 | (pData[i + 17] << 8);
569 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
570 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
571 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
572 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
573 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
574 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
575 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
576 i += 25;
577 j--;
578 k++;
579 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
580 / sizeof(struct XGI21_LVDSCapStruct))));
581 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200582 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530583 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200584}
585
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200586static int XGIfb_validate_mode(int myindex)
587{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530588 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200589
Prashant P. Shahb654f872010-09-06 17:34:26 +0530590 if (xgi_video_info.chip == XG21) {
591 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
592 == DISPTYPE_LCD) {
593 xres = XGI21_LCDCapList[0].LVDSHDE;
594 yres = XGI21_LCDCapList[0].LVDSVDE;
595 if (XGIbios_mode[myindex].xres > xres)
596 return -1;
597 if (XGIbios_mode[myindex].yres > yres)
598 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800599 if ((XGIbios_mode[myindex].xres < xres) &&
600 (XGIbios_mode[myindex].yres < yres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530601 if (XGIbios_mode[myindex].bpp > 8)
602 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200603 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530604
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200605 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530606 return myindex;
607
608 }
609
610 /* FIXME: for now, all is valid on XG27 */
611 if (xgi_video_info.chip == XG27)
612 return myindex;
613
614 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
615 return -1;
616
617 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
618 case DISPTYPE_LCD:
619 switch (XGIhw_ext.ulCRT2LCDType) {
620 case LCD_640x480:
621 xres = 640;
622 yres = 480;
623 break;
624 case LCD_800x600:
625 xres = 800;
626 yres = 600;
627 break;
628 case LCD_1024x600:
629 xres = 1024;
630 yres = 600;
631 break;
632 case LCD_1024x768:
633 xres = 1024;
634 yres = 768;
635 break;
636 case LCD_1152x768:
637 xres = 1152;
638 yres = 768;
639 break;
640 case LCD_1280x960:
641 xres = 1280;
642 yres = 960;
643 break;
644 case LCD_1280x768:
645 xres = 1280;
646 yres = 768;
647 break;
648 case LCD_1280x1024:
649 xres = 1280;
650 yres = 1024;
651 break;
652 case LCD_1400x1050:
653 xres = 1400;
654 yres = 1050;
655 break;
656 case LCD_1600x1200:
657 xres = 1600;
658 yres = 1200;
659 break;
660 /* case LCD_320x480: */ /* TW: FSTN */
661 /*
662 xres = 320;
663 yres = 480;
664 break;
665 */
666 default:
667 xres = 0;
668 yres = 0;
669 break;
670 }
671 if (XGIbios_mode[myindex].xres > xres)
672 return -1;
673 if (XGIbios_mode[myindex].yres > yres)
674 return -1;
675 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800676 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530677 switch (XGIbios_mode[myindex].xres) {
678 case 512:
679 if (XGIbios_mode[myindex].yres != 512)
680 return -1;
681 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
682 return -1;
683 break;
684 case 640:
685 if ((XGIbios_mode[myindex].yres != 400)
686 && (XGIbios_mode[myindex].yres
687 != 480))
688 return -1;
689 break;
690 case 800:
691 if (XGIbios_mode[myindex].yres != 600)
692 return -1;
693 break;
694 case 1024:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800695 if ((XGIbios_mode[myindex].yres != 600) &&
696 (XGIbios_mode[myindex].yres != 768))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530697 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800698 if ((XGIbios_mode[myindex].yres == 600) &&
699 (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530700 return -1;
701 break;
702 case 1152:
703 if ((XGIbios_mode[myindex].yres) != 768)
704 return -1;
705 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
706 return -1;
707 break;
708 case 1280:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800709 if ((XGIbios_mode[myindex].yres != 768) &&
710 (XGIbios_mode[myindex].yres != 1024))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530711 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800712 if ((XGIbios_mode[myindex].yres == 768) &&
713 (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530714 return -1;
715 break;
716 case 1400:
717 if (XGIbios_mode[myindex].yres != 1050)
718 return -1;
719 break;
720 case 1600:
721 if (XGIbios_mode[myindex].yres != 1200)
722 return -1;
723 break;
724 default:
725 return -1;
726 }
727 } else {
728 switch (XGIbios_mode[myindex].xres) {
729 case 512:
730 if (XGIbios_mode[myindex].yres != 512)
731 return -1;
732 break;
733 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800734 if ((XGIbios_mode[myindex].yres != 400) &&
735 (XGIbios_mode[myindex].yres != 480))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530736 return -1;
737 break;
738 case 800:
739 if (XGIbios_mode[myindex].yres != 600)
740 return -1;
741 break;
742 case 1024:
743 if (XGIbios_mode[myindex].yres != 768)
744 return -1;
745 break;
746 case 1280:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800747 if ((XGIbios_mode[myindex].yres != 960) &&
748 (XGIbios_mode[myindex].yres != 1024))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530749 return -1;
750 if (XGIbios_mode[myindex].yres == 960) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800751 if (XGIhw_ext.ulCRT2LCDType ==
752 LCD_1400x1050)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530753 return -1;
754 }
755 break;
756 case 1400:
757 if (XGIbios_mode[myindex].yres != 1050)
758 return -1;
759 break;
760 case 1600:
761 if (XGIbios_mode[myindex].yres != 1200)
762 return -1;
763 break;
764 default:
765 return -1;
766 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200767 }
768 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530769 case DISPTYPE_TV:
770 switch (XGIbios_mode[myindex].xres) {
771 case 512:
772 case 640:
773 case 800:
774 break;
775 case 720:
776 if (xgi_video_info.TV_type == TVMODE_NTSC) {
777 if (XGIbios_mode[myindex].yres != 480)
778 return -1;
779 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
780 if (XGIbios_mode[myindex].yres != 576)
781 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200782 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530783 /* TW: LVDS/CHRONTEL does not support 720 */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800784 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
785 xgi_video_info.hasVB == HASVB_CHRONTEL) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530786 return -1;
787 }
788 break;
789 case 1024:
790 if (xgi_video_info.TV_type == TVMODE_NTSC) {
791 if (XGIbios_mode[myindex].bpp == 32)
792 return -1;
793 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530794 break;
795 default:
796 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200797 }
798 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530799 case DISPTYPE_CRT2:
800 if (XGIbios_mode[myindex].xres > 1280)
801 return -1;
802 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200803 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530804 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200805
806}
807
808static void XGIfb_search_crt2type(const char *name)
809{
810 int i = 0;
811
Prashant P. Shahb654f872010-09-06 17:34:26 +0530812 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200813 return;
814
Prashant P. Shahb654f872010-09-06 17:34:26 +0530815 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200816 if (!strcmp(name, XGI_crt2type[i].name)) {
817 XGIfb_crt2type = XGI_crt2type[i].type_no;
818 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
819 break;
820 }
821 i++;
822 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530823 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200824 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
825}
826
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200827static u8 XGIfb_search_refresh_rate(unsigned int rate)
828{
829 u16 xres, yres;
830 int i = 0;
831
832 xres = XGIbios_mode[xgifb_mode_idx].xres;
833 yres = XGIbios_mode[xgifb_mode_idx].yres;
834
835 XGIfb_rate_idx = 0;
836 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800837 if ((XGIfb_vrate[i].xres == xres) &&
838 (XGIfb_vrate[i].yres == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200839 if (XGIfb_vrate[i].refresh == rate) {
840 XGIfb_rate_idx = XGIfb_vrate[i].idx;
841 break;
842 } else if (XGIfb_vrate[i].refresh > rate) {
843 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
844 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800845 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200846 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800847 xgi_video_info.refresh_rate =
848 XGIfb_vrate[i].refresh;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530849 } else if (((rate - XGIfb_vrate[i - 1].refresh)
850 <= 2) && (XGIfb_vrate[i].idx
851 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200852 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800853 rate, XGIfb_vrate[i-1].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530854 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800855 xgi_video_info.refresh_rate =
856 XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200857 }
858 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530859 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200860 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800861 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530862 XGIfb_rate_idx = XGIfb_vrate[i].idx;
863 break;
864 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200865 }
866 i++;
867 }
868 if (XGIfb_rate_idx > 0) {
869 return XGIfb_rate_idx;
870 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800871 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
872 rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200873 return 0;
874 }
875}
876
877static void XGIfb_search_tvstd(const char *name)
878{
879 int i = 0;
880
Prashant P. Shahb654f872010-09-06 17:34:26 +0530881 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200882 return;
883
884 while (XGI_tvtype[i].type_no != -1) {
885 if (!strcmp(name, XGI_tvtype[i].name)) {
886 XGIfb_tvmode = XGI_tvtype[i].type_no;
887 break;
888 }
889 i++;
890 }
891}
892
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200893/* ----------- FBDev related routines for all series ----------- */
894
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200895static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
896{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530897 switch (var->bits_per_pixel) {
898 case 8:
899 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200900 var->red.length = var->green.length = var->blue.length = 6;
901 xgi_video_info.video_cmap_len = 256;
902 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530903 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200904 var->red.offset = 11;
905 var->red.length = 5;
906 var->green.offset = 5;
907 var->green.length = 6;
908 var->blue.offset = 0;
909 var->blue.length = 5;
910 var->transp.offset = 0;
911 var->transp.length = 0;
912 xgi_video_info.video_cmap_len = 16;
913 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530914 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200915 var->red.offset = 16;
916 var->red.length = 8;
917 var->green.offset = 8;
918 var->green.length = 8;
919 var->blue.offset = 0;
920 var->blue.length = 8;
921 var->transp.offset = 24;
922 var->transp.length = 8;
923 xgi_video_info.video_cmap_len = 16;
924 break;
925 }
926}
927
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300928/* --------------------- SetMode routines ------------------------- */
929
930static void XGIfb_pre_setmode(void)
931{
932 u8 cr30 = 0, cr31 = 0;
933
934 cr31 = xgifb_reg_get(XGICR, 0x31);
935 cr31 &= ~0x60;
936
937 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
938 case DISPTYPE_CRT2:
939 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
940 cr31 |= XGI_DRIVER_MODE;
941 break;
942 case DISPTYPE_LCD:
943 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
944 cr31 |= XGI_DRIVER_MODE;
945 break;
946 case DISPTYPE_TV:
947 if (xgi_video_info.TV_type == TVMODE_HIVISION)
948 cr30 = (XGI_VB_OUTPUT_HIVISION
949 | XGI_SIMULTANEOUS_VIEW_ENABLE);
950 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
951 cr30 = (XGI_VB_OUTPUT_SVIDEO
952 | XGI_SIMULTANEOUS_VIEW_ENABLE);
953 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
954 cr30 = (XGI_VB_OUTPUT_COMPOSITE
955 | XGI_SIMULTANEOUS_VIEW_ENABLE);
956 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
957 cr30 = (XGI_VB_OUTPUT_SCART
958 | XGI_SIMULTANEOUS_VIEW_ENABLE);
959 cr31 |= XGI_DRIVER_MODE;
960
961 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
962 cr31 |= 0x01;
963 else
964 cr31 &= ~0x01;
965 break;
966 default: /* disable CRT2 */
967 cr30 = 0x00;
968 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
969 }
970
971 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
972 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
973 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
974}
975
976static void XGIfb_post_setmode(void)
977{
978 u8 reg;
979 unsigned char doit = 1;
980 /*
981 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
982 xgifb_reg_set(XGICR, 0x13, 0x00);
983 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
984 *test*
985 */
986 if (xgi_video_info.video_bpp == 8) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800987 /* TW: We can't switch off CRT1 on LVDS/Chrontel
988 * in 8bpp Modes */
989 if ((xgi_video_info.hasVB == HASVB_LVDS) ||
990 (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300991 doit = 0;
992 }
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800993 /* TW: We can't switch off CRT1 on 301B-DH
994 * in 8bpp Modes if using LCD */
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300995 if (xgi_video_info.disp_state & DISPTYPE_LCD)
996 doit = 0;
997 }
998
999 /* TW: We can't switch off CRT1 if bridge is in slave mode */
1000 if (xgi_video_info.hasVB != HASVB_NONE) {
1001 reg = xgifb_reg_get(XGIPART1, 0x00);
1002
1003 if ((reg & 0x50) == 0x10)
1004 doit = 0;
1005
1006 } else {
1007 XGIfb_crt1off = 0;
1008 }
1009
1010 reg = xgifb_reg_get(XGICR, 0x17);
1011 if ((XGIfb_crt1off) && (doit))
1012 reg &= ~0x80;
1013 else
1014 reg |= 0x80;
1015 xgifb_reg_set(XGICR, 0x17, reg);
1016
1017 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
1018
1019 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1020 == HASVB_301)) {
1021
1022 reg = xgifb_reg_get(XGIPART4, 0x01);
1023
1024 if (reg < 0xB0) { /* Set filter for XGI301 */
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001025 switch (xgi_video_info.video_width) {
1026 case 320:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001027 filter_tb = (xgi_video_info.TV_type ==
1028 TVMODE_NTSC) ? 4 : 12;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001029 break;
1030 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001031 filter_tb = (xgi_video_info.TV_type ==
1032 TVMODE_NTSC) ? 5 : 13;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001033 break;
1034 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001035 filter_tb = (xgi_video_info.TV_type ==
1036 TVMODE_NTSC) ? 6 : 14;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001037 break;
1038 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001039 filter_tb = (xgi_video_info.TV_type ==
1040 TVMODE_NTSC) ? 7 : 15;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001041 break;
1042 default:
1043 filter = -1;
1044 break;
1045 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001046 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
1047
1048 if (xgi_video_info.TV_type == TVMODE_NTSC) {
1049
1050 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
1051
1052 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1053
1054 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
1055
1056 } else if (xgi_video_info.TV_plug
1057 == TVPLUG_COMPOSITE) {
1058
1059 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1060
1061 switch (xgi_video_info.video_width) {
1062 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001063 xgifb_reg_set(XGIPART2,
1064 0x35,
1065 0xEB);
1066 xgifb_reg_set(XGIPART2,
1067 0x36,
1068 0x04);
1069 xgifb_reg_set(XGIPART2,
1070 0x37,
1071 0x25);
1072 xgifb_reg_set(XGIPART2,
1073 0x38,
1074 0x18);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001075 break;
1076 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001077 xgifb_reg_set(XGIPART2,
1078 0x35,
1079 0xEE);
1080 xgifb_reg_set(XGIPART2,
1081 0x36,
1082 0x0C);
1083 xgifb_reg_set(XGIPART2,
1084 0x37,
1085 0x22);
1086 xgifb_reg_set(XGIPART2,
1087 0x38,
1088 0x08);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001089 break;
1090 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001091 xgifb_reg_set(XGIPART2,
1092 0x35,
1093 0xEB);
1094 xgifb_reg_set(XGIPART2,
1095 0x36,
1096 0x15);
1097 xgifb_reg_set(XGIPART2,
1098 0x37,
1099 0x25);
1100 xgifb_reg_set(XGIPART2,
1101 0x38,
1102 0xF6);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001103 break;
1104 }
1105 }
1106
1107 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
1108
1109 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1110
1111 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
1112
1113 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1114
1115 } else if (xgi_video_info.TV_plug
1116 == TVPLUG_COMPOSITE) {
1117
1118 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1119
1120 switch (xgi_video_info.video_width) {
1121 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001122 xgifb_reg_set(XGIPART2,
1123 0x35,
1124 0xF1);
1125 xgifb_reg_set(XGIPART2,
1126 0x36,
1127 0xF7);
1128 xgifb_reg_set(XGIPART2,
1129 0x37,
1130 0x1F);
1131 xgifb_reg_set(XGIPART2,
1132 0x38,
1133 0x32);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001134 break;
1135 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001136 xgifb_reg_set(XGIPART2,
1137 0x35,
1138 0xF3);
1139 xgifb_reg_set(XGIPART2,
1140 0x36,
1141 0x00);
1142 xgifb_reg_set(XGIPART2,
1143 0x37,
1144 0x1D);
1145 xgifb_reg_set(XGIPART2,
1146 0x38,
1147 0x20);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001148 break;
1149 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001150 xgifb_reg_set(XGIPART2,
1151 0x35,
1152 0xFC);
1153 xgifb_reg_set(XGIPART2,
1154 0x36,
1155 0xFB);
1156 xgifb_reg_set(XGIPART2,
1157 0x37,
1158 0x14);
1159 xgifb_reg_set(XGIPART2,
1160 0x38,
1161 0x2A);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001162 break;
1163 }
1164 }
1165 }
1166
1167 if ((filter >= 0) && (filter <= 7)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001168 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1169 filter_tb, filter,
1170 XGI_TV_filter[filter_tb].
1171 filter[filter][0],
1172 XGI_TV_filter[filter_tb].
1173 filter[filter][1],
1174 XGI_TV_filter[filter_tb].
1175 filter[filter][2],
1176 XGI_TV_filter[filter_tb].
1177 filter[filter][3]
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001178 );
1179 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001180 XGIPART2,
1181 0x35,
1182 (XGI_TV_filter[filter_tb].
1183 filter[filter][0]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001184 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001185 XGIPART2,
1186 0x36,
1187 (XGI_TV_filter[filter_tb].
1188 filter[filter][1]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001189 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001190 XGIPART2,
1191 0x37,
1192 (XGI_TV_filter[filter_tb].
1193 filter[filter][2]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001194 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001195 XGIPART2,
1196 0x38,
1197 (XGI_TV_filter[filter_tb].
1198 filter[filter][3]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001199 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001200 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001201 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001202}
1203
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001204static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301205 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001206{
1207
Prashant P. Shahb654f872010-09-06 17:34:26 +05301208 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1209 + var->hsync_len;
1210 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1211 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001212#if defined(__powerpc__)
1213 u8 sr_data, cr_data;
1214#endif
1215 unsigned int drate = 0, hrate = 0;
1216 int found_mode = 0;
1217 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301218 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001219
1220 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301221 /* 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 +02001222
Prashant P. Shahb654f872010-09-06 17:34:26 +05301223 info->var.xres_virtual = var->xres_virtual;
1224 info->var.yres_virtual = var->yres_virtual;
1225 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001226
1227 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1228 vtotal <<= 1;
1229 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1230 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301231 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1232 /* vtotal <<= 1; */
1233 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001234 }
1235
Prashant P. Shahb654f872010-09-06 17:34:26 +05301236 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001237 DPRINTK("XGIfb: Invalid 'var' information\n");
1238 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301239 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1240 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001241
Prashant P. Shahb654f872010-09-06 17:34:26 +05301242 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001243 drate = 1000000000 / var->pixclock;
1244 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301245 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1246 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001247 } else {
1248 xgi_video_info.refresh_rate = 60;
1249 }
1250
1251 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001252 var->xres,
1253 var->yres,
1254 var->bits_per_pixel,
1255 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001256
1257 old_mode = xgifb_mode_idx;
1258 xgifb_mode_idx = 0;
1259
Prashant P. Shahb654f872010-09-06 17:34:26 +05301260 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1261 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1262 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1263 && (XGIbios_mode[xgifb_mode_idx].yres
1264 == var->yres)
1265 && (XGIbios_mode[xgifb_mode_idx].bpp
1266 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001267 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1268 found_mode = 1;
1269 break;
1270 }
1271 xgifb_mode_idx++;
1272 }
1273
Prashant P. Shahb654f872010-09-06 17:34:26 +05301274 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001275 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1276 else
1277 xgifb_mode_idx = -1;
1278
Prashant P. Shahb654f872010-09-06 17:34:26 +05301279 if (xgifb_mode_idx < 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001280 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1281 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001282 xgifb_mode_idx = old_mode;
1283 return -EINVAL;
1284 }
1285
Prashant P. Shahb654f872010-09-06 17:34:26 +05301286 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001287 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1288 xgi_video_info.refresh_rate = 60;
1289 }
1290
Prashant P. Shahb654f872010-09-06 17:34:26 +05301291 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001292
1293 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301294 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001295 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1296 XGIfb_mode_no);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001297 return -EINVAL;
1298 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301299 info->fix.line_length = ((info->var.xres_virtual
1300 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001301
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001302 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001303
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001304 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001305 xgifb_reg_set(XGISR,
1306 0x0E,
1307 (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001308
1309 XGIfb_post_setmode();
1310
Prashant P. Shahb654f872010-09-06 17:34:26 +05301311 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1312 XGIbios_mode[xgifb_mode_idx].xres,
1313 XGIbios_mode[xgifb_mode_idx].yres,
1314 XGIbios_mode[xgifb_mode_idx].bpp,
1315 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001316
1317 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1318 xgi_video_info.video_vwidth = info->var.xres_virtual;
1319 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1320 xgi_video_info.video_vheight = info->var.yres_virtual;
1321 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1322 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301323 xgi_video_info.video_linelength = info->var.xres_virtual
1324 * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301325 switch (xgi_video_info.video_bpp) {
1326 case 8:
1327 xgi_video_info.DstColor = 0x0000;
1328 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1329 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001330#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001331 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001332 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001333#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301334 break;
1335 case 16:
1336 xgi_video_info.DstColor = 0x8000;
1337 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001338#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001339 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001340 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001341#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301342 xgi_video_info.video_cmap_len = 16;
1343 break;
1344 case 32:
1345 xgi_video_info.DstColor = 0xC000;
1346 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1347 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001348#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001349 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001350 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001351#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301352 break;
1353 default:
1354 xgi_video_info.video_cmap_len = 16;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001355 printk(KERN_ERR "XGIfb: Unsupported depth %d",
1356 xgi_video_info.video_bpp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301357 break;
1358 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001359 }
1360 XGIfb_bpp_to_var(var); /*update ARGB info*/
1361 DEBUGPRN("End of do_set_var");
1362
1363 dumpVGAReg();
1364 return 0;
1365}
1366
1367#ifdef XGIFB_PAN
1368static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1369{
1370 unsigned int base;
1371
Prashant P. Shahb654f872010-09-06 17:34:26 +05301372 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001373
1374 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301375 /* printk("Pan: xo: %d xv %d xr %d\n",
1376 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001377 return -EINVAL;
1378 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301379 if (var->yoffset > (var->yres_virtual - var->yres)) {
1380 /* printk("Pan: yo: %d yv %d yr %d\n",
1381 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001382 return -EINVAL;
1383 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301384 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001385
Prashant P. Shahb654f872010-09-06 17:34:26 +05301386 /* calculate base bpp dep. */
1387 switch (var->bits_per_pixel) {
1388 case 16:
1389 base >>= 1;
1390 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001391 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301392 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001393 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301394 default:
1395 base >>= 2;
1396 break;
1397 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001398
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001399 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001400
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001401 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1402 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1403 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1404 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
Aaro Koskinen65283d42011-04-18 22:14:02 +03001405 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001406
Prashant P. Shahb654f872010-09-06 17:34:26 +05301407 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene67f4d42011-04-18 22:14:00 +03001408 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001409 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1410 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1411 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001412 xgifb_reg_and_or(XGIPART1,
1413 0x02,
1414 0x7F,
1415 ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301416 }
1417 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001418 return 0;
1419}
1420#endif
1421
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001422static int XGIfb_open(struct fb_info *info, int user)
1423{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301424 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001425}
1426
1427static int XGIfb_release(struct fb_info *info, int user)
1428{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301429 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001430}
1431
1432static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1433{
1434 int rc = 16;
1435
Prashant P. Shahb654f872010-09-06 17:34:26 +05301436 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001437 case 8:
1438 rc = 256;
1439 break;
1440 case 16:
1441 rc = 16;
1442 break;
1443 case 32:
1444 rc = 16;
1445 break;
1446 }
1447 return rc;
1448}
1449
Prashant P. Shahb654f872010-09-06 17:34:26 +05301450static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1451 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001452{
1453 if (regno >= XGIfb_get_cmap_len(&info->var))
1454 return 1;
1455
1456 switch (info->var.bits_per_pixel) {
1457 case 8:
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001458 outb(regno, XGIDACA);
1459 outb((red >> 10), XGIDACD);
1460 outb((green >> 10), XGIDACD);
1461 outb((blue >> 10), XGIDACD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001462 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001463 outb(regno, XGIDAC2A);
1464 outb((red >> 8), XGIDAC2D);
1465 outb((green >> 8), XGIDAC2D);
1466 outb((blue >> 8), XGIDAC2D);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001467 }
1468 break;
1469 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301470 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1471 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1472 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001473 break;
1474 case 32:
1475 red >>= 8;
1476 green >>= 8;
1477 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301478 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1479 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001480 break;
1481 }
1482 return 0;
1483}
1484
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001485/* ----------- FBDev related routines for all series ---------- */
1486
1487static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1488 struct fb_info *info)
1489{
1490 DEBUGPRN("inside get_fix");
1491 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1492
1493 strcpy(fix->id, myid);
1494
1495 fix->smem_start = xgi_video_info.video_base;
1496
1497 fix->smem_len = xgi_video_info.video_size;
1498
1499 fix->type = video_type;
1500 fix->type_aux = 0;
1501 if (xgi_video_info.video_bpp == 8)
1502 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1503 else
1504 fix->visual = FB_VISUAL_DIRECTCOLOR;
1505 fix->xpanstep = 0;
1506#ifdef XGIFB_PAN
1507 if (XGIfb_ypan)
1508 fix->ypanstep = 1;
1509#endif
1510 fix->ywrapstep = 0;
1511 fix->line_length = xgi_video_info.video_linelength;
1512 fix->mmio_start = xgi_video_info.mmio_base;
1513 fix->mmio_len = xgi_video_info.mmio_size;
1514 fix->accel = FB_ACCEL_XGI_XABRE;
1515
1516 DEBUGPRN("end of get_fix");
1517 return 0;
1518}
1519
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001520static int XGIfb_set_par(struct fb_info *info)
1521{
1522 int err;
1523
Prashant P. Shahb654f872010-09-06 17:34:26 +05301524 /* printk("XGIfb: inside set_par\n"); */
1525 err = XGIfb_do_set_var(&info->var, 1, info);
1526 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001527 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001528 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301529 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001530 return 0;
1531}
1532
Prashant P. Shahb654f872010-09-06 17:34:26 +05301533static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001534{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301535 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1536 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001537 unsigned int vtotal = 0;
1538 unsigned int drate = 0, hrate = 0;
1539 int found_mode = 0;
1540 int refresh_rate, search_idx;
1541
1542 DEBUGPRN("Inside check_var");
1543
Prashant P. Shahb654f872010-09-06 17:34:26 +05301544 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1545 vtotal = var->upper_margin + var->yres + var->lower_margin
1546 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001547 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301548 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1549 vtotal = var->upper_margin + var->yres + var->lower_margin
1550 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001551 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301552 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1553 vtotal = var->upper_margin + (var->yres / 2)
1554 + var->lower_margin + var->vsync_len;
1555 } else
1556 vtotal = var->upper_margin + var->yres + var->lower_margin
1557 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001558
Prashant P. Shahb654f872010-09-06 17:34:26 +05301559 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001560 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301561
1562 if (var->pixclock && htotal && vtotal) {
1563 drate = 1000000000 / var->pixclock;
1564 hrate = (drate * 1000) / htotal;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001565 xgi_video_info.refresh_rate =
1566 (unsigned int) (hrate * 2 / vtotal);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301567 printk(KERN_DEBUG
1568 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1569 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1570 __func__, var->pixclock, htotal, vtotal,
1571 __func__, drate, hrate, xgi_video_info.refresh_rate);
1572 } else {
1573 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001574 }
1575
Prashant P. Shahb654f872010-09-06 17:34:26 +05301576 /*
1577 if ((var->pixclock) && (htotal)) {
1578 drate = 1E12 / var->pixclock;
1579 hrate = drate / htotal;
1580 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1581 } else {
1582 refresh_rate = 60;
1583 }
1584 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001585 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301586 if ((var->xres == 1024) && (var->yres == 600))
1587 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001588
1589 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301590 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1591 (XGIbios_mode[search_idx].xres <= var->xres)) {
1592 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1593 (XGIbios_mode[search_idx].yres == var->yres) &&
1594 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1595 if (XGIfb_validate_mode(search_idx) > 0) {
1596 found_mode = 1;
1597 break;
1598 }
1599 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001600 search_idx++;
1601 }
1602
Prashant P. Shahb654f872010-09-06 17:34:26 +05301603 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001604
1605 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1606 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301607 search_idx = 0;
1608 while (XGIbios_mode[search_idx].mode_no != 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301609 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001610 (var->yres <= XGIbios_mode[search_idx].yres) &&
1611 (var->bits_per_pixel ==
1612 XGIbios_mode[search_idx].bpp)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301613 if (XGIfb_validate_mode(search_idx) > 0) {
1614 found_mode = 1;
1615 break;
1616 }
1617 }
1618 search_idx++;
1619 }
1620 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001621 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301622 var->yres = XGIbios_mode[search_idx].yres;
1623 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1624 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001625
1626 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301627 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001628 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301629 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001630 }
1631 }
1632
1633 /* TW: TODO: Check the refresh rate */
1634
1635 /* Adapt RGB settings */
1636 XGIfb_bpp_to_var(var);
1637
1638 /* Sanity check for offsets */
1639 if (var->xoffset < 0)
1640 var->xoffset = 0;
1641 if (var->yoffset < 0)
1642 var->yoffset = 0;
1643
Prashant P. Shahb654f872010-09-06 17:34:26 +05301644 if (!XGIfb_ypan) {
1645 if (var->xres != var->xres_virtual)
1646 var->xres_virtual = var->xres;
1647 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001648 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301649 } /* else { */
1650 /* TW: Now patch yres_virtual if we use panning */
1651 /* May I do this? */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001652 /* var->yres_virtual = xgi_video_info.heapstart /
1653 (var->xres * (var->bits_per_pixel >> 3)); */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301654 /* if (var->yres_virtual <= var->yres) { */
1655 /* TW: Paranoia check */
1656 /* var->yres_virtual = var->yres; */
1657 /* } */
1658 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001659
1660 /* Truncate offsets to maximum if too high */
1661 if (var->xoffset > var->xres_virtual - var->xres)
1662 var->xoffset = var->xres_virtual - var->xres - 1;
1663
1664 if (var->yoffset > var->yres_virtual - var->yres)
1665 var->yoffset = var->yres_virtual - var->yres - 1;
1666
1667 /* Set everything else to 0 */
1668 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301669 var->green.msb_right =
1670 var->blue.msb_right =
1671 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001672
1673 DEBUGPRN("end of check_var");
1674 return 0;
1675}
1676
1677#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301678static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1679 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001680{
1681 int err;
1682
Prashant P. Shahb654f872010-09-06 17:34:26 +05301683 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001684
1685 if (var->xoffset > (var->xres_virtual - var->xres))
1686 return -EINVAL;
1687 if (var->yoffset > (var->yres_virtual - var->yres))
1688 return -EINVAL;
1689
1690 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301691 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1692 || var->xoffset)
1693 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001694 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301695 if (var->xoffset + info->var.xres > info->var.xres_virtual
1696 || var->yoffset + info->var.yres
1697 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001698 return -EINVAL;
1699 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301700 err = XGIfb_pan_var(var);
1701 if (err < 0)
1702 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001703
1704 info->var.xoffset = var->xoffset;
1705 info->var.yoffset = var->yoffset;
1706 if (var->vmode & FB_VMODE_YWRAP)
1707 info->var.vmode |= FB_VMODE_YWRAP;
1708 else
1709 info->var.vmode &= ~FB_VMODE_YWRAP;
1710
Prashant P. Shahb654f872010-09-06 17:34:26 +05301711 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001712 return 0;
1713}
1714#endif
1715
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001716static int XGIfb_blank(int blank, struct fb_info *info)
1717{
1718 u8 reg;
1719
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001720 reg = xgifb_reg_get(XGICR, 0x17);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001721
Prashant P. Shahb654f872010-09-06 17:34:26 +05301722 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001723 reg &= 0x7f;
1724 else
1725 reg |= 0x80;
1726
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001727 xgifb_reg_set(XGICR, 0x17, reg);
1728 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1729 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301730 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001731}
1732
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001733static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301734 .owner = THIS_MODULE,
1735 .fb_open = XGIfb_open,
1736 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001737 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301738 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001739 .fb_setcolreg = XGIfb_setcolreg,
1740#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301741 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001742#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301743 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001744 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001745 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001746 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301747 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001748};
1749
1750/* ---------------- Chip generation dependent routines ---------------- */
1751
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001752/* for XGI 315/550/650/740/330 */
1753
1754static int XGIfb_get_dram_size(void)
1755{
1756
Prashant P. Shahb654f872010-09-06 17:34:26 +05301757 u8 ChannelNum, tmp;
1758 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001759
1760 /* xorg driver sets 32MB * 1 channel */
1761 if (xgi_video_info.chip == XG27)
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001762 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001763
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001764 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301765 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1766 case XGI_DRAM_SIZE_1MB:
1767 xgi_video_info.video_size = 0x100000;
1768 break;
1769 case XGI_DRAM_SIZE_2MB:
1770 xgi_video_info.video_size = 0x200000;
1771 break;
1772 case XGI_DRAM_SIZE_4MB:
1773 xgi_video_info.video_size = 0x400000;
1774 break;
1775 case XGI_DRAM_SIZE_8MB:
1776 xgi_video_info.video_size = 0x800000;
1777 break;
1778 case XGI_DRAM_SIZE_16MB:
1779 xgi_video_info.video_size = 0x1000000;
1780 break;
1781 case XGI_DRAM_SIZE_32MB:
1782 xgi_video_info.video_size = 0x2000000;
1783 break;
1784 case XGI_DRAM_SIZE_64MB:
1785 xgi_video_info.video_size = 0x4000000;
1786 break;
1787 case XGI_DRAM_SIZE_128MB:
1788 xgi_video_info.video_size = 0x8000000;
1789 break;
1790 case XGI_DRAM_SIZE_256MB:
1791 xgi_video_info.video_size = 0x10000000;
1792 break;
1793 default:
1794 return -1;
1795 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001796
Prashant P. Shahb654f872010-09-06 17:34:26 +05301797 tmp = (reg & 0x0c) >> 2;
1798 switch (xgi_video_info.chip) {
1799 case XG20:
1800 case XG21:
1801 case XG27:
1802 ChannelNum = 1;
1803 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001804
Prashant P. Shahb654f872010-09-06 17:34:26 +05301805 case XG42:
1806 if (reg & 0x04)
1807 ChannelNum = 2;
1808 else
1809 ChannelNum = 1;
1810 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001811
Prashant P. Shahb654f872010-09-06 17:34:26 +05301812 case XG45:
1813 if (tmp == 1)
1814 ChannelNum = 2;
1815 else if (tmp == 2)
1816 ChannelNum = 3;
1817 else if (tmp == 3)
1818 ChannelNum = 4;
1819 else
1820 ChannelNum = 1;
1821 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001822
Prashant P. Shahb654f872010-09-06 17:34:26 +05301823 case XG40:
1824 default:
1825 if (tmp == 2)
1826 ChannelNum = 2;
1827 else if (tmp == 3)
1828 ChannelNum = 3;
1829 else
1830 ChannelNum = 1;
1831 break;
1832 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001833
Prashant P. Shahb654f872010-09-06 17:34:26 +05301834 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1835 /* PLiad fixed for benchmarking and fb set */
1836 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1837 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001838
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001839 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1840 reg,
1841 xgi_video_info.video_size, ChannelNum);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301842 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001843
1844}
1845
1846static void XGIfb_detect_VB(void)
1847{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301848 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001849
1850 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1851
Prashant P. Shahb654f872010-09-06 17:34:26 +05301852 switch (xgi_video_info.hasVB) {
1853 case HASVB_LVDS_CHRONTEL:
1854 case HASVB_CHRONTEL:
1855 break;
1856 case HASVB_301:
1857 case HASVB_302:
1858 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1859 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001860 }
1861
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001862 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001863
1864 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1865 XGIfb_crt1off = 0;
1866 else {
1867 if (cr32 & 0x5F)
1868 XGIfb_crt1off = 1;
1869 else
1870 XGIfb_crt1off = 0;
1871 }
1872
1873 if (XGIfb_crt2type != -1)
1874 /* TW: Override with option */
1875 xgi_video_info.disp_state = XGIfb_crt2type;
1876 else if (cr32 & XGI_VB_TV)
1877 xgi_video_info.disp_state = DISPTYPE_TV;
1878 else if (cr32 & XGI_VB_LCD)
1879 xgi_video_info.disp_state = DISPTYPE_LCD;
1880 else if (cr32 & XGI_VB_CRT2)
1881 xgi_video_info.disp_state = DISPTYPE_CRT2;
1882 else
1883 xgi_video_info.disp_state = 0;
1884
Prashant P. Shahb654f872010-09-06 17:34:26 +05301885 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001886 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301887 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001888 else if (cr32 & XGI_VB_HIVISION) {
1889 xgi_video_info.TV_type = TVMODE_HIVISION;
1890 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301891 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001892 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1893 else if (cr32 & XGI_VB_COMPOSITE)
1894 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1895 else if (cr32 & XGI_VB_SCART)
1896 xgi_video_info.TV_plug = TVPLUG_SCART;
1897
Prashant P. Shahb654f872010-09-06 17:34:26 +05301898 if (xgi_video_info.TV_type == 0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001899 temp = xgifb_reg_get(XGICR, 0x38);
Aaro Koskinenebe78462011-03-13 12:26:08 +02001900 if (temp & 0x10)
1901 xgi_video_info.TV_type = TVMODE_PAL;
1902 else
1903 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001904 }
1905
1906 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301907 if (XGIfb_forcecrt1 != -1) {
1908 if (XGIfb_forcecrt1)
1909 XGIfb_crt1off = 0;
1910 else
1911 XGIfb_crt1off = 1;
1912 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001913}
1914
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001915static int XGIfb_has_VB(void)
1916{
1917 u8 vb_chipid;
1918
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001919 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001920 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301921 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001922 xgi_video_info.hasVB = HASVB_301;
1923 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301924 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001925 xgi_video_info.hasVB = HASVB_302;
1926 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301927 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001928 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001929 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001930 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001931 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001932}
1933
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001934static void XGIfb_get_VB_type(void)
1935{
1936 u8 reg;
1937
1938 if (!XGIfb_has_VB()) {
1939 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1940 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1941 case XGI310_EXTERNAL_CHIP_LVDS:
1942 xgi_video_info.hasVB = HASVB_LVDS;
1943 break;
1944 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
1945 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1946 break;
1947 default:
1948 break;
1949 }
1950 }
1951}
1952
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001953XGIINITSTATIC int __init XGIfb_setup(char *options)
1954{
1955 char *this_opt;
1956
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001957 xgi_video_info.refresh_rate = 0;
1958
Prashant P. Shahb654f872010-09-06 17:34:26 +05301959 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001960
1961 if (!options || !*options)
1962 return 0;
1963
Prashant P. Shahb654f872010-09-06 17:34:26 +05301964 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001965
Prashant P. Shahb654f872010-09-06 17:34:26 +05301966 if (!*this_opt)
1967 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001968
1969 if (!strncmp(this_opt, "mode:", 5)) {
1970 XGIfb_search_mode(this_opt + 5);
1971 } else if (!strncmp(this_opt, "vesa:", 5)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001972 XGIfb_search_vesamode(simple_strtoul(
1973 this_opt + 5, NULL, 0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001974 } else if (!strncmp(this_opt, "mode:", 5)) {
1975 XGIfb_search_mode(this_opt + 5);
1976 } else if (!strncmp(this_opt, "vesa:", 5)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001977 XGIfb_search_vesamode(simple_strtoul(
1978 this_opt + 5, NULL, 0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001979 } else if (!strncmp(this_opt, "vrate:", 6)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001980 xgi_video_info.refresh_rate = simple_strtoul(
1981 this_opt + 6, NULL, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001982 } else if (!strncmp(this_opt, "rate:", 5)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001983 xgi_video_info.refresh_rate = simple_strtoul(
1984 this_opt + 5, NULL, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001985 } else if (!strncmp(this_opt, "off", 3)) {
1986 XGIfb_off = 1;
1987 } else if (!strncmp(this_opt, "crt1off", 7)) {
1988 XGIfb_crt1off = 1;
1989 } else if (!strncmp(this_opt, "filter:", 7)) {
1990 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
1991 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1992 XGIfb_search_crt2type(this_opt + 14);
1993 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001994 XGIfb_forcecrt1 = (int)simple_strtoul(
1995 this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301996 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001997 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301998 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1999 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302000 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002001 enable_dstn = 1;
2002 /* TW: DSTN overrules forcecrt2type */
2003 XGIfb_crt2type = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002004 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302005 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2006 if (XGIfb_pdc & ~0x3c) {
2007 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2008 XGIfb_pdc = 0;
2009 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002010 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302011 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002012 } else if (!strncmp(this_opt, "userom:", 7)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002013 XGIfb_userom = (int)simple_strtoul(
2014 this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302015 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002016 /* XGIfb_useoem = (int)simple_strtoul(
2017 this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002018 } else {
2019 XGIfb_search_mode(this_opt);
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002020 /* printk(KERN_INFO "XGIfb: Invalid option %s\n",
2021 this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002022 }
2023
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002024 /* TW: Panning only with acceleration */
Javier Martinez Canillas0089bf12011-02-21 18:16:43 +01002025 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002026
2027 }
2028 printk("\nxgifb: outa xgifb_setup 3450");
2029 return 0;
2030}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002031
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002032static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002033{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002034 void __iomem *rom_address;
2035 unsigned char *rom_copy;
2036 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002037
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002038 rom_address = pci_map_rom(dev, &rom_size);
2039 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002040 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002041
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002042 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2043 if (rom_copy == NULL)
2044 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002045
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002046 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2047 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002048
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002049done:
2050 pci_unmap_rom(dev, rom_address);
2051 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002052}
2053
Randy Dunlap89229672010-08-10 08:46:44 -07002054static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302055 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002056{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302057 u8 reg, reg1;
2058 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002059 int ret;
2060
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002061 if (XGIfb_off)
2062 return -ENXIO;
2063
2064 XGIfb_registered = 0;
2065
Bill Pembertone4147ab2010-06-17 13:10:50 -04002066 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302067 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2068 if (!fb_info)
2069 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002070
Prashant P. Shahb654f872010-09-06 17:34:26 +05302071 xgi_video_info.chip_id = pdev->device;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002072 pci_read_config_byte(pdev,
2073 PCI_REVISION_ID,
2074 &xgi_video_info.revision_id);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302075 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002076
Prashant P. Shahb654f872010-09-06 17:34:26 +05302077 xgi_video_info.pcibus = pdev->bus->number;
2078 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2079 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2080 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2081 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002082
Prashant P. Shahb654f872010-09-06 17:34:26 +05302083 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2084 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002085 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302086 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2087 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2088 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2089 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002090 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002091
Aaro Koskinenbb292232011-02-17 23:29:11 +02002092 if (pci_enable_device(pdev)) {
2093 ret = -EIO;
2094 goto error;
2095 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002096
Prashant P. Shahb654f872010-09-06 17:34:26 +05302097 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002098
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002099 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002100 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002101
Prashant P. Shahb654f872010-09-06 17:34:26 +05302102 if (reg1 != 0xa1) { /*I/O error */
2103 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002104 ret = -EIO;
2105 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302106 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002107
2108 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302109 case PCI_DEVICE_ID_XG_20:
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002110 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002111 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002112 if (CR48&GPIOG_READ)
2113 xgi_video_info.chip = XG21;
2114 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302115 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002116 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2117 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302118 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002119 xgi_video_info.chip = XG40;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002120 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2121 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302122 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002123 xgi_video_info.chip = XG41;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002124 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2125 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302126 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002127 xgi_video_info.chip = XG42;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002128 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2129 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302130 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002131 xgi_video_info.chip = XG27;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002132 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2133 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302134 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002135 ret = -ENODEV;
2136 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002137 }
2138
Prashant P. Shahb654f872010-09-06 17:34:26 +05302139 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2140 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002141
Prashant P. Shahb654f872010-09-06 17:34:26 +05302142 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002143 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302144 if (XGIhw_ext.pjVirtualRomBase)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002145 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
2146 XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002147 else
2148 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302149 } else {
2150 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002151 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302152 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302153 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002154
Prashant P. Shahb654f872010-09-06 17:34:26 +05302155 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302156 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002157 ret = -ENODEV;
2158 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302159 }
2160
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002161 if ((xgifb_mode_idx < 0) ||
2162 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302163 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002164 xgifb_reg_or(XGISR,
2165 IND_XGI_PCI_ADDRESS_SET,
2166 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302167 /* Enable 2D accelerator engine */
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002168 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302169 }
2170
2171 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2172
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002173 if (!request_mem_region(xgi_video_info.video_base,
2174 xgi_video_info.video_size,
2175 "XGIfb FB")) {
2176 printk("unable request memory size %x",
2177 xgi_video_info.video_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302178 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2179 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002180 ret = -ENODEV;
2181 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302182 }
2183
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002184 if (!request_mem_region(xgi_video_info.mmio_base,
2185 xgi_video_info.mmio_size,
2186 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302187 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002188 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002189 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302190 }
2191
2192 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2193 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002194 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2195 xgi_video_info.mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302196
2197 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002198 xgi_video_info.video_base,
2199 xgi_video_info.video_vbase,
2200 xgi_video_info.video_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302201
2202 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002203 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2204 xgi_video_info.mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302205 printk("XGIfb: XGIInitNew() ...");
2206 if (XGIInitNew(&XGIhw_ext))
2207 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002208 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002209 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002210
Prashant P. Shahb654f872010-09-06 17:34:26 +05302211 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002212
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002213 if ((xgifb_mode_idx < 0) ||
2214 ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002215 xgi_video_info.hasVB = HASVB_NONE;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002216 if ((xgi_video_info.chip == XG20) ||
2217 (xgi_video_info.chip == XG27)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302218 xgi_video_info.hasVB = HASVB_NONE;
2219 } else if (xgi_video_info.chip == XG21) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002220 CR38 = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302221 if ((CR38&0xE0) == 0xC0) {
2222 xgi_video_info.disp_state = DISPTYPE_LCD;
2223 if (!XGIfb_GetXG21LVDSData()) {
2224 int m;
2225 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2226 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002227 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
Aaro Koskinen8104e322011-03-13 12:26:22 +02002228 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302229 }
2230 }
2231 }
2232 } else if ((CR38&0xE0) == 0x60) {
2233 xgi_video_info.hasVB = HASVB_CHRONTEL;
2234 } else {
2235 xgi_video_info.hasVB = HASVB_NONE;
2236 }
2237 } else {
2238 XGIfb_get_VB_type();
2239 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002240
Prashant P. Shahb654f872010-09-06 17:34:26 +05302241 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002242
Prashant P. Shahb654f872010-09-06 17:34:26 +05302243 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002244
2245 switch (xgi_video_info.hasVB) {
2246 case HASVB_301:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002247 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002248 if (reg >= 0xE0) {
2249 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302250 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2251 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002252 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302253 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2254 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002255 /* else if (reg >= 0xB0) {
2256 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002257 reg1 = xgifb_reg_get(XGIPART4, 0x23);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302258 printk("XGIfb: XGI301B bridge detected\n");
2259 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002260 else {
2261 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2262 printk("XGIfb: XGI301 bridge detected\n");
2263 }
2264 break;
2265 case HASVB_302:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002266 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002267 if (reg >= 0xE0) {
2268 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302269 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2270 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002271 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302272 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2273 } else if (reg >= 0xB0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002274 reg1 = xgifb_reg_get(XGIPART4, 0x23);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002275
Prashant P. Shahb654f872010-09-06 17:34:26 +05302276 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002277
2278 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302279 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002280 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2281 }
2282 break;
2283 case HASVB_LVDS:
2284 XGIhw_ext.ulExternalChip = 0x1;
2285 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2286 break;
2287 case HASVB_TRUMPION:
2288 XGIhw_ext.ulExternalChip = 0x2;
2289 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2290 break;
2291 case HASVB_CHRONTEL:
2292 XGIhw_ext.ulExternalChip = 0x4;
2293 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2294 break;
2295 case HASVB_LVDS_CHRONTEL:
2296 XGIhw_ext.ulExternalChip = 0x5;
2297 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2298 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302299 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002300 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2301 break;
2302 }
2303
Prashant P. Shahb654f872010-09-06 17:34:26 +05302304 if (xgi_video_info.hasVB != HASVB_NONE)
2305 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002306
2307 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2308 if (XGIfb_crt1off)
2309 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2310 else
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002311 xgi_video_info.disp_state |= (DISPMODE_MIRROR |
2312 DISPTYPE_CRT1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002313 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002314 xgi_video_info.disp_state = DISPMODE_SINGLE |
2315 DISPTYPE_CRT1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002316 }
2317
2318 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302319 if (!enable_dstn) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002320 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302321 reg &= 0x0f;
2322 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002323
Prashant P. Shahb654f872010-09-06 17:34:26 +05302324 } else {
2325 /* TW: FSTN/DSTN */
2326 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2327 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002328 }
2329
2330 XGIfb_detectedpdc = 0;
2331
Prashant P. Shahb654f872010-09-06 17:34:26 +05302332 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002333
Prashant P. Shahb654f872010-09-06 17:34:26 +05302334 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002335
Prashant P. Shahb654f872010-09-06 17:34:26 +05302336 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2337 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2338 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2339 int tmp;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002340 tmp = xgifb_reg_get(XGICR, 0x34);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302341 if (tmp <= 0x13) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002342 /* Currently on LCDA?
2343 *(Some BIOSes leave CR38) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002344 tmp = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302345 if ((tmp & 0x03) == 0x03) {
2346 /* XGI_Pr.XGI_UseLCDA = 1; */
2347 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002348 /* Currently on LCDA?
2349 *(Some newer BIOSes set D0 in CR35) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002350 tmp = xgifb_reg_get(XGICR, 0x35);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302351 if (tmp & 0x01) {
2352 /* XGI_Pr.XGI_UseLCDA = 1; */
2353 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002354 tmp = xgifb_reg_get(XGICR,
2355 0x30);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302356 if (tmp & 0x20) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002357 tmp = xgifb_reg_get(
2358 XGIPART1, 0x13);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302359 if (tmp & 0x04) {
2360 /* XGI_Pr.XGI_UseLCDA = 1; */
2361 }
2362 }
2363 }
2364 }
2365 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002366
Prashant P. Shahb654f872010-09-06 17:34:26 +05302367 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002368
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002369 if (xgifb_mode_idx >= 0)
2370 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2371
2372 if (xgifb_mode_idx < 0) {
2373 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302374 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002375 xgifb_mode_idx = DEFAULT_LCDMODE;
2376 if (xgi_video_info.chip == XG21)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002377 xgifb_mode_idx =
2378 XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002379 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302380 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002381 xgifb_mode_idx = DEFAULT_TVMODE;
2382 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302383 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002384 xgifb_mode_idx = DEFAULT_MODE;
2385 break;
2386 }
2387 }
2388
2389 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2390
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002391 /* yilin set default refresh rate */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302392 if (xgi_video_info.refresh_rate == 0)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002393 xgi_video_info.refresh_rate = 60;
2394 if (XGIfb_search_refresh_rate(
2395 xgi_video_info.refresh_rate) == 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302396 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2397 xgi_video_info.refresh_rate = 60;
2398 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002399
2400 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002401 xgi_video_info.video_vwidth =
2402 xgi_video_info.video_width =
2403 XGIbios_mode[xgifb_mode_idx].xres;
2404 xgi_video_info.video_vheight =
2405 xgi_video_info.video_height =
2406 XGIbios_mode[xgifb_mode_idx].yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002407 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002408 xgi_video_info.video_linelength =
2409 xgi_video_info.video_width *
2410 (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302411 switch (xgi_video_info.video_bpp) {
2412 case 8:
2413 xgi_video_info.DstColor = 0x0000;
2414 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002415 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302416 break;
2417 case 16:
2418 xgi_video_info.DstColor = 0x8000;
2419 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002420 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302421 break;
2422 case 32:
2423 xgi_video_info.DstColor = 0xC000;
2424 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002425 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302426 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002427 default:
2428 xgi_video_info.video_cmap_len = 16;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002429 printk(KERN_INFO "XGIfb: Unsupported depth %d",
2430 xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002431 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302432 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002433
2434 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002435 xgi_video_info.video_width,
2436 xgi_video_info.video_height,
2437 xgi_video_info.video_bpp,
2438 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002439
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002440 default_var.xres =
2441 default_var.xres_virtual =
2442 xgi_video_info.video_width;
2443 default_var.yres =
2444 default_var.yres_virtual =
2445 xgi_video_info.video_height;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002446 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2447
2448 XGIfb_bpp_to_var(&default_var);
2449
2450 default_var.pixclock = (u32) (1000000000 /
2451 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2452 XGIfb_mode_no, XGIfb_rate_idx));
2453
Prashant P. Shahb654f872010-09-06 17:34:26 +05302454 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2455 XGIfb_mode_no, XGIfb_rate_idx,
2456 &default_var.left_margin, &default_var.right_margin,
2457 &default_var.upper_margin, &default_var.lower_margin,
2458 &default_var.hsync_len, &default_var.vsync_len,
2459 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002460
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002461 if ((default_var.vmode & FB_VMODE_MASK) ==
2462 FB_VMODE_INTERLACED) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302463 default_var.yres <<= 1;
2464 default_var.yres_virtual <<= 1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002465 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2466 FB_VMODE_DOUBLE) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302467 default_var.pixclock >>= 1;
2468 default_var.yres >>= 1;
2469 default_var.yres_virtual >>= 1;
2470 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002471
Prashant P. Shahb654f872010-09-06 17:34:26 +05302472 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002473
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002474 fb_info->flags = FBINFO_FLAG_DEFAULT;
2475 fb_info->var = default_var;
2476 fb_info->fix = XGIfb_fix;
2477 fb_info->par = &xgi_video_info;
2478 fb_info->screen_base = xgi_video_info.video_vbase;
2479 fb_info->fbops = &XGIfb_ops;
2480 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2481 fb_info->pseudo_palette = pseudo_palette;
2482
2483 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2484
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002485#ifdef CONFIG_MTRR
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002486 xgi_video_info.mtrr = mtrr_add(
2487 (unsigned int) xgi_video_info.video_base,
2488 (unsigned int) xgi_video_info.video_size,
2489 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302490 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002491 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002492#endif
2493
Aaro Koskinenbb292232011-02-17 23:29:11 +02002494 if (register_framebuffer(fb_info) < 0) {
2495 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002496 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002497 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002498
2499 XGIfb_registered = 1;
2500
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002501 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002502 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002503
2504 }
2505
2506 dumpVGAReg();
2507
2508 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002509
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002510error_1:
2511 iounmap(xgi_video_info.mmio_vbase);
2512 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002513 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002514error_0:
2515 release_mem_region(xgi_video_info.video_base,
2516 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002517error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002518 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002519 framebuffer_release(fb_info);
2520 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002521}
2522
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002523/*****************************************************/
2524/* PCI DEVICE HANDLING */
2525/*****************************************************/
2526
2527static void __devexit xgifb_remove(struct pci_dev *pdev)
2528{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302529 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002530 iounmap(xgi_video_info.mmio_vbase);
2531 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002532 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002533 release_mem_region(xgi_video_info.video_base,
2534 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002535 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302536 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002537 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02002538}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002539
2540static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302541 .name = "xgifb",
2542 .id_table = xgifb_pci_table,
2543 .probe = xgifb_probe,
2544 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002545};
2546
2547XGIINITSTATIC int __init xgifb_init(void)
2548{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002549 char *option = NULL;
2550
2551 if (fb_get_options("xgifb", &option))
2552 return -ENODEV;
2553 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04002554
Prashant P. Shahb654f872010-09-06 17:34:26 +05302555 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002556}
2557
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002558#ifndef MODULE
2559module_init(xgifb_init);
2560#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002561
2562/*****************************************************/
2563/* MODULE */
2564/*****************************************************/
2565
2566#ifdef MODULE
2567
Prashant P. Shahb654f872010-09-06 17:34:26 +05302568static char *mode = NULL;
2569static int vesa = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002570static unsigned int rate = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002571static unsigned int mem = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302572static char *forcecrt2type = NULL;
2573static int forcecrt1 = -1;
2574static int pdc = -1;
2575static int pdc1 = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302576static int noypan = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302577static int userom = -1;
2578static int useoem = -1;
2579static char *tvstandard = NULL;
2580static int nocrt2rate = 0;
2581static int scalelcd = -1;
2582static char *specialtiming = NULL;
2583static int lvdshl = -1;
2584static int tvxposoffset = 0, tvyposoffset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002585#if !defined(__i386__) && !defined(__x86_64__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302586static int resetcard = 0;
2587static int videoram = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002588#endif
2589
2590MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2591MODULE_LICENSE("GPL");
2592MODULE_AUTHOR("XGITECH , Others");
2593
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002594module_param(mem, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002595module_param(noypan, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002596module_param(userom, int, 0);
2597module_param(useoem, int, 0);
2598module_param(mode, charp, 0);
2599module_param(vesa, int, 0);
2600module_param(rate, int, 0);
2601module_param(forcecrt1, int, 0);
2602module_param(forcecrt2type, charp, 0);
2603module_param(scalelcd, int, 0);
2604module_param(pdc, int, 0);
2605module_param(pdc1, int, 0);
2606module_param(specialtiming, charp, 0);
2607module_param(lvdshl, int, 0);
2608module_param(tvstandard, charp, 0);
2609module_param(tvxposoffset, int, 0);
2610module_param(tvyposoffset, int, 0);
2611module_param(filter, int, 0);
2612module_param(nocrt2rate, int, 0);
2613#if !defined(__i386__) && !defined(__x86_64__)
2614module_param(resetcard, int, 0);
2615module_param(videoram, int, 0);
2616#endif
2617
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002618MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302619 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2620 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002621
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002622MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302623 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2624 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2625 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2626 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002627
2628MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302629 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2630 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002631
2632MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302633 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2634 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2635 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002636
2637MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302638 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2639 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2640 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002641
2642MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302643 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2644 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2645 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2646 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2647 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2648 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2649 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2650 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002651
2652MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302653 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2654 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2655 "show black bars around the image, TMDS panels will probably do the scaling\n"
2656 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002657
2658MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302659 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2660 "should detect this correctly in most cases; however, sometimes this is not\n"
2661 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2662 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2663 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2664 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002665
2666MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302667 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2668 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2669 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2670 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002671
2672MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302673 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002674
2675MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302676 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002677
2678MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302679 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2680 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002681
2682MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302683 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2684 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002685
2686MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302687 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2688 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002689
2690MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302691 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2692 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002693
2694MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302695 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2696 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002697
Randy Dunlap89229672010-08-10 08:46:44 -07002698static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002699{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302700 printk("\nXGIfb_init_module");
2701 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002702 XGIfb_search_mode(mode);
2703 else if (vesa != -1)
2704 XGIfb_search_vesamode(vesa);
2705
Prashant P. Shahb654f872010-09-06 17:34:26 +05302706 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002707}
2708
2709static void __exit xgifb_remove_module(void)
2710{
2711 pci_unregister_driver(&xgifb_driver);
2712 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2713}
2714
2715module_init(xgifb_init_module);
2716module_exit(xgifb_remove_module);
2717
Prashant P. Shahb654f872010-09-06 17:34:26 +05302718#endif /* /MODULE */