31 #include "evergreen_reg_safe.h"
32 #include "cayman_reg_safe.h"
34 #define MAX(a,b) (((a)>(b))?(a):(b))
35 #define MIN(a,b) (((a)<(b))?(a):(b))
99 static u32 evergreen_cs_get_num_banks(
u32 nbanks)
118 for (i = 0; i < 8; i++) {
125 for (i = 0; i < 12; i++) {
157 for (i = 0; i < 4; i++) {
209 if (surf->
nbx & (palign - 1)) {
211 dev_warn(p->
dev,
"%s:%d %s pitch %d invalid must be aligned with %d\n",
212 __func__, __LINE__, prefix, surf->
nbx, palign);
227 palign =
MAX(8, palign);
232 if ((surf->
nbx & (palign - 1))) {
234 dev_warn(p->
dev,
"%s:%d %s pitch %d invalid must be aligned with %d (%d %d %d)\n",
235 __func__, __LINE__, prefix, surf->
nbx, palign,
240 if ((surf->
nby & (8 - 1))) {
242 dev_warn(p->
dev,
"%s:%d %s height %d invalid must be aligned with 8\n",
243 __func__, __LINE__, prefix, surf->
nby);
255 unsigned palign, halign, tileb, slice_pt;
256 unsigned mtile_pr, mtile_ps, mtileb;
260 if (tileb > surf->
tsplit) {
261 slice_pt = tileb / surf->
tsplit;
263 tileb = tileb / slice_pt;
267 mtileb = (palign / 8) * (halign / 8) * tileb;
268 mtile_pr = surf->
nbx / palign;
269 mtile_ps = (mtile_pr * surf->
nby) / halign;
270 surf->
layer_size = mtile_ps * mtileb * slice_pt;
271 surf->
base_align = (palign / 8) * (halign / 8) * tileb;
275 if ((surf->
nbx & (palign - 1))) {
277 dev_warn(p->
dev,
"%s:%d %s pitch %d invalid must be aligned with %d\n",
278 __func__, __LINE__, prefix, surf->
nbx, palign);
282 if ((surf->
nby & (halign - 1))) {
284 dev_warn(p->
dev,
"%s:%d %s height %d invalid must be aligned with %d\n",
285 __func__, __LINE__, prefix, surf->
nby, halign);
300 switch (surf->
mode) {
302 return evergreen_surface_check_linear(p, surf, prefix);
304 return evergreen_surface_check_linear_aligned(p, surf, prefix);
306 return evergreen_surface_check_1d(p, surf, prefix);
308 return evergreen_surface_check_2d(p, surf, prefix);
310 dev_warn(p->
dev,
"%s:%d %s invalid array mode %d\n",
311 __func__, __LINE__, prefix, surf->
mode);
321 switch (surf->
mode) {
329 dev_warn(p->
dev,
"%s:%d %s invalid array mode %d\n",
330 __func__, __LINE__, prefix, surf->
mode);
335 case 0: surf->
nbanks = 2;
break;
336 case 1: surf->
nbanks = 4;
break;
337 case 2: surf->
nbanks = 8;
break;
338 case 3: surf->
nbanks = 16;
break;
340 dev_warn(p->
dev,
"%s:%d %s invalid number of banks %d\n",
341 __func__, __LINE__, prefix, surf->
nbanks);
344 switch (surf->
bankw) {
345 case 0: surf->
bankw = 1;
break;
346 case 1: surf->
bankw = 2;
break;
347 case 2: surf->
bankw = 4;
break;
348 case 3: surf->
bankw = 8;
break;
351 __func__, __LINE__, prefix, surf->
bankw);
354 switch (surf->
bankh) {
355 case 0: surf->
bankh = 1;
break;
356 case 1: surf->
bankh = 2;
break;
357 case 2: surf->
bankh = 4;
break;
358 case 3: surf->
bankh = 8;
break;
361 __func__, __LINE__, prefix, surf->
bankh);
365 case 0: surf->
mtilea = 1;
break;
366 case 1: surf->
mtilea = 2;
break;
367 case 2: surf->
mtilea = 4;
break;
368 case 3: surf->
mtilea = 8;
break;
370 dev_warn(p->
dev,
"%s:%d %s invalid macro tile aspect %d\n",
371 __func__, __LINE__, prefix, surf->
mtilea);
375 case 0: surf->
tsplit = 64;
break;
376 case 1: surf->
tsplit = 128;
break;
377 case 2: surf->
tsplit = 256;
break;
378 case 3: surf->
tsplit = 512;
break;
379 case 4: surf->
tsplit = 1024;
break;
380 case 5: surf->
tsplit = 2048;
break;
381 case 6: surf->
tsplit = 4096;
break;
383 dev_warn(p->
dev,
"%s:%d %s invalid tile split %d\n",
384 __func__, __LINE__, prefix, surf->
tsplit);
390 static int evergreen_cs_track_validate_cb(
struct radeon_cs_parser *p,
unsigned id)
394 unsigned pitch,
slice, mslice;
401 surf.
nbx = (pitch + 1) * 8;
402 surf.
nby = ((slice + 1) * 64) / surf.
nbx;
413 dev_warn(p->
dev,
"%s:%d cb invalid format %d for %d (0x%08x)\n",
414 __func__, __LINE__, surf.
format,
419 r = evergreen_surface_value_conv_check(p, &surf,
"cb");
424 r = evergreen_surface_check(p, &surf,
"cb");
426 dev_warn(p->
dev,
"%s:%d cb[%d] invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
435 dev_warn(p->
dev,
"%s:%d cb[%d] bo base %ld not aligned with %ld\n",
436 __func__, __LINE__,
id, offset, surf.
base_align);
441 if (offset > radeon_bo_size(track->
cb_color_bo[
id])) {
447 volatile u32 *ib = p->
ib.ptr;
456 for (nby = surf.
nby; nby > min; nby--) {
458 if ((tmp + size * mslice) <= bsize) {
464 slice = ((nby * surf.
nbx) / 64) - 1;
465 if (!evergreen_surface_check(p, &surf,
"cb")) {
475 dev_warn(p->
dev,
"%s:%d cb[%d] bo too small (layer size %d, "
476 "offset %d, max layer %d, bo size %ld, slice %d)\n",
480 dev_warn(p->
dev,
"%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
481 __func__, __LINE__, surf.
nbx, surf.
nby,
493 unsigned nbx,
unsigned nby)
499 dev_warn(p->
dev,
"%s:%d htile enabled without htile surface 0x%08x\n",
529 __func__, __LINE__, track->
npipes);
536 size = nbx * nby * 4;
539 if (size > radeon_bo_size(track->
htile_bo)) {
540 dev_warn(p->
dev,
"%s:%d htile surface too small %ld for %ld (%d %d)\n",
541 __func__, __LINE__, radeon_bo_size(track->
htile_bo),
552 unsigned pitch, slice, mslice;
559 surf.
nbx = (pitch + 1) * 8;
560 surf.
nby = ((slice + 1) * 64) / surf.
nbx;
571 dev_warn(p->
dev,
"%s:%d stencil invalid format %d\n",
572 __func__, __LINE__, surf.
format);
578 r = evergreen_surface_value_conv_check(p, &surf,
"stencil");
583 r = evergreen_surface_check(p, &surf,
NULL);
590 r = evergreen_surface_check(p, &surf,
"stencil");
592 dev_warn(p->
dev,
"%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
601 dev_warn(p->
dev,
"%s:%d stencil read bo base %ld not aligned with %ld\n",
607 dev_warn(p->
dev,
"%s:%d stencil read bo too small (layer size %d, "
608 "offset %ld, max layer %d, bo size %ld)\n",
612 dev_warn(p->
dev,
"%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
620 dev_warn(p->
dev,
"%s:%d stencil write bo base %ld not aligned with %ld\n",
626 dev_warn(p->
dev,
"%s:%d stencil write bo too small (layer size %d, "
627 "offset %ld, max layer %d, bo size %ld)\n",
636 r = evergreen_cs_track_validate_htile(p, surf.
nbx, surf.
nby);
649 unsigned pitch, slice, mslice;
656 surf.
nbx = (pitch + 1) * 8;
657 surf.
nby = ((slice + 1) * 64) / surf.
nbx;
676 dev_warn(p->
dev,
"%s:%d depth invalid format %d\n",
677 __func__, __LINE__, surf.
format);
681 r = evergreen_surface_value_conv_check(p, &surf,
"depth");
683 dev_warn(p->
dev,
"%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
689 r = evergreen_surface_check(p, &surf,
"depth");
691 dev_warn(p->
dev,
"%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n",
699 dev_warn(p->
dev,
"%s:%d stencil read bo base %ld not aligned with %ld\n",
705 dev_warn(p->
dev,
"%s:%d depth read bo too small (layer size %d, "
706 "offset %ld, max layer %d, bo size %ld)\n",
715 dev_warn(p->
dev,
"%s:%d stencil write bo base %ld not aligned with %ld\n",
721 dev_warn(p->
dev,
"%s:%d depth write bo too small (layer size %d, "
722 "offset %ld, max layer %d, bo size %ld)\n",
731 r = evergreen_cs_track_validate_htile(p, surf.
nbx, surf.
nby);
746 unsigned long toffset, moffset;
776 toffset = texdw[2] << 8;
777 moffset = texdw[3] << 8;
780 dev_warn(p->
dev,
"%s:%d texture invalid format %d\n",
781 __func__, __LINE__, surf.
format);
801 dev_warn(p->
dev,
"%s:%d texture invalid dimension %d\n",
802 __func__, __LINE__, dim);
806 r = evergreen_surface_value_conv_check(p, &surf,
"texture");
812 evergreen_surface_check(p, &surf,
NULL);
815 r = evergreen_surface_check(p, &surf,
"texture");
817 dev_warn(p->
dev,
"%s:%d texture invalid 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
818 __func__, __LINE__, texdw[0], texdw[1], texdw[4],
819 texdw[5], texdw[6], texdw[7]);
825 dev_warn(p->
dev,
"%s:%d texture bo base %ld not aligned with %ld\n",
826 __func__, __LINE__, toffset, surf.
base_align);
830 dev_warn(p->
dev,
"%s:%d mipmap bo base %ld not aligned with %ld\n",
831 __func__, __LINE__, moffset, surf.
base_align);
839 if (toffset > radeon_bo_size(texture)) {
840 dev_warn(p->
dev,
"%s:%d texture bo too small (layer size %d, "
841 "offset %ld, max layer %d, depth %d, bo size %ld) (%d %d)\n",
843 (
unsigned long)texdw[2] << 8, mslice,
844 depth, radeon_bo_size(texture),
851 dev_warn(p->
dev,
"%s:%i got NULL MIP_ADDRESS relocation\n",
860 for (i = 1; i <= llevel; i++) {
875 evergreen_surface_check(p, &surf,
NULL);
883 __func__, __LINE__, surf.
mode);
889 r = evergreen_surface_check(p, &surf,
"mipmap");
899 if (moffset > radeon_bo_size(mipmap)) {
900 dev_warn(p->
dev,
"%s:%d mipmap [%d] bo too small (layer size %d, "
901 "offset %ld, coffset %ld, max layer %d, depth %d, "
902 "bo size %ld) level0 (%d %d %d)\n",
904 (
unsigned long)texdw[3] << 8, moffset, mslice,
905 d, radeon_bo_size(mipmap),
906 width, height, depth);
907 dev_warn(p->
dev,
"%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
908 __func__, __LINE__, surf.
nbx, surf.
nby,
924 unsigned buffer_mask = 0;
928 for (i = 0; i < 4; i++) {
934 for (i = 0; i < 4; i++) {
935 if (buffer_mask & (1 << i)) {
940 DRM_ERROR(
"streamout %d bo too small: 0x%llx, 0x%lx\n",
946 dev_warn(p->
dev,
"No buffer for streamout %d\n", i);
961 for (i = 0; i < 8; i++) {
962 if ((tmp >> (i * 4)) & 0xF) {
965 dev_warn(p->
dev,
"%s:%d mask 0x%08X | 0x%08X no cb for %d\n",
970 r = evergreen_cs_track_validate_cb(p, i);
983 r = evergreen_cs_track_validate_stencil(p);
990 r = evergreen_cs_track_validate_depth(p);
1016 DRM_ERROR(
"Can not parse packet at %d after CS end %d !\n",
1025 switch (pkt->
type) {
1036 DRM_ERROR(
"Unknown packet type %d at %d !\n", pkt->
type, idx);
1040 DRM_ERROR(
"Packet (%d:%d:%d) end after CS buffer (%d) !\n",
1067 DRM_ERROR(
"No relocation chunk !\n");
1072 r = evergreen_cs_packet_parse(p, &p3reloc, p->
idx);
1076 p->
idx += p3reloc.count + 2;
1078 DRM_ERROR(
"No packet3 for relocation for packet at %d.\n",
1084 DRM_ERROR(
"Relocs at %d after relocations chunk end %d !\n",
1099 static bool evergreen_cs_packet_next_is_pkt3_nop(
struct radeon_cs_parser *p)
1104 r = evergreen_cs_packet_parse(p, &p3reloc, p->
idx);
1142 r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->
idx);
1149 DRM_ERROR(
"vline wait missing WAIT_REG_MEM segment\n");
1155 if (wait_reg_mem_info & 0x10) {
1156 DRM_ERROR(
"vline WAIT_REG_MEM waiting on MEM rather than REG\n");
1160 if ((wait_reg_mem_info & 0x7) != 0x3) {
1161 DRM_ERROR(
"vline WAIT_REG_MEM function not equal\n");
1165 DRM_ERROR(
"vline WAIT_REG_MEM bad reg\n");
1170 DRM_ERROR(
"vline WAIT_REG_MEM bad bit mask\n");
1175 r = evergreen_cs_packet_parse(p, &p3reloc, p->
idx + wait_reg_mem.count + 2);
1180 p->
idx += wait_reg_mem.count + 2;
1181 p->
idx += p3reloc.count + 2;
1188 DRM_ERROR(
"cannot find crtc %d\n", crtc_id);
1193 crtc_id = radeon_crtc->
crtc_id;
1213 DRM_ERROR(
"unknown crtc reloc\n");
1222 unsigned idx,
unsigned reg)
1228 r = evergreen_cs_packet_parse_vline(p);
1230 DRM_ERROR(
"No reloc for ib[%d]=0x%04X\n",
1252 for (i = 0; i <= pkt->
count; i++, idx++, reg += 4) {
1253 r = evergreen_packet0_check(p, pkt, idx, reg);
1282 last_reg =
ARRAY_SIZE(evergreen_reg_safe_bm);
1285 if (i >= last_reg) {
1286 dev_warn(p->
dev,
"forbidden register 0x%08x at %d\n", reg, idx);
1289 m = 1 << ((reg >> 2) & 31);
1291 if (!(cayman_reg_safe_bm[i] & m))
1294 if (!(evergreen_reg_safe_bm[i] & m))
1339 r = evergreen_cs_packet_next_reloc(p, &reloc);
1345 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1368 r = evergreen_cs_packet_next_reloc(p, &reloc);
1376 ib[
idx] |=
Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
1379 unsigned bankw, bankh, mtaspect, tile_split;
1382 &bankw, &bankh, &mtaspect,
1410 r = evergreen_cs_packet_next_reloc(p, &reloc);
1417 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1422 r = evergreen_cs_packet_next_reloc(p, &reloc);
1429 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1434 r = evergreen_cs_packet_next_reloc(p, &reloc);
1441 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1446 r = evergreen_cs_packet_next_reloc(p, &reloc);
1453 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1469 r = evergreen_cs_packet_next_reloc(p, &reloc);
1477 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1491 r = evergreen_cs_packet_next_reloc(p, &reloc);
1493 dev_warn(p->
dev,
"missing reloc for CP_COHER_BASE "
1497 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1555 r = evergreen_cs_packet_next_reloc(p, &reloc);
1561 ib[
idx] |=
CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
1573 r = evergreen_cs_packet_next_reloc(p, &reloc);
1579 ib[
idx] |=
CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags));
1634 r = evergreen_cs_packet_next_reloc(p, &reloc);
1642 unsigned bankw, bankh, mtaspect, tile_split;
1645 &bankw, &bankh, &mtaspect,
1662 r = evergreen_cs_packet_next_reloc(p, &reloc);
1670 unsigned bankw, bankh, mtaspect, tile_split;
1673 &bankw, &bankh, &mtaspect,
1695 r = evergreen_cs_packet_next_reloc(p, &reloc);
1697 dev_err(p->
dev,
"bad SET_CONTEXT_REG 0x%04X\n", reg);
1700 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1712 r = evergreen_cs_packet_next_reloc(p, &reloc);
1714 dev_err(p->
dev,
"bad SET_CONTEXT_REG 0x%04X\n", reg);
1717 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1750 r = evergreen_cs_packet_next_reloc(p, &reloc);
1758 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1766 r = evergreen_cs_packet_next_reloc(p, &reloc);
1774 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1779 r = evergreen_cs_packet_next_reloc(p, &reloc);
1786 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1895 r = evergreen_cs_packet_next_reloc(p, &reloc);
1901 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1909 r = evergreen_cs_packet_next_reloc(p, &reloc);
1915 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1923 r = evergreen_cs_packet_next_reloc(p, &reloc);
1929 ib[
idx] += (
u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
1935 dev_warn(p->
dev,
"forbidden register 0x%08x at %d\n", reg, idx);
1948 last_reg =
ARRAY_SIZE(evergreen_reg_safe_bm);
1951 if (i >= last_reg) {
1952 dev_warn(p->
dev,
"forbidden register 0x%08x at %d\n", reg, idx);
1955 m = 1 << ((reg >> 2) & 31);
1957 if (!(cayman_reg_safe_bm[i] & m))
1960 if (!(evergreen_reg_safe_bm[i] & m))
1963 dev_warn(p->
dev,
"forbidden register 0x%08x at %d\n", reg, idx);
1975 unsigned start_reg, end_reg,
reg;
1991 if (pkt->
count != 1) {
1992 DRM_ERROR(
"bad SET PREDICATION\n");
1997 pred_op = (tmp >> 16) & 0x7;
2004 DRM_ERROR(
"bad SET PREDICATION operation %d\n", pred_op);
2008 r = evergreen_cs_packet_next_reloc(p, &reloc);
2010 DRM_ERROR(
"bad SET PREDICATION\n");
2014 offset = reloc->
lobj.gpu_offset +
2015 (idx_value & 0xfffffff0) +
2016 ((
u64)(tmp & 0xff) << 32);
2019 ib[idx + 1] = (tmp & 0xffffff00) | (
upper_32_bits(offset) & 0xff);
2023 if (pkt->
count != 1) {
2024 DRM_ERROR(
"bad CONTEXT_CONTROL\n");
2032 DRM_ERROR(
"bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
2038 DRM_ERROR(
"bad PACKET3_DEALLOC_STATE\n");
2042 DRM_ERROR(
"bad INDEX_TYPE/NUM_INSTANCES/CLEAR_STATE\n");
2050 if (pkt->
count != 1) {
2051 DRM_ERROR(
"bad INDEX_BASE\n");
2054 r = evergreen_cs_packet_next_reloc(p, &reloc);
2056 DRM_ERROR(
"bad INDEX_BASE\n");
2060 offset = reloc->
lobj.gpu_offset +
2067 r = evergreen_cs_track_check(p);
2069 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2077 if (pkt->
count != 3) {
2078 DRM_ERROR(
"bad DRAW_INDEX\n");
2081 r = evergreen_cs_packet_next_reloc(p, &reloc);
2083 DRM_ERROR(
"bad DRAW_INDEX\n");
2087 offset = reloc->
lobj.gpu_offset +
2094 r = evergreen_cs_track_check(p);
2096 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2105 if (pkt->
count != 4) {
2106 DRM_ERROR(
"bad DRAW_INDEX_2\n");
2109 r = evergreen_cs_packet_next_reloc(p, &reloc);
2111 DRM_ERROR(
"bad DRAW_INDEX_2\n");
2115 offset = reloc->
lobj.gpu_offset +
2122 r = evergreen_cs_track_check(p);
2124 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2130 if (pkt->
count != 1) {
2131 DRM_ERROR(
"bad DRAW_INDEX_AUTO\n");
2134 r = evergreen_cs_track_check(p);
2136 dev_warn(p->
dev,
"%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
2141 if (pkt->
count != 2) {
2142 DRM_ERROR(
"bad DRAW_INDEX_MULTI_AUTO\n");
2145 r = evergreen_cs_track_check(p);
2147 dev_warn(p->
dev,
"%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
2152 if (pkt->
count < 2) {
2153 DRM_ERROR(
"bad DRAW_INDEX_IMMD\n");
2156 r = evergreen_cs_track_check(p);
2158 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2163 if (pkt->
count != 2) {
2164 DRM_ERROR(
"bad DRAW_INDEX_OFFSET\n");
2167 r = evergreen_cs_track_check(p);
2169 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2174 if (pkt->
count != 3) {
2175 DRM_ERROR(
"bad DRAW_INDEX_OFFSET_2\n");
2178 r = evergreen_cs_track_check(p);
2180 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2185 if (pkt->
count != 3) {
2186 DRM_ERROR(
"bad DISPATCH_DIRECT\n");
2189 r = evergreen_cs_track_check(p);
2191 dev_warn(p->
dev,
"%s:%d invalid cmd stream %d\n", __func__, __LINE__, idx);
2196 if (pkt->
count != 1) {
2197 DRM_ERROR(
"bad DISPATCH_INDIRECT\n");
2200 r = evergreen_cs_packet_next_reloc(p, &reloc);
2202 DRM_ERROR(
"bad DISPATCH_INDIRECT\n");
2205 ib[idx+0] = idx_value + (
u32)(reloc->
lobj.gpu_offset & 0xffffffff);
2206 r = evergreen_cs_track_check(p);
2208 dev_warn(p->
dev,
"%s:%d invalid cmd stream\n", __func__, __LINE__);
2213 if (pkt->
count != 5) {
2214 DRM_ERROR(
"bad WAIT_REG_MEM\n");
2218 if (idx_value & 0x10) {
2221 r = evergreen_cs_packet_next_reloc(p, &reloc);
2223 DRM_ERROR(
"bad WAIT_REG_MEM\n");
2227 offset = reloc->
lobj.gpu_offset +
2231 ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc);
2236 if (pkt->
count != 3) {
2237 DRM_ERROR(
"bad SURFACE_SYNC\n");
2243 r = evergreen_cs_packet_next_reloc(p, &reloc);
2245 DRM_ERROR(
"bad SURFACE_SYNC\n");
2248 ib[idx+2] += (
u32)((reloc->
lobj.gpu_offset >> 8) & 0xffffffff);
2253 DRM_ERROR(
"bad EVENT_WRITE\n");
2259 r = evergreen_cs_packet_next_reloc(p, &reloc);
2261 DRM_ERROR(
"bad EVENT_WRITE\n");
2264 offset = reloc->
lobj.gpu_offset +
2268 ib[idx+1] = offset & 0xfffffff8;
2276 if (pkt->
count != 4) {
2277 DRM_ERROR(
"bad EVENT_WRITE_EOP\n");
2280 r = evergreen_cs_packet_next_reloc(p, &reloc);
2282 DRM_ERROR(
"bad EVENT_WRITE_EOP\n");
2286 offset = reloc->
lobj.gpu_offset +
2290 ib[idx+1] = offset & 0xfffffffc;
2291 ib[idx+2] = (ib[idx+2] & 0xffffff00) | (
upper_32_bits(offset) & 0xff);
2298 if (pkt->
count != 3) {
2299 DRM_ERROR(
"bad EVENT_WRITE_EOS\n");
2302 r = evergreen_cs_packet_next_reloc(p, &reloc);
2304 DRM_ERROR(
"bad EVENT_WRITE_EOS\n");
2308 offset = reloc->
lobj.gpu_offset +
2312 ib[idx+1] = offset & 0xfffffffc;
2313 ib[idx+2] = (ib[idx+2] & 0xffffff00) | (
upper_32_bits(offset) & 0xff);
2318 end_reg = 4 * pkt->
count + start_reg - 4;
2322 DRM_ERROR(
"bad PACKET3_SET_CONFIG_REG\n");
2325 for (i = 0; i < pkt->
count; i++) {
2326 reg = start_reg + (4 *
i);
2327 r = evergreen_cs_check_reg(p, reg, idx+1+i);
2334 end_reg = 4 * pkt->
count + start_reg - 4;
2338 DRM_ERROR(
"bad PACKET3_SET_CONTEXT_REG\n");
2341 for (i = 0; i < pkt->
count; i++) {
2342 reg = start_reg + (4 *
i);
2343 r = evergreen_cs_check_reg(p, reg, idx+1+i);
2349 if (pkt->
count % 8) {
2350 DRM_ERROR(
"bad SET_RESOURCE\n");
2354 end_reg = 4 * pkt->
count + start_reg - 4;
2358 DRM_ERROR(
"bad SET_RESOURCE\n");
2361 for (i = 0; i < (pkt->
count / 8); i++) {
2363 u32 toffset, moffset;
2369 r = evergreen_cs_packet_next_reloc(p, &reloc);
2371 DRM_ERROR(
"bad SET_RESOURCE (tex)\n");
2375 ib[idx+1+(i*8)+1] |=
2378 unsigned bankw, bankh, mtaspect, tile_split;
2381 &bankw, &bankh, &mtaspect,
2384 ib[idx+1+(i*8)+7] |=
2391 texture = reloc->
robj;
2392 toffset = (
u32)((reloc->
lobj.gpu_offset >> 8) & 0xffffffff);
2395 tex_dim = ib[idx+1+(i*8)+0] & 0x7;
2396 mip_address = ib[idx+1+(i*8)+3];
2400 !evergreen_cs_packet_next_is_pkt3_nop(p)) {
2406 r = evergreen_cs_packet_next_reloc(p, &reloc);
2408 DRM_ERROR(
"bad SET_RESOURCE (tex)\n");
2411 moffset = (
u32)((reloc->
lobj.gpu_offset >> 8) & 0xffffffff);
2412 mipmap = reloc->
robj;
2415 r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8));
2418 ib[idx+1+(i*8)+2] += toffset;
2419 ib[idx+1+(i*8)+3] += moffset;
2425 r = evergreen_cs_packet_next_reloc(p, &reloc);
2427 DRM_ERROR(
"bad SET_RESOURCE (vtx)\n");
2432 if (p->
rdev && (size + offset) > radeon_bo_size(reloc->
robj)) {
2434 dev_warn(p->
dev,
"vbo resource seems too big for the bo\n");
2435 ib[idx+1+(i*8)+1] = radeon_bo_size(reloc->
robj) -
offset;
2439 ib[idx+1+(i*8)+0] = offset64;
2440 ib[idx+1+(i*8)+2] = (ib[idx+1+(i*8)+2] & 0xffffff00) |
2447 DRM_ERROR(
"bad SET_RESOURCE\n");
2457 end_reg = 4 * pkt->
count + start_reg - 4;
2461 DRM_ERROR(
"bad SET_BOOL_CONST\n");
2467 end_reg = 4 * pkt->
count + start_reg - 4;
2471 DRM_ERROR(
"bad SET_LOOP_CONST\n");
2477 end_reg = 4 * pkt->
count + start_reg - 4;
2481 DRM_ERROR(
"bad SET_CTL_CONST\n");
2486 if (pkt->
count % 3) {
2487 DRM_ERROR(
"bad SET_SAMPLER\n");
2491 end_reg = 4 * pkt->
count + start_reg - 4;
2495 DRM_ERROR(
"bad SET_SAMPLER\n");
2500 if (pkt->
count != 4) {
2501 DRM_ERROR(
"bad STRMOUT_BUFFER_UPDATE (invalid count)\n");
2505 if (idx_value & 0x1) {
2507 r = evergreen_cs_packet_next_reloc(p, &reloc);
2509 DRM_ERROR(
"bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n");
2514 if ((offset + 4) > radeon_bo_size(reloc->
robj)) {
2515 DRM_ERROR(
"bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n",
2516 offset + 4, radeon_bo_size(reloc->
robj));
2519 offset += reloc->
lobj.gpu_offset;
2524 if (((idx_value >> 1) & 0x3) == 2) {
2526 r = evergreen_cs_packet_next_reloc(p, &reloc);
2528 DRM_ERROR(
"bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n");
2533 if ((offset + 4) > radeon_bo_size(reloc->
robj)) {
2534 DRM_ERROR(
"bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n",
2535 offset + 4, radeon_bo_size(reloc->
robj));
2538 offset += reloc->
lobj.gpu_offset;
2544 if (pkt->
count != 4) {
2545 DRM_ERROR(
"bad COPY_DW (invalid count)\n");
2548 if (idx_value & 0x1) {
2551 r = evergreen_cs_packet_next_reloc(p, &reloc);
2553 DRM_ERROR(
"bad COPY_DW (missing src reloc)\n");
2558 if ((offset + 4) > radeon_bo_size(reloc->
robj)) {
2559 DRM_ERROR(
"bad COPY_DW src bo too small: 0x%llx, 0x%lx\n",
2560 offset + 4, radeon_bo_size(reloc->
robj));
2563 offset += reloc->
lobj.gpu_offset;
2569 if (!evergreen_is_safe_reg(p, reg, idx+1))
2572 if (idx_value & 0x2) {
2575 r = evergreen_cs_packet_next_reloc(p, &reloc);
2577 DRM_ERROR(
"bad COPY_DW (missing dst reloc)\n");
2582 if ((offset + 4) > radeon_bo_size(reloc->
robj)) {
2583 DRM_ERROR(
"bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n",
2584 offset + 4, radeon_bo_size(reloc->
robj));
2587 offset += reloc->
lobj.gpu_offset;
2593 if (!evergreen_is_safe_reg(p, reg, idx+3))
2600 DRM_ERROR(
"Packet3 opcode %x not supported\n", pkt->
opcode);
2618 evergreen_cs_track_init(track);
2620 tmp = p->
rdev->config.cayman.tile_config;
2622 tmp = p->
rdev->config.evergreen.tile_config;
2624 switch (tmp & 0xf) {
2640 switch ((tmp & 0xf0) >> 4) {
2653 switch ((tmp & 0xf00) >> 8) {
2663 switch ((tmp & 0xf000) >> 12) {
2679 r = evergreen_cs_packet_parse(p, &pkt, p->
idx);
2688 r = evergreen_cs_parse_packet0(p, &pkt);
2693 r = evergreen_packet3_check(p, &pkt);
2696 DRM_ERROR(
"Unknown packet type %d !\n", pkt.
type);
2708 for (r = 0; r < p->
ib.length_dw; r++) {
2719 static bool evergreen_vm_reg_valid(
u32 reg)
2835 DRM_ERROR(
"Invalid register 0x%x in CS\n", reg);
2845 u32 start_reg, end_reg,
reg,
i;
2892 if (idx_value & 0x100) {
2893 reg = ib[idx + 5] * 4;
2894 if (!evergreen_vm_reg_valid(reg))
2899 if (idx_value & 0x2) {
2900 reg = ib[idx + 3] * 4;
2901 if (!evergreen_vm_reg_valid(reg))
2907 end_reg = 4 * pkt->
count + start_reg - 4;
2911 DRM_ERROR(
"bad PACKET3_SET_CONFIG_REG\n");
2914 for (i = 0; i < pkt->
count; i++) {
2915 reg = start_reg + (4 *
i);
2916 if (!evergreen_vm_reg_valid(reg))
2939 dev_err(rdev->
dev,
"Packet0 not allowed!\n");
2947 ret = evergreen_vm_packet3_check(rdev, ib->
ptr, &pkt);
2948 idx += pkt.
count + 2;
2957 }
while (idx < ib->length_dw);