Include new updated gamma support.
authorAlan Hourihane <alanh@fairlite.demon.co.uk>
Mon, 5 Jun 2000 00:42:21 +0000 (00:42 +0000)
committerAlan Hourihane <alanh@fairlite.demon.co.uk>
Mon, 5 Jun 2000 00:42:21 +0000 (00:42 +0000)
linux/gamma_dma.c
linux/gamma_drv.c
linux/gamma_drv.h

index eec0f85..444f25e 100644 (file)
@@ -87,13 +87,31 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address,
        GAMMA_WRITE(GAMMA_DMACOUNT, length / 4);
 }
 
-static inline void gamma_dma_quiescent(drm_device_t *dev)
+static inline void gamma_dma_quiescent_single(drm_device_t *dev)
 {
        while (GAMMA_READ(GAMMA_DMACOUNT))
                ;
        while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
                ;
+
+       GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
+       GAMMA_WRITE(GAMMA_SYNC, 0);
+       
+       do {
+               while (!GAMMA_READ(GAMMA_OUTFIFOWORDS))
+                       ;
+       } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
+}
+
+static inline void gamma_dma_quiescent_dual(drm_device_t *dev)
+{
+       while (GAMMA_READ(GAMMA_DMACOUNT))
+               ;
+       while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3)
+               ;
+
        GAMMA_WRITE(GAMMA_BROADCASTMASK, 3);
+
        GAMMA_WRITE(GAMMA_FILTERMODE, 1 << 10);
        GAMMA_WRITE(GAMMA_SYNC, 0);
        
@@ -103,7 +121,6 @@ static inline void gamma_dma_quiescent(drm_device_t *dev)
                        ;
        } while (GAMMA_READ(GAMMA_OUTPUTFIFO) != GAMMA_SYNC_TAG);
        
-
                                /* Read from second MX */
        do {
                while (!GAMMA_READ(GAMMA_OUTFIFOWORDS + 0x10000))
@@ -788,8 +805,13 @@ int gamma_lock(struct inode *inode, struct file *filp, unsigned int cmd,
        if (!ret) {
                if (lock.flags & _DRM_LOCK_READY)
                        gamma_dma_ready(dev);
-               if (lock.flags & _DRM_LOCK_QUIESCENT)
-                       gamma_dma_quiescent(dev);
+               if (lock.flags & _DRM_LOCK_QUIESCENT) {
+                       if (gamma_found() == 1) {
+                               gamma_dma_quiescent_single(dev);
+                       } else {
+                               gamma_dma_quiescent_dual(dev);
+                       }
+               }
        }
        DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
 
index a3c2bd4..8759524 100644 (file)
@@ -31,6 +31,7 @@
 #define EXPORT_SYMTAB
 #include "drmP.h"
 #include "gamma_drv.h"
+#include <linux/pci.h>
 EXPORT_SYMBOL(gamma_init);
 EXPORT_SYMBOL(gamma_cleanup);
 
@@ -98,10 +99,13 @@ static drm_ioctl_desc_t           gamma_ioctls[] = {
 int                          init_module(void);
 void                         cleanup_module(void);
 static char                  *gamma = NULL;
+static int                   devices = 0;
 
 MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas.");
 MODULE_DESCRIPTION("3dlabs GMX 2000");
 MODULE_PARM(gamma, "s");
+MODULE_PARM(devices, "i");
+MODULE_PARM_DESC(devices, "devices=x, where x is the number of MX chips on your card\n");
 
 /* init_module is called when insmod is used to load the module */
 
@@ -314,6 +318,34 @@ static int gamma_takedown(drm_device_t *dev)
        return 0;
 }
 
+int gamma_found(void)
+{
+       return devices;
+}
+
+int gamma_find_devices(void)
+{
+       struct pci_dev *d = NULL, *one = NULL, *two = NULL;
+
+       d = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_GAMMA,d);
+       if (!d) return 0;
+
+       one = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,d);
+       if (!one) return 0;
+
+       /* Make sure it's on the same card, if not - no MX's found */
+       if (PCI_SLOT(d->devfn) != PCI_SLOT(one->devfn)) return 0;
+
+       two = pci_find_device(PCI_VENDOR_ID_3DLABS,PCI_DEVICE_ID_3DLABS_MX,one);
+       if (!two) return 1;
+
+       /* Make sure it's on the same card, if not - only 1 MX found */
+       if (PCI_SLOT(d->devfn) != PCI_SLOT(two->devfn)) return 1;
+
+       /* Two MX's found - we don't currently support more than 2 */
+       return 2;
+}
+
 /* gamma_init is called via init_module at module load time, or via
  * linux/init/main.c (this is not currently supported). */
 
@@ -331,6 +363,8 @@ int gamma_init(void)
 #ifdef MODULE
        drm_parse_options(gamma);
 #endif
+       devices = gamma_find_devices();
+       if (devices == 0) return -1;
 
        if ((retcode = misc_register(&gamma_misc))) {
                DRM_ERROR("Cannot register \"%s\"\n", GAMMA_NAME);
@@ -342,13 +376,14 @@ int gamma_init(void)
        drm_mem_init();
        drm_proc_init(dev);
 
-       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+       DRM_INFO("Initialized %s %d.%d.%d %s on minor %d with %d MX devices\n",
                 GAMMA_NAME,
                 GAMMA_MAJOR,
                 GAMMA_MINOR,
                 GAMMA_PATCHLEVEL,
                 GAMMA_DATE,
-                gamma_misc.minor);
+                gamma_misc.minor,
+                devices);
        
        return 0;
 }
index d78a13e..3d5b5de 100644 (file)
@@ -53,5 +53,7 @@ extern int  gamma_irq_install(drm_device_t *dev, int irq);
 extern int  gamma_irq_uninstall(drm_device_t *dev);
 extern int  gamma_control(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg);
+extern int  gamma_find_devices(void);
+extern int  gamma_found(void);
 
 #endif