mach64: make buffer emission macros normal functions
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 5 Dec 2007 22:53:02 +0000 (22:53 +0000)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 5 Dec 2007 22:54:10 +0000 (22:54 +0000)
shared-core/mach64_dma.c
shared-core/mach64_drv.h

index dd3547f..9aa3f76 100644 (file)
@@ -559,6 +559,233 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
 
 
 /*******************************************************************/
+/** \name DMA descriptor ring macros */
+/*@{*/
+
+static __inline__ void mach64_set_dma_eol(volatile u32 * addr)
+{
+#if defined(__i386__)
+       int nr = 31;
+
+       /* Taken from include/asm-i386/bitops.h linux header */
+       __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr)
+                            :"Ir"(nr));
+#elif defined(__powerpc__)
+       u32 old;
+       u32 mask = cpu_to_le32(MACH64_DMA_EOL);
+
+       /* Taken from the include/asm-ppc/bitops.h linux header */
+       __asm__ __volatile__("\n\
+1:     lwarx   %0,0,%3 \n\
+       or      %0,%0,%2 \n\
+       stwcx.  %0,0,%3 \n\
+       bne-    1b":"=&r"(old), "=m"(*addr)
+                            :"r"(mask), "r"(addr), "m"(*addr)
+                            :"cc");
+#elif defined(__alpha__)
+       u32 temp;
+       u32 mask = MACH64_DMA_EOL;
+
+       /* Taken from the include/asm-alpha/bitops.h linux header */
+       __asm__ __volatile__("1:        ldl_l %0,%3\n"
+                            "  bis %0,%2,%0\n"
+                            "  stl_c %0,%1\n"
+                            "  beq %0,2f\n"
+                            ".subsection 2\n"
+                            "2:        br 1b\n"
+                            ".previous":"=&r"(temp), "=m"(*addr)
+                            :"Ir"(mask), "m"(*addr));
+#else
+       u32 mask = cpu_to_le32(MACH64_DMA_EOL);
+
+       *addr |= mask;
+#endif
+}
+
+static __inline__ void mach64_clear_dma_eol(volatile u32 * addr)
+{
+#if defined(__i386__)
+       int nr = 31;
+
+       /* Taken from include/asm-i386/bitops.h linux header */
+       __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr)
+                            :"Ir"(nr));
+#elif defined(__powerpc__)
+       u32 old;
+       u32 mask = cpu_to_le32(MACH64_DMA_EOL);
+
+       /* Taken from the include/asm-ppc/bitops.h linux header */
+       __asm__ __volatile__("\n\
+1:     lwarx   %0,0,%3 \n\
+       andc    %0,%0,%2 \n\
+       stwcx.  %0,0,%3 \n\
+       bne-    1b":"=&r"(old), "=m"(*addr)
+                            :"r"(mask), "r"(addr), "m"(*addr)
+                            :"cc");
+#elif defined(__alpha__)
+       u32 temp;
+       u32 mask = ~MACH64_DMA_EOL;
+
+       /* Taken from the include/asm-alpha/bitops.h linux header */
+       __asm__ __volatile__("1:        ldl_l %0,%3\n"
+                            "  and %0,%2,%0\n"
+                            "  stl_c %0,%1\n"
+                            "  beq %0,2f\n"
+                            ".subsection 2\n"
+                            "2:        br 1b\n"
+                            ".previous":"=&r"(temp), "=m"(*addr)
+                            :"Ir"(mask), "m"(*addr));
+#else
+       u32 mask = cpu_to_le32(~MACH64_DMA_EOL);
+
+       *addr &= mask;
+#endif
+}
+
+#define RING_LOCALS                                                                    \
+       int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
+
+#define RING_WRITE_OFS  _ring_write
+
+#define BEGIN_RING( n )                                                                        \
+do {                                                                                   \
+       if ( MACH64_VERBOSE ) {                                                         \
+               DRM_INFO( "BEGIN_RING( %d ) in %s\n",                                   \
+                          (n), __FUNCTION__ );                                         \
+       }                                                                               \
+       if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {                              \
+               int ret;                                                                \
+               if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) {        \
+                       DRM_ERROR( "wait_ring failed, resetting engine\n");             \
+                       mach64_dump_engine_info( dev_priv );                            \
+                       mach64_do_engine_reset( dev_priv );                             \
+                       return ret;                                                     \
+               }                                                                       \
+       }                                                                               \
+       dev_priv->ring.space -= (n) * sizeof(u32);                                      \
+       _ring = (u32 *) dev_priv->ring.start;                                           \
+       _ring_tail = _ring_write = dev_priv->ring.tail;                                 \
+       _ring_mask = dev_priv->ring.tail_mask;                                          \
+} while (0)
+
+#define OUT_RING( x )                                          \
+do {                                                           \
+       if ( MACH64_VERBOSE ) {                                 \
+               DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",    \
+                          (unsigned int)(x), _ring_write );    \
+       }                                                       \
+       _ring[_ring_write++] = cpu_to_le32( x );                \
+       _ring_write &= _ring_mask;                              \
+} while (0)
+
+#define ADVANCE_RING()                                                 \
+do {                                                                   \
+       if ( MACH64_VERBOSE ) {                                         \
+               DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",     \
+                         _ring_write, _ring_tail );                    \
+       }                                                               \
+       DRM_MEMORYBARRIER();                                            \
+       mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] );  \
+       DRM_MEMORYBARRIER();                                            \
+       dev_priv->ring.tail = _ring_write;                              \
+       mach64_ring_tick( dev_priv, &(dev_priv)->ring );                \
+} while (0)
+
+
+int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv,
+                           drm_mach64_freelist_t *entry)
+{
+       int bytes, pages, remainder;
+       u32 address, page;
+       int i;
+       struct drm_buf *buf = entry->buf;
+       RING_LOCALS;
+
+       bytes = buf->used;
+       address = GETBUFADDR( buf );
+       pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;
+
+       BEGIN_RING( pages * 4 );
+
+       for ( i = 0 ; i < pages-1 ; i++ ) {
+               page = address + i * MACH64_DMA_CHUNKSIZE;
+               OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
+               OUT_RING( page );
+               OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );
+               OUT_RING( 0 );
+       }
+
+       /* generate the final descriptor for any remaining commands in this buffer */
+       page = address + i * MACH64_DMA_CHUNKSIZE;
+       remainder = bytes - i * MACH64_DMA_CHUNKSIZE;
+
+       /* Save dword offset of last descriptor for this buffer.
+        * This is needed to check for completion of the buffer in freelist_get
+        */
+       entry->ring_ofs = RING_WRITE_OFS;
+
+       OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
+       OUT_RING( page );
+       OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );
+       OUT_RING( 0 );
+
+       ADVANCE_RING();
+       
+       return 0;
+}
+
+int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv,
+                                    drm_mach64_freelist_t *entry)
+{
+       int bytes, pages, remainder;
+       u32 address, page;
+       int i;
+       struct drm_buf *buf = entry->buf;
+       RING_LOCALS;
+       
+       bytes = buf->used - MACH64_HOSTDATA_BLIT_OFFSET;
+       pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;
+       address = GETBUFADDR( buf );
+       
+       BEGIN_RING( 4 + pages * 4 );
+       
+       OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );
+       OUT_RING( address );
+       OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET );
+       OUT_RING( 0 );
+       address += MACH64_HOSTDATA_BLIT_OFFSET;
+       
+       for ( i = 0 ; i < pages-1 ; i++ ) {
+               page = address + i * MACH64_DMA_CHUNKSIZE;
+               OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );
+               OUT_RING( page );
+               OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );
+               OUT_RING( 0 );
+       }
+       
+       /* generate the final descriptor for any remaining commands in this buffer */
+       page = address + i * MACH64_DMA_CHUNKSIZE;
+       remainder = bytes - i * MACH64_DMA_CHUNKSIZE;
+       
+       /* Save dword offset of last descriptor for this buffer.
+        * This is needed to check for completion of the buffer in freelist_get
+        */
+       entry->ring_ofs = RING_WRITE_OFS;
+       
+       OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );
+       OUT_RING( page );
+       OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );
+       OUT_RING( 0 );
+       
+       ADVANCE_RING();
+       
+       return 0;
+}
+
+/*@}*/
+
+
+/*******************************************************************/
 /** \name DMA test and initialization */
 /*@{*/
 
