}
}
+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;
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;
}
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;
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
#ifdef CONFIG_FB_MATROX_32MB
unsigned int p3;
#endif
+ int vbl;
+ unsigned long flags;
+
CRITFLAGS
DBG(__FUNCTION__)
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);
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) {
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.