Commit 42215683 authored by Petr Vandrovec's avatar Petr Vandrovec

Add support for panning at vertical blanking to the matroxfb. Now mplayer output

looks much better on primary output (secondary output is always synced with vbl).
parent 0efd6b69
......@@ -1036,6 +1036,7 @@ static void MGA1064_restore(WPMINFO2) {
DAC1064_restore_1(PMINFO2);
matroxfb_vgaHWrestore(PMINFO2);
ACCESS_FBINFO(crtc1.panpos) = -1;
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
DAC1064_restore_2(PMINFO2);
......@@ -1062,6 +1063,7 @@ static void MGAG100_restore(WPMINFO2) {
if (ACCESS_FBINFO(devflags.support32MB))
mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
#endif
ACCESS_FBINFO(crtc1.panpos) = -1;
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
DAC1064_restore_2(PMINFO2);
......
......@@ -575,6 +575,7 @@ static void Ti3026_restore(WPMINFO2) {
CRITBEGIN
ACCESS_FBINFO(crtc1.panpos) = -1;
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
......
......@@ -176,6 +176,27 @@ static void update_crtc2(WPMINFO unsigned int pos) {
}
}
static void matroxfb_crtc1_panpos(WPMINFO2) {
if (ACCESS_FBINFO(crtc1.panpos) >= 0) {
unsigned long flags;
int panpos;
matroxfb_DAC_lock_irqsave(flags);
panpos = ACCESS_FBINFO(crtc1.panpos);
if (panpos >= 0) {
unsigned int extvga_reg;
ACCESS_FBINFO(crtc1.panpos) = -1; /* No update pending anymore */
extvga_reg = mga_inb(M_EXTVGA_INDEX);
mga_setr(M_EXTVGA_INDEX, 0x00, panpos);
if (extvga_reg != 0x00) {
mga_outb(M_EXTVGA_INDEX, extvga_reg);
}
}
matroxfb_DAC_unlock_irqrestore(flags);
}
}
static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp)
{
u_int32_t status;
......@@ -188,6 +209,7 @@ static irqreturn_t matrox_irq(int irq, void *dev_id, struct pt_regs *fp)
if (status & 0x20) {
mga_outl(M_ICLEAR, 0x20);
ACCESS_FBINFO(crtc1.vsync.cnt)++;
matroxfb_crtc1_panpos(PMINFO2);
wake_up_interruptible(&ACCESS_FBINFO(crtc1.vsync.wait));
handled = 1;
}
......@@ -209,12 +231,13 @@ int matroxfb_enable_irq(WPMINFO int reenable) {
bm = 0x020;
if (!test_and_set_bit(0, &ACCESS_FBINFO(irq_flags))) {
printk(KERN_DEBUG "matroxfb: enabling IRQ\n");
if (request_irq(ACCESS_FBINFO(pcidev)->irq, matrox_irq,
SA_SHIRQ, "MGA Vertical Sync", MINFO)) {
SA_SHIRQ, "matroxfb", MINFO)) {
clear_bit(0, &ACCESS_FBINFO(irq_flags));
return -EINVAL;
}
/* Clear any pending field interrupts */
mga_outl(M_ICLEAR, bm);
mga_outl(M_IEN, mga_inl(M_IEN) | bm);
} else if (reenable) {
u_int32_t ien;
......@@ -230,7 +253,8 @@ int matroxfb_enable_irq(WPMINFO int reenable) {
static void matroxfb_disable_irq(WPMINFO2) {
if (test_and_clear_bit(0, &ACCESS_FBINFO(irq_flags))) {
printk(KERN_DEBUG "matroxfb: disabling IRQ\n");
/* Flush pending pan-at-vbl request... */
matroxfb_crtc1_panpos(PMINFO2);
if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
mga_outl(M_IEN, mga_inl(M_IEN) & ~0x220);
else
......@@ -284,6 +308,9 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
#ifdef CONFIG_FB_MATROX_32MB
unsigned int p3;
#endif
int vbl;
unsigned long flags;
CRITFLAGS
DBG(__FUNCTION__)
......@@ -302,15 +329,26 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
p3 = ACCESS_FBINFO(hw).CRTCEXT[8] = pos >> 21;
#endif
/* FB_ACTIVATE_VBL and we can acquire interrupts? Honor FB_ACTIVATE_VBL then... */
vbl = (var->activate & FB_ACTIVATE_VBL) && (matroxfb_enable_irq(PMINFO 0) == 0);
CRITBEGIN
matroxfb_DAC_lock_irqsave(flags);
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);
if (vbl) {
ACCESS_FBINFO(crtc1.panpos) = p2;
} else {
/* Abort any pending change */
ACCESS_FBINFO(crtc1.panpos) = -1;
mga_setr(M_EXTVGA_INDEX, 0x00, p2);
}
matroxfb_DAC_unlock_irqrestore(flags);
update_crtc2(PMINFO pos);
......@@ -1973,6 +2011,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
ACCESS_FBINFO(irq_flags) = 0;
init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait));
init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait));
ACCESS_FBINFO(crtc1.panpos) = -1;
err = initMatrox2(PMINFO b);
if (!err) {
......@@ -2466,6 +2505,7 @@ module_exit(matrox_done);
EXPORT_SYMBOL(matroxfb_register_driver);
EXPORT_SYMBOL(matroxfb_unregister_driver);
EXPORT_SYMBOL(matroxfb_wait_for_sync);
EXPORT_SYMBOL(matroxfb_enable_irq);
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
......
......@@ -457,6 +457,7 @@ struct matrox_fb_info {
struct matrox_vsync vsync;
unsigned int pixclock;
int mnp;
int panpos;
} crtc1;
struct {
struct matrox_vsync vsync;
......
......@@ -148,7 +148,7 @@ static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,
mga_outl(0x3C10, tmp);
ACCESS_FBINFO(hw).crtc2.ctl = tmp;
tmp = 0x0FFF0000; /* line compare */
tmp = mt->VDisplay << 16; /* line compare */
if (mt->sync & FB_SYNC_HOR_HIGH_ACT)
tmp |= 0x00000100;
if (mt->sync & FB_SYNC_VERT_HIGH_ACT)
......
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