drm: major update from CVS for radeon and core
authorDave Airlie <airlied@starflyer.(none)>
Mon, 2 Jan 2006 10:32:48 +0000 (21:32 +1100)
committerDave Airlie <airlied@linux.ie>
Mon, 2 Jan 2006 10:32:48 +0000 (21:32 +1100)
This patch pull in a lot of changes from CVS to the main core DRM,
and updates the radeon driver to 1.21.0 that supports r300 texrect
and radeon card type ioctl.

Signed-off-by: Dave Airlie <airlied@linux.ie>
12 files changed:
drivers/char/drm/drmP.h
drivers/char/drm/drm_agpsupport.c
drivers/char/drm/drm_bufs.c
drivers/char/drm/drm_fops.c
drivers/char/drm/drm_lock.c
drivers/char/drm/drm_stub.c
drivers/char/drm/r300_cmdbuf.c
drivers/char/drm/r300_reg.h
drivers/char/drm/radeon_cp.c
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_drv.h
drivers/char/drm/radeon_state.c

index 43c49ad..307254d 100644 (file)
@@ -550,7 +550,7 @@ struct drm_driver {
        int (*kernel_context_switch) (struct drm_device * dev, int old,
                                      int new);
        void (*kernel_context_switch_unlock) (struct drm_device * dev,
-                                             drm_lock_t * lock);
+                                             drm_lock_t *lock);
        int (*vblank_wait) (struct drm_device * dev, unsigned int *sequence);
        int (*dri_library_name) (struct drm_device *dev, char *buf);
 
@@ -574,12 +574,11 @@ struct drm_driver {
        void (*irq_postinstall) (struct drm_device * dev);
        void (*irq_uninstall) (struct drm_device * dev);
        void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
-       void (*reclaim_buffers_locked) (struct drm_device *drv,
+       void (*reclaim_buffers_locked) (struct drm_device *dev,
                                        struct file *filp);
        unsigned long (*get_map_ofs) (drm_map_t * map);
        unsigned long (*get_reg_ofs) (struct drm_device * dev);
        void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
-       int (*version) (drm_version_t * version);
 
        int major;
        int minor;
@@ -774,10 +773,6 @@ static inline int drm_mtrr_del(int handle, unsigned long offset,
 /** \name Internal function definitions */
 /*@{*/
 
-                               /* Misc. support (drm_init.h) */
-extern int drm_flags;
-extern void drm_parse_options(char *s);
-
                                /* Driver support (drm_drv.h) */
 extern int drm_init(struct drm_driver *driver);
 extern void drm_exit(struct drm_driver *driver);
@@ -831,6 +826,8 @@ extern int drm_getstats(struct inode *inode, struct file *filp,
                        unsigned int cmd, unsigned long arg);
 extern int drm_setversion(struct inode *inode, struct file *filp,
                          unsigned int cmd, unsigned long arg);
+extern int drm_noop(struct inode *inode, struct file *filp,
+                   unsigned int cmd, unsigned long arg);
 
                                /* Context IOCTL support (drm_context.h) */
 extern int drm_resctx(struct inode *inode, struct file *filp,
@@ -869,10 +866,6 @@ extern int drm_getmagic(struct inode *inode, struct file *filp,
 extern int drm_authmagic(struct inode *inode, struct file *filp,
                         unsigned int cmd, unsigned long arg);
 
-                               /* Placeholder for ioctls past */
-extern int drm_noop(struct inode *inode, struct file *filp,
-                   unsigned int cmd, unsigned long arg);
-
                                /* Locking IOCTL support (drm_lock.h) */
 extern int drm_lock(struct inode *inode, struct file *filp,
                    unsigned int cmd, unsigned long arg);
@@ -885,6 +878,7 @@ extern int drm_lock_free(drm_device_t * dev,
                                /* Buffer management support (drm_bufs.h) */
 extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
 extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
+extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request);
 extern int drm_addmap(drm_device_t * dev, unsigned int offset,
                      unsigned int size, drm_map_type_t type,
                      drm_map_flags_t flags, drm_local_map_t ** map_ptr);
@@ -920,8 +914,8 @@ extern void drm_core_reclaim_buffers(drm_device_t * dev, struct file *filp);
                                /* IRQ support (drm_irq.h) */
 extern int drm_control(struct inode *inode, struct file *filp,
                       unsigned int cmd, unsigned long arg);
-extern int drm_irq_uninstall(drm_device_t * dev);
 extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
+extern int drm_irq_uninstall(drm_device_t * dev);
 extern void drm_driver_irq_preinstall(drm_device_t * dev);
 extern void drm_driver_irq_postinstall(drm_device_t * dev);
 extern void drm_driver_irq_uninstall(drm_device_t * dev);
index b80e61a..fabc930 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * \file drm_agpsupport.h
+ * \file drm_agpsupport.c
  * DRM support for AGP/GART backend
  *
  * \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -91,7 +91,7 @@ int drm_agp_info_ioctl(struct inode *inode, struct file *filp,
 /**
  * Acquire the AGP device.
  *
- * \param dev DRM device that is to acquire AGP
+ * \param dev DRM device that is to acquire AGP.
  * \return zero on success or a negative number on failure.
  *
  * Verifies the AGP device hasn't been acquired before and calls
@@ -134,7 +134,7 @@ int drm_agp_acquire_ioctl(struct inode *inode, struct file *filp,
 /**
  * Release the AGP device.
  *
- * \param dev DRM device that is to release AGP
+ * \param dev DRM device that is to release AGP.
  * \return zero on success or a negative number on failure.
  *
  * Verifies the AGP device has been acquired and calls \c agp_backend_release.
@@ -147,7 +147,6 @@ int drm_agp_release(drm_device_t * dev)
        dev->agp->acquired = 0;
        return 0;
 }
-
 EXPORT_SYMBOL(drm_agp_release);
 
 int drm_agp_release_ioctl(struct inode *inode, struct file *filp,
@@ -447,6 +446,9 @@ int drm_agp_free_ioctl(struct inode *inode, struct file *filp,
  *
  * \return pointer to a drm_agp_head structure.
  *
+ * Gets the drm_agp_t structure which is made available by the agpgart module
+ * via the inter_module_* functions. Creates and initializes a drm_agp_head
+ * structure.
  */
 drm_agp_head_t *drm_agp_init(drm_device_t * dev)
 {
index 319bdea..1845dd0 100644 (file)
 #include <linux/vmalloc.h>
 #include "drmP.h"
 
-unsigned long drm_get_resource_start(drm_device_t * dev, unsigned int resource)
+unsigned long drm_get_resource_start(drm_device_t *dev, unsigned int resource)
 {
        return pci_resource_start(dev->pdev, resource);
 }
-
 EXPORT_SYMBOL(drm_get_resource_start);
 
-unsigned long drm_get_resource_len(drm_device_t * dev, unsigned int resource)
+unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
 {
        return pci_resource_len(dev->pdev, resource);
 }
 
 EXPORT_SYMBOL(drm_get_resource_len);
 
-static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
-                                            drm_local_map_t * map)
+static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
+                                            drm_local_map_t *map)
 {
        struct list_head *list;
 
@@ -74,7 +73,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t * dev,
 
 #ifdef _LP64
 static __inline__ unsigned int HandleID(unsigned long lhandle,
-                                       drm_device_t * dev)
+                                       drm_device_t *dev)
 {
        static unsigned int map32_handle = START_RANGE;
        unsigned int hash;
@@ -301,6 +300,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
                return -EFAULT;
        }
 
+       if (!(capable(CAP_SYS_ADMIN) || map.type == _DRM_AGP))
+               return -EPERM;
+
        err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
                              &maplist);
 
@@ -332,7 +334,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
  *
  * \sa drm_addmap
  */
-int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
+int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
 {
        struct list_head *list;
        drm_map_list_t *r_list = NULL;
@@ -384,10 +386,9 @@ int drm_rmmap_locked(drm_device_t * dev, drm_local_map_t * map)
 
        return 0;
 }
-
 EXPORT_SYMBOL(drm_rmmap_locked);
 
-int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
+int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
 {
        int ret;
 
@@ -397,7 +398,6 @@ int drm_rmmap(drm_device_t * dev, drm_local_map_t * map)
 
        return ret;
 }
-
 EXPORT_SYMBOL(drm_rmmap);
 
 /* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
@@ -548,7 +548,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        DRM_DEBUG("count:      %d\n", count);
        DRM_DEBUG("order:      %d\n", order);
        DRM_DEBUG("size:       %d\n", size);
-       DRM_DEBUG("agp_offset: %lu\n", agp_offset);
+       DRM_DEBUG("agp_offset: %lx\n", agp_offset);
        DRM_DEBUG("alignment:  %d\n", alignment);
        DRM_DEBUG("page_order: %d\n", page_order);
        DRM_DEBUG("total:      %d\n", total);
@@ -649,6 +649,8 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        }
 
        dma->buf_count += entry->buf_count;
+       dma->seg_count += entry->seg_count;
+       dma->page_count += byte_count >> PAGE_SHIFT;
        dma->byte_count += byte_count;
 
        DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -664,7 +666,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request)
        atomic_dec(&dev->buf_alloc);
        return 0;
 }
-
 EXPORT_SYMBOL(drm_addbufs_agp);
 #endif                         /* __OS_HAS_AGP */
 
@@ -689,9 +690,13 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
 
        if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
                return -EINVAL;
+
        if (!dma)
                return -EINVAL;
 
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
        count = request->count;
        order = drm_order(request->size);
        size = 1 << order;
@@ -882,7 +887,6 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
        return 0;
 
 }
-
 EXPORT_SYMBOL(drm_addbufs_pci);
 
 static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
@@ -908,6 +912,9 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        if (!dma)
                return -EINVAL;
 
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
        count = request->count;
        order = drm_order(request->size);
        size = 1 << order;
@@ -1026,6 +1033,8 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        }
 
        dma->buf_count += entry->buf_count;
+       dma->seg_count += entry->seg_count;
+       dma->page_count += byte_count >> PAGE_SHIFT;
        dma->byte_count += byte_count;
 
        DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -1042,7 +1051,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
        return 0;
 }
 
-static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
+int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
 {
        drm_device_dma_t *dma = dev->dma;
        drm_buf_entry_t *entry;
@@ -1065,6 +1074,9 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        if (!dma)
                return -EINVAL;
 
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
        count = request->count;
        order = drm_order(request->size);
        size = 1 << order;
@@ -1181,6 +1193,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        }
 
        dma->buf_count += entry->buf_count;
+       dma->seg_count += entry->seg_count;
+       dma->page_count += byte_count >> PAGE_SHIFT;
        dma->byte_count += byte_count;
 
        DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
@@ -1196,6 +1210,8 @@ static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
        atomic_dec(&dev->buf_alloc);
        return 0;
 }
