]> git.neil.brown.name Git - history.git/commitdiff
Add support for panning at vertical blanking to the matroxfb. Now mplayer output
authorPetr Vandrovec <vandrove@vc.cvut.cz>
Wed, 6 Aug 2003 21:07:09 +0000 (23:07 +0200)
committerPetr Vandrovec <vandrove@vc.cvut.cz>
Wed, 6 Aug 2003 21:07:09 +0000 (23:07 +0200)
looks much better on primary output (secondary output is always synced with vbl).

drivers/video/matrox/matroxfb_DAC1064.c
drivers/video/matrox/matroxfb_Ti3026.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_base.h
drivers/video/matrox/matroxfb_crtc2.c

index 74720255d95d277fbf040c8c1b42e852deb1155b..111f4c04e3f46148a028c4dc3388508e59163070 100644 (file)
@@ -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);
index acfd9304496f0c4220b681ef75fc9461b479229c..cef3472aad8f6924c51b37bef8ce6c0537652643 100644 (file)
@@ -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]);
 
index 02a00c5e42d8b7bab71b1077ee0cebeec60f0eef..1388470cc33c1ef49453ec3b7b6d8856edb58fef 100644 (file)
@@ -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.
index 77965337d571c5bcda72152ddbd421bb7740ded2..4c04dfefa833c95c50c5f13d1828eab55293918a 100644 (file)
@@ -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;
index 1c71df5f87b07c72e2e2029c78b6d0e99613530c..27221ec48f852527a85880e0b3e48438e1da3be9 100644 (file)
@@ -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)