diff options
author | Jose Fonseca <jrfonseca@users.sourceforge.net> | 2003-03-02 21:44:26 +0000 |
---|---|---|
committer | Jose Fonseca <jrfonseca@users.sourceforge.net> | 2003-03-02 21:44:26 +0000 |
commit | 087cdbc0b03dd48d14576183fcdf21e32729b10c (patch) | |
tree | 39181e84bdfbbd62b80d48abebfb2de80d0382bf | |
parent | 47c25e23394666a21934da5d63bb65e085b73aed (diff) |
More bootstrap files (Andreas Karrenbauer)
-rw-r--r-- | linux-core/Makefile.kernel | 2 | ||||
-rw-r--r-- | linux-core/savage.h | 4 | ||||
-rw-r--r-- | linux-core/savage_drm.h | 179 | ||||
-rw-r--r-- | linux-core/savage_drv.c | 5 | ||||
-rw-r--r-- | linux-core/savage_drv.h | 167 | ||||
-rw-r--r-- | linux/Makefile.kernel | 2 | ||||
-rw-r--r-- | linux/Makefile.linux | 8 | ||||
-rw-r--r-- | linux/savage.h | 4 | ||||
-rw-r--r-- | linux/savage_bci.c | 423 | ||||
-rw-r--r-- | linux/savage_drm.h | 179 | ||||
-rw-r--r-- | linux/savage_drv.c | 5 | ||||
-rw-r--r-- | linux/savage_drv.h | 167 |
12 files changed, 1135 insertions, 10 deletions
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel index 92fed6b7..27a1c345 100644 --- a/linux-core/Makefile.kernel +++ b/linux-core/Makefile.kernel @@ -34,7 +34,7 @@ tdfx.o: $(tdfx-objs) $(lib) $(LD) -r -o $@ $(tdfx-objs) $(lib) savage.o: $(savage-objs) $(lib) - $(LD) -r -o $@ $(savage-objs) $(lib) + $(LD) -r -o $@ $(savage-objs) $(lib) mga.o: $(mga-objs) $(lib) $(LD) -r -o $@ $(mga-objs) $(lib) diff --git a/linux-core/savage.h b/linux-core/savage.h index 4fd588c6..f4544f4e 100644 --- a/linux-core/savage.h +++ b/linux-core/savage.h @@ -39,4 +39,8 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { savage_bci_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_SAVAGE_BCI_INIT)] = { savage_bci_init, 1, 1 }, + #endif diff --git a/linux-core/savage_drm.h b/linux-core/savage_drm.h new file mode 100644 index 00000000..08a592d3 --- /dev/null +++ b/linux-core/savage_drm.h @@ -0,0 +1,179 @@ +/* savage_drm.h -- Public header for the savage driver -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __SAVAGE_DRM_H__ +#define __SAVAGE_DRM_H__ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the X server file (savage_sarea.h) + */ +#ifndef __SAVAGE_SAREA_DEFINES__ +#define __SAVAGE_SAREA_DEFINES__ + +/* Keep these small for testing */ +#define SAVAGE_NR_SAREA_CLIPRECTS 12 + +/* There are 2 heaps (local/AGP). Each region within a heap is a + * minimum of 64k, and there are at most 64 of them per heap. + */ +#define SAVAGE_CARD_HEAP 0 +#define SAVAGE_AGP_HEAP 1 +#define SAVAGE_NR_TEX_HEAPS 2 +#define SAVAGE_NR_TEX_REGIONS 64 +#define SAVAGE_LOG_TEX_GRANULARITY 16 + +#define SAVAGE_MAX_TEXTURE_LEVELS 10 +#define SAVAGE_MAX_TEXTURE_UNITS 2 + +#endif + +typedef struct { + unsigned int blue; + unsigned int green; + unsigned int red; + unsigned int alpha; +} savage_color_regs_t; + +typedef struct { + /* Context state */ + + /* Vertex format state */ + + /* Line state */ + + /* Bumpmap state */ + + /* Mask state */ + + /* Viewport state */ + + /* Setup state */ + + /* Misc state */ +} savage_context_regs_t; + +/* Setup registers for each texture unit */ +typedef struct { + unsigned int tex_cntl; + unsigned int tex_addr; + unsigned int tex_blend_cntl; +} savage_texture_regs_t; + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} savage_tex_region_t; + +/* WARNING: Do not change the SAREA structure without changing the kernel + * as well. + */ +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + savage_context_regs_t ContextState; + savage_texture_regs_t TexState[SAVAGE_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof. + */ + drm_clip_rect_t boxes[SAVAGE_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for throttling of rendering clients. + */ + unsigned int last_frame; + unsigned int last_dispatch; + + /* Maintain an LRU of contiguous regions of texture space. If you + * think you own a region of texture memory, and it has an age + * different to the one you set, then you are mistaken and it has + * been stolen by another client. If global texAge hasn't changed, + * there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained texture + * information of other clients - by maintaining them in the same + * lru which is used to age their own textures, clients have an + * approximate lru for the whole of global texture space, and can + * make informed decisions as to which areas to kick out. There is + * no need to choose whether to kick out your own texture or someone + * else's - simply eject them all in LRU order. + */ + /* Last elt is sentinal */ + savage_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + int texAge[SAVAGE_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ +} drm_savage_sarea_t; + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmSavage.h) + * + * KW: actually it's illegal to change any of this (backwards compatibility). + */ + +/* Savage specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( 0x40, drm_savage_init_t) + +typedef struct drm_savage_init { + enum { + SAVAGE_INIT_BCI = 0x01, + SAVAGE_CLEANUP_BCI = 0x02, + } func; + unsigned long sarea_priv_offset; + int is_pci; + int bci_mode; + int agp_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drm_savage_init_t; + +#endif diff --git a/linux-core/savage_drv.c b/linux-core/savage_drv.c index aacf3b77..e7c1b8f5 100644 --- a/linux-core/savage_drv.c +++ b/linux-core/savage_drv.c @@ -39,7 +39,7 @@ #define DRIVER_AUTHOR "bootstraped by Andreas Karrenbauer" #define DRIVER_NAME "savage" -#define DRIVER_DESC "alpha savage dr" +#define DRIVER_DESC "savage driver alpha" #define DRIVER_DATE "20030226" #define DRIVER_MAJOR 1 @@ -60,7 +60,8 @@ static drm_pci_list_t DRM(idlist)[] = { #define DRIVER_CARD_LIST DRM(idlist) - +#include "savage_drm.h" +#include "savage_drv.h" #include "drm_auth.h" #include "drm_bufs.h" #include "drm_context.h" diff --git a/linux-core/savage_drv.h b/linux-core/savage_drv.h new file mode 100644 index 00000000..ebbede31 --- /dev/null +++ b/linux-core/savage_drv.h @@ -0,0 +1,167 @@ +/* savage_drv.h -- Private header for savage driver -*- linux-c -*- + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + +#ifndef __SAVAGE_DRV_H__ +#define __SAVAGE_DRV_H__ + +typedef struct drm_savage_freelist { + unsigned int age; + drm_buf_t *buf; + struct drm_radeon_freelist *next; + struct drm_radeon_freelist *prev; +} drm_savage_freelist_t; + +typedef struct drm_savage_ring_buffer { + u32 *start; + u32 *end; + int size; + int size_l2qw; + + volatile u32 *head; + u32 tail; + u32 tail_mask; + int space; + + int high_mark; +} drm_savage_ring_buffer_t; + +typedef struct drm_savage_depth_clear_t { + u32 rb3d_cntl; + u32 rb3d_zstencilcntl; + u32 se_cntl; +} drm_savage_depth_clear_t; + + +struct mem_block { + struct mem_block *next; + struct mem_block *prev; + int start; + int size; + int pid; /* 0: free, -1: heap, other: real pids */ +}; + +typedef struct drm_savage_private { + drm_savage_ring_buffer_t ring; + drm_savage_sarea_t *sarea_priv; + + int agp_size; + u32 agp_vm_start; + unsigned long agp_buffers_offset; + + int bci_mode; + int bci_running; + + drm_savage_freelist_t *head; + drm_savage_freelist_t *tail; + int last_buf; + volatile u32 *scratch; + int writeback_works; + + int usec_timeout; + + int is_r200; + + int is_pci; + unsigned long phys_pci_gart; + dma_addr_t bus_pci_gart; + + struct { + u32 boxes; + int freelist_timeouts; + int freelist_loops; + int requested_bufs; + int last_frame_reads; + int last_clear_reads; + int clears; + int texture_uploads; + } stats; + + int do_boxes; + int page_flipping; + int current_page; + + u32 color_fmt; + unsigned int front_offset; + unsigned int front_pitch; + unsigned int back_offset; + unsigned int back_pitch; + + u32 depth_fmt; + unsigned int depth_offset; + unsigned int depth_pitch; + + u32 front_pitch_offset; + u32 back_pitch_offset; + u32 depth_pitch_offset; + + drm_savage_depth_clear_t depth_clear; + + drm_map_t *sarea; + drm_map_t *fb; + drm_map_t *mmio; + drm_map_t *bci_ring; + drm_map_t *ring_rptr; + drm_map_t *buffers; + drm_map_t *agp_textures; + + struct mem_block *agp_heap; + struct mem_block *fb_heap; + + /* SW interrupt */ + wait_queue_head_t swi_queue; + atomic_t swi_emitted; + +} drm_savage_private_t; + +typedef struct drm_savage_buf_priv { + u32 age; +} drm_savage_buf_priv_t; + +/* Constants */ +#define SAVAGE_MAX_USEC_TIMEOUT 100000 /* 100 ms */ + + /* savage_bci.c */ +extern int savage_bci_init( DRM_IOCTL_ARGS ); +extern int savage_bci_buffers( DRM_IOCTL_ARGS ); + +extern int savage_do_cleanup_bci( drm_device_t *dev ); + +#define SAVAGE_RING_HIGH_MARK 128 + +#define SAVAGE_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) +#define SAVAGE_ADDR(reg) (SAVAGE_BASE( reg ) + reg) + +#define SAVAGE_READ(reg) DRM_READ32( (volatile u32 *) SAVAGE_ADDR(reg) ) +#define SAVAGE_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) SAVAGE_ADDR(reg), (val) ) + +#define SAVAGE_READ8(reg) DRM_READ8( (volatile u8 *) SAVAGE_ADDR(reg) ) +#define SAVAGE_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) SAVAGE_ADDR(reg), (val) ) + +#endif /* __SAVAGE_DRV_H__ */ diff --git a/linux/Makefile.kernel b/linux/Makefile.kernel index 92fed6b7..27a1c345 100644 --- a/linux/Makefile.kernel +++ b/linux/Makefile.kernel @@ -34,7 +34,7 @@ tdfx.o: $(tdfx-objs) $(lib) $(LD) -r -o $@ $(tdfx-objs) $(lib) savage.o: $(savage-objs) $(lib) - $(LD) -r -o $@ $(savage-objs) $(lib) + $(LD) -r -o $@ $(savage-objs) $(lib) mga.o: $(mga-objs) $(lib) $(LD) -r -o $@ $(mga-objs) $(lib) diff --git a/linux/Makefile.linux b/linux/Makefile.linux index df819750..b9f55883 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -52,8 +52,8 @@ GAMMAHEADERS = gamma_drv.h $(DRMHEADERS) $(DRMTEMPLATES) TDFXOBJS = tdfx_drv.o TDFXHEADERS = tdfx.h $(DRMHEADERS) $(DRMTEMPLATES) -SAVAGEOBJS = savage_drv.o -SAVAGEHEADERS = savage.h $(DRMHEADERS) $(DRMTEMPLATES) +SAVAGEOBJS = savage_drv.o savage_bci.o +SAVAGEHEADERS = savage.h savage_drv.h savage_drm.h $(DRMHEADERS) $(DRMTEMPLATES) R128OBJS = r128_drv.o r128_cce.o r128_state.o R128HEADERS = r128.h r128_drv.h r128_drm.h $(DRMHEADERS) $(DRMTEMPLATES) @@ -228,9 +228,9 @@ tdfx.o: $(TDFXOBJS) $(LIBS) $(LD) -r $^ -o $@ savage_drv.o: savage_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ savage.o: $(SAVAGEOBJS) $(LIBS) - $(LD) -r $^ -o $@ + $(LD) -r $^ -o $@ sis.o: $(SISOBJS) $(LIBS) $(LD) -r $^ -o $@ diff --git a/linux/savage.h b/linux/savage.h index 4fd588c6..f4544f4e 100644 --- a/linux/savage.h +++ b/linux/savage.h @@ -39,4 +39,8 @@ #define __HAVE_MTRR 1 #define __HAVE_CTX_BITMAP 1 +#define DRIVER_IOCTLS \ + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { savage_bci_buffers, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_SAVAGE_BCI_INIT)] = { savage_bci_init, 1, 1 }, + #endif diff --git a/linux/savage_bci.c b/linux/savage_bci.c new file mode 100644 index 00000000..d96f1280 --- /dev/null +++ b/linux/savage_bci.c @@ -0,0 +1,423 @@ +/* savage_bci.c -- BCI support for Savage -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + +#include "savage.h" +#include "drmP.h" +#include "drm.h" +#include "savage_drm.h" +#include "savage_drv.h" + +/* ================================================================ + * BCI control, initialization + */ + +static int savage_do_init_bci( drm_device_t *dev, drm_savage_init_t *init ) +{ + drm_savage_private_t *dev_priv; + u32 tmp; + DRM_INFO( "[drm] initializing bci ...\n" ); + + dev_priv = DRM(alloc)( sizeof(drm_savage_private_t), DRM_MEM_DRIVER ); + if ( dev_priv == NULL ) + return DRM_ERR(ENOMEM); + + memset( dev_priv, 0, sizeof(drm_savage_private_t) ); + + dev_priv->is_pci = init->is_pci; + + if ( dev_priv->is_pci && !dev->sg ) { + DRM_ERROR( "PCI GART memory not allocated!\n" ); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + + dev_priv->usec_timeout = init->usec_timeout; + if ( dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > SAVAGE_MAX_USEC_TIMEOUT ) { + DRM_DEBUG( "TIMEOUT problem!\n" ); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + + dev_priv->do_boxes = 0; + dev_priv->bci_mode = init->bci_mode; + + switch ( init->fb_bpp ) { + case 16: +/* FIXME: dev_priv->color_fmt = SAVAGE_COLOR_FORMAT_RGB565; */ + break; + case 32: + default: +/* FIXME: dev_priv->color_fmt = SAVAGE_COLOR_FORMAT_ARGB8888; */ + break; + } + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + switch ( init->depth_bpp ) { + case 16: +/* FIXME: dev_priv->depth_fmt = SAVAGE_DEPTH_FORMAT_16BIT_INT_Z; */ + break; + case 32: + default: +/* FIXME: dev_priv->depth_fmt = SAVAGE_DEPTH_FORMAT_24BIT_INT_Z; */ + break; + } + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; + + dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | + (dev_priv->front_offset >> 10)); + dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | + (dev_priv->back_offset >> 10)); + dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | + (dev_priv->depth_offset >> 10)); + + DRM_GETSAREA(); + + if(!dev_priv->sarea) { + DRM_ERROR("could not find sarea!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + + DRM_FIND_MAP( dev_priv->fb, init->fb_offset ); + if(!dev_priv->fb) { + DRM_ERROR("could not find framebuffer!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + if(!dev_priv->mmio) { + DRM_ERROR("could not find mmio region!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->bci_ring, init->ring_offset ); + if(!dev_priv->bci_ring) { + DRM_ERROR("could not find bci ring region!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); + if(!dev_priv->ring_rptr) { + DRM_ERROR("could not find ring read pointer!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + if(!dev_priv->buffers) { + DRM_ERROR("could not find dma buffer region!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + + if ( !dev_priv->is_pci ) { + DRM_FIND_MAP( dev_priv->agp_textures, + init->agp_textures_offset ); + if(!dev_priv->agp_textures) { + DRM_ERROR("could not find agp texture region!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + } + + dev_priv->sarea_priv = + (drm_savage_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + if ( !dev_priv->is_pci ) { + DRM_IOREMAP( dev_priv->bci_ring ); + DRM_IOREMAP( dev_priv->ring_rptr ); + DRM_IOREMAP( dev_priv->buffers ); + if(!dev_priv->bci_ring->handle || + !dev_priv->ring_rptr->handle || + !dev_priv->buffers->handle) { + DRM_ERROR("could not find ioremap agp regions!\n"); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(EINVAL); + } + } else { + dev_priv->bci_ring->handle = + (void *)dev_priv->bci_ring->offset; + dev_priv->ring_rptr->handle = + (void *)dev_priv->ring_rptr->offset; + dev_priv->buffers->handle = (void *)dev_priv->buffers->offset; + + DRM_DEBUG( "dev_priv->bci_ring->handle %p\n", + dev_priv->bci_ring->handle ); + DRM_DEBUG( "dev_priv->ring_rptr->handle %p\n", + dev_priv->ring_rptr->handle ); + DRM_DEBUG( "dev_priv->buffers->handle %p\n", + dev_priv->buffers->handle ); + } + + + dev_priv->agp_size = init->agp_size; +/* FIXME: dev_priv->agp_vm_start = SAVAGE_READ( SAVAGE_CONFIG_APER_SIZE ); */ +#if __REALLY_HAVE_AGP + if ( !dev_priv->is_pci ) + dev_priv->agp_buffers_offset = (dev_priv->buffers->offset + - dev->agp->base + + dev_priv->agp_vm_start); + else +#endif + dev_priv->agp_buffers_offset = (dev_priv->buffers->offset + - dev->sg->handle + + dev_priv->agp_vm_start); + + DRM_DEBUG( "dev_priv->agp_size %d\n", + dev_priv->agp_size ); + DRM_DEBUG( "dev_priv->agp_vm_start 0x%x\n", + dev_priv->agp_vm_start ); + DRM_DEBUG( "dev_priv->agp_buffers_offset 0x%lx\n", + dev_priv->agp_buffers_offset ); + + dev_priv->ring.head = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle); + + dev_priv->ring.start = (u32 *)dev_priv->bci_ring->handle; + dev_priv->ring.end = ((u32 *)dev_priv->bci_ring->handle + + init->ring_size / sizeof(u32)); + dev_priv->ring.size = init->ring_size; + dev_priv->ring.size_l2qw = DRM(order)( init->ring_size / 8 ); + + dev_priv->ring.tail_mask = + (dev_priv->ring.size / sizeof(u32)) - 1; + + dev_priv->ring.high_mark = SAVAGE_RING_HIGH_MARK; + +#if __REALLY_HAVE_SG + if ( dev_priv->is_pci ) { + if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart, + &dev_priv->bus_pci_gart)) { + DRM_ERROR( "failed to init PCI GART!\n" ); + dev->dev_private = (void *)dev_priv; + savage_do_cleanup_bci(dev); + return DRM_ERR(ENOMEM); + } + /* Turn on PCI GART + */ + tmp = SAVAGE_READ( SAVAGE_AIC_CNTL ) + | SAVAGE_PCIGART_TRANSLATE_EN; + SAVAGE_WRITE( SAVAGE_AIC_CNTL, tmp ); + + /* set PCI GART page-table base address + */ + SAVAGE_WRITE( SAVAGE_AIC_PT_BASE, dev_priv->bus_pci_gart ); + + /* set address range for PCI address translate + */ + SAVAGE_WRITE( SAVAGE_AIC_LO_ADDR, dev_priv->agp_vm_start ); + SAVAGE_WRITE( SAVAGE_AIC_HI_ADDR, dev_priv->agp_vm_start + + dev_priv->agp_size - 1); + + /* Turn off AGP aperture -- is this required for PCIGART? + */ + SAVAGE_WRITE( SAVAGE_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */ + SAVAGE_WRITE( SAVAGE_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */ + } else { +#endif /* __REALLY_HAVE_SG */ +/* FIXME: Turn off PCI GART + tmp = SAVAGE_READ( SAVAGE_AIC_CNTL ) + & ~SAVAGE_PCIGART_TRANSLATE_EN; + SAVAGE_WRITE( SAVAGE_AIC_CNTL, tmp ); +*/ +#if __REALLY_HAVE_SG + } +#endif /* __REALLY_HAVE_SG */ + +/* FIXME: savage_bci_init_ring_buffer( dev, dev_priv ); */ + + dev_priv->last_buf = 0; + + dev->dev_private = (void *)dev_priv; + +/* FIXME: savage_do_engine_reset( dev ); */ + + return 0; +} + +int savage_do_cleanup_bci( drm_device_t *dev ) +{ + DRM_DEBUG( "\n" ); + + if ( dev->dev_private ) { + drm_savage_private_t *dev_priv = dev->dev_private; + + if ( !dev_priv->is_pci ) { + DRM_IOREMAPFREE( dev_priv->bci_ring ); + DRM_IOREMAPFREE( dev_priv->ring_rptr ); + DRM_IOREMAPFREE( dev_priv->buffers ); + } else { +#if __REALLY_HAVE_SG + if (!DRM(ati_pcigart_cleanup)( dev, + dev_priv->phys_pci_gart, + dev_priv->bus_pci_gart )) + DRM_ERROR( "failed to cleanup PCI GART!\n" ); +#endif /* __REALLY_HAVE_SG */ + } + + DRM(free)( dev->dev_private, sizeof(drm_savage_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int savage_bci_init( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_savage_init_t init; + + DRM_COPY_FROM_USER_IOCTL( init, (drm_savage_init_t *)data, sizeof(init) ); + + switch ( init.func ) { + case SAVAGE_INIT_BCI: + return savage_do_init_bci( dev, &init ); + case SAVAGE_CLEANUP_BCI: + return savage_do_cleanup_bci( dev ); + } + + return DRM_ERR(EINVAL); +} + +drm_buf_t *savage_freelist_get( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_savage_private_t *dev_priv = dev->dev_private; + drm_savage_buf_priv_t *buf_priv; + drm_buf_t *buf; + int i, t; + int start; + + if ( ++dev_priv->last_buf >= dma->buf_count ) + dev_priv->last_buf = 0; + + start = dev_priv->last_buf; + + for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { + u32 done_age = 0; /* FIXME: GET_SCRATCH( 1 ); */ + DRM_DEBUG("done_age = %d\n",done_age); + for ( i = start ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pid == 0 || (buf->pending && + buf_priv->age <= done_age) ) { + dev_priv->stats.requested_bufs++; + buf->pending = 0; + return buf; + } + start = 0; + } + + if (t) { + DRM_UDELAY( 1 ); + dev_priv->stats.freelist_loops++; + } + } + + DRM_ERROR( "returning NULL!\n" ); + return NULL; +} + +static int savage_bci_get_buffers( drm_device_t *dev, drm_dma_t *d ) +{ + int i; + drm_buf_t *buf; + + for ( i = d->granted_count ; i < d->request_count ; i++ ) { + buf = savage_freelist_get( dev ); + if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */ + + buf->pid = DRM_CURRENTPID; + + if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx, + sizeof(buf->idx) ) ) + return DRM_ERR(EFAULT); + if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total, + sizeof(buf->total) ) ) + return DRM_ERR(EFAULT); + + d->granted_count++; + } + return 0; +} + +int savage_bci_buffers( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_device_dma_t *dma = dev->dma; + int ret = 0; + drm_dma_t d; + +/* FIXME: LOCK_TEST_WITH_RETURN( dev ); */ + + DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) ); + + /* Please don't send us buffers. + */ + if ( d.send_count != 0 ) { + DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", + DRM_CURRENTPID, d.send_count ); + return DRM_ERR(EINVAL); + } + + /* We'll send you buffers. + */ + if ( d.request_count < 0 || d.request_count > dma->buf_count ) { + DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", + DRM_CURRENTPID, d.request_count, dma->buf_count ); + return DRM_ERR(EINVAL); + } + + d.granted_count = 0; + + if ( d.request_count ) { + ret = savage_bci_get_buffers( dev, &d ); + } + + DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) ); + + return ret; +} diff --git a/linux/savage_drm.h b/linux/savage_drm.h new file mode 100644 index 00000000..08a592d3 --- /dev/null +++ b/linux/savage_drm.h @@ -0,0 +1,179 @@ +/* savage_drm.h -- Public header for the savage driver -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef __SAVAGE_DRM_H__ +#define __SAVAGE_DRM_H__ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the X server file (savage_sarea.h) + */ +#ifndef __SAVAGE_SAREA_DEFINES__ +#define __SAVAGE_SAREA_DEFINES__ + +/* Keep these small for testing */ +#define SAVAGE_NR_SAREA_CLIPRECTS 12 + +/* There are 2 heaps (local/AGP). Each region within a heap is a + * minimum of 64k, and there are at most 64 of them per heap. + */ +#define SAVAGE_CARD_HEAP 0 +#define SAVAGE_AGP_HEAP 1 +#define SAVAGE_NR_TEX_HEAPS 2 +#define SAVAGE_NR_TEX_REGIONS 64 +#define SAVAGE_LOG_TEX_GRANULARITY 16 + +#define SAVAGE_MAX_TEXTURE_LEVELS 10 +#define SAVAGE_MAX_TEXTURE_UNITS 2 + +#endif + +typedef struct { + unsigned int blue; + unsigned int green; + unsigned int red; + unsigned int alpha; +} savage_color_regs_t; + +typedef struct { + /* Context state */ + + /* Vertex format state */ + + /* Line state */ + + /* Bumpmap state */ + + /* Mask state */ + + /* Viewport state */ + + /* Setup state */ + + /* Misc state */ +} savage_context_regs_t; + +/* Setup registers for each texture unit */ +typedef struct { + unsigned int tex_cntl; + unsigned int tex_addr; + unsigned int tex_blend_cntl; +} savage_texture_regs_t; + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} savage_tex_region_t; + +/* WARNING: Do not change the SAREA structure without changing the kernel + * as well. + */ +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + savage_context_regs_t ContextState; + savage_texture_regs_t TexState[SAVAGE_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof. + */ + drm_clip_rect_t boxes[SAVAGE_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for throttling of rendering clients. + */ + unsigned int last_frame; + unsigned int last_dispatch; + + /* Maintain an LRU of contiguous regions of texture space. If you + * think you own a region of texture memory, and it has an age + * different to the one you set, then you are mistaken and it has + * been stolen by another client. If global texAge hasn't changed, + * there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained texture + * information of other clients - by maintaining them in the same + * lru which is used to age their own textures, clients have an + * approximate lru for the whole of global texture space, and can + * make informed decisions as to which areas to kick out. There is + * no need to choose whether to kick out your own texture or someone + * else's - simply eject them all in LRU order. + */ + /* Last elt is sentinal */ + savage_tex_region_t texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + int texAge[SAVAGE_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ +} drm_savage_sarea_t; + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmSavage.h) + * + * KW: actually it's illegal to change any of this (backwards compatibility). + */ + +/* Savage specific ioctls + * The device specific ioctl range is 0x40 to 0x79. + */ +#define DRM_IOCTL_SAVAGE_BCI_INIT DRM_IOW( 0x40, drm_savage_init_t) + +typedef struct drm_savage_init { + enum { + SAVAGE_INIT_BCI = 0x01, + SAVAGE_CLEANUP_BCI = 0x02, + } func; + unsigned long sarea_priv_offset; + int is_pci; + int bci_mode; + int agp_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drm_savage_init_t; + +#endif diff --git a/linux/savage_drv.c b/linux/savage_drv.c index aacf3b77..e7c1b8f5 100644 --- a/linux/savage_drv.c +++ b/linux/savage_drv.c @@ -39,7 +39,7 @@ #define DRIVER_AUTHOR "bootstraped by Andreas Karrenbauer" #define DRIVER_NAME "savage" -#define DRIVER_DESC "alpha savage dr" +#define DRIVER_DESC "savage driver alpha" #define DRIVER_DATE "20030226" #define DRIVER_MAJOR 1 @@ -60,7 +60,8 @@ static drm_pci_list_t DRM(idlist)[] = { #define DRIVER_CARD_LIST DRM(idlist) - +#include "savage_drm.h" +#include "savage_drv.h" #include "drm_auth.h" #include "drm_bufs.h" #include "drm_context.h" diff --git a/linux/savage_drv.h b/linux/savage_drv.h new file mode 100644 index 00000000..ebbede31 --- /dev/null +++ b/linux/savage_drv.h @@ -0,0 +1,167 @@ +/* savage_drv.h -- Private header for savage driver -*- linux-c -*- + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 VA Linux Systems, Inc., Fremont, California. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + */ + +#ifndef __SAVAGE_DRV_H__ +#define __SAVAGE_DRV_H__ + +typedef struct drm_savage_freelist { + unsigned int age; + drm_buf_t *buf; + struct drm_radeon_freelist *next; + struct drm_radeon_freelist *prev; +} drm_savage_freelist_t; + +typedef struct drm_savage_ring_buffer { + u32 *start; + u32 *end; + int size; + int size_l2qw; + + volatile u32 *head; + u32 tail; + u32 tail_mask; + int space; + + int high_mark; +} drm_savage_ring_buffer_t; + +typedef struct drm_savage_depth_clear_t { + u32 rb3d_cntl; + u32 rb3d_zstencilcntl; + u32 se_cntl; +} drm_savage_depth_clear_t; + + +struct mem_block { + struct mem_block *next; + struct mem_block *prev; + int start; + int size; + int pid; /* 0: free, -1: heap, other: real pids */ +}; + +typedef struct drm_savage_private { + drm_savage_ring_buffer_t ring; + drm_savage_sarea_t *sarea_priv; + + int agp_size; + u32 agp_vm_start; + unsigned long agp_buffers_offset; + + int bci_mode; + int bci_running; + + drm_savage_freelist_t *head; + drm_savage_freelist_t *tail; + int last_buf; + volatile u32 *scratch; + int writeback_works; + + int usec_timeout; + + int is_r200; + + int is_pci; + unsigned long phys_pci_gart; + dma_addr_t bus_pci_gart; + + struct { + u32 boxes; + int freelist_timeouts; + int freelist_loops; + int requested_bufs; + int last_frame_reads; + int last_clear_reads; + int clears; + int texture_uploads; + } stats; + + int do_boxes; + int page_flipping; + int current_page; + + u32 color_fmt; + unsigned int front_offset; + unsigned int front_pitch; + unsigned int back_offset; + unsigned int back_pitch; + + u32 depth_fmt; + unsigned int depth_offset; + unsigned int depth_pitch; + + u32 front_pitch_offset; + u32 back_pitch_offset; + u32 depth_pitch_offset; + + drm_savage_depth_clear_t depth_clear; + + drm_map_t *sarea; + drm_map_t *fb; + drm_map_t *mmio; + drm_map_t *bci_ring; + drm_map_t *ring_rptr; + drm_map_t *buffers; + drm_map_t *agp_textures; + + struct mem_block *agp_heap; + struct mem_block *fb_heap; + + /* SW interrupt */ + wait_queue_head_t swi_queue; + atomic_t swi_emitted; + +} drm_savage_private_t; + +typedef struct drm_savage_buf_priv { + u32 age; +} drm_savage_buf_priv_t; + +/* Constants */ +#define SAVAGE_MAX_USEC_TIMEOUT 100000 /* 100 ms */ + + /* savage_bci.c */ +extern int savage_bci_init( DRM_IOCTL_ARGS ); +extern int savage_bci_buffers( DRM_IOCTL_ARGS ); + +extern int savage_do_cleanup_bci( drm_device_t *dev ); + +#define SAVAGE_RING_HIGH_MARK 128 + +#define SAVAGE_BASE(reg) ((unsigned long)(dev_priv->mmio->handle)) +#define SAVAGE_ADDR(reg) (SAVAGE_BASE( reg ) + reg) + +#define SAVAGE_READ(reg) DRM_READ32( (volatile u32 *) SAVAGE_ADDR(reg) ) +#define SAVAGE_WRITE(reg,val) DRM_WRITE32( (volatile u32 *) SAVAGE_ADDR(reg), (val) ) + +#define SAVAGE_READ8(reg) DRM_READ8( (volatile u8 *) SAVAGE_ADDR(reg) ) +#define SAVAGE_WRITE8(reg,val) DRM_WRITE8( (volatile u8 *) SAVAGE_ADDR(reg), (val) ) + +#endif /* __SAVAGE_DRV_H__ */ |