+EXPORT_SYMBOL(drm_addbufs_fb);
+
 
 /**
  * Add buffers for DMA transfers (ioctl).
@@ -1577,5 +1593,6 @@ int drm_order(unsigned long size)
 
        return order;
 }
-
 EXPORT_SYMBOL(drm_order);
+
+
index b73543c..403f44a 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include "drmP.h"
+#include "drm_sarea.h"
 #include <linux/poll.h>
 
 static int drm_open_helper(struct inode *inode, struct file *filp,
@@ -42,6 +43,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
 
 static int drm_setup(drm_device_t * dev)
 {
+       drm_local_map_t *map;
        int i;
        int ret;
 
@@ -51,6 +53,11 @@ static int drm_setup(drm_device_t * dev)
                        return ret;
        }
 
+       /* prebuild the SAREA */
+       i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
+       if (i != 0)
+               return i;
+
        atomic_set(&dev->ioctl_count, 0);
        atomic_set(&dev->vma_count, 0);
        dev->buf_use = 0;
@@ -152,10 +159,168 @@ int drm_open(struct inode *inode, struct file *filp)
 
        return retcode;
 }
-
 EXPORT_SYMBOL(drm_open);
 
 /**
+ * File \c open operation.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ *
+ * Puts the dev->fops corresponding to the device minor number into
+ * \p filp, call the \c open method, and restore the file operations.
+ */
+int drm_stub_open(struct inode *inode, struct file *filp)
+{
+       drm_device_t *dev = NULL;
+       int minor = iminor(inode);
+       int err = -ENODEV;
+       struct file_operations *old_fops;
+
+       DRM_DEBUG("\n");
+
+       if (!((minor >= 0) && (minor < drm_cards_limit)))
+               return -ENODEV;
+
+       if (!drm_heads[minor])
+               return -ENODEV;
+
+       if (!(dev = drm_heads[minor]->dev))
+               return -ENODEV;
+
+       old_fops = filp->f_op;
+       filp->f_op = fops_get(&dev->driver->fops);
+       if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
+               fops_put(filp->f_op);
+               filp->f_op = fops_get(old_fops);
+       }
+       fops_put(old_fops);
+
+       return err;
+}
+
+/**
+ * Check whether DRI will run on this CPU.
+ *
+ * \return non-zero if the DRI will run on this CPU, or zero otherwise.
+ */
+static int drm_cpu_valid(void)
+{
+#if defined(__i386__)
+       if (boot_cpu_data.x86 == 3)
+               return 0;       /* No cmpxchg on a 386 */
+#endif
+#if defined(__sparc__) && !defined(__sparc_v9__)
+       return 0;               /* No cmpxchg before v9 sparc. */
+#endif
+       return 1;
+}
+
+/**
+ * Called whenever a process opens /dev/drm.
+ *
+ * \param inode device inode.
+ * \param filp file pointer.
+ * \param dev device.
+ * \return zero on success or a negative number on failure.
+ *
+ * Creates and initializes a drm_file structure for the file private data in \p
+ * filp and add it into the double linked list in \p dev.
+ */
+static int drm_open_helper(struct inode *inode, struct file *filp,
+                          drm_device_t * dev)
+{
+       int minor = iminor(inode);
+       drm_file_t *priv;
+       int ret;
+
+       if (filp->f_flags & O_EXCL)
+               return -EBUSY;  /* No exclusive opens */
+       if (!drm_cpu_valid())
+               return -EINVAL;
+
+       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+
+       priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+       if (!priv)
+               return -ENOMEM;
+
+       memset(priv, 0, sizeof(*priv));
+       filp->private_data = priv;
+       priv->uid = current->euid;
+       priv->pid = current->pid;
+       priv->minor = minor;
+       priv->head = drm_heads[minor];
+       priv->ioctl_count = 0;
+       /* for compatibility root is always authenticated */
+       priv->authenticated = capable(CAP_SYS_ADMIN);
+       priv->lock_count = 0;
+
+       if (dev->driver->open) {
+               ret = dev->driver->open(dev, priv);
+               if (ret < 0)
+                       goto out_free;
+       }
+
+       down(&dev->struct_sem);
+       if (!dev->file_last) {
+               priv->next = NULL;
+               priv->prev = NULL;
+               dev->file_first = priv;
+               dev->file_last = priv;
+               /* first opener automatically becomes master */
+               priv->master = 1;
+       } else {
+               priv->next = NULL;
+               priv->prev = dev->file_last;
+               dev->file_last->next = priv;
+               dev->file_last = priv;
+       }
+       up(&dev->struct_sem);
+
+#ifdef __alpha__
+       /*
+        * Default the hose
+        */
+       if (!dev->hose) {
+               struct pci_dev *pci_dev;
+               pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
+               if (pci_dev) {
+                       dev->hose = pci_dev->sysdata;
+                       pci_dev_put(pci_dev);
+               }
+               if (!dev->hose) {
+                       struct pci_bus *b = pci_bus_b(pci_root_buses.next);
+                       if (b)
+                               dev->hose = b->sysdata;
+               }
+       }
+#endif
+
+       return 0;
+      out_free:
+       drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+       filp->private_data = NULL;
+       return ret;
+}
+
+/** No-op. */
+int drm_fasync(int fd, struct file *filp, int on)
+{
+       drm_file_t *priv = filp->private_data;
+       drm_device_t *dev = priv->head->dev;
+       int retcode;
+
+       DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
+                 (long)old_encode_dev(priv->head->device));
+       retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+       if (retcode < 0)
+               return retcode;
+       return 0;
+}
+EXPORT_SYMBOL(drm_fasync);
+
+/**
  * Release file.
  *
  * \param inode device inode
@@ -291,7 +456,6 @@ int drm_release(struct inode *inode, struct file *filp)
 
        if (dev->driver->postclose)
                dev->driver->postclose(dev, priv);
-
        drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
 
        /* ========================================================
@@ -318,132 +482,11 @@ int drm_release(struct inode *inode, struct file *filp)
 
        return retcode;
 }
-
 EXPORT_SYMBOL(drm_release);
 
-/**
- * Check whether DRI will run on this CPU.
- *
- * \return non-zero if the DRI will run on this CPU, or zero otherwise.
- */
-static int drm_cpu_valid(void)
-{
-#if defined(__i386__)
-       if (boot_cpu_data.x86 == 3)
-               return 0;       /* No cmpxchg on a 386 */
-#endif
-#if defined(__sparc__) && !defined(__sparc_v9__)
-       return 0;               /* No cmpxchg before v9 sparc. */
-#endif
-       return 1;
-}
-
-/**
- * Called whenever a process opens /dev/drm.
- *
- * \param inode device inode.
- * \param filp file pointer.
- * \param dev device.
- * \return zero on success or a negative number on failure.
- *
- * Creates and initializes a drm_file structure for the file private data in \p
- * filp and add it into the double linked list in \p dev.
- */
-static int drm_open_helper(struct inode *inode, struct file *filp,
-                          drm_device_t * dev)
-{
-       int minor = iminor(inode);
-       drm_file_t *priv;
-       int ret;
-
-       if (filp->f_flags & O_EXCL)
-               return -EBUSY;  /* No exclusive opens */
-       if (!drm_cpu_valid())
-               return -EINVAL;
-
-       DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
-
-       priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
-       if (!priv)
-               return -ENOMEM;
-
-       memset(priv, 0, sizeof(*priv));
-       filp->private_data = priv;
-       priv->uid = current->euid;
-       priv->pid = current->pid;
-       priv->minor = minor;
-       priv->head = drm_heads[minor];
-       priv->ioctl_count = 0;
-       priv->authenticated = capable(CAP_SYS_ADMIN);
-       priv->lock_count = 0;
-
-       if (dev->driver->open) {
-               ret = dev->driver->open(dev, priv);
-               if (ret < 0)
-                       goto out_free;
-       }
-
-       down(&dev->struct_sem);
-       if (!dev->file_last) {
-               priv->next = NULL;
-               priv->prev = NULL;
-               dev->file_first = priv;
-               dev->file_last = priv;
-       } else {
-               priv->next = NULL;
-               priv->prev = dev->file_last;
-               dev->file_last->next = priv;
-               dev->file_last = priv;
-       }
-       up(&dev->struct_sem);
-
-#ifdef __alpha__
-       /*
-        * Default the hose
-        */
-       if (!dev->hose) {
-               struct pci_dev *pci_dev;
-               pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
-               if (pci_dev) {
-                       dev->hose = pci_dev->sysdata;
-                       pci_dev_put(pci_dev);
-               }
-               if (!dev->hose) {
-                       struct pci_bus *b = pci_bus_b(pci_root_buses.next);
-                       if (b)
-                               dev->hose = b->sysdata;
-               }
-       }
-#endif
-
-       return 0;
-      out_free:
-       drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
-       filp->private_data = NULL;
-       return ret;
-}
-
-/** No-op. */
-int drm_fasync(int fd, struct file *filp, int on)
-{
-       drm_file_t *priv = filp->private_data;
-       drm_device_t *dev = priv->head->dev;
-       int retcode;
-
-       DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
-                 (long)old_encode_dev(priv->head->device));
-       retcode = fasync_helper(fd, filp, on, &dev->buf_async);
-       if (retcode < 0)
-               return retcode;
-       return 0;
-}
-
-EXPORT_SYMBOL(drm_fasync);
-
 /** No-op. */
 unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
 {
        return 0;
 }
