Home | History | Annotate | Line # | Download | only in radeon
      1  1.5  riastrad /*	$NetBSD: radeon_evergreen_cs.c,v 1.5 2021/12/18 23:45:43 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright 2010 Advanced Micro Devices, Inc.
      5  1.1  riastrad  * Copyright 2008 Red Hat Inc.
      6  1.1  riastrad  * Copyright 2009 Jerome Glisse.
      7  1.1  riastrad  *
      8  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      9  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
     10  1.1  riastrad  * to deal in the Software without restriction, including without limitation
     11  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     12  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     13  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     14  1.1  riastrad  *
     15  1.1  riastrad  * The above copyright notice and this permission notice shall be included in
     16  1.1  riastrad  * all copies or substantial portions of the Software.
     17  1.1  riastrad  *
     18  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     21  1.1  riastrad  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     22  1.1  riastrad  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     23  1.1  riastrad  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     24  1.1  riastrad  * OTHER DEALINGS IN THE SOFTWARE.
     25  1.1  riastrad  *
     26  1.1  riastrad  * Authors: Dave Airlie
     27  1.1  riastrad  *          Alex Deucher
     28  1.1  riastrad  *          Jerome Glisse
     29  1.1  riastrad  */
     30  1.5  riastrad 
     31  1.1  riastrad #include <sys/cdefs.h>
     32  1.5  riastrad __KERNEL_RCSID(0, "$NetBSD: radeon_evergreen_cs.c,v 1.5 2021/12/18 23:45:43 riastradh Exp $");
     33  1.1  riastrad 
     34  1.1  riastrad #include "radeon.h"
     35  1.5  riastrad #include "radeon_asic.h"
     36  1.1  riastrad #include "evergreend.h"
     37  1.1  riastrad #include "evergreen_reg_safe.h"
     38  1.1  riastrad #include "cayman_reg_safe.h"
     39  1.1  riastrad 
     40  1.4  riastrad #include <linux/nbsd-namespace.h>
     41  1.4  riastrad 
     42  1.1  riastrad #ifndef __NetBSD__
     43  1.3  riastrad #define MAX(a,b)                   (((a)>(b))?(a):(b))
     44  1.3  riastrad #define MIN(a,b)                   (((a)<(b))?(a):(b))
     45  1.1  riastrad #endif
     46  1.1  riastrad 
     47  1.1  riastrad #define REG_SAFE_BM_SIZE ARRAY_SIZE(evergreen_reg_safe_bm)
     48  1.1  riastrad 
     49  1.1  riastrad int r600_dma_cs_next_reloc(struct radeon_cs_parser *p,
     50  1.1  riastrad 			   struct radeon_bo_list **cs_reloc);
     51  1.1  riastrad struct evergreen_cs_track {
     52  1.1  riastrad 	u32			group_size;
     53  1.1  riastrad 	u32			nbanks;
     54  1.1  riastrad 	u32			npipes;
     55  1.1  riastrad 	u32			row_size;
     56  1.1  riastrad 	/* value we track */
     57  1.1  riastrad 	u32			nsamples;		/* unused */
     58  1.1  riastrad 	struct radeon_bo	*cb_color_bo[12];
     59  1.1  riastrad 	u32			cb_color_bo_offset[12];
     60  1.1  riastrad 	struct radeon_bo	*cb_color_fmask_bo[8];	/* unused */
     61  1.1  riastrad 	struct radeon_bo	*cb_color_cmask_bo[8];	/* unused */
     62  1.1  riastrad 	u32			cb_color_info[12];
     63  1.1  riastrad 	u32			cb_color_view[12];
     64  1.1  riastrad 	u32			cb_color_pitch[12];
     65  1.1  riastrad 	u32			cb_color_slice[12];
     66  1.1  riastrad 	u32			cb_color_slice_idx[12];
     67  1.1  riastrad 	u32			cb_color_attrib[12];
     68  1.1  riastrad 	u32			cb_color_cmask_slice[8];/* unused */
     69  1.1  riastrad 	u32			cb_color_fmask_slice[8];/* unused */
     70  1.1  riastrad 	u32			cb_target_mask;
     71  1.1  riastrad 	u32			cb_shader_mask; /* unused */
     72  1.1  riastrad 	u32			vgt_strmout_config;
     73  1.1  riastrad 	u32			vgt_strmout_buffer_config;
     74  1.1  riastrad 	struct radeon_bo	*vgt_strmout_bo[4];
     75  1.1  riastrad 	u32			vgt_strmout_bo_offset[4];
     76  1.1  riastrad 	u32			vgt_strmout_size[4];
     77  1.1  riastrad 	u32			db_depth_control;
     78  1.1  riastrad 	u32			db_depth_view;
     79  1.1  riastrad 	u32			db_depth_slice;
     80  1.1  riastrad 	u32			db_depth_size;
     81  1.1  riastrad 	u32			db_z_info;
     82  1.1  riastrad 	u32			db_z_read_offset;
     83  1.1  riastrad 	u32			db_z_write_offset;
     84  1.1  riastrad 	struct radeon_bo	*db_z_read_bo;
     85  1.1  riastrad 	struct radeon_bo	*db_z_write_bo;
     86  1.1  riastrad 	u32			db_s_info;
     87  1.1  riastrad 	u32			db_s_read_offset;
     88  1.1  riastrad 	u32			db_s_write_offset;
     89  1.1  riastrad 	struct radeon_bo	*db_s_read_bo;
     90  1.1  riastrad 	struct radeon_bo	*db_s_write_bo;
     91  1.1  riastrad 	bool			sx_misc_kill_all_prims;
     92  1.1  riastrad 	bool			cb_dirty;
     93  1.1  riastrad 	bool			db_dirty;
     94  1.1  riastrad 	bool			streamout_dirty;
     95  1.1  riastrad 	u32			htile_offset;
     96  1.1  riastrad 	u32			htile_surface;
     97  1.1  riastrad 	struct radeon_bo	*htile_bo;
     98  1.1  riastrad 	unsigned long		indirect_draw_buffer_size;
     99  1.1  riastrad 	const unsigned		*reg_safe_bm;
    100  1.1  riastrad };
    101  1.1  riastrad 
    102  1.1  riastrad static u32 evergreen_cs_get_aray_mode(u32 tiling_flags)
    103  1.1  riastrad {
    104  1.1  riastrad 	if (tiling_flags & RADEON_TILING_MACRO)
    105  1.1  riastrad 		return ARRAY_2D_TILED_THIN1;
    106  1.1  riastrad 	else if (tiling_flags & RADEON_TILING_MICRO)
    107  1.1  riastrad 		return ARRAY_1D_TILED_THIN1;
    108  1.1  riastrad 	else
    109  1.1  riastrad 		return ARRAY_LINEAR_GENERAL;
    110  1.1  riastrad }
    111  1.1  riastrad 
    112  1.1  riastrad static u32 evergreen_cs_get_num_banks(u32 nbanks)
    113  1.1  riastrad {
    114  1.1  riastrad 	switch (nbanks) {
    115  1.1  riastrad 	case 2:
    116  1.1  riastrad 		return ADDR_SURF_2_BANK;
    117  1.1  riastrad 	case 4:
    118  1.1  riastrad 		return ADDR_SURF_4_BANK;
    119  1.1  riastrad 	case 8:
    120  1.1  riastrad 	default:
    121  1.1  riastrad 		return ADDR_SURF_8_BANK;
    122  1.1  riastrad 	case 16:
    123  1.1  riastrad 		return ADDR_SURF_16_BANK;
    124  1.1  riastrad 	}
    125  1.1  riastrad }
    126  1.1  riastrad 
    127  1.1  riastrad static void evergreen_cs_track_init(struct evergreen_cs_track *track)
    128  1.1  riastrad {
    129  1.1  riastrad 	int i;
    130  1.1  riastrad 
    131  1.1  riastrad 	for (i = 0; i < 8; i++) {
    132  1.1  riastrad 		track->cb_color_fmask_bo[i] = NULL;
    133  1.1  riastrad 		track->cb_color_cmask_bo[i] = NULL;
    134  1.1  riastrad 		track->cb_color_cmask_slice[i] = 0;
    135  1.1  riastrad 		track->cb_color_fmask_slice[i] = 0;
    136  1.1  riastrad 	}
    137  1.1  riastrad 
    138  1.1  riastrad 	for (i = 0; i < 12; i++) {
    139  1.1  riastrad 		track->cb_color_bo[i] = NULL;
    140  1.1  riastrad 		track->cb_color_bo_offset[i] = 0xFFFFFFFF;
    141  1.1  riastrad 		track->cb_color_info[i] = 0;
    142  1.1  riastrad 		track->cb_color_view[i] = 0xFFFFFFFF;
    143  1.1  riastrad 		track->cb_color_pitch[i] = 0;
    144  1.1  riastrad 		track->cb_color_slice[i] = 0xfffffff;
    145  1.1  riastrad 		track->cb_color_slice_idx[i] = 0;
    146  1.1  riastrad 	}
    147  1.1  riastrad 	track->cb_target_mask = 0xFFFFFFFF;
    148  1.1  riastrad 	track->cb_shader_mask = 0xFFFFFFFF;
    149  1.1  riastrad 	track->cb_dirty = true;
    150  1.1  riastrad 
    151  1.1  riastrad 	track->db_depth_slice = 0xffffffff;
    152  1.1  riastrad 	track->db_depth_view = 0xFFFFC000;
    153  1.1  riastrad 	track->db_depth_size = 0xFFFFFFFF;
    154  1.1  riastrad 	track->db_depth_control = 0xFFFFFFFF;
    155  1.1  riastrad 	track->db_z_info = 0xFFFFFFFF;
    156  1.1  riastrad 	track->db_z_read_offset = 0xFFFFFFFF;
    157  1.1  riastrad 	track->db_z_write_offset = 0xFFFFFFFF;
    158  1.1  riastrad 	track->db_z_read_bo = NULL;
    159  1.1  riastrad 	track->db_z_write_bo = NULL;
    160  1.1  riastrad 	track->db_s_info = 0xFFFFFFFF;
    161  1.1  riastrad 	track->db_s_read_offset = 0xFFFFFFFF;
    162  1.1  riastrad 	track->db_s_write_offset = 0xFFFFFFFF;
    163  1.1  riastrad 	track->db_s_read_bo = NULL;
    164  1.1  riastrad 	track->db_s_write_bo = NULL;
    165  1.1  riastrad 	track->db_dirty = true;
    166  1.1  riastrad 	track->htile_bo = NULL;
    167  1.1  riastrad 	track->htile_offset = 0xFFFFFFFF;
    168  1.1  riastrad 	track->htile_surface = 0;
    169  1.1  riastrad 
    170  1.1  riastrad 	for (i = 0; i < 4; i++) {
    171  1.1  riastrad 		track->vgt_strmout_size[i] = 0;
    172  1.1  riastrad 		track->vgt_strmout_bo[i] = NULL;
    173  1.1  riastrad 		track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF;
    174  1.1  riastrad 	}
    175  1.1  riastrad 	track->streamout_dirty = true;
    176  1.1  riastrad 	track->sx_misc_kill_all_prims = false;
    177  1.1  riastrad }
    178  1.1  riastrad 
    179  1.1  riastrad struct eg_surface {
    180  1.1  riastrad 	/* value gathered from cs */
    181  1.1  riastrad 	unsigned	nbx;
    182  1.1  riastrad 	unsigned	nby;
    183  1.1  riastrad 	unsigned	format;
    184  1.1  riastrad 	unsigned	mode;
    185  1.1  riastrad 	unsigned	nbanks;
    186  1.1  riastrad 	unsigned	bankw;
    187  1.1  riastrad 	unsigned	bankh;
    188  1.1  riastrad 	unsigned	tsplit;
    189  1.1  riastrad 	unsigned	mtilea;
    190  1.1  riastrad 	unsigned	nsamples;
    191  1.1  riastrad 	/* output value */
    192  1.1  riastrad 	unsigned	bpe;
    193  1.1  riastrad 	unsigned	layer_size;
    194  1.1  riastrad 	unsigned	palign;
    195  1.1  riastrad 	unsigned	halign;
    196  1.1  riastrad 	unsigned long	base_align;
    197  1.1  riastrad };
    198  1.1  riastrad 
    199  1.1  riastrad static int evergreen_surface_check_linear(struct radeon_cs_parser *p,
    200  1.1  riastrad 					  struct eg_surface *surf,
    201  1.1  riastrad 					  const char *prefix)
    202  1.1  riastrad {
    203  1.1  riastrad 	surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples;
    204  1.1  riastrad 	surf->base_align = surf->bpe;
    205  1.1  riastrad 	surf->palign = 1;
    206  1.1  riastrad 	surf->halign = 1;
    207  1.1  riastrad 	return 0;
    208  1.1  riastrad }
    209  1.1  riastrad 
    210  1.1  riastrad static int evergreen_surface_check_linear_aligned(struct radeon_cs_parser *p,
    211  1.1  riastrad 						  struct eg_surface *surf,
    212  1.1  riastrad 						  const char *prefix)
    213  1.1  riastrad {
    214  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    215  1.1  riastrad 	unsigned palign;
    216  1.1  riastrad 
    217  1.1  riastrad 	palign = MAX(64, track->group_size / surf->bpe);
    218  1.1  riastrad 	surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples;
    219  1.1  riastrad 	surf->base_align = track->group_size;
    220  1.1  riastrad 	surf->palign = palign;
    221  1.1  riastrad 	surf->halign = 1;
    222  1.1  riastrad 	if (surf->nbx & (palign - 1)) {
    223  1.1  riastrad 		if (prefix) {
    224  1.1  riastrad 			dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n",
    225  1.1  riastrad 				 __func__, __LINE__, prefix, surf->nbx, palign);
    226  1.1  riastrad 		}
    227  1.1  riastrad 		return -EINVAL;
    228  1.1  riastrad 	}
    229  1.1  riastrad 	return 0;
    230  1.1  riastrad }
    231  1.1  riastrad 
    232  1.1  riastrad static int evergreen_surface_check_1d(struct radeon_cs_parser *p,
    233  1.1  riastrad 				      struct eg_surface *surf,
    234  1.1  riastrad 				      const char *prefix)
    235  1.1  riastrad {
    236  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    237  1.1  riastrad 	unsigned palign;
    238  1.1  riastrad 
    239  1.1  riastrad 	palign = track->group_size / (8 * surf->bpe * surf->nsamples);
    240  1.1  riastrad 	palign = MAX(8, palign);
    241  1.1  riastrad 	surf->layer_size = surf->nbx * surf->nby * surf->bpe;
    242  1.1  riastrad 	surf->base_align = track->group_size;
    243  1.1  riastrad 	surf->palign = palign;
    244  1.1  riastrad 	surf->halign = 8;
    245  1.1  riastrad 	if ((surf->nbx & (palign - 1))) {
    246  1.1  riastrad 		if (prefix) {
    247  1.1  riastrad 			dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d (%d %d %d)\n",
    248  1.1  riastrad 				 __func__, __LINE__, prefix, surf->nbx, palign,
    249  1.1  riastrad 				 track->group_size, surf->bpe, surf->nsamples);
    250  1.1  riastrad 		}
    251  1.1  riastrad 		return -EINVAL;
    252  1.1  riastrad 	}
    253  1.1  riastrad 	if ((surf->nby & (8 - 1))) {
    254  1.1  riastrad 		if (prefix) {
    255  1.1  riastrad 			dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with 8\n",
    256  1.1  riastrad 				 __func__, __LINE__, prefix, surf->nby);
    257  1.1  riastrad 		}
    258  1.1  riastrad 		return -EINVAL;
    259  1.1  riastrad 	}
    260  1.1  riastrad 	return 0;
    261  1.1  riastrad }
    262  1.1  riastrad 
    263  1.1  riastrad static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
    264  1.1  riastrad 				      struct eg_surface *surf,
    265  1.1  riastrad 				      const char *prefix)
    266  1.1  riastrad {
    267  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    268  1.1  riastrad 	unsigned palign, halign, tileb, slice_pt;
    269  1.1  riastrad 	unsigned mtile_pr, mtile_ps, mtileb;
    270  1.1  riastrad 
    271  1.1  riastrad 	tileb = 64 * surf->bpe * surf->nsamples;
    272  1.1  riastrad 	slice_pt = 1;
    273  1.1  riastrad 	if (tileb > surf->tsplit) {
    274  1.1  riastrad 		slice_pt = tileb / surf->tsplit;
    275  1.1  riastrad 	}
    276  1.1  riastrad 	tileb = tileb / slice_pt;
    277  1.1  riastrad 	/* macro tile width & height */
    278  1.1  riastrad 	palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
    279  1.1  riastrad 	halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
    280  1.1  riastrad 	mtileb = (palign / 8) * (halign / 8) * tileb;
    281  1.1  riastrad 	mtile_pr = surf->nbx / palign;
    282  1.1  riastrad 	mtile_ps = (mtile_pr * surf->nby) / halign;
    283  1.1  riastrad 	surf->layer_size = mtile_ps * mtileb * slice_pt;
    284  1.1  riastrad 	surf->base_align = (palign / 8) * (halign / 8) * tileb;
    285  1.1  riastrad 	surf->palign = palign;
    286  1.1  riastrad 	surf->halign = halign;
    287  1.1  riastrad 
    288  1.1  riastrad 	if ((surf->nbx & (palign - 1))) {
    289  1.1  riastrad 		if (prefix) {
    290  1.1  riastrad 			dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n",
    291  1.1  riastrad 				 __func__, __LINE__, prefix, surf->nbx, palign);
    292  1.1  riastrad 		}
    293  1.1  riastrad 		return -EINVAL;
    294  1.1  riastrad 	}
    295  1.1  riastrad 	if ((surf->nby & (halign - 1))) {
    296  1.1  riastrad 		if (prefix) {
    297  1.1  riastrad 			dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with %d\n",
    298  1.1  riastrad 				 __func__, __LINE__, prefix, surf->nby, halign);
    299  1.1  riastrad 		}
    300  1.1  riastrad 		return -EINVAL;
    301  1.1  riastrad 	}
    302  1.1  riastrad 
    303  1.1  riastrad 	return 0;
    304  1.1  riastrad }
    305  1.1  riastrad 
    306  1.1  riastrad static int evergreen_surface_check(struct radeon_cs_parser *p,
    307  1.1  riastrad 				   struct eg_surface *surf,
    308  1.1  riastrad 				   const char *prefix)
    309  1.1  riastrad {
    310  1.1  riastrad 	/* some common value computed here */
    311  1.1  riastrad 	surf->bpe = r600_fmt_get_blocksize(surf->format);
    312  1.1  riastrad 
    313  1.1  riastrad 	switch (surf->mode) {
    314  1.1  riastrad 	case ARRAY_LINEAR_GENERAL:
    315  1.1  riastrad 		return evergreen_surface_check_linear(p, surf, prefix);
    316  1.1  riastrad 	case ARRAY_LINEAR_ALIGNED:
    317  1.1  riastrad 		return evergreen_surface_check_linear_aligned(p, surf, prefix);
    318  1.1  riastrad 	case ARRAY_1D_TILED_THIN1:
    319  1.1  riastrad 		return evergreen_surface_check_1d(p, surf, prefix);
    320  1.1  riastrad 	case ARRAY_2D_TILED_THIN1:
    321  1.1  riastrad 		return evergreen_surface_check_2d(p, surf, prefix);
    322  1.1  riastrad 	default:
    323  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid array mode %d\n",
    324  1.1  riastrad 				__func__, __LINE__, prefix, surf->mode);
    325  1.1  riastrad 		return -EINVAL;
    326  1.1  riastrad 	}
    327  1.1  riastrad 	return -EINVAL;
    328  1.1  riastrad }
    329  1.1  riastrad 
    330  1.1  riastrad static int evergreen_surface_value_conv_check(struct radeon_cs_parser *p,
    331  1.1  riastrad 					      struct eg_surface *surf,
    332  1.1  riastrad 					      const char *prefix)
    333  1.1  riastrad {
    334  1.1  riastrad 	switch (surf->mode) {
    335  1.1  riastrad 	case ARRAY_2D_TILED_THIN1:
    336  1.1  riastrad 		break;
    337  1.1  riastrad 	case ARRAY_LINEAR_GENERAL:
    338  1.1  riastrad 	case ARRAY_LINEAR_ALIGNED:
    339  1.1  riastrad 	case ARRAY_1D_TILED_THIN1:
    340  1.1  riastrad 		return 0;
    341  1.1  riastrad 	default:
    342  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid array mode %d\n",
    343  1.1  riastrad 				__func__, __LINE__, prefix, surf->mode);
    344  1.1  riastrad 		return -EINVAL;
    345  1.1  riastrad 	}
    346  1.1  riastrad 
    347  1.1  riastrad 	switch (surf->nbanks) {
    348  1.1  riastrad 	case 0: surf->nbanks = 2; break;
    349  1.1  riastrad 	case 1: surf->nbanks = 4; break;
    350  1.1  riastrad 	case 2: surf->nbanks = 8; break;
    351  1.1  riastrad 	case 3: surf->nbanks = 16; break;
    352  1.1  riastrad 	default:
    353  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid number of banks %d\n",
    354  1.1  riastrad 			 __func__, __LINE__, prefix, surf->nbanks);
    355  1.1  riastrad 		return -EINVAL;
    356  1.1  riastrad 	}
    357  1.1  riastrad 	switch (surf->bankw) {
    358  1.1  riastrad 	case 0: surf->bankw = 1; break;
    359  1.1  riastrad 	case 1: surf->bankw = 2; break;
    360  1.1  riastrad 	case 2: surf->bankw = 4; break;
    361  1.1  riastrad 	case 3: surf->bankw = 8; break;
    362  1.1  riastrad 	default:
    363  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid bankw %d\n",
    364  1.1  riastrad 			 __func__, __LINE__, prefix, surf->bankw);
    365  1.1  riastrad 		return -EINVAL;
    366  1.1  riastrad 	}
    367  1.1  riastrad 	switch (surf->bankh) {
    368  1.1  riastrad 	case 0: surf->bankh = 1; break;
    369  1.1  riastrad 	case 1: surf->bankh = 2; break;
    370  1.1  riastrad 	case 2: surf->bankh = 4; break;
    371  1.1  riastrad 	case 3: surf->bankh = 8; break;
    372  1.1  riastrad 	default:
    373  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid bankh %d\n",
    374  1.1  riastrad 			 __func__, __LINE__, prefix, surf->bankh);
    375  1.1  riastrad 		return -EINVAL;
    376  1.1  riastrad 	}
    377  1.1  riastrad 	switch (surf->mtilea) {
    378  1.1  riastrad 	case 0: surf->mtilea = 1; break;
    379  1.1  riastrad 	case 1: surf->mtilea = 2; break;
    380  1.1  riastrad 	case 2: surf->mtilea = 4; break;
    381  1.1  riastrad 	case 3: surf->mtilea = 8; break;
    382  1.1  riastrad 	default:
    383  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid macro tile aspect %d\n",
    384  1.1  riastrad 			 __func__, __LINE__, prefix, surf->mtilea);
    385  1.1  riastrad 		return -EINVAL;
    386  1.1  riastrad 	}
    387  1.1  riastrad 	switch (surf->tsplit) {
    388  1.1  riastrad 	case 0: surf->tsplit = 64; break;
    389  1.1  riastrad 	case 1: surf->tsplit = 128; break;
    390  1.1  riastrad 	case 2: surf->tsplit = 256; break;
    391  1.1  riastrad 	case 3: surf->tsplit = 512; break;
    392  1.1  riastrad 	case 4: surf->tsplit = 1024; break;
    393  1.1  riastrad 	case 5: surf->tsplit = 2048; break;
    394  1.1  riastrad 	case 6: surf->tsplit = 4096; break;
    395  1.1  riastrad 	default:
    396  1.1  riastrad 		dev_warn(p->dev, "%s:%d %s invalid tile split %d\n",
    397  1.1  riastrad 			 __func__, __LINE__, prefix, surf->tsplit);
    398  1.1  riastrad 		return -EINVAL;
    399  1.1  riastrad 	}
    400  1.1  riastrad 	return 0;
    401  1.1  riastrad }
    402  1.1  riastrad 
    403  1.1  riastrad static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned id)
    404  1.1  riastrad {
    405  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    406  1.1  riastrad 	struct eg_surface surf;
    407  1.1  riastrad 	unsigned pitch, slice, mslice;
    408  1.1  riastrad 	unsigned long offset;
    409  1.1  riastrad 	int r;
    410  1.1  riastrad 
    411  1.1  riastrad 	mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
    412  1.1  riastrad 	pitch = track->cb_color_pitch[id];
    413  1.1  riastrad 	slice = track->cb_color_slice[id];
    414  1.1  riastrad 	surf.nbx = (pitch + 1) * 8;
    415  1.1  riastrad 	surf.nby = ((slice + 1) * 64) / surf.nbx;
    416  1.1  riastrad 	surf.mode = G_028C70_ARRAY_MODE(track->cb_color_info[id]);
    417  1.1  riastrad 	surf.format = G_028C70_FORMAT(track->cb_color_info[id]);
    418  1.1  riastrad 	surf.tsplit = G_028C74_TILE_SPLIT(track->cb_color_attrib[id]);
    419  1.1  riastrad 	surf.nbanks = G_028C74_NUM_BANKS(track->cb_color_attrib[id]);
    420  1.1  riastrad 	surf.bankw = G_028C74_BANK_WIDTH(track->cb_color_attrib[id]);
    421  1.1  riastrad 	surf.bankh = G_028C74_BANK_HEIGHT(track->cb_color_attrib[id]);
    422  1.1  riastrad 	surf.mtilea = G_028C74_MACRO_TILE_ASPECT(track->cb_color_attrib[id]);
    423  1.1  riastrad 	surf.nsamples = 1;
    424  1.1  riastrad 
    425  1.1  riastrad 	if (!r600_fmt_is_valid_color(surf.format)) {
    426  1.1  riastrad 		dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08x)\n",
    427  1.1  riastrad 			 __func__, __LINE__, surf.format,
    428  1.1  riastrad 			id, track->cb_color_info[id]);
    429  1.1  riastrad 		return -EINVAL;
    430  1.1  riastrad 	}
    431  1.1  riastrad 
    432  1.1  riastrad 	r = evergreen_surface_value_conv_check(p, &surf, "cb");
    433  1.1  riastrad 	if (r) {
    434  1.1  riastrad 		return r;
    435  1.1  riastrad 	}
    436  1.1  riastrad 
    437  1.1  riastrad 	r = evergreen_surface_check(p, &surf, "cb");
    438  1.1  riastrad 	if (r) {
    439  1.1  riastrad 		dev_warn(p->dev, "%s:%d cb[%d] invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
    440  1.1  riastrad 			 __func__, __LINE__, id, track->cb_color_pitch[id],
    441  1.1  riastrad 			 track->cb_color_slice[id], track->cb_color_attrib[id],
    442  1.1  riastrad 			 track->cb_color_info[id]);
    443  1.1  riastrad 		return r;
    444  1.1  riastrad 	}
    445  1.1  riastrad 
    446  1.1  riastrad 	offset = track->cb_color_bo_offset[id] << 8;
    447  1.1  riastrad 	if (offset & (surf.base_align - 1)) {
    448  1.1  riastrad 		dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n",
    449  1.1  riastrad 			 __func__, __LINE__, id, offset, surf.base_align);
    450  1.1  riastrad 		return -EINVAL;
    451  1.1  riastrad 	}
    452  1.1  riastrad 
    453  1.1  riastrad 	offset += surf.layer_size * mslice;
    454  1.1  riastrad 	if (offset > radeon_bo_size(track->cb_color_bo[id])) {
    455  1.1  riastrad 		/* old ddx are broken they allocate bo with w*h*bpp but
    456  1.1  riastrad 		 * program slice with ALIGN(h, 8), catch this and patch
    457  1.1  riastrad 		 * command stream.
    458  1.1  riastrad 		 */
    459  1.1  riastrad 		if (!surf.mode) {
    460  1.1  riastrad 			uint32_t *ib = p->ib.ptr;
    461  1.3  riastrad 			unsigned long tmp, nby, bsize, size, min = 0;
    462  1.1  riastrad 
    463  1.1  riastrad 			/* find the height the ddx wants */
    464  1.1  riastrad 			if (surf.nby > 8) {
    465  1.3  riastrad 				min = surf.nby - 8;
    466  1.1  riastrad 			}
    467  1.1  riastrad 			bsize = radeon_bo_size(track->cb_color_bo[id]);
    468  1.1  riastrad 			tmp = track->cb_color_bo_offset[id] << 8;
    469  1.3  riastrad 			for (nby = surf.nby; nby > min; nby--) {
    470  1.1  riastrad 				size = nby * surf.nbx * surf.bpe * surf.nsamples;
    471  1.1  riastrad 				if ((tmp + size * mslice) <= bsize) {
    472  1.1  riastrad 					break;
    473  1.1  riastrad 				}
    474  1.1  riastrad 			}
    475  1.3  riastrad 			if (nby > min) {
    476  1.1  riastrad 				surf.nby = nby;
    477  1.1  riastrad 				slice = ((nby * surf.nbx) / 64) - 1;
    478  1.1  riastrad 				if (!evergreen_surface_check(p, &surf, "cb")) {
    479  1.1  riastrad 					/* check if this one works */
    480  1.1  riastrad 					tmp += surf.layer_size * mslice;
    481  1.1  riastrad 					if (tmp <= bsize) {
    482  1.1  riastrad 						ib[track->cb_color_slice_idx[id]] = slice;
    483  1.1  riastrad 						goto old_ddx_ok;
    484  1.1  riastrad 					}
    485  1.1  riastrad 				}
    486  1.1  riastrad 			}
    487  1.1  riastrad 		}
    488  1.1  riastrad 		dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
    489  1.1  riastrad 			 "offset %d, max layer %d, bo size %ld, slice %d)\n",
    490  1.1  riastrad 			 __func__, __LINE__, id, surf.layer_size,
    491  1.1  riastrad 			track->cb_color_bo_offset[id] << 8, mslice,
    492  1.1  riastrad 			radeon_bo_size(track->cb_color_bo[id]), slice);
    493  1.1  riastrad 		dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
    494  1.1  riastrad 			 __func__, __LINE__, surf.nbx, surf.nby,
    495  1.1  riastrad 			surf.mode, surf.bpe, surf.nsamples,
    496  1.1  riastrad 			surf.bankw, surf.bankh,
    497  1.1  riastrad 			surf.tsplit, surf.mtilea);
    498  1.1  riastrad 		return -EINVAL;
    499  1.1  riastrad 	}
    500  1.1  riastrad old_ddx_ok:
    501  1.1  riastrad 
    502  1.1  riastrad 	return 0;
    503  1.1  riastrad }
    504  1.1  riastrad 
    505  1.1  riastrad static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
    506  1.1  riastrad 						unsigned nbx, unsigned nby)
    507  1.1  riastrad {
    508  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    509  1.1  riastrad 	unsigned long size;
    510  1.1  riastrad 
    511  1.1  riastrad 	if (track->htile_bo == NULL) {
    512  1.1  riastrad 		dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n",
    513  1.1  riastrad 				__func__, __LINE__, track->db_z_info);
    514  1.1  riastrad 		return -EINVAL;
    515  1.1  riastrad 	}
    516  1.1  riastrad 
    517  1.1  riastrad 	if (G_028ABC_LINEAR(track->htile_surface)) {
    518  1.1  riastrad 		/* pitch must be 16 htiles aligned == 16 * 8 pixel aligned */
    519  1.1  riastrad 		nbx = round_up(nbx, 16 * 8);
    520  1.1  riastrad 		/* height is npipes htiles aligned == npipes * 8 pixel aligned */
    521  1.1  riastrad 		nby = round_up(nby, track->npipes * 8);
    522  1.1  riastrad 	} else {
    523  1.1  riastrad 		/* always assume 8x8 htile */
    524  1.1  riastrad 		/* align is htile align * 8, htile align vary according to
    525  1.1  riastrad 		 * number of pipe and tile width and nby
    526  1.1  riastrad 		 */
    527  1.1  riastrad 		switch (track->npipes) {
    528  1.1  riastrad 		case 8:
    529  1.1  riastrad 			/* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
    530  1.1  riastrad 			nbx = round_up(nbx, 64 * 8);
    531  1.1  riastrad 			nby = round_up(nby, 64 * 8);
    532  1.1  riastrad 			break;
    533  1.1  riastrad 		case 4:
    534  1.1  riastrad 			/* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
    535  1.1  riastrad 			nbx = round_up(nbx, 64 * 8);
    536  1.1  riastrad 			nby = round_up(nby, 32 * 8);
    537  1.1  riastrad 			break;
    538  1.1  riastrad 		case 2:
    539  1.1  riastrad 			/* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
    540  1.1  riastrad 			nbx = round_up(nbx, 32 * 8);
    541  1.1  riastrad 			nby = round_up(nby, 32 * 8);
    542  1.1  riastrad 			break;
    543  1.1  riastrad 		case 1:
    544  1.1  riastrad 			/* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
    545  1.1  riastrad 			nbx = round_up(nbx, 32 * 8);
    546  1.1  riastrad 			nby = round_up(nby, 16 * 8);
    547  1.1  riastrad 			break;
    548  1.1  riastrad 		default:
    549  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
    550  1.1  riastrad 					__func__, __LINE__, track->npipes);
    551  1.1  riastrad 			return -EINVAL;
    552  1.1  riastrad 		}
    553  1.1  riastrad 	}
    554  1.1  riastrad 	/* compute number of htile */
    555  1.1  riastrad 	nbx = nbx >> 3;
    556  1.1  riastrad 	nby = nby >> 3;
    557  1.1  riastrad 	/* size must be aligned on npipes * 2K boundary */
    558  1.1  riastrad 	size = roundup(nbx * nby * 4, track->npipes * (2 << 10));
    559  1.1  riastrad 	size += track->htile_offset;
    560  1.1  riastrad 
    561  1.1  riastrad 	if (!track->htile_bo) {
    562  1.1  riastrad 		dev_warn(p->dev, "%s:%d htile_bo not set", __func__, __LINE__);
    563  1.1  riastrad 		return -EINVAL;
    564  1.1  riastrad 	}
    565  1.1  riastrad 	if (size > radeon_bo_size(track->htile_bo)) {
    566  1.1  riastrad 		dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n",
    567  1.1  riastrad 				__func__, __LINE__, radeon_bo_size(track->htile_bo),
    568  1.1  riastrad 				size, nbx, nby);
    569  1.1  riastrad 		return -EINVAL;
    570  1.1  riastrad 	}
    571  1.1  riastrad 	return 0;
    572  1.1  riastrad }
    573  1.1  riastrad 
    574  1.1  riastrad static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p)
    575  1.1  riastrad {
    576  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    577  1.1  riastrad 	struct eg_surface surf;
    578  1.1  riastrad 	unsigned pitch, slice, mslice;
    579  1.1  riastrad 	unsigned long offset;
    580  1.1  riastrad 	int r;
    581  1.1  riastrad 
    582  1.1  riastrad 	mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
    583  1.1  riastrad 	pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size);
    584  1.1  riastrad 	slice = track->db_depth_slice;
    585  1.1  riastrad 	surf.nbx = (pitch + 1) * 8;
    586  1.1  riastrad 	surf.nby = ((slice + 1) * 64) / surf.nbx;
    587  1.1  riastrad 	surf.mode = G_028040_ARRAY_MODE(track->db_z_info);
    588  1.1  riastrad 	surf.format = G_028044_FORMAT(track->db_s_info);
    589  1.1  riastrad 	surf.tsplit = G_028044_TILE_SPLIT(track->db_s_info);
    590  1.1  riastrad 	surf.nbanks = G_028040_NUM_BANKS(track->db_z_info);
    591  1.1  riastrad 	surf.bankw = G_028040_BANK_WIDTH(track->db_z_info);
    592  1.1  riastrad 	surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info);
    593  1.1  riastrad 	surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info);
    594  1.1  riastrad 	surf.nsamples = 1;
    595  1.1  riastrad 
    596  1.1  riastrad 	if (surf.format != 1) {
    597  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil invalid format %d\n",
    598  1.1  riastrad 			 __func__, __LINE__, surf.format);
    599  1.1  riastrad 		return -EINVAL;
    600  1.1  riastrad 	}
    601  1.1  riastrad 	/* replace by color format so we can use same code */
    602  1.1  riastrad 	surf.format = V_028C70_COLOR_8;
    603  1.1  riastrad 
    604  1.1  riastrad 	r = evergreen_surface_value_conv_check(p, &surf, "stencil");
    605  1.1  riastrad 	if (r) {
    606  1.1  riastrad 		return r;
    607  1.1  riastrad 	}
    608  1.1  riastrad 
    609  1.1  riastrad 	r = evergreen_surface_check(p, &surf, NULL);
    610  1.1  riastrad 	if (r) {
    611  1.1  riastrad 		/* old userspace doesn't compute proper depth/stencil alignment
    612  1.1  riastrad 		 * check that alignment against a bigger byte per elements and
    613  1.1  riastrad 		 * only report if that alignment is wrong too.
    614  1.1  riastrad 		 */
    615  1.1  riastrad 		surf.format = V_028C70_COLOR_8_8_8_8;
    616  1.1  riastrad 		r = evergreen_surface_check(p, &surf, "stencil");
    617  1.1  riastrad 		if (r) {
    618  1.1  riastrad 			dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
    619  1.1  riastrad 				 __func__, __LINE__, track->db_depth_size,
    620  1.1  riastrad 				 track->db_depth_slice, track->db_s_info, track->db_z_info);
    621  1.1  riastrad 		}
    622  1.1  riastrad 		return r;
    623  1.1  riastrad 	}
    624  1.1  riastrad 
    625  1.1  riastrad 	offset = track->db_s_read_offset << 8;
    626  1.1  riastrad 	if (offset & (surf.base_align - 1)) {
    627  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
    628  1.1  riastrad 			 __func__, __LINE__, offset, surf.base_align);
    629  1.1  riastrad 		return -EINVAL;
    630  1.1  riastrad 	}
    631  1.1  riastrad 	offset += surf.layer_size * mslice;
    632  1.1  riastrad 	if (!track->db_s_read_bo) {
    633  1.1  riastrad 		dev_warn(p->dev, "%s:%d db_s_read_bo not set", __func__, __LINE__);
    634  1.1  riastrad 		return -EINVAL;
    635  1.1  riastrad 	}
    636  1.1  riastrad 	if (offset > radeon_bo_size(track->db_s_read_bo)) {
    637  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
    638  1.1  riastrad 			 "offset %ld, max layer %d, bo size %ld)\n",
    639  1.1  riastrad 			 __func__, __LINE__, surf.layer_size,
    640  1.1  riastrad 			(unsigned long)track->db_s_read_offset << 8, mslice,
    641  1.1  riastrad 			radeon_bo_size(track->db_s_read_bo));
    642  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
    643  1.1  riastrad 			 __func__, __LINE__, track->db_depth_size,
    644  1.1  riastrad 			 track->db_depth_slice, track->db_s_info, track->db_z_info);
    645  1.1  riastrad 		return -EINVAL;
    646  1.1  riastrad 	}
    647  1.1  riastrad 
    648  1.1  riastrad 	offset = track->db_s_write_offset << 8;
    649  1.1  riastrad 	if (offset & (surf.base_align - 1)) {
    650  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
    651  1.1  riastrad 			 __func__, __LINE__, offset, surf.base_align);
    652  1.1  riastrad 		return -EINVAL;
    653  1.1  riastrad 	}
    654  1.1  riastrad 	offset += surf.layer_size * mslice;
    655  1.1  riastrad 	if (!track->db_s_write_bo) {
    656  1.1  riastrad 		dev_warn(p->dev, "%s:%d db_s_write_bo not set", __func__, __LINE__);
    657  1.1  riastrad 		return -EINVAL;
    658  1.1  riastrad 	}
    659  1.1  riastrad 	if (offset > radeon_bo_size(track->db_s_write_bo)) {
    660  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
    661  1.1  riastrad 			 "offset %ld, max layer %d, bo size %ld)\n",
    662  1.1  riastrad 			 __func__, __LINE__, surf.layer_size,
    663  1.1  riastrad 			(unsigned long)track->db_s_write_offset << 8, mslice,
    664  1.1  riastrad 			radeon_bo_size(track->db_s_write_bo));
    665  1.1  riastrad 		return -EINVAL;
    666  1.1  riastrad 	}
    667  1.1  riastrad 
    668  1.1  riastrad 	/* hyperz */
    669  1.1  riastrad 	if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
    670  1.1  riastrad 		r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
    671  1.1  riastrad 		if (r) {
    672  1.1  riastrad 			return r;
    673  1.1  riastrad 		}
    674  1.1  riastrad 	}
    675  1.1  riastrad 
    676  1.1  riastrad 	return 0;
    677  1.1  riastrad }
    678  1.1  riastrad 
    679  1.1  riastrad static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p)
    680  1.1  riastrad {
    681  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    682  1.1  riastrad 	struct eg_surface surf;
    683  1.1  riastrad 	unsigned pitch, slice, mslice;
    684  1.1  riastrad 	unsigned long offset;
    685  1.1  riastrad 	int r;
    686  1.1  riastrad 
    687  1.1  riastrad 	mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
    688  1.1  riastrad 	pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size);
    689  1.1  riastrad 	slice = track->db_depth_slice;
    690  1.1  riastrad 	surf.nbx = (pitch + 1) * 8;
    691  1.1  riastrad 	surf.nby = ((slice + 1) * 64) / surf.nbx;
    692  1.1  riastrad 	surf.mode = G_028040_ARRAY_MODE(track->db_z_info);
    693  1.1  riastrad 	surf.format = G_028040_FORMAT(track->db_z_info);
    694  1.1  riastrad 	surf.tsplit = G_028040_TILE_SPLIT(track->db_z_info);
    695  1.1  riastrad 	surf.nbanks = G_028040_NUM_BANKS(track->db_z_info);
    696  1.1  riastrad 	surf.bankw = G_028040_BANK_WIDTH(track->db_z_info);
    697  1.1  riastrad 	surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info);
    698  1.1  riastrad 	surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info);
    699  1.1  riastrad 	surf.nsamples = 1;
    700  1.1  riastrad 
    701  1.1  riastrad 	switch (surf.format) {
    702  1.1  riastrad 	case V_028040_Z_16:
    703  1.1  riastrad 		surf.format = V_028C70_COLOR_16;
    704  1.1  riastrad 		break;
    705  1.1  riastrad 	case V_028040_Z_24:
    706  1.1  riastrad 	case V_028040_Z_32_FLOAT:
    707  1.1  riastrad 		surf.format = V_028C70_COLOR_8_8_8_8;
    708  1.1  riastrad 		break;
    709  1.1  riastrad 	default:
    710  1.1  riastrad 		dev_warn(p->dev, "%s:%d depth invalid format %d\n",
    711  1.1  riastrad 			 __func__, __LINE__, surf.format);
    712  1.1  riastrad 		return -EINVAL;
    713  1.1  riastrad 	}
    714  1.1  riastrad 
    715  1.1  riastrad 	r = evergreen_surface_value_conv_check(p, &surf, "depth");
    716  1.1  riastrad 	if (r) {
    717  1.1  riastrad 		dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
    718  1.1  riastrad 			 __func__, __LINE__, track->db_depth_size,
    719  1.1  riastrad 			 track->db_depth_slice, track->db_z_info);
    720  1.1  riastrad 		return r;
    721  1.1  riastrad 	}
    722  1.1  riastrad 
    723  1.1  riastrad 	r = evergreen_surface_check(p, &surf, "depth");
    724  1.1  riastrad 	if (r) {
    725  1.1  riastrad 		dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
    726  1.1  riastrad 			 __func__, __LINE__, track->db_depth_size,
    727  1.1  riastrad 			 track->db_depth_slice, track->db_z_info);
    728  1.1  riastrad 		return r;
    729  1.1  riastrad 	}
    730  1.1  riastrad 
    731  1.1  riastrad 	offset = track->db_z_read_offset << 8;
    732  1.1  riastrad 	if (offset & (surf.base_align - 1)) {
    733  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
    734  1.1  riastrad 			 __func__, __LINE__, offset, surf.base_align);
    735  1.1  riastrad 		return -EINVAL;
    736  1.1  riastrad 	}
    737  1.1  riastrad 	offset += surf.layer_size * mslice;
    738  1.1  riastrad 	if (!track->db_z_read_bo) {
    739  1.1  riastrad 		dev_warn(p->dev, "%s:%d db_z_read_bo not set", __func__, __LINE__);
    740  1.1  riastrad 		return -EINVAL;
    741  1.1  riastrad 	}
    742  1.1  riastrad 	if (offset > radeon_bo_size(track->db_z_read_bo)) {
    743  1.1  riastrad 		dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
    744  1.1  riastrad 			 "offset %ld, max layer %d, bo size %ld)\n",
    745  1.1  riastrad 			 __func__, __LINE__, surf.layer_size,
    746  1.1  riastrad 			(unsigned long)track->db_z_read_offset << 8, mslice,
    747  1.1  riastrad 			radeon_bo_size(track->db_z_read_bo));
    748  1.1  riastrad 		return -EINVAL;
    749  1.1  riastrad 	}
    750  1.1  riastrad 
    751  1.1  riastrad 	offset = track->db_z_write_offset << 8;
    752  1.1  riastrad 	if (offset & (surf.base_align - 1)) {
    753  1.1  riastrad 		dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
    754  1.1  riastrad 			 __func__, __LINE__, offset, surf.base_align);
    755  1.1  riastrad 		return -EINVAL;
    756  1.1  riastrad 	}
    757  1.1  riastrad 	offset += surf.layer_size * mslice;
    758  1.1  riastrad 	if (!track->db_z_write_bo) {
    759  1.1  riastrad 		dev_warn(p->dev, "%s:%d db_z_write_bo not set", __func__, __LINE__);
    760  1.1  riastrad 		return -EINVAL;
    761  1.1  riastrad 	}
    762  1.1  riastrad 	if (offset > radeon_bo_size(track->db_z_write_bo)) {
    763  1.1  riastrad 		dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
    764  1.1  riastrad 			 "offset %ld, max layer %d, bo size %ld)\n",
    765  1.1  riastrad 			 __func__, __LINE__, surf.layer_size,
    766  1.1  riastrad 			(unsigned long)track->db_z_write_offset << 8, mslice,
    767  1.1  riastrad 			radeon_bo_size(track->db_z_write_bo));
    768  1.1  riastrad 		return -EINVAL;
    769  1.1  riastrad 	}
    770  1.1  riastrad 
    771  1.1  riastrad 	/* hyperz */
    772  1.1  riastrad 	if (G_028040_TILE_SURFACE_ENABLE(track->db_z_info)) {
    773  1.1  riastrad 		r = evergreen_cs_track_validate_htile(p, surf.nbx, surf.nby);
    774  1.1  riastrad 		if (r) {
    775  1.1  riastrad 			return r;
    776  1.1  riastrad 		}
    777  1.1  riastrad 	}
    778  1.1  riastrad 
    779  1.1  riastrad 	return 0;
    780  1.1  riastrad }
    781  1.1  riastrad 
    782  1.1  riastrad static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p,
    783  1.1  riastrad 					       struct radeon_bo *texture,
    784  1.1  riastrad 					       struct radeon_bo *mipmap,
    785  1.1  riastrad 					       unsigned idx)
    786  1.1  riastrad {
    787  1.1  riastrad 	struct eg_surface surf;
    788  1.1  riastrad 	unsigned long toffset, moffset;
    789  1.1  riastrad 	unsigned dim, llevel, mslice, width, height, depth, i;
    790  1.1  riastrad 	u32 texdw[8];
    791  1.1  riastrad 	int r;
    792  1.1  riastrad 
    793  1.1  riastrad 	texdw[0] = radeon_get_ib_value(p, idx + 0);
    794  1.1  riastrad 	texdw[1] = radeon_get_ib_value(p, idx + 1);
    795  1.1  riastrad 	texdw[2] = radeon_get_ib_value(p, idx + 2);
    796  1.1  riastrad 	texdw[3] = radeon_get_ib_value(p, idx + 3);
    797  1.1  riastrad 	texdw[4] = radeon_get_ib_value(p, idx + 4);
    798  1.1  riastrad 	texdw[5] = radeon_get_ib_value(p, idx + 5);
    799  1.1  riastrad 	texdw[6] = radeon_get_ib_value(p, idx + 6);
    800  1.1  riastrad 	texdw[7] = radeon_get_ib_value(p, idx + 7);
    801  1.1  riastrad 	dim = G_030000_DIM(texdw[0]);
    802  1.1  riastrad 	llevel = G_030014_LAST_LEVEL(texdw[5]);
    803  1.1  riastrad 	mslice = G_030014_LAST_ARRAY(texdw[5]) + 1;
    804  1.1  riastrad 	width = G_030000_TEX_WIDTH(texdw[0]) + 1;
    805  1.1  riastrad 	height =  G_030004_TEX_HEIGHT(texdw[1]) + 1;
    806  1.1  riastrad 	depth = G_030004_TEX_DEPTH(texdw[1]) + 1;
    807  1.1  riastrad 	surf.format = G_03001C_DATA_FORMAT(texdw[7]);
    808  1.1  riastrad 	surf.nbx = (G_030000_PITCH(texdw[0]) + 1) * 8;
    809  1.1  riastrad 	surf.nbx = r600_fmt_get_nblocksx(surf.format, surf.nbx);
    810  1.1  riastrad 	surf.nby = r600_fmt_get_nblocksy(surf.format, height);
    811  1.1  riastrad 	surf.mode = G_030004_ARRAY_MODE(texdw[1]);
    812  1.1  riastrad 	surf.tsplit = G_030018_TILE_SPLIT(texdw[6]);
    813  1.1  riastrad 	surf.nbanks = G_03001C_NUM_BANKS(texdw[7]);
    814  1.1  riastrad 	surf.bankw = G_03001C_BANK_WIDTH(texdw[7]);
    815  1.1  riastrad 	surf.bankh = G_03001C_BANK_HEIGHT(texdw[7]);
    816  1.1  riastrad 	surf.mtilea = G_03001C_MACRO_TILE_ASPECT(texdw[7]);
    817  1.1  riastrad 	surf.nsamples = 1;
    818  1.1  riastrad 	toffset = texdw[2] << 8;
    819  1.1  riastrad 	moffset = texdw[3] << 8;
    820  1.1  riastrad 
    821  1.1  riastrad 	if (!r600_fmt_is_valid_texture(surf.format, p->family)) {
    822  1.1  riastrad 		dev_warn(p->dev, "%s:%d texture invalid format %d\n",
    823  1.1  riastrad 			 __func__, __LINE__, surf.format);
    824  1.1  riastrad 		return -EINVAL;
    825  1.1  riastrad 	}
    826  1.1  riastrad 	switch (dim) {
    827  1.1  riastrad 	case V_030000_SQ_TEX_DIM_1D:
    828  1.1  riastrad 	case V_030000_SQ_TEX_DIM_2D:
    829  1.1  riastrad 	case V_030000_SQ_TEX_DIM_CUBEMAP:
    830  1.1  riastrad 	case V_030000_SQ_TEX_DIM_1D_ARRAY:
    831  1.1  riastrad 	case V_030000_SQ_TEX_DIM_2D_ARRAY:
    832  1.1  riastrad 		depth = 1;
    833  1.1  riastrad 		break;
    834  1.1  riastrad 	case V_030000_SQ_TEX_DIM_2D_MSAA:
    835  1.1  riastrad 	case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA:
    836  1.1  riastrad 		surf.nsamples = 1 << llevel;
    837  1.1  riastrad 		llevel = 0;
    838  1.1  riastrad 		depth = 1;
    839  1.1  riastrad 		break;
    840  1.1  riastrad 	case V_030000_SQ_TEX_DIM_3D:
    841  1.1  riastrad 		break;
    842  1.1  riastrad 	default:
    843  1.1  riastrad 		dev_warn(p->dev, "%s:%d texture invalid dimension %d\n",
    844  1.1  riastrad 			 __func__, __LINE__, dim);
    845  1.1  riastrad 		return -EINVAL;
    846  1.1  riastrad 	}
    847  1.1  riastrad 
    848  1.1  riastrad 	r = evergreen_surface_value_conv_check(p, &surf, "texture");
    849  1.1  riastrad 	if (r) {
    850  1.1  riastrad 		return r;
    851  1.1  riastrad 	}
    852  1.1  riastrad 
    853  1.1  riastrad 	/* align height */
    854  1.1  riastrad 	evergreen_surface_check(p, &surf, NULL);
    855  1.1  riastrad 	surf.nby = ALIGN(surf.nby, surf.halign);
    856  1.1  riastrad 
    857  1.1  riastrad 	r = evergreen_surface_check(p, &surf, "texture");
    858  1.1  riastrad 	if (r) {
    859  1.1  riastrad 		dev_warn(p->dev, "%s:%d texture invalid 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
    860  1.1  riastrad 			 __func__, __LINE__, texdw[0], texdw[1], texdw[4],
    861  1.1  riastrad 			 texdw[5], texdw[6], texdw[7]);
    862  1.1  riastrad 		return r;
    863  1.1  riastrad 	}
    864  1.1  riastrad 
    865  1.1  riastrad 	/* check texture size */
    866  1.1  riastrad 	if (toffset & (surf.base_align - 1)) {
    867  1.1  riastrad 		dev_warn(p->dev, "%s:%d texture bo base %ld not aligned with %ld\n",
    868  1.1  riastrad 			 __func__, __LINE__, toffset, surf.base_align);
    869  1.1  riastrad 		return -EINVAL;
    870  1.1  riastrad 	}
    871  1.1  riastrad 	if (surf.nsamples <= 1 && moffset & (surf.base_align - 1)) {
    872  1.1  riastrad 		dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n",
    873  1.1  riastrad 			 __func__, __LINE__, moffset, surf.base_align);
    874  1.1  riastrad 		return -EINVAL;
    875  1.1  riastrad 	}
    876  1.1  riastrad 	if (dim == SQ_TEX_DIM_3D) {
    877  1.1  riastrad 		toffset += surf.layer_size * depth;
    878  1.1  riastrad 	} else {
    879  1.1  riastrad 		toffset += surf.layer_size * mslice;
    880  1.1  riastrad 	}
    881  1.1  riastrad 	if (toffset > radeon_bo_size(texture)) {
    882  1.1  riastrad 		dev_warn(p->dev, "%s:%d texture bo too small (layer size %d, "
    883  1.1  riastrad 			 "offset %ld, max layer %d, depth %d, bo size %ld) (%d %d)\n",
    884  1.1  riastrad 			 __func__, __LINE__, surf.layer_size,
    885  1.1  riastrad 			(unsigned long)texdw[2] << 8, mslice,
    886  1.1  riastrad 			depth, radeon_bo_size(texture),
    887  1.1  riastrad 			surf.nbx, surf.nby);
    888  1.1  riastrad 		return -EINVAL;
    889  1.1  riastrad 	}
    890  1.1  riastrad 
    891  1.1  riastrad 	if (!mipmap) {
    892  1.1  riastrad 		if (llevel) {
    893  1.1  riastrad 			dev_warn(p->dev, "%s:%i got NULL MIP_ADDRESS relocation\n",
    894  1.1  riastrad 				 __func__, __LINE__);
    895  1.1  riastrad 			return -EINVAL;
    896  1.1  riastrad 		} else {
    897  1.1  riastrad 			return 0; /* everything's ok */
    898  1.1  riastrad 		}
    899  1.1  riastrad 	}
    900  1.1  riastrad 
    901  1.1  riastrad 	/* check mipmap size */
    902  1.1  riastrad 	for (i = 1; i <= llevel; i++) {
    903  1.1  riastrad 		unsigned w, h, d;
    904  1.1  riastrad 
    905  1.1  riastrad 		w = r600_mip_minify(width, i);
    906  1.1  riastrad 		h = r600_mip_minify(height, i);
    907  1.1  riastrad 		d = r600_mip_minify(depth, i);
    908  1.1  riastrad 		surf.nbx = r600_fmt_get_nblocksx(surf.format, w);
    909  1.1  riastrad 		surf.nby = r600_fmt_get_nblocksy(surf.format, h);
    910  1.1  riastrad 
    911  1.1  riastrad 		switch (surf.mode) {
    912  1.1  riastrad 		case ARRAY_2D_TILED_THIN1:
    913  1.1  riastrad 			if (surf.nbx < surf.palign || surf.nby < surf.halign) {
    914  1.1  riastrad 				surf.mode = ARRAY_1D_TILED_THIN1;
    915  1.1  riastrad 			}
    916  1.1  riastrad 			/* recompute alignment */
    917  1.1  riastrad 			evergreen_surface_check(p, &surf, NULL);
    918  1.1  riastrad 			break;
    919  1.1  riastrad 		case ARRAY_LINEAR_GENERAL:
    920  1.1  riastrad 		case ARRAY_LINEAR_ALIGNED:
    921  1.1  riastrad 		case ARRAY_1D_TILED_THIN1:
    922  1.1  riastrad 			break;
    923  1.1  riastrad 		default:
    924  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid array mode %d\n",
    925  1.1  riastrad 				 __func__, __LINE__, surf.mode);
    926  1.1  riastrad 			return -EINVAL;
    927  1.1  riastrad 		}
    928  1.1  riastrad 		surf.nbx = ALIGN(surf.nbx, surf.palign);
    929  1.1  riastrad 		surf.nby = ALIGN(surf.nby, surf.halign);
    930  1.1  riastrad 
    931  1.1  riastrad 		r = evergreen_surface_check(p, &surf, "mipmap");
    932  1.1  riastrad 		if (r) {
    933  1.1  riastrad 			return r;
    934  1.1  riastrad 		}
    935  1.1  riastrad 
    936  1.1  riastrad 		if (dim == SQ_TEX_DIM_3D) {
    937  1.1  riastrad 			moffset += surf.layer_size * d;
    938  1.1  riastrad 		} else {
    939  1.1  riastrad 			moffset += surf.layer_size * mslice;
    940  1.1  riastrad 		}
    941  1.1  riastrad 		if (moffset > radeon_bo_size(mipmap)) {
    942  1.1  riastrad 			dev_warn(p->dev, "%s:%d mipmap [%d] bo too small (layer size %d, "
    943  1.1  riastrad 					"offset %ld, coffset %ld, max layer %d, depth %d, "
    944  1.1  riastrad 					"bo size %ld) level0 (%d %d %d)\n",
    945  1.1  riastrad 					__func__, __LINE__, i, surf.layer_size,
    946  1.1  riastrad 					(unsigned long)texdw[3] << 8, moffset, mslice,
    947  1.1  riastrad 					d, radeon_bo_size(mipmap),
    948  1.1  riastrad 					width, height, depth);
    949  1.1  riastrad 			dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
    950  1.1  riastrad 				 __func__, __LINE__, surf.nbx, surf.nby,
    951  1.1  riastrad 				surf.mode, surf.bpe, surf.nsamples,
    952  1.1  riastrad 				surf.bankw, surf.bankh,
    953  1.1  riastrad 				surf.tsplit, surf.mtilea);
    954  1.1  riastrad 			return -EINVAL;
    955  1.1  riastrad 		}
    956  1.1  riastrad 	}
    957  1.1  riastrad 
    958  1.1  riastrad 	return 0;
    959  1.1  riastrad }
    960  1.1  riastrad 
    961  1.1  riastrad static int evergreen_cs_track_check(struct radeon_cs_parser *p)
    962  1.1  riastrad {
    963  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
    964  1.1  riastrad 	unsigned tmp, i;
    965  1.1  riastrad 	int r;
    966  1.1  riastrad 	unsigned buffer_mask = 0;
    967  1.1  riastrad 
    968  1.1  riastrad 	/* check streamout */
    969  1.1  riastrad 	if (track->streamout_dirty && track->vgt_strmout_config) {
    970  1.1  riastrad 		for (i = 0; i < 4; i++) {
    971  1.1  riastrad 			if (track->vgt_strmout_config & (1 << i)) {
    972  1.1  riastrad 				buffer_mask |= (track->vgt_strmout_buffer_config >> (i * 4)) & 0xf;
    973  1.1  riastrad 			}
    974  1.1  riastrad 		}
    975  1.1  riastrad 
    976  1.1  riastrad 		for (i = 0; i < 4; i++) {
    977  1.1  riastrad 			if (buffer_mask & (1 << i)) {
    978  1.1  riastrad 				if (track->vgt_strmout_bo[i]) {
    979  1.1  riastrad 					u64 offset = (u64)track->vgt_strmout_bo_offset[i] +
    980  1.1  riastrad 							(u64)track->vgt_strmout_size[i];
    981  1.1  riastrad 					if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
    982  1.1  riastrad 						DRM_ERROR("streamout %d bo too small: 0x%"PRIx64", 0x%lx\n",
    983  1.1  riastrad 							  i, offset,
    984  1.1  riastrad 							  radeon_bo_size(track->vgt_strmout_bo[i]));
    985  1.1  riastrad 						return -EINVAL;
    986  1.1  riastrad 					}
    987  1.1  riastrad 				} else {
    988  1.1  riastrad 					dev_warn(p->dev, "No buffer for streamout %d\n", i);
    989  1.1  riastrad 					return -EINVAL;
    990  1.1  riastrad 				}
    991  1.1  riastrad 			}
    992  1.1  riastrad 		}
    993  1.1  riastrad 		track->streamout_dirty = false;
    994  1.1  riastrad 	}
    995  1.1  riastrad 
    996  1.1  riastrad 	if (track->sx_misc_kill_all_prims)
    997  1.1  riastrad 		return 0;
    998  1.1  riastrad 
    999  1.1  riastrad 	/* check that we have a cb for each enabled target
   1000  1.1  riastrad 	 */
   1001  1.1  riastrad 	if (track->cb_dirty) {
   1002  1.1  riastrad 		tmp = track->cb_target_mask;
   1003  1.1  riastrad 		for (i = 0; i < 8; i++) {
   1004  1.1  riastrad 			u32 format = G_028C70_FORMAT(track->cb_color_info[i]);
   1005  1.1  riastrad 
   1006  1.1  riastrad 			if (format != V_028C70_COLOR_INVALID &&
   1007  1.1  riastrad 			    (tmp >> (i * 4)) & 0xF) {
   1008  1.1  riastrad 				/* at least one component is enabled */
   1009  1.1  riastrad 				if (track->cb_color_bo[i] == NULL) {
   1010  1.1  riastrad 					dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
   1011  1.1  riastrad 						__func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i);
   1012  1.1  riastrad 					return -EINVAL;
   1013  1.1  riastrad 				}
   1014  1.1  riastrad 				/* check cb */
   1015  1.1  riastrad 				r = evergreen_cs_track_validate_cb(p, i);
   1016  1.1  riastrad 				if (r) {
   1017  1.1  riastrad 					return r;
   1018  1.1  riastrad 				}
   1019  1.1  riastrad 			}
   1020  1.1  riastrad 		}
   1021  1.1  riastrad 		track->cb_dirty = false;
   1022  1.1  riastrad 	}
   1023  1.1  riastrad 
   1024  1.1  riastrad 	if (track->db_dirty) {
   1025  1.1  riastrad 		/* Check stencil buffer */
   1026  1.1  riastrad 		if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID &&
   1027  1.1  riastrad 		    G_028800_STENCIL_ENABLE(track->db_depth_control)) {
   1028  1.1  riastrad 			r = evergreen_cs_track_validate_stencil(p);
   1029  1.1  riastrad 			if (r)
   1030  1.1  riastrad 				return r;
   1031  1.1  riastrad 		}
   1032  1.1  riastrad 		/* Check depth buffer */
   1033  1.1  riastrad 		if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID &&
   1034  1.1  riastrad 		    G_028800_Z_ENABLE(track->db_depth_control)) {
   1035  1.1  riastrad 			r = evergreen_cs_track_validate_depth(p);
   1036  1.1  riastrad 			if (r)
   1037  1.1  riastrad 				return r;
   1038  1.1  riastrad 		}
   1039  1.1  riastrad 		track->db_dirty = false;
   1040  1.1  riastrad 	}
   1041  1.1  riastrad 
   1042  1.1  riastrad 	return 0;
   1043  1.1  riastrad }
   1044  1.1  riastrad 
   1045  1.1  riastrad /**
   1046  1.1  riastrad  * evergreen_cs_packet_parse_vline() - parse userspace VLINE packet
   1047  1.1  riastrad  * @parser:		parser structure holding parsing context.
   1048  1.1  riastrad  *
   1049  1.1  riastrad  * This is an Evergreen(+)-specific function for parsing VLINE packets.
   1050  1.1  riastrad  * Real work is done by r600_cs_common_vline_parse function.
   1051  1.1  riastrad  * Here we just set up ASIC-specific register table and call
   1052  1.1  riastrad  * the common implementation function.
   1053  1.1  riastrad  */
   1054  1.1  riastrad static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p)
   1055  1.1  riastrad {
   1056  1.1  riastrad 
   1057  1.1  riastrad 	static uint32_t vline_start_end[6] = {
   1058  1.1  riastrad 		EVERGREEN_VLINE_START_END + EVERGREEN_CRTC0_REGISTER_OFFSET,
   1059  1.1  riastrad 		EVERGREEN_VLINE_START_END + EVERGREEN_CRTC1_REGISTER_OFFSET,
   1060  1.1  riastrad 		EVERGREEN_VLINE_START_END + EVERGREEN_CRTC2_REGISTER_OFFSET,
   1061  1.1  riastrad 		EVERGREEN_VLINE_START_END + EVERGREEN_CRTC3_REGISTER_OFFSET,
   1062  1.1  riastrad 		EVERGREEN_VLINE_START_END + EVERGREEN_CRTC4_REGISTER_OFFSET,
   1063  1.1  riastrad 		EVERGREEN_VLINE_START_END + EVERGREEN_CRTC5_REGISTER_OFFSET
   1064  1.1  riastrad 	};
   1065  1.1  riastrad 	static uint32_t vline_status[6] = {
   1066  1.1  riastrad 		EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET,
   1067  1.1  riastrad 		EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET,
   1068  1.1  riastrad 		EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET,
   1069  1.1  riastrad 		EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET,
   1070  1.1  riastrad 		EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET,
   1071  1.1  riastrad 		EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET
   1072  1.1  riastrad 	};
   1073  1.1  riastrad 
   1074  1.1  riastrad 	return r600_cs_common_vline_parse(p, vline_start_end, vline_status);
   1075  1.1  riastrad }
   1076  1.1  riastrad 
   1077  1.1  riastrad static int evergreen_packet0_check(struct radeon_cs_parser *p,
   1078  1.1  riastrad 				   struct radeon_cs_packet *pkt,
   1079  1.1  riastrad 				   unsigned idx, unsigned reg)
   1080  1.1  riastrad {
   1081  1.1  riastrad 	int r;
   1082  1.1  riastrad 
   1083  1.1  riastrad 	switch (reg) {
   1084  1.1  riastrad 	case EVERGREEN_VLINE_START_END:
   1085  1.1  riastrad 		r = evergreen_cs_packet_parse_vline(p);
   1086  1.1  riastrad 		if (r) {
   1087  1.1  riastrad 			DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
   1088  1.1  riastrad 					idx, reg);
   1089  1.1  riastrad 			return r;
   1090  1.1  riastrad 		}
   1091  1.1  riastrad 		break;
   1092  1.1  riastrad 	default:
   1093  1.5  riastrad 		pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx);
   1094  1.1  riastrad 		return -EINVAL;
   1095  1.1  riastrad 	}
   1096  1.1  riastrad 	return 0;
   1097  1.1  riastrad }
   1098  1.1  riastrad 
   1099  1.1  riastrad static int evergreen_cs_parse_packet0(struct radeon_cs_parser *p,
   1100  1.1  riastrad 				      struct radeon_cs_packet *pkt)
   1101  1.1  riastrad {
   1102  1.1  riastrad 	unsigned reg, i;
   1103  1.1  riastrad 	unsigned idx;
   1104  1.1  riastrad 	int r;
   1105  1.1  riastrad 
   1106  1.1  riastrad 	idx = pkt->idx + 1;
   1107  1.1  riastrad 	reg = pkt->reg;
   1108  1.1  riastrad 	for (i = 0; i <= pkt->count; i++, idx++, reg += 4) {
   1109  1.1  riastrad 		r = evergreen_packet0_check(p, pkt, idx, reg);
   1110  1.1  riastrad 		if (r) {
   1111  1.1  riastrad 			return r;
   1112  1.1  riastrad 		}
   1113  1.1  riastrad 	}
   1114  1.1  riastrad 	return 0;
   1115  1.1  riastrad }
   1116  1.1  riastrad 
   1117  1.1  riastrad /**
   1118  1.1  riastrad  * evergreen_cs_handle_reg() - process registers that need special handling.
   1119  1.1  riastrad  * @parser: parser structure holding parsing context
   1120  1.1  riastrad  * @reg: register we are testing
   1121  1.1  riastrad  * @idx: index into the cs buffer
   1122  1.1  riastrad  */
   1123  1.1  riastrad static int evergreen_cs_handle_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
   1124  1.1  riastrad {
   1125  1.1  riastrad 	struct evergreen_cs_track *track = (struct evergreen_cs_track *)p->track;
   1126  1.1  riastrad 	struct radeon_bo_list *reloc;
   1127  1.1  riastrad 	u32 tmp, *ib;
   1128  1.1  riastrad 	int r;
   1129  1.1  riastrad 
   1130  1.1  riastrad 	ib = p->ib.ptr;
   1131  1.1  riastrad 	switch (reg) {
   1132  1.1  riastrad 	/* force following reg to 0 in an attempt to disable out buffer
   1133  1.1  riastrad 	 * which will need us to better understand how it works to perform
   1134  1.1  riastrad 	 * security check on it (Jerome)
   1135  1.1  riastrad 	 */
   1136  1.1  riastrad 	case SQ_ESGS_RING_SIZE:
   1137  1.1  riastrad 	case SQ_GSVS_RING_SIZE:
   1138  1.1  riastrad 	case SQ_ESTMP_RING_SIZE:
   1139  1.1  riastrad 	case SQ_GSTMP_RING_SIZE:
   1140  1.1  riastrad 	case SQ_HSTMP_RING_SIZE:
   1141  1.1  riastrad 	case SQ_LSTMP_RING_SIZE:
   1142  1.1  riastrad 	case SQ_PSTMP_RING_SIZE:
   1143  1.1  riastrad 	case SQ_VSTMP_RING_SIZE:
   1144  1.1  riastrad 	case SQ_ESGS_RING_ITEMSIZE:
   1145  1.1  riastrad 	case SQ_ESTMP_RING_ITEMSIZE:
   1146  1.1  riastrad 	case SQ_GSTMP_RING_ITEMSIZE:
   1147  1.1  riastrad 	case SQ_GSVS_RING_ITEMSIZE:
   1148  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE:
   1149  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE_1:
   1150  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE_2:
   1151  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE_3:
   1152  1.1  riastrad 	case SQ_GSVS_RING_OFFSET_1:
   1153  1.1  riastrad 	case SQ_GSVS_RING_OFFSET_2:
   1154  1.1  riastrad 	case SQ_GSVS_RING_OFFSET_3:
   1155  1.1  riastrad 	case SQ_HSTMP_RING_ITEMSIZE:
   1156  1.1  riastrad 	case SQ_LSTMP_RING_ITEMSIZE:
   1157  1.1  riastrad 	case SQ_PSTMP_RING_ITEMSIZE:
   1158  1.1  riastrad 	case SQ_VSTMP_RING_ITEMSIZE:
   1159  1.1  riastrad 	case VGT_TF_RING_SIZE:
   1160  1.1  riastrad 		/* get value to populate the IB don't remove */
   1161  1.1  riastrad 		/*tmp =radeon_get_ib_value(p, idx);
   1162  1.1  riastrad 		  ib[idx] = 0;*/
   1163  1.1  riastrad 		break;
   1164  1.1  riastrad 	case SQ_ESGS_RING_BASE:
   1165  1.1  riastrad 	case SQ_GSVS_RING_BASE:
   1166  1.1  riastrad 	case SQ_ESTMP_RING_BASE:
   1167  1.1  riastrad 	case SQ_GSTMP_RING_BASE:
   1168  1.1  riastrad 	case SQ_HSTMP_RING_BASE:
   1169  1.1  riastrad 	case SQ_LSTMP_RING_BASE:
   1170  1.1  riastrad 	case SQ_PSTMP_RING_BASE:
   1171  1.1  riastrad 	case SQ_VSTMP_RING_BASE:
   1172  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1173  1.1  riastrad 		if (r) {
   1174  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1175  1.1  riastrad 					"0x%04X\n", reg);
   1176  1.1  riastrad 			return -EINVAL;
   1177  1.1  riastrad 		}
   1178  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1179  1.1  riastrad 		break;
   1180  1.1  riastrad 	case DB_DEPTH_CONTROL:
   1181  1.1  riastrad 		track->db_depth_control = radeon_get_ib_value(p, idx);
   1182  1.1  riastrad 		track->db_dirty = true;
   1183  1.1  riastrad 		break;
   1184  1.1  riastrad 	case CAYMAN_DB_EQAA:
   1185  1.1  riastrad 		if (p->rdev->family < CHIP_CAYMAN) {
   1186  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1187  1.1  riastrad 				 "0x%04X\n", reg);
   1188  1.1  riastrad 			return -EINVAL;
   1189  1.1  riastrad 		}
   1190  1.1  riastrad 		break;
   1191  1.1  riastrad 	case CAYMAN_DB_DEPTH_INFO:
   1192  1.1  riastrad 		if (p->rdev->family < CHIP_CAYMAN) {
   1193  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1194  1.1  riastrad 				 "0x%04X\n", reg);
   1195  1.1  riastrad 			return -EINVAL;
   1196  1.1  riastrad 		}
   1197  1.1  riastrad 		break;
   1198  1.1  riastrad 	case DB_Z_INFO:
   1199  1.1  riastrad 		track->db_z_info = radeon_get_ib_value(p, idx);
   1200  1.1  riastrad 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
   1201  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1202  1.1  riastrad 			if (r) {
   1203  1.1  riastrad 				dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1204  1.1  riastrad 						"0x%04X\n", reg);
   1205  1.1  riastrad 				return -EINVAL;
   1206  1.1  riastrad 			}
   1207  1.1  riastrad 			ib[idx] &= ~Z_ARRAY_MODE(0xf);
   1208  1.1  riastrad 			track->db_z_info &= ~Z_ARRAY_MODE(0xf);
   1209  1.1  riastrad 			ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   1210  1.1  riastrad 			track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   1211  1.1  riastrad 			if (reloc->tiling_flags & RADEON_TILING_MACRO) {
   1212  1.1  riastrad 				unsigned bankw, bankh, mtaspect, tile_split;
   1213  1.1  riastrad 
   1214  1.1  riastrad 				evergreen_tiling_fields(reloc->tiling_flags,
   1215  1.1  riastrad 							&bankw, &bankh, &mtaspect,
   1216  1.1  riastrad 							&tile_split);
   1217  1.1  riastrad 				ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
   1218  1.1  riastrad 				ib[idx] |= DB_TILE_SPLIT(tile_split) |
   1219  1.1  riastrad 						DB_BANK_WIDTH(bankw) |
   1220  1.1  riastrad 						DB_BANK_HEIGHT(bankh) |
   1221  1.1  riastrad 						DB_MACRO_TILE_ASPECT(mtaspect);
   1222  1.1  riastrad 			}
   1223  1.1  riastrad 		}
   1224  1.1  riastrad 		track->db_dirty = true;
   1225  1.1  riastrad 		break;
   1226  1.1  riastrad 	case DB_STENCIL_INFO:
   1227  1.1  riastrad 		track->db_s_info = radeon_get_ib_value(p, idx);
   1228  1.1  riastrad 		track->db_dirty = true;
   1229  1.1  riastrad 		break;
   1230  1.1  riastrad 	case DB_DEPTH_VIEW:
   1231  1.1  riastrad 		track->db_depth_view = radeon_get_ib_value(p, idx);
   1232  1.1  riastrad 		track->db_dirty = true;
   1233  1.1  riastrad 		break;
   1234  1.1  riastrad 	case DB_DEPTH_SIZE:
   1235  1.1  riastrad 		track->db_depth_size = radeon_get_ib_value(p, idx);
   1236  1.1  riastrad 		track->db_dirty = true;
   1237  1.1  riastrad 		break;
   1238  1.1  riastrad 	case R_02805C_DB_DEPTH_SLICE:
   1239  1.1  riastrad 		track->db_depth_slice = radeon_get_ib_value(p, idx);
   1240  1.1  riastrad 		track->db_dirty = true;
   1241  1.1  riastrad 		break;
   1242  1.1  riastrad 	case DB_Z_READ_BASE:
   1243  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1244  1.1  riastrad 		if (r) {
   1245  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1246  1.1  riastrad 					"0x%04X\n", reg);
   1247  1.1  riastrad 			return -EINVAL;
   1248  1.1  riastrad 		}
   1249  1.1  riastrad 		track->db_z_read_offset = radeon_get_ib_value(p, idx);
   1250  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1251  1.1  riastrad 		track->db_z_read_bo = reloc->robj;
   1252  1.1  riastrad 		track->db_dirty = true;
   1253  1.1  riastrad 		break;
   1254  1.1  riastrad 	case DB_Z_WRITE_BASE:
   1255  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1256  1.1  riastrad 		if (r) {
   1257  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1258  1.1  riastrad 					"0x%04X\n", reg);
   1259  1.1  riastrad 			return -EINVAL;
   1260  1.1  riastrad 		}
   1261  1.1  riastrad 		track->db_z_write_offset = radeon_get_ib_value(p, idx);
   1262  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1263  1.1  riastrad 		track->db_z_write_bo = reloc->robj;
   1264  1.1  riastrad 		track->db_dirty = true;
   1265  1.1  riastrad 		break;
   1266  1.1  riastrad 	case DB_STENCIL_READ_BASE:
   1267  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1268  1.1  riastrad 		if (r) {
   1269  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1270  1.1  riastrad 					"0x%04X\n", reg);
   1271  1.1  riastrad 			return -EINVAL;
   1272  1.1  riastrad 		}
   1273  1.1  riastrad 		track->db_s_read_offset = radeon_get_ib_value(p, idx);
   1274  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1275  1.1  riastrad 		track->db_s_read_bo = reloc->robj;
   1276  1.1  riastrad 		track->db_dirty = true;
   1277  1.1  riastrad 		break;
   1278  1.1  riastrad 	case DB_STENCIL_WRITE_BASE:
   1279  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1280  1.1  riastrad 		if (r) {
   1281  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1282  1.1  riastrad 					"0x%04X\n", reg);
   1283  1.1  riastrad 			return -EINVAL;
   1284  1.1  riastrad 		}
   1285  1.1  riastrad 		track->db_s_write_offset = radeon_get_ib_value(p, idx);
   1286  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1287  1.1  riastrad 		track->db_s_write_bo = reloc->robj;
   1288  1.1  riastrad 		track->db_dirty = true;
   1289  1.1  riastrad 		break;
   1290  1.1  riastrad 	case VGT_STRMOUT_CONFIG:
   1291  1.1  riastrad 		track->vgt_strmout_config = radeon_get_ib_value(p, idx);
   1292  1.1  riastrad 		track->streamout_dirty = true;
   1293  1.1  riastrad 		break;
   1294  1.1  riastrad 	case VGT_STRMOUT_BUFFER_CONFIG:
   1295  1.1  riastrad 		track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx);
   1296  1.1  riastrad 		track->streamout_dirty = true;
   1297  1.1  riastrad 		break;
   1298  1.1  riastrad 	case VGT_STRMOUT_BUFFER_BASE_0:
   1299  1.1  riastrad 	case VGT_STRMOUT_BUFFER_BASE_1:
   1300  1.1  riastrad 	case VGT_STRMOUT_BUFFER_BASE_2:
   1301  1.1  riastrad 	case VGT_STRMOUT_BUFFER_BASE_3:
   1302  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1303  1.1  riastrad 		if (r) {
   1304  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1305  1.1  riastrad 					"0x%04X\n", reg);
   1306  1.1  riastrad 			return -EINVAL;
   1307  1.1  riastrad 		}
   1308  1.1  riastrad 		tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16;
   1309  1.1  riastrad 		track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
   1310  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1311  1.1  riastrad 		track->vgt_strmout_bo[tmp] = reloc->robj;
   1312  1.1  riastrad 		track->streamout_dirty = true;
   1313  1.1  riastrad 		break;
   1314  1.1  riastrad 	case VGT_STRMOUT_BUFFER_SIZE_0:
   1315  1.1  riastrad 	case VGT_STRMOUT_BUFFER_SIZE_1:
   1316  1.1  riastrad 	case VGT_STRMOUT_BUFFER_SIZE_2:
   1317  1.1  riastrad 	case VGT_STRMOUT_BUFFER_SIZE_3:
   1318  1.1  riastrad 		tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16;
   1319  1.1  riastrad 		/* size in register is DWs, convert to bytes */
   1320  1.1  riastrad 		track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4;
   1321  1.1  riastrad 		track->streamout_dirty = true;
   1322  1.1  riastrad 		break;
   1323  1.1  riastrad 	case CP_COHER_BASE:
   1324  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1325  1.1  riastrad 		if (r) {
   1326  1.1  riastrad 			dev_warn(p->dev, "missing reloc for CP_COHER_BASE "
   1327  1.1  riastrad 					"0x%04X\n", reg);
   1328  1.1  riastrad 			return -EINVAL;
   1329  1.1  riastrad 		}
   1330  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1331  1.2       mrg 		break;
   1332  1.1  riastrad 	case CB_TARGET_MASK:
   1333  1.1  riastrad 		track->cb_target_mask = radeon_get_ib_value(p, idx);
   1334  1.1  riastrad 		track->cb_dirty = true;
   1335  1.1  riastrad 		break;
   1336  1.1  riastrad 	case CB_SHADER_MASK:
   1337  1.1  riastrad 		track->cb_shader_mask = radeon_get_ib_value(p, idx);
   1338  1.1  riastrad 		track->cb_dirty = true;
   1339  1.1  riastrad 		break;
   1340  1.1  riastrad 	case PA_SC_AA_CONFIG:
   1341  1.1  riastrad 		if (p->rdev->family >= CHIP_CAYMAN) {
   1342  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1343  1.1  riastrad 				 "0x%04X\n", reg);
   1344  1.1  riastrad 			return -EINVAL;
   1345  1.1  riastrad 		}
   1346  1.1  riastrad 		tmp = radeon_get_ib_value(p, idx) & MSAA_NUM_SAMPLES_MASK;
   1347  1.1  riastrad 		track->nsamples = 1 << tmp;
   1348  1.1  riastrad 		break;
   1349  1.1  riastrad 	case CAYMAN_PA_SC_AA_CONFIG:
   1350  1.1  riastrad 		if (p->rdev->family < CHIP_CAYMAN) {
   1351  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1352  1.1  riastrad 				 "0x%04X\n", reg);
   1353  1.1  riastrad 			return -EINVAL;
   1354  1.1  riastrad 		}
   1355  1.1  riastrad 		tmp = radeon_get_ib_value(p, idx) & CAYMAN_MSAA_NUM_SAMPLES_MASK;
   1356  1.1  riastrad 		track->nsamples = 1 << tmp;
   1357  1.1  riastrad 		break;
   1358  1.1  riastrad 	case CB_COLOR0_VIEW:
   1359  1.1  riastrad 	case CB_COLOR1_VIEW:
   1360  1.1  riastrad 	case CB_COLOR2_VIEW:
   1361  1.1  riastrad 	case CB_COLOR3_VIEW:
   1362  1.1  riastrad 	case CB_COLOR4_VIEW:
   1363  1.1  riastrad 	case CB_COLOR5_VIEW:
   1364  1.1  riastrad 	case CB_COLOR6_VIEW:
   1365  1.1  riastrad 	case CB_COLOR7_VIEW:
   1366  1.1  riastrad 		tmp = (reg - CB_COLOR0_VIEW) / 0x3c;
   1367  1.1  riastrad 		track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
   1368  1.1  riastrad 		track->cb_dirty = true;
   1369  1.1  riastrad 		break;
   1370  1.1  riastrad 	case CB_COLOR8_VIEW:
   1371  1.1  riastrad 	case CB_COLOR9_VIEW:
   1372  1.1  riastrad 	case CB_COLOR10_VIEW:
   1373  1.1  riastrad 	case CB_COLOR11_VIEW:
   1374  1.1  riastrad 		tmp = ((reg - CB_COLOR8_VIEW) / 0x1c) + 8;
   1375  1.1  riastrad 		track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
   1376  1.1  riastrad 		track->cb_dirty = true;
   1377  1.1  riastrad 		break;
   1378  1.1  riastrad 	case CB_COLOR0_INFO:
   1379  1.1  riastrad 	case CB_COLOR1_INFO:
   1380  1.1  riastrad 	case CB_COLOR2_INFO:
   1381  1.1  riastrad 	case CB_COLOR3_INFO:
   1382  1.1  riastrad 	case CB_COLOR4_INFO:
   1383  1.1  riastrad 	case CB_COLOR5_INFO:
   1384  1.1  riastrad 	case CB_COLOR6_INFO:
   1385  1.1  riastrad 	case CB_COLOR7_INFO:
   1386  1.1  riastrad 		tmp = (reg - CB_COLOR0_INFO) / 0x3c;
   1387  1.1  riastrad 		track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
   1388  1.1  riastrad 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
   1389  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1390  1.1  riastrad 			if (r) {
   1391  1.1  riastrad 				dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1392  1.1  riastrad 						"0x%04X\n", reg);
   1393  1.1  riastrad 				return -EINVAL;
   1394  1.1  riastrad 			}
   1395  1.1  riastrad 			ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   1396  1.1  riastrad 			track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   1397  1.1  riastrad 		}
   1398  1.1  riastrad 		track->cb_dirty = true;
   1399  1.1  riastrad 		break;
   1400  1.1  riastrad 	case CB_COLOR8_INFO:
   1401  1.1  riastrad 	case CB_COLOR9_INFO:
   1402  1.1  riastrad 	case CB_COLOR10_INFO:
   1403  1.1  riastrad 	case CB_COLOR11_INFO:
   1404  1.1  riastrad 		tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8;
   1405  1.1  riastrad 		track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
   1406  1.1  riastrad 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
   1407  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1408  1.1  riastrad 			if (r) {
   1409  1.1  riastrad 				dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1410  1.1  riastrad 						"0x%04X\n", reg);
   1411  1.1  riastrad 				return -EINVAL;
   1412  1.1  riastrad 			}
   1413  1.1  riastrad 			ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   1414  1.1  riastrad 			track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   1415  1.1  riastrad 		}
   1416  1.1  riastrad 		track->cb_dirty = true;
   1417  1.1  riastrad 		break;
   1418  1.1  riastrad 	case CB_COLOR0_PITCH:
   1419  1.1  riastrad 	case CB_COLOR1_PITCH:
   1420  1.1  riastrad 	case CB_COLOR2_PITCH:
   1421  1.1  riastrad 	case CB_COLOR3_PITCH:
   1422  1.1  riastrad 	case CB_COLOR4_PITCH:
   1423  1.1  riastrad 	case CB_COLOR5_PITCH:
   1424  1.1  riastrad 	case CB_COLOR6_PITCH:
   1425  1.1  riastrad 	case CB_COLOR7_PITCH:
   1426  1.1  riastrad 		tmp = (reg - CB_COLOR0_PITCH) / 0x3c;
   1427  1.1  riastrad 		track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
   1428  1.1  riastrad 		track->cb_dirty = true;
   1429  1.1  riastrad 		break;
   1430  1.1  riastrad 	case CB_COLOR8_PITCH:
   1431  1.1  riastrad 	case CB_COLOR9_PITCH:
   1432  1.1  riastrad 	case CB_COLOR10_PITCH:
   1433  1.1  riastrad 	case CB_COLOR11_PITCH:
   1434  1.1  riastrad 		tmp = ((reg - CB_COLOR8_PITCH) / 0x1c) + 8;
   1435  1.1  riastrad 		track->cb_color_pitch[tmp] = radeon_get_ib_value(p, idx);
   1436  1.1  riastrad 		track->cb_dirty = true;
   1437  1.1  riastrad 		break;
   1438  1.1  riastrad 	case CB_COLOR0_SLICE:
   1439  1.1  riastrad 	case CB_COLOR1_SLICE:
   1440  1.1  riastrad 	case CB_COLOR2_SLICE:
   1441  1.1  riastrad 	case CB_COLOR3_SLICE:
   1442  1.1  riastrad 	case CB_COLOR4_SLICE:
   1443  1.1  riastrad 	case CB_COLOR5_SLICE:
   1444  1.1  riastrad 	case CB_COLOR6_SLICE:
   1445  1.1  riastrad 	case CB_COLOR7_SLICE:
   1446  1.1  riastrad 		tmp = (reg - CB_COLOR0_SLICE) / 0x3c;
   1447  1.1  riastrad 		track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
   1448  1.1  riastrad 		track->cb_color_slice_idx[tmp] = idx;
   1449  1.1  riastrad 		track->cb_dirty = true;
   1450  1.1  riastrad 		break;
   1451  1.1  riastrad 	case CB_COLOR8_SLICE:
   1452  1.1  riastrad 	case CB_COLOR9_SLICE:
   1453  1.1  riastrad 	case CB_COLOR10_SLICE:
   1454  1.1  riastrad 	case CB_COLOR11_SLICE:
   1455  1.1  riastrad 		tmp = ((reg - CB_COLOR8_SLICE) / 0x1c) + 8;
   1456  1.1  riastrad 		track->cb_color_slice[tmp] = radeon_get_ib_value(p, idx);
   1457  1.1  riastrad 		track->cb_color_slice_idx[tmp] = idx;
   1458  1.1  riastrad 		track->cb_dirty = true;
   1459  1.1  riastrad 		break;
   1460  1.1  riastrad 	case CB_COLOR0_ATTRIB:
   1461  1.1  riastrad 	case CB_COLOR1_ATTRIB:
   1462  1.1  riastrad 	case CB_COLOR2_ATTRIB:
   1463  1.1  riastrad 	case CB_COLOR3_ATTRIB:
   1464  1.1  riastrad 	case CB_COLOR4_ATTRIB:
   1465  1.1  riastrad 	case CB_COLOR5_ATTRIB:
   1466  1.1  riastrad 	case CB_COLOR6_ATTRIB:
   1467  1.1  riastrad 	case CB_COLOR7_ATTRIB:
   1468  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1469  1.1  riastrad 		if (r) {
   1470  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1471  1.1  riastrad 					"0x%04X\n", reg);
   1472  1.1  riastrad 			return -EINVAL;
   1473  1.1  riastrad 		}
   1474  1.1  riastrad 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
   1475  1.1  riastrad 			if (reloc->tiling_flags & RADEON_TILING_MACRO) {
   1476  1.1  riastrad 				unsigned bankw, bankh, mtaspect, tile_split;
   1477  1.1  riastrad 
   1478  1.1  riastrad 				evergreen_tiling_fields(reloc->tiling_flags,
   1479  1.1  riastrad 							&bankw, &bankh, &mtaspect,
   1480  1.1  riastrad 							&tile_split);
   1481  1.1  riastrad 				ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
   1482  1.1  riastrad 				ib[idx] |= CB_TILE_SPLIT(tile_split) |
   1483  1.1  riastrad 					   CB_BANK_WIDTH(bankw) |
   1484  1.1  riastrad 					   CB_BANK_HEIGHT(bankh) |
   1485  1.1  riastrad 					   CB_MACRO_TILE_ASPECT(mtaspect);
   1486  1.1  riastrad 			}
   1487  1.1  riastrad 		}
   1488  1.1  riastrad 		tmp = ((reg - CB_COLOR0_ATTRIB) / 0x3c);
   1489  1.1  riastrad 		track->cb_color_attrib[tmp] = ib[idx];
   1490  1.1  riastrad 		track->cb_dirty = true;
   1491  1.1  riastrad 		break;
   1492  1.1  riastrad 	case CB_COLOR8_ATTRIB:
   1493  1.1  riastrad 	case CB_COLOR9_ATTRIB:
   1494  1.1  riastrad 	case CB_COLOR10_ATTRIB:
   1495  1.1  riastrad 	case CB_COLOR11_ATTRIB:
   1496  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1497  1.1  riastrad 		if (r) {
   1498  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1499  1.1  riastrad 					"0x%04X\n", reg);
   1500  1.1  riastrad 			return -EINVAL;
   1501  1.1  riastrad 		}
   1502  1.1  riastrad 		if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
   1503  1.1  riastrad 			if (reloc->tiling_flags & RADEON_TILING_MACRO) {
   1504  1.1  riastrad 				unsigned bankw, bankh, mtaspect, tile_split;
   1505  1.1  riastrad 
   1506  1.1  riastrad 				evergreen_tiling_fields(reloc->tiling_flags,
   1507  1.1  riastrad 							&bankw, &bankh, &mtaspect,
   1508  1.1  riastrad 							&tile_split);
   1509  1.1  riastrad 				ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
   1510  1.1  riastrad 				ib[idx] |= CB_TILE_SPLIT(tile_split) |
   1511  1.1  riastrad 					   CB_BANK_WIDTH(bankw) |
   1512  1.1  riastrad 					   CB_BANK_HEIGHT(bankh) |
   1513  1.1  riastrad 					   CB_MACRO_TILE_ASPECT(mtaspect);
   1514  1.1  riastrad 			}
   1515  1.1  riastrad 		}
   1516  1.1  riastrad 		tmp = ((reg - CB_COLOR8_ATTRIB) / 0x1c) + 8;
   1517  1.1  riastrad 		track->cb_color_attrib[tmp] = ib[idx];
   1518  1.1  riastrad 		track->cb_dirty = true;
   1519  1.1  riastrad 		break;
   1520  1.1  riastrad 	case CB_COLOR0_FMASK:
   1521  1.1  riastrad 	case CB_COLOR1_FMASK:
   1522  1.1  riastrad 	case CB_COLOR2_FMASK:
   1523  1.1  riastrad 	case CB_COLOR3_FMASK:
   1524  1.1  riastrad 	case CB_COLOR4_FMASK:
   1525  1.1  riastrad 	case CB_COLOR5_FMASK:
   1526  1.1  riastrad 	case CB_COLOR6_FMASK:
   1527  1.1  riastrad 	case CB_COLOR7_FMASK:
   1528  1.1  riastrad 		tmp = (reg - CB_COLOR0_FMASK) / 0x3c;
   1529  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1530  1.1  riastrad 		if (r) {
   1531  1.1  riastrad 			dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
   1532  1.1  riastrad 			return -EINVAL;
   1533  1.1  riastrad 		}
   1534  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1535  1.1  riastrad 		track->cb_color_fmask_bo[tmp] = reloc->robj;
   1536  1.1  riastrad 		break;
   1537  1.1  riastrad 	case CB_COLOR0_CMASK:
   1538  1.1  riastrad 	case CB_COLOR1_CMASK:
   1539  1.1  riastrad 	case CB_COLOR2_CMASK:
   1540  1.1  riastrad 	case CB_COLOR3_CMASK:
   1541  1.1  riastrad 	case CB_COLOR4_CMASK:
   1542  1.1  riastrad 	case CB_COLOR5_CMASK:
   1543  1.1  riastrad 	case CB_COLOR6_CMASK:
   1544  1.1  riastrad 	case CB_COLOR7_CMASK:
   1545  1.1  riastrad 		tmp = (reg - CB_COLOR0_CMASK) / 0x3c;
   1546  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1547  1.1  riastrad 		if (r) {
   1548  1.1  riastrad 			dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg);
   1549  1.1  riastrad 			return -EINVAL;
   1550  1.1  riastrad 		}
   1551  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1552  1.1  riastrad 		track->cb_color_cmask_bo[tmp] = reloc->robj;
   1553  1.1  riastrad 		break;
   1554  1.1  riastrad 	case CB_COLOR0_FMASK_SLICE:
   1555  1.1  riastrad 	case CB_COLOR1_FMASK_SLICE:
   1556  1.1  riastrad 	case CB_COLOR2_FMASK_SLICE:
   1557  1.1  riastrad 	case CB_COLOR3_FMASK_SLICE:
   1558  1.1  riastrad 	case CB_COLOR4_FMASK_SLICE:
   1559  1.1  riastrad 	case CB_COLOR5_FMASK_SLICE:
   1560  1.1  riastrad 	case CB_COLOR6_FMASK_SLICE:
   1561  1.1  riastrad 	case CB_COLOR7_FMASK_SLICE:
   1562  1.1  riastrad 		tmp = (reg - CB_COLOR0_FMASK_SLICE) / 0x3c;
   1563  1.1  riastrad 		track->cb_color_fmask_slice[tmp] = radeon_get_ib_value(p, idx);
   1564  1.1  riastrad 		break;
   1565  1.1  riastrad 	case CB_COLOR0_CMASK_SLICE:
   1566  1.1  riastrad 	case CB_COLOR1_CMASK_SLICE:
   1567  1.1  riastrad 	case CB_COLOR2_CMASK_SLICE:
   1568  1.1  riastrad 	case CB_COLOR3_CMASK_SLICE:
   1569  1.1  riastrad 	case CB_COLOR4_CMASK_SLICE:
   1570  1.1  riastrad 	case CB_COLOR5_CMASK_SLICE:
   1571  1.1  riastrad 	case CB_COLOR6_CMASK_SLICE:
   1572  1.1  riastrad 	case CB_COLOR7_CMASK_SLICE:
   1573  1.1  riastrad 		tmp = (reg - CB_COLOR0_CMASK_SLICE) / 0x3c;
   1574  1.1  riastrad 		track->cb_color_cmask_slice[tmp] = radeon_get_ib_value(p, idx);
   1575  1.1  riastrad 		break;
   1576  1.1  riastrad 	case CB_COLOR0_BASE:
   1577  1.1  riastrad 	case CB_COLOR1_BASE:
   1578  1.1  riastrad 	case CB_COLOR2_BASE:
   1579  1.1  riastrad 	case CB_COLOR3_BASE:
   1580  1.1  riastrad 	case CB_COLOR4_BASE:
   1581  1.1  riastrad 	case CB_COLOR5_BASE:
   1582  1.1  riastrad 	case CB_COLOR6_BASE:
   1583  1.1  riastrad 	case CB_COLOR7_BASE:
   1584  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1585  1.1  riastrad 		if (r) {
   1586  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1587  1.1  riastrad 					"0x%04X\n", reg);
   1588  1.1  riastrad 			return -EINVAL;
   1589  1.1  riastrad 		}
   1590  1.1  riastrad 		tmp = (reg - CB_COLOR0_BASE) / 0x3c;
   1591  1.1  riastrad 		track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
   1592  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1593  1.1  riastrad 		track->cb_color_bo[tmp] = reloc->robj;
   1594  1.1  riastrad 		track->cb_dirty = true;
   1595  1.1  riastrad 		break;
   1596  1.1  riastrad 	case CB_COLOR8_BASE:
   1597  1.1  riastrad 	case CB_COLOR9_BASE:
   1598  1.1  riastrad 	case CB_COLOR10_BASE:
   1599  1.1  riastrad 	case CB_COLOR11_BASE:
   1600  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1601  1.1  riastrad 		if (r) {
   1602  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1603  1.1  riastrad 					"0x%04X\n", reg);
   1604  1.1  riastrad 			return -EINVAL;
   1605  1.1  riastrad 		}
   1606  1.1  riastrad 		tmp = ((reg - CB_COLOR8_BASE) / 0x1c) + 8;
   1607  1.1  riastrad 		track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx);
   1608  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1609  1.1  riastrad 		track->cb_color_bo[tmp] = reloc->robj;
   1610  1.1  riastrad 		track->cb_dirty = true;
   1611  1.1  riastrad 		break;
   1612  1.1  riastrad 	case DB_HTILE_DATA_BASE:
   1613  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1614  1.1  riastrad 		if (r) {
   1615  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1616  1.1  riastrad 					"0x%04X\n", reg);
   1617  1.1  riastrad 			return -EINVAL;
   1618  1.1  riastrad 		}
   1619  1.1  riastrad 		track->htile_offset = radeon_get_ib_value(p, idx);
   1620  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1621  1.1  riastrad 		track->htile_bo = reloc->robj;
   1622  1.1  riastrad 		track->db_dirty = true;
   1623  1.1  riastrad 		break;
   1624  1.1  riastrad 	case DB_HTILE_SURFACE:
   1625  1.1  riastrad 		/* 8x8 only */
   1626  1.1  riastrad 		track->htile_surface = radeon_get_ib_value(p, idx);
   1627  1.1  riastrad 		/* force 8x8 htile width and height */
   1628  1.1  riastrad 		ib[idx] |= 3;
   1629  1.1  riastrad 		track->db_dirty = true;
   1630  1.1  riastrad 		break;
   1631  1.1  riastrad 	case CB_IMMED0_BASE:
   1632  1.1  riastrad 	case CB_IMMED1_BASE:
   1633  1.1  riastrad 	case CB_IMMED2_BASE:
   1634  1.1  riastrad 	case CB_IMMED3_BASE:
   1635  1.1  riastrad 	case CB_IMMED4_BASE:
   1636  1.1  riastrad 	case CB_IMMED5_BASE:
   1637  1.1  riastrad 	case CB_IMMED6_BASE:
   1638  1.1  riastrad 	case CB_IMMED7_BASE:
   1639  1.1  riastrad 	case CB_IMMED8_BASE:
   1640  1.1  riastrad 	case CB_IMMED9_BASE:
   1641  1.1  riastrad 	case CB_IMMED10_BASE:
   1642  1.1  riastrad 	case CB_IMMED11_BASE:
   1643  1.1  riastrad 	case SQ_PGM_START_FS:
   1644  1.1  riastrad 	case SQ_PGM_START_ES:
   1645  1.1  riastrad 	case SQ_PGM_START_VS:
   1646  1.1  riastrad 	case SQ_PGM_START_GS:
   1647  1.1  riastrad 	case SQ_PGM_START_PS:
   1648  1.1  riastrad 	case SQ_PGM_START_HS:
   1649  1.1  riastrad 	case SQ_PGM_START_LS:
   1650  1.1  riastrad 	case SQ_CONST_MEM_BASE:
   1651  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_0:
   1652  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_1:
   1653  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_2:
   1654  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_3:
   1655  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_4:
   1656  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_5:
   1657  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_6:
   1658  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_7:
   1659  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_8:
   1660  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_9:
   1661  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_10:
   1662  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_11:
   1663  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_12:
   1664  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_13:
   1665  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_14:
   1666  1.1  riastrad 	case SQ_ALU_CONST_CACHE_GS_15:
   1667  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_0:
   1668  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_1:
   1669  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_2:
   1670  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_3:
   1671  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_4:
   1672  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_5:
   1673  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_6:
   1674  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_7:
   1675  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_8:
   1676  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_9:
   1677  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_10:
   1678  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_11:
   1679  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_12:
   1680  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_13:
   1681  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_14:
   1682  1.1  riastrad 	case SQ_ALU_CONST_CACHE_PS_15:
   1683  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_0:
   1684  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_1:
   1685  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_2:
   1686  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_3:
   1687  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_4:
   1688  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_5:
   1689  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_6:
   1690  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_7:
   1691  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_8:
   1692  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_9:
   1693  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_10:
   1694  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_11:
   1695  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_12:
   1696  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_13:
   1697  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_14:
   1698  1.1  riastrad 	case SQ_ALU_CONST_CACHE_VS_15:
   1699  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_0:
   1700  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_1:
   1701  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_2:
   1702  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_3:
   1703  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_4:
   1704  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_5:
   1705  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_6:
   1706  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_7:
   1707  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_8:
   1708  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_9:
   1709  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_10:
   1710  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_11:
   1711  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_12:
   1712  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_13:
   1713  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_14:
   1714  1.1  riastrad 	case SQ_ALU_CONST_CACHE_HS_15:
   1715  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_0:
   1716  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_1:
   1717  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_2:
   1718  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_3:
   1719  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_4:
   1720  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_5:
   1721  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_6:
   1722  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_7:
   1723  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_8:
   1724  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_9:
   1725  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_10:
   1726  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_11:
   1727  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_12:
   1728  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_13:
   1729  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_14:
   1730  1.1  riastrad 	case SQ_ALU_CONST_CACHE_LS_15:
   1731  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1732  1.1  riastrad 		if (r) {
   1733  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1734  1.1  riastrad 					"0x%04X\n", reg);
   1735  1.1  riastrad 			return -EINVAL;
   1736  1.1  riastrad 		}
   1737  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1738  1.1  riastrad 		break;
   1739  1.1  riastrad 	case SX_MEMORY_EXPORT_BASE:
   1740  1.1  riastrad 		if (p->rdev->family >= CHIP_CAYMAN) {
   1741  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONFIG_REG "
   1742  1.1  riastrad 				 "0x%04X\n", reg);
   1743  1.1  riastrad 			return -EINVAL;
   1744  1.1  riastrad 		}
   1745  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1746  1.1  riastrad 		if (r) {
   1747  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONFIG_REG "
   1748  1.1  riastrad 					"0x%04X\n", reg);
   1749  1.1  riastrad 			return -EINVAL;
   1750  1.1  riastrad 		}
   1751  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1752  1.1  riastrad 		break;
   1753  1.1  riastrad 	case CAYMAN_SX_SCATTER_EXPORT_BASE:
   1754  1.1  riastrad 		if (p->rdev->family < CHIP_CAYMAN) {
   1755  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1756  1.1  riastrad 				 "0x%04X\n", reg);
   1757  1.1  riastrad 			return -EINVAL;
   1758  1.1  riastrad 		}
   1759  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1760  1.1  riastrad 		if (r) {
   1761  1.1  riastrad 			dev_warn(p->dev, "bad SET_CONTEXT_REG "
   1762  1.1  riastrad 					"0x%04X\n", reg);
   1763  1.1  riastrad 			return -EINVAL;
   1764  1.1  riastrad 		}
   1765  1.1  riastrad 		ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   1766  1.1  riastrad 		break;
   1767  1.1  riastrad 	case SX_MISC:
   1768  1.1  riastrad 		track->sx_misc_kill_all_prims = (radeon_get_ib_value(p, idx) & 0x1) != 0;
   1769  1.1  riastrad 		break;
   1770  1.1  riastrad 	default:
   1771  1.1  riastrad 		dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
   1772  1.1  riastrad 		return -EINVAL;
   1773  1.1  riastrad 	}
   1774  1.1  riastrad 	return 0;
   1775  1.1  riastrad }
   1776  1.1  riastrad 
   1777  1.1  riastrad /**
   1778  1.1  riastrad  * evergreen_is_safe_reg() - check if register is authorized or not
   1779  1.1  riastrad  * @parser: parser structure holding parsing context
   1780  1.1  riastrad  * @reg: register we are testing
   1781  1.1  riastrad  *
   1782  1.1  riastrad  * This function will test against reg_safe_bm and return true
   1783  1.1  riastrad  * if register is safe or false otherwise.
   1784  1.1  riastrad  */
   1785  1.1  riastrad static inline bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg)
   1786  1.1  riastrad {
   1787  1.1  riastrad 	struct evergreen_cs_track *track = p->track;
   1788  1.1  riastrad 	u32 m, i;
   1789  1.1  riastrad 
   1790  1.1  riastrad 	i = (reg >> 7);
   1791  1.1  riastrad 	if (unlikely(i >= REG_SAFE_BM_SIZE)) {
   1792  1.1  riastrad 		return false;
   1793  1.1  riastrad 	}
   1794  1.1  riastrad 	m = 1 << ((reg >> 2) & 31);
   1795  1.1  riastrad 	if (!(track->reg_safe_bm[i] & m))
   1796  1.1  riastrad 		return true;
   1797  1.1  riastrad 
   1798  1.1  riastrad 	return false;
   1799  1.1  riastrad }
   1800  1.1  riastrad 
   1801  1.1  riastrad static int evergreen_packet3_check(struct radeon_cs_parser *p,
   1802  1.1  riastrad 				   struct radeon_cs_packet *pkt)
   1803  1.1  riastrad {
   1804  1.1  riastrad 	struct radeon_bo_list *reloc;
   1805  1.1  riastrad 	struct evergreen_cs_track *track;
   1806  1.1  riastrad 	uint32_t *ib;
   1807  1.1  riastrad 	unsigned idx;
   1808  1.1  riastrad 	unsigned i;
   1809  1.1  riastrad 	unsigned start_reg, end_reg, reg;
   1810  1.1  riastrad 	int r;
   1811  1.1  riastrad 	u32 idx_value;
   1812  1.1  riastrad 
   1813  1.1  riastrad 	track = (struct evergreen_cs_track *)p->track;
   1814  1.1  riastrad 	ib = p->ib.ptr;
   1815  1.1  riastrad 	idx = pkt->idx + 1;
   1816  1.1  riastrad 	idx_value = radeon_get_ib_value(p, idx);
   1817  1.1  riastrad 
   1818  1.1  riastrad 	switch (pkt->opcode) {
   1819  1.1  riastrad 	case PACKET3_SET_PREDICATION:
   1820  1.1  riastrad 	{
   1821  1.1  riastrad 		int pred_op;
   1822  1.1  riastrad 		int tmp;
   1823  1.1  riastrad 		uint64_t offset;
   1824  1.1  riastrad 
   1825  1.1  riastrad 		if (pkt->count != 1) {
   1826  1.1  riastrad 			DRM_ERROR("bad SET PREDICATION\n");
   1827  1.1  riastrad 			return -EINVAL;
   1828  1.1  riastrad 		}
   1829  1.1  riastrad 
   1830  1.1  riastrad 		tmp = radeon_get_ib_value(p, idx + 1);
   1831  1.1  riastrad 		pred_op = (tmp >> 16) & 0x7;
   1832  1.1  riastrad 
   1833  1.1  riastrad 		/* for the clear predicate operation */
   1834  1.1  riastrad 		if (pred_op == 0)
   1835  1.1  riastrad 			return 0;
   1836  1.1  riastrad 
   1837  1.1  riastrad 		if (pred_op > 2) {
   1838  1.1  riastrad 			DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op);
   1839  1.1  riastrad 			return -EINVAL;
   1840  1.1  riastrad 		}
   1841  1.1  riastrad 
   1842  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1843  1.1  riastrad 		if (r) {
   1844  1.1  riastrad 			DRM_ERROR("bad SET PREDICATION\n");
   1845  1.1  riastrad 			return -EINVAL;
   1846  1.1  riastrad 		}
   1847  1.1  riastrad 
   1848  1.1  riastrad 		offset = reloc->gpu_offset +
   1849  1.5  riastrad 			 (idx_value & 0xfffffff0) +
   1850  1.5  riastrad 			 ((u64)(tmp & 0xff) << 32);
   1851  1.1  riastrad 
   1852  1.1  riastrad 		ib[idx + 0] = offset;
   1853  1.1  riastrad 		ib[idx + 1] = (tmp & 0xffffff00) | (upper_32_bits(offset) & 0xff);
   1854  1.1  riastrad 	}
   1855  1.1  riastrad 	break;
   1856  1.1  riastrad 	case PACKET3_CONTEXT_CONTROL:
   1857  1.1  riastrad 		if (pkt->count != 1) {
   1858  1.1  riastrad 			DRM_ERROR("bad CONTEXT_CONTROL\n");
   1859  1.1  riastrad 			return -EINVAL;
   1860  1.1  riastrad 		}
   1861  1.1  riastrad 		break;
   1862  1.1  riastrad 	case PACKET3_INDEX_TYPE:
   1863  1.1  riastrad 	case PACKET3_NUM_INSTANCES:
   1864  1.1  riastrad 	case PACKET3_CLEAR_STATE:
   1865  1.1  riastrad 		if (pkt->count) {
   1866  1.1  riastrad 			DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
   1867  1.1  riastrad 			return -EINVAL;
   1868  1.1  riastrad 		}
   1869  1.1  riastrad 		break;
   1870  1.1  riastrad 	case CAYMAN_PACKET3_DEALLOC_STATE:
   1871  1.1  riastrad 		if (p->rdev->family < CHIP_CAYMAN) {
   1872  1.1  riastrad 			DRM_ERROR("bad PACKET3_DEALLOC_STATE\n");
   1873  1.1  riastrad 			return -EINVAL;
   1874  1.1  riastrad 		}
   1875  1.1  riastrad 		if (pkt->count) {
   1876  1.1  riastrad 			DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
   1877  1.1  riastrad 			return -EINVAL;
   1878  1.1  riastrad 		}
   1879  1.1  riastrad 		break;
   1880  1.1  riastrad 	case PACKET3_INDEX_BASE:
   1881  1.1  riastrad 	{
   1882  1.1  riastrad 		uint64_t offset;
   1883  1.1  riastrad 
   1884  1.1  riastrad 		if (pkt->count != 1) {
   1885  1.1  riastrad 			DRM_ERROR("bad INDEX_BASE\n");
   1886  1.1  riastrad 			return -EINVAL;
   1887  1.1  riastrad 		}
   1888  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1889  1.1  riastrad 		if (r) {
   1890  1.1  riastrad 			DRM_ERROR("bad INDEX_BASE\n");
   1891  1.1  riastrad 			return -EINVAL;
   1892  1.1  riastrad 		}
   1893  1.1  riastrad 
   1894  1.1  riastrad 		offset = reloc->gpu_offset +
   1895  1.5  riastrad 			 idx_value +
   1896  1.5  riastrad 			 ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
   1897  1.1  riastrad 
   1898  1.1  riastrad 		ib[idx+0] = offset;
   1899  1.1  riastrad 		ib[idx+1] = upper_32_bits(offset) & 0xff;
   1900  1.1  riastrad 
   1901  1.1  riastrad 		r = evergreen_cs_track_check(p);
   1902  1.1  riastrad 		if (r) {
   1903  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   1904  1.1  riastrad 			return r;
   1905  1.1  riastrad 		}
   1906  1.1  riastrad 		break;
   1907  1.1  riastrad 	}
   1908  1.1  riastrad 	case PACKET3_INDEX_BUFFER_SIZE:
   1909  1.1  riastrad 	{
   1910  1.1  riastrad 		if (pkt->count != 0) {
   1911  1.1  riastrad 			DRM_ERROR("bad INDEX_BUFFER_SIZE\n");
   1912  1.1  riastrad 			return -EINVAL;
   1913  1.1  riastrad 		}
   1914  1.1  riastrad 		break;
   1915  1.1  riastrad 	}
   1916  1.1  riastrad 	case PACKET3_DRAW_INDEX:
   1917  1.1  riastrad 	{
   1918  1.1  riastrad 		uint64_t offset;
   1919  1.1  riastrad 		if (pkt->count != 3) {
   1920  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX\n");
   1921  1.1  riastrad 			return -EINVAL;
   1922  1.1  riastrad 		}
   1923  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1924  1.1  riastrad 		if (r) {
   1925  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX\n");
   1926  1.1  riastrad 			return -EINVAL;
   1927  1.1  riastrad 		}
   1928  1.1  riastrad 
   1929  1.1  riastrad 		offset = reloc->gpu_offset +
   1930  1.5  riastrad 			 idx_value +
   1931  1.5  riastrad 			 ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
   1932  1.1  riastrad 
   1933  1.1  riastrad 		ib[idx+0] = offset;
   1934  1.1  riastrad 		ib[idx+1] = upper_32_bits(offset) & 0xff;
   1935  1.1  riastrad 
   1936  1.1  riastrad 		r = evergreen_cs_track_check(p);
   1937  1.1  riastrad 		if (r) {
   1938  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   1939  1.1  riastrad 			return r;
   1940  1.1  riastrad 		}
   1941  1.1  riastrad 		break;
   1942  1.1  riastrad 	}
   1943  1.1  riastrad 	case PACKET3_DRAW_INDEX_2:
   1944  1.1  riastrad 	{
   1945  1.1  riastrad 		uint64_t offset;
   1946  1.1  riastrad 
   1947  1.1  riastrad 		if (pkt->count != 4) {
   1948  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_2\n");
   1949  1.1  riastrad 			return -EINVAL;
   1950  1.1  riastrad 		}
   1951  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   1952  1.1  riastrad 		if (r) {
   1953  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_2\n");
   1954  1.1  riastrad 			return -EINVAL;
   1955  1.1  riastrad 		}
   1956  1.1  riastrad 
   1957  1.1  riastrad 		offset = reloc->gpu_offset +
   1958  1.5  riastrad 			 radeon_get_ib_value(p, idx+1) +
   1959  1.5  riastrad 			 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
   1960  1.1  riastrad 
   1961  1.1  riastrad 		ib[idx+1] = offset;
   1962  1.1  riastrad 		ib[idx+2] = upper_32_bits(offset) & 0xff;
   1963  1.1  riastrad 
   1964  1.1  riastrad 		r = evergreen_cs_track_check(p);
   1965  1.1  riastrad 		if (r) {
   1966  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   1967  1.1  riastrad 			return r;
   1968  1.1  riastrad 		}
   1969  1.1  riastrad 		break;
   1970  1.1  riastrad 	}
   1971  1.1  riastrad 	case PACKET3_DRAW_INDEX_AUTO:
   1972  1.1  riastrad 		if (pkt->count != 1) {
   1973  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_AUTO\n");
   1974  1.1  riastrad 			return -EINVAL;
   1975  1.1  riastrad 		}
   1976  1.1  riastrad 		r = evergreen_cs_track_check(p);
   1977  1.1  riastrad 		if (r) {
   1978  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
   1979  1.1  riastrad 			return r;
   1980  1.1  riastrad 		}
   1981  1.1  riastrad 		break;
   1982  1.1  riastrad 	case PACKET3_DRAW_INDEX_MULTI_AUTO:
   1983  1.1  riastrad 		if (pkt->count != 2) {
   1984  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_MULTI_AUTO\n");
   1985  1.1  riastrad 			return -EINVAL;
   1986  1.1  riastrad 		}
   1987  1.1  riastrad 		r = evergreen_cs_track_check(p);
   1988  1.1  riastrad 		if (r) {
   1989  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
   1990  1.1  riastrad 			return r;
   1991  1.1  riastrad 		}
   1992  1.1  riastrad 		break;
   1993  1.1  riastrad 	case PACKET3_DRAW_INDEX_IMMD:
   1994  1.1  riastrad 		if (pkt->count < 2) {
   1995  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_IMMD\n");
   1996  1.1  riastrad 			return -EINVAL;
   1997  1.1  riastrad 		}
   1998  1.1  riastrad 		r = evergreen_cs_track_check(p);
   1999  1.1  riastrad 		if (r) {
   2000  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   2001  1.1  riastrad 			return r;
   2002  1.1  riastrad 		}
   2003  1.1  riastrad 		break;
   2004  1.1  riastrad 	case PACKET3_DRAW_INDEX_OFFSET:
   2005  1.1  riastrad 		if (pkt->count != 2) {
   2006  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_OFFSET\n");
   2007  1.1  riastrad 			return -EINVAL;
   2008  1.1  riastrad 		}
   2009  1.1  riastrad 		r = evergreen_cs_track_check(p);
   2010  1.1  riastrad 		if (r) {
   2011  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   2012  1.1  riastrad 			return r;
   2013  1.1  riastrad 		}
   2014  1.1  riastrad 		break;
   2015  1.1  riastrad 	case PACKET3_DRAW_INDEX_OFFSET_2:
   2016  1.1  riastrad 		if (pkt->count != 3) {
   2017  1.1  riastrad 			DRM_ERROR("bad DRAW_INDEX_OFFSET_2\n");
   2018  1.1  riastrad 			return -EINVAL;
   2019  1.1  riastrad 		}
   2020  1.1  riastrad 		r = evergreen_cs_track_check(p);
   2021  1.1  riastrad 		if (r) {
   2022  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   2023  1.1  riastrad 			return r;
   2024  1.1  riastrad 		}
   2025  1.1  riastrad 		break;
   2026  1.1  riastrad 	case PACKET3_SET_BASE:
   2027  1.1  riastrad 	{
   2028  1.1  riastrad 		/*
   2029  1.1  riastrad 		DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the Header will correspond to the shader type of the Load, see Type-3 Packet.
   2030  1.1  riastrad 		   2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies which base address is specified in the last two DWs.
   2031  1.1  riastrad 		     0001: DX11 Draw_Index_Indirect Patch Table Base: Base address for Draw_Index_Indirect data.
   2032  1.1  riastrad 		   3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned Address. Bits [2:0] - Reserved
   2033  1.1  riastrad 		   4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits of Address [47:32]
   2034  1.1  riastrad 		*/
   2035  1.1  riastrad 		if (pkt->count != 2) {
   2036  1.1  riastrad 			DRM_ERROR("bad SET_BASE\n");
   2037  1.1  riastrad 			return -EINVAL;
   2038  1.1  riastrad 		}
   2039  1.1  riastrad 
   2040  1.1  riastrad 		/* currently only supporting setting indirect draw buffer base address */
   2041  1.1  riastrad 		if (idx_value != 1) {
   2042  1.1  riastrad 			DRM_ERROR("bad SET_BASE\n");
   2043  1.1  riastrad 			return -EINVAL;
   2044  1.1  riastrad 		}
   2045  1.1  riastrad 
   2046  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2047  1.1  riastrad 		if (r) {
   2048  1.1  riastrad 			DRM_ERROR("bad SET_BASE\n");
   2049  1.1  riastrad 			return -EINVAL;
   2050  1.1  riastrad 		}
   2051  1.1  riastrad 
   2052  1.1  riastrad 		track->indirect_draw_buffer_size = radeon_bo_size(reloc->robj);
   2053  1.1  riastrad 
   2054  1.1  riastrad 		ib[idx+1] = reloc->gpu_offset;
   2055  1.1  riastrad 		ib[idx+2] = upper_32_bits(reloc->gpu_offset) & 0xff;
   2056  1.1  riastrad 
   2057  1.1  riastrad 		break;
   2058  1.1  riastrad 	}
   2059  1.1  riastrad 	case PACKET3_DRAW_INDIRECT:
   2060  1.1  riastrad 	case PACKET3_DRAW_INDEX_INDIRECT:
   2061  1.1  riastrad 	{
   2062  1.1  riastrad 		u64 size = pkt->opcode == PACKET3_DRAW_INDIRECT ? 16 : 20;
   2063  1.1  riastrad 
   2064  1.1  riastrad 		/*
   2065  1.1  riastrad 		DW 1 HEADER
   2066  1.1  riastrad 		   2 DATA_OFFSET Bits [31:0] + byte aligned offset where the required data structure starts. Bits 1:0 are zero
   2067  1.1  riastrad 		   3 DRAW_INITIATOR Draw Initiator Register. Written to the VGT_DRAW_INITIATOR register for the assigned context
   2068  1.1  riastrad 		*/
   2069  1.1  riastrad 		if (pkt->count != 1) {
   2070  1.1  riastrad 			DRM_ERROR("bad DRAW_INDIRECT\n");
   2071  1.1  riastrad 			return -EINVAL;
   2072  1.1  riastrad 		}
   2073  1.1  riastrad 
   2074  1.1  riastrad 		if (idx_value + size > track->indirect_draw_buffer_size) {
   2075  1.1  riastrad 			dev_warn(p->dev, "DRAW_INDIRECT buffer too small %u + %"PRIx64" > %lu\n",
   2076  1.1  riastrad 				idx_value, size, track->indirect_draw_buffer_size);
   2077  1.1  riastrad 			return -EINVAL;
   2078  1.1  riastrad 		}
   2079  1.1  riastrad 
   2080  1.1  riastrad 		r = evergreen_cs_track_check(p);
   2081  1.1  riastrad 		if (r) {
   2082  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   2083  1.1  riastrad 			return r;
   2084  1.1  riastrad 		}
   2085  1.1  riastrad 		break;
   2086  1.1  riastrad 	}
   2087  1.1  riastrad 	case PACKET3_DISPATCH_DIRECT:
   2088  1.1  riastrad 		if (pkt->count != 3) {
   2089  1.1  riastrad 			DRM_ERROR("bad DISPATCH_DIRECT\n");
   2090  1.1  riastrad 			return -EINVAL;
   2091  1.1  riastrad 		}
   2092  1.1  riastrad 		r = evergreen_cs_track_check(p);
   2093  1.1  riastrad 		if (r) {
   2094  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
   2095  1.1  riastrad 			return r;
   2096  1.1  riastrad 		}
   2097  1.1  riastrad 		break;
   2098  1.1  riastrad 	case PACKET3_DISPATCH_INDIRECT:
   2099  1.1  riastrad 		if (pkt->count != 1) {
   2100  1.1  riastrad 			DRM_ERROR("bad DISPATCH_INDIRECT\n");
   2101  1.1  riastrad 			return -EINVAL;
   2102  1.1  riastrad 		}
   2103  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2104  1.1  riastrad 		if (r) {
   2105  1.1  riastrad 			DRM_ERROR("bad DISPATCH_INDIRECT\n");
   2106  1.1  riastrad 			return -EINVAL;
   2107  1.1  riastrad 		}
   2108  1.1  riastrad 		ib[idx+0] = idx_value + (u32)(reloc->gpu_offset & 0xffffffff);
   2109  1.1  riastrad 		r = evergreen_cs_track_check(p);
   2110  1.1  riastrad 		if (r) {
   2111  1.1  riastrad 			dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__);
   2112  1.1  riastrad 			return r;
   2113  1.1  riastrad 		}
   2114  1.1  riastrad 		break;
   2115  1.1  riastrad 	case PACKET3_WAIT_REG_MEM:
   2116  1.1  riastrad 		if (pkt->count != 5) {
   2117  1.1  riastrad 			DRM_ERROR("bad WAIT_REG_MEM\n");
   2118  1.1  riastrad 			return -EINVAL;
   2119  1.1  riastrad 		}
   2120  1.1  riastrad 		/* bit 4 is reg (0) or mem (1) */
   2121  1.1  riastrad 		if (idx_value & 0x10) {
   2122  1.1  riastrad 			uint64_t offset;
   2123  1.1  riastrad 
   2124  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2125  1.1  riastrad 			if (r) {
   2126  1.1  riastrad 				DRM_ERROR("bad WAIT_REG_MEM\n");
   2127  1.1  riastrad 				return -EINVAL;
   2128  1.1  riastrad 			}
   2129  1.1  riastrad 
   2130  1.1  riastrad 			offset = reloc->gpu_offset +
   2131  1.5  riastrad 				 (radeon_get_ib_value(p, idx+1) & 0xfffffffc) +
   2132  1.5  riastrad 				 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
   2133  1.1  riastrad 
   2134  1.1  riastrad 			ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc);
   2135  1.1  riastrad 			ib[idx+2] = upper_32_bits(offset) & 0xff;
   2136  1.1  riastrad 		} else if (idx_value & 0x100) {
   2137  1.1  riastrad 			DRM_ERROR("cannot use PFP on REG wait\n");
   2138  1.1  riastrad 			return -EINVAL;
   2139  1.1  riastrad 		}
   2140  1.1  riastrad 		break;
   2141  1.1  riastrad 	case PACKET3_CP_DMA:
   2142  1.1  riastrad 	{
   2143  1.1  riastrad 		u32 command, size, info;
   2144  1.1  riastrad 		u64 offset, tmp;
   2145  1.1  riastrad 		if (pkt->count != 4) {
   2146  1.1  riastrad 			DRM_ERROR("bad CP DMA\n");
   2147  1.1  riastrad 			return -EINVAL;
   2148  1.1  riastrad 		}
   2149  1.1  riastrad 		command = radeon_get_ib_value(p, idx+4);
   2150  1.1  riastrad 		size = command & 0x1fffff;
   2151  1.1  riastrad 		info = radeon_get_ib_value(p, idx+1);
   2152  1.1  riastrad 		if ((((info & 0x60000000) >> 29) != 0) || /* src = GDS or DATA */
   2153  1.1  riastrad 		    (((info & 0x00300000) >> 20) != 0) || /* dst = GDS */
   2154  1.1  riastrad 		    ((((info & 0x00300000) >> 20) == 0) &&
   2155  1.1  riastrad 		     (command & PACKET3_CP_DMA_CMD_DAS)) || /* dst = register */
   2156  1.1  riastrad 		    ((((info & 0x60000000) >> 29) == 0) &&
   2157  1.1  riastrad 		     (command & PACKET3_CP_DMA_CMD_SAS))) { /* src = register */
   2158  1.1  riastrad 			/* non mem to mem copies requires dw aligned count */
   2159  1.1  riastrad 			if (size % 4) {
   2160  1.1  riastrad 				DRM_ERROR("CP DMA command requires dw count alignment\n");
   2161  1.1  riastrad 				return -EINVAL;
   2162  1.1  riastrad 			}
   2163  1.1  riastrad 		}
   2164  1.1  riastrad 		if (command & PACKET3_CP_DMA_CMD_SAS) {
   2165  1.1  riastrad 			/* src address space is register */
   2166  1.1  riastrad 			/* GDS is ok */
   2167  1.1  riastrad 			if (((info & 0x60000000) >> 29) != 1) {
   2168  1.1  riastrad 				DRM_ERROR("CP DMA SAS not supported\n");
   2169  1.1  riastrad 				return -EINVAL;
   2170  1.1  riastrad 			}
   2171  1.1  riastrad 		} else {
   2172  1.1  riastrad 			if (command & PACKET3_CP_DMA_CMD_SAIC) {
   2173  1.1  riastrad 				DRM_ERROR("CP DMA SAIC only supported for registers\n");
   2174  1.1  riastrad 				return -EINVAL;
   2175  1.1  riastrad 			}
   2176  1.1  riastrad 			/* src address space is memory */
   2177  1.1  riastrad 			if (((info & 0x60000000) >> 29) == 0) {
   2178  1.1  riastrad 				r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2179  1.1  riastrad 				if (r) {
   2180  1.1  riastrad 					DRM_ERROR("bad CP DMA SRC\n");
   2181  1.1  riastrad 					return -EINVAL;
   2182  1.1  riastrad 				}
   2183  1.1  riastrad 
   2184  1.1  riastrad 				tmp = radeon_get_ib_value(p, idx) +
   2185  1.1  riastrad 					((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32);
   2186  1.1  riastrad 
   2187  1.1  riastrad 				offset = reloc->gpu_offset + tmp;
   2188  1.1  riastrad 
   2189  1.1  riastrad 				if ((tmp + size) > radeon_bo_size(reloc->robj)) {
   2190  1.1  riastrad 					dev_warn(p->dev, "CP DMA src buffer too small (%"PRIu64" %lu)\n",
   2191  1.1  riastrad 						 tmp + size, radeon_bo_size(reloc->robj));
   2192  1.1  riastrad 					return -EINVAL;
   2193  1.1  riastrad 				}
   2194  1.1  riastrad 
   2195  1.1  riastrad 				ib[idx] = offset;
   2196  1.1  riastrad 				ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
   2197  1.1  riastrad 			} else if (((info & 0x60000000) >> 29) != 2) {
   2198  1.1  riastrad 				DRM_ERROR("bad CP DMA SRC_SEL\n");
   2199  1.1  riastrad 				return -EINVAL;
   2200  1.1  riastrad 			}
   2201  1.1  riastrad 		}
   2202  1.1  riastrad 		if (command & PACKET3_CP_DMA_CMD_DAS) {
   2203  1.1  riastrad 			/* dst address space is register */
   2204  1.1  riastrad 			/* GDS is ok */
   2205  1.1  riastrad 			if (((info & 0x00300000) >> 20) != 1) {
   2206  1.1  riastrad 				DRM_ERROR("CP DMA DAS not supported\n");
   2207  1.1  riastrad 				return -EINVAL;
   2208  1.1  riastrad 			}
   2209  1.1  riastrad 		} else {
   2210  1.1  riastrad 			/* dst address space is memory */
   2211  1.1  riastrad 			if (command & PACKET3_CP_DMA_CMD_DAIC) {
   2212  1.1  riastrad 				DRM_ERROR("CP DMA DAIC only supported for registers\n");
   2213  1.1  riastrad 				return -EINVAL;
   2214  1.1  riastrad 			}
   2215  1.1  riastrad 			if (((info & 0x00300000) >> 20) == 0) {
   2216  1.1  riastrad 				r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2217  1.1  riastrad 				if (r) {
   2218  1.1  riastrad 					DRM_ERROR("bad CP DMA DST\n");
   2219  1.1  riastrad 					return -EINVAL;
   2220  1.1  riastrad 				}
   2221  1.1  riastrad 
   2222  1.1  riastrad 				tmp = radeon_get_ib_value(p, idx+2) +
   2223  1.1  riastrad 					((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32);
   2224  1.1  riastrad 
   2225  1.1  riastrad 				offset = reloc->gpu_offset + tmp;
   2226  1.1  riastrad 
   2227  1.1  riastrad 				if ((tmp + size) > radeon_bo_size(reloc->robj)) {
   2228  1.1  riastrad 					dev_warn(p->dev, "CP DMA dst buffer too small (%"PRIu64" %lu)\n",
   2229  1.1  riastrad 						 tmp + size, radeon_bo_size(reloc->robj));
   2230  1.1  riastrad 					return -EINVAL;
   2231  1.1  riastrad 				}
   2232  1.1  riastrad 
   2233  1.1  riastrad 				ib[idx+2] = offset;
   2234  1.1  riastrad 				ib[idx+3] = upper_32_bits(offset) & 0xff;
   2235  1.1  riastrad 			} else {
   2236  1.1  riastrad 				DRM_ERROR("bad CP DMA DST_SEL\n");
   2237  1.1  riastrad 				return -EINVAL;
   2238  1.1  riastrad 			}
   2239  1.1  riastrad 		}
   2240  1.1  riastrad 		break;
   2241  1.1  riastrad 	}
   2242  1.5  riastrad 	case PACKET3_PFP_SYNC_ME:
   2243  1.5  riastrad 		if (pkt->count) {
   2244  1.5  riastrad 			DRM_ERROR("bad PFP_SYNC_ME\n");
   2245  1.5  riastrad 			return -EINVAL;
   2246  1.5  riastrad 		}
   2247  1.5  riastrad 		break;
   2248  1.1  riastrad 	case PACKET3_SURFACE_SYNC:
   2249  1.1  riastrad 		if (pkt->count != 3) {
   2250  1.1  riastrad 			DRM_ERROR("bad SURFACE_SYNC\n");
   2251  1.1  riastrad 			return -EINVAL;
   2252  1.1  riastrad 		}
   2253  1.1  riastrad 		/* 0xffffffff/0x0 is flush all cache flag */
   2254  1.1  riastrad 		if (radeon_get_ib_value(p, idx + 1) != 0xffffffff ||
   2255  1.1  riastrad 		    radeon_get_ib_value(p, idx + 2) != 0) {
   2256  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2257  1.1  riastrad 			if (r) {
   2258  1.1  riastrad 				DRM_ERROR("bad SURFACE_SYNC\n");
   2259  1.1  riastrad 				return -EINVAL;
   2260  1.1  riastrad 			}
   2261  1.1  riastrad 			ib[idx+2] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   2262  1.1  riastrad 		}
   2263  1.1  riastrad 		break;
   2264  1.1  riastrad 	case PACKET3_EVENT_WRITE:
   2265  1.1  riastrad 		if (pkt->count != 2 && pkt->count != 0) {
   2266  1.1  riastrad 			DRM_ERROR("bad EVENT_WRITE\n");
   2267  1.1  riastrad 			return -EINVAL;
   2268  1.1  riastrad 		}
   2269  1.1  riastrad 		if (pkt->count) {
   2270  1.1  riastrad 			uint64_t offset;
   2271  1.1  riastrad 
   2272  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2273  1.1  riastrad 			if (r) {
   2274  1.1  riastrad 				DRM_ERROR("bad EVENT_WRITE\n");
   2275  1.1  riastrad 				return -EINVAL;
   2276  1.1  riastrad 			}
   2277  1.1  riastrad 			offset = reloc->gpu_offset +
   2278  1.5  riastrad 				 (radeon_get_ib_value(p, idx+1) & 0xfffffff8) +
   2279  1.5  riastrad 				 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
   2280  1.1  riastrad 
   2281  1.1  riastrad 			ib[idx+1] = offset & 0xfffffff8;
   2282  1.1  riastrad 			ib[idx+2] = upper_32_bits(offset) & 0xff;
   2283  1.1  riastrad 		}
   2284  1.1  riastrad 		break;
   2285  1.1  riastrad 	case PACKET3_EVENT_WRITE_EOP:
   2286  1.1  riastrad 	{
   2287  1.1  riastrad 		uint64_t offset;
   2288  1.1  riastrad 
   2289  1.1  riastrad 		if (pkt->count != 4) {
   2290  1.1  riastrad 			DRM_ERROR("bad EVENT_WRITE_EOP\n");
   2291  1.1  riastrad 			return -EINVAL;
   2292  1.1  riastrad 		}
   2293  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2294  1.1  riastrad 		if (r) {
   2295  1.1  riastrad 			DRM_ERROR("bad EVENT_WRITE_EOP\n");
   2296  1.1  riastrad 			return -EINVAL;
   2297  1.1  riastrad 		}
   2298  1.1  riastrad 
   2299  1.1  riastrad 		offset = reloc->gpu_offset +
   2300  1.5  riastrad 			 (radeon_get_ib_value(p, idx+1) & 0xfffffffc) +
   2301  1.5  riastrad 			 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
   2302  1.1  riastrad 
   2303  1.1  riastrad 		ib[idx+1] = offset & 0xfffffffc;
   2304  1.1  riastrad 		ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
   2305  1.1  riastrad 		break;
   2306  1.1  riastrad 	}
   2307  1.1  riastrad 	case PACKET3_EVENT_WRITE_EOS:
   2308  1.1  riastrad 	{
   2309  1.1  riastrad 		uint64_t offset;
   2310  1.1  riastrad 
   2311  1.1  riastrad 		if (pkt->count != 3) {
   2312  1.1  riastrad 			DRM_ERROR("bad EVENT_WRITE_EOS\n");
   2313  1.1  riastrad 			return -EINVAL;
   2314  1.1  riastrad 		}
   2315  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2316  1.1  riastrad 		if (r) {
   2317  1.1  riastrad 			DRM_ERROR("bad EVENT_WRITE_EOS\n");
   2318  1.1  riastrad 			return -EINVAL;
   2319  1.1  riastrad 		}
   2320  1.1  riastrad 
   2321  1.1  riastrad 		offset = reloc->gpu_offset +
   2322  1.5  riastrad 			 (radeon_get_ib_value(p, idx+1) & 0xfffffffc) +
   2323  1.5  riastrad 			 ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
   2324  1.1  riastrad 
   2325  1.1  riastrad 		ib[idx+1] = offset & 0xfffffffc;
   2326  1.1  riastrad 		ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff);
   2327  1.1  riastrad 		break;
   2328  1.1  riastrad 	}
   2329  1.1  riastrad 	case PACKET3_SET_CONFIG_REG:
   2330  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
   2331  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2332  1.1  riastrad 		if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
   2333  1.1  riastrad 		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
   2334  1.1  riastrad 		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
   2335  1.1  riastrad 			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
   2336  1.1  riastrad 			return -EINVAL;
   2337  1.1  riastrad 		}
   2338  1.1  riastrad 		for (reg = start_reg, idx++; reg <= end_reg; reg += 4, idx++) {
   2339  1.1  riastrad 			if (evergreen_is_safe_reg(p, reg))
   2340  1.1  riastrad 				continue;
   2341  1.1  riastrad 			r = evergreen_cs_handle_reg(p, reg, idx);
   2342  1.1  riastrad 			if (r)
   2343  1.1  riastrad 				return r;
   2344  1.1  riastrad 		}
   2345  1.1  riastrad 		break;
   2346  1.1  riastrad 	case PACKET3_SET_CONTEXT_REG:
   2347  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_START;
   2348  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2349  1.1  riastrad 		if ((start_reg < PACKET3_SET_CONTEXT_REG_START) ||
   2350  1.1  riastrad 		    (start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
   2351  1.1  riastrad 		    (end_reg >= PACKET3_SET_CONTEXT_REG_END)) {
   2352  1.1  riastrad 			DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n");
   2353  1.1  riastrad 			return -EINVAL;
   2354  1.1  riastrad 		}
   2355  1.1  riastrad 		for (reg = start_reg, idx++; reg <= end_reg; reg += 4, idx++) {
   2356  1.1  riastrad 			if (evergreen_is_safe_reg(p, reg))
   2357  1.1  riastrad 				continue;
   2358  1.1  riastrad 			r = evergreen_cs_handle_reg(p, reg, idx);
   2359  1.1  riastrad 			if (r)
   2360  1.1  riastrad 				return r;
   2361  1.1  riastrad 		}
   2362  1.1  riastrad 		break;
   2363  1.1  riastrad 	case PACKET3_SET_RESOURCE:
   2364  1.1  riastrad 		if (pkt->count % 8) {
   2365  1.1  riastrad 			DRM_ERROR("bad SET_RESOURCE\n");
   2366  1.1  riastrad 			return -EINVAL;
   2367  1.1  riastrad 		}
   2368  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_START;
   2369  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2370  1.1  riastrad 		if ((start_reg < PACKET3_SET_RESOURCE_START) ||
   2371  1.1  riastrad 		    (start_reg >= PACKET3_SET_RESOURCE_END) ||
   2372  1.1  riastrad 		    (end_reg >= PACKET3_SET_RESOURCE_END)) {
   2373  1.1  riastrad 			DRM_ERROR("bad SET_RESOURCE\n");
   2374  1.1  riastrad 			return -EINVAL;
   2375  1.1  riastrad 		}
   2376  1.1  riastrad 		for (i = 0; i < (pkt->count / 8); i++) {
   2377  1.1  riastrad 			struct radeon_bo *texture, *mipmap;
   2378  1.1  riastrad 			u32 toffset, moffset;
   2379  1.1  riastrad 			u32 size, offset, mip_address, tex_dim;
   2380  1.1  riastrad 
   2381  1.1  riastrad 			switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) {
   2382  1.1  riastrad 			case SQ_TEX_VTX_VALID_TEXTURE:
   2383  1.1  riastrad 				/* tex base */
   2384  1.1  riastrad 				r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2385  1.1  riastrad 				if (r) {
   2386  1.1  riastrad 					DRM_ERROR("bad SET_RESOURCE (tex)\n");
   2387  1.1  riastrad 					return -EINVAL;
   2388  1.1  riastrad 				}
   2389  1.1  riastrad 				if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
   2390  1.1  riastrad 					ib[idx+1+(i*8)+1] |=
   2391  1.1  riastrad 						TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->tiling_flags));
   2392  1.1  riastrad 					if (reloc->tiling_flags & RADEON_TILING_MACRO) {
   2393  1.1  riastrad 						unsigned bankw, bankh, mtaspect, tile_split;
   2394  1.1  riastrad 
   2395  1.1  riastrad 						evergreen_tiling_fields(reloc->tiling_flags,
   2396  1.1  riastrad 									&bankw, &bankh, &mtaspect,
   2397  1.1  riastrad 									&tile_split);
   2398  1.1  riastrad 						ib[idx+1+(i*8)+6] |= TEX_TILE_SPLIT(tile_split);
   2399  1.1  riastrad 						ib[idx+1+(i*8)+7] |=
   2400  1.1  riastrad 							TEX_BANK_WIDTH(bankw) |
   2401  1.1  riastrad 							TEX_BANK_HEIGHT(bankh) |
   2402  1.1  riastrad 							MACRO_TILE_ASPECT(mtaspect) |
   2403  1.1  riastrad 							TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks));
   2404  1.1  riastrad 					}
   2405  1.1  riastrad 				}
   2406  1.1  riastrad 				texture = reloc->robj;
   2407  1.1  riastrad 				toffset = (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   2408  1.1  riastrad 
   2409  1.1  riastrad 				/* tex mip base */
   2410  1.1  riastrad 				tex_dim = ib[idx+1+(i*8)+0] & 0x7;
   2411  1.1  riastrad 				mip_address = ib[idx+1+(i*8)+3];
   2412  1.1  riastrad 
   2413  1.1  riastrad 				if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) &&
   2414  1.1  riastrad 				    !mip_address &&
   2415  1.1  riastrad 				    !radeon_cs_packet_next_is_pkt3_nop(p)) {
   2416  1.1  riastrad 					/* MIP_ADDRESS should point to FMASK for an MSAA texture.
   2417  1.1  riastrad 					 * It should be 0 if FMASK is disabled. */
   2418  1.1  riastrad 					moffset = 0;
   2419  1.1  riastrad 					mipmap = NULL;
   2420  1.1  riastrad 				} else {
   2421  1.1  riastrad 					r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2422  1.1  riastrad 					if (r) {
   2423  1.1  riastrad 						DRM_ERROR("bad SET_RESOURCE (tex)\n");
   2424  1.1  riastrad 						return -EINVAL;
   2425  1.1  riastrad 					}
   2426  1.1  riastrad 					moffset = (u32)((reloc->gpu_offset >> 8) & 0xffffffff);
   2427  1.1  riastrad 					mipmap = reloc->robj;
   2428  1.1  riastrad 				}
   2429  1.1  riastrad 
   2430  1.1  riastrad 				r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8));
   2431  1.1  riastrad 				if (r)
   2432  1.1  riastrad 					return r;
   2433  1.1  riastrad 				ib[idx+1+(i*8)+2] += toffset;
   2434  1.1  riastrad 				ib[idx+1+(i*8)+3] += moffset;
   2435  1.1  riastrad 				break;
   2436  1.1  riastrad 			case SQ_TEX_VTX_VALID_BUFFER:
   2437  1.1  riastrad 			{
   2438  1.1  riastrad 				uint64_t offset64;
   2439  1.1  riastrad 				/* vtx base */
   2440  1.1  riastrad 				r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2441  1.1  riastrad 				if (r) {
   2442  1.1  riastrad 					DRM_ERROR("bad SET_RESOURCE (vtx)\n");
   2443  1.1  riastrad 					return -EINVAL;
   2444  1.1  riastrad 				}
   2445  1.1  riastrad 				offset = radeon_get_ib_value(p, idx+1+(i*8)+0);
   2446  1.1  riastrad 				size = radeon_get_ib_value(p, idx+1+(i*8)+1);
   2447  1.1  riastrad 				if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) {
   2448  1.1  riastrad 					/* force size to size of the buffer */
   2449  1.5  riastrad 					dev_warn_ratelimited(p->dev, "vbo resource seems too big for the bo\n");
   2450  1.1  riastrad 					ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->robj) - offset;
   2451  1.1  riastrad 				}
   2452  1.1  riastrad 
   2453  1.1  riastrad 				offset64 = reloc->gpu_offset + offset;
   2454  1.1  riastrad 				ib[idx+1+(i*8)+0] = offset64;
   2455  1.1  riastrad 				ib[idx+1+(i*8)+2] = (ib[idx+1+(i*8)+2] & 0xffffff00) |
   2456  1.1  riastrad 						    (upper_32_bits(offset64) & 0xff);
   2457  1.1  riastrad 				break;
   2458  1.1  riastrad 			}
   2459  1.1  riastrad 			case SQ_TEX_VTX_INVALID_TEXTURE:
   2460  1.1  riastrad 			case SQ_TEX_VTX_INVALID_BUFFER:
   2461  1.1  riastrad 			default:
   2462  1.1  riastrad 				DRM_ERROR("bad SET_RESOURCE\n");
   2463  1.1  riastrad 				return -EINVAL;
   2464  1.1  riastrad 			}
   2465  1.1  riastrad 		}
   2466  1.1  riastrad 		break;
   2467  1.1  riastrad 	case PACKET3_SET_ALU_CONST:
   2468  1.1  riastrad 		/* XXX fix me ALU const buffers only */
   2469  1.1  riastrad 		break;
   2470  1.1  riastrad 	case PACKET3_SET_BOOL_CONST:
   2471  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_START;
   2472  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2473  1.1  riastrad 		if ((start_reg < PACKET3_SET_BOOL_CONST_START) ||
   2474  1.1  riastrad 		    (start_reg >= PACKET3_SET_BOOL_CONST_END) ||
   2475  1.1  riastrad 		    (end_reg >= PACKET3_SET_BOOL_CONST_END)) {
   2476  1.1  riastrad 			DRM_ERROR("bad SET_BOOL_CONST\n");
   2477  1.1  riastrad 			return -EINVAL;
   2478  1.1  riastrad 		}
   2479  1.1  riastrad 		break;
   2480  1.1  riastrad 	case PACKET3_SET_LOOP_CONST:
   2481  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_START;
   2482  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2483  1.1  riastrad 		if ((start_reg < PACKET3_SET_LOOP_CONST_START) ||
   2484  1.1  riastrad 		    (start_reg >= PACKET3_SET_LOOP_CONST_END) ||
   2485  1.1  riastrad 		    (end_reg >= PACKET3_SET_LOOP_CONST_END)) {
   2486  1.1  riastrad 			DRM_ERROR("bad SET_LOOP_CONST\n");
   2487  1.1  riastrad 			return -EINVAL;
   2488  1.1  riastrad 		}
   2489  1.1  riastrad 		break;
   2490  1.1  riastrad 	case PACKET3_SET_CTL_CONST:
   2491  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_START;
   2492  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2493  1.1  riastrad 		if ((start_reg < PACKET3_SET_CTL_CONST_START) ||
   2494  1.1  riastrad 		    (start_reg >= PACKET3_SET_CTL_CONST_END) ||
   2495  1.1  riastrad 		    (end_reg >= PACKET3_SET_CTL_CONST_END)) {
   2496  1.1  riastrad 			DRM_ERROR("bad SET_CTL_CONST\n");
   2497  1.1  riastrad 			return -EINVAL;
   2498  1.1  riastrad 		}
   2499  1.1  riastrad 		break;
   2500  1.1  riastrad 	case PACKET3_SET_SAMPLER:
   2501  1.1  riastrad 		if (pkt->count % 3) {
   2502  1.1  riastrad 			DRM_ERROR("bad SET_SAMPLER\n");
   2503  1.1  riastrad 			return -EINVAL;
   2504  1.1  riastrad 		}
   2505  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_START;
   2506  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   2507  1.1  riastrad 		if ((start_reg < PACKET3_SET_SAMPLER_START) ||
   2508  1.1  riastrad 		    (start_reg >= PACKET3_SET_SAMPLER_END) ||
   2509  1.1  riastrad 		    (end_reg >= PACKET3_SET_SAMPLER_END)) {
   2510  1.1  riastrad 			DRM_ERROR("bad SET_SAMPLER\n");
   2511  1.1  riastrad 			return -EINVAL;
   2512  1.1  riastrad 		}
   2513  1.1  riastrad 		break;
   2514  1.1  riastrad 	case PACKET3_STRMOUT_BUFFER_UPDATE:
   2515  1.1  riastrad 		if (pkt->count != 4) {
   2516  1.1  riastrad 			DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n");
   2517  1.1  riastrad 			return -EINVAL;
   2518  1.1  riastrad 		}
   2519  1.1  riastrad 		/* Updating memory at DST_ADDRESS. */
   2520  1.1  riastrad 		if (idx_value & 0x1) {
   2521  1.1  riastrad 			u64 offset;
   2522  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2523  1.1  riastrad 			if (r) {
   2524  1.1  riastrad 				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n");
   2525  1.1  riastrad 				return -EINVAL;
   2526  1.1  riastrad 			}
   2527  1.1  riastrad 			offset = radeon_get_ib_value(p, idx+1);
   2528  1.1  riastrad 			offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
   2529  1.1  riastrad 			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
   2530  1.1  riastrad 				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%"PRIx64", 0x%lx\n",
   2531  1.1  riastrad 					  offset + 4, radeon_bo_size(reloc->robj));
   2532  1.1  riastrad 				return -EINVAL;
   2533  1.1  riastrad 			}
   2534  1.1  riastrad 			offset += reloc->gpu_offset;
   2535  1.1  riastrad 			ib[idx+1] = offset;
   2536  1.1  riastrad 			ib[idx+2] = upper_32_bits(offset) & 0xff;
   2537  1.1  riastrad 		}
   2538  1.1  riastrad 		/* Reading data from SRC_ADDRESS. */
   2539  1.1  riastrad 		if (((idx_value >> 1) & 0x3) == 2) {
   2540  1.1  riastrad 			u64 offset;
   2541  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2542  1.1  riastrad 			if (r) {
   2543  1.1  riastrad 				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n");
   2544  1.1  riastrad 				return -EINVAL;
   2545  1.1  riastrad 			}
   2546  1.1  riastrad 			offset = radeon_get_ib_value(p, idx+3);
   2547  1.1  riastrad 			offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
   2548  1.1  riastrad 			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
   2549  1.1  riastrad 				DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%"PRIx64", 0x%lx\n",
   2550  1.1  riastrad 					  offset + 4, radeon_bo_size(reloc->robj));
   2551  1.1  riastrad 				return -EINVAL;
   2552  1.1  riastrad 			}
   2553  1.1  riastrad 			offset += reloc->gpu_offset;
   2554  1.1  riastrad 			ib[idx+3] = offset;
   2555  1.1  riastrad 			ib[idx+4] = upper_32_bits(offset) & 0xff;
   2556  1.1  riastrad 		}
   2557  1.1  riastrad 		break;
   2558  1.1  riastrad 	case PACKET3_MEM_WRITE:
   2559  1.1  riastrad 	{
   2560  1.1  riastrad 		u64 offset;
   2561  1.1  riastrad 
   2562  1.1  riastrad 		if (pkt->count != 3) {
   2563  1.1  riastrad 			DRM_ERROR("bad MEM_WRITE (invalid count)\n");
   2564  1.1  riastrad 			return -EINVAL;
   2565  1.1  riastrad 		}
   2566  1.1  riastrad 		r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2567  1.1  riastrad 		if (r) {
   2568  1.1  riastrad 			DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
   2569  1.1  riastrad 			return -EINVAL;
   2570  1.1  riastrad 		}
   2571  1.1  riastrad 		offset = radeon_get_ib_value(p, idx+0);
   2572  1.1  riastrad 		offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
   2573  1.1  riastrad 		if (offset & 0x7) {
   2574  1.1  riastrad 			DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
   2575  1.1  riastrad 			return -EINVAL;
   2576  1.1  riastrad 		}
   2577  1.1  riastrad 		if ((offset + 8) > radeon_bo_size(reloc->robj)) {
   2578  1.1  riastrad 			DRM_ERROR("bad MEM_WRITE bo too small: 0x%"PRIx64", 0x%lx\n",
   2579  1.1  riastrad 				  offset + 8, radeon_bo_size(reloc->robj));
   2580  1.1  riastrad 			return -EINVAL;
   2581  1.1  riastrad 		}
   2582  1.1  riastrad 		offset += reloc->gpu_offset;
   2583  1.1  riastrad 		ib[idx+0] = offset;
   2584  1.1  riastrad 		ib[idx+1] = upper_32_bits(offset) & 0xff;
   2585  1.1  riastrad 		break;
   2586  1.1  riastrad 	}
   2587  1.1  riastrad 	case PACKET3_COPY_DW:
   2588  1.1  riastrad 		if (pkt->count != 4) {
   2589  1.1  riastrad 			DRM_ERROR("bad COPY_DW (invalid count)\n");
   2590  1.1  riastrad 			return -EINVAL;
   2591  1.1  riastrad 		}
   2592  1.1  riastrad 		if (idx_value & 0x1) {
   2593  1.1  riastrad 			u64 offset;
   2594  1.1  riastrad 			/* SRC is memory. */
   2595  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2596  1.1  riastrad 			if (r) {
   2597  1.1  riastrad 				DRM_ERROR("bad COPY_DW (missing src reloc)\n");
   2598  1.1  riastrad 				return -EINVAL;
   2599  1.1  riastrad 			}
   2600  1.1  riastrad 			offset = radeon_get_ib_value(p, idx+1);
   2601  1.1  riastrad 			offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
   2602  1.1  riastrad 			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
   2603  1.1  riastrad 				DRM_ERROR("bad COPY_DW src bo too small: 0x%"PRIx64", 0x%lx\n",
   2604  1.1  riastrad 					  offset + 4, radeon_bo_size(reloc->robj));
   2605  1.1  riastrad 				return -EINVAL;
   2606  1.1  riastrad 			}
   2607  1.1  riastrad 			offset += reloc->gpu_offset;
   2608  1.1  riastrad 			ib[idx+1] = offset;
   2609  1.1  riastrad 			ib[idx+2] = upper_32_bits(offset) & 0xff;
   2610  1.1  riastrad 		} else {
   2611  1.1  riastrad 			/* SRC is a reg. */
   2612  1.1  riastrad 			reg = radeon_get_ib_value(p, idx+1) << 2;
   2613  1.1  riastrad 			if (!evergreen_is_safe_reg(p, reg)) {
   2614  1.1  riastrad 				dev_warn(p->dev, "forbidden register 0x%08x at %d\n",
   2615  1.1  riastrad 					 reg, idx + 1);
   2616  1.1  riastrad 				return -EINVAL;
   2617  1.1  riastrad 			}
   2618  1.1  riastrad 		}
   2619  1.1  riastrad 		if (idx_value & 0x2) {
   2620  1.1  riastrad 			u64 offset;
   2621  1.1  riastrad 			/* DST is memory. */
   2622  1.1  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2623  1.1  riastrad 			if (r) {
   2624  1.1  riastrad 				DRM_ERROR("bad COPY_DW (missing dst reloc)\n");
   2625  1.1  riastrad 				return -EINVAL;
   2626  1.1  riastrad 			}
   2627  1.1  riastrad 			offset = radeon_get_ib_value(p, idx+3);
   2628  1.1  riastrad 			offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
   2629  1.1  riastrad 			if ((offset + 4) > radeon_bo_size(reloc->robj)) {
   2630  1.1  riastrad 				DRM_ERROR("bad COPY_DW dst bo too small: 0x%"PRIx64", 0x%lx\n",
   2631  1.1  riastrad 					  offset + 4, radeon_bo_size(reloc->robj));
   2632  1.1  riastrad 				return -EINVAL;
   2633  1.1  riastrad 			}
   2634  1.1  riastrad 			offset += reloc->gpu_offset;
   2635  1.1  riastrad 			ib[idx+3] = offset;
   2636  1.1  riastrad 			ib[idx+4] = upper_32_bits(offset) & 0xff;
   2637  1.1  riastrad 		} else {
   2638  1.1  riastrad 			/* DST is a reg. */
   2639  1.1  riastrad 			reg = radeon_get_ib_value(p, idx+3) << 2;
   2640  1.1  riastrad 			if (!evergreen_is_safe_reg(p, reg)) {
   2641  1.1  riastrad 				dev_warn(p->dev, "forbidden register 0x%08x at %d\n",
   2642  1.1  riastrad 					 reg, idx + 3);
   2643  1.1  riastrad 				return -EINVAL;
   2644  1.1  riastrad 			}
   2645  1.1  riastrad 		}
   2646  1.1  riastrad 		break;
   2647  1.5  riastrad 	case PACKET3_SET_APPEND_CNT:
   2648  1.5  riastrad 	{
   2649  1.5  riastrad 		uint32_t areg;
   2650  1.5  riastrad 		uint32_t allowed_reg_base;
   2651  1.5  riastrad 		uint32_t source_sel;
   2652  1.5  riastrad 		if (pkt->count != 2) {
   2653  1.5  riastrad 			DRM_ERROR("bad SET_APPEND_CNT (invalid count)\n");
   2654  1.5  riastrad 			return -EINVAL;
   2655  1.5  riastrad 		}
   2656  1.5  riastrad 
   2657  1.5  riastrad 		allowed_reg_base = GDS_APPEND_COUNT_0;
   2658  1.5  riastrad 		allowed_reg_base -= PACKET3_SET_CONTEXT_REG_START;
   2659  1.5  riastrad 		allowed_reg_base >>= 2;
   2660  1.5  riastrad 
   2661  1.5  riastrad 		areg = idx_value >> 16;
   2662  1.5  riastrad 		if (areg < allowed_reg_base || areg > (allowed_reg_base + 11)) {
   2663  1.5  riastrad 			dev_warn(p->dev, "forbidden register for append cnt 0x%08x at %d\n",
   2664  1.5  riastrad 				 areg, idx);
   2665  1.5  riastrad 			return -EINVAL;
   2666  1.5  riastrad 		}
   2667  1.5  riastrad 
   2668  1.5  riastrad 		source_sel = G_PACKET3_SET_APPEND_CNT_SRC_SELECT(idx_value);
   2669  1.5  riastrad 		if (source_sel == PACKET3_SAC_SRC_SEL_MEM) {
   2670  1.5  riastrad 			uint64_t offset;
   2671  1.5  riastrad 			uint32_t swap;
   2672  1.5  riastrad 			r = radeon_cs_packet_next_reloc(p, &reloc, 0);
   2673  1.5  riastrad 			if (r) {
   2674  1.5  riastrad 				DRM_ERROR("bad SET_APPEND_CNT (missing reloc)\n");
   2675  1.5  riastrad 				return -EINVAL;
   2676  1.5  riastrad 			}
   2677  1.5  riastrad 			offset = radeon_get_ib_value(p, idx + 1);
   2678  1.5  riastrad 			swap = offset & 0x3;
   2679  1.5  riastrad 			offset &= ~0x3;
   2680  1.5  riastrad 
   2681  1.5  riastrad 			offset += ((u64)(radeon_get_ib_value(p, idx + 2) & 0xff)) << 32;
   2682  1.5  riastrad 
   2683  1.5  riastrad 			offset += reloc->gpu_offset;
   2684  1.5  riastrad 			ib[idx+1] = (offset & 0xfffffffc) | swap;
   2685  1.5  riastrad 			ib[idx+2] = upper_32_bits(offset) & 0xff;
   2686  1.5  riastrad 		} else {
   2687  1.5  riastrad 			DRM_ERROR("bad SET_APPEND_CNT (unsupported operation)\n");
   2688  1.5  riastrad 			return -EINVAL;
   2689  1.5  riastrad 		}
   2690  1.5  riastrad 		break;
   2691  1.5  riastrad 	}
   2692  1.1  riastrad 	case PACKET3_NOP:
   2693  1.1  riastrad 		break;
   2694  1.1  riastrad 	default:
   2695  1.1  riastrad 		DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
   2696  1.1  riastrad 		return -EINVAL;
   2697  1.1  riastrad 	}
   2698  1.1  riastrad 	return 0;
   2699  1.1  riastrad }
   2700  1.1  riastrad 
   2701  1.1  riastrad int evergreen_cs_parse(struct radeon_cs_parser *p)
   2702  1.1  riastrad {
   2703  1.1  riastrad 	struct radeon_cs_packet pkt;
   2704  1.1  riastrad 	struct evergreen_cs_track *track;
   2705  1.1  riastrad 	u32 tmp;
   2706  1.1  riastrad 	int r;
   2707  1.1  riastrad 
   2708  1.1  riastrad 	if (p->track == NULL) {
   2709  1.1  riastrad 		/* initialize tracker, we are in kms */
   2710  1.1  riastrad 		track = kzalloc(sizeof(*track), GFP_KERNEL);
   2711  1.1  riastrad 		if (track == NULL)
   2712  1.1  riastrad 			return -ENOMEM;
   2713  1.1  riastrad 		evergreen_cs_track_init(track);
   2714  1.1  riastrad 		if (p->rdev->family >= CHIP_CAYMAN) {
   2715  1.1  riastrad 			tmp = p->rdev->config.cayman.tile_config;
   2716  1.1  riastrad 			track->reg_safe_bm = cayman_reg_safe_bm;
   2717  1.1  riastrad 		} else {
   2718  1.1  riastrad 			tmp = p->rdev->config.evergreen.tile_config;
   2719  1.1  riastrad 			track->reg_safe_bm = evergreen_reg_safe_bm;
   2720  1.1  riastrad 		}
   2721  1.1  riastrad 		BUILD_BUG_ON(ARRAY_SIZE(cayman_reg_safe_bm) != REG_SAFE_BM_SIZE);
   2722  1.1  riastrad 		BUILD_BUG_ON(ARRAY_SIZE(evergreen_reg_safe_bm) != REG_SAFE_BM_SIZE);
   2723  1.1  riastrad 		switch (tmp & 0xf) {
   2724  1.1  riastrad 		case 0:
   2725  1.1  riastrad 			track->npipes = 1;
   2726  1.1  riastrad 			break;
   2727  1.1  riastrad 		case 1:
   2728  1.1  riastrad 		default:
   2729  1.1  riastrad 			track->npipes = 2;
   2730  1.1  riastrad 			break;
   2731  1.1  riastrad 		case 2:
   2732  1.1  riastrad 			track->npipes = 4;
   2733  1.1  riastrad 			break;
   2734  1.1  riastrad 		case 3:
   2735  1.1  riastrad 			track->npipes = 8;
   2736  1.1  riastrad 			break;
   2737  1.1  riastrad 		}
   2738  1.1  riastrad 
   2739  1.1  riastrad 		switch ((tmp & 0xf0) >> 4) {
   2740  1.1  riastrad 		case 0:
   2741  1.1  riastrad 			track->nbanks = 4;
   2742  1.1  riastrad 			break;
   2743  1.1  riastrad 		case 1:
   2744  1.1  riastrad 		default:
   2745  1.1  riastrad 			track->nbanks = 8;
   2746  1.1  riastrad 			break;
   2747  1.1  riastrad 		case 2:
   2748  1.1  riastrad 			track->nbanks = 16;
   2749  1.1  riastrad 			break;
   2750  1.1  riastrad 		}
   2751  1.1  riastrad 
   2752  1.1  riastrad 		switch ((tmp & 0xf00) >> 8) {
   2753  1.1  riastrad 		case 0:
   2754  1.1  riastrad 			track->group_size = 256;
   2755  1.1  riastrad 			break;
   2756  1.1  riastrad 		case 1:
   2757  1.1  riastrad 		default:
   2758  1.1  riastrad 			track->group_size = 512;
   2759  1.1  riastrad 			break;
   2760  1.1  riastrad 		}
   2761  1.1  riastrad 
   2762  1.1  riastrad 		switch ((tmp & 0xf000) >> 12) {
   2763  1.1  riastrad 		case 0:
   2764  1.1  riastrad 			track->row_size = 1;
   2765  1.1  riastrad 			break;
   2766  1.1  riastrad 		case 1:
   2767  1.1  riastrad 		default:
   2768  1.1  riastrad 			track->row_size = 2;
   2769  1.1  riastrad 			break;
   2770  1.1  riastrad 		case 2:
   2771  1.1  riastrad 			track->row_size = 4;
   2772  1.1  riastrad 			break;
   2773  1.1  riastrad 		}
   2774  1.1  riastrad 
   2775  1.1  riastrad 		p->track = track;
   2776  1.1  riastrad 	}
   2777  1.1  riastrad 	do {
   2778  1.1  riastrad 		r = radeon_cs_packet_parse(p, &pkt, p->idx);
   2779  1.1  riastrad 		if (r) {
   2780  1.1  riastrad 			kfree(p->track);
   2781  1.1  riastrad 			p->track = NULL;
   2782  1.1  riastrad 			return r;
   2783  1.1  riastrad 		}
   2784  1.1  riastrad 		p->idx += pkt.count + 2;
   2785  1.1  riastrad 		switch (pkt.type) {
   2786  1.1  riastrad 		case RADEON_PACKET_TYPE0:
   2787  1.1  riastrad 			r = evergreen_cs_parse_packet0(p, &pkt);
   2788  1.1  riastrad 			break;
   2789  1.1  riastrad 		case RADEON_PACKET_TYPE2:
   2790  1.1  riastrad 			break;
   2791  1.1  riastrad 		case RADEON_PACKET_TYPE3:
   2792  1.1  riastrad 			r = evergreen_packet3_check(p, &pkt);
   2793  1.1  riastrad 			break;
   2794  1.1  riastrad 		default:
   2795  1.1  riastrad 			DRM_ERROR("Unknown packet type %d !\n", pkt.type);
   2796  1.1  riastrad 			kfree(p->track);
   2797  1.1  riastrad 			p->track = NULL;
   2798  1.1  riastrad 			return -EINVAL;
   2799  1.1  riastrad 		}
   2800  1.1  riastrad 		if (r) {
   2801  1.1  riastrad 			kfree(p->track);
   2802  1.1  riastrad 			p->track = NULL;
   2803  1.1  riastrad 			return r;
   2804  1.1  riastrad 		}
   2805  1.1  riastrad 	} while (p->idx < p->chunk_ib->length_dw);
   2806  1.1  riastrad #if 0
   2807  1.1  riastrad 	for (r = 0; r < p->ib.length_dw; r++) {
   2808  1.5  riastrad 		pr_info("%05d  0x%08X\n", r, p->ib.ptr[r]);
   2809  1.1  riastrad 		mdelay(1);
   2810  1.1  riastrad 	}
   2811  1.1  riastrad #endif
   2812  1.1  riastrad 	kfree(p->track);
   2813  1.1  riastrad 	p->track = NULL;
   2814  1.1  riastrad 	return 0;
   2815  1.1  riastrad }
   2816  1.1  riastrad 
   2817  1.1  riastrad /**
   2818  1.1  riastrad  * evergreen_dma_cs_parse() - parse the DMA IB
   2819  1.1  riastrad  * @p:		parser structure holding parsing context.
   2820  1.1  riastrad  *
   2821  1.1  riastrad  * Parses the DMA IB from the CS ioctl and updates
   2822  1.1  riastrad  * the GPU addresses based on the reloc information and
   2823  1.1  riastrad  * checks for errors. (Evergreen-Cayman)
   2824  1.1  riastrad  * Returns 0 for success and an error on failure.
   2825  1.1  riastrad  **/
   2826  1.1  riastrad int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
   2827  1.1  riastrad {
   2828  1.1  riastrad 	struct radeon_cs_chunk *ib_chunk = p->chunk_ib;
   2829  1.1  riastrad 	struct radeon_bo_list *src_reloc, *dst_reloc, *dst2_reloc;
   2830  1.1  riastrad 	u32 header, cmd, count, sub_cmd;
   2831  1.1  riastrad 	uint32_t *ib = p->ib.ptr;
   2832  1.1  riastrad 	u32 idx;
   2833  1.1  riastrad 	u64 src_offset, dst_offset, dst2_offset;
   2834  1.1  riastrad 	int r;
   2835  1.1  riastrad 
   2836  1.1  riastrad 	do {
   2837  1.1  riastrad 		if (p->idx >= ib_chunk->length_dw) {
   2838  1.1  riastrad 			DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
   2839  1.1  riastrad 				  p->idx, ib_chunk->length_dw);
   2840  1.1  riastrad 			return -EINVAL;
   2841  1.1  riastrad 		}
   2842  1.1  riastrad 		idx = p->idx;
   2843  1.1  riastrad 		header = radeon_get_ib_value(p, idx);
   2844  1.1  riastrad 		cmd = GET_DMA_CMD(header);
   2845  1.1  riastrad 		count = GET_DMA_COUNT(header);
   2846  1.1  riastrad 		sub_cmd = GET_DMA_SUB_CMD(header);
   2847  1.1  riastrad 
   2848  1.1  riastrad 		switch (cmd) {
   2849  1.1  riastrad 		case DMA_PACKET_WRITE:
   2850  1.1  riastrad 			r = r600_dma_cs_next_reloc(p, &dst_reloc);
   2851  1.1  riastrad 			if (r) {
   2852  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_WRITE\n");
   2853  1.1  riastrad 				return -EINVAL;
   2854  1.1  riastrad 			}
   2855  1.1  riastrad 			switch (sub_cmd) {
   2856  1.1  riastrad 			/* tiled */
   2857  1.1  riastrad 			case 8:
   2858  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   2859  1.1  riastrad 				dst_offset <<= 8;
   2860  1.1  riastrad 
   2861  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   2862  1.1  riastrad 				p->idx += count + 7;
   2863  1.1  riastrad 				break;
   2864  1.1  riastrad 			/* linear */
   2865  1.1  riastrad 			case 0:
   2866  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   2867  1.1  riastrad 				dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
   2868  1.1  riastrad 
   2869  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   2870  1.1  riastrad 				ib[idx+2] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   2871  1.1  riastrad 				p->idx += count + 3;
   2872  1.1  riastrad 				break;
   2873  1.1  riastrad 			default:
   2874  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_WRITE [%6d] 0x%08x sub cmd is not 0 or 8\n", idx, header);
   2875  1.1  riastrad 				return -EINVAL;
   2876  1.1  riastrad 			}
   2877  1.1  riastrad 			if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   2878  1.1  riastrad 				dev_warn(p->dev, "DMA write buffer too small (%"PRIu64" %lu)\n",
   2879  1.1  riastrad 					 dst_offset, radeon_bo_size(dst_reloc->robj));
   2880  1.1  riastrad 				return -EINVAL;
   2881  1.1  riastrad 			}
   2882  1.1  riastrad 			break;
   2883  1.1  riastrad 		case DMA_PACKET_COPY:
   2884  1.1  riastrad 			r = r600_dma_cs_next_reloc(p, &src_reloc);
   2885  1.1  riastrad 			if (r) {
   2886  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_COPY\n");
   2887  1.1  riastrad 				return -EINVAL;
   2888  1.1  riastrad 			}
   2889  1.1  riastrad 			r = r600_dma_cs_next_reloc(p, &dst_reloc);
   2890  1.1  riastrad 			if (r) {
   2891  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_COPY\n");
   2892  1.1  riastrad 				return -EINVAL;
   2893  1.1  riastrad 			}
   2894  1.1  riastrad 			switch (sub_cmd) {
   2895  1.1  riastrad 			/* Copy L2L, DW aligned */
   2896  1.1  riastrad 			case 0x00:
   2897  1.1  riastrad 				/* L2L, dw */
   2898  1.1  riastrad 				src_offset = radeon_get_ib_value(p, idx+2);
   2899  1.1  riastrad 				src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
   2900  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   2901  1.1  riastrad 				dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
   2902  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   2903  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, dw src buffer too small (%"PRIu64" %lu)\n",
   2904  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   2905  1.1  riastrad 					return -EINVAL;
   2906  1.1  riastrad 				}
   2907  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   2908  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, dw dst buffer too small (%"PRIu64" %lu)\n",
   2909  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   2910  1.1  riastrad 					return -EINVAL;
   2911  1.1  riastrad 				}
   2912  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   2913  1.1  riastrad 				ib[idx+2] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   2914  1.1  riastrad 				ib[idx+3] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   2915  1.1  riastrad 				ib[idx+4] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   2916  1.1  riastrad 				p->idx += 5;
   2917  1.1  riastrad 				break;
   2918  1.1  riastrad 			/* Copy L2T/T2L */
   2919  1.1  riastrad 			case 0x08:
   2920  1.1  riastrad 				/* detile bit */
   2921  1.1  riastrad 				if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) {
   2922  1.1  riastrad 					/* tiled src, linear dst */
   2923  1.1  riastrad 					src_offset = radeon_get_ib_value(p, idx+1);
   2924  1.1  riastrad 					src_offset <<= 8;
   2925  1.1  riastrad 					ib[idx+1] += (u32)(src_reloc->gpu_offset >> 8);
   2926  1.1  riastrad 
   2927  1.1  riastrad 					dst_offset = radeon_get_ib_value(p, idx + 7);
   2928  1.1  riastrad 					dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
   2929  1.1  riastrad 					ib[idx+7] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   2930  1.1  riastrad 					ib[idx+8] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   2931  1.1  riastrad 				} else {
   2932  1.1  riastrad 					/* linear src, tiled dst */
   2933  1.1  riastrad 					src_offset = radeon_get_ib_value(p, idx+7);
   2934  1.1  riastrad 					src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
   2935  1.1  riastrad 					ib[idx+7] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   2936  1.1  riastrad 					ib[idx+8] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   2937  1.1  riastrad 
   2938  1.1  riastrad 					dst_offset = radeon_get_ib_value(p, idx+1);
   2939  1.1  riastrad 					dst_offset <<= 8;
   2940  1.1  riastrad 					ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   2941  1.1  riastrad 				}
   2942  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   2943  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, src buffer too small (%"PRIu64" %lu)\n",
   2944  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   2945  1.1  riastrad 					return -EINVAL;
   2946  1.1  riastrad 				}
   2947  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   2948  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, dst buffer too small (%"PRIu64" %lu)\n",
   2949  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   2950  1.1  riastrad 					return -EINVAL;
   2951  1.1  riastrad 				}
   2952  1.1  riastrad 				p->idx += 9;
   2953  1.1  riastrad 				break;
   2954  1.1  riastrad 			/* Copy L2L, byte aligned */
   2955  1.1  riastrad 			case 0x40:
   2956  1.1  riastrad 				/* L2L, byte */
   2957  1.1  riastrad 				src_offset = radeon_get_ib_value(p, idx+2);
   2958  1.1  riastrad 				src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
   2959  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   2960  1.1  riastrad 				dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
   2961  1.1  riastrad 				if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) {
   2962  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, byte src buffer too small (%"PRIu64" %lu)\n",
   2963  1.1  riastrad 							src_offset + count, radeon_bo_size(src_reloc->robj));
   2964  1.1  riastrad 					return -EINVAL;
   2965  1.1  riastrad 				}
   2966  1.1  riastrad 				if ((dst_offset + count) > radeon_bo_size(dst_reloc->robj)) {
   2967  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, byte dst buffer too small (%"PRIu64" %lu)\n",
   2968  1.1  riastrad 							dst_offset + count, radeon_bo_size(dst_reloc->robj));
   2969  1.1  riastrad 					return -EINVAL;
   2970  1.1  riastrad 				}
   2971  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xffffffff);
   2972  1.1  riastrad 				ib[idx+2] += (u32)(src_reloc->gpu_offset & 0xffffffff);
   2973  1.1  riastrad 				ib[idx+3] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   2974  1.1  riastrad 				ib[idx+4] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   2975  1.1  riastrad 				p->idx += 5;
   2976  1.1  riastrad 				break;
   2977  1.1  riastrad 			/* Copy L2L, partial */
   2978  1.1  riastrad 			case 0x41:
   2979  1.1  riastrad 				/* L2L, partial */
   2980  1.1  riastrad 				if (p->family < CHIP_CAYMAN) {
   2981  1.1  riastrad 					DRM_ERROR("L2L Partial is cayman only !\n");
   2982  1.1  riastrad 					return -EINVAL;
   2983  1.1  riastrad 				}
   2984  1.1  riastrad 				ib[idx+1] += (u32)(src_reloc->gpu_offset & 0xffffffff);
   2985  1.1  riastrad 				ib[idx+2] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   2986  1.1  riastrad 				ib[idx+4] += (u32)(dst_reloc->gpu_offset & 0xffffffff);
   2987  1.1  riastrad 				ib[idx+5] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   2988  1.1  riastrad 
   2989  1.1  riastrad 				p->idx += 9;
   2990  1.1  riastrad 				break;
   2991  1.1  riastrad 			/* Copy L2L, DW aligned, broadcast */
   2992  1.1  riastrad 			case 0x44:
   2993  1.1  riastrad 				/* L2L, dw, broadcast */
   2994  1.1  riastrad 				r = r600_dma_cs_next_reloc(p, &dst2_reloc);
   2995  1.1  riastrad 				if (r) {
   2996  1.1  riastrad 					DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n");
   2997  1.1  riastrad 					return -EINVAL;
   2998  1.1  riastrad 				}
   2999  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   3000  1.1  riastrad 				dst_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
   3001  1.1  riastrad 				dst2_offset = radeon_get_ib_value(p, idx+2);
   3002  1.1  riastrad 				dst2_offset |= ((u64)(radeon_get_ib_value(p, idx+5) & 0xff)) << 32;
   3003  1.1  riastrad 				src_offset = radeon_get_ib_value(p, idx+3);
   3004  1.1  riastrad 				src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;
   3005  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   3006  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%"PRIu64" %lu)\n",
   3007  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   3008  1.1  riastrad 					return -EINVAL;
   3009  1.1  riastrad 				}
   3010  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   3011  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, dw, broadcast dst buffer too small (%"PRIu64" %lu)\n",
   3012  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   3013  1.1  riastrad 					return -EINVAL;
   3014  1.1  riastrad 				}
   3015  1.1  riastrad 				if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
   3016  1.1  riastrad 					dev_warn(p->dev, "DMA L2L, dw, broadcast dst2 buffer too small (%"PRIu64" %lu)\n",
   3017  1.1  riastrad 							dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
   3018  1.1  riastrad 					return -EINVAL;
   3019  1.1  riastrad 				}
   3020  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   3021  1.1  riastrad 				ib[idx+2] += (u32)(dst2_reloc->gpu_offset & 0xfffffffc);
   3022  1.1  riastrad 				ib[idx+3] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   3023  1.1  riastrad 				ib[idx+4] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   3024  1.1  riastrad 				ib[idx+5] += upper_32_bits(dst2_reloc->gpu_offset) & 0xff;
   3025  1.1  riastrad 				ib[idx+6] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   3026  1.1  riastrad 				p->idx += 7;
   3027  1.1  riastrad 				break;
   3028  1.1  riastrad 			/* Copy L2T Frame to Field */
   3029  1.1  riastrad 			case 0x48:
   3030  1.1  riastrad 				if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) {
   3031  1.1  riastrad 					DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n");
   3032  1.1  riastrad 					return -EINVAL;
   3033  1.1  riastrad 				}
   3034  1.1  riastrad 				r = r600_dma_cs_next_reloc(p, &dst2_reloc);
   3035  1.1  riastrad 				if (r) {
   3036  1.1  riastrad 					DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n");
   3037  1.1  riastrad 					return -EINVAL;
   3038  1.1  riastrad 				}
   3039  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   3040  1.1  riastrad 				dst_offset <<= 8;
   3041  1.1  riastrad 				dst2_offset = radeon_get_ib_value(p, idx+2);
   3042  1.1  riastrad 				dst2_offset <<= 8;
   3043  1.1  riastrad 				src_offset = radeon_get_ib_value(p, idx+8);
   3044  1.1  riastrad 				src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
   3045  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   3046  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%"PRIu64" %lu)\n",
   3047  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   3048  1.1  riastrad 					return -EINVAL;
   3049  1.1  riastrad 				}
   3050  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   3051  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%"PRIu64" %lu)\n",
   3052  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   3053  1.1  riastrad 					return -EINVAL;
   3054  1.1  riastrad 				}
   3055  1.1  riastrad 				if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
   3056  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%"PRIu64" %lu)\n",
   3057  1.1  riastrad 							dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
   3058  1.1  riastrad 					return -EINVAL;
   3059  1.1  riastrad 				}
   3060  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   3061  1.1  riastrad 				ib[idx+2] += (u32)(dst2_reloc->gpu_offset >> 8);
   3062  1.1  riastrad 				ib[idx+8] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   3063  1.1  riastrad 				ib[idx+9] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   3064  1.1  riastrad 				p->idx += 10;
   3065  1.1  riastrad 				break;
   3066  1.1  riastrad 			/* Copy L2T/T2L, partial */
   3067  1.1  riastrad 			case 0x49:
   3068  1.1  riastrad 				/* L2T, T2L partial */
   3069  1.1  riastrad 				if (p->family < CHIP_CAYMAN) {
   3070  1.1  riastrad 					DRM_ERROR("L2T, T2L Partial is cayman only !\n");
   3071  1.1  riastrad 					return -EINVAL;
   3072  1.1  riastrad 				}
   3073  1.1  riastrad 				/* detile bit */
   3074  1.1  riastrad 				if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) {
   3075  1.1  riastrad 					/* tiled src, linear dst */
   3076  1.1  riastrad 					ib[idx+1] += (u32)(src_reloc->gpu_offset >> 8);
   3077  1.1  riastrad 
   3078  1.1  riastrad 					ib[idx+7] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   3079  1.1  riastrad 					ib[idx+8] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   3080  1.1  riastrad 				} else {
   3081  1.1  riastrad 					/* linear src, tiled dst */
   3082  1.1  riastrad 					ib[idx+7] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   3083  1.1  riastrad 					ib[idx+8] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   3084  1.1  riastrad 
   3085  1.1  riastrad 					ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   3086  1.1  riastrad 				}
   3087  1.1  riastrad 				p->idx += 12;
   3088  1.1  riastrad 				break;
   3089  1.1  riastrad 			/* Copy L2T broadcast */
   3090  1.1  riastrad 			case 0x4b:
   3091  1.1  riastrad 				/* L2T, broadcast */
   3092  1.1  riastrad 				if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) {
   3093  1.1  riastrad 					DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
   3094  1.1  riastrad 					return -EINVAL;
   3095  1.1  riastrad 				}
   3096  1.1  riastrad 				r = r600_dma_cs_next_reloc(p, &dst2_reloc);
   3097  1.1  riastrad 				if (r) {
   3098  1.1  riastrad 					DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
   3099  1.1  riastrad 					return -EINVAL;
   3100  1.1  riastrad 				}
   3101  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   3102  1.1  riastrad 				dst_offset <<= 8;
   3103  1.1  riastrad 				dst2_offset = radeon_get_ib_value(p, idx+2);
   3104  1.1  riastrad 				dst2_offset <<= 8;
   3105  1.1  riastrad 				src_offset = radeon_get_ib_value(p, idx+8);
   3106  1.1  riastrad 				src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
   3107  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   3108  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%"PRIu64" %lu)\n",
   3109  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   3110  1.1  riastrad 					return -EINVAL;
   3111  1.1  riastrad 				}
   3112  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   3113  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%"PRIu64" %lu)\n",
   3114  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   3115  1.1  riastrad 					return -EINVAL;
   3116  1.1  riastrad 				}
   3117  1.1  riastrad 				if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
   3118  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%"PRIu64" %lu)\n",
   3119  1.1  riastrad 							dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
   3120  1.1  riastrad 					return -EINVAL;
   3121  1.1  riastrad 				}
   3122  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   3123  1.1  riastrad 				ib[idx+2] += (u32)(dst2_reloc->gpu_offset >> 8);
   3124  1.1  riastrad 				ib[idx+8] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   3125  1.1  riastrad 				ib[idx+9] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   3126  1.1  riastrad 				p->idx += 10;
   3127  1.1  riastrad 				break;
   3128  1.1  riastrad 			/* Copy L2T/T2L (tile units) */
   3129  1.1  riastrad 			case 0x4c:
   3130  1.1  riastrad 				/* L2T, T2L */
   3131  1.1  riastrad 				/* detile bit */
   3132  1.1  riastrad 				if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) {
   3133  1.1  riastrad 					/* tiled src, linear dst */
   3134  1.1  riastrad 					src_offset = radeon_get_ib_value(p, idx+1);
   3135  1.1  riastrad 					src_offset <<= 8;
   3136  1.1  riastrad 					ib[idx+1] += (u32)(src_reloc->gpu_offset >> 8);
   3137  1.1  riastrad 
   3138  1.1  riastrad 					dst_offset = radeon_get_ib_value(p, idx+7);
   3139  1.1  riastrad 					dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
   3140  1.1  riastrad 					ib[idx+7] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   3141  1.1  riastrad 					ib[idx+8] += upper_32_bits(dst_reloc->gpu_offset) & 0xff;
   3142  1.1  riastrad 				} else {
   3143  1.1  riastrad 					/* linear src, tiled dst */
   3144  1.1  riastrad 					src_offset = radeon_get_ib_value(p, idx+7);
   3145  1.1  riastrad 					src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
   3146  1.1  riastrad 					ib[idx+7] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   3147  1.1  riastrad 					ib[idx+8] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   3148  1.1  riastrad 
   3149  1.1  riastrad 					dst_offset = radeon_get_ib_value(p, idx+1);
   3150  1.1  riastrad 					dst_offset <<= 8;
   3151  1.1  riastrad 					ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   3152  1.1  riastrad 				}
   3153  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   3154  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, T2L src buffer too small (%"PRIu64" %lu)\n",
   3155  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   3156  1.1  riastrad 					return -EINVAL;
   3157  1.1  riastrad 				}
   3158  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   3159  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, T2L dst buffer too small (%"PRIu64" %lu)\n",
   3160  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   3161  1.1  riastrad 					return -EINVAL;
   3162  1.1  riastrad 				}
   3163  1.1  riastrad 				p->idx += 9;
   3164  1.1  riastrad 				break;
   3165  1.1  riastrad 			/* Copy T2T, partial (tile units) */
   3166  1.1  riastrad 			case 0x4d:
   3167  1.1  riastrad 				/* T2T partial */
   3168  1.1  riastrad 				if (p->family < CHIP_CAYMAN) {
   3169  1.1  riastrad 					DRM_ERROR("L2T, T2L Partial is cayman only !\n");
   3170  1.1  riastrad 					return -EINVAL;
   3171  1.1  riastrad 				}
   3172  1.1  riastrad 				ib[idx+1] += (u32)(src_reloc->gpu_offset >> 8);
   3173  1.1  riastrad 				ib[idx+4] += (u32)(dst_reloc->gpu_offset >> 8);
   3174  1.1  riastrad 				p->idx += 13;
   3175  1.1  riastrad 				break;
   3176  1.1  riastrad 			/* Copy L2T broadcast (tile units) */
   3177  1.1  riastrad 			case 0x4f:
   3178  1.1  riastrad 				/* L2T, broadcast */
   3179  1.1  riastrad 				if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) {
   3180  1.1  riastrad 					DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
   3181  1.1  riastrad 					return -EINVAL;
   3182  1.1  riastrad 				}
   3183  1.1  riastrad 				r = r600_dma_cs_next_reloc(p, &dst2_reloc);
   3184  1.1  riastrad 				if (r) {
   3185  1.1  riastrad 					DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
   3186  1.1  riastrad 					return -EINVAL;
   3187  1.1  riastrad 				}
   3188  1.1  riastrad 				dst_offset = radeon_get_ib_value(p, idx+1);
   3189  1.1  riastrad 				dst_offset <<= 8;
   3190  1.1  riastrad 				dst2_offset = radeon_get_ib_value(p, idx+2);
   3191  1.1  riastrad 				dst2_offset <<= 8;
   3192  1.1  riastrad 				src_offset = radeon_get_ib_value(p, idx+8);
   3193  1.1  riastrad 				src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
   3194  1.1  riastrad 				if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
   3195  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%"PRIu64" %lu)\n",
   3196  1.1  riastrad 							src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
   3197  1.1  riastrad 					return -EINVAL;
   3198  1.1  riastrad 				}
   3199  1.1  riastrad 				if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   3200  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%"PRIu64" %lu)\n",
   3201  1.1  riastrad 							dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj));
   3202  1.1  riastrad 					return -EINVAL;
   3203  1.1  riastrad 				}
   3204  1.1  riastrad 				if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) {
   3205  1.1  riastrad 					dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%"PRIu64" %lu)\n",
   3206  1.1  riastrad 							dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj));
   3207  1.1  riastrad 					return -EINVAL;
   3208  1.1  riastrad 				}
   3209  1.1  riastrad 				ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8);
   3210  1.1  riastrad 				ib[idx+2] += (u32)(dst2_reloc->gpu_offset >> 8);
   3211  1.1  riastrad 				ib[idx+8] += (u32)(src_reloc->gpu_offset & 0xfffffffc);
   3212  1.1  riastrad 				ib[idx+9] += upper_32_bits(src_reloc->gpu_offset) & 0xff;
   3213  1.1  riastrad 				p->idx += 10;
   3214  1.1  riastrad 				break;
   3215  1.1  riastrad 			default:
   3216  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_COPY [%6d] 0x%08x invalid sub cmd\n", idx, header);
   3217  1.1  riastrad 				return -EINVAL;
   3218  1.1  riastrad 			}
   3219  1.1  riastrad 			break;
   3220  1.1  riastrad 		case DMA_PACKET_CONSTANT_FILL:
   3221  1.1  riastrad 			r = r600_dma_cs_next_reloc(p, &dst_reloc);
   3222  1.1  riastrad 			if (r) {
   3223  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_CONSTANT_FILL\n");
   3224  1.1  riastrad 				return -EINVAL;
   3225  1.1  riastrad 			}
   3226  1.1  riastrad 			dst_offset = radeon_get_ib_value(p, idx+1);
   3227  1.1  riastrad 			dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16;
   3228  1.1  riastrad 			if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
   3229  1.1  riastrad 				dev_warn(p->dev, "DMA constant fill buffer too small (%"PRIu64" %lu)\n",
   3230  1.1  riastrad 					 dst_offset, radeon_bo_size(dst_reloc->robj));
   3231  1.1  riastrad 				return -EINVAL;
   3232  1.1  riastrad 			}
   3233  1.1  riastrad 			ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc);
   3234  1.1  riastrad 			ib[idx+3] += (upper_32_bits(dst_reloc->gpu_offset) << 16) & 0x00ff0000;
   3235  1.1  riastrad 			p->idx += 4;
   3236  1.1  riastrad 			break;
   3237  1.1  riastrad 		case DMA_PACKET_NOP:
   3238  1.1  riastrad 			p->idx += 1;
   3239  1.1  riastrad 			break;
   3240  1.1  riastrad 		default:
   3241  1.1  riastrad 			DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx);
   3242  1.1  riastrad 			return -EINVAL;
   3243  1.1  riastrad 		}
   3244  1.1  riastrad 	} while (p->idx < p->chunk_ib->length_dw);
   3245  1.1  riastrad #if 0
   3246  1.1  riastrad 	for (r = 0; r < p->ib->length_dw; r++) {
   3247  1.5  riastrad 		pr_info("%05d  0x%08X\n", r, p->ib.ptr[r]);
   3248  1.1  riastrad 		mdelay(1);
   3249  1.1  riastrad 	}
   3250  1.1  riastrad #endif
   3251  1.1  riastrad 	return 0;
   3252  1.1  riastrad }
   3253  1.1  riastrad 
   3254  1.1  riastrad /* vm parser */
   3255  1.1  riastrad static bool evergreen_vm_reg_valid(u32 reg)
   3256  1.1  riastrad {
   3257  1.1  riastrad 	/* context regs are fine */
   3258  1.1  riastrad 	if (reg >= 0x28000)
   3259  1.1  riastrad 		return true;
   3260  1.1  riastrad 
   3261  1.1  riastrad 	/* check config regs */
   3262  1.1  riastrad 	switch (reg) {
   3263  1.1  riastrad 	case WAIT_UNTIL:
   3264  1.1  riastrad 	case GRBM_GFX_INDEX:
   3265  1.1  riastrad 	case CP_STRMOUT_CNTL:
   3266  1.1  riastrad 	case CP_COHER_CNTL:
   3267  1.1  riastrad 	case CP_COHER_SIZE:
   3268  1.1  riastrad 	case VGT_VTX_VECT_EJECT_REG:
   3269  1.1  riastrad 	case VGT_CACHE_INVALIDATION:
   3270  1.1  riastrad 	case VGT_GS_VERTEX_REUSE:
   3271  1.1  riastrad 	case VGT_PRIMITIVE_TYPE:
   3272  1.1  riastrad 	case VGT_INDEX_TYPE:
   3273  1.1  riastrad 	case VGT_NUM_INDICES:
   3274  1.1  riastrad 	case VGT_NUM_INSTANCES:
   3275  1.1  riastrad 	case VGT_COMPUTE_DIM_X:
   3276  1.1  riastrad 	case VGT_COMPUTE_DIM_Y:
   3277  1.1  riastrad 	case VGT_COMPUTE_DIM_Z:
   3278  1.1  riastrad 	case VGT_COMPUTE_START_X:
   3279  1.1  riastrad 	case VGT_COMPUTE_START_Y:
   3280  1.1  riastrad 	case VGT_COMPUTE_START_Z:
   3281  1.1  riastrad 	case VGT_COMPUTE_INDEX:
   3282  1.1  riastrad 	case VGT_COMPUTE_THREAD_GROUP_SIZE:
   3283  1.1  riastrad 	case VGT_HS_OFFCHIP_PARAM:
   3284  1.1  riastrad 	case PA_CL_ENHANCE:
   3285  1.1  riastrad 	case PA_SU_LINE_STIPPLE_VALUE:
   3286  1.1  riastrad 	case PA_SC_LINE_STIPPLE_STATE:
   3287  1.1  riastrad 	case PA_SC_ENHANCE:
   3288  1.1  riastrad 	case SQ_DYN_GPR_CNTL_PS_FLUSH_REQ:
   3289  1.1  riastrad 	case SQ_DYN_GPR_SIMD_LOCK_EN:
   3290  1.1  riastrad 	case SQ_CONFIG:
   3291  1.1  riastrad 	case SQ_GPR_RESOURCE_MGMT_1:
   3292  1.1  riastrad 	case SQ_GLOBAL_GPR_RESOURCE_MGMT_1:
   3293  1.1  riastrad 	case SQ_GLOBAL_GPR_RESOURCE_MGMT_2:
   3294  1.1  riastrad 	case SQ_CONST_MEM_BASE:
   3295  1.1  riastrad 	case SQ_STATIC_THREAD_MGMT_1:
   3296  1.1  riastrad 	case SQ_STATIC_THREAD_MGMT_2:
   3297  1.1  riastrad 	case SQ_STATIC_THREAD_MGMT_3:
   3298  1.1  riastrad 	case SPI_CONFIG_CNTL:
   3299  1.1  riastrad 	case SPI_CONFIG_CNTL_1:
   3300  1.1  riastrad 	case TA_CNTL_AUX:
   3301  1.1  riastrad 	case DB_DEBUG:
   3302  1.1  riastrad 	case DB_DEBUG2:
   3303  1.1  riastrad 	case DB_DEBUG3:
   3304  1.1  riastrad 	case DB_DEBUG4:
   3305  1.1  riastrad 	case DB_WATERMARKS:
   3306  1.1  riastrad 	case TD_PS_BORDER_COLOR_INDEX:
   3307  1.1  riastrad 	case TD_PS_BORDER_COLOR_RED:
   3308  1.1  riastrad 	case TD_PS_BORDER_COLOR_GREEN:
   3309  1.1  riastrad 	case TD_PS_BORDER_COLOR_BLUE:
   3310  1.1  riastrad 	case TD_PS_BORDER_COLOR_ALPHA:
   3311  1.1  riastrad 	case TD_VS_BORDER_COLOR_INDEX:
   3312  1.1  riastrad 	case TD_VS_BORDER_COLOR_RED:
   3313  1.1  riastrad 	case TD_VS_BORDER_COLOR_GREEN:
   3314  1.1  riastrad 	case TD_VS_BORDER_COLOR_BLUE:
   3315  1.1  riastrad 	case TD_VS_BORDER_COLOR_ALPHA:
   3316  1.1  riastrad 	case TD_GS_BORDER_COLOR_INDEX:
   3317  1.1  riastrad 	case TD_GS_BORDER_COLOR_RED:
   3318  1.1  riastrad 	case TD_GS_BORDER_COLOR_GREEN:
   3319  1.1  riastrad 	case TD_GS_BORDER_COLOR_BLUE:
   3320  1.1  riastrad 	case TD_GS_BORDER_COLOR_ALPHA:
   3321  1.1  riastrad 	case TD_HS_BORDER_COLOR_INDEX:
   3322  1.1  riastrad 	case TD_HS_BORDER_COLOR_RED:
   3323  1.1  riastrad 	case TD_HS_BORDER_COLOR_GREEN:
   3324  1.1  riastrad 	case TD_HS_BORDER_COLOR_BLUE:
   3325  1.1  riastrad 	case TD_HS_BORDER_COLOR_ALPHA:
   3326  1.1  riastrad 	case TD_LS_BORDER_COLOR_INDEX:
   3327  1.1  riastrad 	case TD_LS_BORDER_COLOR_RED:
   3328  1.1  riastrad 	case TD_LS_BORDER_COLOR_GREEN:
   3329  1.1  riastrad 	case TD_LS_BORDER_COLOR_BLUE:
   3330  1.1  riastrad 	case TD_LS_BORDER_COLOR_ALPHA:
   3331  1.1  riastrad 	case TD_CS_BORDER_COLOR_INDEX:
   3332  1.1  riastrad 	case TD_CS_BORDER_COLOR_RED:
   3333  1.1  riastrad 	case TD_CS_BORDER_COLOR_GREEN:
   3334  1.1  riastrad 	case TD_CS_BORDER_COLOR_BLUE:
   3335  1.1  riastrad 	case TD_CS_BORDER_COLOR_ALPHA:
   3336  1.1  riastrad 	case SQ_ESGS_RING_SIZE:
   3337  1.1  riastrad 	case SQ_GSVS_RING_SIZE:
   3338  1.1  riastrad 	case SQ_ESTMP_RING_SIZE:
   3339  1.1  riastrad 	case SQ_GSTMP_RING_SIZE:
   3340  1.1  riastrad 	case SQ_HSTMP_RING_SIZE:
   3341  1.1  riastrad 	case SQ_LSTMP_RING_SIZE:
   3342  1.1  riastrad 	case SQ_PSTMP_RING_SIZE:
   3343  1.1  riastrad 	case SQ_VSTMP_RING_SIZE:
   3344  1.1  riastrad 	case SQ_ESGS_RING_ITEMSIZE:
   3345  1.1  riastrad 	case SQ_ESTMP_RING_ITEMSIZE:
   3346  1.1  riastrad 	case SQ_GSTMP_RING_ITEMSIZE:
   3347  1.1  riastrad 	case SQ_GSVS_RING_ITEMSIZE:
   3348  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE:
   3349  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE_1:
   3350  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE_2:
   3351  1.1  riastrad 	case SQ_GS_VERT_ITEMSIZE_3:
   3352  1.1  riastrad 	case SQ_GSVS_RING_OFFSET_1:
   3353  1.1  riastrad 	case SQ_GSVS_RING_OFFSET_2:
   3354  1.1  riastrad 	case SQ_GSVS_RING_OFFSET_3:
   3355  1.1  riastrad 	case SQ_HSTMP_RING_ITEMSIZE:
   3356  1.1  riastrad 	case SQ_LSTMP_RING_ITEMSIZE:
   3357  1.1  riastrad 	case SQ_PSTMP_RING_ITEMSIZE:
   3358  1.1  riastrad 	case SQ_VSTMP_RING_ITEMSIZE:
   3359  1.1  riastrad 	case VGT_TF_RING_SIZE:
   3360  1.1  riastrad 	case SQ_ESGS_RING_BASE:
   3361  1.1  riastrad 	case SQ_GSVS_RING_BASE:
   3362  1.1  riastrad 	case SQ_ESTMP_RING_BASE:
   3363  1.1  riastrad 	case SQ_GSTMP_RING_BASE:
   3364  1.1  riastrad 	case SQ_HSTMP_RING_BASE:
   3365  1.1  riastrad 	case SQ_LSTMP_RING_BASE:
   3366  1.1  riastrad 	case SQ_PSTMP_RING_BASE:
   3367  1.1  riastrad 	case SQ_VSTMP_RING_BASE:
   3368  1.1  riastrad 	case CAYMAN_VGT_OFFCHIP_LDS_BASE:
   3369  1.1  riastrad 	case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS:
   3370  1.1  riastrad 		return true;
   3371  1.1  riastrad 	default:
   3372  1.1  riastrad 		DRM_ERROR("Invalid register 0x%x in CS\n", reg);
   3373  1.1  riastrad 		return false;
   3374  1.1  riastrad 	}
   3375  1.1  riastrad }
   3376  1.1  riastrad 
   3377  1.1  riastrad static int evergreen_vm_packet3_check(struct radeon_device *rdev,
   3378  1.1  riastrad 				      u32 *ib, struct radeon_cs_packet *pkt)
   3379  1.1  riastrad {
   3380  1.1  riastrad 	u32 idx = pkt->idx + 1;
   3381  1.1  riastrad 	u32 idx_value = ib[idx];
   3382  1.1  riastrad 	u32 start_reg, end_reg, reg, i;
   3383  1.1  riastrad 	u32 command, info;
   3384  1.1  riastrad 
   3385  1.1  riastrad 	switch (pkt->opcode) {
   3386  1.1  riastrad 	case PACKET3_NOP:
   3387  1.1  riastrad 		break;
   3388  1.1  riastrad 	case PACKET3_SET_BASE:
   3389  1.1  riastrad 		if (idx_value != 1) {
   3390  1.1  riastrad 			DRM_ERROR("bad SET_BASE");
   3391  1.1  riastrad 			return -EINVAL;
   3392  1.1  riastrad 		}
   3393  1.1  riastrad 		break;
   3394  1.1  riastrad 	case PACKET3_CLEAR_STATE:
   3395  1.1  riastrad 	case PACKET3_INDEX_BUFFER_SIZE:
   3396  1.1  riastrad 	case PACKET3_DISPATCH_DIRECT:
   3397  1.1  riastrad 	case PACKET3_DISPATCH_INDIRECT:
   3398  1.1  riastrad 	case PACKET3_MODE_CONTROL:
   3399  1.1  riastrad 	case PACKET3_SET_PREDICATION:
   3400  1.1  riastrad 	case PACKET3_COND_EXEC:
   3401  1.1  riastrad 	case PACKET3_PRED_EXEC:
   3402  1.1  riastrad 	case PACKET3_DRAW_INDIRECT:
   3403  1.1  riastrad 	case PACKET3_DRAW_INDEX_INDIRECT:
   3404  1.1  riastrad 	case PACKET3_INDEX_BASE:
   3405  1.1  riastrad 	case PACKET3_DRAW_INDEX_2:
   3406  1.1  riastrad 	case PACKET3_CONTEXT_CONTROL:
   3407  1.1  riastrad 	case PACKET3_DRAW_INDEX_OFFSET:
   3408  1.1  riastrad 	case PACKET3_INDEX_TYPE:
   3409  1.1  riastrad 	case PACKET3_DRAW_INDEX:
   3410  1.1  riastrad 	case PACKET3_DRAW_INDEX_AUTO:
   3411  1.1  riastrad 	case PACKET3_DRAW_INDEX_IMMD:
   3412  1.1  riastrad 	case PACKET3_NUM_INSTANCES:
   3413  1.1  riastrad 	case PACKET3_DRAW_INDEX_MULTI_AUTO:
   3414  1.1  riastrad 	case PACKET3_STRMOUT_BUFFER_UPDATE:
   3415  1.1  riastrad 	case PACKET3_DRAW_INDEX_OFFSET_2:
   3416  1.1  riastrad 	case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
   3417  1.1  riastrad 	case PACKET3_MPEG_INDEX:
   3418  1.1  riastrad 	case PACKET3_WAIT_REG_MEM:
   3419  1.1  riastrad 	case PACKET3_MEM_WRITE:
   3420  1.5  riastrad 	case PACKET3_PFP_SYNC_ME:
   3421  1.1  riastrad 	case PACKET3_SURFACE_SYNC:
   3422  1.1  riastrad 	case PACKET3_EVENT_WRITE:
   3423  1.1  riastrad 	case PACKET3_EVENT_WRITE_EOP:
   3424  1.1  riastrad 	case PACKET3_EVENT_WRITE_EOS:
   3425  1.1  riastrad 	case PACKET3_SET_CONTEXT_REG:
   3426  1.1  riastrad 	case PACKET3_SET_BOOL_CONST:
   3427  1.1  riastrad 	case PACKET3_SET_LOOP_CONST:
   3428  1.1  riastrad 	case PACKET3_SET_RESOURCE:
   3429  1.1  riastrad 	case PACKET3_SET_SAMPLER:
   3430  1.1  riastrad 	case PACKET3_SET_CTL_CONST:
   3431  1.1  riastrad 	case PACKET3_SET_RESOURCE_OFFSET:
   3432  1.1  riastrad 	case PACKET3_SET_CONTEXT_REG_INDIRECT:
   3433  1.1  riastrad 	case PACKET3_SET_RESOURCE_INDIRECT:
   3434  1.1  riastrad 	case CAYMAN_PACKET3_DEALLOC_STATE:
   3435  1.1  riastrad 		break;
   3436  1.1  riastrad 	case PACKET3_COND_WRITE:
   3437  1.1  riastrad 		if (idx_value & 0x100) {
   3438  1.1  riastrad 			reg = ib[idx + 5] * 4;
   3439  1.1  riastrad 			if (!evergreen_vm_reg_valid(reg))
   3440  1.1  riastrad 				return -EINVAL;
   3441  1.1  riastrad 		}
   3442  1.1  riastrad 		break;
   3443  1.1  riastrad 	case PACKET3_COPY_DW:
   3444  1.1  riastrad 		if (idx_value & 0x2) {
   3445  1.1  riastrad 			reg = ib[idx + 3] * 4;
   3446  1.1  riastrad 			if (!evergreen_vm_reg_valid(reg))
   3447  1.1  riastrad 				return -EINVAL;
   3448  1.1  riastrad 		}
   3449  1.1  riastrad 		break;
   3450  1.1  riastrad 	case PACKET3_SET_CONFIG_REG:
   3451  1.1  riastrad 		start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
   3452  1.1  riastrad 		end_reg = 4 * pkt->count + start_reg - 4;
   3453  1.1  riastrad 		if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
   3454  1.1  riastrad 		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
   3455  1.1  riastrad 		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
   3456  1.1  riastrad 			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
   3457  1.1  riastrad 			return -EINVAL;
   3458  1.1  riastrad 		}
   3459  1.1  riastrad 		for (i = 0; i < pkt->count; i++) {
   3460  1.1  riastrad 			reg = start_reg + (4 * i);
   3461  1.1  riastrad 			if (!evergreen_vm_reg_valid(reg))
   3462  1.1  riastrad 				return -EINVAL;
   3463  1.1  riastrad 		}
   3464  1.1  riastrad 		break;
   3465  1.1  riastrad 	case PACKET3_CP_DMA:
   3466  1.1  riastrad 		command = ib[idx + 4];
   3467  1.1  riastrad 		info = ib[idx + 1];
   3468  1.1  riastrad 		if ((((info & 0x60000000) >> 29) != 0) || /* src = GDS or DATA */
   3469  1.1  riastrad 		    (((info & 0x00300000) >> 20) != 0) || /* dst = GDS */
   3470  1.1  riastrad 		    ((((info & 0x00300000) >> 20) == 0) &&
   3471  1.1  riastrad 		     (command & PACKET3_CP_DMA_CMD_DAS)) || /* dst = register */
   3472  1.1  riastrad 		    ((((info & 0x60000000) >> 29) == 0) &&
   3473  1.1  riastrad 		     (command & PACKET3_CP_DMA_CMD_SAS))) { /* src = register */
   3474  1.1  riastrad 			/* non mem to mem copies requires dw aligned count */
   3475  1.1  riastrad 			if ((command & 0x1fffff) % 4) {
   3476  1.1  riastrad 				DRM_ERROR("CP DMA command requires dw count alignment\n");
   3477  1.1  riastrad 				return -EINVAL;
   3478  1.1  riastrad 			}
   3479  1.1  riastrad 		}
   3480  1.1  riastrad 		if (command & PACKET3_CP_DMA_CMD_SAS) {
   3481  1.1  riastrad 			/* src address space is register */
   3482  1.1  riastrad 			if (((info & 0x60000000) >> 29) == 0) {
   3483  1.1  riastrad 				start_reg = idx_value << 2;
   3484  1.1  riastrad 				if (command & PACKET3_CP_DMA_CMD_SAIC) {
   3485  1.1  riastrad 					reg = start_reg;
   3486  1.1  riastrad 					if (!evergreen_vm_reg_valid(reg)) {
   3487  1.1  riastrad 						DRM_ERROR("CP DMA Bad SRC register\n");
   3488  1.1  riastrad 						return -EINVAL;
   3489  1.1  riastrad 					}
   3490  1.1  riastrad 				} else {
   3491  1.1  riastrad 					for (i = 0; i < (command & 0x1fffff); i++) {
   3492  1.1  riastrad 						reg = start_reg + (4 * i);
   3493  1.1  riastrad 						if (!evergreen_vm_reg_valid(reg)) {
   3494  1.1  riastrad 							DRM_ERROR("CP DMA Bad SRC register\n");
   3495  1.1  riastrad 							return -EINVAL;
   3496  1.1  riastrad 						}
   3497  1.1  riastrad 					}
   3498  1.1  riastrad 				}
   3499  1.1  riastrad 			}
   3500  1.1  riastrad 		}
   3501  1.1  riastrad 		if (command & PACKET3_CP_DMA_CMD_DAS) {
   3502  1.1  riastrad 			/* dst address space is register */
   3503  1.1  riastrad 			if (((info & 0x00300000) >> 20) == 0) {
   3504  1.1  riastrad 				start_reg = ib[idx + 2];
   3505  1.1  riastrad 				if (command & PACKET3_CP_DMA_CMD_DAIC) {
   3506  1.1  riastrad 					reg = start_reg;
   3507  1.1  riastrad 					if (!evergreen_vm_reg_valid(reg)) {
   3508  1.1  riastrad 						DRM_ERROR("CP DMA Bad DST register\n");
   3509  1.1  riastrad 						return -EINVAL;
   3510  1.1  riastrad 					}
   3511  1.1  riastrad 				} else {
   3512  1.1  riastrad 					for (i = 0; i < (command & 0x1fffff); i++) {
   3513  1.1  riastrad 						reg = start_reg + (4 * i);
   3514  1.1  riastrad 						if (!evergreen_vm_reg_valid(reg)) {
   3515  1.1  riastrad 							DRM_ERROR("CP DMA Bad DST register\n");
   3516  1.1  riastrad 							return -EINVAL;
   3517  1.1  riastrad 						}
   3518  1.1  riastrad 					}
   3519  1.1  riastrad 				}
   3520  1.1  riastrad 			}
   3521  1.1  riastrad 		}
   3522  1.1  riastrad 		break;
   3523  1.5  riastrad 	case PACKET3_SET_APPEND_CNT: {
   3524  1.5  riastrad 		uint32_t areg;
   3525  1.5  riastrad 		uint32_t allowed_reg_base;
   3526  1.5  riastrad 
   3527  1.5  riastrad 		if (pkt->count != 2) {
   3528  1.5  riastrad 			DRM_ERROR("bad SET_APPEND_CNT (invalid count)\n");
   3529  1.5  riastrad 			return -EINVAL;
   3530  1.5  riastrad 		}
   3531  1.5  riastrad 
   3532  1.5  riastrad 		allowed_reg_base = GDS_APPEND_COUNT_0;
   3533  1.5  riastrad 		allowed_reg_base -= PACKET3_SET_CONTEXT_REG_START;
   3534  1.5  riastrad 		allowed_reg_base >>= 2;
   3535  1.5  riastrad 
   3536  1.5  riastrad 		areg = idx_value >> 16;
   3537  1.5  riastrad 		if (areg < allowed_reg_base || areg > (allowed_reg_base + 11)) {
   3538  1.5  riastrad 			DRM_ERROR("forbidden register for append cnt 0x%08x at %d\n",
   3539  1.5  riastrad 				  areg, idx);
   3540  1.5  riastrad 			return -EINVAL;
   3541  1.5  riastrad 		}
   3542  1.5  riastrad 		break;
   3543  1.5  riastrad 	}
   3544  1.1  riastrad 	default:
   3545  1.1  riastrad 		return -EINVAL;
   3546  1.1  riastrad 	}
   3547  1.1  riastrad 	return 0;
   3548  1.1  riastrad }
   3549  1.1  riastrad 
   3550  1.1  riastrad int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
   3551  1.1  riastrad {
   3552  1.1  riastrad 	int ret = 0;
   3553  1.1  riastrad 	u32 idx = 0;
   3554  1.1  riastrad 	struct radeon_cs_packet pkt;
   3555  1.1  riastrad 
   3556  1.1  riastrad 	do {
   3557  1.1  riastrad 		pkt.idx = idx;
   3558  1.1  riastrad 		pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]);
   3559  1.1  riastrad 		pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]);
   3560  1.1  riastrad 		pkt.one_reg_wr = 0;
   3561  1.1  riastrad 		switch (pkt.type) {
   3562  1.1  riastrad 		case RADEON_PACKET_TYPE0:
   3563  1.1  riastrad 			dev_err(rdev->dev, "Packet0 not allowed!\n");
   3564  1.1  riastrad 			ret = -EINVAL;
   3565  1.1  riastrad 			break;
   3566  1.1  riastrad 		case RADEON_PACKET_TYPE2:
   3567  1.1  riastrad 			idx += 1;
   3568  1.1  riastrad 			break;
   3569  1.1  riastrad 		case RADEON_PACKET_TYPE3:
   3570  1.1  riastrad 			pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
   3571  1.1  riastrad 			ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt);
   3572  1.1  riastrad 			idx += pkt.count + 2;
   3573  1.1  riastrad 			break;
   3574  1.1  riastrad 		default:
   3575  1.1  riastrad 			dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
   3576  1.1  riastrad 			ret = -EINVAL;
   3577  1.1  riastrad 			break;
   3578  1.1  riastrad 		}
   3579  1.1  riastrad 		if (ret)
   3580  1.1  riastrad 			break;
   3581  1.1  riastrad 	} while (idx < ib->length_dw);
   3582  1.1  riastrad 
   3583  1.1  riastrad 	return ret;
   3584  1.1  riastrad }
   3585  1.1  riastrad 
   3586  1.1  riastrad /**
   3587  1.1  riastrad  * evergreen_dma_ib_parse() - parse the DMA IB for VM
   3588  1.1  riastrad  * @rdev: radeon_device pointer
   3589  1.1  riastrad  * @ib:	radeon_ib pointer
   3590  1.1  riastrad  *
   3591  1.1  riastrad  * Parses the DMA IB from the VM CS ioctl
   3592  1.1  riastrad  * checks for errors. (Cayman-SI)
   3593  1.1  riastrad  * Returns 0 for success and an error on failure.
   3594  1.1  riastrad  **/
   3595  1.1  riastrad int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
   3596  1.1  riastrad {
   3597  1.1  riastrad 	u32 idx = 0;
   3598  1.1  riastrad 	u32 header, cmd, count, sub_cmd;
   3599  1.1  riastrad 
   3600  1.1  riastrad 	do {
   3601  1.1  riastrad 		header = ib->ptr[idx];
   3602  1.1  riastrad 		cmd = GET_DMA_CMD(header);
   3603  1.1  riastrad 		count = GET_DMA_COUNT(header);
   3604  1.1  riastrad 		sub_cmd = GET_DMA_SUB_CMD(header);
   3605  1.1  riastrad 
   3606  1.1  riastrad 		switch (cmd) {
   3607  1.1  riastrad 		case DMA_PACKET_WRITE:
   3608  1.1  riastrad 			switch (sub_cmd) {
   3609  1.1  riastrad 			/* tiled */
   3610  1.1  riastrad 			case 8:
   3611  1.1  riastrad 				idx += count + 7;
   3612  1.1  riastrad 				break;
   3613  1.1  riastrad 			/* linear */
   3614  1.1  riastrad 			case 0:
   3615  1.1  riastrad 				idx += count + 3;
   3616  1.1  riastrad 				break;
   3617  1.1  riastrad 			default:
   3618  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_WRITE [%6d] 0x%08x sub cmd is not 0 or 8\n", idx, ib->ptr[idx]);
   3619  1.1  riastrad 				return -EINVAL;
   3620  1.1  riastrad 			}
   3621  1.1  riastrad 			break;
   3622  1.1  riastrad 		case DMA_PACKET_COPY:
   3623  1.1  riastrad 			switch (sub_cmd) {
   3624  1.1  riastrad 			/* Copy L2L, DW aligned */
   3625  1.1  riastrad 			case 0x00:
   3626  1.1  riastrad 				idx += 5;
   3627  1.1  riastrad 				break;
   3628  1.1  riastrad 			/* Copy L2T/T2L */
   3629  1.1  riastrad 			case 0x08:
   3630  1.1  riastrad 				idx += 9;
   3631  1.1  riastrad 				break;
   3632  1.1  riastrad 			/* Copy L2L, byte aligned */
   3633  1.1  riastrad 			case 0x40:
   3634  1.1  riastrad 				idx += 5;
   3635  1.1  riastrad 				break;
   3636  1.1  riastrad 			/* Copy L2L, partial */
   3637  1.1  riastrad 			case 0x41:
   3638  1.1  riastrad 				idx += 9;
   3639  1.1  riastrad 				break;
   3640  1.1  riastrad 			/* Copy L2L, DW aligned, broadcast */
   3641  1.1  riastrad 			case 0x44:
   3642  1.1  riastrad 				idx += 7;
   3643  1.1  riastrad 				break;
   3644  1.1  riastrad 			/* Copy L2T Frame to Field */
   3645  1.1  riastrad 			case 0x48:
   3646  1.1  riastrad 				idx += 10;
   3647  1.1  riastrad 				break;
   3648  1.1  riastrad 			/* Copy L2T/T2L, partial */
   3649  1.1  riastrad 			case 0x49:
   3650  1.1  riastrad 				idx += 12;
   3651  1.1  riastrad 				break;
   3652  1.1  riastrad 			/* Copy L2T broadcast */
   3653  1.1  riastrad 			case 0x4b:
   3654  1.1  riastrad 				idx += 10;
   3655  1.1  riastrad 				break;
   3656  1.1  riastrad 			/* Copy L2T/T2L (tile units) */
   3657  1.1  riastrad 			case 0x4c:
   3658  1.1  riastrad 				idx += 9;
   3659  1.1  riastrad 				break;
   3660  1.1  riastrad 			/* Copy T2T, partial (tile units) */
   3661  1.1  riastrad 			case 0x4d:
   3662  1.1  riastrad 				idx += 13;
   3663  1.1  riastrad 				break;
   3664  1.1  riastrad 			/* Copy L2T broadcast (tile units) */
   3665  1.1  riastrad 			case 0x4f:
   3666  1.1  riastrad 				idx += 10;
   3667  1.1  riastrad 				break;
   3668  1.1  riastrad 			default:
   3669  1.1  riastrad 				DRM_ERROR("bad DMA_PACKET_COPY [%6d] 0x%08x invalid sub cmd\n", idx, ib->ptr[idx]);
   3670  1.1  riastrad 				return -EINVAL;
   3671  1.1  riastrad 			}
   3672  1.1  riastrad 			break;
   3673  1.1  riastrad 		case DMA_PACKET_CONSTANT_FILL:
   3674  1.1  riastrad 			idx += 4;
   3675  1.1  riastrad 			break;
   3676  1.1  riastrad 		case DMA_PACKET_NOP:
   3677  1.1  riastrad 			idx += 1;
   3678  1.1  riastrad 			break;
   3679  1.1  riastrad 		default:
   3680  1.1  riastrad 			DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx);
   3681  1.1  riastrad 			return -EINVAL;
   3682  1.1  riastrad 		}
   3683  1.1  riastrad 	} while (idx < ib->length_dw);
   3684  1.1  riastrad 
   3685  1.1  riastrad 	return 0;
   3686  1.1  riastrad }
   3687