OSDN Git Service

xgixp: Remove dependency on TTM fences
authorIan Romanick <idr@us.ibm.com>
Wed, 11 Jun 2008 05:18:14 +0000 (22:18 -0700)
committerIan Romanick <idr@us.ibm.com>
Wed, 11 Jun 2008 05:18:14 +0000 (22:18 -0700)
linux-core/xgi_cmdlist.c
linux-core/xgi_drv.c
linux-core/xgi_drv.h
linux-core/xgi_fence.c
shared-core/xgi_drm.h

index 64401ae..e433c21 100644 (file)
@@ -148,7 +148,9 @@ int xgi_submit_cmdlist(struct drm_device * dev, void * data,
        }
 
        info->cmdring.last_ptr = xgi_find_pcie_virt(info, pCmdInfo->hw_addr);
+#ifdef XGI_HAVE_FENCE
        drm_fence_flush_old(info->dev, 0, info->next_sequence);
+#endif /* XGI_HAVE_FENCE */
        return 0;
 }
 
index f0225f8..532408d 100644 (file)
@@ -37,7 +37,9 @@ static struct pci_device_id pciidlist[] = {
        xgi_PCI_IDS
 };
 
+#ifdef XGI_HAVE_FENCE
 extern struct drm_fence_driver xgi_fence_driver;
+#endif /* XGI_HAVE_FENCE */
 
 int xgi_bootstrap(struct drm_device *, void *, struct drm_file *);
 
@@ -47,6 +49,8 @@ static struct drm_ioctl_desc xgi_ioctls[] = {
        DRM_IOCTL_DEF(DRM_XGI_FREE, xgi_free_ioctl, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_XGI_SUBMIT_CMDLIST, xgi_submit_cmdlist, DRM_AUTH),
        DRM_IOCTL_DEF(DRM_XGI_STATE_CHANGE, xgi_state_change_ioctl, DRM_AUTH|DRM_MASTER),
+       DRM_IOCTL_DEF(DRM_XGI_SET_FENCE, xgi_set_fence_ioctl, DRM_AUTH),
+       DRM_IOCTL_DEF(DRM_XGI_WAIT_FENCE, xgi_wait_fence_ioctl, DRM_AUTH),
 };
 
 static const int xgi_max_ioctl = DRM_ARRAY_SIZE(xgi_ioctls);
@@ -58,6 +62,7 @@ static void xgi_driver_lastclose(struct drm_device * dev);
 static void xgi_reclaim_buffers_locked(struct drm_device * dev,
        struct drm_file * filp);
 static irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS);
+static int xgi_kern_isr_postinstall(struct drm_device * dev);
 
 
 static struct drm_driver driver = {
@@ -70,7 +75,7 @@ static struct drm_driver driver = {
        .lastclose = xgi_driver_lastclose,
        .dma_quiescent = NULL,
        .irq_preinstall = NULL,
-       .irq_postinstall = NULL,
+       .irq_postinstall = xgi_kern_isr_postinstall,
        .irq_uninstall = NULL,
        .irq_handler = xgi_kern_isr,
        .reclaim_buffers = drm_core_reclaim_buffers,
@@ -100,7 +105,9 @@ static struct drm_driver driver = {
                .remove = __devexit_p(drm_cleanup_pci),
        },
 
+#ifdef XGI_HAVE_FENCE
        .fence_driver = &xgi_fence_driver,
+#endif /* XGI_HAVE_FENCE */
 
        .name = DRIVER_NAME,
        .desc = DRIVER_DESC,
@@ -355,7 +362,10 @@ irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS)
                DRM_WRITE32(info->mmio_map,
                            0x2800 + M2REG_AUTO_LINK_SETTING_ADDRESS,
                            cpu_to_le32(M2REG_AUTO_LINK_SETTING_COMMAND | irq_bits));
+#ifdef XGI_HAVE_FENCE
                xgi_fence_handler(dev);
+#endif /* XGI_HAVE_FENCE */
+               DRM_WAKEUP(&info->fence_queue);
                return IRQ_HANDLED;
        } else {
                return IRQ_NONE;
@@ -363,6 +373,15 @@ irqreturn_t xgi_kern_isr(DRM_IRQ_ARGS)
 }
 
 
