/* r128_drv.h -- Private header for r128 driver -*- linux-c -*- * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com */ /* * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, 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: * Rickard E. (Rik) Faith * Kevin E. Martin * Gareth Hughes * Michel D�zer */ #ifndef __R128_DRV_H__ #define __R128_DRV_H__ /* General customization: */ #define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc." #define DRIVER_NAME "r128" #define DRIVER_DESC "ATI Rage 128" #define DRIVER_DATE "20030725" /* Interface history: * * ?? - ?? * 2.4 - Add support for ycbcr textures (no new ioctls) * 2.5 - Add FLIP ioctl, disable FULLSCREEN. */ #define DRIVER_MAJOR 2 #define DRIVER_MINOR 5 #define DRIVER_PATCHLEVEL 0 #define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR ) typedef struct drm_r128_freelist { unsigned int age; struct drm_buf *buf; struct drm_r128_freelist *next; struct drm_r128_freelist *prev; } drm_r128_freelist_t; typedef struct drm_r128_ring_buffer { u32 *start; u32 *end; int size; int size_l2qw; u32 tail; u32 tail_mask; int space; int high_mark; } drm_r128_ring_buffer_t; typedef struct drm_r128_private { drm_r128_ring_buffer_t ring; drm_r128_sarea_t *sarea_priv; int cce_mode; int cce_fifo_size; int cce_running; drm_r128_freelist_t *head; drm_r128_freelist_t *tail; int usec_timeout; int is_pci; unsigned long cce_buffers_offset; atomic_t idle_count; int page_flipping; int current_page; u32 crtc_offset; u32 crtc_offset_cntl; atomic_t vbl_received; 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; unsigned int span_offset; u32 front_pitch_offset_c; u32 back_pitch_offset_c; u32 depth_pitch_offset_c; u32 span_pitch_offset_c; drm_local_map_t *sarea; drm_local_map_t *mmio; drm_local_map_t *cce_ring; drm_local_map_t *ring_rptr; drm_local_map_t *agp_textures; struct drm_ati_pcigart_info gart_info; } drm_r128_private_t; typedef struct drm_r128_buf_priv { u32 age; int prim; int discard; int dispatched; drm_r128_freelist_t *list_entry; } drm_r128_buf_priv_t; extern struct drm_ioctl_desc r128_ioctls[]; extern int r128_max_ioctl; /* r128_cce.c */ extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void r128_freelist_reset(struct drm_device * dev); extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n); extern int r128_do_cce_idle(drm_r128_private_t * dev_priv); extern int r128_do_cleanup_cce(struct drm_device * dev); extern int r128_enable_vblank(struct drm_device *dev, int crtc); extern void r128_disable_vblank(struct drm_device *dev, int crtc); extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc); extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS); extern void r128_driver_irq_preinstall(struct drm_device * dev); extern int r128_driver_irq_postinstall(struct drm_device * dev); extern void r128_driver_irq_uninstall(struct drm_device * dev); extern void r128_driver_lastclose(struct drm_device * dev); extern void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv); extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); /* Register definitions, register access macros and drmAddMap constants * for Rage 128 kernel driver. */ #define R128_AUX_SC_CNTL 0x1660 # define R128_AUX1_SC_EN (1 << 0) # define R128_AUX1_SC_MODE_OR (0 << 1) # define R128_AUX1_SC_MODE_NAND (1 << 1) # define R128_AUX2_SC_EN (1 << 2) # define R128_AUX2_SC_MODE_OR (0 << 3) # define R128_AUX2_SC_MODE_NAND (1 << 3) # define R128_AUX3_SC_EN (1 << 4) # define R128_AUX3_SC_MODE_OR (0 << 5) # define R128_AUX3_SC_MODE_NAND (1 << 5) #define R128_AUX1_SC_LEFT 0x1664 #define R128_AUX1_SC_RIGHT 0x1668 #define R128_AUX1_SC_TOP 0x166c #define R128_AUX1_SC_BOTTOM 0x1670 #define R128_AUX2_SC_LEFT 0x1674 #define R128_AUX2_SC_RIGHT 0x1678 #define R128_AUX2_SC_TOP 0x167c #define R128_AUX2_SC_BOTTOM 0x1680 #define R128_AUX3_SC_LEFT 0x1684 #define R128_AUX3_SC_RIGHT 0x1688 #define R128_AUX3_SC_TOP 0x168c #define R128_AUX3_SC_BOTTOM 0x1690 #define R128_BRUSH_DATA0 0x1480 #define R128_BUS_CNTL 0x0030 # define R128_BUS_MASTER_DIS (1 << 6) #define R128_CLOCK_CNTL_INDEX 0x0008 #define R128_CLOCK_CNTL_DATA 0x000c # define R128_PLL_WR_EN (1 << 7) #define R128_CONSTANT_COLOR_C 0x1d34 #define R128_CRTC_OFFSET 0x0224 #define R128_CRTC_OFFSET_CNTL 0x0228 # define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16) #define R128_DP_GUI_MASTER_CNTL 0x146c # define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) # define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) # define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) # define R128_GMC_BRUSH_NONE (15 << 4) # define R128_GMC_DST_16BPP (4 << 8) # define R128_GMC_DST_24BPP (5 << 8) # define R128_GMC_DST_32BPP (6 << 8) # define R128_GMC_DST_DATATYPE_SHIFT 8 # define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) # define R128_DP_SRC_SOURCE_MEMORY (2 << 24) # define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24) # define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) # define R128_GMC_AUX_CLIP_DIS (1 << 29) # define R128_GMC_WR_MSK_DIS (1 << 30) # define R128_ROP3_S 0x00cc0000 # define R128_ROP3_P 0x00f00000 #define R128_DP_WRITE_MASK 0x16cc #define R128_DST_PITCH_OFFSET_C 0x1c80 # define R128_DST_TILE (1 << 31) #define R128_GEN_INT_CNTL 0x0040 # define R128_CRTC_VBLANK_INT_EN (1 << 0) #define R128_GEN_INT_STATUS 0x0044 # define R128_CRTC_VBLANK_INT (1 << 0) # define R128_CRTC_VBLANK_INT_AK (1 << 0) #define R128_GEN_RESET_CNTL 0x00f0 # define R128_SOFT_RESET_GUI (1 << 0) #define R128_GUI_SCRATCH_REG0 0x15e0 #define R128_GUI_SCRATCH_REG1 0x15e4 #define R128_GUI_SCRATCH_REG2 0x15e8 #define R128_GUI_SCRATCH_REG3 0x15ec #define R128_GUI_SCRATCH_REG4 0x15f0 #define R128_GUI_SCRATCH_REG5 0x15f4 #define R128_GUI_STAT 0x1740 # define R128_GUI_FIFOCNT_MASK 0x0fff # define R128_GUI_ACTIVE (1 << 31) #define R128_MCLK_CNTL 0x000f # define R128_FORCE_GCP (1 << 16) # define R128_FORCE_PIPE3D_CP (1 << 17) # define R128_FORCE_RCP (1 << 18) #define R128_PC_GUI_CTLSTAT 0x1748 #define R128_PC_NGUI_CTLSTAT 0x0184 # define R128_PC_FLUSH_GUI (3 << 0) # define R128_PC_RI_GUI (1 << 2) # define R128_PC_FLUSH_ALL 0x00ff # define R128_PC_BUSY (1 << 31) #define R128_PCI_GART_PAGE 0x017c #define R128_PRIM_TEX_CNTL_C 0x1cb0 #define R128_SCALE_3D_CNTL 0x1a00 #define R128_SEC_TEX_CNTL_C 0x1d00 #define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c #define R128_SETUP_CNTL 0x1bc4 #define R128_STEN_REF_MASK_C 0x1d40 #define R128_TEX_CNTL_C 0x1c9c # define R128_TEX_CACHE_FLUSH (1 << 23) #define R128_WAIT_UNTIL 0x1720 # define R128_EVENT_CRTC_OFFSET (1 << 0) #define R128_WINDOW_XY_OFFSET 0x1bcc /* CCE registers */ #define R128_PM4_BUFFER_OFFSET 0x0700 #define R128_PM4_BUFFER_CNTL 0x0704 # define R128_PM4_MASK (15 << 28) # define R128_PM4_NONPM4 (0 << 28) # define R128_PM4_192PIO (1 << 28) # define R128_PM4_192BM (2 << 28) # define R128_PM4_128PIO_64INDBM (3 << 28) # define R128_PM4_128BM_64INDBM (4 << 28) # define R128_PM4_64PIO_128INDBM (5 << 28) # define R128_PM4_64BM_128INDBM (6 << 28) # define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) # define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) # define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) # define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27) #define R128_PM4_BUFFER_WM_CNTL 0x0708 # define R128_WMA_SHIFT 0 # define R128_WMB_SHIFT 8 # define R128_WMC_SHIFT 16 # define R128_WB_WM_SHIFT 24 #define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c #define R128_PM4_BUFFER_DL_RPTR 0x0710 #define R128_PM4_BUFFER_DL_WPTR 0x0714 # define R128_PM4/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, 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: Rickard E. (Rik) Faith <faith@valinux.com> * * DESCRIPTION * * This file contains a simple, straightforward implementation of the Park * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer * multiplicative linear congruential generator (MLCG) with a period of * 2^31-1. * * This implementation is intended to provide a reliable, portable PRNG * that is suitable for testing a hash table implementation and for * implementing skip lists. * * FUTURE ENHANCEMENTS * * If initial seeds are not selected randomly, two instances of the PRNG * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique * that can eliminate this problem. * * If PRNGs are used for simulation, the period of the current * implementation may be too short. [LE88] discusses methods of combining * MLCGs to produce much longer periods, and suggests some alternative * values for A and M. [LE90 and Sch92] also provide information on * long-period PRNGs. * * REFERENCES * * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2: * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981. * * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number * Generators". CACM 31(6), June 1988, pp. 742-774. * * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10, * October 1990, pp. 85-97. * * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators: * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201. * * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40. * * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In * "Technical Correspondence: Remarks on Choosing and Implementing Random * Number Generators". CACM 36(7), July 1993, pp. 105-110. * */ #include <stdio.h> #include <stdlib.h> #define RANDOM_MAIN 0 #if !RANDOM_MAIN # include "drm.h" # include "xf86drm.h" #endif #define RANDOM_MAGIC 0xfeedbeef #define RANDOM_DEBUG 0 #if RANDOM_MAIN #define RANDOM_ALLOC malloc #define RANDOM_FREE free #else #define RANDOM_ALLOC drmMalloc #define RANDOM_FREE drmFree #endif typedef struct RandomState { unsigned long magic; unsigned long a; unsigned long m; unsigned long q; /* m div a */ unsigned long r; /* m mod a */ unsigned long check; long seed; } RandomState; #if RANDOM_MAIN extern void *drmRandomCreate(unsigned long seed); extern int drmRandomDestroy(void *state); extern unsigned long drmRandom(void *state); extern double drmRandomDouble(void *state); #endif void *drmRandomCreate(unsigned long seed) { RandomState *state; state = RANDOM_ALLOC(sizeof(*state)); if (!state) return NULL; state->magic = RANDOM_MAGIC; #if 0 /* Park & Miller, October 1988 */ state->a = 16807; state->m = 2147483647; state->check = 1043618065; /* After 10000 iterations */ #else /* Park, Miller, and Stockmeyer, July 1993 */ state->a = 48271; state->m = 2147483647; state->check = 399268537; /* After 10000 iterations */ #endif state->q = state->m / state->a; state->r = state->m % state->a; state->seed = seed; /* Check for illegal boundary conditions, and choose closest legal value. */ if (state->seed <= 0) state->seed = 1; if (state->seed >= state->m) state->seed = state->m - 1; return state; } int drmRandomDestroy(void *state) { RANDOM_FREE(state); return 0; } unsigned long drmRandom(void *state) { RandomState *s = (RandomState *)state; long hi; long lo; hi = s->seed / s->q; lo = s->seed % s->q; s->seed = s->a * lo - s->r * hi; if (s->seed <= 0) s->seed += s->m; return s->seed; } double drmRandomDouble(void *state) { RandomState *s = (RandomState *)state; return (double)drmRandom(state)/(double)s->m; } #if RANDOM_MAIN static void check_period(long seed) { unsigned long count = 0; unsigned long initial; void *state; state = drmRandomCreate(seed); initial = drmRandom(state); ++count; while (initial != drmRandom(state)) { if (!++count) break; } printf("With seed of %10ld, period = %10lu (0x%08lx)\n", seed, count, count); drmRandomDestroy(state); } int main(void) { RandomState *state; int i; unsigned long rand; state = drmRandomCreate(1); for (i = 0; i < 10000; i++) { rand = drmRandom(state); } printf("After 10000 iterations: %lu (%lu expected): %s\n", rand, state->check, rand - state->check ? "*INCORRECT*" : "CORRECT"); drmRandomDestroy(state); printf("Checking periods...\n"); check_period(1); check_period(2); check_period(31415926); return 0; } #endif