Merge commit 'crater/master'
[dragonfly.git] / sys / dev / drm / mach64_drv.h
blobe3d9cf000a218ca30be020b6f51ca8e7de453650
1 /* mach64_drv.h -- Private header for mach64 driver -*- linux-c -*-
2 * Created: Fri Nov 24 22:07:58 2000 by gareth@valinux.com
3 */
4 /*-
5 * Copyright 2000 Gareth Hughes
6 * Copyright 2002 Frank C. Earl
7 * Copyright 2002-2003 Leif Delgass
8 * All Rights Reserved.
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice (including the next
18 * paragraph) shall be included in all copies or substantial portions of the
19 * Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Authors:
29 * Gareth Hughes <gareth@valinux.com>
30 * Frank C. Earl <fearl@airmail.net>
31 * Leif Delgass <ldelgass@retinalburn.net>
32 * José Fonseca <j_r_fonseca@yahoo.co.uk>
35 #ifndef __MACH64_DRV_H__
36 #define __MACH64_DRV_H__
38 /* General customization:
41 #define DRIVER_AUTHOR "Gareth Hughes, Leif Delgass, José Fonseca"
43 #define DRIVER_NAME "mach64"
44 #define DRIVER_DESC "DRM module for the ATI Rage Pro"
45 #define DRIVER_DATE "20060718"
47 #define DRIVER_MAJOR 2
48 #define DRIVER_MINOR 0
49 #define DRIVER_PATCHLEVEL 0
51 /* FIXME: remove these when not needed */
52 /* Development driver options */
53 #define MACH64_EXTRA_CHECKING 0 /* Extra sanity checks for DMA/freelist management */
54 #define MACH64_VERBOSE 0 /* Verbose debugging output */
56 typedef struct drm_mach64_freelist {
57 struct list_head list; /* List pointers for free_list, placeholders, or pending list */
58 struct drm_buf *buf; /* Pointer to the buffer */
59 int discard; /* This flag is set when we're done (re)using a buffer */
60 u32 ring_ofs; /* dword offset in ring of last descriptor for this buffer */
61 } drm_mach64_freelist_t;
63 typedef struct drm_mach64_descriptor_ring {
64 void *start; /* write pointer (cpu address) to start of descriptor ring */
65 u32 start_addr; /* bus address of beginning of descriptor ring */
66 int size; /* size of ring in bytes */
68 u32 head_addr; /* bus address of descriptor ring head */
69 u32 head; /* dword offset of descriptor ring head */
70 u32 tail; /* dword offset of descriptor ring tail */
71 u32 tail_mask; /* mask used to wrap ring */
72 int space; /* number of free bytes in ring */
73 } drm_mach64_descriptor_ring_t;
75 typedef struct drm_mach64_private {
76 drm_mach64_sarea_t *sarea_priv;
78 int is_pci;
79 drm_mach64_dma_mode_t driver_mode; /* Async DMA, sync DMA, or MMIO */
81 int usec_timeout; /* Timeout for the wait functions */
83 drm_mach64_descriptor_ring_t ring; /* DMA descriptor table (ring buffer) */
84 int ring_running; /* Is bus mastering is enabled */
86 struct list_head free_list; /* Free-list head */
87 struct list_head placeholders; /* Placeholder list for buffers held by clients */
88 struct list_head pending; /* Buffers pending completion */
90 u32 frame_ofs[MACH64_MAX_QUEUED_FRAMES]; /* dword ring offsets of most recent frame swaps */
92 unsigned int fb_bpp;
93 unsigned int front_offset, front_pitch;
94 unsigned int back_offset, back_pitch;
96 unsigned int depth_bpp;
97 unsigned int depth_offset, depth_pitch;
99 atomic_t vbl_received; /**< Number of vblanks received. */
101 u32 front_offset_pitch;
102 u32 back_offset_pitch;
103 u32 depth_offset_pitch;
105 drm_local_map_t *sarea;
106 drm_local_map_t *fb;
107 drm_local_map_t *mmio;
108 drm_local_map_t *ring_map;
109 drm_local_map_t *dev_buffers; /* this is a pointer to a structure in dev */
110 drm_local_map_t *agp_textures;
111 } drm_mach64_private_t;
113 extern struct drm_ioctl_desc mach64_ioctls[];
114 extern int mach64_max_ioctl;
116 /* mach64_dma.c */
117 extern int mach64_dma_init(struct drm_device *dev, void *data,
118 struct drm_file *file_priv);
119 extern int mach64_dma_idle(struct drm_device *dev, void *data,
120 struct drm_file *file_priv);
121 extern int mach64_dma_flush(struct drm_device *dev, void *data,
122 struct drm_file *file_priv);
123 extern int mach64_engine_reset(struct drm_device *dev, void *data,
124 struct drm_file *file_priv);
125 extern int mach64_dma_buffers(struct drm_device *dev, void *data,
126 struct drm_file *file_priv);
127 extern void mach64_driver_lastclose(struct drm_device * dev);
129 extern int mach64_init_freelist(struct drm_device * dev);
130 extern void mach64_destroy_freelist(struct drm_device * dev);
131 extern struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv);
132 extern int mach64_freelist_put(drm_mach64_private_t * dev_priv,
133 struct drm_buf * copy_buf);
135 extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv,
136 int entries);
137 extern int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv);
138 extern int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n);
139 extern int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv);
140 extern int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv);
141 extern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv);
142 extern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv);
143 extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv);
145 extern int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv,
146 drm_mach64_freelist_t *_entry);
147 extern int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv,
148 drm_mach64_freelist_t *_entry);
150 extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv);
151 extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv);
152 extern int mach64_do_cleanup_dma(struct drm_device * dev);
154 /* mach64_state.c */
155 extern int mach64_dma_clear(struct drm_device *dev, void *data,
156 struct drm_file *file_priv);
157 extern int mach64_dma_swap(struct drm_device *dev, void *data,
158 struct drm_file *file_priv);
159 extern int mach64_dma_vertex(struct drm_device *dev, void *data,
160 struct drm_file *file_priv);
161 extern int mach64_dma_blit(struct drm_device *dev, void *data,
162 struct drm_file *file_priv);
163 extern int mach64_get_param(struct drm_device *dev, void *data,
164 struct drm_file *file_priv);
166 extern int mach64_driver_load(struct drm_device * dev, unsigned long flags);
167 extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc);
168 extern int mach64_enable_vblank(struct drm_device *dev, int crtc);
169 extern void mach64_disable_vblank(struct drm_device *dev, int crtc);
170 extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS);
171 extern void mach64_driver_irq_preinstall(struct drm_device *dev);
172 extern int mach64_driver_irq_postinstall(struct drm_device *dev);
173 extern void mach64_driver_irq_uninstall(struct drm_device *dev);
175 /* ================================================================
176 * Registers
179 #define MACH64_AGP_BASE 0x0148
180 #define MACH64_AGP_CNTL 0x014c
181 #define MACH64_ALPHA_TST_CNTL 0x0550
183 #define MACH64_DSP_CONFIG 0x0420
184 #define MACH64_DSP_ON_OFF 0x0424
185 #define MACH64_EXT_MEM_CNTL 0x04ac
186 #define MACH64_GEN_TEST_CNTL 0x04d0
187 #define MACH64_HW_DEBUG 0x047c
188 #define MACH64_MEM_ADDR_CONFIG 0x0434
189 #define MACH64_MEM_BUF_CNTL 0x042c
190 #define MACH64_MEM_CNTL 0x04b0
192 #define MACH64_BM_ADDR 0x0648
193 #define MACH64_BM_COMMAND 0x0188
194 #define MACH64_BM_DATA 0x0648
195 #define MACH64_BM_FRAME_BUF_OFFSET 0x0180
196 #define MACH64_BM_GUI_TABLE 0x01b8
197 #define MACH64_BM_GUI_TABLE_CMD 0x064c
198 # define MACH64_CIRCULAR_BUF_SIZE_16KB (0 << 0)
199 # define MACH64_CIRCULAR_BUF_SIZE_32KB (1 << 0)
200 # define MACH64_CIRCULAR_BUF_SIZE_64KB (2 << 0)
201 # define MACH64_CIRCULAR_BUF_SIZE_128KB (3 << 0)
202 # define MACH64_LAST_DESCRIPTOR (1 << 31)
203 #define MACH64_BM_HOSTDATA 0x0644
204 #define MACH64_BM_STATUS 0x018c
205 #define MACH64_BM_SYSTEM_MEM_ADDR 0x0184
206 #define MACH64_BM_SYSTEM_TABLE 0x01bc
207 #define MACH64_BUS_CNTL 0x04a0
208 # define MACH64_BUS_MSTR_RESET (1 << 1)
209 # define MACH64_BUS_APER_REG_DIS (1 << 4)
210 # define MACH64_BUS_FLUSH_BUF (1 << 2)
211 # define MACH64_BUS_MASTER_DIS (1 << 6)
212 # define MACH64_BUS_EXT_REG_EN (1 << 27)
214 #define MACH64_CLR_CMP_CLR 0x0700
215 #define MACH64_CLR_CMP_CNTL 0x0708
216 #define MACH64_CLR_CMP_MASK 0x0704
217 #define MACH64_CONFIG_CHIP_ID 0x04e0
218 #define MACH64_CONFIG_CNTL 0x04dc
219 #define MACH64_CONFIG_STAT0 0x04e4
220 #define MACH64_CONFIG_STAT1 0x0494
221 #define MACH64_CONFIG_STAT2 0x0498
222 #define MACH64_CONTEXT_LOAD_CNTL 0x072c
223 #define MACH64_CONTEXT_MASK 0x0720
224 #define MACH64_COMPOSITE_SHADOW_ID 0x0798
225 #define MACH64_CRC_SIG 0x04e8
226 #define MACH64_CUSTOM_MACRO_CNTL 0x04d4
228 #define MACH64_DP_BKGD_CLR 0x06c0
229 #define MACH64_DP_FOG_CLR 0x06c4
230 #define MACH64_DP_FGRD_BKGD_CLR 0x06e0
231 #define MACH64_DP_FRGD_CLR 0x06c4
232 #define MACH64_DP_FGRD_CLR_MIX 0x06dc
234 #define MACH64_DP_MIX 0x06d4
235 # define BKGD_MIX_NOT_D (0 << 0)
236 # define BKGD_MIX_ZERO (1 << 0)
237 # define BKGD_MIX_ONE (2 << 0)
238 # define MACH64_BKGD_MIX_D (3 << 0)
239 # define BKGD_MIX_NOT_S (4 << 0)
240 # define BKGD_MIX_D_XOR_S (5 << 0)
241 # define BKGD_MIX_NOT_D_XOR_S (6 << 0)
242 # define MACH64_BKGD_MIX_S (7 << 0)
243 # define BKGD_MIX_NOT_D_OR_NOT_S (8 << 0)
244 # define BKGD_MIX_D_OR_NOT_S (9 << 0)
245 # define BKGD_MIX_NOT_D_OR_S (10 << 0)
246 # define BKGD_MIX_D_OR_S (11 << 0)
247 # define BKGD_MIX_D_AND_S (12 << 0)
248 # define BKGD_MIX_NOT_D_AND_S (13 << 0)
249 # define BKGD_MIX_D_AND_NOT_S (14 << 0)
250 # define BKGD_MIX_NOT_D_AND_NOT_S (15 << 0)
251 # define BKGD_MIX_D_PLUS_S_DIV2 (23 << 0)
252 # define FRGD_MIX_NOT_D (0 << 16)
253 # define FRGD_MIX_ZERO (1 << 16)
254 # define FRGD_MIX_ONE (2 << 16)
255 # define FRGD_MIX_D (3 << 16)
256 # define FRGD_MIX_NOT_S (4 << 16)
257 # define FRGD_MIX_D_XOR_S (5 << 16)
258 # define FRGD_MIX_NOT_D_XOR_S (6 << 16)
259 # define MACH64_FRGD_MIX_S (7 << 16)
260 # define FRGD_MIX_NOT_D_OR_NOT_S (8 << 16)
261 # define FRGD_MIX_D_OR_NOT_S (9 << 16)
262 # define FRGD_MIX_NOT_D_OR_S (10 << 16)
263 # define FRGD_MIX_D_OR_S (11 << 16)
264 # define FRGD_MIX_D_AND_S (12 << 16)
265 # define FRGD_MIX_NOT_D_AND_S (13 << 16)
266 # define FRGD_MIX_D_AND_NOT_S (14 << 16)
267 # define FRGD_MIX_NOT_D_AND_NOT_S (15 << 16)
268 # define FRGD_MIX_D_PLUS_S_DIV2 (23 << 16)
270 #define MACH64_DP_PIX_WIDTH 0x06d0
271 # define MACH64_HOST_TRIPLE_ENABLE (1 << 13)
272 # define MACH64_BYTE_ORDER_MSB_TO_LSB (0 << 24)
273 # define MACH64_BYTE_ORDER_LSB_TO_MSB (1 << 24)
275 #define MACH64_DP_SRC 0x06d8
276 # define MACH64_BKGD_SRC_BKGD_CLR (0 << 0)
277 # define MACH64_BKGD_SRC_FRGD_CLR (1 << 0)
278 # define MACH64_BKGD_SRC_HOST (2 << 0)
279 # define MACH64_BKGD_SRC_BLIT (3 << 0)
280 # define MACH64_BKGD_SRC_PATTERN (4 << 0)
281 # define MACH64_BKGD_SRC_3D (5 << 0)
282 # define MACH64_FRGD_SRC_BKGD_CLR (0 << 8)
283 # define MACH64_FRGD_SRC_FRGD_CLR (1 << 8)
284 # define MACH64_FRGD_SRC_HOST (2 << 8)
285 # define MACH64_FRGD_SRC_BLIT (3 << 8)
286 # define MACH64_FRGD_SRC_PATTERN (4 << 8)
287 # define MACH64_FRGD_SRC_3D (5 << 8)
288 # define MACH64_MONO_SRC_ONE (0 << 16)
289 # define MACH64_MONO_SRC_PATTERN (1 << 16)
290 # define MACH64_MONO_SRC_HOST (2 << 16)
291 # define MACH64_MONO_SRC_BLIT (3 << 16)
293 #define MACH64_DP_WRITE_MASK 0x06c8
295 #define MACH64_DST_CNTL 0x0530
296 # define MACH64_DST_X_RIGHT_TO_LEFT (0 << 0)
297 # define MACH64_DST_X_LEFT_TO_RIGHT (1 << 0)
298 # define MACH64_DST_Y_BOTTOM_TO_TOP (0 << 1)
299 # define MACH64_DST_Y_TOP_TO_BOTTOM (1 << 1)
300 # define MACH64_DST_X_MAJOR (0 << 2)
301 # define MACH64_DST_Y_MAJOR (1 << 2)
302 # define MACH64_DST_X_TILE (1 << 3)
303 # define MACH64_DST_Y_TILE (1 << 4)
304 # define MACH64_DST_LAST_PEL (1 << 5)
305 # define MACH64_DST_POLYGON_ENABLE (1 << 6)
306 # define MACH64_DST_24_ROTATION_ENABLE (1 << 7)
308 #define MACH64_DST_HEIGHT_WIDTH 0x0518
309 #define MACH64_DST_OFF_PITCH 0x0500
310 #define MACH64_DST_WIDTH_HEIGHT 0x06ec
311 #define MACH64_DST_X_Y 0x06e8
312 #define MACH64_DST_Y_X 0x050c
314 #define MACH64_FIFO_STAT 0x0710
315 # define MACH64_FIFO_SLOT_MASK 0x0000ffff
316 # define MACH64_FIFO_ERR (1 << 31)
318 #define MACH64_GEN_TEST_CNTL 0x04d0
319 # define MACH64_GUI_ENGINE_ENABLE (1 << 8)
320 #define MACH64_GUI_CMDFIFO_DEBUG 0x0170
321 #define MACH64_GUI_CMDFIFO_DATA 0x0174
322 #define MACH64_GUI_CNTL 0x0178
323 # define MACH64_CMDFIFO_SIZE_MASK 0x00000003ul
324 # define MACH64_CMDFIFO_SIZE_192 0x00000000ul
325 # define MACH64_CMDFIFO_SIZE_128 0x00000001ul
326 # define MACH64_CMDFIFO_SIZE_64 0x00000002ul
327 #define MACH64_GUI_STAT 0x0738
328 # define MACH64_GUI_ACTIVE (1 << 0)
329 #define MACH64_GUI_TRAJ_CNTL 0x0730
331 #define MACH64_HOST_CNTL 0x0640
332 #define MACH64_HOST_DATA0 0x0600
334 #define MACH64_ONE_OVER_AREA 0x029c
335 #define MACH64_ONE_OVER_AREA_UC 0x0300
337 #define MACH64_PAT_REG0 0x0680
338 #define MACH64_PAT_REG1 0x0684
340 #define MACH64_SC_LEFT 0x06a0
341 #define MACH64_SC_RIGHT 0x06a4
342 #define MACH64_SC_LEFT_RIGHT 0x06a8
343 #define MACH64_SC_TOP 0x06ac
344 #define MACH64_SC_BOTTOM 0x06b0
345 #define MACH64_SC_TOP_BOTTOM 0x06b4
347 #define MACH64_SCALE_3D_CNTL 0x05fc
348 #define MACH64_SCRATCH_REG0 0x0480
349 #define MACH64_SCRATCH_REG1 0x0484
350 #define MACH64_SECONDARY_TEX_OFF 0x0778
351 #define MACH64_SETUP_CNTL 0x0304
352 #define MACH64_SRC_CNTL 0x05b4
353 # define MACH64_SRC_BM_ENABLE (1 << 8)
354 # define MACH64_SRC_BM_SYNC (1 << 9)
355 # define MACH64_SRC_BM_OP_FRAME_TO_SYSTEM (0 << 10)
356 # define MACH64_SRC_BM_OP_SYSTEM_TO_FRAME (1 << 10)
357 # define MACH64_SRC_BM_OP_REG_TO_SYSTEM (2 << 10)
358 # define MACH64_SRC_BM_OP_SYSTEM_TO_REG (3 << 10)
359 #define MACH64_SRC_HEIGHT1 0x0594
360 #define MACH64_SRC_HEIGHT2 0x05ac
361 #define MACH64_SRC_HEIGHT1_WIDTH1 0x0598
362 #define MACH64_SRC_HEIGHT2_WIDTH2 0x05b0
363 #define MACH64_SRC_OFF_PITCH 0x0580
364 #define MACH64_SRC_WIDTH1 0x0590
365 #define MACH64_SRC_Y_X 0x058c
367 #define MACH64_TEX_0_OFF 0x05c0
368 #define MACH64_TEX_CNTL 0x0774
369 #define MACH64_TEX_SIZE_PITCH 0x0770
370 #define MACH64_TIMER_CONFIG 0x0428
372 #define MACH64_VERTEX_1_ARGB 0x0254
373 #define MACH64_VERTEX_1_S 0x0240
374 #define MACH64_VERTEX_1_SECONDARY_S 0x0328
375 #define MACH64_VERTEX_1_SECONDARY_T 0x032c
376 #define MACH64_VERTEX_1_SECONDARY_W 0x0330
377 #define MACH64_VERTEX_1_SPEC_ARGB 0x024c
378 #define MACH64_VERTEX_1_T 0x0244
379 #define MACH64_VERTEX_1_W 0x0248
380 #define MACH64_VERTEX_1_X_Y 0x0258
381 #define MACH64_VERTEX_1_Z 0x0250
382 #define MACH64_VERTEX_2_ARGB 0x0274
383 #define MACH64_VERTEX_2_S 0x0260
384 #define MACH64_VERTEX_2_SECONDARY_S 0x0334
385 #define MACH64_VERTEX_2_SECONDARY_T 0x0338
386 #define MACH64_VERTEX_2_SECONDARY_W 0x033c
387 #define MACH64_VERTEX_2_SPEC_ARGB 0x026c
388 #define MACH64_VERTEX_2_T 0x0264
389 #define MACH64_VERTEX_2_W 0x0268
390 #define MACH64_VERTEX_2_X_Y 0x0278
391 #define MACH64_VERTEX_2_Z 0x0270
392 #define MACH64_VERTEX_3_ARGB 0x0294
393 #define MACH64_VERTEX_3_S 0x0280
394 #define MACH64_VERTEX_3_SECONDARY_S 0x02a0
395 #define MACH64_VERTEX_3_SECONDARY_T 0x02a4
396 #define MACH64_VERTEX_3_SECONDARY_W 0x02a8
397 #define MACH64_VERTEX_3_SPEC_ARGB 0x028c
398 #define MACH64_VERTEX_3_T 0x0284
399 #define MACH64_VERTEX_3_W 0x0288
400 #define MACH64_VERTEX_3_X_Y 0x0298
401 #define MACH64_VERTEX_3_Z 0x0290
403 #define MACH64_Z_CNTL 0x054c
404 #define MACH64_Z_OFF_PITCH 0x0548
406 #define MACH64_CRTC_VLINE_CRNT_VLINE 0x0410
407 # define MACH64_CRTC_VLINE_MASK 0x000007ff
408 # define MACH64_CRTC_CRNT_VLINE_MASK 0x07ff0000
409 #define MACH64_CRTC_OFF_PITCH 0x0414
410 #define MACH64_CRTC_INT_CNTL 0x0418
411 # define MACH64_CRTC_VBLANK (1 << 0)
412 # define MACH64_CRTC_VBLANK_INT_EN (1 << 1)
413 # define MACH64_CRTC_VBLANK_INT (1 << 2)
414 # define MACH64_CRTC_VLINE_INT_EN (1 << 3)
415 # define MACH64_CRTC_VLINE_INT (1 << 4)
416 # define MACH64_CRTC_VLINE_SYNC (1 << 5) /* 0=even, 1=odd */
417 # define MACH64_CRTC_FRAME (1 << 6) /* 0=even, 1=odd */
418 # define MACH64_CRTC_SNAPSHOT_INT_EN (1 << 7)
419 # define MACH64_CRTC_SNAPSHOT_INT (1 << 8)
420 # define MACH64_CRTC_I2C_INT_EN (1 << 9)
421 # define MACH64_CRTC_I2C_INT (1 << 10)
422 # define MACH64_CRTC2_VBLANK (1 << 11) /* LT Pro */
423 # define MACH64_CRTC2_VBLANK_INT_EN (1 << 12) /* LT Pro */
424 # define MACH64_CRTC2_VBLANK_INT (1 << 13) /* LT Pro */
425 # define MACH64_CRTC2_VLINE_INT_EN (1 << 14) /* LT Pro */
426 # define MACH64_CRTC2_VLINE_INT (1 << 15) /* LT Pro */
427 # define MACH64_CRTC_CAPBUF0_INT_EN (1 << 16)
428 # define MACH64_CRTC_CAPBUF0_INT (1 << 17)
429 # define MACH64_CRTC_CAPBUF1_INT_EN (1 << 18)
430 # define MACH64_CRTC_CAPBUF1_INT (1 << 19)
431 # define MACH64_CRTC_OVERLAY_EOF_INT_EN (1 << 20)
432 # define MACH64_CRTC_OVERLAY_EOF_INT (1 << 21)
433 # define MACH64_CRTC_ONESHOT_CAP_INT_EN (1 << 22)
434 # define MACH64_CRTC_ONESHOT_CAP_INT (1 << 23)
435 # define MACH64_CRTC_BUSMASTER_EOL_INT_EN (1 << 24)
436 # define MACH64_CRTC_BUSMASTER_EOL_INT (1 << 25)
437 # define MACH64_CRTC_GP_INT_EN (1 << 26)
438 # define MACH64_CRTC_GP_INT (1 << 27)
439 # define MACH64_CRTC2_VLINE_SYNC (1 << 28) /* LT Pro */ /* 0=even, 1=odd */
440 # define MACH64_CRTC_SNAPSHOT2_INT_EN (1 << 29) /* LT Pro */
441 # define MACH64_CRTC_SNAPSHOT2_INT (1 << 30) /* LT Pro */
442 # define MACH64_CRTC_VBLANK2_INT (1 << 31)
443 # define MACH64_CRTC_INT_ENS \
445 MACH64_CRTC_VBLANK_INT_EN | \
446 MACH64_CRTC_VLINE_INT_EN | \
447 MACH64_CRTC_SNAPSHOT_INT_EN | \
448 MACH64_CRTC_I2C_INT_EN | \
449 MACH64_CRTC2_VBLANK_INT_EN | \
450 MACH64_CRTC2_VLINE_INT_EN | \
451 MACH64_CRTC_CAPBUF0_INT_EN | \
452 MACH64_CRTC_CAPBUF1_INT_EN | \
453 MACH64_CRTC_OVERLAY_EOF_INT_EN | \
454 MACH64_CRTC_ONESHOT_CAP_INT_EN | \
455 MACH64_CRTC_BUSMASTER_EOL_INT_EN | \
456 MACH64_CRTC_GP_INT_EN | \
457 MACH64_CRTC_SNAPSHOT2_INT_EN | \
460 # define MACH64_CRTC_INT_ACKS \
462 MACH64_CRTC_VBLANK_INT | \
463 MACH64_CRTC_VLINE_INT | \
464 MACH64_CRTC_SNAPSHOT_INT | \
465 MACH64_CRTC_I2C_INT | \
466 MACH64_CRTC2_VBLANK_INT | \
467 MACH64_CRTC2_VLINE_INT | \
468 MACH64_CRTC_CAPBUF0_INT | \
469 MACH64_CRTC_CAPBUF1_INT | \
470 MACH64_CRTC_OVERLAY_EOF_INT | \
471 MACH64_CRTC_ONESHOT_CAP_INT | \
472 MACH64_CRTC_BUSMASTER_EOL_INT | \
473 MACH64_CRTC_GP_INT | \
474 MACH64_CRTC_SNAPSHOT2_INT | \
475 MACH64_CRTC_VBLANK2_INT | \
479 #define MACH64_DATATYPE_CI8 2
480 #define MACH64_DATATYPE_ARGB1555 3
481 #define MACH64_DATATYPE_RGB565 4
482 #define MACH64_DATATYPE_ARGB8888 6
483 #define MACH64_DATATYPE_RGB332 7
484 #define MACH64_DATATYPE_Y8 8
485 #define MACH64_DATATYPE_RGB8 9
486 #define MACH64_DATATYPE_VYUY422 11
487 #define MACH64_DATATYPE_YVYU422 12
488 #define MACH64_DATATYPE_AYUV444 14
489 #define MACH64_DATATYPE_ARGB4444 15
491 #define MACH64_READ(reg) DRM_READ32(dev_priv->mmio, (reg) )
492 #define MACH64_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio, (reg), (val) )
494 #define DWMREG0 0x0400
495 #define DWMREG0_END 0x07ff
496 #define DWMREG1 0x0000
497 #define DWMREG1_END 0x03ff
499 #define ISREG0(r) (((r) >= DWMREG0) && ((r) <= DWMREG0_END))
500 #define DMAREG0(r) (((r) - DWMREG0) >> 2)
501 #define DMAREG1(r) ((((r) - DWMREG1) >> 2 ) | 0x0100)
502 #define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
504 #define MMREG0 0x0000
505 #define MMREG0_END 0x00ff
507 #define ISMMREG0(r) (((r) >= MMREG0) && ((r) <= MMREG0_END))
508 #define MMSELECT0(r) (((r) << 2) + DWMREG0)
509 #define MMSELECT1(r) (((((r) & 0xff) << 2) + DWMREG1))
510 #define MMSELECT(r) (ISMMREG0(r) ? MMSELECT0(r) : MMSELECT1(r))
512 /* ================================================================
513 * DMA constants
516 /* DMA descriptor field indices:
517 * The descriptor fields are loaded into the read-only
518 * BM_* system bus master registers during a bus-master operation
520 #define MACH64_DMA_FRAME_BUF_OFFSET 0 /* BM_FRAME_BUF_OFFSET */
521 #define MACH64_DMA_SYS_MEM_ADDR 1 /* BM_SYSTEM_MEM_ADDR */
522 #define MACH64_DMA_COMMAND 2 /* BM_COMMAND */
523 #define MACH64_DMA_RESERVED 3 /* BM_STATUS */
525 /* BM_COMMAND descriptor field flags */
526 #define MACH64_DMA_HOLD_OFFSET (1<<30) /* Don't increment DMA_FRAME_BUF_OFFSET */
527 #define MACH64_DMA_EOL (1<<31) /* End of descriptor list flag */
529 #define MACH64_DMA_CHUNKSIZE 0x1000 /* 4kB per DMA descriptor */
530 #define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */
532 /* ================================================================
533 * Ring operations
535 * Since the Mach64 bus master engine requires polling, these functions end
536 * up being called frequently, hence being inline.
539 static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
541 drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
543 DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
544 ring->head_addr, ring->head, ring->tail, ring->space);
546 if (mach64_do_wait_for_idle(dev_priv) < 0) {
547 mach64_do_engine_reset(dev_priv);
550 if (dev_priv->driver_mode != MACH64_MODE_MMIO) {
551 /* enable bus mastering and block 1 registers */
552 MACH64_WRITE(MACH64_BUS_CNTL,
553 (MACH64_READ(MACH64_BUS_CNTL) &
554 ~MACH64_BUS_MASTER_DIS)
555 | MACH64_BUS_EXT_REG_EN);
556 mach64_do_wait_for_idle(dev_priv);
559 /* reset descriptor table ring head */
560 MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
561 ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
563 dev_priv->ring_running = 1;
566 static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
567 drm_mach64_descriptor_ring_t * ring)
569 DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
570 ring->head_addr, ring->head, ring->tail, ring->space);
572 /* reset descriptor table ring head */
573 MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
574 ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
576 if (dev_priv->driver_mode == MACH64_MODE_MMIO) {
577 mach64_do_dispatch_pseudo_dma(dev_priv);
578 } else {
579 /* enable GUI bus mastering, and sync the bus master to the GUI */
580 MACH64_WRITE(MACH64_SRC_CNTL,
581 MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC |
582 MACH64_SRC_BM_OP_SYSTEM_TO_REG);
584 /* kick off the transfer */
585 MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0);
586 if (dev_priv->driver_mode == MACH64_MODE_DMA_SYNC) {
587 if ((mach64_do_wait_for_idle(dev_priv)) < 0) {
588 DRM_ERROR("idle failed, resetting engine\n");
589 mach64_dump_engine_info(dev_priv);
590 mach64_do_engine_reset(dev_priv);
591 return;
593 mach64_do_release_used_buffers(dev_priv);
599 * Poll the ring head and make sure the bus master is alive.
601 * Mach64's bus master engine will stop if there are no more entries to process.
602 * This function polls the engine for the last processed entry and calls
603 * mach64_ring_resume if there is an unprocessed entry.
605 * Note also that, since we update the ring tail while the bus master engine is
606 * in operation, it is possible that the last tail update was too late to be
607 * processed, and the bus master engine stops at the previous tail position.
608 * Therefore it is important to call this function frequently.
610 static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv,
611 drm_mach64_descriptor_ring_t * ring)
613 DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
614 ring->head_addr, ring->head, ring->tail, ring->space);
616 if (!dev_priv->ring_running) {
617 mach64_ring_start(dev_priv);
619 if (ring->head != ring->tail) {
620 mach64_ring_resume(dev_priv, ring);
622 } else {
623 /* GUI_ACTIVE must be read before BM_GUI_TABLE to
624 * correctly determine the ring head
626 int gui_active =
627 MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE;
629 ring->head_addr = MACH64_READ(MACH64_BM_GUI_TABLE) & 0xfffffff0;
631 if (gui_active) {
632 /* If not idle, BM_GUI_TABLE points one descriptor
633 * past the current head
635 if (ring->head_addr == ring->start_addr) {
636 ring->head_addr += ring->size;
638 ring->head_addr -= 4 * sizeof(u32);
641 if (ring->head_addr < ring->start_addr ||
642 ring->head_addr >= ring->start_addr + ring->size) {
643 DRM_ERROR("bad ring head address: 0x%08x\n",
644 ring->head_addr);
645 mach64_dump_ring_info(dev_priv);
646 mach64_do_engine_reset(dev_priv);
647 return;
650 ring->head = (ring->head_addr - ring->start_addr) / sizeof(u32);
652 if (!gui_active && ring->head != ring->tail) {
653 mach64_ring_resume(dev_priv, ring);
658 static __inline__ void mach64_ring_stop(drm_mach64_private_t * dev_priv)
660 DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
661 dev_priv->ring.head_addr, dev_priv->ring.head,
662 dev_priv->ring.tail, dev_priv->ring.space);
664 /* restore previous SRC_CNTL to disable busmastering */
665 mach64_do_wait_for_fifo(dev_priv, 1);
666 MACH64_WRITE(MACH64_SRC_CNTL, 0);
668 /* disable busmastering but keep the block 1 registers enabled */
669 mach64_do_wait_for_idle(dev_priv);
670 MACH64_WRITE(MACH64_BUS_CNTL, MACH64_READ(MACH64_BUS_CNTL)
671 | MACH64_BUS_MASTER_DIS | MACH64_BUS_EXT_REG_EN);
673 dev_priv->ring_running = 0;
676 static __inline__ void
677 mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv)
679 drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
681 DRM_DEBUG("\n");
683 mach64_ring_tick(dev_priv, ring);
685 ring->space = (ring->head - ring->tail) * sizeof(u32);
686 if (ring->space <= 0) {
687 ring->space += ring->size;
691 /* ================================================================
692 * DMA macros
694 * Mach64's ring buffer doesn't take register writes directly. These
695 * have to be written indirectly in DMA buffers. These macros simplify
696 * the task of setting up a buffer, writing commands to it, and
697 * queuing the buffer in the ring.
700 #define DMALOCALS \
701 drm_mach64_freelist_t *_entry = NULL; \
702 struct drm_buf *_buf = NULL; \
703 u32 *_buf_wptr; int _outcount
705 #define GETBUFPTR( __buf ) \
706 ((dev_priv->is_pci) ? \
707 ((u32 *)(__buf)->address) : \
708 ((u32 *)((char *)dev_priv->dev_buffers->handle + (__buf)->offset)))
710 #define GETBUFADDR( __buf ) ((u32)(__buf)->bus_address)
712 #define GETRINGOFFSET() (_entry->ring_ofs)
714 static __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t *
715 dev_priv,
716 drm_mach64_freelist_t **
717 entry, struct drm_buf * buf)
719 struct list_head *ptr;
720 #if MACH64_EXTRA_CHECKING
721 if (list_empty(&dev_priv->pending)) {
722 DRM_ERROR("Empty pending list in \n");
723 return -EINVAL;
725 #endif
726 ptr = dev_priv->pending.prev;
727 *entry = list_entry(ptr, drm_mach64_freelist_t, list);
728 while ((*entry)->buf != buf) {
729 if (ptr == &dev_priv->pending) {
730 return -EFAULT;
732 ptr = ptr->prev;
733 *entry = list_entry(ptr, drm_mach64_freelist_t, list);
735 return 0;
738 #define DMASETPTR( _p ) \
739 do { \
740 _buf = (_p); \
741 _outcount = 0; \
742 _buf_wptr = GETBUFPTR( _buf ); \
743 } while(0)
745 /* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */
746 #define DMAGETPTR( file_priv, dev_priv, n ) \
747 do { \
748 if ( MACH64_VERBOSE ) { \
749 DRM_INFO( "DMAGETPTR( %d )\n", (n) ); \
751 _buf = mach64_freelist_get( dev_priv ); \
752 if (_buf == NULL) { \
753 DRM_ERROR("couldn't get buffer in DMAGETPTR\n"); \
754 return -EAGAIN; \
756 if (_buf->pending) { \
757 DRM_ERROR("pending buf in DMAGETPTR\n"); \
758 return -EFAULT; \
760 _buf->file_priv = file_priv; \
761 _outcount = 0; \
763 _buf_wptr = GETBUFPTR( _buf ); \
764 } while (0)
766 #define DMAOUTREG( reg, val ) \
767 do { \
768 if ( MACH64_VERBOSE ) { \
769 DRM_INFO( " DMAOUTREG( 0x%x = 0x%08x )\n", \
770 reg, val ); \
772 _buf_wptr[_outcount++] = cpu_to_le32(DMAREG(reg)); \
773 _buf_wptr[_outcount++] = cpu_to_le32((val)); \
774 _buf->used += 8; \
775 } while (0)
777 #define DMAADVANCE( dev_priv, _discard ) \
778 do { \
779 struct list_head *ptr; \
780 int ret; \
782 if ( MACH64_VERBOSE ) { \
783 DRM_INFO( "DMAADVANCE() in \n" ); \
786 if (_buf->used <= 0) { \
787 DRM_ERROR( "DMAADVANCE(): sending empty buf %d\n", \
788 _buf->idx ); \
789 return -EFAULT; \
791 if (_buf->pending) { \
792 /* This is a resued buffer, so we need to find it in the pending list */ \
793 if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \
794 DRM_ERROR( "DMAADVANCE(): couldn't find pending buf %d\n", _buf->idx ); \
795 return ret; \
797 if (_entry->discard) { \
798 DRM_ERROR( "DMAADVANCE(): sending discarded pending buf %d\n", _buf->idx ); \
799 return -EFAULT; \
801 } else { \
802 if (list_empty(&dev_priv->placeholders)) { \
803 DRM_ERROR( "DMAADVANCE(): empty placeholder list\n"); \
804 return -EFAULT; \
806 ptr = dev_priv->placeholders.next; \
807 list_del(ptr); \
808 _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
809 _buf->pending = 1; \
810 _entry->buf = _buf; \
811 list_add_tail(ptr, &dev_priv->pending); \
813 _entry->discard = (_discard); \
814 if ((ret = mach64_add_buf_to_ring( dev_priv, _entry ))) \
815 return ret; \
816 } while (0)
818 #define DMADISCARDBUF() \
819 do { \
820 if (_entry == NULL) { \
821 int ret; \
822 if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \
823 DRM_ERROR( "couldn't find pending buf %d\n", \
824 _buf->idx ); \
825 return ret; \
828 _entry->discard = 1; \
829 } while(0)
831 #define DMAADVANCEHOSTDATA( dev_priv ) \
832 do { \
833 struct list_head *ptr; \
834 int ret; \
836 if ( MACH64_VERBOSE ) { \
837 DRM_INFO( "DMAADVANCEHOSTDATA() in \n" ); \
840 if (_buf->used <= 0) { \
841 DRM_ERROR( "DMAADVANCEHOSTDATA(): sending empty buf %d\n", _buf->idx ); \
842 return -EFAULT; \
844 if (list_empty(&dev_priv->placeholders)) { \
845 DRM_ERROR( "empty placeholder list in DMAADVANCEHOSTDATA()\n" ); \
846 return -EFAULT; \
849 ptr = dev_priv->placeholders.next; \
850 list_del(ptr); \
851 _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
852 _entry->buf = _buf; \
853 _entry->buf->pending = 1; \
854 list_add_tail(ptr, &dev_priv->pending); \
855 _entry->discard = 1; \
856 if ((ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry ))) \
857 return ret; \
858 } while (0)
860 #endif /* __MACH64_DRV_H__ */