patch-2.3.13 linux/drivers/video/matroxfb.c
Next file: linux/drivers/video/mdacon.c
Previous file: linux/drivers/video/macfb.c
Back to the patch index
Back to the overall index
- Lines: 1760
- Date:
Mon Aug 9 11:56:26 1999
- Orig file:
v2.3.12/linux/drivers/video/matroxfb.c
- Orig date:
Thu Apr 29 12:53:48 1999
diff -u --recursive --new-file v2.3.12/linux/drivers/video/matroxfb.c linux/drivers/video/matroxfb.c
@@ -1,10 +1,10 @@
/*
*
- * Hardware accelerated Matrox Millennium I, II, Mystique and G200
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>
*
- * Version: 1.15 1999/04/19
+ * Version: 1.19 1999/08/05
*
* MTRR stuff: 1998 Tom Rini <tmrini@ntplx.net>
*
@@ -14,8 +14,8 @@
* "Kurt Garloff" <garloff@kg1.ping.de>
* Betatesting, fixes, ideas, videomodes, videomodes timmings
*
- * "Tom Rini" <tmrini@ntplx.net>
- * MTRR stuff, betatesting, fixes, ideas
+ * "Tom Rini" <trini@disparity.net>
+ * MTRR stuff, PPC cleanups, betatesting, fixes, ideas
*
* "Bibek Sahu" <scorpio@dodds.net>
* Access device through readb|w|l and write b|w|l
@@ -60,6 +60,9 @@
* "Cort Dougan" <cort@cs.nmt.edu>
* CHRP fixes and PReP cleanup
*
+ * "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ * G400 support
+ *
* (following author is not in any relation with this code, but his code
* is included in this driver)
*
@@ -87,6 +90,11 @@
/* Debug register calls, too? */
#undef MATROXFB_DEBUG_REG
+/* Log reentrancy attempts - you must have printstate() patch applied */
+#undef MATROXFB_DEBUG_REENTER
+/* you must define DEBUG_REENTER to get debugged CONSOLEBH... */
+#undef MATROXFB_DEBUG_CONSOLEBH
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -127,12 +135,15 @@
#include <video/macmodes.h>
#endif
+/* always compile support for 32MB... It cost almost nothing */
+#define CONFIG_FB_MATROX_32MB
+
#define FBCON_HAS_VGATEXT
#ifdef MATROXFB_DEBUG
#define DEBUG
-#define DBG(x) printk("matroxfb: %s\n", (x));
+#define DBG(x) printk(KERN_DEBUG "matroxfb: %s\n", (x));
#ifdef MATROXFB_DEBUG_HEAVY
#define DBG_HEAVY(x) DBG(x)
@@ -217,6 +228,9 @@
#ifndef PCI_DEVICE_ID_MATROX_G100_AGP
#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001
#endif
+#ifndef PCI_DEVICE_ID_MATROX_G400_AGP
+#define PCI_DEVICE_ID_MATROX_G400_AGP 0x0525
+#endif
#ifndef PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP
#define PCI_SS_ID_MATROX_GENERIC 0xFF00
@@ -422,7 +436,7 @@
unsigned char MiscOutReg;
unsigned char DACpal[768];
unsigned char CRTC[25];
- unsigned char CRTCEXT[6];
+ unsigned char CRTCEXT[9];
unsigned char SEQ[5];
/* unused for MGA mode, but who knows... */
unsigned char GCTL[9];
@@ -453,7 +467,8 @@
}
#define PMXINFO(p) mxinfo(p),
-#define MINFO_FROM_DISP(x) struct matrox_fb_info* minfo = mxinfo(x)
+#define MINFO_FROM(x) struct matrox_fb_info* minfo = x
+#define MINFO_FROM_DISP(x) MINFO_FROM(mxinfo(x))
#else
@@ -476,6 +491,7 @@
#endif
#define PMXINFO(p)
+#define MINFO_FROM(x)
#define MINFO_FROM_DISP(x)
#endif
@@ -563,6 +579,9 @@
int hwcursor;
int blink;
int sgram;
+#ifdef CONFIG_FB_MATROX_32MB
+ int support32MB;
+#endif
int accelerator;
int text_type_aux;
@@ -609,6 +628,8 @@
#if defined(CONFIG_FB_OF)
unsigned char nvram_read_byte(int);
int matrox_of_init(struct device_node *dp);
+static int default_vmode = VMODE_NVRAM;
+static int default_cmode = CMODE_NVRAM;
#endif
#define curr_ydstorg(x) ACCESS_FBINFO2(x, curr.ydstorg.pixels)
@@ -678,6 +699,8 @@
#define M_RESET 0x1E40
+#define M_AGP2PLL 0x1E4C
+
#define M_OPMODE 0x1E54
#define M_OPMODE_DMA_GEN_WRITE 0x00
#define M_OPMODE_DMA_BLIT 0x04
@@ -713,6 +736,9 @@
#define M_EXTVGA_INDEX 0x1FDE
#define M_EXTVGA_DATA 0x1FDF
+/* G200 only */
+#define M_SRCORG 0x2CB4
+
#define M_RAMDAC_BASE 0x3C00
/* fortunately, same on TVP3026 and MGA1064 */
@@ -723,6 +749,9 @@
#define M_X_INDEX 0x00
#define M_X_DATAREG 0x0A
+#define DAC_XGENIOCTRL 0x2A
+#define DAC_XGENIODATA 0x2B
+
#ifdef CONFIG_FB_MATROX_MILLENIUM
#define TVP3026_INDEX 0x00
#define TVP3026_PALWRADD 0x00
@@ -1054,6 +1083,48 @@
#define isMilleniumII(x) (0)
#endif
+#ifdef MATROXFB_DEBUG_REENTER
+static atomic_t guard_counter = ATOMIC_INIT(1);
+static atomic_t guard_printing = ATOMIC_INIT(1);
+static void guard_start(void) {
+ if (atomic_dec_and_test(&guard_counter)) { /* first level */
+ if (!(bh_mask & (1 << CONSOLE_BH))) /* and CONSOLE_BH disabled */
+ return; /* is OK */
+ /* otherwise it is first level with CONSOLE_BH enabled -
+ - if we are __sti or SMP, reentering from console_bh possible */
+ atomic_dec(&guard_printing); /* disable reentrancy warning */
+ printk(KERN_DEBUG "matroxfb entered without CONSOLE_BH disabled\n");
+#ifdef printstate
+ printstate();
+#endif
+ atomic_inc(&guard_printing);
+ return;
+ }
+ /* real reentering... You should be already warned by code above */
+ if (atomic_dec_and_test(&guard_printing)) {
+#ifdef printstate
+ printstate();
+#endif
+ }
+ atomic_inc(&guard_printing);
+}
+
+static inline void guard_end(void) {
+ atomic_inc(&guard_counter);
+}
+
+#define CRITBEGIN guard_start();
+#define CRITEND guard_end();
+
+#else
+
+#define CRITBEGIN
+#define CRITEND
+
+#endif
+
+#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
+
static void matrox_cfbX_init(WPMINFO struct display* p) {
u_int32_t maccess;
u_int32_t mpitch;
@@ -1101,7 +1172,7 @@
mga_outl(M_OPMODE, mopmode);
mga_outl(M_CXBNDRY, 0xFFFF0000);
mga_outl(M_YTOP, 0);
- mga_outl(M_YBOT, 0x007FFFFF);
+ mga_outl(M_YBOT, 0x01FFFFFF);
mga_outl(M_MACCESS, maccess);
ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC;
@@ -1113,7 +1184,9 @@
MINFO_FROM_DISP(p);
DBG("matrox_cfbX_bmove")
-
+
+ CRITBEGIN
+
sx *= fontwidth(p);
dx *= fontwidth(p);
width *= fontwidth(p);
@@ -1142,8 +1215,10 @@
mga_outl(M_AR0, end);
mga_outl(M_AR3, start);
mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
- mga_outl(M_YDSTLEN | M_EXEC, ((dy)<<16) | height);
+ mga_ydstlen(dy, height);
WaitTillIdle();
+
+ CRITEND
}
#ifdef FBCON_HAS_CFB4
@@ -1154,7 +1229,9 @@
also odd, that means that we cannot use acceleration */
DBG("matrox_cfb4_bmove")
-
+
+ CRITBEGIN
+
if ((sx | dx | width) & fontwidth(p) & 1) {
fbcon_cfb4_bmove(p, sy, sx, dy, dx, height, width);
return;
@@ -1194,6 +1271,8 @@
mga_outl(M_YDST, dy*pixx >> 5);
mga_outl(M_LEN | M_EXEC, height);
WaitTillIdle();
+
+ CRITEND
}
#endif
@@ -1201,13 +1280,17 @@
int width) {
DBG("matroxfb_accel_clear")
-
- mga_fifo(4);
+
+ CRITBEGIN
+
+ mga_fifo(5);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE);
mga_outl(M_FCOL, color);
mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
- mga_outl(M_YDSTLEN | M_EXEC, (sy << 16) | height);
+ mga_ydstlen(sy, height);
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_clear(u_int32_t color, struct display* p, int sy, int sx, int height, int width) {
@@ -1225,7 +1308,9 @@
MINFO_FROM_DISP(p);
DBG("matrox_cfb4_clear")
-
+
+ CRITBEGIN
+
whattodo = 0;
bgx = attr_bgcol_ec(p, conp);
bgx |= bgx << 4;
@@ -1277,6 +1362,8 @@
}
}
}
+
+ CRITEND
}
#endif
@@ -1323,7 +1410,10 @@
charcell = fontwidth(p) * fontheight(p);
yy *= fontheight(p);
xx *= fontwidth(p);
- mga_fifo(7);
+
+ CRITBEGIN
+
+ mga_fifo(8);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
mga_outl(M_FCOL, fgx);
@@ -1332,8 +1422,10 @@
ar3 = ACCESS_FBINFO(fastfont.mgabase) + (c & p->charmask) * charcell;
mga_outl(M_AR3, ar3);
mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
@@ -1345,6 +1437,9 @@
yy *= fontheight(p);
xx *= fontwidth(p);
+
+ CRITBEGIN
+
#ifdef __BIG_ENDIAN
WaitTillIdle();
mga_outl(M_OPMODE, M_OPMODE_8BPP);
@@ -1367,7 +1462,7 @@
mga_outl(M_BCOL, bgx);
mga_outl(M_AR3, 0);
mga_outl(M_AR0, fontheight(p)*fontwidth(p)-1);
- mga_outl(M_YDSTLEN | M_EXEC, (yy<<16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, p->fontdata+(c&p->charmask)*charcell, charcell);
} else {
u8* chardata = p->fontdata+(c&p->charmask)*fontheight(p)*step;
@@ -1379,7 +1474,7 @@
mga_outl(M_AR5, 0);
mga_outl(M_AR3, 0);
mga_outl(M_AR0, ar0);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
switch (step) {
case 1:
@@ -1410,6 +1505,7 @@
#ifdef __BIG_ENDIAN
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
#endif
+ CRITEND
}
#ifdef FBCON_HAS_CFB8
@@ -1464,6 +1560,9 @@
yy *= fontheight(p);
xx *= fontwidth(p);
charcell = fontwidth(p) * fontheight(p);
+
+ CRITBEGIN
+
mga_fifo(3);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
mga_outl(M_FCOL, fgx);
@@ -1475,10 +1574,12 @@
mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
mga_outl(M_AR3, ar3);
mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
xx += fontwidth(p);
}
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
@@ -1504,7 +1605,7 @@
step = 4;
charcell = fontheight(p)*step;
xlen = (charcell + 3) & ~3;
- ydstlen = (yy<<16) | fontheight(p);
+ ydstlen = (yy << 16) | fontheight(p);
if (fontwidth(p) == step << 3) {
ar0 = fontheight(p)*fontwidth(p) - 1;
easy = 1;
@@ -1512,6 +1613,9 @@
ar0 = fontwidth(p) - 1;
easy = 0;
}
+
+ CRITBEGIN
+
#ifdef __BIG_ENDIAN
WaitTillIdle();
mga_outl(M_OPMODE, M_OPMODE_8BPP);
@@ -1529,7 +1633,7 @@
while (count--) {
u_int8_t* chardata = p->fontdata + (scr_readw(s++) & p->charmask)*charcell;
- mga_fifo(5);
+ mga_fifo(6);
mga_writel(mmio, M_FXBNDRY, fxbndry);
mga_writel(mmio, M_AR0, ar0);
mga_writel(mmio, M_AR3, 0);
@@ -1573,6 +1677,7 @@
#ifdef __BIG_ENDIAN
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
#endif
+ CRITEND
}
#ifdef FBCON_HAS_CFB8
@@ -1635,6 +1740,8 @@
xx |= (xx + fontwidth(p)) << 16;
xx >>= 1;
+ CRITBEGIN
+
mga_fifo(5);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
mga_outl(M_FCOL, 0xFFFFFFFF);
@@ -1642,6 +1749,8 @@
mga_outl(M_YDST, yy * p->var.xres_virtual >> 6);
mga_outl(M_LEN | M_EXEC, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
#endif
@@ -1654,12 +1763,16 @@
yy *= fontheight(p);
xx *= fontwidth(p);
+ CRITBEGIN
+
mga_fifo(4);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
mga_outl(M_FCOL, 0x0F0F0F0F);
mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
#endif
@@ -1671,12 +1784,16 @@
yy *= fontheight(p);
xx *= fontwidth(p);
+ CRITBEGIN
+
mga_fifo(4);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
mga_outl(M_FCOL, 0xFFFFFFFF);
mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) {
@@ -1840,6 +1957,9 @@
DBG("matroxfb_ti3026_cursor")
+ if (ACCESS_FBINFO(currcon_display) != p)
+ return;
+
if (mode == CM_ERASE) {
if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
@@ -1914,6 +2034,9 @@
xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
cursorbase = ACCESS_FBINFO(video.vbase);
h = ACCESS_FBINFO(features.DAC1064.cursorimage);
+
+ CRITBEGIN
+
#ifdef __BIG_ENDIAN
WaitTillIdle();
mga_outl(M_OPMODE, M_OPMODE_32BPP);
@@ -1944,12 +2067,17 @@
#ifdef __BIG_ENDIAN
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
#endif
+
+ CRITEND
}
static void matroxfb_DAC1064_cursor(struct display* p, int mode, int x, int y) {
unsigned long flags;
MINFO_FROM_DISP(p);
+ if (ACCESS_FBINFO(currcon_display) != p)
+ return;
+
if (mode == CM_ERASE) {
if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
@@ -2010,6 +2138,9 @@
fsize = (p->userfont?FNTCHARCNT(p->fontdata):256) * fontheight(p);
if (((fsize * width + 31) / 32) * 4 > ACCESS_FBINFO(fastfont.size))
return 0;
+
+ CRITBEGIN
+
mga_outl(M_OPMODE, M_OPMODE_8BPP);
if (width <= 8) {
if (width == 8)
@@ -2100,6 +2231,9 @@
}
}
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
+
+ CRITEND
+
return 1;
}
@@ -2117,6 +2251,8 @@
unsigned int step;
MINFO_FROM_DISP(p);
+ CRITBEGIN
+
step = ACCESS_FBINFO(devflags.textstep);
srcoff = (sy * p->next_line) + (sx * step);
dstoff = (dy * p->next_line) + (dx * step);
@@ -2144,6 +2280,7 @@
height--;
}
}
+ CRITEND
}
static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, int sx,
@@ -2156,6 +2293,9 @@
step = ACCESS_FBINFO(devflags.textstep);
offs = sy * p->next_line + sx * step;
val = ntohs((attr_bgcol(p, conp->vc_video_erase_char) << 4) | attr_fgcol(p, conp->vc_video_erase_char) | (' ' << 8));
+
+ CRITBEGIN
+
while (height > 0) {
int i;
for (i = width; i > 0; offs += step, i--)
@@ -2163,6 +2303,7 @@
offs += p->next_line - width * step;
height--;
}
+ CRITEND
}
static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
@@ -2175,7 +2316,12 @@
offs = yy * p->next_line + xx * step;
chr = attr_fgcol(p,c) | (attr_bgcol(p,c) << 4) | ((c & p->charmask) << 8);
if (chr & 0x10000) chr |= 0x08;
+
+ CRITBEGIN
+
mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(chr));
+
+ CRITEND
}
static void matrox_text_putcs(struct vc_data* conp, struct display* p, const unsigned short* s,
@@ -2188,12 +2334,17 @@
step = ACCESS_FBINFO(devflags.textstep);
offs = yy * p->next_line + xx * step;
attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4);
+
+ CRITBEGIN
+
while (count-- > 0) {
unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
if (chr & 0x10000) chr ^= 0x10008;
mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr));
offs += step;
}
+
+ CRITEND
}
static void matrox_text_revc(struct display* p, int xx, int yy) {
@@ -2203,7 +2354,12 @@
step = ACCESS_FBINFO(devflags.textstep);
offs = yy * p->next_line + xx * step + 1;
+
+ CRITBEGIN
+
mga_writeb(ACCESS_FBINFO(video.vbase), offs, mga_readb(ACCESS_FBINFO(video.vbase), offs) ^ 0x77);
+
+ CRITEND
}
static int matrox_text_loadfont(WPMINFO struct display* p) {
@@ -2221,6 +2377,9 @@
dst = ACCESS_FBINFO(video.vbase);
i = 2;
font = (u_int8_t*)p->fontdata;
+
+ CRITBEGIN
+
mga_setr(M_SEQ_INDEX, 0x02, 0x04);
while (fsize--) {
int l;
@@ -2233,6 +2392,9 @@
i += (32 - fontheight(p)) * ACCESS_FBINFO(devflags.vgastep);
}
mga_setr(M_SEQ_INDEX, 0x02, 0x03);
+
+ CRITEND
+
return 1;
}
@@ -2242,17 +2404,31 @@
return;
matroxfb_createcursorshape(PMINFO p, 0);
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
mga_setr(M_CRTC_INDEX, 0x0B, ACCESS_FBINFO(cursor.d) - 1);
+
+ CRITEND
}
static void matrox_text_cursor(struct display* p, int mode, int x, int y) {
unsigned int pos;
MINFO_FROM_DISP(p);
+ if (ACCESS_FBINFO(currcon_display) != p)
+ return;
+
if (mode == CM_ERASE) {
if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0A, 0x20);
+
+ CRITEND
+
ACCESS_FBINFO(cursor.state) = CM_ERASE;
}
return;
@@ -2264,10 +2440,16 @@
ACCESS_FBINFO(cursor.x) = x;
ACCESS_FBINFO(cursor.y) = y;
pos = p->next_line / ACCESS_FBINFO(devflags.textstep) * y + x;
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0F, pos);
mga_setr(M_CRTC_INDEX, 0x0E, pos >> 8);
mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
+
+ CRITEND
+
ACCESS_FBINFO(cursor.state) = CM_DRAW;
}
@@ -2523,6 +2705,9 @@
static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
unsigned int pos;
unsigned short p0, p1, p2;
+#ifdef CONFIG_FB_MATROX_32MB
+ unsigned int p3;
+#endif
struct display *disp;
DBG("matrox_pan_var")
@@ -2536,10 +2721,22 @@
}
p0 = ACCESS_FBINFO(currenthw)->CRTC[0x0D] = pos & 0xFF;
p1 = ACCESS_FBINFO(currenthw)->CRTC[0x0C] = (pos & 0xFF00) >> 8;
- p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F);
+ p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+#ifdef CONFIG_FB_MATROX_32MB
+ p3 = ACCESS_FBINFO(currenthw)->CRTCEXT[8] = pos >> 21;
+#endif
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0D, p0);
mga_setr(M_CRTC_INDEX, 0x0C, p1);
+#ifdef CONFIG_FB_MATROX_32MB
+ if (ACCESS_FBINFO(devflags.support32MB))
+ mga_setr(M_EXTVGA_INDEX, 0x08, p3);
+#endif
mga_setr(M_EXTVGA_INDEX, 0x00, p2);
+
+ CRITEND
}
/*
@@ -2627,13 +2824,16 @@
case 0: return xres;
case 4: rounding = 128;
break;
- case 8: rounding = 64;
+ case 8: rounding = 64; /* doc says 64; 32 is OK for G400 */
break;
case 16: rounding = 32;
break;
- case 24: rounding = 64;
+ case 24: rounding = 64; /* doc says 64; 32 is OK for G400 */
break;
default: rounding = 16;
+ /* on G400, 16 really does not work */
+ if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
+ rounding = 32;
break;
}
if (isInterleave(MINFO)) {
@@ -3140,7 +3340,7 @@
hw->DACclk[2] = p;
}
-__initfunc(static void DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem)) {
+static void __init DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){
u_int32_t mx;
DBG("DAC1064_setmclk")
@@ -3288,6 +3488,8 @@
static void DAC1064_restore_1(CPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {
DBG("DAC1064_restore_1")
+
+ CRITBEGIN
outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
@@ -3298,6 +3500,8 @@
for (i = 0; i < sizeof(MGA1064_DAC_regs); i++)
outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
}
+
+ CRITEND
}
static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {
@@ -3305,6 +3509,8 @@
unsigned int tmout;
DBG("DAC1064_restore_2")
+
+ CRITBEGIN
for (i = 0; i < 3; i++)
outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]);
@@ -3313,6 +3519,9 @@
break;
udelay(10);
};
+
+ CRITEND
+
if (!tmout)
printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
@@ -3585,7 +3794,9 @@
var->pixclock = 15000; /* limit for "normal" gclk & mclk */
#endif
}
-
+ /* YDSTLEN contains only signed 16bit value */
+ if (var->yres_virtual > 32767)
+ var->yres_virtual = 32767;
if (var->yres_virtual < var->yres)
var->yres = var->yres_virtual;
if (var->xres_virtual < var->xres)
@@ -3684,7 +3895,7 @@
}
#ifdef CONFIG_FB_MATROX_MILLENIUM
-__initfunc(static void ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout)) {
+static void __init ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout){
unsigned int f_pll;
unsigned int pclk_m, pclk_n, pclk_p;
unsigned int mclk_m, mclk_n, mclk_p;
@@ -3783,7 +3994,7 @@
printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
}
-__initfunc(static void ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw)) {
+static void __init ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw){
DBG("ti3026_ramdac_init")
@@ -3800,7 +4011,7 @@
}
#endif
-__initfunc(static void matroxfb_fastfont_init(struct matrox_fb_info* minfo)) {
+static void matroxfb_fastfont_init(struct matrox_fb_info* minfo){
unsigned int size;
size = ACCESS_FBINFO(fastfont.size);
@@ -3824,7 +4035,7 @@
}
#ifdef CONFIG_FB_MATROX_MYSTIQUE
-__initfunc(static void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw)) {
+static void __init MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){
DBG("MGA1064_ramdac_init");
@@ -3841,7 +4052,7 @@
DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
}
-__initfunc(static int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw)) {
+static int __init MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){
static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
2048, 0};
@@ -3873,7 +4084,7 @@
return 0;
}
-__initfunc(static void MGA1064_reset(WPMINFO struct matrox_hw_state* hw)) {
+static void __init MGA1064_reset(WPMINFO struct matrox_hw_state* hw){
DBG("MGA1064_reset");
@@ -3893,7 +4104,7 @@
static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
#endif
-__initfunc(static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p)) {
+static void __init MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){
int reg;
int selClk;
int clk;
@@ -3937,7 +4148,7 @@
outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
}
-__initfunc(static void MGAG100_setPixClock(CPMINFO int flags, int freq)) {
+static void __init MGAG100_setPixClock(CPMINFO int flags, int freq){
unsigned int m, n, p;
DBG("MGAG100_setPixClock")
@@ -3946,7 +4157,7 @@
MGAG100_progPixClock(PMINFO flags, m, n, p);
}
-__initfunc(static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw)) {
+static int __init MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){
static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
2048, 0};
@@ -4036,7 +4247,7 @@
return 0;
}
-__initfunc(static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw)) {
+static void __init MGAG100_reset(WPMINFO struct matrox_hw_state* hw){
u_int8_t b;
DBG("MGAG100_reset")
@@ -4104,6 +4315,8 @@
dprintk("%02X:", hw->ATTR[i]);
dprintk("\n");
+ CRITBEGIN
+
mga_inb(M_ATTR_RESET);
mga_outb(M_ATTR_INDEX, 0);
mga_outb(M_MISC_REG, hw->MiscOutReg);
@@ -4125,6 +4338,8 @@
mga_outb(M_DAC_VAL, hw->DACpal[i]);
mga_inb(M_ATTR_RESET);
mga_outb(M_ATTR_INDEX, 0x20);
+
+ CRITEND
}
static int matrox_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -4227,10 +4442,15 @@
int i;
DBG("MGA1064_restore")
+
+ CRITBEGIN
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
mga_outb(M_IEN, 0x00);
mga_outb(M_CACHEFLUSH, 0x00);
+
+ CRITEND
+
DAC1064_restore_1(PMINFO hw, oldhw);
vgaHWrestore(PMINFO hw, oldhw);
for (i = 0; i < 6; i++)
@@ -4244,10 +4464,18 @@
int i;
DBG("MGAG100_restore")
-
+
+ CRITBEGIN
+
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+ CRITEND
+
DAC1064_restore_1(PMINFO hw, oldhw);
vgaHWrestore(PMINFO hw, oldhw);
+#ifdef CONFIG_FB_MATROX_32MB
+ if (ACCESS_FBINFO(devflags.support32MB))
+ mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
+#endif
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
DAC1064_restore_2(PMINFO hw, oldhw, p);
@@ -4265,9 +4493,16 @@
dprintk("%02X:", hw->CRTCEXT[i]);
dprintk("\n");
+ CRITBEGIN
+
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+ CRITEND
+
vgaHWrestore(PMINFO hw, oldhw);
+
+ CRITBEGIN
+
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
@@ -4285,11 +4520,13 @@
oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
}
+ CRITEND
if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) {
/* agrhh... setting up PLL is very slow on Millenium... */
/* Mystique PLL is locked in few ms, but Millenium PLL lock takes about 0.15 s... */
/* Maybe even we should call schedule() ? */
+ CRITBEGIN
outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0);
@@ -4307,24 +4544,31 @@
break;
udelay(10);
}
+
+ CRITEND
+
if (!tmout)
printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
else
dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
+ CRITBEGIN
}
outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
for (i = 3; i < 6; i++)
outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
+ CRITEND
if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
int tmout;
+ CRITBEGIN
outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
for (tmout = 500000; tmout; --tmout) {
if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40)
break;
udelay(10);
}
+ CRITEND
if (!tmout)
printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");
else
@@ -4379,7 +4623,7 @@
strcpy(fix->id,"MATROX");
fix->smem_start = (void*)ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);
- fix->smem_len = ACCESS_FBINFO(video.len) - ACCESS_FBINFO(curr.ydstorg.bytes);
+ fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes);
fix->type = p->type;
fix->type_aux = p->type_aux;
fix->visual = p->visual;
@@ -4531,7 +4775,8 @@
hw->CRTC[0x0D] = pos & 0xFF;
hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;
- hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F);
+ hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+ hw->CRTCEXT[8] = pos >> 21;
ACCESS_FBINFO(hw_switch->restore(PMINFO hw, ohw, display));
ACCESS_FBINFO(cursor.redraw) = 1;
ACCESS_FBINFO(currenthw) = hw;
@@ -4717,10 +4962,16 @@
case 4: seq = 0x20; crtc = 0x30; break;
default: seq = 0x00; crtc = 0x00; break;
}
+
+ CRITBEGIN
+
mga_outb(M_SEQ_INDEX, 1);
mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq);
mga_outb(M_EXTVGA_INDEX, 1);
mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc);
+
+ CRITEND
+
#undef minfo
}
@@ -4739,7 +4990,8 @@
#define RS1056x344 12 /* 132 x 43 text */
#define RS1056x400 13 /* 132 x 50 text */
#define RS1056x480 14 /* 132 x 60 text */
-/* 0F-FF */
+#define RSNoxNo 15
+/* 10-FF */
static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = {
{ 640, 400, 48, 16, 39, 8, 96, 2, 70 },
{ 640, 480, 48, 16, 33, 10, 96, 2, 60 },
@@ -4754,7 +5006,8 @@
{ 640, 350, 48, 16, 39, 8, 96, 2, 70 },
{ 1056, 344, 96, 24, 59, 44, 160, 2, 70 },
{ 1056, 400, 96, 24, 39, 8, 160, 2, 70 },
- { 1056, 480, 96, 24, 36, 12, 160, 3, 60 }
+ { 1056, 480, 96, 24, 36, 12, 160, 3, 60 },
+ { 0, 0, ~0, ~0, ~0, ~0, 0, 0, 0 }
};
#define RSDepth(X) (((X) >> 8) & 0x0F)
@@ -4775,13 +5028,14 @@
{ { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 4 },
{ { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 24 },
{ { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode with (default) VGA8x16 */
- { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 } /* textmode hardwired to VGA8x8 */
+ { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode hardwired to VGA8x8 */
};
#define RSCreate(X,Y) ((X) | ((Y) << 8))
static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = {
/* default must be first */
#ifdef FBCON_HAS_CFB8
+ { ~0, RSCreate(RSNoxNo, RS8bpp ) },
{ 0x101, RSCreate(RS640x480, RS8bpp ) },
{ 0x100, RSCreate(RS640x400, RS8bpp ) },
{ 0x180, RSCreate(RS768x576, RS8bpp ) },
@@ -4793,14 +5047,8 @@
{ 0x198, RSCreate(RS1408x1056, RS8bpp ) },
{ 0x11C, RSCreate(RS1600x1200, RS8bpp ) },
#endif
-#ifdef FBCON_HAS_CFB4
- { 0x010, RSCreate(RS640x350, RS4bpp ) },
- { 0x012, RSCreate(RS640x480, RS4bpp ) },
- { 0x102, RSCreate(RS800x600, RS4bpp ) },
- { 0x104, RSCreate(RS1024x768, RS4bpp ) },
- { 0x106, RSCreate(RS1280x1024, RS4bpp ) },
-#endif
#ifdef FBCON_HAS_CFB16
+ { ~0, RSCreate(RSNoxNo, RS15bpp) },
{ 0x110, RSCreate(RS640x480, RS15bpp) },
{ 0x181, RSCreate(RS768x576, RS15bpp) },
{ 0x113, RSCreate(RS800x600, RS15bpp) },
@@ -4821,6 +5069,7 @@
{ 0x11E, RSCreate(RS1600x1200, RS16bpp) },
#endif
#ifdef FBCON_HAS_CFB24
+ { ~0, RSCreate(RSNoxNo, RS24bpp) },
{ 0x1B2, RSCreate(RS640x480, RS24bpp) },
{ 0x184, RSCreate(RS768x576, RS24bpp) },
{ 0x1B5, RSCreate(RS800x600, RS24bpp) },
@@ -4832,6 +5081,7 @@
{ 0x1BF, RSCreate(RS1600x1200, RS24bpp) },
#endif
#ifdef FBCON_HAS_CFB32
+ { ~0, RSCreate(RSNoxNo, RS32bpp) },
{ 0x112, RSCreate(RS640x480, RS32bpp) },
{ 0x183, RSCreate(RS768x576, RS32bpp) },
{ 0x115, RSCreate(RS800x600, RS32bpp) },
@@ -4843,6 +5093,7 @@
{ 0x11F, RSCreate(RS1600x1200, RS32bpp) },
#endif
#ifdef FBCON_HAS_VGATEXT
+ { ~0, RSCreate(RSNoxNo, RSText) },
{ 0x002, RSCreate(RS640x400, RSText) }, /* 80x25 */
{ 0x003, RSCreate(RS640x400, RSText) }, /* 80x25 */
{ 0x007, RSCreate(RS640x400, RSText) }, /* 80x25 */
@@ -4853,6 +5104,14 @@
{ 0x10B, RSCreate(RS1056x400, RSText8) }, /* 132x50 */
{ 0x10C, RSCreate(RS1056x480, RSText8) }, /* 132x60 */
#endif
+#ifdef FBCON_HAS_CFB4
+ { ~0, RSCreate(RSNoxNo, RS4bpp ) },
+ { 0x010, RSCreate(RS640x350, RS4bpp ) },
+ { 0x012, RSCreate(RS640x480, RS4bpp ) },
+ { 0x102, RSCreate(RS800x600, RS4bpp ) },
+ { 0x104, RSCreate(RS1024x768, RS4bpp ) },
+ { 0x106, RSCreate(RS1280x1024, RS4bpp ) },
+#endif
{ 0, 0 }};
/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
@@ -4871,19 +5130,21 @@
static int hwcursor = 1; /* "matrox:nohwcursor" */
static int blink = 1; /* "matrox:noblink" */
static int sgram = 0; /* "matrox:sgram" */
+#ifdef CONFIG_MTRR
static int mtrr = 1; /* "matrox:nomtrr" */
+#endif
static int grayscale = 0; /* "matrox:grayscale" */
static unsigned int fastfont = 0; /* "matrox:fastfont:xxxxx" */
static int dev = -1; /* "matrox:dev:xxxxx" */
-static unsigned int vesa = 0x101; /* "matrox:vesa:xxxxx" */
+static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */
static int depth = -1; /* "matrox:depth:xxxxx" */
static unsigned int xres = 0; /* "matrox:xres:xxxxx" */
static unsigned int yres = 0; /* "matrox:yres:xxxxx" */
-static unsigned int upper = 0; /* "matrox:upper:xxxxx" */
-static unsigned int lower = 0; /* "matrox:lower:xxxxx" */
+static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */
+static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */
static unsigned int vslen = 0; /* "matrox:vslen:xxxxx" */
-static unsigned int left = 0; /* "matrox:left:xxxxx" */
-static unsigned int right = 0; /* "matrox:right:xxxxx" */
+static unsigned int left = ~0; /* "matrox:left:xxxxx" */
+static unsigned int right = ~0; /* "matrox:right:xxxxx" */
static unsigned int hslen = 0; /* "matrox:hslen:xxxxx" */
static unsigned int pixclock = 0; /* "matrox:pixclock:xxxxx" */
static int sync = -1; /* "matrox:sync:xxxxx" */
@@ -4893,7 +5154,7 @@
static char fontname[64]; /* "matrox:font:xxxxx" */
#ifndef MODULE
-__initfunc(void matroxfb_setup(char *options, int *ints)) {
+void __init matroxfb_setup(char *options, int *ints){
char *this_opt;
DBG("matroxfb_setup")
@@ -4901,7 +5162,7 @@
fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
if (!*this_opt) continue;
@@ -4954,6 +5215,31 @@
fv = simple_strtoul(this_opt+3, NULL, 0);
else if (!strncmp(this_opt, "mem:", 4))
mem = simple_strtoul(this_opt+4, NULL, 0);
+ else if (!strncmp(this_opt, "mode:", 5))
+ strcpy(videomode, this_opt+5);
+#ifdef CONFIG_FB_OF
+ else if (!strncmp(this_opt, "vmode:", 6)) {
+ unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
+ if (vmode > 0 && vmode <= VMODE_MAX)
+ default_vmode = vmode;
+ } else if (!strncmp(this_opt, "cmode:", 6)) {
+ unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
+ switch (cmode) {
+ case 0:
+ case 8:
+ default_cmode = CMODE_8;
+ break;
+ case 15:
+ case 16:
+ default_cmode = CMODE_16;
+ break;
+ case 24:
+ case 32:
+ default_cmode = CMODE_32;
+ break;
+ }
+ }
+#endif
else if (!strncmp(this_opt, "fastfont:", 9))
fastfont = simple_strtoul(this_opt+9, NULL, 0);
else if (!strcmp(this_opt, "nofastfont")) /* fastfont:N and nofastfont (nofastfont = fastfont:0) */
@@ -4987,8 +5273,10 @@
nobios = !value;
else if (!strcmp(this_opt, "init"))
noinit = !value;
+#ifdef CONFIG_MTRR
else if (!strcmp(this_opt, "mtrr"))
mtrr = value;
+#endif
else if (!strcmp(this_opt, "inv24"))
inv24 = value;
else if (!strcmp(this_opt, "cross4MB"))
@@ -5004,15 +5292,16 @@
}
}
}
+ return 0;
}
#endif
-__initfunc(static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int* realOffset, unsigned int *realSize)) {
+static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int* realOffset, unsigned int *realSize){
vaddr_t vm;
unsigned int offs;
unsigned int offs2;
unsigned char store;
- unsigned char bytes[16];
+ unsigned char bytes[32];
unsigned char* tmp;
unsigned long cbase;
unsigned long mbase;
@@ -5025,7 +5314,7 @@
maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */
/* at least 2MB */
if (maxSize < 0x0200000) return 0;
- if (maxSize > 0x1000000) maxSize = 0x1000000;
+ if (maxSize > 0x2000000) maxSize = 0x2000000;
mga_outb(M_EXTVGA_INDEX, 0x03);
mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80);
@@ -5080,7 +5369,7 @@
}
#ifdef CONFIG_FB_MATROX_MILLENIUM
-__initfunc(static int Ti3026_preinit(WPMINFO struct matrox_hw_state* hw)) {
+static int __init Ti3026_preinit(WPMINFO struct matrox_hw_state* hw){
static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
2048, 0};
@@ -5133,7 +5422,7 @@
return 0;
}
-__initfunc(static void Ti3026_reset(WPMINFO struct matrox_hw_state* hw)) {
+static void __init Ti3026_reset(WPMINFO struct matrox_hw_state* hw){
DBG("Ti3026_reset")
@@ -5163,20 +5452,28 @@
struct video_board {
int maxvram;
+ int maxdisplayable;
int accelID;
struct matrox_switch* lowlevel;
};
#ifdef CONFIG_FB_MATROX_MILLENIUM
-static struct video_board vbMillenium __initdata = {0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millenium};
-static struct video_board vbMillenium2 __initdata = {0x1000000, FB_ACCEL_MATROX_MGA2164W, &matrox_millenium};
-static struct video_board vbMillenium2A __initdata = {0x1000000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millenium};
+static struct video_board vbMillenium __initdata = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millenium};
+static struct video_board vbMillenium2 __initdata = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W, &matrox_millenium};
+static struct video_board vbMillenium2A __initdata = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millenium};
#endif /* CONFIG_FB_MATROX_MILLENIUM */
#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static struct video_board vbMystique __initdata = {0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique};
+static struct video_board vbMystique __initdata = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique};
#endif /* CONFIG_FB_MATROX_MYSTIQUE */
#ifdef CONFIG_FB_MATROX_G100
-static struct video_board vbG100 __initdata = {0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100};
-static struct video_board vbG200 __initdata = {0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100};
+static struct video_board vbG100 __initdata = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100};
+static struct video_board vbG200 __initdata = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100};
+#ifdef CONFIG_FB_MATROX_32MB
+/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for
+ whole 32MB */
+static struct video_board vbG400 __initdata = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};
+#else
+static struct video_board vbG400 __initdata = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};
+#endif
#endif
#define DEVF_VIDEO64BIT 0x01
@@ -5185,6 +5482,15 @@
#define DEVF_MILLENIUM2 0x08
#define DEVF_CROSS4MB 0x10
#define DEVF_TEXT4B 0x20
+#define DEVF_DDC_8_2 0x40
+#define DEVF_DMA 0x80
+#define DEVF_SUPPORT32MB 0x100
+#define DEVF_ANY_VXRES 0x200
+
+#define DEVF_G100 (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2) /* no doc, no vxres... */
+#define DEVF_G200 (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2 | DEVF_ANY_VXRES)
+#define DEVF_G400 (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2 | DEVF_ANY_VXRES | DEVF_SUPPORT32MB)
+
static struct board {
unsigned short vendor, device, rev, svid, sid;
unsigned int flags;
@@ -5229,88 +5535,94 @@
#ifdef CONFIG_FB_MATROX_G100
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_PCI,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"unknown G100 (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G100_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"Productiva G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"unknown G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
250000,
&vbG200,
"unknown G200 (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
220000,
&vbG200,
"MGA-G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"Mystique G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENIUM_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
250000,
&vbG200,
"Millennium G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MARVEL_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"Marvel G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"MGA-G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"unknown G200 (AGP)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0xFF,
+ 0, 0,
+ DEVF_G400,
+ 360000,
+ &vbG400,
+ "unknown G400 (AGP)"},
#endif
{0, 0, 0xFF,
0, 0,
@@ -5319,7 +5631,7 @@
NULL,
NULL}};
-__initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
+static int __init initMatrox2(WPMINFO struct display* d, struct board* b){
unsigned long ctrlptr_phys = 0;
unsigned long video_base_phys = 0;
unsigned int memsize;
@@ -5348,17 +5660,21 @@
ACCESS_FBINFO(devflags.vgastepdisp) = 64;
ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8;
}
+#ifdef CONFIG_FB_MATROX_32MB
+ ACCESS_FBINFO(devflags.support32MB) = b->flags & DEVF_SUPPORT32MB;
+#endif
+ ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES);
ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
if (ACCESS_FBINFO(capable.cross4MB) < 0)
ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB;
if (b->flags & DEVF_SWAPS) {
- ctrlptr_phys = ACCESS_FBINFO(pcidev)->base_address[1] & ~0x3FFF;
- video_base_phys = ACCESS_FBINFO(pcidev)->base_address[0] & ~0x7FFFFF; /* aligned at 8MB (or 16 for Mill 2) */
+ ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
+ video_base_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
} else {
- ctrlptr_phys = ACCESS_FBINFO(pcidev)->base_address[0] & ~0x3FFF;
- video_base_phys = ACCESS_FBINFO(pcidev)->base_address[1] & ~0x7FFFFF; /* aligned at 8MB */
+ ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
+ video_base_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
}
if (!ctrlptr_phys) {
printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n");
@@ -5472,8 +5788,8 @@
return -ENOMEM;
}
ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len);
- if (ACCESS_FBINFO(video.len_usable) > 0x08000000)
- ACCESS_FBINFO(video.len_usable) = 0x08000000;
+ if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable)
+ ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable;
#ifdef CONFIG_MTRR
if (mtrr) {
ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1);
@@ -5482,11 +5798,16 @@
}
#endif /* CONFIG_MTRR */
+ if (!ACCESS_FBINFO(devflags.novga))
+ request_region(0x3C0, 32, "matrox");
+ ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
+
/* validate params, autodetect k, M */
if (fh < 1000) fh *= 1000; /* 1kHz minimum */
if (maxclk < 1000) maxclk *= 1000; /* kHz -> Hz, MHz -> kHz */
if (maxclk < 1000000) maxclk *= 1000; /* kHz -> Hz, 1MHz minimum */
- vesa &= 0x1DFF; /* mask out clearscreen, acceleration and so on */
+ if (vesa != ~0)
+ vesa &= 0x1DFF; /* mask out clearscreen, acceleration and so on */
ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0;
ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh;
@@ -5504,19 +5825,19 @@
}
{
int res = RSResolution(RSptr->info)-1;
- if (!left)
+ if (left == ~0)
left = timmings[res].left;
if (!xres)
xres = timmings[res].xres;
- if (!right)
+ if (right == ~0)
right = timmings[res].right;
if (!hslen)
hslen = timmings[res].hslen;
- if (!upper)
+ if (upper == ~0)
upper = timmings[res].upper;
if (!yres)
yres = timmings[res].yres;
- if (!lower)
+ if (lower == ~0)
lower = timmings[res].lower;
if (!vslen)
vslen = timmings[res].vslen;
@@ -5525,6 +5846,7 @@
if (depth == -1)
depth = RSDepth(RSptr->info);
}
+#if 0
if (sync == -1) {
sync = 0;
if (yres < 400)
@@ -5532,31 +5854,7 @@
else if (yres < 480)
sync |= FB_SYNC_VERT_HIGH_ACT;
}
- if (xres < 320)
- xres = 320;
- if (xres > 2048)
- xres = 2048;
- if (yres < 200)
- yres = 200;
- if (yres > 2048)
- yres = 2048;
- {
- unsigned int tmp;
-
- if (fv) {
- tmp = fv * (upper + yres + lower + vslen);
- if ((tmp < fh) || (fh == 0)) fh = tmp;
- }
- if (fh) {
- tmp = fh * (left + xres + right + hslen);
- if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
- }
- maxclk = (maxclk + 499) / 500;
- if (maxclk) {
- tmp = (2000000000 + maxclk) / maxclk;
- if (tmp > pixclock) pixclock = tmp;
- }
- }
+#endif
if ((depth == RSText8) && (!*ACCESS_FBINFO(fbcon.fontname))) {
strcpy(ACCESS_FBINFO(fbcon.fontname), "VGA8x8");
}
@@ -5564,27 +5862,8 @@
vesafb_defined.green = colors[depth-1].green;
vesafb_defined.blue = colors[depth-1].blue;
vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel;
- if (pixclock < 2000) /* > 500MHz */
- pixclock = 4000; /* 250MHz */
- if (pixclock > 1000000)
- pixclock = 1000000; /* 1MHz */
- vesafb_defined.xres = xres;
- vesafb_defined.yres = yres;
- vesafb_defined.xoffset = 0;
- vesafb_defined.yoffset = 0;
vesafb_defined.grayscale = grayscale;
- vesafb_defined.pixclock = pixclock;
- vesafb_defined.left_margin = left;
- vesafb_defined.right_margin = right;
- vesafb_defined.hsync_len = hslen;
- vesafb_defined.upper_margin = upper;
- vesafb_defined.lower_margin = lower;
- vesafb_defined.vsync_len = vslen;
- vesafb_defined.sync = sync;
vesafb_defined.vmode = 0;
-
- if (!ACCESS_FBINFO(devflags.novga))
- request_region(0x3C0, 32, "matrox");
if (noaccel)
vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;
@@ -5597,8 +5876,60 @@
ACCESS_FBINFO(fbcon.updatevar) = &matroxfb_updatevar;
ACCESS_FBINFO(fbcon.blank) = &matroxfb_blank;
ACCESS_FBINFO(fbcon.flags) = FBINFO_FLAG_DEFAULT;
- ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;
+
+#if 0
+ fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL,
+ NULL, 0, NULL, vesafb_defined.bits_per_pixel);
+#endif
+ /* mode modifiers */
+ if (sync != -1)
+ vesafb_defined.sync = sync;
+ if (hslen)
+ vesafb_defined.hsync_len = hslen;
+ if (vslen)
+ vesafb_defined.vsync_len = vslen;
+ if (left != ~0)
+ vesafb_defined.left_margin = left;
+ if (right != ~0)
+ vesafb_defined.right_margin = right;
+ if (upper != ~0)
+ vesafb_defined.upper_margin = upper;
+ if (lower != ~0)
+ vesafb_defined.lower_margin = lower;
+ if (xres)
+ vesafb_defined.xres = xres;
+ if (yres)
+ vesafb_defined.yres = yres;
+ /* fv, fh, maxclk limits was specified */
+ {
+ unsigned int tmp;
+
+ if (fv) {
+ tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres
+ + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
+ if ((tmp < fh) || (fh == 0)) fh = tmp;
+ }
+ if (fh) {
+ tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres
+ + vesafb_defined.right_margin + vesafb_defined.hsync_len);
+ if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
+ }
+ maxclk = (maxclk + 499) / 500;
+ if (maxclk) {
+ tmp = (2000000000 + maxclk) / maxclk;
+ if (tmp > pixclock) pixclock = tmp;
+ }
+ }
+ if (pixclock) {
+ if (pixclock < 2000) /* > 500MHz */
+ pixclock = 4000; /* 250MHz */
+ if (pixclock > 1000000)
+ pixclock = 1000000; /* 1MHz */
+ vesafb_defined.pixclock = pixclock;
+ }
+
+ /* FIXME: Where to move this?! */
#if defined(CONFIG_FB_OF)
#if defined(CONFIG_FB_COMPAT_XPMAC)
strcpy(ACCESS_FBINFO(matrox_name), "MTRX,"); /* OpenFirmware naming convension */
@@ -5608,30 +5939,30 @@
#endif
if ((xres <= 640) && (yres <= 480)) {
struct fb_var_screeninfo var;
- int default_vmode = nvram_read_byte(NV_VMODE);
- int default_cmode = nvram_read_byte(NV_CMODE);
-
- if ((default_vmode <= 0) || (default_vmode > VMODE_MAX))
+ if (default_vmode == VMODE_NVRAM) {
+ default_vmode = nvram_read_byte(NV_VMODE);
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+ default_vmode = VMODE_CHOOSE;
+ }
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
default_vmode = VMODE_640_480_60;
- if ((default_cmode < CMODE_8) || (default_cmode > CMODE_32))
+ if (default_cmode == CMODE_NVRAM)
+ default_cmode = nvram_read_byte(NV_CMODE);
+ if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_cmode = CMODE_8;
if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {
var.accel_flags = vesafb_defined.accel_flags;
var.xoffset = var.yoffset = 0;
vesafb_defined = var; /* Note: mac_vmode_to_var() doesnot set all parameters */
- }
+ }
}
#endif
- {
- int pixel_size = vesafb_defined.bits_per_pixel;
-
- vesafb_defined.xres_virtual = matroxfb_pitch_adjust(PMINFO vesafb_defined.xres, pixel_size);
- if (nopan) {
- vesafb_defined.yres_virtual = vesafb_defined.yres;
- } else {
- vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
- to yres_virtual * xres_virtual < 2^32 */
- }
+ vesafb_defined.xres_virtual = vesafb_defined.xres;
+ if (nopan) {
+ vesafb_defined.yres_virtual = vesafb_defined.yres;
+ } else {
+ vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
+ to yres_virtual * xres_virtual < 2^32 */
}
if (matroxfb_set_var(&vesafb_defined, -2, &ACCESS_FBINFO(fbcon))) {
printk(KERN_ERR "matroxfb: cannot set required parameters\n");
@@ -5647,8 +5978,9 @@
/* We do not have to set currcon to 0... register_framebuffer do it for us on first console
* and we do not want currcon == 0 for subsequent framebuffers */
- if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0)
+ if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) {
return -EINVAL;
+ }
printk("fb%d: %s frame buffer device\n",
GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
if (ACCESS_FBINFO(currcon) < 0) {
@@ -5663,7 +5995,7 @@
static struct matrox_fb_info* fb_list = NULL;
-__initfunc(static int matrox_init(void)) {
+static int __init matrox_init(void){
struct pci_dev* pdev = NULL;
DBG("matrox_init")
@@ -5756,7 +6088,7 @@
#ifndef MODULE
static int __init initialized = 0;
-__initfunc(void matroxfb_init(void))
+void __init matroxfb_init(void)
{
DBG("matroxfb_init")
@@ -5764,10 +6096,12 @@
initialized = 1;
matrox_init();
}
+ if (!fb_list) return -ENXIO;
+ return 0;
}
#if defined(CONFIG_FB_OF)
-__initfunc(int matrox_of_init(struct device_node *dp)) {
+int __init matrox_of_init(struct device_node *dp){
DBG("matrox_of_init");
if (!initialized) {
@@ -5781,8 +6115,8 @@
#else
-MODULE_AUTHOR("(c) 1998 Petr Vandrovec <vandrove@vc.cvut.cz>");
-MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200");
+MODULE_AUTHOR("(c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400");
MODULE_PARM(mem, "i");
MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
MODULE_PARM(disabled, "i");
@@ -5802,7 +6136,7 @@
MODULE_PARM(mtrr, "i");
MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
MODULE_PARM(sgram, "i");
-MODULE_PARM_DESC(sgram, "Indicates that G200 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
+MODULE_PARM_DESC(sgram, "Indicates that G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
MODULE_PARM(inv24, "i");
MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
MODULE_PARM(inverse, "i");
@@ -5855,14 +6189,20 @@
MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)");
MODULE_PARM(cross4MB, "i");
MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
+#ifdef CONFIG_FB_OF
+MODULE_PARM(vmode, "i");
+MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
+MODULE_PARM(cmode, "i");
+MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)");
+#endif
-__initfunc(int init_module(void)) {
+int __init init_module(void){
DBG("init_module")
#ifdef DEBUG
if( disabled )
- return 0;
+ return -ENXIO;
#endif /* DEBUG */
if (depth == 0)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)