|
From: Andy P. <at...@us...> - 2002-04-11 14:36:01
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox
In directory usw-pr-cvs1:/tmp/cvs-serv12946/video/matrox
Modified Files:
i2c-matroxfb.c matroxfb_DAC1064.c matroxfb_DAC1064.h
matroxfb_Ti3026.c matroxfb_accel.c matroxfb_base.c
matroxfb_base.h matroxfb_crtc2.c matroxfb_g450.c
matroxfb_g450.h matroxfb_maven.c matroxfb_misc.c
Log Message:
synch 2.4.15 commit 54
Index: i2c-matroxfb.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/i2c-matroxfb.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- i2c-matroxfb.c 14 Jan 2001 18:56:08 -0000 1.1.1.1
+++ i2c-matroxfb.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -1,3 +1,15 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
+ *
+ * (c) 1998-2001 Petr Vandrovec <van...@vc...>
+ *
+ * Version: 1.51 2001/01/19
+ *
+ * See matroxfb_base.c for contributors.
+ *
+ */
+
#include "matroxfb_base.h"
#include "matroxfb_maven.h"
#include <linux/i2c.h>
@@ -282,8 +294,8 @@
return NULL;
matroxfb_DAC_lock_irqsave(flags);
- matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0x00);
- matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0xFF);
+ matroxfb_DAC_out(PMINFO DAC_XGENIODATA, 0xFF);
+ matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0x00);
matroxfb_DAC_unlock_irqrestore(flags);
memset(m2info, 0, sizeof(*m2info));
@@ -343,9 +355,10 @@
matroxfb_unregister_driver(&i2c_matroxfb);
}
-MODULE_AUTHOR("(c) 1999 Petr Vandrovec <van...@vc...>");
+MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <van...@vc...>");
MODULE_DESCRIPTION("Support module providing I2C buses present on Matrox videocards");
module_init(i2c_matroxfb_init);
module_exit(i2c_matroxfb_exit);
/* no __setup required */
+MODULE_LICENSE("GPL");
Index: matroxfb_DAC1064.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_DAC1064.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- matroxfb_DAC1064.c 25 Feb 2001 23:15:12 -0000 1.1.1.2
+++ matroxfb_DAC1064.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -4,7 +4,7 @@
*
* (c) 1998-2001 Petr Vandrovec <van...@vc...>
*
- * Version: 1.52 2001/02/02
+ * Version: 1.54 2001/09/09
*
* See matroxfb_base.c for contributors.
*
@@ -33,12 +33,14 @@
#define DAC1064_OPT_RESERVED 0x10
static void matroxfb_DAC1064_flashcursor(unsigned long ptr) {
+ unsigned long flags;
+
#define minfo ((struct matrox_fb_info*)ptr)
- matroxfb_DAC_lock();
+ matroxfb_DAC_lock_irqsave(flags);
outDAC1064(PMINFO M1064_XCURCTRL, inDAC1064(PMINFO M1064_XCURCTRL) ^ M1064_XCURCTRL_DIS ^ M1064_XCURCTRL_XGA);
ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
add_timer(&ACCESS_FBINFO(cursor.timer));
- matroxfb_DAC_unlock();
+ matroxfb_DAC_unlock_irqrestore(flags);
#undef minfo
}
@@ -317,9 +319,10 @@
outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);
if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
outDAC1064(PMINFO 0x20, 0x04);
- outDAC1064(PMINFO 0x1F, 0x00);
+ outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));
if (ACCESS_FBINFO(devflags.g450dac)) {
- outDAC1064(PMINFO M1064_X8B, 0xCC); /* only matrox know... */
+ outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC); /* only matrox know... */
+ outDAC1064(PMINFO M1064_XPWRCTRL, 0x1F); /* powerup everything */
outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);
}
}
@@ -416,7 +419,12 @@
outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);
- if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs))) {
+ /*
+ * We must ALWAYS reprogram hardware due to broken XF4 matrox drivers...
+ *
+ * if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs)))
+ */
+ {
unsigned int i;
for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {
@@ -714,7 +722,8 @@
ACCESS_FBINFO(capable.vxres) = vxres_g100;
ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
- ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) != FB_ACCEL_MATROX_MGAG100;
+ ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
+ ? ACCESS_FBINFO(devflags.sgram) : 1;
ACCESS_FBINFO(primout) = &m1064;
@@ -843,6 +852,11 @@
}
}
DAC1064_setmclk(PMINFO hw, DAC1064_OPT_RESERVED | DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV1 | DAC1064_OPT_SCLK_PLL, 133333);
+ if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {
+ if (ACCESS_FBINFO(devflags.dfp_type) == -1) {
+ ACCESS_FBINFO(devflags.dfp_type) = inDAC1064(PMINFO 0x1F);
+ }
+ }
if (ACCESS_FBINFO(devflags.noinit))
return;
MGAG100_setPixClock(PMINFO 4, 25175);
@@ -921,3 +935,4 @@
EXPORT_SYMBOL(DAC1064_global_init);
EXPORT_SYMBOL(DAC1064_global_restore);
#endif
+MODULE_LICENSE("GPL");
Index: matroxfb_DAC1064.h
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_DAC1064.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_DAC1064.h 14 Jan 2001 18:56:13 -0000 1.1.1.1
+++ matroxfb_DAC1064.h 11 Apr 2002 13:26:54 -0000 1.2
@@ -138,11 +138,13 @@
#define M1064_XTVO_DATA 0x88
#define M1064_XOUTPUTCONN 0x8A
-#define M1064_X8B 0x8B
+#define M1064_XSYNCCTRL 0x8B
#define M1064_XPIXPLL2STAT 0x8C
#define M1064_XPIXPLL2P 0x8D
#define M1064_XPIXPLL2N 0x8E
#define M1064_XPIXPLL2M 0x8F
+
+#define M1064_XPWRCTRL 0xA0
enum POS1064 {
POS1064_XCURADDL=0, POS1064_XCURADDH, POS1064_XCURCTRL,
Index: matroxfb_Ti3026.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_Ti3026.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_Ti3026.c 14 Jan 2001 18:56:17 -0000 1.1.1.1
+++ matroxfb_Ti3026.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -279,12 +279,14 @@
0x00, 0x00, TVP3026_XCURCTRL_DIS };
static void matroxfb_ti3026_flashcursor(unsigned long ptr) {
+ unsigned long flags;
+
#define minfo ((struct matrox_fb_info*)ptr)
- matroxfb_DAC_lock();
+ matroxfb_DAC_lock_irqsave(flags);
outTi3026(PMINFO TVP3026_XCURCTRL, inTi3026(PMINFO TVP3026_XCURCTRL) ^ TVP3026_XCURCTRL_DIS ^ TVP3026_XCURCTRL_XGA);
ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;
add_timer(&ACCESS_FBINFO(cursor.timer));
- matroxfb_DAC_unlock();
+ matroxfb_DAC_unlock_irqrestore(flags);
#undef minfo
}
@@ -861,3 +863,4 @@
};
EXPORT_SYMBOL(matrox_millennium);
#endif
+MODULE_LICENSE("GPL");
Index: matroxfb_accel.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_accel.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_accel.c 14 Jan 2001 18:56:22 -0000 1.1.1.1
+++ matroxfb_accel.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -2,9 +2,9 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
- * (c) 1998,1999,2000 Petr Vandrovec <van...@vc...>
+ * (c) 1998-2001 Petr Vandrovec <van...@vc...>
*
- * Version: 1.50 2000/08/10
+ * Version: 1.51 2001/06/18
*
* MTRR stuff: 1998 Tom Rini <tr...@ke...>
*
@@ -129,6 +129,10 @@
mga_outl(M_YDSTORG, curr_ydstorg(MINFO));
if (ACCESS_FBINFO(capable.plnwt))
mga_outl(M_PLNWT, -1);
+ if (ACCESS_FBINFO(capable.srcorg)) {
+ mga_outl(M_SRCORG, 0);
+ mga_outl(M_DSTORG, 0);
+ }
mga_outl(M_OPMODE, mopmode);
mga_outl(M_CXBNDRY, 0xFFFF0000);
mga_outl(M_YTOP, 0);
@@ -650,13 +654,15 @@
#ifdef FBCON_HAS_CFB8
static void matrox_cfb8_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+ u_int16_t c;
u_int32_t fgx, bgx;
MINFO_FROM_DISP(p);
DBG_HEAVY("matroxfb_cfb8_putcs");
- fgx = attr_fgcol(p, scr_readw(s));
- bgx = attr_bgcol(p, scr_readw(s));
+ c = scr_readw(s);
+ fgx = attr_fgcol(p, c);
+ bgx = attr_bgcol(p, c);
fgx |= (fgx << 8);
fgx |= (fgx << 16);
bgx |= (bgx << 8);
@@ -667,13 +673,15 @@
#ifdef FBCON_HAS_CFB16
static void matrox_cfb16_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+ u_int16_t c;
u_int32_t fgx, bgx;
MINFO_FROM_DISP(p);
DBG_HEAVY("matroxfb_cfb16_putcs");
- fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u_int16_t*)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol(p, c)];
fgx |= (fgx << 16);
bgx |= (bgx << 16);
ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
@@ -682,13 +690,15 @@
#if defined(FBCON_HAS_CFB32) || defined(FBCON_HAS_CFB24)
static void matrox_cfb32_putcs(struct vc_data* conp, struct display* p, const unsigned short* s, int count, int yy, int xx) {
+ u_int16_t c;
u_int32_t fgx, bgx;
MINFO_FROM_DISP(p);
DBG_HEAVY("matroxfb_cfb32_putcs");
- fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, scr_readw(s))];
- bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, scr_readw(s))];
+ c = scr_readw(s);
+ fgx = ((u_int32_t*)p->dispsw_data)[attr_fgcol(p, c)];
+ bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol(p, c)];
ACCESS_FBINFO(curr.putcs)(fgx, bgx, p, s, count, yy, xx);
}
#endif
@@ -896,12 +906,14 @@
unsigned int offs;
unsigned int attr;
unsigned int step;
+ u_int16_t c;
CRITFLAGS
MINFO_FROM_DISP(p);
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);
+ c = scr_readw(s);
+ attr = attr_fgcol(p, c) | (attr_bgcol(p, c) << 4);
CRITBEGIN
@@ -1233,3 +1245,4 @@
ACCESS_FBINFO(curr.putcs) = matrox_cfbX_putcs;
}
}
+MODULE_LICENSE("GPL");
Index: matroxfb_base.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_base.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- matroxfb_base.c 25 Feb 2001 23:15:12 -0000 1.1.1.2
+++ matroxfb_base.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -4,7 +4,7 @@
*
* (c) 1998-2001 Petr Vandrovec <van...@vc...>
*
- * Version: 1.52 2001/02/02
+ * Version: 1.54 2001/09/09
*
* MTRR stuff: 1998 Tom Rini <tr...@ke...>
*
@@ -72,6 +72,9 @@
* "Ken Aaker" <kd...@rc...>
* memtype extension (needed for GXT130P RS/6000 adapter)
*
+ * "Uns Lider" <uns...@mi...>
+ * G100 PLNWT fixes
+ *
* (following author is not in any relation with this code, but his code
* is included in this driver)
*
@@ -985,8 +988,6 @@
#undef minfo
}
-static int matroxfb_switch(int con, struct fb_info *info);
-
static int matroxfb_get_vblank(CPMINFO struct fb_vblank *vblank)
{
unsigned int sts1;
@@ -1180,7 +1181,7 @@
fb_ioctl: matroxfb_ioctl,
};
-static int matroxfb_switch(int con, struct fb_info *info)
+int matroxfb_switch(int con, struct fb_info *info)
{
#define minfo ((struct matrox_fb_info*)info)
struct fb_cmap* cmap;
@@ -1323,6 +1324,7 @@
static unsigned int fh; /* "matrox:fh:xxxxxk" */
static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */
static int dfp; /* "matrox:dfp */
+static int dfp_type = -1; /* "matrox:dfp:xxx */
static int memtype = -1; /* "matrox:memtype:xxx" */
static char fontname[64]; /* "matrox:font:xxxxx" */
@@ -1409,12 +1411,12 @@
#define DEVF_VIDEO64BIT 0x0001
#define DEVF_SWAPS 0x0002
-/* #define DEVF_recycled 0x0004 */
-/* #define DEVF_recycled 0x0008 */
+#define DEVF_SRCORG 0x0004
+#define DEVF_BOTHDACS 0x0008 /* put CRTC1 on both outputs by default */
#define DEVF_CROSS4MB 0x0010
#define DEVF_TEXT4B 0x0020
#define DEVF_DDC_8_2 0x0040
-/* #define DEVF_recycled 0x0080 */
+#define DEVF_G550DAC 0x0080
#define DEVF_SUPPORT32MB 0x0100
#define DEVF_ANY_VXRES 0x0200
#define DEVF_TEXT16B 0x0400
@@ -1424,12 +1426,13 @@
#define DEVF_G450DAC 0x4000
#define DEVF_GCORE (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2)
-#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE)
+#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG)
#define DEVF_G100 (DEVF_GCORE) /* no doc, no vxres... */
#define DEVF_G200 (DEVF_G2CORE)
#define DEVF_G400 (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)
/* if you'll find how to drive DFP... */
-#define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC)
+#define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG)
+#define DEVF_G550 (DEVF_G450 | DEVF_G550DAC | DEVF_BOTHDACS)
static struct board {
unsigned short vendor, device, rev, svid, sid;
@@ -1473,13 +1476,13 @@
"Mystique 220 (PCI)"},
#endif
#ifdef CONFIG_FB_MATROX_G100
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF,
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_PCI,
DEVF_G100,
230000,
&vbG100,
"MGA-G100 (PCI)"},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF,
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF,
0, 0,
DEVF_G100,
230000,
@@ -1556,25 +1559,31 @@
DEVF_G200,
230000,
&vbG200,
- "unknown G200 (AGP)"},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0x80,
+ "G200 (AGP)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP,
DEVF_G400,
360000,
&vbG400,
"Millennium G400 MAX (AGP)"},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0x80,
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80,
0, 0,
DEVF_G400,
300000,
&vbG400,
- "unknown G400 (AGP)"},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0xFF,
+ "G400 (AGP)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0xFF,
0, 0,
DEVF_G450,
500000, /* ??? vco goes up to 900MHz... */
&vbG400,
- "unknown G450 (AGP)"},
+ "G450"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, 0xFF,
+ 0, 0,
+ DEVF_G550,
+ 500000,
+ &vbG400,
+ "G550"},
#endif
{0, 0, 0xFF,
0, 0,
@@ -1611,6 +1620,7 @@
printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name);
ACCESS_FBINFO(capable.plnwt) = 1;
+ ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG;
ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT;
if (b->flags & DEVF_TEXT4B) {
ACCESS_FBINFO(devflags.vgastep) = 4;
@@ -1636,7 +1646,18 @@
if (dfp)
ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_DFP;
}
+ if (b->flags & DEVF_BOTHDACS) {
+#ifdef CONFIG_FB_MATROX_G450
+ ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;
+ ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_SECONDARY;
+#else
+ printk(KERN_INFO "Only digital output of G550 is now working (in analog mode). Enable G450 support in\n");
+ printk(KERN_INFO "kernel configuration if you have analog monitor connected to G550 analog output.\n");
+#endif
+ }
+ ACCESS_FBINFO(devflags.dfp_type) = dfp_type;
ACCESS_FBINFO(devflags.g450dac) = b->flags & DEVF_G450DAC;
+ ACCESS_FBINFO(devflags.g550dac) = b->flags & DEVF_G550DAC;
ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
@@ -2054,7 +2075,7 @@
ACCESS_FBINFO(pcidev) = pdev;
ACCESS_FBINFO(dead) = 0;
ACCESS_FBINFO(usecount) = 0;
- pdev->driver_data = MINFO;
+ pci_set_drvdata(pdev, MINFO);
/* CMDLINE */
memcpy(ACCESS_FBINFO(fbcon.fontname), fontname, sizeof(ACCESS_FBINFO(fbcon.fontname)));
/* DEVFLAGS */
@@ -2116,7 +2137,7 @@
static void pci_remove_matrox(struct pci_dev* pdev) {
struct matrox_fb_info* minfo;
- minfo = pdev->driver_data;
+ minfo = pci_get_drvdata(pdev);
matroxfb_remove(PMINFO 1);
}
@@ -2134,7 +2155,7 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
#endif
#ifdef CONFIG_FB_MATROX_G100
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100,
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -2142,7 +2163,9 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP,
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
#endif
{0, 0,
@@ -2151,6 +2174,7 @@
MODULE_DEVICE_TABLE(pci, matroxfb_devices);
+
static struct pci_driver matroxfb_driver = {
name: "matroxfb",
id_table: matroxfb_devices,
@@ -2348,7 +2372,7 @@
if (!options || !*options)
return 0;
- for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ while ((this_opt = strsep(&options, ",")) != NULL) {
if (!*this_opt) continue;
dprintk("matroxfb_setup: option %s\n", this_opt);
@@ -2401,6 +2425,10 @@
mem = simple_strtoul(this_opt+4, NULL, 0);
else if (!strncmp(this_opt, "mode:", 5))
strncpy(videomode, this_opt+5, sizeof(videomode)-1);
+ else if (!strncmp(this_opt, "dfp:", 4)) {
+ dfp_type = simple_strtoul(this_opt+4, NULL, 0);
+ dfp = 1;
+ }
#ifdef CONFIG_PPC
else if (!strncmp(this_opt, "vmode:", 6)) {
unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
@@ -2483,7 +2511,7 @@
return 0;
}
-static int __init initialized = 0;
+static int __initdata initialized = 0;
int __init matroxfb_init(void)
{
@@ -2495,6 +2523,7 @@
initialized = 1;
matrox_init();
}
+ hotplug = 1;
/* never return failure, user can hotplug matrox later... */
return 0;
}
@@ -2505,6 +2534,8 @@
MODULE_AUTHOR("(c) 1998-2001 Petr Vandrovec <van...@vc...>");
MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400/G450");
+MODULE_LICENSE("GPL");
+
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");
@@ -2526,7 +2557,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/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
+MODULE_PARM_DESC(sgram, "Indicates that G100/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");
@@ -2581,6 +2612,8 @@
MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
MODULE_PARM(dfp, "i");
MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)");
+MODULE_PARM(dfp_type, "i");
+MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)");
#ifdef CONFIG_PPC
MODULE_PARM(vmode, "i");
MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
@@ -2622,6 +2655,7 @@
module_exit(matrox_done);
EXPORT_SYMBOL(matroxfb_register_driver);
EXPORT_SYMBOL(matroxfb_unregister_driver);
+EXPORT_SYMBOL(matroxfb_switch);
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
Index: matroxfb_base.h
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_base.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -u -r1.1.1.2 -r1.2
--- matroxfb_base.h 25 Feb 2001 23:15:12 -0000 1.1.1.2
+++ matroxfb_base.h 11 Apr 2002 13:26:54 -0000 1.2
@@ -1,8 +1,8 @@
/*
*
- * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450
*
- * (c) 1998,1999,2000 Petr Vandrovec <van...@vc...>
+ * (c) 1998,1999,2000,2001 Petr Vandrovec <van...@vc...>
*
*/
#ifndef __MATROXFB_H__
@@ -102,7 +102,7 @@
#endif /* MATROXFB_DEBUG */
-#ifndef __i386__
+#if !defined(__i386__) && !defined(__x86_64__)
#ifndef ioremap_nocache
#define ioremap_nocache(X,Y) ioremap(X,Y)
#endif
@@ -117,7 +117,7 @@
/* I benchmarked PII/350MHz with G200... MEMCPY, MEMCPYTOIO and WRITEL are on same speed ( <2% diff) */
/* so that means that G200 speed (or AGP speed?) is our limit... I do not have benchmark to test, how */
/* much of PCI bandwidth is used during transfers... */
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
#define MEMCPYTOIO_MEMCPY
#else
#define MEMCPYTOIO_WRITEL
@@ -146,21 +146,6 @@
#ifndef PCI_SS_VENDOR_ID_MATROX
#define PCI_SS_VENDOR_ID_MATROX PCI_VENDOR_ID_MATROX
#endif
-#ifndef PCI_DEVICE_ID_MATROX_G200_PCI
-#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G200_AGP
-#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521
-#endif
-#ifndef PCI_DEVICE_ID_MATROX_G100
-#define PCI_DEVICE_ID_MATROX_G100 0x1000
-#endif
-#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
@@ -492,6 +477,7 @@
int cross4MB;
int text;
int plnwt;
+ int srcorg;
} capable;
struct {
unsigned int size;
@@ -532,6 +518,8 @@
/* 0 except for 6MB Millenium */
int memtype;
int g450dac;
+ int g550dac;
+ int dfp_type;
} devflags;
struct display_switch dispsw;
struct {
@@ -738,6 +726,7 @@
/* G200 only */
#define M_SRCORG 0x2CB4
+#define M_DSTORG 0x2CB8
#define M_RAMDAC_BASE 0x3C00
Index: matroxfb_crtc2.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_crtc2.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_crtc2.c 14 Jan 2001 18:56:38 -0000 1.1.1.1
+++ matroxfb_crtc2.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -1,3 +1,13 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
+ *
+ * (c) 1998-2001 Petr Vandrovec <van...@vc...>
+ *
+ * Version: 1.52 2001/05/25
+ *
+ */
+
#include "matroxfb_maven.h"
#include "matroxfb_crtc2.h"
#include "matroxfb_misc.h"
@@ -120,14 +130,31 @@
if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY)
tmp |= 0x00100000; /* connect CRTC2 to DAC */
}
+ if (mt->interlaced) {
+ tmp |= 0x02000000; /* interlaced, second field is bigger, as G450 apparently ignores it */
+ mt->VDisplay >>= 1;
+ mt->VSyncStart >>= 1;
+ mt->VSyncEnd >>= 1;
+ mt->VTotal >>= 1;
+ }
mga_outl(0x3C10, tmp | 0x10000000); /* depth and so on... 0x10000000 is VIDRST polarity */
mga_outl(0x3C14, ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8));
mga_outl(0x3C18, ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8));
mga_outl(0x3C1C, ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1));
mga_outl(0x3C20, ((mt->VSyncEnd - 1) << 16) | (mt->VSyncStart - 1));
mga_outl(0x3C24, ((mt->VSyncStart) << 16) | (mt->HSyncStart)); /* preload */
- mga_outl(0x3C28, pos); /* vmemory start */
- mga_outl(0x3C40, p->var.xres_virtual * (p->var.bits_per_pixel >> 3));
+ {
+ u_int32_t linelen = p->var.xres_virtual * (p->var.bits_per_pixel >> 3);
+ if (mt->interlaced) {
+ /* field #0 is smaller, so... */
+ mga_outl(0x3C2C, pos); /* field #1 vmemory start */
+ mga_outl(0x3C28, pos + linelen); /* field #0 vmemory start */
+ linelen <<= 1;
+ } else {
+ mga_outl(0x3C28, pos); /* vmemory start */
+ }
+ mga_outl(0x3C40, linelen);
+ }
tmp = 0x0FFF0000; /* line compare */
if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
tmp |= 0x00000100;
@@ -145,11 +172,20 @@
static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,
struct fb_var_screeninfo* var) {
unsigned int pos;
+ unsigned int linelen;
+ unsigned int pixelsize;
#define minfo (m2info->primary_dev)
- pos = (var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel >> 3;
+ pixelsize = var->bits_per_pixel >> 3;
+ linelen = var->xres_virtual * pixelsize;
+ pos = var->yoffset * linelen + var->xoffset * pixelsize;
pos += m2info->video.offbase;
- mga_outl(0x3C28, pos);
+ if (var->vmode & FB_VMODE_INTERLACED) {
+ mga_outl(0x3C2C, pos);
+ mga_outl(0x3C28, pos + linelen);
+ } else {
+ mga_outl(0x3C28, pos);
+ }
#undef minfo
}
@@ -649,6 +685,9 @@
void* oldcrtc2;
d = kmalloc(sizeof(*d), GFP_KERNEL);
+ if (!d) {
+ return -ENOMEM;
+ }
memset(d, 0, sizeof(*d));
@@ -687,15 +726,13 @@
m2info->mmio.len = ACCESS_FBINFO(mmio.len);
/*
- * If we have two outputs, connect CRTC2 to it...
+ * If we have unused output, connect CRTC2 to it...
*/
- if (ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_SECONDARY) {
+ if ((ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_SECONDARY) &&
+ !(ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) &&
+ !(ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)) {
ACCESS_FBINFO(output.sh) |= MATROXFB_OUTPUT_CONN_SECONDARY;
- ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
- if (ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_DFP) {
- ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_DFP;
- ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_DFP;
- }
+ ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_DFP;
}
matroxfb_dh_set_var(&matroxfb_dh_defined, -2, &m2info->fbcon);
@@ -800,8 +837,9 @@
matroxfb_unregister_driver(&crtc2);
}
-MODULE_AUTHOR("(c) 1999,2000 Petr Vandrovec <van...@vc...>");
+MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <van...@vc...>");
MODULE_DESCRIPTION("Matrox G400 CRTC2 driver");
+MODULE_LICENSE("GPL");
module_init(matroxfb_crtc2_init);
module_exit(matroxfb_crtc2_exit);
/* we do not have __setup() yet */
Index: matroxfb_g450.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_g450.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_g450.c 14 Jan 2001 18:56:45 -0000 1.1.1.1
+++ matroxfb_g450.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -1,3 +1,15 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
+ *
+ * (c) 1998-2001 Petr Vandrovec <van...@vc...>
+ *
+ * Version: 1.51 2001/01/19
+ *
+ * See matroxfb_base.c for contributors.
+ *
+ */
+
#include "matroxfb_g450.h"
#include "matroxfb_misc.h"
#include "matroxfb_DAC1064.h"
@@ -6,17 +18,20 @@
static int matroxfb_g450_get_reg(WPMINFO int reg) {
int val;
+ unsigned long flags;
- matroxfb_DAC_lock();
+ matroxfb_DAC_lock_irqsave(flags);
val = matroxfb_DAC_in(PMINFO reg);
- matroxfb_DAC_unlock();
+ matroxfb_DAC_unlock_irqrestore(flags);
return val;
}
static int matroxfb_g450_set_reg(WPMINFO int reg, int val) {
- matroxfb_DAC_lock();
+ unsigned long flags;
+
+ matroxfb_DAC_lock_irqsave(flags);
matroxfb_DAC_out(PMINFO reg, val);
- matroxfb_DAC_unlock();
+ matroxfb_DAC_unlock_irqrestore(flags);
return 0;
}
@@ -28,36 +43,53 @@
3
};
+static const struct matrox_pll_features g550_pll = {
+ 135000,
+ 27000,
+ 4, 127,
+ 0, 9,
+ 3
+};
+
static void DAC1064_calcclock(unsigned int freq, unsigned int fmax,
- unsigned int* in, unsigned int* feed, unsigned int* post) {
+ unsigned int* in, unsigned int* feed, unsigned int* post,
+ unsigned int timmings) {
unsigned int fvco;
unsigned int p;
- fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p);
- /* 0 => 100 ... 275 MHz
- 1 => 243 ... 367 MHz
- 2 => 320 ... 475 MHz
- 3 => 453 ... 556 MHz
- 4 => 540 ... 594 MHz
- 5 => 588 ... 621 MHz
- 6 => 626 ... 637 MHz
- 7 => 631 ... 642 MHz
-
- As you can see, never choose frequency > 621 MHz, there is unavailable gap...
- Just to be sure, currently driver uses 110 ... 500 MHz range.
- */
- if (fvco <= 260000)
- ;
- else if (fvco <= 350000)
- p |= 0x08;
- else if (fvco <= 460000)
- p |= 0x10;
- else if (fvco <= 550000)
- p |= 0x18;
- else if (fvco <= 590000)
- p |= 0x20;
- else
- p |= 0x28;
+ switch (timmings) {
+ default:
+ fvco = matroxfb_PLL_calcclock(&maven_pll, freq, fmax, in, feed, &p);
+ /* 0 => 100 ... 275 MHz
+ 1 => 243 ... 367 MHz
+ 2 => 320 ... 475 MHz
+ 3 => 453 ... 556 MHz
+ 4 => 540 ... 594 MHz
+ 5 => 588 ... 621 MHz
+ 6 => 626 ... 637 MHz
+ 7 => 631 ... 642 MHz
+
+ As you can see, never choose frequency > 621 MHz, there is unavailable gap...
+ Just to be sure, currently driver uses 110 ... 500 MHz range.
+ */
+ if (fvco <= 260000)
+ ;
+ else if (fvco <= 350000)
+ p |= 0x08;
+ else if (fvco <= 460000)
+ p |= 0x10;
+ else if (fvco <= 550000)
+ p |= 0x18;
+ else if (fvco <= 590000)
+ p |= 0x20;
+ else
+ p |= 0x28;
+ break;
+ case 1:
+ fvco = matroxfb_PLL_calcclock(&g550_pll, freq, fmax, in, feed, &p);
+ /* p |= 0x00; */
+ break;
+ }
*post = p;
return;
}
@@ -67,7 +99,7 @@
struct mavenregs* m) {
unsigned int a, b, c;
- DAC1064_calcclock(mt->pixclock, 500000, &a, &b, &c);
+ DAC1064_calcclock(mt->pixclock, 300000, &a, &b, &c, m2info->timmings);
m->regs[0x80] = a;
m->regs[0x81] = b;
m->regs[0x82] = c;
@@ -136,6 +168,7 @@
ACCESS_FBINFO(altout.output) = &matroxfb_g450_altout;
up_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;
+ matroxfb_switch(ACCESS_FBINFO(currcon), (struct fb_info*)MINFO);
return 0;
}
@@ -168,6 +201,11 @@
}
memset(m2info, 0, sizeof(*m2info));
m2info->primary_dev = MINFO;
+ if (ACCESS_FBINFO(devflags.g550dac)) {
+ m2info->timmings = 1;
+ } else {
+ m2info->timmings = 0;
+ }
if (matroxfb_g450_connect(m2info)) {
kfree(m2info);
printk(KERN_ERR "matroxfb_g450: G450 DAC failed to initialize\n");
@@ -195,7 +233,8 @@
matroxfb_unregister_driver(&g450);
}
-MODULE_AUTHOR("(c) 2000 Petr Vandrovec <van...@vc...>");
+MODULE_AUTHOR("(c) 2000-2001 Petr Vandrovec <van...@vc...>");
MODULE_DESCRIPTION("Matrox G450 secondary output driver");
+MODULE_LICENSE("GPL");
module_init(matroxfb_g450_init);
module_exit(matroxfb_g450_exit);
Index: matroxfb_g450.h
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_g450.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_g450.h 14 Jan 2001 18:56:45 -0000 1.1.1.1
+++ matroxfb_g450.h 11 Apr 2002 13:26:54 -0000 1.2
@@ -6,6 +6,7 @@
struct matroxfb_g450_info {
struct matrox_fb_info* primary_dev;
+ unsigned int timmings;
};
#endif /* __MATROXFB_MAVEN_H__ */
Index: matroxfb_maven.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_maven.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_maven.c 14 Jan 2001 18:56:42 -0000 1.1.1.1
+++ matroxfb_maven.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -1,3 +1,15 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
+ *
+ * (c) 1998-2001 Petr Vandrovec <van...@vc...>
+ *
+ * Version: 1.51 2001/01/19
+ *
+ * See matroxfb_base.c for contributors.
+ *
+ */
+
#include "matroxfb_maven.h"
#include "matroxfb_misc.h"
#include "matroxfb_DAC1064.h"
@@ -1030,8 +1042,9 @@
i2c_del_driver(&maven_driver);
}
-MODULE_AUTHOR("(c) 1999,2000 Petr Vandrovec <van...@vc...>");
+MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <van...@vc...>");
MODULE_DESCRIPTION("Matrox G200/G400 Matrox MGA-TVO driver");
+MODULE_LICENSE("GPL");
module_init(matroxfb_maven_init);
module_exit(matroxfb_maven_exit);
/* we do not have __setup() yet */
Index: matroxfb_misc.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/video/matrox/matroxfb_misc.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- matroxfb_misc.c 14 Jan 2001 18:56:45 -0000 1.1.1.1
+++ matroxfb_misc.c 11 Apr 2002 13:26:54 -0000 1.2
@@ -4,7 +4,7 @@
*
* (c) 1998,1999,2000 Petr Vandrovec <van...@vc...>
*
- * Version: 1.50 2000/08/10
+ * Version: 1.54 2001/09/09
*
* MTRR stuff: 1998 Tom Rini <tr...@ke...>
*
@@ -63,6 +63,9 @@
* "Mark Vojkovich" <mvo...@uc...>
* G400 support
*
+ * "David C. Hansen" <hav...@us...>
+ * Fixes
+ *
* (following author is not in any relation with this code, but his code
* is included in this driver)
*
@@ -654,7 +657,7 @@
EXPORT_SYMBOL(matroxfb_fastfont_init); /* DAC1064, Ti3026 */
EXPORT_SYMBOL(matroxfb_vgaHWinit); /* DAC1064, Ti3026 */
EXPORT_SYMBOL(matroxfb_vgaHWrestore); /* DAC1064, Ti3026 */
-#ifdef MATROXFB_USE_SPINLOCK
-spinlock_t matroxfb_spinlock = SPIN_LOCK_UNLOCKED;
-EXPORT_SYMBOL(matroxfb_spinlock);
-#endif
+
+MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <van...@vc...>");
+MODULE_DESCRIPTION("Miscellaneous support for Matrox video cards");
+MODULE_LICENSE("GPL");
|