blob: d45d5aadd93d9f90eeb6a7551236b7712343885c [file] [log] [blame]
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001/*
2 * XG20, XG21, XG40, XG42 frame buffer device
3 * for Linux kernels 2.5.x, 2.6.x
4 * Base on TW's sis fbdev code.
5 */
6
Prashant P. Shahb654f872010-09-06 17:34:26 +05307/* #include <linux/config.h> */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02008#include <linux/version.h>
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/kernel.h>
12#include <linux/spinlock.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/tty.h>
17#include <linux/slab.h>
18#include <linux/delay.h>
19#include <linux/fb.h>
20#include <linux/console.h>
21#include <linux/selection.h>
22#include <linux/ioport.h>
23#include <linux/init.h>
24#include <linux/pci.h>
25#include <linux/vmalloc.h>
26#include <linux/vt_kern.h>
27#include <linux/capability.h>
28#include <linux/fs.h>
29#include <linux/types.h>
30#include <linux/proc_fs.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020031
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020032#ifndef XGIFB_PAN
33#define XGIFB_PAN
34#endif
35
36#include <asm/io.h>
37#ifdef CONFIG_MTRR
38#include <asm/mtrr.h>
39#endif
40
41#include "XGIfb.h"
42#include "vgatypes.h"
43#include "XGI_main.h"
44#include "vb_util.h"
45
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020046#define Index_CR_GPIO_Reg1 0x48
47#define Index_CR_GPIO_Reg2 0x49
48#define Index_CR_GPIO_Reg3 0x4a
49
50#define GPIOG_EN (1<<6)
51#define GPIOG_WRITE (1<<6)
52#define GPIOG_READ (1<<1)
53int XGIfb_GetXG21DefaultLVDSModeIdx(void);
54
Aaro Koskinen0f07d942011-02-17 23:29:13 +020055#define XGIFB_ROM_SIZE 65536
56
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020057/* -------------------- Macro definitions ---------------------------- */
58
59#undef XGIFBDEBUG
60
61#ifdef XGIFBDEBUG
62#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
63#else
64#define DPRINTK(fmt, args...)
65#endif
66
67#ifdef XGIFBDEBUG
68static void dumpVGAReg(void)
69{
Prashant P. Shahb654f872010-09-06 17:34:26 +053070 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020071
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030072 xgifb_reg_set(XGISR, 0x05, 0x86);
Prashant P. Shahb654f872010-09-06 17:34:26 +053073 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030074 xgifb_reg_set(XGISR, 0x08, 0x4f);
75 xgifb_reg_set(XGISR, 0x0f, 0x20);
76 xgifb_reg_set(XGISR, 0x11, 0x4f);
77 xgifb_reg_set(XGISR, 0x13, 0x45);
78 xgifb_reg_set(XGISR, 0x14, 0x51);
79 xgifb_reg_set(XGISR, 0x1e, 0x41);
80 xgifb_reg_set(XGISR, 0x1f, 0x0);
81 xgifb_reg_set(XGISR, 0x20, 0xa1);
82 xgifb_reg_set(XGISR, 0x22, 0xfb);
83 xgifb_reg_set(XGISR, 0x26, 0x22);
84 xgifb_reg_set(XGISR, 0x3e, 0x07);
Prashant P. Shahb654f872010-09-06 17:34:26 +053085 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020086
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030087 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
88 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
89 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
90 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020091
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030092 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020093
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030094 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
95 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020096
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030097 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
98 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
Prashant P. Shahb654f872010-09-06 17:34:26 +053099 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300100 xgifb_reg_set(XGICR, 0x99, 0x1);
101 xgifb_reg_set(XGICR, 0x41, 0x40);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530102 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200103
Prashant P. Shahb654f872010-09-06 17:34:26 +0530104 for (i = 0; i < 0x4f; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300105 reg = xgifb_reg_get(XGISR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530106 printk("\no 3c4 %x", i);
107 printk("\ni 3c5 => %x", reg);
108 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200109
Prashant P. Shahb654f872010-09-06 17:34:26 +0530110 for (i = 0; i < 0xF0; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300111 reg = xgifb_reg_get(XGICR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530112 printk("\no 3d4 %x", i);
113 printk("\ni 3d5 => %x", reg);
114 }
115 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300116 xgifb_reg_set(XGIPART1,0x2F,1);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530117 for (i=1; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300118 reg = xgifb_reg_get(XGIPART1, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530119 printk("\no d004 %x", i);
120 printk("\ni d005 => %x", reg);
121 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200122
Prashant P. Shahb654f872010-09-06 17:34:26 +0530123 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300124 reg = xgifb_reg_get(XGIPART2, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530125 printk("\no d010 %x", i);
126 printk("\ni d011 => %x", reg);
127 }
128 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300129 reg = xgifb_reg_get(XGIPART3, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530130 printk("\no d012 %x",i);
131 printk("\ni d013 => %x",reg);
132 }
133 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300134 reg = xgifb_reg_get(XGIPART4, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530135 printk("\no d014 %x",i);
136 printk("\ni d015 => %x",reg);
137 }
138 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200139}
140#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530141static inline void dumpVGAReg(void)
142{
143}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200144#endif
145
146/* data for XGI components */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530147struct video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200148
149#if 1
150#define DEBUGPRN(x)
151#else
152#define DEBUGPRN(x) printk(KERN_INFO x "\n");
153#endif
154
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200155/* --------------- Hardware Access Routines -------------------------- */
156
Prashant P. Shahb654f872010-09-06 17:34:26 +0530157static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
158 struct xgi_hw_device_info *HwDeviceExtension,
159 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200160{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530161 unsigned short ModeNo = modeno;
162 unsigned short ModeIdIndex = 0, ClockIndex = 0;
163 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200164
Prashant P. Shahb654f872010-09-06 17:34:26 +0530165 /* unsigned long temp = 0; */
166 int Clock;
167 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
168 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200169
Prashant P. Shahb654f872010-09-06 17:34:26 +0530170 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
171 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200172
Prashant P. Shahb654f872010-09-06 17:34:26 +0530173 /*
174 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
175 if (!temp) {
176 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
177 return 65000;
178 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200179
Prashant P. Shahb654f872010-09-06 17:34:26 +0530180 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
181 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200182
Prashant P. Shahb654f872010-09-06 17:34:26 +0530183 */
184 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200185
Prashant P. Shahb654f872010-09-06 17:34:26 +0530186 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
187
188 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200189}
190
Prashant P. Shahb654f872010-09-06 17:34:26 +0530191static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
192 struct xgi_hw_device_info *HwDeviceExtension,
193 unsigned char modeno, unsigned char rateindex,
194 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
195 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
196 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200197{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530198 unsigned short ModeNo = modeno;
199 unsigned short ModeIdIndex = 0, index = 0;
200 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200201
Prashant P. Shahb654f872010-09-06 17:34:26 +0530202 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
203 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
204 unsigned char sr_data, cr_data, cr_data2;
205 unsigned long cr_data3;
206 int A, B, C, D, E, F, temp, j;
207 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
208 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
209 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
210 ModeIdIndex, XGI_Pr);
211 /*
212 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
213 if (!temp)
214 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200215
Prashant P. Shahb654f872010-09-06 17:34:26 +0530216 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
217 RefreshRateTableIndex += (rateindex - 1);
218 */
219 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200220
Prashant P. Shahb654f872010-09-06 17:34:26 +0530221 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200222
Prashant P. Shahb654f872010-09-06 17:34:26 +0530223 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200224
Prashant P. Shahb654f872010-09-06 17:34:26 +0530225 /* Horizontal total */
226 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
227 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200228
Prashant P. Shahb654f872010-09-06 17:34:26 +0530229 /*
230 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200231
Prashant P. Shahb654f872010-09-06 17:34:26 +0530232 Horizontal display enable end
233 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
234 */
235 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
236 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200237
Prashant P. Shahb654f872010-09-06 17:34:26 +0530238 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200239
Prashant P. Shahb654f872010-09-06 17:34:26 +0530240 /* Horizontal retrace (=sync) start */
241 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
242 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200243
Prashant P. Shahb654f872010-09-06 17:34:26 +0530244 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200245
Prashant P. Shahb654f872010-09-06 17:34:26 +0530246 /* Horizontal blank start */
247 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200248
Prashant P. Shahb654f872010-09-06 17:34:26 +0530249 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200250
Prashant P. Shahb654f872010-09-06 17:34:26 +0530251 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200252
Prashant P. Shahb654f872010-09-06 17:34:26 +0530253 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200254
Prashant P. Shahb654f872010-09-06 17:34:26 +0530255 /* Horizontal blank end */
256 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
257 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200258
Prashant P. Shahb654f872010-09-06 17:34:26 +0530259 /* Horizontal retrace (=sync) end */
260 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200261
Prashant P. Shahb654f872010-09-06 17:34:26 +0530262 temp = HBE - ((E - 1) & 255);
263 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200264
Prashant P. Shahb654f872010-09-06 17:34:26 +0530265 temp = HRE - ((E + F + 3) & 63);
266 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200267
Prashant P. Shahb654f872010-09-06 17:34:26 +0530268 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200269
Prashant P. Shahb654f872010-09-06 17:34:26 +0530270 *left_margin = D * 8;
271 *right_margin = F * 8;
272 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200273
Prashant P. Shahb654f872010-09-06 17:34:26 +0530274 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200275
Prashant P. Shahb654f872010-09-06 17:34:26 +0530276 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200277
Prashant P. Shahb654f872010-09-06 17:34:26 +0530278 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200279
Prashant P. Shahb654f872010-09-06 17:34:26 +0530280 /* Vertical total */
281 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
282 | ((unsigned short) (cr_data2 & 0x20) << 4)
283 | ((unsigned short) (sr_data & 0x01) << 10);
284 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200285
Prashant P. Shahb654f872010-09-06 17:34:26 +0530286 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200287
Prashant P. Shahb654f872010-09-06 17:34:26 +0530288 /* Vertical display enable end */
289 /*
290 VDE = (cr_data & 0xff) |
291 ((unsigned short) (cr_data2 & 0x02) << 7) |
292 ((unsigned short) (cr_data2 & 0x40) << 3) |
293 ((unsigned short) (sr_data & 0x02) << 9);
294 */
295 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
296 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200297
Prashant P. Shahb654f872010-09-06 17:34:26 +0530298 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200299
Prashant P. Shahb654f872010-09-06 17:34:26 +0530300 /* Vertical retrace (=sync) start */
301 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
302 | ((unsigned short) (cr_data2 & 0x80) << 2)
303 | ((unsigned short) (sr_data & 0x08) << 7);
304 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200305
Prashant P. Shahb654f872010-09-06 17:34:26 +0530306 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200307
Prashant P. Shahb654f872010-09-06 17:34:26 +0530308 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200309
Prashant P. Shahb654f872010-09-06 17:34:26 +0530310 /* Vertical blank start */
311 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
312 | ((unsigned short) (cr_data3 & 0x20) << 4)
313 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200314
Prashant P. Shahb654f872010-09-06 17:34:26 +0530315 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200316
Prashant P. Shahb654f872010-09-06 17:34:26 +0530317 /* Vertical blank end */
318 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
319 temp = VBE - ((E - 1) & 511);
320 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200321
Prashant P. Shahb654f872010-09-06 17:34:26 +0530322 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200323
Prashant P. Shahb654f872010-09-06 17:34:26 +0530324 /* Vertical retrace (=sync) end */
325 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
326 temp = VRE - ((E + F - 1) & 31);
327 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200328
Prashant P. Shahb654f872010-09-06 17:34:26 +0530329 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200330
Prashant P. Shahb654f872010-09-06 17:34:26 +0530331 *upper_margin = D;
332 *lower_margin = F;
333 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200334
Prashant P. Shahb654f872010-09-06 17:34:26 +0530335 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
336 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
337 else
338 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200339
Prashant P. Shahb654f872010-09-06 17:34:26 +0530340 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
341 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
342 else
343 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200344
Prashant P. Shahb654f872010-09-06 17:34:26 +0530345 *vmode = FB_VMODE_NONINTERLACED;
346 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
347 *vmode = FB_VMODE_INTERLACED;
348 else {
349 j = 0;
350 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
351 if (XGI_Pr->EModeIDTable[j].Ext_ModeID
352 == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
353 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
354 & DoubleScanMode) {
355 *vmode = FB_VMODE_DOUBLE;
356 }
357 break;
358 }
359 j++;
360 }
361 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200362
Prashant P. Shahb654f872010-09-06 17:34:26 +0530363 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200364}
365
Randy Dunlap89229672010-08-10 08:46:44 -0700366static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200367{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530368 XGI_Pr->RelIO = BaseAddr;
369 XGI_Pr->P3c4 = BaseAddr + 0x14;
370 XGI_Pr->P3d4 = BaseAddr + 0x24;
371 XGI_Pr->P3c0 = BaseAddr + 0x10;
372 XGI_Pr->P3ce = BaseAddr + 0x1e;
373 XGI_Pr->P3c2 = BaseAddr + 0x12;
374 XGI_Pr->P3ca = BaseAddr + 0x1a;
375 XGI_Pr->P3c6 = BaseAddr + 0x16;
376 XGI_Pr->P3c7 = BaseAddr + 0x17;
377 XGI_Pr->P3c8 = BaseAddr + 0x18;
378 XGI_Pr->P3c9 = BaseAddr + 0x19;
379 XGI_Pr->P3da = BaseAddr + 0x2A;
380 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
381 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
382 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
383 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
384 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200385
386}
387
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200388void XGIfb_set_reg4(u16 port, unsigned long data)
389{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530390 outl((u32)(data & 0xffffffff), port);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200391}
392
393u32 XGIfb_get_reg3(u16 port)
394{
395 u32 data;
396
397 data = inl(port);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530398 return data;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200399}
400
401/* ------------ Interface for init & mode switching code ------------- */
402
Prashant P. Shahb654f872010-09-06 17:34:26 +0530403unsigned char XGIfb_query_VGA_config_space(
404 struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
405 unsigned long set, unsigned long *value)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200406{
407 static struct pci_dev *pdev = NULL;
408 static unsigned char init = 0, valid_pdev = 0;
409
410 if (!set)
411 DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset);
412 else
413 DPRINTK("XGIfb: Set offset 0x%lx to 0x%lx\n", offset, *value);
414
415 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400416 init = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530417 pdev = pci_get_device(PCI_VENDOR_ID_XG, xgi_video_info.chip_id,
418 pdev);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200419 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400420 valid_pdev = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200421 pci_dev_put(pdev);
422 }
423 }
424
425 if (!valid_pdev) {
426 printk(KERN_DEBUG "XGIfb: Can't find XGI %d VGA device.\n",
427 xgi_video_info.chip_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400428 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200429 }
430
431 if (set == 0)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530432 pci_read_config_dword(pdev, offset, (u32 *) value);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200433 else
434 pci_write_config_dword(pdev, offset, (u32)(*value));
435
Bill Pembertondda08c52010-06-17 13:10:42 -0400436 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200437}
438
Prashant P. Shahb654f872010-09-06 17:34:26 +0530439/*
440unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200441 unsigned long offset, unsigned long set, unsigned long *value)
442{
443 static struct pci_dev *pdev = NULL;
444 static unsigned char init = 0, valid_pdev = 0;
445 u16 nbridge_id = 0;
446
447 if (!init) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400448 init = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200449 switch (xgi_video_info.chip) {
450 case XGI_540:
451 nbridge_id = PCI_DEVICE_ID_XG_540;
452 break;
453 case XGI_630:
454 nbridge_id = PCI_DEVICE_ID_XG_630;
455 break;
456 case XGI_730:
457 nbridge_id = PCI_DEVICE_ID_XG_730;
458 break;
459 case XGI_550:
460 nbridge_id = PCI_DEVICE_ID_XG_550;
461 break;
462 case XGI_650:
463 nbridge_id = PCI_DEVICE_ID_XG_650;
464 break;
465 case XGI_740:
466 nbridge_id = PCI_DEVICE_ID_XG_740;
467 break;
468 default:
469 nbridge_id = 0;
470 break;
471 }
472
Atul Sowanifc2347e2010-11-03 18:40:56 +0530473 pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
474 if (pdev) {
Bill Pembertondda08c52010-06-17 13:10:42 -0400475 valid_pdev = 1;
Atul Sowanifc2347e2010-11-03 18:40:56 +0530476 pci_dev_put(pdev);
477 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200478 }
479
480 if (!valid_pdev) {
481 printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530482 nbridge_id);
Bill Pembertondda08c52010-06-17 13:10:42 -0400483 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200484 }
485
486 if (set == 0)
487 pci_read_config_dword(pdev, offset, (u32 *)value);
488 else
489 pci_write_config_dword(pdev, offset, (u32)(*value));
490
Bill Pembertondda08c52010-06-17 13:10:42 -0400491 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200492}
493*/
494/* ------------------ Internal helper routines ----------------- */
495
496static void XGIfb_search_mode(const char *name)
497{
498 int i = 0, j = 0, l;
499
Prashant P. Shahb654f872010-09-06 17:34:26 +0530500 if (name == NULL) {
501 printk(KERN_ERR "XGIfb: Internal error, using default mode.\n");
502 xgifb_mode_idx = DEFAULT_MODE;
503 if ((xgi_video_info.chip == XG21)
504 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
505 == DISPTYPE_LCD)) {
506 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
507 }
508 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200509 }
510
Prashant P. Shahb654f872010-09-06 17:34:26 +0530511 if (!strcmp(name, XGIbios_mode[MODE_INDEX_NONE].name)) {
512 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
513 xgifb_mode_idx = DEFAULT_MODE;
514 if ((xgi_video_info.chip == XG21)
515 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
516 == DISPTYPE_LCD)) {
517 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
518 }
519 return;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200520 }
521
Prashant P. Shahb654f872010-09-06 17:34:26 +0530522 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200523 l = min(strlen(name), strlen(XGIbios_mode[i].name));
524 if (!strncmp(name, XGIbios_mode[i].name, l)) {
525 xgifb_mode_idx = i;
526 j = 1;
527 break;
528 }
529 i++;
530 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530531 if (!j)
532 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200533}
534
535static void XGIfb_search_vesamode(unsigned int vesamode)
536{
537 int i = 0, j = 0;
538
Prashant P. Shahb654f872010-09-06 17:34:26 +0530539 if (vesamode == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200540
541 printk(KERN_ERR "XGIfb: Mode 'none' not supported anymore. Using default.\n");
542 xgifb_mode_idx = DEFAULT_MODE;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530543 if ((xgi_video_info.chip == XG21)
544 && ((xgi_video_info.disp_state & DISPTYPE_DISP2)
545 == DISPTYPE_LCD)) {
546 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200547 }
548 return;
549 }
550
Prashant P. Shahb654f872010-09-06 17:34:26 +0530551 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200552
Prashant P. Shahb654f872010-09-06 17:34:26 +0530553 while (XGIbios_mode[i].mode_no != 0) {
554 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
555 || (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200556 xgifb_mode_idx = i;
557 j = 1;
558 break;
559 }
560 i++;
561 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530562 if (!j)
563 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200564}
565
Randy Dunlap89229672010-08-10 08:46:44 -0700566static int XGIfb_GetXG21LVDSData(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200567{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530568 u8 tmp;
569 unsigned char *pData;
570 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200571
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300572 tmp = xgifb_reg_get(XGISR, 0x1e);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300573 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200574
Prashant P. Shahb654f872010-09-06 17:34:26 +0530575 pData = xgi_video_info.mmio_vbase + 0x20000;
576 if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
577 i = pData[0x316] | (pData[0x317] << 8);
578 j = pData[i - 1];
579 if (j == 0xff)
580 j = 1;
581
582 k = 0;
583 do {
584 XGI21_LCDCapList[k].LVDS_Capability = pData[i]
585 | (pData[i + 1] << 8);
586 XGI21_LCDCapList[k].LVDSHT = pData[i + 2] | (pData[i
587 + 3] << 8);
588 XGI21_LCDCapList[k].LVDSVT = pData[i + 4] | (pData[i
589 + 5] << 8);
590 XGI21_LCDCapList[k].LVDSHDE = pData[i + 6] | (pData[i
591 + 7] << 8);
592 XGI21_LCDCapList[k].LVDSVDE = pData[i + 8] | (pData[i
593 + 9] << 8);
594 XGI21_LCDCapList[k].LVDSHFP = pData[i + 10] | (pData[i
595 + 11] << 8);
596 XGI21_LCDCapList[k].LVDSVFP = pData[i + 12] | (pData[i
597 + 13] << 8);
598 XGI21_LCDCapList[k].LVDSHSYNC = pData[i + 14]
599 | (pData[i + 15] << 8);
600 XGI21_LCDCapList[k].LVDSVSYNC = pData[i + 16]
601 | (pData[i + 17] << 8);
602 XGI21_LCDCapList[k].VCLKData1 = pData[i + 18];
603 XGI21_LCDCapList[k].VCLKData2 = pData[i + 19];
604 XGI21_LCDCapList[k].PSC_S1 = pData[i + 20];
605 XGI21_LCDCapList[k].PSC_S2 = pData[i + 21];
606 XGI21_LCDCapList[k].PSC_S3 = pData[i + 22];
607 XGI21_LCDCapList[k].PSC_S4 = pData[i + 23];
608 XGI21_LCDCapList[k].PSC_S5 = pData[i + 24];
609 i += 25;
610 j--;
611 k++;
612 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
613 / sizeof(struct XGI21_LVDSCapStruct))));
614 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200615 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530616 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200617}
618
619int XGIfb_GetXG21DefaultLVDSModeIdx(void)
620{
621
622 int found_mode = 0;
623 int XGIfb_mode_idx = 0;
624
625 found_mode = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530626 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
627 && (XGIbios_mode[XGIfb_mode_idx].xres
628 <= XGI21_LCDCapList[0].LVDSHDE)) {
629 if ((XGIbios_mode[XGIfb_mode_idx].xres
630 == XGI21_LCDCapList[0].LVDSHDE)
631 && (XGIbios_mode[XGIfb_mode_idx].yres
632 == XGI21_LCDCapList[0].LVDSVDE)
633 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200634 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
635 found_mode = 1;
636 break;
637 }
638 XGIfb_mode_idx++;
639 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530640 if (!found_mode)
641 XGIfb_mode_idx = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200642
Prashant P. Shahb654f872010-09-06 17:34:26 +0530643 return XGIfb_mode_idx;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200644}
645
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200646static int XGIfb_validate_mode(int myindex)
647{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530648 u16 xres, yres;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200649
Prashant P. Shahb654f872010-09-06 17:34:26 +0530650 if (xgi_video_info.chip == XG21) {
651 if ((xgi_video_info.disp_state & DISPTYPE_DISP2)
652 == DISPTYPE_LCD) {
653 xres = XGI21_LCDCapList[0].LVDSHDE;
654 yres = XGI21_LCDCapList[0].LVDSVDE;
655 if (XGIbios_mode[myindex].xres > xres)
656 return -1;
657 if (XGIbios_mode[myindex].yres > yres)
658 return -1;
659 if ((XGIbios_mode[myindex].xres < xres)
660 && (XGIbios_mode[myindex].yres < yres)) {
661 if (XGIbios_mode[myindex].bpp > 8)
662 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200663 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530664
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200665 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530666 return myindex;
667
668 }
669
670 /* FIXME: for now, all is valid on XG27 */
671 if (xgi_video_info.chip == XG27)
672 return myindex;
673
674 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
675 return -1;
676
677 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
678 case DISPTYPE_LCD:
679 switch (XGIhw_ext.ulCRT2LCDType) {
680 case LCD_640x480:
681 xres = 640;
682 yres = 480;
683 break;
684 case LCD_800x600:
685 xres = 800;
686 yres = 600;
687 break;
688 case LCD_1024x600:
689 xres = 1024;
690 yres = 600;
691 break;
692 case LCD_1024x768:
693 xres = 1024;
694 yres = 768;
695 break;
696 case LCD_1152x768:
697 xres = 1152;
698 yres = 768;
699 break;
700 case LCD_1280x960:
701 xres = 1280;
702 yres = 960;
703 break;
704 case LCD_1280x768:
705 xres = 1280;
706 yres = 768;
707 break;
708 case LCD_1280x1024:
709 xres = 1280;
710 yres = 1024;
711 break;
712 case LCD_1400x1050:
713 xres = 1400;
714 yres = 1050;
715 break;
716 case LCD_1600x1200:
717 xres = 1600;
718 yres = 1200;
719 break;
720 /* case LCD_320x480: */ /* TW: FSTN */
721 /*
722 xres = 320;
723 yres = 480;
724 break;
725 */
726 default:
727 xres = 0;
728 yres = 0;
729 break;
730 }
731 if (XGIbios_mode[myindex].xres > xres)
732 return -1;
733 if (XGIbios_mode[myindex].yres > yres)
734 return -1;
735 if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
736 (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
737 switch (XGIbios_mode[myindex].xres) {
738 case 512:
739 if (XGIbios_mode[myindex].yres != 512)
740 return -1;
741 if (XGIhw_ext.ulCRT2LCDType == LCD_1024x600)
742 return -1;
743 break;
744 case 640:
745 if ((XGIbios_mode[myindex].yres != 400)
746 && (XGIbios_mode[myindex].yres
747 != 480))
748 return -1;
749 break;
750 case 800:
751 if (XGIbios_mode[myindex].yres != 600)
752 return -1;
753 break;
754 case 1024:
755 if ((XGIbios_mode[myindex].yres != 600)
756 && (XGIbios_mode[myindex].yres
757 != 768))
758 return -1;
759 if ((XGIbios_mode[myindex].yres == 600)
760 && (XGIhw_ext.ulCRT2LCDType
761 != LCD_1024x600))
762 return -1;
763 break;
764 case 1152:
765 if ((XGIbios_mode[myindex].yres) != 768)
766 return -1;
767 if (XGIhw_ext.ulCRT2LCDType != LCD_1152x768)
768 return -1;
769 break;
770 case 1280:
771 if ((XGIbios_mode[myindex].yres != 768)
772 && (XGIbios_mode[myindex].yres
773 != 1024))
774 return -1;
775 if ((XGIbios_mode[myindex].yres == 768)
776 && (XGIhw_ext.ulCRT2LCDType
777 != LCD_1280x768))
778 return -1;
779 break;
780 case 1400:
781 if (XGIbios_mode[myindex].yres != 1050)
782 return -1;
783 break;
784 case 1600:
785 if (XGIbios_mode[myindex].yres != 1200)
786 return -1;
787 break;
788 default:
789 return -1;
790 }
791 } else {
792 switch (XGIbios_mode[myindex].xres) {
793 case 512:
794 if (XGIbios_mode[myindex].yres != 512)
795 return -1;
796 break;
797 case 640:
798 if ((XGIbios_mode[myindex].yres != 400)
799 && (XGIbios_mode[myindex].yres
800 != 480))
801 return -1;
802 break;
803 case 800:
804 if (XGIbios_mode[myindex].yres != 600)
805 return -1;
806 break;
807 case 1024:
808 if (XGIbios_mode[myindex].yres != 768)
809 return -1;
810 break;
811 case 1280:
812 if ((XGIbios_mode[myindex].yres != 960)
813 && (XGIbios_mode[myindex].yres
814 != 1024))
815 return -1;
816 if (XGIbios_mode[myindex].yres == 960) {
817 if (XGIhw_ext.ulCRT2LCDType
818 == LCD_1400x1050)
819 return -1;
820 }
821 break;
822 case 1400:
823 if (XGIbios_mode[myindex].yres != 1050)
824 return -1;
825 break;
826 case 1600:
827 if (XGIbios_mode[myindex].yres != 1200)
828 return -1;
829 break;
830 default:
831 return -1;
832 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200833 }
834 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530835 case DISPTYPE_TV:
836 switch (XGIbios_mode[myindex].xres) {
837 case 512:
838 case 640:
839 case 800:
840 break;
841 case 720:
842 if (xgi_video_info.TV_type == TVMODE_NTSC) {
843 if (XGIbios_mode[myindex].yres != 480)
844 return -1;
845 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
846 if (XGIbios_mode[myindex].yres != 576)
847 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200848 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530849 /* TW: LVDS/CHRONTEL does not support 720 */
850 if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
851 || xgi_video_info.hasVB == HASVB_CHRONTEL) {
852 return -1;
853 }
854 break;
855 case 1024:
856 if (xgi_video_info.TV_type == TVMODE_NTSC) {
857 if (XGIbios_mode[myindex].bpp == 32)
858 return -1;
859 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530860 break;
861 default:
862 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200863 }
864 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530865 case DISPTYPE_CRT2:
866 if (XGIbios_mode[myindex].xres > 1280)
867 return -1;
868 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200869 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530870 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200871
872}
873
874static void XGIfb_search_crt2type(const char *name)
875{
876 int i = 0;
877
Prashant P. Shahb654f872010-09-06 17:34:26 +0530878 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200879 return;
880
Prashant P. Shahb654f872010-09-06 17:34:26 +0530881 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200882 if (!strcmp(name, XGI_crt2type[i].name)) {
883 XGIfb_crt2type = XGI_crt2type[i].type_no;
884 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
885 break;
886 }
887 i++;
888 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530889 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200890 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
891}
892
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200893static u8 XGIfb_search_refresh_rate(unsigned int rate)
894{
895 u16 xres, yres;
896 int i = 0;
897
898 xres = XGIbios_mode[xgifb_mode_idx].xres;
899 yres = XGIbios_mode[xgifb_mode_idx].yres;
900
901 XGIfb_rate_idx = 0;
902 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530903 if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
904 == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200905 if (XGIfb_vrate[i].refresh == rate) {
906 XGIfb_rate_idx = XGIfb_vrate[i].idx;
907 break;
908 } else if (XGIfb_vrate[i].refresh > rate) {
909 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
910 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530911 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200912 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530913 xgi_video_info.refresh_rate
914 = XGIfb_vrate[i].refresh;
915 } else if (((rate - XGIfb_vrate[i - 1].refresh)
916 <= 2) && (XGIfb_vrate[i].idx
917 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200918 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +0530919 rate, XGIfb_vrate[i-1].refresh);
920 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
921 xgi_video_info.refresh_rate
922 = XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200923 }
924 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530925 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200926 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
927 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530928 XGIfb_rate_idx = XGIfb_vrate[i].idx;
929 break;
930 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200931 }
932 i++;
933 }
934 if (XGIfb_rate_idx > 0) {
935 return XGIfb_rate_idx;
936 } else {
937 printk(KERN_INFO
Prashant P. Shahb654f872010-09-06 17:34:26 +0530938 "XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200939 return 0;
940 }
941}
942
943static void XGIfb_search_tvstd(const char *name)
944{
945 int i = 0;
946
Prashant P. Shahb654f872010-09-06 17:34:26 +0530947 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200948 return;
949
950 while (XGI_tvtype[i].type_no != -1) {
951 if (!strcmp(name, XGI_tvtype[i].name)) {
952 XGIfb_tvmode = XGI_tvtype[i].type_no;
953 break;
954 }
955 i++;
956 }
957}
958
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200959/* ----------- FBDev related routines for all series ----------- */
960
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200961static void XGIfb_bpp_to_var(struct fb_var_screeninfo *var)
962{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530963 switch (var->bits_per_pixel) {
964 case 8:
965 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200966 var->red.length = var->green.length = var->blue.length = 6;
967 xgi_video_info.video_cmap_len = 256;
968 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530969 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200970 var->red.offset = 11;
971 var->red.length = 5;
972 var->green.offset = 5;
973 var->green.length = 6;
974 var->blue.offset = 0;
975 var->blue.length = 5;
976 var->transp.offset = 0;
977 var->transp.length = 0;
978 xgi_video_info.video_cmap_len = 16;
979 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530980 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200981 var->red.offset = 16;
982 var->red.length = 8;
983 var->green.offset = 8;
984 var->green.length = 8;
985 var->blue.offset = 0;
986 var->blue.length = 8;
987 var->transp.offset = 24;
988 var->transp.length = 8;
989 xgi_video_info.video_cmap_len = 16;
990 break;
991 }
992}
993
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200994static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +0530995 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200996{
997
Prashant P. Shahb654f872010-09-06 17:34:26 +0530998 unsigned int htotal = var->left_margin + var->xres + var->right_margin
999 + var->hsync_len;
1000 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1001 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001002#if defined(__powerpc__)
1003 u8 sr_data, cr_data;
1004#endif
1005 unsigned int drate = 0, hrate = 0;
1006 int found_mode = 0;
1007 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301008 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001009
1010 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301011 /* printk(KERN_DEBUG "XGIfb:var->yres=%d, var->upper_margin=%d, var->lower_margin=%d, var->vsync_len=%d\n", var->yres, var->upper_margin, var->lower_margin, var->vsync_len); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001012
Prashant P. Shahb654f872010-09-06 17:34:26 +05301013 info->var.xres_virtual = var->xres_virtual;
1014 info->var.yres_virtual = var->yres_virtual;
1015 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001016
1017 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1018 vtotal <<= 1;
1019 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1020 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301021 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1022 /* vtotal <<= 1; */
1023 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001024 }
1025
Prashant P. Shahb654f872010-09-06 17:34:26 +05301026 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001027 DPRINTK("XGIfb: Invalid 'var' information\n");
1028 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301029 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1030 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001031
Prashant P. Shahb654f872010-09-06 17:34:26 +05301032 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001033 drate = 1000000000 / var->pixclock;
1034 hrate = (drate * 1000) / htotal;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301035 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2
1036 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001037 } else {
1038 xgi_video_info.refresh_rate = 60;
1039 }
1040
1041 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05301042 var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001043
1044 old_mode = xgifb_mode_idx;
1045 xgifb_mode_idx = 0;
1046
Prashant P. Shahb654f872010-09-06 17:34:26 +05301047 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1048 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1049 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1050 && (XGIbios_mode[xgifb_mode_idx].yres
1051 == var->yres)
1052 && (XGIbios_mode[xgifb_mode_idx].bpp
1053 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001054 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1055 found_mode = 1;
1056 break;
1057 }
1058 xgifb_mode_idx++;
1059 }
1060
Prashant P. Shahb654f872010-09-06 17:34:26 +05301061 if (found_mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001062 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
1063 else
1064 xgifb_mode_idx = -1;
1065
Prashant P. Shahb654f872010-09-06 17:34:26 +05301066 if (xgifb_mode_idx < 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001067 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301068 var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001069 xgifb_mode_idx = old_mode;
1070 return -EINVAL;
1071 }
1072
Prashant P. Shahb654f872010-09-06 17:34:26 +05301073 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001074 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
1075 xgi_video_info.refresh_rate = 60;
1076 }
1077
Prashant P. Shahb654f872010-09-06 17:34:26 +05301078 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001079
1080 XGIfb_pre_setmode();
Prashant P. Shahb654f872010-09-06 17:34:26 +05301081 if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001082 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
1083 return -EINVAL;
1084 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301085 info->fix.line_length = ((info->var.xres_virtual
1086 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001087
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001088 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001089
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001090 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
1091 xgifb_reg_set(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001092
1093 XGIfb_post_setmode();
1094
Prashant P. Shahb654f872010-09-06 17:34:26 +05301095 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1096 XGIbios_mode[xgifb_mode_idx].xres,
1097 XGIbios_mode[xgifb_mode_idx].yres,
1098 XGIbios_mode[xgifb_mode_idx].bpp,
1099 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001100
1101 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1102 xgi_video_info.video_vwidth = info->var.xres_virtual;
1103 xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
1104 xgi_video_info.video_vheight = info->var.yres_virtual;
1105 xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
1106 xgi_video_info.org_x = xgi_video_info.org_y = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301107 xgi_video_info.video_linelength = info->var.xres_virtual
1108 * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301109 switch (xgi_video_info.video_bpp) {
1110 case 8:
1111 xgi_video_info.DstColor = 0x0000;
1112 xgi_video_info.XGI310_AccelDepth = 0x00000000;
1113 xgi_video_info.video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001114#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001115 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001116 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001117#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301118 break;
1119 case 16:
1120 xgi_video_info.DstColor = 0x8000;
1121 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001122#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001123 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001124 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001125#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301126 xgi_video_info.video_cmap_len = 16;
1127 break;
1128 case 32:
1129 xgi_video_info.DstColor = 0xC000;
1130 xgi_video_info.XGI310_AccelDepth = 0x00020000;
1131 xgi_video_info.video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001132#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001133 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001134 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001135#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301136 break;
1137 default:
1138 xgi_video_info.video_cmap_len = 16;
1139 printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301140 break;
1141 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001142 }
1143 XGIfb_bpp_to_var(var); /*update ARGB info*/
1144 DEBUGPRN("End of do_set_var");
1145
1146 dumpVGAReg();
1147 return 0;
1148}
1149
1150#ifdef XGIFB_PAN
1151static int XGIfb_pan_var(struct fb_var_screeninfo *var)
1152{
1153 unsigned int base;
1154
Prashant P. Shahb654f872010-09-06 17:34:26 +05301155 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001156
1157 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301158 /* printk("Pan: xo: %d xv %d xr %d\n",
1159 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001160 return -EINVAL;
1161 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301162 if (var->yoffset > (var->yres_virtual - var->yres)) {
1163 /* printk("Pan: yo: %d yv %d yr %d\n",
1164 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001165 return -EINVAL;
1166 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301167 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001168
Prashant P. Shahb654f872010-09-06 17:34:26 +05301169 /* calculate base bpp dep. */
1170 switch (var->bits_per_pixel) {
1171 case 16:
1172 base >>= 1;
1173 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001174 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301175 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001176 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301177 default:
1178 base >>= 2;
1179 break;
1180 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001181
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001182 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001183
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001184 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1185 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1186 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1187 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001188 setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
1189
Prashant P. Shahb654f872010-09-06 17:34:26 +05301190 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001191 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001192 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1193 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1194 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001195 setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301196 }
1197 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001198 return 0;
1199}
1200#endif
1201
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001202static int XGIfb_open(struct fb_info *info, int user)
1203{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301204 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001205}
1206
1207static int XGIfb_release(struct fb_info *info, int user)
1208{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301209 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001210}
1211
1212static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1213{
1214 int rc = 16;
1215
Prashant P. Shahb654f872010-09-06 17:34:26 +05301216 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001217 case 8:
1218 rc = 256;
1219 break;
1220 case 16:
1221 rc = 16;
1222 break;
1223 case 32:
1224 rc = 16;
1225 break;
1226 }
1227 return rc;
1228}
1229
Prashant P. Shahb654f872010-09-06 17:34:26 +05301230static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1231 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001232{
1233 if (regno >= XGIfb_get_cmap_len(&info->var))
1234 return 1;
1235
1236 switch (info->var.bits_per_pixel) {
1237 case 8:
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001238 outb(regno, XGIDACA);
1239 outb((red >> 10), XGIDACD);
1240 outb((green >> 10), XGIDACD);
1241 outb((blue >> 10), XGIDACD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001242 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001243 outb(regno, XGIDAC2A);
1244 outb((red >> 8), XGIDAC2D);
1245 outb((green >> 8), XGIDAC2D);
1246 outb((blue >> 8), XGIDAC2D);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001247 }
1248 break;
1249 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301250 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1251 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1252 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001253 break;
1254 case 32:
1255 red >>= 8;
1256 green >>= 8;
1257 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301258 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1259 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001260 break;
1261 }
1262 return 0;
1263}
1264
1265static int XGIfb_set_par(struct fb_info *info)
1266{
1267 int err;
1268
Prashant P. Shahb654f872010-09-06 17:34:26 +05301269 /* printk("XGIfb: inside set_par\n"); */
1270 err = XGIfb_do_set_var(&info->var, 1, info);
1271 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001272 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001273 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301274 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001275 return 0;
1276}
1277
Prashant P. Shahb654f872010-09-06 17:34:26 +05301278static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001279{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301280 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1281 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001282 unsigned int vtotal = 0;
1283 unsigned int drate = 0, hrate = 0;
1284 int found_mode = 0;
1285 int refresh_rate, search_idx;
1286
1287 DEBUGPRN("Inside check_var");
1288
Prashant P. Shahb654f872010-09-06 17:34:26 +05301289 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1290 vtotal = var->upper_margin + var->yres + var->lower_margin
1291 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001292 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301293 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1294 vtotal = var->upper_margin + var->yres + var->lower_margin
1295 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001296 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301297 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1298 vtotal = var->upper_margin + (var->yres / 2)
1299 + var->lower_margin + var->vsync_len;
1300 } else
1301 vtotal = var->upper_margin + var->yres + var->lower_margin
1302 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001303
Prashant P. Shahb654f872010-09-06 17:34:26 +05301304 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001305 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301306
1307 if (var->pixclock && htotal && vtotal) {
1308 drate = 1000000000 / var->pixclock;
1309 hrate = (drate * 1000) / htotal;
1310 xgi_video_info.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
1311 printk(KERN_DEBUG
1312 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1313 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1314 __func__, var->pixclock, htotal, vtotal,
1315 __func__, drate, hrate, xgi_video_info.refresh_rate);
1316 } else {
1317 xgi_video_info.refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001318 }
1319
Prashant P. Shahb654f872010-09-06 17:34:26 +05301320 /*
1321 if ((var->pixclock) && (htotal)) {
1322 drate = 1E12 / var->pixclock;
1323 hrate = drate / htotal;
1324 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1325 } else {
1326 refresh_rate = 60;
1327 }
1328 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001329 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301330 if ((var->xres == 1024) && (var->yres == 600))
1331 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001332
1333 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301334 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1335 (XGIbios_mode[search_idx].xres <= var->xres)) {
1336 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1337 (XGIbios_mode[search_idx].yres == var->yres) &&
1338 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
1339 if (XGIfb_validate_mode(search_idx) > 0) {
1340 found_mode = 1;
1341 break;
1342 }
1343 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001344 search_idx++;
1345 }
1346
Prashant P. Shahb654f872010-09-06 17:34:26 +05301347 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001348
1349 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1350 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301351 search_idx = 0;
1352 while (XGIbios_mode[search_idx].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001353
Prashant P. Shahb654f872010-09-06 17:34:26 +05301354 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
1355 (var->yres <= XGIbios_mode[search_idx].yres) &&
1356 (var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
1357 if (XGIfb_validate_mode(search_idx) > 0) {
1358 found_mode = 1;
1359 break;
1360 }
1361 }
1362 search_idx++;
1363 }
1364 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001365 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301366 var->yres = XGIbios_mode[search_idx].yres;
1367 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1368 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001369
1370 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301371 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001372 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301373 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001374 }
1375 }
1376
1377 /* TW: TODO: Check the refresh rate */
1378
1379 /* Adapt RGB settings */
1380 XGIfb_bpp_to_var(var);
1381
1382 /* Sanity check for offsets */
1383 if (var->xoffset < 0)
1384 var->xoffset = 0;
1385 if (var->yoffset < 0)
1386 var->yoffset = 0;
1387
Prashant P. Shahb654f872010-09-06 17:34:26 +05301388 if (!XGIfb_ypan) {
1389 if (var->xres != var->xres_virtual)
1390 var->xres_virtual = var->xres;
1391 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001392 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301393 } /* else { */
1394 /* TW: Now patch yres_virtual if we use panning */
1395 /* May I do this? */
1396 /* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
1397 /* if (var->yres_virtual <= var->yres) { */
1398 /* TW: Paranoia check */
1399 /* var->yres_virtual = var->yres; */
1400 /* } */
1401 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001402
1403 /* Truncate offsets to maximum if too high */
1404 if (var->xoffset > var->xres_virtual - var->xres)
1405 var->xoffset = var->xres_virtual - var->xres - 1;
1406
1407 if (var->yoffset > var->yres_virtual - var->yres)
1408 var->yoffset = var->yres_virtual - var->yres - 1;
1409
1410 /* Set everything else to 0 */
1411 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301412 var->green.msb_right =
1413 var->blue.msb_right =
1414 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001415
1416 DEBUGPRN("end of check_var");
1417 return 0;
1418}
1419
1420#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301421static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1422 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001423{
1424 int err;
1425
Prashant P. Shahb654f872010-09-06 17:34:26 +05301426 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001427
1428 if (var->xoffset > (var->xres_virtual - var->xres))
1429 return -EINVAL;
1430 if (var->yoffset > (var->yres_virtual - var->yres))
1431 return -EINVAL;
1432
1433 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301434 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1435 || var->xoffset)
1436 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001437 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301438 if (var->xoffset + info->var.xres > info->var.xres_virtual
1439 || var->yoffset + info->var.yres
1440 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001441 return -EINVAL;
1442 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301443 err = XGIfb_pan_var(var);
1444 if (err < 0)
1445 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001446
1447 info->var.xoffset = var->xoffset;
1448 info->var.yoffset = var->yoffset;
1449 if (var->vmode & FB_VMODE_YWRAP)
1450 info->var.vmode |= FB_VMODE_YWRAP;
1451 else
1452 info->var.vmode &= ~FB_VMODE_YWRAP;
1453
Prashant P. Shahb654f872010-09-06 17:34:26 +05301454 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001455 return 0;
1456}
1457#endif
1458
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001459static int XGIfb_blank(int blank, struct fb_info *info)
1460{
1461 u8 reg;
1462
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001463 reg = xgifb_reg_get(XGICR, 0x17);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001464
Prashant P. Shahb654f872010-09-06 17:34:26 +05301465 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001466 reg &= 0x7f;
1467 else
1468 reg |= 0x80;
1469
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001470 xgifb_reg_set(XGICR, 0x17, reg);
1471 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1472 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301473 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001474}
1475
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001476/* ----------- FBDev related routines for all series ---------- */
1477
1478static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301479 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001480{
1481 DEBUGPRN("inside get_fix");
1482 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1483
1484 strcpy(fix->id, myid);
1485
1486 fix->smem_start = xgi_video_info.video_base;
1487
1488 fix->smem_len = xgi_video_info.video_size;
1489
Prashant P. Shahb654f872010-09-06 17:34:26 +05301490 fix->type = video_type;
1491 fix->type_aux = 0;
1492 if (xgi_video_info.video_bpp == 8)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001493 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1494 else
1495 fix->visual = FB_VISUAL_DIRECTCOLOR;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301496 fix->xpanstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001497#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301498 if (XGIfb_ypan)
1499 fix->ypanstep = 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001500#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301501 fix->ywrapstep = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001502 fix->line_length = xgi_video_info.video_linelength;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301503 fix->mmio_start = xgi_video_info.mmio_base;
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02001504 fix->mmio_len = xgi_video_info.mmio_size;
Aaro Koskinen06587332011-03-13 12:26:10 +02001505 fix->accel = FB_ACCEL_XGI_XABRE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001506
1507 DEBUGPRN("end of get_fix");
1508 return 0;
1509}
1510
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001511static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301512 .owner = THIS_MODULE,
1513 .fb_open = XGIfb_open,
1514 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001515 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301516 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001517 .fb_setcolreg = XGIfb_setcolreg,
1518#ifdef XGIFB_PAN
Prashant P. Shahb654f872010-09-06 17:34:26 +05301519 .fb_pan_display = XGIfb_pan_display,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001520#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301521 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001522 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001523 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001524 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301525 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001526};
1527
1528/* ---------------- Chip generation dependent routines ---------------- */
1529
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001530/* for XGI 315/550/650/740/330 */
1531
1532static int XGIfb_get_dram_size(void)
1533{
1534
Prashant P. Shahb654f872010-09-06 17:34:26 +05301535 u8 ChannelNum, tmp;
1536 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001537
1538 /* xorg driver sets 32MB * 1 channel */
1539 if (xgi_video_info.chip == XG27)
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001540 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001541
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001542 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301543 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1544 case XGI_DRAM_SIZE_1MB:
1545 xgi_video_info.video_size = 0x100000;
1546 break;
1547 case XGI_DRAM_SIZE_2MB:
1548 xgi_video_info.video_size = 0x200000;
1549 break;
1550 case XGI_DRAM_SIZE_4MB:
1551 xgi_video_info.video_size = 0x400000;
1552 break;
1553 case XGI_DRAM_SIZE_8MB:
1554 xgi_video_info.video_size = 0x800000;
1555 break;
1556 case XGI_DRAM_SIZE_16MB:
1557 xgi_video_info.video_size = 0x1000000;
1558 break;
1559 case XGI_DRAM_SIZE_32MB:
1560 xgi_video_info.video_size = 0x2000000;
1561 break;
1562 case XGI_DRAM_SIZE_64MB:
1563 xgi_video_info.video_size = 0x4000000;
1564 break;
1565 case XGI_DRAM_SIZE_128MB:
1566 xgi_video_info.video_size = 0x8000000;
1567 break;
1568 case XGI_DRAM_SIZE_256MB:
1569 xgi_video_info.video_size = 0x10000000;
1570 break;
1571 default:
1572 return -1;
1573 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001574
Prashant P. Shahb654f872010-09-06 17:34:26 +05301575 tmp = (reg & 0x0c) >> 2;
1576 switch (xgi_video_info.chip) {
1577 case XG20:
1578 case XG21:
1579 case XG27:
1580 ChannelNum = 1;
1581 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001582
Prashant P. Shahb654f872010-09-06 17:34:26 +05301583 case XG42:
1584 if (reg & 0x04)
1585 ChannelNum = 2;
1586 else
1587 ChannelNum = 1;
1588 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001589
Prashant P. Shahb654f872010-09-06 17:34:26 +05301590 case XG45:
1591 if (tmp == 1)
1592 ChannelNum = 2;
1593 else if (tmp == 2)
1594 ChannelNum = 3;
1595 else if (tmp == 3)
1596 ChannelNum = 4;
1597 else
1598 ChannelNum = 1;
1599 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001600
Prashant P. Shahb654f872010-09-06 17:34:26 +05301601 case XG40:
1602 default:
1603 if (tmp == 2)
1604 ChannelNum = 2;
1605 else if (tmp == 3)
1606 ChannelNum = 3;
1607 else
1608 ChannelNum = 1;
1609 break;
1610 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001611
Prashant P. Shahb654f872010-09-06 17:34:26 +05301612 xgi_video_info.video_size = xgi_video_info.video_size * ChannelNum;
1613 /* PLiad fixed for benchmarking and fb set */
1614 /* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
1615 /* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001616
Prashant P. Shahb654f872010-09-06 17:34:26 +05301617 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
1618 xgi_video_info.video_size, ChannelNum);
1619 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001620
1621}
1622
1623static void XGIfb_detect_VB(void)
1624{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301625 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001626
1627 xgi_video_info.TV_plug = xgi_video_info.TV_type = 0;
1628
Prashant P. Shahb654f872010-09-06 17:34:26 +05301629 switch (xgi_video_info.hasVB) {
1630 case HASVB_LVDS_CHRONTEL:
1631 case HASVB_CHRONTEL:
1632 break;
1633 case HASVB_301:
1634 case HASVB_302:
1635 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1636 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001637 }
1638
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001639 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001640
1641 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1642 XGIfb_crt1off = 0;
1643 else {
1644 if (cr32 & 0x5F)
1645 XGIfb_crt1off = 1;
1646 else
1647 XGIfb_crt1off = 0;
1648 }
1649
1650 if (XGIfb_crt2type != -1)
1651 /* TW: Override with option */
1652 xgi_video_info.disp_state = XGIfb_crt2type;
1653 else if (cr32 & XGI_VB_TV)
1654 xgi_video_info.disp_state = DISPTYPE_TV;
1655 else if (cr32 & XGI_VB_LCD)
1656 xgi_video_info.disp_state = DISPTYPE_LCD;
1657 else if (cr32 & XGI_VB_CRT2)
1658 xgi_video_info.disp_state = DISPTYPE_CRT2;
1659 else
1660 xgi_video_info.disp_state = 0;
1661
Prashant P. Shahb654f872010-09-06 17:34:26 +05301662 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001663 /* PR/TW: Override with option */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301664 xgi_video_info.TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001665 else if (cr32 & XGI_VB_HIVISION) {
1666 xgi_video_info.TV_type = TVMODE_HIVISION;
1667 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301668 } else if (cr32 & XGI_VB_SVIDEO)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001669 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1670 else if (cr32 & XGI_VB_COMPOSITE)
1671 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1672 else if (cr32 & XGI_VB_SCART)
1673 xgi_video_info.TV_plug = TVPLUG_SCART;
1674
Prashant P. Shahb654f872010-09-06 17:34:26 +05301675 if (xgi_video_info.TV_type == 0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001676 temp = xgifb_reg_get(XGICR, 0x38);
Aaro Koskinenebe78462011-03-13 12:26:08 +02001677 if (temp & 0x10)
1678 xgi_video_info.TV_type = TVMODE_PAL;
1679 else
1680 xgi_video_info.TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001681 }
1682
1683 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301684 if (XGIfb_forcecrt1 != -1) {
1685 if (XGIfb_forcecrt1)
1686 XGIfb_crt1off = 0;
1687 else
1688 XGIfb_crt1off = 1;
1689 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001690}
1691
1692static void XGIfb_get_VB_type(void)
1693{
1694 u8 reg;
1695
1696 if (!XGIfb_has_VB()) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001697 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001698 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301699 case XGI310_EXTERNAL_CHIP_LVDS:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001700 xgi_video_info.hasVB = HASVB_LVDS;
1701 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301702 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001703 xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
1704 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301705 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001706 break;
1707 }
1708 }
1709}
1710
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001711static int XGIfb_has_VB(void)
1712{
1713 u8 vb_chipid;
1714
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001715 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001716 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301717 case 0x01:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001718 xgi_video_info.hasVB = HASVB_301;
1719 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301720 case 0x02:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001721 xgi_video_info.hasVB = HASVB_302;
1722 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301723 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001724 xgi_video_info.hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001725 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001726 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001727 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001728}
1729
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001730/* ------------------ Sensing routines ------------------ */
1731
1732/* TW: Determine and detect attached devices on XGI30x */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301733int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001734{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301735 int temp, i;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001736
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001737 xgifb_reg_set(XGIPART4, 0x11, tempbl);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301738 temp = tempbh | tempcl;
1739 setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
1740 for (i = 0; i < 10; i++)
1741 XGI_LongWait(&XGI_Pr);
1742 tempch &= 0x7f;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001743 temp = xgifb_reg_get(XGIPART4, 0x03);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301744 temp ^= 0x0e;
1745 temp &= tempch;
1746 return temp;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001747}
1748
Prashant P. Shahb654f872010-09-06 17:34:26 +05301749void XGI_Sense30x(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001750{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301751 u8 backupP4_0d;
1752 u8 testsvhs_tempbl, testsvhs_tempbh;
1753 u8 testsvhs_tempcl, testsvhs_tempch;
1754 u8 testcvbs_tempbl, testcvbs_tempbh;
1755 u8 testcvbs_tempcl, testcvbs_tempch;
1756 u8 testvga2_tempbl, testvga2_tempbh;
1757 u8 testvga2_tempcl, testvga2_tempch;
1758 int myflag, result;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001759
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001760 backupP4_0d = xgifb_reg_get(XGIPART4, 0x0d);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001761 xgifb_reg_set(XGIPART4, 0x0d, (backupP4_0d | 0x04));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001762
Prashant P. Shahb654f872010-09-06 17:34:26 +05301763 testvga2_tempbh = 0x00;
1764 testvga2_tempbl = 0xd1;
1765 testsvhs_tempbh = 0x00;
1766 testsvhs_tempbl = 0xb9;
1767 testcvbs_tempbh = 0x00;
1768 testcvbs_tempbl = 0xb3;
1769 if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
1770 != VB_CHIP_302)) {
1771 testvga2_tempbh = 0x01;
1772 testvga2_tempbl = 0x90;
1773 testsvhs_tempbh = 0x01;
1774 testsvhs_tempbl = 0x6b;
1775 testcvbs_tempbh = 0x01;
1776 testcvbs_tempbl = 0x74;
1777 if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
1778 || XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
1779 testvga2_tempbh = 0x00;
1780 testvga2_tempbl = 0x00;
1781 testsvhs_tempbh = 0x02;
1782 testsvhs_tempbl = 0x00;
1783 testcvbs_tempbh = 0x01;
1784 testcvbs_tempbl = 0x00;
1785 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001786 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301787 if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
1788 != VB_CHIP_302LV) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001789 myflag = xgifb_reg_get(XGIPART4, 0x01);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301790 if (myflag & 0x04) {
1791 testvga2_tempbh = 0x00;
1792 testvga2_tempbl = 0xfd;
1793 testsvhs_tempbh = 0x00;
1794 testsvhs_tempbl = 0xdd;
1795 testcvbs_tempbh = 0x00;
1796 testcvbs_tempbl = 0xee;
1797 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001798 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301799 if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
1800 == VB_CHIP_302LV)) {
1801 testvga2_tempbh = 0x00;
1802 testvga2_tempbl = 0x00;
1803 testvga2_tempch = 0x00;
1804 testvga2_tempcl = 0x00;
1805 testsvhs_tempch = 0x04;
1806 testsvhs_tempcl = 0x08;
1807 testcvbs_tempch = 0x08;
1808 testcvbs_tempcl = 0x08;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001809 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301810 testvga2_tempch = 0x0e;
1811 testvga2_tempcl = 0x08;
1812 testsvhs_tempch = 0x06;
1813 testsvhs_tempcl = 0x04;
1814 testcvbs_tempch = 0x08;
1815 testcvbs_tempcl = 0x04;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001816 }
1817
Prashant P. Shahb654f872010-09-06 17:34:26 +05301818 if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
1819 || testvga2_tempbl) {
1820 result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
1821 testvga2_tempcl, testvga2_tempch);
1822 if (result) {
1823 printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
1824 orXGIIDXREG(XGICR, 0x32, 0x10);
1825 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001826 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001827
Prashant P. Shahb654f872010-09-06 17:34:26 +05301828 result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
1829 testsvhs_tempch);
1830 if (result) {
1831 printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
1832 /* TW: So we can be sure that there IS a SVHS output */
1833 xgi_video_info.TV_plug = TVPLUG_SVIDEO;
1834 orXGIIDXREG(XGICR, 0x32, 0x02);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001835 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001836
Prashant P. Shahb654f872010-09-06 17:34:26 +05301837 if (!result) {
1838 result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
1839 testcvbs_tempcl, testcvbs_tempch);
1840 if (result) {
1841 printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
1842 /* TW: So we can be sure that there IS a CVBS output */
1843 xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
1844 orXGIIDXREG(XGICR, 0x32, 0x01);
1845 }
1846 }
1847 XGIDoSense(0, 0, 0, 0);
1848
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001849 xgifb_reg_set(XGIPART4, 0x0d, backupP4_0d);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001850}
1851
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001852/* --------------------- SetMode routines ------------------------- */
1853
1854static void XGIfb_pre_setmode(void)
1855{
1856 u8 cr30 = 0, cr31 = 0;
1857
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001858 cr31 = xgifb_reg_get(XGICR, 0x31);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001859 cr31 &= ~0x60;
1860
1861 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301862 case DISPTYPE_CRT2:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001863 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
1864 cr31 |= XGI_DRIVER_MODE;
1865 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301866 case DISPTYPE_LCD:
1867 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001868 cr31 |= XGI_DRIVER_MODE;
1869 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301870 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001871 if (xgi_video_info.TV_type == TVMODE_HIVISION)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301872 cr30 = (XGI_VB_OUTPUT_HIVISION
1873 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001874 else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301875 cr30 = (XGI_VB_OUTPUT_SVIDEO
1876 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001877 else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301878 cr30 = (XGI_VB_OUTPUT_COMPOSITE
1879 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001880 else if (xgi_video_info.TV_plug == TVPLUG_SCART)
Prashant P. Shahb654f872010-09-06 17:34:26 +05301881 cr30 = (XGI_VB_OUTPUT_SCART
1882 | XGI_SIMULTANEOUS_VIEW_ENABLE);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001883 cr31 |= XGI_DRIVER_MODE;
1884
Prashant P. Shahb654f872010-09-06 17:34:26 +05301885 if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001886 cr31 |= 0x01;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301887 else
1888 cr31 &= ~0x01;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001889 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301890 default: /* disable CRT2 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001891 cr30 = 0x00;
1892 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
1893 }
1894
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001895 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
1896 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
1897 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001898}
1899
1900static void XGIfb_post_setmode(void)
1901{
1902 u8 reg;
Bill Pemberton82d6eb52010-06-17 13:10:46 -04001903 unsigned char doit = 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301904 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001905 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
1906 xgifb_reg_set(XGICR, 0x13, 0x00);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301907 setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
1908 *test*
1909 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001910 if (xgi_video_info.video_bpp == 8) {
1911 /* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301912 if ((xgi_video_info.hasVB == HASVB_LVDS)
1913 || (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
Bill Pembertondda08c52010-06-17 13:10:42 -04001914 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001915 }
1916 /* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301917 if (xgi_video_info.disp_state & DISPTYPE_LCD)
Bill Pembertondda08c52010-06-17 13:10:42 -04001918 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001919 }
1920
1921 /* TW: We can't switch off CRT1 if bridge is in slave mode */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301922 if (xgi_video_info.hasVB != HASVB_NONE) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001923 reg = xgifb_reg_get(XGIPART1, 0x00);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001924
Bill Pembertondda08c52010-06-17 13:10:42 -04001925 if ((reg & 0x50) == 0x10)
1926 doit = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001927
Prashant P. Shahb654f872010-09-06 17:34:26 +05301928 } else {
Bill Pembertondda08c52010-06-17 13:10:42 -04001929 XGIfb_crt1off = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301930 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001931
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001932 reg = xgifb_reg_get(XGICR, 0x17);
Bill Pembertondda08c52010-06-17 13:10:42 -04001933 if ((XGIfb_crt1off) && (doit))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001934 reg &= ~0x80;
1935 else
1936 reg |= 0x80;
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001937 xgifb_reg_set(XGICR, 0x17, reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001938
Prashant P. Shahb654f872010-09-06 17:34:26 +05301939 andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001940
Prashant P. Shahb654f872010-09-06 17:34:26 +05301941 if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
1942 == HASVB_301)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001943
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001944 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001945
Prashant P. Shahb654f872010-09-06 17:34:26 +05301946 if (reg < 0xB0) { /* Set filter for XGI301 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001947
Prashant P. Shahb654f872010-09-06 17:34:26 +05301948 switch (xgi_video_info.video_width) {
1949 case 320:
1950 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
1951 break;
1952 case 640:
1953 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
1954 break;
1955 case 720:
1956 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
1957 break;
1958 case 800:
1959 filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
1960 break;
1961 default:
1962 filter = -1;
1963 break;
1964 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001965
Prashant P. Shahb654f872010-09-06 17:34:26 +05301966 orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001967
Prashant P. Shahb654f872010-09-06 17:34:26 +05301968 if (xgi_video_info.TV_type == TVMODE_NTSC) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001969
Prashant P. Shahb654f872010-09-06 17:34:26 +05301970 andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001971
Prashant P. Shahb654f872010-09-06 17:34:26 +05301972 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001973
Prashant P. Shahb654f872010-09-06 17:34:26 +05301974 andXGIIDXREG(XGIPART2, 0x30, 0xdf);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001975
Prashant P. Shahb654f872010-09-06 17:34:26 +05301976 } else if (xgi_video_info.TV_plug
1977 == TVPLUG_COMPOSITE) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001978
Prashant P. Shahb654f872010-09-06 17:34:26 +05301979 orXGIIDXREG(XGIPART2, 0x30, 0x20);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001980
Prashant P. Shahb654f872010-09-06 17:34:26 +05301981 switch (xgi_video_info.video_width) {
1982 case 640:
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001983 xgifb_reg_set(XGIPART2, 0x35, 0xEB);
1984 xgifb_reg_set(XGIPART2, 0x36, 0x04);
1985 xgifb_reg_set(XGIPART2, 0x37, 0x25);
1986 xgifb_reg_set(XGIPART2, 0x38, 0x18);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301987 break;
1988 case 720:
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001989 xgifb_reg_set(XGIPART2, 0x35, 0xEE);
1990 xgifb_reg_set(XGIPART2, 0x36, 0x0C);
1991 xgifb_reg_set(XGIPART2, 0x37, 0x22);
1992 xgifb_reg_set(XGIPART2, 0x38, 0x08);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301993 break;
1994 case 800:
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001995 xgifb_reg_set(XGIPART2, 0x35, 0xEB);
1996 xgifb_reg_set(XGIPART2, 0x36, 0x15);
1997 xgifb_reg_set(XGIPART2, 0x37, 0x25);
1998 xgifb_reg_set(XGIPART2, 0x38, 0xF6);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301999 break;
2000 }
2001 }
2002
2003 } else if (xgi_video_info.TV_type == TVMODE_PAL) {
2004
2005 andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
2006
2007 if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
2008
2009 andXGIIDXREG(XGIPART2, 0x30, 0xDF);
2010
2011 } else if (xgi_video_info.TV_plug
2012 == TVPLUG_COMPOSITE) {
2013
2014 orXGIIDXREG(XGIPART2, 0x30, 0x20);
2015
2016 switch (xgi_video_info.video_width) {
2017 case 640:
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002018 xgifb_reg_set(XGIPART2, 0x35, 0xF1);
2019 xgifb_reg_set(XGIPART2, 0x36, 0xF7);
2020 xgifb_reg_set(XGIPART2, 0x37, 0x1F);
2021 xgifb_reg_set(XGIPART2, 0x38, 0x32);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302022 break;
2023 case 720:
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002024 xgifb_reg_set(XGIPART2, 0x35, 0xF3);
2025 xgifb_reg_set(XGIPART2, 0x36, 0x00);
2026 xgifb_reg_set(XGIPART2, 0x37, 0x1D);
2027 xgifb_reg_set(XGIPART2, 0x38, 0x20);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302028 break;
2029 case 800:
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002030 xgifb_reg_set(XGIPART2, 0x35, 0xFC);
2031 xgifb_reg_set(XGIPART2, 0x36, 0xFB);
2032 xgifb_reg_set(XGIPART2, 0x37, 0x14);
2033 xgifb_reg_set(XGIPART2, 0x38, 0x2A);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302034 break;
2035 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002036 }
2037 }
2038
Prashant P. Shahb654f872010-09-06 17:34:26 +05302039 if ((filter >= 0) && (filter <= 7)) {
2040 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
2041 XGI_TV_filter[filter_tb].filter[filter][0],
2042 XGI_TV_filter[filter_tb].filter[filter][1],
2043 XGI_TV_filter[filter_tb].filter[filter][2],
2044 XGI_TV_filter[filter_tb].filter[filter][3]
2045 );
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002046 xgifb_reg_set(
Prashant P. Shahb654f872010-09-06 17:34:26 +05302047 XGIPART2,
2048 0x35,
2049 (XGI_TV_filter[filter_tb].filter[filter][0]));
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002050 xgifb_reg_set(
Prashant P. Shahb654f872010-09-06 17:34:26 +05302051 XGIPART2,
2052 0x36,
2053 (XGI_TV_filter[filter_tb].filter[filter][1]));
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002054 xgifb_reg_set(
Prashant P. Shahb654f872010-09-06 17:34:26 +05302055 XGIPART2,
2056 0x37,
2057 (XGI_TV_filter[filter_tb].filter[filter][2]));
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002058 xgifb_reg_set(
Prashant P. Shahb654f872010-09-06 17:34:26 +05302059 XGIPART2,
2060 0x38,
2061 (XGI_TV_filter[filter_tb].filter[filter][3]));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002062 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002063
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002064 }
2065
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002066 }
2067
2068}
2069
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002070XGIINITSTATIC int __init XGIfb_setup(char *options)
2071{
2072 char *this_opt;
2073
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002074 xgi_video_info.refresh_rate = 0;
2075
Prashant P. Shahb654f872010-09-06 17:34:26 +05302076 printk(KERN_INFO "XGIfb: Options %s\n", options);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002077
2078 if (!options || !*options)
2079 return 0;
2080
Prashant P. Shahb654f872010-09-06 17:34:26 +05302081 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002082
Prashant P. Shahb654f872010-09-06 17:34:26 +05302083 if (!*this_opt)
2084 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002085
2086 if (!strncmp(this_opt, "mode:", 5)) {
2087 XGIfb_search_mode(this_opt + 5);
2088 } else if (!strncmp(this_opt, "vesa:", 5)) {
2089 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2090 } else if (!strncmp(this_opt, "mode:", 5)) {
2091 XGIfb_search_mode(this_opt + 5);
2092 } else if (!strncmp(this_opt, "vesa:", 5)) {
2093 XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
2094 } else if (!strncmp(this_opt, "vrate:", 6)) {
2095 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
2096 } else if (!strncmp(this_opt, "rate:", 5)) {
2097 xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
2098 } else if (!strncmp(this_opt, "off", 3)) {
2099 XGIfb_off = 1;
2100 } else if (!strncmp(this_opt, "crt1off", 7)) {
2101 XGIfb_crt1off = 1;
2102 } else if (!strncmp(this_opt, "filter:", 7)) {
2103 filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
2104 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
2105 XGIfb_search_crt2type(this_opt + 14);
2106 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
2107 XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302108 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002109 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302110 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
2111 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302112 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002113 enable_dstn = 1;
2114 /* TW: DSTN overrules forcecrt2type */
2115 XGIfb_crt2type = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002116 } else if (!strncmp(this_opt, "pdc:", 4)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302117 XGIfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
2118 if (XGIfb_pdc & ~0x3c) {
2119 printk(KERN_INFO "XGIfb: Illegal pdc parameter\n");
2120 XGIfb_pdc = 0;
2121 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002122 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302123 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002124 } else if (!strncmp(this_opt, "userom:", 7)) {
2125 XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302126 /* } else if (!strncmp(this_opt, "useoem:", 7)) { */
2127 /* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002128 } else {
2129 XGIfb_search_mode(this_opt);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302130 /* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002131 }
2132
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002133 /* TW: Panning only with acceleration */
Javier Martinez Canillas0089bf12011-02-21 18:16:43 +01002134 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002135
2136 }
2137 printk("\nxgifb: outa xgifb_setup 3450");
2138 return 0;
2139}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002140
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002141static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002142{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002143 void __iomem *rom_address;
2144 unsigned char *rom_copy;
2145 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002146
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002147 rom_address = pci_map_rom(dev, &rom_size);
2148 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002149 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002150
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002151 rom_copy = vzalloc(XGIFB_ROM_SIZE);
2152 if (rom_copy == NULL)
2153 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002154
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002155 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
2156 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002157
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002158done:
2159 pci_unmap_rom(dev, rom_address);
2160 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002161}
2162
Randy Dunlap89229672010-08-10 08:46:44 -07002163static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302164 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002165{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302166 u8 reg, reg1;
2167 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002168 int ret;
2169
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002170 if (XGIfb_off)
2171 return -ENXIO;
2172
2173 XGIfb_registered = 0;
2174
Bill Pembertone4147ab2010-06-17 13:10:50 -04002175 memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05302176 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
2177 if (!fb_info)
2178 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002179
Prashant P. Shahb654f872010-09-06 17:34:26 +05302180 xgi_video_info.chip_id = pdev->device;
2181 pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302182 XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002183
Prashant P. Shahb654f872010-09-06 17:34:26 +05302184 xgi_video_info.pcibus = pdev->bus->number;
2185 xgi_video_info.pcislot = PCI_SLOT(pdev->devfn);
2186 xgi_video_info.pcifunc = PCI_FUNC(pdev->devfn);
2187 xgi_video_info.subsysvendor = pdev->subsystem_vendor;
2188 xgi_video_info.subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002189
Prashant P. Shahb654f872010-09-06 17:34:26 +05302190 xgi_video_info.video_base = pci_resource_start(pdev, 0);
2191 xgi_video_info.mmio_base = pci_resource_start(pdev, 1);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002192 xgi_video_info.mmio_size = pci_resource_len(pdev, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302193 xgi_video_info.vga_base = pci_resource_start(pdev, 2) + 0x30;
2194 XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
2195 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
2196 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
2197 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002198
Aaro Koskinenbb292232011-02-17 23:29:11 +02002199 if (pci_enable_device(pdev)) {
2200 ret = -EIO;
2201 goto error;
2202 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002203
Prashant P. Shahb654f872010-09-06 17:34:26 +05302204 XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002205
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002206 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002207 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002208
Prashant P. Shahb654f872010-09-06 17:34:26 +05302209 if (reg1 != 0xa1) { /*I/O error */
2210 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002211 ret = -EIO;
2212 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302213 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002214
2215 switch (xgi_video_info.chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302216 case PCI_DEVICE_ID_XG_20:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002217 orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002218 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002219 if (CR48&GPIOG_READ)
2220 xgi_video_info.chip = XG21;
2221 else
Prashant P. Shahb654f872010-09-06 17:34:26 +05302222 xgi_video_info.chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002223 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2224 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302225 case PCI_DEVICE_ID_XG_40:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002226 xgi_video_info.chip = XG40;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002227 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2228 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302229 case PCI_DEVICE_ID_XG_41:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002230 xgi_video_info.chip = XG41;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002231 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2232 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302233 case PCI_DEVICE_ID_XG_42:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002234 xgi_video_info.chip = XG42;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002235 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2236 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302237 case PCI_DEVICE_ID_XG_27:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002238 xgi_video_info.chip = XG27;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002239 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2240 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302241 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002242 ret = -ENODEV;
2243 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002244 }
2245
Prashant P. Shahb654f872010-09-06 17:34:26 +05302246 printk("XGIfb:chipid = %x\n", xgi_video_info.chip);
2247 XGIhw_ext.jChipType = xgi_video_info.chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002248
Prashant P. Shahb654f872010-09-06 17:34:26 +05302249 if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002250 XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302251 if (XGIhw_ext.pjVirtualRomBase)
2252 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002253 else
2254 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302255 } else {
2256 XGIhw_ext.pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002257 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302258 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302259 XGIhw_ext.pQueryVGAConfigSpace = &XGIfb_query_VGA_config_space;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002260
Prashant P. Shahb654f872010-09-06 17:34:26 +05302261 if (XGIfb_get_dram_size()) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302262 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002263 ret = -ENODEV;
2264 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302265 }
2266
2267 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
2268 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2269 orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2270 /* Enable 2D accelerator engine */
2271 orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
2272 }
2273
2274 XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
2275
2276 if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
2277 printk("unable request memory size %x", xgi_video_info.video_size);
2278 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2279 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002280 ret = -ENODEV;
2281 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302282 }
2283
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002284 if (!request_mem_region(xgi_video_info.mmio_base,
2285 xgi_video_info.mmio_size,
2286 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302287 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002288 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002289 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302290 }
2291
2292 xgi_video_info.video_vbase = XGIhw_ext.pjVideoMemoryAddress =
2293 ioremap(xgi_video_info.video_base, xgi_video_info.video_size);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002294 xgi_video_info.mmio_vbase = ioremap(xgi_video_info.mmio_base,
2295 xgi_video_info.mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302296
2297 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
2298 xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
2299
2300 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002301 xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
2302 xgi_video_info.mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302303 printk("XGIfb: XGIInitNew() ...");
2304 if (XGIInitNew(&XGIhw_ext))
2305 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002306 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002307 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002308
Prashant P. Shahb654f872010-09-06 17:34:26 +05302309 xgi_video_info.mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002310
Prashant P. Shahb654f872010-09-06 17:34:26 +05302311 if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002312 xgi_video_info.hasVB = HASVB_NONE;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302313 if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
2314 xgi_video_info.hasVB = HASVB_NONE;
2315 } else if (xgi_video_info.chip == XG21) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002316 CR38 = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302317 if ((CR38&0xE0) == 0xC0) {
2318 xgi_video_info.disp_state = DISPTYPE_LCD;
2319 if (!XGIfb_GetXG21LVDSData()) {
2320 int m;
2321 for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
2322 if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
2323 (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
Aaro Koskinen8104e322011-03-13 12:26:22 +02002324 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302325 }
2326 }
2327 }
2328 } else if ((CR38&0xE0) == 0x60) {
2329 xgi_video_info.hasVB = HASVB_CHRONTEL;
2330 } else {
2331 xgi_video_info.hasVB = HASVB_NONE;
2332 }
2333 } else {
2334 XGIfb_get_VB_type();
2335 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002336
Prashant P. Shahb654f872010-09-06 17:34:26 +05302337 XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002338
Prashant P. Shahb654f872010-09-06 17:34:26 +05302339 XGIhw_ext.ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002340
2341 switch (xgi_video_info.hasVB) {
2342 case HASVB_301:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002343 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002344 if (reg >= 0xE0) {
2345 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302346 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2347 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002348 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302349 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
2350 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002351 /* else if (reg >= 0xB0) {
2352 XGIhw_ext.ujVBChipID = VB_CHIP_301B;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002353 reg1 = xgifb_reg_get(XGIPART4, 0x23);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302354 printk("XGIfb: XGI301B bridge detected\n");
2355 } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002356 else {
2357 XGIhw_ext.ujVBChipID = VB_CHIP_301;
2358 printk("XGIfb: XGI301 bridge detected\n");
2359 }
2360 break;
2361 case HASVB_302:
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002362 reg = xgifb_reg_get(XGIPART4, 0x01);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002363 if (reg >= 0xE0) {
2364 XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302365 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2366 } else if (reg >= 0xD0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002367 XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302368 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2369 } else if (reg >= 0xB0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002370 reg1 = xgifb_reg_get(XGIPART4, 0x23);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002371
Prashant P. Shahb654f872010-09-06 17:34:26 +05302372 XGIhw_ext.ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002373
2374 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302375 XGIhw_ext.ujVBChipID = VB_CHIP_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002376 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
2377 }
2378 break;
2379 case HASVB_LVDS:
2380 XGIhw_ext.ulExternalChip = 0x1;
2381 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2382 break;
2383 case HASVB_TRUMPION:
2384 XGIhw_ext.ulExternalChip = 0x2;
2385 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2386 break;
2387 case HASVB_CHRONTEL:
2388 XGIhw_ext.ulExternalChip = 0x4;
2389 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2390 break;
2391 case HASVB_LVDS_CHRONTEL:
2392 XGIhw_ext.ulExternalChip = 0x5;
2393 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2394 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302395 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002396 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2397 break;
2398 }
2399
Prashant P. Shahb654f872010-09-06 17:34:26 +05302400 if (xgi_video_info.hasVB != HASVB_NONE)
2401 XGIfb_detect_VB();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002402
2403 if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
2404 if (XGIfb_crt1off)
2405 xgi_video_info.disp_state |= DISPMODE_SINGLE;
2406 else
2407 xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
2408 } else {
2409 xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
2410 }
2411
2412 if (xgi_video_info.disp_state & DISPTYPE_LCD) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302413 if (!enable_dstn) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002414 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302415 reg &= 0x0f;
2416 XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002417
Prashant P. Shahb654f872010-09-06 17:34:26 +05302418 } else {
2419 /* TW: FSTN/DSTN */
2420 XGIhw_ext.ulCRT2LCDType = LCD_320x480;
2421 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002422 }
2423
2424 XGIfb_detectedpdc = 0;
2425
Prashant P. Shahb654f872010-09-06 17:34:26 +05302426 XGIfb_detectedlcda = 0xff;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002427
Prashant P. Shahb654f872010-09-06 17:34:26 +05302428 /* TW: Try to find about LCDA */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002429
Prashant P. Shahb654f872010-09-06 17:34:26 +05302430 if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) ||
2431 (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
2432 (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
2433 int tmp;
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002434 tmp = xgifb_reg_get(XGICR, 0x34);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302435 if (tmp <= 0x13) {
2436 /* Currently on LCDA? (Some BIOSes leave CR38) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002437 tmp = xgifb_reg_get(XGICR, 0x38);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302438 if ((tmp & 0x03) == 0x03) {
2439 /* XGI_Pr.XGI_UseLCDA = 1; */
2440 } else {
2441 /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002442 tmp = xgifb_reg_get(XGICR, 0x35);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302443 if (tmp & 0x01) {
2444 /* XGI_Pr.XGI_UseLCDA = 1; */
2445 } else {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002446 tmp = xgifb_reg_get(XGICR, 0x30);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302447 if (tmp & 0x20) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002448 tmp = xgifb_reg_get(XGIPART1, 0x13);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302449 if (tmp & 0x04) {
2450 /* XGI_Pr.XGI_UseLCDA = 1; */
2451 }
2452 }
2453 }
2454 }
2455 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002456
Prashant P. Shahb654f872010-09-06 17:34:26 +05302457 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002458
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002459 if (xgifb_mode_idx >= 0)
2460 xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx);
2461
2462 if (xgifb_mode_idx < 0) {
2463 switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302464 case DISPTYPE_LCD:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002465 xgifb_mode_idx = DEFAULT_LCDMODE;
2466 if (xgi_video_info.chip == XG21)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302467 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002468 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302469 case DISPTYPE_TV:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002470 xgifb_mode_idx = DEFAULT_TVMODE;
2471 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302472 default:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002473 xgifb_mode_idx = DEFAULT_MODE;
2474 break;
2475 }
2476 }
2477
2478 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2479
Prashant P. Shahb654f872010-09-06 17:34:26 +05302480 if (xgi_video_info.refresh_rate == 0)
2481 xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
2482 if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
2483 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
2484 xgi_video_info.refresh_rate = 60;
2485 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002486
2487 xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2488 xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
2489 xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
2490 xgi_video_info.org_x = xgi_video_info.org_y = 0;
2491 xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302492 switch (xgi_video_info.video_bpp) {
2493 case 8:
2494 xgi_video_info.DstColor = 0x0000;
2495 xgi_video_info.XGI310_AccelDepth = 0x00000000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002496 xgi_video_info.video_cmap_len = 256;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302497 break;
2498 case 16:
2499 xgi_video_info.DstColor = 0x8000;
2500 xgi_video_info.XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002501 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302502 break;
2503 case 32:
2504 xgi_video_info.DstColor = 0xC000;
2505 xgi_video_info.XGI310_AccelDepth = 0x00020000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002506 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302507 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002508 default:
2509 xgi_video_info.video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302510 printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002511 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302512 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002513
2514 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302515 xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
2516 xgi_video_info.refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002517
2518 default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
2519 default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
2520 default_var.bits_per_pixel = xgi_video_info.video_bpp;
2521
2522 XGIfb_bpp_to_var(&default_var);
2523
2524 default_var.pixclock = (u32) (1000000000 /
2525 XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext,
2526 XGIfb_mode_no, XGIfb_rate_idx));
2527
Prashant P. Shahb654f872010-09-06 17:34:26 +05302528 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext,
2529 XGIfb_mode_no, XGIfb_rate_idx,
2530 &default_var.left_margin, &default_var.right_margin,
2531 &default_var.upper_margin, &default_var.lower_margin,
2532 &default_var.hsync_len, &default_var.vsync_len,
2533 &default_var.sync, &default_var.vmode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002534
Prashant P. Shahb654f872010-09-06 17:34:26 +05302535 if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
2536 default_var.yres <<= 1;
2537 default_var.yres_virtual <<= 1;
2538 } else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
2539 default_var.pixclock >>= 1;
2540 default_var.yres >>= 1;
2541 default_var.yres_virtual >>= 1;
2542 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002543
Prashant P. Shahb654f872010-09-06 17:34:26 +05302544 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002545
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002546 fb_info->flags = FBINFO_FLAG_DEFAULT;
2547 fb_info->var = default_var;
2548 fb_info->fix = XGIfb_fix;
2549 fb_info->par = &xgi_video_info;
2550 fb_info->screen_base = xgi_video_info.video_vbase;
2551 fb_info->fbops = &XGIfb_ops;
2552 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2553 fb_info->pseudo_palette = pseudo_palette;
2554
2555 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2556
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002557#ifdef CONFIG_MTRR
2558 xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
2559 (unsigned int) xgi_video_info.video_size,
2560 MTRR_TYPE_WRCOMB, 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302561 if (xgi_video_info.mtrr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002562 printk(KERN_INFO "XGIfb: Added MTRRs\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002563#endif
2564
Aaro Koskinenbb292232011-02-17 23:29:11 +02002565 if (register_framebuffer(fb_info) < 0) {
2566 ret = -EINVAL;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002567 goto error_1;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002568 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002569
2570 XGIfb_registered = 1;
2571
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002572 printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
Prashant P. Shahb654f872010-09-06 17:34:26 +05302573 fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002574
2575 }
2576
2577 dumpVGAReg();
2578
2579 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002580
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002581error_1:
2582 iounmap(xgi_video_info.mmio_vbase);
2583 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002584 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002585error_0:
2586 release_mem_region(xgi_video_info.video_base,
2587 xgi_video_info.video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002588error:
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002589 vfree(XGIhw_ext.pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002590 framebuffer_release(fb_info);
2591 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002592}
2593
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002594/*****************************************************/
2595/* PCI DEVICE HANDLING */
2596/*****************************************************/
2597
2598static void __devexit xgifb_remove(struct pci_dev *pdev)
2599{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302600 unregister_framebuffer(fb_info);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002601 iounmap(xgi_video_info.mmio_vbase);
2602 iounmap(xgi_video_info.video_vbase);
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002603 release_mem_region(xgi_video_info.mmio_base, xgi_video_info.mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002604 release_mem_region(xgi_video_info.video_base,
2605 xgi_video_info.video_size);
Aaro Koskinen0f07d942011-02-17 23:29:13 +02002606 vfree(XGIhw_ext.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302607 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002608 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02002609}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002610
2611static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302612 .name = "xgifb",
2613 .id_table = xgifb_pci_table,
2614 .probe = xgifb_probe,
2615 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002616};
2617
2618XGIINITSTATIC int __init xgifb_init(void)
2619{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002620 char *option = NULL;
2621
2622 if (fb_get_options("xgifb", &option))
2623 return -ENODEV;
2624 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04002625
Prashant P. Shahb654f872010-09-06 17:34:26 +05302626 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002627}
2628
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002629#ifndef MODULE
2630module_init(xgifb_init);
2631#endif
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002632
2633/*****************************************************/
2634/* MODULE */
2635/*****************************************************/
2636
2637#ifdef MODULE
2638
Prashant P. Shahb654f872010-09-06 17:34:26 +05302639static char *mode = NULL;
2640static int vesa = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002641static unsigned int rate = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002642static unsigned int mem = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302643static char *forcecrt2type = NULL;
2644static int forcecrt1 = -1;
2645static int pdc = -1;
2646static int pdc1 = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302647static int noypan = -1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302648static int userom = -1;
2649static int useoem = -1;
2650static char *tvstandard = NULL;
2651static int nocrt2rate = 0;
2652static int scalelcd = -1;
2653static char *specialtiming = NULL;
2654static int lvdshl = -1;
2655static int tvxposoffset = 0, tvyposoffset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002656#if !defined(__i386__) && !defined(__x86_64__)
Prashant P. Shahb654f872010-09-06 17:34:26 +05302657static int resetcard = 0;
2658static int videoram = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002659#endif
2660
2661MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2662MODULE_LICENSE("GPL");
2663MODULE_AUTHOR("XGITECH , Others");
2664
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002665module_param(mem, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002666module_param(noypan, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002667module_param(userom, int, 0);
2668module_param(useoem, int, 0);
2669module_param(mode, charp, 0);
2670module_param(vesa, int, 0);
2671module_param(rate, int, 0);
2672module_param(forcecrt1, int, 0);
2673module_param(forcecrt2type, charp, 0);
2674module_param(scalelcd, int, 0);
2675module_param(pdc, int, 0);
2676module_param(pdc1, int, 0);
2677module_param(specialtiming, charp, 0);
2678module_param(lvdshl, int, 0);
2679module_param(tvstandard, charp, 0);
2680module_param(tvxposoffset, int, 0);
2681module_param(tvyposoffset, int, 0);
2682module_param(filter, int, 0);
2683module_param(nocrt2rate, int, 0);
2684#if !defined(__i386__) && !defined(__x86_64__)
2685module_param(resetcard, int, 0);
2686module_param(videoram, int, 0);
2687#endif
2688
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002689MODULE_PARM_DESC(noypan,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302690 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
2691 "will be performed by redrawing the screen. (default: 0)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002692
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002693MODULE_PARM_DESC(mode,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302694 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2695 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
2696 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
2697 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002698
2699MODULE_PARM_DESC(vesa,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302700 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
2701 "0x117 (default: 0x0103)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002702
2703MODULE_PARM_DESC(rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302704 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
2705 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
2706 "will be ignored (default: 60)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002707
2708MODULE_PARM_DESC(forcecrt1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302709 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is\n"
2710 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
2711 "0=CRT1 OFF) (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002712
2713MODULE_PARM_DESC(forcecrt2type,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302714 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
2715 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
2716 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
2717 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
2718 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
2719 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
2720 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
2721 "depends on the very hardware in use. (default: [autodetected])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002722
2723MODULE_PARM_DESC(scalelcd,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302724 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
2725 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
2726 "show black bars around the image, TMDS panels will probably do the scaling\n"
2727 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002728
2729MODULE_PARM_DESC(pdc,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302730 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
2731 "should detect this correctly in most cases; however, sometimes this is not\n"
2732 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
2733 "on a 300 series chipset; 6 on a 315 series chipset. If the problem persists,\n"
2734 "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
2735 "any value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002736
2737MODULE_PARM_DESC(pdc1,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302738 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330\n"
2739 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
2740 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
2741 "implemented yet.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002742
2743MODULE_PARM_DESC(specialtiming,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302744 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002745
2746MODULE_PARM_DESC(lvdshl,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302747 "\nPlease refer to documentation for more information on this option.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002748
2749MODULE_PARM_DESC(tvstandard,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302750 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
2751 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002752
2753MODULE_PARM_DESC(tvxposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302754 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
2755 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002756
2757MODULE_PARM_DESC(tvyposoffset,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302758 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
2759 "Default: 0\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002760
2761MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302762 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2763 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002764
2765MODULE_PARM_DESC(nocrt2rate,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302766 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
2767 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002768
Randy Dunlap89229672010-08-10 08:46:44 -07002769static int __init xgifb_init_module(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002770{
Prashant P. Shahb654f872010-09-06 17:34:26 +05302771 printk("\nXGIfb_init_module");
2772 if (mode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002773 XGIfb_search_mode(mode);
2774 else if (vesa != -1)
2775 XGIfb_search_vesamode(vesa);
2776
Prashant P. Shahb654f872010-09-06 17:34:26 +05302777 return xgifb_init();
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002778}
2779
2780static void __exit xgifb_remove_module(void)
2781{
2782 pci_unregister_driver(&xgifb_driver);
2783 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2784}
2785
2786module_init(xgifb_init_module);
2787module_exit(xgifb_remove_module);
2788
Prashant P. Shahb654f872010-09-06 17:34:26 +05302789#endif /* /MODULE */