index 347c942..7bd40a6 100644 (file)
@@ -140,6 +140,11 @@ extern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv);
 extern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv);
 extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv);
 
+extern int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv,
+                                  drm_mach64_freelist_t *_entry);
+extern int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv,
+                                           drm_mach64_freelist_t *_entry);
+
 extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv);
 extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv);
 extern int mach64_do_cleanup_dma(struct drm_device * dev);
@@ -521,89 +526,9 @@ extern void mach64_driver_irq_uninstall(struct drm_device * dev);
 #define MACH64_APERTURE_OFFSET         0x7ff800        /* frame-buffer offset for gui-masters */
 
 /* ================================================================
- * Misc helper macros
+ * Ring operations
  */
 
-static __inline__ void mach64_set_dma_eol(volatile u32 * addr)
-{
-#if defined(__i386__)
-       int nr = 31;
-
-       /* Taken from include/asm-i386/bitops.h linux header */
-       __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr)
-                            :"Ir"(nr));
-#elif defined(__powerpc__)
-       u32 old;
-       u32 mask = cpu_to_le32(MACH64_DMA_EOL);
-
-       /* Taken from the include/asm-ppc/bitops.h linux header */
-       __asm__ __volatile__("\n\
-1:     lwarx   %0,0,%3 \n\
-       or      %0,%0,%2 \n\
-       stwcx.  %0,0,%3 \n\
-       bne-    1b":"=&r"(old), "=m"(*addr)
-                            :"r"(mask), "r"(addr), "m"(*addr)
-                            :"cc");
-#elif defined(__alpha__)
-       u32 temp;
-       u32 mask = MACH64_DMA_EOL;
-
-       /* Taken from the include/asm-alpha/bitops.h linux header */
-       __asm__ __volatile__("1:        ldl_l %0,%3\n"
-                            "  bis %0,%2,%0\n"
-                            "  stl_c %0,%1\n"
-                            "  beq %0,2f\n"
-                            ".subsection 2\n"
-                            "2:        br 1b\n"
-                            ".previous":"=&r"(temp), "=m"(*addr)
-                            :"Ir"(mask), "m"(*addr));
-#else
-       u32 mask = cpu_to_le32(MACH64_DMA_EOL);
-
-       *addr |= mask;
-#endif
-}
-
-static __inline__ void mach64_clear_dma_eol(volatile u32 * addr)
-{
-#if defined(__i386__)
-       int nr = 31;
-
-       /* Taken from include/asm-i386/bitops.h linux header */
-       __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr)
-                            :"Ir"(nr));
-#elif defined(__powerpc__)
-       u32 old;
-       u32 mask = cpu_to_le32(MACH64_DMA_EOL);
-
-       /* Taken from the include/asm-ppc/bitops.h linux header */
-       __asm__ __volatile__("\n\
-1:     lwarx   %0,0,%3 \n\
-       andc    %0,%0,%2 \n\
-       stwcx.  %0,0,%3 \n\
-       bne-    1b":"=&r"(old), "=m"(*addr)
-                            :"r"(mask), "r"(addr), "m"(*addr)
-                            :"cc");
-#elif defined(__alpha__)
-       u32 temp;
-       u32 mask = ~MACH64_DMA_EOL;
-
-       /* Taken from the include/asm-alpha/bitops.h linux header */
-       __asm__ __volatile__("1:        ldl_l %0,%3\n"
-                            "  and %0,%2,%0\n"
-                            "  stl_c %0,%1\n"
-                            "  beq %0,2f\n"
-                            ".subsection 2\n"
-                            "2:        br 1b\n"
-                            ".previous":"=&r"(temp), "=m"(*addr)
-                            :"Ir"(mask), "m"(*addr));
-#else
-       u32 mask = cpu_to_le32(~MACH64_DMA_EOL);
-
-       *addr &= mask;
-#endif
-}
-
 static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
 {
        drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
@@ -750,59 +675,6 @@ mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv)
 }
 
 /* ================================================================
- * DMA descriptor ring macros
- */
-
-#define RING_LOCALS                                                                    \
-       int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
-
-#define RING_WRITE_OFS  _ring_write
-
-#define BEGIN_RING( n )                                                                        \
-do {                                                                                   \
-       if ( MACH64_VERBOSE ) {                                                         \
-               DRM_INFO( "BEGIN_RING( %d ) in %s\n",                                   \
-                          (n), __FUNCTION__ );                                         \
-       }                                                                               \
-       if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {                              \
-               int ret;                                                                \
-               if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) {        \
-                       DRM_ERROR( "wait_ring failed, resetting engine\n");             \
-                       mach64_dump_engine_info( dev_priv );                            \
-                       mach64_do_engine_reset( dev_priv );                             \
-                       return ret;                                                     \
-               }                                                                       \
-       }                                                                               \
-       dev_priv->ring.space -= (n) * sizeof(u32);                                      \
-       _ring = (u32 *) dev_priv->ring.start;                                           \
-       _ring_tail = _ring_write = dev_priv->ring.tail;                                 \
-       _ring_mask = dev_priv->ring.tail_mask;                                          \
-} while (0)
-
-#define OUT_RING( x )                                          \
-do {                                                           \
-       if ( MACH64_VERBOSE ) {                                 \
-               DRM_INFO( "   OUT_RING( 0x%08x ) at 0x%x\n",    \
-                          (unsigned int)(x), _ring_write );    \
-       }                                                       \
-       _ring[_ring_write++] = cpu_to_le32( x );                \
-       _ring_write &= _ring_mask;                              \
-} while (0)
-
-#define ADVANCE_RING()                                                 \
-do {                                                                   \
-       if ( MACH64_VERBOSE ) {                                         \
-               DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n",     \
-                         _ring_write, _ring_tail );                    \
-       }                                                               \
-       DRM_MEMORYBARRIER();                                            \
-       mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] );  \
-       DRM_MEMORYBARRIER();                                            \
-       dev_priv->ring.tail = _ring_write;                              \
-       mach64_ring_tick( dev_priv, &(dev_priv)->ring );                \
-} while (0)
-
-/* ================================================================
  * DMA macros
  */
 
@@ -889,7 +761,7 @@ do {                                                                \
 #define DMAADVANCE( dev_priv, _discard )                                                    \
 do {                                                                                        \
        struct list_head *ptr;                                                               \
-       RING_LOCALS;                                                                         \
+       int ret;                                                                             \
                                                                                             \
        if ( MACH64_VERBOSE ) {                                                              \
                DRM_INFO( "DMAADVANCE() in %s\n", __FUNCTION__ );                            \
@@ -902,7 +774,6 @@ do {                                                                                             \
        }                                                                                    \
        if (_buf->pending) {                                                                 \
                 /* This is a resued buffer, so we need to find it in the pending list */     \
-               int ret;                                                                     \
                if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) {        \
                        DRM_ERROR( "DMAADVANCE() in %s: couldn't find pending buf %d\n",     \
                                   __FUNCTION__, _buf->idx );                                \
@@ -927,7 +798,8 @@ do {                                                                                             \
                list_add_tail(ptr, &dev_priv->pending);                                      \
        }                                                                                    \
        _entry->discard = (_discard);                                                        \
-       ADD_BUF_TO_RING( dev_priv );                                                         \
+       if ( (ret = mach64_add_buf_to_ring( dev_priv, _entry )) )                            \
+               return ret;                                                                  \
 } while (0)
 
 #define DMADISCARDBUF()                                                                        \
@@ -943,48 +815,10 @@ do {                                                                                      \
        _entry->discard = 1;                                                            \
 } while(0)
 
-#define ADD_BUF_TO_RING( dev_priv )                                                    \
-do {                                                                                   \
-       int bytes, pages, remainder;                                                    \
-       u32 address, page;                                                              \
-       int i;                                                                          \
-                                                                                       \
-       bytes = _buf->used;                                                             \
-       address = GETBUFADDR( _buf );                                                   \
-                                                                                       \
-       pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;              \
-                                                                                       \
-       BEGIN_RING( pages * 4 );                                                        \
-                                                                                       \
-       for ( i = 0 ; i < pages-1 ; i++ ) {                                             \
-               page = address + i * MACH64_DMA_CHUNKSIZE;                              \
-               OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );                    \
-               OUT_RING( page );                                                       \
-               OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );              \
-               OUT_RING( 0 );                                                          \
-       }                                                                               \
-                                                                                       \
-       /* generate the final descriptor for any remaining commands in this buffer */   \
-       page = address + i * MACH64_DMA_CHUNKSIZE;                                      \
-       remainder = bytes - i * MACH64_DMA_CHUNKSIZE;                                   \
-                                                                                       \
-       /* Save dword offset of last descriptor for this buffer.                        \
-        * This is needed to check for completion of the buffer in freelist_get         \
-        */                                                                             \
-       _entry->ring_ofs = RING_WRITE_OFS;                                              \
-                                                                                       \
-       OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );                            \
-       OUT_RING( page );                                                               \
-       OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );                \
-       OUT_RING( 0 );                                                                  \
-                                                                                       \
-       ADVANCE_RING();                                                                 \
-} while(0)
-
 #define DMAADVANCEHOSTDATA( dev_priv )                                                 \
 do {                                                                                   \
        struct list_head *ptr;                                                          \
-       RING_LOCALS;                                                                    \
+       int ret;                                                                        \
                                                                                        \
        if ( MACH64_VERBOSE ) {                                                         \
                DRM_INFO( "DMAADVANCEHOSTDATA() in %s\n", __FUNCTION__ );               \
@@ -1008,51 +842,8 @@ do {                                                                                      \
        _entry->buf->pending = 1;                                                       \
        list_add_tail(ptr, &dev_priv->pending);                                         \
        _entry->discard = 1;                                                            \
-       ADD_HOSTDATA_BUF_TO_RING( dev_priv );                                           \
+       if ( (ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry )) )              \
+               return ret;                                                             \
 } while (0)
 
-#define ADD_HOSTDATA_BUF_TO_RING( dev_priv )                                            \
-do {                                                                                    \
-       int bytes, pages, remainder;                                                     \
-       u32 address, page;                                                               \
-       int i;                                                                           \
-                                                                                        \
-       bytes = _buf->used - MACH64_HOSTDATA_BLIT_OFFSET;                                \
-       pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE;               \
-       address = GETBUFADDR( _buf );                                                    \
-                                                                                        \
-       BEGIN_RING( 4 + pages * 4 );                                                     \
-                                                                                        \
-       OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR );                             \
-       OUT_RING( address );                                                             \
-       OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET );                \
-       OUT_RING( 0 );                                                                   \
-                                                                                        \
-       address += MACH64_HOSTDATA_BLIT_OFFSET;                                          \
-                                                                                        \
-       for ( i = 0 ; i < pages-1 ; i++ ) {                                              \
-               page = address + i * MACH64_DMA_CHUNKSIZE;                               \
-               OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );                 \
-               OUT_RING( page );                                                        \
-               OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET );               \
-               OUT_RING( 0 );                                                           \
-       }                                                                                \
-                                                                                        \
-       /* generate the final descriptor for any remaining commands in this buffer */    \
-       page = address + i * MACH64_DMA_CHUNKSIZE;                                       \
-       remainder = bytes - i * MACH64_DMA_CHUNKSIZE;                                    \
-                                                                                        \
-       /* Save dword offset of last descriptor for this buffer.                         \
-        * This is needed to check for completion of the buffer in freelist_get          \
-        */                                                                              \
-       _entry->ring_ofs = RING_WRITE_OFS;                                               \
-                                                                                        \
-       OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA );                         \
-       OUT_RING( page );                                                                \
-       OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL );                 \
-       OUT_RING( 0 );                                                                   \
-                                                                                        \
-       ADVANCE_RING();                                                                  \
-} while(0)
-
 #endif                         /* __MACH64_DRV_H__ */