patch-2.4.21 linux-2.4.21/drivers/video/matrox/matroxfb_crtc2.c
Next file: linux-2.4.21/drivers/video/matrox/matroxfb_crtc2.h
Previous file: linux-2.4.21/drivers/video/matrox/matroxfb_base.h
Back to the patch index
Back to the overall index
- Lines: 638
- Date:
2003-06-13 07:51:37.000000000 -0700
- Orig file:
linux-2.4.20/drivers/video/matrox/matroxfb_crtc2.c
- Orig date:
2002-08-02 17:39:45.000000000 -0700
diff -urN linux-2.4.20/drivers/video/matrox/matroxfb_crtc2.c linux-2.4.21/drivers/video/matrox/matroxfb_crtc2.c
@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
*
- * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
+ * (c) 1998-2002 Petr Vandrovec <vandrove@vc.cvut.cz>
*
* Portions Copyright (c) 2001 Matrox Graphics Inc.
*
- * Version: 1.62 2001/11/29
+ * Version: 1.64 2002/06/10
*
*/
@@ -28,8 +28,8 @@
static int matroxfb_dh_getcolreg(unsigned regno, unsigned *red, unsigned *green,
unsigned *blue, unsigned *transp, struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
- if (regno > 16)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
+ if (regno >= 16)
return 1;
*red = m2info->palette[regno].red;
*blue = m2info->palette[regno].blue;
@@ -41,10 +41,10 @@
static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
struct display* p;
- if (regno > 16)
+ if (regno >= 16)
return 1;
m2info->palette[regno].red = red;
m2info->palette[regno].blue = blue;
@@ -84,86 +84,129 @@
#undef m2info
}
-static void do_install_cmap(struct matroxfb_dh_fb_info* m2info, struct display* p) {
- if (p->cmap.len)
- fb_set_cmap(&p->cmap, 1, matroxfb_dh_setcolreg, &m2info->fbcon);
+static inline void my_install_cmap(struct matroxfb_dh_fb_info* m2info)
+{
+ /* Do not touch this code if you do not understand what it does! */
+ /* Never try to use do_install_cmap() instead. It is crap. */
+ struct fb_cmap* cmap = &m2info->currcon_display->cmap;
+
+ if (cmap->len)
+ fb_set_cmap(cmap, 1, matroxfb_dh_setcolreg, &m2info->fbcon);
else
fb_set_cmap(fb_default_cmap(16), 1, matroxfb_dh_setcolreg, &m2info->fbcon);
}
+
static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
struct my_timming* mt,
struct display* p,
int mode,
unsigned int pos) {
- u_int32_t tmp;
+ struct matrox_crtc2 c2;
MINFO_FROM(m2info->primary_dev);
switch (mode) {
case 15:
- tmp = 0x00200000;
+ c2.ctl = 0x00200000;
break;
case 16:
- tmp = 0x00400000;
+ c2.ctl = 0x00400000;
break;
/* case 32: */
default:
- tmp = 0x00800000;
+ c2.ctl = 0x00800000;
break;
}
-
- if (ACCESS_FBINFO(output.sh)) {
- tmp |= 0x00000001; /* enable CRTC2 */
-
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
- if (ACCESS_FBINFO(devflags.g450dac)) {
- tmp |= 0x00000006; /* source from secondary pixel PLL */
- /* no vidrst */
- } else {
- tmp |= 0x00000002; /* source from VDOCLK */
- tmp |= 0xC0000000; /* enable vvidrst & hvidrst */
- /* MGA TVO is our clock source */
+ c2.ctl |= 0x00000001; /* enable CRTC2 */
+ c2.datactl = 0;
+ if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) {
+ if (ACCESS_FBINFO(devflags.g450dac)) {
+ c2.ctl |= 0x00000006; /* source from secondary pixel PLL */
+ /* no vidrst when in monitor mode */
+ if (ACCESS_FBINFO(outputs[1]).mode != MATROXFB_OUTPUT_MODE_MONITOR) {
+ c2.ctl |= 0xC0001000; /* Enable H/V vidrst */
}
- } else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
- tmp |= 0x00000004; /* source from pixclock */
- /* PIXPLL is our clock source */
- }
-
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY)
- tmp |= 0x00100000; /* connect CRTC2 to DAC */
+ } else {
+ c2.ctl |= 0x00000002; /* source from VDOCLK */
+ c2.ctl |= 0xC0000000; /* enable vvidrst & hvidrst */
+ /* MGA TVO is our clock source */
+ }
+ } else if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) {
+ c2.ctl |= 0x00000004; /* source from pixclock */
+ /* PIXPLL is our clock source */
+ }
+ if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) {
+ c2.ctl |= 0x00100000; /* connect CRTC2 to DAC */
}
if (mt->interlaced) {
- tmp |= 0x02000000; /* interlaced, second field is bigger, as G450 apparently ignores it */
+ c2.ctl |= 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 */
+ if ((mt->HTotal & 7) == 2) {
+ c2.datactl |= 0x00000010;
+ mt->HTotal &= ~7;
+ }
+ c2.ctl |= 0x10000000; /* 0x10000000 is VIDRST polarity */
+ c2.hparam = ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8);
+ c2.hsync = ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8);
+ c2.vparam = ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1);
+ c2.vsync = ((mt->VSyncEnd - 1) << 16) | (mt->VSyncStart - 1);
+ c2.preload = ((mt->VSyncStart) << 16) | (mt->HSyncStart);
+ mga_outl(0x3C14, c2.hparam);
+ mga_outl(0x3C18, c2.hsync);
+ mga_outl(0x3C1C, c2.vparam);
+ mga_outl(0x3C20, c2.vsync);
+ mga_outl(0x3C24, c2.preload);
{
u_int32_t linelen = p->var.xres_virtual * (p->var.bits_per_pixel >> 3);
- if (mt->interlaced) {
+ if (c2.ctl & 0x02000000) {
/* field #0 is smaller, so... */
mga_outl(0x3C2C, pos); /* field #1 vmemory start */
mga_outl(0x3C28, pos + linelen); /* field #0 vmemory start */
linelen <<= 1;
+ m2info->interlaced = 1;
} else {
mga_outl(0x3C28, pos); /* vmemory start */
+ m2info->interlaced = 0;
}
mga_outl(0x3C40, linelen);
}
- tmp = 0x0FFF0000; /* line compare */
- if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
- tmp |= 0x00000100;
- if (mt->sync & FB_SYNC_VERT_HIGH_ACT)
- tmp |= 0x00000200;
- mga_outl(0x3C44, tmp);
- mga_outl(0x3C4C, 0); /* data control */
+ mga_outl(0x3C4C, c2.datactl); /* data control */
+ if (c2.ctl & 0x02000000) {
+ int i;
+
+ mga_outl(0x3C10, c2.ctl & ~0x02000000);
+ for (i = 0; i < 2; i++) {
+ unsigned int nl;
+ unsigned int lastl = 0;
+
+ while ((nl = mga_inl(0x3C48) & 0xFFF) >= lastl) {
+ lastl = nl;
+ }
+ }
+ }
+ mga_outl(0x3C10, c2.ctl);
+ ACCESS_FBINFO(hw).crtc2.ctl = c2.ctl;
+ {
+ u_int32_t tmp;
+
+ tmp = 0x0FFF0000; /* line compare */
+ if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
+ tmp |= 0x00000100;
+ if (mt->sync & FB_SYNC_VERT_HIGH_ACT)
+ tmp |= 0x00000200;
+ mga_outl(0x3C44, tmp);
+ }
+}
+
+static void matroxfb_dh_disable(struct matroxfb_dh_fb_info* m2info) {
+ MINFO_FROM(m2info->primary_dev);
+
+ mga_outl(0x3C10, 0x00000004); /* disable CRTC2, CRTC1->DAC1, PLL as clock source */
+ ACCESS_FBINFO(hw).crtc2.ctl = 0x00000004;
}
static void matroxfb_dh_cfbX_init(struct matroxfb_dh_fb_info* m2info,
@@ -176,19 +219,18 @@
unsigned int pos;
unsigned int linelen;
unsigned int pixelsize;
+ MINFO_FROM(m2info->primary_dev);
-#define minfo (m2info->primary_dev)
pixelsize = var->bits_per_pixel >> 3;
linelen = var->xres_virtual * pixelsize;
pos = var->yoffset * linelen + var->xoffset * pixelsize;
pos += m2info->video.offbase;
- if (var->vmode & FB_VMODE_INTERLACED) {
+ if (m2info->interlaced) {
mga_outl(0x3C2C, pos);
mga_outl(0x3C28, pos + linelen);
} else {
mga_outl(0x3C28, pos);
}
-#undef minfo
}
static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info,
@@ -292,7 +334,7 @@
}
static int matroxfb_dh_open(struct fb_info* info, int user) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
MINFO_FROM(m2info->primary_dev);
if (MINFO) {
@@ -305,7 +347,7 @@
}
static int matroxfb_dh_release(struct fb_info* info, int user) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
MINFO_FROM(m2info->primary_dev);
if (MINFO) {
@@ -316,7 +358,7 @@
static int matroxfb_dh_get_fix(struct fb_fix_screeninfo* fix, int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
struct display* p;
if (con >= 0)
@@ -345,7 +387,7 @@
static int matroxfb_dh_get_var(struct fb_var_screeninfo* var, int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
if (con < 0)
*var = m2info->fbcon.disp->var;
else
@@ -356,7 +398,7 @@
static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
struct display* p;
int chgvar;
int visual;
@@ -390,7 +432,7 @@
chgvar = 0;
p->var = *var;
/* cmap */
- p->screen_base = vaddr_va(m2info->video.vbase);
+ p->screen_base = m2info->fbcon.screen_base = vaddr_va(m2info->video.vbase);
p->visual = visual;
p->ypanstep = 1;
p->ywrapstep = 0;
@@ -405,48 +447,52 @@
if (con == m2info->currcon) {
struct my_timming mt;
unsigned int pos;
+ int out;
+ int cnt;
matroxfb_var2my(var, &mt);
+ mt.crtc = MATROXFB_SRC_CRTC2;
/* CRTC2 delay */
mt.delay = 34;
pos = (var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel >> 3;
pos += m2info->video.offbase;
- DAC1064_global_init(PMINFO2);
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
- if (ACCESS_FBINFO(primout))
- ACCESS_FBINFO(primout)->compute(MINFO, &mt);
+ cnt = 0;
+ down_read(&ACCESS_FBINFO(altout).lock);
+ for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
+ if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) {
+ cnt++;
+ if (ACCESS_FBINFO(outputs[out]).output->compute) {
+ ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt);
+ }
+ }
}
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
- down_read(&ACCESS_FBINFO(altout.lock));
- if (ACCESS_FBINFO(altout.output))
- ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt);
- up_read(&ACCESS_FBINFO(altout.lock));
+ ACCESS_FBINFO(crtc2).pixclock = mt.pixclock;
+ ACCESS_FBINFO(crtc2).mnp = mt.mnp;
+ up_read(&ACCESS_FBINFO(altout).lock);
+ if (cnt) {
+ matroxfb_dh_restore(m2info, &mt, p, mode, pos);
+ } else {
+ matroxfb_dh_disable(m2info);
}
- matroxfb_dh_restore(m2info, &mt, p, mode, pos);
+ DAC1064_global_init(PMINFO2);
DAC1064_global_restore(PMINFO2);
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
- if (ACCESS_FBINFO(primout))
- ACCESS_FBINFO(primout)->program(MINFO);
- }
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
- down_read(&ACCESS_FBINFO(altout.lock));
- if (ACCESS_FBINFO(altout.output))
- ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device));
- up_read(&ACCESS_FBINFO(altout.lock));
- }
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
- if (ACCESS_FBINFO(primout))
- ACCESS_FBINFO(primout)->start(MINFO);
+ down_read(&ACCESS_FBINFO(altout).lock);
+ for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
+ if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2 &&
+ ACCESS_FBINFO(outputs[out]).output->program) {
+ ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data);
+ }
}
- if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
- down_read(&ACCESS_FBINFO(altout.lock));
- if (ACCESS_FBINFO(altout.output))
- ACCESS_FBINFO(altout.output)->start(ACCESS_FBINFO(altout.device));
- up_read(&ACCESS_FBINFO(altout.lock));
+ for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
+ if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2 &&
+ ACCESS_FBINFO(outputs[out]).output->start) {
+ ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data);
+ }
}
+ up_read(&ACCESS_FBINFO(altout).lock);
matroxfb_dh_cfbX_init(m2info, p);
- do_install_cmap(m2info, p);
+ my_install_cmap(m2info);
}
return 0;
#undef m2info
@@ -454,7 +500,7 @@
static int matroxfb_dh_get_cmap(struct fb_cmap* cmap, int kspc, int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
struct display* dsp;
if (con < 0)
@@ -473,7 +519,7 @@
static int matroxfb_dh_set_cmap(struct fb_cmap* cmap, int kspc, int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
struct display* dsp;
if (con < 0)
@@ -497,7 +543,7 @@
static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual ||
var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)
return -EINVAL;
@@ -530,7 +576,7 @@
unsigned long arg,
int con,
struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
MINFO_FROM(m2info->primary_dev);
DBG("matroxfb_crtc2_ioctl")
@@ -557,38 +603,84 @@
case MATROXFB_SET_OUTPUT_CONNECTION:
{
u_int32_t tmp;
+ int out;
+ int changes;
if (get_user(tmp, (u_int32_t*)arg))
return -EFAULT;
- if (tmp & ~ACCESS_FBINFO(output.all))
- return -EINVAL;
- if (tmp & ACCESS_FBINFO(output.ph))
- return -EINVAL;
- if (tmp & MATROXFB_OUTPUT_CONN_DFP)
- return -EINVAL;
- if ((ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP) && tmp)
- return -EINVAL;
- if (tmp == ACCESS_FBINFO(output.sh))
+ for (out = 0; out < 32; out++) {
+ if (tmp & (1 << out)) {
+ if (out >= MATROXFB_MAX_OUTPUTS)
+ return -ENXIO;
+ if (!ACCESS_FBINFO(outputs[out]).output)
+ return -ENXIO;
+ switch (ACCESS_FBINFO(outputs[out]).src) {
+ case MATROXFB_SRC_NONE:
+ case MATROXFB_SRC_CRTC2:
+ break;
+ default:
+ return -EBUSY;
+ }
+ }
+ }
+ if (ACCESS_FBINFO(devflags.panellink)) {
+ if (tmp & MATROXFB_OUTPUT_CONN_DFP)
+ return -EINVAL;
+ if ((ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) && tmp)
+ return -EBUSY;
+ }
+ changes = 0;
+ for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
+ if (tmp & (1 << out)) {
+ if (ACCESS_FBINFO(outputs[out]).src != MATROXFB_SRC_CRTC2) {
+ changes = 1;
+ ACCESS_FBINFO(outputs[out]).src = MATROXFB_SRC_CRTC2;
+ }
+ } else if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) {
+ changes = 1;
+ ACCESS_FBINFO(outputs[out]).src = MATROXFB_SRC_NONE;
+ }
+ }
+ if (!changes)
return 0;
- ACCESS_FBINFO(output.sh) = tmp;
matroxfb_dh_switch(m2info->currcon, info);
return 0;
}
case MATROXFB_GET_OUTPUT_CONNECTION:
{
- if (put_user(ACCESS_FBINFO(output.sh), (u_int32_t*)arg))
+ u_int32_t conn = 0;
+ int out;
+
+ for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
+ if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC2) {
+ conn |= 1 << out;
+ }
+ }
+ if (put_user(conn, (u_int32_t*)arg))
return -EFAULT;
return 0;
}
case MATROXFB_GET_AVAILABLE_OUTPUTS:
{
- u_int32_t tmp;
+ u_int32_t tmp = 0;
+ int out;
- /* we do not support DFP from CRTC2 */
- tmp = ACCESS_FBINFO(output.all) & ~ACCESS_FBINFO(output.ph) & ~MATROXFB_OUTPUT_CONN_DFP;
- /* CRTC1 in DFP mode disables CRTC2 at all (I know, I'm lazy) */
- if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)
- tmp = 0;
+ for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {
+ if (ACCESS_FBINFO(outputs[out]).output) {
+ switch (ACCESS_FBINFO(outputs[out]).src) {
+ case MATROXFB_SRC_NONE:
+ case MATROXFB_SRC_CRTC2:
+ tmp |= 1 << out;
+ break;
+ }
+ }
+ }
+ if (ACCESS_FBINFO(devflags.panellink)) {
+ tmp &= ~MATROXFB_OUTPUT_CONN_DFP;
+ if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1) {
+ tmp = 0;
+ }
+ }
if (put_user(tmp, (u_int32_t*)arg))
return -EFAULT;
return 0;
@@ -598,6 +690,24 @@
#undef m2info
}
+static int matroxfb_dh_blank(int blank, struct fb_info* info) {
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
+ switch (blank) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ default:;
+ }
+ /* do something... */
+ return 0;
+#undef m2info
+}
+
+static void matroxfb_dh_blank24(int blank, struct fb_info* info) {
+ matroxfb_dh_blank(blank, info);
+}
+
static struct fb_ops matroxfb_dh_ops = {
owner: THIS_MODULE,
fb_open: matroxfb_dh_open,
@@ -612,7 +722,7 @@
};
static int matroxfb_dh_switch(int con, struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
struct fb_cmap* cmap;
struct display* p;
@@ -635,25 +745,12 @@
}
static int matroxfb_dh_updatevar(int con, struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
+#define m2info (list_entry(info, struct matroxfb_dh_fb_info, fbcon))
matroxfb_dh_pan_var(m2info, &fb_display[con].var);
return 0;
#undef m2info
}
-static void matroxfb_dh_blank(int blank, struct fb_info* info) {
-#define m2info ((struct matroxfb_dh_fb_info*)info)
- switch (blank) {
- case 1:
- case 2:
- case 3:
- case 4:
- default:;
- }
- /* do something... */
-#undef m2info
-}
-
static struct fb_var_screeninfo matroxfb_dh_defined = {
640,480,640,480,/* W,H, virtual W,H */
0,0, /* offset */
@@ -692,7 +789,7 @@
m2info->fbcon.disp = d;
m2info->fbcon.switch_con = &matroxfb_dh_switch;
m2info->fbcon.updatevar = &matroxfb_dh_updatevar;
- m2info->fbcon.blank = &matroxfb_dh_blank;
+ m2info->fbcon.blank = &matroxfb_dh_blank24;
m2info->fbcon.flags = FBINFO_FLAG_DEFAULT;
m2info->currcon = -1;
m2info->currcon_display = d;
@@ -722,11 +819,10 @@
/*
* If we have unused output, connect CRTC2 to it...
*/
- 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.sh) &= ~MATROXFB_OUTPUT_CONN_DFP;
+ if (ACCESS_FBINFO(outputs[1]).output &&
+ ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_NONE &&
+ ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_NONE) {
+ ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_CRTC2;
}
matroxfb_dh_set_var(&matroxfb_dh_defined, -2, &m2info->fbcon);
@@ -739,7 +835,7 @@
}
down_write(&ACCESS_FBINFO(crtc2.lock));
oldcrtc2 = ACCESS_FBINFO(crtc2.info);
- ACCESS_FBINFO(crtc2.info) = &m2info->fbcon;
+ ACCESS_FBINFO(crtc2.info) = m2info;
up_write(&ACCESS_FBINFO(crtc2.lock));
if (oldcrtc2) {
printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n",
@@ -768,16 +864,16 @@
#define minfo (m2info->primary_dev)
if (m2info->fbcon_registered) {
int id;
- struct fb_info* crtc2;
+ struct matroxfb_dh_fb_info* crtc2;
down_write(&ACCESS_FBINFO(crtc2.lock));
crtc2 = ACCESS_FBINFO(crtc2.info);
- if (crtc2 == &m2info->fbcon)
+ if (crtc2 == m2info)
ACCESS_FBINFO(crtc2.info) = NULL;
up_write(&ACCESS_FBINFO(crtc2.lock));
- if (crtc2 != &m2info->fbcon) {
+ if (crtc2 != m2info) {
printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n",
- crtc2, &m2info->fbcon);
+ crtc2, m2info);
printk(KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");
return;
}
@@ -815,6 +911,7 @@
static void matroxfb_crtc2_remove(struct matrox_fb_info* minfo, void* crtc2) {
matroxfb_dh_deregisterfb(crtc2);
+ kfree(crtc2);
}
static struct matroxfb_driver crtc2 = {
@@ -831,7 +928,7 @@
matroxfb_unregister_driver(&crtc2);
}
-MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_AUTHOR("(c) 1999-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");
MODULE_DESCRIPTION("Matrox G400 CRTC2 driver");
MODULE_LICENSE("GPL");
module_init(matroxfb_crtc2_init);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)