1 1.1 riastrad /* $NetBSD: radeon_r600_cs.c,v 1.2 2021/12/18 23:45:43 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2008 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.1 riastrad #include <sys/cdefs.h> 31 1.1 riastrad __KERNEL_RCSID(0, "$NetBSD: radeon_r600_cs.c,v 1.2 2021/12/18 23:45:43 riastradh Exp $"); 32 1.1 riastrad 33 1.1 riastrad #include <linux/kernel.h> 34 1.2 riastrad 35 1.1 riastrad #include "radeon.h" 36 1.2 riastrad #include "radeon_asic.h" 37 1.1 riastrad #include "r600d.h" 38 1.1 riastrad #include "r600_reg_safe.h" 39 1.1 riastrad 40 1.1 riastrad static int r600_nomm; 41 1.1 riastrad extern void r600_cs_legacy_get_tiling_conf(struct drm_device *dev, u32 *npipes, u32 *nbanks, u32 *group_size); 42 1.1 riastrad 43 1.1 riastrad 44 1.1 riastrad struct r600_cs_track { 45 1.1 riastrad /* configuration we miror so that we use same code btw kms/ums */ 46 1.1 riastrad u32 group_size; 47 1.1 riastrad u32 nbanks; 48 1.1 riastrad u32 npipes; 49 1.1 riastrad /* value we track */ 50 1.1 riastrad u32 sq_config; 51 1.1 riastrad u32 log_nsamples; 52 1.1 riastrad u32 nsamples; 53 1.1 riastrad u32 cb_color_base_last[8]; 54 1.1 riastrad struct radeon_bo *cb_color_bo[8]; 55 1.1 riastrad u64 cb_color_bo_mc[8]; 56 1.1 riastrad u64 cb_color_bo_offset[8]; 57 1.1 riastrad struct radeon_bo *cb_color_frag_bo[8]; 58 1.1 riastrad u64 cb_color_frag_offset[8]; 59 1.1 riastrad struct radeon_bo *cb_color_tile_bo[8]; 60 1.1 riastrad u64 cb_color_tile_offset[8]; 61 1.1 riastrad u32 cb_color_mask[8]; 62 1.1 riastrad u32 cb_color_info[8]; 63 1.1 riastrad u32 cb_color_view[8]; 64 1.1 riastrad u32 cb_color_size_idx[8]; /* unused */ 65 1.1 riastrad u32 cb_target_mask; 66 1.1 riastrad u32 cb_shader_mask; /* unused */ 67 1.1 riastrad bool is_resolve; 68 1.1 riastrad u32 cb_color_size[8]; 69 1.1 riastrad u32 vgt_strmout_en; 70 1.1 riastrad u32 vgt_strmout_buffer_en; 71 1.1 riastrad struct radeon_bo *vgt_strmout_bo[4]; 72 1.1 riastrad u64 vgt_strmout_bo_mc[4]; /* unused */ 73 1.1 riastrad u32 vgt_strmout_bo_offset[4]; 74 1.1 riastrad u32 vgt_strmout_size[4]; 75 1.1 riastrad u32 db_depth_control; 76 1.1 riastrad u32 db_depth_info; 77 1.1 riastrad u32 db_depth_size_idx; 78 1.1 riastrad u32 db_depth_view; 79 1.1 riastrad u32 db_depth_size; 80 1.1 riastrad u32 db_offset; 81 1.1 riastrad struct radeon_bo *db_bo; 82 1.1 riastrad u64 db_bo_mc; 83 1.1 riastrad bool sx_misc_kill_all_prims; 84 1.1 riastrad bool cb_dirty; 85 1.1 riastrad bool db_dirty; 86 1.1 riastrad bool streamout_dirty; 87 1.1 riastrad struct radeon_bo *htile_bo; 88 1.1 riastrad u64 htile_offset; 89 1.1 riastrad u32 htile_surface; 90 1.1 riastrad }; 91 1.1 riastrad 92 1.1 riastrad #define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } 93 1.1 riastrad #define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 } 94 1.1 riastrad #define FMT_24_BIT(fmt) [fmt] = { 1, 1, 4, 0, CHIP_R600 } 95 1.1 riastrad #define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 } 96 1.1 riastrad #define FMT_48_BIT(fmt) [fmt] = { 1, 1, 8, 0, CHIP_R600 } 97 1.1 riastrad #define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 } 98 1.1 riastrad #define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 } 99 1.1 riastrad #define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 } 100 1.1 riastrad 101 1.1 riastrad struct gpu_formats { 102 1.1 riastrad unsigned blockwidth; 103 1.1 riastrad unsigned blockheight; 104 1.1 riastrad unsigned blocksize; 105 1.1 riastrad unsigned valid_color; 106 1.1 riastrad enum radeon_family min_family; 107 1.1 riastrad }; 108 1.1 riastrad 109 1.1 riastrad static const struct gpu_formats color_formats_table[] = { 110 1.1 riastrad /* 8 bit */ 111 1.1 riastrad FMT_8_BIT(V_038004_COLOR_8, 1), 112 1.1 riastrad FMT_8_BIT(V_038004_COLOR_4_4, 1), 113 1.1 riastrad FMT_8_BIT(V_038004_COLOR_3_3_2, 1), 114 1.1 riastrad FMT_8_BIT(V_038004_FMT_1, 0), 115 1.1 riastrad 116 1.1 riastrad /* 16-bit */ 117 1.1 riastrad FMT_16_BIT(V_038004_COLOR_16, 1), 118 1.1 riastrad FMT_16_BIT(V_038004_COLOR_16_FLOAT, 1), 119 1.1 riastrad FMT_16_BIT(V_038004_COLOR_8_8, 1), 120 1.1 riastrad FMT_16_BIT(V_038004_COLOR_5_6_5, 1), 121 1.1 riastrad FMT_16_BIT(V_038004_COLOR_6_5_5, 1), 122 1.1 riastrad FMT_16_BIT(V_038004_COLOR_1_5_5_5, 1), 123 1.1 riastrad FMT_16_BIT(V_038004_COLOR_4_4_4_4, 1), 124 1.1 riastrad FMT_16_BIT(V_038004_COLOR_5_5_5_1, 1), 125 1.1 riastrad 126 1.1 riastrad /* 24-bit */ 127 1.1 riastrad FMT_24_BIT(V_038004_FMT_8_8_8), 128 1.1 riastrad 129 1.1 riastrad /* 32-bit */ 130 1.1 riastrad FMT_32_BIT(V_038004_COLOR_32, 1), 131 1.1 riastrad FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1), 132 1.1 riastrad FMT_32_BIT(V_038004_COLOR_16_16, 1), 133 1.1 riastrad FMT_32_BIT(V_038004_COLOR_16_16_FLOAT, 1), 134 1.1 riastrad FMT_32_BIT(V_038004_COLOR_8_24, 1), 135 1.1 riastrad FMT_32_BIT(V_038004_COLOR_8_24_FLOAT, 1), 136 1.1 riastrad FMT_32_BIT(V_038004_COLOR_24_8, 1), 137 1.1 riastrad FMT_32_BIT(V_038004_COLOR_24_8_FLOAT, 1), 138 1.1 riastrad FMT_32_BIT(V_038004_COLOR_10_11_11, 1), 139 1.1 riastrad FMT_32_BIT(V_038004_COLOR_10_11_11_FLOAT, 1), 140 1.1 riastrad FMT_32_BIT(V_038004_COLOR_11_11_10, 1), 141 1.1 riastrad FMT_32_BIT(V_038004_COLOR_11_11_10_FLOAT, 1), 142 1.1 riastrad FMT_32_BIT(V_038004_COLOR_2_10_10_10, 1), 143 1.1 riastrad FMT_32_BIT(V_038004_COLOR_8_8_8_8, 1), 144 1.1 riastrad FMT_32_BIT(V_038004_COLOR_10_10_10_2, 1), 145 1.1 riastrad FMT_32_BIT(V_038004_FMT_5_9_9_9_SHAREDEXP, 0), 146 1.1 riastrad FMT_32_BIT(V_038004_FMT_32_AS_8, 0), 147 1.1 riastrad FMT_32_BIT(V_038004_FMT_32_AS_8_8, 0), 148 1.1 riastrad 149 1.1 riastrad /* 48-bit */ 150 1.1 riastrad FMT_48_BIT(V_038004_FMT_16_16_16), 151 1.1 riastrad FMT_48_BIT(V_038004_FMT_16_16_16_FLOAT), 152 1.1 riastrad 153 1.1 riastrad /* 64-bit */ 154 1.1 riastrad FMT_64_BIT(V_038004_COLOR_X24_8_32_FLOAT, 1), 155 1.1 riastrad FMT_64_BIT(V_038004_COLOR_32_32, 1), 156 1.1 riastrad FMT_64_BIT(V_038004_COLOR_32_32_FLOAT, 1), 157 1.1 riastrad FMT_64_BIT(V_038004_COLOR_16_16_16_16, 1), 158 1.1 riastrad FMT_64_BIT(V_038004_COLOR_16_16_16_16_FLOAT, 1), 159 1.1 riastrad 160 1.1 riastrad FMT_96_BIT(V_038004_FMT_32_32_32), 161 1.1 riastrad FMT_96_BIT(V_038004_FMT_32_32_32_FLOAT), 162 1.1 riastrad 163 1.1 riastrad /* 128-bit */ 164 1.1 riastrad FMT_128_BIT(V_038004_COLOR_32_32_32_32, 1), 165 1.1 riastrad FMT_128_BIT(V_038004_COLOR_32_32_32_32_FLOAT, 1), 166 1.1 riastrad 167 1.1 riastrad [V_038004_FMT_GB_GR] = { 2, 1, 4, 0 }, 168 1.1 riastrad [V_038004_FMT_BG_RG] = { 2, 1, 4, 0 }, 169 1.1 riastrad 170 1.1 riastrad /* block compressed formats */ 171 1.1 riastrad [V_038004_FMT_BC1] = { 4, 4, 8, 0 }, 172 1.1 riastrad [V_038004_FMT_BC2] = { 4, 4, 16, 0 }, 173 1.1 riastrad [V_038004_FMT_BC3] = { 4, 4, 16, 0 }, 174 1.1 riastrad [V_038004_FMT_BC4] = { 4, 4, 8, 0 }, 175 1.1 riastrad [V_038004_FMT_BC5] = { 4, 4, 16, 0}, 176 1.1 riastrad [V_038004_FMT_BC6] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */ 177 1.1 riastrad [V_038004_FMT_BC7] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */ 178 1.1 riastrad 179 1.1 riastrad /* The other Evergreen formats */ 180 1.1 riastrad [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR}, 181 1.1 riastrad }; 182 1.1 riastrad 183 1.1 riastrad bool r600_fmt_is_valid_color(u32 format) 184 1.1 riastrad { 185 1.1 riastrad if (format >= ARRAY_SIZE(color_formats_table)) 186 1.1 riastrad return false; 187 1.1 riastrad 188 1.1 riastrad if (color_formats_table[format].valid_color) 189 1.1 riastrad return true; 190 1.1 riastrad 191 1.1 riastrad return false; 192 1.1 riastrad } 193 1.1 riastrad 194 1.1 riastrad bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family) 195 1.1 riastrad { 196 1.1 riastrad if (format >= ARRAY_SIZE(color_formats_table)) 197 1.1 riastrad return false; 198 1.1 riastrad 199 1.1 riastrad if (family < color_formats_table[format].min_family) 200 1.1 riastrad return false; 201 1.1 riastrad 202 1.1 riastrad if (color_formats_table[format].blockwidth > 0) 203 1.1 riastrad return true; 204 1.1 riastrad 205 1.1 riastrad return false; 206 1.1 riastrad } 207 1.1 riastrad 208 1.1 riastrad int r600_fmt_get_blocksize(u32 format) 209 1.1 riastrad { 210 1.1 riastrad if (format >= ARRAY_SIZE(color_formats_table)) 211 1.1 riastrad return 0; 212 1.1 riastrad 213 1.1 riastrad return color_formats_table[format].blocksize; 214 1.1 riastrad } 215 1.1 riastrad 216 1.1 riastrad int r600_fmt_get_nblocksx(u32 format, u32 w) 217 1.1 riastrad { 218 1.1 riastrad unsigned bw; 219 1.1 riastrad 220 1.1 riastrad if (format >= ARRAY_SIZE(color_formats_table)) 221 1.1 riastrad return 0; 222 1.1 riastrad 223 1.1 riastrad bw = color_formats_table[format].blockwidth; 224 1.1 riastrad if (bw == 0) 225 1.1 riastrad return 0; 226 1.1 riastrad 227 1.1 riastrad return (w + bw - 1) / bw; 228 1.1 riastrad } 229 1.1 riastrad 230 1.1 riastrad int r600_fmt_get_nblocksy(u32 format, u32 h) 231 1.1 riastrad { 232 1.1 riastrad unsigned bh; 233 1.1 riastrad 234 1.1 riastrad if (format >= ARRAY_SIZE(color_formats_table)) 235 1.1 riastrad return 0; 236 1.1 riastrad 237 1.1 riastrad bh = color_formats_table[format].blockheight; 238 1.1 riastrad if (bh == 0) 239 1.1 riastrad return 0; 240 1.1 riastrad 241 1.1 riastrad return (h + bh - 1) / bh; 242 1.1 riastrad } 243 1.1 riastrad 244 1.1 riastrad struct array_mode_checker { 245 1.1 riastrad int array_mode; 246 1.1 riastrad u32 group_size; 247 1.1 riastrad u32 nbanks; 248 1.1 riastrad u32 npipes; 249 1.1 riastrad u32 nsamples; 250 1.1 riastrad u32 blocksize; 251 1.1 riastrad }; 252 1.1 riastrad 253 1.1 riastrad /* returns alignment in pixels for pitch/height/depth and bytes for base */ 254 1.1 riastrad static int r600_get_array_mode_alignment(struct array_mode_checker *values, 255 1.1 riastrad u32 *pitch_align, 256 1.1 riastrad u32 *height_align, 257 1.1 riastrad u32 *depth_align, 258 1.1 riastrad u64 *base_align) 259 1.1 riastrad { 260 1.1 riastrad u32 tile_width = 8; 261 1.1 riastrad u32 tile_height = 8; 262 1.1 riastrad u32 macro_tile_width = values->nbanks; 263 1.1 riastrad u32 macro_tile_height = values->npipes; 264 1.1 riastrad u32 tile_bytes = tile_width * tile_height * values->blocksize * values->nsamples; 265 1.1 riastrad u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; 266 1.1 riastrad 267 1.1 riastrad switch (values->array_mode) { 268 1.1 riastrad case ARRAY_LINEAR_GENERAL: 269 1.1 riastrad /* technically tile_width/_height for pitch/height */ 270 1.1 riastrad *pitch_align = 1; /* tile_width */ 271 1.1 riastrad *height_align = 1; /* tile_height */ 272 1.1 riastrad *depth_align = 1; 273 1.1 riastrad *base_align = 1; 274 1.1 riastrad break; 275 1.1 riastrad case ARRAY_LINEAR_ALIGNED: 276 1.1 riastrad *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize)); 277 1.1 riastrad *height_align = 1; 278 1.1 riastrad *depth_align = 1; 279 1.1 riastrad *base_align = values->group_size; 280 1.1 riastrad break; 281 1.1 riastrad case ARRAY_1D_TILED_THIN1: 282 1.1 riastrad *pitch_align = max((u32)tile_width, 283 1.1 riastrad (u32)(values->group_size / 284 1.1 riastrad (tile_height * values->blocksize * values->nsamples))); 285 1.1 riastrad *height_align = tile_height; 286 1.1 riastrad *depth_align = 1; 287 1.1 riastrad *base_align = values->group_size; 288 1.1 riastrad break; 289 1.1 riastrad case ARRAY_2D_TILED_THIN1: 290 1.1 riastrad *pitch_align = max((u32)macro_tile_width * tile_width, 291 1.1 riastrad (u32)((values->group_size * values->nbanks) / 292 1.1 riastrad (values->blocksize * values->nsamples * tile_width))); 293 1.1 riastrad *height_align = macro_tile_height * tile_height; 294 1.1 riastrad *depth_align = 1; 295 1.1 riastrad *base_align = max(macro_tile_bytes, 296 1.1 riastrad (*pitch_align) * values->blocksize * (*height_align) * values->nsamples); 297 1.1 riastrad break; 298 1.1 riastrad default: 299 1.1 riastrad return -EINVAL; 300 1.1 riastrad } 301 1.1 riastrad 302 1.1 riastrad return 0; 303 1.1 riastrad } 304 1.1 riastrad 305 1.1 riastrad static void r600_cs_track_init(struct r600_cs_track *track) 306 1.1 riastrad { 307 1.1 riastrad int i; 308 1.1 riastrad 309 1.1 riastrad /* assume DX9 mode */ 310 1.1 riastrad track->sq_config = DX9_CONSTS; 311 1.1 riastrad for (i = 0; i < 8; i++) { 312 1.1 riastrad track->cb_color_base_last[i] = 0; 313 1.1 riastrad track->cb_color_size[i] = 0; 314 1.1 riastrad track->cb_color_size_idx[i] = 0; 315 1.1 riastrad track->cb_color_info[i] = 0; 316 1.1 riastrad track->cb_color_view[i] = 0xFFFFFFFF; 317 1.1 riastrad track->cb_color_bo[i] = NULL; 318 1.1 riastrad track->cb_color_bo_offset[i] = 0xFFFFFFFF; 319 1.1 riastrad track->cb_color_bo_mc[i] = 0xFFFFFFFF; 320 1.1 riastrad track->cb_color_frag_bo[i] = NULL; 321 1.1 riastrad track->cb_color_frag_offset[i] = 0xFFFFFFFF; 322 1.1 riastrad track->cb_color_tile_bo[i] = NULL; 323 1.1 riastrad track->cb_color_tile_offset[i] = 0xFFFFFFFF; 324 1.1 riastrad track->cb_color_mask[i] = 0xFFFFFFFF; 325 1.1 riastrad } 326 1.1 riastrad track->is_resolve = false; 327 1.1 riastrad track->nsamples = 16; 328 1.1 riastrad track->log_nsamples = 4; 329 1.1 riastrad track->cb_target_mask = 0xFFFFFFFF; 330 1.1 riastrad track->cb_shader_mask = 0xFFFFFFFF; 331 1.1 riastrad track->cb_dirty = true; 332 1.1 riastrad track->db_bo = NULL; 333 1.1 riastrad track->db_bo_mc = 0xFFFFFFFF; 334 1.1 riastrad /* assume the biggest format and that htile is enabled */ 335 1.1 riastrad track->db_depth_info = 7 | (1 << 25); 336 1.1 riastrad track->db_depth_view = 0xFFFFC000; 337 1.1 riastrad track->db_depth_size = 0xFFFFFFFF; 338 1.1 riastrad track->db_depth_size_idx = 0; 339 1.1 riastrad track->db_depth_control = 0xFFFFFFFF; 340 1.1 riastrad track->db_dirty = true; 341 1.1 riastrad track->htile_bo = NULL; 342 1.1 riastrad track->htile_offset = 0xFFFFFFFF; 343 1.1 riastrad track->htile_surface = 0; 344 1.1 riastrad 345 1.1 riastrad for (i = 0; i < 4; i++) { 346 1.1 riastrad track->vgt_strmout_size[i] = 0; 347 1.1 riastrad track->vgt_strmout_bo[i] = NULL; 348 1.1 riastrad track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF; 349 1.1 riastrad track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF; 350 1.1 riastrad } 351 1.1 riastrad track->streamout_dirty = true; 352 1.1 riastrad track->sx_misc_kill_all_prims = false; 353 1.1 riastrad } 354 1.1 riastrad 355 1.1 riastrad static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) 356 1.1 riastrad { 357 1.1 riastrad struct r600_cs_track *track = p->track; 358 1.2 riastrad u32 slice_tile_max, tmp; 359 1.1 riastrad u32 height, height_align, pitch, pitch_align, depth_align; 360 1.1 riastrad u64 base_offset, base_align; 361 1.1 riastrad struct array_mode_checker array_check; 362 1.1 riastrad volatile u32 *ib = p->ib.ptr; 363 1.1 riastrad unsigned array_mode; 364 1.1 riastrad u32 format; 365 1.1 riastrad /* When resolve is used, the second colorbuffer has always 1 sample. */ 366 1.1 riastrad unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples; 367 1.1 riastrad 368 1.1 riastrad format = G_0280A0_FORMAT(track->cb_color_info[i]); 369 1.1 riastrad if (!r600_fmt_is_valid_color(format)) { 370 1.1 riastrad dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", 371 1.1 riastrad __func__, __LINE__, format, 372 1.1 riastrad i, track->cb_color_info[i]); 373 1.1 riastrad return -EINVAL; 374 1.1 riastrad } 375 1.1 riastrad /* pitch in pixels */ 376 1.1 riastrad pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8; 377 1.1 riastrad slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; 378 1.1 riastrad slice_tile_max *= 64; 379 1.1 riastrad height = slice_tile_max / pitch; 380 1.1 riastrad if (height > 8192) 381 1.1 riastrad height = 8192; 382 1.1 riastrad array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); 383 1.1 riastrad 384 1.1 riastrad base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i]; 385 1.1 riastrad array_check.array_mode = array_mode; 386 1.1 riastrad array_check.group_size = track->group_size; 387 1.1 riastrad array_check.nbanks = track->nbanks; 388 1.1 riastrad array_check.npipes = track->npipes; 389 1.1 riastrad array_check.nsamples = nsamples; 390 1.1 riastrad array_check.blocksize = r600_fmt_get_blocksize(format); 391 1.1 riastrad if (r600_get_array_mode_alignment(&array_check, 392 1.1 riastrad &pitch_align, &height_align, &depth_align, &base_align)) { 393 1.1 riastrad dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, 394 1.1 riastrad G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, 395 1.1 riastrad track->cb_color_info[i]); 396 1.1 riastrad return -EINVAL; 397 1.1 riastrad } 398 1.1 riastrad switch (array_mode) { 399 1.1 riastrad case V_0280A0_ARRAY_LINEAR_GENERAL: 400 1.1 riastrad break; 401 1.1 riastrad case V_0280A0_ARRAY_LINEAR_ALIGNED: 402 1.1 riastrad break; 403 1.1 riastrad case V_0280A0_ARRAY_1D_TILED_THIN1: 404 1.1 riastrad /* avoid breaking userspace */ 405 1.1 riastrad if (height > 7) 406 1.1 riastrad height &= ~0x7; 407 1.1 riastrad break; 408 1.1 riastrad case V_0280A0_ARRAY_2D_TILED_THIN1: 409 1.1 riastrad break; 410 1.1 riastrad default: 411 1.1 riastrad dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, 412 1.1 riastrad G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, 413 1.1 riastrad track->cb_color_info[i]); 414 1.1 riastrad return -EINVAL; 415 1.1 riastrad } 416 1.1 riastrad 417 1.1 riastrad if (!IS_ALIGNED(pitch, pitch_align)) { 418 1.1 riastrad dev_warn(p->dev, "%s:%d cb pitch (%d, 0x%x, %d) invalid\n", 419 1.1 riastrad __func__, __LINE__, pitch, pitch_align, array_mode); 420 1.1 riastrad return -EINVAL; 421 1.1 riastrad } 422 1.1 riastrad if (!IS_ALIGNED(height, height_align)) { 423 1.1 riastrad dev_warn(p->dev, "%s:%d cb height (%d, 0x%x, %d) invalid\n", 424 1.1 riastrad __func__, __LINE__, height, height_align, array_mode); 425 1.1 riastrad return -EINVAL; 426 1.1 riastrad } 427 1.1 riastrad if (!IS_ALIGNED(base_offset, base_align)) { 428 1.1 riastrad dev_warn(p->dev, "%s offset[%d] 0x%"PRIx64" 0x%"PRIx64", %d not aligned\n", __func__, i, 429 1.1 riastrad base_offset, base_align, array_mode); 430 1.1 riastrad return -EINVAL; 431 1.1 riastrad } 432 1.1 riastrad 433 1.1 riastrad /* check offset */ 434 1.1 riastrad tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * 435 1.1 riastrad r600_fmt_get_blocksize(format) * nsamples; 436 1.1 riastrad switch (array_mode) { 437 1.1 riastrad default: 438 1.1 riastrad case V_0280A0_ARRAY_LINEAR_GENERAL: 439 1.1 riastrad case V_0280A0_ARRAY_LINEAR_ALIGNED: 440 1.1 riastrad tmp += track->cb_color_view[i] & 0xFF; 441 1.1 riastrad break; 442 1.1 riastrad case V_0280A0_ARRAY_1D_TILED_THIN1: 443 1.1 riastrad case V_0280A0_ARRAY_2D_TILED_THIN1: 444 1.1 riastrad tmp += G_028080_SLICE_MAX(track->cb_color_view[i]) * tmp; 445 1.1 riastrad break; 446 1.1 riastrad } 447 1.1 riastrad if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { 448 1.1 riastrad if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { 449 1.1 riastrad /* the initial DDX does bad things with the CB size occasionally */ 450 1.1 riastrad /* it rounds up height too far for slice tile max but the BO is smaller */ 451 1.1 riastrad /* r600c,g also seem to flush at bad times in some apps resulting in 452 1.1 riastrad * bogus values here. So for linear just allow anything to avoid breaking 453 1.1 riastrad * broken userspace. 454 1.1 riastrad */ 455 1.1 riastrad } else { 456 1.1 riastrad dev_warn(p->dev, "%s offset[%d] %d %"PRIu64" %d %lu too big (%d %d) (%d %d %d)\n", 457 1.1 riastrad __func__, i, array_mode, 458 1.1 riastrad track->cb_color_bo_offset[i], tmp, 459 1.1 riastrad radeon_bo_size(track->cb_color_bo[i]), 460 1.1 riastrad pitch, height, r600_fmt_get_nblocksx(format, pitch), 461 1.1 riastrad r600_fmt_get_nblocksy(format, height), 462 1.1 riastrad r600_fmt_get_blocksize(format)); 463 1.1 riastrad return -EINVAL; 464 1.1 riastrad } 465 1.1 riastrad } 466 1.1 riastrad /* limit max tile */ 467 1.1 riastrad tmp = (height * pitch) >> 6; 468 1.1 riastrad if (tmp < slice_tile_max) 469 1.1 riastrad slice_tile_max = tmp; 470 1.1 riastrad tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | 471 1.1 riastrad S_028060_SLICE_TILE_MAX(slice_tile_max - 1); 472 1.1 riastrad ib[track->cb_color_size_idx[i]] = tmp; 473 1.1 riastrad 474 1.1 riastrad /* FMASK/CMASK */ 475 1.1 riastrad switch (G_0280A0_TILE_MODE(track->cb_color_info[i])) { 476 1.1 riastrad case V_0280A0_TILE_DISABLE: 477 1.1 riastrad break; 478 1.1 riastrad case V_0280A0_FRAG_ENABLE: 479 1.1 riastrad if (track->nsamples > 1) { 480 1.1 riastrad uint32_t tile_max = G_028100_FMASK_TILE_MAX(track->cb_color_mask[i]); 481 1.1 riastrad /* the tile size is 8x8, but the size is in units of bits. 482 1.1 riastrad * for bytes, do just * 8. */ 483 1.1 riastrad uint32_t bytes = track->nsamples * track->log_nsamples * 8 * (tile_max + 1); 484 1.1 riastrad 485 1.1 riastrad if (bytes + track->cb_color_frag_offset[i] > 486 1.1 riastrad radeon_bo_size(track->cb_color_frag_bo[i])) { 487 1.1 riastrad dev_warn(p->dev, "%s FMASK_TILE_MAX too large " 488 1.1 riastrad "(tile_max=%u, bytes=%u, offset=%"PRIu64", bo_size=%lu)\n", 489 1.1 riastrad __func__, tile_max, bytes, 490 1.1 riastrad track->cb_color_frag_offset[i], 491 1.1 riastrad radeon_bo_size(track->cb_color_frag_bo[i])); 492 1.1 riastrad return -EINVAL; 493 1.1 riastrad } 494 1.1 riastrad } 495 1.1 riastrad /* fall through */ 496 1.1 riastrad case V_0280A0_CLEAR_ENABLE: 497 1.1 riastrad { 498 1.1 riastrad uint32_t block_max = G_028100_CMASK_BLOCK_MAX(track->cb_color_mask[i]); 499 1.1 riastrad /* One block = 128x128 pixels, one 8x8 tile has 4 bits.. 500 1.1 riastrad * (128*128) / (8*8) / 2 = 128 bytes per block. */ 501 1.1 riastrad uint32_t bytes = (block_max + 1) * 128; 502 1.1 riastrad 503 1.1 riastrad if (bytes + track->cb_color_tile_offset[i] > 504 1.1 riastrad radeon_bo_size(track->cb_color_tile_bo[i])) { 505 1.1 riastrad dev_warn(p->dev, "%s CMASK_BLOCK_MAX too large " 506 1.1 riastrad "(block_max=%u, bytes=%u, offset=%"PRIu64", bo_size=%lu)\n", 507 1.1 riastrad __func__, block_max, bytes, 508 1.1 riastrad track->cb_color_tile_offset[i], 509 1.1 riastrad radeon_bo_size(track->cb_color_tile_bo[i])); 510 1.1 riastrad return -EINVAL; 511 1.1 riastrad } 512 1.1 riastrad break; 513 1.1 riastrad } 514 1.1 riastrad default: 515 1.1 riastrad dev_warn(p->dev, "%s invalid tile mode\n", __func__); 516 1.1 riastrad return -EINVAL; 517 1.1 riastrad } 518 1.1 riastrad return 0; 519 1.1 riastrad } 520 1.1 riastrad 521 1.1 riastrad static int r600_cs_track_validate_db(struct radeon_cs_parser *p) 522 1.1 riastrad { 523 1.1 riastrad struct r600_cs_track *track = p->track; 524 1.2 riastrad u32 nviews, bpe, ntiles, slice_tile_max, tmp; 525 1.1 riastrad u32 height_align, pitch_align, depth_align; 526 1.1 riastrad u32 pitch = 8192; 527 1.1 riastrad u32 height = 8192; 528 1.1 riastrad u64 base_offset, base_align; 529 1.1 riastrad struct array_mode_checker array_check; 530 1.1 riastrad int array_mode; 531 1.1 riastrad volatile u32 *ib = p->ib.ptr; 532 1.1 riastrad 533 1.1 riastrad 534 1.1 riastrad if (track->db_bo == NULL) { 535 1.1 riastrad dev_warn(p->dev, "z/stencil with no depth buffer\n"); 536 1.1 riastrad return -EINVAL; 537 1.1 riastrad } 538 1.1 riastrad switch (G_028010_FORMAT(track->db_depth_info)) { 539 1.1 riastrad case V_028010_DEPTH_16: 540 1.1 riastrad bpe = 2; 541 1.1 riastrad break; 542 1.1 riastrad case V_028010_DEPTH_X8_24: 543 1.1 riastrad case V_028010_DEPTH_8_24: 544 1.1 riastrad case V_028010_DEPTH_X8_24_FLOAT: 545 1.1 riastrad case V_028010_DEPTH_8_24_FLOAT: 546 1.1 riastrad case V_028010_DEPTH_32_FLOAT: 547 1.1 riastrad bpe = 4; 548 1.1 riastrad break; 549 1.1 riastrad case V_028010_DEPTH_X24_8_32_FLOAT: 550 1.1 riastrad bpe = 8; 551 1.1 riastrad break; 552 1.1 riastrad default: 553 1.1 riastrad dev_warn(p->dev, "z/stencil with invalid format %d\n", G_028010_FORMAT(track->db_depth_info)); 554 1.1 riastrad return -EINVAL; 555 1.1 riastrad } 556 1.1 riastrad if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { 557 1.1 riastrad if (!track->db_depth_size_idx) { 558 1.1 riastrad dev_warn(p->dev, "z/stencil buffer size not set\n"); 559 1.1 riastrad return -EINVAL; 560 1.1 riastrad } 561 1.1 riastrad tmp = radeon_bo_size(track->db_bo) - track->db_offset; 562 1.1 riastrad tmp = (tmp / bpe) >> 6; 563 1.1 riastrad if (!tmp) { 564 1.1 riastrad dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %ld)\n", 565 1.1 riastrad track->db_depth_size, bpe, track->db_offset, 566 1.1 riastrad radeon_bo_size(track->db_bo)); 567 1.1 riastrad return -EINVAL; 568 1.1 riastrad } 569 1.1 riastrad ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); 570 1.1 riastrad } else { 571 1.1 riastrad /* pitch in pixels */ 572 1.1 riastrad pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; 573 1.1 riastrad slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; 574 1.1 riastrad slice_tile_max *= 64; 575 1.1 riastrad height = slice_tile_max / pitch; 576 1.1 riastrad if (height > 8192) 577 1.1 riastrad height = 8192; 578 1.1 riastrad base_offset = track->db_bo_mc + track->db_offset; 579 1.1 riastrad array_mode = G_028010_ARRAY_MODE(track->db_depth_info); 580 1.1 riastrad array_check.array_mode = array_mode; 581 1.1 riastrad array_check.group_size = track->group_size; 582 1.1 riastrad array_check.nbanks = track->nbanks; 583 1.1 riastrad array_check.npipes = track->npipes; 584 1.1 riastrad array_check.nsamples = track->nsamples; 585 1.1 riastrad array_check.blocksize = bpe; 586 1.1 riastrad if (r600_get_array_mode_alignment(&array_check, 587 1.1 riastrad &pitch_align, &height_align, &depth_align, &base_align)) { 588 1.1 riastrad dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, 589 1.1 riastrad G_028010_ARRAY_MODE(track->db_depth_info), 590 1.1 riastrad track->db_depth_info); 591 1.1 riastrad return -EINVAL; 592 1.1 riastrad } 593 1.1 riastrad switch (array_mode) { 594 1.1 riastrad case V_028010_ARRAY_1D_TILED_THIN1: 595 1.1 riastrad /* don't break userspace */ 596 1.1 riastrad height &= ~0x7; 597 1.1 riastrad break; 598 1.1 riastrad case V_028010_ARRAY_2D_TILED_THIN1: 599 1.1 riastrad break; 600 1.1 riastrad default: 601 1.1 riastrad dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, 602 1.1 riastrad G_028010_ARRAY_MODE(track->db_depth_info), 603 1.1 riastrad track->db_depth_info); 604 1.1 riastrad return -EINVAL; 605 1.1 riastrad } 606 1.1 riastrad 607 1.1 riastrad if (!IS_ALIGNED(pitch, pitch_align)) { 608 1.1 riastrad dev_warn(p->dev, "%s:%d db pitch (%d, 0x%x, %d) invalid\n", 609 1.1 riastrad __func__, __LINE__, pitch, pitch_align, array_mode); 610 1.1 riastrad return -EINVAL; 611 1.1 riastrad } 612 1.1 riastrad if (!IS_ALIGNED(height, height_align)) { 613 1.1 riastrad dev_warn(p->dev, "%s:%d db height (%d, 0x%x, %d) invalid\n", 614 1.1 riastrad __func__, __LINE__, height, height_align, array_mode); 615 1.1 riastrad return -EINVAL; 616 1.1 riastrad } 617 1.1 riastrad if (!IS_ALIGNED(base_offset, base_align)) { 618 1.1 riastrad dev_warn(p->dev, "%s offset 0x%"PRIx64", 0x%"PRIx64", %d not aligned\n", __func__, 619 1.1 riastrad base_offset, base_align, array_mode); 620 1.1 riastrad return -EINVAL; 621 1.1 riastrad } 622 1.1 riastrad 623 1.1 riastrad ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; 624 1.1 riastrad nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; 625 1.1 riastrad tmp = ntiles * bpe * 64 * nviews * track->nsamples; 626 1.1 riastrad if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { 627 1.1 riastrad dev_warn(p->dev, "z/stencil buffer (%d) too small (0x%08X %d %d %d -> %u have %lu)\n", 628 1.1 riastrad array_mode, 629 1.1 riastrad track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, 630 1.1 riastrad radeon_bo_size(track->db_bo)); 631 1.1 riastrad return -EINVAL; 632 1.1 riastrad } 633 1.1 riastrad } 634 1.1 riastrad 635 1.1 riastrad /* hyperz */ 636 1.1 riastrad if (G_028010_TILE_SURFACE_ENABLE(track->db_depth_info)) { 637 1.1 riastrad unsigned long size; 638 1.1 riastrad unsigned nbx, nby; 639 1.1 riastrad 640 1.1 riastrad if (track->htile_bo == NULL) { 641 1.1 riastrad dev_warn(p->dev, "%s:%d htile enabled without htile surface 0x%08x\n", 642 1.1 riastrad __func__, __LINE__, track->db_depth_info); 643 1.1 riastrad return -EINVAL; 644 1.1 riastrad } 645 1.1 riastrad if ((track->db_depth_size & 0xFFFFFC00) == 0xFFFFFC00) { 646 1.1 riastrad dev_warn(p->dev, "%s:%d htile can't be enabled with bogus db_depth_size 0x%08x\n", 647 1.1 riastrad __func__, __LINE__, track->db_depth_size); 648 1.1 riastrad return -EINVAL; 649 1.1 riastrad } 650 1.1 riastrad 651 1.1 riastrad nbx = pitch; 652 1.1 riastrad nby = height; 653 1.1 riastrad if (G_028D24_LINEAR(track->htile_surface)) { 654 1.1 riastrad /* nbx must be 16 htiles aligned == 16 * 8 pixel aligned */ 655 1.1 riastrad nbx = round_up(nbx, 16 * 8); 656 1.1 riastrad /* nby is npipes htiles aligned == npipes * 8 pixel aligned */ 657 1.1 riastrad nby = round_up(nby, track->npipes * 8); 658 1.1 riastrad } else { 659 1.1 riastrad /* always assume 8x8 htile */ 660 1.1 riastrad /* align is htile align * 8, htile align vary according to 661 1.1 riastrad * number of pipe and tile width and nby 662 1.1 riastrad */ 663 1.1 riastrad switch (track->npipes) { 664 1.1 riastrad case 8: 665 1.1 riastrad /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ 666 1.1 riastrad nbx = round_up(nbx, 64 * 8); 667 1.1 riastrad nby = round_up(nby, 64 * 8); 668 1.1 riastrad break; 669 1.1 riastrad case 4: 670 1.1 riastrad /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ 671 1.1 riastrad nbx = round_up(nbx, 64 * 8); 672 1.1 riastrad nby = round_up(nby, 32 * 8); 673 1.1 riastrad break; 674 1.1 riastrad case 2: 675 1.1 riastrad /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ 676 1.1 riastrad nbx = round_up(nbx, 32 * 8); 677 1.1 riastrad nby = round_up(nby, 32 * 8); 678 1.1 riastrad break; 679 1.1 riastrad case 1: 680 1.1 riastrad /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/ 681 1.1 riastrad nbx = round_up(nbx, 32 * 8); 682 1.1 riastrad nby = round_up(nby, 16 * 8); 683 1.1 riastrad break; 684 1.1 riastrad default: 685 1.1 riastrad dev_warn(p->dev, "%s:%d invalid num pipes %d\n", 686 1.1 riastrad __func__, __LINE__, track->npipes); 687 1.1 riastrad return -EINVAL; 688 1.1 riastrad } 689 1.1 riastrad } 690 1.1 riastrad /* compute number of htile */ 691 1.1 riastrad nbx = nbx >> 3; 692 1.1 riastrad nby = nby >> 3; 693 1.1 riastrad /* size must be aligned on npipes * 2K boundary */ 694 1.1 riastrad size = roundup(nbx * nby * 4, track->npipes * (2 << 10)); 695 1.1 riastrad size += track->htile_offset; 696 1.1 riastrad 697 1.1 riastrad if (size > radeon_bo_size(track->htile_bo)) { 698 1.1 riastrad dev_warn(p->dev, "%s:%d htile surface too small %ld for %ld (%d %d)\n", 699 1.1 riastrad __func__, __LINE__, radeon_bo_size(track->htile_bo), 700 1.1 riastrad size, nbx, nby); 701 1.1 riastrad return -EINVAL; 702 1.1 riastrad } 703 1.1 riastrad } 704 1.1 riastrad 705 1.1 riastrad track->db_dirty = false; 706 1.1 riastrad return 0; 707 1.1 riastrad } 708 1.1 riastrad 709 1.1 riastrad static int r600_cs_track_check(struct radeon_cs_parser *p) 710 1.1 riastrad { 711 1.1 riastrad struct r600_cs_track *track = p->track; 712 1.1 riastrad u32 tmp; 713 1.1 riastrad int r, i; 714 1.1 riastrad 715 1.1 riastrad /* on legacy kernel we don't perform advanced check */ 716 1.1 riastrad if (p->rdev == NULL) 717 1.1 riastrad return 0; 718 1.1 riastrad 719 1.1 riastrad /* check streamout */ 720 1.1 riastrad if (track->streamout_dirty && track->vgt_strmout_en) { 721 1.1 riastrad for (i = 0; i < 4; i++) { 722 1.1 riastrad if (track->vgt_strmout_buffer_en & (1 << i)) { 723 1.1 riastrad if (track->vgt_strmout_bo[i]) { 724 1.1 riastrad u64 offset = (u64)track->vgt_strmout_bo_offset[i] + 725 1.1 riastrad (u64)track->vgt_strmout_size[i]; 726 1.1 riastrad if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) { 727 1.1 riastrad DRM_ERROR("streamout %d bo too small: 0x%"PRIx64", 0x%lx\n", 728 1.1 riastrad i, offset, 729 1.1 riastrad radeon_bo_size(track->vgt_strmout_bo[i])); 730 1.1 riastrad return -EINVAL; 731 1.1 riastrad } 732 1.1 riastrad } else { 733 1.1 riastrad dev_warn(p->dev, "No buffer for streamout %d\n", i); 734 1.1 riastrad return -EINVAL; 735 1.1 riastrad } 736 1.1 riastrad } 737 1.1 riastrad } 738 1.1 riastrad track->streamout_dirty = false; 739 1.1 riastrad } 740 1.1 riastrad 741 1.1 riastrad if (track->sx_misc_kill_all_prims) 742 1.1 riastrad return 0; 743 1.1 riastrad 744 1.1 riastrad /* check that we have a cb for each enabled target, we don't check 745 1.1 riastrad * shader_mask because it seems mesa isn't always setting it :( 746 1.1 riastrad */ 747 1.1 riastrad if (track->cb_dirty) { 748 1.1 riastrad tmp = track->cb_target_mask; 749 1.1 riastrad 750 1.1 riastrad /* We must check both colorbuffers for RESOLVE. */ 751 1.1 riastrad if (track->is_resolve) { 752 1.1 riastrad tmp |= 0xff; 753 1.1 riastrad } 754 1.1 riastrad 755 1.1 riastrad for (i = 0; i < 8; i++) { 756 1.1 riastrad u32 format = G_0280A0_FORMAT(track->cb_color_info[i]); 757 1.1 riastrad 758 1.1 riastrad if (format != V_0280A0_COLOR_INVALID && 759 1.1 riastrad (tmp >> (i * 4)) & 0xF) { 760 1.1 riastrad /* at least one component is enabled */ 761 1.1 riastrad if (track->cb_color_bo[i] == NULL) { 762 1.1 riastrad dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n", 763 1.1 riastrad __func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i); 764 1.1 riastrad return -EINVAL; 765 1.1 riastrad } 766 1.1 riastrad /* perform rewrite of CB_COLOR[0-7]_SIZE */ 767 1.1 riastrad r = r600_cs_track_validate_cb(p, i); 768 1.1 riastrad if (r) 769 1.1 riastrad return r; 770 1.1 riastrad } 771 1.1 riastrad } 772 1.1 riastrad track->cb_dirty = false; 773 1.1 riastrad } 774 1.1 riastrad 775 1.1 riastrad /* Check depth buffer */ 776 1.1 riastrad if (track->db_dirty && 777 1.1 riastrad G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && 778 1.1 riastrad (G_028800_STENCIL_ENABLE(track->db_depth_control) || 779 1.1 riastrad G_028800_Z_ENABLE(track->db_depth_control))) { 780 1.1 riastrad r = r600_cs_track_validate_db(p); 781 1.1 riastrad if (r) 782 1.1 riastrad return r; 783 1.1 riastrad } 784 1.1 riastrad 785 1.1 riastrad return 0; 786 1.1 riastrad } 787 1.1 riastrad 788 1.1 riastrad /** 789 1.1 riastrad * r600_cs_packet_parse_vline() - parse userspace VLINE packet 790 1.1 riastrad * @parser: parser structure holding parsing context. 791 1.1 riastrad * 792 1.1 riastrad * This is an R600-specific function for parsing VLINE packets. 793 1.1 riastrad * Real work is done by r600_cs_common_vline_parse function. 794 1.1 riastrad * Here we just set up ASIC-specific register table and call 795 1.1 riastrad * the common implementation function. 796 1.1 riastrad */ 797 1.1 riastrad static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) 798 1.1 riastrad { 799 1.1 riastrad static uint32_t vline_start_end[2] = {AVIVO_D1MODE_VLINE_START_END, 800 1.1 riastrad AVIVO_D2MODE_VLINE_START_END}; 801 1.1 riastrad static uint32_t vline_status[2] = {AVIVO_D1MODE_VLINE_STATUS, 802 1.1 riastrad AVIVO_D2MODE_VLINE_STATUS}; 803 1.1 riastrad 804 1.1 riastrad return r600_cs_common_vline_parse(p, vline_start_end, vline_status); 805 1.1 riastrad } 806 1.1 riastrad 807 1.1 riastrad /** 808 1.1 riastrad * r600_cs_common_vline_parse() - common vline parser 809 1.1 riastrad * @parser: parser structure holding parsing context. 810 1.1 riastrad * @vline_start_end: table of vline_start_end registers 811 1.1 riastrad * @vline_status: table of vline_status registers 812 1.1 riastrad * 813 1.1 riastrad * Userspace sends a special sequence for VLINE waits. 814 1.1 riastrad * PACKET0 - VLINE_START_END + value 815 1.1 riastrad * PACKET3 - WAIT_REG_MEM poll vline status reg 816 1.1 riastrad * RELOC (P3) - crtc_id in reloc. 817 1.1 riastrad * 818 1.1 riastrad * This function parses this and relocates the VLINE START END 819 1.1 riastrad * and WAIT_REG_MEM packets to the correct crtc. 820 1.1 riastrad * It also detects a switched off crtc and nulls out the 821 1.1 riastrad * wait in that case. This function is common for all ASICs that 822 1.1 riastrad * are R600 and newer. The parsing algorithm is the same, and only 823 1.1 riastrad * differs in which registers are used. 824 1.1 riastrad * 825 1.1 riastrad * Caller is the ASIC-specific function which passes the parser 826 1.1 riastrad * context and ASIC-specific register table 827 1.1 riastrad */ 828 1.1 riastrad int r600_cs_common_vline_parse(struct radeon_cs_parser *p, 829 1.1 riastrad uint32_t *vline_start_end, 830 1.1 riastrad uint32_t *vline_status) 831 1.1 riastrad { 832 1.1 riastrad struct drm_crtc *crtc; 833 1.1 riastrad struct radeon_crtc *radeon_crtc; 834 1.1 riastrad struct radeon_cs_packet p3reloc, wait_reg_mem; 835 1.1 riastrad int crtc_id; 836 1.1 riastrad int r; 837 1.1 riastrad uint32_t header, h_idx, reg, wait_reg_mem_info; 838 1.1 riastrad volatile uint32_t *ib; 839 1.1 riastrad 840 1.1 riastrad ib = p->ib.ptr; 841 1.1 riastrad 842 1.1 riastrad /* parse the WAIT_REG_MEM */ 843 1.1 riastrad r = radeon_cs_packet_parse(p, &wait_reg_mem, p->idx); 844 1.1 riastrad if (r) 845 1.1 riastrad return r; 846 1.1 riastrad 847 1.1 riastrad /* check its a WAIT_REG_MEM */ 848 1.1 riastrad if (wait_reg_mem.type != RADEON_PACKET_TYPE3 || 849 1.1 riastrad wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { 850 1.1 riastrad DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); 851 1.1 riastrad return -EINVAL; 852 1.1 riastrad } 853 1.1 riastrad 854 1.1 riastrad wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); 855 1.1 riastrad /* bit 4 is reg (0) or mem (1) */ 856 1.1 riastrad if (wait_reg_mem_info & 0x10) { 857 1.1 riastrad DRM_ERROR("vline WAIT_REG_MEM waiting on MEM instead of REG\n"); 858 1.1 riastrad return -EINVAL; 859 1.1 riastrad } 860 1.1 riastrad /* bit 8 is me (0) or pfp (1) */ 861 1.1 riastrad if (wait_reg_mem_info & 0x100) { 862 1.1 riastrad DRM_ERROR("vline WAIT_REG_MEM waiting on PFP instead of ME\n"); 863 1.1 riastrad return -EINVAL; 864 1.1 riastrad } 865 1.1 riastrad /* waiting for value to be equal */ 866 1.1 riastrad if ((wait_reg_mem_info & 0x7) != 0x3) { 867 1.1 riastrad DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); 868 1.1 riastrad return -EINVAL; 869 1.1 riastrad } 870 1.1 riastrad if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != vline_status[0]) { 871 1.1 riastrad DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); 872 1.1 riastrad return -EINVAL; 873 1.1 riastrad } 874 1.1 riastrad 875 1.1 riastrad if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != RADEON_VLINE_STAT) { 876 1.1 riastrad DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); 877 1.1 riastrad return -EINVAL; 878 1.1 riastrad } 879 1.1 riastrad 880 1.1 riastrad /* jump over the NOP */ 881 1.1 riastrad r = radeon_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); 882 1.1 riastrad if (r) 883 1.1 riastrad return r; 884 1.1 riastrad 885 1.1 riastrad h_idx = p->idx - 2; 886 1.1 riastrad p->idx += wait_reg_mem.count + 2; 887 1.1 riastrad p->idx += p3reloc.count + 2; 888 1.1 riastrad 889 1.1 riastrad header = radeon_get_ib_value(p, h_idx); 890 1.1 riastrad crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); 891 1.1 riastrad reg = R600_CP_PACKET0_GET_REG(header); 892 1.1 riastrad 893 1.2 riastrad crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id); 894 1.1 riastrad if (!crtc) { 895 1.1 riastrad DRM_ERROR("cannot find crtc %d\n", crtc_id); 896 1.1 riastrad return -ENOENT; 897 1.1 riastrad } 898 1.1 riastrad radeon_crtc = to_radeon_crtc(crtc); 899 1.1 riastrad crtc_id = radeon_crtc->crtc_id; 900 1.1 riastrad 901 1.1 riastrad if (!crtc->enabled) { 902 1.1 riastrad /* CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ 903 1.1 riastrad ib[h_idx + 2] = PACKET2(0); 904 1.1 riastrad ib[h_idx + 3] = PACKET2(0); 905 1.1 riastrad ib[h_idx + 4] = PACKET2(0); 906 1.1 riastrad ib[h_idx + 5] = PACKET2(0); 907 1.1 riastrad ib[h_idx + 6] = PACKET2(0); 908 1.1 riastrad ib[h_idx + 7] = PACKET2(0); 909 1.1 riastrad ib[h_idx + 8] = PACKET2(0); 910 1.1 riastrad } else if (reg == vline_start_end[0]) { 911 1.1 riastrad header &= ~R600_CP_PACKET0_REG_MASK; 912 1.1 riastrad header |= vline_start_end[crtc_id] >> 2; 913 1.1 riastrad ib[h_idx] = header; 914 1.1 riastrad ib[h_idx + 4] = vline_status[crtc_id] >> 2; 915 1.1 riastrad } else { 916 1.1 riastrad DRM_ERROR("unknown crtc reloc\n"); 917 1.1 riastrad return -EINVAL; 918 1.1 riastrad } 919 1.1 riastrad return 0; 920 1.1 riastrad } 921 1.1 riastrad 922 1.1 riastrad static int r600_packet0_check(struct radeon_cs_parser *p, 923 1.1 riastrad struct radeon_cs_packet *pkt, 924 1.1 riastrad unsigned idx, unsigned reg) 925 1.1 riastrad { 926 1.1 riastrad int r; 927 1.1 riastrad 928 1.1 riastrad switch (reg) { 929 1.1 riastrad case AVIVO_D1MODE_VLINE_START_END: 930 1.1 riastrad r = r600_cs_packet_parse_vline(p); 931 1.1 riastrad if (r) { 932 1.1 riastrad DRM_ERROR("No reloc for ib[%d]=0x%04X\n", 933 1.1 riastrad idx, reg); 934 1.1 riastrad return r; 935 1.1 riastrad } 936 1.1 riastrad break; 937 1.1 riastrad default: 938 1.2 riastrad pr_err("Forbidden register 0x%04X in cs at %d\n", reg, idx); 939 1.1 riastrad return -EINVAL; 940 1.1 riastrad } 941 1.1 riastrad return 0; 942 1.1 riastrad } 943 1.1 riastrad 944 1.1 riastrad static int r600_cs_parse_packet0(struct radeon_cs_parser *p, 945 1.1 riastrad struct radeon_cs_packet *pkt) 946 1.1 riastrad { 947 1.1 riastrad unsigned reg, i; 948 1.1 riastrad unsigned idx; 949 1.1 riastrad int r; 950 1.1 riastrad 951 1.1 riastrad idx = pkt->idx + 1; 952 1.1 riastrad reg = pkt->reg; 953 1.1 riastrad for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { 954 1.1 riastrad r = r600_packet0_check(p, pkt, idx, reg); 955 1.1 riastrad if (r) { 956 1.1 riastrad return r; 957 1.1 riastrad } 958 1.1 riastrad } 959 1.1 riastrad return 0; 960 1.1 riastrad } 961 1.1 riastrad 962 1.1 riastrad /** 963 1.1 riastrad * r600_cs_check_reg() - check if register is authorized or not 964 1.1 riastrad * @parser: parser structure holding parsing context 965 1.1 riastrad * @reg: register we are testing 966 1.1 riastrad * @idx: index into the cs buffer 967 1.1 riastrad * 968 1.1 riastrad * This function will test against r600_reg_safe_bm and return 0 969 1.1 riastrad * if register is safe. If register is not flag as safe this function 970 1.1 riastrad * will test it against a list of register needind special handling. 971 1.1 riastrad */ 972 1.1 riastrad static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) 973 1.1 riastrad { 974 1.1 riastrad struct r600_cs_track *track = (struct r600_cs_track *)p->track; 975 1.1 riastrad struct radeon_bo_list *reloc; 976 1.1 riastrad u32 m, i, tmp, *ib; 977 1.1 riastrad int r; 978 1.1 riastrad 979 1.1 riastrad i = (reg >> 7); 980 1.1 riastrad if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { 981 1.1 riastrad dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); 982 1.1 riastrad return -EINVAL; 983 1.1 riastrad } 984 1.1 riastrad m = 1 << ((reg >> 2) & 31); 985 1.1 riastrad if (!(r600_reg_safe_bm[i] & m)) 986 1.1 riastrad return 0; 987 1.1 riastrad ib = p->ib.ptr; 988 1.1 riastrad switch (reg) { 989 1.1 riastrad /* force following reg to 0 in an attempt to disable out buffer 990 1.1 riastrad * which will need us to better understand how it works to perform 991 1.1 riastrad * security check on it (Jerome) 992 1.1 riastrad */ 993 1.1 riastrad case R_0288A8_SQ_ESGS_RING_ITEMSIZE: 994 1.1 riastrad case R_008C44_SQ_ESGS_RING_SIZE: 995 1.1 riastrad case R_0288B0_SQ_ESTMP_RING_ITEMSIZE: 996 1.1 riastrad case R_008C54_SQ_ESTMP_RING_SIZE: 997 1.1 riastrad case R_0288C0_SQ_FBUF_RING_ITEMSIZE: 998 1.1 riastrad case R_008C74_SQ_FBUF_RING_SIZE: 999 1.1 riastrad case R_0288B4_SQ_GSTMP_RING_ITEMSIZE: 1000 1.1 riastrad case R_008C5C_SQ_GSTMP_RING_SIZE: 1001 1.1 riastrad case R_0288AC_SQ_GSVS_RING_ITEMSIZE: 1002 1.1 riastrad case R_008C4C_SQ_GSVS_RING_SIZE: 1003 1.1 riastrad case R_0288BC_SQ_PSTMP_RING_ITEMSIZE: 1004 1.1 riastrad case R_008C6C_SQ_PSTMP_RING_SIZE: 1005 1.1 riastrad case R_0288C4_SQ_REDUC_RING_ITEMSIZE: 1006 1.1 riastrad case R_008C7C_SQ_REDUC_RING_SIZE: 1007 1.1 riastrad case R_0288B8_SQ_VSTMP_RING_ITEMSIZE: 1008 1.1 riastrad case R_008C64_SQ_VSTMP_RING_SIZE: 1009 1.1 riastrad case R_0288C8_SQ_GS_VERT_ITEMSIZE: 1010 1.1 riastrad /* get value to populate the IB don't remove */ 1011 1.1 riastrad /*tmp =radeon_get_ib_value(p, idx); 1012 1.1 riastrad ib[idx] = 0;*/ 1013 1.1 riastrad break; 1014 1.1 riastrad case SQ_ESGS_RING_BASE: 1015 1.1 riastrad case SQ_GSVS_RING_BASE: 1016 1.1 riastrad case SQ_ESTMP_RING_BASE: 1017 1.1 riastrad case SQ_GSTMP_RING_BASE: 1018 1.1 riastrad case SQ_PSTMP_RING_BASE: 1019 1.1 riastrad case SQ_VSTMP_RING_BASE: 1020 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, 0); 1021 1.1 riastrad if (r) { 1022 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1023 1.1 riastrad "0x%04X\n", reg); 1024 1.1 riastrad return -EINVAL; 1025 1.1 riastrad } 1026 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1027 1.1 riastrad break; 1028 1.1 riastrad case SQ_CONFIG: 1029 1.1 riastrad track->sq_config = radeon_get_ib_value(p, idx); 1030 1.1 riastrad break; 1031 1.1 riastrad case R_028800_DB_DEPTH_CONTROL: 1032 1.1 riastrad track->db_depth_control = radeon_get_ib_value(p, idx); 1033 1.1 riastrad track->db_dirty = true; 1034 1.1 riastrad break; 1035 1.1 riastrad case R_028010_DB_DEPTH_INFO: 1036 1.1 riastrad if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && 1037 1.1 riastrad radeon_cs_packet_next_is_pkt3_nop(p)) { 1038 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1039 1.1 riastrad if (r) { 1040 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1041 1.1 riastrad "0x%04X\n", reg); 1042 1.1 riastrad return -EINVAL; 1043 1.1 riastrad } 1044 1.1 riastrad track->db_depth_info = radeon_get_ib_value(p, idx); 1045 1.1 riastrad ib[idx] &= C_028010_ARRAY_MODE; 1046 1.1 riastrad track->db_depth_info &= C_028010_ARRAY_MODE; 1047 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MACRO) { 1048 1.1 riastrad ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); 1049 1.1 riastrad track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_2D_TILED_THIN1); 1050 1.1 riastrad } else { 1051 1.1 riastrad ib[idx] |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); 1052 1.1 riastrad track->db_depth_info |= S_028010_ARRAY_MODE(V_028010_ARRAY_1D_TILED_THIN1); 1053 1.1 riastrad } 1054 1.1 riastrad } else { 1055 1.1 riastrad track->db_depth_info = radeon_get_ib_value(p, idx); 1056 1.1 riastrad } 1057 1.1 riastrad track->db_dirty = true; 1058 1.1 riastrad break; 1059 1.1 riastrad case R_028004_DB_DEPTH_VIEW: 1060 1.1 riastrad track->db_depth_view = radeon_get_ib_value(p, idx); 1061 1.1 riastrad track->db_dirty = true; 1062 1.1 riastrad break; 1063 1.1 riastrad case R_028000_DB_DEPTH_SIZE: 1064 1.1 riastrad track->db_depth_size = radeon_get_ib_value(p, idx); 1065 1.1 riastrad track->db_depth_size_idx = idx; 1066 1.1 riastrad track->db_dirty = true; 1067 1.1 riastrad break; 1068 1.1 riastrad case R_028AB0_VGT_STRMOUT_EN: 1069 1.1 riastrad track->vgt_strmout_en = radeon_get_ib_value(p, idx); 1070 1.1 riastrad track->streamout_dirty = true; 1071 1.1 riastrad break; 1072 1.1 riastrad case R_028B20_VGT_STRMOUT_BUFFER_EN: 1073 1.1 riastrad track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx); 1074 1.1 riastrad track->streamout_dirty = true; 1075 1.1 riastrad break; 1076 1.1 riastrad case VGT_STRMOUT_BUFFER_BASE_0: 1077 1.1 riastrad case VGT_STRMOUT_BUFFER_BASE_1: 1078 1.1 riastrad case VGT_STRMOUT_BUFFER_BASE_2: 1079 1.1 riastrad case VGT_STRMOUT_BUFFER_BASE_3: 1080 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1081 1.1 riastrad if (r) { 1082 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1083 1.1 riastrad "0x%04X\n", reg); 1084 1.1 riastrad return -EINVAL; 1085 1.1 riastrad } 1086 1.1 riastrad tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16; 1087 1.1 riastrad track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; 1088 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1089 1.1 riastrad track->vgt_strmout_bo[tmp] = reloc->robj; 1090 1.1 riastrad track->vgt_strmout_bo_mc[tmp] = reloc->gpu_offset; 1091 1.1 riastrad track->streamout_dirty = true; 1092 1.1 riastrad break; 1093 1.1 riastrad case VGT_STRMOUT_BUFFER_SIZE_0: 1094 1.1 riastrad case VGT_STRMOUT_BUFFER_SIZE_1: 1095 1.1 riastrad case VGT_STRMOUT_BUFFER_SIZE_2: 1096 1.1 riastrad case VGT_STRMOUT_BUFFER_SIZE_3: 1097 1.1 riastrad tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16; 1098 1.1 riastrad /* size in register is DWs, convert to bytes */ 1099 1.1 riastrad track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4; 1100 1.1 riastrad track->streamout_dirty = true; 1101 1.1 riastrad break; 1102 1.1 riastrad case CP_COHER_BASE: 1103 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1104 1.1 riastrad if (r) { 1105 1.1 riastrad dev_warn(p->dev, "missing reloc for CP_COHER_BASE " 1106 1.1 riastrad "0x%04X\n", reg); 1107 1.1 riastrad return -EINVAL; 1108 1.1 riastrad } 1109 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1110 1.1 riastrad break; 1111 1.1 riastrad case R_028238_CB_TARGET_MASK: 1112 1.1 riastrad track->cb_target_mask = radeon_get_ib_value(p, idx); 1113 1.1 riastrad track->cb_dirty = true; 1114 1.1 riastrad break; 1115 1.1 riastrad case R_02823C_CB_SHADER_MASK: 1116 1.1 riastrad track->cb_shader_mask = radeon_get_ib_value(p, idx); 1117 1.1 riastrad break; 1118 1.1 riastrad case R_028C04_PA_SC_AA_CONFIG: 1119 1.1 riastrad tmp = G_028C04_MSAA_NUM_SAMPLES(radeon_get_ib_value(p, idx)); 1120 1.1 riastrad track->log_nsamples = tmp; 1121 1.1 riastrad track->nsamples = 1 << tmp; 1122 1.1 riastrad track->cb_dirty = true; 1123 1.1 riastrad break; 1124 1.1 riastrad case R_028808_CB_COLOR_CONTROL: 1125 1.1 riastrad tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx)); 1126 1.1 riastrad track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX; 1127 1.1 riastrad track->cb_dirty = true; 1128 1.1 riastrad break; 1129 1.1 riastrad case R_0280A0_CB_COLOR0_INFO: 1130 1.1 riastrad case R_0280A4_CB_COLOR1_INFO: 1131 1.1 riastrad case R_0280A8_CB_COLOR2_INFO: 1132 1.1 riastrad case R_0280AC_CB_COLOR3_INFO: 1133 1.1 riastrad case R_0280B0_CB_COLOR4_INFO: 1134 1.1 riastrad case R_0280B4_CB_COLOR5_INFO: 1135 1.1 riastrad case R_0280B8_CB_COLOR6_INFO: 1136 1.1 riastrad case R_0280BC_CB_COLOR7_INFO: 1137 1.1 riastrad if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && 1138 1.1 riastrad radeon_cs_packet_next_is_pkt3_nop(p)) { 1139 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1140 1.1 riastrad if (r) { 1141 1.1 riastrad dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); 1142 1.1 riastrad return -EINVAL; 1143 1.1 riastrad } 1144 1.1 riastrad tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; 1145 1.1 riastrad track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); 1146 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MACRO) { 1147 1.1 riastrad ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); 1148 1.1 riastrad track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_2D_TILED_THIN1); 1149 1.1 riastrad } else if (reloc->tiling_flags & RADEON_TILING_MICRO) { 1150 1.1 riastrad ib[idx] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); 1151 1.1 riastrad track->cb_color_info[tmp] |= S_0280A0_ARRAY_MODE(V_0280A0_ARRAY_1D_TILED_THIN1); 1152 1.1 riastrad } 1153 1.1 riastrad } else { 1154 1.1 riastrad tmp = (reg - R_0280A0_CB_COLOR0_INFO) / 4; 1155 1.1 riastrad track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); 1156 1.1 riastrad } 1157 1.1 riastrad track->cb_dirty = true; 1158 1.1 riastrad break; 1159 1.1 riastrad case R_028080_CB_COLOR0_VIEW: 1160 1.1 riastrad case R_028084_CB_COLOR1_VIEW: 1161 1.1 riastrad case R_028088_CB_COLOR2_VIEW: 1162 1.1 riastrad case R_02808C_CB_COLOR3_VIEW: 1163 1.1 riastrad case R_028090_CB_COLOR4_VIEW: 1164 1.1 riastrad case R_028094_CB_COLOR5_VIEW: 1165 1.1 riastrad case R_028098_CB_COLOR6_VIEW: 1166 1.1 riastrad case R_02809C_CB_COLOR7_VIEW: 1167 1.1 riastrad tmp = (reg - R_028080_CB_COLOR0_VIEW) / 4; 1168 1.1 riastrad track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); 1169 1.1 riastrad track->cb_dirty = true; 1170 1.1 riastrad break; 1171 1.1 riastrad case R_028060_CB_COLOR0_SIZE: 1172 1.1 riastrad case R_028064_CB_COLOR1_SIZE: 1173 1.1 riastrad case R_028068_CB_COLOR2_SIZE: 1174 1.1 riastrad case R_02806C_CB_COLOR3_SIZE: 1175 1.1 riastrad case R_028070_CB_COLOR4_SIZE: 1176 1.1 riastrad case R_028074_CB_COLOR5_SIZE: 1177 1.1 riastrad case R_028078_CB_COLOR6_SIZE: 1178 1.1 riastrad case R_02807C_CB_COLOR7_SIZE: 1179 1.1 riastrad tmp = (reg - R_028060_CB_COLOR0_SIZE) / 4; 1180 1.1 riastrad track->cb_color_size[tmp] = radeon_get_ib_value(p, idx); 1181 1.1 riastrad track->cb_color_size_idx[tmp] = idx; 1182 1.1 riastrad track->cb_dirty = true; 1183 1.1 riastrad break; 1184 1.1 riastrad /* This register were added late, there is userspace 1185 1.1 riastrad * which does provide relocation for those but set 1186 1.1 riastrad * 0 offset. In order to avoid breaking old userspace 1187 1.1 riastrad * we detect this and set address to point to last 1188 1.1 riastrad * CB_COLOR0_BASE, note that if userspace doesn't set 1189 1.1 riastrad * CB_COLOR0_BASE before this register we will report 1190 1.1 riastrad * error. Old userspace always set CB_COLOR0_BASE 1191 1.1 riastrad * before any of this. 1192 1.1 riastrad */ 1193 1.1 riastrad case R_0280E0_CB_COLOR0_FRAG: 1194 1.1 riastrad case R_0280E4_CB_COLOR1_FRAG: 1195 1.1 riastrad case R_0280E8_CB_COLOR2_FRAG: 1196 1.1 riastrad case R_0280EC_CB_COLOR3_FRAG: 1197 1.1 riastrad case R_0280F0_CB_COLOR4_FRAG: 1198 1.1 riastrad case R_0280F4_CB_COLOR5_FRAG: 1199 1.1 riastrad case R_0280F8_CB_COLOR6_FRAG: 1200 1.1 riastrad case R_0280FC_CB_COLOR7_FRAG: 1201 1.1 riastrad tmp = (reg - R_0280E0_CB_COLOR0_FRAG) / 4; 1202 1.1 riastrad if (!radeon_cs_packet_next_is_pkt3_nop(p)) { 1203 1.1 riastrad if (!track->cb_color_base_last[tmp]) { 1204 1.1 riastrad dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); 1205 1.1 riastrad return -EINVAL; 1206 1.1 riastrad } 1207 1.1 riastrad track->cb_color_frag_bo[tmp] = track->cb_color_bo[tmp]; 1208 1.1 riastrad track->cb_color_frag_offset[tmp] = track->cb_color_bo_offset[tmp]; 1209 1.1 riastrad ib[idx] = track->cb_color_base_last[tmp]; 1210 1.1 riastrad } else { 1211 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1212 1.1 riastrad if (r) { 1213 1.1 riastrad dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); 1214 1.1 riastrad return -EINVAL; 1215 1.1 riastrad } 1216 1.1 riastrad track->cb_color_frag_bo[tmp] = reloc->robj; 1217 1.1 riastrad track->cb_color_frag_offset[tmp] = (u64)ib[idx] << 8; 1218 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1219 1.1 riastrad } 1220 1.1 riastrad if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { 1221 1.1 riastrad track->cb_dirty = true; 1222 1.1 riastrad } 1223 1.1 riastrad break; 1224 1.1 riastrad case R_0280C0_CB_COLOR0_TILE: 1225 1.1 riastrad case R_0280C4_CB_COLOR1_TILE: 1226 1.1 riastrad case R_0280C8_CB_COLOR2_TILE: 1227 1.1 riastrad case R_0280CC_CB_COLOR3_TILE: 1228 1.1 riastrad case R_0280D0_CB_COLOR4_TILE: 1229 1.1 riastrad case R_0280D4_CB_COLOR5_TILE: 1230 1.1 riastrad case R_0280D8_CB_COLOR6_TILE: 1231 1.1 riastrad case R_0280DC_CB_COLOR7_TILE: 1232 1.1 riastrad tmp = (reg - R_0280C0_CB_COLOR0_TILE) / 4; 1233 1.1 riastrad if (!radeon_cs_packet_next_is_pkt3_nop(p)) { 1234 1.1 riastrad if (!track->cb_color_base_last[tmp]) { 1235 1.1 riastrad dev_err(p->dev, "Broken old userspace ? no cb_color0_base supplied before trying to write 0x%08X\n", reg); 1236 1.1 riastrad return -EINVAL; 1237 1.1 riastrad } 1238 1.1 riastrad track->cb_color_tile_bo[tmp] = track->cb_color_bo[tmp]; 1239 1.1 riastrad track->cb_color_tile_offset[tmp] = track->cb_color_bo_offset[tmp]; 1240 1.1 riastrad ib[idx] = track->cb_color_base_last[tmp]; 1241 1.1 riastrad } else { 1242 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1243 1.1 riastrad if (r) { 1244 1.1 riastrad dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); 1245 1.1 riastrad return -EINVAL; 1246 1.1 riastrad } 1247 1.1 riastrad track->cb_color_tile_bo[tmp] = reloc->robj; 1248 1.1 riastrad track->cb_color_tile_offset[tmp] = (u64)ib[idx] << 8; 1249 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1250 1.1 riastrad } 1251 1.1 riastrad if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { 1252 1.1 riastrad track->cb_dirty = true; 1253 1.1 riastrad } 1254 1.1 riastrad break; 1255 1.1 riastrad case R_028100_CB_COLOR0_MASK: 1256 1.1 riastrad case R_028104_CB_COLOR1_MASK: 1257 1.1 riastrad case R_028108_CB_COLOR2_MASK: 1258 1.1 riastrad case R_02810C_CB_COLOR3_MASK: 1259 1.1 riastrad case R_028110_CB_COLOR4_MASK: 1260 1.1 riastrad case R_028114_CB_COLOR5_MASK: 1261 1.1 riastrad case R_028118_CB_COLOR6_MASK: 1262 1.1 riastrad case R_02811C_CB_COLOR7_MASK: 1263 1.1 riastrad tmp = (reg - R_028100_CB_COLOR0_MASK) / 4; 1264 1.1 riastrad track->cb_color_mask[tmp] = radeon_get_ib_value(p, idx); 1265 1.1 riastrad if (G_0280A0_TILE_MODE(track->cb_color_info[tmp])) { 1266 1.1 riastrad track->cb_dirty = true; 1267 1.1 riastrad } 1268 1.1 riastrad break; 1269 1.1 riastrad case CB_COLOR0_BASE: 1270 1.1 riastrad case CB_COLOR1_BASE: 1271 1.1 riastrad case CB_COLOR2_BASE: 1272 1.1 riastrad case CB_COLOR3_BASE: 1273 1.1 riastrad case CB_COLOR4_BASE: 1274 1.1 riastrad case CB_COLOR5_BASE: 1275 1.1 riastrad case CB_COLOR6_BASE: 1276 1.1 riastrad case CB_COLOR7_BASE: 1277 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1278 1.1 riastrad if (r) { 1279 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1280 1.1 riastrad "0x%04X\n", reg); 1281 1.1 riastrad return -EINVAL; 1282 1.1 riastrad } 1283 1.1 riastrad tmp = (reg - CB_COLOR0_BASE) / 4; 1284 1.1 riastrad track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; 1285 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1286 1.1 riastrad track->cb_color_base_last[tmp] = ib[idx]; 1287 1.1 riastrad track->cb_color_bo[tmp] = reloc->robj; 1288 1.1 riastrad track->cb_color_bo_mc[tmp] = reloc->gpu_offset; 1289 1.1 riastrad track->cb_dirty = true; 1290 1.1 riastrad break; 1291 1.1 riastrad case DB_DEPTH_BASE: 1292 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1293 1.1 riastrad if (r) { 1294 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1295 1.1 riastrad "0x%04X\n", reg); 1296 1.1 riastrad return -EINVAL; 1297 1.1 riastrad } 1298 1.1 riastrad track->db_offset = radeon_get_ib_value(p, idx) << 8; 1299 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1300 1.1 riastrad track->db_bo = reloc->robj; 1301 1.1 riastrad track->db_bo_mc = reloc->gpu_offset; 1302 1.1 riastrad track->db_dirty = true; 1303 1.1 riastrad break; 1304 1.1 riastrad case DB_HTILE_DATA_BASE: 1305 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1306 1.1 riastrad if (r) { 1307 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1308 1.1 riastrad "0x%04X\n", reg); 1309 1.1 riastrad return -EINVAL; 1310 1.1 riastrad } 1311 1.1 riastrad track->htile_offset = radeon_get_ib_value(p, idx) << 8; 1312 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1313 1.1 riastrad track->htile_bo = reloc->robj; 1314 1.1 riastrad track->db_dirty = true; 1315 1.1 riastrad break; 1316 1.1 riastrad case DB_HTILE_SURFACE: 1317 1.1 riastrad track->htile_surface = radeon_get_ib_value(p, idx); 1318 1.1 riastrad /* force 8x8 htile width and height */ 1319 1.1 riastrad ib[idx] |= 3; 1320 1.1 riastrad track->db_dirty = true; 1321 1.1 riastrad break; 1322 1.1 riastrad case SQ_PGM_START_FS: 1323 1.1 riastrad case SQ_PGM_START_ES: 1324 1.1 riastrad case SQ_PGM_START_VS: 1325 1.1 riastrad case SQ_PGM_START_GS: 1326 1.1 riastrad case SQ_PGM_START_PS: 1327 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_0: 1328 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_1: 1329 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_2: 1330 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_3: 1331 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_4: 1332 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_5: 1333 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_6: 1334 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_7: 1335 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_8: 1336 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_9: 1337 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_10: 1338 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_11: 1339 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_12: 1340 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_13: 1341 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_14: 1342 1.1 riastrad case SQ_ALU_CONST_CACHE_GS_15: 1343 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_0: 1344 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_1: 1345 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_2: 1346 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_3: 1347 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_4: 1348 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_5: 1349 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_6: 1350 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_7: 1351 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_8: 1352 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_9: 1353 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_10: 1354 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_11: 1355 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_12: 1356 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_13: 1357 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_14: 1358 1.1 riastrad case SQ_ALU_CONST_CACHE_PS_15: 1359 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_0: 1360 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_1: 1361 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_2: 1362 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_3: 1363 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_4: 1364 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_5: 1365 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_6: 1366 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_7: 1367 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_8: 1368 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_9: 1369 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_10: 1370 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_11: 1371 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_12: 1372 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_13: 1373 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_14: 1374 1.1 riastrad case SQ_ALU_CONST_CACHE_VS_15: 1375 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1376 1.1 riastrad if (r) { 1377 1.1 riastrad dev_warn(p->dev, "bad SET_CONTEXT_REG " 1378 1.1 riastrad "0x%04X\n", reg); 1379 1.1 riastrad return -EINVAL; 1380 1.1 riastrad } 1381 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1382 1.1 riastrad break; 1383 1.1 riastrad case SX_MEMORY_EXPORT_BASE: 1384 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1385 1.1 riastrad if (r) { 1386 1.1 riastrad dev_warn(p->dev, "bad SET_CONFIG_REG " 1387 1.1 riastrad "0x%04X\n", reg); 1388 1.1 riastrad return -EINVAL; 1389 1.1 riastrad } 1390 1.1 riastrad ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1391 1.1 riastrad break; 1392 1.1 riastrad case SX_MISC: 1393 1.1 riastrad track->sx_misc_kill_all_prims = (radeon_get_ib_value(p, idx) & 0x1) != 0; 1394 1.1 riastrad break; 1395 1.1 riastrad default: 1396 1.1 riastrad dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); 1397 1.1 riastrad return -EINVAL; 1398 1.1 riastrad } 1399 1.1 riastrad return 0; 1400 1.1 riastrad } 1401 1.1 riastrad 1402 1.1 riastrad unsigned r600_mip_minify(unsigned size, unsigned level) 1403 1.1 riastrad { 1404 1.1 riastrad unsigned val; 1405 1.1 riastrad 1406 1.1 riastrad val = max(1U, size >> level); 1407 1.1 riastrad if (level > 0) 1408 1.1 riastrad val = roundup_pow_of_two(val); 1409 1.1 riastrad return val; 1410 1.1 riastrad } 1411 1.1 riastrad 1412 1.1 riastrad static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, 1413 1.1 riastrad unsigned w0, unsigned h0, unsigned d0, unsigned nsamples, unsigned format, 1414 1.1 riastrad unsigned block_align, unsigned height_align, unsigned base_align, 1415 1.1 riastrad unsigned *l0_size, unsigned *mipmap_size) 1416 1.1 riastrad { 1417 1.1 riastrad unsigned offset, i, level; 1418 1.1 riastrad unsigned width, height, depth, size; 1419 1.1 riastrad unsigned blocksize; 1420 1.1 riastrad unsigned nbx, nby; 1421 1.1 riastrad unsigned nlevels = llevel - blevel + 1; 1422 1.1 riastrad 1423 1.1 riastrad *l0_size = -1; 1424 1.1 riastrad blocksize = r600_fmt_get_blocksize(format); 1425 1.1 riastrad 1426 1.1 riastrad w0 = r600_mip_minify(w0, 0); 1427 1.1 riastrad h0 = r600_mip_minify(h0, 0); 1428 1.1 riastrad d0 = r600_mip_minify(d0, 0); 1429 1.1 riastrad for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { 1430 1.1 riastrad width = r600_mip_minify(w0, i); 1431 1.1 riastrad nbx = r600_fmt_get_nblocksx(format, width); 1432 1.1 riastrad 1433 1.1 riastrad nbx = round_up(nbx, block_align); 1434 1.1 riastrad 1435 1.1 riastrad height = r600_mip_minify(h0, i); 1436 1.1 riastrad nby = r600_fmt_get_nblocksy(format, height); 1437 1.1 riastrad nby = round_up(nby, height_align); 1438 1.1 riastrad 1439 1.1 riastrad depth = r600_mip_minify(d0, i); 1440 1.1 riastrad 1441 1.1 riastrad size = nbx * nby * blocksize * nsamples; 1442 1.1 riastrad if (nfaces) 1443 1.1 riastrad size *= nfaces; 1444 1.1 riastrad else 1445 1.1 riastrad size *= depth; 1446 1.1 riastrad 1447 1.1 riastrad if (i == 0) 1448 1.1 riastrad *l0_size = size; 1449 1.1 riastrad 1450 1.1 riastrad if (i == 0 || i == 1) 1451 1.1 riastrad offset = round_up(offset, base_align); 1452 1.1 riastrad 1453 1.1 riastrad offset += size; 1454 1.1 riastrad } 1455 1.1 riastrad *mipmap_size = offset; 1456 1.1 riastrad if (llevel == 0) 1457 1.1 riastrad *mipmap_size = *l0_size; 1458 1.1 riastrad if (!blevel) 1459 1.1 riastrad *mipmap_size -= *l0_size; 1460 1.1 riastrad } 1461 1.1 riastrad 1462 1.1 riastrad /** 1463 1.1 riastrad * r600_check_texture_resource() - check if register is authorized or not 1464 1.1 riastrad * @p: parser structure holding parsing context 1465 1.1 riastrad * @idx: index into the cs buffer 1466 1.1 riastrad * @texture: texture's bo structure 1467 1.1 riastrad * @mipmap: mipmap's bo structure 1468 1.1 riastrad * 1469 1.1 riastrad * This function will check that the resource has valid field and that 1470 1.1 riastrad * the texture and mipmap bo object are big enough to cover this resource. 1471 1.1 riastrad */ 1472 1.1 riastrad static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, 1473 1.1 riastrad struct radeon_bo *texture, 1474 1.1 riastrad struct radeon_bo *mipmap, 1475 1.1 riastrad u64 base_offset, 1476 1.1 riastrad u64 mip_offset, 1477 1.1 riastrad u32 tiling_flags) 1478 1.1 riastrad { 1479 1.1 riastrad struct r600_cs_track *track = p->track; 1480 1.1 riastrad u32 dim, nfaces, llevel, blevel, w0, h0, d0; 1481 1.1 riastrad u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; 1482 1.1 riastrad u32 height_align, pitch, pitch_align, depth_align; 1483 1.1 riastrad u32 barray, larray; 1484 1.1 riastrad u64 base_align; 1485 1.1 riastrad struct array_mode_checker array_check; 1486 1.1 riastrad u32 format; 1487 1.1 riastrad bool is_array; 1488 1.1 riastrad 1489 1.1 riastrad /* on legacy kernel we don't perform advanced check */ 1490 1.1 riastrad if (p->rdev == NULL) 1491 1.1 riastrad return 0; 1492 1.1 riastrad 1493 1.1 riastrad /* convert to bytes */ 1494 1.1 riastrad base_offset <<= 8; 1495 1.1 riastrad mip_offset <<= 8; 1496 1.1 riastrad 1497 1.1 riastrad word0 = radeon_get_ib_value(p, idx + 0); 1498 1.1 riastrad if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 1499 1.1 riastrad if (tiling_flags & RADEON_TILING_MACRO) 1500 1.1 riastrad word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); 1501 1.1 riastrad else if (tiling_flags & RADEON_TILING_MICRO) 1502 1.1 riastrad word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); 1503 1.1 riastrad } 1504 1.1 riastrad word1 = radeon_get_ib_value(p, idx + 1); 1505 1.1 riastrad word2 = radeon_get_ib_value(p, idx + 2) << 8; 1506 1.1 riastrad word3 = radeon_get_ib_value(p, idx + 3) << 8; 1507 1.1 riastrad word4 = radeon_get_ib_value(p, idx + 4); 1508 1.1 riastrad word5 = radeon_get_ib_value(p, idx + 5); 1509 1.1 riastrad dim = G_038000_DIM(word0); 1510 1.1 riastrad w0 = G_038000_TEX_WIDTH(word0) + 1; 1511 1.1 riastrad pitch = (G_038000_PITCH(word0) + 1) * 8; 1512 1.1 riastrad h0 = G_038004_TEX_HEIGHT(word1) + 1; 1513 1.1 riastrad d0 = G_038004_TEX_DEPTH(word1); 1514 1.1 riastrad format = G_038004_DATA_FORMAT(word1); 1515 1.1 riastrad blevel = G_038010_BASE_LEVEL(word4); 1516 1.1 riastrad llevel = G_038014_LAST_LEVEL(word5); 1517 1.1 riastrad /* pitch in texels */ 1518 1.1 riastrad array_check.array_mode = G_038000_TILE_MODE(word0); 1519 1.1 riastrad array_check.group_size = track->group_size; 1520 1.1 riastrad array_check.nbanks = track->nbanks; 1521 1.1 riastrad array_check.npipes = track->npipes; 1522 1.1 riastrad array_check.nsamples = 1; 1523 1.1 riastrad array_check.blocksize = r600_fmt_get_blocksize(format); 1524 1.1 riastrad nfaces = 1; 1525 1.1 riastrad is_array = false; 1526 1.1 riastrad switch (dim) { 1527 1.1 riastrad case V_038000_SQ_TEX_DIM_1D: 1528 1.1 riastrad case V_038000_SQ_TEX_DIM_2D: 1529 1.1 riastrad case V_038000_SQ_TEX_DIM_3D: 1530 1.1 riastrad break; 1531 1.1 riastrad case V_038000_SQ_TEX_DIM_CUBEMAP: 1532 1.1 riastrad if (p->family >= CHIP_RV770) 1533 1.1 riastrad nfaces = 8; 1534 1.1 riastrad else 1535 1.1 riastrad nfaces = 6; 1536 1.1 riastrad break; 1537 1.1 riastrad case V_038000_SQ_TEX_DIM_1D_ARRAY: 1538 1.1 riastrad case V_038000_SQ_TEX_DIM_2D_ARRAY: 1539 1.1 riastrad is_array = true; 1540 1.1 riastrad break; 1541 1.1 riastrad case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: 1542 1.1 riastrad is_array = true; 1543 1.1 riastrad /* fall through */ 1544 1.1 riastrad case V_038000_SQ_TEX_DIM_2D_MSAA: 1545 1.1 riastrad array_check.nsamples = 1 << llevel; 1546 1.1 riastrad llevel = 0; 1547 1.1 riastrad break; 1548 1.1 riastrad default: 1549 1.1 riastrad dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); 1550 1.1 riastrad return -EINVAL; 1551 1.1 riastrad } 1552 1.1 riastrad if (!r600_fmt_is_valid_texture(format, p->family)) { 1553 1.1 riastrad dev_warn(p->dev, "%s:%d texture invalid format %d\n", 1554 1.1 riastrad __func__, __LINE__, format); 1555 1.1 riastrad return -EINVAL; 1556 1.1 riastrad } 1557 1.1 riastrad 1558 1.1 riastrad if (r600_get_array_mode_alignment(&array_check, 1559 1.1 riastrad &pitch_align, &height_align, &depth_align, &base_align)) { 1560 1.1 riastrad dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", 1561 1.1 riastrad __func__, __LINE__, G_038000_TILE_MODE(word0)); 1562 1.1 riastrad return -EINVAL; 1563 1.1 riastrad } 1564 1.1 riastrad 1565 1.1 riastrad /* XXX check height as well... */ 1566 1.1 riastrad 1567 1.1 riastrad if (!IS_ALIGNED(pitch, pitch_align)) { 1568 1.1 riastrad dev_warn(p->dev, "%s:%d tex pitch (%d, 0x%x, %d) invalid\n", 1569 1.1 riastrad __func__, __LINE__, pitch, pitch_align, G_038000_TILE_MODE(word0)); 1570 1.1 riastrad return -EINVAL; 1571 1.1 riastrad } 1572 1.1 riastrad if (!IS_ALIGNED(base_offset, base_align)) { 1573 1.1 riastrad dev_warn(p->dev, "%s:%d tex base offset (0x%"PRIx64", 0x%"PRIx64", %d) invalid\n", 1574 1.1 riastrad __func__, __LINE__, base_offset, base_align, G_038000_TILE_MODE(word0)); 1575 1.1 riastrad return -EINVAL; 1576 1.1 riastrad } 1577 1.1 riastrad if (!IS_ALIGNED(mip_offset, base_align)) { 1578 1.1 riastrad dev_warn(p->dev, "%s:%d tex mip offset (0x%"PRIx64", 0x%"PRIx64", %d) invalid\n", 1579 1.1 riastrad __func__, __LINE__, mip_offset, base_align, G_038000_TILE_MODE(word0)); 1580 1.1 riastrad return -EINVAL; 1581 1.1 riastrad } 1582 1.1 riastrad 1583 1.1 riastrad if (blevel > llevel) { 1584 1.1 riastrad dev_warn(p->dev, "texture blevel %d > llevel %d\n", 1585 1.1 riastrad blevel, llevel); 1586 1.1 riastrad } 1587 1.1 riastrad if (is_array) { 1588 1.1 riastrad barray = G_038014_BASE_ARRAY(word5); 1589 1.1 riastrad larray = G_038014_LAST_ARRAY(word5); 1590 1.1 riastrad 1591 1.1 riastrad nfaces = larray - barray + 1; 1592 1.1 riastrad } 1593 1.1 riastrad r600_texture_size(nfaces, blevel, llevel, w0, h0, d0, array_check.nsamples, format, 1594 1.1 riastrad pitch_align, height_align, base_align, 1595 1.1 riastrad &l0_size, &mipmap_size); 1596 1.1 riastrad /* using get ib will give us the offset into the texture bo */ 1597 1.1 riastrad if ((l0_size + word2) > radeon_bo_size(texture)) { 1598 1.1 riastrad dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n", 1599 1.1 riastrad w0, h0, pitch_align, height_align, 1600 1.1 riastrad array_check.array_mode, format, word2, 1601 1.1 riastrad l0_size, radeon_bo_size(texture)); 1602 1.1 riastrad dev_warn(p->dev, "alignments %d %d %d %"PRIu64"\n", pitch, pitch_align, height_align, base_align); 1603 1.1 riastrad return -EINVAL; 1604 1.1 riastrad } 1605 1.1 riastrad /* using get ib will give us the offset into the mipmap bo */ 1606 1.1 riastrad if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { 1607 1.1 riastrad /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", 1608 1.1 riastrad w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ 1609 1.1 riastrad } 1610 1.1 riastrad return 0; 1611 1.1 riastrad } 1612 1.1 riastrad 1613 1.1 riastrad static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) 1614 1.1 riastrad { 1615 1.1 riastrad u32 m, i; 1616 1.1 riastrad 1617 1.1 riastrad i = (reg >> 7); 1618 1.1 riastrad if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { 1619 1.1 riastrad dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); 1620 1.1 riastrad return false; 1621 1.1 riastrad } 1622 1.1 riastrad m = 1 << ((reg >> 2) & 31); 1623 1.1 riastrad if (!(r600_reg_safe_bm[i] & m)) 1624 1.1 riastrad return true; 1625 1.1 riastrad dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); 1626 1.1 riastrad return false; 1627 1.1 riastrad } 1628 1.1 riastrad 1629 1.1 riastrad static int r600_packet3_check(struct radeon_cs_parser *p, 1630 1.1 riastrad struct radeon_cs_packet *pkt) 1631 1.1 riastrad { 1632 1.1 riastrad struct radeon_bo_list *reloc; 1633 1.1 riastrad struct r600_cs_track *track; 1634 1.1 riastrad volatile u32 *ib; 1635 1.1 riastrad unsigned idx; 1636 1.1 riastrad unsigned i; 1637 1.1 riastrad unsigned start_reg, end_reg, reg; 1638 1.1 riastrad int r; 1639 1.1 riastrad u32 idx_value; 1640 1.1 riastrad 1641 1.1 riastrad track = (struct r600_cs_track *)p->track; 1642 1.1 riastrad ib = p->ib.ptr; 1643 1.1 riastrad idx = pkt->idx + 1; 1644 1.1 riastrad idx_value = radeon_get_ib_value(p, idx); 1645 1.1 riastrad 1646 1.1 riastrad switch (pkt->opcode) { 1647 1.1 riastrad case PACKET3_SET_PREDICATION: 1648 1.1 riastrad { 1649 1.1 riastrad int pred_op; 1650 1.1 riastrad int tmp; 1651 1.1 riastrad uint64_t offset; 1652 1.1 riastrad 1653 1.1 riastrad if (pkt->count != 1) { 1654 1.1 riastrad DRM_ERROR("bad SET PREDICATION\n"); 1655 1.1 riastrad return -EINVAL; 1656 1.1 riastrad } 1657 1.1 riastrad 1658 1.1 riastrad tmp = radeon_get_ib_value(p, idx + 1); 1659 1.1 riastrad pred_op = (tmp >> 16) & 0x7; 1660 1.1 riastrad 1661 1.1 riastrad /* for the clear predicate operation */ 1662 1.1 riastrad if (pred_op == 0) 1663 1.1 riastrad return 0; 1664 1.1 riastrad 1665 1.1 riastrad if (pred_op > 2) { 1666 1.1 riastrad DRM_ERROR("bad SET PREDICATION operation %d\n", pred_op); 1667 1.1 riastrad return -EINVAL; 1668 1.1 riastrad } 1669 1.1 riastrad 1670 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1671 1.1 riastrad if (r) { 1672 1.1 riastrad DRM_ERROR("bad SET PREDICATION\n"); 1673 1.1 riastrad return -EINVAL; 1674 1.1 riastrad } 1675 1.1 riastrad 1676 1.1 riastrad offset = reloc->gpu_offset + 1677 1.2 riastrad (idx_value & 0xfffffff0) + 1678 1.2 riastrad ((u64)(tmp & 0xff) << 32); 1679 1.1 riastrad 1680 1.1 riastrad ib[idx + 0] = offset; 1681 1.1 riastrad ib[idx + 1] = (tmp & 0xffffff00) | (upper_32_bits(offset) & 0xff); 1682 1.1 riastrad } 1683 1.1 riastrad break; 1684 1.1 riastrad 1685 1.1 riastrad case PACKET3_START_3D_CMDBUF: 1686 1.1 riastrad if (p->family >= CHIP_RV770 || pkt->count) { 1687 1.1 riastrad DRM_ERROR("bad START_3D\n"); 1688 1.1 riastrad return -EINVAL; 1689 1.1 riastrad } 1690 1.1 riastrad break; 1691 1.1 riastrad case PACKET3_CONTEXT_CONTROL: 1692 1.1 riastrad if (pkt->count != 1) { 1693 1.1 riastrad DRM_ERROR("bad CONTEXT_CONTROL\n"); 1694 1.1 riastrad return -EINVAL; 1695 1.1 riastrad } 1696 1.1 riastrad break; 1697 1.1 riastrad case PACKET3_INDEX_TYPE: 1698 1.1 riastrad case PACKET3_NUM_INSTANCES: 1699 1.1 riastrad if (pkt->count) { 1700 1.1 riastrad DRM_ERROR("bad INDEX_TYPE/NUM_INSTANCES\n"); 1701 1.1 riastrad return -EINVAL; 1702 1.1 riastrad } 1703 1.1 riastrad break; 1704 1.1 riastrad case PACKET3_DRAW_INDEX: 1705 1.1 riastrad { 1706 1.1 riastrad uint64_t offset; 1707 1.1 riastrad if (pkt->count != 3) { 1708 1.1 riastrad DRM_ERROR("bad DRAW_INDEX\n"); 1709 1.1 riastrad return -EINVAL; 1710 1.1 riastrad } 1711 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1712 1.1 riastrad if (r) { 1713 1.1 riastrad DRM_ERROR("bad DRAW_INDEX\n"); 1714 1.1 riastrad return -EINVAL; 1715 1.1 riastrad } 1716 1.1 riastrad 1717 1.1 riastrad offset = reloc->gpu_offset + 1718 1.2 riastrad idx_value + 1719 1.2 riastrad ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); 1720 1.1 riastrad 1721 1.1 riastrad ib[idx+0] = offset; 1722 1.1 riastrad ib[idx+1] = upper_32_bits(offset) & 0xff; 1723 1.1 riastrad 1724 1.1 riastrad r = r600_cs_track_check(p); 1725 1.1 riastrad if (r) { 1726 1.1 riastrad dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); 1727 1.1 riastrad return r; 1728 1.1 riastrad } 1729 1.1 riastrad break; 1730 1.1 riastrad } 1731 1.1 riastrad case PACKET3_DRAW_INDEX_AUTO: 1732 1.1 riastrad if (pkt->count != 1) { 1733 1.1 riastrad DRM_ERROR("bad DRAW_INDEX_AUTO\n"); 1734 1.1 riastrad return -EINVAL; 1735 1.1 riastrad } 1736 1.1 riastrad r = r600_cs_track_check(p); 1737 1.1 riastrad if (r) { 1738 1.1 riastrad dev_warn(p->dev, "%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx); 1739 1.1 riastrad return r; 1740 1.1 riastrad } 1741 1.1 riastrad break; 1742 1.1 riastrad case PACKET3_DRAW_INDEX_IMMD_BE: 1743 1.1 riastrad case PACKET3_DRAW_INDEX_IMMD: 1744 1.1 riastrad if (pkt->count < 2) { 1745 1.1 riastrad DRM_ERROR("bad DRAW_INDEX_IMMD\n"); 1746 1.1 riastrad return -EINVAL; 1747 1.1 riastrad } 1748 1.1 riastrad r = r600_cs_track_check(p); 1749 1.1 riastrad if (r) { 1750 1.1 riastrad dev_warn(p->dev, "%s:%d invalid cmd stream\n", __func__, __LINE__); 1751 1.1 riastrad return r; 1752 1.1 riastrad } 1753 1.1 riastrad break; 1754 1.1 riastrad case PACKET3_WAIT_REG_MEM: 1755 1.1 riastrad if (pkt->count != 5) { 1756 1.1 riastrad DRM_ERROR("bad WAIT_REG_MEM\n"); 1757 1.1 riastrad return -EINVAL; 1758 1.1 riastrad } 1759 1.1 riastrad /* bit 4 is reg (0) or mem (1) */ 1760 1.1 riastrad if (idx_value & 0x10) { 1761 1.1 riastrad uint64_t offset; 1762 1.1 riastrad 1763 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1764 1.1 riastrad if (r) { 1765 1.1 riastrad DRM_ERROR("bad WAIT_REG_MEM\n"); 1766 1.1 riastrad return -EINVAL; 1767 1.1 riastrad } 1768 1.1 riastrad 1769 1.1 riastrad offset = reloc->gpu_offset + 1770 1.2 riastrad (radeon_get_ib_value(p, idx+1) & 0xfffffff0) + 1771 1.2 riastrad ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); 1772 1.1 riastrad 1773 1.1 riastrad ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffff0); 1774 1.1 riastrad ib[idx+2] = upper_32_bits(offset) & 0xff; 1775 1.1 riastrad } else if (idx_value & 0x100) { 1776 1.1 riastrad DRM_ERROR("cannot use PFP on REG wait\n"); 1777 1.1 riastrad return -EINVAL; 1778 1.1 riastrad } 1779 1.1 riastrad break; 1780 1.1 riastrad case PACKET3_CP_DMA: 1781 1.1 riastrad { 1782 1.1 riastrad u32 command, size; 1783 1.1 riastrad u64 offset, tmp; 1784 1.1 riastrad if (pkt->count != 4) { 1785 1.1 riastrad DRM_ERROR("bad CP DMA\n"); 1786 1.1 riastrad return -EINVAL; 1787 1.1 riastrad } 1788 1.1 riastrad command = radeon_get_ib_value(p, idx+4); 1789 1.1 riastrad size = command & 0x1fffff; 1790 1.1 riastrad if (command & PACKET3_CP_DMA_CMD_SAS) { 1791 1.1 riastrad /* src address space is register */ 1792 1.1 riastrad DRM_ERROR("CP DMA SAS not supported\n"); 1793 1.1 riastrad return -EINVAL; 1794 1.1 riastrad } else { 1795 1.1 riastrad if (command & PACKET3_CP_DMA_CMD_SAIC) { 1796 1.1 riastrad DRM_ERROR("CP DMA SAIC only supported for registers\n"); 1797 1.1 riastrad return -EINVAL; 1798 1.1 riastrad } 1799 1.1 riastrad /* src address space is memory */ 1800 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1801 1.1 riastrad if (r) { 1802 1.1 riastrad DRM_ERROR("bad CP DMA SRC\n"); 1803 1.1 riastrad return -EINVAL; 1804 1.1 riastrad } 1805 1.1 riastrad 1806 1.1 riastrad tmp = radeon_get_ib_value(p, idx) + 1807 1.1 riastrad ((u64)(radeon_get_ib_value(p, idx+1) & 0xff) << 32); 1808 1.1 riastrad 1809 1.1 riastrad offset = reloc->gpu_offset + tmp; 1810 1.1 riastrad 1811 1.1 riastrad if ((tmp + size) > radeon_bo_size(reloc->robj)) { 1812 1.1 riastrad dev_warn(p->dev, "CP DMA src buffer too small (%"PRIu64" %lu)\n", 1813 1.1 riastrad tmp + size, radeon_bo_size(reloc->robj)); 1814 1.1 riastrad return -EINVAL; 1815 1.1 riastrad } 1816 1.1 riastrad 1817 1.1 riastrad ib[idx] = offset; 1818 1.1 riastrad ib[idx+1] = (ib[idx+1] & 0xffffff00) | (upper_32_bits(offset) & 0xff); 1819 1.1 riastrad } 1820 1.1 riastrad if (command & PACKET3_CP_DMA_CMD_DAS) { 1821 1.1 riastrad /* dst address space is register */ 1822 1.1 riastrad DRM_ERROR("CP DMA DAS not supported\n"); 1823 1.1 riastrad return -EINVAL; 1824 1.1 riastrad } else { 1825 1.1 riastrad /* dst address space is memory */ 1826 1.1 riastrad if (command & PACKET3_CP_DMA_CMD_DAIC) { 1827 1.1 riastrad DRM_ERROR("CP DMA DAIC only supported for registers\n"); 1828 1.1 riastrad return -EINVAL; 1829 1.1 riastrad } 1830 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1831 1.1 riastrad if (r) { 1832 1.1 riastrad DRM_ERROR("bad CP DMA DST\n"); 1833 1.1 riastrad return -EINVAL; 1834 1.1 riastrad } 1835 1.1 riastrad 1836 1.1 riastrad tmp = radeon_get_ib_value(p, idx+2) + 1837 1.1 riastrad ((u64)(radeon_get_ib_value(p, idx+3) & 0xff) << 32); 1838 1.1 riastrad 1839 1.1 riastrad offset = reloc->gpu_offset + tmp; 1840 1.1 riastrad 1841 1.1 riastrad if ((tmp + size) > radeon_bo_size(reloc->robj)) { 1842 1.1 riastrad dev_warn(p->dev, "CP DMA dst buffer too small (%"PRIu64" %lu)\n", 1843 1.1 riastrad tmp + size, radeon_bo_size(reloc->robj)); 1844 1.1 riastrad return -EINVAL; 1845 1.1 riastrad } 1846 1.1 riastrad 1847 1.1 riastrad ib[idx+2] = offset; 1848 1.1 riastrad ib[idx+3] = upper_32_bits(offset) & 0xff; 1849 1.1 riastrad } 1850 1.1 riastrad break; 1851 1.1 riastrad } 1852 1.1 riastrad case PACKET3_SURFACE_SYNC: 1853 1.1 riastrad if (pkt->count != 3) { 1854 1.1 riastrad DRM_ERROR("bad SURFACE_SYNC\n"); 1855 1.1 riastrad return -EINVAL; 1856 1.1 riastrad } 1857 1.1 riastrad /* 0xffffffff/0x0 is flush all cache flag */ 1858 1.1 riastrad if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || 1859 1.1 riastrad radeon_get_ib_value(p, idx + 2) != 0) { 1860 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1861 1.1 riastrad if (r) { 1862 1.1 riastrad DRM_ERROR("bad SURFACE_SYNC\n"); 1863 1.1 riastrad return -EINVAL; 1864 1.1 riastrad } 1865 1.1 riastrad ib[idx+2] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1866 1.1 riastrad } 1867 1.1 riastrad break; 1868 1.1 riastrad case PACKET3_EVENT_WRITE: 1869 1.1 riastrad if (pkt->count != 2 && pkt->count != 0) { 1870 1.1 riastrad DRM_ERROR("bad EVENT_WRITE\n"); 1871 1.1 riastrad return -EINVAL; 1872 1.1 riastrad } 1873 1.1 riastrad if (pkt->count) { 1874 1.1 riastrad uint64_t offset; 1875 1.1 riastrad 1876 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1877 1.1 riastrad if (r) { 1878 1.1 riastrad DRM_ERROR("bad EVENT_WRITE\n"); 1879 1.1 riastrad return -EINVAL; 1880 1.1 riastrad } 1881 1.1 riastrad offset = reloc->gpu_offset + 1882 1.2 riastrad (radeon_get_ib_value(p, idx+1) & 0xfffffff8) + 1883 1.2 riastrad ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); 1884 1.1 riastrad 1885 1.1 riastrad ib[idx+1] = offset & 0xfffffff8; 1886 1.1 riastrad ib[idx+2] = upper_32_bits(offset) & 0xff; 1887 1.1 riastrad } 1888 1.1 riastrad break; 1889 1.1 riastrad case PACKET3_EVENT_WRITE_EOP: 1890 1.1 riastrad { 1891 1.1 riastrad uint64_t offset; 1892 1.1 riastrad 1893 1.1 riastrad if (pkt->count != 4) { 1894 1.1 riastrad DRM_ERROR("bad EVENT_WRITE_EOP\n"); 1895 1.1 riastrad return -EINVAL; 1896 1.1 riastrad } 1897 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1898 1.1 riastrad if (r) { 1899 1.1 riastrad DRM_ERROR("bad EVENT_WRITE\n"); 1900 1.1 riastrad return -EINVAL; 1901 1.1 riastrad } 1902 1.1 riastrad 1903 1.1 riastrad offset = reloc->gpu_offset + 1904 1.2 riastrad (radeon_get_ib_value(p, idx+1) & 0xfffffffc) + 1905 1.2 riastrad ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32); 1906 1.1 riastrad 1907 1.1 riastrad ib[idx+1] = offset & 0xfffffffc; 1908 1.1 riastrad ib[idx+2] = (ib[idx+2] & 0xffffff00) | (upper_32_bits(offset) & 0xff); 1909 1.1 riastrad break; 1910 1.1 riastrad } 1911 1.1 riastrad case PACKET3_SET_CONFIG_REG: 1912 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_OFFSET; 1913 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 1914 1.1 riastrad if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) || 1915 1.1 riastrad (start_reg >= PACKET3_SET_CONFIG_REG_END) || 1916 1.1 riastrad (end_reg >= PACKET3_SET_CONFIG_REG_END)) { 1917 1.1 riastrad DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); 1918 1.1 riastrad return -EINVAL; 1919 1.1 riastrad } 1920 1.1 riastrad for (i = 0; i < pkt->count; i++) { 1921 1.1 riastrad reg = start_reg + (4 * i); 1922 1.1 riastrad r = r600_cs_check_reg(p, reg, idx+1+i); 1923 1.1 riastrad if (r) 1924 1.1 riastrad return r; 1925 1.1 riastrad } 1926 1.1 riastrad break; 1927 1.1 riastrad case PACKET3_SET_CONTEXT_REG: 1928 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_OFFSET; 1929 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 1930 1.1 riastrad if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) || 1931 1.1 riastrad (start_reg >= PACKET3_SET_CONTEXT_REG_END) || 1932 1.1 riastrad (end_reg >= PACKET3_SET_CONTEXT_REG_END)) { 1933 1.1 riastrad DRM_ERROR("bad PACKET3_SET_CONTEXT_REG\n"); 1934 1.1 riastrad return -EINVAL; 1935 1.1 riastrad } 1936 1.1 riastrad for (i = 0; i < pkt->count; i++) { 1937 1.1 riastrad reg = start_reg + (4 * i); 1938 1.1 riastrad r = r600_cs_check_reg(p, reg, idx+1+i); 1939 1.1 riastrad if (r) 1940 1.1 riastrad return r; 1941 1.1 riastrad } 1942 1.1 riastrad break; 1943 1.1 riastrad case PACKET3_SET_RESOURCE: 1944 1.1 riastrad if (pkt->count % 7) { 1945 1.1 riastrad DRM_ERROR("bad SET_RESOURCE\n"); 1946 1.1 riastrad return -EINVAL; 1947 1.1 riastrad } 1948 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_OFFSET; 1949 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 1950 1.1 riastrad if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) || 1951 1.1 riastrad (start_reg >= PACKET3_SET_RESOURCE_END) || 1952 1.1 riastrad (end_reg >= PACKET3_SET_RESOURCE_END)) { 1953 1.1 riastrad DRM_ERROR("bad SET_RESOURCE\n"); 1954 1.1 riastrad return -EINVAL; 1955 1.1 riastrad } 1956 1.1 riastrad for (i = 0; i < (pkt->count / 7); i++) { 1957 1.1 riastrad struct radeon_bo *texture, *mipmap; 1958 1.1 riastrad u32 size, offset, base_offset, mip_offset; 1959 1.1 riastrad 1960 1.1 riastrad switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { 1961 1.1 riastrad case SQ_TEX_VTX_VALID_TEXTURE: 1962 1.1 riastrad /* tex base */ 1963 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1964 1.1 riastrad if (r) { 1965 1.1 riastrad DRM_ERROR("bad SET_RESOURCE\n"); 1966 1.1 riastrad return -EINVAL; 1967 1.1 riastrad } 1968 1.1 riastrad base_offset = (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1969 1.1 riastrad if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { 1970 1.1 riastrad if (reloc->tiling_flags & RADEON_TILING_MACRO) 1971 1.1 riastrad ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); 1972 1.1 riastrad else if (reloc->tiling_flags & RADEON_TILING_MICRO) 1973 1.1 riastrad ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); 1974 1.1 riastrad } 1975 1.1 riastrad texture = reloc->robj; 1976 1.1 riastrad /* tex mip base */ 1977 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1978 1.1 riastrad if (r) { 1979 1.1 riastrad DRM_ERROR("bad SET_RESOURCE\n"); 1980 1.1 riastrad return -EINVAL; 1981 1.1 riastrad } 1982 1.1 riastrad mip_offset = (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 1983 1.1 riastrad mipmap = reloc->robj; 1984 1.1 riastrad r = r600_check_texture_resource(p, idx+(i*7)+1, 1985 1.1 riastrad texture, mipmap, 1986 1.1 riastrad base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2), 1987 1.1 riastrad mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3), 1988 1.1 riastrad reloc->tiling_flags); 1989 1.1 riastrad if (r) 1990 1.1 riastrad return r; 1991 1.1 riastrad ib[idx+1+(i*7)+2] += base_offset; 1992 1.1 riastrad ib[idx+1+(i*7)+3] += mip_offset; 1993 1.1 riastrad break; 1994 1.1 riastrad case SQ_TEX_VTX_VALID_BUFFER: 1995 1.1 riastrad { 1996 1.1 riastrad uint64_t offset64; 1997 1.1 riastrad /* vtx base */ 1998 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 1999 1.1 riastrad if (r) { 2000 1.1 riastrad DRM_ERROR("bad SET_RESOURCE\n"); 2001 1.1 riastrad return -EINVAL; 2002 1.1 riastrad } 2003 1.1 riastrad offset = radeon_get_ib_value(p, idx+1+(i*7)+0); 2004 1.1 riastrad size = radeon_get_ib_value(p, idx+1+(i*7)+1) + 1; 2005 1.1 riastrad if (p->rdev && (size + offset) > radeon_bo_size(reloc->robj)) { 2006 1.1 riastrad /* force size to size of the buffer */ 2007 1.1 riastrad dev_warn(p->dev, "vbo resource seems too big (%d) for the bo (%ld)\n", 2008 1.1 riastrad size + offset, radeon_bo_size(reloc->robj)); 2009 1.1 riastrad ib[idx+1+(i*7)+1] = radeon_bo_size(reloc->robj) - offset; 2010 1.1 riastrad } 2011 1.1 riastrad 2012 1.1 riastrad offset64 = reloc->gpu_offset + offset; 2013 1.1 riastrad ib[idx+1+(i*8)+0] = offset64; 2014 1.1 riastrad ib[idx+1+(i*8)+2] = (ib[idx+1+(i*8)+2] & 0xffffff00) | 2015 1.1 riastrad (upper_32_bits(offset64) & 0xff); 2016 1.1 riastrad break; 2017 1.1 riastrad } 2018 1.1 riastrad case SQ_TEX_VTX_INVALID_TEXTURE: 2019 1.1 riastrad case SQ_TEX_VTX_INVALID_BUFFER: 2020 1.1 riastrad default: 2021 1.1 riastrad DRM_ERROR("bad SET_RESOURCE\n"); 2022 1.1 riastrad return -EINVAL; 2023 1.1 riastrad } 2024 1.1 riastrad } 2025 1.1 riastrad break; 2026 1.1 riastrad case PACKET3_SET_ALU_CONST: 2027 1.1 riastrad if (track->sq_config & DX9_CONSTS) { 2028 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET; 2029 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 2030 1.1 riastrad if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || 2031 1.1 riastrad (start_reg >= PACKET3_SET_ALU_CONST_END) || 2032 1.1 riastrad (end_reg >= PACKET3_SET_ALU_CONST_END)) { 2033 1.1 riastrad DRM_ERROR("bad SET_ALU_CONST\n"); 2034 1.1 riastrad return -EINVAL; 2035 1.1 riastrad } 2036 1.1 riastrad } 2037 1.1 riastrad break; 2038 1.1 riastrad case PACKET3_SET_BOOL_CONST: 2039 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_OFFSET; 2040 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 2041 1.1 riastrad if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) || 2042 1.1 riastrad (start_reg >= PACKET3_SET_BOOL_CONST_END) || 2043 1.1 riastrad (end_reg >= PACKET3_SET_BOOL_CONST_END)) { 2044 1.1 riastrad DRM_ERROR("bad SET_BOOL_CONST\n"); 2045 1.1 riastrad return -EINVAL; 2046 1.1 riastrad } 2047 1.1 riastrad break; 2048 1.1 riastrad case PACKET3_SET_LOOP_CONST: 2049 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_OFFSET; 2050 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 2051 1.1 riastrad if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) || 2052 1.1 riastrad (start_reg >= PACKET3_SET_LOOP_CONST_END) || 2053 1.1 riastrad (end_reg >= PACKET3_SET_LOOP_CONST_END)) { 2054 1.1 riastrad DRM_ERROR("bad SET_LOOP_CONST\n"); 2055 1.1 riastrad return -EINVAL; 2056 1.1 riastrad } 2057 1.1 riastrad break; 2058 1.1 riastrad case PACKET3_SET_CTL_CONST: 2059 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_OFFSET; 2060 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 2061 1.1 riastrad if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) || 2062 1.1 riastrad (start_reg >= PACKET3_SET_CTL_CONST_END) || 2063 1.1 riastrad (end_reg >= PACKET3_SET_CTL_CONST_END)) { 2064 1.1 riastrad DRM_ERROR("bad SET_CTL_CONST\n"); 2065 1.1 riastrad return -EINVAL; 2066 1.1 riastrad } 2067 1.1 riastrad break; 2068 1.1 riastrad case PACKET3_SET_SAMPLER: 2069 1.1 riastrad if (pkt->count % 3) { 2070 1.1 riastrad DRM_ERROR("bad SET_SAMPLER\n"); 2071 1.1 riastrad return -EINVAL; 2072 1.1 riastrad } 2073 1.1 riastrad start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_OFFSET; 2074 1.1 riastrad end_reg = 4 * pkt->count + start_reg - 4; 2075 1.1 riastrad if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) || 2076 1.1 riastrad (start_reg >= PACKET3_SET_SAMPLER_END) || 2077 1.1 riastrad (end_reg >= PACKET3_SET_SAMPLER_END)) { 2078 1.1 riastrad DRM_ERROR("bad SET_SAMPLER\n"); 2079 1.1 riastrad return -EINVAL; 2080 1.1 riastrad } 2081 1.1 riastrad break; 2082 1.1 riastrad case PACKET3_STRMOUT_BASE_UPDATE: 2083 1.1 riastrad /* RS780 and RS880 also need this */ 2084 1.1 riastrad if (p->family < CHIP_RS780) { 2085 1.1 riastrad DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); 2086 1.1 riastrad return -EINVAL; 2087 1.1 riastrad } 2088 1.1 riastrad if (pkt->count != 1) { 2089 1.1 riastrad DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n"); 2090 1.1 riastrad return -EINVAL; 2091 1.1 riastrad } 2092 1.1 riastrad if (idx_value > 3) { 2093 1.1 riastrad DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n"); 2094 1.1 riastrad return -EINVAL; 2095 1.1 riastrad } 2096 1.1 riastrad { 2097 1.1 riastrad u64 offset; 2098 1.1 riastrad 2099 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 2100 1.1 riastrad if (r) { 2101 1.1 riastrad DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); 2102 1.1 riastrad return -EINVAL; 2103 1.1 riastrad } 2104 1.1 riastrad 2105 1.1 riastrad if (reloc->robj != track->vgt_strmout_bo[idx_value]) { 2106 1.1 riastrad DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n"); 2107 1.1 riastrad return -EINVAL; 2108 1.1 riastrad } 2109 1.1 riastrad 2110 1.1 riastrad offset = radeon_get_ib_value(p, idx+1) << 8; 2111 1.1 riastrad if (offset != track->vgt_strmout_bo_offset[idx_value]) { 2112 1.1 riastrad DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%"PRIx64", 0x%x\n", 2113 1.1 riastrad offset, track->vgt_strmout_bo_offset[idx_value]); 2114 1.1 riastrad return -EINVAL; 2115 1.1 riastrad } 2116 1.1 riastrad 2117 1.1 riastrad if ((offset + 4) > radeon_bo_size(reloc->robj)) { 2118 1.1 riastrad DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%"PRIx64", 0x%lx\n", 2119 1.1 riastrad offset + 4, radeon_bo_size(reloc->robj)); 2120 1.1 riastrad return -EINVAL; 2121 1.1 riastrad } 2122 1.1 riastrad ib[idx+1] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); 2123 1.1 riastrad } 2124 1.1 riastrad break; 2125 1.1 riastrad case PACKET3_SURFACE_BASE_UPDATE: 2126 1.1 riastrad if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { 2127 1.1 riastrad DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); 2128 1.1 riastrad return -EINVAL; 2129 1.1 riastrad } 2130 1.1 riastrad if (pkt->count) { 2131 1.1 riastrad DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); 2132 1.1 riastrad return -EINVAL; 2133 1.1 riastrad } 2134 1.1 riastrad break; 2135 1.1 riastrad case PACKET3_STRMOUT_BUFFER_UPDATE: 2136 1.1 riastrad if (pkt->count != 4) { 2137 1.1 riastrad DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n"); 2138 1.1 riastrad return -EINVAL; 2139 1.1 riastrad } 2140 1.1 riastrad /* Updating memory at DST_ADDRESS. */ 2141 1.1 riastrad if (idx_value & 0x1) { 2142 1.1 riastrad u64 offset; 2143 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 2144 1.1 riastrad if (r) { 2145 1.1 riastrad DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); 2146 1.1 riastrad return -EINVAL; 2147 1.1 riastrad } 2148 1.1 riastrad offset = radeon_get_ib_value(p, idx+1); 2149 1.1 riastrad offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; 2150 1.1 riastrad if ((offset + 4) > radeon_bo_size(reloc->robj)) { 2151 1.1 riastrad DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%"PRIx64", 0x%lx\n", 2152 1.1 riastrad offset + 4, radeon_bo_size(reloc->robj)); 2153 1.1 riastrad return -EINVAL; 2154 1.1 riastrad } 2155 1.1 riastrad offset += reloc->gpu_offset; 2156 1.1 riastrad ib[idx+1] = offset; 2157 1.1 riastrad ib[idx+2] = upper_32_bits(offset) & 0xff; 2158 1.1 riastrad } 2159 1.1 riastrad /* Reading data from SRC_ADDRESS. */ 2160 1.1 riastrad if (((idx_value >> 1) & 0x3) == 2) { 2161 1.1 riastrad u64 offset; 2162 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 2163 1.1 riastrad if (r) { 2164 1.1 riastrad DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); 2165 1.1 riastrad return -EINVAL; 2166 1.1 riastrad } 2167 1.1 riastrad offset = radeon_get_ib_value(p, idx+3); 2168 1.1 riastrad offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; 2169 1.1 riastrad if ((offset + 4) > radeon_bo_size(reloc->robj)) { 2170 1.1 riastrad DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%"PRIx64", 0x%lx\n", 2171 1.1 riastrad offset + 4, radeon_bo_size(reloc->robj)); 2172 1.1 riastrad return -EINVAL; 2173 1.1 riastrad } 2174 1.1 riastrad offset += reloc->gpu_offset; 2175 1.1 riastrad ib[idx+3] = offset; 2176 1.1 riastrad ib[idx+4] = upper_32_bits(offset) & 0xff; 2177 1.1 riastrad } 2178 1.1 riastrad break; 2179 1.1 riastrad case PACKET3_MEM_WRITE: 2180 1.1 riastrad { 2181 1.1 riastrad u64 offset; 2182 1.1 riastrad 2183 1.1 riastrad if (pkt->count != 3) { 2184 1.1 riastrad DRM_ERROR("bad MEM_WRITE (invalid count)\n"); 2185 1.1 riastrad return -EINVAL; 2186 1.1 riastrad } 2187 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 2188 1.1 riastrad if (r) { 2189 1.1 riastrad DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); 2190 1.1 riastrad return -EINVAL; 2191 1.1 riastrad } 2192 1.1 riastrad offset = radeon_get_ib_value(p, idx+0); 2193 1.1 riastrad offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL; 2194 1.1 riastrad if (offset & 0x7) { 2195 1.1 riastrad DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n"); 2196 1.1 riastrad return -EINVAL; 2197 1.1 riastrad } 2198 1.1 riastrad if ((offset + 8) > radeon_bo_size(reloc->robj)) { 2199 1.1 riastrad DRM_ERROR("bad MEM_WRITE bo too small: 0x%"PRIx64", 0x%lx\n", 2200 1.1 riastrad offset + 8, radeon_bo_size(reloc->robj)); 2201 1.1 riastrad return -EINVAL; 2202 1.1 riastrad } 2203 1.1 riastrad offset += reloc->gpu_offset; 2204 1.1 riastrad ib[idx+0] = offset; 2205 1.1 riastrad ib[idx+1] = upper_32_bits(offset) & 0xff; 2206 1.1 riastrad break; 2207 1.1 riastrad } 2208 1.1 riastrad case PACKET3_COPY_DW: 2209 1.1 riastrad if (pkt->count != 4) { 2210 1.1 riastrad DRM_ERROR("bad COPY_DW (invalid count)\n"); 2211 1.1 riastrad return -EINVAL; 2212 1.1 riastrad } 2213 1.1 riastrad if (idx_value & 0x1) { 2214 1.1 riastrad u64 offset; 2215 1.1 riastrad /* SRC is memory. */ 2216 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 2217 1.1 riastrad if (r) { 2218 1.1 riastrad DRM_ERROR("bad COPY_DW (missing src reloc)\n"); 2219 1.1 riastrad return -EINVAL; 2220 1.1 riastrad } 2221 1.1 riastrad offset = radeon_get_ib_value(p, idx+1); 2222 1.1 riastrad offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; 2223 1.1 riastrad if ((offset + 4) > radeon_bo_size(reloc->robj)) { 2224 1.1 riastrad DRM_ERROR("bad COPY_DW src bo too small: 0x%"PRIx64", 0x%lx\n", 2225 1.1 riastrad offset + 4, radeon_bo_size(reloc->robj)); 2226 1.1 riastrad return -EINVAL; 2227 1.1 riastrad } 2228 1.1 riastrad offset += reloc->gpu_offset; 2229 1.1 riastrad ib[idx+1] = offset; 2230 1.1 riastrad ib[idx+2] = upper_32_bits(offset) & 0xff; 2231 1.1 riastrad } else { 2232 1.1 riastrad /* SRC is a reg. */ 2233 1.1 riastrad reg = radeon_get_ib_value(p, idx+1) << 2; 2234 1.1 riastrad if (!r600_is_safe_reg(p, reg, idx+1)) 2235 1.1 riastrad return -EINVAL; 2236 1.1 riastrad } 2237 1.1 riastrad if (idx_value & 0x2) { 2238 1.1 riastrad u64 offset; 2239 1.1 riastrad /* DST is memory. */ 2240 1.1 riastrad r = radeon_cs_packet_next_reloc(p, &reloc, r600_nomm); 2241 1.1 riastrad if (r) { 2242 1.1 riastrad DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); 2243 1.1 riastrad return -EINVAL; 2244 1.1 riastrad } 2245 1.1 riastrad offset = radeon_get_ib_value(p, idx+3); 2246 1.1 riastrad offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; 2247 1.1 riastrad if ((offset + 4) > radeon_bo_size(reloc->robj)) { 2248 1.1 riastrad DRM_ERROR("bad COPY_DW dst bo too small: 0x%"PRIx64", 0x%lx\n", 2249 1.1 riastrad offset + 4, radeon_bo_size(reloc->robj)); 2250 1.1 riastrad return -EINVAL; 2251 1.1 riastrad } 2252 1.1 riastrad offset += reloc->gpu_offset; 2253 1.1 riastrad ib[idx+3] = offset; 2254 1.1 riastrad ib[idx+4] = upper_32_bits(offset) & 0xff; 2255 1.1 riastrad } else { 2256 1.1 riastrad /* DST is a reg. */ 2257 1.1 riastrad reg = radeon_get_ib_value(p, idx+3) << 2; 2258 1.1 riastrad if (!r600_is_safe_reg(p, reg, idx+3)) 2259 1.1 riastrad return -EINVAL; 2260 1.1 riastrad } 2261 1.1 riastrad break; 2262 1.1 riastrad case PACKET3_NOP: 2263 1.1 riastrad break; 2264 1.1 riastrad default: 2265 1.1 riastrad DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); 2266 1.1 riastrad return -EINVAL; 2267 1.1 riastrad } 2268 1.1 riastrad return 0; 2269 1.1 riastrad } 2270 1.1 riastrad 2271 1.1 riastrad int r600_cs_parse(struct radeon_cs_parser *p) 2272 1.1 riastrad { 2273 1.1 riastrad struct radeon_cs_packet pkt; 2274 1.1 riastrad struct r600_cs_track *track; 2275 1.1 riastrad int r; 2276 1.1 riastrad 2277 1.1 riastrad if (p->track == NULL) { 2278 1.1 riastrad /* initialize tracker, we are in kms */ 2279 1.1 riastrad track = kzalloc(sizeof(*track), GFP_KERNEL); 2280 1.1 riastrad if (track == NULL) 2281 1.1 riastrad return -ENOMEM; 2282 1.1 riastrad r600_cs_track_init(track); 2283 1.1 riastrad if (p->rdev->family < CHIP_RV770) { 2284 1.1 riastrad track->npipes = p->rdev->config.r600.tiling_npipes; 2285 1.1 riastrad track->nbanks = p->rdev->config.r600.tiling_nbanks; 2286 1.1 riastrad track->group_size = p->rdev->config.r600.tiling_group_size; 2287 1.1 riastrad } else if (p->rdev->family <= CHIP_RV740) { 2288 1.1 riastrad track->npipes = p->rdev->config.rv770.tiling_npipes; 2289 1.1 riastrad track->nbanks = p->rdev->config.rv770.tiling_nbanks; 2290 1.1 riastrad track->group_size = p->rdev->config.rv770.tiling_group_size; 2291 1.1 riastrad } 2292 1.1 riastrad p->track = track; 2293 1.1 riastrad } 2294 1.1 riastrad do { 2295 1.1 riastrad r = radeon_cs_packet_parse(p, &pkt, p->idx); 2296 1.1 riastrad if (r) { 2297 1.1 riastrad kfree(p->track); 2298 1.1 riastrad p->track = NULL; 2299 1.1 riastrad return r; 2300 1.1 riastrad } 2301 1.1 riastrad p->idx += pkt.count + 2; 2302 1.1 riastrad switch (pkt.type) { 2303 1.1 riastrad case RADEON_PACKET_TYPE0: 2304 1.1 riastrad r = r600_cs_parse_packet0(p, &pkt); 2305 1.1 riastrad break; 2306 1.1 riastrad case RADEON_PACKET_TYPE2: 2307 1.1 riastrad break; 2308 1.1 riastrad case RADEON_PACKET_TYPE3: 2309 1.1 riastrad r = r600_packet3_check(p, &pkt); 2310 1.1 riastrad break; 2311 1.1 riastrad default: 2312 1.1 riastrad DRM_ERROR("Unknown packet type %d !\n", pkt.type); 2313 1.1 riastrad kfree(p->track); 2314 1.1 riastrad p->track = NULL; 2315 1.1 riastrad return -EINVAL; 2316 1.1 riastrad } 2317 1.1 riastrad if (r) { 2318 1.1 riastrad kfree(p->track); 2319 1.1 riastrad p->track = NULL; 2320 1.1 riastrad return r; 2321 1.1 riastrad } 2322 1.1 riastrad } while (p->idx < p->chunk_ib->length_dw); 2323 1.1 riastrad #if 0 2324 1.1 riastrad for (r = 0; r < p->ib.length_dw; r++) { 2325 1.2 riastrad pr_info("%05d 0x%08X\n", r, p->ib.ptr[r]); 2326 1.1 riastrad mdelay(1); 2327 1.1 riastrad } 2328 1.1 riastrad #endif 2329 1.1 riastrad kfree(p->track); 2330 1.1 riastrad p->track = NULL; 2331 1.1 riastrad return 0; 2332 1.1 riastrad } 2333 1.1 riastrad 2334 1.1 riastrad /* 2335 1.1 riastrad * DMA 2336 1.1 riastrad */ 2337 1.1 riastrad /** 2338 1.1 riastrad * r600_dma_cs_next_reloc() - parse next reloc 2339 1.1 riastrad * @p: parser structure holding parsing context. 2340 1.1 riastrad * @cs_reloc: reloc informations 2341 1.1 riastrad * 2342 1.1 riastrad * Return the next reloc, do bo validation and compute 2343 1.1 riastrad * GPU offset using the provided start. 2344 1.1 riastrad **/ 2345 1.1 riastrad int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, 2346 1.1 riastrad struct radeon_bo_list **cs_reloc) 2347 1.1 riastrad { 2348 1.1 riastrad unsigned idx; 2349 1.1 riastrad 2350 1.1 riastrad *cs_reloc = NULL; 2351 1.1 riastrad if (p->chunk_relocs == NULL) { 2352 1.1 riastrad DRM_ERROR("No relocation chunk !\n"); 2353 1.1 riastrad return -EINVAL; 2354 1.1 riastrad } 2355 1.1 riastrad idx = p->dma_reloc_idx; 2356 1.1 riastrad if (idx >= p->nrelocs) { 2357 1.1 riastrad DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", 2358 1.1 riastrad idx, p->nrelocs); 2359 1.1 riastrad return -EINVAL; 2360 1.1 riastrad } 2361 1.1 riastrad *cs_reloc = &p->relocs[idx]; 2362 1.1 riastrad p->dma_reloc_idx++; 2363 1.1 riastrad return 0; 2364 1.1 riastrad } 2365 1.1 riastrad 2366 1.1 riastrad #define GET_DMA_CMD(h) (((h) & 0xf0000000) >> 28) 2367 1.1 riastrad #define GET_DMA_COUNT(h) ((h) & 0x0000ffff) 2368 1.1 riastrad #define GET_DMA_T(h) (((h) & 0x00800000) >> 23) 2369 1.1 riastrad 2370 1.1 riastrad /** 2371 1.1 riastrad * r600_dma_cs_parse() - parse the DMA IB 2372 1.1 riastrad * @p: parser structure holding parsing context. 2373 1.1 riastrad * 2374 1.1 riastrad * Parses the DMA IB from the CS ioctl and updates 2375 1.1 riastrad * the GPU addresses based on the reloc information and 2376 1.1 riastrad * checks for errors. (R6xx-R7xx) 2377 1.1 riastrad * Returns 0 for success and an error on failure. 2378 1.1 riastrad **/ 2379 1.1 riastrad int r600_dma_cs_parse(struct radeon_cs_parser *p) 2380 1.1 riastrad { 2381 1.1 riastrad struct radeon_cs_chunk *ib_chunk = p->chunk_ib; 2382 1.1 riastrad struct radeon_bo_list *src_reloc, *dst_reloc; 2383 1.1 riastrad u32 header, cmd, count, tiled; 2384 1.1 riastrad volatile u32 *ib = p->ib.ptr; 2385 1.1 riastrad u32 idx, idx_value; 2386 1.1 riastrad u64 src_offset, dst_offset; 2387 1.1 riastrad int r; 2388 1.1 riastrad 2389 1.1 riastrad do { 2390 1.1 riastrad if (p->idx >= ib_chunk->length_dw) { 2391 1.1 riastrad DRM_ERROR("Can not parse packet at %d after CS end %d !\n", 2392 1.1 riastrad p->idx, ib_chunk->length_dw); 2393 1.1 riastrad return -EINVAL; 2394 1.1 riastrad } 2395 1.1 riastrad idx = p->idx; 2396 1.1 riastrad header = radeon_get_ib_value(p, idx); 2397 1.1 riastrad cmd = GET_DMA_CMD(header); 2398 1.1 riastrad count = GET_DMA_COUNT(header); 2399 1.1 riastrad tiled = GET_DMA_T(header); 2400 1.1 riastrad 2401 1.1 riastrad switch (cmd) { 2402 1.1 riastrad case DMA_PACKET_WRITE: 2403 1.1 riastrad r = r600_dma_cs_next_reloc(p, &dst_reloc); 2404 1.1 riastrad if (r) { 2405 1.1 riastrad DRM_ERROR("bad DMA_PACKET_WRITE\n"); 2406 1.1 riastrad return -EINVAL; 2407 1.1 riastrad } 2408 1.1 riastrad if (tiled) { 2409 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+1); 2410 1.1 riastrad dst_offset <<= 8; 2411 1.1 riastrad 2412 1.1 riastrad ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8); 2413 1.1 riastrad p->idx += count + 5; 2414 1.1 riastrad } else { 2415 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+1); 2416 1.1 riastrad dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; 2417 1.1 riastrad 2418 1.1 riastrad ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc); 2419 1.1 riastrad ib[idx+2] += upper_32_bits(dst_reloc->gpu_offset) & 0xff; 2420 1.1 riastrad p->idx += count + 3; 2421 1.1 riastrad } 2422 1.1 riastrad if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { 2423 1.1 riastrad dev_warn(p->dev, "DMA write buffer too small (%"PRIu64" %lu)\n", 2424 1.1 riastrad dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); 2425 1.1 riastrad return -EINVAL; 2426 1.1 riastrad } 2427 1.1 riastrad break; 2428 1.1 riastrad case DMA_PACKET_COPY: 2429 1.1 riastrad r = r600_dma_cs_next_reloc(p, &src_reloc); 2430 1.1 riastrad if (r) { 2431 1.1 riastrad DRM_ERROR("bad DMA_PACKET_COPY\n"); 2432 1.1 riastrad return -EINVAL; 2433 1.1 riastrad } 2434 1.1 riastrad r = r600_dma_cs_next_reloc(p, &dst_reloc); 2435 1.1 riastrad if (r) { 2436 1.1 riastrad DRM_ERROR("bad DMA_PACKET_COPY\n"); 2437 1.1 riastrad return -EINVAL; 2438 1.1 riastrad } 2439 1.1 riastrad if (tiled) { 2440 1.1 riastrad idx_value = radeon_get_ib_value(p, idx + 2); 2441 1.1 riastrad /* detile bit */ 2442 1.1 riastrad if (idx_value & (1 << 31)) { 2443 1.1 riastrad /* tiled src, linear dst */ 2444 1.1 riastrad src_offset = radeon_get_ib_value(p, idx+1); 2445 1.1 riastrad src_offset <<= 8; 2446 1.1 riastrad ib[idx+1] += (u32)(src_reloc->gpu_offset >> 8); 2447 1.1 riastrad 2448 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+5); 2449 1.1 riastrad dst_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32; 2450 1.1 riastrad ib[idx+5] += (u32)(dst_reloc->gpu_offset & 0xfffffffc); 2451 1.1 riastrad ib[idx+6] += upper_32_bits(dst_reloc->gpu_offset) & 0xff; 2452 1.1 riastrad } else { 2453 1.1 riastrad /* linear src, tiled dst */ 2454 1.1 riastrad src_offset = radeon_get_ib_value(p, idx+5); 2455 1.1 riastrad src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32; 2456 1.1 riastrad ib[idx+5] += (u32)(src_reloc->gpu_offset & 0xfffffffc); 2457 1.1 riastrad ib[idx+6] += upper_32_bits(src_reloc->gpu_offset) & 0xff; 2458 1.1 riastrad 2459 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+1); 2460 1.1 riastrad dst_offset <<= 8; 2461 1.1 riastrad ib[idx+1] += (u32)(dst_reloc->gpu_offset >> 8); 2462 1.1 riastrad } 2463 1.1 riastrad p->idx += 7; 2464 1.1 riastrad } else { 2465 1.1 riastrad if (p->family >= CHIP_RV770) { 2466 1.1 riastrad src_offset = radeon_get_ib_value(p, idx+2); 2467 1.1 riastrad src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; 2468 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+1); 2469 1.1 riastrad dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; 2470 1.1 riastrad 2471 1.1 riastrad ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc); 2472 1.1 riastrad ib[idx+2] += (u32)(src_reloc->gpu_offset & 0xfffffffc); 2473 1.1 riastrad ib[idx+3] += upper_32_bits(dst_reloc->gpu_offset) & 0xff; 2474 1.1 riastrad ib[idx+4] += upper_32_bits(src_reloc->gpu_offset) & 0xff; 2475 1.1 riastrad p->idx += 5; 2476 1.1 riastrad } else { 2477 1.1 riastrad src_offset = radeon_get_ib_value(p, idx+2); 2478 1.1 riastrad src_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; 2479 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+1); 2480 1.1 riastrad dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff0000)) << 16; 2481 1.1 riastrad 2482 1.1 riastrad ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc); 2483 1.1 riastrad ib[idx+2] += (u32)(src_reloc->gpu_offset & 0xfffffffc); 2484 1.1 riastrad ib[idx+3] += upper_32_bits(src_reloc->gpu_offset) & 0xff; 2485 1.1 riastrad ib[idx+3] += (upper_32_bits(dst_reloc->gpu_offset) & 0xff) << 16; 2486 1.1 riastrad p->idx += 4; 2487 1.1 riastrad } 2488 1.1 riastrad } 2489 1.1 riastrad if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 2490 1.1 riastrad dev_warn(p->dev, "DMA copy src buffer too small (%"PRIu64" %lu)\n", 2491 1.1 riastrad src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); 2492 1.1 riastrad return -EINVAL; 2493 1.1 riastrad } 2494 1.1 riastrad if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { 2495 1.1 riastrad dev_warn(p->dev, "DMA write dst buffer too small (%"PRIu64" %lu)\n", 2496 1.1 riastrad dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); 2497 1.1 riastrad return -EINVAL; 2498 1.1 riastrad } 2499 1.1 riastrad break; 2500 1.1 riastrad case DMA_PACKET_CONSTANT_FILL: 2501 1.1 riastrad if (p->family < CHIP_RV770) { 2502 1.1 riastrad DRM_ERROR("Constant Fill is 7xx only !\n"); 2503 1.1 riastrad return -EINVAL; 2504 1.1 riastrad } 2505 1.1 riastrad r = r600_dma_cs_next_reloc(p, &dst_reloc); 2506 1.1 riastrad if (r) { 2507 1.1 riastrad DRM_ERROR("bad DMA_PACKET_WRITE\n"); 2508 1.1 riastrad return -EINVAL; 2509 1.1 riastrad } 2510 1.1 riastrad dst_offset = radeon_get_ib_value(p, idx+1); 2511 1.1 riastrad dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16; 2512 1.1 riastrad if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { 2513 1.1 riastrad dev_warn(p->dev, "DMA constant fill buffer too small (%"PRIu64" %lu)\n", 2514 1.1 riastrad dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); 2515 1.1 riastrad return -EINVAL; 2516 1.1 riastrad } 2517 1.1 riastrad ib[idx+1] += (u32)(dst_reloc->gpu_offset & 0xfffffffc); 2518 1.1 riastrad ib[idx+3] += (upper_32_bits(dst_reloc->gpu_offset) << 16) & 0x00ff0000; 2519 1.1 riastrad p->idx += 4; 2520 1.1 riastrad break; 2521 1.1 riastrad case DMA_PACKET_NOP: 2522 1.1 riastrad p->idx += 1; 2523 1.1 riastrad break; 2524 1.1 riastrad default: 2525 1.1 riastrad DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx); 2526 1.1 riastrad return -EINVAL; 2527 1.1 riastrad } 2528 1.1 riastrad } while (p->idx < p->chunk_ib->length_dw); 2529 1.1 riastrad #if 0 2530 1.1 riastrad for (r = 0; r < p->ib->length_dw; r++) { 2531 1.2 riastrad pr_info("%05d 0x%08X\n", r, p->ib.ptr[r]); 2532 1.1 riastrad mdelay(1); 2533 1.1 riastrad } 2534 1.1 riastrad #endif 2535 1.1 riastrad return 0; 2536 1.1 riastrad } 2537