+int xgi_kern_isr_postinstall(struct drm_device * dev)
+{
+       struct xgi_info *info = dev->dev_private;
+
+       DRM_INIT_WAITQUEUE(&info->fence_queue);
+       return 0;
+}
+
+
 int xgi_driver_load(struct drm_device *dev, unsigned long flags)
 {
        struct xgi_info *info = drm_alloc(sizeof(*info), DRM_MEM_DRIVER);
index 0d85e55..2fd73b9 100644 (file)
@@ -74,6 +74,7 @@ struct xgi_info {
        struct xgi_cmdring_info cmdring;
 
        DRM_SPINTYPE fence_lock;
+       wait_queue_head_t fence_queue;
        unsigned complete_sequence;
        unsigned next_sequence;
 };
@@ -98,12 +99,24 @@ extern void xgi_disable_mmio(struct xgi_info * info);
 extern void xgi_enable_ge(struct xgi_info * info);
 extern void xgi_disable_ge(struct xgi_info * info);
 
+/* TTM-style fences.
+ */
+#ifdef XGI_HAVE_FENCE
 extern void xgi_poke_flush(struct drm_device * dev, uint32_t class);
 extern int xgi_fence_emit_sequence(struct drm_device * dev, uint32_t class,
        uint32_t flags, uint32_t * sequence, uint32_t * native_type);
 extern void xgi_fence_handler(struct drm_device * dev);
 extern int xgi_fence_has_irq(struct drm_device *dev, uint32_t class,
        uint32_t flags);
+#endif /* XGI_HAVE_FENCE */
+
+
+/* Non-TTM-style fences.
+ */
+extern int xgi_set_fence_ioctl(struct drm_device * dev, void * data,
+       struct drm_file * filp);
+extern int xgi_wait_fence_ioctl(struct drm_device * dev, void * data,
+       struct drm_file * filp);
 
 extern int xgi_alloc_ioctl(struct drm_device * dev, void * data,
        struct drm_file * filp);
index 63ed29e..38cf9e4 100644 (file)
 #include "xgi_misc.h"
 #include "xgi_cmdlist.h"
 
+static int xgi_low_level_fence_emit(struct drm_device *dev, u32 *sequence)
+{
+       struct xgi_info *const info = dev->dev_private;
+
+       if (info == NULL) {
+               DRM_ERROR("called with no initialization\n");
+               return -EINVAL;
+       }
+
+       DRM_SPINLOCK(&info->fence_lock);
+       info->next_sequence++;
+       if (info->next_sequence > BEGIN_BEGIN_IDENTIFICATION_MASK) {
+               info->next_sequence = 1;
+       }
+
+       *sequence = (u32) info->next_sequence;
+       DRM_SPINUNLOCK(&info->fence_lock);
+
+
+       xgi_emit_irq(info);
+       return 0;
+}
+
+#define GET_BEGIN_ID(i) (le32_to_cpu(DRM_READ32((i)->mmio_map, 0x2820)) \
+                                & BEGIN_BEGIN_IDENTIFICATION_MASK)
+
+static int xgi_low_level_fence_wait(struct drm_device *dev, unsigned *sequence)
+{
+       struct xgi_info *const info = dev->dev_private;
+       unsigned int cur_fence;
+       int ret = 0;
+
+       if (info == NULL) {
+               DRM_ERROR("called with no initialization\n");
+               return -EINVAL;
+       }
+
+       /* Assume that the user has missed the current sequence number
+        * by about a day rather than she wants to wait for years
+        * using fences.
+        */
+       DRM_WAIT_ON(ret, info->fence_queue, 3 * DRM_HZ,
+                   ((((cur_fence = GET_BEGIN_ID(info))
+                     - *sequence) & BEGIN_BEGIN_IDENTIFICATION_MASK)
+                    <= (1 << 18)));
+
+       info->complete_sequence = cur_fence;
+       *sequence = cur_fence;
+
+       return ret;
+}
+
+
+int xgi_set_fence_ioctl(struct drm_device * dev, void * data,
+                       struct drm_file * filp)
+{
+       (void) filp;
+       return xgi_low_level_fence_emit(dev, (u32 *) data);
+}
+
+
+int xgi_wait_fence_ioctl(struct drm_device * dev, void * data,
+                        struct drm_file * filp)
+{
+       (void) filp;
+       return xgi_low_level_fence_wait(dev, (u32 *) data);
+}
+
+
+#ifdef XGI_HAVE_FENCE
 static void xgi_fence_poll(struct drm_device * dev, uint32_t class, 
                           uint32_t waiting_types)
 {
@@ -68,25 +138,18 @@ int xgi_fence_emit_sequence(struct drm_device * dev, uint32_t class,
                            uint32_t flags, uint32_t * sequence,
                            uint32_t * native_type)
 {
-       struct xgi_info * info = dev->dev_private;
+       int err;
 
-       if ((info == NULL) || (class != 0))
-               return -EINVAL;
-
-
-       DRM_SPINLOCK(&info->fence_lock);
-       info->next_sequence++;
-       if (info->next_sequence > BEGIN_BEGIN_IDENTIFICATION_MASK) {
-               info->next_sequence = 1;
-       }
-       DRM_SPINUNLOCK(&info->fence_lock);
+       (void) flags;
 
+       if (class != 0)
+               return -EINVAL;
 
-       xgi_emit_irq(info);
+       err = xgi_low_level_fence_emit(dev, sequence);
+       if (err)
+               return err;
 
-       *sequence = (uint32_t) info->next_sequence;
        *native_type = DRM_FENCE_TYPE_EXE;
-
        return 0;
 }
 
@@ -120,3 +183,4 @@ struct drm_fence_driver xgi_fence_driver = {
        .wait = NULL
 };
 
+#endif /* XGI_HAVE_FENCE */
index ce58442..7d01065 100644 (file)
@@ -123,11 +123,15 @@ struct xgi_state_info {
 #define DRM_XGI_FREE                2
 #define DRM_XGI_SUBMIT_CMDLIST      3
 #define DRM_XGI_STATE_CHANGE        4
+#define DRM_XGI_SET_FENCE           5
+#define DRM_XGI_WAIT_FENCE          6
 
 #define XGI_IOCTL_BOOTSTRAP         DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_BOOTSTRAP, struct xgi_bootstrap)
 #define XGI_IOCTL_ALLOC             DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_ALLOC, struct xgi_mem_alloc)
 #define XGI_IOCTL_FREE              DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_FREE, __u32)
 #define XGI_IOCTL_SUBMIT_CMDLIST    DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_SUBMIT_CMDLIST, struct xgi_cmd_info)
 #define XGI_IOCTL_STATE_CHANGE      DRM_IOW(DRM_COMMAND_BASE + DRM_XGI_STATE_CHANGE, struct xgi_state_info)
+#define XGI_IOCTL_SET_FENCE         DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_SET_FENCE, u32)
+#define XGI_IOCTL_WAIT_FENCE        DRM_IOWR(DRM_COMMAND_BASE + DRM_XGI_WAIT_FENCE, u32)
 
 #endif /* _XGI_DRM_H_ */