Use wrap counter to extend 16-bit hardware event tags to 32-bit logical
authorFelix Kuehling <fxkuehl@gmx.de>
Wed, 23 Feb 2005 16:34:30 +0000 (16:34 +0000)
committerFelix Kuehling <fxkuehl@gmx.de>
Wed, 23 Feb 2005 16:34:30 +0000 (16:34 +0000)
    event counters in the SAVAGE_EVENT_EMIT/WAIT ioctls. This is needed for
    reliable client-side texture heap aging. Slightly simplified DMA buffer
    aging while at it. Bumped minor version and driver date.

shared-core/savage_bci.c
shared-core/savage_drv.h

index 36fb873..3ddcccb 100644 (file)
@@ -246,6 +246,8 @@ static drm_buf_t *savage_freelist_get(drm_device_t *dev)
        else
                event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
        wrap = dev_priv->event_wrap;
+       if (event > dev_priv->event_counter)
+           wrap--; /* hardware hasn't passed the last wrap yet */
 
        DRM_DEBUG("   tail=0x%04x %d\n", tail->age.event, tail->age.wrap);
        DRM_DEBUG("   head=0x%04x %d\n", event, wrap);
@@ -623,6 +625,7 @@ int savage_bci_event_emit(DRM_IOCTL_ARGS)
                                 sizeof(event));
 
        event.count = savage_bci_emit_event(dev_priv, event.flags);
+       event.count |= dev_priv->event_wrap << 16;
        DRM_COPY_TO_USER_IOCTL(&((drm_savage_event_emit_t __user *)data)->count,
                               event.count, sizeof(event.count));
        return 0;
@@ -633,16 +636,34 @@ int savage_bci_event_wait(DRM_IOCTL_ARGS)
        DRM_DEVICE;
        drm_savage_private_t *dev_priv = dev->dev_private;
        drm_savage_event_wait_t event;
+       unsigned int event_e, hw_e;
+       unsigned int event_w, hw_w;
 
        DRM_DEBUG("\n");
 
        DRM_COPY_FROM_USER_IOCTL(event, (drm_savage_event_wait_t __user *)data,
                                 sizeof(event));
 
-       if (event.count > 0xffff)
-               return DRM_ERR(EINVAL);
+       UPDATE_EVENT_COUNTER();
+       if (dev_priv->status_ptr)
+               hw_e = dev_priv->status_ptr[1] & 0xffff;
+       else
+               hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
+       hw_w = dev_priv->event_wrap;
+       if (hw_e > dev_priv->event_counter)
+           hw_w--; /* hardware hasn't passed the last wrap yet */
 
-       return dev_priv->wait_evnt(dev_priv, event.count);
+       event_e = event.count & 0xffff;
+       event_w = event.count >> 16;
+
+       /* Don't need to wait if
+        * - event counter wrapped since the event was emitted or
+        * - the hardware has advanced up to or over the event to wait for.
+        */
+       if (event_w < hw_w || event_e <= hw_e )
+               return 0;
+       else
+               return dev_priv->wait_evnt(dev_priv, event_e);
 }
 
 /*
index 54ba7e7..2b44e52 100644 (file)
 
 #define DRIVER_NAME    "savage"
 #define DRIVER_DESC    "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]"
-#define DRIVER_DATE    "20050120"
+#define DRIVER_DATE    "20050222"
 
 #define DRIVER_MAJOR           2
-#define DRIVER_MINOR           2
+#define DRIVER_MINOR           3
 #define DRIVER_PATCHLEVEL      0
 /* Interface history:
  *
@@ -42,6 +42,9 @@
  * 2.1   Scissors registers managed by the DRM, 3D operations clipped by
  *       cliprects of the cmdbuf ioctl
  * 2.2   Implemented SAVAGE_CMD_DMA_IDX and SAVAGE_CMD_VB_IDX
+ * 2.3   Event counters used by BCI_EVENT_EMIT/WAIT ioctls are now 32 bits
+ *       wide and thus very long lived (unlikely to ever wrap). The size
+ *       in the struct was 32 bits before, but only 16 bits were used
  */
 
 typedef struct drm_savage_age {
@@ -489,9 +492,7 @@ extern void savage_emit_clip_rect_s4(drm_savage_private_t *dev_priv,
        (age)->wrap = w;                \
 } while(0)
 
-#define TEST_AGE( age, e, w )                                          \
-       ( (age)->wrap+1 < (w) ||                                        \
-         ( (age)->wrap+1 == (w) && (e) <= dev_priv->event_counter ) || \
-         (age)->event <= (e) )
+#define TEST_AGE( age, e, w )                          \
+       ( (age)->wrap < (w) || (age)->event <= (e) )
 
 #endif /* __SAVAGE_DRV_H__ */