-
 EXPORT_SYMBOL(drm_poll);
index b276ae8..f970dc3 100644 (file)
@@ -104,6 +104,9 @@ int drm_lock(struct inode *inode, struct file *filp,
        __set_current_state(TASK_RUNNING);
        remove_wait_queue(&dev->lock.lock_queue, &entry);
 
+       DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" );
+       if (ret) return ret;
+
        sigemptyset(&dev->sigmask);
        sigaddset(&dev->sigmask, SIGSTOP);
        sigaddset(&dev->sigmask, SIGTSTP);
@@ -116,21 +119,20 @@ int drm_lock(struct inode *inode, struct file *filp,
        if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
                dev->driver->dma_ready(dev);
 
-       if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
-               return dev->driver->dma_quiescent(dev);
-
-       /* dev->driver->kernel_context_switch isn't used by any of the x86
-        *  drivers but is used by the Sparc driver.
-        */
+       if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) {
+               if (dev->driver->dma_quiescent(dev)) {
+                       DRM_DEBUG( "%d waiting for DMA quiescent\n", lock.context);
+                       return DRM_ERR(EBUSY);
+               }
+       }
 
        if (dev->driver->kernel_context_switch &&
            dev->last_context != lock.context) {
                dev->driver->kernel_context_switch(dev, dev->last_context,
                                                   lock.context);
        }
-       DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
 
-       return ret;
+       return 0;
 }
 
 /**
index b7f2a85..42d7663 100644 (file)
@@ -128,43 +128,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
        return retcode;
 }
 
-/**
- * File \c open operation.
- *
- * \param inode device inode.
- * \param filp file pointer.
- *
- * Puts the dev->fops corresponding to the device minor number into
- * \p filp, call the \c open method, and restore the file operations.
- */
-int drm_stub_open(struct inode *inode, struct file *filp)
-{
-       drm_device_t *dev = NULL;
-       int minor = iminor(inode);
-       int err = -ENODEV;
-       struct file_operations *old_fops;
-
-       DRM_DEBUG("\n");
-
-       if (!((minor >= 0) && (minor < drm_cards_limit)))
-               return -ENODEV;
-
-       if (!drm_heads[minor])
-               return -ENODEV;
-
-       if (!(dev = drm_heads[minor]->dev))
-               return -ENODEV;
-
-       old_fops = filp->f_op;
-       filp->f_op = fops_get(&dev->driver->fops);
-       if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
-               fops_put(filp->f_op);
-               filp->f_op = fops_get(old_fops);
-       }
-       fops_put(old_fops);
-
-       return err;
-}
 
 /**
  * Get a secondary minor number.
index 3a1ac5f..291dbf4 100644 (file)
@@ -52,8 +52,8 @@ static const int r300_cliprect_cntl[4] = {
  * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
  * buffer, starting with index n.
  */
