2 * Copyright 2010 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
24 * Authors: Dave Airlie
30 #include "evergreend.h"
31 #include "evergreen_reg_safe.h"
32 #include "cayman_reg_safe.h"
34 static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser
*p
,
35 struct radeon_cs_reloc
**cs_reloc
);
37 struct evergreen_cs_track
{
44 u32 cb_color_base_last
[12];
45 struct radeon_bo
*cb_color_bo
[12];
46 u32 cb_color_bo_offset
[12];
47 struct radeon_bo
*cb_color_fmask_bo
[8];
48 struct radeon_bo
*cb_color_cmask_bo
[8];
49 u32 cb_color_info
[12];
50 u32 cb_color_view
[12];
51 u32 cb_color_pitch_idx
[12];
52 u32 cb_color_slice_idx
[12];
53 u32 cb_color_dim_idx
[12];
55 u32 cb_color_pitch
[12];
56 u32 cb_color_slice
[12];
57 u32 cb_color_cmask_slice
[8];
58 u32 cb_color_fmask_slice
[8];
61 u32 vgt_strmout_config
;
62 u32 vgt_strmout_buffer_config
;
66 u32 db_depth_size_idx
;
70 u32 db_z_write_offset
;
71 struct radeon_bo
*db_z_read_bo
;
72 struct radeon_bo
*db_z_write_bo
;
76 u32 db_s_write_offset
;
77 struct radeon_bo
*db_s_read_bo
;
78 struct radeon_bo
*db_s_write_bo
;
81 static u32
evergreen_cs_get_aray_mode(u32 tiling_flags
)
83 if (tiling_flags
& RADEON_TILING_MACRO
)
84 return ARRAY_2D_TILED_THIN1
;
85 else if (tiling_flags
& RADEON_TILING_MICRO
)
86 return ARRAY_1D_TILED_THIN1
;
88 return ARRAY_LINEAR_GENERAL
;
91 static u32
evergreen_cs_get_num_banks(u32 nbanks
)
95 return ADDR_SURF_2_BANK
;
97 return ADDR_SURF_4_BANK
;
100 return ADDR_SURF_8_BANK
;
102 return ADDR_SURF_16_BANK
;
106 static u32
evergreen_cs_get_tile_split(u32 row_size
)
111 return ADDR_SURF_TILE_SPLIT_1KB
;
113 return ADDR_SURF_TILE_SPLIT_2KB
;
115 return ADDR_SURF_TILE_SPLIT_4KB
;
119 static void evergreen_cs_track_init(struct evergreen_cs_track
*track
)
123 for (i
= 0; i
< 8; i
++) {
124 track
->cb_color_fmask_bo
[i
] = NULL
;
125 track
->cb_color_cmask_bo
[i
] = NULL
;
126 track
->cb_color_cmask_slice
[i
] = 0;
127 track
->cb_color_fmask_slice
[i
] = 0;
130 for (i
= 0; i
< 12; i
++) {
131 track
->cb_color_base_last
[i
] = 0;
132 track
->cb_color_bo
[i
] = NULL
;
133 track
->cb_color_bo_offset
[i
] = 0xFFFFFFFF;
134 track
->cb_color_info
[i
] = 0;
135 track
->cb_color_view
[i
] = 0;
136 track
->cb_color_pitch_idx
[i
] = 0;
137 track
->cb_color_slice_idx
[i
] = 0;
138 track
->cb_color_dim
[i
] = 0;
139 track
->cb_color_pitch
[i
] = 0;
140 track
->cb_color_slice
[i
] = 0;
141 track
->cb_color_dim
[i
] = 0;
143 track
->cb_target_mask
= 0xFFFFFFFF;
144 track
->cb_shader_mask
= 0xFFFFFFFF;
146 track
->db_depth_view
= 0xFFFFC000;
147 track
->db_depth_size
= 0xFFFFFFFF;
148 track
->db_depth_size_idx
= 0;
149 track
->db_depth_control
= 0xFFFFFFFF;
150 track
->db_z_info
= 0xFFFFFFFF;
151 track
->db_z_idx
= 0xFFFFFFFF;
152 track
->db_z_read_offset
= 0xFFFFFFFF;
153 track
->db_z_write_offset
= 0xFFFFFFFF;
154 track
->db_z_read_bo
= NULL
;
155 track
->db_z_write_bo
= NULL
;
156 track
->db_s_info
= 0xFFFFFFFF;
157 track
->db_s_idx
= 0xFFFFFFFF;
158 track
->db_s_read_offset
= 0xFFFFFFFF;
159 track
->db_s_write_offset
= 0xFFFFFFFF;
160 track
->db_s_read_bo
= NULL
;
161 track
->db_s_write_bo
= NULL
;
164 static int evergreen_cs_track_check(struct radeon_cs_parser
*p
)
166 struct evergreen_cs_track
*track
= p
->track
;
168 /* we don't support stream out buffer yet */
169 if (track
->vgt_strmout_config
|| track
->vgt_strmout_buffer_config
) {
170 dev_warn(p
->dev
, "this kernel doesn't support SMX output buffer\n");
179 * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet
180 * @parser: parser structure holding parsing context.
181 * @pkt: where to store packet informations
183 * Assume that chunk_ib_index is properly set. Will return -EINVAL
184 * if packet is bigger than remaining ib size. or if packets is unknown.
186 int evergreen_cs_packet_parse(struct radeon_cs_parser
*p
,
187 struct radeon_cs_packet
*pkt
,
190 struct radeon_cs_chunk
*ib_chunk
= &p
->chunks
[p
->chunk_ib_idx
];
193 if (idx
>= ib_chunk
->length_dw
) {
194 DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
195 idx
, ib_chunk
->length_dw
);
198 header
= radeon_get_ib_value(p
, idx
);
200 pkt
->type
= CP_PACKET_GET_TYPE(header
);
201 pkt
->count
= CP_PACKET_GET_COUNT(header
);
205 pkt
->reg
= CP_PACKET0_GET_REG(header
);
208 pkt
->opcode
= CP_PACKET3_GET_OPCODE(header
);
214 DRM_ERROR("Unknown packet type %d at %d !\n", pkt
->type
, idx
);
217 if ((pkt
->count
+ 1 + pkt
->idx
) >= ib_chunk
->length_dw
) {
218 DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
219 pkt
->idx
, pkt
->type
, pkt
->count
, ib_chunk
->length_dw
);
226 * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3
227 * @parser: parser structure holding parsing context.
228 * @data: pointer to relocation data
229 * @offset_start: starting offset
230 * @offset_mask: offset mask (to align start offset on)
231 * @reloc: reloc informations
233 * Check next packet is relocation packet3, do bo validation and compute
234 * GPU offset using the provided start.
236 static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser
*p
,
237 struct radeon_cs_reloc
**cs_reloc
)
239 struct radeon_cs_chunk
*relocs_chunk
;
240 struct radeon_cs_packet p3reloc
;
244 if (p
->chunk_relocs_idx
== -1) {
245 DRM_ERROR("No relocation chunk !\n");
249 relocs_chunk
= &p
->chunks
[p
->chunk_relocs_idx
];
250 r
= evergreen_cs_packet_parse(p
, &p3reloc
, p
->idx
);
254 p
->idx
+= p3reloc
.count
+ 2;
255 if (p3reloc
.type
!= PACKET_TYPE3
|| p3reloc
.opcode
!= PACKET3_NOP
) {
256 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
260 idx
= radeon_get_ib_value(p
, p3reloc
.idx
+ 1);
261 if (idx
>= relocs_chunk
->length_dw
) {
262 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
263 idx
, relocs_chunk
->length_dw
);
266 /* FIXME: we assume reloc size is 4 dwords */
267 *cs_reloc
= p
->relocs_ptr
[(idx
/ 4)];
272 * evergreen_cs_packet_next_vline() - parse userspace VLINE packet
273 * @parser: parser structure holding parsing context.
275 * Userspace sends a special sequence for VLINE waits.
276 * PACKET0 - VLINE_START_END + value
277 * PACKET3 - WAIT_REG_MEM poll vline status reg
278 * RELOC (P3) - crtc_id in reloc.
280 * This function parses this and relocates the VLINE START END
281 * and WAIT_REG_MEM packets to the correct crtc.
282 * It also detects a switched off crtc and nulls out the
285 static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser
*p
)
287 struct drm_mode_object
*obj
;
288 struct drm_crtc
*crtc
;
289 struct radeon_crtc
*radeon_crtc
;
290 struct radeon_cs_packet p3reloc
, wait_reg_mem
;
293 uint32_t header
, h_idx
, reg
, wait_reg_mem_info
;
294 volatile uint32_t *ib
;
298 /* parse the WAIT_REG_MEM */
299 r
= evergreen_cs_packet_parse(p
, &wait_reg_mem
, p
->idx
);
303 /* check its a WAIT_REG_MEM */
304 if (wait_reg_mem
.type
!= PACKET_TYPE3
||
305 wait_reg_mem
.opcode
!= PACKET3_WAIT_REG_MEM
) {
306 DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
310 wait_reg_mem_info
= radeon_get_ib_value(p
, wait_reg_mem
.idx
+ 1);
311 /* bit 4 is reg (0) or mem (1) */
312 if (wait_reg_mem_info
& 0x10) {
313 DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
316 /* waiting for value to be equal */
317 if ((wait_reg_mem_info
& 0x7) != 0x3) {
318 DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
321 if ((radeon_get_ib_value(p
, wait_reg_mem
.idx
+ 2) << 2) != EVERGREEN_VLINE_STATUS
) {
322 DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
326 if (radeon_get_ib_value(p
, wait_reg_mem
.idx
+ 5) != EVERGREEN_VLINE_STAT
) {
327 DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
331 /* jump over the NOP */
332 r
= evergreen_cs_packet_parse(p
, &p3reloc
, p
->idx
+ wait_reg_mem
.count
+ 2);
337 p
->idx
+= wait_reg_mem
.count
+ 2;
338 p
->idx
+= p3reloc
.count
+ 2;
340 header
= radeon_get_ib_value(p
, h_idx
);
341 crtc_id
= radeon_get_ib_value(p
, h_idx
+ 2 + 7 + 1);
342 reg
= CP_PACKET0_GET_REG(header
);
343 obj
= drm_mode_object_find(p
->rdev
->ddev
, crtc_id
, DRM_MODE_OBJECT_CRTC
);
345 DRM_ERROR("cannot find crtc %d\n", crtc_id
);
348 crtc
= obj_to_crtc(obj
);
349 radeon_crtc
= to_radeon_crtc(crtc
);
350 crtc_id
= radeon_crtc
->crtc_id
;
352 if (!crtc
->enabled
) {
353 /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
354 ib
[h_idx
+ 2] = PACKET2(0);
355 ib
[h_idx
+ 3] = PACKET2(0);
356 ib
[h_idx
+ 4] = PACKET2(0);
357 ib
[h_idx
+ 5] = PACKET2(0);
358 ib
[h_idx
+ 6] = PACKET2(0);
359 ib
[h_idx
+ 7] = PACKET2(0);
360 ib
[h_idx
+ 8] = PACKET2(0);
363 case EVERGREEN_VLINE_START_END
:
364 header
&= ~R600_CP_PACKET0_REG_MASK
;
365 header
|= (EVERGREEN_VLINE_START_END
+ radeon_crtc
->crtc_offset
) >> 2;
367 ib
[h_idx
+ 4] = (EVERGREEN_VLINE_STATUS
+ radeon_crtc
->crtc_offset
) >> 2;
370 DRM_ERROR("unknown crtc reloc\n");
377 static int evergreen_packet0_check(struct radeon_cs_parser
*p
,
378 struct radeon_cs_packet
*pkt
,
379 unsigned idx
, unsigned reg
)
384 case EVERGREEN_VLINE_START_END
:
385 r
= evergreen_cs_packet_parse_vline(p
);
387 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
393 printk(KERN_ERR
"Forbidden register 0x%04X in cs at %d\n",
400 static int evergreen_cs_parse_packet0(struct radeon_cs_parser
*p
,
401 struct radeon_cs_packet
*pkt
)
409 for (i
= 0; i
<= pkt
->count
; i
++, idx
++, reg
+= 4) {
410 r
= evergreen_packet0_check(p
, pkt
, idx
, reg
);
419 * evergreen_cs_check_reg() - check if register is authorized or not
420 * @parser: parser structure holding parsing context
421 * @reg: register we are testing
422 * @idx: index into the cs buffer
424 * This function will test against evergreen_reg_safe_bm and return 0
425 * if register is safe. If register is not flag as safe this function
426 * will test it against a list of register needind special handling.
428 static int evergreen_cs_check_reg(struct radeon_cs_parser
*p
, u32 reg
, u32 idx
)
430 struct evergreen_cs_track
*track
= (struct evergreen_cs_track
*)p
->track
;
431 struct radeon_cs_reloc
*reloc
;
436 if (p
->rdev
->family
>= CHIP_CAYMAN
)
437 last_reg
= ARRAY_SIZE(cayman_reg_safe_bm
);
439 last_reg
= ARRAY_SIZE(evergreen_reg_safe_bm
);
443 dev_warn(p
->dev
, "forbidden register 0x%08x at %d\n", reg
, idx
);
446 m
= 1 << ((reg
>> 2) & 31);
447 if (p
->rdev
->family
>= CHIP_CAYMAN
) {
448 if (!(cayman_reg_safe_bm
[i
] & m
))
451 if (!(evergreen_reg_safe_bm
[i
] & m
))
456 /* force following reg to 0 in an attempt to disable out buffer
457 * which will need us to better understand how it works to perform
458 * security check on it (Jerome)
460 case SQ_ESGS_RING_SIZE
:
461 case SQ_GSVS_RING_SIZE
:
462 case SQ_ESTMP_RING_SIZE
:
463 case SQ_GSTMP_RING_SIZE
:
464 case SQ_HSTMP_RING_SIZE
:
465 case SQ_LSTMP_RING_SIZE
:
466 case SQ_PSTMP_RING_SIZE
:
467 case SQ_VSTMP_RING_SIZE
:
468 case SQ_ESGS_RING_ITEMSIZE
:
469 case SQ_ESTMP_RING_ITEMSIZE
:
470 case SQ_GSTMP_RING_ITEMSIZE
:
471 case SQ_GSVS_RING_ITEMSIZE
:
472 case SQ_GS_VERT_ITEMSIZE
:
473 case SQ_GS_VERT_ITEMSIZE_1
:
474 case SQ_GS_VERT_ITEMSIZE_2
:
475 case SQ_GS_VERT_ITEMSIZE_3
:
476 case SQ_GSVS_RING_OFFSET_1
:
477 case SQ_GSVS_RING_OFFSET_2
:
478 case SQ_GSVS_RING_OFFSET_3
:
479 case SQ_HSTMP_RING_ITEMSIZE
:
480 case SQ_LSTMP_RING_ITEMSIZE
:
481 case SQ_PSTMP_RING_ITEMSIZE
:
482 case SQ_VSTMP_RING_ITEMSIZE
:
483 case VGT_TF_RING_SIZE
:
484 /* get value to populate the IB don't remove */
485 /*tmp =radeon_get_ib_value(p, idx);
488 case SQ_ESGS_RING_BASE
:
489 case SQ_GSVS_RING_BASE
:
490 case SQ_ESTMP_RING_BASE
:
491 case SQ_GSTMP_RING_BASE
:
492 case SQ_HSTMP_RING_BASE
:
493 case SQ_LSTMP_RING_BASE
:
494 case SQ_PSTMP_RING_BASE
:
495 case SQ_VSTMP_RING_BASE
:
496 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
498 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
502 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
504 case DB_DEPTH_CONTROL
:
505 track
->db_depth_control
= radeon_get_ib_value(p
, idx
);
508 if (p
->rdev
->family
< CHIP_CAYMAN
) {
509 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
514 case CAYMAN_DB_DEPTH_INFO
:
515 if (p
->rdev
->family
< CHIP_CAYMAN
) {
516 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
522 track
->db_z_info
= radeon_get_ib_value(p
, idx
);
523 if (!p
->keep_tiling_flags
) {
524 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
526 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
530 ib
[idx
] &= ~Z_ARRAY_MODE(0xf);
531 track
->db_z_info
&= ~Z_ARRAY_MODE(0xf);
532 ib
[idx
] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
533 track
->db_z_info
|= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
534 if (reloc
->lobj
.tiling_flags
& RADEON_TILING_MACRO
) {
535 ib
[idx
] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track
->nbanks
));
536 ib
[idx
] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track
->row_size
));
540 case DB_STENCIL_INFO
:
541 track
->db_s_info
= radeon_get_ib_value(p
, idx
);
544 track
->db_depth_view
= radeon_get_ib_value(p
, idx
);
547 track
->db_depth_size
= radeon_get_ib_value(p
, idx
);
548 track
->db_depth_size_idx
= idx
;
551 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
553 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
557 track
->db_z_read_offset
= radeon_get_ib_value(p
, idx
);
558 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
559 track
->db_z_read_bo
= reloc
->robj
;
561 case DB_Z_WRITE_BASE
:
562 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
564 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
568 track
->db_z_write_offset
= radeon_get_ib_value(p
, idx
);
569 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
570 track
->db_z_write_bo
= reloc
->robj
;
572 case DB_STENCIL_READ_BASE
:
573 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
575 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
579 track
->db_s_read_offset
= radeon_get_ib_value(p
, idx
);
580 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
581 track
->db_s_read_bo
= reloc
->robj
;
583 case DB_STENCIL_WRITE_BASE
:
584 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
586 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
590 track
->db_s_write_offset
= radeon_get_ib_value(p
, idx
);
591 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
592 track
->db_s_write_bo
= reloc
->robj
;
594 case VGT_STRMOUT_CONFIG
:
595 track
->vgt_strmout_config
= radeon_get_ib_value(p
, idx
);
597 case VGT_STRMOUT_BUFFER_CONFIG
:
598 track
->vgt_strmout_buffer_config
= radeon_get_ib_value(p
, idx
);
601 track
->cb_target_mask
= radeon_get_ib_value(p
, idx
);
604 track
->cb_shader_mask
= radeon_get_ib_value(p
, idx
);
606 case PA_SC_AA_CONFIG
:
607 if (p
->rdev
->family
>= CHIP_CAYMAN
) {
608 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
612 tmp
= radeon_get_ib_value(p
, idx
) & MSAA_NUM_SAMPLES_MASK
;
613 track
->nsamples
= 1 << tmp
;
615 case CAYMAN_PA_SC_AA_CONFIG
:
616 if (p
->rdev
->family
< CHIP_CAYMAN
) {
617 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
621 tmp
= radeon_get_ib_value(p
, idx
) & CAYMAN_MSAA_NUM_SAMPLES_MASK
;
622 track
->nsamples
= 1 << tmp
;
632 tmp
= (reg
- CB_COLOR0_VIEW
) / 0x3c;
633 track
->cb_color_view
[tmp
] = radeon_get_ib_value(p
, idx
);
637 case CB_COLOR10_VIEW
:
638 case CB_COLOR11_VIEW
:
639 tmp
= ((reg
- CB_COLOR8_VIEW
) / 0x1c) + 8;
640 track
->cb_color_view
[tmp
] = radeon_get_ib_value(p
, idx
);
650 tmp
= (reg
- CB_COLOR0_INFO
) / 0x3c;
651 track
->cb_color_info
[tmp
] = radeon_get_ib_value(p
, idx
);
652 if (!p
->keep_tiling_flags
) {
653 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
655 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
659 ib
[idx
] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
660 track
->cb_color_info
[tmp
] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
665 case CB_COLOR10_INFO
:
666 case CB_COLOR11_INFO
:
667 tmp
= ((reg
- CB_COLOR8_INFO
) / 0x1c) + 8;
668 track
->cb_color_info
[tmp
] = radeon_get_ib_value(p
, idx
);
669 if (!p
->keep_tiling_flags
) {
670 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
672 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
676 ib
[idx
] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
677 track
->cb_color_info
[tmp
] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
680 case CB_COLOR0_PITCH
:
681 case CB_COLOR1_PITCH
:
682 case CB_COLOR2_PITCH
:
683 case CB_COLOR3_PITCH
:
684 case CB_COLOR4_PITCH
:
685 case CB_COLOR5_PITCH
:
686 case CB_COLOR6_PITCH
:
687 case CB_COLOR7_PITCH
:
688 tmp
= (reg
- CB_COLOR0_PITCH
) / 0x3c;
689 track
->cb_color_pitch
[tmp
] = radeon_get_ib_value(p
, idx
);
690 track
->cb_color_pitch_idx
[tmp
] = idx
;
692 case CB_COLOR8_PITCH
:
693 case CB_COLOR9_PITCH
:
694 case CB_COLOR10_PITCH
:
695 case CB_COLOR11_PITCH
:
696 tmp
= ((reg
- CB_COLOR8_PITCH
) / 0x1c) + 8;
697 track
->cb_color_pitch
[tmp
] = radeon_get_ib_value(p
, idx
);
698 track
->cb_color_pitch_idx
[tmp
] = idx
;
700 case CB_COLOR0_SLICE
:
701 case CB_COLOR1_SLICE
:
702 case CB_COLOR2_SLICE
:
703 case CB_COLOR3_SLICE
:
704 case CB_COLOR4_SLICE
:
705 case CB_COLOR5_SLICE
:
706 case CB_COLOR6_SLICE
:
707 case CB_COLOR7_SLICE
:
708 tmp
= (reg
- CB_COLOR0_SLICE
) / 0x3c;
709 track
->cb_color_slice
[tmp
] = radeon_get_ib_value(p
, idx
);
710 track
->cb_color_slice_idx
[tmp
] = idx
;
712 case CB_COLOR8_SLICE
:
713 case CB_COLOR9_SLICE
:
714 case CB_COLOR10_SLICE
:
715 case CB_COLOR11_SLICE
:
716 tmp
= ((reg
- CB_COLOR8_SLICE
) / 0x1c) + 8;
717 track
->cb_color_slice
[tmp
] = radeon_get_ib_value(p
, idx
);
718 track
->cb_color_slice_idx
[tmp
] = idx
;
720 case CB_COLOR0_ATTRIB
:
721 case CB_COLOR1_ATTRIB
:
722 case CB_COLOR2_ATTRIB
:
723 case CB_COLOR3_ATTRIB
:
724 case CB_COLOR4_ATTRIB
:
725 case CB_COLOR5_ATTRIB
:
726 case CB_COLOR6_ATTRIB
:
727 case CB_COLOR7_ATTRIB
:
728 case CB_COLOR8_ATTRIB
:
729 case CB_COLOR9_ATTRIB
:
730 case CB_COLOR10_ATTRIB
:
731 case CB_COLOR11_ATTRIB
:
732 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
734 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
738 if (reloc
->lobj
.tiling_flags
& RADEON_TILING_MACRO
) {
739 ib
[idx
] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track
->nbanks
));
740 ib
[idx
] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track
->row_size
));
751 tmp
= (reg
- CB_COLOR0_DIM
) / 0x3c;
752 track
->cb_color_dim
[tmp
] = radeon_get_ib_value(p
, idx
);
753 track
->cb_color_dim_idx
[tmp
] = idx
;
759 tmp
= ((reg
- CB_COLOR8_DIM
) / 0x1c) + 8;
760 track
->cb_color_dim
[tmp
] = radeon_get_ib_value(p
, idx
);
761 track
->cb_color_dim_idx
[tmp
] = idx
;
763 case CB_COLOR0_FMASK
:
764 case CB_COLOR1_FMASK
:
765 case CB_COLOR2_FMASK
:
766 case CB_COLOR3_FMASK
:
767 case CB_COLOR4_FMASK
:
768 case CB_COLOR5_FMASK
:
769 case CB_COLOR6_FMASK
:
770 case CB_COLOR7_FMASK
:
771 tmp
= (reg
- CB_COLOR0_FMASK
) / 0x3c;
772 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
774 dev_err(p
->dev
, "bad SET_CONTEXT_REG 0x%04X\n", reg
);
777 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
778 track
->cb_color_fmask_bo
[tmp
] = reloc
->robj
;
780 case CB_COLOR0_CMASK
:
781 case CB_COLOR1_CMASK
:
782 case CB_COLOR2_CMASK
:
783 case CB_COLOR3_CMASK
:
784 case CB_COLOR4_CMASK
:
785 case CB_COLOR5_CMASK
:
786 case CB_COLOR6_CMASK
:
787 case CB_COLOR7_CMASK
:
788 tmp
= (reg
- CB_COLOR0_CMASK
) / 0x3c;
789 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
791 dev_err(p
->dev
, "bad SET_CONTEXT_REG 0x%04X\n", reg
);
794 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
795 track
->cb_color_cmask_bo
[tmp
] = reloc
->robj
;
797 case CB_COLOR0_FMASK_SLICE
:
798 case CB_COLOR1_FMASK_SLICE
:
799 case CB_COLOR2_FMASK_SLICE
:
800 case CB_COLOR3_FMASK_SLICE
:
801 case CB_COLOR4_FMASK_SLICE
:
802 case CB_COLOR5_FMASK_SLICE
:
803 case CB_COLOR6_FMASK_SLICE
:
804 case CB_COLOR7_FMASK_SLICE
:
805 tmp
= (reg
- CB_COLOR0_FMASK_SLICE
) / 0x3c;
806 track
->cb_color_fmask_slice
[tmp
] = radeon_get_ib_value(p
, idx
);
808 case CB_COLOR0_CMASK_SLICE
:
809 case CB_COLOR1_CMASK_SLICE
:
810 case CB_COLOR2_CMASK_SLICE
:
811 case CB_COLOR3_CMASK_SLICE
:
812 case CB_COLOR4_CMASK_SLICE
:
813 case CB_COLOR5_CMASK_SLICE
:
814 case CB_COLOR6_CMASK_SLICE
:
815 case CB_COLOR7_CMASK_SLICE
:
816 tmp
= (reg
- CB_COLOR0_CMASK_SLICE
) / 0x3c;
817 track
->cb_color_cmask_slice
[tmp
] = radeon_get_ib_value(p
, idx
);
827 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
829 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
833 tmp
= (reg
- CB_COLOR0_BASE
) / 0x3c;
834 track
->cb_color_bo_offset
[tmp
] = radeon_get_ib_value(p
, idx
);
835 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
836 track
->cb_color_base_last
[tmp
] = ib
[idx
];
837 track
->cb_color_bo
[tmp
] = reloc
->robj
;
841 case CB_COLOR10_BASE
:
842 case CB_COLOR11_BASE
:
843 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
845 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
849 tmp
= ((reg
- CB_COLOR8_BASE
) / 0x1c) + 8;
850 track
->cb_color_bo_offset
[tmp
] = radeon_get_ib_value(p
, idx
);
851 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
852 track
->cb_color_base_last
[tmp
] = ib
[idx
];
853 track
->cb_color_bo
[tmp
] = reloc
->robj
;
865 case CB_IMMED10_BASE
:
866 case CB_IMMED11_BASE
:
867 case DB_HTILE_DATA_BASE
:
868 case SQ_PGM_START_FS
:
869 case SQ_PGM_START_ES
:
870 case SQ_PGM_START_VS
:
871 case SQ_PGM_START_GS
:
872 case SQ_PGM_START_PS
:
873 case SQ_PGM_START_HS
:
874 case SQ_PGM_START_LS
:
875 case SQ_CONST_MEM_BASE
:
876 case SQ_ALU_CONST_CACHE_GS_0
:
877 case SQ_ALU_CONST_CACHE_GS_1
:
878 case SQ_ALU_CONST_CACHE_GS_2
:
879 case SQ_ALU_CONST_CACHE_GS_3
:
880 case SQ_ALU_CONST_CACHE_GS_4
:
881 case SQ_ALU_CONST_CACHE_GS_5
:
882 case SQ_ALU_CONST_CACHE_GS_6
:
883 case SQ_ALU_CONST_CACHE_GS_7
:
884 case SQ_ALU_CONST_CACHE_GS_8
:
885 case SQ_ALU_CONST_CACHE_GS_9
:
886 case SQ_ALU_CONST_CACHE_GS_10
:
887 case SQ_ALU_CONST_CACHE_GS_11
:
888 case SQ_ALU_CONST_CACHE_GS_12
:
889 case SQ_ALU_CONST_CACHE_GS_13
:
890 case SQ_ALU_CONST_CACHE_GS_14
:
891 case SQ_ALU_CONST_CACHE_GS_15
:
892 case SQ_ALU_CONST_CACHE_PS_0
:
893 case SQ_ALU_CONST_CACHE_PS_1
:
894 case SQ_ALU_CONST_CACHE_PS_2
:
895 case SQ_ALU_CONST_CACHE_PS_3
:
896 case SQ_ALU_CONST_CACHE_PS_4
:
897 case SQ_ALU_CONST_CACHE_PS_5
:
898 case SQ_ALU_CONST_CACHE_PS_6
:
899 case SQ_ALU_CONST_CACHE_PS_7
:
900 case SQ_ALU_CONST_CACHE_PS_8
:
901 case SQ_ALU_CONST_CACHE_PS_9
:
902 case SQ_ALU_CONST_CACHE_PS_10
:
903 case SQ_ALU_CONST_CACHE_PS_11
:
904 case SQ_ALU_CONST_CACHE_PS_12
:
905 case SQ_ALU_CONST_CACHE_PS_13
:
906 case SQ_ALU_CONST_CACHE_PS_14
:
907 case SQ_ALU_CONST_CACHE_PS_15
:
908 case SQ_ALU_CONST_CACHE_VS_0
:
909 case SQ_ALU_CONST_CACHE_VS_1
:
910 case SQ_ALU_CONST_CACHE_VS_2
:
911 case SQ_ALU_CONST_CACHE_VS_3
:
912 case SQ_ALU_CONST_CACHE_VS_4
:
913 case SQ_ALU_CONST_CACHE_VS_5
:
914 case SQ_ALU_CONST_CACHE_VS_6
:
915 case SQ_ALU_CONST_CACHE_VS_7
:
916 case SQ_ALU_CONST_CACHE_VS_8
:
917 case SQ_ALU_CONST_CACHE_VS_9
:
918 case SQ_ALU_CONST_CACHE_VS_10
:
919 case SQ_ALU_CONST_CACHE_VS_11
:
920 case SQ_ALU_CONST_CACHE_VS_12
:
921 case SQ_ALU_CONST_CACHE_VS_13
:
922 case SQ_ALU_CONST_CACHE_VS_14
:
923 case SQ_ALU_CONST_CACHE_VS_15
:
924 case SQ_ALU_CONST_CACHE_HS_0
:
925 case SQ_ALU_CONST_CACHE_HS_1
:
926 case SQ_ALU_CONST_CACHE_HS_2
:
927 case SQ_ALU_CONST_CACHE_HS_3
:
928 case SQ_ALU_CONST_CACHE_HS_4
:
929 case SQ_ALU_CONST_CACHE_HS_5
:
930 case SQ_ALU_CONST_CACHE_HS_6
:
931 case SQ_ALU_CONST_CACHE_HS_7
:
932 case SQ_ALU_CONST_CACHE_HS_8
:
933 case SQ_ALU_CONST_CACHE_HS_9
:
934 case SQ_ALU_CONST_CACHE_HS_10
:
935 case SQ_ALU_CONST_CACHE_HS_11
:
936 case SQ_ALU_CONST_CACHE_HS_12
:
937 case SQ_ALU_CONST_CACHE_HS_13
:
938 case SQ_ALU_CONST_CACHE_HS_14
:
939 case SQ_ALU_CONST_CACHE_HS_15
:
940 case SQ_ALU_CONST_CACHE_LS_0
:
941 case SQ_ALU_CONST_CACHE_LS_1
:
942 case SQ_ALU_CONST_CACHE_LS_2
:
943 case SQ_ALU_CONST_CACHE_LS_3
:
944 case SQ_ALU_CONST_CACHE_LS_4
:
945 case SQ_ALU_CONST_CACHE_LS_5
:
946 case SQ_ALU_CONST_CACHE_LS_6
:
947 case SQ_ALU_CONST_CACHE_LS_7
:
948 case SQ_ALU_CONST_CACHE_LS_8
:
949 case SQ_ALU_CONST_CACHE_LS_9
:
950 case SQ_ALU_CONST_CACHE_LS_10
:
951 case SQ_ALU_CONST_CACHE_LS_11
:
952 case SQ_ALU_CONST_CACHE_LS_12
:
953 case SQ_ALU_CONST_CACHE_LS_13
:
954 case SQ_ALU_CONST_CACHE_LS_14
:
955 case SQ_ALU_CONST_CACHE_LS_15
:
956 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
958 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
962 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
964 case SX_MEMORY_EXPORT_BASE
:
965 if (p
->rdev
->family
>= CHIP_CAYMAN
) {
966 dev_warn(p
->dev
, "bad SET_CONFIG_REG "
970 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
972 dev_warn(p
->dev
, "bad SET_CONFIG_REG "
976 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
978 case CAYMAN_SX_SCATTER_EXPORT_BASE
:
979 if (p
->rdev
->family
< CHIP_CAYMAN
) {
980 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
984 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
986 dev_warn(p
->dev
, "bad SET_CONTEXT_REG "
990 ib
[idx
] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
993 dev_warn(p
->dev
, "forbidden register 0x%08x at %d\n", reg
, idx
);
1000 * evergreen_check_texture_resource() - check if register is authorized or not
1001 * @p: parser structure holding parsing context
1002 * @idx: index into the cs buffer
1003 * @texture: texture's bo structure
1004 * @mipmap: mipmap's bo structure
1006 * This function will check that the resource has valid field and that
1007 * the texture and mipmap bo object are big enough to cover this resource.
1009 static int evergreen_check_texture_resource(struct radeon_cs_parser
*p
, u32 idx
,
1010 struct radeon_bo
*texture
,
1011 struct radeon_bo
*mipmap
)
1017 static int evergreen_packet3_check(struct radeon_cs_parser
*p
,
1018 struct radeon_cs_packet
*pkt
)
1020 struct radeon_cs_reloc
*reloc
;
1021 struct evergreen_cs_track
*track
;
1025 unsigned start_reg
, end_reg
, reg
;
1029 track
= (struct evergreen_cs_track
*)p
->track
;
1032 idx_value
= radeon_get_ib_value(p
, idx
);
1034 switch (pkt
->opcode
) {
1035 case PACKET3_SET_PREDICATION
:
1039 if (pkt
->count
!= 1) {
1040 DRM_ERROR("bad SET PREDICATION\n");
1044 tmp
= radeon_get_ib_value(p
, idx
+ 1);
1045 pred_op
= (tmp
>> 16) & 0x7;
1047 /* for the clear predicate operation */
1052 DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op
);
1056 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1058 DRM_ERROR("bad SET PREDICATION\n");
1062 ib
[idx
+ 0] = idx_value
+ (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1063 ib
[idx
+ 1] = tmp
+ (upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff);
1066 case PACKET3_CONTEXT_CONTROL
:
1067 if (pkt
->count
!= 1) {
1068 DRM_ERROR("bad CONTEXT_CONTROL\n");
1072 case PACKET3_INDEX_TYPE
:
1073 case PACKET3_NUM_INSTANCES
:
1074 case PACKET3_CLEAR_STATE
:
1076 DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
1080 case CAYMAN_PACKET3_DEALLOC_STATE
:
1081 if (p
->rdev
->family
< CHIP_CAYMAN
) {
1082 DRM_ERROR("bad PACKET3_DEALLOC_STATE\n");
1086 DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
1090 case PACKET3_INDEX_BASE
:
1091 if (pkt
->count
!= 1) {
1092 DRM_ERROR("bad INDEX_BASE\n");
1095 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1097 DRM_ERROR("bad INDEX_BASE\n");
1100 ib
[idx
+0] = idx_value
+ (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1101 ib
[idx
+1] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1102 r
= evergreen_cs_track_check(p
);
1104 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1108 case PACKET3_DRAW_INDEX
:
1109 if (pkt
->count
!= 3) {
1110 DRM_ERROR("bad DRAW_INDEX\n");
1113 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1115 DRM_ERROR("bad DRAW_INDEX\n");
1118 ib
[idx
+0] = idx_value
+ (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1119 ib
[idx
+1] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1120 r
= evergreen_cs_track_check(p
);
1122 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1126 case PACKET3_DRAW_INDEX_2
:
1127 if (pkt
->count
!= 4) {
1128 DRM_ERROR("bad DRAW_INDEX_2\n");
1131 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1133 DRM_ERROR("bad DRAW_INDEX_2\n");
1136 ib
[idx
+1] = idx_value
+ (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1137 ib
[idx
+2] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1138 r
= evergreen_cs_track_check(p
);
1140 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1144 case PACKET3_DRAW_INDEX_AUTO
:
1145 if (pkt
->count
!= 1) {
1146 DRM_ERROR("bad DRAW_INDEX_AUTO\n");
1149 r
= evergreen_cs_track_check(p
);
1151 dev_warn(p
->dev
, "%s:%d invalid cmd stream %d\n", __func__
, __LINE__
, idx
);
1155 case PACKET3_DRAW_INDEX_MULTI_AUTO
:
1156 if (pkt
->count
!= 2) {
1157 DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n");
1160 r
= evergreen_cs_track_check(p
);
1162 dev_warn(p
->dev
, "%s:%d invalid cmd stream %d\n", __func__
, __LINE__
, idx
);
1166 case PACKET3_DRAW_INDEX_IMMD
:
1167 if (pkt
->count
< 2) {
1168 DRM_ERROR("bad DRAW_INDEX_IMMD\n");
1171 r
= evergreen_cs_track_check(p
);
1173 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1177 case PACKET3_DRAW_INDEX_OFFSET
:
1178 if (pkt
->count
!= 2) {
1179 DRM_ERROR("bad DRAW_INDEX_OFFSET\n");
1182 r
= evergreen_cs_track_check(p
);
1184 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1188 case PACKET3_DRAW_INDEX_OFFSET_2
:
1189 if (pkt
->count
!= 3) {
1190 DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n");
1193 r
= evergreen_cs_track_check(p
);
1195 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1199 case PACKET3_DISPATCH_DIRECT
:
1200 if (pkt
->count
!= 3) {
1201 DRM_ERROR("bad DISPATCH_DIRECT\n");
1204 r
= evergreen_cs_track_check(p
);
1206 dev_warn(p
->dev
, "%s:%d invalid cmd stream %d\n", __func__
, __LINE__
, idx
);
1210 case PACKET3_DISPATCH_INDIRECT
:
1211 if (pkt
->count
!= 1) {
1212 DRM_ERROR("bad DISPATCH_INDIRECT\n");
1215 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1217 DRM_ERROR("bad DISPATCH_INDIRECT\n");
1220 ib
[idx
+0] = idx_value
+ (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1221 r
= evergreen_cs_track_check(p
);
1223 dev_warn(p
->dev
, "%s:%d invalid cmd stream\n", __func__
, __LINE__
);
1227 case PACKET3_WAIT_REG_MEM
:
1228 if (pkt
->count
!= 5) {
1229 DRM_ERROR("bad WAIT_REG_MEM\n");
1232 /* bit 4 is reg (0) or mem (1) */
1233 if (idx_value
& 0x10) {
1234 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1236 DRM_ERROR("bad WAIT_REG_MEM\n");
1239 ib
[idx
+1] += (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1240 ib
[idx
+2] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1243 case PACKET3_SURFACE_SYNC
:
1244 if (pkt
->count
!= 3) {
1245 DRM_ERROR("bad SURFACE_SYNC\n");
1248 /* 0xffffffff/0x0 is flush all cache flag */
1249 if (radeon_get_ib_value(p
, idx
+ 1) != 0xffffffff ||
1250 radeon_get_ib_value(p
, idx
+ 2) != 0) {
1251 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1253 DRM_ERROR("bad SURFACE_SYNC\n");
1256 ib
[idx
+2] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
1259 case PACKET3_EVENT_WRITE
:
1260 if (pkt
->count
!= 2 && pkt
->count
!= 0) {
1261 DRM_ERROR("bad EVENT_WRITE\n");
1265 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1267 DRM_ERROR("bad EVENT_WRITE\n");
1270 ib
[idx
+1] += (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1271 ib
[idx
+2] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1274 case PACKET3_EVENT_WRITE_EOP
:
1275 if (pkt
->count
!= 4) {
1276 DRM_ERROR("bad EVENT_WRITE_EOP\n");
1279 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1281 DRM_ERROR("bad EVENT_WRITE_EOP\n");
1284 ib
[idx
+1] += (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1285 ib
[idx
+2] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1287 case PACKET3_EVENT_WRITE_EOS
:
1288 if (pkt
->count
!= 3) {
1289 DRM_ERROR("bad EVENT_WRITE_EOS\n");
1292 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1294 DRM_ERROR("bad EVENT_WRITE_EOS\n");
1297 ib
[idx
+1] += (u32
)(reloc
->lobj
.gpu_offset
& 0xffffffff);
1298 ib
[idx
+2] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1300 case PACKET3_SET_CONFIG_REG
:
1301 start_reg
= (idx_value
<< 2) + PACKET3_SET_CONFIG_REG_START
;
1302 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1303 if ((start_reg
< PACKET3_SET_CONFIG_REG_START
) ||
1304 (start_reg
>= PACKET3_SET_CONFIG_REG_END
) ||
1305 (end_reg
>= PACKET3_SET_CONFIG_REG_END
)) {
1306 DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
1309 for (i
= 0; i
< pkt
->count
; i
++) {
1310 reg
= start_reg
+ (4 * i
);
1311 r
= evergreen_cs_check_reg(p
, reg
, idx
+1+i
);
1316 case PACKET3_SET_CONTEXT_REG
:
1317 start_reg
= (idx_value
<< 2) + PACKET3_SET_CONTEXT_REG_START
;
1318 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1319 if ((start_reg
< PACKET3_SET_CONTEXT_REG_START
) ||
1320 (start_reg
>= PACKET3_SET_CONTEXT_REG_END
) ||
1321 (end_reg
>= PACKET3_SET_CONTEXT_REG_END
)) {
1322 DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
1325 for (i
= 0; i
< pkt
->count
; i
++) {
1326 reg
= start_reg
+ (4 * i
);
1327 r
= evergreen_cs_check_reg(p
, reg
, idx
+1+i
);
1332 case PACKET3_SET_RESOURCE
:
1333 if (pkt
->count
% 8) {
1334 DRM_ERROR("bad SET_RESOURCE\n");
1337 start_reg
= (idx_value
<< 2) + PACKET3_SET_RESOURCE_START
;
1338 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1339 if ((start_reg
< PACKET3_SET_RESOURCE_START
) ||
1340 (start_reg
>= PACKET3_SET_RESOURCE_END
) ||
1341 (end_reg
>= PACKET3_SET_RESOURCE_END
)) {
1342 DRM_ERROR("bad SET_RESOURCE\n");
1345 for (i
= 0; i
< (pkt
->count
/ 8); i
++) {
1346 struct radeon_bo
*texture
, *mipmap
;
1349 switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p
, idx
+1+(i
*8)+7))) {
1350 case SQ_TEX_VTX_VALID_TEXTURE
:
1352 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1354 DRM_ERROR("bad SET_RESOURCE (tex)\n");
1357 ib
[idx
+1+(i
*8)+2] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
1358 if (!p
->keep_tiling_flags
) {
1359 ib
[idx
+1+(i
*8)+1] |=
1360 TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc
->lobj
.tiling_flags
));
1361 if (reloc
->lobj
.tiling_flags
& RADEON_TILING_MACRO
) {
1362 ib
[idx
+1+(i
*8)+6] |=
1363 TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track
->row_size
));
1364 ib
[idx
+1+(i
*8)+7] |=
1365 TEX_NUM_BANKS(evergreen_cs_get_num_banks(track
->nbanks
));
1368 texture
= reloc
->robj
;
1370 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1372 DRM_ERROR("bad SET_RESOURCE (tex)\n");
1375 ib
[idx
+1+(i
*8)+3] += (u32
)((reloc
->lobj
.gpu_offset
>> 8) & 0xffffffff);
1376 mipmap
= reloc
->robj
;
1377 r
= evergreen_check_texture_resource(p
, idx
+1+(i
*8),
1382 case SQ_TEX_VTX_VALID_BUFFER
:
1384 r
= evergreen_cs_packet_next_reloc(p
, &reloc
);
1386 DRM_ERROR("bad SET_RESOURCE (vtx)\n");
1389 offset
= radeon_get_ib_value(p
, idx
+1+(i
*8)+0);
1390 size
= radeon_get_ib_value(p
, idx
+1+(i
*8)+1);
1391 if (p
->rdev
&& (size
+ offset
) > radeon_bo_size(reloc
->robj
)) {
1392 /* force size to size of the buffer */
1393 dev_warn(p
->dev
, "vbo resource seems too big for the bo\n");
1394 ib
[idx
+1+(i
*8)+1] = radeon_bo_size(reloc
->robj
);
1396 ib
[idx
+1+(i
*8)+0] += (u32
)((reloc
->lobj
.gpu_offset
) & 0xffffffff);
1397 ib
[idx
+1+(i
*8)+2] += upper_32_bits(reloc
->lobj
.gpu_offset
) & 0xff;
1399 case SQ_TEX_VTX_INVALID_TEXTURE
:
1400 case SQ_TEX_VTX_INVALID_BUFFER
:
1402 DRM_ERROR("bad SET_RESOURCE\n");
1407 case PACKET3_SET_ALU_CONST
:
1408 /* XXX fix me ALU const buffers only */
1410 case PACKET3_SET_BOOL_CONST
:
1411 start_reg
= (idx_value
<< 2) + PACKET3_SET_BOOL_CONST_START
;
1412 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1413 if ((start_reg
< PACKET3_SET_BOOL_CONST_START
) ||
1414 (start_reg
>= PACKET3_SET_BOOL_CONST_END
) ||
1415 (end_reg
>= PACKET3_SET_BOOL_CONST_END
)) {
1416 DRM_ERROR("bad SET_BOOL_CONST\n");
1420 case PACKET3_SET_LOOP_CONST
:
1421 start_reg
= (idx_value
<< 2) + PACKET3_SET_LOOP_CONST_START
;
1422 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1423 if ((start_reg
< PACKET3_SET_LOOP_CONST_START
) ||
1424 (start_reg
>= PACKET3_SET_LOOP_CONST_END
) ||
1425 (end_reg
>= PACKET3_SET_LOOP_CONST_END
)) {
1426 DRM_ERROR("bad SET_LOOP_CONST\n");
1430 case PACKET3_SET_CTL_CONST
:
1431 start_reg
= (idx_value
<< 2) + PACKET3_SET_CTL_CONST_START
;
1432 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1433 if ((start_reg
< PACKET3_SET_CTL_CONST_START
) ||
1434 (start_reg
>= PACKET3_SET_CTL_CONST_END
) ||
1435 (end_reg
>= PACKET3_SET_CTL_CONST_END
)) {
1436 DRM_ERROR("bad SET_CTL_CONST\n");
1440 case PACKET3_SET_SAMPLER
:
1441 if (pkt
->count
% 3) {
1442 DRM_ERROR("bad SET_SAMPLER\n");
1445 start_reg
= (idx_value
<< 2) + PACKET3_SET_SAMPLER_START
;
1446 end_reg
= 4 * pkt
->count
+ start_reg
- 4;
1447 if ((start_reg
< PACKET3_SET_SAMPLER_START
) ||
1448 (start_reg
>= PACKET3_SET_SAMPLER_END
) ||
1449 (end_reg
>= PACKET3_SET_SAMPLER_END
)) {
1450 DRM_ERROR("bad SET_SAMPLER\n");
1457 DRM_ERROR("Packet3 opcode %x not supported\n", pkt
->opcode
);
1463 int evergreen_cs_parse(struct radeon_cs_parser
*p
)
1465 struct radeon_cs_packet pkt
;
1466 struct evergreen_cs_track
*track
;
1470 if (p
->track
== NULL
) {
1471 /* initialize tracker, we are in kms */
1472 track
= kzalloc(sizeof(*track
), GFP_KERNEL
);
1475 evergreen_cs_track_init(track
);
1476 if (p
->rdev
->family
>= CHIP_CAYMAN
)
1477 tmp
= p
->rdev
->config
.cayman
.tile_config
;
1479 tmp
= p
->rdev
->config
.evergreen
.tile_config
;
1481 switch (tmp
& 0xf) {
1497 switch ((tmp
& 0xf0) >> 4) {
1510 switch ((tmp
& 0xf00) >> 8) {
1512 track
->group_size
= 256;
1516 track
->group_size
= 512;
1520 switch ((tmp
& 0xf000) >> 12) {
1522 track
->row_size
= 1;
1526 track
->row_size
= 2;
1529 track
->row_size
= 4;
1536 r
= evergreen_cs_packet_parse(p
, &pkt
, p
->idx
);
1542 p
->idx
+= pkt
.count
+ 2;
1545 r
= evergreen_cs_parse_packet0(p
, &pkt
);
1550 r
= evergreen_packet3_check(p
, &pkt
);
1553 DRM_ERROR("Unknown packet type %d !\n", pkt
.type
);
1563 } while (p
->idx
< p
->chunks
[p
->chunk_ib_idx
].length_dw
);
1565 for (r
= 0; r
< p
->ib
->length_dw
; r
++) {
1566 printk(KERN_INFO
"%05d 0x%08X\n", r
, p
->ib
->ptr
[r
]);