blob: bb53144e588e62e2207d7fa09840d4ad653a6e04 [file] [log] [blame]
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001/*
2 * XG20, XG21, XG40, XG42 frame buffer device
3 * for Linux kernels 2.5.x, 2.6.x
4 * Base on TW's sis fbdev code.
5 */
6
Prashant P. Shahb654f872010-09-06 17:34:26 +05307/* #include <linux/config.h> */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02008#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/kernel.h>
11#include <linux/spinlock.h>
12#include <linux/errno.h>
13#include <linux/string.h>
14#include <linux/mm.h>
15#include <linux/tty.h>
16#include <linux/slab.h>
17#include <linux/delay.h>
18#include <linux/fb.h>
19#include <linux/console.h>
20#include <linux/selection.h>
21#include <linux/ioport.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/vmalloc.h>
25#include <linux/vt_kern.h>
26#include <linux/capability.h>
27#include <linux/fs.h>
28#include <linux/types.h>
29#include <linux/proc_fs.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020030
Kenji Toyamaa12c27c2011-04-26 12:13:43 +080031#include <linux/io.h>
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020032#ifdef CONFIG_MTRR
33#include <asm/mtrr.h>
34#endif
35
36#include "XGIfb.h"
37#include "vgatypes.h"
38#include "XGI_main.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030039#include "vb_init.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020040#include "vb_util.h"
Aaro Koskinend542af52011-04-18 22:14:06 +030041#include "vb_setmode.h"
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020042
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020043#define Index_CR_GPIO_Reg1 0x48
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020044#define Index_CR_GPIO_Reg3 0x4a
45
46#define GPIOG_EN (1<<6)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020047#define GPIOG_READ (1<<1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020048
Aaro Koskinen0f07d942011-02-17 23:29:13 +020049#define XGIFB_ROM_SIZE 65536
50
Aaro Koskinendfbdf802011-08-29 23:14:25 +030051static char *mode;
Aaro Koskinenc3228302011-08-29 23:14:32 +030052static int vesa = -1;
Aaro Koskinen7548a832011-10-11 21:47:17 +030053static unsigned int refresh_rate;
Aaro Koskinendfbdf802011-08-29 23:14:25 +030054
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020055/* -------------------- Macro definitions ---------------------------- */
56
57#undef XGIFBDEBUG
58
59#ifdef XGIFBDEBUG
60#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
61#else
62#define DPRINTK(fmt, args...)
63#endif
64
65#ifdef XGIFBDEBUG
66static void dumpVGAReg(void)
67{
Prashant P. Shahb654f872010-09-06 17:34:26 +053068 u8 i, reg;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020069
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030070 xgifb_reg_set(XGISR, 0x05, 0x86);
Prashant P. Shahb654f872010-09-06 17:34:26 +053071 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030072 xgifb_reg_set(XGISR, 0x08, 0x4f);
73 xgifb_reg_set(XGISR, 0x0f, 0x20);
74 xgifb_reg_set(XGISR, 0x11, 0x4f);
75 xgifb_reg_set(XGISR, 0x13, 0x45);
76 xgifb_reg_set(XGISR, 0x14, 0x51);
77 xgifb_reg_set(XGISR, 0x1e, 0x41);
78 xgifb_reg_set(XGISR, 0x1f, 0x0);
79 xgifb_reg_set(XGISR, 0x20, 0xa1);
80 xgifb_reg_set(XGISR, 0x22, 0xfb);
81 xgifb_reg_set(XGISR, 0x26, 0x22);
82 xgifb_reg_set(XGISR, 0x3e, 0x07);
Prashant P. Shahb654f872010-09-06 17:34:26 +053083 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020084
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030085 /* xgifb_reg_set(XGICR, 0x19, 0x00); */
86 /* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
87 /* xgifb_reg_set(XGICR, 0x22, 0xff); */
88 /* xgifb_reg_set(XGICR, 0x3D, 0x10); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020089
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030090 /* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020091
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030092 /* xgifb_reg_set(XGICR, 0x57, 0x0); */
93 /* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +020094
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030095 /* xgifb_reg_set(XGICR, 0x82, 0xcc); */
96 /* xgifb_reg_set(XGICR, 0x8c, 0x0); */
Prashant P. Shahb654f872010-09-06 17:34:26 +053097 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +030098 xgifb_reg_set(XGICR, 0x99, 0x1);
99 xgifb_reg_set(XGICR, 0x41, 0x40);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530100 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200101
Prashant P. Shahb654f872010-09-06 17:34:26 +0530102 for (i = 0; i < 0x4f; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300103 reg = xgifb_reg_get(XGISR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530104 printk("\no 3c4 %x", i);
105 printk("\ni 3c5 => %x", reg);
106 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200107
Prashant P. Shahb654f872010-09-06 17:34:26 +0530108 for (i = 0; i < 0xF0; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300109 reg = xgifb_reg_get(XGICR, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530110 printk("\no 3d4 %x", i);
111 printk("\ni 3d5 => %x", reg);
112 }
113 /*
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300114 xgifb_reg_set(XGIPART1,0x2F,1);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530115 for (i=1; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300116 reg = xgifb_reg_get(XGIPART1, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530117 printk("\no d004 %x", i);
118 printk("\ni d005 => %x", reg);
119 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200120
Prashant P. Shahb654f872010-09-06 17:34:26 +0530121 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300122 reg = xgifb_reg_get(XGIPART2, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530123 printk("\no d010 %x", i);
124 printk("\ni d011 => %x", reg);
125 }
126 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300127 reg = xgifb_reg_get(XGIPART3, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530128 printk("\no d012 %x",i);
129 printk("\ni d013 => %x",reg);
130 }
131 for (i=0; i < 0x50; i++) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300132 reg = xgifb_reg_get(XGIPART4, i);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530133 printk("\no d014 %x",i);
134 printk("\ni d015 => %x",reg);
135 }
136 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200137}
138#else
Prashant P. Shahb654f872010-09-06 17:34:26 +0530139static inline void dumpVGAReg(void)
140{
141}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200142#endif
143
144/* data for XGI components */
Aaro Koskinenab886ff2011-10-11 21:47:18 +0300145struct xgifb_video_info xgi_video_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200146
147#if 1
148#define DEBUGPRN(x)
149#else
150#define DEBUGPRN(x) printk(KERN_INFO x "\n");
151#endif
152
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200153/* --------------- Hardware Access Routines -------------------------- */
154
Prashant P. Shahb654f872010-09-06 17:34:26 +0530155static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
156 struct xgi_hw_device_info *HwDeviceExtension,
157 unsigned char modeno, unsigned char rateindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200158{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530159 unsigned short ModeNo = modeno;
160 unsigned short ModeIdIndex = 0, ClockIndex = 0;
161 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200162
Prashant P. Shahb654f872010-09-06 17:34:26 +0530163 /* unsigned long temp = 0; */
164 int Clock;
165 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
166 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200167
Prashant P. Shahb654f872010-09-06 17:34:26 +0530168 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
169 ModeIdIndex, XGI_Pr);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200170
Prashant P. Shahb654f872010-09-06 17:34:26 +0530171 /*
172 temp = XGI_SearchModeID(ModeNo , &ModeIdIndex, XGI_Pr) ;
173 if (!temp) {
174 printk(KERN_ERR "Could not find mode %x\n", ModeNo);
175 return 65000;
176 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200177
Prashant P. Shahb654f872010-09-06 17:34:26 +0530178 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
179 RefreshRateTableIndex += (rateindex - 1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200180
Prashant P. Shahb654f872010-09-06 17:34:26 +0530181 */
182 ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200183
Prashant P. Shahb654f872010-09-06 17:34:26 +0530184 Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000;
185
186 return Clock;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200187}
188
Prashant P. Shahb654f872010-09-06 17:34:26 +0530189static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
190 struct xgi_hw_device_info *HwDeviceExtension,
191 unsigned char modeno, unsigned char rateindex,
192 u32 *left_margin, u32 *right_margin, u32 *upper_margin,
193 u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
194 u32 *vmode)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200195{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530196 unsigned short ModeNo = modeno;
197 unsigned short ModeIdIndex = 0, index = 0;
198 unsigned short RefreshRateTableIndex = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200199
Prashant P. Shahb654f872010-09-06 17:34:26 +0530200 unsigned short VRE, VBE, VRS, VBS, VDE, VT;
201 unsigned short HRE, HBE, HRS, HBS, HDE, HT;
202 unsigned char sr_data, cr_data, cr_data2;
203 unsigned long cr_data3;
204 int A, B, C, D, E, F, temp, j;
205 XGI_Pr->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
206 InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
207 RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
208 ModeIdIndex, XGI_Pr);
209 /*
210 temp = XGI_SearchModeID(ModeNo, &ModeIdIndex, XGI_Pr);
211 if (!temp)
212 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200213
Prashant P. Shahb654f872010-09-06 17:34:26 +0530214 RefreshRateTableIndex = XGI_Pr->EModeIDTable[ModeIdIndex].REFindex;
215 RefreshRateTableIndex += (rateindex - 1);
216 */
217 index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200218
Prashant P. Shahb654f872010-09-06 17:34:26 +0530219 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200220
Prashant P. Shahb654f872010-09-06 17:34:26 +0530221 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200222
Prashant P. Shahb654f872010-09-06 17:34:26 +0530223 /* Horizontal total */
224 HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8);
225 A = HT + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200226
Prashant P. Shahb654f872010-09-06 17:34:26 +0530227 /*
228 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200229
Prashant P. Shahb654f872010-09-06 17:34:26 +0530230 Horizontal display enable end
231 HDE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x0C) << 6);
232 */
233 HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1;
234 E = HDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200235
Prashant P. Shahb654f872010-09-06 17:34:26 +0530236 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200237
Prashant P. Shahb654f872010-09-06 17:34:26 +0530238 /* Horizontal retrace (=sync) start */
239 HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
240 F = HRS - E - 3;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200241
Prashant P. Shahb654f872010-09-06 17:34:26 +0530242 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200243
Prashant P. Shahb654f872010-09-06 17:34:26 +0530244 /* Horizontal blank start */
245 HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200246
Prashant P. Shahb654f872010-09-06 17:34:26 +0530247 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200248
Prashant P. Shahb654f872010-09-06 17:34:26 +0530249 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200250
Prashant P. Shahb654f872010-09-06 17:34:26 +0530251 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200252
Prashant P. Shahb654f872010-09-06 17:34:26 +0530253 /* Horizontal blank end */
254 HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
255 | ((unsigned short) (sr_data & 0x03) << 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200256
Prashant P. Shahb654f872010-09-06 17:34:26 +0530257 /* Horizontal retrace (=sync) end */
258 HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200259
Prashant P. Shahb654f872010-09-06 17:34:26 +0530260 temp = HBE - ((E - 1) & 255);
261 B = (temp > 0) ? temp : (temp + 256);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200262
Prashant P. Shahb654f872010-09-06 17:34:26 +0530263 temp = HRE - ((E + F + 3) & 63);
264 C = (temp > 0) ? temp : (temp + 64);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200265
Prashant P. Shahb654f872010-09-06 17:34:26 +0530266 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200267
Prashant P. Shahb654f872010-09-06 17:34:26 +0530268 *left_margin = D * 8;
269 *right_margin = F * 8;
270 *hsync_len = C * 8;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200271
Prashant P. Shahb654f872010-09-06 17:34:26 +0530272 sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200273
Prashant P. Shahb654f872010-09-06 17:34:26 +0530274 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200275
Prashant P. Shahb654f872010-09-06 17:34:26 +0530276 cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200277
Prashant P. Shahb654f872010-09-06 17:34:26 +0530278 /* Vertical total */
279 VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8)
280 | ((unsigned short) (cr_data2 & 0x20) << 4)
281 | ((unsigned short) (sr_data & 0x01) << 10);
282 A = VT + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200283
Prashant P. Shahb654f872010-09-06 17:34:26 +0530284 /* cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200285
Prashant P. Shahb654f872010-09-06 17:34:26 +0530286 /* Vertical display enable end */
287 /*
288 VDE = (cr_data & 0xff) |
289 ((unsigned short) (cr_data2 & 0x02) << 7) |
290 ((unsigned short) (cr_data2 & 0x40) << 3) |
291 ((unsigned short) (sr_data & 0x02) << 9);
292 */
293 VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1;
294 E = VDE + 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200295
Prashant P. Shahb654f872010-09-06 17:34:26 +0530296 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200297
Prashant P. Shahb654f872010-09-06 17:34:26 +0530298 /* Vertical retrace (=sync) start */
299 VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
300 | ((unsigned short) (cr_data2 & 0x80) << 2)
301 | ((unsigned short) (sr_data & 0x08) << 7);
302 F = VRS + 1 - E;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200303
Prashant P. Shahb654f872010-09-06 17:34:26 +0530304 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200305
Prashant P. Shahb654f872010-09-06 17:34:26 +0530306 cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200307
Prashant P. Shahb654f872010-09-06 17:34:26 +0530308 /* Vertical blank start */
309 VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5)
310 | ((unsigned short) (cr_data3 & 0x20) << 4)
311 | ((unsigned short) (sr_data & 0x04) << 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200312
Prashant P. Shahb654f872010-09-06 17:34:26 +0530313 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200314
Prashant P. Shahb654f872010-09-06 17:34:26 +0530315 /* Vertical blank end */
316 VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
317 temp = VBE - ((E - 1) & 511);
318 B = (temp > 0) ? temp : (temp + 512);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200319
Prashant P. Shahb654f872010-09-06 17:34:26 +0530320 cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11];
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200321
Prashant P. Shahb654f872010-09-06 17:34:26 +0530322 /* Vertical retrace (=sync) end */
323 VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
324 temp = VRE - ((E + F - 1) & 31);
325 C = (temp > 0) ? temp : (temp + 32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200326
Prashant P. Shahb654f872010-09-06 17:34:26 +0530327 D = B - F - C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200328
Prashant P. Shahb654f872010-09-06 17:34:26 +0530329 *upper_margin = D;
330 *lower_margin = F;
331 *vsync_len = C;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200332
Prashant P. Shahb654f872010-09-06 17:34:26 +0530333 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
334 *sync &= ~FB_SYNC_VERT_HIGH_ACT;
335 else
336 *sync |= FB_SYNC_VERT_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200337
Prashant P. Shahb654f872010-09-06 17:34:26 +0530338 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
339 *sync &= ~FB_SYNC_HOR_HIGH_ACT;
340 else
341 *sync |= FB_SYNC_HOR_HIGH_ACT;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200342
Prashant P. Shahb654f872010-09-06 17:34:26 +0530343 *vmode = FB_VMODE_NONINTERLACED;
344 if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
345 *vmode = FB_VMODE_INTERLACED;
346 else {
347 j = 0;
348 while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800349 if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
350 XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
351 if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
352 DoubleScanMode) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530353 *vmode = FB_VMODE_DOUBLE;
354 }
355 break;
356 }
357 j++;
358 }
359 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200360
Prashant P. Shahb654f872010-09-06 17:34:26 +0530361 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200362}
363
Randy Dunlap89229672010-08-10 08:46:44 -0700364static void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200365{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530366 XGI_Pr->RelIO = BaseAddr;
367 XGI_Pr->P3c4 = BaseAddr + 0x14;
368 XGI_Pr->P3d4 = BaseAddr + 0x24;
369 XGI_Pr->P3c0 = BaseAddr + 0x10;
370 XGI_Pr->P3ce = BaseAddr + 0x1e;
371 XGI_Pr->P3c2 = BaseAddr + 0x12;
372 XGI_Pr->P3ca = BaseAddr + 0x1a;
373 XGI_Pr->P3c6 = BaseAddr + 0x16;
374 XGI_Pr->P3c7 = BaseAddr + 0x17;
375 XGI_Pr->P3c8 = BaseAddr + 0x18;
376 XGI_Pr->P3c9 = BaseAddr + 0x19;
377 XGI_Pr->P3da = BaseAddr + 0x2A;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800378 /* Digital video interface registers (LCD) */
379 XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
380 /* 301 TV Encoder registers */
381 XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
382 /* 301 Macrovision registers */
383 XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
384 /* 301 VGA2 (and LCD) registers */
385 XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
386 /* 301 palette address port registers */
387 XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200388
389}
390
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200391/* ------------------ Internal helper routines ----------------- */
392
Aaro Koskinen8a94d1a2011-04-18 22:14:08 +0300393static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300394{
395
396 int found_mode = 0;
397 int XGIfb_mode_idx = 0;
398
399 found_mode = 0;
400 while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
401 && (XGIbios_mode[XGIfb_mode_idx].xres
402 <= XGI21_LCDCapList[0].LVDSHDE)) {
403 if ((XGIbios_mode[XGIfb_mode_idx].xres
404 == XGI21_LCDCapList[0].LVDSHDE)
405 && (XGIbios_mode[XGIfb_mode_idx].yres
406 == XGI21_LCDCapList[0].LVDSVDE)
407 && (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
408 XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
409 found_mode = 1;
410 break;
411 }
412 XGIfb_mode_idx++;
413 }
414 if (!found_mode)
Aaro Koskinende736db2011-08-29 23:14:29 +0300415 XGIfb_mode_idx = -1;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300416
417 return XGIfb_mode_idx;
418}
419
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200420static void XGIfb_search_mode(const char *name)
421{
422 int i = 0, j = 0, l;
423
Prashant P. Shahb654f872010-09-06 17:34:26 +0530424 while (XGIbios_mode[i].mode_no != 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200425 l = min(strlen(name), strlen(XGIbios_mode[i].name));
426 if (!strncmp(name, XGIbios_mode[i].name, l)) {
427 xgifb_mode_idx = i;
428 j = 1;
429 break;
430 }
431 i++;
432 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530433 if (!j)
434 printk(KERN_INFO "XGIfb: Invalid mode '%s'\n", name);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200435}
436
437static void XGIfb_search_vesamode(unsigned int vesamode)
438{
439 int i = 0, j = 0;
440
Aaro Koskinenc3228302011-08-29 23:14:32 +0300441 if (vesamode == 0)
442 goto invalid;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200443
Prashant P. Shahb654f872010-09-06 17:34:26 +0530444 vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200445
Prashant P. Shahb654f872010-09-06 17:34:26 +0530446 while (XGIbios_mode[i].mode_no != 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800447 if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
448 (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200449 xgifb_mode_idx = i;
450 j = 1;
451 break;
452 }
453 i++;
454 }
Aaro Koskinenc3228302011-08-29 23:14:32 +0300455
456invalid:
Prashant P. Shahb654f872010-09-06 17:34:26 +0530457 if (!j)
458 printk(KERN_INFO "XGIfb: Invalid VESA mode 0x%x'\n", vesamode);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200459}
460
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300461static int XGIfb_GetXG21LVDSData(struct xgifb_video_info *xgifb_info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200462{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530463 u8 tmp;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300464 void __iomem *data = xgifb_info->mmio_vbase + 0x20000;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530465 int i, j, k;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200466
Aaro Koskinen7e119b72011-04-18 22:13:58 +0300467 tmp = xgifb_reg_get(XGISR, 0x1e);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +0300468 xgifb_reg_set(XGISR, 0x1e, tmp | 4);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200469
Aaro Koskinen863c02a2011-09-13 22:49:31 +0300470 if ((readb(data) == 0x55) &&
471 (readb(data + 1) == 0xAA) &&
472 (readb(data + 0x65) & 0x1)) {
473 i = readw(data + 0x316);
474 j = readb(data + i - 1);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530475 if (j == 0xff)
476 j = 1;
477
478 k = 0;
479 do {
Aaro Koskinen863c02a2011-09-13 22:49:31 +0300480 XGI21_LCDCapList[k].LVDS_Capability = readw(data + i);
481 XGI21_LCDCapList[k].LVDSHT = readw(data + i + 2);
482 XGI21_LCDCapList[k].LVDSVT = readw(data + i + 4);
483 XGI21_LCDCapList[k].LVDSHDE = readw(data + i + 6);
484 XGI21_LCDCapList[k].LVDSVDE = readw(data + i + 8);
485 XGI21_LCDCapList[k].LVDSHFP = readw(data + i + 10);
486 XGI21_LCDCapList[k].LVDSVFP = readw(data + i + 12);
487 XGI21_LCDCapList[k].LVDSHSYNC = readw(data + i + 14);
488 XGI21_LCDCapList[k].LVDSVSYNC = readw(data + i + 16);
489 XGI21_LCDCapList[k].VCLKData1 = readb(data + i + 18);
490 XGI21_LCDCapList[k].VCLKData2 = readb(data + i + 19);
491 XGI21_LCDCapList[k].PSC_S1 = readb(data + i + 20);
492 XGI21_LCDCapList[k].PSC_S2 = readb(data + i + 21);
493 XGI21_LCDCapList[k].PSC_S3 = readb(data + i + 22);
494 XGI21_LCDCapList[k].PSC_S4 = readb(data + i + 23);
495 XGI21_LCDCapList[k].PSC_S5 = readb(data + i + 24);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530496 i += 25;
497 j--;
498 k++;
499 } while ((j > 0) && (k < (sizeof(XGI21_LCDCapList)
500 / sizeof(struct XGI21_LVDSCapStruct))));
501 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200502 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530503 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200504}
505
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300506static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200507{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530508 u16 xres, yres;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300509 struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200510
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300511 if (xgifb_info->chip == XG21) {
512 if ((xgifb_info->disp_state & DISPTYPE_DISP2)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530513 == DISPTYPE_LCD) {
514 xres = XGI21_LCDCapList[0].LVDSHDE;
515 yres = XGI21_LCDCapList[0].LVDSVDE;
516 if (XGIbios_mode[myindex].xres > xres)
517 return -1;
518 if (XGIbios_mode[myindex].yres > yres)
519 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800520 if ((XGIbios_mode[myindex].xres < xres) &&
521 (XGIbios_mode[myindex].yres < yres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530522 if (XGIbios_mode[myindex].bpp > 8)
523 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200524 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530525
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200526 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530527 return myindex;
528
529 }
530
531 /* FIXME: for now, all is valid on XG27 */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300532 if (xgifb_info->chip == XG27)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530533 return myindex;
534
535 if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
536 return -1;
537
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300538 switch (xgifb_info->disp_state & DISPTYPE_DISP2) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530539 case DISPTYPE_LCD:
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300540 switch (hw_info->ulCRT2LCDType) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530541 case LCD_640x480:
542 xres = 640;
543 yres = 480;
544 break;
545 case LCD_800x600:
546 xres = 800;
547 yres = 600;
548 break;
549 case LCD_1024x600:
550 xres = 1024;
551 yres = 600;
552 break;
553 case LCD_1024x768:
554 xres = 1024;
555 yres = 768;
556 break;
557 case LCD_1152x768:
558 xres = 1152;
559 yres = 768;
560 break;
561 case LCD_1280x960:
562 xres = 1280;
563 yres = 960;
564 break;
565 case LCD_1280x768:
566 xres = 1280;
567 yres = 768;
568 break;
569 case LCD_1280x1024:
570 xres = 1280;
571 yres = 1024;
572 break;
573 case LCD_1400x1050:
574 xres = 1400;
575 yres = 1050;
576 break;
577 case LCD_1600x1200:
578 xres = 1600;
579 yres = 1200;
580 break;
581 /* case LCD_320x480: */ /* TW: FSTN */
582 /*
583 xres = 320;
584 yres = 480;
585 break;
586 */
587 default:
588 xres = 0;
589 yres = 0;
590 break;
591 }
592 if (XGIbios_mode[myindex].xres > xres)
593 return -1;
594 if (XGIbios_mode[myindex].yres > yres)
595 return -1;
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300596 if ((hw_info->ulExternalChip == 0x01) || /* LVDS */
597 (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */
Prashant P. Shahb654f872010-09-06 17:34:26 +0530598 switch (XGIbios_mode[myindex].xres) {
599 case 512:
600 if (XGIbios_mode[myindex].yres != 512)
601 return -1;
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300602 if (hw_info->ulCRT2LCDType == LCD_1024x600)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530603 return -1;
604 break;
605 case 640:
606 if ((XGIbios_mode[myindex].yres != 400)
607 && (XGIbios_mode[myindex].yres
608 != 480))
609 return -1;
610 break;
611 case 800:
612 if (XGIbios_mode[myindex].yres != 600)
613 return -1;
614 break;
615 case 1024:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800616 if ((XGIbios_mode[myindex].yres != 600) &&
617 (XGIbios_mode[myindex].yres != 768))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530618 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800619 if ((XGIbios_mode[myindex].yres == 600) &&
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300620 (hw_info->ulCRT2LCDType != LCD_1024x600))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530621 return -1;
622 break;
623 case 1152:
624 if ((XGIbios_mode[myindex].yres) != 768)
625 return -1;
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300626 if (hw_info->ulCRT2LCDType != LCD_1152x768)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530627 return -1;
628 break;
629 case 1280:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800630 if ((XGIbios_mode[myindex].yres != 768) &&
631 (XGIbios_mode[myindex].yres != 1024))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530632 return -1;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800633 if ((XGIbios_mode[myindex].yres == 768) &&
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300634 (hw_info->ulCRT2LCDType != LCD_1280x768))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530635 return -1;
636 break;
637 case 1400:
638 if (XGIbios_mode[myindex].yres != 1050)
639 return -1;
640 break;
641 case 1600:
642 if (XGIbios_mode[myindex].yres != 1200)
643 return -1;
644 break;
645 default:
646 return -1;
647 }
648 } else {
649 switch (XGIbios_mode[myindex].xres) {
650 case 512:
651 if (XGIbios_mode[myindex].yres != 512)
652 return -1;
653 break;
654 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800655 if ((XGIbios_mode[myindex].yres != 400) &&
656 (XGIbios_mode[myindex].yres != 480))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530657 return -1;
658 break;
659 case 800:
660 if (XGIbios_mode[myindex].yres != 600)
661 return -1;
662 break;
663 case 1024:
664 if (XGIbios_mode[myindex].yres != 768)
665 return -1;
666 break;
667 case 1280:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800668 if ((XGIbios_mode[myindex].yres != 960) &&
669 (XGIbios_mode[myindex].yres != 1024))
Prashant P. Shahb654f872010-09-06 17:34:26 +0530670 return -1;
671 if (XGIbios_mode[myindex].yres == 960) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +0300672 if (hw_info->ulCRT2LCDType ==
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800673 LCD_1400x1050)
Prashant P. Shahb654f872010-09-06 17:34:26 +0530674 return -1;
675 }
676 break;
677 case 1400:
678 if (XGIbios_mode[myindex].yres != 1050)
679 return -1;
680 break;
681 case 1600:
682 if (XGIbios_mode[myindex].yres != 1200)
683 return -1;
684 break;
685 default:
686 return -1;
687 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200688 }
689 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530690 case DISPTYPE_TV:
691 switch (XGIbios_mode[myindex].xres) {
692 case 512:
693 case 640:
694 case 800:
695 break;
696 case 720:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300697 if (xgifb_info->TV_type == TVMODE_NTSC) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530698 if (XGIbios_mode[myindex].yres != 480)
699 return -1;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300700 } else if (xgifb_info->TV_type == TVMODE_PAL) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530701 if (XGIbios_mode[myindex].yres != 576)
702 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200703 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530704 /* TW: LVDS/CHRONTEL does not support 720 */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300705 if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL ||
706 xgifb_info->hasVB == HASVB_CHRONTEL) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530707 return -1;
708 }
709 break;
710 case 1024:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300711 if (xgifb_info->TV_type == TVMODE_NTSC) {
Prashant P. Shahb654f872010-09-06 17:34:26 +0530712 if (XGIbios_mode[myindex].bpp == 32)
713 return -1;
714 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530715 break;
716 default:
717 return -1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200718 }
719 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530720 case DISPTYPE_CRT2:
721 if (XGIbios_mode[myindex].xres > 1280)
722 return -1;
723 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200724 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530725 return myindex;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200726
727}
728
729static void XGIfb_search_crt2type(const char *name)
730{
731 int i = 0;
732
Prashant P. Shahb654f872010-09-06 17:34:26 +0530733 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200734 return;
735
Prashant P. Shahb654f872010-09-06 17:34:26 +0530736 while (XGI_crt2type[i].type_no != -1) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200737 if (!strcmp(name, XGI_crt2type[i].name)) {
738 XGIfb_crt2type = XGI_crt2type[i].type_no;
739 XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
740 break;
741 }
742 i++;
743 }
Prashant P. Shahb654f872010-09-06 17:34:26 +0530744 if (XGIfb_crt2type < 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200745 printk(KERN_INFO "XGIfb: Invalid CRT2 type: %s\n", name);
746}
747
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300748static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
749 unsigned int rate)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200750{
751 u16 xres, yres;
752 int i = 0;
753
754 xres = XGIbios_mode[xgifb_mode_idx].xres;
755 yres = XGIbios_mode[xgifb_mode_idx].yres;
756
757 XGIfb_rate_idx = 0;
758 while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800759 if ((XGIfb_vrate[i].xres == xres) &&
760 (XGIfb_vrate[i].yres == yres)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200761 if (XGIfb_vrate[i].refresh == rate) {
762 XGIfb_rate_idx = XGIfb_vrate[i].idx;
763 break;
764 } else if (XGIfb_vrate[i].refresh > rate) {
765 if ((XGIfb_vrate[i].refresh - rate) <= 3) {
766 DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800767 rate, XGIfb_vrate[i].refresh);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200768 XGIfb_rate_idx = XGIfb_vrate[i].idx;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300769 xgifb_info->refresh_rate =
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800770 XGIfb_vrate[i].refresh;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530771 } else if (((rate - XGIfb_vrate[i - 1].refresh)
772 <= 2) && (XGIfb_vrate[i].idx
773 != 1)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200774 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800775 rate, XGIfb_vrate[i-1].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530776 XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300777 xgifb_info->refresh_rate =
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800778 XGIfb_vrate[i - 1].refresh;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200779 }
780 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530781 } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200782 DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800783 rate, XGIfb_vrate[i].refresh);
Prashant P. Shahb654f872010-09-06 17:34:26 +0530784 XGIfb_rate_idx = XGIfb_vrate[i].idx;
785 break;
786 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200787 }
788 i++;
789 }
790 if (XGIfb_rate_idx > 0) {
791 return XGIfb_rate_idx;
792 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800793 printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
794 rate, xres, yres);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200795 return 0;
796 }
797}
798
799static void XGIfb_search_tvstd(const char *name)
800{
801 int i = 0;
802
Prashant P. Shahb654f872010-09-06 17:34:26 +0530803 if (name == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200804 return;
805
806 while (XGI_tvtype[i].type_no != -1) {
807 if (!strcmp(name, XGI_tvtype[i].name)) {
808 XGIfb_tvmode = XGI_tvtype[i].type_no;
809 break;
810 }
811 i++;
812 }
813}
814
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200815/* ----------- FBDev related routines for all series ----------- */
816
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300817static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info,
818 struct fb_var_screeninfo *var)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200819{
Prashant P. Shahb654f872010-09-06 17:34:26 +0530820 switch (var->bits_per_pixel) {
821 case 8:
822 var->red.offset = var->green.offset = var->blue.offset = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200823 var->red.length = var->green.length = var->blue.length = 6;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300824 xgifb_info->video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200825 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530826 case 16:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200827 var->red.offset = 11;
828 var->red.length = 5;
829 var->green.offset = 5;
830 var->green.length = 6;
831 var->blue.offset = 0;
832 var->blue.length = 5;
833 var->transp.offset = 0;
834 var->transp.length = 0;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300835 xgifb_info->video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200836 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +0530837 case 32:
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200838 var->red.offset = 16;
839 var->red.length = 8;
840 var->green.offset = 8;
841 var->green.length = 8;
842 var->blue.offset = 0;
843 var->blue.length = 8;
844 var->transp.offset = 24;
845 var->transp.length = 8;
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300846 xgifb_info->video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +0200847 break;
848 }
849}
850
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300851/* --------------------- SetMode routines ------------------------- */
852
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300853static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300854{
855 u8 cr30 = 0, cr31 = 0;
856
857 cr31 = xgifb_reg_get(XGICR, 0x31);
858 cr31 &= ~0x60;
859
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300860 switch (xgifb_info->disp_state & DISPTYPE_DISP2) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300861 case DISPTYPE_CRT2:
862 cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
863 cr31 |= XGI_DRIVER_MODE;
864 break;
865 case DISPTYPE_LCD:
866 cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
867 cr31 |= XGI_DRIVER_MODE;
868 break;
869 case DISPTYPE_TV:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300870 if (xgifb_info->TV_type == TVMODE_HIVISION)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300871 cr30 = (XGI_VB_OUTPUT_HIVISION
872 | XGI_SIMULTANEOUS_VIEW_ENABLE);
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300873 else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300874 cr30 = (XGI_VB_OUTPUT_SVIDEO
875 | XGI_SIMULTANEOUS_VIEW_ENABLE);
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300876 else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300877 cr30 = (XGI_VB_OUTPUT_COMPOSITE
878 | XGI_SIMULTANEOUS_VIEW_ENABLE);
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300879 else if (xgifb_info->TV_plug == TVPLUG_SCART)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300880 cr30 = (XGI_VB_OUTPUT_SCART
881 | XGI_SIMULTANEOUS_VIEW_ENABLE);
882 cr31 |= XGI_DRIVER_MODE;
883
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300884 if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300885 cr31 |= 0x01;
886 else
887 cr31 &= ~0x01;
888 break;
889 default: /* disable CRT2 */
890 cr30 = 0x00;
891 cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
892 }
893
894 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
895 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
896 xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
897}
898
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300899static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300900{
901 u8 reg;
902 unsigned char doit = 1;
903 /*
904 xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
905 xgifb_reg_set(XGICR, 0x13, 0x00);
906 xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
907 *test*
908 */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300909 if (xgifb_info->video_bpp == 8) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800910 /* TW: We can't switch off CRT1 on LVDS/Chrontel
911 * in 8bpp Modes */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300912 if ((xgifb_info->hasVB == HASVB_LVDS) ||
913 (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300914 doit = 0;
915 }
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800916 /* TW: We can't switch off CRT1 on 301B-DH
917 * in 8bpp Modes if using LCD */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300918 if (xgifb_info->disp_state & DISPTYPE_LCD)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300919 doit = 0;
920 }
921
922 /* TW: We can't switch off CRT1 if bridge is in slave mode */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300923 if (xgifb_info->hasVB != HASVB_NONE) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300924 reg = xgifb_reg_get(XGIPART1, 0x00);
925
926 if ((reg & 0x50) == 0x10)
927 doit = 0;
928
929 } else {
930 XGIfb_crt1off = 0;
931 }
932
933 reg = xgifb_reg_get(XGICR, 0x17);
934 if ((XGIfb_crt1off) && (doit))
935 reg &= ~0x80;
936 else
937 reg |= 0x80;
938 xgifb_reg_set(XGICR, 0x17, reg);
939
940 xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
941
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300942 if ((xgifb_info->disp_state & DISPTYPE_TV) && (xgifb_info->hasVB
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300943 == HASVB_301)) {
944
945 reg = xgifb_reg_get(XGIPART4, 0x01);
946
947 if (reg < 0xB0) { /* Set filter for XGI301 */
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300948 switch (xgifb_info->video_width) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300949 case 320:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300950 filter_tb = (xgifb_info->TV_type ==
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800951 TVMODE_NTSC) ? 4 : 12;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300952 break;
953 case 640:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300954 filter_tb = (xgifb_info->TV_type ==
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800955 TVMODE_NTSC) ? 5 : 13;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300956 break;
957 case 720:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300958 filter_tb = (xgifb_info->TV_type ==
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800959 TVMODE_NTSC) ? 6 : 14;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300960 break;
961 case 800:
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300962 filter_tb = (xgifb_info->TV_type ==
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800963 TVMODE_NTSC) ? 7 : 15;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300964 break;
965 default:
966 filter = -1;
967 break;
968 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300969 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
970
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300971 if (xgifb_info->TV_type == TVMODE_NTSC) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300972
973 xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
974
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300975 if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300976
977 xgifb_reg_and(XGIPART2, 0x30, 0xdf);
978
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300979 } else if (xgifb_info->TV_plug
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300980 == TVPLUG_COMPOSITE) {
981
982 xgifb_reg_or(XGIPART2, 0x30, 0x20);
983
Aaro Koskinenfd26d422011-10-11 21:47:19 +0300984 switch (xgifb_info->video_width) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300985 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +0800986 xgifb_reg_set(XGIPART2,
987 0x35,
988 0xEB);
989 xgifb_reg_set(XGIPART2,
990 0x36,
991 0x04);
992 xgifb_reg_set(XGIPART2,
993 0x37,
994 0x25);
995 xgifb_reg_set(XGIPART2,
996 0x38,
997 0x18);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +0300998 break;
999 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001000 xgifb_reg_set(XGIPART2,
1001 0x35,
1002 0xEE);
1003 xgifb_reg_set(XGIPART2,
1004 0x36,
1005 0x0C);
1006 xgifb_reg_set(XGIPART2,
1007 0x37,
1008 0x22);
1009 xgifb_reg_set(XGIPART2,
1010 0x38,
1011 0x08);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001012 break;
1013 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001014 xgifb_reg_set(XGIPART2,
1015 0x35,
1016 0xEB);
1017 xgifb_reg_set(XGIPART2,
1018 0x36,
1019 0x15);
1020 xgifb_reg_set(XGIPART2,
1021 0x37,
1022 0x25);
1023 xgifb_reg_set(XGIPART2,
1024 0x38,
1025 0xF6);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001026 break;
1027 }
1028 }
1029
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001030 } else if (xgifb_info->TV_type == TVMODE_PAL) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001031
1032 xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
1033
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001034 if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001035
1036 xgifb_reg_and(XGIPART2, 0x30, 0xDF);
1037
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001038 } else if (xgifb_info->TV_plug
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001039 == TVPLUG_COMPOSITE) {
1040
1041 xgifb_reg_or(XGIPART2, 0x30, 0x20);
1042
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001043 switch (xgifb_info->video_width) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001044 case 640:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001045 xgifb_reg_set(XGIPART2,
1046 0x35,
1047 0xF1);
1048 xgifb_reg_set(XGIPART2,
1049 0x36,
1050 0xF7);
1051 xgifb_reg_set(XGIPART2,
1052 0x37,
1053 0x1F);
1054 xgifb_reg_set(XGIPART2,
1055 0x38,
1056 0x32);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001057 break;
1058 case 720:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001059 xgifb_reg_set(XGIPART2,
1060 0x35,
1061 0xF3);
1062 xgifb_reg_set(XGIPART2,
1063 0x36,
1064 0x00);
1065 xgifb_reg_set(XGIPART2,
1066 0x37,
1067 0x1D);
1068 xgifb_reg_set(XGIPART2,
1069 0x38,
1070 0x20);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001071 break;
1072 case 800:
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001073 xgifb_reg_set(XGIPART2,
1074 0x35,
1075 0xFC);
1076 xgifb_reg_set(XGIPART2,
1077 0x36,
1078 0xFB);
1079 xgifb_reg_set(XGIPART2,
1080 0x37,
1081 0x14);
1082 xgifb_reg_set(XGIPART2,
1083 0x38,
1084 0x2A);
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001085 break;
1086 }
1087 }
1088 }
1089
1090 if ((filter >= 0) && (filter <= 7)) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001091 DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
1092 filter_tb, filter,
1093 XGI_TV_filter[filter_tb].
1094 filter[filter][0],
1095 XGI_TV_filter[filter_tb].
1096 filter[filter][1],
1097 XGI_TV_filter[filter_tb].
1098 filter[filter][2],
1099 XGI_TV_filter[filter_tb].
1100 filter[filter][3]
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001101 );
1102 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001103 XGIPART2,
1104 0x35,
1105 (XGI_TV_filter[filter_tb].
1106 filter[filter][0]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001107 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001108 XGIPART2,
1109 0x36,
1110 (XGI_TV_filter[filter_tb].
1111 filter[filter][1]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001112 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001113 XGIPART2,
1114 0x37,
1115 (XGI_TV_filter[filter_tb].
1116 filter[filter][2]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001117 xgifb_reg_set(
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001118 XGIPART2,
1119 0x38,
1120 (XGI_TV_filter[filter_tb].
1121 filter[filter][3]));
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001122 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001123 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001124 }
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001125}
1126
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001127static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301128 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001129{
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001130 struct xgifb_video_info *xgifb_info = info->par;
1131 struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301132 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1133 + var->hsync_len;
1134 unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
1135 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001136#if defined(__powerpc__)
1137 u8 sr_data, cr_data;
1138#endif
1139 unsigned int drate = 0, hrate = 0;
1140 int found_mode = 0;
1141 int old_mode;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301142 /* unsigned char reg, reg1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001143
1144 DEBUGPRN("Inside do_set_var");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301145 /* 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 +02001146
Prashant P. Shahb654f872010-09-06 17:34:26 +05301147 info->var.xres_virtual = var->xres_virtual;
1148 info->var.yres_virtual = var->yres_virtual;
1149 info->var.bits_per_pixel = var->bits_per_pixel;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001150
1151 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
1152 vtotal <<= 1;
1153 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
1154 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301155 else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1156 /* vtotal <<= 1; */
1157 /* var->yres <<= 1; */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001158 }
1159
Prashant P. Shahb654f872010-09-06 17:34:26 +05301160 if (!htotal || !vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001161 DPRINTK("XGIfb: Invalid 'var' information\n");
1162 return -EINVAL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301163 } printk(KERN_DEBUG "XGIfb: var->pixclock=%d, htotal=%d, vtotal=%d\n",
1164 var->pixclock, htotal, vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001165
Prashant P. Shahb654f872010-09-06 17:34:26 +05301166 if (var->pixclock && htotal && vtotal) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001167 drate = 1000000000 / var->pixclock;
1168 hrate = (drate * 1000) / htotal;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001169 xgifb_info->refresh_rate = (unsigned int) (hrate * 2
Prashant P. Shahb654f872010-09-06 17:34:26 +05301170 / vtotal);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001171 } else {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001172 xgifb_info->refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001173 }
1174
1175 printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001176 var->xres,
1177 var->yres,
1178 var->bits_per_pixel,
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001179 xgifb_info->refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001180
1181 old_mode = xgifb_mode_idx;
1182 xgifb_mode_idx = 0;
1183
Prashant P. Shahb654f872010-09-06 17:34:26 +05301184 while ((XGIbios_mode[xgifb_mode_idx].mode_no != 0)
1185 && (XGIbios_mode[xgifb_mode_idx].xres <= var->xres)) {
1186 if ((XGIbios_mode[xgifb_mode_idx].xres == var->xres)
1187 && (XGIbios_mode[xgifb_mode_idx].yres
1188 == var->yres)
1189 && (XGIbios_mode[xgifb_mode_idx].bpp
1190 == var->bits_per_pixel)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001191 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
1192 found_mode = 1;
1193 break;
1194 }
1195 xgifb_mode_idx++;
1196 }
1197
Prashant P. Shahb654f872010-09-06 17:34:26 +05301198 if (found_mode)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001199 xgifb_mode_idx = XGIfb_validate_mode(xgifb_info,
1200 xgifb_mode_idx);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001201 else
1202 xgifb_mode_idx = -1;
1203
Prashant P. Shahb654f872010-09-06 17:34:26 +05301204 if (xgifb_mode_idx < 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001205 printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
1206 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001207 xgifb_mode_idx = old_mode;
1208 return -EINVAL;
1209 }
1210
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001211 if (XGIfb_search_refresh_rate(xgifb_info,
1212 xgifb_info->refresh_rate) == 0) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001213 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001214 xgifb_info->refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001215 }
1216
Prashant P. Shahb654f872010-09-06 17:34:26 +05301217 if (isactive) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001218
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001219 XGIfb_pre_setmode(xgifb_info);
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03001220 if (XGISetModeNew(hw_info, XGIfb_mode_no) == 0) {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001221 printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
1222 XGIfb_mode_no);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001223 return -EINVAL;
1224 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301225 info->fix.line_length = ((info->var.xres_virtual
1226 * info->var.bits_per_pixel) >> 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001227
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001228 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001229
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001230 xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001231 xgifb_reg_set(XGISR,
1232 0x0E,
1233 (info->fix.line_length & 0xff00) >> 8);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001234
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001235 XGIfb_post_setmode(xgifb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001236
Prashant P. Shahb654f872010-09-06 17:34:26 +05301237 DPRINTK("XGIfb: Set new mode: %dx%dx%d-%d\n",
1238 XGIbios_mode[xgifb_mode_idx].xres,
1239 XGIbios_mode[xgifb_mode_idx].yres,
1240 XGIbios_mode[xgifb_mode_idx].bpp,
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001241 xgifb_info->refresh_rate);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001242
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001243 xgifb_info->video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
1244 xgifb_info->video_vwidth = info->var.xres_virtual;
1245 xgifb_info->video_width = XGIbios_mode[xgifb_mode_idx].xres;
1246 xgifb_info->video_vheight = info->var.yres_virtual;
1247 xgifb_info->video_height = XGIbios_mode[xgifb_mode_idx].yres;
1248 xgifb_info->org_x = xgifb_info->org_y = 0;
1249 xgifb_info->video_linelength = info->var.xres_virtual
1250 * (xgifb_info->video_bpp >> 3);
1251 switch (xgifb_info->video_bpp) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301252 case 8:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001253 xgifb_info->DstColor = 0x0000;
1254 xgifb_info->XGI310_AccelDepth = 0x00000000;
1255 xgifb_info->video_cmap_len = 256;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001256#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001257 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001258 xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001259#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301260 break;
1261 case 16:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001262 xgifb_info->DstColor = 0x8000;
1263 xgifb_info->XGI310_AccelDepth = 0x00010000;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001264#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001265 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001266 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001267#endif
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001268 xgifb_info->video_cmap_len = 16;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301269 break;
1270 case 32:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001271 xgifb_info->DstColor = 0xC000;
1272 xgifb_info->XGI310_AccelDepth = 0x00020000;
1273 xgifb_info->video_cmap_len = 16;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001274#if defined(__powerpc__)
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001275 cr_data = xgifb_reg_get(XGICR, 0x4D);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001276 xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001277#endif
Prashant P. Shahb654f872010-09-06 17:34:26 +05301278 break;
1279 default:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001280 xgifb_info->video_cmap_len = 16;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001281 printk(KERN_ERR "XGIfb: Unsupported depth %d",
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001282 xgifb_info->video_bpp);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301283 break;
1284 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001285 }
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001286 XGIfb_bpp_to_var(xgifb_info, var); /*update ARGB info*/
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001287 DEBUGPRN("End of do_set_var");
1288
1289 dumpVGAReg();
1290 return 0;
1291}
1292
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001293static int XGIfb_pan_var(struct xgifb_video_info *xgifb_info,
1294 struct fb_var_screeninfo *var)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001295{
1296 unsigned int base;
1297
Prashant P. Shahb654f872010-09-06 17:34:26 +05301298 /* printk("Inside pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001299
1300 if (var->xoffset > (var->xres_virtual - var->xres)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301301 /* printk("Pan: xo: %d xv %d xr %d\n",
1302 var->xoffset, var->xres_virtual, var->xres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001303 return -EINVAL;
1304 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301305 if (var->yoffset > (var->yres_virtual - var->yres)) {
1306 /* printk("Pan: yo: %d yv %d yr %d\n",
1307 var->yoffset, var->yres_virtual, var->yres); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001308 return -EINVAL;
1309 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05301310 base = var->yoffset * var->xres_virtual + var->xoffset;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001311
Prashant P. Shahb654f872010-09-06 17:34:26 +05301312 /* calculate base bpp dep. */
1313 switch (var->bits_per_pixel) {
1314 case 16:
1315 base >>= 1;
1316 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001317 case 32:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301318 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001319 case 8:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301320 default:
1321 base >>= 2;
1322 break;
1323 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001324
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001325 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001326
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001327 xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
1328 xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
1329 xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
1330 xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
Aaro Koskinen65283d42011-04-18 22:14:02 +03001331 xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001332
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001333 if (xgifb_info->disp_state & DISPTYPE_DISP2) {
Aaro Koskinene67f4d42011-04-18 22:14:00 +03001334 xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001335 xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
1336 xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
1337 xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001338 xgifb_reg_and_or(XGIPART1,
1339 0x02,
1340 0x7F,
1341 ((base >> 24) & 0x01) << 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301342 }
1343 /* printk("End of pan_var"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001344 return 0;
1345}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001346
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001347static int XGIfb_open(struct fb_info *info, int user)
1348{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301349 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001350}
1351
1352static int XGIfb_release(struct fb_info *info, int user)
1353{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301354 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001355}
1356
1357static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
1358{
1359 int rc = 16;
1360
Prashant P. Shahb654f872010-09-06 17:34:26 +05301361 switch (var->bits_per_pixel) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001362 case 8:
1363 rc = 256;
1364 break;
1365 case 16:
1366 rc = 16;
1367 break;
1368 case 32:
1369 rc = 16;
1370 break;
1371 }
1372 return rc;
1373}
1374
Prashant P. Shahb654f872010-09-06 17:34:26 +05301375static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1376 unsigned blue, unsigned transp, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001377{
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001378 struct xgifb_video_info *xgifb_info = info->par;
1379
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001380 if (regno >= XGIfb_get_cmap_len(&info->var))
1381 return 1;
1382
1383 switch (info->var.bits_per_pixel) {
1384 case 8:
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001385 outb(regno, XGIDACA);
1386 outb((red >> 10), XGIDACD);
1387 outb((green >> 10), XGIDACD);
1388 outb((blue >> 10), XGIDACD);
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001389 if (xgifb_info->disp_state & DISPTYPE_DISP2) {
Aaro Koskinene3d5ceb2011-04-18 22:13:57 +03001390 outb(regno, XGIDAC2A);
1391 outb((red >> 8), XGIDAC2D);
1392 outb((green >> 8), XGIDAC2D);
1393 outb((blue >> 8), XGIDAC2D);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001394 }
1395 break;
1396 case 16:
Prashant P. Shahb654f872010-09-06 17:34:26 +05301397 ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
1398 | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
1399 >> 11);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001400 break;
1401 case 32:
1402 red >>= 8;
1403 green >>= 8;
1404 blue >>= 8;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301405 ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
1406 << 8) | (blue);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001407 break;
1408 }
1409 return 0;
1410}
1411
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001412/* ----------- FBDev related routines for all series ---------- */
1413
1414static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
1415 struct fb_info *info)
1416{
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001417 struct xgifb_video_info *xgifb_info = info->par;
1418
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001419 DEBUGPRN("inside get_fix");
1420 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
1421
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001422 fix->smem_start = xgifb_info->video_base;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001423
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001424 fix->smem_len = xgifb_info->video_size;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001425
Aaro Koskinende351ba2011-08-19 22:40:27 +03001426 fix->type = FB_TYPE_PACKED_PIXELS;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001427 fix->type_aux = 0;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001428 if (xgifb_info->video_bpp == 8)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001429 fix->visual = FB_VISUAL_PSEUDOCOLOR;
1430 else
1431 fix->visual = FB_VISUAL_DIRECTCOLOR;
1432 fix->xpanstep = 0;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001433 if (XGIfb_ypan)
1434 fix->ypanstep = 1;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001435 fix->ywrapstep = 0;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001436 fix->line_length = xgifb_info->video_linelength;
1437 fix->mmio_start = xgifb_info->mmio_base;
1438 fix->mmio_len = xgifb_info->mmio_size;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001439 fix->accel = FB_ACCEL_XGI_XABRE;
1440
1441 DEBUGPRN("end of get_fix");
1442 return 0;
1443}
1444
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001445static int XGIfb_set_par(struct fb_info *info)
1446{
1447 int err;
1448
Prashant P. Shahb654f872010-09-06 17:34:26 +05301449 /* printk("XGIfb: inside set_par\n"); */
1450 err = XGIfb_do_set_var(&info->var, 1, info);
1451 if (err)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001452 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001453 XGIfb_get_fix(&info->fix, -1, info);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301454 /* printk("XGIfb: end of set_par\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001455 return 0;
1456}
1457
Prashant P. Shahb654f872010-09-06 17:34:26 +05301458static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001459{
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001460 struct xgifb_video_info *xgifb_info = info->par;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301461 unsigned int htotal = var->left_margin + var->xres + var->right_margin
1462 + var->hsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001463 unsigned int vtotal = 0;
1464 unsigned int drate = 0, hrate = 0;
1465 int found_mode = 0;
1466 int refresh_rate, search_idx;
1467
1468 DEBUGPRN("Inside check_var");
1469
Prashant P. Shahb654f872010-09-06 17:34:26 +05301470 if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
1471 vtotal = var->upper_margin + var->yres + var->lower_margin
1472 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001473 vtotal <<= 1;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301474 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
1475 vtotal = var->upper_margin + var->yres + var->lower_margin
1476 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001477 vtotal <<= 2;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301478 } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
1479 vtotal = var->upper_margin + (var->yres / 2)
1480 + var->lower_margin + var->vsync_len;
1481 } else
1482 vtotal = var->upper_margin + var->yres + var->lower_margin
1483 + var->vsync_len;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001484
Prashant P. Shahb654f872010-09-06 17:34:26 +05301485 if (!(htotal) || !(vtotal))
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001486 XGIFAIL("XGIfb: no valid timing data");
Prashant P. Shahb654f872010-09-06 17:34:26 +05301487
1488 if (var->pixclock && htotal && vtotal) {
1489 drate = 1000000000 / var->pixclock;
1490 hrate = (drate * 1000) / htotal;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001491 xgifb_info->refresh_rate =
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001492 (unsigned int) (hrate * 2 / vtotal);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301493 printk(KERN_DEBUG
1494 "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
1495 "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
1496 __func__, var->pixclock, htotal, vtotal,
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001497 __func__, drate, hrate, xgifb_info->refresh_rate);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301498 } else {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001499 xgifb_info->refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001500 }
1501
Prashant P. Shahb654f872010-09-06 17:34:26 +05301502 /*
1503 if ((var->pixclock) && (htotal)) {
1504 drate = 1E12 / var->pixclock;
1505 hrate = drate / htotal;
1506 refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
1507 } else {
1508 refresh_rate = 60;
1509 }
1510 */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001511 /* TW: Calculation wrong for 1024x600 - force it to 60Hz */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301512 if ((var->xres == 1024) && (var->yres == 600))
1513 refresh_rate = 60;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001514
1515 search_idx = 0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301516 while ((XGIbios_mode[search_idx].mode_no != 0) &&
1517 (XGIbios_mode[search_idx].xres <= var->xres)) {
1518 if ((XGIbios_mode[search_idx].xres == var->xres) &&
1519 (XGIbios_mode[search_idx].yres == var->yres) &&
1520 (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001521 if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301522 found_mode = 1;
1523 break;
1524 }
1525 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001526 search_idx++;
1527 }
1528
Prashant P. Shahb654f872010-09-06 17:34:26 +05301529 if (!found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001530
1531 printk(KERN_ERR "XGIfb: %dx%dx%d is no valid mode\n",
1532 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301533 search_idx = 0;
1534 while (XGIbios_mode[search_idx].mode_no != 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301535 if ((var->xres <= XGIbios_mode[search_idx].xres) &&
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001536 (var->yres <= XGIbios_mode[search_idx].yres) &&
1537 (var->bits_per_pixel ==
1538 XGIbios_mode[search_idx].bpp)) {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001539 if (XGIfb_validate_mode(xgifb_info,
1540 search_idx) > 0) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301541 found_mode = 1;
1542 break;
1543 }
1544 }
1545 search_idx++;
1546 }
1547 if (found_mode) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001548 var->xres = XGIbios_mode[search_idx].xres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301549 var->yres = XGIbios_mode[search_idx].yres;
1550 printk(KERN_DEBUG "XGIfb: Adapted to mode %dx%dx%d\n",
1551 var->xres, var->yres, var->bits_per_pixel);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001552
1553 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301554 printk(KERN_ERR "XGIfb: Failed to find similar mode to %dx%dx%d\n",
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001555 var->xres, var->yres, var->bits_per_pixel);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301556 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001557 }
1558 }
1559
1560 /* TW: TODO: Check the refresh rate */
1561
1562 /* Adapt RGB settings */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001563 XGIfb_bpp_to_var(xgifb_info, var);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001564
1565 /* Sanity check for offsets */
1566 if (var->xoffset < 0)
1567 var->xoffset = 0;
1568 if (var->yoffset < 0)
1569 var->yoffset = 0;
1570
Prashant P. Shahb654f872010-09-06 17:34:26 +05301571 if (!XGIfb_ypan) {
1572 if (var->xres != var->xres_virtual)
1573 var->xres_virtual = var->xres;
1574 if (var->yres != var->yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001575 var->yres_virtual = var->yres;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301576 } /* else { */
1577 /* TW: Now patch yres_virtual if we use panning */
1578 /* May I do this? */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001579 /* var->yres_virtual = xgifb_info->heapstart /
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001580 (var->xres * (var->bits_per_pixel >> 3)); */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301581 /* if (var->yres_virtual <= var->yres) { */
1582 /* TW: Paranoia check */
1583 /* var->yres_virtual = var->yres; */
1584 /* } */
1585 /* } */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001586
1587 /* Truncate offsets to maximum if too high */
1588 if (var->xoffset > var->xres_virtual - var->xres)
1589 var->xoffset = var->xres_virtual - var->xres - 1;
1590
1591 if (var->yoffset > var->yres_virtual - var->yres)
1592 var->yoffset = var->yres_virtual - var->yres - 1;
1593
1594 /* Set everything else to 0 */
1595 var->red.msb_right =
Prashant P. Shahb654f872010-09-06 17:34:26 +05301596 var->green.msb_right =
1597 var->blue.msb_right =
1598 var->transp.offset = var->transp.length = var->transp.msb_right = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001599
1600 DEBUGPRN("end of check_var");
1601 return 0;
1602}
1603
Prashant P. Shahb654f872010-09-06 17:34:26 +05301604static int XGIfb_pan_display(struct fb_var_screeninfo *var,
1605 struct fb_info *info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001606{
1607 int err;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001608 struct xgifb_video_info *xgifb_info = info->par;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001609
Prashant P. Shahb654f872010-09-06 17:34:26 +05301610 /* printk("\nInside pan_display:\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001611
1612 if (var->xoffset > (var->xres_virtual - var->xres))
1613 return -EINVAL;
1614 if (var->yoffset > (var->yres_virtual - var->yres))
1615 return -EINVAL;
1616
1617 if (var->vmode & FB_VMODE_YWRAP) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301618 if (var->yoffset < 0 || var->yoffset >= info->var.yres_virtual
1619 || var->xoffset)
1620 return -EINVAL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001621 } else {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301622 if (var->xoffset + info->var.xres > info->var.xres_virtual
1623 || var->yoffset + info->var.yres
1624 > info->var.yres_virtual)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001625 return -EINVAL;
1626 }
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001627 err = XGIfb_pan_var(xgifb_info, var);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301628 if (err < 0)
1629 return err;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001630
1631 info->var.xoffset = var->xoffset;
1632 info->var.yoffset = var->yoffset;
1633 if (var->vmode & FB_VMODE_YWRAP)
1634 info->var.vmode |= FB_VMODE_YWRAP;
1635 else
1636 info->var.vmode &= ~FB_VMODE_YWRAP;
1637
Prashant P. Shahb654f872010-09-06 17:34:26 +05301638 /* printk("End of pan_display\n"); */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001639 return 0;
1640}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001641
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001642static int XGIfb_blank(int blank, struct fb_info *info)
1643{
1644 u8 reg;
1645
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001646 reg = xgifb_reg_get(XGICR, 0x17);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001647
Prashant P. Shahb654f872010-09-06 17:34:26 +05301648 if (blank > 0)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001649 reg &= 0x7f;
1650 else
1651 reg |= 0x80;
1652
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001653 xgifb_reg_set(XGICR, 0x17, reg);
1654 xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
1655 xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301656 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001657}
1658
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001659static struct fb_ops XGIfb_ops = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301660 .owner = THIS_MODULE,
1661 .fb_open = XGIfb_open,
1662 .fb_release = XGIfb_release,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001663 .fb_check_var = XGIfb_check_var,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301664 .fb_set_par = XGIfb_set_par,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001665 .fb_setcolreg = XGIfb_setcolreg,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301666 .fb_pan_display = XGIfb_pan_display,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301667 .fb_blank = XGIfb_blank,
Aaro Koskinen1b402962011-02-28 20:59:22 +02001668 .fb_fillrect = cfb_fillrect,
Aaro Koskinen85c3c562011-02-28 20:59:21 +02001669 .fb_copyarea = cfb_copyarea,
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001670 .fb_imageblit = cfb_imageblit,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301671 /* .fb_mmap = XGIfb_mmap, */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001672};
1673
1674/* ---------------- Chip generation dependent routines ---------------- */
1675
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001676/* for XGI 315/550/650/740/330 */
1677
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001678static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001679{
1680
Prashant P. Shahb654f872010-09-06 17:34:26 +05301681 u8 ChannelNum, tmp;
1682 u8 reg = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001683
1684 /* xorg driver sets 32MB * 1 channel */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001685 if (xgifb_info->chip == XG27)
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03001686 xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001687
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001688 reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301689 switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
1690 case XGI_DRAM_SIZE_1MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001691 xgifb_info->video_size = 0x100000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301692 break;
1693 case XGI_DRAM_SIZE_2MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001694 xgifb_info->video_size = 0x200000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301695 break;
1696 case XGI_DRAM_SIZE_4MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001697 xgifb_info->video_size = 0x400000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301698 break;
1699 case XGI_DRAM_SIZE_8MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001700 xgifb_info->video_size = 0x800000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301701 break;
1702 case XGI_DRAM_SIZE_16MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001703 xgifb_info->video_size = 0x1000000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301704 break;
1705 case XGI_DRAM_SIZE_32MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001706 xgifb_info->video_size = 0x2000000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301707 break;
1708 case XGI_DRAM_SIZE_64MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001709 xgifb_info->video_size = 0x4000000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301710 break;
1711 case XGI_DRAM_SIZE_128MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001712 xgifb_info->video_size = 0x8000000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301713 break;
1714 case XGI_DRAM_SIZE_256MB:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001715 xgifb_info->video_size = 0x10000000;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301716 break;
1717 default:
1718 return -1;
1719 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001720
Prashant P. Shahb654f872010-09-06 17:34:26 +05301721 tmp = (reg & 0x0c) >> 2;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001722 switch (xgifb_info->chip) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301723 case XG20:
1724 case XG21:
1725 case XG27:
1726 ChannelNum = 1;
1727 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001728
Prashant P. Shahb654f872010-09-06 17:34:26 +05301729 case XG42:
1730 if (reg & 0x04)
1731 ChannelNum = 2;
1732 else
1733 ChannelNum = 1;
1734 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001735
Prashant P. Shahb654f872010-09-06 17:34:26 +05301736 case XG45:
1737 if (tmp == 1)
1738 ChannelNum = 2;
1739 else if (tmp == 2)
1740 ChannelNum = 3;
1741 else if (tmp == 3)
1742 ChannelNum = 4;
1743 else
1744 ChannelNum = 1;
1745 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001746
Prashant P. Shahb654f872010-09-06 17:34:26 +05301747 case XG40:
1748 default:
1749 if (tmp == 2)
1750 ChannelNum = 2;
1751 else if (tmp == 3)
1752 ChannelNum = 3;
1753 else
1754 ChannelNum = 1;
1755 break;
1756 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001757
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001758 xgifb_info->video_size = xgifb_info->video_size * ChannelNum;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301759 /* PLiad fixed for benchmarking and fb set */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001760 /* xgifb_info->video_size = 0x200000; */ /* 1024x768x16 */
1761 /* xgifb_info->video_size = 0x1000000; */ /* benchmark */
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001762
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001763 printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
1764 reg,
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001765 xgifb_info->video_size, ChannelNum);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301766 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001767
1768}
1769
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001770static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001771{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301772 u8 cr32, temp = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001773
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001774 xgifb_info->TV_plug = xgifb_info->TV_type = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001775
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001776 switch (xgifb_info->hasVB) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301777 case HASVB_LVDS_CHRONTEL:
1778 case HASVB_CHRONTEL:
1779 break;
1780 case HASVB_301:
1781 case HASVB_302:
1782 /* XGI_Sense30x(); */ /* Yi-Lin TV Sense? */
1783 break;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001784 }
1785
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001786 cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001787
1788 if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
1789 XGIfb_crt1off = 0;
1790 else {
1791 if (cr32 & 0x5F)
1792 XGIfb_crt1off = 1;
1793 else
1794 XGIfb_crt1off = 0;
1795 }
1796
1797 if (XGIfb_crt2type != -1)
1798 /* TW: Override with option */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001799 xgifb_info->disp_state = XGIfb_crt2type;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001800 else if (cr32 & XGI_VB_TV)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001801 xgifb_info->disp_state = DISPTYPE_TV;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001802 else if (cr32 & XGI_VB_LCD)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001803 xgifb_info->disp_state = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001804 else if (cr32 & XGI_VB_CRT2)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001805 xgifb_info->disp_state = DISPTYPE_CRT2;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001806 else
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001807 xgifb_info->disp_state = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001808
Prashant P. Shahb654f872010-09-06 17:34:26 +05301809 if (XGIfb_tvplug != -1)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001810 /* PR/TW: Override with option */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001811 xgifb_info->TV_plug = XGIfb_tvplug;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001812 else if (cr32 & XGI_VB_HIVISION) {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001813 xgifb_info->TV_type = TVMODE_HIVISION;
1814 xgifb_info->TV_plug = TVPLUG_SVIDEO;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301815 } else if (cr32 & XGI_VB_SVIDEO)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001816 xgifb_info->TV_plug = TVPLUG_SVIDEO;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001817 else if (cr32 & XGI_VB_COMPOSITE)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001818 xgifb_info->TV_plug = TVPLUG_COMPOSITE;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001819 else if (cr32 & XGI_VB_SCART)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001820 xgifb_info->TV_plug = TVPLUG_SCART;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001821
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001822 if (xgifb_info->TV_type == 0) {
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001823 temp = xgifb_reg_get(XGICR, 0x38);
Aaro Koskinenebe78462011-03-13 12:26:08 +02001824 if (temp & 0x10)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001825 xgifb_info->TV_type = TVMODE_PAL;
Aaro Koskinenebe78462011-03-13 12:26:08 +02001826 else
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001827 xgifb_info->TV_type = TVMODE_NTSC;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001828 }
1829
1830 /* TW: Copy forceCRT1 option to CRT1off if option is given */
Prashant P. Shahb654f872010-09-06 17:34:26 +05301831 if (XGIfb_forcecrt1 != -1) {
1832 if (XGIfb_forcecrt1)
1833 XGIfb_crt1off = 0;
1834 else
1835 XGIfb_crt1off = 1;
1836 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001837}
1838
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001839static int XGIfb_has_VB(struct xgifb_video_info *xgifb_info)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001840{
1841 u8 vb_chipid;
1842
Aaro Koskinen7e119b72011-04-18 22:13:58 +03001843 vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001844 switch (vb_chipid) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301845 case 0x01:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001846 xgifb_info->hasVB = HASVB_301;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001847 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301848 case 0x02:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001849 xgifb_info->hasVB = HASVB_302;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001850 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301851 default:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001852 xgifb_info->hasVB = HASVB_NONE;
Bill Pembertondda08c52010-06-17 13:10:42 -04001853 return 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001854 }
Bill Pembertondda08c52010-06-17 13:10:42 -04001855 return 1;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001856}
1857
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001858static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001859{
1860 u8 reg;
1861
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001862 if (!XGIfb_has_VB(xgifb_info)) {
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001863 reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
1864 switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
1865 case XGI310_EXTERNAL_CHIP_LVDS:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001866 xgifb_info->hasVB = HASVB_LVDS;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001867 break;
1868 case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001869 xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
Aaro Koskinenc4fa7df2011-04-18 22:14:05 +03001870 break;
1871 default:
1872 break;
1873 }
1874 }
1875}
1876
Aaro Koskinend27c6bc2011-08-29 23:14:23 +03001877static int __init xgifb_optval(char *fullopt, int validx)
1878{
1879 unsigned long lres;
1880
1881 if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) {
1882 pr_err("xgifb: invalid value for option: %s\n", fullopt);
1883 return 0;
1884 }
1885 return lres;
1886}
1887
Ruslan Pisarev032abf72011-07-21 11:59:11 +03001888static int __init XGIfb_setup(char *options)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001889{
1890 char *this_opt;
1891
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001892 if (!options || !*options)
1893 return 0;
1894
Aaro Koskinen79bea042011-08-29 23:14:21 +03001895 pr_info("xgifb: options: %s\n", options);
1896
Prashant P. Shahb654f872010-09-06 17:34:26 +05301897 while ((this_opt = strsep(&options, ",")) != NULL) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001898
Prashant P. Shahb654f872010-09-06 17:34:26 +05301899 if (!*this_opt)
1900 continue;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001901
1902 if (!strncmp(this_opt, "mode:", 5)) {
Aaro Koskinendfbdf802011-08-29 23:14:25 +03001903 mode = this_opt + 5;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001904 } else if (!strncmp(this_opt, "vesa:", 5)) {
Aaro Koskinendfbdf802011-08-29 23:14:25 +03001905 vesa = xgifb_optval(this_opt, 5);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001906 } else if (!strncmp(this_opt, "vrate:", 6)) {
Aaro Koskinen7548a832011-10-11 21:47:17 +03001907 refresh_rate = xgifb_optval(this_opt, 6);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001908 } else if (!strncmp(this_opt, "rate:", 5)) {
Aaro Koskinen7548a832011-10-11 21:47:17 +03001909 refresh_rate = xgifb_optval(this_opt, 5);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001910 } else if (!strncmp(this_opt, "crt1off", 7)) {
1911 XGIfb_crt1off = 1;
1912 } else if (!strncmp(this_opt, "filter:", 7)) {
Aaro Koskinend27c6bc2011-08-29 23:14:23 +03001913 filter = xgifb_optval(this_opt, 7);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001914 } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
1915 XGIfb_search_crt2type(this_opt + 14);
1916 } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
Aaro Koskinend27c6bc2011-08-29 23:14:23 +03001917 XGIfb_forcecrt1 = xgifb_optval(this_opt, 10);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301918 } else if (!strncmp(this_opt, "tvmode:", 7)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001919 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301920 } else if (!strncmp(this_opt, "tvstandard:", 11)) {
1921 XGIfb_search_tvstd(this_opt + 7);
Prashant P. Shahb654f872010-09-06 17:34:26 +05301922 } else if (!strncmp(this_opt, "dstn", 4)) {
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001923 enable_dstn = 1;
1924 /* TW: DSTN overrules forcecrt2type */
1925 XGIfb_crt2type = DISPTYPE_LCD;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001926 } else if (!strncmp(this_opt, "noypan", 6)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05301927 XGIfb_ypan = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001928 } else if (!strncmp(this_opt, "userom:", 7)) {
Aaro Koskinend27c6bc2011-08-29 23:14:23 +03001929 XGIfb_userom = xgifb_optval(this_opt, 7);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001930 } else {
Aaro Koskinendfbdf802011-08-29 23:14:25 +03001931 mode = this_opt;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001932 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001933 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001934 return 0;
1935}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001936
Aaro Koskinen0f07d942011-02-17 23:29:13 +02001937static unsigned char *xgifb_copy_rom(struct pci_dev *dev)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001938{
Aaro Koskinen0f07d942011-02-17 23:29:13 +02001939 void __iomem *rom_address;
1940 unsigned char *rom_copy;
1941 size_t rom_size;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001942
Aaro Koskinen0f07d942011-02-17 23:29:13 +02001943 rom_address = pci_map_rom(dev, &rom_size);
1944 if (rom_address == NULL)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001945 return NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001946
Aaro Koskinen0f07d942011-02-17 23:29:13 +02001947 rom_copy = vzalloc(XGIFB_ROM_SIZE);
1948 if (rom_copy == NULL)
1949 goto done;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001950
Aaro Koskinen0f07d942011-02-17 23:29:13 +02001951 rom_size = min_t(size_t, rom_size, XGIFB_ROM_SIZE);
1952 memcpy_fromio(rom_copy, rom_address, rom_size);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001953
Aaro Koskinen0f07d942011-02-17 23:29:13 +02001954done:
1955 pci_unmap_rom(dev, rom_address);
1956 return rom_copy;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001957}
1958
Randy Dunlap89229672010-08-10 08:46:44 -07001959static int __devinit xgifb_probe(struct pci_dev *pdev,
Prashant P. Shahb654f872010-09-06 17:34:26 +05301960 const struct pci_device_id *ent)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001961{
Prashant P. Shahb654f872010-09-06 17:34:26 +05301962 u8 reg, reg1;
1963 u8 CR48, CR38;
Aaro Koskinenbb292232011-02-17 23:29:11 +02001964 int ret;
Aaro Koskinen009adf2d2011-08-29 23:14:24 +03001965 bool xgi21_drvlcdcaplist = false;
Aaro Koskinen19c1e882011-10-11 21:47:14 +03001966 struct fb_info *fb_info;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001967 struct xgifb_video_info *xgifb_info = &xgi_video_info;
1968 struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
Aaro Koskinenbb292232011-02-17 23:29:11 +02001969
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03001970 memset(hw_info, 0, sizeof(struct xgi_hw_device_info));
Prashant P. Shahb654f872010-09-06 17:34:26 +05301971 fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
1972 if (!fb_info)
1973 return -ENOMEM;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001974
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001975 xgifb_info->fb_info = fb_info;
1976 xgifb_info->chip_id = pdev->device;
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001977 pci_read_config_byte(pdev,
1978 PCI_REVISION_ID,
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001979 &xgifb_info->revision_id);
1980 hw_info->jChipRevision = xgifb_info->revision_id;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001981
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001982 xgifb_info->pcibus = pdev->bus->number;
1983 xgifb_info->pcislot = PCI_SLOT(pdev->devfn);
1984 xgifb_info->pcifunc = PCI_FUNC(pdev->devfn);
1985 xgifb_info->subsysvendor = pdev->subsystem_vendor;
1986 xgifb_info->subsysdevice = pdev->subsystem_device;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001987
Aaro Koskinenfd26d422011-10-11 21:47:19 +03001988 xgifb_info->video_base = pci_resource_start(pdev, 0);
1989 xgifb_info->mmio_base = pci_resource_start(pdev, 1);
1990 xgifb_info->mmio_size = pci_resource_len(pdev, 1);
1991 xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
1992 hw_info->pjIOAddress = (unsigned char *)xgifb_info->vga_base;
Prashant P. Shahb654f872010-09-06 17:34:26 +05301993 /* XGI_Pr.RelIO = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
1994 printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08001995 (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02001996
Aaro Koskinenbb292232011-02-17 23:29:11 +02001997 if (pci_enable_device(pdev)) {
1998 ret = -EIO;
1999 goto error;
2000 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002001
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002002 XGIRegInit(&XGI_Pr, (unsigned long)hw_info->pjIOAddress);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002003
Aaro Koskinenb6e2dc32011-04-18 22:13:59 +03002004 xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002005 reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002006
Prashant P. Shahb654f872010-09-06 17:34:26 +05302007 if (reg1 != 0xa1) { /*I/O error */
2008 printk("\nXGIfb: I/O error!!!");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002009 ret = -EIO;
2010 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302011 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002012
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002013 switch (xgifb_info->chip_id) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302014 case PCI_DEVICE_ID_XG_20:
Aaro Koskinene67f4d42011-04-18 22:14:00 +03002015 xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
Aaro Koskinen7e119b72011-04-18 22:13:58 +03002016 CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002017 if (CR48&GPIOG_READ)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002018 xgifb_info->chip = XG21;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002019 else
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002020 xgifb_info->chip = XG20;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002021 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2022 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302023 case PCI_DEVICE_ID_XG_40:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002024 xgifb_info->chip = XG40;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002025 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2026 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302027 case PCI_DEVICE_ID_XG_41:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002028 xgifb_info->chip = XG41;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002029 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2030 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302031 case PCI_DEVICE_ID_XG_42:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002032 xgifb_info->chip = XG42;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002033 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2034 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302035 case PCI_DEVICE_ID_XG_27:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002036 xgifb_info->chip = XG27;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002037 XGIfb_CRT2_write_enable = IND_XGI_CRT2_WRITE_ENABLE_315;
2038 break;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302039 default:
Aaro Koskinenbb292232011-02-17 23:29:11 +02002040 ret = -ENODEV;
2041 goto error;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002042 }
2043
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002044 printk("XGIfb:chipid = %x\n", xgifb_info->chip);
2045 hw_info->jChipType = xgifb_info->chip;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002046
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002047 if ((xgifb_info->chip == XG21) || (XGIfb_userom)) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002048 hw_info->pjVirtualRomBase = xgifb_copy_rom(pdev);
2049 if (hw_info->pjVirtualRomBase)
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002050 printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002051 hw_info->pjVirtualRomBase);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002052 else
2053 printk(KERN_INFO "XGIfb: Video ROM not found\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302054 } else {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002055 hw_info->pjVirtualRomBase = NULL;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002056 printk(KERN_INFO "XGIfb: Video ROM usage disabled\n");
Prashant P. Shahb654f872010-09-06 17:34:26 +05302057 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002058
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002059 if (XGIfb_get_dram_size(xgifb_info)) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302060 printk(KERN_INFO "XGIfb: Fatal error: Unable to determine RAM size.\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002061 ret = -ENODEV;
2062 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302063 }
2064
Aaro Koskinene1521a12011-08-19 22:40:26 +03002065 /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
2066 xgifb_reg_or(XGISR,
2067 IND_XGI_PCI_ADDRESS_SET,
2068 (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
2069 /* Enable 2D accelerator engine */
2070 xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302071
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002072 hw_info->ulVideoMemorySize = xgifb_info->video_size;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302073
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002074 if (!request_mem_region(xgifb_info->video_base,
2075 xgifb_info->video_size,
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002076 "XGIfb FB")) {
2077 printk("unable request memory size %x",
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002078 xgifb_info->video_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302079 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
2080 printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002081 ret = -ENODEV;
2082 goto error;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302083 }
2084
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002085 if (!request_mem_region(xgifb_info->mmio_base,
2086 xgifb_info->mmio_size,
Aaro Koskinen1b3909e2011-02-17 23:29:17 +02002087 "XGIfb MMIO")) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302088 printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve MMIO region\n");
Aaro Koskinenbb292232011-02-17 23:29:11 +02002089 ret = -ENODEV;
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002090 goto error_0;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302091 }
2092
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002093 xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress =
2094 ioremap(xgifb_info->video_base, xgifb_info->video_size);
2095 xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
2096 xgifb_info->mmio_size);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302097
2098 printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002099 xgifb_info->video_base,
2100 xgifb_info->video_vbase,
2101 xgifb_info->video_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302102
2103 printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002104 xgifb_info->mmio_base, xgifb_info->mmio_vbase,
2105 xgifb_info->mmio_size / 1024);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302106 printk("XGIfb: XGIInitNew() ...");
Aaro Koskinen6048d7612011-10-11 21:47:16 +03002107 pci_set_drvdata(pdev, &xgi_video_info);
2108 if (XGIInitNew(pdev))
Prashant P. Shahb654f872010-09-06 17:34:26 +05302109 printk("OK\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002110 else
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002111 printk("Fail\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002112
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002113 xgifb_info->mtrr = (unsigned int) 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002114
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002115 xgifb_info->hasVB = HASVB_NONE;
2116 if ((xgifb_info->chip == XG20) ||
2117 (xgifb_info->chip == XG27)) {
2118 xgifb_info->hasVB = HASVB_NONE;
2119 } else if (xgifb_info->chip == XG21) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002120 CR38 = xgifb_reg_get(XGICR, 0x38);
2121 if ((CR38&0xE0) == 0xC0) {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002122 xgifb_info->disp_state = DISPTYPE_LCD;
2123 if (!XGIfb_GetXG21LVDSData(xgifb_info))
Aaro Koskinen009adf2d2011-08-29 23:14:24 +03002124 xgi21_drvlcdcaplist = true;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002125 } else if ((CR38&0xE0) == 0x60) {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002126 xgifb_info->hasVB = HASVB_CHRONTEL;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302127 } else {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002128 xgifb_info->hasVB = HASVB_NONE;
Prashant P. Shahb654f872010-09-06 17:34:26 +05302129 }
Aaro Koskinene1521a12011-08-19 22:40:26 +03002130 } else {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002131 XGIfb_get_VB_type(xgifb_info);
Aaro Koskinene1521a12011-08-19 22:40:26 +03002132 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002133
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002134 hw_info->ujVBChipID = VB_CHIP_UNKNOWN;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002135
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002136 hw_info->ulExternalChip = 0;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002137
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002138 switch (xgifb_info->hasVB) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002139 case HASVB_301:
2140 reg = xgifb_reg_get(XGIPART4, 0x01);
2141 if (reg >= 0xE0) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002142 hw_info->ujVBChipID = VB_CHIP_302LV;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002143 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2144 } else if (reg >= 0xD0) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002145 hw_info->ujVBChipID = VB_CHIP_301LV;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002146 printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002147 }
Aaro Koskinene1521a12011-08-19 22:40:26 +03002148 /* else if (reg >= 0xB0) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002149 hw_info->ujVBChipID = VB_CHIP_301B;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002150 reg1 = xgifb_reg_get(XGIPART4, 0x23);
2151 printk("XGIfb: XGI301B bridge detected\n");
2152 } */
2153 else {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002154 hw_info->ujVBChipID = VB_CHIP_301;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002155 printk("XGIfb: XGI301 bridge detected\n");
2156 }
2157 break;
2158 case HASVB_302:
2159 reg = xgifb_reg_get(XGIPART4, 0x01);
2160 if (reg >= 0xE0) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002161 hw_info->ujVBChipID = VB_CHIP_302LV;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002162 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2163 } else if (reg >= 0xD0) {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002164 hw_info->ujVBChipID = VB_CHIP_301LV;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002165 printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
2166 } else if (reg >= 0xB0) {
2167 reg1 = xgifb_reg_get(XGIPART4, 0x23);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002168
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002169 hw_info->ujVBChipID = VB_CHIP_302B;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002170
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002171 } else {
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002172 hw_info->ujVBChipID = VB_CHIP_302;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002173 printk(KERN_INFO "XGIfb: XGI302 bridge detected\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002174 }
Aaro Koskinene1521a12011-08-19 22:40:26 +03002175 break;
2176 case HASVB_LVDS:
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002177 hw_info->ulExternalChip = 0x1;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002178 printk(KERN_INFO "XGIfb: LVDS transmitter detected\n");
2179 break;
2180 case HASVB_TRUMPION:
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002181 hw_info->ulExternalChip = 0x2;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002182 printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n");
2183 break;
2184 case HASVB_CHRONTEL:
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002185 hw_info->ulExternalChip = 0x4;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002186 printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n");
2187 break;
2188 case HASVB_LVDS_CHRONTEL:
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002189 hw_info->ulExternalChip = 0x5;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002190 printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n");
2191 break;
2192 default:
2193 printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n");
2194 break;
2195 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002196
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002197 if (xgifb_info->hasVB != HASVB_NONE)
2198 XGIfb_detect_VB(xgifb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002199
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002200 if (xgifb_info->disp_state & DISPTYPE_DISP2) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002201 if (XGIfb_crt1off)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002202 xgifb_info->disp_state |= DISPMODE_SINGLE;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002203 else
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002204 xgifb_info->disp_state |= (DISPMODE_MIRROR |
Aaro Koskinene1521a12011-08-19 22:40:26 +03002205 DISPTYPE_CRT1);
2206 } else {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002207 xgifb_info->disp_state = DISPMODE_SINGLE |
Aaro Koskinene1521a12011-08-19 22:40:26 +03002208 DISPTYPE_CRT1;
2209 }
2210
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002211 if (xgifb_info->disp_state & DISPTYPE_LCD) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002212 if (!enable_dstn) {
2213 reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
2214 reg &= 0x0f;
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002215 hw_info->ulCRT2LCDType = XGI310paneltype[reg];
Aaro Koskinene1521a12011-08-19 22:40:26 +03002216
2217 } else {
2218 /* TW: FSTN/DSTN */
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002219 hw_info->ulCRT2LCDType = LCD_320x480;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002220 }
2221 }
2222
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002223 if ((hw_info->ujVBChipID == VB_CHIP_302B) ||
2224 (hw_info->ujVBChipID == VB_CHIP_301LV) ||
2225 (hw_info->ujVBChipID == VB_CHIP_302LV)) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002226 int tmp;
2227 tmp = xgifb_reg_get(XGICR, 0x34);
2228 if (tmp <= 0x13) {
2229 /* Currently on LCDA?
2230 *(Some BIOSes leave CR38) */
2231 tmp = xgifb_reg_get(XGICR, 0x38);
2232 if ((tmp & 0x03) == 0x03) {
2233 /* XGI_Pr.XGI_UseLCDA = 1; */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302234 } else {
Kenji Toyamaa12c27c2011-04-26 12:13:43 +08002235 /* Currently on LCDA?
Aaro Koskinene1521a12011-08-19 22:40:26 +03002236 *(Some newer BIOSes set D0 in CR35) */
2237 tmp = xgifb_reg_get(XGICR, 0x35);
2238 if (tmp & 0x01) {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302239 /* XGI_Pr.XGI_UseLCDA = 1; */
2240 } else {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002241 tmp = xgifb_reg_get(XGICR,
2242 0x30);
2243 if (tmp & 0x20) {
2244 tmp = xgifb_reg_get(
2245 XGIPART1, 0x13);
2246 if (tmp & 0x04) {
2247 /* XGI_Pr.XGI_UseLCDA = 1; */
Prashant P. Shahb654f872010-09-06 17:34:26 +05302248 }
2249 }
2250 }
2251 }
Prashant P. Shahb654f872010-09-06 17:34:26 +05302252 }
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002253
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002254 }
2255
Aaro Koskinendfbdf802011-08-29 23:14:25 +03002256 if (mode)
2257 XGIfb_search_mode(mode);
2258 else if (vesa != -1)
2259 XGIfb_search_vesamode(vesa);
2260
Aaro Koskinene1521a12011-08-19 22:40:26 +03002261 if (xgifb_mode_idx >= 0)
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002262 xgifb_mode_idx = XGIfb_validate_mode(xgifb_info,
2263 xgifb_mode_idx);
Aaro Koskinene1521a12011-08-19 22:40:26 +03002264
2265 if (xgifb_mode_idx < 0) {
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002266 if ((xgifb_info->disp_state & DISPTYPE_DISP2) ==
Aaro Koskinenc8bec1f2011-08-29 23:14:30 +03002267 DISPTYPE_LCD &&
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002268 xgifb_info->chip == XG21)
Aaro Koskinenc8bec1f2011-08-29 23:14:30 +03002269 xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
2270 else
Aaro Koskinene1521a12011-08-19 22:40:26 +03002271 xgifb_mode_idx = DEFAULT_MODE;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002272 }
2273
Aaro Koskinende736db2011-08-29 23:14:29 +03002274 if (xgifb_mode_idx < 0) {
2275 dev_err(&pdev->dev, "no supported video mode found\n");
2276 goto error_1;
2277 }
2278
Aaro Koskinen009adf2d2011-08-29 23:14:24 +03002279 if (xgi21_drvlcdcaplist) {
2280 int m;
2281
2282 for (m = 0; m < ARRAY_SIZE(XGI21_LCDCapList); m++)
2283 if ((XGI21_LCDCapList[m].LVDSHDE ==
2284 XGIbios_mode[xgifb_mode_idx].xres) &&
2285 (XGI21_LCDCapList[m].LVDSVDE ==
2286 XGIbios_mode[xgifb_mode_idx].yres)) {
2287 xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
2288 break;
2289 }
2290 }
2291
Aaro Koskinene1521a12011-08-19 22:40:26 +03002292 XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
2293
2294 /* yilin set default refresh rate */
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002295 xgifb_info->refresh_rate = refresh_rate;
2296 if (xgifb_info->refresh_rate == 0)
2297 xgifb_info->refresh_rate = 60;
2298 if (XGIfb_search_refresh_rate(xgifb_info,
2299 xgifb_info->refresh_rate) == 0) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002300 XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002301 xgifb_info->refresh_rate = 60;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002302 }
2303
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002304 xgifb_info->video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
2305 xgifb_info->video_vwidth =
2306 xgifb_info->video_width =
Aaro Koskinene1521a12011-08-19 22:40:26 +03002307 XGIbios_mode[xgifb_mode_idx].xres;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002308 xgifb_info->video_vheight =
2309 xgifb_info->video_height =
Aaro Koskinene1521a12011-08-19 22:40:26 +03002310 XGIbios_mode[xgifb_mode_idx].yres;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002311 xgifb_info->org_x = xgifb_info->org_y = 0;
2312 xgifb_info->video_linelength =
2313 xgifb_info->video_width *
2314 (xgifb_info->video_bpp >> 3);
2315 switch (xgifb_info->video_bpp) {
Aaro Koskinene1521a12011-08-19 22:40:26 +03002316 case 8:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002317 xgifb_info->DstColor = 0x0000;
2318 xgifb_info->XGI310_AccelDepth = 0x00000000;
2319 xgifb_info->video_cmap_len = 256;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002320 break;
2321 case 16:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002322 xgifb_info->DstColor = 0x8000;
2323 xgifb_info->XGI310_AccelDepth = 0x00010000;
2324 xgifb_info->video_cmap_len = 16;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002325 break;
2326 case 32:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002327 xgifb_info->DstColor = 0xC000;
2328 xgifb_info->XGI310_AccelDepth = 0x00020000;
2329 xgifb_info->video_cmap_len = 16;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002330 break;
2331 default:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002332 xgifb_info->video_cmap_len = 16;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002333 printk(KERN_INFO "XGIfb: Unsupported depth %d",
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002334 xgifb_info->video_bpp);
Aaro Koskinene1521a12011-08-19 22:40:26 +03002335 break;
2336 }
2337
2338 printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002339 xgifb_info->video_width,
2340 xgifb_info->video_height,
2341 xgifb_info->video_bpp,
2342 xgifb_info->refresh_rate);
Aaro Koskinene1521a12011-08-19 22:40:26 +03002343
2344 default_var.xres =
2345 default_var.xres_virtual =
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002346 xgifb_info->video_width;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002347 default_var.yres =
2348 default_var.yres_virtual =
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002349 xgifb_info->video_height;
2350 default_var.bits_per_pixel = xgifb_info->video_bpp;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002351
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002352 XGIfb_bpp_to_var(xgifb_info, &default_var);
Aaro Koskinene1521a12011-08-19 22:40:26 +03002353
2354 default_var.pixclock = (u32) (1000000000 /
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002355 XGIfb_mode_rate_to_dclock(&XGI_Pr, hw_info,
Aaro Koskinene1521a12011-08-19 22:40:26 +03002356 XGIfb_mode_no, XGIfb_rate_idx));
2357
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002358 if (XGIfb_mode_rate_to_ddata(&XGI_Pr, hw_info,
Aaro Koskinene1521a12011-08-19 22:40:26 +03002359 XGIfb_mode_no, XGIfb_rate_idx,
2360 &default_var.left_margin, &default_var.right_margin,
2361 &default_var.upper_margin, &default_var.lower_margin,
2362 &default_var.hsync_len, &default_var.vsync_len,
2363 &default_var.sync, &default_var.vmode)) {
2364
2365 if ((default_var.vmode & FB_VMODE_MASK) ==
2366 FB_VMODE_INTERLACED) {
2367 default_var.yres <<= 1;
2368 default_var.yres_virtual <<= 1;
2369 } else if ((default_var.vmode & FB_VMODE_MASK) ==
2370 FB_VMODE_DOUBLE) {
2371 default_var.pixclock >>= 1;
2372 default_var.yres >>= 1;
2373 default_var.yres_virtual >>= 1;
2374 }
2375
2376 }
2377
2378 fb_info->flags = FBINFO_FLAG_DEFAULT;
2379 fb_info->var = default_var;
2380 fb_info->fix = XGIfb_fix;
2381 fb_info->par = &xgi_video_info;
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002382 fb_info->screen_base = xgifb_info->video_vbase;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002383 fb_info->fbops = &XGIfb_ops;
2384 XGIfb_get_fix(&fb_info->fix, -1, fb_info);
2385 fb_info->pseudo_palette = pseudo_palette;
2386
2387 fb_alloc_cmap(&fb_info->cmap, 256 , 0);
2388
2389#ifdef CONFIG_MTRR
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002390 xgifb_info->mtrr = mtrr_add(xgifb_info->video_base,
2391 xgifb_info->video_size, MTRR_TYPE_WRCOMB, 1);
2392 if (xgifb_info->mtrr >= 0)
Aaro Koskinen15ebe6c2011-09-11 00:29:54 +03002393 dev_info(&pdev->dev, "added MTRR\n");
Aaro Koskinene1521a12011-08-19 22:40:26 +03002394#endif
2395
2396 if (register_framebuffer(fb_info) < 0) {
2397 ret = -EINVAL;
Aaro Koskinen30284742011-09-11 00:29:53 +03002398 goto error_mtrr;
Aaro Koskinene1521a12011-08-19 22:40:26 +03002399 }
2400
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002401 dumpVGAReg();
2402
2403 return 0;
Aaro Koskinenbb292232011-02-17 23:29:11 +02002404
Aaro Koskinen30284742011-09-11 00:29:53 +03002405error_mtrr:
2406#ifdef CONFIG_MTRR
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002407 if (xgifb_info->mtrr >= 0)
2408 mtrr_del(xgifb_info->mtrr, xgifb_info->video_base,
2409 xgifb_info->video_size);
Aaro Koskinen30284742011-09-11 00:29:53 +03002410#endif /* CONFIG_MTRR */
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002411error_1:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002412 iounmap(xgifb_info->mmio_vbase);
2413 iounmap(xgifb_info->video_vbase);
2414 release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
Aaro Koskinen5c0ef2a2011-02-17 23:29:15 +02002415error_0:
Aaro Koskinenfd26d422011-10-11 21:47:19 +03002416 release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002417error:
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002418 vfree(hw_info->pjVirtualRomBase);
Aaro Koskinenbb292232011-02-17 23:29:11 +02002419 framebuffer_release(fb_info);
2420 return ret;
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002421}
2422
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002423/*****************************************************/
2424/* PCI DEVICE HANDLING */
2425/*****************************************************/
2426
2427static void __devexit xgifb_remove(struct pci_dev *pdev)
2428{
Aaro Koskinenab886ff2011-10-11 21:47:18 +03002429 struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
Aaro Koskinen19c1e882011-10-11 21:47:14 +03002430 struct fb_info *fb_info = xgifb_info->fb_info;
Aaro Koskinen54301b52011-10-11 21:47:13 +03002431
Prashant P. Shahb654f872010-09-06 17:34:26 +05302432 unregister_framebuffer(fb_info);
Aaro Koskinen30284742011-09-11 00:29:53 +03002433#ifdef CONFIG_MTRR
Aaro Koskinen54301b52011-10-11 21:47:13 +03002434 if (xgifb_info->mtrr >= 0)
2435 mtrr_del(xgifb_info->mtrr, xgifb_info->video_base,
2436 xgifb_info->video_size);
Aaro Koskinen30284742011-09-11 00:29:53 +03002437#endif /* CONFIG_MTRR */
Aaro Koskinen54301b52011-10-11 21:47:13 +03002438 iounmap(xgifb_info->mmio_vbase);
2439 iounmap(xgifb_info->video_vbase);
2440 release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
2441 release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
Aaro Koskinenc62f2e42011-10-11 21:47:15 +03002442 vfree(xgifb_info->hw_info.pjVirtualRomBase);
Prashant P. Shahb654f872010-09-06 17:34:26 +05302443 framebuffer_release(fb_info);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002444 pci_set_drvdata(pdev, NULL);
Aaro Koskinen45dcfaf2011-02-17 23:29:16 +02002445}
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002446
2447static struct pci_driver xgifb_driver = {
Prashant P. Shahb654f872010-09-06 17:34:26 +05302448 .name = "xgifb",
2449 .id_table = xgifb_pci_table,
2450 .probe = xgifb_probe,
2451 .remove = __devexit_p(xgifb_remove)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002452};
2453
Ruslan Pisarev032abf72011-07-21 11:59:11 +03002454static int __init xgifb_init(void)
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002455{
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002456 char *option = NULL;
2457
2458 if (fb_get_options("xgifb", &option))
2459 return -ENODEV;
2460 XGIfb_setup(option);
Javier Martinez Canillas328f55b2010-09-08 00:07:57 -04002461
Prashant P. Shahb654f872010-09-06 17:34:26 +05302462 return pci_register_driver(&xgifb_driver);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002463}
2464
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002465module_init(xgifb_init);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002466
2467/*****************************************************/
2468/* MODULE */
2469/*****************************************************/
2470
2471#ifdef MODULE
2472
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002473MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
2474MODULE_LICENSE("GPL");
2475MODULE_AUTHOR("XGITECH , Others");
2476
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002477module_param(mode, charp, 0);
2478module_param(vesa, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002479module_param(filter, int, 0);
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002480
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002481MODULE_PARM_DESC(mode,
Aaro Koskinen47c92d52011-08-29 23:14:33 +03002482 "\nSelects the desired default display mode in the format XxYxDepth,\n"
2483 "eg. 1024x768x16.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002484
2485MODULE_PARM_DESC(vesa,
Aaro Koskinen47c92d52011-08-29 23:14:33 +03002486 "\nSelects the desired default display mode by VESA mode number, eg.\n"
2487 "0x117.\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002488
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002489MODULE_PARM_DESC(filter,
Prashant P. Shahb654f872010-09-06 17:34:26 +05302490 "\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
2491 "(Possible values 0-7, default: [no filter])\n");
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002492
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002493static void __exit xgifb_remove_module(void)
2494{
2495 pci_unregister_driver(&xgifb_driver);
2496 printk(KERN_DEBUG "xgifb: Module unloaded\n");
2497}
2498
apatard@mandriva.comd7636e02010-05-19 10:44:14 +02002499module_exit(xgifb_remove_module);
2500
Prashant P. Shahb654f872010-09-06 17:34:26 +05302501#endif /* /MODULE */