1145132Sanholt/* mach64_drv.h -- Private header for mach64 driver -*- linux-c -*- 2145132Sanholt * Created: Fri Nov 24 22:07:58 2000 by gareth@valinux.com 3152909Sanholt */ 4152909Sanholt/*- 5145132Sanholt * Copyright 2000 Gareth Hughes 6145132Sanholt * Copyright 2002 Frank C. Earl 7145132Sanholt * Copyright 2002-2003 Leif Delgass 8145132Sanholt * All Rights Reserved. 9145132Sanholt * 10145132Sanholt * Permission is hereby granted, free of charge, to any person obtaining a 11145132Sanholt * copy of this software and associated documentation files (the "Software"), 12145132Sanholt * to deal in the Software without restriction, including without limitation 13145132Sanholt * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14145132Sanholt * and/or sell copies of the Software, and to permit persons to whom the 15145132Sanholt * Software is furnished to do so, subject to the following conditions: 16145132Sanholt * 17145132Sanholt * The above copyright notice and this permission notice (including the next 18145132Sanholt * paragraph) shall be included in all copies or substantial portions of the 19145132Sanholt * Software. 20145132Sanholt * 21145132Sanholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22145132Sanholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23145132Sanholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24145132Sanholt * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 25145132Sanholt * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 26145132Sanholt * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27145132Sanholt * 28145132Sanholt * Authors: 29145132Sanholt * Gareth Hughes <gareth@valinux.com> 30145132Sanholt * Frank C. Earl <fearl@airmail.net> 31145132Sanholt * Leif Delgass <ldelgass@retinalburn.net> 32182080Srnoland * Jos�� Fonseca <j_r_fonseca@yahoo.co.uk> 33145132Sanholt */ 34145132Sanholt 35152909Sanholt#include <sys/cdefs.h> 36152909Sanholt__FBSDID("$FreeBSD$"); 37152909Sanholt 38145132Sanholt#ifndef __MACH64_DRV_H__ 39145132Sanholt#define __MACH64_DRV_H__ 40145132Sanholt 41145132Sanholt/* General customization: 42145132Sanholt */ 43145132Sanholt 44145132Sanholt#define DRIVER_AUTHOR "Gareth Hughes, Leif Delgass, Jos�� Fonseca" 45145132Sanholt 46145132Sanholt#define DRIVER_NAME "mach64" 47145132Sanholt#define DRIVER_DESC "DRM module for the ATI Rage Pro" 48182080Srnoland#define DRIVER_DATE "20060718" 49145132Sanholt 50182080Srnoland#define DRIVER_MAJOR 2 51145132Sanholt#define DRIVER_MINOR 0 52145132Sanholt#define DRIVER_PATCHLEVEL 0 53145132Sanholt 54145132Sanholt/* FIXME: remove these when not needed */ 55145132Sanholt/* Development driver options */ 56145132Sanholt#define MACH64_EXTRA_CHECKING 0 /* Extra sanity checks for DMA/freelist management */ 57145132Sanholt#define MACH64_VERBOSE 0 /* Verbose debugging output */ 58145132Sanholt 59145132Sanholttypedef struct drm_mach64_freelist { 60145132Sanholt struct list_head list; /* List pointers for free_list, placeholders, or pending list */ 61182080Srnoland struct drm_buf *buf; /* Pointer to the buffer */ 62145132Sanholt int discard; /* This flag is set when we're done (re)using a buffer */ 63145132Sanholt u32 ring_ofs; /* dword offset in ring of last descriptor for this buffer */ 64145132Sanholt} drm_mach64_freelist_t; 65145132Sanholt 66145132Sanholttypedef struct drm_mach64_descriptor_ring { 67145132Sanholt void *start; /* write pointer (cpu address) to start of descriptor ring */ 68145132Sanholt u32 start_addr; /* bus address of beginning of descriptor ring */ 69145132Sanholt int size; /* size of ring in bytes */ 70145132Sanholt 71145132Sanholt u32 head_addr; /* bus address of descriptor ring head */ 72145132Sanholt u32 head; /* dword offset of descriptor ring head */ 73145132Sanholt u32 tail; /* dword offset of descriptor ring tail */ 74145132Sanholt u32 tail_mask; /* mask used to wrap ring */ 75145132Sanholt int space; /* number of free bytes in ring */ 76145132Sanholt} drm_mach64_descriptor_ring_t; 77145132Sanholt 78145132Sanholttypedef struct drm_mach64_private { 79145132Sanholt drm_mach64_sarea_t *sarea_priv; 80145132Sanholt 81145132Sanholt int is_pci; 82145132Sanholt drm_mach64_dma_mode_t driver_mode; /* Async DMA, sync DMA, or MMIO */ 83145132Sanholt 84145132Sanholt int usec_timeout; /* Timeout for the wait functions */ 85145132Sanholt 86145132Sanholt drm_mach64_descriptor_ring_t ring; /* DMA descriptor table (ring buffer) */ 87145132Sanholt int ring_running; /* Is bus mastering is enabled */ 88145132Sanholt 89145132Sanholt struct list_head free_list; /* Free-list head */ 90145132Sanholt struct list_head placeholders; /* Placeholder list for buffers held by clients */ 91145132Sanholt struct list_head pending; /* Buffers pending completion */ 92145132Sanholt 93145132Sanholt u32 frame_ofs[MACH64_MAX_QUEUED_FRAMES]; /* dword ring offsets of most recent frame swaps */ 94145132Sanholt 95145132Sanholt unsigned int fb_bpp; 96145132Sanholt unsigned int front_offset, front_pitch; 97145132Sanholt unsigned int back_offset, back_pitch; 98145132Sanholt 99145132Sanholt unsigned int depth_bpp; 100145132Sanholt unsigned int depth_offset, depth_pitch; 101145132Sanholt 102182080Srnoland atomic_t vbl_received; /**< Number of vblanks received. */ 103182080Srnoland 104145132Sanholt u32 front_offset_pitch; 105145132Sanholt u32 back_offset_pitch; 106145132Sanholt u32 depth_offset_pitch; 107145132Sanholt 108145132Sanholt drm_local_map_t *sarea; 109145132Sanholt drm_local_map_t *fb; 110145132Sanholt drm_local_map_t *mmio; 111145132Sanholt drm_local_map_t *ring_map; 112145132Sanholt drm_local_map_t *dev_buffers; /* this is a pointer to a structure in dev */ 113145132Sanholt drm_local_map_t *agp_textures; 114145132Sanholt} drm_mach64_private_t; 115145132Sanholt 116182080Srnolandextern struct drm_ioctl_desc mach64_ioctls[]; 117152909Sanholtextern int mach64_max_ioctl; 118152909Sanholt 119145132Sanholt /* mach64_dma.c */ 120182080Srnolandextern int mach64_dma_init(struct drm_device *dev, void *data, 121182080Srnoland struct drm_file *file_priv); 122182080Srnolandextern int mach64_dma_idle(struct drm_device *dev, void *data, 123182080Srnoland struct drm_file *file_priv); 124182080Srnolandextern int mach64_dma_flush(struct drm_device *dev, void *data, 125182080Srnoland struct drm_file *file_priv); 126182080Srnolandextern int mach64_engine_reset(struct drm_device *dev, void *data, 127182080Srnoland struct drm_file *file_priv); 128182080Srnolandextern int mach64_dma_buffers(struct drm_device *dev, void *data, 129182080Srnoland struct drm_file *file_priv); 130182080Srnolandextern void mach64_driver_lastclose(struct drm_device * dev); 131145132Sanholt 132182080Srnolandextern int mach64_init_freelist(struct drm_device * dev); 133182080Srnolandextern void mach64_destroy_freelist(struct drm_device * dev); 134182080Srnolandextern struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv); 135182080Srnolandextern int mach64_freelist_put(drm_mach64_private_t * dev_priv, 136182080Srnoland struct drm_buf * copy_buf); 137145132Sanholt 138145132Sanholtextern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, 139145132Sanholt int entries); 140145132Sanholtextern int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv); 141145132Sanholtextern int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n); 142145132Sanholtextern int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv); 143145132Sanholtextern int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv); 144145132Sanholtextern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv); 145145132Sanholtextern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv); 146145132Sanholtextern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv); 147145132Sanholt 148182080Srnolandextern int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, 149182080Srnoland drm_mach64_freelist_t *_entry); 150182080Srnolandextern int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv, 151182080Srnoland drm_mach64_freelist_t *_entry); 152182080Srnoland 153145132Sanholtextern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv); 154145132Sanholtextern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv); 155182080Srnolandextern int mach64_do_cleanup_dma(struct drm_device * dev); 156145132Sanholt 157145132Sanholt /* mach64_state.c */ 158182080Srnolandextern int mach64_dma_clear(struct drm_device *dev, void *data, 159182080Srnoland struct drm_file *file_priv); 160182080Srnolandextern int mach64_dma_swap(struct drm_device *dev, void *data, 161182080Srnoland struct drm_file *file_priv); 162182080Srnolandextern int mach64_dma_vertex(struct drm_device *dev, void *data, 163182080Srnoland struct drm_file *file_priv); 164182080Srnolandextern int mach64_dma_blit(struct drm_device *dev, void *data, 165182080Srnoland struct drm_file *file_priv); 166182080Srnolandextern int mach64_get_param(struct drm_device *dev, void *data, 167182080Srnoland struct drm_file *file_priv); 168145132Sanholt 169189130Srnolandextern int mach64_driver_load(struct drm_device * dev, unsigned long flags); 170182080Srnolandextern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc); 171182080Srnolandextern int mach64_enable_vblank(struct drm_device *dev, int crtc); 172182080Srnolandextern void mach64_disable_vblank(struct drm_device *dev, int crtc); 173145132Sanholtextern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS); 174182080Srnolandextern void mach64_driver_irq_preinstall(struct drm_device *dev); 175182080Srnolandextern int mach64_driver_irq_postinstall(struct drm_device *dev); 176182080Srnolandextern void mach64_driver_irq_uninstall(struct drm_device *dev); 177145132Sanholt 178145132Sanholt/* ================================================================ 179145132Sanholt * Registers 180145132Sanholt */ 181145132Sanholt 182145132Sanholt#define MACH64_AGP_BASE 0x0148 183145132Sanholt#define MACH64_AGP_CNTL 0x014c 184145132Sanholt#define MACH64_ALPHA_TST_CNTL 0x0550 185145132Sanholt 186182080Srnoland#define MACH64_DSP_CONFIG 0x0420 187182080Srnoland#define MACH64_DSP_ON_OFF 0x0424 188182080Srnoland#define MACH64_EXT_MEM_CNTL 0x04ac 189182080Srnoland#define MACH64_GEN_TEST_CNTL 0x04d0 190182080Srnoland#define MACH64_HW_DEBUG 0x047c 191182080Srnoland#define MACH64_MEM_ADDR_CONFIG 0x0434 192182080Srnoland#define MACH64_MEM_BUF_CNTL 0x042c 193182080Srnoland#define MACH64_MEM_CNTL 0x04b0 194145132Sanholt 195145132Sanholt#define MACH64_BM_ADDR 0x0648 196145132Sanholt#define MACH64_BM_COMMAND 0x0188 197145132Sanholt#define MACH64_BM_DATA 0x0648 198145132Sanholt#define MACH64_BM_FRAME_BUF_OFFSET 0x0180 199145132Sanholt#define MACH64_BM_GUI_TABLE 0x01b8 200145132Sanholt#define MACH64_BM_GUI_TABLE_CMD 0x064c 201145132Sanholt# define MACH64_CIRCULAR_BUF_SIZE_16KB (0 << 0) 202145132Sanholt# define MACH64_CIRCULAR_BUF_SIZE_32KB (1 << 0) 203145132Sanholt# define MACH64_CIRCULAR_BUF_SIZE_64KB (2 << 0) 204145132Sanholt# define MACH64_CIRCULAR_BUF_SIZE_128KB (3 << 0) 205145132Sanholt# define MACH64_LAST_DESCRIPTOR (1 << 31) 206145132Sanholt#define MACH64_BM_HOSTDATA 0x0644 207145132Sanholt#define MACH64_BM_STATUS 0x018c 208145132Sanholt#define MACH64_BM_SYSTEM_MEM_ADDR 0x0184 209145132Sanholt#define MACH64_BM_SYSTEM_TABLE 0x01bc 210145132Sanholt#define MACH64_BUS_CNTL 0x04a0 211145132Sanholt# define MACH64_BUS_MSTR_RESET (1 << 1) 212145132Sanholt# define MACH64_BUS_APER_REG_DIS (1 << 4) 213145132Sanholt# define MACH64_BUS_FLUSH_BUF (1 << 2) 214145132Sanholt# define MACH64_BUS_MASTER_DIS (1 << 6) 215145132Sanholt# define MACH64_BUS_EXT_REG_EN (1 << 27) 216145132Sanholt 217145132Sanholt#define MACH64_CLR_CMP_CLR 0x0700 218145132Sanholt#define MACH64_CLR_CMP_CNTL 0x0708 219145132Sanholt#define MACH64_CLR_CMP_MASK 0x0704 220182080Srnoland#define MACH64_CONFIG_CHIP_ID 0x04e0 221182080Srnoland#define MACH64_CONFIG_CNTL 0x04dc 222182080Srnoland#define MACH64_CONFIG_STAT0 0x04e4 223182080Srnoland#define MACH64_CONFIG_STAT1 0x0494 224182080Srnoland#define MACH64_CONFIG_STAT2 0x0498 225145132Sanholt#define MACH64_CONTEXT_LOAD_CNTL 0x072c 226145132Sanholt#define MACH64_CONTEXT_MASK 0x0720 227145132Sanholt#define MACH64_COMPOSITE_SHADOW_ID 0x0798 228182080Srnoland#define MACH64_CRC_SIG 0x04e8 229182080Srnoland#define MACH64_CUSTOM_MACRO_CNTL 0x04d4 230145132Sanholt 231145132Sanholt#define MACH64_DP_BKGD_CLR 0x06c0 232145132Sanholt#define MACH64_DP_FOG_CLR 0x06c4 233145132Sanholt#define MACH64_DP_FGRD_BKGD_CLR 0x06e0 234145132Sanholt#define MACH64_DP_FRGD_CLR 0x06c4 235145132Sanholt#define MACH64_DP_FGRD_CLR_MIX 0x06dc 236145132Sanholt 237145132Sanholt#define MACH64_DP_MIX 0x06d4 238145132Sanholt# define BKGD_MIX_NOT_D (0 << 0) 239145132Sanholt# define BKGD_MIX_ZERO (1 << 0) 240145132Sanholt# define BKGD_MIX_ONE (2 << 0) 241145132Sanholt# define MACH64_BKGD_MIX_D (3 << 0) 242145132Sanholt# define BKGD_MIX_NOT_S (4 << 0) 243145132Sanholt# define BKGD_MIX_D_XOR_S (5 << 0) 244145132Sanholt# define BKGD_MIX_NOT_D_XOR_S (6 << 0) 245145132Sanholt# define MACH64_BKGD_MIX_S (7 << 0) 246145132Sanholt# define BKGD_MIX_NOT_D_OR_NOT_S (8 << 0) 247145132Sanholt# define BKGD_MIX_D_OR_NOT_S (9 << 0) 248145132Sanholt# define BKGD_MIX_NOT_D_OR_S (10 << 0) 249145132Sanholt# define BKGD_MIX_D_OR_S (11 << 0) 250145132Sanholt# define BKGD_MIX_D_AND_S (12 << 0) 251145132Sanholt# define BKGD_MIX_NOT_D_AND_S (13 << 0) 252145132Sanholt# define BKGD_MIX_D_AND_NOT_S (14 << 0) 253145132Sanholt# define BKGD_MIX_NOT_D_AND_NOT_S (15 << 0) 254145132Sanholt# define BKGD_MIX_D_PLUS_S_DIV2 (23 << 0) 255145132Sanholt# define FRGD_MIX_NOT_D (0 << 16) 256145132Sanholt# define FRGD_MIX_ZERO (1 << 16) 257145132Sanholt# define FRGD_MIX_ONE (2 << 16) 258145132Sanholt# define FRGD_MIX_D (3 << 16) 259145132Sanholt# define FRGD_MIX_NOT_S (4 << 16) 260145132Sanholt# define FRGD_MIX_D_XOR_S (5 << 16) 261145132Sanholt# define FRGD_MIX_NOT_D_XOR_S (6 << 16) 262145132Sanholt# define MACH64_FRGD_MIX_S (7 << 16) 263145132Sanholt# define FRGD_MIX_NOT_D_OR_NOT_S (8 << 16) 264145132Sanholt# define FRGD_MIX_D_OR_NOT_S (9 << 16) 265145132Sanholt# define FRGD_MIX_NOT_D_OR_S (10 << 16) 266145132Sanholt# define FRGD_MIX_D_OR_S (11 << 16) 267145132Sanholt# define FRGD_MIX_D_AND_S (12 << 16) 268145132Sanholt# define FRGD_MIX_NOT_D_AND_S (13 << 16) 269145132Sanholt# define FRGD_MIX_D_AND_NOT_S (14 << 16) 270145132Sanholt# define FRGD_MIX_NOT_D_AND_NOT_S (15 << 16) 271145132Sanholt# define FRGD_MIX_D_PLUS_S_DIV2 (23 << 16) 272145132Sanholt 273145132Sanholt#define MACH64_DP_PIX_WIDTH 0x06d0 274145132Sanholt# define MACH64_HOST_TRIPLE_ENABLE (1 << 13) 275145132Sanholt# define MACH64_BYTE_ORDER_MSB_TO_LSB (0 << 24) 276145132Sanholt# define MACH64_BYTE_ORDER_LSB_TO_MSB (1 << 24) 277145132Sanholt 278145132Sanholt#define MACH64_DP_SRC 0x06d8 279145132Sanholt# define MACH64_BKGD_SRC_BKGD_CLR (0 << 0) 280145132Sanholt# define MACH64_BKGD_SRC_FRGD_CLR (1 << 0) 281145132Sanholt# define MACH64_BKGD_SRC_HOST (2 << 0) 282145132Sanholt# define MACH64_BKGD_SRC_BLIT (3 << 0) 283145132Sanholt# define MACH64_BKGD_SRC_PATTERN (4 << 0) 284145132Sanholt# define MACH64_BKGD_SRC_3D (5 << 0) 285145132Sanholt# define MACH64_FRGD_SRC_BKGD_CLR (0 << 8) 286145132Sanholt# define MACH64_FRGD_SRC_FRGD_CLR (1 << 8) 287145132Sanholt# define MACH64_FRGD_SRC_HOST (2 << 8) 288145132Sanholt# define MACH64_FRGD_SRC_BLIT (3 << 8) 289145132Sanholt# define MACH64_FRGD_SRC_PATTERN (4 << 8) 290145132Sanholt# define MACH64_FRGD_SRC_3D (5 << 8) 291145132Sanholt# define MACH64_MONO_SRC_ONE (0 << 16) 292145132Sanholt# define MACH64_MONO_SRC_PATTERN (1 << 16) 293145132Sanholt# define MACH64_MONO_SRC_HOST (2 << 16) 294145132Sanholt# define MACH64_MONO_SRC_BLIT (3 << 16) 295145132Sanholt 296145132Sanholt#define MACH64_DP_WRITE_MASK 0x06c8 297145132Sanholt 298145132Sanholt#define MACH64_DST_CNTL 0x0530 299145132Sanholt# define MACH64_DST_X_RIGHT_TO_LEFT (0 << 0) 300145132Sanholt# define MACH64_DST_X_LEFT_TO_RIGHT (1 << 0) 301145132Sanholt# define MACH64_DST_Y_BOTTOM_TO_TOP (0 << 1) 302145132Sanholt# define MACH64_DST_Y_TOP_TO_BOTTOM (1 << 1) 303145132Sanholt# define MACH64_DST_X_MAJOR (0 << 2) 304145132Sanholt# define MACH64_DST_Y_MAJOR (1 << 2) 305145132Sanholt# define MACH64_DST_X_TILE (1 << 3) 306145132Sanholt# define MACH64_DST_Y_TILE (1 << 4) 307145132Sanholt# define MACH64_DST_LAST_PEL (1 << 5) 308145132Sanholt# define MACH64_DST_POLYGON_ENABLE (1 << 6) 309145132Sanholt# define MACH64_DST_24_ROTATION_ENABLE (1 << 7) 310145132Sanholt 311145132Sanholt#define MACH64_DST_HEIGHT_WIDTH 0x0518 312145132Sanholt#define MACH64_DST_OFF_PITCH 0x0500 313145132Sanholt#define MACH64_DST_WIDTH_HEIGHT 0x06ec 314145132Sanholt#define MACH64_DST_X_Y 0x06e8 315145132Sanholt#define MACH64_DST_Y_X 0x050c 316145132Sanholt 317145132Sanholt#define MACH64_FIFO_STAT 0x0710 318145132Sanholt# define MACH64_FIFO_SLOT_MASK 0x0000ffff 319145132Sanholt# define MACH64_FIFO_ERR (1 << 31) 320145132Sanholt 321145132Sanholt#define MACH64_GEN_TEST_CNTL 0x04d0 322145132Sanholt# define MACH64_GUI_ENGINE_ENABLE (1 << 8) 323145132Sanholt#define MACH64_GUI_CMDFIFO_DEBUG 0x0170 324145132Sanholt#define MACH64_GUI_CMDFIFO_DATA 0x0174 325145132Sanholt#define MACH64_GUI_CNTL 0x0178 326145132Sanholt# define MACH64_CMDFIFO_SIZE_MASK 0x00000003ul 327145132Sanholt# define MACH64_CMDFIFO_SIZE_192 0x00000000ul 328145132Sanholt# define MACH64_CMDFIFO_SIZE_128 0x00000001ul 329145132Sanholt# define MACH64_CMDFIFO_SIZE_64 0x00000002ul 330145132Sanholt#define MACH64_GUI_STAT 0x0738 331145132Sanholt# define MACH64_GUI_ACTIVE (1 << 0) 332145132Sanholt#define MACH64_GUI_TRAJ_CNTL 0x0730 333145132Sanholt 334145132Sanholt#define MACH64_HOST_CNTL 0x0640 335145132Sanholt#define MACH64_HOST_DATA0 0x0600 336145132Sanholt 337145132Sanholt#define MACH64_ONE_OVER_AREA 0x029c 338145132Sanholt#define MACH64_ONE_OVER_AREA_UC 0x0300 339145132Sanholt 340145132Sanholt#define MACH64_PAT_REG0 0x0680 341145132Sanholt#define MACH64_PAT_REG1 0x0684 342145132Sanholt 343145132Sanholt#define MACH64_SC_LEFT 0x06a0 344145132Sanholt#define MACH64_SC_RIGHT 0x06a4 345145132Sanholt#define MACH64_SC_LEFT_RIGHT 0x06a8 346145132Sanholt#define MACH64_SC_TOP 0x06ac 347145132Sanholt#define MACH64_SC_BOTTOM 0x06b0 348145132Sanholt#define MACH64_SC_TOP_BOTTOM 0x06b4 349145132Sanholt 350145132Sanholt#define MACH64_SCALE_3D_CNTL 0x05fc 351145132Sanholt#define MACH64_SCRATCH_REG0 0x0480 352145132Sanholt#define MACH64_SCRATCH_REG1 0x0484 353145132Sanholt#define MACH64_SECONDARY_TEX_OFF 0x0778 354145132Sanholt#define MACH64_SETUP_CNTL 0x0304 355145132Sanholt#define MACH64_SRC_CNTL 0x05b4 356145132Sanholt# define MACH64_SRC_BM_ENABLE (1 << 8) 357145132Sanholt# define MACH64_SRC_BM_SYNC (1 << 9) 358145132Sanholt# define MACH64_SRC_BM_OP_FRAME_TO_SYSTEM (0 << 10) 359145132Sanholt# define MACH64_SRC_BM_OP_SYSTEM_TO_FRAME (1 << 10) 360145132Sanholt# define MACH64_SRC_BM_OP_REG_TO_SYSTEM (2 << 10) 361145132Sanholt# define MACH64_SRC_BM_OP_SYSTEM_TO_REG (3 << 10) 362145132Sanholt#define MACH64_SRC_HEIGHT1 0x0594 363145132Sanholt#define MACH64_SRC_HEIGHT2 0x05ac 364145132Sanholt#define MACH64_SRC_HEIGHT1_WIDTH1 0x0598 365145132Sanholt#define MACH64_SRC_HEIGHT2_WIDTH2 0x05b0 366145132Sanholt#define MACH64_SRC_OFF_PITCH 0x0580 367145132Sanholt#define MACH64_SRC_WIDTH1 0x0590 368145132Sanholt#define MACH64_SRC_Y_X 0x058c 369145132Sanholt 370145132Sanholt#define MACH64_TEX_0_OFF 0x05c0 371145132Sanholt#define MACH64_TEX_CNTL 0x0774 372145132Sanholt#define MACH64_TEX_SIZE_PITCH 0x0770 373182080Srnoland#define MACH64_TIMER_CONFIG 0x0428 374145132Sanholt 375145132Sanholt#define MACH64_VERTEX_1_ARGB 0x0254 376145132Sanholt#define MACH64_VERTEX_1_S 0x0240 377145132Sanholt#define MACH64_VERTEX_1_SECONDARY_S 0x0328 378145132Sanholt#define MACH64_VERTEX_1_SECONDARY_T 0x032c 379145132Sanholt#define MACH64_VERTEX_1_SECONDARY_W 0x0330 380145132Sanholt#define MACH64_VERTEX_1_SPEC_ARGB 0x024c 381145132Sanholt#define MACH64_VERTEX_1_T 0x0244 382145132Sanholt#define MACH64_VERTEX_1_W 0x0248 383145132Sanholt#define MACH64_VERTEX_1_X_Y 0x0258 384145132Sanholt#define MACH64_VERTEX_1_Z 0x0250 385145132Sanholt#define MACH64_VERTEX_2_ARGB 0x0274 386145132Sanholt#define MACH64_VERTEX_2_S 0x0260 387145132Sanholt#define MACH64_VERTEX_2_SECONDARY_S 0x0334 388145132Sanholt#define MACH64_VERTEX_2_SECONDARY_T 0x0338 389145132Sanholt#define MACH64_VERTEX_2_SECONDARY_W 0x033c 390145132Sanholt#define MACH64_VERTEX_2_SPEC_ARGB 0x026c 391145132Sanholt#define MACH64_VERTEX_2_T 0x0264 392145132Sanholt#define MACH64_VERTEX_2_W 0x0268 393145132Sanholt#define MACH64_VERTEX_2_X_Y 0x0278 394145132Sanholt#define MACH64_VERTEX_2_Z 0x0270 395145132Sanholt#define MACH64_VERTEX_3_ARGB 0x0294 396145132Sanholt#define MACH64_VERTEX_3_S 0x0280 397145132Sanholt#define MACH64_VERTEX_3_SECONDARY_S 0x02a0 398145132Sanholt#define MACH64_VERTEX_3_SECONDARY_T 0x02a4 399145132Sanholt#define MACH64_VERTEX_3_SECONDARY_W 0x02a8 400145132Sanholt#define MACH64_VERTEX_3_SPEC_ARGB 0x028c 401145132Sanholt#define MACH64_VERTEX_3_T 0x0284 402145132Sanholt#define MACH64_VERTEX_3_W 0x0288 403145132Sanholt#define MACH64_VERTEX_3_X_Y 0x0298 404145132Sanholt#define MACH64_VERTEX_3_Z 0x0290 405145132Sanholt 406145132Sanholt#define MACH64_Z_CNTL 0x054c 407145132Sanholt#define MACH64_Z_OFF_PITCH 0x0548 408145132Sanholt 409145132Sanholt#define MACH64_CRTC_VLINE_CRNT_VLINE 0x0410 410145132Sanholt# define MACH64_CRTC_VLINE_MASK 0x000007ff 411145132Sanholt# define MACH64_CRTC_CRNT_VLINE_MASK 0x07ff0000 412145132Sanholt#define MACH64_CRTC_OFF_PITCH 0x0414 413145132Sanholt#define MACH64_CRTC_INT_CNTL 0x0418 414145132Sanholt# define MACH64_CRTC_VBLANK (1 << 0) 415145132Sanholt# define MACH64_CRTC_VBLANK_INT_EN (1 << 1) 416145132Sanholt# define MACH64_CRTC_VBLANK_INT (1 << 2) 417145132Sanholt# define MACH64_CRTC_VLINE_INT_EN (1 << 3) 418145132Sanholt# define MACH64_CRTC_VLINE_INT (1 << 4) 419145132Sanholt# define MACH64_CRTC_VLINE_SYNC (1 << 5) /* 0=even, 1=odd */ 420145132Sanholt# define MACH64_CRTC_FRAME (1 << 6) /* 0=even, 1=odd */ 421145132Sanholt# define MACH64_CRTC_SNAPSHOT_INT_EN (1 << 7) 422145132Sanholt# define MACH64_CRTC_SNAPSHOT_INT (1 << 8) 423145132Sanholt# define MACH64_CRTC_I2C_INT_EN (1 << 9) 424145132Sanholt# define MACH64_CRTC_I2C_INT (1 << 10) 425145132Sanholt# define MACH64_CRTC2_VBLANK (1 << 11) /* LT Pro */ 426145132Sanholt# define MACH64_CRTC2_VBLANK_INT_EN (1 << 12) /* LT Pro */ 427145132Sanholt# define MACH64_CRTC2_VBLANK_INT (1 << 13) /* LT Pro */ 428145132Sanholt# define MACH64_CRTC2_VLINE_INT_EN (1 << 14) /* LT Pro */ 429145132Sanholt# define MACH64_CRTC2_VLINE_INT (1 << 15) /* LT Pro */ 430145132Sanholt# define MACH64_CRTC_CAPBUF0_INT_EN (1 << 16) 431145132Sanholt# define MACH64_CRTC_CAPBUF0_INT (1 << 17) 432145132Sanholt# define MACH64_CRTC_CAPBUF1_INT_EN (1 << 18) 433145132Sanholt# define MACH64_CRTC_CAPBUF1_INT (1 << 19) 434145132Sanholt# define MACH64_CRTC_OVERLAY_EOF_INT_EN (1 << 20) 435145132Sanholt# define MACH64_CRTC_OVERLAY_EOF_INT (1 << 21) 436145132Sanholt# define MACH64_CRTC_ONESHOT_CAP_INT_EN (1 << 22) 437145132Sanholt# define MACH64_CRTC_ONESHOT_CAP_INT (1 << 23) 438145132Sanholt# define MACH64_CRTC_BUSMASTER_EOL_INT_EN (1 << 24) 439145132Sanholt# define MACH64_CRTC_BUSMASTER_EOL_INT (1 << 25) 440145132Sanholt# define MACH64_CRTC_GP_INT_EN (1 << 26) 441145132Sanholt# define MACH64_CRTC_GP_INT (1 << 27) 442145132Sanholt# define MACH64_CRTC2_VLINE_SYNC (1 << 28) /* LT Pro */ /* 0=even, 1=odd */ 443145132Sanholt# define MACH64_CRTC_SNAPSHOT2_INT_EN (1 << 29) /* LT Pro */ 444145132Sanholt# define MACH64_CRTC_SNAPSHOT2_INT (1 << 30) /* LT Pro */ 445145132Sanholt# define MACH64_CRTC_VBLANK2_INT (1 << 31) 446145132Sanholt# define MACH64_CRTC_INT_ENS \ 447145132Sanholt ( \ 448145132Sanholt MACH64_CRTC_VBLANK_INT_EN | \ 449145132Sanholt MACH64_CRTC_VLINE_INT_EN | \ 450145132Sanholt MACH64_CRTC_SNAPSHOT_INT_EN | \ 451145132Sanholt MACH64_CRTC_I2C_INT_EN | \ 452145132Sanholt MACH64_CRTC2_VBLANK_INT_EN | \ 453145132Sanholt MACH64_CRTC2_VLINE_INT_EN | \ 454145132Sanholt MACH64_CRTC_CAPBUF0_INT_EN | \ 455145132Sanholt MACH64_CRTC_CAPBUF1_INT_EN | \ 456145132Sanholt MACH64_CRTC_OVERLAY_EOF_INT_EN | \ 457145132Sanholt MACH64_CRTC_ONESHOT_CAP_INT_EN | \ 458145132Sanholt MACH64_CRTC_BUSMASTER_EOL_INT_EN | \ 459145132Sanholt MACH64_CRTC_GP_INT_EN | \ 460145132Sanholt MACH64_CRTC_SNAPSHOT2_INT_EN | \ 461145132Sanholt 0 \ 462145132Sanholt ) 463145132Sanholt# define MACH64_CRTC_INT_ACKS \ 464145132Sanholt ( \ 465145132Sanholt MACH64_CRTC_VBLANK_INT | \ 466145132Sanholt MACH64_CRTC_VLINE_INT | \ 467145132Sanholt MACH64_CRTC_SNAPSHOT_INT | \ 468145132Sanholt MACH64_CRTC_I2C_INT | \ 469145132Sanholt MACH64_CRTC2_VBLANK_INT | \ 470145132Sanholt MACH64_CRTC2_VLINE_INT | \ 471145132Sanholt MACH64_CRTC_CAPBUF0_INT | \ 472145132Sanholt MACH64_CRTC_CAPBUF1_INT | \ 473145132Sanholt MACH64_CRTC_OVERLAY_EOF_INT | \ 474145132Sanholt MACH64_CRTC_ONESHOT_CAP_INT | \ 475145132Sanholt MACH64_CRTC_BUSMASTER_EOL_INT | \ 476145132Sanholt MACH64_CRTC_GP_INT | \ 477145132Sanholt MACH64_CRTC_SNAPSHOT2_INT | \ 478145132Sanholt MACH64_CRTC_VBLANK2_INT | \ 479145132Sanholt 0 \ 480145132Sanholt ) 481145132Sanholt 482145132Sanholt#define MACH64_DATATYPE_CI8 2 483145132Sanholt#define MACH64_DATATYPE_ARGB1555 3 484145132Sanholt#define MACH64_DATATYPE_RGB565 4 485145132Sanholt#define MACH64_DATATYPE_ARGB8888 6 486145132Sanholt#define MACH64_DATATYPE_RGB332 7 487145132Sanholt#define MACH64_DATATYPE_Y8 8 488145132Sanholt#define MACH64_DATATYPE_RGB8 9 489145132Sanholt#define MACH64_DATATYPE_VYUY422 11 490145132Sanholt#define MACH64_DATATYPE_YVYU422 12 491145132Sanholt#define MACH64_DATATYPE_AYUV444 14 492145132Sanholt#define MACH64_DATATYPE_ARGB4444 15 493145132Sanholt 494145132Sanholt#define MACH64_READ(reg) DRM_READ32(dev_priv->mmio, (reg) ) 495145132Sanholt#define MACH64_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio, (reg), (val) ) 496145132Sanholt 497145132Sanholt#define DWMREG0 0x0400 498145132Sanholt#define DWMREG0_END 0x07ff 499145132Sanholt#define DWMREG1 0x0000 500145132Sanholt#define DWMREG1_END 0x03ff 501145132Sanholt 502145132Sanholt#define ISREG0(r) (((r) >= DWMREG0) && ((r) <= DWMREG0_END)) 503145132Sanholt#define DMAREG0(r) (((r) - DWMREG0) >> 2) 504145132Sanholt#define DMAREG1(r) ((((r) - DWMREG1) >> 2 ) | 0x0100) 505145132Sanholt#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) 506145132Sanholt 507145132Sanholt#define MMREG0 0x0000 508145132Sanholt#define MMREG0_END 0x00ff 509145132Sanholt 510145132Sanholt#define ISMMREG0(r) (((r) >= MMREG0) && ((r) <= MMREG0_END)) 511145132Sanholt#define MMSELECT0(r) (((r) << 2) + DWMREG0) 512145132Sanholt#define MMSELECT1(r) (((((r) & 0xff) << 2) + DWMREG1)) 513145132Sanholt#define MMSELECT(r) (ISMMREG0(r) ? MMSELECT0(r) : MMSELECT1(r)) 514145132Sanholt 515145132Sanholt/* ================================================================ 516145132Sanholt * DMA constants 517145132Sanholt */ 518145132Sanholt 519145132Sanholt/* DMA descriptor field indices: 520145132Sanholt * The descriptor fields are loaded into the read-only 521145132Sanholt * BM_* system bus master registers during a bus-master operation 522145132Sanholt */ 523145132Sanholt#define MACH64_DMA_FRAME_BUF_OFFSET 0 /* BM_FRAME_BUF_OFFSET */ 524145132Sanholt#define MACH64_DMA_SYS_MEM_ADDR 1 /* BM_SYSTEM_MEM_ADDR */ 525145132Sanholt#define MACH64_DMA_COMMAND 2 /* BM_COMMAND */ 526145132Sanholt#define MACH64_DMA_RESERVED 3 /* BM_STATUS */ 527145132Sanholt 528145132Sanholt/* BM_COMMAND descriptor field flags */ 529145132Sanholt#define MACH64_DMA_HOLD_OFFSET (1<<30) /* Don't increment DMA_FRAME_BUF_OFFSET */ 530145132Sanholt#define MACH64_DMA_EOL (1<<31) /* End of descriptor list flag */ 531145132Sanholt 532145132Sanholt#define MACH64_DMA_CHUNKSIZE 0x1000 /* 4kB per DMA descriptor */ 533145132Sanholt#define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */ 534145132Sanholt 535145132Sanholt/* ================================================================ 536182080Srnoland * Ring operations 537182080Srnoland * 538182080Srnoland * Since the Mach64 bus master engine requires polling, these functions end 539182080Srnoland * up being called frequently, hence being inline. 540145132Sanholt */ 541145132Sanholt 542145132Sanholtstatic __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv) 543145132Sanholt{ 544145132Sanholt drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; 545145132Sanholt 546182080Srnoland DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", 547145132Sanholt ring->head_addr, ring->head, ring->tail, ring->space); 548145132Sanholt 549145132Sanholt if (mach64_do_wait_for_idle(dev_priv) < 0) { 550145132Sanholt mach64_do_engine_reset(dev_priv); 551145132Sanholt } 552145132Sanholt 553145132Sanholt if (dev_priv->driver_mode != MACH64_MODE_MMIO) { 554145132Sanholt /* enable bus mastering and block 1 registers */ 555145132Sanholt MACH64_WRITE(MACH64_BUS_CNTL, 556145132Sanholt (MACH64_READ(MACH64_BUS_CNTL) & 557145132Sanholt ~MACH64_BUS_MASTER_DIS) 558145132Sanholt | MACH64_BUS_EXT_REG_EN); 559145132Sanholt mach64_do_wait_for_idle(dev_priv); 560145132Sanholt } 561145132Sanholt 562145132Sanholt /* reset descriptor table ring head */ 563145132Sanholt MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, 564145132Sanholt ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); 565145132Sanholt 566145132Sanholt dev_priv->ring_running = 1; 567145132Sanholt} 568145132Sanholt 569145132Sanholtstatic __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv, 570145132Sanholt drm_mach64_descriptor_ring_t * ring) 571145132Sanholt{ 572182080Srnoland DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", 573145132Sanholt ring->head_addr, ring->head, ring->tail, ring->space); 574145132Sanholt 575145132Sanholt /* reset descriptor table ring head */ 576145132Sanholt MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, 577145132Sanholt ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); 578145132Sanholt 579145132Sanholt if (dev_priv->driver_mode == MACH64_MODE_MMIO) { 580145132Sanholt mach64_do_dispatch_pseudo_dma(dev_priv); 581145132Sanholt } else { 582145132Sanholt /* enable GUI bus mastering, and sync the bus master to the GUI */ 583145132Sanholt MACH64_WRITE(MACH64_SRC_CNTL, 584145132Sanholt MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC | 585145132Sanholt MACH64_SRC_BM_OP_SYSTEM_TO_REG); 586145132Sanholt 587145132Sanholt /* kick off the transfer */ 588145132Sanholt MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0); 589145132Sanholt if (dev_priv->driver_mode == MACH64_MODE_DMA_SYNC) { 590145132Sanholt if ((mach64_do_wait_for_idle(dev_priv)) < 0) { 591182080Srnoland DRM_ERROR("idle failed, resetting engine\n"); 592145132Sanholt mach64_dump_engine_info(dev_priv); 593145132Sanholt mach64_do_engine_reset(dev_priv); 594145132Sanholt return; 595145132Sanholt } 596145132Sanholt mach64_do_release_used_buffers(dev_priv); 597145132Sanholt } 598145132Sanholt } 599145132Sanholt} 600145132Sanholt 601182080Srnoland/** 602182080Srnoland * Poll the ring head and make sure the bus master is alive. 603182080Srnoland * 604182080Srnoland * Mach64's bus master engine will stop if there are no more entries to process. 605182080Srnoland * This function polls the engine for the last processed entry and calls 606182080Srnoland * mach64_ring_resume if there is an unprocessed entry. 607182080Srnoland * 608182080Srnoland * Note also that, since we update the ring tail while the bus master engine is 609182080Srnoland * in operation, it is possible that the last tail update was too late to be 610182080Srnoland * processed, and the bus master engine stops at the previous tail position. 611182080Srnoland * Therefore it is important to call this function frequently. 612182080Srnoland */ 613145132Sanholtstatic __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv, 614145132Sanholt drm_mach64_descriptor_ring_t * ring) 615145132Sanholt{ 616182080Srnoland DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", 617145132Sanholt ring->head_addr, ring->head, ring->tail, ring->space); 618145132Sanholt 619145132Sanholt if (!dev_priv->ring_running) { 620145132Sanholt mach64_ring_start(dev_priv); 621145132Sanholt 622145132Sanholt if (ring->head != ring->tail) { 623145132Sanholt mach64_ring_resume(dev_priv, ring); 624145132Sanholt } 625145132Sanholt } else { 626145132Sanholt /* GUI_ACTIVE must be read before BM_GUI_TABLE to 627145132Sanholt * correctly determine the ring head 628145132Sanholt */ 629145132Sanholt int gui_active = 630145132Sanholt MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE; 631145132Sanholt 632145132Sanholt ring->head_addr = MACH64_READ(MACH64_BM_GUI_TABLE) & 0xfffffff0; 633145132Sanholt 634145132Sanholt if (gui_active) { 635145132Sanholt /* If not idle, BM_GUI_TABLE points one descriptor 636145132Sanholt * past the current head 637145132Sanholt */ 638145132Sanholt if (ring->head_addr == ring->start_addr) { 639145132Sanholt ring->head_addr += ring->size; 640145132Sanholt } 641145132Sanholt ring->head_addr -= 4 * sizeof(u32); 642145132Sanholt } 643145132Sanholt 644145132Sanholt if (ring->head_addr < ring->start_addr || 645145132Sanholt ring->head_addr >= ring->start_addr + ring->size) { 646145132Sanholt DRM_ERROR("bad ring head address: 0x%08x\n", 647145132Sanholt ring->head_addr); 648145132Sanholt mach64_dump_ring_info(dev_priv); 649145132Sanholt mach64_do_engine_reset(dev_priv); 650145132Sanholt return; 651145132Sanholt } 652145132Sanholt 653145132Sanholt ring->head = (ring->head_addr - ring->start_addr) / sizeof(u32); 654145132Sanholt 655145132Sanholt if (!gui_active && ring->head != ring->tail) { 656145132Sanholt mach64_ring_resume(dev_priv, ring); 657145132Sanholt } 658145132Sanholt } 659145132Sanholt} 660145132Sanholt 661145132Sanholtstatic __inline__ void mach64_ring_stop(drm_mach64_private_t * dev_priv) 662145132Sanholt{ 663182080Srnoland DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", 664145132Sanholt dev_priv->ring.head_addr, dev_priv->ring.head, 665145132Sanholt dev_priv->ring.tail, dev_priv->ring.space); 666145132Sanholt 667145132Sanholt /* restore previous SRC_CNTL to disable busmastering */ 668145132Sanholt mach64_do_wait_for_fifo(dev_priv, 1); 669145132Sanholt MACH64_WRITE(MACH64_SRC_CNTL, 0); 670145132Sanholt 671145132Sanholt /* disable busmastering but keep the block 1 registers enabled */ 672145132Sanholt mach64_do_wait_for_idle(dev_priv); 673145132Sanholt MACH64_WRITE(MACH64_BUS_CNTL, MACH64_READ(MACH64_BUS_CNTL) 674145132Sanholt | MACH64_BUS_MASTER_DIS | MACH64_BUS_EXT_REG_EN); 675145132Sanholt 676145132Sanholt dev_priv->ring_running = 0; 677145132Sanholt} 678145132Sanholt 679145132Sanholtstatic __inline__ void 680145132Sanholtmach64_update_ring_snapshot(drm_mach64_private_t * dev_priv) 681145132Sanholt{ 682145132Sanholt drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; 683145132Sanholt 684182080Srnoland DRM_DEBUG("\n"); 685145132Sanholt 686145132Sanholt mach64_ring_tick(dev_priv, ring); 687145132Sanholt 688145132Sanholt ring->space = (ring->head - ring->tail) * sizeof(u32); 689145132Sanholt if (ring->space <= 0) { 690145132Sanholt ring->space += ring->size; 691145132Sanholt } 692145132Sanholt} 693145132Sanholt 694145132Sanholt/* ================================================================ 695145132Sanholt * DMA macros 696182080Srnoland * 697182080Srnoland * Mach64's ring buffer doesn't take register writes directly. These 698182080Srnoland * have to be written indirectly in DMA buffers. These macros simplify 699182080Srnoland * the task of setting up a buffer, writing commands to it, and 700182080Srnoland * queuing the buffer in the ring. 701145132Sanholt */ 702145132Sanholt 703145132Sanholt#define DMALOCALS \ 704145132Sanholt drm_mach64_freelist_t *_entry = NULL; \ 705182080Srnoland struct drm_buf *_buf = NULL; \ 706145132Sanholt u32 *_buf_wptr; int _outcount 707145132Sanholt 708145132Sanholt#define GETBUFPTR( __buf ) \ 709182080Srnoland((dev_priv->is_pci) ? \ 710182080Srnoland ((u32 *)(__buf)->address) : \ 711145132Sanholt ((u32 *)((char *)dev_priv->dev_buffers->handle + (__buf)->offset))) 712145132Sanholt 713145132Sanholt#define GETBUFADDR( __buf ) ((u32)(__buf)->bus_address) 714145132Sanholt 715145132Sanholt#define GETRINGOFFSET() (_entry->ring_ofs) 716145132Sanholt 717145132Sanholtstatic __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t * 718145132Sanholt dev_priv, 719145132Sanholt drm_mach64_freelist_t ** 720182080Srnoland entry, struct drm_buf * buf) 721145132Sanholt{ 722145132Sanholt struct list_head *ptr; 723145132Sanholt#if MACH64_EXTRA_CHECKING 724145132Sanholt if (list_empty(&dev_priv->pending)) { 725182080Srnoland DRM_ERROR("Empty pending list in \n"); 726182080Srnoland return -EINVAL; 727145132Sanholt } 728145132Sanholt#endif 729145132Sanholt ptr = dev_priv->pending.prev; 730145132Sanholt *entry = list_entry(ptr, drm_mach64_freelist_t, list); 731145132Sanholt while ((*entry)->buf != buf) { 732145132Sanholt if (ptr == &dev_priv->pending) { 733182080Srnoland return -EFAULT; 734145132Sanholt } 735145132Sanholt ptr = ptr->prev; 736145132Sanholt *entry = list_entry(ptr, drm_mach64_freelist_t, list); 737145132Sanholt } 738145132Sanholt return 0; 739145132Sanholt} 740145132Sanholt 741182080Srnoland#define DMASETPTR( _p ) \ 742145132Sanholtdo { \ 743145132Sanholt _buf = (_p); \ 744145132Sanholt _outcount = 0; \ 745145132Sanholt _buf_wptr = GETBUFPTR( _buf ); \ 746145132Sanholt} while(0) 747145132Sanholt 748145132Sanholt/* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */ 749182080Srnoland#define DMAGETPTR( file_priv, dev_priv, n ) \ 750145132Sanholtdo { \ 751145132Sanholt if ( MACH64_VERBOSE ) { \ 752182080Srnoland DRM_INFO( "DMAGETPTR( %d )\n", (n) ); \ 753145132Sanholt } \ 754145132Sanholt _buf = mach64_freelist_get( dev_priv ); \ 755145132Sanholt if (_buf == NULL) { \ 756182080Srnoland DRM_ERROR("couldn't get buffer in DMAGETPTR\n"); \ 757182080Srnoland return -EAGAIN; \ 758145132Sanholt } \ 759145132Sanholt if (_buf->pending) { \ 760182080Srnoland DRM_ERROR("pending buf in DMAGETPTR\n"); \ 761182080Srnoland return -EFAULT; \ 762145132Sanholt } \ 763182080Srnoland _buf->file_priv = file_priv; \ 764145132Sanholt _outcount = 0; \ 765145132Sanholt \ 766145132Sanholt _buf_wptr = GETBUFPTR( _buf ); \ 767145132Sanholt} while (0) 768145132Sanholt 769145132Sanholt#define DMAOUTREG( reg, val ) \ 770145132Sanholtdo { \ 771145132Sanholt if ( MACH64_VERBOSE ) { \ 772145132Sanholt DRM_INFO( " DMAOUTREG( 0x%x = 0x%08x )\n", \ 773145132Sanholt reg, val ); \ 774145132Sanholt } \ 775145132Sanholt _buf_wptr[_outcount++] = cpu_to_le32(DMAREG(reg)); \ 776145132Sanholt _buf_wptr[_outcount++] = cpu_to_le32((val)); \ 777145132Sanholt _buf->used += 8; \ 778145132Sanholt} while (0) 779145132Sanholt 780182080Srnoland#define DMAADVANCE( dev_priv, _discard ) \ 781182080Srnoland do { \ 782182080Srnoland struct list_head *ptr; \ 783182080Srnoland int ret; \ 784182080Srnoland \ 785182080Srnoland if ( MACH64_VERBOSE ) { \ 786182080Srnoland DRM_INFO( "DMAADVANCE() in \n" ); \ 787182080Srnoland } \ 788182080Srnoland \ 789182080Srnoland if (_buf->used <= 0) { \ 790182080Srnoland DRM_ERROR( "DMAADVANCE(): sending empty buf %d\n", \ 791182080Srnoland _buf->idx ); \ 792182080Srnoland return -EFAULT; \ 793182080Srnoland } \ 794182080Srnoland if (_buf->pending) { \ 795182080Srnoland /* This is a resued buffer, so we need to find it in the pending list */ \ 796182080Srnoland if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \ 797182080Srnoland DRM_ERROR( "DMAADVANCE(): couldn't find pending buf %d\n", _buf->idx ); \ 798182080Srnoland return ret; \ 799182080Srnoland } \ 800182080Srnoland if (_entry->discard) { \ 801182080Srnoland DRM_ERROR( "DMAADVANCE(): sending discarded pending buf %d\n", _buf->idx ); \ 802182080Srnoland return -EFAULT; \ 803182080Srnoland } \ 804182080Srnoland } else { \ 805182080Srnoland if (list_empty(&dev_priv->placeholders)) { \ 806182080Srnoland DRM_ERROR( "DMAADVANCE(): empty placeholder list\n"); \ 807182080Srnoland return -EFAULT; \ 808182080Srnoland } \ 809182080Srnoland ptr = dev_priv->placeholders.next; \ 810182080Srnoland list_del(ptr); \ 811182080Srnoland _entry = list_entry(ptr, drm_mach64_freelist_t, list); \ 812182080Srnoland _buf->pending = 1; \ 813182080Srnoland _entry->buf = _buf; \ 814182080Srnoland list_add_tail(ptr, &dev_priv->pending); \ 815182080Srnoland } \ 816182080Srnoland _entry->discard = (_discard); \ 817182080Srnoland if ((ret = mach64_add_buf_to_ring( dev_priv, _entry ))) \ 818182080Srnoland return ret; \ 819182080Srnoland } while (0) 820145132Sanholt 821182080Srnoland#define DMADISCARDBUF() \ 822182080Srnoland do { \ 823182080Srnoland if (_entry == NULL) { \ 824182080Srnoland int ret; \ 825182080Srnoland if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \ 826182080Srnoland DRM_ERROR( "couldn't find pending buf %d\n", \ 827182080Srnoland _buf->idx ); \ 828182080Srnoland return ret; \ 829182080Srnoland } \ 830182080Srnoland } \ 831182080Srnoland _entry->discard = 1; \ 832182080Srnoland } while(0) 833145132Sanholt 834182080Srnoland#define DMAADVANCEHOSTDATA( dev_priv ) \ 835182080Srnoland do { \ 836182080Srnoland struct list_head *ptr; \ 837182080Srnoland int ret; \ 838182080Srnoland \ 839182080Srnoland if ( MACH64_VERBOSE ) { \ 840182080Srnoland DRM_INFO( "DMAADVANCEHOSTDATA() in \n" ); \ 841182080Srnoland } \ 842182080Srnoland \ 843182080Srnoland if (_buf->used <= 0) { \ 844182080Srnoland DRM_ERROR( "DMAADVANCEHOSTDATA(): sending empty buf %d\n", _buf->idx ); \ 845182080Srnoland return -EFAULT; \ 846182080Srnoland } \ 847182080Srnoland if (list_empty(&dev_priv->placeholders)) { \ 848182080Srnoland DRM_ERROR( "empty placeholder list in DMAADVANCEHOSTDATA()\n" ); \ 849182080Srnoland return -EFAULT; \ 850182080Srnoland } \ 851182080Srnoland \ 852182080Srnoland ptr = dev_priv->placeholders.next; \ 853182080Srnoland list_del(ptr); \ 854182080Srnoland _entry = list_entry(ptr, drm_mach64_freelist_t, list); \ 855182080Srnoland _entry->buf = _buf; \ 856182080Srnoland _entry->buf->pending = 1; \ 857182080Srnoland list_add_tail(ptr, &dev_priv->pending); \ 858182080Srnoland _entry->discard = 1; \ 859182080Srnoland if ((ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry ))) \ 860182080Srnoland return ret; \ 861182080Srnoland } while (0) 862145132Sanholt 863145132Sanholt#endif /* __MACH64_DRV_H__ */ 864