diff options
-rw-r--r-- | shared-core/savage_bci.c | 27 | ||||
-rw-r--r-- | shared-core/savage_drv.h | 13 |
2 files changed, 31 insertions, 9 deletions
diff --git a/shared-core/savage_bci.c b/shared-core/savage_bci.c index 36fb8737..3ddcccb6 100644 --- a/shared-core/savage_bci.c +++ b/shared-core/savage_bci.c @@ -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); } /* diff --git a/shared-core/savage_drv.h b/shared-core/savage_drv.h index 54ba7e71..2b44e529 100644 --- a/shared-core/savage_drv.h +++ b/shared-core/savage_drv.h @@ -30,10 +30,10 @@ #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__ */ |