1 /*
2  * Copyright 2010 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  * Copyright 2009 Jerome Glisse.
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 shall be included in
14  * all copies or substantial portions of the 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  * 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.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  *          Jerome Glisse
27  */
28 #include "drmP.h"
29 #include "radeon.h"
30 #include "evergreend.h"
31 #include "evergreen_reg_safe.h"
32 #include "cayman_reg_safe.h"
33 
34 static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
35 					  struct radeon_cs_reloc **cs_reloc);
36 
37 struct evergreen_cs_track {
38 	u32			group_size;
39 	u32			nbanks;
40 	u32			npipes;
41 	u32			row_size;
42 	/* value we track */
43 	u32			nsamples;
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];
54 	u32			cb_color_dim[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];
59 	u32			cb_target_mask;
60 	u32			cb_shader_mask;
61 	u32			vgt_strmout_config;
62 	u32			vgt_strmout_buffer_config;
63 	u32			db_depth_control;
64 	u32			db_depth_view;
65 	u32			db_depth_size;
66 	u32			db_depth_size_idx;
67 	u32			db_z_info;
68 	u32			db_z_idx;
69 	u32			db_z_read_offset;
70 	u32			db_z_write_offset;
71 	struct radeon_bo	*db_z_read_bo;
72 	struct radeon_bo	*db_z_write_bo;
73 	u32			db_s_info;
74 	u32			db_s_idx;
75 	u32			db_s_read_offset;
76 	u32			db_s_write_offset;
77 	struct radeon_bo	*db_s_read_bo;
78 	struct radeon_bo	*db_s_write_bo;
79 };
80 
evergreen_cs_get_aray_mode(u32 tiling_flags)81 static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
82 {
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;
87 	else
88 		return ARRAY_LINEAR_GENERAL;
89 }
90 
evergreen_cs_get_num_banks(u32 nbanks)91 static u32 evergreen_cs_get_num_banks(u32 nbanks)
92 {
93 	switch (nbanks) {
94 	case 2:
95 		return ADDR_SURF_2_BANK;
96 	case 4:
97 		return ADDR_SURF_4_BANK;
98 	case 8:
99 	default:
100 		return ADDR_SURF_8_BANK;
101 	case 16:
102 		return ADDR_SURF_16_BANK;
103 	}
104 }
105 
evergreen_cs_get_tile_split(u32 row_size)106 static u32 evergreen_cs_get_tile_split(u32 row_size)
107 {
108 	switch (row_size) {
109 	case 1:
110 	default:
111 		return ADDR_SURF_TILE_SPLIT_1KB;
112 	case 2:
113 		return ADDR_SURF_TILE_SPLIT_2KB;
114 	case 4:
115 		return ADDR_SURF_TILE_SPLIT_4KB;
116 	}
117 }
118 
evergreen_cs_track_init(struct evergreen_cs_track * track)119 static void evergreen_cs_track_init(struct evergreen_cs_track *track)
120 {
121 	int i;
122 
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;
128 	}
129 
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;
142 	}
143 	track->cb_target_mask = 0xFFFFFFFF;
144 	track->cb_shader_mask = 0xFFFFFFFF;
145 
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;
162 }
163 
evergreen_cs_track_check(struct radeon_cs_parser * p)164 static int evergreen_cs_track_check(struct radeon_cs_parser *p)
165 {
166 	struct evergreen_cs_track *track = p->track;
167 
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");
171 		return -EINVAL;
172 	}
173 
174 	/* XXX fill in */
175 	return 0;
176 }
177 
178 /**
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
182  *
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.
185  **/
evergreen_cs_packet_parse(struct radeon_cs_parser * p,struct radeon_cs_packet * pkt,unsigned idx)186 int evergreen_cs_packet_parse(struct radeon_cs_parser *p,
187 			      struct radeon_cs_packet *pkt,
188 			      unsigned idx)
189 {
190 	struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
191 	uint32_t header;
192 
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);
196 		return -EINVAL;
197 	}
198 	header = radeon_get_ib_value(p, idx);
199 	pkt->idx = idx;
200 	pkt->type = CP_PACKET_GET_TYPE(header);
201 	pkt->count = CP_PACKET_GET_COUNT(header);
202 	pkt->one_reg_wr = 0;
203 	switch (pkt->type) {
204 	case PACKET_TYPE0:
205 		pkt->reg = CP_PACKET0_GET_REG(header);
206 		break;
207 	case PACKET_TYPE3:
208 		pkt->opcode = CP_PACKET3_GET_OPCODE(header);
209 		break;
210 	case PACKET_TYPE2:
211 		pkt->count = -1;
212 		break;
213 	default:
214 		DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
215 		return -EINVAL;
216 	}
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);
220 		return -EINVAL;
221 	}
222 	return 0;
223 }
224 
225 /**
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
232  *
233  * Check next packet is relocation packet3, do bo validation and compute
234  * GPU offset using the provided start.
235  **/
evergreen_cs_packet_next_reloc(struct radeon_cs_parser * p,struct radeon_cs_reloc ** cs_reloc)236 static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p,
237 					  struct radeon_cs_reloc **cs_reloc)
238 {
239 	struct radeon_cs_chunk *relocs_chunk;
240 	struct radeon_cs_packet p3reloc;
241 	unsigned idx;
242 	int r;
243 
244 	if (p->chunk_relocs_idx == -1) {
245 		DRM_ERROR("No relocation chunk !\n");
246 		return -EINVAL;
247 	}
248 	*cs_reloc = NULL;
249 	relocs_chunk = &p->chunks[p->chunk_relocs_idx];
250 	r = evergreen_cs_packet_parse(p, &p3reloc, p->idx);
251 	if (r) {
252 		return r;
253 	}
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",
257 			  p3reloc.idx);
258 		return -EINVAL;
259 	}
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);
264 		return -EINVAL;
265 	}
266 	/* FIXME: we assume reloc size is 4 dwords */
267 	*cs_reloc = p->relocs_ptr[(idx / 4)];
268 	return 0;
269 }
270 
271 /**
272  * evergreen_cs_packet_next_vline() - parse userspace VLINE packet
273  * @parser:		parser structure holding parsing context.
274  *
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.
279  *
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
283  * wait in that case.
284  */
evergreen_cs_packet_parse_vline(struct radeon_cs_parser * p)285 static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p)
286 {
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;
291 	int crtc_id;
292 	int r;
293 	uint32_t header, h_idx, reg, wait_reg_mem_info;
294 	volatile uint32_t *ib;
295 
296 	ib = p->ib->ptr;
297 
298 	/* parse the WAIT_REG_MEM */
299 	r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx);
300 	if (r)
301 		return r;
302 
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");
307 		return -EINVAL;
308 	}
309 
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");
314 		return -EINVAL;
315 	}
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");
319 		return -EINVAL;
320 	}
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");
323 		return -EINVAL;
324 	}
325 
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");
328 		return -EINVAL;
329 	}
330 
331 	/* jump over the NOP */
332 	r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
333 	if (r)
334 		return r;
335 
336 	h_idx = p->idx - 2;
337 	p->idx += wait_reg_mem.count + 2;
338 	p->idx += p3reloc.count + 2;
339 
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);
344 	if (!obj) {
345 		DRM_ERROR("cannot find crtc %d\n", crtc_id);
346 		return -EINVAL;
347 	}
348 	crtc = obj_to_crtc(obj);
349 	radeon_crtc = to_radeon_crtc(crtc);
350 	crtc_id = radeon_crtc->crtc_id;
351 
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);
361 	} else {
362 		switch (reg) {
363 		case EVERGREEN_VLINE_START_END:
364 			header &= ~R600_CP_PACKET0_REG_MASK;
365 			header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2;
366 			ib[h_idx] = header;
367 			ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2;
368 			break;
369 		default:
370 			DRM_ERROR("unknown crtc reloc\n");
371 			return -EINVAL;
372 		}
373 	}
374 	return 0;
375 }
376 
evergreen_packet0_check(struct radeon_cs_parser * p,struct radeon_cs_packet * pkt,unsigned idx,unsigned reg)377 static int evergreen_packet0_check(struct radeon_cs_parser *p,
378 				   struct radeon_cs_packet *pkt,
379 				   unsigned idx, unsigned reg)
380 {
381 	int r;
382 
383 	switch (reg) {
384 	case EVERGREEN_VLINE_START_END:
385 		r = evergreen_cs_packet_parse_vline(p);
386 		if (r) {
387 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
388 					idx, reg);
389 			return r;
390 		}
391 		break;
392 	default:
393 		printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
394 		       reg, idx);
395 		return -EINVAL;
396 	}
397 	return 0;
398 }
399 
evergreen_cs_parse_packet0(struct radeon_cs_parser * p,struct radeon_cs_packet * pkt)400 static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p,
401 				      struct radeon_cs_packet *pkt)
402 {
403 	unsigned reg, i;
404 	unsigned idx;
405 	int r;
406 
407 	idx = pkt->idx + 1;
408 	reg = pkt->reg;
409 	for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
410 		r = evergreen_packet0_check(p, pkt, idx, reg);
411 		if (r) {
412 			return r;
413 		}
414 	}
415 	return 0;
416 }
417 
418 /**
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
423  *
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.
427  */
evergreen_cs_check_reg(struct radeon_cs_parser * p,u32 reg,u32 idx)428 static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
429 {
430 	struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
431 	struct radeon_cs_reloc *reloc;
432 	u32 last_reg;
433 	u32 m, i, tmp, *ib;
434 	int r;
435 
436 	if (p->rdev->family >= CHIP_CAYMAN)
437 		last_reg = ARRAY_SIZE(cayman_reg_safe_bm);
438 	else
439 		last_reg = ARRAY_SIZE(evergreen_reg_safe_bm);
440 
441 	i = (reg >> 7);
442 	if (i >= last_reg) {
443 		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
444 		return -EINVAL;
445 	}
446 	m = 1 << ((reg >> 2) & 31);
447 	if (p->rdev->family >= CHIP_CAYMAN) {
448 		if (!(cayman_reg_safe_bm[i] & m))
449 			return 0;
450 	} else {
451 		if (!(evergreen_reg_safe_bm[i] & m))
452 			return 0;
453 	}
454 	ib = p->ib->ptr;
455 	switch (reg) {
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)
459 	 */
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);
486 		  ib[idx] = 0;*/
487 		break;
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);
497 		if (r) {
498 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
499 					"0x%04X\n", reg);
500 			return -EINVAL;
501 		}
502 		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
503 		break;
504 	case DB_DEPTH_CONTROL:
505 		track->db_depth_control = radeon_get_ib_value(p, idx);
506 		break;
507 	case CAYMAN_DB_EQAA:
508 		if (p->rdev->family < CHIP_CAYMAN) {
509 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
510 				 "0x%04X\n", reg);
511 			return -EINVAL;
512 		}
513 		break;
514 	case CAYMAN_DB_DEPTH_INFO:
515 		if (p->rdev->family < CHIP_CAYMAN) {
516 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
517 				 "0x%04X\n", reg);
518 			return -EINVAL;
519 		}
520 		break;
521 	case DB_Z_INFO:
522 		track->db_z_info = radeon_get_ib_value(p, idx);
523 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
524 			r = evergreen_cs_packet_next_reloc(p, &reloc);
525 			if (r) {
526 				dev_warn(p->dev, "bad SET_CONTEXT_REG "
527 						"0x%04X\n", reg);
528 				return -EINVAL;
529 			}
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));
537 			}
538 		}
539 		break;
540 	case DB_STENCIL_INFO:
541 		track->db_s_info = radeon_get_ib_value(p, idx);
542 		break;
543 	case DB_DEPTH_VIEW:
544 		track->db_depth_view = radeon_get_ib_value(p, idx);
545 		break;
546 	case DB_DEPTH_SIZE:
547 		track->db_depth_size = radeon_get_ib_value(p, idx);
548 		track->db_depth_size_idx = idx;
549 		break;
550 	case DB_Z_READ_BASE:
551 		r = evergreen_cs_packet_next_reloc(p, &reloc);
552 		if (r) {
553 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
554 					"0x%04X\n", reg);
555 			return -EINVAL;
556 		}
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;
560 		break;
561 	case DB_Z_WRITE_BASE:
562 		r = evergreen_cs_packet_next_reloc(p, &reloc);
563 		if (r) {
564 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
565 					"0x%04X\n", reg);
566 			return -EINVAL;
567 		}
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;
571 		break;
572 	case DB_STENCIL_READ_BASE:
573 		r = evergreen_cs_packet_next_reloc(p, &reloc);
574 		if (r) {
575 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
576 					"0x%04X\n", reg);
577 			return -EINVAL;
578 		}
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;
582 		break;
583 	case DB_STENCIL_WRITE_BASE:
584 		r = evergreen_cs_packet_next_reloc(p, &reloc);
585 		if (r) {
586 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
587 					"0x%04X\n", reg);
588 			return -EINVAL;
589 		}
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;
593 		break;
594 	case VGT_STRMOUT_CONFIG:
595 		track->vgt_strmout_config = radeon_get_ib_value(p, idx);
596 		break;
597 	case VGT_STRMOUT_BUFFER_CONFIG:
598 		track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx);
599 		break;
600 	case CB_TARGET_MASK:
601 		track->cb_target_mask = radeon_get_ib_value(p, idx);
602 		break;
603 	case CB_SHADER_MASK:
604 		track->cb_shader_mask = radeon_get_ib_value(p, idx);
605 		break;
606 	case PA_SC_AA_CONFIG:
607 		if (p->rdev->family >= CHIP_CAYMAN) {
608 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
609 				 "0x%04X\n", reg);
610 			return -EINVAL;
611 		}
612 		tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK;
613 		track->nsamples = 1 << tmp;
614 		break;
615 	case CAYMAN_PA_SC_AA_CONFIG:
616 		if (p->rdev->family < CHIP_CAYMAN) {
617 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
618 				 "0x%04X\n", reg);
619 			return -EINVAL;
620 		}
621 		tmp = radeon_get_ib_value(p, idx) & CAYMAN_MSAA_NUM_SAMPLES_MASK;
622 		track->nsamples = 1 << tmp;
623 		break;
624 	case CB_COLOR0_VIEW:
625 	case CB_COLOR1_VIEW:
626 	case CB_COLOR2_VIEW:
627 	case CB_COLOR3_VIEW:
628 	case CB_COLOR4_VIEW:
629 	case CB_COLOR5_VIEW:
630 	case CB_COLOR6_VIEW:
631 	case CB_COLOR7_VIEW:
632 		tmp = (reg - CB_COLOR0_VIEW) / 0x3c;
633 		track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
634 		break;
635 	case CB_COLOR8_VIEW:
636 	case CB_COLOR9_VIEW:
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);
641 		break;
642 	case CB_COLOR0_INFO:
643 	case CB_COLOR1_INFO:
644 	case CB_COLOR2_INFO:
645 	case CB_COLOR3_INFO:
646 	case CB_COLOR4_INFO:
647 	case CB_COLOR5_INFO:
648 	case CB_COLOR6_INFO:
649 	case CB_COLOR7_INFO:
650 		tmp = (reg - CB_COLOR0_INFO) / 0x3c;
651 		track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
652 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
653 			r = evergreen_cs_packet_next_reloc(p, &reloc);
654 			if (r) {
655 				dev_warn(p->dev, "bad SET_CONTEXT_REG "
656 						"0x%04X\n", reg);
657 				return -EINVAL;
658 			}
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));
661 		}
662 		break;
663 	case CB_COLOR8_INFO:
664 	case CB_COLOR9_INFO:
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->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
670 			r = evergreen_cs_packet_next_reloc(p, &reloc);
671 			if (r) {
672 				dev_warn(p->dev, "bad SET_CONTEXT_REG "
673 						"0x%04X\n", reg);
674 				return -EINVAL;
675 			}
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));
678 		}
679 		break;
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;
691 		break;
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;
699 		break;
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;
711 		break;
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;
719 		break;
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);
733 		if (r) {
734 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
735 					"0x%04X\n", reg);
736 			return -EINVAL;
737 		}
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));
741 		}
742 		break;
743 	case CB_COLOR0_DIM:
744 	case CB_COLOR1_DIM:
745 	case CB_COLOR2_DIM:
746 	case CB_COLOR3_DIM:
747 	case CB_COLOR4_DIM:
748 	case CB_COLOR5_DIM:
749 	case CB_COLOR6_DIM:
750 	case CB_COLOR7_DIM:
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;
754 		break;
755 	case CB_COLOR8_DIM:
756 	case CB_COLOR9_DIM:
757 	case CB_COLOR10_DIM:
758 	case CB_COLOR11_DIM:
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;
762 		break;
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);
773 		if (r) {
774 			dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
775 			return -EINVAL;
776 		}
777 		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
778 		track->cb_color_fmask_bo[tmp] = reloc->robj;
779 		break;
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);
790 		if (r) {
791 			dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
792 			return -EINVAL;
793 		}
794 		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
795 		track->cb_color_cmask_bo[tmp] = reloc->robj;
796 		break;
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);
807 		break;
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);
818 		break;
819 	case CB_COLOR0_BASE:
820 	case CB_COLOR1_BASE:
821 	case CB_COLOR2_BASE:
822 	case CB_COLOR3_BASE:
823 	case CB_COLOR4_BASE:
824 	case CB_COLOR5_BASE:
825 	case CB_COLOR6_BASE:
826 	case CB_COLOR7_BASE:
827 		r = evergreen_cs_packet_next_reloc(p, &reloc);
828 		if (r) {
829 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
830 					"0x%04X\n", reg);
831 			return -EINVAL;
832 		}
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;
838 		break;
839 	case CB_COLOR8_BASE:
840 	case CB_COLOR9_BASE:
841 	case CB_COLOR10_BASE:
842 	case CB_COLOR11_BASE:
843 		r = evergreen_cs_packet_next_reloc(p, &reloc);
844 		if (r) {
845 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
846 					"0x%04X\n", reg);
847 			return -EINVAL;
848 		}
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;
854 		break;
855 	case CB_IMMED0_BASE:
856 	case CB_IMMED1_BASE:
857 	case CB_IMMED2_BASE:
858 	case CB_IMMED3_BASE:
859 	case CB_IMMED4_BASE:
860 	case CB_IMMED5_BASE:
861 	case CB_IMMED6_BASE:
862 	case CB_IMMED7_BASE:
863 	case CB_IMMED8_BASE:
864 	case CB_IMMED9_BASE:
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);
957 		if (r) {
958 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
959 					"0x%04X\n", reg);
960 			return -EINVAL;
961 		}
962 		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
963 		break;
964 	case SX_MEMORY_EXPORT_BASE:
965 		if (p->rdev->family >= CHIP_CAYMAN) {
966 			dev_warn(p->dev, "bad SET_CONFIG_REG "
967 				 "0x%04X\n", reg);
968 			return -EINVAL;
969 		}
970 		r = evergreen_cs_packet_next_reloc(p, &reloc);
971 		if (r) {
972 			dev_warn(p->dev, "bad SET_CONFIG_REG "
973 					"0x%04X\n", reg);
974 			return -EINVAL;
975 		}
976 		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
977 		break;
978 	case CAYMAN_SX_SCATTER_EXPORT_BASE:
979 		if (p->rdev->family < CHIP_CAYMAN) {
980 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
981 				 "0x%04X\n", reg);
982 			return -EINVAL;
983 		}
984 		r = evergreen_cs_packet_next_reloc(p, &reloc);
985 		if (r) {
986 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
987 					"0x%04X\n", reg);
988 			return -EINVAL;
989 		}
990 		ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
991 		break;
992 	default:
993 		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
994 		return -EINVAL;
995 	}
996 	return 0;
997 }
998 
999 /**
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
1005  *
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.
1008  */
evergreen_check_texture_resource(struct radeon_cs_parser * p,u32 idx,struct radeon_bo * texture,struct radeon_bo * mipmap)1009 static int evergreen_check_texture_resource(struct radeon_cs_parser *p,  u32 idx,
1010 						   struct radeon_bo *texture,
1011 						   struct radeon_bo *mipmap)
1012 {
1013 	/* XXX fill in */
1014 	return 0;
1015 }
1016 
evergreen_packet3_check(struct radeon_cs_parser * p,struct radeon_cs_packet * pkt)1017 static int evergreen_packet3_check(struct radeon_cs_parser *p,
1018 				   struct radeon_cs_packet *pkt)
1019 {
1020 	struct radeon_cs_reloc *reloc;
1021 	struct evergreen_cs_track *track;
1022 	volatile u32 *ib;
1023 	unsigned idx;
1024 	unsigned i;
1025 	unsigned start_reg, end_reg, reg;
1026 	int r;
1027 	u32 idx_value;
1028 
1029 	track = (struct evergreen_cs_track *)p->track;
1030 	ib = p->ib->ptr;
1031 	idx = pkt->idx + 1;
1032 	idx_value = radeon_get_ib_value(p, idx);
1033 
1034 	switch (pkt->opcode) {
1035 	case PACKET3_SET_PREDICATION:
1036 	{
1037 		int pred_op;
1038 		int tmp;
1039 		if (pkt->count != 1) {
1040 			DRM_ERROR("bad SET PREDICATION\n");
1041 			return -EINVAL;
1042 		}
1043 
1044 		tmp = radeon_get_ib_value(p, idx + 1);
1045 		pred_op = (tmp >> 16) & 0x7;
1046 
1047 		/* for the clear predicate operation */
1048 		if (pred_op == 0)
1049 			return 0;
1050 
1051 		if (pred_op > 2) {
1052 			DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op);
1053 			return -EINVAL;
1054 		}
1055 
1056 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1057 		if (r) {
1058 			DRM_ERROR("bad SET PREDICATION\n");
1059 			return -EINVAL;
1060 		}
1061 
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);
1064 	}
1065 	break;
1066 	case PACKET3_CONTEXT_CONTROL:
1067 		if (pkt->count != 1) {
1068 			DRM_ERROR("bad CONTEXT_CONTROL\n");
1069 			return -EINVAL;
1070 		}
1071 		break;
1072 	case PACKET3_INDEX_TYPE:
1073 	case PACKET3_NUM_INSTANCES:
1074 	case PACKET3_CLEAR_STATE:
1075 		if (pkt->count) {
1076 			DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
1077 			return -EINVAL;
1078 		}
1079 		break;
1080 	case CAYMAN_PACKET3_DEALLOC_STATE:
1081 		if (p->rdev->family < CHIP_CAYMAN) {
1082 			DRM_ERROR("bad PACKET3_DEALLOC_STATE\n");
1083 			return -EINVAL;
1084 		}
1085 		if (pkt->count) {
1086 			DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
1087 			return -EINVAL;
1088 		}
1089 		break;
1090 	case PACKET3_INDEX_BASE:
1091 		if (pkt->count != 1) {
1092 			DRM_ERROR("bad INDEX_BASE\n");
1093 			return -EINVAL;
1094 		}
1095 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1096 		if (r) {
1097 			DRM_ERROR("bad INDEX_BASE\n");
1098 			return -EINVAL;
1099 		}
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);
1103 		if (r) {
1104 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1105 			return r;
1106 		}
1107 		break;
1108 	case PACKET3_DRAW_INDEX:
1109 		if (pkt->count != 3) {
1110 			DRM_ERROR("bad DRAW_INDEX\n");
1111 			return -EINVAL;
1112 		}
1113 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1114 		if (r) {
1115 			DRM_ERROR("bad DRAW_INDEX\n");
1116 			return -EINVAL;
1117 		}
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);
1121 		if (r) {
1122 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1123 			return r;
1124 		}
1125 		break;
1126 	case PACKET3_DRAW_INDEX_2:
1127 		if (pkt->count != 4) {
1128 			DRM_ERROR("bad DRAW_INDEX_2\n");
1129 			return -EINVAL;
1130 		}
1131 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1132 		if (r) {
1133 			DRM_ERROR("bad DRAW_INDEX_2\n");
1134 			return -EINVAL;
1135 		}
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);
1139 		if (r) {
1140 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1141 			return r;
1142 		}
1143 		break;
1144 	case PACKET3_DRAW_INDEX_AUTO:
1145 		if (pkt->count != 1) {
1146 			DRM_ERROR("bad DRAW_INDEX_AUTO\n");
1147 			return -EINVAL;
1148 		}
1149 		r = evergreen_cs_track_check(p);
1150 		if (r) {
1151 			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
1152 			return r;
1153 		}
1154 		break;
1155 	case PACKET3_DRAW_INDEX_MULTI_AUTO:
1156 		if (pkt->count != 2) {
1157 			DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n");
1158 			return -EINVAL;
1159 		}
1160 		r = evergreen_cs_track_check(p);
1161 		if (r) {
1162 			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
1163 			return r;
1164 		}
1165 		break;
1166 	case PACKET3_DRAW_INDEX_IMMD:
1167 		if (pkt->count < 2) {
1168 			DRM_ERROR("bad DRAW_INDEX_IMMD\n");
1169 			return -EINVAL;
1170 		}
1171 		r = evergreen_cs_track_check(p);
1172 		if (r) {
1173 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1174 			return r;
1175 		}
1176 		break;
1177 	case PACKET3_DRAW_INDEX_OFFSET:
1178 		if (pkt->count != 2) {
1179 			DRM_ERROR("bad DRAW_INDEX_OFFSET\n");
1180 			return -EINVAL;
1181 		}
1182 		r = evergreen_cs_track_check(p);
1183 		if (r) {
1184 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1185 			return r;
1186 		}
1187 		break;
1188 	case PACKET3_DRAW_INDEX_OFFSET_2:
1189 		if (pkt->count != 3) {
1190 			DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n");
1191 			return -EINVAL;
1192 		}
1193 		r = evergreen_cs_track_check(p);
1194 		if (r) {
1195 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1196 			return r;
1197 		}
1198 		break;
1199 	case PACKET3_DISPATCH_DIRECT:
1200 		if (pkt->count != 3) {
1201 			DRM_ERROR("bad DISPATCH_DIRECT\n");
1202 			return -EINVAL;
1203 		}
1204 		r = evergreen_cs_track_check(p);
1205 		if (r) {
1206 			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
1207 			return r;
1208 		}
1209 		break;
1210 	case PACKET3_DISPATCH_INDIRECT:
1211 		if (pkt->count != 1) {
1212 			DRM_ERROR("bad DISPATCH_INDIRECT\n");
1213 			return -EINVAL;
1214 		}
1215 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1216 		if (r) {
1217 			DRM_ERROR("bad DISPATCH_INDIRECT\n");
1218 			return -EINVAL;
1219 		}
1220 		ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1221 		r = evergreen_cs_track_check(p);
1222 		if (r) {
1223 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
1224 			return r;
1225 		}
1226 		break;
1227 	case PACKET3_WAIT_REG_MEM:
1228 		if (pkt->count != 5) {
1229 			DRM_ERROR("bad WAIT_REG_MEM\n");
1230 			return -EINVAL;
1231 		}
1232 		/* bit 4 is reg (0) or mem (1) */
1233 		if (idx_value & 0x10) {
1234 			r = evergreen_cs_packet_next_reloc(p, &reloc);
1235 			if (r) {
1236 				DRM_ERROR("bad WAIT_REG_MEM\n");
1237 				return -EINVAL;
1238 			}
1239 			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1240 			ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1241 		}
1242 		break;
1243 	case PACKET3_SURFACE_SYNC:
1244 		if (pkt->count != 3) {
1245 			DRM_ERROR("bad SURFACE_SYNC\n");
1246 			return -EINVAL;
1247 		}
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);
1252 			if (r) {
1253 				DRM_ERROR("bad SURFACE_SYNC\n");
1254 				return -EINVAL;
1255 			}
1256 			ib[idx+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1257 		}
1258 		break;
1259 	case PACKET3_EVENT_WRITE:
1260 		if (pkt->count != 2 && pkt->count != 0) {
1261 			DRM_ERROR("bad EVENT_WRITE\n");
1262 			return -EINVAL;
1263 		}
1264 		if (pkt->count) {
1265 			r = evergreen_cs_packet_next_reloc(p, &reloc);
1266 			if (r) {
1267 				DRM_ERROR("bad EVENT_WRITE\n");
1268 				return -EINVAL;
1269 			}
1270 			ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1271 			ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1272 		}
1273 		break;
1274 	case PACKET3_EVENT_WRITE_EOP:
1275 		if (pkt->count != 4) {
1276 			DRM_ERROR("bad EVENT_WRITE_EOP\n");
1277 			return -EINVAL;
1278 		}
1279 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1280 		if (r) {
1281 			DRM_ERROR("bad EVENT_WRITE_EOP\n");
1282 			return -EINVAL;
1283 		}
1284 		ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1285 		ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1286 		break;
1287 	case PACKET3_EVENT_WRITE_EOS:
1288 		if (pkt->count != 3) {
1289 			DRM_ERROR("bad EVENT_WRITE_EOS\n");
1290 			return -EINVAL;
1291 		}
1292 		r = evergreen_cs_packet_next_reloc(p, &reloc);
1293 		if (r) {
1294 			DRM_ERROR("bad EVENT_WRITE_EOS\n");
1295 			return -EINVAL;
1296 		}
1297 		ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
1298 		ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
1299 		break;
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");
1307 			return -EINVAL;
1308 		}
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);
1312 			if (r)
1313 				return r;
1314 		}
1315 		break;
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");
1323 			return -EINVAL;
1324 		}
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);
1328 			if (r)
1329 				return r;
1330 		}
1331 		break;
1332 	case PACKET3_SET_RESOURCE:
1333 		if (pkt->count % 8) {
1334 			DRM_ERROR("bad SET_RESOURCE\n");
1335 			return -EINVAL;
1336 		}
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");
1343 			return -EINVAL;
1344 		}
1345 		for (i = 0; i < (pkt->count / 8); i++) {
1346 			struct radeon_bo *texture, *mipmap;
1347 			u32 size, offset;
1348 
1349 			switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
1350 			case SQ_TEX_VTX_VALID_TEXTURE:
1351 				/* tex base */
1352 				r = evergreen_cs_packet_next_reloc(p, &reloc);
1353 				if (r) {
1354 					DRM_ERROR("bad SET_RESOURCE (tex)\n");
1355 					return -EINVAL;
1356 				}
1357 				ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1358 				if (!(p->cs_flags & RADEON_CS_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));
1366 					}
1367 				}
1368 				texture = reloc->robj;
1369 				/* tex mip base */
1370 				r = evergreen_cs_packet_next_reloc(p, &reloc);
1371 				if (r) {
1372 					DRM_ERROR("bad SET_RESOURCE (tex)\n");
1373 					return -EINVAL;
1374 				}
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),
1378 						texture, mipmap);
1379 				if (r)
1380 					return r;
1381 				break;
1382 			case SQ_TEX_VTX_VALID_BUFFER:
1383 				/* vtx base */
1384 				r = evergreen_cs_packet_next_reloc(p, &reloc);
1385 				if (r) {
1386 					DRM_ERROR("bad SET_RESOURCE (vtx)\n");
1387 					return -EINVAL;
1388 				}
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);
1395 				}
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;
1398 				break;
1399 			case SQ_TEX_VTX_INVALID_TEXTURE:
1400 			case SQ_TEX_VTX_INVALID_BUFFER:
1401 			default:
1402 				DRM_ERROR("bad SET_RESOURCE\n");
1403 				return -EINVAL;
1404 			}
1405 		}
1406 		break;
1407 	case PACKET3_SET_ALU_CONST:
1408 		/* XXX fix me ALU const buffers only */
1409 		break;
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");
1417 			return -EINVAL;
1418 		}
1419 		break;
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");
1427 			return -EINVAL;
1428 		}
1429 		break;
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");
1437 			return -EINVAL;
1438 		}
1439 		break;
1440 	case PACKET3_SET_SAMPLER:
1441 		if (pkt->count % 3) {
1442 			DRM_ERROR("bad SET_SAMPLER\n");
1443 			return -EINVAL;
1444 		}
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");
1451 			return -EINVAL;
1452 		}
1453 		break;
1454 	case PACKET3_NOP:
1455 		break;
1456 	default:
1457 		DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
1458 		return -EINVAL;
1459 	}
1460 	return 0;
1461 }
1462 
evergreen_cs_parse(struct radeon_cs_parser * p)1463 int evergreen_cs_parse(struct radeon_cs_parser *p)
1464 {
1465 	struct radeon_cs_packet pkt;
1466 	struct evergreen_cs_track *track;
1467 	u32 tmp;
1468 	int r;
1469 
1470 	if (p->track == NULL) {
1471 		/* initialize tracker, we are in kms */
1472 		track = kzalloc(sizeof(*track), GFP_KERNEL);
1473 		if (track == NULL)
1474 			return -ENOMEM;
1475 		evergreen_cs_track_init(track);
1476 		if (p->rdev->family >= CHIP_CAYMAN)
1477 			tmp = p->rdev->config.cayman.tile_config;
1478 		else
1479 			tmp = p->rdev->config.evergreen.tile_config;
1480 
1481 		switch (tmp & 0xf) {
1482 		case 0:
1483 			track->npipes = 1;
1484 			break;
1485 		case 1:
1486 		default:
1487 			track->npipes = 2;
1488 			break;
1489 		case 2:
1490 			track->npipes = 4;
1491 			break;
1492 		case 3:
1493 			track->npipes = 8;
1494 			break;
1495 		}
1496 
1497 		switch ((tmp & 0xf0) >> 4) {
1498 		case 0:
1499 			track->nbanks = 4;
1500 			break;
1501 		case 1:
1502 		default:
1503 			track->nbanks = 8;
1504 			break;
1505 		case 2:
1506 			track->nbanks = 16;
1507 			break;
1508 		}
1509 
1510 		switch ((tmp & 0xf00) >> 8) {
1511 		case 0:
1512 			track->group_size = 256;
1513 			break;
1514 		case 1:
1515 		default:
1516 			track->group_size = 512;
1517 			break;
1518 		}
1519 
1520 		switch ((tmp & 0xf000) >> 12) {
1521 		case 0:
1522 			track->row_size = 1;
1523 			break;
1524 		case 1:
1525 		default:
1526 			track->row_size = 2;
1527 			break;
1528 		case 2:
1529 			track->row_size = 4;
1530 			break;
1531 		}
1532 
1533 		p->track = track;
1534 	}
1535 	do {
1536 		r = evergreen_cs_packet_parse(p, &pkt, p->idx);
1537 		if (r) {
1538 			kfree(p->track);
1539 			p->track = NULL;
1540 			return r;
1541 		}
1542 		p->idx += pkt.count + 2;
1543 		switch (pkt.type) {
1544 		case PACKET_TYPE0:
1545 			r = evergreen_cs_parse_packet0(p, &pkt);
1546 			break;
1547 		case PACKET_TYPE2:
1548 			break;
1549 		case PACKET_TYPE3:
1550 			r = evergreen_packet3_check(p, &pkt);
1551 			break;
1552 		default:
1553 			DRM_ERROR("Unknown packet type %d !\n", pkt.type);
1554 			kfree(p->track);
1555 			p->track = NULL;
1556 			return -EINVAL;
1557 		}
1558 		if (r) {
1559 			kfree(p->track);
1560 			p->track = NULL;
1561 			return r;
1562 		}
1563 	} while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
1564 #if 0
1565 	for (r = 0; r < p->ib->length_dw; r++) {
1566 		printk(KERN_INFO "%05d  0x%08X\n", r, p->ib->ptr[r]);
1567 		mdelay(1);
1568 	}
1569 #endif
1570 	kfree(p->track);
1571 	p->track = NULL;
1572 	return 0;
1573 }
1574 
1575 /* vm parser */
evergreen_vm_reg_valid(u32 reg)1576 static bool evergreen_vm_reg_valid(u32 reg)
1577 {
1578 	/* context regs are fine */
1579 	if (reg >= 0x28000)
1580 		return true;
1581 
1582 	/* check config regs */
1583 	switch (reg) {
1584 	case GRBM_GFX_INDEX:
1585 	case VGT_VTX_VECT_EJECT_REG:
1586 	case VGT_CACHE_INVALIDATION:
1587 	case VGT_GS_VERTEX_REUSE:
1588 	case VGT_PRIMITIVE_TYPE:
1589 	case VGT_INDEX_TYPE:
1590 	case VGT_NUM_INDICES:
1591 	case VGT_NUM_INSTANCES:
1592 	case VGT_COMPUTE_DIM_X:
1593 	case VGT_COMPUTE_DIM_Y:
1594 	case VGT_COMPUTE_DIM_Z:
1595 	case VGT_COMPUTE_START_X:
1596 	case VGT_COMPUTE_START_Y:
1597 	case VGT_COMPUTE_START_Z:
1598 	case VGT_COMPUTE_INDEX:
1599 	case VGT_COMPUTE_THREAD_GROUP_SIZE:
1600 	case VGT_HS_OFFCHIP_PARAM:
1601 	case PA_CL_ENHANCE:
1602 	case PA_SU_LINE_STIPPLE_VALUE:
1603 	case PA_SC_LINE_STIPPLE_STATE:
1604 	case PA_SC_ENHANCE:
1605 	case SQ_DYN_GPR_CNTL_PS_FLUSH_REQ:
1606 	case SQ_DYN_GPR_SIMD_LOCK_EN:
1607 	case SQ_CONFIG:
1608 	case SQ_GPR_RESOURCE_MGMT_1:
1609 	case SQ_GLOBAL_GPR_RESOURCE_MGMT_1:
1610 	case SQ_GLOBAL_GPR_RESOURCE_MGMT_2:
1611 	case SQ_CONST_MEM_BASE:
1612 	case SQ_STATIC_THREAD_MGMT_1:
1613 	case SQ_STATIC_THREAD_MGMT_2:
1614 	case SQ_STATIC_THREAD_MGMT_3:
1615 	case SPI_CONFIG_CNTL:
1616 	case SPI_CONFIG_CNTL_1:
1617 	case TA_CNTL_AUX:
1618 	case DB_DEBUG:
1619 	case DB_DEBUG2:
1620 	case DB_DEBUG3:
1621 	case DB_DEBUG4:
1622 	case DB_WATERMARKS:
1623 	case TD_PS_BORDER_COLOR_INDEX:
1624 	case TD_PS_BORDER_COLOR_RED:
1625 	case TD_PS_BORDER_COLOR_GREEN:
1626 	case TD_PS_BORDER_COLOR_BLUE:
1627 	case TD_PS_BORDER_COLOR_ALPHA:
1628 	case TD_VS_BORDER_COLOR_INDEX:
1629 	case TD_VS_BORDER_COLOR_RED:
1630 	case TD_VS_BORDER_COLOR_GREEN:
1631 	case TD_VS_BORDER_COLOR_BLUE:
1632 	case TD_VS_BORDER_COLOR_ALPHA:
1633 	case TD_GS_BORDER_COLOR_INDEX:
1634 	case TD_GS_BORDER_COLOR_RED:
1635 	case TD_GS_BORDER_COLOR_GREEN:
1636 	case TD_GS_BORDER_COLOR_BLUE:
1637 	case TD_GS_BORDER_COLOR_ALPHA:
1638 	case TD_HS_BORDER_COLOR_INDEX:
1639 	case TD_HS_BORDER_COLOR_RED:
1640 	case TD_HS_BORDER_COLOR_GREEN:
1641 	case TD_HS_BORDER_COLOR_BLUE:
1642 	case TD_HS_BORDER_COLOR_ALPHA:
1643 	case TD_LS_BORDER_COLOR_INDEX:
1644 	case TD_LS_BORDER_COLOR_RED:
1645 	case TD_LS_BORDER_COLOR_GREEN:
1646 	case TD_LS_BORDER_COLOR_BLUE:
1647 	case TD_LS_BORDER_COLOR_ALPHA:
1648 	case TD_CS_BORDER_COLOR_INDEX:
1649 	case TD_CS_BORDER_COLOR_RED:
1650 	case TD_CS_BORDER_COLOR_GREEN:
1651 	case TD_CS_BORDER_COLOR_BLUE:
1652 	case TD_CS_BORDER_COLOR_ALPHA:
1653 	case SQ_ESGS_RING_SIZE:
1654 	case SQ_GSVS_RING_SIZE:
1655 	case SQ_ESTMP_RING_SIZE:
1656 	case SQ_GSTMP_RING_SIZE:
1657 	case SQ_HSTMP_RING_SIZE:
1658 	case SQ_LSTMP_RING_SIZE:
1659 	case SQ_PSTMP_RING_SIZE:
1660 	case SQ_VSTMP_RING_SIZE:
1661 	case SQ_ESGS_RING_ITEMSIZE:
1662 	case SQ_ESTMP_RING_ITEMSIZE:
1663 	case SQ_GSTMP_RING_ITEMSIZE:
1664 	case SQ_GSVS_RING_ITEMSIZE:
1665 	case SQ_GS_VERT_ITEMSIZE:
1666 	case SQ_GS_VERT_ITEMSIZE_1:
1667 	case SQ_GS_VERT_ITEMSIZE_2:
1668 	case SQ_GS_VERT_ITEMSIZE_3:
1669 	case SQ_GSVS_RING_OFFSET_1:
1670 	case SQ_GSVS_RING_OFFSET_2:
1671 	case SQ_GSVS_RING_OFFSET_3:
1672 	case SQ_HSTMP_RING_ITEMSIZE:
1673 	case SQ_LSTMP_RING_ITEMSIZE:
1674 	case SQ_PSTMP_RING_ITEMSIZE:
1675 	case SQ_VSTMP_RING_ITEMSIZE:
1676 	case VGT_TF_RING_SIZE:
1677 	case SQ_ESGS_RING_BASE:
1678 	case SQ_GSVS_RING_BASE:
1679 	case SQ_ESTMP_RING_BASE:
1680 	case SQ_GSTMP_RING_BASE:
1681 	case SQ_HSTMP_RING_BASE:
1682 	case SQ_LSTMP_RING_BASE:
1683 	case SQ_PSTMP_RING_BASE:
1684 	case SQ_VSTMP_RING_BASE:
1685 	case CAYMAN_VGT_OFFCHIP_LDS_BASE:
1686 	case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS:
1687 		return true;
1688 	default:
1689 		return false;
1690 	}
1691 }
1692 
evergreen_vm_packet3_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)1693 static int evergreen_vm_packet3_check(struct radeon_device *rdev,
1694 				      u32 *ib, struct radeon_cs_packet *pkt)
1695 {
1696 	u32 idx = pkt->idx + 1;
1697 	u32 idx_value = ib[idx];
1698 	u32 start_reg, end_reg, reg, i;
1699 
1700 	switch (pkt->opcode) {
1701 	case PACKET3_NOP:
1702 	case PACKET3_SET_BASE:
1703 	case PACKET3_CLEAR_STATE:
1704 	case PACKET3_INDEX_BUFFER_SIZE:
1705 	case PACKET3_DISPATCH_DIRECT:
1706 	case PACKET3_DISPATCH_INDIRECT:
1707 	case PACKET3_MODE_CONTROL:
1708 	case PACKET3_SET_PREDICATION:
1709 	case PACKET3_COND_EXEC:
1710 	case PACKET3_PRED_EXEC:
1711 	case PACKET3_DRAW_INDIRECT:
1712 	case PACKET3_DRAW_INDEX_INDIRECT:
1713 	case PACKET3_INDEX_BASE:
1714 	case PACKET3_DRAW_INDEX_2:
1715 	case PACKET3_CONTEXT_CONTROL:
1716 	case PACKET3_DRAW_INDEX_OFFSET:
1717 	case PACKET3_INDEX_TYPE:
1718 	case PACKET3_DRAW_INDEX:
1719 	case PACKET3_DRAW_INDEX_AUTO:
1720 	case PACKET3_DRAW_INDEX_IMMD:
1721 	case PACKET3_NUM_INSTANCES:
1722 	case PACKET3_DRAW_INDEX_MULTI_AUTO:
1723 	case PACKET3_STRMOUT_BUFFER_UPDATE:
1724 	case PACKET3_DRAW_INDEX_OFFSET_2:
1725 	case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
1726 	case PACKET3_MPEG_INDEX:
1727 	case PACKET3_WAIT_REG_MEM:
1728 	case PACKET3_MEM_WRITE:
1729 	case PACKET3_SURFACE_SYNC:
1730 	case PACKET3_EVENT_WRITE:
1731 	case PACKET3_EVENT_WRITE_EOP:
1732 	case PACKET3_EVENT_WRITE_EOS:
1733 	case PACKET3_SET_CONTEXT_REG:
1734 	case PACKET3_SET_BOOL_CONST:
1735 	case PACKET3_SET_LOOP_CONST:
1736 	case PACKET3_SET_RESOURCE:
1737 	case PACKET3_SET_SAMPLER:
1738 	case PACKET3_SET_CTL_CONST:
1739 	case PACKET3_SET_RESOURCE_OFFSET:
1740 	case PACKET3_SET_CONTEXT_REG_INDIRECT:
1741 	case PACKET3_SET_RESOURCE_INDIRECT:
1742 	case CAYMAN_PACKET3_DEALLOC_STATE:
1743 		break;
1744 	case PACKET3_COND_WRITE:
1745 		if (idx_value & 0x100) {
1746 			reg = ib[idx + 5] * 4;
1747 			if (!evergreen_vm_reg_valid(reg))
1748 				return -EINVAL;
1749 		}
1750 		break;
1751 	case PACKET3_COPY_DW:
1752 		if (idx_value & 0x2) {
1753 			reg = ib[idx + 3] * 4;
1754 			if (!evergreen_vm_reg_valid(reg))
1755 				return -EINVAL;
1756 		}
1757 		break;
1758 	case PACKET3_SET_CONFIG_REG:
1759 		start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
1760 		end_reg = 4 * pkt->count + start_reg - 4;
1761 		if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
1762 		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
1763 		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
1764 			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
1765 			return -EINVAL;
1766 		}
1767 		for (i = 0; i < pkt->count; i++) {
1768 			reg = start_reg + (4 * i);
1769 			if (!evergreen_vm_reg_valid(reg))
1770 				return -EINVAL;
1771 		}
1772 		break;
1773 	default:
1774 		return -EINVAL;
1775 	}
1776 	return 0;
1777 }
1778 
evergreen_ib_parse(struct radeon_device * rdev,struct radeon_ib * ib)1779 int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
1780 {
1781 	int ret = 0;
1782 	u32 idx = 0;
1783 	struct radeon_cs_packet pkt;
1784 
1785 	do {
1786 		pkt.idx = idx;
1787 		pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]);
1788 		pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]);
1789 		pkt.one_reg_wr = 0;
1790 		switch (pkt.type) {
1791 		case PACKET_TYPE0:
1792 			dev_err(rdev->dev, "Packet0 not allowed!\n");
1793 			ret = -EINVAL;
1794 			break;
1795 		case PACKET_TYPE2:
1796 			idx += 1;
1797 			break;
1798 		case PACKET_TYPE3:
1799 			pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
1800 			ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt);
1801 			idx += pkt.count + 2;
1802 			break;
1803 		default:
1804 			dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
1805 			ret = -EINVAL;
1806 			break;
1807 		}
1808 		if (ret)
1809 			break;
1810 	} while (idx < ib->length_dw);
1811 
1812 	return ret;
1813 }
1814