-static int r300_emit_cliprects(drm_radeon_private_t * dev_priv,
-                              drm_radeon_kcmd_buffer_t * cmdbuf, int n)
+static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
+                              drm_radeon_kcmd_buffer_t *cmdbuf, int n)
 {
        drm_clip_rect_t box;
        int nr;
@@ -216,6 +216,7 @@ void r300_init_reg_flags(void)
        ADD_RANGE(R300_TX_UNK1_0, 16);
        ADD_RANGE(R300_TX_SIZE_0, 16);
        ADD_RANGE(R300_TX_FORMAT_0, 16);
+       ADD_RANGE(R300_TX_PITCH_0, 16);
        /* Texture offset is dangerous and needs more checking */
        ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
        ADD_RANGE(R300_TX_UNK4_0, 16);
@@ -242,7 +243,7 @@ static __inline__ int r300_check_range(unsigned reg, int count)
 
   /* we expect offsets passed to the framebuffer to be either within video memory or
      within AGP space */
-static __inline__ int r300_check_offset(drm_radeon_private_t * dev_priv,
+static __inline__ int r300_check_offset(drm_radeon_private_t *dev_priv,
                                        u32 offset)
 {
        /* we realy want to check against end of video aperture
@@ -317,8 +318,8 @@ static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
  *
  * Note that checks are performed on contents and addresses of the registers
  */
-static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
-                                       drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv,
+                                       drm_radeon_kcmd_buffer_t *cmdbuf,
                                        drm_r300_cmd_header_t header)
 {
        int reg;
@@ -363,8 +364,8 @@ static __inline__ int r300_emit_packet0(drm_radeon_private_t * dev_priv,
  * the graphics card.
  * Called by r300_do_cp_cmdbuf.
  */
-static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
-                                   drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
+                                   drm_radeon_kcmd_buffer_t *cmdbuf,
                                    drm_r300_cmd_header_t header)
 {
        int sz;
@@ -400,8 +401,8 @@ static __inline__ int r300_emit_vpu(drm_radeon_private_t * dev_priv,
  * Emit a clear packet from userspace.
  * Called by r300_emit_packet3.
  */
-static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
-                                     drm_radeon_kcmd_buffer_t * cmdbuf)
+static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
+                                     drm_radeon_kcmd_buffer_t *cmdbuf)
 {
        RING_LOCALS;
 
@@ -421,8 +422,8 @@ static __inline__ int r300_emit_clear(drm_radeon_private_t * dev_priv,
        return 0;
 }
 
-static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
-                                              drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
+                                              drm_radeon_kcmd_buffer_t *cmdbuf,
                                               u32 header)
 {
        int count, i, k;
@@ -489,8 +490,8 @@ static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t * dev_priv,
        return 0;
 }
 
-static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
-                                           drm_radeon_kcmd_buffer_t * cmdbuf)
+static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
+                                           drm_radeon_kcmd_buffer_t *cmdbuf)
 {
        u32 header;
        int count;
@@ -554,8 +555,8 @@ static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t * dev_priv,
  * Emit a rendering packet3 from userspace.
  * Called by r300_do_cp_cmdbuf.
  */
-static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
-                                       drm_radeon_kcmd_buffer_t * cmdbuf,
+static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
+                                       drm_radeon_kcmd_buffer_t *cmdbuf,
                                        drm_r300_cmd_header_t header)
 {
        int n;
@@ -623,7 +624,7 @@ static __inline__ int r300_emit_packet3(drm_radeon_private_t * dev_priv,
 /**
  * Emit the sequence to pacify R300.
  */
-static __inline__ void r300_pacify(drm_radeon_private_t * dev_priv)
+static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
 {
        RING_LOCALS;
 
@@ -657,9 +658,10 @@ static void r300_discard_buffer(drm_device_t * dev, drm_buf_t * buf)
  * commands on the DMA ring buffer.
  * Called by the ioctl handler function radeon_cp_cmdbuf.
  */
-int r300_do_cp_cmdbuf(drm_device_t * dev,
+int r300_do_cp_cmdbuf(drm_device_t *dev,
                      DRMFILE filp,
-                     drm_file_t * filp_priv, drm_radeon_kcmd_buffer_t * cmdbuf)
+                     drm_file_t *filp_priv,
+                     drm_radeon_kcmd_buffer_t *cmdbuf)
 {
        drm_radeon_private_t *dev_priv = dev->dev_private;
        drm_device_dma_t *dma = dev->dma;
index e5b73c0..a0ed20e 100644 (file)
@@ -797,6 +797,7 @@ I am fairly certain that they are correct unless stated otherwise in comments.
 
 #      define R300_TX_FORMAT_YUV_MODE          0x00800000
 
+#define R300_TX_PITCH_0                            0x4500
 #define R300_TX_OFFSET_0                    0x4540
 /* BEGIN: Guess from R200 */
 #       define R300_TXO_ENDIAN_NO_SWAP           (0 << 0)
index eaa0e2b..915665c 100644 (file)
@@ -824,7 +824,7 @@ static int RADEON_READ_PLL(drm_device_t * dev, int addr)
        return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
 }
 
-static int RADEON_READ_PCIE(drm_radeon_private_t * dev_priv, int addr)
+static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
 {
        RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
        return RADEON_READ(RADEON_PCIE_DATA);
@@ -1125,7 +1125,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
                     | (dev_priv->fb_location >> 16));
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci) {
+       if (dev_priv->flags & CHIP_IS_AGP) {
                RADEON_WRITE(RADEON_MC_AGP_LOCATION,
                             (((dev_priv->gart_vm_start - 1 +
                                dev_priv->gart_size) & 0xffff0000) |
@@ -1152,7 +1152,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev,
        dev_priv->ring.tail = cur_read_ptr;
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci) {
+       if (dev_priv->flags & CHIP_IS_AGP) {
                /* set RADEON_AGP_BASE here instead of relying on X from user space */
                RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
                RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
@@ -1278,13 +1278,15 @@ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
 /* Enable or disable PCI GART on the chip */
 static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
 {
-       u32 tmp = RADEON_READ(RADEON_AIC_CNTL);
+       u32 tmp;
 
        if (dev_priv->flags & CHIP_IS_PCIE) {
                radeon_set_pciegart(dev_priv, on);
                return;
        }
 
+       tmp = RADEON_READ(RADEON_AIC_CNTL);
+
        if (on) {
                RADEON_WRITE(RADEON_AIC_CNTL,
                             tmp | RADEON_PCIGART_TRANSLATE_EN);
@@ -1311,14 +1313,18 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
 
 static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;;
+       drm_radeon_private_t *dev_priv = dev->dev_private;
+
        DRM_DEBUG("\n");
 
-       dev_priv->is_pci = init->is_pci;
+       if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP))
+       {
+               DRM_DEBUG("Forcing AGP card to PCI mode\n");
+               dev_priv->flags &= ~CHIP_IS_AGP;
+       }
 
-       if (dev_priv->is_pci && !dev->sg) {
+       if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) {
                DRM_ERROR("PCI GART memory not allocated!\n");
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
@@ -1327,12 +1333,11 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
        if (dev_priv->usec_timeout < 1 ||
            dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
                DRM_DEBUG("TIMEOUT problem!\n");
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
 
-       switch (init->func) {
+       switch(init->func) {
        case RADEON_INIT_R200_CP:
                dev_priv->microcode_version = UCODE_R200;
                break;
@@ -1353,7 +1358,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
        if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
            (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
                DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
@@ -1416,8 +1420,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
 
        DRM_GETSAREA();
 
-       dev_priv->fb_offset = init->fb_offset;
-       dev_priv->mmio_offset = init->mmio_offset;
        dev_priv->ring_offset = init->ring_offset;
        dev_priv->ring_rptr_offset = init->ring_rptr_offset;
        dev_priv->buffers_offset = init->buffers_offset;
@@ -1425,29 +1427,19 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
 
        if (!dev_priv->sarea) {
                DRM_ERROR("could not find sarea!\n");
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
 
-       dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
-       if (!dev_priv->mmio) {
-               DRM_ERROR("could not find mmio region!\n");
-               dev->dev_private = (void *)dev_priv;
-               radeon_do_cleanup_cp(dev);
-               return DRM_ERR(EINVAL);
-       }
        dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
        if (!dev_priv->cp_ring) {
                DRM_ERROR("could not find cp ring region!\n");
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
        dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
        if (!dev_priv->ring_rptr) {
                DRM_ERROR("could not find ring read pointer!\n");
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
@@ -1455,7 +1447,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
        dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
        if (!dev->agp_buffer_map) {
                DRM_ERROR("could not find dma buffer region!\n");
-               dev->dev_private = (void *)dev_priv;
                radeon_do_cleanup_cp(dev);
                return DRM_ERR(EINVAL);
        }
@@ -1465,7 +1456,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
                    drm_core_findmap(dev, init->gart_textures_offset);
                if (!dev_priv->gart_textures) {
                        DRM_ERROR("could not find GART texture region!\n");
-                       dev->dev_private = (void *)dev_priv;
                        radeon_do_cleanup_cp(dev);
                        return DRM_ERR(EINVAL);
                }
@@ -1476,7 +1466,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
                                    init->sarea_priv_offset);
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci) {
+       if (dev_priv->flags & CHIP_IS_AGP) {
                drm_core_ioremap(dev_priv->cp_ring, dev);
                drm_core_ioremap(dev_priv->ring_rptr, dev);
                drm_core_ioremap(dev->agp_buffer_map, dev);
@@ -1484,7 +1474,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
                    !dev_priv->ring_rptr->handle ||
                    !dev->agp_buffer_map->handle) {
                        DRM_ERROR("could not find ioremap agp regions!\n");
-                       dev->dev_private = (void *)dev_priv;
                        radeon_do_cleanup_cp(dev);
                        return DRM_ERR(EINVAL);
                }
@@ -1525,7 +1514,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
            + RADEON_READ(RADEON_CONFIG_APER_SIZE);
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci)
+       if (dev_priv->flags & CHIP_IS_AGP)
                dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
                                                 - dev->agp->base
                                                 + dev_priv->gart_vm_start);
@@ -1551,7 +1540,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
        dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci) {
+       if (dev_priv->flags & CHIP_IS_AGP) {
                /* Turn off PCI GART */
                radeon_set_pcigart(dev_priv, 0);
        } else
@@ -1593,7 +1582,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
 
                if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
                        DRM_ERROR("failed to init PCI GART!\n");
-                       dev->dev_private = (void *)dev_priv;
                        radeon_do_cleanup_cp(dev);
                        return DRM_ERR(ENOMEM);
                }
@@ -1607,8 +1595,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
 
        dev_priv->last_buf = 0;
 
-       dev->dev_private = (void *)dev_priv;
-
        radeon_do_engine_reset(dev);
 
        return 0;
@@ -1627,11 +1613,15 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
                drm_irq_uninstall(dev);
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci) {
-               if (dev_priv->cp_ring != NULL)
+       if (dev_priv->flags & CHIP_IS_AGP) {
+               if (dev_priv->cp_ring != NULL) {
                        drm_core_ioremapfree(dev_priv->cp_ring, dev);
-               if (dev_priv->ring_rptr != NULL)
+                       dev_priv->cp_ring = NULL;
+               }
+               if (dev_priv->ring_rptr != NULL) {
                        drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+                       dev_priv->ring_rptr = NULL;
+               }
                if (dev->agp_buffer_map != NULL) {
                        drm_core_ioremapfree(dev->agp_buffer_map, dev);
                        dev->agp_buffer_map = NULL;
@@ -1639,16 +1629,20 @@ static int radeon_do_cleanup_cp(drm_device_t * dev)
        } else
 #endif
        {
-               if (dev_priv->gart_info.bus_addr)
+
+               if (dev_priv->gart_info.bus_addr) {
+                       /* Turn off PCI GART */
+                       radeon_set_pcigart(dev_priv, 0);
                        if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
                                DRM_ERROR("failed to cleanup PCI GART!\n");
+               }
 
-               if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
+               if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
+               {
                        drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
                        dev_priv->gart_info.addr = 0;
                }
        }
-
        /* only clear to the start of flags */
        memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
 
@@ -1674,7 +1668,7 @@ static int radeon_do_resume_cp(drm_device_t * dev)
        DRM_DEBUG("Starting radeon_do_resume_cp()\n");
 
 #if __OS_HAS_AGP
-       if (!dev_priv->is_pci) {
+       if (dev_priv->flags & CHIP_IS_AGP) {
                /* Turn off PCI GART */
                radeon_set_pcigart(dev_priv, 0);
        } else
@@ -2138,7 +2132,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
                dev_priv->flags |= CHIP_IS_PCIE;
 
        DRM_DEBUG("%s card detected\n",
-                 ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
+                 ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI"))));
        return ret;
 }
 
@@ -2171,7 +2165,6 @@ int radeon_driver_unload(struct drm_device *dev)
        drm_radeon_private_t *dev_priv = dev->dev_private;
 
        DRM_DEBUG("\n");
-
        drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
 
        dev->dev_private = NULL;
index 1cd81a6..9c177a6 100644 (file)
@@ -624,6 +624,11 @@ typedef struct drm_radeon_indirect {
        int discard;
 } drm_radeon_indirect_t;
 
+/* enum for card type parameters */
+#define RADEON_CARD_PCI 0
+#define RADEON_CARD_AGP 1
+#define RADEON_CARD_PCIE 2
+
 /* 1.3: An ioctl to get parameters that aren't available to the 3d
  * client any other way.
  */
@@ -640,6 +645,7 @@ typedef struct drm_radeon_indirect {
 #define RADEON_PARAM_SAREA_HANDLE          9
 #define RADEON_PARAM_GART_TEX_HANDLE       10
 #define RADEON_PARAM_SCRATCH_OFFSET        11
+#define RADEON_PARAM_CARD_TYPE             12
 
 typedef struct drm_radeon_getparam {
        int param;
index c37f2ea..498b19b 100644 (file)
@@ -38,7 +38,7 @@
 
 #define DRIVER_NAME            "radeon"
 #define DRIVER_DESC            "ATI Radeon"
-#define DRIVER_DATE            "20050911"
+#define DRIVER_DATE            "20051229"
 
 /* Interface history:
  *
@@ -73,7 +73,7 @@
  * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
  *       and GL_EXT_blend_[func|equation]_separate on r200
  * 1.12- Add R300 CP microcode support - this just loads the CP on r300
- *       (No 3D support yet - just microcode loading)
+ *       (No 3D support yet - just microcode loading).
  * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
  *     - Add hyperz support, add hyperz flags to clear ioctl.
  * 1.14- Add support for color tiling
  *       R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
  *       (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
  * 1.19- Add support for gart table in FB memory and PCIE r300
+ * 1.20- Add support for r300 texrect
+ * 1.21- Add support for card type getparam
  */
 #define DRIVER_MAJOR           1
-#define DRIVER_MINOR           19
+#define DRIVER_MINOR           21
 #define DRIVER_PATCHLEVEL      0
 
-#define GET_RING_HEAD(dev_priv)                DRM_READ32(  (dev_priv)->ring_rptr, 0 )
-#define SET_RING_HEAD(dev_priv,val)    DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
-
 /*
  * Radeon chip families
  */
@@ -138,6 +137,9 @@ enum radeon_chip_flags {
        CHIP_IS_PCIE = 0x00200000UL,
 };
 
+#define GET_RING_HEAD(dev_priv)                DRM_READ32(  (dev_priv)->ring_rptr, 0 )
+#define SET_RING_HEAD(dev_priv,val)    DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
+
 typedef struct drm_radeon_freelist {
        unsigned int age;
        drm_buf_t *buf;
@@ -214,8 +216,6 @@ typedef struct drm_radeon_private {
 
        int microcode_version;
 
-       int is_pci;
-
        struct {
                u32 boxes;
                int freelist_timeouts;
@@ -247,8 +247,6 @@ typedef struct drm_radeon_private {
 
        drm_radeon_depth_clear_t depth_clear;
 
-       unsigned long fb_offset;
-       unsigned long mmio_offset;
        unsigned long ring_offset;
        unsigned long ring_rptr_offset;
        unsigned long buffers_offset;
@@ -362,6 +360,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
  */
 
 #define RADEON_AGP_COMMAND             0x0f60
+#define RADEON_AGP_COMMAND_PCI_CONFIG   0x0060 /* offset in PCI config */
+#      define RADEON_AGP_ENABLE        (1<<8)
 #define RADEON_AUX_SCISSOR_CNTL                0x26f0
 #      define RADEON_EXCLUSIVE_SCISSOR_0       (1 << 24)
 #      define RADEON_EXCLUSIVE_SCISSOR_1       (1 << 25)
@@ -377,6 +377,7 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
 #      define RADEON_PLL_WR_EN                 (1 << 7)
 #define RADEON_CLOCK_CNTL_INDEX                0x0008
 #define RADEON_CONFIG_APER_SIZE                0x0108
+#define RADEON_CONFIG_MEMSIZE          0x00f8
 #define RADEON_CRTC_OFFSET             0x0224
 #define RADEON_CRTC_OFFSET_CNTL                0x0228
 #      define RADEON_CRTC_TILE_EN              (1 << 15)
@@ -648,6 +649,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
 
 #define RADEON_WAIT_UNTIL              0x1720
 #      define RADEON_WAIT_CRTC_PFLIP           (1 << 0)
+#      define RADEON_WAIT_2D_IDLE              (1 << 14)
+#      define RADEON_WAIT_3D_IDLE              (1 << 15)
 #      define RADEON_WAIT_2D_IDLECLEAN         (1 << 16)
 #      define RADEON_WAIT_3D_IDLECLEAN         (1 << 17)
 #      define RADEON_WAIT_HOST_IDLECLEAN       (1 << 18)
@@ -1102,7 +1105,6 @@ do {                                                                      \
                write = 0;                                      \
                _tab += _i;                                     \
        }                                                       \
-                                                               \
        while (_size > 0) {                                     \
                *(ring + write) = *_tab++;                      \
                write++;                                        \
index 9e816c6..e9d8ec3 100644 (file)
@@ -1,5 +1,5 @@
-/* radeon_state.c -- State support for Radeon -*- linux-c -*-
- *
+/* radeon_state.c -- State support for Radeon -*- linux-c -*- */
+/*
  * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
  * All Rights Reserved.
  *
@@ -72,10 +72,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
 
        case RADEON_EMIT_PP_MISC:
                if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
-                                                 &data[(RADEON_RB3D_DEPTHOFFSET
-                                                        -
-                                                        RADEON_PP_MISC) /
-                                                       4])) {
+                   &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) {
                        DRM_ERROR("Invalid depth buffer offset\n");
                        return DRM_ERR(EINVAL);
                }
@@ -83,10 +80,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
 
        case RADEON_EMIT_PP_CNTL:
                if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
-                                                 &data[(RADEON_RB3D_COLOROFFSET
-                                                        -
-                                                        RADEON_PP_CNTL) /
-                                                       4])) {
+                   &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) {
                        DRM_ERROR("Invalid colour buffer offset\n");
                        return DRM_ERR(EINVAL);
                }
@@ -109,10 +103,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
        case RADEON_EMIT_PP_TXFILTER_1:
        case RADEON_EMIT_PP_TXFILTER_2:
                if (radeon_check_and_fixup_offset(dev_priv, filp_priv,
-                                                 &data[(RADEON_PP_TXOFFSET_0
-                                                        -
-                                                        RADEON_PP_TXFILTER_0) /
-                                                       4])) {
+                   &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) {
                        DRM_ERROR("Invalid R100 texture offset\n");
                        return DRM_ERR(EINVAL);
                }
@@ -126,8 +117,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
        case R200_EMIT_PP_CUBIC_OFFSETS_5:{
                        int i;
                        for (i = 0; i < 5; i++) {
-                               if (radeon_check_and_fixup_offset
-                                   (dev_priv, filp_priv, &data[i])) {
+                               if (radeon_check_and_fixup_offset(dev_priv,
+                                                                 filp_priv,
+                                                                 &data[i])) {
                                        DRM_ERROR
                                            ("Invalid R200 cubic texture offset\n");
                                        return DRM_ERR(EINVAL);
@@ -239,8 +231,9 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
 
 static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
                                                     dev_priv,
-                                                    drm_file_t * filp_priv,
-                                                    drm_radeon_kcmd_buffer_t *cmdbuf,
+                                                    drm_file_t *filp_priv,
+                                                    drm_radeon_kcmd_buffer_t *
+                                                    cmdbuf,
                                                     unsigned int *cmdsz)
 {
        u32 *cmd = (u32 *) cmdbuf->buf;
@@ -555,7 +548,8 @@ static struct {
        {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
        {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
        {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
-       {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
+       {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
+        "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
        {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
        {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
        {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
@@ -569,7 +563,7 @@ static struct {
        {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
                    "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
        {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"},    /* 61 */
-       {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"},    /* 62 */
+       {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
        {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
        {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
        {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
@@ -592,7 +586,7 @@ static struct {
        {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
        {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
        {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
-       {R200_PP_AFS_0, 32, "R200_PP_AFS_0"},   /* 85 */
+       {R200_PP_AFS_0, 32, "R200_PP_AFS_0"},     /* 85 */
        {R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
        {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
        {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
@@ -985,8 +979,8 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev,
         * rendering a quad into just those buffers.  Thus, we have to
         * make sure the 3D engine is configured correctly.
         */
-       if ((dev_priv->microcode_version == UCODE_R200) &&
-           (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
+       else if ((dev_priv->microcode_version == UCODE_R200) &&
+               (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
 
                int tempPP_CNTL;
                int tempRE_CNTL;
@@ -1637,6 +1631,14 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
                    (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
                dwords = size / 4;
 
+#define RADEON_COPY_MT(_buf, _data, _width) \
+       do { \
+               if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
+                       DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
+                       return DRM_ERR(EFAULT); \
+               } \
+       } while(0)
+
                if (microtile) {
                        /* texture micro tiling in use, minimum texture width is thus 16 bytes.
                           however, we cannot use blitter directly for texture width < 64 bytes,
@@ -1648,46 +1650,19 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
                           from user space. */
                        if (tex->height == 1) {
                                if (tex_width >= 64 || tex_width <= 16) {
-                                       if (DRM_COPY_FROM_USER(buffer, data,
-                                                              tex_width *
-                                                              sizeof(u32))) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer, data,
+                                                tex_width * sizeof(u32));
                                } else if (tex_width == 32) {
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer, data, 16)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer + 8, data + 16, 16)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer, data, 16);
+                                       RADEON_COPY_MT(buffer + 8,
+                                                      data + 16, 16);
                                }
                        } else if (tex_width >= 64 || tex_width == 16) {
-                               if (DRM_COPY_FROM_USER(buffer, data,
-                                                      dwords * sizeof(u32))) {
-                                       DRM_ERROR("EFAULT on data, %d dwords\n",
-                                                 dwords);
-                                       return DRM_ERR(EFAULT);
-                               }
+                               RADEON_COPY_MT(buffer, data,
+                                              dwords * sizeof(u32));
                        } else if (tex_width < 16) {
                                for (i = 0; i < tex->height; i++) {
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer, data, tex_width)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer, data, tex_width);
                                        buffer += 4;
                                        data += tex_width;
                                }
@@ -1695,37 +1670,13 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
                                /* TODO: make sure this works when not fitting in one buffer
                                   (i.e. 32bytes x 2048...) */
                                for (i = 0; i < tex->height; i += 2) {
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer, data, 16)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer, data, 16);
                                        data += 16;
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer + 8, data, 16)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer + 8, data, 16);
                                        data += 16;
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer + 4, data, 16)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer + 4, data, 16);
                                        data += 16;
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer + 12, data, 16)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer + 12, data, 16);
                                        data += 16;
                                        buffer += 16;
                                }
@@ -1735,31 +1686,22 @@ static int radeon_cp_dispatch_texture(DRMFILE filp,
                                /* Texture image width is larger than the minimum, so we
                                 * can upload it directly.
                                 */
-                               if (DRM_COPY_FROM_USER(buffer, data,
-                                                      dwords * sizeof(u32))) {
-                                       DRM_ERROR("EFAULT on data, %d dwords\n",
-                                                 dwords);
-                                       return DRM_ERR(EFAULT);
-                               }
+                               RADEON_COPY_MT(buffer, data,
+                                              dwords * sizeof(u32));
                        } else {
                                /* Texture image width is less than the minimum, so we
                                 * need to pad out each image scanline to the minimum
                                 * width.
                                 */
                                for (i = 0; i < tex->height; i++) {
-                                       if (DRM_COPY_FROM_USER
-                                           (buffer, data, tex_width)) {
-                                               DRM_ERROR
-                                                   ("EFAULT on pad, %d bytes\n",
-                                                    tex_width);
-                                               return DRM_ERR(EFAULT);
-                                       }
+                                       RADEON_COPY_MT(buffer, data, tex_width);
                                        buffer += 8;
                                        data += tex_width;
                                }
                        }
                }
 
+#undef RADEON_COPY_MT
                buf->filp = filp;
                buf->used = size;
                offset = dev_priv->gart_buffers_offset + buf->offset;
@@ -1821,7 +1763,7 @@ static void radeon_cp_dispatch_stipple(drm_device_t * dev, u32 * stipple)
 }
 
 static void radeon_apply_surface_regs(int surf_index,
-                                     drm_radeon_private_t * dev_priv)
+                                     drm_radeon_private_t *dev_priv)
 {
        if (!dev_priv->mmio)
                return;
@@ -1847,8 +1789,8 @@ static void radeon_apply_surface_regs(int surf_index,
  * freed, we suddenly need two surfaces to store A and C, which might
  * not always be available.
  */
-static int alloc_surface(drm_radeon_surface_alloc_t * new,
-                        drm_radeon_private_t * dev_priv, DRMFILE filp)
+static int alloc_surface(drm_radeon_surface_alloc_t *new,
+                        drm_radeon_private_t *dev_priv, DRMFILE filp)
 {
        struct radeon_virt_surface *s;
        int i;
@@ -2158,6 +2100,11 @@ static int radeon_cp_vertex(DRM_IOCTL_ARGS)
 
        LOCK_TEST_WITH_RETURN(dev, filp);
 
+       if (!dev_priv) {
+               DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+               return DRM_ERR(EINVAL);
+       }
+
        DRM_GET_PRIV_WITH_RETURN(filp_priv, filp);
 
        DRM_COPY_FROM_USER_IOCTL(vertex, (drm_radeon_vertex_t __user *) data,
@@ -2596,9 +2543,9 @@ static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
        return 0;
 }
 
-static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
+static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
                                          drm_radeon_cmd_header_t header,
-                                         drm_radeon_kcmd_buffer_t * cmdbuf)
+                                         drm_radeon_kcmd_buffer_t *cmdbuf)
 {
        int sz = header.scalars.count;
        int start = header.scalars.offset;
@@ -2618,9 +2565,9 @@ static __inline__ int radeon_emit_scalars(drm_radeon_private_t * dev_priv,
 
 /* God this is ugly
  */
-static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
+static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
                                           drm_radeon_cmd_header_t header,
-                                          drm_radeon_kcmd_buffer_t * cmdbuf)
+                                          drm_radeon_kcmd_buffer_t *cmdbuf)
 {
        int sz = header.scalars.count;
        int start = ((unsigned int)header.scalars.offset) + 0x100;
@@ -2638,9 +2585,9 @@ static __inline__ int radeon_emit_scalars2(drm_radeon_private_t * dev_priv,
        return 0;
 }
 
-static __inline__ int radeon_emit_vectors(drm_radeon_private_t * dev_priv,
+static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
                                          drm_radeon_cmd_header_t header,
-                                         drm_radeon_kcmd_buffer_t * cmdbuf)
+                                         drm_radeon_kcmd_buffer_t *cmdbuf)
 {
        int sz = header.vectors.count;
        int start = header.vectors.offset;
@@ -2685,8 +2632,8 @@ static int radeon_emit_packet3(drm_device_t * dev,
        return 0;
 }
 
-static int radeon_emit_packet3_cliprect(drm_device_t * dev,
-                                       drm_file_t * filp_priv,
+static int radeon_emit_packet3_cliprect(drm_device_t *dev,
+                                       drm_file_t *filp_priv,
                                        drm_radeon_kcmd_buffer_t *cmdbuf,
                                        int orig_nbox)
 {
@@ -2818,7 +2765,8 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
                kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
                if (kbuf == NULL)
                        return DRM_ERR(ENOMEM);
-               if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf, cmdbuf.bufsz)) {
+               if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf.buf,
+                                      cmdbuf.bufsz)) {
                        drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
                        return DRM_ERR(EFAULT);
                }
@@ -2981,7 +2929,7 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
                value = dev_priv->gart_vm_start;
                break;
        case RADEON_PARAM_REGISTER_HANDLE:
-               value = dev_priv->mmio_offset;
+               value = dev_priv->mmio->offset;
                break;
        case RADEON_PARAM_STATUS_HANDLE:
                value = dev_priv->ring_rptr_offset;
@@ -3004,6 +2952,15 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS)
        case RADEON_PARAM_GART_TEX_HANDLE:
                value = dev_priv->gart_textures_offset;
                break;
+       
+       case RADEON_PARAM_CARD_TYPE:
+               if (dev_priv->flags & CHIP_IS_PCIE)
+                       value = RADEON_CARD_PCIE;
+               else if (dev_priv->flags & CHIP_IS_AGP)
+                       value = RADEON_CARD_AGP;
+               else
+                       value = RADEON_CARD_PCI;
+               break;
        default:
                return DRM_ERR(EINVAL);
        }
@@ -3066,6 +3023,7 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
 /* When a client dies:
  *    - Check for and clean up flipped page state
  *    - Free any alloced GART memory.
+ *    - Free any alloced radeon surfaces.
  *
  * DRM infrastructure takes care of reclaiming dma buffers.
  */
@@ -3092,6 +3050,7 @@ int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv)
        drm_radeon_private_t *dev_priv = dev->dev_private;
        struct drm_radeon_driver_file_fields *radeon_priv;
 
+       DRM_DEBUG("\n");
        radeon_priv =
            (struct drm_radeon_driver_file_fields *)
            drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
@@ -3100,6 +3059,7 @@ int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv)
                return -ENOMEM;
 
        filp_priv->driver_priv = radeon_priv;
+
        if (dev_priv)
                radeon_priv->radeon_fb_delta = dev_priv->fb_location;
        else