From d46925898f8ae56b7a897f5a2b9362ea4a17c577 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 6 Aug 2002 13:41:41 +0000 Subject: commit Sven Luther's patch to new tdlabs-0-0-1-branch for Permedia3/Gamma work. --- linux/gamma.h | 93 +++++++++++++++++++++++++++++++++++++++---------------- linux/gamma_dma.c | 89 ++++++++++++++++++++++++++++++++++++++++++---------- linux/gamma_drm.h | 7 +++++ linux/gamma_drv.h | 5 +++ 4 files changed, 152 insertions(+), 42 deletions(-) diff --git a/linux/gamma.h b/linux/gamma.h index 44d8d5bc..0ce9b143 100644 --- a/linux/gamma.h +++ b/linux/gamma.h @@ -1,4 +1,4 @@ -/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*- +/* gamma.h -- 3dlabs GMX 2000 driver -*- linux-c -*- * Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com * * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. @@ -25,6 +25,7 @@ * * Authors: * Gareth Hughes + * Sven Luther */ #ifndef __GAMMA_H__ @@ -42,10 +43,10 @@ #define DRIVER_NAME "gamma" #define DRIVER_DESC "3DLabs gamma" -#define DRIVER_DATE "20010624" +#define DRIVER_DATE "20020704" #define DRIVER_MAJOR 2 -#define DRIVER_MINOR 0 +#define DRIVER_MINOR 1 #define DRIVER_PATCHLEVEL 0 #define DRIVER_IOCTLS \ @@ -87,8 +88,11 @@ #define __HAVE_DMA_QUIESCENT 1 #define DRIVER_DMA_QUIESCENT() do { \ - /* FIXME ! */ \ - gamma_dma_quiescent_single(dev); \ + drm_gamma_private_t *dev_priv = \ + (drm_gamma_private_t *)dev->dev_private;\ + if (dev_priv->num_rast == 2) \ + gamma_dma_quiescent_dual(dev); \ + else gamma_dma_quiescent_single(dev); \ return 0; \ } while (0) @@ -99,47 +103,84 @@ #define DRIVER_PREINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); \ - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ + switch (dev_priv->chip_type) { \ + case GAMMA_CHIP_IS_GAMMA : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, 0x00000004 ); \ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ + break; \ + } \ } while (0) #define DRIVER_POSTINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ + switch (dev_priv->chip_type) { \ + case GAMMA_CHIP_IS_GAMMA : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002001 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000008 ); \ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00039090 ); \ + break; \ + case GAMMA_CHIP_IS_PERMEDIA2 : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 1); \ + GAMMA_WRITE( GAMMA_INTENABLE, 0x00000081 ); \ + break; \ + case GAMMA_CHIP_IS_PERMEDIA3 : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 1); \ + GAMMA_WRITE( GAMMA_INTENABLE, 0x00002081 ); \ + break; \ + } \ } while (0) #else #define DRIVER_POSTINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); \ + switch (dev_priv->chip_type) { \ + case GAMMA_CHIP_IS_GAMMA : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00002000 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000004 ); \ + break; \ + case GAMMA_CHIP_IS_PERMEDIA2 : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 1); \ + GAMMA_WRITE( GAMMA_INTENABLE, 0x00000081 ); \ + break; \ + case GAMMA_CHIP_IS_PERMEDIA3 : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 1); \ + GAMMA_WRITE( GAMMA_INTENABLE, 0x00002081 ); \ + break; \ + } \ } while (0) #define DRIVER_PREINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );\ - GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 );\ + switch (dev_priv->chip_type) { \ + case GAMMA_CHIP_IS_GAMMA : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ + GAMMA_WRITE( GAMMA_GCOMMANDMODE, GAMMA_QUEUED_DMA_MODE );\ + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x00000000 ); \ + break; \ + } \ } while (0) #endif #define DRIVER_UNINSTALL() do { \ drm_gamma_private_t *dev_priv = \ (drm_gamma_private_t *)dev->dev_private;\ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 2); \ - while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ - GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ - GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ - GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ + switch (dev_priv->chip_type) { \ + case GAMMA_CHIP_IS_GAMMA : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 3); \ + GAMMA_WRITE( GAMMA_GDELAYTIMER, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_COMMANDINTENABLE, 0x00000000 ); \ + GAMMA_WRITE( GAMMA_GINTENABLE, 0x00000000 ); \ + break; \ + case GAMMA_CHIP_IS_PERMEDIA2 : \ + case GAMMA_CHIP_IS_PERMEDIA3 : \ + while(GAMMA_READ(GAMMA_INFIFOSPACE) < 1); \ + GAMMA_WRITE( GAMMA_INTENABLE, 0x00000000 ); \ + break; \ + } \ } while (0) #define DRIVER_AGP_BUFFERS_MAP( dev ) \ diff --git a/linux/gamma_dma.c b/linux/gamma_dma.c index e18a577c..621665a9 100644 --- a/linux/gamma_dma.c +++ b/linux/gamma_dma.c @@ -26,6 +26,7 @@ * * Authors: * Rickard E. (Rik) Faith + * Sven Luther * */ @@ -46,8 +47,17 @@ static inline void gamma_dma_dispatch(drm_device_t *dev, unsigned long address, (drm_gamma_private_t *)dev->dev_private; mb(); while ( GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - GAMMA_WRITE(GAMMA_DMAADDRESS, address); - while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4); + switch (dev_priv->chip_type) { + case GAMMA_CHIP_IS_GAMMA : + GAMMA_WRITE(GAMMA_DMAADDRESS, address); + while (GAMMA_READ(GAMMA_GCOMMANDSTATUS) != 4); + break; + case GAMMA_CHIP_IS_PERMEDIA2 : + case GAMMA_CHIP_IS_PERMEDIA3 : + GAMMA_WRITE(GAMMA_DMAADDRESS, virt_to_phys((void *)address)); + while (GAMMA_READ(GAMMA_DMACOUNT)); + break; + } GAMMA_WRITE(GAMMA_DMACOUNT, length / 4); } @@ -114,10 +124,22 @@ void gamma_dma_service(int irq, void *device, struct pt_regs *regs) atomic_inc(&dev->counts[6]); /* _DRM_STAT_IRQ */ - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3); - GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ - GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); - GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); + switch (dev_priv->chip_type) { + case GAMMA_CHIP_IS_GAMMA : + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 3); + GAMMA_WRITE(GAMMA_GDELAYTIMER, 0xc350/2); /* 0x05S */ + GAMMA_WRITE(GAMMA_GCOMMANDINTFLAGS, 8); + GAMMA_WRITE(GAMMA_GINTFLAGS, 0x2001); + break; + case GAMMA_CHIP_IS_PERMEDIA2 : + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1); + GAMMA_WRITE(GAMMA_INTFLAGS, 0x0081); + break; + case GAMMA_CHIP_IS_PERMEDIA3 : + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1); + GAMMA_WRITE(GAMMA_INTFLAGS, 0x2081); + break; + } if (gamma_dma_is_ready(dev)) { /* Free previous buffer */ if (test_and_set_bit(0, &dev->dma_flag)) return; @@ -141,6 +163,8 @@ static int gamma_do_dma(drm_device_t *dev, int locked) drm_buf_t *buf; int retcode = 0; drm_device_dma_t *dma = dev->dma; + drm_gamma_private_t *dev_priv = + (drm_gamma_private_t *)dev->dev_private; #if DRM_DMA_HISTOGRAM cycles_t dma_start, dma_stop; #endif @@ -158,9 +182,20 @@ static int gamma_do_dma(drm_device_t *dev, int locked) } buf = dma->next_buffer; - /* WE NOW ARE ON LOGICAL PAGES!! - using page table setup in dma_init */ - /* So we pass the buffer index value into the physical page offset */ - address = buf->idx << 12; + + switch (dev_priv->chip_type) { + case GAMMA_CHIP_IS_GAMMA : + /* WE NOW ARE ON LOGICAL PAGES!! - using page table + * setup in dma_init so we pass the buffer index value + * into the physical page offset */ + address = buf->idx << 12; + case GAMMA_CHIP_IS_PERMEDIA2 : + case GAMMA_CHIP_IS_PERMEDIA3 : + default : + /* Permedia3 does not support logical pages */ + address = (unsigned long)buf->address; + break; + } length = buf->used; DRM_DEBUG("context %d, buffer %d (%ld bytes)\n", @@ -227,8 +262,13 @@ static int gamma_do_dma(drm_device_t *dev, int locked) buf->time_dispatched = get_cycles(); #endif - /* WE NOW ARE ON LOGICAL PAGES!!! - overriding address */ - address = buf->idx << 12; + + switch (dev_priv->chip_type) { + case GAMMA_CHIP_IS_GAMMA : + /* WE NOW ARE ON LOGICAL PAGES!!! - overriding address */ + address = buf->idx << 12; + break; + } gamma_dma_dispatch(dev, address, length); gamma_free_buffer(dev, dma->this_buffer); @@ -605,6 +645,9 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) memset( dev_priv, 0, sizeof(drm_gamma_private_t) ); + dev_priv->chip_type = init->chip_type; + dev_priv->num_rast = init->num_rast; + list_for_each(list, &dev->maplist->head) { drm_map_list_t *r_list = (drm_map_list_t *)list; if( r_list->map && @@ -651,12 +694,26 @@ static int gamma_do_init_dma( drm_device_t *dev, drm_gamma_init_t *init ) buf = dma->buflist[GLINT_DRI_BUF_COUNT]; - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1); - GAMMA_WRITE( GAMMA_GDMACONTROL, 0xe); + + switch (dev_priv->chip_type) { + case GAMMA_CHIP_IS_GAMMA : + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0xe); + break; + case GAMMA_CHIP_IS_PERMEDIA2 : + case GAMMA_CHIP_IS_PERMEDIA3 : + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 1); + GAMMA_WRITE( GAMMA_GDMACONTROL, 0x2); + break; + } + } + switch (dev_priv->chip_type) { + case GAMMA_CHIP_IS_GAMMA : + while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); + GAMMA_WRITE( GAMMA_PAGETABLEADDR, virt_to_phys((void*)buf->address) ); + GAMMA_WRITE( GAMMA_PAGETABLELENGTH, 2 ); + break; } - while (GAMMA_READ(GAMMA_INFIFOSPACE) < 2); - GAMMA_WRITE( GAMMA_PAGETABLEADDR, virt_to_phys((void*)buf->address) ); - GAMMA_WRITE( GAMMA_PAGETABLELENGTH, 2 ); return 0; } diff --git a/linux/gamma_drm.h b/linux/gamma_drm.h index 0d58b07b..791d61ca 100644 --- a/linux/gamma_drm.h +++ b/linux/gamma_drm.h @@ -84,6 +84,13 @@ typedef struct drm_gamma_init { unsigned int mmio2; unsigned int mmio3; unsigned int buffers_offset; + enum { + GAMMA_CHIP_IS_DELTA = 0x01, + GAMMA_CHIP_IS_GAMMA = 0x02, + GAMMA_CHIP_IS_PERMEDIA2 = 0x03, + GAMMA_CHIP_IS_PERMEDIA3 = 0x04 + } chip_type; + int num_rast; } drm_gamma_init_t; #endif /* _GAMMA_DRM_H_ */ diff --git a/linux/gamma_drv.h b/linux/gamma_drv.h index e7d0c896..71bf2e39 100644 --- a/linux/gamma_drv.h +++ b/linux/gamma_drv.h @@ -26,6 +26,7 @@ * * Authors: * Rickard E. (Rik) Faith + * Sven Luther * */ @@ -40,6 +41,8 @@ typedef struct drm_gamma_private { drm_map_t *mmio1; drm_map_t *mmio2; drm_map_t *mmio3; + int chip_type; + int num_rast; } drm_gamma_private_t; #define LOCK_TEST_WITH_RETURN( dev ) \ @@ -111,6 +114,8 @@ extern int gamma_found(void); #define GAMMA_SYNC_TAG 0x0188 #define GAMMA_PAGETABLEADDR 0x0C00 #define GAMMA_PAGETABLELENGTH 0x0C08 +#define GAMMA_INTENABLE 0x0008 +#define GAMMA_INTFLAGS 0x0010 #define GAMMA_PASSTHROUGH 0x1FE #define GAMMA_DMAADDRTAG 0x530 -- cgit v1.2.3