Commit daf389a0 authored by Petr Vandrovec's avatar Petr Vandrovec

Use arrays for holding Matrox output drivers, it is nicer and more extensible

than current solution with per-CRTC bitmaps.
parent ca5d8440
......@@ -300,7 +300,7 @@ void DAC1064_global_init(WPMINFO2) {
hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;
hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;
hw->DACreg[POS1064_XOUTPUTCONN] = 0x01; /* output #1 enabled */
if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {
if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1) {
if (ACCESS_FBINFO(devflags.g450dac)) {
hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL2;
hw->DACreg[POS1064_XOUTPUTCONN] = 0x05; /* output #1 enabled; CRTC1 connected to output #2 */
......@@ -308,15 +308,15 @@ void DAC1064_global_init(WPMINFO2) {
hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;
hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;
}
} else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {
} else if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) {
hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;
hw->DACreg[POS1064_XOUTPUTCONN] = 0x09; /* output #1 enabled; CRTC2 connected to output #2 */
} else if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)
} else if (ACCESS_FBINFO(outputs[2]).src == MATROXFB_SRC_CRTC1)
hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;
else
hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;
if ((ACCESS_FBINFO(output.ph) | ACCESS_FBINFO(output.sh)) & MATROXFB_OUTPUT_CONN_PRIMARY)
if (ACCESS_FBINFO(outputs[0]).src != MATROXFB_SRC_NONE)
hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;
}
......@@ -505,6 +505,7 @@ static int m1064_compute(void* outdev, struct my_timming* m) {
}
static struct matrox_altout m1064 = {
.name = "Primary output",
.compute = m1064_compute,
};
......@@ -651,7 +652,10 @@ static int MGA1064_preinit(WPMINFO2) {
ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
ACCESS_FBINFO(cursor.timer.function) = matroxfb_DAC1064_flashcursor;
ACCESS_FBINFO(primout) = &m1064;
ACCESS_FBINFO(outputs[0]).output = &m1064;
ACCESS_FBINFO(outputs[0]).src = MATROXFB_SRC_CRTC1;
ACCESS_FBINFO(outputs[0]).data = MINFO;
ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
if (ACCESS_FBINFO(devflags.noinit))
return 0; /* do not modify settings */
......@@ -835,7 +839,10 @@ static int MGAG100_preinit(WPMINFO2) {
ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
? ACCESS_FBINFO(devflags.sgram) : 1;
ACCESS_FBINFO(primout) = &m1064;
ACCESS_FBINFO(outputs[0]).output = &m1064;
ACCESS_FBINFO(outputs[0]).src = MATROXFB_SRC_CRTC1;
ACCESS_FBINFO(outputs[0]).data = MINFO;
ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
if (ACCESS_FBINFO(devflags.g450dac)) {
/* we must do this always, BIOS does not do it for us
......
......@@ -2,11 +2,11 @@
*
* Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (c) 1998,1999,2000 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 2000/11/29
* Version: 1.64 2002/06/10
*
* MTRR stuff: 1998 Tom Rini <trini@kernel.crashing.org>
*
......@@ -84,6 +84,7 @@
#include "matroxfb_Ti3026.h"
#include "matroxfb_misc.h"
#include "matroxfb_accel.h"
#include <linux/matroxfb.h>
#ifdef CONFIG_FB_MATROX_MILLENIUM
#define outTi3026 matroxfb_DAC_out
......@@ -811,6 +812,10 @@ static void Ti3026_reset(WPMINFO2) {
ti3026_ramdac_init(PMINFO2);
}
static struct matrox_altout ti3026_output = {
.name = "Primary output",
};
static int Ti3026_preinit(WPMINFO2) {
static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
......@@ -829,6 +834,11 @@ static int Ti3026_preinit(WPMINFO2) {
ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1;
ACCESS_FBINFO(cursor.timer.function) = matroxfb_ti3026_flashcursor;
ACCESS_FBINFO(outputs[0]).data = MINFO;
ACCESS_FBINFO(outputs[0]).output = &ti3026_output;
ACCESS_FBINFO(outputs[0]).src = MATROXFB_SRC_CRTC1;
ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
if (ACCESS_FBINFO(devflags.noinit))
return 0;
/* preserve VGA I/O, BIOS and PPC */
......
This diff is collapsed.
......@@ -396,12 +396,17 @@ struct matrox_accel_data {
};
struct matrox_altout {
const char *name;
int (*compute)(void* altout_dev, struct my_timming* input);
int (*program)(void* altout_dev);
int (*start)(void* altout_dev);
int (*verifymode)(void* altout_dev, u_int32_t mode);
};
#define MATROXFB_SRC_NONE 0
#define MATROXFB_SRC_CRTC1 1
#define MATROXFB_SRC_CRTC2 2
enum mga_chip { MGA_2064, MGA_2164, MGA_1064, MGA_1164, MGA_G100, MGA_G200, MGA_G400, MGA_G450, MGA_G550 };
struct matrox_bios {
......@@ -435,22 +440,20 @@ struct matrox_fb_info {
struct pci_dev* pcidev;
struct {
u_int32_t all;
u_int32_t ph;
u_int32_t sh;
} output;
struct matrox_altout* primout;
struct {
struct fb_info* info;
struct rw_semaphore lock;
} crtc2;
struct {
struct rw_semaphore lock;
} altout;
#define MATROXFB_MAX_OUTPUTS 3
struct {
unsigned int src;
struct matrox_altout* output;
void* device;
struct rw_semaphore lock;
void* data;
unsigned int mode;
} altout;
} outputs[MATROXFB_MAX_OUTPUTS];
#define MATROXFB_MAX_FB_DRIVERS 5
struct matroxfb_driver* (drivers[MATROXFB_MAX_FB_DRIVERS]);
......@@ -539,6 +542,7 @@ struct matrox_fb_info {
int memtype;
int g450dac;
int dfp_type;
int panellink; /* G400 DFP possible (not G450/G550) */
int dualhead;
unsigned int fbResource;
} devflags;
......
......@@ -118,25 +118,22 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
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 */
}
} else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {
tmp |= 0x00000004; /* source from pixclock */
/* PIXPLL is our clock source */
tmp |= 0x00000001; /* enable CRTC2 */
if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC2) {
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 */
}
if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY)
tmp |= 0x00100000; /* connect CRTC2 to DAC */
} else if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) {
tmp |= 0x00000004; /* source from pixclock */
/* PIXPLL is our clock source */
}
if (ACCESS_FBINFO(outputs[0]).src == MATROXFB_SRC_CRTC2) {
tmp |= 0x00100000; /* connect CRTC2 to DAC */
}
if (mt->interlaced) {
tmp |= 0x02000000; /* interlaced, second field is bigger, as G450 apparently ignores it */
......@@ -172,6 +169,12 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mga_outl(0x3C4C, 0); /* data control */
}
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 */
}
static void matroxfb_dh_cfbX_init(struct matroxfb_dh_fb_info* m2info,
struct display* p) {
/* no acceleration for secondary head... */
......@@ -411,6 +414,8 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
if (con == m2info->fbcon.currcon) {
struct my_timming mt;
unsigned int pos;
int out;
int cnt;
matroxfb_var2my(var, &mt);
/* CRTC2 delay */
......@@ -418,39 +423,38 @@ static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,
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)
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.output)->compute(ACCESS_FBINFO(altout.device), &mt);
up_read(&ACCESS_FBINFO(altout.lock));
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)
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.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)
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.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);
my_install_cmap(m2info);
}
......@@ -563,38 +567,84 @@ static int matroxfb_dh_ioctl(struct inode* inode,
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->fbcon.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;
/* 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;
u_int32_t tmp = 0;
int out;
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;
......@@ -730,11 +780,10 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {
/*
* 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);
......@@ -839,7 +888,7 @@ static void matroxfb_crtc2_exit(void) {
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);
......
......@@ -34,30 +34,31 @@ static int matroxfb_g450_program(void* md) {
}
static struct matrox_altout matroxfb_g450_altout = {
.name = "Secondary output",
.compute = matroxfb_g450_compute,
.program = matroxfb_g450_program,
};
void matroxfb_g450_connect(WPMINFO2) {
/* hardware is not G450... */
if (!ACCESS_FBINFO(devflags.g450dac))
return;
down_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(altout.device) = MINFO;
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(fbcon.currcon), (struct fb_info*)MINFO);
if (ACCESS_FBINFO(devflags.g450dac)) {
down_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_CRTC1;
ACCESS_FBINFO(outputs[1]).data = MINFO;
ACCESS_FBINFO(outputs[1]).output = &matroxfb_g450_altout;
ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock));
}
}
void matroxfb_g450_shutdown(WPMINFO2) {
ACCESS_FBINFO(output.all) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
ACCESS_FBINFO(output.ph) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
down_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(altout.device) = NULL;
ACCESS_FBINFO(altout.output) = NULL;
up_write(&ACCESS_FBINFO(altout.lock));
if (ACCESS_FBINFO(devflags.g450dac)) {
down_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE;
ACCESS_FBINFO(outputs[1]).output = NULL;
ACCESS_FBINFO(outputs[1]).data = NULL;
ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock));
}
}
EXPORT_SYMBOL(matroxfb_g450_connect);
......
......@@ -327,7 +327,7 @@ static void maven_init_TVdata(const struct maven_data* md, struct mavenregs* dat
}, MODE_NTSC, 525, 60 };
MINFO_FROM(md->primary_head);
if (ACCESS_FBINFO(altout.mode) == MODE_PAL)
if (ACCESS_FBINFO(outputs[1]).mode == MODE_PAL)
*data = palregs;
else
*data = ntscregs;
......@@ -585,7 +585,7 @@ static inline int maven_compute_timming(struct maven_data* md,
unsigned int a, bv, c;
MINFO_FROM(md->primary_head);
m->mode = ACCESS_FBINFO(altout.mode);
m->mode = ACCESS_FBINFO(outputs[1]).mode;
if (MODE_TV(m->mode)) {
unsigned int lmargin;
unsigned int umargin;
......@@ -893,6 +893,7 @@ static int maven_out_verify_mode(void* md, u_int32_t arg) {
}
static struct matrox_altout maven_altout = {
.name = "Secondary output",
.compute = maven_out_compute,
.program = maven_out_program,
.start = maven_out_start,
......@@ -904,14 +905,14 @@ static int maven_init_client(struct i2c_client* clnt) {
struct maven_data* md = clnt->data;
MINFO_FROM(((struct i2c_bit_adapter*)a)->minfo);
ACCESS_FBINFO(altout.mode) = MODE_MONITOR;
md->primary_head = MINFO;
md->client = clnt;
down_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(altout.device) = md;
ACCESS_FBINFO(altout.output) = &maven_altout;
ACCESS_FBINFO(outputs[1]).output = &maven_altout;
ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE;
ACCESS_FBINFO(outputs[1]).data = md;
ACCESS_FBINFO(outputs[1]).mode = MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY;
if (maven_get_reg(clnt, 0xB2) < 0x14) {
md->version = MGATVO_B;
} else {
......@@ -924,13 +925,14 @@ static int maven_shutdown_client(struct i2c_client* clnt) {
struct maven_data* md = clnt->data;
if (md->primary_head) {
md->primary_head->output.all &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
md->primary_head->output.ph &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
md->primary_head->output.sh &= ~MATROXFB_OUTPUT_CONN_SECONDARY;
down_write(&md->primary_head->altout.lock);
md->primary_head->altout.device = NULL;
md->primary_head->altout.output = NULL;
up_write(&md->primary_head->altout.lock);
MINFO_FROM(md->primary_head);
down_write(&ACCESS_FBINFO(altout.lock));
ACCESS_FBINFO(outputs[1]).src = MATROXFB_SRC_NONE;
ACCESS_FBINFO(outputs[1]).output = NULL;
ACCESS_FBINFO(outputs[1]).data = NULL;
ACCESS_FBINFO(outputs[1]).mode = MATROXFB_OUTPUT_MODE_MONITOR;
up_write(&ACCESS_FBINFO(altout.lock));
md->primary_head = NULL;
}
return 0;
......
......@@ -360,7 +360,8 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m, struct display* p) {
((hd & 0x100) >> 7) | /* blanking */
((hs & 0x100) >> 6) | /* sync start */
(hbe & 0x040); /* end hor. blanking */
if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY)
/* FIXME: Enable vidrst only on G400, and only if TV-out is used */
if (ACCESS_FBINFO(outputs[1]).src == MATROXFB_SRC_CRTC1)
hw->CRTCEXT[1] |= 0x88; /* enable horizontal and vertical vidrst */
hw->CRTCEXT[2] = ((vt & 0xC00) >> 10) |
((vd & 0x400) >> 8) | /* disp end */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment