From c04bb660f45137a8585724f1b8819919054494c5 Mon Sep 17 00:00:00 2001 From: Jose Fonseca Date: Tue, 23 Apr 2002 23:47:09 +0000 Subject: [PATCH] Better support for kernel ring buffers. Changes to allow the evetual use of buffer aging. --- linux/mach64_dma.c | 16 ++++++++++++++++ linux/mach64_drv.h | 35 ++++++++++++++++++++++++++++++++--- linux/mach64_state.c | 6 +++--- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/linux/mach64_dma.c b/linux/mach64_dma.c index ede02e9e..4e6c8ddf 100644 --- a/linux/mach64_dma.c +++ b/linux/mach64_dma.c @@ -77,6 +77,8 @@ int mach64_do_wait_for_idle( drm_mach64_private_t *dev_priv ) * DMA initialization, cleanup */ + + /* Reset the engine. This will stop the DMA if it is running. */ int mach64_do_engine_reset( drm_device_t *dev ) @@ -338,6 +340,20 @@ drm_buf_t *mach64_freelist_get( drm_device_t *dev ) DRM_ERROR( "returning NULL!\n" ); return NULL; } + +void mach64_freelist_reset( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + int i; + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + drm_buf_t *buf = dma->buflist[i]; + drm_mach64_buf_priv_t *buf_priv = buf->dev_private; + buf_priv->age = 0; + } +} + + /* ================================================================ * DMA command submission */ diff --git a/linux/mach64_drv.h b/linux/mach64_drv.h index e483bf5c..5c2e7adc 100644 --- a/linux/mach64_drv.h +++ b/linux/mach64_drv.h @@ -29,8 +29,20 @@ #ifndef __MACH64_DRV_H__ #define __MACH64_DRV_H__ +typedef struct drm_mach64_freelist { + unsigned int age; + drm_buf_t *buf; + struct drm_mach64_freelist *next; + struct drm_mach64_freelist *prev; +} drm_mach64_freelist_t; + typedef struct drm_mach64_private { drm_mach64_sarea_t *sarea_priv; + + drm_mach64_freelist_t *head; + drm_mach64_freelist_t *tail; + + int usec_timeout; int is_pci; unsigned int fb_bpp; @@ -44,8 +56,6 @@ typedef struct drm_mach64_private { u32 back_offset_pitch; u32 depth_offset_pitch; - int usec_timeout; - drm_map_t *sarea; drm_map_t *fb; drm_map_t *mmio; @@ -54,7 +64,11 @@ typedef struct drm_mach64_private { } drm_mach64_private_t; typedef struct drm_mach64_buf_priv { - int age; + u32 age; + int prim; + int discard; + int dispatched; + drm_mach64_freelist_t *list_entry; } drm_mach64_buf_priv_t; /* mach64_dma.c */ @@ -67,6 +81,9 @@ extern int mach64_engine_reset( struct inode *inode, struct file *filp, extern int mach64_dma_buffers( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +extern void mach64_freelist_reset( drm_device_t *dev ); +extern drm_buf_t *mach64_freelist_get( drm_device_t *dev ); + extern int mach64_do_wait_for_fifo( drm_mach64_private_t *dev_priv, int entries ); extern int mach64_do_wait_for_idle( drm_mach64_private_t *dev_priv ); @@ -367,6 +384,18 @@ do { \ } \ } while (0) +#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \ +do { \ + drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; \ + if ( sarea_priv->last_dispatch >= MACH64_MAX_VB_AGE ) { \ + int __ret = mach64_do_dma_idle( dev_priv ); \ + if ( __ret < 0 ) return __ret; \ + sarea_priv->last_dispatch = 0; \ + mach64_freelist_reset( dev ); \ + } \ +} while (0) + + /* ================================================================ * DMA macros */ diff --git a/linux/mach64_state.c b/linux/mach64_state.c index 2a55242a..b1bd9783 100644 --- a/linux/mach64_state.c +++ b/linux/mach64_state.c @@ -591,8 +591,10 @@ int mach64_dma_vertex( struct inode *inode, struct file *filp, DRM_ERROR( "buffer prim %d\n", vertex.prim ); return -EINVAL; } -#endif + VB_AGE_TEST_WITH_RETURN( dev_priv ); +#endif + buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; @@ -607,10 +609,8 @@ int mach64_dma_vertex( struct inode *inode, struct file *filp, } buf->used = vertex.count; -#if 0 buf_priv->prim = vertex.prim; buf_priv->discard = vertex.discard; -#endif mach64_dma_dispatch_vertex( dev, buf );