aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-05-28 20:09:59 -0400
committerDave Airlie <airlied@redhat.com>2008-07-13 20:45:01 -0400
commitc0e09200dc0813972442e550a5905a132768e56c (patch)
treed38e635a30ff8b0a2b98b9d7f97cab1501f8209e /drivers/gpu/drm/radeon
parentbce7f793daec3e65ec5c5705d2457b81fe7b5725 (diff)
drm: reorganise drm tree to be more future proof.
With the coming of kernel based modesetting and the memory manager stuff, the everything in one directory approach was getting very ugly and starting to be unmanageable. This restructures the drm along the lines of other kernel components. It creates a drivers/gpu/drm directory and moves the hw drivers into subdirectores. It moves the includes into an include/drm, and sets up the unifdef for the userspace headers we should be exporting. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/Makefile10
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c1071
-rw-r--r--drivers/gpu/drm/radeon/r300_reg.h1772
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c1773
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c126
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h1406
-rw-r--r--drivers/gpu/drm/radeon/radeon_ioc32.c424
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c320
-rw-r--r--drivers/gpu/drm/radeon/radeon_mem.c302
-rw-r--r--drivers/gpu/drm/radeon/radeon_microcode.h1844
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c3203
11 files changed, 12251 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
new file mode 100644
index 000000000000..feb521ebc393
--- /dev/null
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for the drm device driver. This driver provides support for the
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4
5ccflags-y := -Iinclude/drm
6radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
7
8radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
9
10obj-$(CONFIG_DRM_RADEON)+= radeon.o
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
new file mode 100644
index 000000000000..702df45320f7
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -0,0 +1,1071 @@
1/* r300_cmdbuf.c -- Command buffer emission for R300 -*- linux-c -*-
2 *
3 * Copyright (C) The Weather Channel, Inc. 2002.
4 * Copyright (C) 2004 Nicolai Haehnle.
5 * All Rights Reserved.
6 *
7 * The Weather Channel (TM) funded Tungsten Graphics to develop the
8 * initial release of the Radeon 8500 driver under the XFree86 license.
9 * This notice must be preserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 *
30 * Authors:
31 * Nicolai Haehnle <prefect_@gmx.net>
32 */
33
34#include "drmP.h"
35#include "drm.h"
36#include "radeon_drm.h"
37#include "radeon_drv.h"
38#include "r300_reg.h"
39
40#define R300_SIMULTANEOUS_CLIPRECTS 4
41
42/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
43 */
44static const int r300_cliprect_cntl[4] = {
45 0xAAAA,
46 0xEEEE,
47 0xFEFE,
48 0xFFFE
49};
50
51/**
52 * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
53 * buffer, starting with index n.
54 */
55static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
56 drm_radeon_kcmd_buffer_t *cmdbuf, int n)
57{
58 struct drm_clip_rect box;
59 int nr;
60 int i;
61 RING_LOCALS;
62
63 nr = cmdbuf->nbox - n;
64 if (nr > R300_SIMULTANEOUS_CLIPRECTS)
65 nr = R300_SIMULTANEOUS_CLIPRECTS;
66
67 DRM_DEBUG("%i cliprects\n", nr);
68
69 if (nr) {
70 BEGIN_RING(6 + nr * 2);
71 OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1));
72
73 for (i = 0; i < nr; ++i) {
74 if (DRM_COPY_FROM_USER_UNCHECKED
75 (&box, &cmdbuf->boxes[n + i], sizeof(box))) {
76 DRM_ERROR("copy cliprect faulted\n");
77 return -EFAULT;
78 }
79
80 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
81 box.x1 = (box.x1) &
82 R300_CLIPRECT_MASK;
83 box.y1 = (box.y1) &
84 R300_CLIPRECT_MASK;
85 box.x2 = (box.x2) &
86 R300_CLIPRECT_MASK;
87 box.y2 = (box.y2) &
88 R300_CLIPRECT_MASK;
89 } else {
90 box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) &
91 R300_CLIPRECT_MASK;
92 box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) &
93 R300_CLIPRECT_MASK;
94 box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) &
95 R300_CLIPRECT_MASK;
96 box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) &
97 R300_CLIPRECT_MASK;
98
99 }
100 OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
101 (box.y1 << R300_CLIPRECT_Y_SHIFT));
102 OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
103 (box.y2 << R300_CLIPRECT_Y_SHIFT));
104
105 }
106
107 OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
108
109 /* TODO/SECURITY: Force scissors to a safe value, otherwise the
110 * client might be able to trample over memory.
111 * The impact should be very limited, but I'd rather be safe than
112 * sorry.
113 */
114 OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1));
115 OUT_RING(0);
116 OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK);
117 ADVANCE_RING();
118 } else {
119 /* Why we allow zero cliprect rendering:
120 * There are some commands in a command buffer that must be submitted
121 * even when there are no cliprects, e.g. DMA buffer discard
122 * or state setting (though state setting could be avoided by
123 * simulating a loss of context).
124 *
125 * Now since the cmdbuf interface is so chaotic right now (and is
126 * bound to remain that way for a bit until things settle down),
127 * it is basically impossible to filter out the commands that are
128 * necessary and those that aren't.
129 *
130 * So I choose the safe way and don't do any filtering at all;
131 * instead, I simply set up the engine so that all rendering
132 * can't produce any fragments.
133 */
134 BEGIN_RING(2);
135 OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0);
136 ADVANCE_RING();
137 }
138
139 return 0;
140}
141
142static u8 r300_reg_flags[0x10000 >> 2];
143
144void r300_init_reg_flags(struct drm_device *dev)
145{
146 int i;
147 drm_radeon_private_t *dev_priv = dev->dev_private;
148
149 memset(r300_reg_flags, 0, 0x10000 >> 2);
150#define ADD_RANGE_MARK(reg, count,mark) \
151 for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
152 r300_reg_flags[i]|=(mark);
153
154#define MARK_SAFE 1
155#define MARK_CHECK_OFFSET 2
156
157#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
158
159 /* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */
160 ADD_RANGE(R300_SE_VPORT_XSCALE, 6);
161 ADD_RANGE(R300_VAP_CNTL, 1);
162 ADD_RANGE(R300_SE_VTE_CNTL, 2);
163 ADD_RANGE(0x2134, 2);
164 ADD_RANGE(R300_VAP_CNTL_STATUS, 1);
165 ADD_RANGE(R300_VAP_INPUT_CNTL_0, 2);
166 ADD_RANGE(0x21DC, 1);
167 ADD_RANGE(R300_VAP_UNKNOWN_221C, 1);
168 ADD_RANGE(R300_VAP_CLIP_X_0, 4);
169 ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1);
170 ADD_RANGE(R300_VAP_UNKNOWN_2288, 1);
171 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
172 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
173 ADD_RANGE(R300_GB_ENABLE, 1);
174 ADD_RANGE(R300_GB_MSPOS0, 5);
175 ADD_RANGE(R300_TX_CNTL, 1);
176 ADD_RANGE(R300_TX_ENABLE, 1);
177 ADD_RANGE(0x4200, 4);
178 ADD_RANGE(0x4214, 1);
179 ADD_RANGE(R300_RE_POINTSIZE, 1);
180 ADD_RANGE(0x4230, 3);
181 ADD_RANGE(R300_RE_LINE_CNT, 1);
182 ADD_RANGE(R300_RE_UNK4238, 1);
183 ADD_RANGE(0x4260, 3);
184 ADD_RANGE(R300_RE_SHADE, 4);
185 ADD_RANGE(R300_RE_POLYGON_MODE, 5);
186 ADD_RANGE(R300_RE_ZBIAS_CNTL, 1);
187 ADD_RANGE(R300_RE_ZBIAS_T_FACTOR, 4);
188 ADD_RANGE(R300_RE_OCCLUSION_CNTL, 1);
189 ADD_RANGE(R300_RE_CULL_CNTL, 1);
190 ADD_RANGE(0x42C0, 2);
191 ADD_RANGE(R300_RS_CNTL_0, 2);
192
193 ADD_RANGE(R300_SC_HYPERZ, 2);
194 ADD_RANGE(0x43E8, 1);
195
196 ADD_RANGE(0x46A4, 5);
197
198 ADD_RANGE(R300_RE_FOG_STATE, 1);
199 ADD_RANGE(R300_FOG_COLOR_R, 3);
200 ADD_RANGE(R300_PP_ALPHA_TEST, 2);
201 ADD_RANGE(0x4BD8, 1);
202 ADD_RANGE(R300_PFS_PARAM_0_X, 64);
203 ADD_RANGE(0x4E00, 1);
204 ADD_RANGE(R300_RB3D_CBLEND, 2);
205 ADD_RANGE(R300_RB3D_COLORMASK, 1);
206 ADD_RANGE(R300_RB3D_BLEND_COLOR, 3);
207 ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
208 ADD_RANGE(R300_RB3D_COLORPITCH0, 1);
209 ADD_RANGE(0x4E50, 9);
210 ADD_RANGE(0x4E88, 1);
211 ADD_RANGE(0x4EA0, 2);
212 ADD_RANGE(R300_ZB_CNTL, 3);
213 ADD_RANGE(R300_ZB_FORMAT, 4);
214 ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
215 ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
216 ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
217 ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
218
219 ADD_RANGE(R300_TX_FILTER_0, 16);
220 ADD_RANGE(R300_TX_FILTER1_0, 16);
221 ADD_RANGE(R300_TX_SIZE_0, 16);
222 ADD_RANGE(R300_TX_FORMAT_0, 16);
223 ADD_RANGE(R300_TX_PITCH_0, 16);
224 /* Texture offset is dangerous and needs more checking */
225 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
226 ADD_RANGE(R300_TX_CHROMA_KEY_0, 16);
227 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
228
229 /* Sporadic registers used as primitives are emitted */
230 ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1);
231 ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1);
232 ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
233 ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
234
235 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
236 ADD_RANGE(R500_VAP_INDEX_OFFSET, 1);
237 ADD_RANGE(R500_US_CONFIG, 2);
238 ADD_RANGE(R500_US_CODE_ADDR, 3);
239 ADD_RANGE(R500_US_FC_CTRL, 1);
240 ADD_RANGE(R500_RS_IP_0, 16);
241 ADD_RANGE(R500_RS_INST_0, 16);
242 ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
243 ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2);
244 ADD_RANGE(R500_ZB_FIFO_SIZE, 2);
245 } else {
246 ADD_RANGE(R300_PFS_CNTL_0, 3);
247 ADD_RANGE(R300_PFS_NODE_0, 4);
248 ADD_RANGE(R300_PFS_TEXI_0, 64);
249 ADD_RANGE(R300_PFS_INSTR0_0, 64);
250 ADD_RANGE(R300_PFS_INSTR1_0, 64);
251 ADD_RANGE(R300_PFS_INSTR2_0, 64);
252 ADD_RANGE(R300_PFS_INSTR3_0, 64);
253 ADD_RANGE(R300_RS_INTERP_0, 8);
254 ADD_RANGE(R300_RS_ROUTE_0, 8);
255
256 }
257}
258
259static __inline__ int r300_check_range(unsigned reg, int count)
260{
261 int i;
262 if (reg & ~0xffff)
263 return -1;
264 for (i = (reg >> 2); i < (reg >> 2) + count; i++)
265 if (r300_reg_flags[i] != MARK_SAFE)
266 return 1;
267 return 0;
268}
269
270static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
271 dev_priv,
272 drm_radeon_kcmd_buffer_t
273 * cmdbuf,
274 drm_r300_cmd_header_t
275 header)
276{
277 int reg;
278 int sz;
279 int i;
280 int values[64];
281 RING_LOCALS;
282
283 sz = header.packet0.count;
284 reg = (header.packet0.reghi << 8) | header.packet0.reglo;
285
286 if ((sz > 64) || (sz < 0)) {
287 DRM_ERROR
288 ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
289 reg, sz);
290 return -EINVAL;
291 }
292 for (i = 0; i < sz; i++) {
293 values[i] = ((int *)cmdbuf->buf)[i];
294 switch (r300_reg_flags[(reg >> 2) + i]) {
295 case MARK_SAFE:
296 break;
297 case MARK_CHECK_OFFSET:
298 if (!radeon_check_offset(dev_priv, (u32) values[i])) {
299 DRM_ERROR
300 ("Offset failed range check (reg=%04x sz=%d)\n",
301 reg, sz);
302 return -EINVAL;
303 }
304 break;
305 default:
306 DRM_ERROR("Register %04x failed check as flag=%02x\n",
307 reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
308 return -EINVAL;
309 }
310 }
311
312 BEGIN_RING(1 + sz);
313 OUT_RING(CP_PACKET0(reg, sz - 1));
314 OUT_RING_TABLE(values, sz);
315 ADVANCE_RING();
316
317 cmdbuf->buf += sz * 4;
318 cmdbuf->bufsz -= sz * 4;
319
320 return 0;
321}
322
323/**
324 * Emits a packet0 setting arbitrary registers.
325 * Called by r300_do_cp_cmdbuf.
326 *
327 * Note that checks are performed on contents and addresses of the registers
328 */
329static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv,
330 drm_radeon_kcmd_buffer_t *cmdbuf,
331 drm_r300_cmd_header_t header)
332{
333 int reg;
334 int sz;
335 RING_LOCALS;
336
337 sz = header.packet0.count;
338 reg = (header.packet0.reghi << 8) | header.packet0.reglo;
339
340 if (!sz)
341 return 0;
342
343 if (sz * 4 > cmdbuf->bufsz)
344 return -EINVAL;
345
346 if (reg + sz * 4 >= 0x10000) {
347 DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg,
348 sz);
349 return -EINVAL;
350 }
351
352 if (r300_check_range(reg, sz)) {
353 /* go and check everything */
354 return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf,
355 header);
356 }
357 /* the rest of the data is safe to emit, whatever the values the user passed */
358
359 BEGIN_RING(1 + sz);
360 OUT_RING(CP_PACKET0(reg, sz - 1));
361 OUT_RING_TABLE((int *)cmdbuf->buf, sz);
362 ADVANCE_RING();
363
364 cmdbuf->buf += sz * 4;
365 cmdbuf->bufsz -= sz * 4;
366
367 return 0;
368}
369
370/**
371 * Uploads user-supplied vertex program instructions or parameters onto
372 * the graphics card.
373 * Called by r300_do_cp_cmdbuf.
374 */
375static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
376 drm_radeon_kcmd_buffer_t *cmdbuf,
377 drm_r300_cmd_header_t header)
378{
379 int sz;
380 int addr;
381 RING_LOCALS;
382
383 sz = header.vpu.count;
384 addr = (header.vpu.adrhi << 8) | header.vpu.adrlo;
385
386 if (!sz)
387 return 0;
388 if (sz * 16 > cmdbuf->bufsz)
389 return -EINVAL;
390
391 BEGIN_RING(5 + sz * 4);
392 /* Wait for VAP to come to senses.. */
393 /* there is no need to emit it multiple times, (only once before VAP is programmed,
394 but this optimization is for later */
395 OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
396 OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
397 OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
398 OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
399
400 ADVANCE_RING();
401
402 cmdbuf->buf += sz * 16;
403 cmdbuf->bufsz -= sz * 16;
404
405 return 0;
406}
407
408/**
409 * Emit a clear packet from userspace.
410 * Called by r300_emit_packet3.
411 */
412static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
413 drm_radeon_kcmd_buffer_t *cmdbuf)
414{
415 RING_LOCALS;
416
417 if (8 * 4 > cmdbuf->bufsz)
418 return -EINVAL;
419
420 BEGIN_RING(10);
421 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
422 OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
423 (1 << R300_PRIM_NUM_VERTICES_SHIFT));
424 OUT_RING_TABLE((int *)cmdbuf->buf, 8);
425 ADVANCE_RING();
426
427 cmdbuf->buf += 8 * 4;
428 cmdbuf->bufsz -= 8 * 4;
429
430 return 0;
431}
432
433static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
434 drm_radeon_kcmd_buffer_t *cmdbuf,
435 u32 header)
436{
437 int count, i, k;
438#define MAX_ARRAY_PACKET 64
439 u32 payload[MAX_ARRAY_PACKET];
440 u32 narrays;
441 RING_LOCALS;
442
443 count = (header >> 16) & 0x3fff;
444
445 if ((count + 1) > MAX_ARRAY_PACKET) {
446 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
447 count);
448 return -EINVAL;
449 }
450 memset(payload, 0, MAX_ARRAY_PACKET * 4);
451 memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4);
452
453 /* carefully check packet contents */
454
455 narrays = payload[0];
456 k = 0;
457 i = 1;
458 while ((k < narrays) && (i < (count + 1))) {
459 i++; /* skip attribute field */
460 if (!radeon_check_offset(dev_priv, payload[i])) {
461 DRM_ERROR
462 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
463 k, i);
464 return -EINVAL;
465 }
466 k++;
467 i++;
468 if (k == narrays)
469 break;
470 /* have one more to process, they come in pairs */
471 if (!radeon_check_offset(dev_priv, payload[i])) {
472 DRM_ERROR
473 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
474 k, i);
475 return -EINVAL;
476 }
477 k++;
478 i++;
479 }
480 /* do the counts match what we expect ? */
481 if ((k != narrays) || (i != (count + 1))) {
482 DRM_ERROR
483 ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
484 k, i, narrays, count + 1);
485 return -EINVAL;
486 }
487
488 /* all clear, output packet */
489
490 BEGIN_RING(count + 2);
491 OUT_RING(header);
492 OUT_RING_TABLE(payload, count + 1);
493 ADVANCE_RING();
494
495 cmdbuf->buf += (count + 2) * 4;
496 cmdbuf->bufsz -= (count + 2) * 4;
497
498 return 0;
499}
500
501static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
502 drm_radeon_kcmd_buffer_t *cmdbuf)
503{
504 u32 *cmd = (u32 *) cmdbuf->buf;
505 int count, ret;
506 RING_LOCALS;
507
508 count=(cmd[0]>>16) & 0x3fff;
509
510 if (cmd[0] & 0x8000) {
511 u32 offset;
512
513 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
514 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
515 offset = cmd[2] << 10;
516 ret = !radeon_check_offset(dev_priv, offset);
517 if (ret) {
518 DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
519 return -EINVAL;
520 }
521 }
522
523 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
524 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
525 offset = cmd[3] << 10;
526 ret = !radeon_check_offset(dev_priv, offset);
527 if (ret) {
528 DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
529 return -EINVAL;
530 }
531
532 }
533 }
534
535 BEGIN_RING(count+2);
536 OUT_RING(cmd[0]);
537 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
538 ADVANCE_RING();
539
540 cmdbuf->buf += (count+2)*4;
541 cmdbuf->bufsz -= (count+2)*4;
542
543 return 0;
544}
545
546static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
547 drm_radeon_kcmd_buffer_t *cmdbuf)
548{
549 u32 *cmd = (u32 *) cmdbuf->buf;
550 int count, ret;
551 RING_LOCALS;
552
553 count=(cmd[0]>>16) & 0x3fff;
554
555 if ((cmd[1] & 0x8000ffff) != 0x80000810) {
556 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
557 return -EINVAL;
558 }
559 ret = !radeon_check_offset(dev_priv, cmd[2]);
560 if (ret) {
561 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
562 return -EINVAL;
563 }
564
565 BEGIN_RING(count+2);
566 OUT_RING(cmd[0]);
567 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
568 ADVANCE_RING();
569
570 cmdbuf->buf += (count+2)*4;
571 cmdbuf->bufsz -= (count+2)*4;
572
573 return 0;
574}
575
576static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
577 drm_radeon_kcmd_buffer_t *cmdbuf)
578{
579 u32 header;
580 int count;
581 RING_LOCALS;
582
583 if (4 > cmdbuf->bufsz)
584 return -EINVAL;
585
586 /* Fixme !! This simply emits a packet without much checking.
587 We need to be smarter. */
588
589 /* obtain first word - actual packet3 header */
590 header = *(u32 *) cmdbuf->buf;
591
592 /* Is it packet 3 ? */
593 if ((header >> 30) != 0x3) {
594 DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
595 return -EINVAL;
596 }
597
598 count = (header >> 16) & 0x3fff;
599
600 /* Check again now that we know how much data to expect */
601 if ((count + 2) * 4 > cmdbuf->bufsz) {
602 DRM_ERROR
603 ("Expected packet3 of length %d but have only %d bytes left\n",
604 (count + 2) * 4, cmdbuf->bufsz);
605 return -EINVAL;
606 }
607
608 /* Is it a packet type we know about ? */
609 switch (header & 0xff00) {
610 case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
611 return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
612
613 case RADEON_CNTL_BITBLT_MULTI:
614 return r300_emit_bitblt_multi(dev_priv, cmdbuf);
615
616 case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
617 return r300_emit_indx_buffer(dev_priv, cmdbuf);
618 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
619 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
620 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
621 case RADEON_WAIT_FOR_IDLE:
622 case RADEON_CP_NOP:
623 /* these packets are safe */
624 break;
625 default:
626 DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
627 return -EINVAL;
628 }
629
630 BEGIN_RING(count + 2);
631 OUT_RING(header);
632 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
633 ADVANCE_RING();
634
635 cmdbuf->buf += (count + 2) * 4;
636 cmdbuf->bufsz -= (count + 2) * 4;
637
638 return 0;
639}
640
641/**
642 * Emit a rendering packet3 from userspace.
643 * Called by r300_do_cp_cmdbuf.
644 */
645static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
646 drm_radeon_kcmd_buffer_t *cmdbuf,
647 drm_r300_cmd_header_t header)
648{
649 int n;
650 int ret;
651 char *orig_buf = cmdbuf->buf;
652 int orig_bufsz = cmdbuf->bufsz;
653
654 /* This is a do-while-loop so that we run the interior at least once,
655 * even if cmdbuf->nbox is 0. Compare r300_emit_cliprects for rationale.
656 */
657 n = 0;
658 do {
659 if (cmdbuf->nbox > R300_SIMULTANEOUS_CLIPRECTS) {
660 ret = r300_emit_cliprects(dev_priv, cmdbuf, n);
661 if (ret)
662 return ret;
663
664 cmdbuf->buf = orig_buf;
665 cmdbuf->bufsz = orig_bufsz;
666 }
667
668 switch (header.packet3.packet) {
669 case R300_CMD_PACKET3_CLEAR:
670 DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n");
671 ret = r300_emit_clear(dev_priv, cmdbuf);
672 if (ret) {
673 DRM_ERROR("r300_emit_clear failed\n");
674 return ret;
675 }
676 break;
677
678 case R300_CMD_PACKET3_RAW:
679 DRM_DEBUG("R300_CMD_PACKET3_RAW\n");
680 ret = r300_emit_raw_packet3(dev_priv, cmdbuf);
681 if (ret) {
682 DRM_ERROR("r300_emit_raw_packet3 failed\n");
683 return ret;
684 }
685 break;
686
687 default:
688 DRM_ERROR("bad packet3 type %i at %p\n",
689 header.packet3.packet,
690 cmdbuf->buf - sizeof(header));
691 return -EINVAL;
692 }
693
694 n += R300_SIMULTANEOUS_CLIPRECTS;
695 } while (n < cmdbuf->nbox);
696
697 return 0;
698}
699
700/* Some of the R300 chips seem to be extremely touchy about the two registers
701 * that are configured in r300_pacify.
702 * Among the worst offenders seems to be the R300 ND (0x4E44): When userspace
703 * sends a command buffer that contains only state setting commands and a
704 * vertex program/parameter upload sequence, this will eventually lead to a
705 * lockup, unless the sequence is bracketed by calls to r300_pacify.
706 * So we should take great care to *always* call r300_pacify before
707 * *anything* 3D related, and again afterwards. This is what the
708 * call bracket in r300_do_cp_cmdbuf is for.
709 */
710
711/**
712 * Emit the sequence to pacify R300.
713 */
714static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
715{
716 RING_LOCALS;
717
718 BEGIN_RING(6);
719 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
720 OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
721 OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0));
722 OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE|
723 R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
724 OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
725 OUT_RING(0x0);
726 ADVANCE_RING();
727}
728
729/**
730 * Called by r300_do_cp_cmdbuf to update the internal buffer age and state.
731 * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
732 * be careful about how this function is called.
733 */
734static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
735{
736 drm_radeon_private_t *dev_priv = dev->dev_private;
737 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
738
739 buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
740 buf->pending = 1;
741 buf->used = 0;
742}
743
744static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
745 drm_r300_cmd_header_t header)
746{
747 u32 wait_until;
748 RING_LOCALS;
749
750 if (!header.wait.flags)
751 return;
752
753 wait_until = 0;
754
755 switch(header.wait.flags) {
756 case R300_WAIT_2D:
757 wait_until = RADEON_WAIT_2D_IDLE;
758 break;
759 case R300_WAIT_3D:
760 wait_until = RADEON_WAIT_3D_IDLE;
761 break;
762 case R300_NEW_WAIT_2D_3D:
763 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE;
764 break;
765 case R300_NEW_WAIT_2D_2D_CLEAN:
766 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
767 break;
768 case R300_NEW_WAIT_3D_3D_CLEAN:
769 wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
770 break;
771 case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN:
772 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
773 wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
774 break;
775 default:
776 return;
777 }
778
779 BEGIN_RING(2);
780 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
781 OUT_RING(wait_until);
782 ADVANCE_RING();
783}
784
785static int r300_scratch(drm_radeon_private_t *dev_priv,
786 drm_radeon_kcmd_buffer_t *cmdbuf,
787 drm_r300_cmd_header_t header)
788{
789 u32 *ref_age_base;
790 u32 i, buf_idx, h_pending;
791 RING_LOCALS;
792
793 if (cmdbuf->bufsz <
794 (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) {
795 return -EINVAL;
796 }
797
798 if (header.scratch.reg >= 5) {
799 return -EINVAL;
800 }
801
802 dev_priv->scratch_ages[header.scratch.reg]++;
803
804 ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf);
805
806 cmdbuf->buf += sizeof(u64);
807 cmdbuf->bufsz -= sizeof(u64);
808
809 for (i=0; i < header.scratch.n_bufs; i++) {
810 buf_idx = *(u32 *)cmdbuf->buf;
811 buf_idx *= 2; /* 8 bytes per buf */
812
813 if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
814 return -EINVAL;
815 }
816
817 if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
818 return -EINVAL;
819 }
820
821 if (h_pending == 0) {
822 return -EINVAL;
823 }
824
825 h_pending--;
826
827 if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
828 return -EINVAL;
829 }
830
831 cmdbuf->buf += sizeof(buf_idx);
832 cmdbuf->bufsz -= sizeof(buf_idx);
833 }
834
835 BEGIN_RING(2);
836 OUT_RING( CP_PACKET0( RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0 ) );
837 OUT_RING( dev_priv->scratch_ages[header.scratch.reg] );
838 ADVANCE_RING();
839
840 return 0;
841}
842
843/**
844 * Uploads user-supplied vertex program instructions or parameters onto
845 * the graphics card.
846 * Called by r300_do_cp_cmdbuf.
847 */
848static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv,
849 drm_radeon_kcmd_buffer_t *cmdbuf,
850 drm_r300_cmd_header_t header)
851{
852 int sz;
853 int addr;
854 int type;
855 int clamp;
856 int stride;
857 RING_LOCALS;
858
859 sz = header.r500fp.count;
860 /* address is 9 bits 0 - 8, bit 1 of flags is part of address */
861 addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo;
862
863 type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE);
864 clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP);
865
866 addr |= (type << 16);
867 addr |= (clamp << 17);
868
869 stride = type ? 4 : 6;
870
871 DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type);
872 if (!sz)
873 return 0;
874 if (sz * stride * 4 > cmdbuf->bufsz)
875 return -EINVAL;
876
877 BEGIN_RING(3 + sz * stride);
878 OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr);
879 OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1));
880 OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride);
881
882 ADVANCE_RING();
883
884 cmdbuf->buf += sz * stride * 4;
885 cmdbuf->bufsz -= sz * stride * 4;
886
887 return 0;
888}
889
890
891/**
892 * Parses and validates a user-supplied command buffer and emits appropriate
893 * commands on the DMA ring buffer.
894 * Called by the ioctl handler function radeon_cp_cmdbuf.
895 */
896int r300_do_cp_cmdbuf(struct drm_device *dev,
897 struct drm_file *file_priv,
898 drm_radeon_kcmd_buffer_t *cmdbuf)
899{
900 drm_radeon_private_t *dev_priv = dev->dev_private;
901 struct drm_device_dma *dma = dev->dma;
902 struct drm_buf *buf = NULL;
903 int emit_dispatch_age = 0;
904 int ret = 0;
905
906 DRM_DEBUG("\n");
907
908 /* See the comment above r300_emit_begin3d for why this call must be here,
909 * and what the cleanup gotos are for. */
910 r300_pacify(dev_priv);
911
912 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {
913 ret = r300_emit_cliprects(dev_priv, cmdbuf, 0);
914 if (ret)
915 goto cleanup;
916 }
917
918 while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
919 int idx;
920 drm_r300_cmd_header_t header;
921
922 header.u = *(unsigned int *)cmdbuf->buf;
923
924 cmdbuf->buf += sizeof(header);
925 cmdbuf->bufsz -= sizeof(header);
926
927 switch (header.header.cmd_type) {
928 case R300_CMD_PACKET0:
929 DRM_DEBUG("R300_CMD_PACKET0\n");
930 ret = r300_emit_packet0(dev_priv, cmdbuf, header);
931 if (ret) {
932 DRM_ERROR("r300_emit_packet0 failed\n");
933 goto cleanup;
934 }
935 break;
936
937 case R300_CMD_VPU:
938 DRM_DEBUG("R300_CMD_VPU\n");
939 ret = r300_emit_vpu(dev_priv, cmdbuf, header);
940 if (ret) {
941 DRM_ERROR("r300_emit_vpu failed\n");
942 goto cleanup;
943 }
944 break;
945
946 case R300_CMD_PACKET3:
947 DRM_DEBUG("R300_CMD_PACKET3\n");
948 ret = r300_emit_packet3(dev_priv, cmdbuf, header);
949 if (ret) {
950 DRM_ERROR("r300_emit_packet3 failed\n");
951 goto cleanup;
952 }
953 break;
954
955 case R300_CMD_END3D:
956 DRM_DEBUG("R300_CMD_END3D\n");
957 /* TODO:
958 Ideally userspace driver should not need to issue this call,
959 i.e. the drm driver should issue it automatically and prevent
960 lockups.
961
962 In practice, we do not understand why this call is needed and what
963 it does (except for some vague guesses that it has to do with cache
964 coherence) and so the user space driver does it.
965
966 Once we are sure which uses prevent lockups the code could be moved
967 into the kernel and the userspace driver will not
968 need to use this command.
969
970 Note that issuing this command does not hurt anything
971 except, possibly, performance */
972 r300_pacify(dev_priv);
973 break;
974
975 case R300_CMD_CP_DELAY:
976 /* simple enough, we can do it here */
977 DRM_DEBUG("R300_CMD_CP_DELAY\n");
978 {
979 int i;
980 RING_LOCALS;
981
982 BEGIN_RING(header.delay.count);
983 for (i = 0; i < header.delay.count; i++)
984 OUT_RING(RADEON_CP_PACKET2);
985 ADVANCE_RING();
986 }
987 break;
988
989 case R300_CMD_DMA_DISCARD:
990 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
991 idx = header.dma.buf_idx;
992 if (idx < 0 || idx >= dma->buf_count) {
993 DRM_ERROR("buffer index %d (of %d max)\n",
994 idx, dma->buf_count - 1);
995 ret = -EINVAL;
996 goto cleanup;
997 }
998
999 buf = dma->buflist[idx];
1000 if (buf->file_priv != file_priv || buf->pending) {
1001 DRM_ERROR("bad buffer %p %p %d\n",
1002 buf->file_priv, file_priv,
1003 buf->pending);
1004 ret = -EINVAL;
1005 goto cleanup;
1006 }
1007
1008 emit_dispatch_age = 1;
1009 r300_discard_buffer(dev, buf);
1010 break;
1011
1012 case R300_CMD_WAIT:
1013 DRM_DEBUG("R300_CMD_WAIT\n");
1014 r300_cmd_wait(dev_priv, header);
1015 break;
1016
1017 case R300_CMD_SCRATCH:
1018 DRM_DEBUG("R300_CMD_SCRATCH\n");
1019 ret = r300_scratch(dev_priv, cmdbuf, header);
1020 if (ret) {
1021 DRM_ERROR("r300_scratch failed\n");
1022 goto cleanup;
1023 }
1024 break;
1025
1026 case R300_CMD_R500FP:
1027 if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
1028 DRM_ERROR("Calling r500 command on r300 card\n");
1029 ret = -EINVAL;
1030 goto cleanup;
1031 }
1032 DRM_DEBUG("R300_CMD_R500FP\n");
1033 ret = r300_emit_r500fp(dev_priv, cmdbuf, header);
1034 if (ret) {
1035 DRM_ERROR("r300_emit_r500fp failed\n");
1036 goto cleanup;
1037 }
1038 break;
1039 default:
1040 DRM_ERROR("bad cmd_type %i at %p\n",
1041 header.header.cmd_type,
1042 cmdbuf->buf - sizeof(header));
1043 ret = -EINVAL;
1044 goto cleanup;
1045 }
1046 }
1047
1048 DRM_DEBUG("END\n");
1049
1050 cleanup:
1051 r300_pacify(dev_priv);
1052
1053 /* We emit the vertex buffer age here, outside the pacifier "brackets"
1054 * for two reasons:
1055 * (1) This may coalesce multiple age emissions into a single one and
1056 * (2) more importantly, some chips lock up hard when scratch registers
1057 * are written inside the pacifier bracket.
1058 */
1059 if (emit_dispatch_age) {
1060 RING_LOCALS;
1061
1062 /* Emit the vertex buffer age */
1063 BEGIN_RING(2);
1064 RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
1065 ADVANCE_RING();
1066 }
1067
1068 COMMIT_RING();
1069
1070 return ret;
1071}
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h
new file mode 100644
index 000000000000..a6802f26afc4
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r300_reg.h
@@ -0,0 +1,1772 @@
1/**************************************************************************
2
3Copyright (C) 2004-2005 Nicolai Haehnle et al.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8on the rights to use, copy, modify, merge, publish, distribute, sub
9license, and/or sell copies of the Software, and to permit persons to whom
10the Software is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice (including the next
13paragraph) shall be included in all copies or substantial portions of the
14Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24**************************************************************************/
25
26#ifndef _R300_REG_H
27#define _R300_REG_H
28
29#define R300_MC_INIT_MISC_LAT_TIMER 0x180
30# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0
31# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4
32# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8
33# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12
34# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16
35# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20
36# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24
37# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28
38
39#define R300_MC_INIT_GFX_LAT_TIMER 0x154
40# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0
41# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4
42# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8
43# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12
44# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16
45# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20
46# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24
47# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28
48
49/*
50 * This file contains registers and constants for the R300. They have been
51 * found mostly by examining command buffers captured using glxtest, as well
52 * as by extrapolating some known registers and constants from the R200.
53 * I am fairly certain that they are correct unless stated otherwise
54 * in comments.
55 */
56
57#define R300_SE_VPORT_XSCALE 0x1D98
58#define R300_SE_VPORT_XOFFSET 0x1D9C
59#define R300_SE_VPORT_YSCALE 0x1DA0
60#define R300_SE_VPORT_YOFFSET 0x1DA4
61#define R300_SE_VPORT_ZSCALE 0x1DA8
62#define R300_SE_VPORT_ZOFFSET 0x1DAC
63
64
65/*
66 * Vertex Array Processing (VAP) Control
67 * Stolen from r200 code from Christoph Brill (It's a guess!)
68 */
69#define R300_VAP_CNTL 0x2080
70
71/* This register is written directly and also starts data section
72 * in many 3d CP_PACKET3's
73 */
74#define R300_VAP_VF_CNTL 0x2084
75# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0
76# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0)
77# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0)
78# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0)
79# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0)
80# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0)
81# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0)
82# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0)
83# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0)
84# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0)
85# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0)
86# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0)
87
88# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4
89 /* State based - direct writes to registers trigger vertex
90 generation */
91# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4)
92# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4)
93# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4)
94# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4)
95
96 /* I don't think I saw these three used.. */
97# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6
98# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9
99# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10
100
101 /* index size - when not set the indices are assumed to be 16 bit */
102# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11)
103 /* number of vertices */
104# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16
105
106/* BEGIN: Wild guesses */
107#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090
108# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0)
109# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1)
110# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
111# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
112# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
113# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
114
115#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
116 /* each of the following is 3 bits wide, specifies number
117 of components */
118# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
119# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
120# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
121# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
122# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
123# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
124# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
125# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
126/* END: Wild guesses */
127
128#define R300_SE_VTE_CNTL 0x20b0
129# define R300_VPORT_X_SCALE_ENA 0x00000001
130# define R300_VPORT_X_OFFSET_ENA 0x00000002
131# define R300_VPORT_Y_SCALE_ENA 0x00000004
132# define R300_VPORT_Y_OFFSET_ENA 0x00000008
133# define R300_VPORT_Z_SCALE_ENA 0x00000010
134# define R300_VPORT_Z_OFFSET_ENA 0x00000020
135# define R300_VTX_XY_FMT 0x00000100
136# define R300_VTX_Z_FMT 0x00000200
137# define R300_VTX_W0_FMT 0x00000400
138# define R300_VTX_W0_NORMALIZE 0x00000800
139# define R300_VTX_ST_DENORMALIZED 0x00001000
140
141/* BEGIN: Vertex data assembly - lots of uncertainties */
142
143/* gap */
144
145#define R300_VAP_CNTL_STATUS 0x2140
146# define R300_VC_NO_SWAP (0 << 0)
147# define R300_VC_16BIT_SWAP (1 << 0)
148# define R300_VC_32BIT_SWAP (2 << 0)
149# define R300_VAP_TCL_BYPASS (1 << 8)
150
151/* gap */
152
153/* Where do we get our vertex data?
154 *
155 * Vertex data either comes either from immediate mode registers or from
156 * vertex arrays.
157 * There appears to be no mixed mode (though we can force the pitch of
158 * vertex arrays to 0, effectively reusing the same element over and over
159 * again).
160 *
161 * Immediate mode is controlled by the INPUT_CNTL registers. I am not sure
162 * if these registers influence vertex array processing.
163 *
164 * Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3.
165 *
166 * In both cases, vertex attributes are then passed through INPUT_ROUTE.
167 *
168 * Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data
169 * into the vertex processor's input registers.
170 * The first word routes the first input, the second word the second, etc.
171 * The corresponding input is routed into the register with the given index.
172 * The list is ended by a word with INPUT_ROUTE_END set.
173 *
174 * Always set COMPONENTS_4 in immediate mode.
175 */
176
177#define R300_VAP_INPUT_ROUTE_0_0 0x2150
178# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0)
179# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0)
180# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0)
181# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0)
182# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
183# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8
184# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
185# define R300_VAP_INPUT_ROUTE_END (1 << 13)
186# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
187# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
188# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
189# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
190#define R300_VAP_INPUT_ROUTE_0_1 0x2154
191#define R300_VAP_INPUT_ROUTE_0_2 0x2158
192#define R300_VAP_INPUT_ROUTE_0_3 0x215C
193#define R300_VAP_INPUT_ROUTE_0_4 0x2160
194#define R300_VAP_INPUT_ROUTE_0_5 0x2164
195#define R300_VAP_INPUT_ROUTE_0_6 0x2168
196#define R300_VAP_INPUT_ROUTE_0_7 0x216C
197
198/* gap */
199
200/* Notes:
201 * - always set up to produce at least two attributes:
202 * if vertex program uses only position, fglrx will set normal, too
203 * - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal.
204 */
205#define R300_VAP_INPUT_CNTL_0 0x2180
206# define R300_INPUT_CNTL_0_COLOR 0x00000001
207#define R300_VAP_INPUT_CNTL_1 0x2184
208# define R300_INPUT_CNTL_POS 0x00000001
209# define R300_INPUT_CNTL_NORMAL 0x00000002
210# define R300_INPUT_CNTL_COLOR 0x00000004
211# define R300_INPUT_CNTL_TC0 0x00000400
212# define R300_INPUT_CNTL_TC1 0x00000800
213# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
214# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
215# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
216# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
217# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
218# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
219
220/* gap */
221
222/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
223 * are set to a swizzling bit pattern, other words are 0.
224 *
225 * In immediate mode, the pattern is always set to xyzw. In vertex array
226 * mode, the swizzling pattern is e.g. used to set zw components in texture
227 * coordinates with only tweo components.
228 */
229#define R300_VAP_INPUT_ROUTE_1_0 0x21E0
230# define R300_INPUT_ROUTE_SELECT_X 0
231# define R300_INPUT_ROUTE_SELECT_Y 1
232# define R300_INPUT_ROUTE_SELECT_Z 2
233# define R300_INPUT_ROUTE_SELECT_W 3
234# define R300_INPUT_ROUTE_SELECT_ZERO 4
235# define R300_INPUT_ROUTE_SELECT_ONE 5
236# define R300_INPUT_ROUTE_SELECT_MASK 7
237# define R300_INPUT_ROUTE_X_SHIFT 0
238# define R300_INPUT_ROUTE_Y_SHIFT 3
239# define R300_INPUT_ROUTE_Z_SHIFT 6
240# define R300_INPUT_ROUTE_W_SHIFT 9
241# define R300_INPUT_ROUTE_ENABLE (15 << 12)
242#define R300_VAP_INPUT_ROUTE_1_1 0x21E4
243#define R300_VAP_INPUT_ROUTE_1_2 0x21E8
244#define R300_VAP_INPUT_ROUTE_1_3 0x21EC
245#define R300_VAP_INPUT_ROUTE_1_4 0x21F0
246#define R300_VAP_INPUT_ROUTE_1_5 0x21F4
247#define R300_VAP_INPUT_ROUTE_1_6 0x21F8
248#define R300_VAP_INPUT_ROUTE_1_7 0x21FC
249
250/* END: Vertex data assembly */
251
252/* gap */
253
254/* BEGIN: Upload vertex program and data */
255
256/*
257 * The programmable vertex shader unit has a memory bank of unknown size
258 * that can be written to in 16 byte units by writing the address into
259 * UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs).
260 *
261 * Pointers into the memory bank are always in multiples of 16 bytes.
262 *
263 * The memory bank is divided into areas with fixed meaning.
264 *
265 * Starting at address UPLOAD_PROGRAM: Vertex program instructions.
266 * Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB),
267 * whereas the difference between known addresses suggests size 512.
268 *
269 * Starting at address UPLOAD_PARAMETERS: Vertex program parameters.
270 * Native reported limits and the VPI layout suggest size 256, whereas
271 * difference between known addresses suggests size 512.
272 *
273 * At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the
274 * floating point pointsize. The exact purpose of this state is uncertain,
275 * as there is also the R300_RE_POINTSIZE register.
276 *
277 * Multiple vertex programs and parameter sets can be loaded at once,
278 * which could explain the size discrepancy.
279 */
280#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200
281# define R300_PVS_UPLOAD_PROGRAM 0x00000000
282# define R300_PVS_UPLOAD_PARAMETERS 0x00000200
283# define R300_PVS_UPLOAD_POINTSIZE 0x00000406
284
285/* gap */
286
287#define R300_VAP_PVS_UPLOAD_DATA 0x2208
288
289/* END: Upload vertex program and data */
290
291/* gap */
292
293/* I do not know the purpose of this register. However, I do know that
294 * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL
295 * for normal rendering.
296 */
297#define R300_VAP_UNKNOWN_221C 0x221C
298# define R300_221C_NORMAL 0x00000000
299# define R300_221C_CLEAR 0x0001C000
300
301/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first
302 * plane is per-pixel and the second plane is per-vertex.
303 *
304 * This was determined by experimentation alone but I believe it is correct.
305 *
306 * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest.
307 */
308#define R300_VAP_CLIP_X_0 0x2220
309#define R300_VAP_CLIP_X_1 0x2224
310#define R300_VAP_CLIP_Y_0 0x2228
311#define R300_VAP_CLIP_Y_1 0x2230
312
313/* gap */
314
315/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
316 * rendering commands and overwriting vertex program parameters.
317 * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
318 * avoids bugs caused by still running shaders reading bad data from memory.
319 */
320#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
321
322/* Absolutely no clue what this register is about. */
323#define R300_VAP_UNKNOWN_2288 0x2288
324# define R300_2288_R300 0x00750000 /* -- nh */
325# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
326
327/* gap */
328
329/* Addresses are relative to the vertex program instruction area of the
330 * memory bank. PROGRAM_END points to the last instruction of the active
331 * program
332 *
333 * The meaning of the two UNKNOWN fields is obviously not known. However,
334 * experiments so far have shown that both *must* point to an instruction
335 * inside the vertex program, otherwise the GPU locks up.
336 *
337 * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
338 * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to
339 * position takes place.
340 *
341 * Most likely this is used to ignore rest of the program in cases
342 * where group of verts arent visible. For some reason this "section"
343 * is sometimes accepted other instruction that have no relationship with
344 * position calculations.
345 */
346#define R300_VAP_PVS_CNTL_1 0x22D0
347# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
348# define R300_PVS_CNTL_1_POS_END_SHIFT 10
349# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20
350/* Addresses are relative the the vertex program parameters area. */
351#define R300_VAP_PVS_CNTL_2 0x22D4
352# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
353# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16
354#define R300_VAP_PVS_CNTL_3 0x22D8
355# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10
356# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0
357
358/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for
359 * immediate vertices
360 */
361#define R300_VAP_VTX_COLOR_R 0x2464
362#define R300_VAP_VTX_COLOR_G 0x2468
363#define R300_VAP_VTX_COLOR_B 0x246C
364#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
365#define R300_VAP_VTX_POS_0_Y_1 0x2494
366#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
367#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
368#define R300_VAP_VTX_POS_0_Y_2 0x24A4
369#define R300_VAP_VTX_POS_0_Z_2 0x24A8
370/* write 0 to indicate end of packet? */
371#define R300_VAP_VTX_END_OF_PKT 0x24AC
372
373/* gap */
374
375/* These are values from r300_reg/r300_reg.h - they are known to be correct
376 * and are here so we can use one register file instead of several
377 * - Vladimir
378 */
379#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000
380# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0)
381# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1)
382# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2)
383# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3)
384# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4)
385# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5)
386# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16)
387
388#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004
389 /* each of the following is 3 bits wide, specifies number
390 of components */
391# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
392# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
393# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
394# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
395# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
396# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
397# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
398# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
399
400/* UNK30 seems to enables point to quad transformation on textures
401 * (or something closely related to that).
402 * This bit is rather fatal at the time being due to lackings at pixel
403 * shader side
404 */
405#define R300_GB_ENABLE 0x4008
406# define R300_GB_POINT_STUFF_ENABLE (1<<0)
407# define R300_GB_LINE_STUFF_ENABLE (1<<1)
408# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2)
409# define R300_GB_STENCIL_AUTO_ENABLE (1<<4)
410# define R300_GB_UNK31 (1<<31)
411 /* each of the following is 2 bits wide */
412#define R300_GB_TEX_REPLICATE 0
413#define R300_GB_TEX_ST 1
414#define R300_GB_TEX_STR 2
415# define R300_GB_TEX0_SOURCE_SHIFT 16
416# define R300_GB_TEX1_SOURCE_SHIFT 18
417# define R300_GB_TEX2_SOURCE_SHIFT 20
418# define R300_GB_TEX3_SOURCE_SHIFT 22
419# define R300_GB_TEX4_SOURCE_SHIFT 24
420# define R300_GB_TEX5_SOURCE_SHIFT 26
421# define R300_GB_TEX6_SOURCE_SHIFT 28
422# define R300_GB_TEX7_SOURCE_SHIFT 30
423
424/* MSPOS - positions for multisample antialiasing (?) */
425#define R300_GB_MSPOS0 0x4010
426 /* shifts - each of the fields is 4 bits */
427# define R300_GB_MSPOS0__MS_X0_SHIFT 0
428# define R300_GB_MSPOS0__MS_Y0_SHIFT 4
429# define R300_GB_MSPOS0__MS_X1_SHIFT 8
430# define R300_GB_MSPOS0__MS_Y1_SHIFT 12
431# define R300_GB_MSPOS0__MS_X2_SHIFT 16
432# define R300_GB_MSPOS0__MS_Y2_SHIFT 20
433# define R300_GB_MSPOS0__MSBD0_Y 24
434# define R300_GB_MSPOS0__MSBD0_X 28
435
436#define R300_GB_MSPOS1 0x4014
437# define R300_GB_MSPOS1__MS_X3_SHIFT 0
438# define R300_GB_MSPOS1__MS_Y3_SHIFT 4
439# define R300_GB_MSPOS1__MS_X4_SHIFT 8
440# define R300_GB_MSPOS1__MS_Y4_SHIFT 12
441# define R300_GB_MSPOS1__MS_X5_SHIFT 16
442# define R300_GB_MSPOS1__MS_Y5_SHIFT 20
443# define R300_GB_MSPOS1__MSBD1 24
444
445
446#define R300_GB_TILE_CONFIG 0x4018
447# define R300_GB_TILE_ENABLE (1<<0)
448# define R300_GB_TILE_PIPE_COUNT_RV300 0
449# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1)
450# define R300_GB_TILE_PIPE_COUNT_R420 (7<<1)
451# define R300_GB_TILE_PIPE_COUNT_RV410 (3<<1)
452# define R300_GB_TILE_SIZE_8 0
453# define R300_GB_TILE_SIZE_16 (1<<4)
454# define R300_GB_TILE_SIZE_32 (2<<4)
455# define R300_GB_SUPER_SIZE_1 (0<<6)
456# define R300_GB_SUPER_SIZE_2 (1<<6)
457# define R300_GB_SUPER_SIZE_4 (2<<6)
458# define R300_GB_SUPER_SIZE_8 (3<<6)
459# define R300_GB_SUPER_SIZE_16 (4<<6)
460# define R300_GB_SUPER_SIZE_32 (5<<6)
461# define R300_GB_SUPER_SIZE_64 (6<<6)
462# define R300_GB_SUPER_SIZE_128 (7<<6)
463# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */
464# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */
465# define R300_GB_SUPER_TILE_A 0
466# define R300_GB_SUPER_TILE_B (1<<15)
467# define R300_GB_SUBPIXEL_1_12 0
468# define R300_GB_SUBPIXEL_1_16 (1<<16)
469
470#define R300_GB_FIFO_SIZE 0x4024
471 /* each of the following is 2 bits wide */
472#define R300_GB_FIFO_SIZE_32 0
473#define R300_GB_FIFO_SIZE_64 1
474#define R300_GB_FIFO_SIZE_128 2
475#define R300_GB_FIFO_SIZE_256 3
476# define R300_SC_IFIFO_SIZE_SHIFT 0
477# define R300_SC_TZFIFO_SIZE_SHIFT 2
478# define R300_SC_BFIFO_SIZE_SHIFT 4
479
480# define R300_US_OFIFO_SIZE_SHIFT 12
481# define R300_US_WFIFO_SIZE_SHIFT 14
482 /* the following use the same constants as above, but meaning is
483 is times 2 (i.e. instead of 32 words it means 64 */
484# define R300_RS_TFIFO_SIZE_SHIFT 6
485# define R300_RS_CFIFO_SIZE_SHIFT 8
486# define R300_US_RAM_SIZE_SHIFT 10
487 /* watermarks, 3 bits wide */
488# define R300_RS_HIGHWATER_COL_SHIFT 16
489# define R300_RS_HIGHWATER_TEX_SHIFT 19
490# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */
491# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24
492
493#define R300_GB_SELECT 0x401C
494# define R300_GB_FOG_SELECT_C0A 0
495# define R300_GB_FOG_SELECT_C1A 1
496# define R300_GB_FOG_SELECT_C2A 2
497# define R300_GB_FOG_SELECT_C3A 3
498# define R300_GB_FOG_SELECT_1_1_W 4
499# define R300_GB_FOG_SELECT_Z 5
500# define R300_GB_DEPTH_SELECT_Z 0
501# define R300_GB_DEPTH_SELECT_1_1_W (1<<3)
502# define R300_GB_W_SELECT_1_W 0
503# define R300_GB_W_SELECT_1 (1<<4)
504
505#define R300_GB_AA_CONFIG 0x4020
506# define R300_AA_DISABLE 0x00
507# define R300_AA_ENABLE 0x01
508# define R300_AA_SUBSAMPLES_2 0
509# define R300_AA_SUBSAMPLES_3 (1<<1)
510# define R300_AA_SUBSAMPLES_4 (2<<1)
511# define R300_AA_SUBSAMPLES_6 (3<<1)
512
513/* gap */
514
515/* Zero to flush caches. */
516#define R300_TX_CNTL 0x4100
517#define R300_TX_FLUSH 0x0
518
519/* The upper enable bits are guessed, based on fglrx reported limits. */
520#define R300_TX_ENABLE 0x4104
521# define R300_TX_ENABLE_0 (1 << 0)
522# define R300_TX_ENABLE_1 (1 << 1)
523# define R300_TX_ENABLE_2 (1 << 2)
524# define R300_TX_ENABLE_3 (1 << 3)
525# define R300_TX_ENABLE_4 (1 << 4)
526# define R300_TX_ENABLE_5 (1 << 5)
527# define R300_TX_ENABLE_6 (1 << 6)
528# define R300_TX_ENABLE_7 (1 << 7)
529# define R300_TX_ENABLE_8 (1 << 8)
530# define R300_TX_ENABLE_9 (1 << 9)
531# define R300_TX_ENABLE_10 (1 << 10)
532# define R300_TX_ENABLE_11 (1 << 11)
533# define R300_TX_ENABLE_12 (1 << 12)
534# define R300_TX_ENABLE_13 (1 << 13)
535# define R300_TX_ENABLE_14 (1 << 14)
536# define R300_TX_ENABLE_15 (1 << 15)
537
538/* The pointsize is given in multiples of 6. The pointsize can be
539 * enormous: Clear() renders a single point that fills the entire
540 * framebuffer.
541 */
542#define R300_RE_POINTSIZE 0x421C
543# define R300_POINTSIZE_Y_SHIFT 0
544# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
545# define R300_POINTSIZE_X_SHIFT 16
546# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
547# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6)
548
549/* The line width is given in multiples of 6.
550 * In default mode lines are classified as vertical lines.
551 * HO: horizontal
552 * VE: vertical or horizontal
553 * HO & VE: no classification
554 */
555#define R300_RE_LINE_CNT 0x4234
556# define R300_LINESIZE_SHIFT 0
557# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
558# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6)
559# define R300_LINE_CNT_HO (1 << 16)
560# define R300_LINE_CNT_VE (1 << 17)
561
562/* Some sort of scale or clamp value for texcoordless textures. */
563#define R300_RE_UNK4238 0x4238
564
565/* Something shade related */
566#define R300_RE_SHADE 0x4274
567
568#define R300_RE_SHADE_MODEL 0x4278
569# define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa
570# define R300_RE_SHADE_MODEL_FLAT 0x39595
571
572/* Dangerous */
573#define R300_RE_POLYGON_MODE 0x4288
574# define R300_PM_ENABLED (1 << 0)
575# define R300_PM_FRONT_POINT (0 << 0)
576# define R300_PM_BACK_POINT (0 << 0)
577# define R300_PM_FRONT_LINE (1 << 4)
578# define R300_PM_FRONT_FILL (1 << 5)
579# define R300_PM_BACK_LINE (1 << 7)
580# define R300_PM_BACK_FILL (1 << 8)
581
582/* Fog parameters */
583#define R300_RE_FOG_SCALE 0x4294
584#define R300_RE_FOG_START 0x4298
585
586/* Not sure why there are duplicate of factor and constant values.
587 * My best guess so far is that there are separate zbiases for test and write.
588 * Ordering might be wrong.
589 * Some of the tests indicate that fgl has a fallback implementation of zbias
590 * via pixel shaders.
591 */
592#define R300_RE_ZBIAS_CNTL 0x42A0 /* GUESS */
593#define R300_RE_ZBIAS_T_FACTOR 0x42A4
594#define R300_RE_ZBIAS_T_CONSTANT 0x42A8
595#define R300_RE_ZBIAS_W_FACTOR 0x42AC
596#define R300_RE_ZBIAS_W_CONSTANT 0x42B0
597
598/* This register needs to be set to (1<<1) for RV350 to correctly
599 * perform depth test (see --vb-triangles in r300_demo)
600 * Don't know about other chips. - Vladimir
601 * This is set to 3 when GL_POLYGON_OFFSET_FILL is on.
602 * My guess is that there are two bits for each zbias primitive
603 * (FILL, LINE, POINT).
604 * One to enable depth test and one for depth write.
605 * Yet this doesnt explain why depth writes work ...
606 */
607#define R300_RE_OCCLUSION_CNTL 0x42B4
608# define R300_OCCLUSION_ON (1<<1)
609
610#define R300_RE_CULL_CNTL 0x42B8
611# define R300_CULL_FRONT (1 << 0)
612# define R300_CULL_BACK (1 << 1)
613# define R300_FRONT_FACE_CCW (0 << 2)
614# define R300_FRONT_FACE_CW (1 << 2)
615
616
617/* BEGIN: Rasterization / Interpolators - many guesses */
618
619/* 0_UNKNOWN_18 has always been set except for clear operations.
620 * TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
621 * on the vertex program, *not* the fragment program)
622 */
623#define R300_RS_CNTL_0 0x4300
624# define R300_RS_CNTL_TC_CNT_SHIFT 2
625# define R300_RS_CNTL_TC_CNT_MASK (7 << 2)
626 /* number of color interpolators used */
627# define R300_RS_CNTL_CI_CNT_SHIFT 7
628# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18)
629 /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n
630 register. */
631#define R300_RS_CNTL_1 0x4304
632
633/* gap */
634
635/* Only used for texture coordinates.
636 * Use the source field to route texture coordinate input from the
637 * vertex program to the desired interpolator. Note that the source
638 * field is relative to the outputs the vertex program *actually*
639 * writes. If a vertex program only writes texcoord[1], this will
640 * be source index 0.
641 * Set INTERP_USED on all interpolators that produce data used by
642 * the fragment program. INTERP_USED looks like a swizzling mask,
643 * but I haven't seen it used that way.
644 *
645 * Note: The _UNKNOWN constants are always set in their respective
646 * register. I don't know if this is necessary.
647 */
648#define R300_RS_INTERP_0 0x4310
649#define R300_RS_INTERP_1 0x4314
650# define R300_RS_INTERP_1_UNKNOWN 0x40
651#define R300_RS_INTERP_2 0x4318
652# define R300_RS_INTERP_2_UNKNOWN 0x80
653#define R300_RS_INTERP_3 0x431C
654# define R300_RS_INTERP_3_UNKNOWN 0xC0
655#define R300_RS_INTERP_4 0x4320
656#define R300_RS_INTERP_5 0x4324
657#define R300_RS_INTERP_6 0x4328
658#define R300_RS_INTERP_7 0x432C
659# define R300_RS_INTERP_SRC_SHIFT 2
660# define R300_RS_INTERP_SRC_MASK (7 << 2)
661# define R300_RS_INTERP_USED 0x00D10000
662
663/* These DWORDs control how vertex data is routed into fragment program
664 * registers, after interpolators.
665 */
666#define R300_RS_ROUTE_0 0x4330
667#define R300_RS_ROUTE_1 0x4334
668#define R300_RS_ROUTE_2 0x4338
669#define R300_RS_ROUTE_3 0x433C /* GUESS */
670#define R300_RS_ROUTE_4 0x4340 /* GUESS */
671#define R300_RS_ROUTE_5 0x4344 /* GUESS */
672#define R300_RS_ROUTE_6 0x4348 /* GUESS */
673#define R300_RS_ROUTE_7 0x434C /* GUESS */
674# define R300_RS_ROUTE_SOURCE_INTERP_0 0
675# define R300_RS_ROUTE_SOURCE_INTERP_1 1
676# define R300_RS_ROUTE_SOURCE_INTERP_2 2
677# define R300_RS_ROUTE_SOURCE_INTERP_3 3
678# define R300_RS_ROUTE_SOURCE_INTERP_4 4
679# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
680# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
681# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
682# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
683# define R300_RS_ROUTE_DEST_SHIFT 6
684# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
685
686/* Special handling for color: When the fragment program uses color,
687 * the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
688 * color register index.
689 *
690 * Apperently you may set the R300_RS_ROUTE_0_COLOR bit, but not provide any
691 * R300_RS_ROUTE_0_COLOR_DEST value; this setup is used for clearing the state.
692 * See r300_ioctl.c:r300EmitClearState. I'm not sure if this setup is strictly
693 * correct or not. - Oliver.
694 */
695# define R300_RS_ROUTE_0_COLOR (1 << 14)
696# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17
697# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
698/* As above, but for secondary color */
699# define R300_RS_ROUTE_1_COLOR1 (1 << 14)
700# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17
701# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17)
702# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11)
703/* END: Rasterization / Interpolators - many guesses */
704
705/* Hierarchical Z Enable */
706#define R300_SC_HYPERZ 0x43a4
707# define R300_SC_HYPERZ_DISABLE (0 << 0)
708# define R300_SC_HYPERZ_ENABLE (1 << 0)
709# define R300_SC_HYPERZ_MIN (0 << 1)
710# define R300_SC_HYPERZ_MAX (1 << 1)
711# define R300_SC_HYPERZ_ADJ_256 (0 << 2)
712# define R300_SC_HYPERZ_ADJ_128 (1 << 2)
713# define R300_SC_HYPERZ_ADJ_64 (2 << 2)
714# define R300_SC_HYPERZ_ADJ_32 (3 << 2)
715# define R300_SC_HYPERZ_ADJ_16 (4 << 2)
716# define R300_SC_HYPERZ_ADJ_8 (5 << 2)
717# define R300_SC_HYPERZ_ADJ_4 (6 << 2)
718# define R300_SC_HYPERZ_ADJ_2 (7 << 2)
719# define R300_SC_HYPERZ_HZ_Z0MIN_NO (0 << 5)
720# define R300_SC_HYPERZ_HZ_Z0MIN (1 << 5)
721# define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6)
722# define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6)
723
724#define R300_SC_EDGERULE 0x43a8
725
726/* BEGIN: Scissors and cliprects */
727
728/* There are four clipping rectangles. Their corner coordinates are inclusive.
729 * Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending
730 * on whether the pixel is inside cliprects 0-3, respectively. For example,
731 * if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned
732 * the number 3 (binary 0011).
733 * Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set,
734 * the pixel is rasterized.
735 *
736 * In addition to this, there is a scissors rectangle. Only pixels inside the
737 * scissors rectangle are drawn. (coordinates are inclusive)
738 *
739 * For some reason, the top-left corner of the framebuffer is at (1440, 1440)
740 * for the purpose of clipping and scissors.
741 */
742#define R300_RE_CLIPRECT_TL_0 0x43B0
743#define R300_RE_CLIPRECT_BR_0 0x43B4
744#define R300_RE_CLIPRECT_TL_1 0x43B8
745#define R300_RE_CLIPRECT_BR_1 0x43BC
746#define R300_RE_CLIPRECT_TL_2 0x43C0
747#define R300_RE_CLIPRECT_BR_2 0x43C4
748#define R300_RE_CLIPRECT_TL_3 0x43C8
749#define R300_RE_CLIPRECT_BR_3 0x43CC
750# define R300_CLIPRECT_OFFSET 1440
751# define R300_CLIPRECT_MASK 0x1FFF
752# define R300_CLIPRECT_X_SHIFT 0
753# define R300_CLIPRECT_X_MASK (0x1FFF << 0)
754# define R300_CLIPRECT_Y_SHIFT 13
755# define R300_CLIPRECT_Y_MASK (0x1FFF << 13)
756#define R300_RE_CLIPRECT_CNTL 0x43D0
757# define R300_CLIP_OUT (1 << 0)
758# define R300_CLIP_0 (1 << 1)
759# define R300_CLIP_1 (1 << 2)
760# define R300_CLIP_10 (1 << 3)
761# define R300_CLIP_2 (1 << 4)
762# define R300_CLIP_20 (1 << 5)
763# define R300_CLIP_21 (1 << 6)
764# define R300_CLIP_210 (1 << 7)
765# define R300_CLIP_3 (1 << 8)
766# define R300_CLIP_30 (1 << 9)
767# define R300_CLIP_31 (1 << 10)
768# define R300_CLIP_310 (1 << 11)
769# define R300_CLIP_32 (1 << 12)
770# define R300_CLIP_320 (1 << 13)
771# define R300_CLIP_321 (1 << 14)
772# define R300_CLIP_3210 (1 << 15)
773
774/* gap */
775
776#define R300_RE_SCISSORS_TL 0x43E0
777#define R300_RE_SCISSORS_BR 0x43E4
778# define R300_SCISSORS_OFFSET 1440
779# define R300_SCISSORS_X_SHIFT 0
780# define R300_SCISSORS_X_MASK (0x1FFF << 0)
781# define R300_SCISSORS_Y_SHIFT 13
782# define R300_SCISSORS_Y_MASK (0x1FFF << 13)
783/* END: Scissors and cliprects */
784
785/* BEGIN: Texture specification */
786
787/*
788 * The texture specification dwords are grouped by meaning and not by texture
789 * unit. This means that e.g. the offset for texture image unit N is found in
790 * register TX_OFFSET_0 + (4*N)
791 */
792#define R300_TX_FILTER_0 0x4400
793# define R300_TX_REPEAT 0
794# define R300_TX_MIRRORED 1
795# define R300_TX_CLAMP 4
796# define R300_TX_CLAMP_TO_EDGE 2
797# define R300_TX_CLAMP_TO_BORDER 6
798# define R300_TX_WRAP_S_SHIFT 0
799# define R300_TX_WRAP_S_MASK (7 << 0)
800# define R300_TX_WRAP_T_SHIFT 3
801# define R300_TX_WRAP_T_MASK (7 << 3)
802# define R300_TX_WRAP_Q_SHIFT 6
803# define R300_TX_WRAP_Q_MASK (7 << 6)
804# define R300_TX_MAG_FILTER_NEAREST (1 << 9)
805# define R300_TX_MAG_FILTER_LINEAR (2 << 9)
806# define R300_TX_MAG_FILTER_MASK (3 << 9)
807# define R300_TX_MIN_FILTER_NEAREST (1 << 11)
808# define R300_TX_MIN_FILTER_LINEAR (2 << 11)
809# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11)
810# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11)
811# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11)
812# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11)
813
814/* NOTE: NEAREST doesnt seem to exist.
815 * Im not seting MAG_FILTER_MASK and (3 << 11) on for all
816 * anisotropy modes because that would void selected mag filter
817 */
818# define R300_TX_MIN_FILTER_ANISO_NEAREST (0 << 13)
819# define R300_TX_MIN_FILTER_ANISO_LINEAR (0 << 13)
820# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (1 << 13)
821# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (2 << 13)
822# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) )
823# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21)
824# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21)
825# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21)
826# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21)
827# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21)
828# define R300_TX_MAX_ANISO_MASK (14 << 21)
829
830#define R300_TX_FILTER1_0 0x4440
831# define R300_CHROMA_KEY_MODE_DISABLE 0
832# define R300_CHROMA_KEY_FORCE 1
833# define R300_CHROMA_KEY_BLEND 2
834# define R300_MC_ROUND_NORMAL (0<<2)
835# define R300_MC_ROUND_MPEG4 (1<<2)
836# define R300_LOD_BIAS_MASK 0x1fff
837# define R300_EDGE_ANISO_EDGE_DIAG (0<<13)
838# define R300_EDGE_ANISO_EDGE_ONLY (1<<13)
839# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14)
840# define R300_MC_COORD_TRUNCATE_MPEG (1<<14)
841# define R300_TX_TRI_PERF_0_8 (0<<15)
842# define R300_TX_TRI_PERF_1_8 (1<<15)
843# define R300_TX_TRI_PERF_1_4 (2<<15)
844# define R300_TX_TRI_PERF_3_8 (3<<15)
845# define R300_ANISO_THRESHOLD_MASK (7<<17)
846
847#define R300_TX_SIZE_0 0x4480
848# define R300_TX_WIDTHMASK_SHIFT 0
849# define R300_TX_WIDTHMASK_MASK (2047 << 0)
850# define R300_TX_HEIGHTMASK_SHIFT 11
851# define R300_TX_HEIGHTMASK_MASK (2047 << 11)
852# define R300_TX_UNK23 (1 << 23)
853# define R300_TX_MAX_MIP_LEVEL_SHIFT 26
854# define R300_TX_MAX_MIP_LEVEL_MASK (0xf << 26)
855# define R300_TX_SIZE_PROJECTED (1<<30)
856# define R300_TX_SIZE_TXPITCH_EN (1<<31)
857#define R300_TX_FORMAT_0 0x44C0
858 /* The interpretation of the format word by Wladimir van der Laan */
859 /* The X, Y, Z and W refer to the layout of the components.
860 They are given meanings as R, G, B and Alpha by the swizzle
861 specification */
862# define R300_TX_FORMAT_X8 0x0
863# define R300_TX_FORMAT_X16 0x1
864# define R300_TX_FORMAT_Y4X4 0x2
865# define R300_TX_FORMAT_Y8X8 0x3
866# define R300_TX_FORMAT_Y16X16 0x4
867# define R300_TX_FORMAT_Z3Y3X2 0x5
868# define R300_TX_FORMAT_Z5Y6X5 0x6
869# define R300_TX_FORMAT_Z6Y5X5 0x7
870# define R300_TX_FORMAT_Z11Y11X10 0x8
871# define R300_TX_FORMAT_Z10Y11X11 0x9
872# define R300_TX_FORMAT_W4Z4Y4X4 0xA
873# define R300_TX_FORMAT_W1Z5Y5X5 0xB
874# define R300_TX_FORMAT_W8Z8Y8X8 0xC
875# define R300_TX_FORMAT_W2Z10Y10X10 0xD
876# define R300_TX_FORMAT_W16Z16Y16X16 0xE
877# define R300_TX_FORMAT_DXT1 0xF
878# define R300_TX_FORMAT_DXT3 0x10
879# define R300_TX_FORMAT_DXT5 0x11
880# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
881# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
882# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
883# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
884 /* 0x16 - some 16 bit green format.. ?? */
885# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
886# define R300_TX_FORMAT_CUBIC_MAP (1 << 26)
887
888 /* gap */
889 /* Floating point formats */
890 /* Note - hardware supports both 16 and 32 bit floating point */
891# define R300_TX_FORMAT_FL_I16 0x18
892# define R300_TX_FORMAT_FL_I16A16 0x19
893# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A
894# define R300_TX_FORMAT_FL_I32 0x1B
895# define R300_TX_FORMAT_FL_I32A32 0x1C
896# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D
897 /* alpha modes, convenience mostly */
898 /* if you have alpha, pick constant appropriate to the
899 number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
900# define R300_TX_FORMAT_ALPHA_1CH 0x000
901# define R300_TX_FORMAT_ALPHA_2CH 0x200
902# define R300_TX_FORMAT_ALPHA_4CH 0x600
903# define R300_TX_FORMAT_ALPHA_NONE 0xA00
904 /* Swizzling */
905 /* constants */
906# define R300_TX_FORMAT_X 0
907# define R300_TX_FORMAT_Y 1
908# define R300_TX_FORMAT_Z 2
909# define R300_TX_FORMAT_W 3
910# define R300_TX_FORMAT_ZERO 4
911# define R300_TX_FORMAT_ONE 5
912 /* 2.0*Z, everything above 1.0 is set to 0.0 */
913# define R300_TX_FORMAT_CUT_Z 6
914 /* 2.0*W, everything above 1.0 is set to 0.0 */
915# define R300_TX_FORMAT_CUT_W 7
916
917# define R300_TX_FORMAT_B_SHIFT 18
918# define R300_TX_FORMAT_G_SHIFT 15
919# define R300_TX_FORMAT_R_SHIFT 12
920# define R300_TX_FORMAT_A_SHIFT 9
921 /* Convenience macro to take care of layout and swizzling */
922# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) ( \
923 ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT) \
924 | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \
925 | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \
926 | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \
927 | (R300_TX_FORMAT_##FMT) \
928 )
929 /* These can be ORed with result of R300_EASY_TX_FORMAT()
930 We don't really know what they do. Take values from a
931 constant color ? */
932# define R300_TX_FORMAT_CONST_X (1<<5)
933# define R300_TX_FORMAT_CONST_Y (2<<5)
934# define R300_TX_FORMAT_CONST_Z (4<<5)
935# define R300_TX_FORMAT_CONST_W (8<<5)
936
937# define R300_TX_FORMAT_YUV_MODE 0x00800000
938
939#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */
940#define R300_TX_OFFSET_0 0x4540
941 /* BEGIN: Guess from R200 */
942# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
943# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
944# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
945# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
946# define R300_TXO_MACRO_TILE (1 << 2)
947# define R300_TXO_MICRO_TILE (1 << 3)
948# define R300_TXO_OFFSET_MASK 0xffffffe0
949# define R300_TXO_OFFSET_SHIFT 5
950 /* END: Guess from R200 */
951
952/* 32 bit chroma key */
953#define R300_TX_CHROMA_KEY_0 0x4580
954/* ff00ff00 == { 0, 1.0, 0, 1.0 } */
955#define R300_TX_BORDER_COLOR_0 0x45C0
956
957/* END: Texture specification */
958
959/* BEGIN: Fragment program instruction set */
960
961/* Fragment programs are written directly into register space.
962 * There are separate instruction streams for texture instructions and ALU
963 * instructions.
964 * In order to synchronize these streams, the program is divided into up
965 * to 4 nodes. Each node begins with a number of TEX operations, followed
966 * by a number of ALU operations.
967 * The first node can have zero TEX ops, all subsequent nodes must have at
968 * least
969 * one TEX ops.
970 * All nodes must have at least one ALU op.
971 *
972 * The index of the last node is stored in PFS_CNTL_0: A value of 0 means
973 * 1 node, a value of 3 means 4 nodes.
974 * The total amount of instructions is defined in PFS_CNTL_2. The offsets are
975 * offsets into the respective instruction streams, while *_END points to the
976 * last instruction relative to this offset.
977 */
978#define R300_PFS_CNTL_0 0x4600
979# define R300_PFS_CNTL_LAST_NODES_SHIFT 0
980# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0)
981# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3)
982#define R300_PFS_CNTL_1 0x4604
983/* There is an unshifted value here which has so far always been equal to the
984 * index of the highest used temporary register.
985 */
986#define R300_PFS_CNTL_2 0x4608
987# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0
988# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0)
989# define R300_PFS_CNTL_ALU_END_SHIFT 6
990# define R300_PFS_CNTL_ALU_END_MASK (63 << 6)
991# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
992# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
993# define R300_PFS_CNTL_TEX_END_SHIFT 18
994# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
995
996/* gap */
997
998/* Nodes are stored backwards. The last active node is always stored in
999 * PFS_NODE_3.
1000 * Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The
1001 * first node is stored in NODE_2, the second node is stored in NODE_3.
1002 *
1003 * Offsets are relative to the master offset from PFS_CNTL_2.
1004 */
1005#define R300_PFS_NODE_0 0x4610
1006#define R300_PFS_NODE_1 0x4614
1007#define R300_PFS_NODE_2 0x4618
1008#define R300_PFS_NODE_3 0x461C
1009# define R300_PFS_NODE_ALU_OFFSET_SHIFT 0
1010# define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0)
1011# define R300_PFS_NODE_ALU_END_SHIFT 6
1012# define R300_PFS_NODE_ALU_END_MASK (63 << 6)
1013# define R300_PFS_NODE_TEX_OFFSET_SHIFT 12
1014# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
1015# define R300_PFS_NODE_TEX_END_SHIFT 17
1016# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
1017# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22)
1018# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23)
1019
1020/* TEX
1021 * As far as I can tell, texture instructions cannot write into output
1022 * registers directly. A subsequent ALU instruction is always necessary,
1023 * even if it's just MAD o0, r0, 1, 0
1024 */
1025#define R300_PFS_TEXI_0 0x4620
1026# define R300_FPITX_SRC_SHIFT 0
1027# define R300_FPITX_SRC_MASK (31 << 0)
1028 /* GUESS */
1029# define R300_FPITX_SRC_CONST (1 << 5)
1030# define R300_FPITX_DST_SHIFT 6
1031# define R300_FPITX_DST_MASK (31 << 6)
1032# define R300_FPITX_IMAGE_SHIFT 11
1033 /* GUESS based on layout and native limits */
1034# define R300_FPITX_IMAGE_MASK (15 << 11)
1035/* Unsure if these are opcodes, or some kind of bitfield, but this is how
1036 * they were set when I checked
1037 */
1038# define R300_FPITX_OPCODE_SHIFT 15
1039# define R300_FPITX_OP_TEX 1
1040# define R300_FPITX_OP_KIL 2
1041# define R300_FPITX_OP_TXP 3
1042# define R300_FPITX_OP_TXB 4
1043# define R300_FPITX_OPCODE_MASK (7 << 15)
1044
1045/* ALU
1046 * The ALU instructions register blocks are enumerated according to the order
1047 * in which fglrx. I assume there is space for 64 instructions, since
1048 * each block has space for a maximum of 64 DWORDs, and this matches reported
1049 * native limits.
1050 *
1051 * The basic functional block seems to be one MAD for each color and alpha,
1052 * and an adder that adds all components after the MUL.
1053 * - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands
1054 * - DP4: Use OUTC_DP4, OUTA_DP4
1055 * - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands
1056 * - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands
1057 * - CMPH: If ARG2 > 0.5, return ARG0, else return ARG1
1058 * - CMP: If ARG2 < 0, return ARG1, else return ARG0
1059 * - FLR: use FRC+MAD
1060 * - XPD: use MAD+MAD
1061 * - SGE, SLT: use MAD+CMP
1062 * - RSQ: use ABS modifier for argument
1063 * - Use OUTC_REPL_ALPHA to write results of an alpha-only operation
1064 * (e.g. RCP) into color register
1065 * - apparently, there's no quick DST operation
1066 * - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2"
1067 * - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0"
1068 * - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1"
1069 *
1070 * Operand selection
1071 * First stage selects three sources from the available registers and
1072 * constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha).
1073 * fglrx sorts the three source fields: Registers before constants,
1074 * lower indices before higher indices; I do not know whether this is
1075 * necessary.
1076 *
1077 * fglrx fills unused sources with "read constant 0"
1078 * According to specs, you cannot select more than two different constants.
1079 *
1080 * Second stage selects the operands from the sources. This is defined in
1081 * INSTR0 (color) and INSTR2 (alpha). You can also select the special constants
1082 * zero and one.
1083 * Swizzling and negation happens in this stage, as well.
1084 *
1085 * Important: Color and alpha seem to be mostly separate, i.e. their sources
1086 * selection appears to be fully independent (the register storage is probably
1087 * physically split into a color and an alpha section).
1088 * However (because of the apparent physical split), there is some interaction
1089 * WRT swizzling. If, for example, you want to load an R component into an
1090 * Alpha operand, this R component is taken from a *color* source, not from
1091 * an alpha source. The corresponding register doesn't even have to appear in
1092 * the alpha sources list. (I hope this all makes sense to you)
1093 *
1094 * Destination selection
1095 * The destination register index is in FPI1 (color) and FPI3 (alpha)
1096 * together with enable bits.
1097 * There are separate enable bits for writing into temporary registers
1098 * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_*
1099 * /DSTA_OUTPUT). You can write to both at once, or not write at all (the
1100 * same index must be used for both).
1101 *
1102 * Note: There is a special form for LRP
1103 * - Argument order is the same as in ARB_fragment_program.
1104 * - Operation is MAD
1105 * - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP
1106 * - Set FPI0/FPI2_SPECIAL_LRP
1107 * Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD
1108 */
1109#define R300_PFS_INSTR1_0 0x46C0
1110# define R300_FPI1_SRC0C_SHIFT 0
1111# define R300_FPI1_SRC0C_MASK (31 << 0)
1112# define R300_FPI1_SRC0C_CONST (1 << 5)
1113# define R300_FPI1_SRC1C_SHIFT 6
1114# define R300_FPI1_SRC1C_MASK (31 << 6)
1115# define R300_FPI1_SRC1C_CONST (1 << 11)
1116# define R300_FPI1_SRC2C_SHIFT 12
1117# define R300_FPI1_SRC2C_MASK (31 << 12)
1118# define R300_FPI1_SRC2C_CONST (1 << 17)
1119# define R300_FPI1_SRC_MASK 0x0003ffff
1120# define R300_FPI1_DSTC_SHIFT 18
1121# define R300_FPI1_DSTC_MASK (31 << 18)
1122# define R300_FPI1_DSTC_REG_MASK_SHIFT 23
1123# define R300_FPI1_DSTC_REG_X (1 << 23)
1124# define R300_FPI1_DSTC_REG_Y (1 << 24)
1125# define R300_FPI1_DSTC_REG_Z (1 << 25)
1126# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26
1127# define R300_FPI1_DSTC_OUTPUT_X (1 << 26)
1128# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27)
1129# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28)
1130
1131#define R300_PFS_INSTR3_0 0x47C0
1132# define R300_FPI3_SRC0A_SHIFT 0
1133# define R300_FPI3_SRC0A_MASK (31 << 0)
1134# define R300_FPI3_SRC0A_CONST (1 << 5)
1135# define R300_FPI3_SRC1A_SHIFT 6
1136# define R300_FPI3_SRC1A_MASK (31 << 6)
1137# define R300_FPI3_SRC1A_CONST (1 << 11)
1138# define R300_FPI3_SRC2A_SHIFT 12
1139# define R300_FPI3_SRC2A_MASK (31 << 12)
1140# define R300_FPI3_SRC2A_CONST (1 << 17)
1141# define R300_FPI3_SRC_MASK 0x0003ffff
1142# define R300_FPI3_DSTA_SHIFT 18
1143# define R300_FPI3_DSTA_MASK (31 << 18)
1144# define R300_FPI3_DSTA_REG (1 << 23)
1145# define R300_FPI3_DSTA_OUTPUT (1 << 24)
1146# define R300_FPI3_DSTA_DEPTH (1 << 27)
1147
1148#define R300_PFS_INSTR0_0 0x48C0
1149# define R300_FPI0_ARGC_SRC0C_XYZ 0
1150# define R300_FPI0_ARGC_SRC0C_XXX 1
1151# define R300_FPI0_ARGC_SRC0C_YYY 2
1152# define R300_FPI0_ARGC_SRC0C_ZZZ 3
1153# define R300_FPI0_ARGC_SRC1C_XYZ 4
1154# define R300_FPI0_ARGC_SRC1C_XXX 5
1155# define R300_FPI0_ARGC_SRC1C_YYY 6
1156# define R300_FPI0_ARGC_SRC1C_ZZZ 7
1157# define R300_FPI0_ARGC_SRC2C_XYZ 8
1158# define R300_FPI0_ARGC_SRC2C_XXX 9
1159# define R300_FPI0_ARGC_SRC2C_YYY 10
1160# define R300_FPI0_ARGC_SRC2C_ZZZ 11
1161# define R300_FPI0_ARGC_SRC0A 12
1162# define R300_FPI0_ARGC_SRC1A 13
1163# define R300_FPI0_ARGC_SRC2A 14
1164# define R300_FPI0_ARGC_SRC1C_LRP 15
1165# define R300_FPI0_ARGC_ZERO 20
1166# define R300_FPI0_ARGC_ONE 21
1167 /* GUESS */
1168# define R300_FPI0_ARGC_HALF 22
1169# define R300_FPI0_ARGC_SRC0C_YZX 23
1170# define R300_FPI0_ARGC_SRC1C_YZX 24
1171# define R300_FPI0_ARGC_SRC2C_YZX 25
1172# define R300_FPI0_ARGC_SRC0C_ZXY 26
1173# define R300_FPI0_ARGC_SRC1C_ZXY 27
1174# define R300_FPI0_ARGC_SRC2C_ZXY 28
1175# define R300_FPI0_ARGC_SRC0CA_WZY 29
1176# define R300_FPI0_ARGC_SRC1CA_WZY 30
1177# define R300_FPI0_ARGC_SRC2CA_WZY 31
1178
1179# define R300_FPI0_ARG0C_SHIFT 0
1180# define R300_FPI0_ARG0C_MASK (31 << 0)
1181# define R300_FPI0_ARG0C_NEG (1 << 5)
1182# define R300_FPI0_ARG0C_ABS (1 << 6)
1183# define R300_FPI0_ARG1C_SHIFT 7
1184# define R300_FPI0_ARG1C_MASK (31 << 7)
1185# define R300_FPI0_ARG1C_NEG (1 << 12)
1186# define R300_FPI0_ARG1C_ABS (1 << 13)
1187# define R300_FPI0_ARG2C_SHIFT 14
1188# define R300_FPI0_ARG2C_MASK (31 << 14)
1189# define R300_FPI0_ARG2C_NEG (1 << 19)
1190# define R300_FPI0_ARG2C_ABS (1 << 20)
1191# define R300_FPI0_SPECIAL_LRP (1 << 21)
1192# define R300_FPI0_OUTC_MAD (0 << 23)
1193# define R300_FPI0_OUTC_DP3 (1 << 23)
1194# define R300_FPI0_OUTC_DP4 (2 << 23)
1195# define R300_FPI0_OUTC_MIN (4 << 23)
1196# define R300_FPI0_OUTC_MAX (5 << 23)
1197# define R300_FPI0_OUTC_CMPH (7 << 23)
1198# define R300_FPI0_OUTC_CMP (8 << 23)
1199# define R300_FPI0_OUTC_FRC (9 << 23)
1200# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23)
1201# define R300_FPI0_OUTC_SAT (1 << 30)
1202# define R300_FPI0_INSERT_NOP (1 << 31)
1203
1204#define R300_PFS_INSTR2_0 0x49C0
1205# define R300_FPI2_ARGA_SRC0C_X 0
1206# define R300_FPI2_ARGA_SRC0C_Y 1
1207# define R300_FPI2_ARGA_SRC0C_Z 2
1208# define R300_FPI2_ARGA_SRC1C_X 3
1209# define R300_FPI2_ARGA_SRC1C_Y 4
1210# define R300_FPI2_ARGA_SRC1C_Z 5
1211# define R300_FPI2_ARGA_SRC2C_X 6
1212# define R300_FPI2_ARGA_SRC2C_Y 7
1213# define R300_FPI2_ARGA_SRC2C_Z 8
1214# define R300_FPI2_ARGA_SRC0A 9
1215# define R300_FPI2_ARGA_SRC1A 10
1216# define R300_FPI2_ARGA_SRC2A 11
1217# define R300_FPI2_ARGA_SRC1A_LRP 15
1218# define R300_FPI2_ARGA_ZERO 16
1219# define R300_FPI2_ARGA_ONE 17
1220 /* GUESS */
1221# define R300_FPI2_ARGA_HALF 18
1222# define R300_FPI2_ARG0A_SHIFT 0
1223# define R300_FPI2_ARG0A_MASK (31 << 0)
1224# define R300_FPI2_ARG0A_NEG (1 << 5)
1225 /* GUESS */
1226# define R300_FPI2_ARG0A_ABS (1 << 6)
1227# define R300_FPI2_ARG1A_SHIFT 7
1228# define R300_FPI2_ARG1A_MASK (31 << 7)
1229# define R300_FPI2_ARG1A_NEG (1 << 12)
1230 /* GUESS */
1231# define R300_FPI2_ARG1A_ABS (1 << 13)
1232# define R300_FPI2_ARG2A_SHIFT 14
1233# define R300_FPI2_ARG2A_MASK (31 << 14)
1234# define R300_FPI2_ARG2A_NEG (1 << 19)
1235 /* GUESS */
1236# define R300_FPI2_ARG2A_ABS (1 << 20)
1237# define R300_FPI2_SPECIAL_LRP (1 << 21)
1238# define R300_FPI2_OUTA_MAD (0 << 23)
1239# define R300_FPI2_OUTA_DP4 (1 << 23)
1240# define R300_FPI2_OUTA_MIN (2 << 23)
1241# define R300_FPI2_OUTA_MAX (3 << 23)
1242# define R300_FPI2_OUTA_CMP (6 << 23)
1243# define R300_FPI2_OUTA_FRC (7 << 23)
1244# define R300_FPI2_OUTA_EX2 (8 << 23)
1245# define R300_FPI2_OUTA_LG2 (9 << 23)
1246# define R300_FPI2_OUTA_RCP (10 << 23)
1247# define R300_FPI2_OUTA_RSQ (11 << 23)
1248# define R300_FPI2_OUTA_SAT (1 << 30)
1249# define R300_FPI2_UNKNOWN_31 (1 << 31)
1250/* END: Fragment program instruction set */
1251
1252/* Fog state and color */
1253#define R300_RE_FOG_STATE 0x4BC0
1254# define R300_FOG_ENABLE (1 << 0)
1255# define R300_FOG_MODE_LINEAR (0 << 1)
1256# define R300_FOG_MODE_EXP (1 << 1)
1257# define R300_FOG_MODE_EXP2 (2 << 1)
1258# define R300_FOG_MODE_MASK (3 << 1)
1259#define R300_FOG_COLOR_R 0x4BC8
1260#define R300_FOG_COLOR_G 0x4BCC
1261#define R300_FOG_COLOR_B 0x4BD0
1262
1263#define R300_PP_ALPHA_TEST 0x4BD4
1264# define R300_REF_ALPHA_MASK 0x000000ff
1265# define R300_ALPHA_TEST_FAIL (0 << 8)
1266# define R300_ALPHA_TEST_LESS (1 << 8)
1267# define R300_ALPHA_TEST_LEQUAL (3 << 8)
1268# define R300_ALPHA_TEST_EQUAL (2 << 8)
1269# define R300_ALPHA_TEST_GEQUAL (6 << 8)
1270# define R300_ALPHA_TEST_GREATER (4 << 8)
1271# define R300_ALPHA_TEST_NEQUAL (5 << 8)
1272# define R300_ALPHA_TEST_PASS (7 << 8)
1273# define R300_ALPHA_TEST_OP_MASK (7 << 8)
1274# define R300_ALPHA_TEST_ENABLE (1 << 11)
1275
1276/* gap */
1277
1278/* Fragment program parameters in 7.16 floating point */
1279#define R300_PFS_PARAM_0_X 0x4C00
1280#define R300_PFS_PARAM_0_Y 0x4C04
1281#define R300_PFS_PARAM_0_Z 0x4C08
1282#define R300_PFS_PARAM_0_W 0x4C0C
1283/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */
1284#define R300_PFS_PARAM_31_X 0x4DF0
1285#define R300_PFS_PARAM_31_Y 0x4DF4
1286#define R300_PFS_PARAM_31_Z 0x4DF8
1287#define R300_PFS_PARAM_31_W 0x4DFC
1288
1289/* Notes:
1290 * - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in
1291 * the application
1292 * - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND
1293 * are set to the same
1294 * function (both registers are always set up completely in any case)
1295 * - Most blend flags are simply copied from R200 and not tested yet
1296 */
1297#define R300_RB3D_CBLEND 0x4E04
1298#define R300_RB3D_ABLEND 0x4E08
1299/* the following only appear in CBLEND */
1300# define R300_BLEND_ENABLE (1 << 0)
1301# define R300_BLEND_UNKNOWN (3 << 1)
1302# define R300_BLEND_NO_SEPARATE (1 << 3)
1303/* the following are shared between CBLEND and ABLEND */
1304# define R300_FCN_MASK (3 << 12)
1305# define R300_COMB_FCN_ADD_CLAMP (0 << 12)
1306# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12)
1307# define R300_COMB_FCN_SUB_CLAMP (2 << 12)
1308# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12)
1309# define R300_COMB_FCN_MIN (4 << 12)
1310# define R300_COMB_FCN_MAX (5 << 12)
1311# define R300_COMB_FCN_RSUB_CLAMP (6 << 12)
1312# define R300_COMB_FCN_RSUB_NOCLAMP (7 << 12)
1313# define R300_BLEND_GL_ZERO (32)
1314# define R300_BLEND_GL_ONE (33)
1315# define R300_BLEND_GL_SRC_COLOR (34)
1316# define R300_BLEND_GL_ONE_MINUS_SRC_COLOR (35)
1317# define R300_BLEND_GL_DST_COLOR (36)
1318# define R300_BLEND_GL_ONE_MINUS_DST_COLOR (37)
1319# define R300_BLEND_GL_SRC_ALPHA (38)
1320# define R300_BLEND_GL_ONE_MINUS_SRC_ALPHA (39)
1321# define R300_BLEND_GL_DST_ALPHA (40)
1322# define R300_BLEND_GL_ONE_MINUS_DST_ALPHA (41)
1323# define R300_BLEND_GL_SRC_ALPHA_SATURATE (42)
1324# define R300_BLEND_GL_CONST_COLOR (43)
1325# define R300_BLEND_GL_ONE_MINUS_CONST_COLOR (44)
1326# define R300_BLEND_GL_CONST_ALPHA (45)
1327# define R300_BLEND_GL_ONE_MINUS_CONST_ALPHA (46)
1328# define R300_BLEND_MASK (63)
1329# define R300_SRC_BLEND_SHIFT (16)
1330# define R300_DST_BLEND_SHIFT (24)
1331#define R300_RB3D_BLEND_COLOR 0x4E10
1332#define R300_RB3D_COLORMASK 0x4E0C
1333# define R300_COLORMASK0_B (1<<0)
1334# define R300_COLORMASK0_G (1<<1)
1335# define R300_COLORMASK0_R (1<<2)
1336# define R300_COLORMASK0_A (1<<3)
1337
1338/* gap */
1339
1340#define R300_RB3D_COLOROFFSET0 0x4E28
1341# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
1342#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
1343#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
1344#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
1345
1346/* gap */
1347
1348/* Bit 16: Larger tiles
1349 * Bit 17: 4x2 tiles
1350 * Bit 18: Extremely weird tile like, but some pixels duplicated?
1351 */
1352#define R300_RB3D_COLORPITCH0 0x4E38
1353# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
1354# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
1355# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
1356# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
1357# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
1358# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
1359# define R300_COLOR_FORMAT_RGB565 (2 << 22)
1360# define R300_COLOR_FORMAT_ARGB8888 (3 << 22)
1361#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
1362#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
1363#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
1364
1365/* gap */
1366
1367/* Guess by Vladimir.
1368 * Set to 0A before 3D operations, set to 02 afterwards.
1369 */
1370/*#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C*/
1371# define R300_RB3D_DSTCACHE_UNKNOWN_02 0x00000002
1372# define R300_RB3D_DSTCACHE_UNKNOWN_0A 0x0000000A
1373
1374/* gap */
1375/* There seems to be no "write only" setting, so use Z-test = ALWAYS
1376 * for this.
1377 * Bit (1<<8) is the "test" bit. so plain write is 6 - vd
1378 */
1379#define R300_ZB_CNTL 0x4F00
1380# define R300_STENCIL_ENABLE (1 << 0)
1381# define R300_Z_ENABLE (1 << 1)
1382# define R300_Z_WRITE_ENABLE (1 << 2)
1383# define R300_Z_SIGNED_COMPARE (1 << 3)
1384# define R300_STENCIL_FRONT_BACK (1 << 4)
1385
1386#define R300_ZB_ZSTENCILCNTL 0x4f04
1387 /* functions */
1388# define R300_ZS_NEVER 0
1389# define R300_ZS_LESS 1
1390# define R300_ZS_LEQUAL 2
1391# define R300_ZS_EQUAL 3
1392# define R300_ZS_GEQUAL 4
1393# define R300_ZS_GREATER 5
1394# define R300_ZS_NOTEQUAL 6
1395# define R300_ZS_ALWAYS 7
1396# define R300_ZS_MASK 7
1397 /* operations */
1398# define R300_ZS_KEEP 0
1399# define R300_ZS_ZERO 1
1400# define R300_ZS_REPLACE 2
1401# define R300_ZS_INCR 3
1402# define R300_ZS_DECR 4
1403# define R300_ZS_INVERT 5
1404# define R300_ZS_INCR_WRAP 6
1405# define R300_ZS_DECR_WRAP 7
1406# define R300_Z_FUNC_SHIFT 0
1407 /* front and back refer to operations done for front
1408 and back faces, i.e. separate stencil function support */
1409# define R300_S_FRONT_FUNC_SHIFT 3
1410# define R300_S_FRONT_SFAIL_OP_SHIFT 6
1411# define R300_S_FRONT_ZPASS_OP_SHIFT 9
1412# define R300_S_FRONT_ZFAIL_OP_SHIFT 12
1413# define R300_S_BACK_FUNC_SHIFT 15
1414# define R300_S_BACK_SFAIL_OP_SHIFT 18
1415# define R300_S_BACK_ZPASS_OP_SHIFT 21
1416# define R300_S_BACK_ZFAIL_OP_SHIFT 24
1417
1418#define R300_ZB_STENCILREFMASK 0x4f08
1419# define R300_STENCILREF_SHIFT 0
1420# define R300_STENCILREF_MASK 0x000000ff
1421# define R300_STENCILMASK_SHIFT 8
1422# define R300_STENCILMASK_MASK 0x0000ff00
1423# define R300_STENCILWRITEMASK_SHIFT 16
1424# define R300_STENCILWRITEMASK_MASK 0x00ff0000
1425
1426/* gap */
1427
1428#define R300_ZB_FORMAT 0x4f10
1429# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0)
1430# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0)
1431# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0)
1432/* reserved up to (15 << 0) */
1433# define R300_INVERT_13E3_LEADING_ONES (0 << 4)
1434# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4)
1435
1436#define R300_ZB_ZTOP 0x4F14
1437# define R300_ZTOP_DISABLE (0 << 0)
1438# define R300_ZTOP_ENABLE (1 << 0)
1439
1440/* gap */
1441
1442#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
1443# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0)
1444# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0)
1445# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1)
1446# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1)
1447# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31)
1448# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31)
1449
1450#define R300_ZB_BW_CNTL 0x4f1c
1451# define R300_HIZ_DISABLE (0 << 0)
1452# define R300_HIZ_ENABLE (1 << 0)
1453# define R300_HIZ_MIN (0 << 1)
1454# define R300_HIZ_MAX (1 << 1)
1455# define R300_FAST_FILL_DISABLE (0 << 2)
1456# define R300_FAST_FILL_ENABLE (1 << 2)
1457# define R300_RD_COMP_DISABLE (0 << 3)
1458# define R300_RD_COMP_ENABLE (1 << 3)
1459# define R300_WR_COMP_DISABLE (0 << 4)
1460# define R300_WR_COMP_ENABLE (1 << 4)
1461# define R300_ZB_CB_CLEAR_RMW (0 << 5)
1462# define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5)
1463# define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6)
1464# define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6)
1465
1466# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7)
1467# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7)
1468# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8)
1469# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8)
1470
1471# define R500_BMASK_ENABLE (0 << 10)
1472# define R500_BMASK_DISABLE (1 << 10)
1473# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11)
1474# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11)
1475# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12)
1476# define R500_HIZ_FP_EXP_BITS_1 (1 << 12)
1477# define R500_HIZ_FP_EXP_BITS_2 (2 << 12)
1478# define R500_HIZ_FP_EXP_BITS_3 (3 << 12)
1479# define R500_HIZ_FP_EXP_BITS_4 (4 << 12)
1480# define R500_HIZ_FP_EXP_BITS_5 (5 << 12)
1481# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15)
1482# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15)
1483# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16)
1484# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16)
1485# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17)
1486# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17)
1487# define R500_PEQ_PACKING_DISABLE (0 << 18)
1488# define R500_PEQ_PACKING_ENABLE (1 << 18)
1489# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18)
1490# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18)
1491
1492
1493/* gap */
1494
1495/* Z Buffer Address Offset.
1496 * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles.
1497 */
1498#define R300_ZB_DEPTHOFFSET 0x4f20
1499
1500/* Z Buffer Pitch and Endian Control */
1501#define R300_ZB_DEPTHPITCH 0x4f24
1502# define R300_DEPTHPITCH_MASK 0x00003FFC
1503# define R300_DEPTHMACROTILE_DISABLE (0 << 16)
1504# define R300_DEPTHMACROTILE_ENABLE (1 << 16)
1505# define R300_DEPTHMICROTILE_LINEAR (0 << 17)
1506# define R300_DEPTHMICROTILE_TILED (1 << 17)
1507# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17)
1508# define R300_DEPTHENDIAN_NO_SWAP (0 << 18)
1509# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18)
1510# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18)
1511# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18)
1512
1513/* Z Buffer Clear Value */
1514#define R300_ZB_DEPTHCLEARVALUE 0x4f28
1515
1516#define R300_ZB_ZMASK_OFFSET 0x4f30
1517#define R300_ZB_ZMASK_PITCH 0x4f34
1518#define R300_ZB_ZMASK_WRINDEX 0x4f38
1519#define R300_ZB_ZMASK_DWORD 0x4f3c
1520#define R300_ZB_ZMASK_RDINDEX 0x4f40
1521
1522/* Hierarchical Z Memory Offset */
1523#define R300_ZB_HIZ_OFFSET 0x4f44
1524
1525/* Hierarchical Z Write Index */
1526#define R300_ZB_HIZ_WRINDEX 0x4f48
1527
1528/* Hierarchical Z Data */
1529#define R300_ZB_HIZ_DWORD 0x4f4c
1530
1531/* Hierarchical Z Read Index */
1532#define R300_ZB_HIZ_RDINDEX 0x4f50
1533
1534/* Hierarchical Z Pitch */
1535#define R300_ZB_HIZ_PITCH 0x4f54
1536
1537/* Z Buffer Z Pass Counter Data */
1538#define R300_ZB_ZPASS_DATA 0x4f58
1539
1540/* Z Buffer Z Pass Counter Address */
1541#define R300_ZB_ZPASS_ADDR 0x4f5c
1542
1543/* Depth buffer X and Y coordinate offset */
1544#define R300_ZB_DEPTHXY_OFFSET 0x4f60
1545# define R300_DEPTHX_OFFSET_SHIFT 1
1546# define R300_DEPTHX_OFFSET_MASK 0x000007FE
1547# define R300_DEPTHY_OFFSET_SHIFT 17
1548# define R300_DEPTHY_OFFSET_MASK 0x07FE0000
1549
1550/* Sets the fifo sizes */
1551#define R500_ZB_FIFO_SIZE 0x4fd0
1552# define R500_OP_FIFO_SIZE_FULL (0 << 0)
1553# define R500_OP_FIFO_SIZE_HALF (1 << 0)
1554# define R500_OP_FIFO_SIZE_QUATER (2 << 0)
1555# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0)
1556
1557/* Stencil Reference Value and Mask for backfacing quads */
1558/* R300_ZB_STENCILREFMASK handles front face */
1559#define R500_ZB_STENCILREFMASK_BF 0x4fd4
1560# define R500_STENCILREF_SHIFT 0
1561# define R500_STENCILREF_MASK 0x000000ff
1562# define R500_STENCILMASK_SHIFT 8
1563# define R500_STENCILMASK_MASK 0x0000ff00
1564# define R500_STENCILWRITEMASK_SHIFT 16
1565# define R500_STENCILWRITEMASK_MASK 0x00ff0000
1566
1567/* BEGIN: Vertex program instruction set */
1568
1569/* Every instruction is four dwords long:
1570 * DWORD 0: output and opcode
1571 * DWORD 1: first argument
1572 * DWORD 2: second argument
1573 * DWORD 3: third argument
1574 *
1575 * Notes:
1576 * - ABS r, a is implemented as MAX r, a, -a
1577 * - MOV is implemented as ADD to zero
1578 * - XPD is implemented as MUL + MAD
1579 * - FLR is implemented as FRC + ADD
1580 * - apparently, fglrx tries to schedule instructions so that there is at
1581 * least one instruction between the write to a temporary and the first
1582 * read from said temporary; however, violations of this scheduling are
1583 * allowed
1584 * - register indices seem to be unrelated with OpenGL aliasing to
1585 * conventional state
1586 * - only one attribute and one parameter can be loaded at a time; however,
1587 * the same attribute/parameter can be used for more than one argument
1588 * - the second software argument for POW is the third hardware argument
1589 * (no idea why)
1590 * - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2
1591 *
1592 * There is some magic surrounding LIT:
1593 * The single argument is replicated across all three inputs, but swizzled:
1594 * First argument: xyzy
1595 * Second argument: xyzx
1596 * Third argument: xyzw
1597 * Whenever the result is used later in the fragment program, fglrx forces
1598 * x and w to be 1.0 in the input selection; I don't know whether this is
1599 * strictly necessary
1600 */
1601#define R300_VPI_OUT_OP_DOT (1 << 0)
1602#define R300_VPI_OUT_OP_MUL (2 << 0)
1603#define R300_VPI_OUT_OP_ADD (3 << 0)
1604#define R300_VPI_OUT_OP_MAD (4 << 0)
1605#define R300_VPI_OUT_OP_DST (5 << 0)
1606#define R300_VPI_OUT_OP_FRC (6 << 0)
1607#define R300_VPI_OUT_OP_MAX (7 << 0)
1608#define R300_VPI_OUT_OP_MIN (8 << 0)
1609#define R300_VPI_OUT_OP_SGE (9 << 0)
1610#define R300_VPI_OUT_OP_SLT (10 << 0)
1611 /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
1612#define R300_VPI_OUT_OP_UNK12 (12 << 0)
1613#define R300_VPI_OUT_OP_ARL (13 << 0)
1614#define R300_VPI_OUT_OP_EXP (65 << 0)
1615#define R300_VPI_OUT_OP_LOG (66 << 0)
1616 /* Used in fog computations, scalar(scalar) */
1617#define R300_VPI_OUT_OP_UNK67 (67 << 0)
1618#define R300_VPI_OUT_OP_LIT (68 << 0)
1619#define R300_VPI_OUT_OP_POW (69 << 0)
1620#define R300_VPI_OUT_OP_RCP (70 << 0)
1621#define R300_VPI_OUT_OP_RSQ (72 << 0)
1622 /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
1623#define R300_VPI_OUT_OP_UNK73 (73 << 0)
1624#define R300_VPI_OUT_OP_EX2 (75 << 0)
1625#define R300_VPI_OUT_OP_LG2 (76 << 0)
1626#define R300_VPI_OUT_OP_MAD_2 (128 << 0)
1627 /* all temps, vector(scalar, vector, vector) */
1628#define R300_VPI_OUT_OP_UNK129 (129 << 0)
1629
1630#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8)
1631#define R300_VPI_OUT_REG_CLASS_ADDR (1 << 8)
1632#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8)
1633#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8)
1634
1635#define R300_VPI_OUT_REG_INDEX_SHIFT 13
1636 /* GUESS based on fglrx native limits */
1637#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13)
1638
1639#define R300_VPI_OUT_WRITE_X (1 << 20)
1640#define R300_VPI_OUT_WRITE_Y (1 << 21)
1641#define R300_VPI_OUT_WRITE_Z (1 << 22)
1642#define R300_VPI_OUT_WRITE_W (1 << 23)
1643
1644#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0)
1645#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
1646#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
1647#define R300_VPI_IN_REG_CLASS_NONE (9 << 0)
1648#define R300_VPI_IN_REG_CLASS_MASK (31 << 0)
1649
1650#define R300_VPI_IN_REG_INDEX_SHIFT 5
1651 /* GUESS based on fglrx native limits */
1652#define R300_VPI_IN_REG_INDEX_MASK (255 << 5)
1653
1654/* The R300 can select components from the input register arbitrarily.
1655 * Use the following constants, shifted by the component shift you
1656 * want to select
1657 */
1658#define R300_VPI_IN_SELECT_X 0
1659#define R300_VPI_IN_SELECT_Y 1
1660#define R300_VPI_IN_SELECT_Z 2
1661#define R300_VPI_IN_SELECT_W 3
1662#define R300_VPI_IN_SELECT_ZERO 4
1663#define R300_VPI_IN_SELECT_ONE 5
1664#define R300_VPI_IN_SELECT_MASK 7
1665
1666#define R300_VPI_IN_X_SHIFT 13
1667#define R300_VPI_IN_Y_SHIFT 16
1668#define R300_VPI_IN_Z_SHIFT 19
1669#define R300_VPI_IN_W_SHIFT 22
1670
1671#define R300_VPI_IN_NEG_X (1 << 25)
1672#define R300_VPI_IN_NEG_Y (1 << 26)
1673#define R300_VPI_IN_NEG_Z (1 << 27)
1674#define R300_VPI_IN_NEG_W (1 << 28)
1675/* END: Vertex program instruction set */
1676
1677/* BEGIN: Packet 3 commands */
1678
1679/* A primitive emission dword. */
1680#define R300_PRIM_TYPE_NONE (0 << 0)
1681#define R300_PRIM_TYPE_POINT (1 << 0)
1682#define R300_PRIM_TYPE_LINE (2 << 0)
1683#define R300_PRIM_TYPE_LINE_STRIP (3 << 0)
1684#define R300_PRIM_TYPE_TRI_LIST (4 << 0)
1685#define R300_PRIM_TYPE_TRI_FAN (5 << 0)
1686#define R300_PRIM_TYPE_TRI_STRIP (6 << 0)
1687#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0)
1688#define R300_PRIM_TYPE_RECT_LIST (8 << 0)
1689#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
1690#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
1691 /* GUESS (based on r200) */
1692#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0)
1693#define R300_PRIM_TYPE_LINE_LOOP (12 << 0)
1694#define R300_PRIM_TYPE_QUADS (13 << 0)
1695#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0)
1696#define R300_PRIM_TYPE_POLYGON (15 << 0)
1697#define R300_PRIM_TYPE_MASK 0xF
1698#define R300_PRIM_WALK_IND (1 << 4)
1699#define R300_PRIM_WALK_LIST (2 << 4)
1700#define R300_PRIM_WALK_RING (3 << 4)
1701#define R300_PRIM_WALK_MASK (3 << 4)
1702 /* GUESS (based on r200) */
1703#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6)
1704#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6)
1705#define R300_PRIM_NUM_VERTICES_SHIFT 16
1706#define R300_PRIM_NUM_VERTICES_MASK 0xffff
1707
1708/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
1709 * Two parameter dwords:
1710 * 0. The first parameter appears to be always 0
1711 * 1. The second parameter is a standard primitive emission dword.
1712 */
1713#define R300_PACKET3_3D_DRAW_VBUF 0x00002800
1714
1715/* Specify the full set of vertex arrays as (address, stride).
1716 * The first parameter is the number of vertex arrays specified.
1717 * The rest of the command is a variable length list of blocks, where
1718 * each block is three dwords long and specifies two arrays.
1719 * The first dword of a block is split into two words, the lower significant
1720 * word refers to the first array, the more significant word to the second
1721 * array in the block.
1722 * The low byte of each word contains the size of an array entry in dwords,
1723 * the high byte contains the stride of the array.
1724 * The second dword of a block contains the pointer to the first array,
1725 * the third dword of a block contains the pointer to the second array.
1726 * Note that if the total number of arrays is odd, the third dword of
1727 * the last block is omitted.
1728 */
1729#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00
1730
1731#define R300_PACKET3_INDX_BUFFER 0x00003300
1732# define R300_EB_UNK1_SHIFT 24
1733# define R300_EB_UNK1 (0x80<<24)
1734# define R300_EB_UNK2 0x0810
1735#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400
1736#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600
1737
1738/* END: Packet 3 commands */
1739
1740
1741/* Color formats for 2d packets
1742 */
1743#define R300_CP_COLOR_FORMAT_CI8 2
1744#define R300_CP_COLOR_FORMAT_ARGB1555 3
1745#define R300_CP_COLOR_FORMAT_RGB565 4
1746#define R300_CP_COLOR_FORMAT_ARGB8888 6
1747#define R300_CP_COLOR_FORMAT_RGB332 7
1748#define R300_CP_COLOR_FORMAT_RGB8 9
1749#define R300_CP_COLOR_FORMAT_ARGB4444 15
1750
1751/*
1752 * CP type-3 packets
1753 */
1754#define R300_CP_CMD_BITBLT_MULTI 0xC0009B00
1755
1756#define R500_VAP_INDEX_OFFSET 0x208c
1757
1758#define R500_GA_US_VECTOR_INDEX 0x4250
1759#define R500_GA_US_VECTOR_DATA 0x4254
1760
1761#define R500_RS_IP_0 0x4074
1762#define R500_RS_INST_0 0x4320
1763
1764#define R500_US_CONFIG 0x4600
1765
1766#define R500_US_FC_CTRL 0x4624
1767#define R500_US_CODE_ADDR 0x4630
1768
1769#define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0
1770#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8
1771
1772#endif /* _R300_REG_H */
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
new file mode 100644
index 000000000000..e53158f0ecb5
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -0,0 +1,1773 @@
1/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */
2/*
3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * Copyright 2007 Advanced Micro Devices, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Kevin E. Martin <martin@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36#include "r300_reg.h"
37
38#include "radeon_microcode.h"
39
40#define RADEON_FIFO_DEBUG 0
41
42static int radeon_do_cleanup_cp(struct drm_device * dev);
43
44static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
45{
46 u32 ret;
47 RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
48 ret = RADEON_READ(R520_MC_IND_DATA);
49 RADEON_WRITE(R520_MC_IND_INDEX, 0);
50 return ret;
51}
52
53static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
54{
55 u32 ret;
56 RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff);
57 ret = RADEON_READ(RS480_NB_MC_DATA);
58 RADEON_WRITE(RS480_NB_MC_INDEX, 0xff);
59 return ret;
60}
61
62static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
63{
64 u32 ret;
65 RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
66 ret = RADEON_READ(RS690_MC_DATA);
67 RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
68 return ret;
69}
70
71static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
72{
73 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
74 return RS690_READ_MCIND(dev_priv, addr);
75 else
76 return RS480_READ_MCIND(dev_priv, addr);
77}
78
79u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
80{
81
82 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
83 return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
84 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
85 return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
86 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
87 return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
88 else
89 return RADEON_READ(RADEON_MC_FB_LOCATION);
90}
91
92static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
93{
94 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
95 R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
96 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
97 RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
98 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
99 R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
100 else
101 RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
102}
103
104static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
105{
106 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
107 R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
108 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
109 RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
110 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
111 R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
112 else
113 RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
114}
115
116static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
117{
118 u32 agp_base_hi = upper_32_bits(agp_base);
119 u32 agp_base_lo = agp_base & 0xffffffff;
120
121 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
122 R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
123 R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
124 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
125 RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
126 RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
127 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
128 R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
129 R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
130 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) {
131 RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
132 RADEON_WRITE(RS480_AGP_BASE_2, 0);
133 } else {
134 RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
135 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200)
136 RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi);
137 }
138}
139
140static int RADEON_READ_PLL(struct drm_device * dev, int addr)
141{
142 drm_radeon_private_t *dev_priv = dev->dev_private;
143
144 RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
145 return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
146}
147
148static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
149{
150 RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
151 return RADEON_READ(RADEON_PCIE_DATA);
152}
153
154#if RADEON_FIFO_DEBUG
155static void radeon_status(drm_radeon_private_t * dev_priv)
156{
157 printk("%s:\n", __func__);
158 printk("RBBM_STATUS = 0x%08x\n",
159 (unsigned int)RADEON_READ(RADEON_RBBM_STATUS));
160 printk("CP_RB_RTPR = 0x%08x\n",
161 (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR));
162 printk("CP_RB_WTPR = 0x%08x\n",
163 (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR));
164 printk("AIC_CNTL = 0x%08x\n",
165 (unsigned int)RADEON_READ(RADEON_AIC_CNTL));
166 printk("AIC_STAT = 0x%08x\n",
167 (unsigned int)RADEON_READ(RADEON_AIC_STAT));
168 printk("AIC_PT_BASE = 0x%08x\n",
169 (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE));
170 printk("TLB_ADDR = 0x%08x\n",
171 (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR));
172 printk("TLB_DATA = 0x%08x\n",
173 (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA));
174}
175#endif
176
177/* ================================================================
178 * Engine, FIFO control
179 */
180
181static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
182{
183 u32 tmp;
184 int i;
185
186 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
187
188 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {
189 tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
190 tmp |= RADEON_RB3D_DC_FLUSH_ALL;
191 RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
192
193 for (i = 0; i < dev_priv->usec_timeout; i++) {
194 if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
195 & RADEON_RB3D_DC_BUSY)) {
196 return 0;
197 }
198 DRM_UDELAY(1);
199 }
200 } else {
201 /* 3D */
202 tmp = RADEON_READ(R300_RB3D_DSTCACHE_CTLSTAT);
203 tmp |= RADEON_RB3D_DC_FLUSH_ALL;
204 RADEON_WRITE(R300_RB3D_DSTCACHE_CTLSTAT, tmp);
205
206 /* 2D */
207 tmp = RADEON_READ(R300_DSTCACHE_CTLSTAT);
208 tmp |= RADEON_RB3D_DC_FLUSH_ALL;
209 RADEON_WRITE(R300_DSTCACHE_CTLSTAT, tmp);
210
211 for (i = 0; i < dev_priv->usec_timeout; i++) {
212 if (!(RADEON_READ(R300_DSTCACHE_CTLSTAT)
213 & RADEON_RB3D_DC_BUSY)) {
214 return 0;
215 }
216 DRM_UDELAY(1);
217 }
218 }
219
220#if RADEON_FIFO_DEBUG
221 DRM_ERROR("failed!\n");
222 radeon_status(dev_priv);
223#endif
224 return -EBUSY;
225}
226
227static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
228{
229 int i;
230
231 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
232
233 for (i = 0; i < dev_priv->usec_timeout; i++) {
234 int slots = (RADEON_READ(RADEON_RBBM_STATUS)
235 & RADEON_RBBM_FIFOCNT_MASK);
236 if (slots >= entries)
237 return 0;
238 DRM_UDELAY(1);
239 }
240
241#if RADEON_FIFO_DEBUG
242 DRM_ERROR("failed!\n");
243 radeon_status(dev_priv);
244#endif
245 return -EBUSY;
246}
247
248static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
249{
250 int i, ret;
251
252 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
253
254 ret = radeon_do_wait_for_fifo(dev_priv, 64);
255 if (ret)
256 return ret;
257
258 for (i = 0; i < dev_priv->usec_timeout; i++) {
259 if (!(RADEON_READ(RADEON_RBBM_STATUS)
260 & RADEON_RBBM_ACTIVE)) {
261 radeon_do_pixcache_flush(dev_priv);
262 return 0;
263 }
264 DRM_UDELAY(1);
265 }
266
267#if RADEON_FIFO_DEBUG
268 DRM_ERROR("failed!\n");
269 radeon_status(dev_priv);
270#endif
271 return -EBUSY;
272}
273
274static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
275{
276 uint32_t gb_tile_config, gb_pipe_sel = 0;
277
278 /* RS4xx/RS6xx/R4xx/R5xx */
279 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R420) {
280 gb_pipe_sel = RADEON_READ(R400_GB_PIPE_SELECT);
281 dev_priv->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
282 } else {
283 /* R3xx */
284 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
285 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350)) {
286 dev_priv->num_gb_pipes = 2;
287 } else {
288 /* R3Vxx */
289 dev_priv->num_gb_pipes = 1;
290 }
291 }
292 DRM_INFO("Num pipes: %d\n", dev_priv->num_gb_pipes);
293
294 gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 /*| R300_SUBPIXEL_1_16*/);
295
296 switch (dev_priv->num_gb_pipes) {
297 case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
298 case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
299 case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
300 default:
301 case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
302 }
303
304 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
305 RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
306 RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
307 }
308 RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
309 radeon_do_wait_for_idle(dev_priv);
310 RADEON_WRITE(R300_DST_PIPE_CONFIG, RADEON_READ(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
311 RADEON_WRITE(R300_RB2D_DSTCACHE_MODE, (RADEON_READ(R300_RB2D_DSTCACHE_MODE) |
312 R300_DC_AUTOFLUSH_ENABLE |
313 R300_DC_DC_DISABLE_IGNORE_PE));
314
315
316}
317
318/* ================================================================
319 * CP control, initialization
320 */
321
322/* Load the microcode for the CP */
323static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
324{
325 int i;
326 DRM_DEBUG("\n");
327
328 radeon_do_wait_for_idle(dev_priv);
329
330 RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
331 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) ||
332 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) ||
333 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) ||
334 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS100) ||
335 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS200)) {
336 DRM_INFO("Loading R100 Microcode\n");
337 for (i = 0; i < 256; i++) {
338 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
339 R100_cp_microcode[i][1]);
340 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
341 R100_cp_microcode[i][0]);
342 }
343 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R200) ||
344 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV250) ||
345 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV280) ||
346 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS300)) {
347 DRM_INFO("Loading R200 Microcode\n");
348 for (i = 0; i < 256; i++) {
349 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
350 R200_cp_microcode[i][1]);
351 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
352 R200_cp_microcode[i][0]);
353 }
354 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R300) ||
355 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
356 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
357 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) ||
358 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
359 DRM_INFO("Loading R300 Microcode\n");
360 for (i = 0; i < 256; i++) {
361 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
362 R300_cp_microcode[i][1]);
363 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
364 R300_cp_microcode[i][0]);
365 }
366 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
367 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
368 DRM_INFO("Loading R400 Microcode\n");
369 for (i = 0; i < 256; i++) {
370 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
371 R420_cp_microcode[i][1]);
372 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
373 R420_cp_microcode[i][0]);
374 }
375 } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
376 DRM_INFO("Loading RS690 Microcode\n");
377 for (i = 0; i < 256; i++) {
378 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
379 RS690_cp_microcode[i][1]);
380 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
381 RS690_cp_microcode[i][0]);
382 }
383 } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
384 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
385 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
386 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R580) ||
387 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV560) ||
388 ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV570)) {
389 DRM_INFO("Loading R500 Microcode\n");
390 for (i = 0; i < 256; i++) {
391 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
392 R520_cp_microcode[i][1]);
393 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
394 R520_cp_microcode[i][0]);
395 }
396 }
397}
398
399/* Flush any pending commands to the CP. This should only be used just
400 * prior to a wait for idle, as it informs the engine that the command
401 * stream is ending.
402 */
403static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv)
404{
405 DRM_DEBUG("\n");
406#if 0
407 u32 tmp;
408
409 tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31);
410 RADEON_WRITE(RADEON_CP_RB_WPTR, tmp);
411#endif
412}
413
414/* Wait for the CP to go idle.
415 */
416int radeon_do_cp_idle(drm_radeon_private_t * dev_priv)
417{
418 RING_LOCALS;
419 DRM_DEBUG("\n");
420
421 BEGIN_RING(6);
422
423 RADEON_PURGE_CACHE();
424 RADEON_PURGE_ZCACHE();
425 RADEON_WAIT_UNTIL_IDLE();
426
427 ADVANCE_RING();
428 COMMIT_RING();
429
430 return radeon_do_wait_for_idle(dev_priv);
431}
432
433/* Start the Command Processor.
434 */
435static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
436{
437 RING_LOCALS;
438 DRM_DEBUG("\n");
439
440 radeon_do_wait_for_idle(dev_priv);
441
442 RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode);
443
444 dev_priv->cp_running = 1;
445
446 BEGIN_RING(6);
447
448 RADEON_PURGE_CACHE();
449 RADEON_PURGE_ZCACHE();
450 RADEON_WAIT_UNTIL_IDLE();
451
452 ADVANCE_RING();
453 COMMIT_RING();
454}
455
456/* Reset the Command Processor. This will not flush any pending
457 * commands, so you must wait for the CP command stream to complete
458 * before calling this routine.
459 */
460static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
461{
462 u32 cur_read_ptr;
463 DRM_DEBUG("\n");
464
465 cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
466 RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
467 SET_RING_HEAD(dev_priv, cur_read_ptr);
468 dev_priv->ring.tail = cur_read_ptr;
469}
470
471/* Stop the Command Processor. This will not flush any pending
472 * commands, so you must flush the command stream and wait for the CP
473 * to go idle before calling this routine.
474 */
475static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
476{
477 DRM_DEBUG("\n");
478
479 RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
480
481 dev_priv->cp_running = 0;
482}
483
484/* Reset the engine. This will stop the CP if it is running.
485 */
486static int radeon_do_engine_reset(struct drm_device * dev)
487{
488 drm_radeon_private_t *dev_priv = dev->dev_private;
489 u32 clock_cntl_index = 0, mclk_cntl = 0, rbbm_soft_reset;
490 DRM_DEBUG("\n");
491
492 radeon_do_pixcache_flush(dev_priv);
493
494 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
495 /* may need something similar for newer chips */
496 clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
497 mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
498
499 RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
500 RADEON_FORCEON_MCLKA |
501 RADEON_FORCEON_MCLKB |
502 RADEON_FORCEON_YCLKA |
503 RADEON_FORCEON_YCLKB |
504 RADEON_FORCEON_MC |
505 RADEON_FORCEON_AIC));
506 }
507
508 rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
509
510 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
511 RADEON_SOFT_RESET_CP |
512 RADEON_SOFT_RESET_HI |
513 RADEON_SOFT_RESET_SE |
514 RADEON_SOFT_RESET_RE |
515 RADEON_SOFT_RESET_PP |
516 RADEON_SOFT_RESET_E2 |
517 RADEON_SOFT_RESET_RB));
518 RADEON_READ(RADEON_RBBM_SOFT_RESET);
519 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
520 ~(RADEON_SOFT_RESET_CP |
521 RADEON_SOFT_RESET_HI |
522 RADEON_SOFT_RESET_SE |
523 RADEON_SOFT_RESET_RE |
524 RADEON_SOFT_RESET_PP |
525 RADEON_SOFT_RESET_E2 |
526 RADEON_SOFT_RESET_RB)));
527 RADEON_READ(RADEON_RBBM_SOFT_RESET);
528
529 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV410) {
530 RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
531 RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
532 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
533 }
534
535 /* setup the raster pipes */
536 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R300)
537 radeon_init_pipes(dev_priv);
538
539 /* Reset the CP ring */
540 radeon_do_cp_reset(dev_priv);
541
542 /* The CP is no longer running after an engine reset */
543 dev_priv->cp_running = 0;
544
545 /* Reset any pending vertex, indirect buffers */
546 radeon_freelist_reset(dev);
547
548 return 0;
549}
550
551static void radeon_cp_init_ring_buffer(struct drm_device * dev,
552 drm_radeon_private_t * dev_priv)
553{
554 u32 ring_start, cur_read_ptr;
555 u32 tmp;
556
557 /* Initialize the memory controller. With new memory map, the fb location
558 * is not changed, it should have been properly initialized already. Part
559 * of the problem is that the code below is bogus, assuming the GART is
560 * always appended to the fb which is not necessarily the case
561 */
562 if (!dev_priv->new_memmap)
563 radeon_write_fb_location(dev_priv,
564 ((dev_priv->gart_vm_start - 1) & 0xffff0000)
565 | (dev_priv->fb_location >> 16));
566
567#if __OS_HAS_AGP
568 if (dev_priv->flags & RADEON_IS_AGP) {
569 radeon_write_agp_base(dev_priv, dev->agp->base);
570
571 radeon_write_agp_location(dev_priv,
572 (((dev_priv->gart_vm_start - 1 +
573 dev_priv->gart_size) & 0xffff0000) |
574 (dev_priv->gart_vm_start >> 16)));
575
576 ring_start = (dev_priv->cp_ring->offset
577 - dev->agp->base
578 + dev_priv->gart_vm_start);
579 } else
580#endif
581 ring_start = (dev_priv->cp_ring->offset
582 - (unsigned long)dev->sg->virtual
583 + dev_priv->gart_vm_start);
584
585 RADEON_WRITE(RADEON_CP_RB_BASE, ring_start);
586
587 /* Set the write pointer delay */
588 RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0);
589
590 /* Initialize the ring buffer's read and write pointers */
591 cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
592 RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
593 SET_RING_HEAD(dev_priv, cur_read_ptr);
594 dev_priv->ring.tail = cur_read_ptr;
595
596#if __OS_HAS_AGP
597 if (dev_priv->flags & RADEON_IS_AGP) {
598 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
599 dev_priv->ring_rptr->offset
600 - dev->agp->base + dev_priv->gart_vm_start);
601 } else
602#endif
603 {
604 struct drm_sg_mem *entry = dev->sg;
605 unsigned long tmp_ofs, page_ofs;
606
607 tmp_ofs = dev_priv->ring_rptr->offset -
608 (unsigned long)dev->sg->virtual;
609 page_ofs = tmp_ofs >> PAGE_SHIFT;
610
611 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
612 DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
613 (unsigned long)entry->busaddr[page_ofs],
614 entry->handle + tmp_ofs);
615 }
616
617 /* Set ring buffer size */
618#ifdef __BIG_ENDIAN
619 RADEON_WRITE(RADEON_CP_RB_CNTL,
620 RADEON_BUF_SWAP_32BIT |
621 (dev_priv->ring.fetch_size_l2ow << 18) |
622 (dev_priv->ring.rptr_update_l2qw << 8) |
623 dev_priv->ring.size_l2qw);
624#else
625 RADEON_WRITE(RADEON_CP_RB_CNTL,
626 (dev_priv->ring.fetch_size_l2ow << 18) |
627 (dev_priv->ring.rptr_update_l2qw << 8) |
628 dev_priv->ring.size_l2qw);
629#endif
630
631 /* Start with assuming that writeback doesn't work */
632 dev_priv->writeback_works = 0;
633
634 /* Initialize the scratch register pointer. This will cause
635 * the scratch register values to be written out to memory
636 * whenever they are updated.
637 *
638 * We simply put this behind the ring read pointer, this works
639 * with PCI GART as well as (whatever kind of) AGP GART
640 */
641 RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
642 + RADEON_SCRATCH_REG_OFFSET);
643
644 dev_priv->scratch = ((__volatile__ u32 *)
645 dev_priv->ring_rptr->handle +
646 (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
647
648 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
649
650 /* Turn on bus mastering */
651 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
652 RADEON_WRITE(RADEON_BUS_CNTL, tmp);
653
654 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
655 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
656
657 dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
658 RADEON_WRITE(RADEON_LAST_DISPATCH_REG,
659 dev_priv->sarea_priv->last_dispatch);
660
661 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
662 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
663
664 radeon_do_wait_for_idle(dev_priv);
665
666 /* Sync everything up */
667 RADEON_WRITE(RADEON_ISYNC_CNTL,
668 (RADEON_ISYNC_ANY2D_IDLE3D |
669 RADEON_ISYNC_ANY3D_IDLE2D |
670 RADEON_ISYNC_WAIT_IDLEGUI |
671 RADEON_ISYNC_CPSCRATCH_IDLEGUI));
672
673}
674
675static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
676{
677 u32 tmp;
678
679 /* Writeback doesn't seem to work everywhere, test it here and possibly
680 * enable it if it appears to work
681 */
682 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
683 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
684
685 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
686 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
687 0xdeadbeef)
688 break;
689 DRM_UDELAY(1);
690 }
691
692 if (tmp < dev_priv->usec_timeout) {
693 dev_priv->writeback_works = 1;
694 DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
695 } else {
696 dev_priv->writeback_works = 0;
697 DRM_INFO("writeback test failed\n");
698 }
699 if (radeon_no_wb == 1) {
700 dev_priv->writeback_works = 0;
701 DRM_INFO("writeback forced off\n");
702 }
703
704 if (!dev_priv->writeback_works) {
705 /* Disable writeback to avoid unnecessary bus master transfer */
706 RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) |
707 RADEON_RB_NO_UPDATE);
708 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0);
709 }
710}
711
712/* Enable or disable IGP GART on the chip */
713static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
714{
715 u32 temp;
716
717 if (on) {
718 DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
719 dev_priv->gart_vm_start,
720 (long)dev_priv->gart_info.bus_addr,
721 dev_priv->gart_size);
722
723 temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL);
724 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
725 IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN |
726 RS690_BLOCK_GFX_D3_EN));
727 else
728 IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN);
729
730 IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
731 RS480_VA_SIZE_32MB));
732
733 temp = IGP_READ_MCIND(dev_priv, RS480_GART_FEATURE_ID);
734 IGP_WRITE_MCIND(RS480_GART_FEATURE_ID, (RS480_HANG_EN |
735 RS480_TLB_ENABLE |
736 RS480_GTW_LAC_EN |
737 RS480_1LEVEL_GART));
738
739 temp = dev_priv->gart_info.bus_addr & 0xfffff000;
740 temp |= (upper_32_bits(dev_priv->gart_info.bus_addr) & 0xff) << 4;
741 IGP_WRITE_MCIND(RS480_GART_BASE, temp);
742
743 temp = IGP_READ_MCIND(dev_priv, RS480_AGP_MODE_CNTL);
744 IGP_WRITE_MCIND(RS480_AGP_MODE_CNTL, ((1 << RS480_REQ_TYPE_SNOOP_SHIFT) |
745 RS480_REQ_TYPE_SNOOP_DIS));
746
747 radeon_write_agp_base(dev_priv, dev_priv->gart_vm_start);
748
749 dev_priv->gart_size = 32*1024*1024;
750 temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
751 0xffff0000) | (dev_priv->gart_vm_start >> 16));
752
753 radeon_write_agp_location(dev_priv, temp);
754
755 temp = IGP_READ_MCIND(dev_priv, RS480_AGP_ADDRESS_SPACE_SIZE);
756 IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN |
757 RS480_VA_SIZE_32MB));
758
759 do {
760 temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
761 if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
762 break;
763 DRM_UDELAY(1);
764 } while (1);
765
766 IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL,
767 RS480_GART_CACHE_INVALIDATE);
768
769 do {
770 temp = IGP_READ_MCIND(dev_priv, RS480_GART_CACHE_CNTRL);
771 if ((temp & RS480_GART_CACHE_INVALIDATE) == 0)
772 break;
773 DRM_UDELAY(1);
774 } while (1);
775
776 IGP_WRITE_MCIND(RS480_GART_CACHE_CNTRL, 0);
777 } else {
778 IGP_WRITE_MCIND(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
779 }
780}
781
782static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
783{
784 u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
785 if (on) {
786
787 DRM_DEBUG("programming pcie %08X %08lX %08X\n",
788 dev_priv->gart_vm_start,
789 (long)dev_priv->gart_info.bus_addr,
790 dev_priv->gart_size);
791 RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO,
792 dev_priv->gart_vm_start);
793 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE,
794 dev_priv->gart_info.bus_addr);
795 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO,
796 dev_priv->gart_vm_start);
797 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO,
798 dev_priv->gart_vm_start +
799 dev_priv->gart_size - 1);
800
801 radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */
802
803 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
804 RADEON_PCIE_TX_GART_EN);
805 } else {
806 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
807 tmp & ~RADEON_PCIE_TX_GART_EN);
808 }
809}
810
811/* Enable or disable PCI GART on the chip */
812static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
813{
814 u32 tmp;
815
816 if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
817 (dev_priv->flags & RADEON_IS_IGPGART)) {
818 radeon_set_igpgart(dev_priv, on);
819 return;
820 }
821
822 if (dev_priv->flags & RADEON_IS_PCIE) {
823 radeon_set_pciegart(dev_priv, on);
824 return;
825 }
826
827 tmp = RADEON_READ(RADEON_AIC_CNTL);
828
829 if (on) {
830 RADEON_WRITE(RADEON_AIC_CNTL,
831 tmp | RADEON_PCIGART_TRANSLATE_EN);
832
833 /* set PCI GART page-table base address
834 */
835 RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr);
836
837 /* set address range for PCI address translate
838 */
839 RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start);
840 RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
841 + dev_priv->gart_size - 1);
842
843 /* Turn off AGP aperture -- is this required for PCI GART?
844 */
845 radeon_write_agp_location(dev_priv, 0xffffffc0);
846 RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
847 } else {
848 RADEON_WRITE(RADEON_AIC_CNTL,
849 tmp & ~RADEON_PCIGART_TRANSLATE_EN);
850 }
851}
852
853static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
854{
855 drm_radeon_private_t *dev_priv = dev->dev_private;
856
857 DRM_DEBUG("\n");
858
859 /* if we require new memory map but we don't have it fail */
860 if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
861 DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
862 radeon_do_cleanup_cp(dev);
863 return -EINVAL;
864 }
865
866 if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
867 DRM_DEBUG("Forcing AGP card to PCI mode\n");
868 dev_priv->flags &= ~RADEON_IS_AGP;
869 } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
870 && !init->is_pci) {
871 DRM_DEBUG("Restoring AGP flag\n");
872 dev_priv->flags |= RADEON_IS_AGP;
873 }
874
875 if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) {
876 DRM_ERROR("PCI GART memory not allocated!\n");
877 radeon_do_cleanup_cp(dev);
878 return -EINVAL;
879 }
880
881 dev_priv->usec_timeout = init->usec_timeout;
882 if (dev_priv->usec_timeout < 1 ||
883 dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
884 DRM_DEBUG("TIMEOUT problem!\n");
885 radeon_do_cleanup_cp(dev);
886 return -EINVAL;
887 }
888
889 /* Enable vblank on CRTC1 for older X servers
890 */
891 dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
892
893 switch(init->func) {
894 case RADEON_INIT_R200_CP:
895 dev_priv->microcode_version = UCODE_R200;
896 break;
897 case RADEON_INIT_R300_CP:
898 dev_priv->microcode_version = UCODE_R300;
899 break;
900 default:
901 dev_priv->microcode_version = UCODE_R100;
902 }
903
904 dev_priv->do_boxes = 0;
905 dev_priv->cp_mode = init->cp_mode;
906
907 /* We don't support anything other than bus-mastering ring mode,
908 * but the ring can be in either AGP or PCI space for the ring
909 * read pointer.
910 */
911 if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
912 (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
913 DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
914 radeon_do_cleanup_cp(dev);
915 return -EINVAL;
916 }
917
918 switch (init->fb_bpp) {
919 case 16:
920 dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
921 break;
922 case 32:
923 default:
924 dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
925 break;
926 }
927 dev_priv->front_offset = init->front_offset;
928 dev_priv->front_pitch = init->front_pitch;
929 dev_priv->back_offset = init->back_offset;
930 dev_priv->back_pitch = init->back_pitch;
931
932 switch (init->depth_bpp) {
933 case 16:
934 dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
935 break;
936 case 32:
937 default:
938 dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
939 break;
940 }
941 dev_priv->depth_offset = init->depth_offset;
942 dev_priv->depth_pitch = init->depth_pitch;
943
944 /* Hardware state for depth clears. Remove this if/when we no
945 * longer clear the depth buffer with a 3D rectangle. Hard-code
946 * all values to prevent unwanted 3D state from slipping through
947 * and screwing with the clear operation.
948 */
949 dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
950 (dev_priv->color_fmt << 10) |
951 (dev_priv->microcode_version ==
952 UCODE_R100 ? RADEON_ZBLOCK16 : 0));
953
954 dev_priv->depth_clear.rb3d_zstencilcntl =
955 (dev_priv->depth_fmt |
956 RADEON_Z_TEST_ALWAYS |
957 RADEON_STENCIL_TEST_ALWAYS |
958 RADEON_STENCIL_S_FAIL_REPLACE |
959 RADEON_STENCIL_ZPASS_REPLACE |
960 RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE);
961
962 dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
963 RADEON_BFACE_SOLID |
964 RADEON_FFACE_SOLID |
965 RADEON_FLAT_SHADE_VTX_LAST |
966 RADEON_DIFFUSE_SHADE_FLAT |
967 RADEON_ALPHA_SHADE_FLAT |
968 RADEON_SPECULAR_SHADE_FLAT |
969 RADEON_FOG_SHADE_FLAT |
970 RADEON_VTX_PIX_CENTER_OGL |
971 RADEON_ROUND_MODE_TRUNC |
972 RADEON_ROUND_PREC_8TH_PIX);
973
974
975 dev_priv->ring_offset = init->ring_offset;
976 dev_priv->ring_rptr_offset = init->ring_rptr_offset;
977 dev_priv->buffers_offset = init->buffers_offset;
978 dev_priv->gart_textures_offset = init->gart_textures_offset;
979
980 dev_priv->sarea = drm_getsarea(dev);
981 if (!dev_priv->sarea) {
982 DRM_ERROR("could not find sarea!\n");
983 radeon_do_cleanup_cp(dev);
984 return -EINVAL;
985 }
986
987 dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
988 if (!dev_priv->cp_ring) {
989 DRM_ERROR("could not find cp ring region!\n");
990 radeon_do_cleanup_cp(dev);
991 return -EINVAL;
992 }
993 dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
994 if (!dev_priv->ring_rptr) {
995 DRM_ERROR("could not find ring read pointer!\n");
996 radeon_do_cleanup_cp(dev);
997 return -EINVAL;
998 }
999 dev->agp_buffer_token = init->buffers_offset;
1000 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
1001 if (!dev->agp_buffer_map) {
1002 DRM_ERROR("could not find dma buffer region!\n");
1003 radeon_do_cleanup_cp(dev);
1004 return -EINVAL;
1005 }
1006
1007 if (init->gart_textures_offset) {
1008 dev_priv->gart_textures =
1009 drm_core_findmap(dev, init->gart_textures_offset);
1010 if (!dev_priv->gart_textures) {
1011 DRM_ERROR("could not find GART texture region!\n");
1012 radeon_do_cleanup_cp(dev);
1013 return -EINVAL;
1014 }
1015 }
1016
1017 dev_priv->sarea_priv =
1018 (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
1019 init->sarea_priv_offset);
1020
1021#if __OS_HAS_AGP
1022 if (dev_priv->flags & RADEON_IS_AGP) {
1023 drm_core_ioremap(dev_priv->cp_ring, dev);
1024 drm_core_ioremap(dev_priv->ring_rptr, dev);
1025 drm_core_ioremap(dev->agp_buffer_map, dev);
1026 if (!dev_priv->cp_ring->handle ||
1027 !dev_priv->ring_rptr->handle ||
1028 !dev->agp_buffer_map->handle) {
1029 DRM_ERROR("could not find ioremap agp regions!\n");
1030 radeon_do_cleanup_cp(dev);
1031 return -EINVAL;
1032 }
1033 } else
1034#endif
1035 {
1036 dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
1037 dev_priv->ring_rptr->handle =
1038 (void *)dev_priv->ring_rptr->offset;
1039 dev->agp_buffer_map->handle =
1040 (void *)dev->agp_buffer_map->offset;
1041
1042 DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
1043 dev_priv->cp_ring->handle);
1044 DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
1045 dev_priv->ring_rptr->handle);
1046 DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
1047 dev->agp_buffer_map->handle);
1048 }
1049
1050 dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
1051 dev_priv->fb_size =
1052 ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
1053 - dev_priv->fb_location;
1054
1055 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
1056 ((dev_priv->front_offset
1057 + dev_priv->fb_location) >> 10));
1058
1059 dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
1060 ((dev_priv->back_offset
1061 + dev_priv->fb_location) >> 10));
1062
1063 dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
1064 ((dev_priv->depth_offset
1065 + dev_priv->fb_location) >> 10));
1066
1067 dev_priv->gart_size = init->gart_size;
1068
1069 /* New let's set the memory map ... */
1070 if (dev_priv->new_memmap) {
1071 u32 base = 0;
1072
1073 DRM_INFO("Setting GART location based on new memory map\n");
1074
1075 /* If using AGP, try to locate the AGP aperture at the same
1076 * location in the card and on the bus, though we have to
1077 * align it down.
1078 */
1079#if __OS_HAS_AGP
1080 if (dev_priv->flags & RADEON_IS_AGP) {
1081 base = dev->agp->base;
1082 /* Check if valid */
1083 if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
1084 base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
1085 DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
1086 dev->agp->base);
1087 base = 0;
1088 }
1089 }
1090#endif
1091 /* If not or if AGP is at 0 (Macs), try to put it elsewhere */
1092 if (base == 0) {
1093 base = dev_priv->fb_location + dev_priv->fb_size;
1094 if (base < dev_priv->fb_location ||
1095 ((base + dev_priv->gart_size) & 0xfffffffful) < base)
1096 base = dev_priv->fb_location
1097 - dev_priv->gart_size;
1098 }
1099 dev_priv->gart_vm_start = base & 0xffc00000u;
1100 if (dev_priv->gart_vm_start != base)
1101 DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
1102 base, dev_priv->gart_vm_start);
1103 } else {
1104 DRM_INFO("Setting GART location based on old memory map\n");
1105 dev_priv->gart_vm_start = dev_priv->fb_location +
1106 RADEON_READ(RADEON_CONFIG_APER_SIZE);
1107 }
1108
1109#if __OS_HAS_AGP
1110 if (dev_priv->flags & RADEON_IS_AGP)
1111 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1112 - dev->agp->base
1113 + dev_priv->gart_vm_start);
1114 else
1115#endif
1116 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1117 - (unsigned long)dev->sg->virtual
1118 + dev_priv->gart_vm_start);
1119
1120 DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
1121 DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start);
1122 DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n",
1123 dev_priv->gart_buffers_offset);
1124
1125 dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
1126 dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
1127 + init->ring_size / sizeof(u32));
1128 dev_priv->ring.size = init->ring_size;
1129 dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
1130
1131 dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
1132 dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8);
1133
1134 dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
1135 dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16);
1136 dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
1137
1138 dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
1139
1140#if __OS_HAS_AGP
1141 if (dev_priv->flags & RADEON_IS_AGP) {
1142 /* Turn off PCI GART */
1143 radeon_set_pcigart(dev_priv, 0);
1144 } else
1145#endif
1146 {
1147 dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
1148 /* if we have an offset set from userspace */
1149 if (dev_priv->pcigart_offset_set) {
1150 dev_priv->gart_info.bus_addr =
1151 dev_priv->pcigart_offset + dev_priv->fb_location;
1152 dev_priv->gart_info.mapping.offset =
1153 dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
1154 dev_priv->gart_info.mapping.size =
1155 dev_priv->gart_info.table_size;
1156
1157 drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
1158 dev_priv->gart_info.addr =
1159 dev_priv->gart_info.mapping.handle;
1160
1161 if (dev_priv->flags & RADEON_IS_PCIE)
1162 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
1163 else
1164 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
1165 dev_priv->gart_info.gart_table_location =
1166 DRM_ATI_GART_FB;
1167
1168 DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
1169 dev_priv->gart_info.addr,
1170 dev_priv->pcigart_offset);
1171 } else {
1172 if (dev_priv->flags & RADEON_IS_IGPGART)
1173 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
1174 else
1175 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
1176 dev_priv->gart_info.gart_table_location =
1177 DRM_ATI_GART_MAIN;
1178 dev_priv->gart_info.addr = NULL;
1179 dev_priv->gart_info.bus_addr = 0;
1180 if (dev_priv->flags & RADEON_IS_PCIE) {
1181 DRM_ERROR
1182 ("Cannot use PCI Express without GART in FB memory\n");
1183 radeon_do_cleanup_cp(dev);
1184 return -EINVAL;
1185 }
1186 }
1187
1188 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
1189 DRM_ERROR("failed to init PCI GART!\n");
1190 radeon_do_cleanup_cp(dev);
1191 return -ENOMEM;
1192 }
1193
1194 /* Turn on PCI GART */
1195 radeon_set_pcigart(dev_priv, 1);
1196 }
1197
1198 radeon_cp_load_microcode(dev_priv);
1199 radeon_cp_init_ring_buffer(dev, dev_priv);
1200
1201 dev_priv->last_buf = 0;
1202
1203 radeon_do_engine_reset(dev);
1204 radeon_test_writeback(dev_priv);
1205
1206 return 0;
1207}
1208
1209static int radeon_do_cleanup_cp(struct drm_device * dev)
1210{
1211 drm_radeon_private_t *dev_priv = dev->dev_private;
1212 DRM_DEBUG("\n");
1213
1214 /* Make sure interrupts are disabled here because the uninstall ioctl
1215 * may not have been called from userspace and after dev_private
1216 * is freed, it's too late.
1217 */
1218 if (dev->irq_enabled)
1219 drm_irq_uninstall(dev);
1220
1221#if __OS_HAS_AGP
1222 if (dev_priv->flags & RADEON_IS_AGP) {
1223 if (dev_priv->cp_ring != NULL) {
1224 drm_core_ioremapfree(dev_priv->cp_ring, dev);
1225 dev_priv->cp_ring = NULL;
1226 }
1227 if (dev_priv->ring_rptr != NULL) {
1228 drm_core_ioremapfree(dev_priv->ring_rptr, dev);
1229 dev_priv->ring_rptr = NULL;
1230 }
1231 if (dev->agp_buffer_map != NULL) {
1232 drm_core_ioremapfree(dev->agp_buffer_map, dev);
1233 dev->agp_buffer_map = NULL;
1234 }
1235 } else
1236#endif
1237 {
1238
1239 if (dev_priv->gart_info.bus_addr) {
1240 /* Turn off PCI GART */
1241 radeon_set_pcigart(dev_priv, 0);
1242 if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
1243 DRM_ERROR("failed to cleanup PCI GART!\n");
1244 }
1245
1246 if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
1247 {
1248 drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
1249 dev_priv->gart_info.addr = 0;
1250 }
1251 }
1252 /* only clear to the start of flags */
1253 memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
1254
1255 return 0;
1256}
1257
1258/* This code will reinit the Radeon CP hardware after a resume from disc.
1259 * AFAIK, it would be very difficult to pickle the state at suspend time, so
1260 * here we make sure that all Radeon hardware initialisation is re-done without
1261 * affecting running applications.
1262 *
1263 * Charl P. Botha <http://cpbotha.net>
1264 */
1265static int radeon_do_resume_cp(struct drm_device * dev)
1266{
1267 drm_radeon_private_t *dev_priv = dev->dev_private;
1268
1269 if (!dev_priv) {
1270 DRM_ERROR("Called with no initialization\n");
1271 return -EINVAL;
1272 }
1273
1274 DRM_DEBUG("Starting radeon_do_resume_cp()\n");
1275
1276#if __OS_HAS_AGP
1277 if (dev_priv->flags & RADEON_IS_AGP) {
1278 /* Turn off PCI GART */
1279 radeon_set_pcigart(dev_priv, 0);
1280 } else
1281#endif
1282 {
1283 /* Turn on PCI GART */
1284 radeon_set_pcigart(dev_priv, 1);
1285 }
1286
1287 radeon_cp_load_microcode(dev_priv);
1288 radeon_cp_init_ring_buffer(dev, dev_priv);
1289
1290 radeon_do_engine_reset(dev);
1291 radeon_enable_interrupt(dev);
1292
1293 DRM_DEBUG("radeon_do_resume_cp() complete\n");
1294
1295 return 0;
1296}
1297
1298int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
1299{
1300 drm_radeon_init_t *init = data;
1301
1302 LOCK_TEST_WITH_RETURN(dev, file_priv);
1303
1304 if (init->func == RADEON_INIT_R300_CP)
1305 r300_init_reg_flags(dev);
1306
1307 switch (init->func) {
1308 case RADEON_INIT_CP:
1309 case RADEON_INIT_R200_CP:
1310 case RADEON_INIT_R300_CP:
1311 return radeon_do_init_cp(dev, init);
1312 case RADEON_CLEANUP_CP:
1313 return radeon_do_cleanup_cp(dev);
1314 }
1315
1316 return -EINVAL;
1317}
1318
1319int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv)
1320{
1321 drm_radeon_private_t *dev_priv = dev->dev_private;
1322 DRM_DEBUG("\n");
1323
1324 LOCK_TEST_WITH_RETURN(dev, file_priv);
1325
1326 if (dev_priv->cp_running) {
1327 DRM_DEBUG("while CP running\n");
1328 return 0;
1329 }
1330 if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
1331 DRM_DEBUG("called with bogus CP mode (%d)\n",
1332 dev_priv->cp_mode);
1333 return 0;
1334 }
1335
1336 radeon_do_cp_start(dev_priv);
1337
1338 return 0;
1339}
1340
1341/* Stop the CP. The engine must have been idled before calling this
1342 * routine.
1343 */
1344int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv)
1345{
1346 drm_radeon_private_t *dev_priv = dev->dev_private;
1347 drm_radeon_cp_stop_t *stop = data;
1348 int ret;
1349 DRM_DEBUG("\n");
1350
1351 LOCK_TEST_WITH_RETURN(dev, file_priv);
1352
1353 if (!dev_priv->cp_running)
1354 return 0;
1355
1356 /* Flush any pending CP commands. This ensures any outstanding
1357 * commands are exectuted by the engine before we turn it off.
1358 */
1359 if (stop->flush) {
1360 radeon_do_cp_flush(dev_priv);
1361 }
1362
1363 /* If we fail to make the engine go idle, we return an error
1364 * code so that the DRM ioctl wrapper can try again.
1365 */
1366 if (stop->idle) {
1367 ret = radeon_do_cp_idle(dev_priv);
1368 if (ret)
1369 return ret;
1370 }
1371
1372 /* Finally, we can turn off the CP. If the engine isn't idle,
1373 * we will get some dropped triangles as they won't be fully
1374 * rendered before the CP is shut down.
1375 */
1376 radeon_do_cp_stop(dev_priv);
1377
1378 /* Reset the engine */
1379 radeon_do_engine_reset(dev);
1380
1381 return 0;
1382}
1383
1384void radeon_do_release(struct drm_device * dev)
1385{
1386 drm_radeon_private_t *dev_priv = dev->dev_private;
1387 int i, ret;
1388
1389 if (dev_priv) {
1390 if (dev_priv->cp_running) {
1391 /* Stop the cp */
1392 while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
1393 DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
1394#ifdef __linux__
1395 schedule();
1396#else
1397 tsleep(&ret, PZERO, "rdnrel", 1);
1398#endif
1399 }
1400 radeon_do_cp_stop(dev_priv);
1401 radeon_do_engine_reset(dev);
1402 }
1403
1404 /* Disable *all* interrupts */
1405 if (dev_priv->mmio) /* remove this after permanent addmaps */
1406 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
1407
1408 if (dev_priv->mmio) { /* remove all surfaces */
1409 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1410 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
1411 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
1412 16 * i, 0);
1413 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
1414 16 * i, 0);
1415 }
1416 }
1417
1418 /* Free memory heap structures */
1419 radeon_mem_takedown(&(dev_priv->gart_heap));
1420 radeon_mem_takedown(&(dev_priv->fb_heap));
1421
1422 /* deallocate kernel resources */
1423 radeon_do_cleanup_cp(dev);
1424 }
1425}
1426
1427/* Just reset the CP ring. Called as part of an X Server engine reset.
1428 */
1429int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
1430{
1431 drm_radeon_private_t *dev_priv = dev->dev_private;
1432 DRM_DEBUG("\n");
1433
1434 LOCK_TEST_WITH_RETURN(dev, file_priv);
1435
1436 if (!dev_priv) {
1437 DRM_DEBUG("called before init done\n");
1438 return -EINVAL;
1439 }
1440
1441 radeon_do_cp_reset(dev_priv);
1442
1443 /* The CP is no longer running after an engine reset */
1444 dev_priv->cp_running = 0;
1445
1446 return 0;
1447}
1448
1449int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv)
1450{
1451 drm_radeon_private_t *dev_priv = dev->dev_private;
1452 DRM_DEBUG("\n");
1453
1454 LOCK_TEST_WITH_RETURN(dev, file_priv);
1455
1456 return radeon_do_cp_idle(dev_priv);
1457}
1458
1459/* Added by Charl P. Botha to call radeon_do_resume_cp().
1460 */
1461int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
1462{
1463
1464 return radeon_do_resume_cp(dev);
1465}
1466
1467int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
1468{
1469 DRM_DEBUG("\n");
1470
1471 LOCK_TEST_WITH_RETURN(dev, file_priv);
1472
1473 return radeon_do_engine_reset(dev);
1474}
1475
1476/* ================================================================
1477 * Fullscreen mode
1478 */
1479
1480/* KW: Deprecated to say the least:
1481 */
1482int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv)
1483{
1484 return 0;
1485}
1486
1487/* ================================================================
1488 * Freelist management
1489 */
1490
1491/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through
1492 * bufs until freelist code is used. Note this hides a problem with
1493 * the scratch register * (used to keep track of last buffer
1494 * completed) being written to before * the last buffer has actually
1495 * completed rendering.
1496 *
1497 * KW: It's also a good way to find free buffers quickly.
1498 *
1499 * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
1500 * sleep. However, bugs in older versions of radeon_accel.c mean that
1501 * we essentially have to do this, else old clients will break.
1502 *
1503 * However, it does leave open a potential deadlock where all the
1504 * buffers are held by other clients, which can't release them because
1505 * they can't get the lock.
1506 */
1507
1508struct drm_buf *radeon_freelist_get(struct drm_device * dev)
1509{
1510 struct drm_device_dma *dma = dev->dma;
1511 drm_radeon_private_t *dev_priv = dev->dev_private;
1512 drm_radeon_buf_priv_t *buf_priv;
1513 struct drm_buf *buf;
1514 int i, t;
1515 int start;
1516
1517 if (++dev_priv->last_buf >= dma->buf_count)
1518 dev_priv->last_buf = 0;
1519
1520 start = dev_priv->last_buf;
1521
1522 for (t = 0; t < dev_priv->usec_timeout; t++) {
1523 u32 done_age = GET_SCRATCH(1);
1524 DRM_DEBUG("done_age = %d\n", done_age);
1525 for (i = start; i < dma->buf_count; i++) {
1526 buf = dma->buflist[i];
1527 buf_priv = buf->dev_private;
1528 if (buf->file_priv == NULL || (buf->pending &&
1529 buf_priv->age <=
1530 done_age)) {
1531 dev_priv->stats.requested_bufs++;
1532 buf->pending = 0;
1533 return buf;
1534 }
1535 start = 0;
1536 }
1537
1538 if (t) {
1539 DRM_UDELAY(1);
1540 dev_priv->stats.freelist_loops++;
1541 }
1542 }
1543
1544 DRM_DEBUG("returning NULL!\n");
1545 return NULL;
1546}
1547
1548#if 0
1549struct drm_buf *radeon_freelist_get(struct drm_device * dev)
1550{
1551 struct drm_device_dma *dma = dev->dma;
1552 drm_radeon_private_t *dev_priv = dev->dev_private;
1553 drm_radeon_buf_priv_t *buf_priv;
1554 struct drm_buf *buf;
1555 int i, t;
1556 int start;
1557 u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
1558
1559 if (++dev_priv->last_buf >= dma->buf_count)
1560 dev_priv->last_buf = 0;
1561
1562 start = dev_priv->last_buf;
1563 dev_priv->stats.freelist_loops++;
1564
1565 for (t = 0; t < 2; t++) {
1566 for (i = start; i < dma->buf_count; i++) {
1567 buf = dma->buflist[i];
1568 buf_priv = buf->dev_private;
1569 if (buf->file_priv == 0 || (buf->pending &&
1570 buf_priv->age <=
1571 done_age)) {
1572 dev_priv->stats.requested_bufs++;
1573 buf->pending = 0;
1574 return buf;
1575 }
1576 }
1577 start = 0;
1578 }
1579
1580 return NULL;
1581}
1582#endif
1583
1584void radeon_freelist_reset(struct drm_device * dev)
1585{
1586 struct drm_device_dma *dma = dev->dma;
1587 drm_radeon_private_t *dev_priv = dev->dev_private;
1588 int i;
1589
1590 dev_priv->last_buf = 0;
1591 for (i = 0; i < dma->buf_count; i++) {
1592 struct drm_buf *buf = dma->buflist[i];
1593 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1594 buf_priv->age = 0;
1595 }
1596}
1597
1598/* ================================================================
1599 * CP command submission
1600 */
1601
1602int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n)
1603{
1604 drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
1605 int i;
1606 u32 last_head = GET_RING_HEAD(dev_priv);
1607
1608 for (i = 0; i < dev_priv->usec_timeout; i++) {
1609 u32 head = GET_RING_HEAD(dev_priv);
1610
1611 ring->space = (head - ring->tail) * sizeof(u32);
1612 if (ring->space <= 0)
1613 ring->space += ring->size;
1614 if (ring->space > n)
1615 return 0;
1616
1617 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
1618
1619 if (head != last_head)
1620 i = 0;
1621 last_head = head;
1622
1623 DRM_UDELAY(1);
1624 }
1625
1626 /* FIXME: This return value is ignored in the BEGIN_RING macro! */
1627#if RADEON_FIFO_DEBUG
1628 radeon_status(dev_priv);
1629 DRM_ERROR("failed!\n");
1630#endif
1631 return -EBUSY;
1632}
1633
1634static int radeon_cp_get_buffers(struct drm_device *dev,
1635 struct drm_file *file_priv,
1636 struct drm_dma * d)
1637{
1638 int i;
1639 struct drm_buf *buf;
1640
1641 for (i = d->granted_count; i < d->request_count; i++) {
1642 buf = radeon_freelist_get(dev);
1643 if (!buf)
1644 return -EBUSY; /* NOTE: broken client */
1645
1646 buf->file_priv = file_priv;
1647
1648 if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
1649 sizeof(buf->idx)))
1650 return -EFAULT;
1651 if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
1652 sizeof(buf->total)))
1653 return -EFAULT;
1654
1655 d->granted_count++;
1656 }
1657 return 0;
1658}
1659
1660int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv)
1661{
1662 struct drm_device_dma *dma = dev->dma;
1663 int ret = 0;
1664 struct drm_dma *d = data;
1665
1666 LOCK_TEST_WITH_RETURN(dev, file_priv);
1667
1668 /* Please don't send us buffers.
1669 */
1670 if (d->send_count != 0) {
1671 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1672 DRM_CURRENTPID, d->send_count);
1673 return -EINVAL;
1674 }
1675
1676 /* We'll send you buffers.
1677 */
1678 if (d->request_count < 0 || d->request_count > dma->buf_count) {
1679 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1680 DRM_CURRENTPID, d->request_count, dma->buf_count);
1681 return -EINVAL;
1682 }
1683
1684 d->granted_count = 0;
1685
1686 if (d->request_count) {
1687 ret = radeon_cp_get_buffers(dev, file_priv, d);
1688 }
1689
1690 return ret;
1691}
1692
1693int radeon_driver_load(struct drm_device *dev, unsigned long flags)
1694{
1695 drm_radeon_private_t *dev_priv;
1696 int ret = 0;
1697
1698 dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
1699 if (dev_priv == NULL)
1700 return -ENOMEM;
1701
1702 memset(dev_priv, 0, sizeof(drm_radeon_private_t));
1703 dev->dev_private = (void *)dev_priv;
1704 dev_priv->flags = flags;
1705
1706 switch (flags & RADEON_FAMILY_MASK) {
1707 case CHIP_R100:
1708 case CHIP_RV200:
1709 case CHIP_R200:
1710 case CHIP_R300:
1711 case CHIP_R350:
1712 case CHIP_R420:
1713 case CHIP_RV410:
1714 case CHIP_RV515:
1715 case CHIP_R520:
1716 case CHIP_RV570:
1717 case CHIP_R580:
1718 dev_priv->flags |= RADEON_HAS_HIERZ;
1719 break;
1720 default:
1721 /* all other chips have no hierarchical z buffer */
1722 break;
1723 }
1724
1725 if (drm_device_is_agp(dev))
1726 dev_priv->flags |= RADEON_IS_AGP;
1727 else if (drm_device_is_pcie(dev))
1728 dev_priv->flags |= RADEON_IS_PCIE;
1729 else
1730 dev_priv->flags |= RADEON_IS_PCI;
1731
1732 DRM_DEBUG("%s card detected\n",
1733 ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
1734 return ret;
1735}
1736
1737/* Create mappings for registers and framebuffer so userland doesn't necessarily
1738 * have to find them.
1739 */
1740int radeon_driver_firstopen(struct drm_device *dev)
1741{
1742 int ret;
1743 drm_local_map_t *map;
1744 drm_radeon_private_t *dev_priv = dev->dev_private;
1745
1746 dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
1747
1748 ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
1749 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
1750 _DRM_READ_ONLY, &dev_priv->mmio);
1751 if (ret != 0)
1752 return ret;
1753
1754 dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
1755 ret = drm_addmap(dev, dev_priv->fb_aper_offset,
1756 drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
1757 _DRM_WRITE_COMBINING, &map);
1758 if (ret != 0)
1759 return ret;
1760
1761 return 0;
1762}
1763
1764int radeon_driver_unload(struct drm_device *dev)
1765{
1766 drm_radeon_private_t *dev_priv = dev->dev_private;
1767
1768 DRM_DEBUG("\n");
1769 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
1770
1771 dev->dev_private = NULL;
1772 return 0;
1773}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
new file mode 100644
index 000000000000..349ac3d3b848
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -0,0 +1,126 @@
1/**
2 * \file radeon_drv.c
3 * ATI Radeon driver
4 *
5 * \author Gareth Hughes <gareth@valinux.com>
6 */
7
8/*
9 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
10 * All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
21 * Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37#include "drm_pciids.h"
38
39int radeon_no_wb;
40
41MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
42module_param_named(no_wb, radeon_no_wb, int, 0444);
43
44static int dri_library_name(struct drm_device *dev, char *buf)
45{
46 drm_radeon_private_t *dev_priv = dev->dev_private;
47 int family = dev_priv->flags & RADEON_FAMILY_MASK;
48
49 return snprintf(buf, PAGE_SIZE, "%s\n",
50 (family < CHIP_R200) ? "radeon" :
51 ((family < CHIP_R300) ? "r200" :
52 "r300"));
53}
54
55static struct pci_device_id pciidlist[] = {
56 radeon_PCI_IDS
57};
58
59static struct drm_driver driver = {
60 .driver_features =
61 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
62 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
63 DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
64 .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
65 .load = radeon_driver_load,
66 .firstopen = radeon_driver_firstopen,
67 .open = radeon_driver_open,
68 .preclose = radeon_driver_preclose,
69 .postclose = radeon_driver_postclose,
70 .lastclose = radeon_driver_lastclose,
71 .unload = radeon_driver_unload,
72 .vblank_wait = radeon_driver_vblank_wait,
73 .vblank_wait2 = radeon_driver_vblank_wait2,
74 .dri_library_name = dri_library_name,
75 .irq_preinstall = radeon_driver_irq_preinstall,
76 .irq_postinstall = radeon_driver_irq_postinstall,
77 .irq_uninstall = radeon_driver_irq_uninstall,
78 .irq_handler = radeon_driver_irq_handler,
79 .reclaim_buffers = drm_core_reclaim_buffers,
80 .get_map_ofs = drm_core_get_map_ofs,
81 .get_reg_ofs = drm_core_get_reg_ofs,
82 .ioctls = radeon_ioctls,
83 .dma_ioctl = radeon_cp_buffers,
84 .fops = {
85 .owner = THIS_MODULE,
86 .open = drm_open,
87 .release = drm_release,
88 .ioctl = drm_ioctl,
89 .mmap = drm_mmap,
90 .poll = drm_poll,
91 .fasync = drm_fasync,
92#ifdef CONFIG_COMPAT
93 .compat_ioctl = radeon_compat_ioctl,
94#endif
95 },
96
97 .pci_driver = {
98 .name = DRIVER_NAME,
99 .id_table = pciidlist,
100 },
101
102 .name = DRIVER_NAME,
103 .desc = DRIVER_DESC,
104 .date = DRIVER_DATE,
105 .major = DRIVER_MAJOR,
106 .minor = DRIVER_MINOR,
107 .patchlevel = DRIVER_PATCHLEVEL,
108};
109
110static int __init radeon_init(void)
111{
112 driver.num_ioctls = radeon_max_ioctl;
113 return drm_init(&driver);
114}
115
116static void __exit radeon_exit(void)
117{
118 drm_exit(&driver);
119}
120
121module_init(radeon_init);
122module_exit(radeon_exit);
123
124MODULE_AUTHOR(DRIVER_AUTHOR);
125MODULE_DESCRIPTION(DRIVER_DESC);
126MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
new file mode 100644
index 000000000000..3f0eca957aa7
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -0,0 +1,1406 @@
1/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*-
2 *
3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Kevin E. Martin <martin@valinux.com>
28 * Gareth Hughes <gareth@valinux.com>
29 */
30
31#ifndef __RADEON_DRV_H__
32#define __RADEON_DRV_H__
33
34/* General customization:
35 */
36
37#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others."
38
39#define DRIVER_NAME "radeon"
40#define DRIVER_DESC "ATI Radeon"
41#define DRIVER_DATE "20080528"
42
43/* Interface history:
44 *
45 * 1.1 - ??
46 * 1.2 - Add vertex2 ioctl (keith)
47 * - Add stencil capability to clear ioctl (gareth, keith)
48 * - Increase MAX_TEXTURE_LEVELS (brian)
49 * 1.3 - Add cmdbuf ioctl (keith)
50 * - Add support for new radeon packets (keith)
51 * - Add getparam ioctl (keith)
52 * - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
53 * 1.4 - Add scratch registers to get_param ioctl.
54 * 1.5 - Add r200 packets to cmdbuf ioctl
55 * - Add r200 function to init ioctl
56 * - Add 'scalar2' instruction to cmdbuf
57 * 1.6 - Add static GART memory manager
58 * Add irq handler (won't be turned on unless X server knows to)
59 * Add irq ioctls and irq_active getparam.
60 * Add wait command for cmdbuf ioctl
61 * Add GART offset query for getparam
62 * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
63 * and R200_PP_CUBIC_OFFSET_F1_[0..5].
64 * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
65 * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
66 * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
67 * Add 'GET' queries for starting additional clients on different VT's.
68 * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
69 * Add texture rectangle support for r100.
70 * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
71 * clients use to tell the DRM where they think the framebuffer is
72 * located in the card's address space
73 * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
74 * and GL_EXT_blend_[func|equation]_separate on r200
75 * 1.12- Add R300 CP microcode support - this just loads the CP on r300
76 * (No 3D support yet - just microcode loading).
77 * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
78 * - Add hyperz support, add hyperz flags to clear ioctl.
79 * 1.14- Add support for color tiling
80 * - Add R100/R200 surface allocation/free support
81 * 1.15- Add support for texture micro tiling
82 * - Add support for r100 cube maps
83 * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear
84 * texture filtering on r200
85 * 1.17- Add initial support for R300 (3D).
86 * 1.18- Add support for GL_ATI_fragment_shader, new packets
87 * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces
88 * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
89 * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
90 * 1.19- Add support for gart table in FB memory and PCIE r300
91 * 1.20- Add support for r300 texrect
92 * 1.21- Add support for card type getparam
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
94 * 1.23- Add new radeon memory map work from benh
95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
96 * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
97 * new packet type)
98 * 1.26- Add support for variable size PCI(E) gart aperture
99 * 1.27- Add support for IGP GART
100 * 1.28- Add support for VBL on CRTC2
101 * 1.29- R500 3D cmd buffer support
102 */
103#define DRIVER_MAJOR 1
104#define DRIVER_MINOR 29
105#define DRIVER_PATCHLEVEL 0
106
107/*
108 * Radeon chip families
109 */
110enum radeon_family {
111 CHIP_R100,
112 CHIP_RV100,
113 CHIP_RS100,
114 CHIP_RV200,
115 CHIP_RS200,
116 CHIP_R200,
117 CHIP_RV250,
118 CHIP_RS300,
119 CHIP_RV280,
120 CHIP_R300,
121 CHIP_R350,
122 CHIP_RV350,
123 CHIP_RV380,
124 CHIP_R420,
125 CHIP_RV410,
126 CHIP_RS480,
127 CHIP_RS690,
128 CHIP_RV515,
129 CHIP_R520,
130 CHIP_RV530,
131 CHIP_RV560,
132 CHIP_RV570,
133 CHIP_R580,
134 CHIP_LAST,
135};
136
137enum radeon_cp_microcode_version {
138 UCODE_R100,
139 UCODE_R200,
140 UCODE_R300,
141};
142
143/*
144 * Chip flags
145 */
146enum radeon_chip_flags {
147 RADEON_FAMILY_MASK = 0x0000ffffUL,
148 RADEON_FLAGS_MASK = 0xffff0000UL,
149 RADEON_IS_MOBILITY = 0x00010000UL,
150 RADEON_IS_IGP = 0x00020000UL,
151 RADEON_SINGLE_CRTC = 0x00040000UL,
152 RADEON_IS_AGP = 0x00080000UL,
153 RADEON_HAS_HIERZ = 0x00100000UL,
154 RADEON_IS_PCIE = 0x00200000UL,
155 RADEON_NEW_MEMMAP = 0x00400000UL,
156 RADEON_IS_PCI = 0x00800000UL,
157 RADEON_IS_IGPGART = 0x01000000UL,
158};
159
160#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
161 DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
162#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
163
164typedef struct drm_radeon_freelist {
165 unsigned int age;
166 struct drm_buf *buf;
167 struct drm_radeon_freelist *next;
168 struct drm_radeon_freelist *prev;
169} drm_radeon_freelist_t;
170
171typedef struct drm_radeon_ring_buffer {
172 u32 *start;
173 u32 *end;
174 int size;
175 int size_l2qw;
176
177 int rptr_update; /* Double Words */
178 int rptr_update_l2qw; /* log2 Quad Words */
179
180 int fetch_size; /* Double Words */
181 int fetch_size_l2ow; /* log2 Oct Words */
182
183 u32 tail;
184 u32 tail_mask;
185 int space;
186
187 int high_mark;
188} drm_radeon_ring_buffer_t;
189
190typedef struct drm_radeon_depth_clear_t {
191 u32 rb3d_cntl;
192 u32 rb3d_zstencilcntl;
193 u32 se_cntl;
194} drm_radeon_depth_clear_t;
195
196struct drm_radeon_driver_file_fields {
197 int64_t radeon_fb_delta;
198};
199
200struct mem_block {
201 struct mem_block *next;
202 struct mem_block *prev;
203 int start;
204 int size;
205 struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
206};
207
208struct radeon_surface {
209 int refcount;
210 u32 lower;
211 u32 upper;
212 u32 flags;
213};
214
215struct radeon_virt_surface {
216 int surface_index;
217 u32 lower;
218 u32 upper;
219 u32 flags;
220 struct drm_file *file_priv;
221};
222
223typedef struct drm_radeon_private {
224 drm_radeon_ring_buffer_t ring;
225 drm_radeon_sarea_t *sarea_priv;
226
227 u32 fb_location;
228 u32 fb_size;
229 int new_memmap;
230
231 int gart_size;
232 u32 gart_vm_start;
233 unsigned long gart_buffers_offset;
234
235 int cp_mode;
236 int cp_running;
237
238 drm_radeon_freelist_t *head;
239 drm_radeon_freelist_t *tail;
240 int last_buf;
241 volatile u32 *scratch;
242 int writeback_works;
243
244 int usec_timeout;
245
246 int microcode_version;
247
248 struct {
249 u32 boxes;
250 int freelist_timeouts;
251 int freelist_loops;
252 int requested_bufs;
253 int last_frame_reads;
254 int last_clear_reads;
255 int clears;
256 int texture_uploads;
257 } stats;
258
259 int do_boxes;
260 int page_flipping;
261
262 u32 color_fmt;
263 unsigned int front_offset;
264 unsigned int front_pitch;
265 unsigned int back_offset;
266 unsigned int back_pitch;
267
268 u32 depth_fmt;
269 unsigned int depth_offset;
270 unsigned int depth_pitch;
271
272 u32 front_pitch_offset;
273 u32 back_pitch_offset;
274 u32 depth_pitch_offset;
275
276 drm_radeon_depth_clear_t depth_clear;
277
278 unsigned long ring_offset;
279 unsigned long ring_rptr_offset;
280 unsigned long buffers_offset;
281 unsigned long gart_textures_offset;
282
283 drm_local_map_t *sarea;
284 drm_local_map_t *mmio;
285 drm_local_map_t *cp_ring;
286 drm_local_map_t *ring_rptr;
287 drm_local_map_t *gart_textures;
288
289 struct mem_block *gart_heap;
290 struct mem_block *fb_heap;
291
292 /* SW interrupt */
293 wait_queue_head_t swi_queue;
294 atomic_t swi_emitted;
295 int vblank_crtc;
296 uint32_t irq_enable_reg;
297 int irq_enabled;
298 uint32_t r500_disp_irq_reg;
299
300 struct radeon_surface surfaces[RADEON_MAX_SURFACES];
301 struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
302
303 unsigned long pcigart_offset;
304 unsigned int pcigart_offset_set;
305 struct drm_ati_pcigart_info gart_info;
306
307 u32 scratch_ages[5];
308
309 /* starting from here on, data is preserved accross an open */
310 uint32_t flags; /* see radeon_chip_flags */
311 unsigned long fb_aper_offset;
312
313 int num_gb_pipes;
314} drm_radeon_private_t;
315
316typedef struct drm_radeon_buf_priv {
317 u32 age;
318} drm_radeon_buf_priv_t;
319
320typedef struct drm_radeon_kcmd_buffer {
321 int bufsz;
322 char *buf;
323 int nbox;
324 struct drm_clip_rect __user *boxes;
325} drm_radeon_kcmd_buffer_t;
326
327extern int radeon_no_wb;
328extern struct drm_ioctl_desc radeon_ioctls[];
329extern int radeon_max_ioctl;
330
331/* Check whether the given hardware address is inside the framebuffer or the
332 * GART area.
333 */
334static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
335 u64 off)
336{
337 u32 fb_start = dev_priv->fb_location;
338 u32 fb_end = fb_start + dev_priv->fb_size - 1;
339 u32 gart_start = dev_priv->gart_vm_start;
340 u32 gart_end = gart_start + dev_priv->gart_size - 1;
341
342 return ((off >= fb_start && off <= fb_end) ||
343 (off >= gart_start && off <= gart_end));
344}
345
346 /* radeon_cp.c */
347extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
348extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv);
349extern int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv);
350extern int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
351extern int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv);
352extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv);
353extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
354extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
355extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
356extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
357
358extern void radeon_freelist_reset(struct drm_device * dev);
359extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
360
361extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
362
363extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
364
365extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
366extern int radeon_presetup(struct drm_device *dev);
367extern int radeon_driver_postcleanup(struct drm_device *dev);
368
369extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
370extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
371extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv);
372extern void radeon_mem_takedown(struct mem_block **heap);
373extern void radeon_mem_release(struct drm_file *file_priv,
374 struct mem_block *heap);
375
376 /* radeon_irq.c */
377extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
378extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
379
380extern void radeon_do_release(struct drm_device * dev);
381extern int radeon_driver_vblank_wait(struct drm_device * dev,
382 unsigned int *sequence);
383extern int radeon_driver_vblank_wait2(struct drm_device * dev,
384 unsigned int *sequence);
385extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
386extern void radeon_driver_irq_preinstall(struct drm_device * dev);
387extern void radeon_driver_irq_postinstall(struct drm_device * dev);
388extern void radeon_driver_irq_uninstall(struct drm_device * dev);
389extern void radeon_enable_interrupt(struct drm_device *dev);
390extern int radeon_vblank_crtc_get(struct drm_device *dev);
391extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
392
393extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
394extern int radeon_driver_unload(struct drm_device *dev);
395extern int radeon_driver_firstopen(struct drm_device *dev);
396extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv);
397extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp);
398extern void radeon_driver_lastclose(struct drm_device * dev);
399extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv);
400extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
401 unsigned long arg);
402
403/* r300_cmdbuf.c */
404extern void r300_init_reg_flags(struct drm_device *dev);
405
406extern int r300_do_cp_cmdbuf(struct drm_device * dev,
407 struct drm_file *file_priv,
408 drm_radeon_kcmd_buffer_t * cmdbuf);
409
410/* Flags for stats.boxes
411 */
412#define RADEON_BOX_DMA_IDLE 0x1
413#define RADEON_BOX_RING_FULL 0x2
414#define RADEON_BOX_FLIP 0x4
415#define RADEON_BOX_WAIT_IDLE 0x8
416#define RADEON_BOX_TEXTURE_LOAD 0x10
417
418/* Register definitions, register access macros and drmAddMap constants
419 * for Radeon kernel driver.
420 */
421
422#define RADEON_AGP_COMMAND 0x0f60
423#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
424# define RADEON_AGP_ENABLE (1<<8)
425#define RADEON_AUX_SCISSOR_CNTL 0x26f0
426# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24)
427# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25)
428# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26)
429# define RADEON_SCISSOR_0_ENABLE (1 << 28)
430# define RADEON_SCISSOR_1_ENABLE (1 << 29)
431# define RADEON_SCISSOR_2_ENABLE (1 << 30)
432
433#define RADEON_BUS_CNTL 0x0030
434# define RADEON_BUS_MASTER_DIS (1 << 6)
435
436#define RADEON_CLOCK_CNTL_DATA 0x000c
437# define RADEON_PLL_WR_EN (1 << 7)
438#define RADEON_CLOCK_CNTL_INDEX 0x0008
439#define RADEON_CONFIG_APER_SIZE 0x0108
440#define RADEON_CONFIG_MEMSIZE 0x00f8
441#define RADEON_CRTC_OFFSET 0x0224
442#define RADEON_CRTC_OFFSET_CNTL 0x0228
443# define RADEON_CRTC_TILE_EN (1 << 15)
444# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
445#define RADEON_CRTC2_OFFSET 0x0324
446#define RADEON_CRTC2_OFFSET_CNTL 0x0328
447
448#define RADEON_PCIE_INDEX 0x0030
449#define RADEON_PCIE_DATA 0x0034
450#define RADEON_PCIE_TX_GART_CNTL 0x10
451# define RADEON_PCIE_TX_GART_EN (1 << 0)
452# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0 << 1)
453# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1 << 1)
454# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3 << 1)
455# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0 << 3)
456# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1 << 3)
457# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1 << 5)
458# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1 << 8)
459#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
460#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
461#define RADEON_PCIE_TX_GART_BASE 0x13
462#define RADEON_PCIE_TX_GART_START_LO 0x14
463#define RADEON_PCIE_TX_GART_START_HI 0x15
464#define RADEON_PCIE_TX_GART_END_LO 0x16
465#define RADEON_PCIE_TX_GART_END_HI 0x17
466
467#define RS480_NB_MC_INDEX 0x168
468# define RS480_NB_MC_IND_WR_EN (1 << 8)
469#define RS480_NB_MC_DATA 0x16c
470
471#define RS690_MC_INDEX 0x78
472# define RS690_MC_INDEX_MASK 0x1ff
473# define RS690_MC_INDEX_WR_EN (1 << 9)
474# define RS690_MC_INDEX_WR_ACK 0x7f
475#define RS690_MC_DATA 0x7c
476
477/* MC indirect registers */
478#define RS480_MC_MISC_CNTL 0x18
479# define RS480_DISABLE_GTW (1 << 1)
480/* switch between MCIND GART and MM GART registers. 0 = mmgart, 1 = mcind gart */
481# define RS480_GART_INDEX_REG_EN (1 << 12)
482# define RS690_BLOCK_GFX_D3_EN (1 << 14)
483#define RS480_K8_FB_LOCATION 0x1e
484#define RS480_GART_FEATURE_ID 0x2b
485# define RS480_HANG_EN (1 << 11)
486# define RS480_TLB_ENABLE (1 << 18)
487# define RS480_P2P_ENABLE (1 << 19)
488# define RS480_GTW_LAC_EN (1 << 25)
489# define RS480_2LEVEL_GART (0 << 30)
490# define RS480_1LEVEL_GART (1 << 30)
491# define RS480_PDC_EN (1 << 31)
492#define RS480_GART_BASE 0x2c
493#define RS480_GART_CACHE_CNTRL 0x2e
494# define RS480_GART_CACHE_INVALIDATE (1 << 0) /* wait for it to clear */
495#define RS480_AGP_ADDRESS_SPACE_SIZE 0x38
496# define RS480_GART_EN (1 << 0)
497# define RS480_VA_SIZE_32MB (0 << 1)
498# define RS480_VA_SIZE_64MB (1 << 1)
499# define RS480_VA_SIZE_128MB (2 << 1)
500# define RS480_VA_SIZE_256MB (3 << 1)
501# define RS480_VA_SIZE_512MB (4 << 1)
502# define RS480_VA_SIZE_1GB (5 << 1)
503# define RS480_VA_SIZE_2GB (6 << 1)
504#define RS480_AGP_MODE_CNTL 0x39
505# define RS480_POST_GART_Q_SIZE (1 << 18)
506# define RS480_NONGART_SNOOP (1 << 19)
507# define RS480_AGP_RD_BUF_SIZE (1 << 20)
508# define RS480_REQ_TYPE_SNOOP_SHIFT 22
509# define RS480_REQ_TYPE_SNOOP_MASK 0x3
510# define RS480_REQ_TYPE_SNOOP_DIS (1 << 24)
511#define RS480_MC_MISC_UMA_CNTL 0x5f
512#define RS480_MC_MCLK_CNTL 0x7a
513#define RS480_MC_UMA_DUALCH_CNTL 0x86
514
515#define RS690_MC_FB_LOCATION 0x100
516#define RS690_MC_AGP_LOCATION 0x101
517#define RS690_MC_AGP_BASE 0x102
518#define RS690_MC_AGP_BASE_2 0x103
519
520#define R520_MC_IND_INDEX 0x70
521#define R520_MC_IND_WR_EN (1 << 24)
522#define R520_MC_IND_DATA 0x74
523
524#define RV515_MC_FB_LOCATION 0x01
525#define RV515_MC_AGP_LOCATION 0x02
526#define RV515_MC_AGP_BASE 0x03
527#define RV515_MC_AGP_BASE_2 0x04
528
529#define R520_MC_FB_LOCATION 0x04
530#define R520_MC_AGP_LOCATION 0x05
531#define R520_MC_AGP_BASE 0x06
532#define R520_MC_AGP_BASE_2 0x07
533
534#define RADEON_MPP_TB_CONFIG 0x01c0
535#define RADEON_MEM_CNTL 0x0140
536#define RADEON_MEM_SDRAM_MODE_REG 0x0158
537#define RADEON_AGP_BASE_2 0x015c /* r200+ only */
538#define RS480_AGP_BASE_2 0x0164
539#define RADEON_AGP_BASE 0x0170
540
541/* pipe config regs */
542#define R400_GB_PIPE_SELECT 0x402c
543#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
544#define R500_SU_REG_DEST 0x42c8
545#define R300_GB_TILE_CONFIG 0x4018
546# define R300_ENABLE_TILING (1 << 0)
547# define R300_PIPE_COUNT_RV350 (0 << 1)
548# define R300_PIPE_COUNT_R300 (3 << 1)
549# define R300_PIPE_COUNT_R420_3P (6 << 1)
550# define R300_PIPE_COUNT_R420 (7 << 1)
551# define R300_TILE_SIZE_8 (0 << 4)
552# define R300_TILE_SIZE_16 (1 << 4)
553# define R300_TILE_SIZE_32 (2 << 4)
554# define R300_SUBPIXEL_1_12 (0 << 16)
555# define R300_SUBPIXEL_1_16 (1 << 16)
556#define R300_DST_PIPE_CONFIG 0x170c
557# define R300_PIPE_AUTO_CONFIG (1 << 31)
558#define R300_RB2D_DSTCACHE_MODE 0x3428
559# define R300_DC_AUTOFLUSH_ENABLE (1 << 8)
560# define R300_DC_DC_DISABLE_IGNORE_PE (1 << 17)
561
562#define RADEON_RB3D_COLOROFFSET 0x1c40
563#define RADEON_RB3D_COLORPITCH 0x1c48
564
565#define RADEON_SRC_X_Y 0x1590
566
567#define RADEON_DP_GUI_MASTER_CNTL 0x146c
568# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
569# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
570# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4)
571# define RADEON_GMC_BRUSH_NONE (15 << 4)
572# define RADEON_GMC_DST_16BPP (4 << 8)
573# define RADEON_GMC_DST_24BPP (5 << 8)
574# define RADEON_GMC_DST_32BPP (6 << 8)
575# define RADEON_GMC_DST_DATATYPE_SHIFT 8
576# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12)
577# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24)
578# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24)
579# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28)
580# define RADEON_GMC_WR_MSK_DIS (1 << 30)
581# define RADEON_ROP3_S 0x00cc0000
582# define RADEON_ROP3_P 0x00f00000
583#define RADEON_DP_WRITE_MASK 0x16cc
584#define RADEON_SRC_PITCH_OFFSET 0x1428
585#define RADEON_DST_PITCH_OFFSET 0x142c
586#define RADEON_DST_PITCH_OFFSET_C 0x1c80
587# define RADEON_DST_TILE_LINEAR (0 << 30)
588# define RADEON_DST_TILE_MACRO (1 << 30)
589# define RADEON_DST_TILE_MICRO (2 << 30)
590# define RADEON_DST_TILE_BOTH (3 << 30)
591
592#define RADEON_SCRATCH_REG0 0x15e0
593#define RADEON_SCRATCH_REG1 0x15e4
594#define RADEON_SCRATCH_REG2 0x15e8
595#define RADEON_SCRATCH_REG3 0x15ec
596#define RADEON_SCRATCH_REG4 0x15f0
597#define RADEON_SCRATCH_REG5 0x15f4
598#define RADEON_SCRATCH_UMSK 0x0770
599#define RADEON_SCRATCH_ADDR 0x0774
600
601#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
602
603#define GET_SCRATCH( x ) (dev_priv->writeback_works \
604 ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
605 : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
606
607#define RADEON_GEN_INT_CNTL 0x0040
608# define RADEON_CRTC_VBLANK_MASK (1 << 0)
609# define RADEON_CRTC2_VBLANK_MASK (1 << 9)
610# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19)
611# define RADEON_SW_INT_ENABLE (1 << 25)
612
613#define RADEON_GEN_INT_STATUS 0x0044
614# define RADEON_CRTC_VBLANK_STAT (1 << 0)
615# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0)
616# define RADEON_CRTC2_VBLANK_STAT (1 << 9)
617# define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9)
618# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19)
619# define RADEON_SW_INT_TEST (1 << 25)
620# define RADEON_SW_INT_TEST_ACK (1 << 25)
621# define RADEON_SW_INT_FIRE (1 << 26)
622
623#define RADEON_HOST_PATH_CNTL 0x0130
624# define RADEON_HDP_SOFT_RESET (1 << 26)
625# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
626# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28)
627
628#define RADEON_ISYNC_CNTL 0x1724
629# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
630# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1)
631# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2)
632# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3)
633# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
634# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
635
636#define RADEON_RBBM_GUICNTL 0x172c
637# define RADEON_HOST_DATA_SWAP_NONE (0 << 0)
638# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0)
639# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0)
640# define RADEON_HOST_DATA_SWAP_HDW (3 << 0)
641
642#define RADEON_MC_AGP_LOCATION 0x014c
643#define RADEON_MC_FB_LOCATION 0x0148
644#define RADEON_MCLK_CNTL 0x0012
645# define RADEON_FORCEON_MCLKA (1 << 16)
646# define RADEON_FORCEON_MCLKB (1 << 17)
647# define RADEON_FORCEON_YCLKA (1 << 18)
648# define RADEON_FORCEON_YCLKB (1 << 19)
649# define RADEON_FORCEON_MC (1 << 20)
650# define RADEON_FORCEON_AIC (1 << 21)
651
652#define RADEON_PP_BORDER_COLOR_0 0x1d40
653#define RADEON_PP_BORDER_COLOR_1 0x1d44
654#define RADEON_PP_BORDER_COLOR_2 0x1d48
655#define RADEON_PP_CNTL 0x1c38
656# define RADEON_SCISSOR_ENABLE (1 << 1)
657#define RADEON_PP_LUM_MATRIX 0x1d00
658#define RADEON_PP_MISC 0x1c14
659#define RADEON_PP_ROT_MATRIX_0 0x1d58
660#define RADEON_PP_TXFILTER_0 0x1c54
661#define RADEON_PP_TXOFFSET_0 0x1c5c
662#define RADEON_PP_TXFILTER_1 0x1c6c
663#define RADEON_PP_TXFILTER_2 0x1c84
664
665#define R300_RB2D_DSTCACHE_CTLSTAT 0x342c /* use R300_DSTCACHE_CTLSTAT */
666#define R300_DSTCACHE_CTLSTAT 0x1714
667# define R300_RB2D_DC_FLUSH (3 << 0)
668# define R300_RB2D_DC_FREE (3 << 2)
669# define R300_RB2D_DC_FLUSH_ALL 0xf
670# define R300_RB2D_DC_BUSY (1 << 31)
671#define RADEON_RB3D_CNTL 0x1c3c
672# define RADEON_ALPHA_BLEND_ENABLE (1 << 0)
673# define RADEON_PLANE_MASK_ENABLE (1 << 1)
674# define RADEON_DITHER_ENABLE (1 << 2)
675# define RADEON_ROUND_ENABLE (1 << 3)
676# define RADEON_SCALE_DITHER_ENABLE (1 << 4)
677# define RADEON_DITHER_INIT (1 << 5)
678# define RADEON_ROP_ENABLE (1 << 6)
679# define RADEON_STENCIL_ENABLE (1 << 7)
680# define RADEON_Z_ENABLE (1 << 8)
681# define RADEON_ZBLOCK16 (1 << 15)
682#define RADEON_RB3D_DEPTHOFFSET 0x1c24
683#define RADEON_RB3D_DEPTHCLEARVALUE 0x3230
684#define RADEON_RB3D_DEPTHPITCH 0x1c28
685#define RADEON_RB3D_PLANEMASK 0x1d84
686#define RADEON_RB3D_STENCILREFMASK 0x1d7c
687#define RADEON_RB3D_ZCACHE_MODE 0x3250
688#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254
689# define RADEON_RB3D_ZC_FLUSH (1 << 0)
690# define RADEON_RB3D_ZC_FREE (1 << 2)
691# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
692# define RADEON_RB3D_ZC_BUSY (1 << 31)
693#define R300_ZB_ZCACHE_CTLSTAT 0x4f18
694# define R300_ZC_FLUSH (1 << 0)
695# define R300_ZC_FREE (1 << 1)
696# define R300_ZC_FLUSH_ALL 0x3
697# define R300_ZC_BUSY (1 << 31)
698#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
699# define RADEON_RB3D_DC_FLUSH (3 << 0)
700# define RADEON_RB3D_DC_FREE (3 << 2)
701# define RADEON_RB3D_DC_FLUSH_ALL 0xf
702# define RADEON_RB3D_DC_BUSY (1 << 31)
703#define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c
704# define R300_RB3D_DC_FINISH (1 << 4)
705#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
706# define RADEON_Z_TEST_MASK (7 << 4)
707# define RADEON_Z_TEST_ALWAYS (7 << 4)
708# define RADEON_Z_HIERARCHY_ENABLE (1 << 8)
709# define RADEON_STENCIL_TEST_ALWAYS (7 << 12)
710# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16)
711# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20)
712# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24)
713# define RADEON_Z_COMPRESSION_ENABLE (1 << 28)
714# define RADEON_FORCE_Z_DIRTY (1 << 29)
715# define RADEON_Z_WRITE_ENABLE (1 << 30)
716# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31)
717#define RADEON_RBBM_SOFT_RESET 0x00f0
718# define RADEON_SOFT_RESET_CP (1 << 0)
719# define RADEON_SOFT_RESET_HI (1 << 1)
720# define RADEON_SOFT_RESET_SE (1 << 2)
721# define RADEON_SOFT_RESET_RE (1 << 3)
722# define RADEON_SOFT_RESET_PP (1 << 4)
723# define RADEON_SOFT_RESET_E2 (1 << 5)
724# define RADEON_SOFT_RESET_RB (1 << 6)
725# define RADEON_SOFT_RESET_HDP (1 << 7)
726/*
727 * 6:0 Available slots in the FIFO
728 * 8 Host Interface active
729 * 9 CP request active
730 * 10 FIFO request active
731 * 11 Host Interface retry active
732 * 12 CP retry active
733 * 13 FIFO retry active
734 * 14 FIFO pipeline busy
735 * 15 Event engine busy
736 * 16 CP command stream busy
737 * 17 2D engine busy
738 * 18 2D portion of render backend busy
739 * 20 3D setup engine busy
740 * 26 GA engine busy
741 * 27 CBA 2D engine busy
742 * 31 2D engine busy or 3D engine busy or FIFO not empty or CP busy or
743 * command stream queue not empty or Ring Buffer not empty
744 */
745#define RADEON_RBBM_STATUS 0x0e40
746/* Same as the previous RADEON_RBBM_STATUS; this is a mirror of that register. */
747/* #define RADEON_RBBM_STATUS 0x1740 */
748/* bits 6:0 are dword slots available in the cmd fifo */
749# define RADEON_RBBM_FIFOCNT_MASK 0x007f
750# define RADEON_HIRQ_ON_RBB (1 << 8)
751# define RADEON_CPRQ_ON_RBB (1 << 9)
752# define RADEON_CFRQ_ON_RBB (1 << 10)
753# define RADEON_HIRQ_IN_RTBUF (1 << 11)
754# define RADEON_CPRQ_IN_RTBUF (1 << 12)
755# define RADEON_CFRQ_IN_RTBUF (1 << 13)
756# define RADEON_PIPE_BUSY (1 << 14)
757# define RADEON_ENG_EV_BUSY (1 << 15)
758# define RADEON_CP_CMDSTRM_BUSY (1 << 16)
759# define RADEON_E2_BUSY (1 << 17)
760# define RADEON_RB2D_BUSY (1 << 18)
761# define RADEON_RB3D_BUSY (1 << 19) /* not used on r300 */
762# define RADEON_VAP_BUSY (1 << 20)
763# define RADEON_RE_BUSY (1 << 21) /* not used on r300 */
764# define RADEON_TAM_BUSY (1 << 22) /* not used on r300 */
765# define RADEON_TDM_BUSY (1 << 23) /* not used on r300 */
766# define RADEON_PB_BUSY (1 << 24) /* not used on r300 */
767# define RADEON_TIM_BUSY (1 << 25) /* not used on r300 */
768# define RADEON_GA_BUSY (1 << 26)
769# define RADEON_CBA2D_BUSY (1 << 27)
770# define RADEON_RBBM_ACTIVE (1 << 31)
771#define RADEON_RE_LINE_PATTERN 0x1cd0
772#define RADEON_RE_MISC 0x26c4
773#define RADEON_RE_TOP_LEFT 0x26c0
774#define RADEON_RE_WIDTH_HEIGHT 0x1c44
775#define RADEON_RE_STIPPLE_ADDR 0x1cc8
776#define RADEON_RE_STIPPLE_DATA 0x1ccc
777
778#define RADEON_SCISSOR_TL_0 0x1cd8
779#define RADEON_SCISSOR_BR_0 0x1cdc
780#define RADEON_SCISSOR_TL_1 0x1ce0
781#define RADEON_SCISSOR_BR_1 0x1ce4
782#define RADEON_SCISSOR_TL_2 0x1ce8
783#define RADEON_SCISSOR_BR_2 0x1cec
784#define RADEON_SE_COORD_FMT 0x1c50
785#define RADEON_SE_CNTL 0x1c4c
786# define RADEON_FFACE_CULL_CW (0 << 0)
787# define RADEON_BFACE_SOLID (3 << 1)
788# define RADEON_FFACE_SOLID (3 << 3)
789# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6)
790# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8)
791# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8)
792# define RADEON_ALPHA_SHADE_FLAT (1 << 10)
793# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10)
794# define RADEON_SPECULAR_SHADE_FLAT (1 << 12)
795# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12)
796# define RADEON_FOG_SHADE_FLAT (1 << 14)
797# define RADEON_FOG_SHADE_GOURAUD (2 << 14)
798# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24)
799# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25)
800# define RADEON_VTX_PIX_CENTER_OGL (1 << 27)
801# define RADEON_ROUND_MODE_TRUNC (0 << 28)
802# define RADEON_ROUND_PREC_8TH_PIX (1 << 30)
803#define RADEON_SE_CNTL_STATUS 0x2140
804#define RADEON_SE_LINE_WIDTH 0x1db8
805#define RADEON_SE_VPORT_XSCALE 0x1d98
806#define RADEON_SE_ZBIAS_FACTOR 0x1db0
807#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210
808#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254
809#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200
810# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16
811# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28
812#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204
813#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208
814# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16
815#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C
816#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8
817#define RADEON_SURFACE_ACCESS_CLR 0x0bfc
818#define RADEON_SURFACE_CNTL 0x0b00
819# define RADEON_SURF_TRANSLATION_DIS (1 << 8)
820# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20)
821# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20)
822# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20)
823# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20)
824# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22)
825# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22)
826# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22)
827# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22)
828#define RADEON_SURFACE0_INFO 0x0b0c
829# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0)
830# define RADEON_SURF_TILE_MODE_MASK (3 << 16)
831# define RADEON_SURF_TILE_MODE_MACRO (0 << 16)
832# define RADEON_SURF_TILE_MODE_MICRO (1 << 16)
833# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16)
834# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16)
835#define RADEON_SURFACE0_LOWER_BOUND 0x0b04
836#define RADEON_SURFACE0_UPPER_BOUND 0x0b08
837# define RADEON_SURF_ADDRESS_FIXED_MASK (0x3ff << 0)
838#define RADEON_SURFACE1_INFO 0x0b1c
839#define RADEON_SURFACE1_LOWER_BOUND 0x0b14
840#define RADEON_SURFACE1_UPPER_BOUND 0x0b18
841#define RADEON_SURFACE2_INFO 0x0b2c
842#define RADEON_SURFACE2_LOWER_BOUND 0x0b24
843#define RADEON_SURFACE2_UPPER_BOUND 0x0b28
844#define RADEON_SURFACE3_INFO 0x0b3c
845#define RADEON_SURFACE3_LOWER_BOUND 0x0b34
846#define RADEON_SURFACE3_UPPER_BOUND 0x0b38
847#define RADEON_SURFACE4_INFO 0x0b4c
848#define RADEON_SURFACE4_LOWER_BOUND 0x0b44
849#define RADEON_SURFACE4_UPPER_BOUND 0x0b48
850#define RADEON_SURFACE5_INFO 0x0b5c
851#define RADEON_SURFACE5_LOWER_BOUND 0x0b54
852#define RADEON_SURFACE5_UPPER_BOUND 0x0b58
853#define RADEON_SURFACE6_INFO 0x0b6c
854#define RADEON_SURFACE6_LOWER_BOUND 0x0b64
855#define RADEON_SURFACE6_UPPER_BOUND 0x0b68
856#define RADEON_SURFACE7_INFO 0x0b7c
857#define RADEON_SURFACE7_LOWER_BOUND 0x0b74
858#define RADEON_SURFACE7_UPPER_BOUND 0x0b78
859#define RADEON_SW_SEMAPHORE 0x013c
860
861#define RADEON_WAIT_UNTIL 0x1720
862# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
863# define RADEON_WAIT_2D_IDLE (1 << 14)
864# define RADEON_WAIT_3D_IDLE (1 << 15)
865# define RADEON_WAIT_2D_IDLECLEAN (1 << 16)
866# define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
867# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
868
869#define RADEON_RB3D_ZMASKOFFSET 0x3234
870#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
871# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
872# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
873
874/* CP registers */
875#define RADEON_CP_ME_RAM_ADDR 0x07d4
876#define RADEON_CP_ME_RAM_RADDR 0x07d8
877#define RADEON_CP_ME_RAM_DATAH 0x07dc
878#define RADEON_CP_ME_RAM_DATAL 0x07e0
879
880#define RADEON_CP_RB_BASE 0x0700
881#define RADEON_CP_RB_CNTL 0x0704
882# define RADEON_BUF_SWAP_32BIT (2 << 16)
883# define RADEON_RB_NO_UPDATE (1 << 27)
884#define RADEON_CP_RB_RPTR_ADDR 0x070c
885#define RADEON_CP_RB_RPTR 0x0710
886#define RADEON_CP_RB_WPTR 0x0714
887
888#define RADEON_CP_RB_WPTR_DELAY 0x0718
889# define RADEON_PRE_WRITE_TIMER_SHIFT 0
890# define RADEON_PRE_WRITE_LIMIT_SHIFT 23
891
892#define RADEON_CP_IB_BASE 0x0738
893
894#define RADEON_CP_CSQ_CNTL 0x0740
895# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0)
896# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28)
897# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28)
898# define RADEON_CSQ_PRIBM_INDDIS (2 << 28)
899# define RADEON_CSQ_PRIPIO_INDBM (3 << 28)
900# define RADEON_CSQ_PRIBM_INDBM (4 << 28)
901# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28)
902
903#define RADEON_AIC_CNTL 0x01d0
904# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
905#define RADEON_AIC_STAT 0x01d4
906#define RADEON_AIC_PT_BASE 0x01d8
907#define RADEON_AIC_LO_ADDR 0x01dc
908#define RADEON_AIC_HI_ADDR 0x01e0
909#define RADEON_AIC_TLB_ADDR 0x01e4
910#define RADEON_AIC_TLB_DATA 0x01e8
911
912/* CP command packets */
913#define RADEON_CP_PACKET0 0x00000000
914# define RADEON_ONE_REG_WR (1 << 15)
915#define RADEON_CP_PACKET1 0x40000000
916#define RADEON_CP_PACKET2 0x80000000
917#define RADEON_CP_PACKET3 0xC0000000
918# define RADEON_CP_NOP 0x00001000
919# define RADEON_CP_NEXT_CHAR 0x00001900
920# define RADEON_CP_PLY_NEXTSCAN 0x00001D00
921# define RADEON_CP_SET_SCISSORS 0x00001E00
922 /* GEN_INDX_PRIM is unsupported starting with R300 */
923# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
924# define RADEON_WAIT_FOR_IDLE 0x00002600
925# define RADEON_3D_DRAW_VBUF 0x00002800
926# define RADEON_3D_DRAW_IMMD 0x00002900
927# define RADEON_3D_DRAW_INDX 0x00002A00
928# define RADEON_CP_LOAD_PALETTE 0x00002C00
929# define RADEON_3D_LOAD_VBPNTR 0x00002F00
930# define RADEON_MPEG_IDCT_MACROBLOCK 0x00003000
931# define RADEON_MPEG_IDCT_MACROBLOCK_REV 0x00003100
932# define RADEON_3D_CLEAR_ZMASK 0x00003200
933# define RADEON_CP_INDX_BUFFER 0x00003300
934# define RADEON_CP_3D_DRAW_VBUF_2 0x00003400
935# define RADEON_CP_3D_DRAW_IMMD_2 0x00003500
936# define RADEON_CP_3D_DRAW_INDX_2 0x00003600
937# define RADEON_3D_CLEAR_HIZ 0x00003700
938# define RADEON_CP_3D_CLEAR_CMASK 0x00003802
939# define RADEON_CNTL_HOSTDATA_BLT 0x00009400
940# define RADEON_CNTL_PAINT_MULTI 0x00009A00
941# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
942# define RADEON_CNTL_SET_SCISSORS 0xC0001E00
943
944#define RADEON_CP_PACKET_MASK 0xC0000000
945#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
946#define RADEON_CP_PACKET0_REG_MASK 0x000007ff
947#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff
948#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
949
950#define RADEON_VTX_Z_PRESENT (1 << 31)
951#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3)
952
953#define RADEON_PRIM_TYPE_NONE (0 << 0)
954#define RADEON_PRIM_TYPE_POINT (1 << 0)
955#define RADEON_PRIM_TYPE_LINE (2 << 0)
956#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0)
957#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0)
958#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0)
959#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0)
960#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0)
961#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0)
962#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
963#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
964#define RADEON_PRIM_TYPE_MASK 0xf
965#define RADEON_PRIM_WALK_IND (1 << 4)
966#define RADEON_PRIM_WALK_LIST (2 << 4)
967#define RADEON_PRIM_WALK_RING (3 << 4)
968#define RADEON_COLOR_ORDER_BGRA (0 << 6)
969#define RADEON_COLOR_ORDER_RGBA (1 << 6)
970#define RADEON_MAOS_ENABLE (1 << 7)
971#define RADEON_VTX_FMT_R128_MODE (0 << 8)
972#define RADEON_VTX_FMT_RADEON_MODE (1 << 8)
973#define RADEON_NUM_VERTICES_SHIFT 16
974
975#define RADEON_COLOR_FORMAT_CI8 2
976#define RADEON_COLOR_FORMAT_ARGB1555 3
977#define RADEON_COLOR_FORMAT_RGB565 4
978#define RADEON_COLOR_FORMAT_ARGB8888 6
979#define RADEON_COLOR_FORMAT_RGB332 7
980#define RADEON_COLOR_FORMAT_RGB8 9
981#define RADEON_COLOR_FORMAT_ARGB4444 15
982
983#define RADEON_TXFORMAT_I8 0
984#define RADEON_TXFORMAT_AI88 1
985#define RADEON_TXFORMAT_RGB332 2
986#define RADEON_TXFORMAT_ARGB1555 3
987#define RADEON_TXFORMAT_RGB565 4
988#define RADEON_TXFORMAT_ARGB4444 5
989#define RADEON_TXFORMAT_ARGB8888 6
990#define RADEON_TXFORMAT_RGBA8888 7
991#define RADEON_TXFORMAT_Y8 8
992#define RADEON_TXFORMAT_VYUY422 10
993#define RADEON_TXFORMAT_YVYU422 11
994#define RADEON_TXFORMAT_DXT1 12
995#define RADEON_TXFORMAT_DXT23 14
996#define RADEON_TXFORMAT_DXT45 15
997
998#define R200_PP_TXCBLEND_0 0x2f00
999#define R200_PP_TXCBLEND_1 0x2f10
1000#define R200_PP_TXCBLEND_2 0x2f20
1001#define R200_PP_TXCBLEND_3 0x2f30
1002#define R200_PP_TXCBLEND_4 0x2f40
1003#define R200_PP_TXCBLEND_5 0x2f50
1004#define R200_PP_TXCBLEND_6 0x2f60
1005#define R200_PP_TXCBLEND_7 0x2f70
1006#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
1007#define R200_PP_TFACTOR_0 0x2ee0
1008#define R200_SE_VTX_FMT_0 0x2088
1009#define R200_SE_VAP_CNTL 0x2080
1010#define R200_SE_TCL_MATRIX_SEL_0 0x2230
1011#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
1012#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
1013#define R200_PP_TXFILTER_5 0x2ca0
1014#define R200_PP_TXFILTER_4 0x2c80
1015#define R200_PP_TXFILTER_3 0x2c60
1016#define R200_PP_TXFILTER_2 0x2c40
1017#define R200_PP_TXFILTER_1 0x2c20
1018#define R200_PP_TXFILTER_0 0x2c00
1019#define R200_PP_TXOFFSET_5 0x2d78
1020#define R200_PP_TXOFFSET_4 0x2d60
1021#define R200_PP_TXOFFSET_3 0x2d48
1022#define R200_PP_TXOFFSET_2 0x2d30
1023#define R200_PP_TXOFFSET_1 0x2d18
1024#define R200_PP_TXOFFSET_0 0x2d00
1025
1026#define R200_PP_CUBIC_FACES_0 0x2c18
1027#define R200_PP_CUBIC_FACES_1 0x2c38
1028#define R200_PP_CUBIC_FACES_2 0x2c58
1029#define R200_PP_CUBIC_FACES_3 0x2c78
1030#define R200_PP_CUBIC_FACES_4 0x2c98
1031#define R200_PP_CUBIC_FACES_5 0x2cb8
1032#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
1033#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
1034#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
1035#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
1036#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
1037#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
1038#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
1039#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
1040#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
1041#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
1042#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
1043#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
1044#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
1045#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
1046#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
1047#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
1048#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
1049#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
1050#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
1051#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
1052#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
1053#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
1054#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
1055#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
1056#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
1057#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
1058#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
1059#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
1060#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
1061#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
1062
1063#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
1064#define R200_SE_VTE_CNTL 0x20b0
1065#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250
1066#define R200_PP_TAM_DEBUG3 0x2d9c
1067#define R200_PP_CNTL_X 0x2cc4
1068#define R200_SE_VAP_CNTL_STATUS 0x2140
1069#define R200_RE_SCISSOR_TL_0 0x1cd8
1070#define R200_RE_SCISSOR_TL_1 0x1ce0
1071#define R200_RE_SCISSOR_TL_2 0x1ce8
1072#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
1073#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
1074#define R200_SE_VTX_STATE_CNTL 0x2180
1075#define R200_RE_POINTSIZE 0x2648
1076#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
1077
1078#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
1079#define RADEON_PP_TEX_SIZE_1 0x1d0c
1080#define RADEON_PP_TEX_SIZE_2 0x1d14
1081
1082#define RADEON_PP_CUBIC_FACES_0 0x1d24
1083#define RADEON_PP_CUBIC_FACES_1 0x1d28
1084#define RADEON_PP_CUBIC_FACES_2 0x1d2c
1085#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */
1086#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00
1087#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14
1088
1089#define RADEON_SE_TCL_STATE_FLUSH 0x2284
1090
1091#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001
1092#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000
1093#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012
1094#define SE_VTE_CNTL__VTX_XY_FMT_MASK 0x00000100
1095#define SE_VTE_CNTL__VTX_Z_FMT_MASK 0x00000200
1096#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK 0x00000001
1097#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK 0x00000002
1098#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b
1099#define R200_3D_DRAW_IMMD_2 0xC0003500
1100#define R200_SE_VTX_FMT_1 0x208c
1101#define R200_RE_CNTL 0x1c50
1102
1103#define R200_RB3D_BLENDCOLOR 0x3218
1104
1105#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4
1106
1107#define R200_PP_TRI_PERF 0x2cf8
1108
1109#define R200_PP_AFS_0 0x2f80
1110#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */
1111
1112#define R200_VAP_PVS_CNTL_1 0x22D0
1113
1114#define R500_D1CRTC_STATUS 0x609c
1115#define R500_D2CRTC_STATUS 0x689c
1116#define R500_CRTC_V_BLANK (1<<0)
1117
1118#define R500_D1CRTC_FRAME_COUNT 0x60a4
1119#define R500_D2CRTC_FRAME_COUNT 0x68a4
1120
1121#define R500_D1MODE_V_COUNTER 0x6530
1122#define R500_D2MODE_V_COUNTER 0x6d30
1123
1124#define R500_D1MODE_VBLANK_STATUS 0x6534
1125#define R500_D2MODE_VBLANK_STATUS 0x6d34
1126#define R500_VBLANK_OCCURED (1<<0)
1127#define R500_VBLANK_ACK (1<<4)
1128#define R500_VBLANK_STAT (1<<12)
1129#define R500_VBLANK_INT (1<<16)
1130
1131#define R500_DxMODE_INT_MASK 0x6540
1132#define R500_D1MODE_INT_MASK (1<<0)
1133#define R500_D2MODE_INT_MASK (1<<8)
1134
1135#define R500_DISP_INTERRUPT_STATUS 0x7edc
1136#define R500_D1_VBLANK_INTERRUPT (1 << 4)
1137#define R500_D2_VBLANK_INTERRUPT (1 << 5)
1138
1139/* Constants */
1140#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
1141
1142#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0
1143#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1
1144#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2
1145#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3
1146#define RADEON_LAST_DISPATCH 1
1147
1148#define RADEON_MAX_VB_AGE 0x7fffffff
1149#define RADEON_MAX_VB_VERTS (0xffff)
1150
1151#define RADEON_RING_HIGH_MARK 128
1152
1153#define RADEON_PCIGART_TABLE_SIZE (32*1024)
1154
1155#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
1156#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
1157#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
1158#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
1159
1160#define RADEON_WRITE_PLL(addr, val) \
1161do { \
1162 RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \
1163 ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \
1164 RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \
1165} while (0)
1166
1167#define RADEON_WRITE_PCIE(addr, val) \
1168do { \
1169 RADEON_WRITE8(RADEON_PCIE_INDEX, \
1170 ((addr) & 0xff)); \
1171 RADEON_WRITE(RADEON_PCIE_DATA, (val)); \
1172} while (0)
1173
1174#define R500_WRITE_MCIND(addr, val) \
1175do { \
1176 RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \
1177 RADEON_WRITE(R520_MC_IND_DATA, (val)); \
1178 RADEON_WRITE(R520_MC_IND_INDEX, 0); \
1179} while (0)
1180
1181#define RS480_WRITE_MCIND(addr, val) \
1182do { \
1183 RADEON_WRITE(RS480_NB_MC_INDEX, \
1184 ((addr) & 0xff) | RS480_NB_MC_IND_WR_EN); \
1185 RADEON_WRITE(RS480_NB_MC_DATA, (val)); \
1186 RADEON_WRITE(RS480_NB_MC_INDEX, 0xff); \
1187} while (0)
1188
1189#define RS690_WRITE_MCIND(addr, val) \
1190do { \
1191 RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \
1192 RADEON_WRITE(RS690_MC_DATA, val); \
1193 RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
1194} while (0)
1195
1196#define IGP_WRITE_MCIND(addr, val) \
1197do { \
1198 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \
1199 RS690_WRITE_MCIND(addr, val); \
1200 else \
1201 RS480_WRITE_MCIND(addr, val); \
1202} while (0)
1203
1204#define CP_PACKET0( reg, n ) \
1205 (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
1206#define CP_PACKET0_TABLE( reg, n ) \
1207 (RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2))
1208#define CP_PACKET1( reg0, reg1 ) \
1209 (RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2))
1210#define CP_PACKET2() \
1211 (RADEON_CP_PACKET2)
1212#define CP_PACKET3( pkt, n ) \
1213 (RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
1214
1215/* ================================================================
1216 * Engine control helper macros
1217 */
1218
1219#define RADEON_WAIT_UNTIL_2D_IDLE() do { \
1220 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1221 OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
1222 RADEON_WAIT_HOST_IDLECLEAN) ); \
1223} while (0)
1224
1225#define RADEON_WAIT_UNTIL_3D_IDLE() do { \
1226 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1227 OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \
1228 RADEON_WAIT_HOST_IDLECLEAN) ); \
1229} while (0)
1230
1231#define RADEON_WAIT_UNTIL_IDLE() do { \
1232 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1233 OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
1234 RADEON_WAIT_3D_IDLECLEAN | \
1235 RADEON_WAIT_HOST_IDLECLEAN) ); \
1236} while (0)
1237
1238#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \
1239 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1240 OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \
1241} while (0)
1242
1243#define RADEON_FLUSH_CACHE() do { \
1244 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
1245 OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
1246 OUT_RING(RADEON_RB3D_DC_FLUSH); \
1247 } else { \
1248 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
1249 OUT_RING(RADEON_RB3D_DC_FLUSH); \
1250 } \
1251} while (0)
1252
1253#define RADEON_PURGE_CACHE() do { \
1254 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
1255 OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); \
1256 OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
1257 } else { \
1258 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
1259 OUT_RING(RADEON_RB3D_DC_FLUSH_ALL); \
1260 } \
1261} while (0)
1262
1263#define RADEON_FLUSH_ZCACHE() do { \
1264 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
1265 OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \
1266 OUT_RING(RADEON_RB3D_ZC_FLUSH); \
1267 } else { \
1268 OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); \
1269 OUT_RING(R300_ZC_FLUSH); \
1270 } \
1271} while (0)
1272
1273#define RADEON_PURGE_ZCACHE() do { \
1274 if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) { \
1275 OUT_RING(CP_PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); \
1276 OUT_RING(RADEON_RB3D_ZC_FLUSH_ALL); \
1277 } else { \
1278 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); \
1279 OUT_RING(R300_ZC_FLUSH_ALL); \
1280 } \
1281} while (0)
1282
1283/* ================================================================
1284 * Misc helper macros
1285 */
1286
1287/* Perfbox functionality only.
1288 */
1289#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
1290do { \
1291 if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \
1292 u32 head = GET_RING_HEAD( dev_priv ); \
1293 if (head == dev_priv->ring.tail) \
1294 dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \
1295 } \
1296} while (0)
1297
1298#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
1299do { \
1300 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \
1301 if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
1302 int __ret = radeon_do_cp_idle( dev_priv ); \
1303 if ( __ret ) return __ret; \
1304 sarea_priv->last_dispatch = 0; \
1305 radeon_freelist_reset( dev ); \
1306 } \
1307} while (0)
1308
1309#define RADEON_DISPATCH_AGE( age ) do { \
1310 OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \
1311 OUT_RING( age ); \
1312} while (0)
1313
1314#define RADEON_FRAME_AGE( age ) do { \
1315 OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \
1316 OUT_RING( age ); \
1317} while (0)
1318
1319#define RADEON_CLEAR_AGE( age ) do { \
1320 OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \
1321 OUT_RING( age ); \
1322} while (0)
1323
1324/* ================================================================
1325 * Ring control
1326 */
1327
1328#define RADEON_VERBOSE 0
1329
1330#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring;
1331
1332#define BEGIN_RING( n ) do { \
1333 if ( RADEON_VERBOSE ) { \
1334 DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
1335 } \
1336 if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
1337 COMMIT_RING(); \
1338 radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
1339 } \
1340 _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
1341 ring = dev_priv->ring.start; \
1342 write = dev_priv->ring.tail; \
1343 mask = dev_priv->ring.tail_mask; \
1344} while (0)
1345
1346#define ADVANCE_RING() do { \
1347 if ( RADEON_VERBOSE ) { \
1348 DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
1349 write, dev_priv->ring.tail ); \
1350 } \
1351 if (((dev_priv->ring.tail + _nr) & mask) != write) { \
1352 DRM_ERROR( \
1353 "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
1354 ((dev_priv->ring.tail + _nr) & mask), \
1355 write, __LINE__); \
1356 } else \
1357 dev_priv->ring.tail = write; \
1358} while (0)
1359
1360#define COMMIT_RING() do { \
1361 /* Flush writes to ring */ \
1362 DRM_MEMORYBARRIER(); \
1363 GET_RING_HEAD( dev_priv ); \
1364 RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
1365 /* read from PCI bus to ensure correct posting */ \
1366 RADEON_READ( RADEON_CP_RB_RPTR ); \
1367} while (0)
1368
1369#define OUT_RING( x ) do { \
1370 if ( RADEON_VERBOSE ) { \
1371 DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
1372 (unsigned int)(x), write ); \
1373 } \
1374 ring[write++] = (x); \
1375 write &= mask; \
1376} while (0)
1377
1378#define OUT_RING_REG( reg, val ) do { \
1379 OUT_RING( CP_PACKET0( reg, 0 ) ); \
1380 OUT_RING( val ); \
1381} while (0)
1382
1383#define OUT_RING_TABLE( tab, sz ) do { \
1384 int _size = (sz); \
1385 int *_tab = (int *)(tab); \
1386 \
1387 if (write + _size > mask) { \
1388 int _i = (mask+1) - write; \
1389 _size -= _i; \
1390 while (_i > 0 ) { \
1391 *(int *)(ring + write) = *_tab++; \
1392 write++; \
1393 _i--; \
1394 } \
1395 write = 0; \
1396 _tab += _i; \
1397 } \
1398 while (_size > 0) { \
1399 *(ring + write) = *_tab++; \
1400 write++; \
1401 _size--; \
1402 } \
1403 write &= mask; \
1404} while (0)
1405
1406#endif /* __RADEON_DRV_H__ */
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
new file mode 100644
index 000000000000..56decda2a71f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -0,0 +1,424 @@
1/**
2 * \file radeon_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the Radeon DRM.
5 *
6 * \author Paul Mackerras <paulus@samba.org>
7 *
8 * Copyright (C) Paul Mackerras 2005
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/compat.h>
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37typedef struct drm_radeon_init32 {
38 int func;
39 u32 sarea_priv_offset;
40 int is_pci;
41 int cp_mode;
42 int gart_size;
43 int ring_size;
44 int usec_timeout;
45
46 unsigned int fb_bpp;
47 unsigned int front_offset, front_pitch;
48 unsigned int back_offset, back_pitch;
49 unsigned int depth_bpp;
50 unsigned int depth_offset, depth_pitch;
51
52 u32 fb_offset;
53 u32 mmio_offset;
54 u32 ring_offset;
55 u32 ring_rptr_offset;
56 u32 buffers_offset;
57 u32 gart_textures_offset;
58} drm_radeon_init32_t;
59
60static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
61 unsigned long arg)
62{
63 drm_radeon_init32_t init32;
64 drm_radeon_init_t __user *init;
65
66 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
67 return -EFAULT;
68
69 init = compat_alloc_user_space(sizeof(*init));
70 if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
71 || __put_user(init32.func, &init->func)
72 || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
73 || __put_user(init32.is_pci, &init->is_pci)
74 || __put_user(init32.cp_mode, &init->cp_mode)
75 || __put_user(init32.gart_size, &init->gart_size)
76 || __put_user(init32.ring_size, &init->ring_size)
77 || __put_user(init32.usec_timeout, &init->usec_timeout)
78 || __put_user(init32.fb_bpp, &init->fb_bpp)
79 || __put_user(init32.front_offset, &init->front_offset)
80 || __put_user(init32.front_pitch, &init->front_pitch)
81 || __put_user(init32.back_offset, &init->back_offset)
82 || __put_user(init32.back_pitch, &init->back_pitch)
83 || __put_user(init32.depth_bpp, &init->depth_bpp)
84 || __put_user(init32.depth_offset, &init->depth_offset)
85 || __put_user(init32.depth_pitch, &init->depth_pitch)
86 || __put_user(init32.fb_offset, &init->fb_offset)
87 || __put_user(init32.mmio_offset, &init->mmio_offset)
88 || __put_user(init32.ring_offset, &init->ring_offset)
89 || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
90 || __put_user(init32.buffers_offset, &init->buffers_offset)
91 || __put_user(init32.gart_textures_offset,
92 &init->gart_textures_offset))
93 return -EFAULT;
94
95 return drm_ioctl(file->f_path.dentry->d_inode, file,
96 DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
97}
98
99typedef struct drm_radeon_clear32 {
100 unsigned int flags;
101 unsigned int clear_color;
102 unsigned int clear_depth;
103 unsigned int color_mask;
104 unsigned int depth_mask; /* misnamed field: should be stencil */
105 u32 depth_boxes;
106} drm_radeon_clear32_t;
107
108static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
109 unsigned long arg)
110{
111 drm_radeon_clear32_t clr32;
112 drm_radeon_clear_t __user *clr;
113
114 if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
115 return -EFAULT;
116
117 clr = compat_alloc_user_space(sizeof(*clr));
118 if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
119 || __put_user(clr32.flags, &clr->flags)
120 || __put_user(clr32.clear_color, &clr->clear_color)
121 || __put_user(clr32.clear_depth, &clr->clear_depth)
122 || __put_user(clr32.color_mask, &clr->color_mask)
123 || __put_user(clr32.depth_mask, &clr->depth_mask)
124 || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
125 &clr->depth_boxes))
126 return -EFAULT;
127
128 return drm_ioctl(file->f_path.dentry->d_inode, file,
129 DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
130}
131
132typedef struct drm_radeon_stipple32 {
133 u32 mask;
134} drm_radeon_stipple32_t;
135
136static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
137 unsigned long arg)
138{
139 drm_radeon_stipple32_t __user *argp = (void __user *)arg;
140 drm_radeon_stipple_t __user *request;
141 u32 mask;
142
143 if (get_user(mask, &argp->mask))
144 return -EFAULT;
145
146 request = compat_alloc_user_space(sizeof(*request));
147 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
148 || __put_user((unsigned int __user *)(unsigned long)mask,
149 &request->mask))
150 return -EFAULT;
151
152 return drm_ioctl(file->f_path.dentry->d_inode, file,
153 DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
154}
155
156typedef struct drm_radeon_tex_image32 {
157 unsigned int x, y; /* Blit coordinates */
158 unsigned int width, height;
159 u32 data;
160} drm_radeon_tex_image32_t;
161
162typedef struct drm_radeon_texture32 {
163 unsigned int offset;
164 int pitch;
165 int format;
166 int width; /* Texture image coordinates */
167 int height;
168 u32 image;
169} drm_radeon_texture32_t;
170
171static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
172 unsigned long arg)
173{
174 drm_radeon_texture32_t req32;
175 drm_radeon_texture_t __user *request;
176 drm_radeon_tex_image32_t img32;
177 drm_radeon_tex_image_t __user *image;
178
179 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
180 return -EFAULT;
181 if (req32.image == 0)
182 return -EINVAL;
183 if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
184 sizeof(img32)))
185 return -EFAULT;
186
187 request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
188 if (!access_ok(VERIFY_WRITE, request,
189 sizeof(*request) + sizeof(*image)))
190 return -EFAULT;
191 image = (drm_radeon_tex_image_t __user *) (request + 1);
192
193 if (__put_user(req32.offset, &request->offset)
194 || __put_user(req32.pitch, &request->pitch)
195 || __put_user(req32.format, &request->format)
196 || __put_user(req32.width, &request->width)
197 || __put_user(req32.height, &request->height)
198 || __put_user(image, &request->image)
199 || __put_user(img32.x, &image->x)
200 || __put_user(img32.y, &image->y)
201 || __put_user(img32.width, &image->width)
202 || __put_user(img32.height, &image->height)
203 || __put_user((const void __user *)(unsigned long)img32.data,
204 &image->data))
205 return -EFAULT;
206
207 return drm_ioctl(file->f_path.dentry->d_inode, file,
208 DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
209}
210
211typedef struct drm_radeon_vertex2_32 {
212 int idx; /* Index of vertex buffer */
213 int discard; /* Client finished with buffer? */
214 int nr_states;
215 u32 state;
216 int nr_prims;
217 u32 prim;
218} drm_radeon_vertex2_32_t;
219
220static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
221 unsigned long arg)
222{
223 drm_radeon_vertex2_32_t req32;
224 drm_radeon_vertex2_t __user *request;
225
226 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
227 return -EFAULT;
228
229 request = compat_alloc_user_space(sizeof(*request));
230 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
231 || __put_user(req32.idx, &request->idx)
232 || __put_user(req32.discard, &request->discard)
233 || __put_user(req32.nr_states, &request->nr_states)
234 || __put_user((void __user *)(unsigned long)req32.state,
235 &request->state)
236 || __put_user(req32.nr_prims, &request->nr_prims)
237 || __put_user((void __user *)(unsigned long)req32.prim,
238 &request->prim))
239 return -EFAULT;
240
241 return drm_ioctl(file->f_path.dentry->d_inode, file,
242 DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
243}
244
245typedef struct drm_radeon_cmd_buffer32 {
246 int bufsz;
247 u32 buf;
248 int nbox;
249 u32 boxes;
250} drm_radeon_cmd_buffer32_t;
251
252static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
253 unsigned long arg)
254{
255 drm_radeon_cmd_buffer32_t req32;
256 drm_radeon_cmd_buffer_t __user *request;
257
258 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
259 return -EFAULT;
260
261 request = compat_alloc_user_space(sizeof(*request));
262 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
263 || __put_user(req32.bufsz, &request->bufsz)
264 || __put_user((void __user *)(unsigned long)req32.buf,
265 &request->buf)
266 || __put_user(req32.nbox, &request->nbox)
267 || __put_user((void __user *)(unsigned long)req32.boxes,
268 &request->boxes))
269 return -EFAULT;
270
271 return drm_ioctl(file->f_path.dentry->d_inode, file,
272 DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
273}
274
275typedef struct drm_radeon_getparam32 {
276 int param;
277 u32 value;
278} drm_radeon_getparam32_t;
279
280static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
281 unsigned long arg)
282{
283 drm_radeon_getparam32_t req32;
284 drm_radeon_getparam_t __user *request;
285
286 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
287 return -EFAULT;
288
289 request = compat_alloc_user_space(sizeof(*request));
290 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
291 || __put_user(req32.param, &request->param)
292 || __put_user((void __user *)(unsigned long)req32.value,
293 &request->value))
294 return -EFAULT;
295
296 return drm_ioctl(file->f_path.dentry->d_inode, file,
297 DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
298}
299
300typedef struct drm_radeon_mem_alloc32 {
301 int region;
302 int alignment;
303 int size;
304 u32 region_offset; /* offset from start of fb or GART */
305} drm_radeon_mem_alloc32_t;
306
307static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
308 unsigned long arg)
309{
310 drm_radeon_mem_alloc32_t req32;
311 drm_radeon_mem_alloc_t __user *request;
312
313 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
314 return -EFAULT;
315
316 request = compat_alloc_user_space(sizeof(*request));
317 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
318 || __put_user(req32.region, &request->region)
319 || __put_user(req32.alignment, &request->alignment)
320 || __put_user(req32.size, &request->size)
321 || __put_user((int __user *)(unsigned long)req32.region_offset,
322 &request->region_offset))
323 return -EFAULT;
324
325 return drm_ioctl(file->f_path.dentry->d_inode, file,
326 DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
327}
328
329typedef struct drm_radeon_irq_emit32 {
330 u32 irq_seq;
331} drm_radeon_irq_emit32_t;
332
333static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
334 unsigned long arg)
335{
336 drm_radeon_irq_emit32_t req32;
337 drm_radeon_irq_emit_t __user *request;
338
339 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
340 return -EFAULT;
341
342 request = compat_alloc_user_space(sizeof(*request));
343 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
344 || __put_user((int __user *)(unsigned long)req32.irq_seq,
345 &request->irq_seq))
346 return -EFAULT;
347
348 return drm_ioctl(file->f_path.dentry->d_inode, file,
349 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
350}
351
352/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
353#if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
354typedef struct drm_radeon_setparam32 {
355 int param;
356 u64 value;
357} __attribute__((packed)) drm_radeon_setparam32_t;
358
359static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
360 unsigned long arg)
361{
362 drm_radeon_setparam32_t req32;
363 drm_radeon_setparam_t __user *request;
364
365 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
366 return -EFAULT;
367
368 request = compat_alloc_user_space(sizeof(*request));
369 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
370 || __put_user(req32.param, &request->param)
371 || __put_user((void __user *)(unsigned long)req32.value,
372 &request->value))
373 return -EFAULT;
374
375 return drm_ioctl(file->f_dentry->d_inode, file,
376 DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
377}
378#else
379#define compat_radeon_cp_setparam NULL
380#endif /* X86_64 || IA64 */
381
382drm_ioctl_compat_t *radeon_compat_ioctls[] = {
383 [DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
384 [DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
385 [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
386 [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
387 [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
388 [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
389 [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
390 [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam,
391 [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
392 [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
393};
394
395/**
396 * Called whenever a 32-bit process running under a 64-bit kernel
397 * performs an ioctl on /dev/dri/card<n>.
398 *
399 * \param filp file pointer.
400 * \param cmd command.
401 * \param arg user argument.
402 * \return zero on success or negative number on failure.
403 */
404long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
405{
406 unsigned int nr = DRM_IOCTL_NR(cmd);
407 drm_ioctl_compat_t *fn = NULL;
408 int ret;
409
410 if (nr < DRM_COMMAND_BASE)
411 return drm_compat_ioctl(filp, cmd, arg);
412
413 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
414 fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
415
416 lock_kernel(); /* XXX for now */
417 if (fn != NULL)
418 ret = (*fn) (filp, cmd, arg);
419 else
420 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
421 unlock_kernel();
422
423 return ret;
424}
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
new file mode 100644
index 000000000000..ee40d197deb7
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -0,0 +1,320 @@
1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Michel Dänzer <michel@daenzer.net>
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "radeon_drm.h"
36#include "radeon_drv.h"
37
38static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
39 u32 mask)
40{
41 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
42 if (irqs)
43 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
44 return irqs;
45}
46
47/* Interrupts - Used for device synchronization and flushing in the
48 * following circumstances:
49 *
50 * - Exclusive FB access with hw idle:
51 * - Wait for GUI Idle (?) interrupt, then do normal flush.
52 *
53 * - Frame throttling, NV_fence:
54 * - Drop marker irq's into command stream ahead of time.
55 * - Wait on irq's with lock *not held*
56 * - Check each for termination condition
57 *
58 * - Internally in cp_getbuffer, etc:
59 * - as above, but wait with lock held???
60 *
61 * NOTE: These functions are misleadingly named -- the irq's aren't
62 * tied to dma at all, this is just a hangover from dri prehistory.
63 */
64
65irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
66{
67 struct drm_device *dev = (struct drm_device *) arg;
68 drm_radeon_private_t *dev_priv =
69 (drm_radeon_private_t *) dev->dev_private;
70 u32 stat;
71
72 /* Only consider the bits we're interested in - others could be used
73 * outside the DRM
74 */
75 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
76 RADEON_CRTC_VBLANK_STAT |
77 RADEON_CRTC2_VBLANK_STAT));
78 if (!stat)
79 return IRQ_NONE;
80
81 stat &= dev_priv->irq_enable_reg;
82
83 /* SW interrupt */
84 if (stat & RADEON_SW_INT_TEST) {
85 DRM_WAKEUP(&dev_priv->swi_queue);
86 }
87
88 /* VBLANK interrupt */
89 if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) {
90 int vblank_crtc = dev_priv->vblank_crtc;
91
92 if ((vblank_crtc &
93 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
94 (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
95 if (stat & RADEON_CRTC_VBLANK_STAT)
96 atomic_inc(&dev->vbl_received);
97 if (stat & RADEON_CRTC2_VBLANK_STAT)
98 atomic_inc(&dev->vbl_received2);
99 } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
100 (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
101 ((stat & RADEON_CRTC2_VBLANK_STAT) &&
102 (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
103 atomic_inc(&dev->vbl_received);
104
105 DRM_WAKEUP(&dev->vbl_queue);
106 drm_vbl_send_signals(dev);
107 }
108
109 return IRQ_HANDLED;
110}
111
112static int radeon_emit_irq(struct drm_device * dev)
113{
114 drm_radeon_private_t *dev_priv = dev->dev_private;
115 unsigned int ret;
116 RING_LOCALS;
117
118 atomic_inc(&dev_priv->swi_emitted);
119 ret = atomic_read(&dev_priv->swi_emitted);
120
121 BEGIN_RING(4);
122 OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
123 OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
124 ADVANCE_RING();
125 COMMIT_RING();
126
127 return ret;
128}
129
130static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
131{
132 drm_radeon_private_t *dev_priv =
133 (drm_radeon_private_t *) dev->dev_private;
134 int ret = 0;
135
136 if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
137 return 0;
138
139 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
140
141 DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
142 RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
143
144 return ret;
145}
146
147static int radeon_driver_vblank_do_wait(struct drm_device * dev,
148 unsigned int *sequence, int crtc)
149{
150 drm_radeon_private_t *dev_priv =
151 (drm_radeon_private_t *) dev->dev_private;
152 unsigned int cur_vblank;
153 int ret = 0;
154 int ack = 0;
155 atomic_t *counter;
156 if (!dev_priv) {
157 DRM_ERROR("called with no initialization\n");
158 return -EINVAL;
159 }
160
161 if (crtc == DRM_RADEON_VBLANK_CRTC1) {
162 counter = &dev->vbl_received;
163 ack |= RADEON_CRTC_VBLANK_STAT;
164 } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
165 counter = &dev->vbl_received2;
166 ack |= RADEON_CRTC2_VBLANK_STAT;
167 } else
168 return -EINVAL;
169
170 radeon_acknowledge_irqs(dev_priv, ack);
171
172 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
173
174 /* Assume that the user has missed the current sequence number
175 * by about a day rather than she wants to wait for years
176 * using vertical blanks...
177 */
178 DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
179 (((cur_vblank = atomic_read(counter))
180 - *sequence) <= (1 << 23)));
181
182 *sequence = cur_vblank;
183
184 return ret;
185}
186
187int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
188{
189 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
190}
191
192int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
193{
194 return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
195}
196
197/* Needs the lock as it touches the ring.
198 */
199int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
200{
201 drm_radeon_private_t *dev_priv = dev->dev_private;
202 drm_radeon_irq_emit_t *emit = data;
203 int result;
204
205 LOCK_TEST_WITH_RETURN(dev, file_priv);
206
207 if (!dev_priv) {
208 DRM_ERROR("called with no initialization\n");
209 return -EINVAL;
210 }
211
212 result = radeon_emit_irq(dev);
213
214 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
215 DRM_ERROR("copy_to_user\n");
216 return -EFAULT;
217 }
218
219 return 0;
220}
221
222/* Doesn't need the hardware lock.
223 */
224int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv)
225{
226 drm_radeon_private_t *dev_priv = dev->dev_private;
227 drm_radeon_irq_wait_t *irqwait = data;
228
229 if (!dev_priv) {
230 DRM_ERROR("called with no initialization\n");
231 return -EINVAL;
232 }
233
234 return radeon_wait_irq(dev, irqwait->irq_seq);
235}
236
237void radeon_enable_interrupt(struct drm_device *dev)
238{
239 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
240
241 dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
242 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
243 dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
244
245 if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
246 dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
247
248 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
249 dev_priv->irq_enabled = 1;
250}
251
252/* drm_dma.h hooks
253*/
254void radeon_driver_irq_preinstall(struct drm_device * dev)
255{
256 drm_radeon_private_t *dev_priv =
257 (drm_radeon_private_t *) dev->dev_private;
258
259 /* Disable *all* interrupts */
260 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
261
262 /* Clear bits if they're already high */
263 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
264 RADEON_CRTC_VBLANK_STAT |
265 RADEON_CRTC2_VBLANK_STAT));
266}
267
268void radeon_driver_irq_postinstall(struct drm_device * dev)
269{
270 drm_radeon_private_t *dev_priv =
271 (drm_radeon_private_t *) dev->dev_private;
272
273 atomic_set(&dev_priv->swi_emitted, 0);
274 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
275
276 radeon_enable_interrupt(dev);
277}
278
279void radeon_driver_irq_uninstall(struct drm_device * dev)
280{
281 drm_radeon_private_t *dev_priv =
282 (drm_radeon_private_t *) dev->dev_private;
283 if (!dev_priv)
284 return;
285
286 dev_priv->irq_enabled = 0;
287
288 /* Disable *all* interrupts */
289 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
290}
291
292
293int radeon_vblank_crtc_get(struct drm_device *dev)
294{
295 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
296 u32 flag;
297 u32 value;
298
299 flag = RADEON_READ(RADEON_GEN_INT_CNTL);
300 value = 0;
301
302 if (flag & RADEON_CRTC_VBLANK_MASK)
303 value |= DRM_RADEON_VBLANK_CRTC1;
304
305 if (flag & RADEON_CRTC2_VBLANK_MASK)
306 value |= DRM_RADEON_VBLANK_CRTC2;
307 return value;
308}
309
310int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
311{
312 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
313 if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
314 DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value);
315 return -EINVAL;
316 }
317 dev_priv->vblank_crtc = (unsigned int)value;
318 radeon_enable_interrupt(dev);
319 return 0;
320}
diff --git a/drivers/gpu/drm/radeon/radeon_mem.c b/drivers/gpu/drm/radeon/radeon_mem.c
new file mode 100644
index 000000000000..4af5286a36fb
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_mem.c
@@ -0,0 +1,302 @@
1/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37/* Very simple allocator for GART memory, working on a static range
38 * already mapped into each client's address space.
39 */
40
41static struct mem_block *split_block(struct mem_block *p, int start, int size,
42 struct drm_file *file_priv)
43{
44 /* Maybe cut off the start of an existing block */
45 if (start > p->start) {
46 struct mem_block *newblock =
47 drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
48 if (!newblock)
49 goto out;
50 newblock->start = start;
51 newblock->size = p->size - (start - p->start);
52 newblock->file_priv = NULL;
53 newblock->next = p->next;
54 newblock->prev = p;
55 p->next->prev = newblock;
56 p->next = newblock;
57 p->size -= newblock->size;
58 p = newblock;
59 }
60
61 /* Maybe cut off the end of an existing block */
62 if (size < p->size) {
63 struct mem_block *newblock =
64 drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
65 if (!newblock)
66 goto out;
67 newblock->start = start + size;
68 newblock->size = p->size - size;
69 newblock->file_priv = NULL;
70 newblock->next = p->next;
71 newblock->prev = p;
72 p->next->prev = newblock;
73 p->next = newblock;
74 p->size = size;
75 }
76
77 out:
78 /* Our block is in the middle */
79 p->file_priv = file_priv;
80 return p;
81}
82
83static struct mem_block *alloc_block(struct mem_block *heap, int size,
84 int align2, struct drm_file *file_priv)
85{
86 struct mem_block *p;
87 int mask = (1 << align2) - 1;
88
89 list_for_each(p, heap) {
90 int start = (p->start + mask) & ~mask;
91 if (p->file_priv == NULL && start + size <= p->start + p->size)
92 return split_block(p, start, size, file_priv);
93 }
94
95 return NULL;
96}
97
98static struct mem_block *find_block(struct mem_block *heap, int start)
99{
100 struct mem_block *p;
101
102 list_for_each(p, heap)
103 if (p->start == start)
104 return p;
105
106 return NULL;
107}
108
109static void free_block(struct mem_block *p)
110{
111 p->file_priv = NULL;
112
113 /* Assumes a single contiguous range. Needs a special file_priv in
114 * 'heap' to stop it being subsumed.
115 */
116 if (p->next->file_priv == NULL) {
117 struct mem_block *q = p->next;
118 p->size += q->size;
119 p->next = q->next;
120 p->next->prev = p;
121 drm_free(q, sizeof(*q), DRM_MEM_BUFS);
122 }
123
124 if (p->prev->file_priv == NULL) {
125 struct mem_block *q = p->prev;
126 q->size += p->size;
127 q->next = p->next;
128 q->next->prev = q;
129 drm_free(p, sizeof(*q), DRM_MEM_BUFS);
130 }
131}
132
133/* Initialize. How to check for an uninitialized heap?
134 */
135static int init_heap(struct mem_block **heap, int start, int size)
136{
137 struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
138
139 if (!blocks)
140 return -ENOMEM;
141
142 *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
143 if (!*heap) {
144 drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
145 return -ENOMEM;
146 }
147
148 blocks->start = start;
149 blocks->size = size;
150 blocks->file_priv = NULL;
151 blocks->next = blocks->prev = *heap;
152
153 memset(*heap, 0, sizeof(**heap));
154 (*heap)->file_priv = (struct drm_file *) - 1;
155 (*heap)->next = (*heap)->prev = blocks;
156 return 0;
157}
158
159/* Free all blocks associated with the releasing file.
160 */
161void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap)
162{
163 struct mem_block *p;
164
165 if (!heap || !heap->next)
166 return;
167
168 list_for_each(p, heap) {
169 if (p->file_priv == file_priv)
170 p->file_priv = NULL;
171 }
172
173 /* Assumes a single contiguous range. Needs a special file_priv in
174 * 'heap' to stop it being subsumed.
175 */
176 list_for_each(p, heap) {
177 while (p->file_priv == NULL && p->next->file_priv == NULL) {
178 struct mem_block *q = p->next;
179 p->size += q->size;
180 p->next = q->next;
181 p->next->prev = p;
182 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
183 }
184 }
185}
186
187/* Shutdown.
188 */
189void radeon_mem_takedown(struct mem_block **heap)
190{
191 struct mem_block *p;
192
193 if (!*heap)
194 return;
195
196 for (p = (*heap)->next; p != *heap;) {
197 struct mem_block *q = p;
198 p = p->next;
199 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
200 }
201
202 drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
203 *heap = NULL;
204}
205
206/* IOCTL HANDLERS */
207
208static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region)
209{
210 switch (region) {
211 case RADEON_MEM_REGION_GART:
212 return &dev_priv->gart_heap;
213 case RADEON_MEM_REGION_FB:
214 return &dev_priv->fb_heap;
215 default:
216 return NULL;
217 }
218}
219
220int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
221{
222 drm_radeon_private_t *dev_priv = dev->dev_private;
223 drm_radeon_mem_alloc_t *alloc = data;
224 struct mem_block *block, **heap;
225
226 if (!dev_priv) {
227 DRM_ERROR("called with no initialization\n");
228 return -EINVAL;
229 }
230
231 heap = get_heap(dev_priv, alloc->region);
232 if (!heap || !*heap)
233 return -EFAULT;
234
235 /* Make things easier on ourselves: all allocations at least
236 * 4k aligned.
237 */
238 if (alloc->alignment < 12)
239 alloc->alignment = 12;
240
241 block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);
242
243 if (!block)
244 return -ENOMEM;
245
246 if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
247 sizeof(int))) {
248 DRM_ERROR("copy_to_user\n");
249 return -EFAULT;
250 }
251
252 return 0;
253}
254
255int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
256{
257 drm_radeon_private_t *dev_priv = dev->dev_private;
258 drm_radeon_mem_free_t *memfree = data;
259 struct mem_block *block, **heap;
260
261 if (!dev_priv) {
262 DRM_ERROR("called with no initialization\n");
263 return -EINVAL;
264 }
265
266 heap = get_heap(dev_priv, memfree->region);
267 if (!heap || !*heap)
268 return -EFAULT;
269
270 block = find_block(*heap, memfree->region_offset);
271 if (!block)
272 return -EFAULT;
273
274 if (block->file_priv != file_priv)
275 return -EPERM;
276
277 free_block(block);
278 return 0;
279}
280
281int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv)
282{
283 drm_radeon_private_t *dev_priv = dev->dev_private;
284 drm_radeon_mem_init_heap_t *initheap = data;
285 struct mem_block **heap;
286
287 if (!dev_priv) {
288 DRM_ERROR("called with no initialization\n");
289 return -EINVAL;
290 }
291
292 heap = get_heap(dev_priv, initheap->region);
293 if (!heap)
294 return -EFAULT;
295
296 if (*heap) {
297 DRM_ERROR("heap already initialized?");
298 return -EFAULT;
299 }
300
301 return init_heap(heap, initheap->start, initheap->size);
302}
diff --git a/drivers/gpu/drm/radeon/radeon_microcode.h b/drivers/gpu/drm/radeon/radeon_microcode.h
new file mode 100644
index 000000000000..a348c9e7db1c
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_microcode.h
@@ -0,0 +1,1844 @@
1/*
2 * Copyright 2007 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26#ifndef RADEON_MICROCODE_H
27#define RADEON_MICROCODE_H
28
29/* production radeon ucode r1xx-r6xx */
30static const u32 R100_cp_microcode[][2] = {
31 { 0x21007000, 0000000000 },
32 { 0x20007000, 0000000000 },
33 { 0x000000b4, 0x00000004 },
34 { 0x000000b8, 0x00000004 },
35 { 0x6f5b4d4c, 0000000000 },
36 { 0x4c4c427f, 0000000000 },
37 { 0x5b568a92, 0000000000 },
38 { 0x4ca09c6d, 0000000000 },
39 { 0xad4c4c4c, 0000000000 },
40 { 0x4ce1af3d, 0000000000 },
41 { 0xd8afafaf, 0000000000 },
42 { 0xd64c4cdc, 0000000000 },
43 { 0x4cd10d10, 0000000000 },
44 { 0x000f0000, 0x00000016 },
45 { 0x362f242d, 0000000000 },
46 { 0x00000012, 0x00000004 },
47 { 0x000f0000, 0x00000016 },
48 { 0x362f282d, 0000000000 },
49 { 0x000380e7, 0x00000002 },
50 { 0x04002c97, 0x00000002 },
51 { 0x000f0001, 0x00000016 },
52 { 0x333a3730, 0000000000 },
53 { 0x000077ef, 0x00000002 },
54 { 0x00061000, 0x00000002 },
55 { 0x00000021, 0x0000001a },
56 { 0x00004000, 0x0000001e },
57 { 0x00061000, 0x00000002 },
58 { 0x00000021, 0x0000001a },
59 { 0x00004000, 0x0000001e },
60 { 0x00061000, 0x00000002 },
61 { 0x00000021, 0x0000001a },
62 { 0x00004000, 0x0000001e },
63 { 0x00000017, 0x00000004 },
64 { 0x0003802b, 0x00000002 },
65 { 0x040067e0, 0x00000002 },
66 { 0x00000017, 0x00000004 },
67 { 0x000077e0, 0x00000002 },
68 { 0x00065000, 0x00000002 },
69 { 0x000037e1, 0x00000002 },
70 { 0x040067e1, 0x00000006 },
71 { 0x000077e0, 0x00000002 },
72 { 0x000077e1, 0x00000002 },
73 { 0x000077e1, 0x00000006 },
74 { 0xffffffff, 0000000000 },
75 { 0x10000000, 0000000000 },
76 { 0x0003802b, 0x00000002 },
77 { 0x040067e0, 0x00000006 },
78 { 0x00007675, 0x00000002 },
79 { 0x00007676, 0x00000002 },
80 { 0x00007677, 0x00000002 },
81 { 0x00007678, 0x00000006 },
82 { 0x0003802c, 0x00000002 },
83 { 0x04002676, 0x00000002 },
84 { 0x00007677, 0x00000002 },
85 { 0x00007678, 0x00000006 },
86 { 0x0000002f, 0x00000018 },
87 { 0x0000002f, 0x00000018 },
88 { 0000000000, 0x00000006 },
89 { 0x00000030, 0x00000018 },
90 { 0x00000030, 0x00000018 },
91 { 0000000000, 0x00000006 },
92 { 0x01605000, 0x00000002 },
93 { 0x00065000, 0x00000002 },
94 { 0x00098000, 0x00000002 },
95 { 0x00061000, 0x00000002 },
96 { 0x64c0603e, 0x00000004 },
97 { 0x000380e6, 0x00000002 },
98 { 0x040025c5, 0x00000002 },
99 { 0x00080000, 0x00000016 },
100 { 0000000000, 0000000000 },
101 { 0x0400251d, 0x00000002 },
102 { 0x00007580, 0x00000002 },
103 { 0x00067581, 0x00000002 },
104 { 0x04002580, 0x00000002 },
105 { 0x00067581, 0x00000002 },
106 { 0x00000049, 0x00000004 },
107 { 0x00005000, 0000000000 },
108 { 0x000380e6, 0x00000002 },
109 { 0x040025c5, 0x00000002 },
110 { 0x00061000, 0x00000002 },
111 { 0x0000750e, 0x00000002 },
112 { 0x00019000, 0x00000002 },
113 { 0x00011055, 0x00000014 },
114 { 0x00000055, 0x00000012 },
115 { 0x0400250f, 0x00000002 },
116 { 0x0000504f, 0x00000004 },
117 { 0x000380e6, 0x00000002 },
118 { 0x040025c5, 0x00000002 },
119 { 0x00007565, 0x00000002 },
120 { 0x00007566, 0x00000002 },
121 { 0x00000058, 0x00000004 },
122 { 0x000380e6, 0x00000002 },
123 { 0x040025c5, 0x00000002 },
124 { 0x01e655b4, 0x00000002 },
125 { 0x4401b0e4, 0x00000002 },
126 { 0x01c110e4, 0x00000002 },
127 { 0x26667066, 0x00000018 },
128 { 0x040c2565, 0x00000002 },
129 { 0x00000066, 0x00000018 },
130 { 0x04002564, 0x00000002 },
131 { 0x00007566, 0x00000002 },
132 { 0x0000005d, 0x00000004 },
133 { 0x00401069, 0x00000008 },
134 { 0x00101000, 0x00000002 },
135 { 0x000d80ff, 0x00000002 },
136 { 0x0080006c, 0x00000008 },
137 { 0x000f9000, 0x00000002 },
138 { 0x000e00ff, 0x00000002 },
139 { 0000000000, 0x00000006 },
140 { 0x0000008f, 0x00000018 },
141 { 0x0000005b, 0x00000004 },
142 { 0x000380e6, 0x00000002 },
143 { 0x040025c5, 0x00000002 },
144 { 0x00007576, 0x00000002 },
145 { 0x00065000, 0x00000002 },
146 { 0x00009000, 0x00000002 },
147 { 0x00041000, 0x00000002 },
148 { 0x0c00350e, 0x00000002 },
149 { 0x00049000, 0x00000002 },
150 { 0x00051000, 0x00000002 },
151 { 0x01e785f8, 0x00000002 },
152 { 0x00200000, 0x00000002 },
153 { 0x0060007e, 0x0000000c },
154 { 0x00007563, 0x00000002 },
155 { 0x006075f0, 0x00000021 },
156 { 0x20007073, 0x00000004 },
157 { 0x00005073, 0x00000004 },
158 { 0x000380e6, 0x00000002 },
159 { 0x040025c5, 0x00000002 },
160 { 0x00007576, 0x00000002 },
161 { 0x00007577, 0x00000002 },
162 { 0x0000750e, 0x00000002 },
163 { 0x0000750f, 0x00000002 },
164 { 0x00a05000, 0x00000002 },
165 { 0x00600083, 0x0000000c },
166 { 0x006075f0, 0x00000021 },
167 { 0x000075f8, 0x00000002 },
168 { 0x00000083, 0x00000004 },
169 { 0x000a750e, 0x00000002 },
170 { 0x000380e6, 0x00000002 },
171 { 0x040025c5, 0x00000002 },
172 { 0x0020750f, 0x00000002 },
173 { 0x00600086, 0x00000004 },
174 { 0x00007570, 0x00000002 },
175 { 0x00007571, 0x00000002 },
176 { 0x00007572, 0x00000006 },
177 { 0x000380e6, 0x00000002 },
178 { 0x040025c5, 0x00000002 },
179 { 0x00005000, 0x00000002 },
180 { 0x00a05000, 0x00000002 },
181 { 0x00007568, 0x00000002 },
182 { 0x00061000, 0x00000002 },
183 { 0x00000095, 0x0000000c },
184 { 0x00058000, 0x00000002 },
185 { 0x0c607562, 0x00000002 },
186 { 0x00000097, 0x00000004 },
187 { 0x000380e6, 0x00000002 },
188 { 0x040025c5, 0x00000002 },
189 { 0x00600096, 0x00000004 },
190 { 0x400070e5, 0000000000 },
191 { 0x000380e6, 0x00000002 },
192 { 0x040025c5, 0x00000002 },
193 { 0x000380e5, 0x00000002 },
194 { 0x000000a8, 0x0000001c },
195 { 0x000650aa, 0x00000018 },
196 { 0x040025bb, 0x00000002 },
197 { 0x000610ab, 0x00000018 },
198 { 0x040075bc, 0000000000 },
199 { 0x000075bb, 0x00000002 },
200 { 0x000075bc, 0000000000 },
201 { 0x00090000, 0x00000006 },
202 { 0x00090000, 0x00000002 },
203 { 0x000d8002, 0x00000006 },
204 { 0x00007832, 0x00000002 },
205 { 0x00005000, 0x00000002 },
206 { 0x000380e7, 0x00000002 },
207 { 0x04002c97, 0x00000002 },
208 { 0x00007820, 0x00000002 },
209 { 0x00007821, 0x00000002 },
210 { 0x00007800, 0000000000 },
211 { 0x01200000, 0x00000002 },
212 { 0x20077000, 0x00000002 },
213 { 0x01200000, 0x00000002 },
214 { 0x20007000, 0x00000002 },
215 { 0x00061000, 0x00000002 },
216 { 0x0120751b, 0x00000002 },
217 { 0x8040750a, 0x00000002 },
218 { 0x8040750b, 0x00000002 },
219 { 0x00110000, 0x00000002 },
220 { 0x000380e5, 0x00000002 },
221 { 0x000000c6, 0x0000001c },
222 { 0x000610ab, 0x00000018 },
223 { 0x844075bd, 0x00000002 },
224 { 0x000610aa, 0x00000018 },
225 { 0x840075bb, 0x00000002 },
226 { 0x000610ab, 0x00000018 },
227 { 0x844075bc, 0x00000002 },
228 { 0x000000c9, 0x00000004 },
229 { 0x804075bd, 0x00000002 },
230 { 0x800075bb, 0x00000002 },
231 { 0x804075bc, 0x00000002 },
232 { 0x00108000, 0x00000002 },
233 { 0x01400000, 0x00000002 },
234 { 0x006000cd, 0x0000000c },
235 { 0x20c07000, 0x00000020 },
236 { 0x000000cf, 0x00000012 },
237 { 0x00800000, 0x00000006 },
238 { 0x0080751d, 0x00000006 },
239 { 0000000000, 0000000000 },
240 { 0x0000775c, 0x00000002 },
241 { 0x00a05000, 0x00000002 },
242 { 0x00661000, 0x00000002 },
243 { 0x0460275d, 0x00000020 },
244 { 0x00004000, 0000000000 },
245 { 0x01e00830, 0x00000002 },
246 { 0x21007000, 0000000000 },
247 { 0x6464614d, 0000000000 },
248 { 0x69687420, 0000000000 },
249 { 0x00000073, 0000000000 },
250 { 0000000000, 0000000000 },
251 { 0x00005000, 0x00000002 },
252 { 0x000380d0, 0x00000002 },
253 { 0x040025e0, 0x00000002 },
254 { 0x000075e1, 0000000000 },
255 { 0x00000001, 0000000000 },
256 { 0x000380e0, 0x00000002 },
257 { 0x04002394, 0x00000002 },
258 { 0x00005000, 0000000000 },
259 { 0000000000, 0000000000 },
260 { 0000000000, 0000000000 },
261 { 0x00000008, 0000000000 },
262 { 0x00000004, 0000000000 },
263 { 0000000000, 0000000000 },
264 { 0000000000, 0000000000 },
265 { 0000000000, 0000000000 },
266 { 0000000000, 0000000000 },
267 { 0000000000, 0000000000 },
268 { 0000000000, 0000000000 },
269 { 0000000000, 0000000000 },
270 { 0000000000, 0000000000 },
271 { 0000000000, 0000000000 },
272 { 0000000000, 0000000000 },
273 { 0000000000, 0000000000 },
274 { 0000000000, 0000000000 },
275 { 0000000000, 0000000000 },
276 { 0000000000, 0000000000 },
277 { 0000000000, 0000000000 },
278 { 0000000000, 0000000000 },
279 { 0000000000, 0000000000 },
280 { 0000000000, 0000000000 },
281 { 0000000000, 0000000000 },
282 { 0000000000, 0000000000 },
283 { 0000000000, 0000000000 },
284 { 0000000000, 0000000000 },
285 { 0000000000, 0000000000 },
286 { 0000000000, 0000000000 },
287};
288
289static const u32 R200_cp_microcode[][2] = {
290 { 0x21007000, 0000000000 },
291 { 0x20007000, 0000000000 },
292 { 0x000000bf, 0x00000004 },
293 { 0x000000c3, 0x00000004 },
294 { 0x7a685e5d, 0000000000 },
295 { 0x5d5d5588, 0000000000 },
296 { 0x68659197, 0000000000 },
297 { 0x5da19f78, 0000000000 },
298 { 0x5d5d5d5d, 0000000000 },
299 { 0x5dee5d50, 0000000000 },
300 { 0xf2acacac, 0000000000 },
301 { 0xe75df9e9, 0000000000 },
302 { 0xb1dd0e11, 0000000000 },
303 { 0xe2afafaf, 0000000000 },
304 { 0x000f0000, 0x00000016 },
305 { 0x452f232d, 0000000000 },
306 { 0x00000013, 0x00000004 },
307 { 0x000f0000, 0x00000016 },
308 { 0x452f272d, 0000000000 },
309 { 0x000f0001, 0x00000016 },
310 { 0x3e4d4a37, 0000000000 },
311 { 0x000077ef, 0x00000002 },
312 { 0x00061000, 0x00000002 },
313 { 0x00000020, 0x0000001a },
314 { 0x00004000, 0x0000001e },
315 { 0x00061000, 0x00000002 },
316 { 0x00000020, 0x0000001a },
317 { 0x00004000, 0x0000001e },
318 { 0x00061000, 0x00000002 },
319 { 0x00000020, 0x0000001a },
320 { 0x00004000, 0x0000001e },
321 { 0x00000016, 0x00000004 },
322 { 0x0003802a, 0x00000002 },
323 { 0x040067e0, 0x00000002 },
324 { 0x00000016, 0x00000004 },
325 { 0x000077e0, 0x00000002 },
326 { 0x00065000, 0x00000002 },
327 { 0x000037e1, 0x00000002 },
328 { 0x040067e1, 0x00000006 },
329 { 0x000077e0, 0x00000002 },
330 { 0x000077e1, 0x00000002 },
331 { 0x000077e1, 0x00000006 },
332 { 0xffffffff, 0000000000 },
333 { 0x10000000, 0000000000 },
334 { 0x07f007f0, 0000000000 },
335 { 0x0003802a, 0x00000002 },
336 { 0x040067e0, 0x00000006 },
337 { 0x0003802c, 0x00000002 },
338 { 0x04002741, 0x00000002 },
339 { 0x04002741, 0x00000002 },
340 { 0x04002743, 0x00000002 },
341 { 0x00007675, 0x00000002 },
342 { 0x00007676, 0x00000002 },
343 { 0x00007677, 0x00000002 },
344 { 0x00007678, 0x00000006 },
345 { 0x0003802c, 0x00000002 },
346 { 0x04002741, 0x00000002 },
347 { 0x04002741, 0x00000002 },
348 { 0x04002743, 0x00000002 },
349 { 0x00007676, 0x00000002 },
350 { 0x00007677, 0x00000002 },
351 { 0x00007678, 0x00000006 },
352 { 0x0003802b, 0x00000002 },
353 { 0x04002676, 0x00000002 },
354 { 0x00007677, 0x00000002 },
355 { 0x0003802c, 0x00000002 },
356 { 0x04002741, 0x00000002 },
357 { 0x04002743, 0x00000002 },
358 { 0x00007678, 0x00000006 },
359 { 0x0003802c, 0x00000002 },
360 { 0x04002741, 0x00000002 },
361 { 0x04002741, 0x00000002 },
362 { 0x04002743, 0x00000002 },
363 { 0x00007678, 0x00000006 },
364 { 0x0000002f, 0x00000018 },
365 { 0x0000002f, 0x00000018 },
366 { 0000000000, 0x00000006 },
367 { 0x00000037, 0x00000018 },
368 { 0x00000037, 0x00000018 },
369 { 0000000000, 0x00000006 },
370 { 0x01605000, 0x00000002 },
371 { 0x00065000, 0x00000002 },
372 { 0x00098000, 0x00000002 },
373 { 0x00061000, 0x00000002 },
374 { 0x64c06051, 0x00000004 },
375 { 0x00080000, 0x00000016 },
376 { 0000000000, 0000000000 },
377 { 0x0400251d, 0x00000002 },
378 { 0x00007580, 0x00000002 },
379 { 0x00067581, 0x00000002 },
380 { 0x04002580, 0x00000002 },
381 { 0x00067581, 0x00000002 },
382 { 0x0000005a, 0x00000004 },
383 { 0x00005000, 0000000000 },
384 { 0x00061000, 0x00000002 },
385 { 0x0000750e, 0x00000002 },
386 { 0x00019000, 0x00000002 },
387 { 0x00011064, 0x00000014 },
388 { 0x00000064, 0x00000012 },
389 { 0x0400250f, 0x00000002 },
390 { 0x0000505e, 0x00000004 },
391 { 0x00007565, 0x00000002 },
392 { 0x00007566, 0x00000002 },
393 { 0x00000065, 0x00000004 },
394 { 0x01e655b4, 0x00000002 },
395 { 0x4401b0f0, 0x00000002 },
396 { 0x01c110f0, 0x00000002 },
397 { 0x26667071, 0x00000018 },
398 { 0x040c2565, 0x00000002 },
399 { 0x00000071, 0x00000018 },
400 { 0x04002564, 0x00000002 },
401 { 0x00007566, 0x00000002 },
402 { 0x00000068, 0x00000004 },
403 { 0x00401074, 0x00000008 },
404 { 0x00101000, 0x00000002 },
405 { 0x000d80ff, 0x00000002 },
406 { 0x00800077, 0x00000008 },
407 { 0x000f9000, 0x00000002 },
408 { 0x000e00ff, 0x00000002 },
409 { 0000000000, 0x00000006 },
410 { 0x00000094, 0x00000018 },
411 { 0x00000068, 0x00000004 },
412 { 0x00007576, 0x00000002 },
413 { 0x00065000, 0x00000002 },
414 { 0x00009000, 0x00000002 },
415 { 0x00041000, 0x00000002 },
416 { 0x0c00350e, 0x00000002 },
417 { 0x00049000, 0x00000002 },
418 { 0x00051000, 0x00000002 },
419 { 0x01e785f8, 0x00000002 },
420 { 0x00200000, 0x00000002 },
421 { 0x00600087, 0x0000000c },
422 { 0x00007563, 0x00000002 },
423 { 0x006075f0, 0x00000021 },
424 { 0x2000707c, 0x00000004 },
425 { 0x0000507c, 0x00000004 },
426 { 0x00007576, 0x00000002 },
427 { 0x00007577, 0x00000002 },
428 { 0x0000750e, 0x00000002 },
429 { 0x0000750f, 0x00000002 },
430 { 0x00a05000, 0x00000002 },
431 { 0x0060008a, 0x0000000c },
432 { 0x006075f0, 0x00000021 },
433 { 0x000075f8, 0x00000002 },
434 { 0x0000008a, 0x00000004 },
435 { 0x000a750e, 0x00000002 },
436 { 0x0020750f, 0x00000002 },
437 { 0x0060008d, 0x00000004 },
438 { 0x00007570, 0x00000002 },
439 { 0x00007571, 0x00000002 },
440 { 0x00007572, 0x00000006 },
441 { 0x00005000, 0x00000002 },
442 { 0x00a05000, 0x00000002 },
443 { 0x00007568, 0x00000002 },
444 { 0x00061000, 0x00000002 },
445 { 0x00000098, 0x0000000c },
446 { 0x00058000, 0x00000002 },
447 { 0x0c607562, 0x00000002 },
448 { 0x0000009a, 0x00000004 },
449 { 0x00600099, 0x00000004 },
450 { 0x400070f1, 0000000000 },
451 { 0x000380f1, 0x00000002 },
452 { 0x000000a7, 0x0000001c },
453 { 0x000650a9, 0x00000018 },
454 { 0x040025bb, 0x00000002 },
455 { 0x000610aa, 0x00000018 },
456 { 0x040075bc, 0000000000 },
457 { 0x000075bb, 0x00000002 },
458 { 0x000075bc, 0000000000 },
459 { 0x00090000, 0x00000006 },
460 { 0x00090000, 0x00000002 },
461 { 0x000d8002, 0x00000006 },
462 { 0x00005000, 0x00000002 },
463 { 0x00007821, 0x00000002 },
464 { 0x00007800, 0000000000 },
465 { 0x00007821, 0x00000002 },
466 { 0x00007800, 0000000000 },
467 { 0x01665000, 0x00000002 },
468 { 0x000a0000, 0x00000002 },
469 { 0x000671cc, 0x00000002 },
470 { 0x0286f1cd, 0x00000002 },
471 { 0x000000b7, 0x00000010 },
472 { 0x21007000, 0000000000 },
473 { 0x000000be, 0x0000001c },
474 { 0x00065000, 0x00000002 },
475 { 0x000a0000, 0x00000002 },
476 { 0x00061000, 0x00000002 },
477 { 0x000b0000, 0x00000002 },
478 { 0x38067000, 0x00000002 },
479 { 0x000a00ba, 0x00000004 },
480 { 0x20007000, 0000000000 },
481 { 0x01200000, 0x00000002 },
482 { 0x20077000, 0x00000002 },
483 { 0x01200000, 0x00000002 },
484 { 0x20007000, 0000000000 },
485 { 0x00061000, 0x00000002 },
486 { 0x0120751b, 0x00000002 },
487 { 0x8040750a, 0x00000002 },
488 { 0x8040750b, 0x00000002 },
489 { 0x00110000, 0x00000002 },
490 { 0x000380f1, 0x00000002 },
491 { 0x000000d1, 0x0000001c },
492 { 0x000610aa, 0x00000018 },
493 { 0x844075bd, 0x00000002 },
494 { 0x000610a9, 0x00000018 },
495 { 0x840075bb, 0x00000002 },
496 { 0x000610aa, 0x00000018 },
497 { 0x844075bc, 0x00000002 },
498 { 0x000000d4, 0x00000004 },
499 { 0x804075bd, 0x00000002 },
500 { 0x800075bb, 0x00000002 },
501 { 0x804075bc, 0x00000002 },
502 { 0x00108000, 0x00000002 },
503 { 0x01400000, 0x00000002 },
504 { 0x006000d8, 0x0000000c },
505 { 0x20c07000, 0x00000020 },
506 { 0x000000da, 0x00000012 },
507 { 0x00800000, 0x00000006 },
508 { 0x0080751d, 0x00000006 },
509 { 0x000025bb, 0x00000002 },
510 { 0x000040d4, 0x00000004 },
511 { 0x0000775c, 0x00000002 },
512 { 0x00a05000, 0x00000002 },
513 { 0x00661000, 0x00000002 },
514 { 0x0460275d, 0x00000020 },
515 { 0x00004000, 0000000000 },
516 { 0x00007999, 0x00000002 },
517 { 0x00a05000, 0x00000002 },
518 { 0x00661000, 0x00000002 },
519 { 0x0460299b, 0x00000020 },
520 { 0x00004000, 0000000000 },
521 { 0x01e00830, 0x00000002 },
522 { 0x21007000, 0000000000 },
523 { 0x00005000, 0x00000002 },
524 { 0x00038056, 0x00000002 },
525 { 0x040025e0, 0x00000002 },
526 { 0x000075e1, 0000000000 },
527 { 0x00000001, 0000000000 },
528 { 0x000380ed, 0x00000002 },
529 { 0x04007394, 0000000000 },
530 { 0000000000, 0000000000 },
531 { 0000000000, 0000000000 },
532 { 0x000078c4, 0x00000002 },
533 { 0x000078c5, 0x00000002 },
534 { 0x000078c6, 0x00000002 },
535 { 0x00007924, 0x00000002 },
536 { 0x00007925, 0x00000002 },
537 { 0x00007926, 0x00000002 },
538 { 0x000000f2, 0x00000004 },
539 { 0x00007924, 0x00000002 },
540 { 0x00007925, 0x00000002 },
541 { 0x00007926, 0x00000002 },
542 { 0x000000f9, 0x00000004 },
543 { 0000000000, 0000000000 },
544 { 0000000000, 0000000000 },
545 { 0000000000, 0000000000 },
546};
547
548static const u32 R300_cp_microcode[][2] = {
549 { 0x4200e000, 0000000000 },
550 { 0x4000e000, 0000000000 },
551 { 0x000000ae, 0x00000008 },
552 { 0x000000b2, 0x00000008 },
553 { 0x67554b4a, 0000000000 },
554 { 0x4a4a4475, 0000000000 },
555 { 0x55527d83, 0000000000 },
556 { 0x4a8c8b65, 0000000000 },
557 { 0x4aef4af6, 0000000000 },
558 { 0x4ae14a4a, 0000000000 },
559 { 0xe4979797, 0000000000 },
560 { 0xdb4aebdd, 0000000000 },
561 { 0x9ccc4a4a, 0000000000 },
562 { 0xd1989898, 0000000000 },
563 { 0x4a0f9ad6, 0000000000 },
564 { 0x000ca000, 0x00000004 },
565 { 0x000d0012, 0x00000038 },
566 { 0x0000e8b4, 0x00000004 },
567 { 0x000d0014, 0x00000038 },
568 { 0x0000e8b6, 0x00000004 },
569 { 0x000d0016, 0x00000038 },
570 { 0x0000e854, 0x00000004 },
571 { 0x000d0018, 0x00000038 },
572 { 0x0000e855, 0x00000004 },
573 { 0x000d001a, 0x00000038 },
574 { 0x0000e856, 0x00000004 },
575 { 0x000d001c, 0x00000038 },
576 { 0x0000e857, 0x00000004 },
577 { 0x000d001e, 0x00000038 },
578 { 0x0000e824, 0x00000004 },
579 { 0x000d0020, 0x00000038 },
580 { 0x0000e825, 0x00000004 },
581 { 0x000d0022, 0x00000038 },
582 { 0x0000e830, 0x00000004 },
583 { 0x000d0024, 0x00000038 },
584 { 0x0000f0c0, 0x00000004 },
585 { 0x000d0026, 0x00000038 },
586 { 0x0000f0c1, 0x00000004 },
587 { 0x000d0028, 0x00000038 },
588 { 0x0000f041, 0x00000004 },
589 { 0x000d002a, 0x00000038 },
590 { 0x0000f184, 0x00000004 },
591 { 0x000d002c, 0x00000038 },
592 { 0x0000f185, 0x00000004 },
593 { 0x000d002e, 0x00000038 },
594 { 0x0000f186, 0x00000004 },
595 { 0x000d0030, 0x00000038 },
596 { 0x0000f187, 0x00000004 },
597 { 0x000d0032, 0x00000038 },
598 { 0x0000f180, 0x00000004 },
599 { 0x000d0034, 0x00000038 },
600 { 0x0000f393, 0x00000004 },
601 { 0x000d0036, 0x00000038 },
602 { 0x0000f38a, 0x00000004 },
603 { 0x000d0038, 0x00000038 },
604 { 0x0000f38e, 0x00000004 },
605 { 0x0000e821, 0x00000004 },
606 { 0x0140a000, 0x00000004 },
607 { 0x00000043, 0x00000018 },
608 { 0x00cce800, 0x00000004 },
609 { 0x001b0001, 0x00000004 },
610 { 0x08004800, 0x00000004 },
611 { 0x001b0001, 0x00000004 },
612 { 0x08004800, 0x00000004 },
613 { 0x001b0001, 0x00000004 },
614 { 0x08004800, 0x00000004 },
615 { 0x0000003a, 0x00000008 },
616 { 0x0000a000, 0000000000 },
617 { 0x2000451d, 0x00000004 },
618 { 0x0000e580, 0x00000004 },
619 { 0x000ce581, 0x00000004 },
620 { 0x08004580, 0x00000004 },
621 { 0x000ce581, 0x00000004 },
622 { 0x00000047, 0x00000008 },
623 { 0x0000a000, 0000000000 },
624 { 0x000c2000, 0x00000004 },
625 { 0x0000e50e, 0x00000004 },
626 { 0x00032000, 0x00000004 },
627 { 0x00022051, 0x00000028 },
628 { 0x00000051, 0x00000024 },
629 { 0x0800450f, 0x00000004 },
630 { 0x0000a04b, 0x00000008 },
631 { 0x0000e565, 0x00000004 },
632 { 0x0000e566, 0x00000004 },
633 { 0x00000052, 0x00000008 },
634 { 0x03cca5b4, 0x00000004 },
635 { 0x05432000, 0x00000004 },
636 { 0x00022000, 0x00000004 },
637 { 0x4ccce05e, 0x00000030 },
638 { 0x08274565, 0x00000004 },
639 { 0x0000005e, 0x00000030 },
640 { 0x08004564, 0x00000004 },
641 { 0x0000e566, 0x00000004 },
642 { 0x00000055, 0x00000008 },
643 { 0x00802061, 0x00000010 },
644 { 0x00202000, 0x00000004 },
645 { 0x001b00ff, 0x00000004 },
646 { 0x01000064, 0x00000010 },
647 { 0x001f2000, 0x00000004 },
648 { 0x001c00ff, 0x00000004 },
649 { 0000000000, 0x0000000c },
650 { 0x00000080, 0x00000030 },
651 { 0x00000055, 0x00000008 },
652 { 0x0000e576, 0x00000004 },
653 { 0x000ca000, 0x00000004 },
654 { 0x00012000, 0x00000004 },
655 { 0x00082000, 0x00000004 },
656 { 0x1800650e, 0x00000004 },
657 { 0x00092000, 0x00000004 },
658 { 0x000a2000, 0x00000004 },
659 { 0x000f0000, 0x00000004 },
660 { 0x00400000, 0x00000004 },
661 { 0x00000074, 0x00000018 },
662 { 0x0000e563, 0x00000004 },
663 { 0x00c0e5f9, 0x000000c2 },
664 { 0x00000069, 0x00000008 },
665 { 0x0000a069, 0x00000008 },
666 { 0x0000e576, 0x00000004 },
667 { 0x0000e577, 0x00000004 },
668 { 0x0000e50e, 0x00000004 },
669 { 0x0000e50f, 0x00000004 },
670 { 0x0140a000, 0x00000004 },
671 { 0x00000077, 0x00000018 },
672 { 0x00c0e5f9, 0x000000c2 },
673 { 0x00000077, 0x00000008 },
674 { 0x0014e50e, 0x00000004 },
675 { 0x0040e50f, 0x00000004 },
676 { 0x00c0007a, 0x00000008 },
677 { 0x0000e570, 0x00000004 },
678 { 0x0000e571, 0x00000004 },
679 { 0x0000e572, 0x0000000c },
680 { 0x0000a000, 0x00000004 },
681 { 0x0140a000, 0x00000004 },
682 { 0x0000e568, 0x00000004 },
683 { 0x000c2000, 0x00000004 },
684 { 0x00000084, 0x00000018 },
685 { 0x000b0000, 0x00000004 },
686 { 0x18c0e562, 0x00000004 },
687 { 0x00000086, 0x00000008 },
688 { 0x00c00085, 0x00000008 },
689 { 0x000700e3, 0x00000004 },
690 { 0x00000092, 0x00000038 },
691 { 0x000ca094, 0x00000030 },
692 { 0x080045bb, 0x00000004 },
693 { 0x000c2095, 0x00000030 },
694 { 0x0800e5bc, 0000000000 },
695 { 0x0000e5bb, 0x00000004 },
696 { 0x0000e5bc, 0000000000 },
697 { 0x00120000, 0x0000000c },
698 { 0x00120000, 0x00000004 },
699 { 0x001b0002, 0x0000000c },
700 { 0x0000a000, 0x00000004 },
701 { 0x0000e821, 0x00000004 },
702 { 0x0000e800, 0000000000 },
703 { 0x0000e821, 0x00000004 },
704 { 0x0000e82e, 0000000000 },
705 { 0x02cca000, 0x00000004 },
706 { 0x00140000, 0x00000004 },
707 { 0x000ce1cc, 0x00000004 },
708 { 0x050de1cd, 0x00000004 },
709 { 0x00400000, 0x00000004 },
710 { 0x000000a4, 0x00000018 },
711 { 0x00c0a000, 0x00000004 },
712 { 0x000000a1, 0x00000008 },
713 { 0x000000a6, 0x00000020 },
714 { 0x4200e000, 0000000000 },
715 { 0x000000ad, 0x00000038 },
716 { 0x000ca000, 0x00000004 },
717 { 0x00140000, 0x00000004 },
718 { 0x000c2000, 0x00000004 },
719 { 0x00160000, 0x00000004 },
720 { 0x700ce000, 0x00000004 },
721 { 0x001400a9, 0x00000008 },
722 { 0x4000e000, 0000000000 },
723 { 0x02400000, 0x00000004 },
724 { 0x400ee000, 0x00000004 },
725 { 0x02400000, 0x00000004 },
726 { 0x4000e000, 0000000000 },
727 { 0x000c2000, 0x00000004 },
728 { 0x0240e51b, 0x00000004 },
729 { 0x0080e50a, 0x00000005 },
730 { 0x0080e50b, 0x00000005 },
731 { 0x00220000, 0x00000004 },
732 { 0x000700e3, 0x00000004 },
733 { 0x000000c0, 0x00000038 },
734 { 0x000c2095, 0x00000030 },
735 { 0x0880e5bd, 0x00000005 },
736 { 0x000c2094, 0x00000030 },
737 { 0x0800e5bb, 0x00000005 },
738 { 0x000c2095, 0x00000030 },
739 { 0x0880e5bc, 0x00000005 },
740 { 0x000000c3, 0x00000008 },
741 { 0x0080e5bd, 0x00000005 },
742 { 0x0000e5bb, 0x00000005 },
743 { 0x0080e5bc, 0x00000005 },
744 { 0x00210000, 0x00000004 },
745 { 0x02800000, 0x00000004 },
746 { 0x00c000c7, 0x00000018 },
747 { 0x4180e000, 0x00000040 },
748 { 0x000000c9, 0x00000024 },
749 { 0x01000000, 0x0000000c },
750 { 0x0100e51d, 0x0000000c },
751 { 0x000045bb, 0x00000004 },
752 { 0x000080c3, 0x00000008 },
753 { 0x0000f3ce, 0x00000004 },
754 { 0x0140a000, 0x00000004 },
755 { 0x00cc2000, 0x00000004 },
756 { 0x08c053cf, 0x00000040 },
757 { 0x00008000, 0000000000 },
758 { 0x0000f3d2, 0x00000004 },
759 { 0x0140a000, 0x00000004 },
760 { 0x00cc2000, 0x00000004 },
761 { 0x08c053d3, 0x00000040 },
762 { 0x00008000, 0000000000 },
763 { 0x0000f39d, 0x00000004 },
764 { 0x0140a000, 0x00000004 },
765 { 0x00cc2000, 0x00000004 },
766 { 0x08c0539e, 0x00000040 },
767 { 0x00008000, 0000000000 },
768 { 0x03c00830, 0x00000004 },
769 { 0x4200e000, 0000000000 },
770 { 0x0000a000, 0x00000004 },
771 { 0x200045e0, 0x00000004 },
772 { 0x0000e5e1, 0000000000 },
773 { 0x00000001, 0000000000 },
774 { 0x000700e0, 0x00000004 },
775 { 0x0800e394, 0000000000 },
776 { 0000000000, 0000000000 },
777 { 0x0000e8c4, 0x00000004 },
778 { 0x0000e8c5, 0x00000004 },
779 { 0x0000e8c6, 0x00000004 },
780 { 0x0000e928, 0x00000004 },
781 { 0x0000e929, 0x00000004 },
782 { 0x0000e92a, 0x00000004 },
783 { 0x000000e4, 0x00000008 },
784 { 0x0000e928, 0x00000004 },
785 { 0x0000e929, 0x00000004 },
786 { 0x0000e92a, 0x00000004 },
787 { 0x000000eb, 0x00000008 },
788 { 0x02c02000, 0x00000004 },
789 { 0x00060000, 0x00000004 },
790 { 0x000000f3, 0x00000034 },
791 { 0x000000f0, 0x00000008 },
792 { 0x00008000, 0x00000004 },
793 { 0xc000e000, 0000000000 },
794 { 0000000000, 0000000000 },
795 { 0x000c2000, 0x00000004 },
796 { 0x001d0018, 0x00000004 },
797 { 0x001a0001, 0x00000004 },
798 { 0x000000fb, 0x00000034 },
799 { 0x0000004a, 0x00000008 },
800 { 0x0500a04a, 0x00000008 },
801 { 0000000000, 0000000000 },
802 { 0000000000, 0000000000 },
803 { 0000000000, 0000000000 },
804 { 0000000000, 0000000000 },
805};
806
807static const u32 R420_cp_microcode[][2] = {
808 { 0x4200e000, 0000000000 },
809 { 0x4000e000, 0000000000 },
810 { 0x00000099, 0x00000008 },
811 { 0x0000009d, 0x00000008 },
812 { 0x4a554b4a, 0000000000 },
813 { 0x4a4a4467, 0000000000 },
814 { 0x55526f75, 0000000000 },
815 { 0x4a7e7d65, 0000000000 },
816 { 0xd9d3dff6, 0000000000 },
817 { 0x4ac54a4a, 0000000000 },
818 { 0xc8828282, 0000000000 },
819 { 0xbf4acfc1, 0000000000 },
820 { 0x87b04a4a, 0000000000 },
821 { 0xb5838383, 0000000000 },
822 { 0x4a0f85ba, 0000000000 },
823 { 0x000ca000, 0x00000004 },
824 { 0x000d0012, 0x00000038 },
825 { 0x0000e8b4, 0x00000004 },
826 { 0x000d0014, 0x00000038 },
827 { 0x0000e8b6, 0x00000004 },
828 { 0x000d0016, 0x00000038 },
829 { 0x0000e854, 0x00000004 },
830 { 0x000d0018, 0x00000038 },
831 { 0x0000e855, 0x00000004 },
832 { 0x000d001a, 0x00000038 },
833 { 0x0000e856, 0x00000004 },
834 { 0x000d001c, 0x00000038 },
835 { 0x0000e857, 0x00000004 },
836 { 0x000d001e, 0x00000038 },
837 { 0x0000e824, 0x00000004 },
838 { 0x000d0020, 0x00000038 },
839 { 0x0000e825, 0x00000004 },
840 { 0x000d0022, 0x00000038 },
841 { 0x0000e830, 0x00000004 },
842 { 0x000d0024, 0x00000038 },
843 { 0x0000f0c0, 0x00000004 },
844 { 0x000d0026, 0x00000038 },
845 { 0x0000f0c1, 0x00000004 },
846 { 0x000d0028, 0x00000038 },
847 { 0x0000f041, 0x00000004 },
848 { 0x000d002a, 0x00000038 },
849 { 0x0000f184, 0x00000004 },
850 { 0x000d002c, 0x00000038 },
851 { 0x0000f185, 0x00000004 },
852 { 0x000d002e, 0x00000038 },
853 { 0x0000f186, 0x00000004 },
854 { 0x000d0030, 0x00000038 },
855 { 0x0000f187, 0x00000004 },
856 { 0x000d0032, 0x00000038 },
857 { 0x0000f180, 0x00000004 },
858 { 0x000d0034, 0x00000038 },
859 { 0x0000f393, 0x00000004 },
860 { 0x000d0036, 0x00000038 },
861 { 0x0000f38a, 0x00000004 },
862 { 0x000d0038, 0x00000038 },
863 { 0x0000f38e, 0x00000004 },
864 { 0x0000e821, 0x00000004 },
865 { 0x0140a000, 0x00000004 },
866 { 0x00000043, 0x00000018 },
867 { 0x00cce800, 0x00000004 },
868 { 0x001b0001, 0x00000004 },
869 { 0x08004800, 0x00000004 },
870 { 0x001b0001, 0x00000004 },
871 { 0x08004800, 0x00000004 },
872 { 0x001b0001, 0x00000004 },
873 { 0x08004800, 0x00000004 },
874 { 0x0000003a, 0x00000008 },
875 { 0x0000a000, 0000000000 },
876 { 0x2000451d, 0x00000004 },
877 { 0x0000e580, 0x00000004 },
878 { 0x000ce581, 0x00000004 },
879 { 0x08004580, 0x00000004 },
880 { 0x000ce581, 0x00000004 },
881 { 0x00000047, 0x00000008 },
882 { 0x0000a000, 0000000000 },
883 { 0x000c2000, 0x00000004 },
884 { 0x0000e50e, 0x00000004 },
885 { 0x00032000, 0x00000004 },
886 { 0x00022051, 0x00000028 },
887 { 0x00000051, 0x00000024 },
888 { 0x0800450f, 0x00000004 },
889 { 0x0000a04b, 0x00000008 },
890 { 0x0000e565, 0x00000004 },
891 { 0x0000e566, 0x00000004 },
892 { 0x00000052, 0x00000008 },
893 { 0x03cca5b4, 0x00000004 },
894 { 0x05432000, 0x00000004 },
895 { 0x00022000, 0x00000004 },
896 { 0x4ccce05e, 0x00000030 },
897 { 0x08274565, 0x00000004 },
898 { 0x0000005e, 0x00000030 },
899 { 0x08004564, 0x00000004 },
900 { 0x0000e566, 0x00000004 },
901 { 0x00000055, 0x00000008 },
902 { 0x00802061, 0x00000010 },
903 { 0x00202000, 0x00000004 },
904 { 0x001b00ff, 0x00000004 },
905 { 0x01000064, 0x00000010 },
906 { 0x001f2000, 0x00000004 },
907 { 0x001c00ff, 0x00000004 },
908 { 0000000000, 0x0000000c },
909 { 0x00000072, 0x00000030 },
910 { 0x00000055, 0x00000008 },
911 { 0x0000e576, 0x00000004 },
912 { 0x0000e577, 0x00000004 },
913 { 0x0000e50e, 0x00000004 },
914 { 0x0000e50f, 0x00000004 },
915 { 0x0140a000, 0x00000004 },
916 { 0x00000069, 0x00000018 },
917 { 0x00c0e5f9, 0x000000c2 },
918 { 0x00000069, 0x00000008 },
919 { 0x0014e50e, 0x00000004 },
920 { 0x0040e50f, 0x00000004 },
921 { 0x00c0006c, 0x00000008 },
922 { 0x0000e570, 0x00000004 },
923 { 0x0000e571, 0x00000004 },
924 { 0x0000e572, 0x0000000c },
925 { 0x0000a000, 0x00000004 },
926 { 0x0140a000, 0x00000004 },
927 { 0x0000e568, 0x00000004 },
928 { 0x000c2000, 0x00000004 },
929 { 0x00000076, 0x00000018 },
930 { 0x000b0000, 0x00000004 },
931 { 0x18c0e562, 0x00000004 },
932 { 0x00000078, 0x00000008 },
933 { 0x00c00077, 0x00000008 },
934 { 0x000700c7, 0x00000004 },
935 { 0x00000080, 0x00000038 },
936 { 0x0000e5bb, 0x00000004 },
937 { 0x0000e5bc, 0000000000 },
938 { 0x0000a000, 0x00000004 },
939 { 0x0000e821, 0x00000004 },
940 { 0x0000e800, 0000000000 },
941 { 0x0000e821, 0x00000004 },
942 { 0x0000e82e, 0000000000 },
943 { 0x02cca000, 0x00000004 },
944 { 0x00140000, 0x00000004 },
945 { 0x000ce1cc, 0x00000004 },
946 { 0x050de1cd, 0x00000004 },
947 { 0x00400000, 0x00000004 },
948 { 0x0000008f, 0x00000018 },
949 { 0x00c0a000, 0x00000004 },
950 { 0x0000008c, 0x00000008 },
951 { 0x00000091, 0x00000020 },
952 { 0x4200e000, 0000000000 },
953 { 0x00000098, 0x00000038 },
954 { 0x000ca000, 0x00000004 },
955 { 0x00140000, 0x00000004 },
956 { 0x000c2000, 0x00000004 },
957 { 0x00160000, 0x00000004 },
958 { 0x700ce000, 0x00000004 },
959 { 0x00140094, 0x00000008 },
960 { 0x4000e000, 0000000000 },
961 { 0x02400000, 0x00000004 },
962 { 0x400ee000, 0x00000004 },
963 { 0x02400000, 0x00000004 },
964 { 0x4000e000, 0000000000 },
965 { 0x000c2000, 0x00000004 },
966 { 0x0240e51b, 0x00000004 },
967 { 0x0080e50a, 0x00000005 },
968 { 0x0080e50b, 0x00000005 },
969 { 0x00220000, 0x00000004 },
970 { 0x000700c7, 0x00000004 },
971 { 0x000000a4, 0x00000038 },
972 { 0x0080e5bd, 0x00000005 },
973 { 0x0000e5bb, 0x00000005 },
974 { 0x0080e5bc, 0x00000005 },
975 { 0x00210000, 0x00000004 },
976 { 0x02800000, 0x00000004 },
977 { 0x00c000ab, 0x00000018 },
978 { 0x4180e000, 0x00000040 },
979 { 0x000000ad, 0x00000024 },
980 { 0x01000000, 0x0000000c },
981 { 0x0100e51d, 0x0000000c },
982 { 0x000045bb, 0x00000004 },
983 { 0x000080a7, 0x00000008 },
984 { 0x0000f3ce, 0x00000004 },
985 { 0x0140a000, 0x00000004 },
986 { 0x00cc2000, 0x00000004 },
987 { 0x08c053cf, 0x00000040 },
988 { 0x00008000, 0000000000 },
989 { 0x0000f3d2, 0x00000004 },
990 { 0x0140a000, 0x00000004 },
991 { 0x00cc2000, 0x00000004 },
992 { 0x08c053d3, 0x00000040 },
993 { 0x00008000, 0000000000 },
994 { 0x0000f39d, 0x00000004 },
995 { 0x0140a000, 0x00000004 },
996 { 0x00cc2000, 0x00000004 },
997 { 0x08c0539e, 0x00000040 },
998 { 0x00008000, 0000000000 },
999 { 0x03c00830, 0x00000004 },
1000 { 0x4200e000, 0000000000 },
1001 { 0x0000a000, 0x00000004 },
1002 { 0x200045e0, 0x00000004 },
1003 { 0x0000e5e1, 0000000000 },
1004 { 0x00000001, 0000000000 },
1005 { 0x000700c4, 0x00000004 },
1006 { 0x0800e394, 0000000000 },
1007 { 0000000000, 0000000000 },
1008 { 0x0000e8c4, 0x00000004 },
1009 { 0x0000e8c5, 0x00000004 },
1010 { 0x0000e8c6, 0x00000004 },
1011 { 0x0000e928, 0x00000004 },
1012 { 0x0000e929, 0x00000004 },
1013 { 0x0000e92a, 0x00000004 },
1014 { 0x000000c8, 0x00000008 },
1015 { 0x0000e928, 0x00000004 },
1016 { 0x0000e929, 0x00000004 },
1017 { 0x0000e92a, 0x00000004 },
1018 { 0x000000cf, 0x00000008 },
1019 { 0x02c02000, 0x00000004 },
1020 { 0x00060000, 0x00000004 },
1021 { 0x000000d7, 0x00000034 },
1022 { 0x000000d4, 0x00000008 },
1023 { 0x00008000, 0x00000004 },
1024 { 0xc000e000, 0000000000 },
1025 { 0x0000e1cc, 0x00000004 },
1026 { 0x0500e1cd, 0x00000004 },
1027 { 0x000ca000, 0x00000004 },
1028 { 0x000000de, 0x00000034 },
1029 { 0x000000da, 0x00000008 },
1030 { 0x0000a000, 0000000000 },
1031 { 0x0019e1cc, 0x00000004 },
1032 { 0x001b0001, 0x00000004 },
1033 { 0x0500a000, 0x00000004 },
1034 { 0x080041cd, 0x00000004 },
1035 { 0x000ca000, 0x00000004 },
1036 { 0x000000fb, 0x00000034 },
1037 { 0x0000004a, 0x00000008 },
1038 { 0000000000, 0000000000 },
1039 { 0000000000, 0000000000 },
1040 { 0000000000, 0000000000 },
1041 { 0000000000, 0000000000 },
1042 { 0000000000, 0000000000 },
1043 { 0000000000, 0000000000 },
1044 { 0000000000, 0000000000 },
1045 { 0000000000, 0000000000 },
1046 { 0000000000, 0000000000 },
1047 { 0000000000, 0000000000 },
1048 { 0000000000, 0000000000 },
1049 { 0000000000, 0000000000 },
1050 { 0000000000, 0000000000 },
1051 { 0000000000, 0000000000 },
1052 { 0000000000, 0000000000 },
1053 { 0000000000, 0000000000 },
1054 { 0x000c2000, 0x00000004 },
1055 { 0x001d0018, 0x00000004 },
1056 { 0x001a0001, 0x00000004 },
1057 { 0x000000fb, 0x00000034 },
1058 { 0x0000004a, 0x00000008 },
1059 { 0x0500a04a, 0x00000008 },
1060 { 0000000000, 0000000000 },
1061 { 0000000000, 0000000000 },
1062 { 0000000000, 0000000000 },
1063 { 0000000000, 0000000000 },
1064};
1065
1066static const u32 RS600_cp_microcode[][2] = {
1067 { 0x4200e000, 0000000000 },
1068 { 0x4000e000, 0000000000 },
1069 { 0x000000a0, 0x00000008 },
1070 { 0x000000a4, 0x00000008 },
1071 { 0x4a554b4a, 0000000000 },
1072 { 0x4a4a4467, 0000000000 },
1073 { 0x55526f75, 0000000000 },
1074 { 0x4a7e7d65, 0000000000 },
1075 { 0x4ae74af6, 0000000000 },
1076 { 0x4ad34a4a, 0000000000 },
1077 { 0xd6898989, 0000000000 },
1078 { 0xcd4addcf, 0000000000 },
1079 { 0x8ebe4ae2, 0000000000 },
1080 { 0xc38a8a8a, 0000000000 },
1081 { 0x4a0f8cc8, 0000000000 },
1082 { 0x000ca000, 0x00000004 },
1083 { 0x000d0012, 0x00000038 },
1084 { 0x0000e8b4, 0x00000004 },
1085 { 0x000d0014, 0x00000038 },
1086 { 0x0000e8b6, 0x00000004 },
1087 { 0x000d0016, 0x00000038 },
1088 { 0x0000e854, 0x00000004 },
1089 { 0x000d0018, 0x00000038 },
1090 { 0x0000e855, 0x00000004 },
1091 { 0x000d001a, 0x00000038 },
1092 { 0x0000e856, 0x00000004 },
1093 { 0x000d001c, 0x00000038 },
1094 { 0x0000e857, 0x00000004 },
1095 { 0x000d001e, 0x00000038 },
1096 { 0x0000e824, 0x00000004 },
1097 { 0x000d0020, 0x00000038 },
1098 { 0x0000e825, 0x00000004 },
1099 { 0x000d0022, 0x00000038 },
1100 { 0x0000e830, 0x00000004 },
1101 { 0x000d0024, 0x00000038 },
1102 { 0x0000f0c0, 0x00000004 },
1103 { 0x000d0026, 0x00000038 },
1104 { 0x0000f0c1, 0x00000004 },
1105 { 0x000d0028, 0x00000038 },
1106 { 0x0000f041, 0x00000004 },
1107 { 0x000d002a, 0x00000038 },
1108 { 0x0000f184, 0x00000004 },
1109 { 0x000d002c, 0x00000038 },
1110 { 0x0000f185, 0x00000004 },
1111 { 0x000d002e, 0x00000038 },
1112 { 0x0000f186, 0x00000004 },
1113 { 0x000d0030, 0x00000038 },
1114 { 0x0000f187, 0x00000004 },
1115 { 0x000d0032, 0x00000038 },
1116 { 0x0000f180, 0x00000004 },
1117 { 0x000d0034, 0x00000038 },
1118 { 0x0000f393, 0x00000004 },
1119 { 0x000d0036, 0x00000038 },
1120 { 0x0000f38a, 0x00000004 },
1121 { 0x000d0038, 0x00000038 },
1122 { 0x0000f38e, 0x00000004 },
1123 { 0x0000e821, 0x00000004 },
1124 { 0x0140a000, 0x00000004 },
1125 { 0x00000043, 0x00000018 },
1126 { 0x00cce800, 0x00000004 },
1127 { 0x001b0001, 0x00000004 },
1128 { 0x08004800, 0x00000004 },
1129 { 0x001b0001, 0x00000004 },
1130 { 0x08004800, 0x00000004 },
1131 { 0x001b0001, 0x00000004 },
1132 { 0x08004800, 0x00000004 },
1133 { 0x0000003a, 0x00000008 },
1134 { 0x0000a000, 0000000000 },
1135 { 0x2000451d, 0x00000004 },
1136 { 0x0000e580, 0x00000004 },
1137 { 0x000ce581, 0x00000004 },
1138 { 0x08004580, 0x00000004 },
1139 { 0x000ce581, 0x00000004 },
1140 { 0x00000047, 0x00000008 },
1141 { 0x0000a000, 0000000000 },
1142 { 0x000c2000, 0x00000004 },
1143 { 0x0000e50e, 0x00000004 },
1144 { 0x00032000, 0x00000004 },
1145 { 0x00022051, 0x00000028 },
1146 { 0x00000051, 0x00000024 },
1147 { 0x0800450f, 0x00000004 },
1148 { 0x0000a04b, 0x00000008 },
1149 { 0x0000e565, 0x00000004 },
1150 { 0x0000e566, 0x00000004 },
1151 { 0x00000052, 0x00000008 },
1152 { 0x03cca5b4, 0x00000004 },
1153 { 0x05432000, 0x00000004 },
1154 { 0x00022000, 0x00000004 },
1155 { 0x4ccce05e, 0x00000030 },
1156 { 0x08274565, 0x00000004 },
1157 { 0x0000005e, 0x00000030 },
1158 { 0x08004564, 0x00000004 },
1159 { 0x0000e566, 0x00000004 },
1160 { 0x00000055, 0x00000008 },
1161 { 0x00802061, 0x00000010 },
1162 { 0x00202000, 0x00000004 },
1163 { 0x001b00ff, 0x00000004 },
1164 { 0x01000064, 0x00000010 },
1165 { 0x001f2000, 0x00000004 },
1166 { 0x001c00ff, 0x00000004 },
1167 { 0000000000, 0x0000000c },
1168 { 0x00000072, 0x00000030 },
1169 { 0x00000055, 0x00000008 },
1170 { 0x0000e576, 0x00000004 },
1171 { 0x0000e577, 0x00000004 },
1172 { 0x0000e50e, 0x00000004 },
1173 { 0x0000e50f, 0x00000004 },
1174 { 0x0140a000, 0x00000004 },
1175 { 0x00000069, 0x00000018 },
1176 { 0x00c0e5f9, 0x000000c2 },
1177 { 0x00000069, 0x00000008 },
1178 { 0x0014e50e, 0x00000004 },
1179 { 0x0040e50f, 0x00000004 },
1180 { 0x00c0006c, 0x00000008 },
1181 { 0x0000e570, 0x00000004 },
1182 { 0x0000e571, 0x00000004 },
1183 { 0x0000e572, 0x0000000c },
1184 { 0x0000a000, 0x00000004 },
1185 { 0x0140a000, 0x00000004 },
1186 { 0x0000e568, 0x00000004 },
1187 { 0x000c2000, 0x00000004 },
1188 { 0x00000076, 0x00000018 },
1189 { 0x000b0000, 0x00000004 },
1190 { 0x18c0e562, 0x00000004 },
1191 { 0x00000078, 0x00000008 },
1192 { 0x00c00077, 0x00000008 },
1193 { 0x000700d5, 0x00000004 },
1194 { 0x00000084, 0x00000038 },
1195 { 0x000ca086, 0x00000030 },
1196 { 0x080045bb, 0x00000004 },
1197 { 0x000c2087, 0x00000030 },
1198 { 0x0800e5bc, 0000000000 },
1199 { 0x0000e5bb, 0x00000004 },
1200 { 0x0000e5bc, 0000000000 },
1201 { 0x00120000, 0x0000000c },
1202 { 0x00120000, 0x00000004 },
1203 { 0x001b0002, 0x0000000c },
1204 { 0x0000a000, 0x00000004 },
1205 { 0x0000e821, 0x00000004 },
1206 { 0x0000e800, 0000000000 },
1207 { 0x0000e821, 0x00000004 },
1208 { 0x0000e82e, 0000000000 },
1209 { 0x02cca000, 0x00000004 },
1210 { 0x00140000, 0x00000004 },
1211 { 0x000ce1cc, 0x00000004 },
1212 { 0x050de1cd, 0x00000004 },
1213 { 0x00400000, 0x00000004 },
1214 { 0x00000096, 0x00000018 },
1215 { 0x00c0a000, 0x00000004 },
1216 { 0x00000093, 0x00000008 },
1217 { 0x00000098, 0x00000020 },
1218 { 0x4200e000, 0000000000 },
1219 { 0x0000009f, 0x00000038 },
1220 { 0x000ca000, 0x00000004 },
1221 { 0x00140000, 0x00000004 },
1222 { 0x000c2000, 0x00000004 },
1223 { 0x00160000, 0x00000004 },
1224 { 0x700ce000, 0x00000004 },
1225 { 0x0014009b, 0x00000008 },
1226 { 0x4000e000, 0000000000 },
1227 { 0x02400000, 0x00000004 },
1228 { 0x400ee000, 0x00000004 },
1229 { 0x02400000, 0x00000004 },
1230 { 0x4000e000, 0000000000 },
1231 { 0x000c2000, 0x00000004 },
1232 { 0x0240e51b, 0x00000004 },
1233 { 0x0080e50a, 0x00000005 },
1234 { 0x0080e50b, 0x00000005 },
1235 { 0x00220000, 0x00000004 },
1236 { 0x000700d5, 0x00000004 },
1237 { 0x000000b2, 0x00000038 },
1238 { 0x000c2087, 0x00000030 },
1239 { 0x0880e5bd, 0x00000005 },
1240 { 0x000c2086, 0x00000030 },
1241 { 0x0800e5bb, 0x00000005 },
1242 { 0x000c2087, 0x00000030 },
1243 { 0x0880e5bc, 0x00000005 },
1244 { 0x000000b5, 0x00000008 },
1245 { 0x0080e5bd, 0x00000005 },
1246 { 0x0000e5bb, 0x00000005 },
1247 { 0x0080e5bc, 0x00000005 },
1248 { 0x00210000, 0x00000004 },
1249 { 0x02800000, 0x00000004 },
1250 { 0x00c000b9, 0x00000018 },
1251 { 0x4180e000, 0x00000040 },
1252 { 0x000000bb, 0x00000024 },
1253 { 0x01000000, 0x0000000c },
1254 { 0x0100e51d, 0x0000000c },
1255 { 0x000045bb, 0x00000004 },
1256 { 0x000080b5, 0x00000008 },
1257 { 0x0000f3ce, 0x00000004 },
1258 { 0x0140a000, 0x00000004 },
1259 { 0x00cc2000, 0x00000004 },
1260 { 0x08c053cf, 0x00000040 },
1261 { 0x00008000, 0000000000 },
1262 { 0x0000f3d2, 0x00000004 },
1263 { 0x0140a000, 0x00000004 },
1264 { 0x00cc2000, 0x00000004 },
1265 { 0x08c053d3, 0x00000040 },
1266 { 0x00008000, 0000000000 },
1267 { 0x0000f39d, 0x00000004 },
1268 { 0x0140a000, 0x00000004 },
1269 { 0x00cc2000, 0x00000004 },
1270 { 0x08c0539e, 0x00000040 },
1271 { 0x00008000, 0000000000 },
1272 { 0x03c00830, 0x00000004 },
1273 { 0x4200e000, 0000000000 },
1274 { 0x0000a000, 0x00000004 },
1275 { 0x200045e0, 0x00000004 },
1276 { 0x0000e5e1, 0000000000 },
1277 { 0x00000001, 0000000000 },
1278 { 0x000700d2, 0x00000004 },
1279 { 0x0800e394, 0000000000 },
1280 { 0000000000, 0000000000 },
1281 { 0x0000e8c4, 0x00000004 },
1282 { 0x0000e8c5, 0x00000004 },
1283 { 0x0000e8c6, 0x00000004 },
1284 { 0x0000e928, 0x00000004 },
1285 { 0x0000e929, 0x00000004 },
1286 { 0x0000e92a, 0x00000004 },
1287 { 0x000000d6, 0x00000008 },
1288 { 0x0000e928, 0x00000004 },
1289 { 0x0000e929, 0x00000004 },
1290 { 0x0000e92a, 0x00000004 },
1291 { 0x000000dd, 0x00000008 },
1292 { 0x00e00116, 0000000000 },
1293 { 0x000700e1, 0x00000004 },
1294 { 0x0800401c, 0x00000004 },
1295 { 0x200050e7, 0x00000004 },
1296 { 0x0000e01d, 0x00000004 },
1297 { 0x000000e4, 0x00000008 },
1298 { 0x02c02000, 0x00000004 },
1299 { 0x00060000, 0x00000004 },
1300 { 0x000000eb, 0x00000034 },
1301 { 0x000000e8, 0x00000008 },
1302 { 0x00008000, 0x00000004 },
1303 { 0xc000e000, 0000000000 },
1304 { 0000000000, 0000000000 },
1305 { 0000000000, 0000000000 },
1306 { 0000000000, 0000000000 },
1307 { 0000000000, 0000000000 },
1308 { 0000000000, 0000000000 },
1309 { 0000000000, 0000000000 },
1310 { 0000000000, 0000000000 },
1311 { 0000000000, 0000000000 },
1312 { 0000000000, 0000000000 },
1313 { 0x000c2000, 0x00000004 },
1314 { 0x001d0018, 0x00000004 },
1315 { 0x001a0001, 0x00000004 },
1316 { 0x000000fb, 0x00000034 },
1317 { 0x0000004a, 0x00000008 },
1318 { 0x0500a04a, 0x00000008 },
1319 { 0000000000, 0000000000 },
1320 { 0000000000, 0000000000 },
1321 { 0000000000, 0000000000 },
1322 { 0000000000, 0000000000 },
1323};
1324
1325static const u32 RS690_cp_microcode[][2] = {
1326 { 0x000000dd, 0x00000008 },
1327 { 0x000000df, 0x00000008 },
1328 { 0x000000a0, 0x00000008 },
1329 { 0x000000a4, 0x00000008 },
1330 { 0x4a554b4a, 0000000000 },
1331 { 0x4a4a4467, 0000000000 },
1332 { 0x55526f75, 0000000000 },
1333 { 0x4a7e7d65, 0000000000 },
1334 { 0x4ad74af6, 0000000000 },
1335 { 0x4ac94a4a, 0000000000 },
1336 { 0xcc898989, 0000000000 },
1337 { 0xc34ad3c5, 0000000000 },
1338 { 0x8e4a4a4a, 0000000000 },
1339 { 0x4a8a8a8a, 0000000000 },
1340 { 0x4a0f8c4a, 0000000000 },
1341 { 0x000ca000, 0x00000004 },
1342 { 0x000d0012, 0x00000038 },
1343 { 0x0000e8b4, 0x00000004 },
1344 { 0x000d0014, 0x00000038 },
1345 { 0x0000e8b6, 0x00000004 },
1346 { 0x000d0016, 0x00000038 },
1347 { 0x0000e854, 0x00000004 },
1348 { 0x000d0018, 0x00000038 },
1349 { 0x0000e855, 0x00000004 },
1350 { 0x000d001a, 0x00000038 },
1351 { 0x0000e856, 0x00000004 },
1352 { 0x000d001c, 0x00000038 },
1353 { 0x0000e857, 0x00000004 },
1354 { 0x000d001e, 0x00000038 },
1355 { 0x0000e824, 0x00000004 },
1356 { 0x000d0020, 0x00000038 },
1357 { 0x0000e825, 0x00000004 },
1358 { 0x000d0022, 0x00000038 },
1359 { 0x0000e830, 0x00000004 },
1360 { 0x000d0024, 0x00000038 },
1361 { 0x0000f0c0, 0x00000004 },
1362 { 0x000d0026, 0x00000038 },
1363 { 0x0000f0c1, 0x00000004 },
1364 { 0x000d0028, 0x00000038 },
1365 { 0x0000f041, 0x00000004 },
1366 { 0x000d002a, 0x00000038 },
1367 { 0x0000f184, 0x00000004 },
1368 { 0x000d002c, 0x00000038 },
1369 { 0x0000f185, 0x00000004 },
1370 { 0x000d002e, 0x00000038 },
1371 { 0x0000f186, 0x00000004 },
1372 { 0x000d0030, 0x00000038 },
1373 { 0x0000f187, 0x00000004 },
1374 { 0x000d0032, 0x00000038 },
1375 { 0x0000f180, 0x00000004 },
1376 { 0x000d0034, 0x00000038 },
1377 { 0x0000f393, 0x00000004 },
1378 { 0x000d0036, 0x00000038 },
1379 { 0x0000f38a, 0x00000004 },
1380 { 0x000d0038, 0x00000038 },
1381 { 0x0000f38e, 0x00000004 },
1382 { 0x0000e821, 0x00000004 },
1383 { 0x0140a000, 0x00000004 },
1384 { 0x00000043, 0x00000018 },
1385 { 0x00cce800, 0x00000004 },
1386 { 0x001b0001, 0x00000004 },
1387 { 0x08004800, 0x00000004 },
1388 { 0x001b0001, 0x00000004 },
1389 { 0x08004800, 0x00000004 },
1390 { 0x001b0001, 0x00000004 },
1391 { 0x08004800, 0x00000004 },
1392 { 0x0000003a, 0x00000008 },
1393 { 0x0000a000, 0000000000 },
1394 { 0x2000451d, 0x00000004 },
1395 { 0x0000e580, 0x00000004 },
1396 { 0x000ce581, 0x00000004 },
1397 { 0x08004580, 0x00000004 },
1398 { 0x000ce581, 0x00000004 },
1399 { 0x00000047, 0x00000008 },
1400 { 0x0000a000, 0000000000 },
1401 { 0x000c2000, 0x00000004 },
1402 { 0x0000e50e, 0x00000004 },
1403 { 0x00032000, 0x00000004 },
1404 { 0x00022051, 0x00000028 },
1405 { 0x00000051, 0x00000024 },
1406 { 0x0800450f, 0x00000004 },
1407 { 0x0000a04b, 0x00000008 },
1408 { 0x0000e565, 0x00000004 },
1409 { 0x0000e566, 0x00000004 },
1410 { 0x00000052, 0x00000008 },
1411 { 0x03cca5b4, 0x00000004 },
1412 { 0x05432000, 0x00000004 },
1413 { 0x00022000, 0x00000004 },
1414 { 0x4ccce05e, 0x00000030 },
1415 { 0x08274565, 0x00000004 },
1416 { 0x0000005e, 0x00000030 },
1417 { 0x08004564, 0x00000004 },
1418 { 0x0000e566, 0x00000004 },
1419 { 0x00000055, 0x00000008 },
1420 { 0x00802061, 0x00000010 },
1421 { 0x00202000, 0x00000004 },
1422 { 0x001b00ff, 0x00000004 },
1423 { 0x01000064, 0x00000010 },
1424 { 0x001f2000, 0x00000004 },
1425 { 0x001c00ff, 0x00000004 },
1426 { 0000000000, 0x0000000c },
1427 { 0x00000072, 0x00000030 },
1428 { 0x00000055, 0x00000008 },
1429 { 0x0000e576, 0x00000004 },
1430 { 0x0000e577, 0x00000004 },
1431 { 0x0000e50e, 0x00000004 },
1432 { 0x0000e50f, 0x00000004 },
1433 { 0x0140a000, 0x00000004 },
1434 { 0x00000069, 0x00000018 },
1435 { 0x00c0e5f9, 0x000000c2 },
1436 { 0x00000069, 0x00000008 },
1437 { 0x0014e50e, 0x00000004 },
1438 { 0x0040e50f, 0x00000004 },
1439 { 0x00c0006c, 0x00000008 },
1440 { 0x0000e570, 0x00000004 },
1441 { 0x0000e571, 0x00000004 },
1442 { 0x0000e572, 0x0000000c },
1443 { 0x0000a000, 0x00000004 },
1444 { 0x0140a000, 0x00000004 },
1445 { 0x0000e568, 0x00000004 },
1446 { 0x000c2000, 0x00000004 },
1447 { 0x00000076, 0x00000018 },
1448 { 0x000b0000, 0x00000004 },
1449 { 0x18c0e562, 0x00000004 },
1450 { 0x00000078, 0x00000008 },
1451 { 0x00c00077, 0x00000008 },
1452 { 0x000700cb, 0x00000004 },
1453 { 0x00000084, 0x00000038 },
1454 { 0x000ca086, 0x00000030 },
1455 { 0x080045bb, 0x00000004 },
1456 { 0x000c2087, 0x00000030 },
1457 { 0x0800e5bc, 0000000000 },
1458 { 0x0000e5bb, 0x00000004 },
1459 { 0x0000e5bc, 0000000000 },
1460 { 0x00120000, 0x0000000c },
1461 { 0x00120000, 0x00000004 },
1462 { 0x001b0002, 0x0000000c },
1463 { 0x0000a000, 0x00000004 },
1464 { 0x0000e821, 0x00000004 },
1465 { 0x0000e800, 0000000000 },
1466 { 0x0000e821, 0x00000004 },
1467 { 0x0000e82e, 0000000000 },
1468 { 0x02cca000, 0x00000004 },
1469 { 0x00140000, 0x00000004 },
1470 { 0x000ce1cc, 0x00000004 },
1471 { 0x050de1cd, 0x00000004 },
1472 { 0x00400000, 0x00000004 },
1473 { 0x00000096, 0x00000018 },
1474 { 0x00c0a000, 0x00000004 },
1475 { 0x00000093, 0x00000008 },
1476 { 0x00000098, 0x00000020 },
1477 { 0x4200e000, 0000000000 },
1478 { 0x0000009f, 0x00000038 },
1479 { 0x000ca000, 0x00000004 },
1480 { 0x00140000, 0x00000004 },
1481 { 0x000c2000, 0x00000004 },
1482 { 0x00160000, 0x00000004 },
1483 { 0x700ce000, 0x00000004 },
1484 { 0x0014009b, 0x00000008 },
1485 { 0x4000e000, 0000000000 },
1486 { 0x02400000, 0x00000004 },
1487 { 0x400ee000, 0x00000004 },
1488 { 0x02400000, 0x00000004 },
1489 { 0x4000e000, 0000000000 },
1490 { 0x00100000, 0x0000002c },
1491 { 0x00004000, 0000000000 },
1492 { 0x080045c8, 0x00000004 },
1493 { 0x00240005, 0x00000004 },
1494 { 0x08004d0b, 0x00000004 },
1495 { 0x000c2000, 0x00000004 },
1496 { 0x0240e51b, 0x00000004 },
1497 { 0x0080e50a, 0x00000005 },
1498 { 0x0080e50b, 0x00000005 },
1499 { 0x00220000, 0x00000004 },
1500 { 0x000700cb, 0x00000004 },
1501 { 0x000000b7, 0x00000038 },
1502 { 0x000c2087, 0x00000030 },
1503 { 0x0880e5bd, 0x00000005 },
1504 { 0x000c2086, 0x00000030 },
1505 { 0x0800e5bb, 0x00000005 },
1506 { 0x000c2087, 0x00000030 },
1507 { 0x0880e5bc, 0x00000005 },
1508 { 0x000000ba, 0x00000008 },
1509 { 0x0080e5bd, 0x00000005 },
1510 { 0x0000e5bb, 0x00000005 },
1511 { 0x0080e5bc, 0x00000005 },
1512 { 0x00210000, 0x00000004 },
1513 { 0x02800000, 0x00000004 },
1514 { 0x00c000be, 0x00000018 },
1515 { 0x4180e000, 0x00000040 },
1516 { 0x000000c0, 0x00000024 },
1517 { 0x01000000, 0x0000000c },
1518 { 0x0100e51d, 0x0000000c },
1519 { 0x000045bb, 0x00000004 },
1520 { 0x000080ba, 0x00000008 },
1521 { 0x03c00830, 0x00000004 },
1522 { 0x4200e000, 0000000000 },
1523 { 0x0000a000, 0x00000004 },
1524 { 0x200045e0, 0x00000004 },
1525 { 0x0000e5e1, 0000000000 },
1526 { 0x00000001, 0000000000 },
1527 { 0x000700c8, 0x00000004 },
1528 { 0x0800e394, 0000000000 },
1529 { 0000000000, 0000000000 },
1530 { 0x0000e8c4, 0x00000004 },
1531 { 0x0000e8c5, 0x00000004 },
1532 { 0x0000e8c6, 0x00000004 },
1533 { 0x0000e928, 0x00000004 },
1534 { 0x0000e929, 0x00000004 },
1535 { 0x0000e92a, 0x00000004 },
1536 { 0x000000cc, 0x00000008 },
1537 { 0x0000e928, 0x00000004 },
1538 { 0x0000e929, 0x00000004 },
1539 { 0x0000e92a, 0x00000004 },
1540 { 0x000000d3, 0x00000008 },
1541 { 0x02c02000, 0x00000004 },
1542 { 0x00060000, 0x00000004 },
1543 { 0x000000db, 0x00000034 },
1544 { 0x000000d8, 0x00000008 },
1545 { 0x00008000, 0x00000004 },
1546 { 0xc000e000, 0000000000 },
1547 { 0x000000e1, 0x00000030 },
1548 { 0x4200e000, 0000000000 },
1549 { 0x000000e1, 0x00000030 },
1550 { 0x4000e000, 0000000000 },
1551 { 0x0025001b, 0x00000004 },
1552 { 0x00230000, 0x00000004 },
1553 { 0x00250005, 0x00000004 },
1554 { 0x000000e6, 0x00000034 },
1555 { 0000000000, 0x0000000c },
1556 { 0x00244000, 0x00000004 },
1557 { 0x080045c8, 0x00000004 },
1558 { 0x00240005, 0x00000004 },
1559 { 0x08004d0b, 0x0000000c },
1560 { 0000000000, 0000000000 },
1561 { 0000000000, 0000000000 },
1562 { 0000000000, 0000000000 },
1563 { 0000000000, 0000000000 },
1564 { 0000000000, 0000000000 },
1565 { 0000000000, 0000000000 },
1566 { 0000000000, 0000000000 },
1567 { 0000000000, 0000000000 },
1568 { 0000000000, 0000000000 },
1569 { 0000000000, 0000000000 },
1570 { 0000000000, 0000000000 },
1571 { 0000000000, 0000000000 },
1572 { 0x000c2000, 0x00000004 },
1573 { 0x001d0018, 0x00000004 },
1574 { 0x001a0001, 0x00000004 },
1575 { 0x000000fb, 0x00000034 },
1576 { 0x0000004a, 0x00000008 },
1577 { 0x0500a04a, 0x00000008 },
1578 { 0000000000, 0000000000 },
1579 { 0000000000, 0000000000 },
1580 { 0000000000, 0000000000 },
1581 { 0000000000, 0000000000 },
1582};
1583
1584static const u32 R520_cp_microcode[][2] = {
1585 { 0x4200e000, 0000000000 },
1586 { 0x4000e000, 0000000000 },
1587 { 0x00000099, 0x00000008 },
1588 { 0x0000009d, 0x00000008 },
1589 { 0x4a554b4a, 0000000000 },
1590 { 0x4a4a4467, 0000000000 },
1591 { 0x55526f75, 0000000000 },
1592 { 0x4a7e7d65, 0000000000 },
1593 { 0xe0dae6f6, 0000000000 },
1594 { 0x4ac54a4a, 0000000000 },
1595 { 0xc8828282, 0000000000 },
1596 { 0xbf4acfc1, 0000000000 },
1597 { 0x87b04ad5, 0000000000 },
1598 { 0xb5838383, 0000000000 },
1599 { 0x4a0f85ba, 0000000000 },
1600 { 0x000ca000, 0x00000004 },
1601 { 0x000d0012, 0x00000038 },
1602 { 0x0000e8b4, 0x00000004 },
1603 { 0x000d0014, 0x00000038 },
1604 { 0x0000e8b6, 0x00000004 },
1605 { 0x000d0016, 0x00000038 },
1606 { 0x0000e854, 0x00000004 },
1607 { 0x000d0018, 0x00000038 },
1608 { 0x0000e855, 0x00000004 },
1609 { 0x000d001a, 0x00000038 },
1610 { 0x0000e856, 0x00000004 },
1611 { 0x000d001c, 0x00000038 },
1612 { 0x0000e857, 0x00000004 },
1613 { 0x000d001e, 0x00000038 },
1614 { 0x0000e824, 0x00000004 },
1615 { 0x000d0020, 0x00000038 },
1616 { 0x0000e825, 0x00000004 },
1617 { 0x000d0022, 0x00000038 },
1618 { 0x0000e830, 0x00000004 },
1619 { 0x000d0024, 0x00000038 },
1620 { 0x0000f0c0, 0x00000004 },
1621 { 0x000d0026, 0x00000038 },
1622 { 0x0000f0c1, 0x00000004 },
1623 { 0x000d0028, 0x00000038 },
1624 { 0x0000e000, 0x00000004 },
1625 { 0x000d002a, 0x00000038 },
1626 { 0x0000e000, 0x00000004 },
1627 { 0x000d002c, 0x00000038 },
1628 { 0x0000e000, 0x00000004 },
1629 { 0x000d002e, 0x00000038 },
1630 { 0x0000e000, 0x00000004 },
1631 { 0x000d0030, 0x00000038 },
1632 { 0x0000e000, 0x00000004 },
1633 { 0x000d0032, 0x00000038 },
1634 { 0x0000f180, 0x00000004 },
1635 { 0x000d0034, 0x00000038 },
1636 { 0x0000f393, 0x00000004 },
1637 { 0x000d0036, 0x00000038 },
1638 { 0x0000f38a, 0x00000004 },
1639 { 0x000d0038, 0x00000038 },
1640 { 0x0000f38e, 0x00000004 },
1641 { 0x0000e821, 0x00000004 },
1642 { 0x0140a000, 0x00000004 },
1643 { 0x00000043, 0x00000018 },
1644 { 0x00cce800, 0x00000004 },
1645 { 0x001b0001, 0x00000004 },
1646 { 0x08004800, 0x00000004 },
1647 { 0x001b0001, 0x00000004 },
1648 { 0x08004800, 0x00000004 },
1649 { 0x001b0001, 0x00000004 },
1650 { 0x08004800, 0x00000004 },
1651 { 0x0000003a, 0x00000008 },
1652 { 0x0000a000, 0000000000 },
1653 { 0x2000451d, 0x00000004 },
1654 { 0x0000e580, 0x00000004 },
1655 { 0x000ce581, 0x00000004 },
1656 { 0x08004580, 0x00000004 },
1657 { 0x000ce581, 0x00000004 },
1658 { 0x00000047, 0x00000008 },
1659 { 0x0000a000, 0000000000 },
1660 { 0x000c2000, 0x00000004 },
1661 { 0x0000e50e, 0x00000004 },
1662 { 0x00032000, 0x00000004 },
1663 { 0x00022051, 0x00000028 },
1664 { 0x00000051, 0x00000024 },
1665 { 0x0800450f, 0x00000004 },
1666 { 0x0000a04b, 0x00000008 },
1667 { 0x0000e565, 0x00000004 },
1668 { 0x0000e566, 0x00000004 },
1669 { 0x00000052, 0x00000008 },
1670 { 0x03cca5b4, 0x00000004 },
1671 { 0x05432000, 0x00000004 },
1672 { 0x00022000, 0x00000004 },
1673 { 0x4ccce05e, 0x00000030 },
1674 { 0x08274565, 0x00000004 },
1675 { 0x0000005e, 0x00000030 },
1676 { 0x08004564, 0x00000004 },
1677 { 0x0000e566, 0x00000004 },
1678 { 0x00000055, 0x00000008 },
1679 { 0x00802061, 0x00000010 },
1680 { 0x00202000, 0x00000004 },
1681 { 0x001b00ff, 0x00000004 },
1682 { 0x01000064, 0x00000010 },
1683 { 0x001f2000, 0x00000004 },
1684 { 0x001c00ff, 0x00000004 },
1685 { 0000000000, 0x0000000c },
1686 { 0x00000072, 0x00000030 },
1687 { 0x00000055, 0x00000008 },
1688 { 0x0000e576, 0x00000004 },
1689 { 0x0000e577, 0x00000004 },
1690 { 0x0000e50e, 0x00000004 },
1691 { 0x0000e50f, 0x00000004 },
1692 { 0x0140a000, 0x00000004 },
1693 { 0x00000069, 0x00000018 },
1694 { 0x00c0e5f9, 0x000000c2 },
1695 { 0x00000069, 0x00000008 },
1696 { 0x0014e50e, 0x00000004 },
1697 { 0x0040e50f, 0x00000004 },
1698 { 0x00c0006c, 0x00000008 },
1699 { 0x0000e570, 0x00000004 },
1700 { 0x0000e571, 0x00000004 },
1701 { 0x0000e572, 0x0000000c },
1702 { 0x0000a000, 0x00000004 },
1703 { 0x0140a000, 0x00000004 },
1704 { 0x0000e568, 0x00000004 },
1705 { 0x000c2000, 0x00000004 },
1706 { 0x00000076, 0x00000018 },
1707 { 0x000b0000, 0x00000004 },
1708 { 0x18c0e562, 0x00000004 },
1709 { 0x00000078, 0x00000008 },
1710 { 0x00c00077, 0x00000008 },
1711 { 0x000700c7, 0x00000004 },
1712 { 0x00000080, 0x00000038 },
1713 { 0x0000e5bb, 0x00000004 },
1714 { 0x0000e5bc, 0000000000 },
1715 { 0x0000a000, 0x00000004 },
1716 { 0x0000e821, 0x00000004 },
1717 { 0x0000e800, 0000000000 },
1718 { 0x0000e821, 0x00000004 },
1719 { 0x0000e82e, 0000000000 },
1720 { 0x02cca000, 0x00000004 },
1721 { 0x00140000, 0x00000004 },
1722 { 0x000ce1cc, 0x00000004 },
1723 { 0x050de1cd, 0x00000004 },
1724 { 0x00400000, 0x00000004 },
1725 { 0x0000008f, 0x00000018 },
1726 { 0x00c0a000, 0x00000004 },
1727 { 0x0000008c, 0x00000008 },
1728 { 0x00000091, 0x00000020 },
1729 { 0x4200e000, 0000000000 },
1730 { 0x00000098, 0x00000038 },
1731 { 0x000ca000, 0x00000004 },
1732 { 0x00140000, 0x00000004 },
1733 { 0x000c2000, 0x00000004 },
1734 { 0x00160000, 0x00000004 },
1735 { 0x700ce000, 0x00000004 },
1736 { 0x00140094, 0x00000008 },
1737 { 0x4000e000, 0000000000 },
1738 { 0x02400000, 0x00000004 },
1739 { 0x400ee000, 0x00000004 },
1740 { 0x02400000, 0x00000004 },
1741 { 0x4000e000, 0000000000 },
1742 { 0x000c2000, 0x00000004 },
1743 { 0x0240e51b, 0x00000004 },
1744 { 0x0080e50a, 0x00000005 },
1745 { 0x0080e50b, 0x00000005 },
1746 { 0x00220000, 0x00000004 },
1747 { 0x000700c7, 0x00000004 },
1748 { 0x000000a4, 0x00000038 },
1749 { 0x0080e5bd, 0x00000005 },
1750 { 0x0000e5bb, 0x00000005 },
1751 { 0x0080e5bc, 0x00000005 },
1752 { 0x00210000, 0x00000004 },
1753 { 0x02800000, 0x00000004 },
1754 { 0x00c000ab, 0x00000018 },
1755 { 0x4180e000, 0x00000040 },
1756 { 0x000000ad, 0x00000024 },
1757 { 0x01000000, 0x0000000c },
1758 { 0x0100e51d, 0x0000000c },
1759 { 0x000045bb, 0x00000004 },
1760 { 0x000080a7, 0x00000008 },
1761 { 0x0000f3ce, 0x00000004 },
1762 { 0x0140a000, 0x00000004 },
1763 { 0x00cc2000, 0x00000004 },
1764 { 0x08c053cf, 0x00000040 },
1765 { 0x00008000, 0000000000 },
1766 { 0x0000f3d2, 0x00000004 },
1767 { 0x0140a000, 0x00000004 },
1768 { 0x00cc2000, 0x00000004 },
1769 { 0x08c053d3, 0x00000040 },
1770 { 0x00008000, 0000000000 },
1771 { 0x0000f39d, 0x00000004 },
1772 { 0x0140a000, 0x00000004 },
1773 { 0x00cc2000, 0x00000004 },
1774 { 0x08c0539e, 0x00000040 },
1775 { 0x00008000, 0000000000 },
1776 { 0x03c00830, 0x00000004 },
1777 { 0x4200e000, 0000000000 },
1778 { 0x0000a000, 0x00000004 },
1779 { 0x200045e0, 0x00000004 },
1780 { 0x0000e5e1, 0000000000 },
1781 { 0x00000001, 0000000000 },
1782 { 0x000700c4, 0x00000004 },
1783 { 0x0800e394, 0000000000 },
1784 { 0000000000, 0000000000 },
1785 { 0x0000e8c4, 0x00000004 },
1786 { 0x0000e8c5, 0x00000004 },
1787 { 0x0000e8c6, 0x00000004 },
1788 { 0x0000e928, 0x00000004 },
1789 { 0x0000e929, 0x00000004 },
1790 { 0x0000e92a, 0x00000004 },
1791 { 0x000000c8, 0x00000008 },
1792 { 0x0000e928, 0x00000004 },
1793 { 0x0000e929, 0x00000004 },
1794 { 0x0000e92a, 0x00000004 },
1795 { 0x000000cf, 0x00000008 },
1796 { 0xdeadbeef, 0000000000 },
1797 { 0x00000116, 0000000000 },
1798 { 0x000700d3, 0x00000004 },
1799 { 0x080050e7, 0x00000004 },
1800 { 0x000700d4, 0x00000004 },
1801 { 0x0800401c, 0x00000004 },
1802 { 0x0000e01d, 0000000000 },
1803 { 0x02c02000, 0x00000004 },
1804 { 0x00060000, 0x00000004 },
1805 { 0x000000de, 0x00000034 },
1806 { 0x000000db, 0x00000008 },
1807 { 0x00008000, 0x00000004 },
1808 { 0xc000e000, 0000000000 },
1809 { 0x0000e1cc, 0x00000004 },
1810 { 0x0500e1cd, 0x00000004 },
1811 { 0x000ca000, 0x00000004 },
1812 { 0x000000e5, 0x00000034 },
1813 { 0x000000e1, 0x00000008 },
1814 { 0x0000a000, 0000000000 },
1815 { 0x0019e1cc, 0x00000004 },
1816 { 0x001b0001, 0x00000004 },
1817 { 0x0500a000, 0x00000004 },
1818 { 0x080041cd, 0x00000004 },
1819 { 0x000ca000, 0x00000004 },
1820 { 0x000000fb, 0x00000034 },
1821 { 0x0000004a, 0x00000008 },
1822 { 0000000000, 0000000000 },
1823 { 0000000000, 0000000000 },
1824 { 0000000000, 0000000000 },
1825 { 0000000000, 0000000000 },
1826 { 0000000000, 0000000000 },
1827 { 0000000000, 0000000000 },
1828 { 0000000000, 0000000000 },
1829 { 0000000000, 0000000000 },
1830 { 0000000000, 0000000000 },
1831 { 0x000c2000, 0x00000004 },
1832 { 0x001d0018, 0x00000004 },
1833 { 0x001a0001, 0x00000004 },
1834 { 0x000000fb, 0x00000034 },
1835 { 0x0000004a, 0x00000008 },
1836 { 0x0500a04a, 0x00000008 },
1837 { 0000000000, 0000000000 },
1838 { 0000000000, 0000000000 },
1839 { 0000000000, 0000000000 },
1840 { 0000000000, 0000000000 },
1841};
1842
1843
1844#endif
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
new file mode 100644
index 000000000000..11c146b49211
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -0,0 +1,3203 @@
1/* radeon_state.c -- State support for Radeon -*- linux-c -*- */
2/*
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Gareth Hughes <gareth@valinux.com>
27 * Kevin E. Martin <martin@valinux.com>
28 */
29
30#include "drmP.h"
31#include "drm.h"
32#include "drm_sarea.h"
33#include "radeon_drm.h"
34#include "radeon_drv.h"
35
36/* ================================================================
37 * Helper functions for client state checking and fixup
38 */
39
40static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
41 dev_priv,
42 struct drm_file * file_priv,
43 u32 *offset)
44{
45 u64 off = *offset;
46 u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
47 struct drm_radeon_driver_file_fields *radeon_priv;
48
49 /* Hrm ... the story of the offset ... So this function converts
50 * the various ideas of what userland clients might have for an
51 * offset in the card address space into an offset into the card
52 * address space :) So with a sane client, it should just keep
53 * the value intact and just do some boundary checking. However,
54 * not all clients are sane. Some older clients pass us 0 based
55 * offsets relative to the start of the framebuffer and some may
56 * assume the AGP aperture it appended to the framebuffer, so we
57 * try to detect those cases and fix them up.
58 *
59 * Note: It might be a good idea here to make sure the offset lands
60 * in some "allowed" area to protect things like the PCIE GART...
61 */
62
63 /* First, the best case, the offset already lands in either the
64 * framebuffer or the GART mapped space
65 */
66 if (radeon_check_offset(dev_priv, off))
67 return 0;
68
69 /* Ok, that didn't happen... now check if we have a zero based
70 * offset that fits in the framebuffer + gart space, apply the
71 * magic offset we get from SETPARAM or calculated from fb_location
72 */
73 if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
74 radeon_priv = file_priv->driver_priv;
75 off += radeon_priv->radeon_fb_delta;
76 }
77
78 /* Finally, assume we aimed at a GART offset if beyond the fb */
79 if (off > fb_end)
80 off = off - fb_end - 1 + dev_priv->gart_vm_start;
81
82 /* Now recheck and fail if out of bounds */
83 if (radeon_check_offset(dev_priv, off)) {
84 DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
85 *offset = off;
86 return 0;
87 }
88 return -EINVAL;
89}
90
91static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
92 dev_priv,
93 struct drm_file *file_priv,
94 int id, u32 *data)
95{
96 switch (id) {
97
98 case RADEON_EMIT_PP_MISC:
99 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
100 &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) {
101 DRM_ERROR("Invalid depth buffer offset\n");
102 return -EINVAL;
103 }
104 break;
105
106 case RADEON_EMIT_PP_CNTL:
107 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
108 &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) {
109 DRM_ERROR("Invalid colour buffer offset\n");
110 return -EINVAL;
111 }
112 break;
113
114 case R200_EMIT_PP_TXOFFSET_0:
115 case R200_EMIT_PP_TXOFFSET_1:
116 case R200_EMIT_PP_TXOFFSET_2:
117 case R200_EMIT_PP_TXOFFSET_3:
118 case R200_EMIT_PP_TXOFFSET_4:
119 case R200_EMIT_PP_TXOFFSET_5:
120 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
121 &data[0])) {
122 DRM_ERROR("Invalid R200 texture offset\n");
123 return -EINVAL;
124 }
125 break;
126
127 case RADEON_EMIT_PP_TXFILTER_0:
128 case RADEON_EMIT_PP_TXFILTER_1:
129 case RADEON_EMIT_PP_TXFILTER_2:
130 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
131 &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) {
132 DRM_ERROR("Invalid R100 texture offset\n");
133 return -EINVAL;
134 }
135 break;
136
137 case R200_EMIT_PP_CUBIC_OFFSETS_0:
138 case R200_EMIT_PP_CUBIC_OFFSETS_1:
139 case R200_EMIT_PP_CUBIC_OFFSETS_2:
140 case R200_EMIT_PP_CUBIC_OFFSETS_3:
141 case R200_EMIT_PP_CUBIC_OFFSETS_4:
142 case R200_EMIT_PP_CUBIC_OFFSETS_5:{
143 int i;
144 for (i = 0; i < 5; i++) {
145 if (radeon_check_and_fixup_offset(dev_priv,
146 file_priv,
147 &data[i])) {
148 DRM_ERROR
149 ("Invalid R200 cubic texture offset\n");
150 return -EINVAL;
151 }
152 }
153 break;
154 }
155
156 case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
157 case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
158 case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{
159 int i;
160 for (i = 0; i < 5; i++) {
161 if (radeon_check_and_fixup_offset(dev_priv,
162 file_priv,
163 &data[i])) {
164 DRM_ERROR
165 ("Invalid R100 cubic texture offset\n");
166 return -EINVAL;
167 }
168 }
169 }
170 break;
171
172 case R200_EMIT_VAP_CTL:{
173 RING_LOCALS;
174 BEGIN_RING(2);
175 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
176 ADVANCE_RING();
177 }
178 break;
179
180 case RADEON_EMIT_RB3D_COLORPITCH:
181 case RADEON_EMIT_RE_LINE_PATTERN:
182 case RADEON_EMIT_SE_LINE_WIDTH:
183 case RADEON_EMIT_PP_LUM_MATRIX:
184 case RADEON_EMIT_PP_ROT_MATRIX_0:
185 case RADEON_EMIT_RB3D_STENCILREFMASK:
186 case RADEON_EMIT_SE_VPORT_XSCALE:
187 case RADEON_EMIT_SE_CNTL:
188 case RADEON_EMIT_SE_CNTL_STATUS:
189 case RADEON_EMIT_RE_MISC:
190 case RADEON_EMIT_PP_BORDER_COLOR_0:
191 case RADEON_EMIT_PP_BORDER_COLOR_1:
192 case RADEON_EMIT_PP_BORDER_COLOR_2:
193 case RADEON_EMIT_SE_ZBIAS_FACTOR:
194 case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT:
195 case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED:
196 case R200_EMIT_PP_TXCBLEND_0:
197 case R200_EMIT_PP_TXCBLEND_1:
198 case R200_EMIT_PP_TXCBLEND_2:
199 case R200_EMIT_PP_TXCBLEND_3:
200 case R200_EMIT_PP_TXCBLEND_4:
201 case R200_EMIT_PP_TXCBLEND_5:
202 case R200_EMIT_PP_TXCBLEND_6:
203 case R200_EMIT_PP_TXCBLEND_7:
204 case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
205 case R200_EMIT_TFACTOR_0:
206 case R200_EMIT_VTX_FMT_0:
207 case R200_EMIT_MATRIX_SELECT_0:
208 case R200_EMIT_TEX_PROC_CTL_2:
209 case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
210 case R200_EMIT_PP_TXFILTER_0:
211 case R200_EMIT_PP_TXFILTER_1:
212 case R200_EMIT_PP_TXFILTER_2:
213 case R200_EMIT_PP_TXFILTER_3:
214 case R200_EMIT_PP_TXFILTER_4:
215 case R200_EMIT_PP_TXFILTER_5:
216 case R200_EMIT_VTE_CNTL:
217 case R200_EMIT_OUTPUT_VTX_COMP_SEL:
218 case R200_EMIT_PP_TAM_DEBUG3:
219 case R200_EMIT_PP_CNTL_X:
220 case R200_EMIT_RB3D_DEPTHXY_OFFSET:
221 case R200_EMIT_RE_AUX_SCISSOR_CNTL:
222 case R200_EMIT_RE_SCISSOR_TL_0:
223 case R200_EMIT_RE_SCISSOR_TL_1:
224 case R200_EMIT_RE_SCISSOR_TL_2:
225 case R200_EMIT_SE_VAP_CNTL_STATUS:
226 case R200_EMIT_SE_VTX_STATE_CNTL:
227 case R200_EMIT_RE_POINTSIZE:
228 case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0:
229 case R200_EMIT_PP_CUBIC_FACES_0:
230 case R200_EMIT_PP_CUBIC_FACES_1:
231 case R200_EMIT_PP_CUBIC_FACES_2:
232 case R200_EMIT_PP_CUBIC_FACES_3:
233 case R200_EMIT_PP_CUBIC_FACES_4:
234 case R200_EMIT_PP_CUBIC_FACES_5:
235 case RADEON_EMIT_PP_TEX_SIZE_0:
236 case RADEON_EMIT_PP_TEX_SIZE_1:
237 case RADEON_EMIT_PP_TEX_SIZE_2:
238 case R200_EMIT_RB3D_BLENDCOLOR:
239 case R200_EMIT_TCL_POINT_SPRITE_CNTL:
240 case RADEON_EMIT_PP_CUBIC_FACES_0:
241 case RADEON_EMIT_PP_CUBIC_FACES_1:
242 case RADEON_EMIT_PP_CUBIC_FACES_2:
243 case R200_EMIT_PP_TRI_PERF_CNTL:
244 case R200_EMIT_PP_AFS_0:
245 case R200_EMIT_PP_AFS_1:
246 case R200_EMIT_ATF_TFACTOR:
247 case R200_EMIT_PP_TXCTLALL_0:
248 case R200_EMIT_PP_TXCTLALL_1:
249 case R200_EMIT_PP_TXCTLALL_2:
250 case R200_EMIT_PP_TXCTLALL_3:
251 case R200_EMIT_PP_TXCTLALL_4:
252 case R200_EMIT_PP_TXCTLALL_5:
253 case R200_EMIT_VAP_PVS_CNTL:
254 /* These packets don't contain memory offsets */
255 break;
256
257 default:
258 DRM_ERROR("Unknown state packet ID %d\n", id);
259 return -EINVAL;
260 }
261
262 return 0;
263}
264
265static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
266 dev_priv,
267 struct drm_file *file_priv,
268 drm_radeon_kcmd_buffer_t *
269 cmdbuf,
270 unsigned int *cmdsz)
271{
272 u32 *cmd = (u32 *) cmdbuf->buf;
273 u32 offset, narrays;
274 int count, i, k;
275
276 *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
277
278 if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) {
279 DRM_ERROR("Not a type 3 packet\n");
280 return -EINVAL;
281 }
282
283 if (4 * *cmdsz > cmdbuf->bufsz) {
284 DRM_ERROR("Packet size larger than size of data provided\n");
285 return -EINVAL;
286 }
287
288 switch(cmd[0] & 0xff00) {
289 /* XXX Are there old drivers needing other packets? */
290
291 case RADEON_3D_DRAW_IMMD:
292 case RADEON_3D_DRAW_VBUF:
293 case RADEON_3D_DRAW_INDX:
294 case RADEON_WAIT_FOR_IDLE:
295 case RADEON_CP_NOP:
296 case RADEON_3D_CLEAR_ZMASK:
297/* case RADEON_CP_NEXT_CHAR:
298 case RADEON_CP_PLY_NEXTSCAN:
299 case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
300 /* these packets are safe */
301 break;
302
303 case RADEON_CP_3D_DRAW_IMMD_2:
304 case RADEON_CP_3D_DRAW_VBUF_2:
305 case RADEON_CP_3D_DRAW_INDX_2:
306 case RADEON_3D_CLEAR_HIZ:
307 /* safe but r200 only */
308 if (dev_priv->microcode_version != UCODE_R200) {
309 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
310 return -EINVAL;
311 }
312 break;
313
314 case RADEON_3D_LOAD_VBPNTR:
315 count = (cmd[0] >> 16) & 0x3fff;
316
317 if (count > 18) { /* 12 arrays max */
318 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
319 count);
320 return -EINVAL;
321 }
322
323 /* carefully check packet contents */
324 narrays = cmd[1] & ~0xc000;
325 k = 0;
326 i = 2;
327 while ((k < narrays) && (i < (count + 2))) {
328 i++; /* skip attribute field */
329 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
330 &cmd[i])) {
331 DRM_ERROR
332 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
333 k, i);
334 return -EINVAL;
335 }
336 k++;
337 i++;
338 if (k == narrays)
339 break;
340 /* have one more to process, they come in pairs */
341 if (radeon_check_and_fixup_offset(dev_priv,
342 file_priv, &cmd[i]))
343 {
344 DRM_ERROR
345 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
346 k, i);
347 return -EINVAL;
348 }
349 k++;
350 i++;
351 }
352 /* do the counts match what we expect ? */
353 if ((k != narrays) || (i != (count + 2))) {
354 DRM_ERROR
355 ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
356 k, i, narrays, count + 1);
357 return -EINVAL;
358 }
359 break;
360
361 case RADEON_3D_RNDR_GEN_INDX_PRIM:
362 if (dev_priv->microcode_version != UCODE_R100) {
363 DRM_ERROR("Invalid 3d packet for r200-class chip\n");
364 return -EINVAL;
365 }
366 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) {
367 DRM_ERROR("Invalid rndr_gen_indx offset\n");
368 return -EINVAL;
369 }
370 break;
371
372 case RADEON_CP_INDX_BUFFER:
373 if (dev_priv->microcode_version != UCODE_R200) {
374 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
375 return -EINVAL;
376 }
377 if ((cmd[1] & 0x8000ffff) != 0x80000810) {
378 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
379 return -EINVAL;
380 }
381 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[2])) {
382 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
383 return -EINVAL;
384 }
385 break;
386
387 case RADEON_CNTL_HOSTDATA_BLT:
388 case RADEON_CNTL_PAINT_MULTI:
389 case RADEON_CNTL_BITBLT_MULTI:
390 /* MSB of opcode: next DWORD GUI_CNTL */
391 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
392 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
393 offset = cmd[2] << 10;
394 if (radeon_check_and_fixup_offset
395 (dev_priv, file_priv, &offset)) {
396 DRM_ERROR("Invalid first packet offset\n");
397 return -EINVAL;
398 }
399 cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10;
400 }
401
402 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
403 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
404 offset = cmd[3] << 10;
405 if (radeon_check_and_fixup_offset
406 (dev_priv, file_priv, &offset)) {
407 DRM_ERROR("Invalid second packet offset\n");
408 return -EINVAL;
409 }
410 cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
411 }
412 break;
413
414 default:
415 DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
416 return -EINVAL;
417 }
418
419 return 0;
420}
421
422/* ================================================================
423 * CP hardware state programming functions
424 */
425
426static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,
427 struct drm_clip_rect * box)
428{
429 RING_LOCALS;
430
431 DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
432 box->x1, box->y1, box->x2, box->y2);
433
434 BEGIN_RING(4);
435 OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
436 OUT_RING((box->y1 << 16) | box->x1);
437 OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
438 OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));
439 ADVANCE_RING();
440}
441
442/* Emit 1.1 state
443 */
444static int radeon_emit_state(drm_radeon_private_t * dev_priv,
445 struct drm_file *file_priv,
446 drm_radeon_context_regs_t * ctx,
447 drm_radeon_texture_regs_t * tex,
448 unsigned int dirty)
449{
450 RING_LOCALS;
451 DRM_DEBUG("dirty=0x%08x\n", dirty);
452
453 if (dirty & RADEON_UPLOAD_CONTEXT) {
454 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
455 &ctx->rb3d_depthoffset)) {
456 DRM_ERROR("Invalid depth buffer offset\n");
457 return -EINVAL;
458 }
459
460 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
461 &ctx->rb3d_coloroffset)) {
462 DRM_ERROR("Invalid depth buffer offset\n");
463 return -EINVAL;
464 }
465
466 BEGIN_RING(14);
467 OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));
468 OUT_RING(ctx->pp_misc);
469 OUT_RING(ctx->pp_fog_color);
470 OUT_RING(ctx->re_solid_color);
471 OUT_RING(ctx->rb3d_blendcntl);
472 OUT_RING(ctx->rb3d_depthoffset);
473 OUT_RING(ctx->rb3d_depthpitch);
474 OUT_RING(ctx->rb3d_zstencilcntl);
475 OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));
476 OUT_RING(ctx->pp_cntl);
477 OUT_RING(ctx->rb3d_cntl);
478 OUT_RING(ctx->rb3d_coloroffset);
479 OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
480 OUT_RING(ctx->rb3d_colorpitch);
481 ADVANCE_RING();
482 }
483
484 if (dirty & RADEON_UPLOAD_VERTFMT) {
485 BEGIN_RING(2);
486 OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));
487 OUT_RING(ctx->se_coord_fmt);
488 ADVANCE_RING();
489 }
490
491 if (dirty & RADEON_UPLOAD_LINE) {
492 BEGIN_RING(5);
493 OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));
494 OUT_RING(ctx->re_line_pattern);
495 OUT_RING(ctx->re_line_state);
496 OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));
497 OUT_RING(ctx->se_line_width);
498 ADVANCE_RING();
499 }
500
501 if (dirty & RADEON_UPLOAD_BUMPMAP) {
502 BEGIN_RING(5);
503 OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));
504 OUT_RING(ctx->pp_lum_matrix);
505 OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));
506 OUT_RING(ctx->pp_rot_matrix_0);
507 OUT_RING(ctx->pp_rot_matrix_1);
508 ADVANCE_RING();
509 }
510
511 if (dirty & RADEON_UPLOAD_MASKS) {
512 BEGIN_RING(4);
513 OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));
514 OUT_RING(ctx->rb3d_stencilrefmask);
515 OUT_RING(ctx->rb3d_ropcntl);
516 OUT_RING(ctx->rb3d_planemask);
517 ADVANCE_RING();
518 }
519
520 if (dirty & RADEON_UPLOAD_VIEWPORT) {
521 BEGIN_RING(7);
522 OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));
523 OUT_RING(ctx->se_vport_xscale);
524 OUT_RING(ctx->se_vport_xoffset);
525 OUT_RING(ctx->se_vport_yscale);
526 OUT_RING(ctx->se_vport_yoffset);
527 OUT_RING(ctx->se_vport_zscale);
528 OUT_RING(ctx->se_vport_zoffset);
529 ADVANCE_RING();
530 }
531
532 if (dirty & RADEON_UPLOAD_SETUP) {
533 BEGIN_RING(4);
534 OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));
535 OUT_RING(ctx->se_cntl);
536 OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));
537 OUT_RING(ctx->se_cntl_status);
538 ADVANCE_RING();
539 }
540
541 if (dirty & RADEON_UPLOAD_MISC) {
542 BEGIN_RING(2);
543 OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));
544 OUT_RING(ctx->re_misc);
545 ADVANCE_RING();
546 }
547
548 if (dirty & RADEON_UPLOAD_TEX0) {
549 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
550 &tex[0].pp_txoffset)) {
551 DRM_ERROR("Invalid texture offset for unit 0\n");
552 return -EINVAL;
553 }
554
555 BEGIN_RING(9);
556 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));
557 OUT_RING(tex[0].pp_txfilter);
558 OUT_RING(tex[0].pp_txformat);
559 OUT_RING(tex[0].pp_txoffset);
560 OUT_RING(tex[0].pp_txcblend);
561 OUT_RING(tex[0].pp_txablend);
562 OUT_RING(tex[0].pp_tfactor);
563 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));
564 OUT_RING(tex[0].pp_border_color);
565 ADVANCE_RING();
566 }
567
568 if (dirty & RADEON_UPLOAD_TEX1) {
569 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
570 &tex[1].pp_txoffset)) {
571 DRM_ERROR("Invalid texture offset for unit 1\n");
572 return -EINVAL;
573 }
574
575 BEGIN_RING(9);
576 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));
577 OUT_RING(tex[1].pp_txfilter);
578 OUT_RING(tex[1].pp_txformat);
579 OUT_RING(tex[1].pp_txoffset);
580 OUT_RING(tex[1].pp_txcblend);
581 OUT_RING(tex[1].pp_txablend);
582 OUT_RING(tex[1].pp_tfactor);
583 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));
584 OUT_RING(tex[1].pp_border_color);
585 ADVANCE_RING();
586 }
587
588 if (dirty & RADEON_UPLOAD_TEX2) {
589 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
590 &tex[2].pp_txoffset)) {
591 DRM_ERROR("Invalid texture offset for unit 2\n");
592 return -EINVAL;
593 }
594
595 BEGIN_RING(9);
596 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));
597 OUT_RING(tex[2].pp_txfilter);
598 OUT_RING(tex[2].pp_txformat);
599 OUT_RING(tex[2].pp_txoffset);
600 OUT_RING(tex[2].pp_txcblend);
601 OUT_RING(tex[2].pp_txablend);
602 OUT_RING(tex[2].pp_tfactor);
603 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));
604 OUT_RING(tex[2].pp_border_color);
605 ADVANCE_RING();
606 }
607
608 return 0;
609}
610
611/* Emit 1.2 state
612 */
613static int radeon_emit_state2(drm_radeon_private_t * dev_priv,
614 struct drm_file *file_priv,
615 drm_radeon_state_t * state)
616{
617 RING_LOCALS;
618
619 if (state->dirty & RADEON_UPLOAD_ZBIAS) {
620 BEGIN_RING(3);
621 OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));
622 OUT_RING(state->context2.se_zbias_factor);
623 OUT_RING(state->context2.se_zbias_constant);
624 ADVANCE_RING();
625 }
626
627 return radeon_emit_state(dev_priv, file_priv, &state->context,
628 state->tex, state->dirty);
629}
630
631/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
632 * 1.3 cmdbuffers allow all previous state to be updated as well as
633 * the tcl scalar and vector areas.
634 */
635static struct {
636 int start;
637 int len;
638 const char *name;
639} packet[RADEON_MAX_STATE_PACKETS] = {
640 {RADEON_PP_MISC, 7, "RADEON_PP_MISC"},
641 {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"},
642 {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"},
643 {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"},
644 {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"},
645 {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"},
646 {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"},
647 {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"},
648 {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"},
649 {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"},
650 {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"},
651 {RADEON_RE_MISC, 1, "RADEON_RE_MISC"},
652 {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"},
653 {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"},
654 {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"},
655 {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"},
656 {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"},
657 {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"},
658 {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"},
659 {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
660 {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17,
661 "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
662 {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"},
663 {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"},
664 {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"},
665 {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"},
666 {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"},
667 {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"},
668 {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"},
669 {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"},
670 {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
671 {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"},
672 {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"},
673 {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"},
674 {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"},
675 {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
676 {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
677 {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"},
678 {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"},
679 {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"},
680 {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"},
681 {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"},
682 {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"},
683 {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"},
684 {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"},
685 {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"},
686 {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"},
687 {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
688 {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
689 {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
690 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
691 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
692 {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
693 {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
694 {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
695 {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"},
696 {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"},
697 {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"},
698 {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"},
699 {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"},
700 {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"},
701 {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"},
702 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
703 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
704 {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
705 {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
706 {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
707 {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
708 {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
709 {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
710 {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"},
711 {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
712 {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"},
713 {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
714 {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"},
715 {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
716 {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"},
717 {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"},
718 {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"},
719 {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"},
720 {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
721 {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
722 {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
723 {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
724 {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
725 {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
726 {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
727 {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
728 {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
729 {R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
730 {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
731 {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
732 {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},
733 {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},
734 {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
735 {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
736 {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
737 {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},
738};
739
740/* ================================================================
741 * Performance monitoring functions
742 */
743
744static void radeon_clear_box(drm_radeon_private_t * dev_priv,
745 int x, int y, int w, int h, int r, int g, int b)
746{
747 u32 color;
748 RING_LOCALS;
749
750 x += dev_priv->sarea_priv->boxes[0].x1;
751 y += dev_priv->sarea_priv->boxes[0].y1;
752
753 switch (dev_priv->color_fmt) {
754 case RADEON_COLOR_FORMAT_RGB565:
755 color = (((r & 0xf8) << 8) |
756 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
757 break;
758 case RADEON_COLOR_FORMAT_ARGB8888:
759 default:
760 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
761 break;
762 }
763
764 BEGIN_RING(4);
765 RADEON_WAIT_UNTIL_3D_IDLE();
766 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
767 OUT_RING(0xffffffff);
768 ADVANCE_RING();
769
770 BEGIN_RING(6);
771
772 OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
773 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
774 RADEON_GMC_BRUSH_SOLID_COLOR |
775 (dev_priv->color_fmt << 8) |
776 RADEON_GMC_SRC_DATATYPE_COLOR |
777 RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
778
779 if (dev_priv->sarea_priv->pfCurrentPage == 1) {
780 OUT_RING(dev_priv->front_pitch_offset);
781 } else {
782 OUT_RING(dev_priv->back_pitch_offset);
783 }
784
785 OUT_RING(color);
786
787 OUT_RING((x << 16) | y);
788 OUT_RING((w << 16) | h);
789
790 ADVANCE_RING();
791}
792
793static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
794{
795 /* Collapse various things into a wait flag -- trying to
796 * guess if userspase slept -- better just to have them tell us.
797 */
798 if (dev_priv->stats.last_frame_reads > 1 ||
799 dev_priv->stats.last_clear_reads > dev_priv->stats.clears) {
800 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
801 }
802
803 if (dev_priv->stats.freelist_loops) {
804 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
805 }
806
807 /* Purple box for page flipping
808 */
809 if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
810 radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
811
812 /* Red box if we have to wait for idle at any point
813 */
814 if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
815 radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
816
817 /* Blue box: lost context?
818 */
819
820 /* Yellow box for texture swaps
821 */
822 if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
823 radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
824
825 /* Green box if hardware never idles (as far as we can tell)
826 */
827 if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
828 radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
829
830 /* Draw bars indicating number of buffers allocated
831 * (not a great measure, easily confused)
832 */
833 if (dev_priv->stats.requested_bufs) {
834 if (dev_priv->stats.requested_bufs > 100)
835 dev_priv->stats.requested_bufs = 100;
836
837 radeon_clear_box(dev_priv, 4, 16,
838 dev_priv->stats.requested_bufs, 4,
839 196, 128, 128);
840 }
841
842 memset(&dev_priv->stats, 0, sizeof(dev_priv->stats));
843
844}
845
846/* ================================================================
847 * CP command dispatch functions
848 */
849
850static void radeon_cp_dispatch_clear(struct drm_device * dev,
851 drm_radeon_clear_t * clear,
852 drm_radeon_clear_rect_t * depth_boxes)
853{
854 drm_radeon_private_t *dev_priv = dev->dev_private;
855 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
856 drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
857 int nbox = sarea_priv->nbox;
858 struct drm_clip_rect *pbox = sarea_priv->boxes;
859 unsigned int flags = clear->flags;
860 u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0;
861 int i;
862 RING_LOCALS;
863 DRM_DEBUG("flags = 0x%x\n", flags);
864
865 dev_priv->stats.clears++;
866
867 if (dev_priv->sarea_priv->pfCurrentPage == 1) {
868 unsigned int tmp = flags;
869
870 flags &= ~(RADEON_FRONT | RADEON_BACK);
871 if (tmp & RADEON_FRONT)
872 flags |= RADEON_BACK;
873 if (tmp & RADEON_BACK)
874 flags |= RADEON_FRONT;
875 }
876
877 if (flags & (RADEON_FRONT | RADEON_BACK)) {
878
879 BEGIN_RING(4);
880
881 /* Ensure the 3D stream is idle before doing a
882 * 2D fill to clear the front or back buffer.
883 */
884 RADEON_WAIT_UNTIL_3D_IDLE();
885
886 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
887 OUT_RING(clear->color_mask);
888
889 ADVANCE_RING();
890
891 /* Make sure we restore the 3D state next time.
892 */
893 dev_priv->sarea_priv->ctx_owner = 0;
894
895 for (i = 0; i < nbox; i++) {
896 int x = pbox[i].x1;
897 int y = pbox[i].y1;
898 int w = pbox[i].x2 - x;
899 int h = pbox[i].y2 - y;
900
901 DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
902 x, y, w, h, flags);
903
904 if (flags & RADEON_FRONT) {
905 BEGIN_RING(6);
906
907 OUT_RING(CP_PACKET3
908 (RADEON_CNTL_PAINT_MULTI, 4));
909 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
910 RADEON_GMC_BRUSH_SOLID_COLOR |
911 (dev_priv->
912 color_fmt << 8) |
913 RADEON_GMC_SRC_DATATYPE_COLOR |
914 RADEON_ROP3_P |
915 RADEON_GMC_CLR_CMP_CNTL_DIS);
916
917 OUT_RING(dev_priv->front_pitch_offset);
918 OUT_RING(clear->clear_color);
919
920 OUT_RING((x << 16) | y);
921 OUT_RING((w << 16) | h);
922
923 ADVANCE_RING();
924 }
925
926 if (flags & RADEON_BACK) {
927 BEGIN_RING(6);
928
929 OUT_RING(CP_PACKET3
930 (RADEON_CNTL_PAINT_MULTI, 4));
931 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
932 RADEON_GMC_BRUSH_SOLID_COLOR |
933 (dev_priv->
934 color_fmt << 8) |
935 RADEON_GMC_SRC_DATATYPE_COLOR |
936 RADEON_ROP3_P |
937 RADEON_GMC_CLR_CMP_CNTL_DIS);
938
939 OUT_RING(dev_priv->back_pitch_offset);
940 OUT_RING(clear->clear_color);
941
942 OUT_RING((x << 16) | y);
943 OUT_RING((w << 16) | h);
944
945 ADVANCE_RING();
946 }
947 }
948 }
949
950 /* hyper z clear */
951 /* no docs available, based on reverse engeneering by Stephane Marchesin */
952 if ((flags & (RADEON_DEPTH | RADEON_STENCIL))
953 && (flags & RADEON_CLEAR_FASTZ)) {
954
955 int i;
956 int depthpixperline =
957 dev_priv->depth_fmt ==
958 RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch /
959 2) : (dev_priv->
960 depth_pitch / 4);
961
962 u32 clearmask;
963
964 u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
965 ((clear->depth_mask & 0xff) << 24);
966
967 /* Make sure we restore the 3D state next time.
968 * we haven't touched any "normal" state - still need this?
969 */
970 dev_priv->sarea_priv->ctx_owner = 0;
971
972 if ((dev_priv->flags & RADEON_HAS_HIERZ)
973 && (flags & RADEON_USE_HIERZ)) {
974 /* FIXME : reverse engineer that for Rx00 cards */
975 /* FIXME : the mask supposedly contains low-res z values. So can't set
976 just to the max (0xff? or actually 0x3fff?), need to take z clear
977 value into account? */
978 /* pattern seems to work for r100, though get slight
979 rendering errors with glxgears. If hierz is not enabled for r100,
980 only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
981 other ones are ignored, and the same clear mask can be used. That's
982 very different behaviour than R200 which needs different clear mask
983 and different number of tiles to clear if hierz is enabled or not !?!
984 */
985 clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f;
986 } else {
987 /* clear mask : chooses the clearing pattern.
988 rv250: could be used to clear only parts of macrotiles
989 (but that would get really complicated...)?
990 bit 0 and 1 (either or both of them ?!?!) are used to
991 not clear tile (or maybe one of the bits indicates if the tile is
992 compressed or not), bit 2 and 3 to not clear tile 1,...,.
993 Pattern is as follows:
994 | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
995 bits -------------------------------------------------
996 | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
997 rv100: clearmask covers 2x8 4x1 tiles, but one clear still
998 covers 256 pixels ?!?
999 */
1000 clearmask = 0x0;
1001 }
1002
1003 BEGIN_RING(8);
1004 RADEON_WAIT_UNTIL_2D_IDLE();
1005 OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE,
1006 tempRB3D_DEPTHCLEARVALUE);
1007 /* what offset is this exactly ? */
1008 OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0);
1009 /* need ctlstat, otherwise get some strange black flickering */
1010 OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT,
1011 RADEON_RB3D_ZC_FLUSH_ALL);
1012 ADVANCE_RING();
1013
1014 for (i = 0; i < nbox; i++) {
1015 int tileoffset, nrtilesx, nrtilesy, j;
1016 /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
1017 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1018 && !(dev_priv->microcode_version == UCODE_R200)) {
1019 /* FIXME : figure this out for r200 (when hierz is enabled). Or
1020 maybe r200 actually doesn't need to put the low-res z value into
1021 the tile cache like r100, but just needs to clear the hi-level z-buffer?
1022 Works for R100, both with hierz and without.
1023 R100 seems to operate on 2x1 8x8 tiles, but...
1024 odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
1025 problematic with resolutions which are not 64 pix aligned? */
1026 tileoffset =
1027 ((pbox[i].y1 >> 3) * depthpixperline +
1028 pbox[i].x1) >> 6;
1029 nrtilesx =
1030 ((pbox[i].x2 & ~63) -
1031 (pbox[i].x1 & ~63)) >> 4;
1032 nrtilesy =
1033 (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1034 for (j = 0; j <= nrtilesy; j++) {
1035 BEGIN_RING(4);
1036 OUT_RING(CP_PACKET3
1037 (RADEON_3D_CLEAR_ZMASK, 2));
1038 /* first tile */
1039 OUT_RING(tileoffset * 8);
1040 /* the number of tiles to clear */
1041 OUT_RING(nrtilesx + 4);
1042 /* clear mask : chooses the clearing pattern. */
1043 OUT_RING(clearmask);
1044 ADVANCE_RING();
1045 tileoffset += depthpixperline >> 6;
1046 }
1047 } else if (dev_priv->microcode_version == UCODE_R200) {
1048 /* works for rv250. */
1049 /* find first macro tile (8x2 4x4 z-pixels on rv250) */
1050 tileoffset =
1051 ((pbox[i].y1 >> 3) * depthpixperline +
1052 pbox[i].x1) >> 5;
1053 nrtilesx =
1054 (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
1055 nrtilesy =
1056 (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1057 for (j = 0; j <= nrtilesy; j++) {
1058 BEGIN_RING(4);
1059 OUT_RING(CP_PACKET3
1060 (RADEON_3D_CLEAR_ZMASK, 2));
1061 /* first tile */
1062 /* judging by the first tile offset needed, could possibly
1063 directly address/clear 4x4 tiles instead of 8x2 * 4x4
1064 macro tiles, though would still need clear mask for
1065 right/bottom if truely 4x4 granularity is desired ? */
1066 OUT_RING(tileoffset * 16);
1067 /* the number of tiles to clear */
1068 OUT_RING(nrtilesx + 1);
1069 /* clear mask : chooses the clearing pattern. */
1070 OUT_RING(clearmask);
1071 ADVANCE_RING();
1072 tileoffset += depthpixperline >> 5;
1073 }
1074 } else { /* rv 100 */
1075 /* rv100 might not need 64 pix alignment, who knows */
1076 /* offsets are, hmm, weird */
1077 tileoffset =
1078 ((pbox[i].y1 >> 4) * depthpixperline +
1079 pbox[i].x1) >> 6;
1080 nrtilesx =
1081 ((pbox[i].x2 & ~63) -
1082 (pbox[i].x1 & ~63)) >> 4;
1083 nrtilesy =
1084 (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
1085 for (j = 0; j <= nrtilesy; j++) {
1086 BEGIN_RING(4);
1087 OUT_RING(CP_PACKET3
1088 (RADEON_3D_CLEAR_ZMASK, 2));
1089 OUT_RING(tileoffset * 128);
1090 /* the number of tiles to clear */
1091 OUT_RING(nrtilesx + 4);
1092 /* clear mask : chooses the clearing pattern. */
1093 OUT_RING(clearmask);
1094 ADVANCE_RING();
1095 tileoffset += depthpixperline >> 6;
1096 }
1097 }
1098 }
1099
1100 /* TODO don't always clear all hi-level z tiles */
1101 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1102 && (dev_priv->microcode_version == UCODE_R200)
1103 && (flags & RADEON_USE_HIERZ))
1104 /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
1105 /* FIXME : the mask supposedly contains low-res z values. So can't set
1106 just to the max (0xff? or actually 0x3fff?), need to take z clear
1107 value into account? */
1108 {
1109 BEGIN_RING(4);
1110 OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2));
1111 OUT_RING(0x0); /* First tile */
1112 OUT_RING(0x3cc0);
1113 OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
1114 ADVANCE_RING();
1115 }
1116 }
1117
1118 /* We have to clear the depth and/or stencil buffers by
1119 * rendering a quad into just those buffers. Thus, we have to
1120 * make sure the 3D engine is configured correctly.
1121 */
1122 else if ((dev_priv->microcode_version == UCODE_R200) &&
1123 (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1124
1125 int tempPP_CNTL;
1126 int tempRE_CNTL;
1127 int tempRB3D_CNTL;
1128 int tempRB3D_ZSTENCILCNTL;
1129 int tempRB3D_STENCILREFMASK;
1130 int tempRB3D_PLANEMASK;
1131 int tempSE_CNTL;
1132 int tempSE_VTE_CNTL;
1133 int tempSE_VTX_FMT_0;
1134 int tempSE_VTX_FMT_1;
1135 int tempSE_VAP_CNTL;
1136 int tempRE_AUX_SCISSOR_CNTL;
1137
1138 tempPP_CNTL = 0;
1139 tempRE_CNTL = 0;
1140
1141 tempRB3D_CNTL = depth_clear->rb3d_cntl;
1142
1143 tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1144 tempRB3D_STENCILREFMASK = 0x0;
1145
1146 tempSE_CNTL = depth_clear->se_cntl;
1147
1148 /* Disable TCL */
1149
1150 tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
1151 (0x9 <<
1152 SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
1153
1154 tempRB3D_PLANEMASK = 0x0;
1155
1156 tempRE_AUX_SCISSOR_CNTL = 0x0;
1157
1158 tempSE_VTE_CNTL =
1159 SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK;
1160
1161 /* Vertex format (X, Y, Z, W) */
1162 tempSE_VTX_FMT_0 =
1163 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
1164 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
1165 tempSE_VTX_FMT_1 = 0x0;
1166
1167 /*
1168 * Depth buffer specific enables
1169 */
1170 if (flags & RADEON_DEPTH) {
1171 /* Enable depth buffer */
1172 tempRB3D_CNTL |= RADEON_Z_ENABLE;
1173 } else {
1174 /* Disable depth buffer */
1175 tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
1176 }
1177
1178 /*
1179 * Stencil buffer specific enables
1180 */
1181 if (flags & RADEON_STENCIL) {
1182 tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
1183 tempRB3D_STENCILREFMASK = clear->depth_mask;
1184 } else {
1185 tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
1186 tempRB3D_STENCILREFMASK = 0x00000000;
1187 }
1188
1189 if (flags & RADEON_USE_COMP_ZBUF) {
1190 tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1191 RADEON_Z_DECOMPRESSION_ENABLE;
1192 }
1193 if (flags & RADEON_USE_HIERZ) {
1194 tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1195 }
1196
1197 BEGIN_RING(26);
1198 RADEON_WAIT_UNTIL_2D_IDLE();
1199
1200 OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL);
1201 OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL);
1202 OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL);
1203 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1204 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK,
1205 tempRB3D_STENCILREFMASK);
1206 OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK);
1207 OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL);
1208 OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL);
1209 OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0);
1210 OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1);
1211 OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL);
1212 OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL);
1213 ADVANCE_RING();
1214
1215 /* Make sure we restore the 3D state next time.
1216 */
1217 dev_priv->sarea_priv->ctx_owner = 0;
1218
1219 for (i = 0; i < nbox; i++) {
1220
1221 /* Funny that this should be required --
1222 * sets top-left?
1223 */
1224 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1225
1226 BEGIN_RING(14);
1227 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12));
1228 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1229 RADEON_PRIM_WALK_RING |
1230 (3 << RADEON_NUM_VERTICES_SHIFT)));
1231 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1232 OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1233 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1234 OUT_RING(0x3f800000);
1235 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1236 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1237 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1238 OUT_RING(0x3f800000);
1239 OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1240 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1241 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1242 OUT_RING(0x3f800000);
1243 ADVANCE_RING();
1244 }
1245 } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1246
1247 int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1248
1249 rb3d_cntl = depth_clear->rb3d_cntl;
1250
1251 if (flags & RADEON_DEPTH) {
1252 rb3d_cntl |= RADEON_Z_ENABLE;
1253 } else {
1254 rb3d_cntl &= ~RADEON_Z_ENABLE;
1255 }
1256
1257 if (flags & RADEON_STENCIL) {
1258 rb3d_cntl |= RADEON_STENCIL_ENABLE;
1259 rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
1260 } else {
1261 rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
1262 rb3d_stencilrefmask = 0x00000000;
1263 }
1264
1265 if (flags & RADEON_USE_COMP_ZBUF) {
1266 tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1267 RADEON_Z_DECOMPRESSION_ENABLE;
1268 }
1269 if (flags & RADEON_USE_HIERZ) {
1270 tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1271 }
1272
1273 BEGIN_RING(13);
1274 RADEON_WAIT_UNTIL_2D_IDLE();
1275
1276 OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1));
1277 OUT_RING(0x00000000);
1278 OUT_RING(rb3d_cntl);
1279
1280 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1281 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask);
1282 OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000);
1283 OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl);
1284 ADVANCE_RING();
1285
1286 /* Make sure we restore the 3D state next time.
1287 */
1288 dev_priv->sarea_priv->ctx_owner = 0;
1289
1290 for (i = 0; i < nbox; i++) {
1291
1292 /* Funny that this should be required --
1293 * sets top-left?
1294 */
1295 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1296
1297 BEGIN_RING(15);
1298
1299 OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13));
1300 OUT_RING(RADEON_VTX_Z_PRESENT |
1301 RADEON_VTX_PKCOLOR_PRESENT);
1302 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1303 RADEON_PRIM_WALK_RING |
1304 RADEON_MAOS_ENABLE |
1305 RADEON_VTX_FMT_RADEON_MODE |
1306 (3 << RADEON_NUM_VERTICES_SHIFT)));
1307
1308 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1309 OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1310 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1311 OUT_RING(0x0);
1312
1313 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1314 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1315 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1316 OUT_RING(0x0);
1317
1318 OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1319 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1320 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1321 OUT_RING(0x0);
1322
1323 ADVANCE_RING();
1324 }
1325 }
1326
1327 /* Increment the clear counter. The client-side 3D driver must
1328 * wait on this value before performing the clear ioctl. We
1329 * need this because the card's so damned fast...
1330 */
1331 dev_priv->sarea_priv->last_clear++;
1332
1333 BEGIN_RING(4);
1334
1335 RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
1336 RADEON_WAIT_UNTIL_IDLE();
1337
1338 ADVANCE_RING();
1339}
1340
1341static void radeon_cp_dispatch_swap(struct drm_device * dev)
1342{
1343 drm_radeon_private_t *dev_priv = dev->dev_private;
1344 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1345 int nbox = sarea_priv->nbox;
1346 struct drm_clip_rect *pbox = sarea_priv->boxes;
1347 int i;
1348 RING_LOCALS;
1349 DRM_DEBUG("\n");
1350
1351 /* Do some trivial performance monitoring...
1352 */
1353 if (dev_priv->do_boxes)
1354 radeon_cp_performance_boxes(dev_priv);
1355
1356 /* Wait for the 3D stream to idle before dispatching the bitblt.
1357 * This will prevent data corruption between the two streams.
1358 */
1359 BEGIN_RING(2);
1360
1361 RADEON_WAIT_UNTIL_3D_IDLE();
1362
1363 ADVANCE_RING();
1364
1365 for (i = 0; i < nbox; i++) {
1366 int x = pbox[i].x1;
1367 int y = pbox[i].y1;
1368 int w = pbox[i].x2 - x;
1369 int h = pbox[i].y2 - y;
1370
1371 DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
1372
1373 BEGIN_RING(9);
1374
1375 OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0));
1376 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1377 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1378 RADEON_GMC_BRUSH_NONE |
1379 (dev_priv->color_fmt << 8) |
1380 RADEON_GMC_SRC_DATATYPE_COLOR |
1381 RADEON_ROP3_S |
1382 RADEON_DP_SRC_SOURCE_MEMORY |
1383 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1384
1385 /* Make this work even if front & back are flipped:
1386 */
1387 OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
1388 if (dev_priv->sarea_priv->pfCurrentPage == 0) {
1389 OUT_RING(dev_priv->back_pitch_offset);
1390 OUT_RING(dev_priv->front_pitch_offset);
1391 } else {
1392 OUT_RING(dev_priv->front_pitch_offset);
1393 OUT_RING(dev_priv->back_pitch_offset);
1394 }
1395
1396 OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2));
1397 OUT_RING((x << 16) | y);
1398 OUT_RING((x << 16) | y);
1399 OUT_RING((w << 16) | h);
1400
1401 ADVANCE_RING();
1402 }
1403
1404 /* Increment the frame counter. The client-side 3D driver must
1405 * throttle the framerate by waiting for this value before
1406 * performing the swapbuffer ioctl.
1407 */
1408 dev_priv->sarea_priv->last_frame++;
1409
1410 BEGIN_RING(4);
1411
1412 RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
1413 RADEON_WAIT_UNTIL_2D_IDLE();
1414
1415 ADVANCE_RING();
1416}
1417
1418static void radeon_cp_dispatch_flip(struct drm_device * dev)
1419{
1420 drm_radeon_private_t *dev_priv = dev->dev_private;
1421 struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle;
1422 int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
1423 ? dev_priv->front_offset : dev_priv->back_offset;
1424 RING_LOCALS;
1425 DRM_DEBUG("pfCurrentPage=%d\n",
1426 dev_priv->sarea_priv->pfCurrentPage);
1427
1428 /* Do some trivial performance monitoring...
1429 */
1430 if (dev_priv->do_boxes) {
1431 dev_priv->stats.boxes |= RADEON_BOX_FLIP;
1432 radeon_cp_performance_boxes(dev_priv);
1433 }
1434
1435 /* Update the frame offsets for both CRTCs
1436 */
1437 BEGIN_RING(6);
1438
1439 RADEON_WAIT_UNTIL_3D_IDLE();
1440 OUT_RING_REG(RADEON_CRTC_OFFSET,
1441 ((sarea->frame.y * dev_priv->front_pitch +
1442 sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
1443 + offset);
1444 OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
1445 + offset);
1446
1447 ADVANCE_RING();
1448
1449 /* Increment the frame counter. The client-side 3D driver must
1450 * throttle the framerate by waiting for this value before
1451 * performing the swapbuffer ioctl.
1452 */
1453 dev_priv->sarea_priv->last_frame++;
1454 dev_priv->sarea_priv->pfCurrentPage =
1455 1 - dev_priv->sarea_priv->pfCurrentPage;
1456
1457 BEGIN_RING(2);
1458
1459 RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
1460
1461 ADVANCE_RING();
1462}
1463
1464static int bad_prim_vertex_nr(int primitive, int nr)
1465{
1466 switch (primitive & RADEON_PRIM_TYPE_MASK) {
1467 case RADEON_PRIM_TYPE_NONE:
1468 case RADEON_PRIM_TYPE_POINT:
1469 return nr < 1;
1470 case RADEON_PRIM_TYPE_LINE:
1471 return (nr & 1) || nr == 0;
1472 case RADEON_PRIM_TYPE_LINE_STRIP:
1473 return nr < 2;
1474 case RADEON_PRIM_TYPE_TRI_LIST:
1475 case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
1476 case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
1477 case RADEON_PRIM_TYPE_RECT_LIST:
1478 return nr % 3 || nr == 0;
1479 case RADEON_PRIM_TYPE_TRI_FAN:
1480 case RADEON_PRIM_TYPE_TRI_STRIP:
1481 return nr < 3;
1482 default:
1483 return 1;
1484 }
1485}
1486
1487typedef struct {
1488 unsigned int start;
1489 unsigned int finish;
1490 unsigned int prim;
1491 unsigned int numverts;
1492 unsigned int offset;
1493 unsigned int vc_format;
1494} drm_radeon_tcl_prim_t;
1495
1496static void radeon_cp_dispatch_vertex(struct drm_device * dev,
1497 struct drm_buf * buf,
1498 drm_radeon_tcl_prim_t * prim)
1499{
1500 drm_radeon_private_t *dev_priv = dev->dev_private;
1501 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1502 int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
1503 int numverts = (int)prim->numverts;
1504 int nbox = sarea_priv->nbox;
1505 int i = 0;
1506 RING_LOCALS;
1507
1508 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1509 prim->prim,
1510 prim->vc_format, prim->start, prim->finish, prim->numverts);
1511
1512 if (bad_prim_vertex_nr(prim->prim, prim->numverts)) {
1513 DRM_ERROR("bad prim %x numverts %d\n",
1514 prim->prim, prim->numverts);
1515 return;
1516 }
1517
1518 do {
1519 /* Emit the next cliprect */
1520 if (i < nbox) {
1521 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1522 }
1523
1524 /* Emit the vertex buffer rendering commands */
1525 BEGIN_RING(5);
1526
1527 OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3));
1528 OUT_RING(offset);
1529 OUT_RING(numverts);
1530 OUT_RING(prim->vc_format);
1531 OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST |
1532 RADEON_COLOR_ORDER_RGBA |
1533 RADEON_VTX_FMT_RADEON_MODE |
1534 (numverts << RADEON_NUM_VERTICES_SHIFT));
1535
1536 ADVANCE_RING();
1537
1538 i++;
1539 } while (i < nbox);
1540}
1541
1542static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
1543{
1544 drm_radeon_private_t *dev_priv = dev->dev_private;
1545 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1546 RING_LOCALS;
1547
1548 buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
1549
1550 /* Emit the vertex buffer age */
1551 BEGIN_RING(2);
1552 RADEON_DISPATCH_AGE(buf_priv->age);
1553 ADVANCE_RING();
1554
1555 buf->pending = 1;
1556 buf->used = 0;
1557}
1558
1559static void radeon_cp_dispatch_indirect(struct drm_device * dev,
1560 struct drm_buf * buf, int start, int end)
1561{
1562 drm_radeon_private_t *dev_priv = dev->dev_private;
1563 RING_LOCALS;
1564 DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
1565
1566 if (start != end) {
1567 int offset = (dev_priv->gart_buffers_offset
1568 + buf->offset + start);
1569 int dwords = (end - start + 3) / sizeof(u32);
1570
1571 /* Indirect buffer data must be an even number of
1572 * dwords, so if we've been given an odd number we must
1573 * pad the data with a Type-2 CP packet.
1574 */
1575 if (dwords & 1) {
1576 u32 *data = (u32 *)
1577 ((char *)dev->agp_buffer_map->handle
1578 + buf->offset + start);
1579 data[dwords++] = RADEON_CP_PACKET2;
1580 }
1581
1582 /* Fire off the indirect buffer */
1583 BEGIN_RING(3);
1584
1585 OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
1586 OUT_RING(offset);
1587 OUT_RING(dwords);
1588
1589 ADVANCE_RING();
1590 }
1591}
1592
1593static void radeon_cp_dispatch_indices(struct drm_device * dev,
1594 struct drm_buf * elt_buf,
1595 drm_radeon_tcl_prim_t * prim)
1596{
1597 drm_radeon_private_t *dev_priv = dev->dev_private;
1598 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1599 int offset = dev_priv->gart_buffers_offset + prim->offset;
1600 u32 *data;
1601 int dwords;
1602 int i = 0;
1603 int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
1604 int count = (prim->finish - start) / sizeof(u16);
1605 int nbox = sarea_priv->nbox;
1606
1607 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1608 prim->prim,
1609 prim->vc_format,
1610 prim->start, prim->finish, prim->offset, prim->numverts);
1611
1612 if (bad_prim_vertex_nr(prim->prim, count)) {
1613 DRM_ERROR("bad prim %x count %d\n", prim->prim, count);
1614 return;
1615 }
1616
1617 if (start >= prim->finish || (prim->start & 0x7)) {
1618 DRM_ERROR("buffer prim %d\n", prim->prim);
1619 return;
1620 }
1621
1622 dwords = (prim->finish - prim->start + 3) / sizeof(u32);
1623
1624 data = (u32 *) ((char *)dev->agp_buffer_map->handle +
1625 elt_buf->offset + prim->start);
1626
1627 data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
1628 data[1] = offset;
1629 data[2] = prim->numverts;
1630 data[3] = prim->vc_format;
1631 data[4] = (prim->prim |
1632 RADEON_PRIM_WALK_IND |
1633 RADEON_COLOR_ORDER_RGBA |
1634 RADEON_VTX_FMT_RADEON_MODE |
1635 (count << RADEON_NUM_VERTICES_SHIFT));
1636
1637 do {
1638 if (i < nbox)
1639 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1640
1641 radeon_cp_dispatch_indirect(dev, elt_buf,
1642 prim->start, prim->finish);
1643
1644 i++;
1645 } while (i < nbox);
1646
1647}
1648
1649#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1650
1651static int radeon_cp_dispatch_texture(struct drm_device * dev,
1652 struct drm_file *file_priv,
1653 drm_radeon_texture_t * tex,
1654 drm_radeon_tex_image_t * image)
1655{
1656 drm_radeon_private_t *dev_priv = dev->dev_private;
1657 struct drm_buf *buf;
1658 u32 format;
1659 u32 *buffer;
1660 const u8 __user *data;
1661 int size, dwords, tex_width, blit_width, spitch;
1662 u32 height;
1663 int i;
1664 u32 texpitch, microtile;
1665 u32 offset, byte_offset;
1666 RING_LOCALS;
1667
1668 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
1669 DRM_ERROR("Invalid destination offset\n");
1670 return -EINVAL;
1671 }
1672
1673 dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
1674
1675 /* Flush the pixel cache. This ensures no pixel data gets mixed
1676 * up with the texture data from the host data blit, otherwise
1677 * part of the texture image may be corrupted.
1678 */
1679 BEGIN_RING(4);
1680 RADEON_FLUSH_CACHE();
1681 RADEON_WAIT_UNTIL_IDLE();
1682 ADVANCE_RING();
1683
1684 /* The compiler won't optimize away a division by a variable,
1685 * even if the only legal values are powers of two. Thus, we'll
1686 * use a shift instead.
1687 */
1688 switch (tex->format) {
1689 case RADEON_TXFORMAT_ARGB8888:
1690 case RADEON_TXFORMAT_RGBA8888:
1691 format = RADEON_COLOR_FORMAT_ARGB8888;
1692 tex_width = tex->width * 4;
1693 blit_width = image->width * 4;
1694 break;
1695 case RADEON_TXFORMAT_AI88:
1696 case RADEON_TXFORMAT_ARGB1555:
1697 case RADEON_TXFORMAT_RGB565:
1698 case RADEON_TXFORMAT_ARGB4444:
1699 case RADEON_TXFORMAT_VYUY422:
1700 case RADEON_TXFORMAT_YVYU422:
1701 format = RADEON_COLOR_FORMAT_RGB565;
1702 tex_width = tex->width * 2;
1703 blit_width = image->width * 2;
1704 break;
1705 case RADEON_TXFORMAT_I8:
1706 case RADEON_TXFORMAT_RGB332:
1707 format = RADEON_COLOR_FORMAT_CI8;
1708 tex_width = tex->width * 1;
1709 blit_width = image->width * 1;
1710 break;
1711 default:
1712 DRM_ERROR("invalid texture format %d\n", tex->format);
1713 return -EINVAL;
1714 }
1715 spitch = blit_width >> 6;
1716 if (spitch == 0 && image->height > 1)
1717 return -EINVAL;
1718
1719 texpitch = tex->pitch;
1720 if ((texpitch << 22) & RADEON_DST_TILE_MICRO) {
1721 microtile = 1;
1722 if (tex_width < 64) {
1723 texpitch &= ~(RADEON_DST_TILE_MICRO >> 22);
1724 /* we got tiled coordinates, untile them */
1725 image->x *= 2;
1726 }
1727 } else
1728 microtile = 0;
1729
1730 /* this might fail for zero-sized uploads - are those illegal? */
1731 if (!radeon_check_offset(dev_priv, tex->offset + image->height *
1732 blit_width - 1)) {
1733 DRM_ERROR("Invalid final destination offset\n");
1734 return -EINVAL;
1735 }
1736
1737 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
1738
1739 do {
1740 DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1741 tex->offset >> 10, tex->pitch, tex->format,
1742 image->x, image->y, image->width, image->height);
1743
1744 /* Make a copy of some parameters in case we have to
1745 * update them for a multi-pass texture blit.
1746 */
1747 height = image->height;
1748 data = (const u8 __user *)image->data;
1749
1750 size = height * blit_width;
1751
1752 if (size > RADEON_MAX_TEXTURE_SIZE) {
1753 height = RADEON_MAX_TEXTURE_SIZE / blit_width;
1754 size = height * blit_width;
1755 } else if (size < 4 && size > 0) {
1756 size = 4;
1757 } else if (size == 0) {
1758 return 0;
1759 }
1760
1761 buf = radeon_freelist_get(dev);
1762 if (0 && !buf) {
1763 radeon_do_cp_idle(dev_priv);
1764 buf = radeon_freelist_get(dev);
1765 }
1766 if (!buf) {
1767 DRM_DEBUG("EAGAIN\n");
1768 if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
1769 return -EFAULT;
1770 return -EAGAIN;
1771 }
1772
1773 /* Dispatch the indirect buffer.
1774 */
1775 buffer =
1776 (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
1777 dwords = size / 4;
1778
1779#define RADEON_COPY_MT(_buf, _data, _width) \
1780 do { \
1781 if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1782 DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
1783 return -EFAULT; \
1784 } \
1785 } while(0)
1786
1787 if (microtile) {
1788 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
1789 however, we cannot use blitter directly for texture width < 64 bytes,
1790 since minimum tex pitch is 64 bytes and we need this to match
1791 the texture width, otherwise the blitter will tile it wrong.
1792 Thus, tiling manually in this case. Additionally, need to special
1793 case tex height = 1, since our actual image will have height 2
1794 and we need to ensure we don't read beyond the texture size
1795 from user space. */
1796 if (tex->height == 1) {
1797 if (tex_width >= 64 || tex_width <= 16) {
1798 RADEON_COPY_MT(buffer, data,
1799 (int)(tex_width * sizeof(u32)));
1800 } else if (tex_width == 32) {
1801 RADEON_COPY_MT(buffer, data, 16);
1802 RADEON_COPY_MT(buffer + 8,
1803 data + 16, 16);
1804 }
1805 } else if (tex_width >= 64 || tex_width == 16) {
1806 RADEON_COPY_MT(buffer, data,
1807 (int)(dwords * sizeof(u32)));
1808 } else if (tex_width < 16) {
1809 for (i = 0; i < tex->height; i++) {
1810 RADEON_COPY_MT(buffer, data, tex_width);
1811 buffer += 4;
1812 data += tex_width;
1813 }
1814 } else if (tex_width == 32) {
1815 /* TODO: make sure this works when not fitting in one buffer
1816 (i.e. 32bytes x 2048...) */
1817 for (i = 0; i < tex->height; i += 2) {
1818 RADEON_COPY_MT(buffer, data, 16);
1819 data += 16;
1820 RADEON_COPY_MT(buffer + 8, data, 16);
1821 data += 16;
1822 RADEON_COPY_MT(buffer + 4, data, 16);
1823 data += 16;
1824 RADEON_COPY_MT(buffer + 12, data, 16);
1825 data += 16;
1826 buffer += 16;
1827 }
1828 }
1829 } else {
1830 if (tex_width >= 32) {
1831 /* Texture image width is larger than the minimum, so we
1832 * can upload it directly.
1833 */
1834 RADEON_COPY_MT(buffer, data,
1835 (int)(dwords * sizeof(u32)));
1836 } else {
1837 /* Texture image width is less than the minimum, so we
1838 * need to pad out each image scanline to the minimum
1839 * width.
1840 */
1841 for (i = 0; i < tex->height; i++) {
1842 RADEON_COPY_MT(buffer, data, tex_width);
1843 buffer += 8;
1844 data += tex_width;
1845 }
1846 }
1847 }
1848
1849#undef RADEON_COPY_MT
1850 byte_offset = (image->y & ~2047) * blit_width;
1851 buf->file_priv = file_priv;
1852 buf->used = size;
1853 offset = dev_priv->gart_buffers_offset + buf->offset;
1854 BEGIN_RING(9);
1855 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
1856 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1857 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1858 RADEON_GMC_BRUSH_NONE |
1859 (format << 8) |
1860 RADEON_GMC_SRC_DATATYPE_COLOR |
1861 RADEON_ROP3_S |
1862 RADEON_DP_SRC_SOURCE_MEMORY |
1863 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1864 OUT_RING((spitch << 22) | (offset >> 10));
1865 OUT_RING((texpitch << 22) | ((tex->offset >> 10) + (byte_offset >> 10)));
1866 OUT_RING(0);
1867 OUT_RING((image->x << 16) | (image->y % 2048));
1868 OUT_RING((image->width << 16) | height);
1869 RADEON_WAIT_UNTIL_2D_IDLE();
1870 ADVANCE_RING();
1871 COMMIT_RING();
1872
1873 radeon_cp_discard_buffer(dev, buf);
1874
1875 /* Update the input parameters for next time */
1876 image->y += height;
1877 image->height -= height;
1878 image->data = (const u8 __user *)image->data + size;
1879 } while (image->height > 0);
1880
1881 /* Flush the pixel cache after the blit completes. This ensures
1882 * the texture data is written out to memory before rendering
1883 * continues.
1884 */
1885 BEGIN_RING(4);
1886 RADEON_FLUSH_CACHE();
1887 RADEON_WAIT_UNTIL_2D_IDLE();
1888 ADVANCE_RING();
1889 COMMIT_RING();
1890
1891 return 0;
1892}
1893
1894static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple)
1895{
1896 drm_radeon_private_t *dev_priv = dev->dev_private;
1897 int i;
1898 RING_LOCALS;
1899 DRM_DEBUG("\n");
1900
1901 BEGIN_RING(35);
1902
1903 OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0));
1904 OUT_RING(0x00000000);
1905
1906 OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31));
1907 for (i = 0; i < 32; i++) {
1908 OUT_RING(stipple[i]);
1909 }
1910
1911 ADVANCE_RING();
1912}
1913
1914static void radeon_apply_surface_regs(int surf_index,
1915 drm_radeon_private_t *dev_priv)
1916{
1917 if (!dev_priv->mmio)
1918 return;
1919
1920 radeon_do_cp_idle(dev_priv);
1921
1922 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index,
1923 dev_priv->surfaces[surf_index].flags);
1924 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index,
1925 dev_priv->surfaces[surf_index].lower);
1926 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index,
1927 dev_priv->surfaces[surf_index].upper);
1928}
1929
1930/* Allocates a virtual surface
1931 * doesn't always allocate a real surface, will stretch an existing
1932 * surface when possible.
1933 *
1934 * Note that refcount can be at most 2, since during a free refcount=3
1935 * might mean we have to allocate a new surface which might not always
1936 * be available.
1937 * For example : we allocate three contigous surfaces ABC. If B is
1938 * freed, we suddenly need two surfaces to store A and C, which might
1939 * not always be available.
1940 */
1941static int alloc_surface(drm_radeon_surface_alloc_t *new,
1942 drm_radeon_private_t *dev_priv,
1943 struct drm_file *file_priv)
1944{
1945 struct radeon_virt_surface *s;
1946 int i;
1947 int virt_surface_index;
1948 uint32_t new_upper, new_lower;
1949
1950 new_lower = new->address;
1951 new_upper = new_lower + new->size - 1;
1952
1953 /* sanity check */
1954 if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
1955 ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) !=
1956 RADEON_SURF_ADDRESS_FIXED_MASK)
1957 || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
1958 return -1;
1959
1960 /* make sure there is no overlap with existing surfaces */
1961 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1962 if ((dev_priv->surfaces[i].refcount != 0) &&
1963 (((new_lower >= dev_priv->surfaces[i].lower) &&
1964 (new_lower < dev_priv->surfaces[i].upper)) ||
1965 ((new_lower < dev_priv->surfaces[i].lower) &&
1966 (new_upper > dev_priv->surfaces[i].lower)))) {
1967 return -1;
1968 }
1969 }
1970
1971 /* find a virtual surface */
1972 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
1973 if (dev_priv->virt_surfaces[i].file_priv == 0)
1974 break;
1975 if (i == 2 * RADEON_MAX_SURFACES) {
1976 return -1;
1977 }
1978 virt_surface_index = i;
1979
1980 /* try to reuse an existing surface */
1981 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1982 /* extend before */
1983 if ((dev_priv->surfaces[i].refcount == 1) &&
1984 (new->flags == dev_priv->surfaces[i].flags) &&
1985 (new_upper + 1 == dev_priv->surfaces[i].lower)) {
1986 s = &(dev_priv->virt_surfaces[virt_surface_index]);
1987 s->surface_index = i;
1988 s->lower = new_lower;
1989 s->upper = new_upper;
1990 s->flags = new->flags;
1991 s->file_priv = file_priv;
1992 dev_priv->surfaces[i].refcount++;
1993 dev_priv->surfaces[i].lower = s->lower;
1994 radeon_apply_surface_regs(s->surface_index, dev_priv);
1995 return virt_surface_index;
1996 }
1997
1998 /* extend after */
1999 if ((dev_priv->surfaces[i].refcount == 1) &&
2000 (new->flags == dev_priv->surfaces[i].flags) &&
2001 (new_lower == dev_priv->surfaces[i].upper + 1)) {
2002 s = &(dev_priv->virt_surfaces[virt_surface_index]);
2003 s->surface_index = i;
2004 s->lower = new_lower;
2005 s->upper = new_upper;
2006 s->flags = new->flags;
2007 s->file_priv = file_priv;
2008 dev_priv->surfaces[i].refcount++;
2009 dev_priv->surfaces[i].upper = s->upper;
2010 radeon_apply_surface_regs(s->surface_index, dev_priv);
2011 return virt_surface_index;
2012 }
2013 }
2014
2015 /* okay, we need a new one */
2016 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2017 if (dev_priv->surfaces[i].refcount == 0) {
2018 s = &(dev_priv->virt_surfaces[virt_surface_index]);
2019 s->surface_index = i;
2020 s->lower = new_lower;
2021 s->upper = new_upper;
2022 s->flags = new->flags;
2023 s->file_priv = file_priv;
2024 dev_priv->surfaces[i].refcount = 1;
2025 dev_priv->surfaces[i].lower = s->lower;
2026 dev_priv->surfaces[i].upper = s->upper;
2027 dev_priv->surfaces[i].flags = s->flags;
2028 radeon_apply_surface_regs(s->surface_index, dev_priv);
2029 return virt_surface_index;
2030 }
2031 }
2032
2033 /* we didn't find anything */
2034 return -1;
2035}
2036
2037static int free_surface(struct drm_file *file_priv,
2038 drm_radeon_private_t * dev_priv,
2039 int lower)
2040{
2041 struct radeon_virt_surface *s;
2042 int i;
2043 /* find the virtual surface */
2044 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2045 s = &(dev_priv->virt_surfaces[i]);
2046 if (s->file_priv) {
2047 if ((lower == s->lower) && (file_priv == s->file_priv))
2048 {
2049 if (dev_priv->surfaces[s->surface_index].
2050 lower == s->lower)
2051 dev_priv->surfaces[s->surface_index].
2052 lower = s->upper;
2053
2054 if (dev_priv->surfaces[s->surface_index].
2055 upper == s->upper)
2056 dev_priv->surfaces[s->surface_index].
2057 upper = s->lower;
2058
2059 dev_priv->surfaces[s->surface_index].refcount--;
2060 if (dev_priv->surfaces[s->surface_index].
2061 refcount == 0)
2062 dev_priv->surfaces[s->surface_index].
2063 flags = 0;
2064 s->file_priv = NULL;
2065 radeon_apply_surface_regs(s->surface_index,
2066 dev_priv);
2067 return 0;
2068 }
2069 }
2070 }
2071 return 1;
2072}
2073
2074static void radeon_surfaces_release(struct drm_file *file_priv,
2075 drm_radeon_private_t * dev_priv)
2076{
2077 int i;
2078 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2079 if (dev_priv->virt_surfaces[i].file_priv == file_priv)
2080 free_surface(file_priv, dev_priv,
2081 dev_priv->virt_surfaces[i].lower);
2082 }
2083}
2084
2085/* ================================================================
2086 * IOCTL functions
2087 */
2088static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
2089{
2090 drm_radeon_private_t *dev_priv = dev->dev_private;
2091 drm_radeon_surface_alloc_t *alloc = data;
2092
2093 if (alloc_surface(alloc, dev_priv, file_priv) == -1)
2094 return -EINVAL;
2095 else
2096 return 0;
2097}
2098
2099static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
2100{
2101 drm_radeon_private_t *dev_priv = dev->dev_private;
2102 drm_radeon_surface_free_t *memfree = data;
2103
2104 if (free_surface(file_priv, dev_priv, memfree->address))
2105 return -EINVAL;
2106 else
2107 return 0;
2108}
2109
2110static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
2111{
2112 drm_radeon_private_t *dev_priv = dev->dev_private;
2113 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2114 drm_radeon_clear_t *clear = data;
2115 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
2116 DRM_DEBUG("\n");
2117
2118 LOCK_TEST_WITH_RETURN(dev, file_priv);
2119
2120 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2121
2122 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2123 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2124
2125 if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
2126 sarea_priv->nbox * sizeof(depth_boxes[0])))
2127 return -EFAULT;
2128
2129 radeon_cp_dispatch_clear(dev, clear, depth_boxes);
2130
2131 COMMIT_RING();
2132 return 0;
2133}
2134
2135/* Not sure why this isn't set all the time:
2136 */
2137static int radeon_do_init_pageflip(struct drm_device * dev)
2138{
2139 drm_radeon_private_t *dev_priv = dev->dev_private;
2140 RING_LOCALS;
2141
2142 DRM_DEBUG("\n");
2143
2144 BEGIN_RING(6);
2145 RADEON_WAIT_UNTIL_3D_IDLE();
2146 OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0));
2147 OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) |
2148 RADEON_CRTC_OFFSET_FLIP_CNTL);
2149 OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0));
2150 OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) |
2151 RADEON_CRTC_OFFSET_FLIP_CNTL);
2152 ADVANCE_RING();
2153
2154 dev_priv->page_flipping = 1;
2155
2156 if (dev_priv->sarea_priv->pfCurrentPage != 1)
2157 dev_priv->sarea_priv->pfCurrentPage = 0;
2158
2159 return 0;
2160}
2161
2162/* Swapping and flipping are different operations, need different ioctls.
2163 * They can & should be intermixed to support multiple 3d windows.
2164 */
2165static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
2166{
2167 drm_radeon_private_t *dev_priv = dev->dev_private;
2168 DRM_DEBUG("\n");
2169
2170 LOCK_TEST_WITH_RETURN(dev, file_priv);
2171
2172 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2173
2174 if (!dev_priv->page_flipping)
2175 radeon_do_init_pageflip(dev);
2176
2177 radeon_cp_dispatch_flip(dev);
2178
2179 COMMIT_RING();
2180 return 0;
2181}
2182
2183static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
2184{
2185 drm_radeon_private_t *dev_priv = dev->dev_private;
2186 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2187 DRM_DEBUG("\n");
2188
2189 LOCK_TEST_WITH_RETURN(dev, file_priv);
2190
2191 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2192
2193 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2194 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2195
2196 radeon_cp_dispatch_swap(dev);
2197 dev_priv->sarea_priv->ctx_owner = 0;
2198
2199 COMMIT_RING();
2200 return 0;
2201}
2202
2203static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
2204{
2205 drm_radeon_private_t *dev_priv = dev->dev_private;
2206 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2207 struct drm_device_dma *dma = dev->dma;
2208 struct drm_buf *buf;
2209 drm_radeon_vertex_t *vertex = data;
2210 drm_radeon_tcl_prim_t prim;
2211
2212 LOCK_TEST_WITH_RETURN(dev, file_priv);
2213
2214 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2215 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
2216
2217 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2218 DRM_ERROR("buffer index %d (of %d max)\n",
2219 vertex->idx, dma->buf_count - 1);
2220 return -EINVAL;
2221 }
2222 if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2223 DRM_ERROR("buffer prim %d\n", vertex->prim);
2224 return -EINVAL;
2225 }
2226
2227 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2228 VB_AGE_TEST_WITH_RETURN(dev_priv);
2229
2230 buf = dma->buflist[vertex->idx];
2231
2232 if (buf->file_priv != file_priv) {
2233 DRM_ERROR("process %d using buffer owned by %p\n",
2234 DRM_CURRENTPID, buf->file_priv);
2235 return -EINVAL;
2236 }
2237 if (buf->pending) {
2238 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2239 return -EINVAL;
2240 }
2241
2242 /* Build up a prim_t record:
2243 */
2244 if (vertex->count) {
2245 buf->used = vertex->count; /* not used? */
2246
2247 if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2248 if (radeon_emit_state(dev_priv, file_priv,
2249 &sarea_priv->context_state,
2250 sarea_priv->tex_state,
2251 sarea_priv->dirty)) {
2252 DRM_ERROR("radeon_emit_state failed\n");
2253 return -EINVAL;
2254 }
2255
2256 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2257 RADEON_UPLOAD_TEX1IMAGES |
2258 RADEON_UPLOAD_TEX2IMAGES |
2259 RADEON_REQUIRE_QUIESCENCE);
2260 }
2261
2262 prim.start = 0;
2263 prim.finish = vertex->count; /* unused */
2264 prim.prim = vertex->prim;
2265 prim.numverts = vertex->count;
2266 prim.vc_format = dev_priv->sarea_priv->vc_format;
2267
2268 radeon_cp_dispatch_vertex(dev, buf, &prim);
2269 }
2270
2271 if (vertex->discard) {
2272 radeon_cp_discard_buffer(dev, buf);
2273 }
2274
2275 COMMIT_RING();
2276 return 0;
2277}
2278
2279static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
2280{
2281 drm_radeon_private_t *dev_priv = dev->dev_private;
2282 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2283 struct drm_device_dma *dma = dev->dma;
2284 struct drm_buf *buf;
2285 drm_radeon_indices_t *elts = data;
2286 drm_radeon_tcl_prim_t prim;
2287 int count;
2288
2289 LOCK_TEST_WITH_RETURN(dev, file_priv);
2290
2291 DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2292 DRM_CURRENTPID, elts->idx, elts->start, elts->end,
2293 elts->discard);
2294
2295 if (elts->idx < 0 || elts->idx >= dma->buf_count) {
2296 DRM_ERROR("buffer index %d (of %d max)\n",
2297 elts->idx, dma->buf_count - 1);
2298 return -EINVAL;
2299 }
2300 if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2301 DRM_ERROR("buffer prim %d\n", elts->prim);
2302 return -EINVAL;
2303 }
2304
2305 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2306 VB_AGE_TEST_WITH_RETURN(dev_priv);
2307
2308 buf = dma->buflist[elts->idx];
2309
2310 if (buf->file_priv != file_priv) {
2311 DRM_ERROR("process %d using buffer owned by %p\n",
2312 DRM_CURRENTPID, buf->file_priv);
2313 return -EINVAL;
2314 }
2315 if (buf->pending) {
2316 DRM_ERROR("sending pending buffer %d\n", elts->idx);
2317 return -EINVAL;
2318 }
2319
2320 count = (elts->end - elts->start) / sizeof(u16);
2321 elts->start -= RADEON_INDEX_PRIM_OFFSET;
2322
2323 if (elts->start & 0x7) {
2324 DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
2325 return -EINVAL;
2326 }
2327 if (elts->start < buf->used) {
2328 DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
2329 return -EINVAL;
2330 }
2331
2332 buf->used = elts->end;
2333
2334 if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2335 if (radeon_emit_state(dev_priv, file_priv,
2336 &sarea_priv->context_state,
2337 sarea_priv->tex_state,
2338 sarea_priv->dirty)) {
2339 DRM_ERROR("radeon_emit_state failed\n");
2340 return -EINVAL;
2341 }
2342
2343 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2344 RADEON_UPLOAD_TEX1IMAGES |
2345 RADEON_UPLOAD_TEX2IMAGES |
2346 RADEON_REQUIRE_QUIESCENCE);
2347 }
2348
2349 /* Build up a prim_t record:
2350 */
2351 prim.start = elts->start;
2352 prim.finish = elts->end;
2353 prim.prim = elts->prim;
2354 prim.offset = 0; /* offset from start of dma buffers */
2355 prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
2356 prim.vc_format = dev_priv->sarea_priv->vc_format;
2357
2358 radeon_cp_dispatch_indices(dev, buf, &prim);
2359 if (elts->discard) {
2360 radeon_cp_discard_buffer(dev, buf);
2361 }
2362
2363 COMMIT_RING();
2364 return 0;
2365}
2366
2367static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv)
2368{
2369 drm_radeon_private_t *dev_priv = dev->dev_private;
2370 drm_radeon_texture_t *tex = data;
2371 drm_radeon_tex_image_t image;
2372 int ret;
2373
2374 LOCK_TEST_WITH_RETURN(dev, file_priv);
2375
2376 if (tex->image == NULL) {
2377 DRM_ERROR("null texture image!\n");
2378 return -EINVAL;
2379 }
2380
2381 if (DRM_COPY_FROM_USER(&image,
2382 (drm_radeon_tex_image_t __user *) tex->image,
2383 sizeof(image)))
2384 return -EFAULT;
2385
2386 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2387 VB_AGE_TEST_WITH_RETURN(dev_priv);
2388
2389 ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
2390
2391 return ret;
2392}
2393
2394static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
2395{
2396 drm_radeon_private_t *dev_priv = dev->dev_private;
2397 drm_radeon_stipple_t *stipple = data;
2398 u32 mask[32];
2399
2400 LOCK_TEST_WITH_RETURN(dev, file_priv);
2401
2402 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
2403 return -EFAULT;
2404
2405 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2406
2407 radeon_cp_dispatch_stipple(dev, mask);
2408
2409 COMMIT_RING();
2410 return 0;
2411}
2412
2413static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
2414{
2415 drm_radeon_private_t *dev_priv = dev->dev_private;
2416 struct drm_device_dma *dma = dev->dma;
2417 struct drm_buf *buf;
2418 drm_radeon_indirect_t *indirect = data;
2419 RING_LOCALS;
2420
2421 LOCK_TEST_WITH_RETURN(dev, file_priv);
2422
2423 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
2424 indirect->idx, indirect->start, indirect->end,
2425 indirect->discard);
2426
2427 if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
2428 DRM_ERROR("buffer index %d (of %d max)\n",
2429 indirect->idx, dma->buf_count - 1);
2430 return -EINVAL;
2431 }
2432
2433 buf = dma->buflist[indirect->idx];
2434
2435 if (buf->file_priv != file_priv) {
2436 DRM_ERROR("process %d using buffer owned by %p\n",
2437 DRM_CURRENTPID, buf->file_priv);
2438 return -EINVAL;
2439 }
2440 if (buf->pending) {
2441 DRM_ERROR("sending pending buffer %d\n", indirect->idx);
2442 return -EINVAL;
2443 }
2444
2445 if (indirect->start < buf->used) {
2446 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2447 indirect->start, buf->used);
2448 return -EINVAL;
2449 }
2450
2451 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2452 VB_AGE_TEST_WITH_RETURN(dev_priv);
2453
2454 buf->used = indirect->end;
2455
2456 /* Wait for the 3D stream to idle before the indirect buffer
2457 * containing 2D acceleration commands is processed.
2458 */
2459 BEGIN_RING(2);
2460
2461 RADEON_WAIT_UNTIL_3D_IDLE();
2462
2463 ADVANCE_RING();
2464
2465 /* Dispatch the indirect buffer full of commands from the
2466 * X server. This is insecure and is thus only available to
2467 * privileged clients.
2468 */
2469 radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2470 if (indirect->discard) {
2471 radeon_cp_discard_buffer(dev, buf);
2472 }
2473
2474 COMMIT_RING();
2475 return 0;
2476}
2477
2478static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
2479{
2480 drm_radeon_private_t *dev_priv = dev->dev_private;
2481 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2482 struct drm_device_dma *dma = dev->dma;
2483 struct drm_buf *buf;
2484 drm_radeon_vertex2_t *vertex = data;
2485 int i;
2486 unsigned char laststate;
2487
2488 LOCK_TEST_WITH_RETURN(dev, file_priv);
2489
2490 DRM_DEBUG("pid=%d index=%d discard=%d\n",
2491 DRM_CURRENTPID, vertex->idx, vertex->discard);
2492
2493 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2494 DRM_ERROR("buffer index %d (of %d max)\n",
2495 vertex->idx, dma->buf_count - 1);
2496 return -EINVAL;
2497 }
2498
2499 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2500 VB_AGE_TEST_WITH_RETURN(dev_priv);
2501
2502 buf = dma->buflist[vertex->idx];
2503
2504 if (buf->file_priv != file_priv) {
2505 DRM_ERROR("process %d using buffer owned by %p\n",
2506 DRM_CURRENTPID, buf->file_priv);
2507 return -EINVAL;
2508 }
2509
2510 if (buf->pending) {
2511 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2512 return -EINVAL;
2513 }
2514
2515 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2516 return -EINVAL;
2517
2518 for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) {
2519 drm_radeon_prim_t prim;
2520 drm_radeon_tcl_prim_t tclprim;
2521
2522 if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim)))
2523 return -EFAULT;
2524
2525 if (prim.stateidx != laststate) {
2526 drm_radeon_state_t state;
2527
2528 if (DRM_COPY_FROM_USER(&state,
2529 &vertex->state[prim.stateidx],
2530 sizeof(state)))
2531 return -EFAULT;
2532
2533 if (radeon_emit_state2(dev_priv, file_priv, &state)) {
2534 DRM_ERROR("radeon_emit_state2 failed\n");
2535 return -EINVAL;
2536 }
2537
2538 laststate = prim.stateidx;
2539 }
2540
2541 tclprim.start = prim.start;
2542 tclprim.finish = prim.finish;
2543 tclprim.prim = prim.prim;
2544 tclprim.vc_format = prim.vc_format;
2545
2546 if (prim.prim & RADEON_PRIM_WALK_IND) {
2547 tclprim.offset = prim.numverts * 64;
2548 tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
2549
2550 radeon_cp_dispatch_indices(dev, buf, &tclprim);
2551 } else {
2552 tclprim.numverts = prim.numverts;
2553 tclprim.offset = 0; /* not used */
2554
2555 radeon_cp_dispatch_vertex(dev, buf, &tclprim);
2556 }
2557
2558 if (sarea_priv->nbox == 1)
2559 sarea_priv->nbox = 0;
2560 }
2561
2562 if (vertex->discard) {
2563 radeon_cp_discard_buffer(dev, buf);
2564 }
2565
2566 COMMIT_RING();
2567 return 0;
2568}
2569
2570static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
2571 struct drm_file *file_priv,
2572 drm_radeon_cmd_header_t header,
2573 drm_radeon_kcmd_buffer_t *cmdbuf)
2574{
2575 int id = (int)header.packet.packet_id;
2576 int sz, reg;
2577 int *data = (int *)cmdbuf->buf;
2578 RING_LOCALS;
2579
2580 if (id >= RADEON_MAX_STATE_PACKETS)
2581 return -EINVAL;
2582
2583 sz = packet[id].len;
2584 reg = packet[id].start;
2585
2586 if (sz * sizeof(int) > cmdbuf->bufsz) {
2587 DRM_ERROR("Packet size provided larger than data provided\n");
2588 return -EINVAL;
2589 }
2590
2591 if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, data)) {
2592 DRM_ERROR("Packet verification failed\n");
2593 return -EINVAL;
2594 }
2595
2596 BEGIN_RING(sz + 1);
2597 OUT_RING(CP_PACKET0(reg, (sz - 1)));
2598 OUT_RING_TABLE(data, sz);
2599 ADVANCE_RING();
2600
2601 cmdbuf->buf += sz * sizeof(int);
2602 cmdbuf->bufsz -= sz * sizeof(int);
2603 return 0;
2604}
2605
2606static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
2607 drm_radeon_cmd_header_t header,
2608 drm_radeon_kcmd_buffer_t *cmdbuf)
2609{
2610 int sz = header.scalars.count;
2611 int start = header.scalars.offset;
2612 int stride = header.scalars.stride;
2613 RING_LOCALS;
2614
2615 BEGIN_RING(3 + sz);
2616 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2617 OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2618 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2619 OUT_RING_TABLE(cmdbuf->buf, sz);
2620 ADVANCE_RING();
2621 cmdbuf->buf += sz * sizeof(int);
2622 cmdbuf->bufsz -= sz * sizeof(int);
2623 return 0;
2624}
2625
2626/* God this is ugly
2627 */
2628static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
2629 drm_radeon_cmd_header_t header,
2630 drm_radeon_kcmd_buffer_t *cmdbuf)
2631{
2632 int sz = header.scalars.count;
2633 int start = ((unsigned int)header.scalars.offset) + 0x100;
2634 int stride = header.scalars.stride;
2635 RING_LOCALS;
2636
2637 BEGIN_RING(3 + sz);
2638 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2639 OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2640 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2641 OUT_RING_TABLE(cmdbuf->buf, sz);
2642 ADVANCE_RING();
2643 cmdbuf->buf += sz * sizeof(int);
2644 cmdbuf->bufsz -= sz * sizeof(int);
2645 return 0;
2646}
2647
2648static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2649 drm_radeon_cmd_header_t header,
2650 drm_radeon_kcmd_buffer_t *cmdbuf)
2651{
2652 int sz = header.vectors.count;
2653 int start = header.vectors.offset;
2654 int stride = header.vectors.stride;
2655 RING_LOCALS;
2656
2657 BEGIN_RING(5 + sz);
2658 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2659 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2660 OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2661 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2662 OUT_RING_TABLE(cmdbuf->buf, sz);
2663 ADVANCE_RING();
2664
2665 cmdbuf->buf += sz * sizeof(int);
2666 cmdbuf->bufsz -= sz * sizeof(int);
2667 return 0;
2668}
2669
2670static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv,
2671 drm_radeon_cmd_header_t header,
2672 drm_radeon_kcmd_buffer_t *cmdbuf)
2673{
2674 int sz = header.veclinear.count * 4;
2675 int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8);
2676 RING_LOCALS;
2677
2678 if (!sz)
2679 return 0;
2680 if (sz * 4 > cmdbuf->bufsz)
2681 return -EINVAL;
2682
2683 BEGIN_RING(5 + sz);
2684 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2685 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2686 OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2687 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2688 OUT_RING_TABLE(cmdbuf->buf, sz);
2689 ADVANCE_RING();
2690
2691 cmdbuf->buf += sz * sizeof(int);
2692 cmdbuf->bufsz -= sz * sizeof(int);
2693 return 0;
2694}
2695
2696static int radeon_emit_packet3(struct drm_device * dev,
2697 struct drm_file *file_priv,
2698 drm_radeon_kcmd_buffer_t *cmdbuf)
2699{
2700 drm_radeon_private_t *dev_priv = dev->dev_private;
2701 unsigned int cmdsz;
2702 int ret;
2703 RING_LOCALS;
2704
2705 DRM_DEBUG("\n");
2706
2707 if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2708 cmdbuf, &cmdsz))) {
2709 DRM_ERROR("Packet verification failed\n");
2710 return ret;
2711 }
2712
2713 BEGIN_RING(cmdsz);
2714 OUT_RING_TABLE(cmdbuf->buf, cmdsz);
2715 ADVANCE_RING();
2716
2717 cmdbuf->buf += cmdsz * 4;
2718 cmdbuf->bufsz -= cmdsz * 4;
2719 return 0;
2720}
2721
2722static int radeon_emit_packet3_cliprect(struct drm_device *dev,
2723 struct drm_file *file_priv,
2724 drm_radeon_kcmd_buffer_t *cmdbuf,
2725 int orig_nbox)
2726{
2727 drm_radeon_private_t *dev_priv = dev->dev_private;
2728 struct drm_clip_rect box;
2729 unsigned int cmdsz;
2730 int ret;
2731 struct drm_clip_rect __user *boxes = cmdbuf->boxes;
2732 int i = 0;
2733 RING_LOCALS;
2734
2735 DRM_DEBUG("\n");
2736
2737 if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2738 cmdbuf, &cmdsz))) {
2739 DRM_ERROR("Packet verification failed\n");
2740 return ret;
2741 }
2742
2743 if (!orig_nbox)
2744 goto out;
2745
2746 do {
2747 if (i < cmdbuf->nbox) {
2748 if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box)))
2749 return -EFAULT;
2750 /* FIXME The second and subsequent times round
2751 * this loop, send a WAIT_UNTIL_3D_IDLE before
2752 * calling emit_clip_rect(). This fixes a
2753 * lockup on fast machines when sending
2754 * several cliprects with a cmdbuf, as when
2755 * waving a 2D window over a 3D
2756 * window. Something in the commands from user
2757 * space seems to hang the card when they're
2758 * sent several times in a row. That would be
2759 * the correct place to fix it but this works
2760 * around it until I can figure that out - Tim
2761 * Smith */
2762 if (i) {
2763 BEGIN_RING(2);
2764 RADEON_WAIT_UNTIL_3D_IDLE();
2765 ADVANCE_RING();
2766 }
2767 radeon_emit_clip_rect(dev_priv, &box);
2768 }
2769
2770 BEGIN_RING(cmdsz);
2771 OUT_RING_TABLE(cmdbuf->buf, cmdsz);
2772 ADVANCE_RING();
2773
2774 } while (++i < cmdbuf->nbox);
2775 if (cmdbuf->nbox == 1)
2776 cmdbuf->nbox = 0;
2777
2778 out:
2779 cmdbuf->buf += cmdsz * 4;
2780 cmdbuf->bufsz -= cmdsz * 4;
2781 return 0;
2782}
2783
2784static int radeon_emit_wait(struct drm_device * dev, int flags)
2785{
2786 drm_radeon_private_t *dev_priv = dev->dev_private;
2787 RING_LOCALS;
2788
2789 DRM_DEBUG("%x\n", flags);
2790 switch (flags) {
2791 case RADEON_WAIT_2D:
2792 BEGIN_RING(2);
2793 RADEON_WAIT_UNTIL_2D_IDLE();
2794 ADVANCE_RING();
2795 break;
2796 case RADEON_WAIT_3D:
2797 BEGIN_RING(2);
2798 RADEON_WAIT_UNTIL_3D_IDLE();
2799 ADVANCE_RING();
2800 break;
2801 case RADEON_WAIT_2D | RADEON_WAIT_3D:
2802 BEGIN_RING(2);
2803 RADEON_WAIT_UNTIL_IDLE();
2804 ADVANCE_RING();
2805 break;
2806 default:
2807 return -EINVAL;
2808 }
2809
2810 return 0;
2811}
2812
2813static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv)
2814{
2815 drm_radeon_private_t *dev_priv = dev->dev_private;
2816 struct drm_device_dma *dma = dev->dma;
2817 struct drm_buf *buf = NULL;
2818 int idx;
2819 drm_radeon_kcmd_buffer_t *cmdbuf = data;
2820 drm_radeon_cmd_header_t header;
2821 int orig_nbox, orig_bufsz;
2822 char *kbuf = NULL;
2823
2824 LOCK_TEST_WITH_RETURN(dev, file_priv);
2825
2826 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2827 VB_AGE_TEST_WITH_RETURN(dev_priv);
2828
2829 if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) {
2830 return -EINVAL;
2831 }
2832
2833 /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid
2834 * races between checking values and using those values in other code,
2835 * and simply to avoid a lot of function calls to copy in data.
2836 */
2837 orig_bufsz = cmdbuf->bufsz;
2838 if (orig_bufsz != 0) {
2839 kbuf = drm_alloc(cmdbuf->bufsz, DRM_MEM_DRIVER);
2840 if (kbuf == NULL)
2841 return -ENOMEM;
2842 if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf,
2843 cmdbuf->bufsz)) {
2844 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2845 return -EFAULT;
2846 }
2847 cmdbuf->buf = kbuf;
2848 }
2849
2850 orig_nbox = cmdbuf->nbox;
2851
2852 if (dev_priv->microcode_version == UCODE_R300) {
2853 int temp;
2854 temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
2855
2856 if (orig_bufsz != 0)
2857 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2858
2859 return temp;
2860 }
2861
2862 /* microcode_version != r300 */
2863 while (cmdbuf->bufsz >= sizeof(header)) {
2864
2865 header.i = *(int *)cmdbuf->buf;
2866 cmdbuf->buf += sizeof(header);
2867 cmdbuf->bufsz -= sizeof(header);
2868
2869 switch (header.header.cmd_type) {
2870 case RADEON_CMD_PACKET:
2871 DRM_DEBUG("RADEON_CMD_PACKET\n");
2872 if (radeon_emit_packets
2873 (dev_priv, file_priv, header, cmdbuf)) {
2874 DRM_ERROR("radeon_emit_packets failed\n");
2875 goto err;
2876 }
2877 break;
2878
2879 case RADEON_CMD_SCALARS:
2880 DRM_DEBUG("RADEON_CMD_SCALARS\n");
2881 if (radeon_emit_scalars(dev_priv, header, cmdbuf)) {
2882 DRM_ERROR("radeon_emit_scalars failed\n");
2883 goto err;
2884 }
2885 break;
2886
2887 case RADEON_CMD_VECTORS:
2888 DRM_DEBUG("RADEON_CMD_VECTORS\n");
2889 if (radeon_emit_vectors(dev_priv, header, cmdbuf)) {
2890 DRM_ERROR("radeon_emit_vectors failed\n");
2891 goto err;
2892 }
2893 break;
2894
2895 case RADEON_CMD_DMA_DISCARD:
2896 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2897 idx = header.dma.buf_idx;
2898 if (idx < 0 || idx >= dma->buf_count) {
2899 DRM_ERROR("buffer index %d (of %d max)\n",
2900 idx, dma->buf_count - 1);
2901 goto err;
2902 }
2903
2904 buf = dma->buflist[idx];
2905 if (buf->file_priv != file_priv || buf->pending) {
2906 DRM_ERROR("bad buffer %p %p %d\n",
2907 buf->file_priv, file_priv,
2908 buf->pending);
2909 goto err;
2910 }
2911
2912 radeon_cp_discard_buffer(dev, buf);
2913 break;
2914
2915 case RADEON_CMD_PACKET3:
2916 DRM_DEBUG("RADEON_CMD_PACKET3\n");
2917 if (radeon_emit_packet3(dev, file_priv, cmdbuf)) {
2918 DRM_ERROR("radeon_emit_packet3 failed\n");
2919 goto err;
2920 }
2921 break;
2922
2923 case RADEON_CMD_PACKET3_CLIP:
2924 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2925 if (radeon_emit_packet3_cliprect
2926 (dev, file_priv, cmdbuf, orig_nbox)) {
2927 DRM_ERROR("radeon_emit_packet3_clip failed\n");
2928 goto err;
2929 }
2930 break;
2931
2932 case RADEON_CMD_SCALARS2:
2933 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2934 if (radeon_emit_scalars2(dev_priv, header, cmdbuf)) {
2935 DRM_ERROR("radeon_emit_scalars2 failed\n");
2936 goto err;
2937 }
2938 break;
2939
2940 case RADEON_CMD_WAIT:
2941 DRM_DEBUG("RADEON_CMD_WAIT\n");
2942 if (radeon_emit_wait(dev, header.wait.flags)) {
2943 DRM_ERROR("radeon_emit_wait failed\n");
2944 goto err;
2945 }
2946 break;
2947 case RADEON_CMD_VECLINEAR:
2948 DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
2949 if (radeon_emit_veclinear(dev_priv, header, cmdbuf)) {
2950 DRM_ERROR("radeon_emit_veclinear failed\n");
2951 goto err;
2952 }
2953 break;
2954
2955 default:
2956 DRM_ERROR("bad cmd_type %d at %p\n",
2957 header.header.cmd_type,
2958 cmdbuf->buf - sizeof(header));
2959 goto err;
2960 }
2961 }
2962
2963 if (orig_bufsz != 0)
2964 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2965
2966 DRM_DEBUG("DONE\n");
2967 COMMIT_RING();
2968 return 0;
2969
2970 err:
2971 if (orig_bufsz != 0)
2972 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2973 return -EINVAL;
2974}
2975
2976static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
2977{
2978 drm_radeon_private_t *dev_priv = dev->dev_private;
2979 drm_radeon_getparam_t *param = data;
2980 int value;
2981
2982 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
2983
2984 switch (param->param) {
2985 case RADEON_PARAM_GART_BUFFER_OFFSET:
2986 value = dev_priv->gart_buffers_offset;
2987 break;
2988 case RADEON_PARAM_LAST_FRAME:
2989 dev_priv->stats.last_frame_reads++;
2990 value = GET_SCRATCH(0);
2991 break;
2992 case RADEON_PARAM_LAST_DISPATCH:
2993 value = GET_SCRATCH(1);
2994 break;
2995 case RADEON_PARAM_LAST_CLEAR:
2996 dev_priv->stats.last_clear_reads++;
2997 value = GET_SCRATCH(2);
2998 break;
2999 case RADEON_PARAM_IRQ_NR:
3000 value = dev->irq;
3001 break;
3002 case RADEON_PARAM_GART_BASE:
3003 value = dev_priv->gart_vm_start;
3004 break;
3005 case RADEON_PARAM_REGISTER_HANDLE:
3006 value = dev_priv->mmio->offset;
3007 break;
3008 case RADEON_PARAM_STATUS_HANDLE:
3009 value = dev_priv->ring_rptr_offset;
3010 break;
3011#if BITS_PER_LONG == 32
3012 /*
3013 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
3014 * pointer which can't fit into an int-sized variable. According to
3015 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
3016 * not supporting it shouldn't be a problem. If the same functionality
3017 * is needed on 64-bit platforms, a new ioctl() would have to be added,
3018 * so backwards-compatibility for the embedded platforms can be
3019 * maintained. --davidm 4-Feb-2004.
3020 */
3021 case RADEON_PARAM_SAREA_HANDLE:
3022 /* The lock is the first dword in the sarea. */
3023 value = (long)dev->lock.hw_lock;
3024 break;
3025#endif
3026 case RADEON_PARAM_GART_TEX_HANDLE:
3027 value = dev_priv->gart_textures_offset;
3028 break;
3029 case RADEON_PARAM_SCRATCH_OFFSET:
3030 if (!dev_priv->writeback_works)
3031 return -EINVAL;
3032 value = RADEON_SCRATCH_REG_OFFSET;
3033 break;
3034 case RADEON_PARAM_CARD_TYPE:
3035 if (dev_priv->flags & RADEON_IS_PCIE)
3036 value = RADEON_CARD_PCIE;
3037 else if (dev_priv->flags & RADEON_IS_AGP)
3038 value = RADEON_CARD_AGP;
3039 else
3040 value = RADEON_CARD_PCI;
3041 break;
3042 case RADEON_PARAM_VBLANK_CRTC:
3043 value = radeon_vblank_crtc_get(dev);
3044 break;
3045 case RADEON_PARAM_FB_LOCATION:
3046 value = radeon_read_fb_location(dev_priv);
3047 break;
3048 case RADEON_PARAM_NUM_GB_PIPES:
3049 value = dev_priv->num_gb_pipes;
3050 break;
3051 default:
3052 DRM_DEBUG("Invalid parameter %d\n", param->param);
3053 return -EINVAL;
3054 }
3055
3056 if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
3057 DRM_ERROR("copy_to_user\n");
3058 return -EFAULT;
3059 }
3060
3061 return 0;
3062}
3063
3064static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
3065{
3066 drm_radeon_private_t *dev_priv = dev->dev_private;
3067 drm_radeon_setparam_t *sp = data;
3068 struct drm_radeon_driver_file_fields *radeon_priv;
3069
3070 switch (sp->param) {
3071 case RADEON_SETPARAM_FB_LOCATION:
3072 radeon_priv = file_priv->driver_priv;
3073 radeon_priv->radeon_fb_delta = dev_priv->fb_location -
3074 sp->value;
3075 break;
3076 case RADEON_SETPARAM_SWITCH_TILING:
3077 if (sp->value == 0) {
3078 DRM_DEBUG("color tiling disabled\n");
3079 dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3080 dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3081 dev_priv->sarea_priv->tiling_enabled = 0;
3082 } else if (sp->value == 1) {
3083 DRM_DEBUG("color tiling enabled\n");
3084 dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
3085 dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
3086 dev_priv->sarea_priv->tiling_enabled = 1;
3087 }
3088 break;
3089 case RADEON_SETPARAM_PCIGART_LOCATION:
3090 dev_priv->pcigart_offset = sp->value;
3091 dev_priv->pcigart_offset_set = 1;
3092 break;
3093 case RADEON_SETPARAM_NEW_MEMMAP:
3094 dev_priv->new_memmap = sp->value;
3095 break;
3096 case RADEON_SETPARAM_PCIGART_TABLE_SIZE:
3097 dev_priv->gart_info.table_size = sp->value;
3098 if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE)
3099 dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
3100 break;
3101 case RADEON_SETPARAM_VBLANK_CRTC:
3102 return radeon_vblank_crtc_set(dev, sp->value);
3103 break;
3104 default:
3105 DRM_DEBUG("Invalid parameter %d\n", sp->param);
3106 return -EINVAL;
3107 }
3108
3109 return 0;
3110}
3111
3112/* When a client dies:
3113 * - Check for and clean up flipped page state
3114 * - Free any alloced GART memory.
3115 * - Free any alloced radeon surfaces.
3116 *
3117 * DRM infrastructure takes care of reclaiming dma buffers.
3118 */
3119void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
3120{
3121 if (dev->dev_private) {
3122 drm_radeon_private_t *dev_priv = dev->dev_private;
3123 dev_priv->page_flipping = 0;
3124 radeon_mem_release(file_priv, dev_priv->gart_heap);
3125 radeon_mem_release(file_priv, dev_priv->fb_heap);
3126 radeon_surfaces_release(file_priv, dev_priv);
3127 }
3128}
3129
3130void radeon_driver_lastclose(struct drm_device *dev)
3131{
3132 if (dev->dev_private) {
3133 drm_radeon_private_t *dev_priv = dev->dev_private;
3134
3135 if (dev_priv->sarea_priv &&
3136 dev_priv->sarea_priv->pfCurrentPage != 0)
3137 radeon_cp_dispatch_flip(dev);
3138 }
3139
3140 radeon_do_release(dev);
3141}
3142
3143int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv)
3144{
3145 drm_radeon_private_t *dev_priv = dev->dev_private;
3146 struct drm_radeon_driver_file_fields *radeon_priv;
3147
3148 DRM_DEBUG("\n");
3149 radeon_priv =
3150 (struct drm_radeon_driver_file_fields *)
3151 drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
3152
3153 if (!radeon_priv)
3154 return -ENOMEM;
3155
3156 file_priv->driver_priv = radeon_priv;
3157
3158 if (dev_priv)
3159 radeon_priv->radeon_fb_delta = dev_priv->fb_location;
3160 else
3161 radeon_priv->radeon_fb_delta = 0;
3162 return 0;
3163}
3164
3165void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
3166{
3167 struct drm_radeon_driver_file_fields *radeon_priv =
3168 file_priv->driver_priv;
3169
3170 drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
3171}
3172
3173struct drm_ioctl_desc radeon_ioctls[] = {
3174 DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3175 DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3176 DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3177 DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3178 DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH),
3179 DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH),
3180 DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH),
3181 DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH),
3182 DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH),
3183 DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH),
3184 DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH),
3185 DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH),
3186 DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH),
3187 DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH),
3188 DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3189 DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH),
3190 DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH),
3191 DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH),
3192 DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH),
3193 DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH),
3194 DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH),
3195 DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3196 DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH),
3197 DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
3198 DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
3199 DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
3200 DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
3201};
3202
3203int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);