diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 19:46:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 19:46:44 -0500 |
commit | fffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb (patch) | |
tree | 71bc5e597124dbaf7550f1e089d675718b3ed5c0 /drivers/gpu/drm/radeon/evergreen_cs.c | |
parent | 69086a78bdc973ec0b722be790b146e84ba8a8c4 (diff) | |
parent | be88298b0a3f771a4802f20c5e66af74bfd1dff1 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm merge from Dave Airlie:
"Highlights:
- TI LCD controller KMS driver
- TI OMAP KMS driver merged from staging
- drop gma500 stub driver
- the fbcon locking fixes
- the vgacon dirty like zebra fix.
- open firmware videomode and hdmi common code helpers
- major locking rework for kms object handling - pageflip/cursor
won't block on polling anymore!
- fbcon helper and prime helper cleanups
- i915: all over the map, haswell power well enhancements, valleyview
macro horrors cleaned up, killing lots of legacy GTT code,
- radeon: CS ioctl unification, deprecated UMS support, gpu reset
rework, VM fixes
- nouveau: reworked thermal code, external dp/tmds encoder support
(anx9805), fences sleep instead of polling,
- exynos: all over the driver fixes."
Lovely conflict in radeon/evergreen_cs.c between commit de0babd60d8d
("drm/radeon: enforce use of radeon_get_ib_value when reading user cmd")
and the new changes that modified that evergreen_dma_cs_parse()
function.
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (508 commits)
drm/tilcdc: only build on arm
drm/i915: Revert hdmi HDP pin checks
drm/tegra: Add list of framebuffers to debugfs
drm/tegra: Fix color expansion
drm/tegra: Split DC_CMD_STATE_CONTROL register write
drm/tegra: Implement page-flipping support
drm/tegra: Implement VBLANK support
drm/tegra: Implement .mode_set_base()
drm/tegra: Add plane support
drm/tegra: Remove bogus tegra_framebuffer structure
drm: Add consistency check for page-flipping
drm/radeon: Use generic HDMI infoframe helpers
drm/tegra: Use generic HDMI infoframe helpers
drm: Add EDID helper documentation
drm: Add HDMI infoframe helpers
video: Add generic HDMI infoframe helpers
drm: Add some missing forward declarations
drm: Move mode tables to drm_edid.c
drm: Remove duplicate drm_mode_cea_vic()
gma500: Fix n, m1 and m2 clock limits for sdvo and lvds
...
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen_cs.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_cs.c | 1149 |
1 files changed, 470 insertions, 679 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index ee4cff534f10..99fb13286fd0 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -36,9 +36,6 @@ | |||
36 | 36 | ||
37 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, | 37 | int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, |
38 | struct radeon_cs_reloc **cs_reloc); | 38 | struct radeon_cs_reloc **cs_reloc); |
39 | static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, | ||
40 | struct radeon_cs_reloc **cs_reloc); | ||
41 | |||
42 | struct evergreen_cs_track { | 39 | struct evergreen_cs_track { |
43 | u32 group_size; | 40 | u32 group_size; |
44 | u32 nbanks; | 41 | u32 nbanks; |
@@ -1009,223 +1006,35 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
1009 | } | 1006 | } |
1010 | 1007 | ||
1011 | /** | 1008 | /** |
1012 | * evergreen_cs_packet_parse() - parse cp packet and point ib index to next packet | 1009 | * evergreen_cs_packet_parse_vline() - parse userspace VLINE packet |
1013 | * @parser: parser structure holding parsing context. | ||
1014 | * @pkt: where to store packet informations | ||
1015 | * | ||
1016 | * Assume that chunk_ib_index is properly set. Will return -EINVAL | ||
1017 | * if packet is bigger than remaining ib size. or if packets is unknown. | ||
1018 | **/ | ||
1019 | static int evergreen_cs_packet_parse(struct radeon_cs_parser *p, | ||
1020 | struct radeon_cs_packet *pkt, | ||
1021 | unsigned idx) | ||
1022 | { | ||
1023 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
1024 | uint32_t header; | ||
1025 | |||
1026 | if (idx >= ib_chunk->length_dw) { | ||
1027 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", | ||
1028 | idx, ib_chunk->length_dw); | ||
1029 | return -EINVAL; | ||
1030 | } | ||
1031 | header = radeon_get_ib_value(p, idx); | ||
1032 | pkt->idx = idx; | ||
1033 | pkt->type = CP_PACKET_GET_TYPE(header); | ||
1034 | pkt->count = CP_PACKET_GET_COUNT(header); | ||
1035 | pkt->one_reg_wr = 0; | ||
1036 | switch (pkt->type) { | ||
1037 | case PACKET_TYPE0: | ||
1038 | pkt->reg = CP_PACKET0_GET_REG(header); | ||
1039 | break; | ||
1040 | case PACKET_TYPE3: | ||
1041 | pkt->opcode = CP_PACKET3_GET_OPCODE(header); | ||
1042 | break; | ||
1043 | case PACKET_TYPE2: | ||
1044 | pkt->count = -1; | ||
1045 | break; | ||
1046 | default: | ||
1047 | DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx); | ||
1048 | return -EINVAL; | ||
1049 | } | ||
1050 | if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) { | ||
1051 | DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n", | ||
1052 | pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw); | ||
1053 | return -EINVAL; | ||
1054 | } | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | /** | ||
1059 | * evergreen_cs_packet_next_reloc() - parse next packet which should be reloc packet3 | ||
1060 | * @parser: parser structure holding parsing context. | 1010 | * @parser: parser structure holding parsing context. |
1061 | * @data: pointer to relocation data | ||
1062 | * @offset_start: starting offset | ||
1063 | * @offset_mask: offset mask (to align start offset on) | ||
1064 | * @reloc: reloc informations | ||
1065 | * | 1011 | * |
1066 | * Check next packet is relocation packet3, do bo validation and compute | 1012 | * This is an Evergreen(+)-specific function for parsing VLINE packets. |
1067 | * GPU offset using the provided start. | 1013 | * Real work is done by r600_cs_common_vline_parse function. |
1068 | **/ | 1014 | * Here we just set up ASIC-specific register table and call |
1069 | static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, | 1015 | * the common implementation function. |
1070 | struct radeon_cs_reloc **cs_reloc) | ||
1071 | { | ||
1072 | struct radeon_cs_chunk *relocs_chunk; | ||
1073 | struct radeon_cs_packet p3reloc; | ||
1074 | unsigned idx; | ||
1075 | int r; | ||
1076 | |||
1077 | if (p->chunk_relocs_idx == -1) { | ||
1078 | DRM_ERROR("No relocation chunk !\n"); | ||
1079 | return -EINVAL; | ||
1080 | } | ||
1081 | *cs_reloc = NULL; | ||
1082 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | ||
1083 | r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); | ||
1084 | if (r) { | ||
1085 | return r; | ||
1086 | } | ||
1087 | p->idx += p3reloc.count + 2; | ||
1088 | if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { | ||
1089 | DRM_ERROR("No packet3 for relocation for packet at %d.\n", | ||
1090 | p3reloc.idx); | ||
1091 | return -EINVAL; | ||
1092 | } | ||
1093 | idx = radeon_get_ib_value(p, p3reloc.idx + 1); | ||
1094 | if (idx >= relocs_chunk->length_dw) { | ||
1095 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | ||
1096 | idx, relocs_chunk->length_dw); | ||
1097 | return -EINVAL; | ||
1098 | } | ||
1099 | /* FIXME: we assume reloc size is 4 dwords */ | ||
1100 | *cs_reloc = p->relocs_ptr[(idx / 4)]; | ||
1101 | return 0; | ||
1102 | } | ||
1103 | |||
1104 | /** | ||
1105 | * evergreen_cs_packet_next_is_pkt3_nop() - test if the next packet is NOP | ||
1106 | * @p: structure holding the parser context. | ||
1107 | * | ||
1108 | * Check if the next packet is a relocation packet3. | ||
1109 | **/ | ||
1110 | static bool evergreen_cs_packet_next_is_pkt3_nop(struct radeon_cs_parser *p) | ||
1111 | { | ||
1112 | struct radeon_cs_packet p3reloc; | ||
1113 | int r; | ||
1114 | |||
1115 | r = evergreen_cs_packet_parse(p, &p3reloc, p->idx); | ||
1116 | if (r) { | ||
1117 | return false; | ||
1118 | } | ||
1119 | if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) { | ||
1120 | return false; | ||
1121 | } | ||
1122 | return true; | ||
1123 | } | ||
1124 | |||
1125 | /** | ||
1126 | * evergreen_cs_packet_next_vline() - parse userspace VLINE packet | ||
1127 | * @parser: parser structure holding parsing context. | ||
1128 | * | ||
1129 | * Userspace sends a special sequence for VLINE waits. | ||
1130 | * PACKET0 - VLINE_START_END + value | ||
1131 | * PACKET3 - WAIT_REG_MEM poll vline status reg | ||
1132 | * RELOC (P3) - crtc_id in reloc. | ||
1133 | * | ||
1134 | * This function parses this and relocates the VLINE START END | ||
1135 | * and WAIT_REG_MEM packets to the correct crtc. | ||
1136 | * It also detects a switched off crtc and nulls out the | ||
1137 | * wait in that case. | ||
1138 | */ | 1016 | */ |
1139 | static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) | 1017 | static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) |
1140 | { | 1018 | { |
1141 | struct drm_mode_object *obj; | ||
1142 | struct drm_crtc *crtc; | ||
1143 | struct radeon_crtc *radeon_crtc; | ||
1144 | struct radeon_cs_packet p3reloc, wait_reg_mem; | ||
1145 | int crtc_id; | ||
1146 | int r; | ||
1147 | uint32_t header, h_idx, reg, wait_reg_mem_info; | ||
1148 | volatile uint32_t *ib; | ||
1149 | |||
1150 | ib = p->ib.ptr; | ||
1151 | |||
1152 | /* parse the WAIT_REG_MEM */ | ||
1153 | r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx); | ||
1154 | if (r) | ||
1155 | return r; | ||
1156 | |||
1157 | /* check its a WAIT_REG_MEM */ | ||
1158 | if (wait_reg_mem.type != PACKET_TYPE3 || | ||
1159 | wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { | ||
1160 | DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); | ||
1161 | return -EINVAL; | ||
1162 | } | ||
1163 | |||
1164 | wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); | ||
1165 | /* bit 4 is reg (0) or mem (1) */ | ||
1166 | if (wait_reg_mem_info & 0x10) { | ||
1167 | DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); | ||
1168 | return -EINVAL; | ||
1169 | } | ||
1170 | /* waiting for value to be equal */ | ||
1171 | if ((wait_reg_mem_info & 0x7) != 0x3) { | ||
1172 | DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); | ||
1173 | return -EINVAL; | ||
1174 | } | ||
1175 | if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != EVERGREEN_VLINE_STATUS) { | ||
1176 | DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); | ||
1177 | return -EINVAL; | ||
1178 | } | ||
1179 | |||
1180 | if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != EVERGREEN_VLINE_STAT) { | ||
1181 | DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); | ||
1182 | return -EINVAL; | ||
1183 | } | ||
1184 | |||
1185 | /* jump over the NOP */ | ||
1186 | r = evergreen_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); | ||
1187 | if (r) | ||
1188 | return r; | ||
1189 | |||
1190 | h_idx = p->idx - 2; | ||
1191 | p->idx += wait_reg_mem.count + 2; | ||
1192 | p->idx += p3reloc.count + 2; | ||
1193 | 1019 | ||
1194 | header = radeon_get_ib_value(p, h_idx); | 1020 | static uint32_t vline_start_end[6] = { |
1195 | crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); | 1021 | EVERGREEN_VLINE_START_END + EVERGREEN_CRTC0_REGISTER_OFFSET, |
1196 | reg = CP_PACKET0_GET_REG(header); | 1022 | EVERGREEN_VLINE_START_END + EVERGREEN_CRTC1_REGISTER_OFFSET, |
1197 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); | 1023 | EVERGREEN_VLINE_START_END + EVERGREEN_CRTC2_REGISTER_OFFSET, |
1198 | if (!obj) { | 1024 | EVERGREEN_VLINE_START_END + EVERGREEN_CRTC3_REGISTER_OFFSET, |
1199 | DRM_ERROR("cannot find crtc %d\n", crtc_id); | 1025 | EVERGREEN_VLINE_START_END + EVERGREEN_CRTC4_REGISTER_OFFSET, |
1200 | return -EINVAL; | 1026 | EVERGREEN_VLINE_START_END + EVERGREEN_CRTC5_REGISTER_OFFSET |
1201 | } | 1027 | }; |
1202 | crtc = obj_to_crtc(obj); | 1028 | static uint32_t vline_status[6] = { |
1203 | radeon_crtc = to_radeon_crtc(crtc); | 1029 | EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, |
1204 | crtc_id = radeon_crtc->crtc_id; | 1030 | EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, |
1205 | 1031 | EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, | |
1206 | if (!crtc->enabled) { | 1032 | EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, |
1207 | /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ | 1033 | EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, |
1208 | ib[h_idx + 2] = PACKET2(0); | 1034 | EVERGREEN_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET |
1209 | ib[h_idx + 3] = PACKET2(0); | 1035 | }; |
1210 | ib[h_idx + 4] = PACKET2(0); | 1036 | |
1211 | ib[h_idx + 5] = PACKET2(0); | 1037 | return r600_cs_common_vline_parse(p, vline_start_end, vline_status); |
1212 | ib[h_idx + 6] = PACKET2(0); | ||
1213 | ib[h_idx + 7] = PACKET2(0); | ||
1214 | ib[h_idx + 8] = PACKET2(0); | ||
1215 | } else { | ||
1216 | switch (reg) { | ||
1217 | case EVERGREEN_VLINE_START_END: | ||
1218 | header &= ~R600_CP_PACKET0_REG_MASK; | ||
1219 | header |= (EVERGREEN_VLINE_START_END + radeon_crtc->crtc_offset) >> 2; | ||
1220 | ib[h_idx] = header; | ||
1221 | ib[h_idx + 4] = (EVERGREEN_VLINE_STATUS + radeon_crtc->crtc_offset) >> 2; | ||
1222 | break; | ||
1223 | default: | ||
1224 | DRM_ERROR("unknown crtc reloc\n"); | ||
1225 | return -EINVAL; | ||
1226 | } | ||
1227 | } | ||
1228 | return 0; | ||
1229 | } | 1038 | } |
1230 | 1039 | ||
1231 | static int evergreen_packet0_check(struct radeon_cs_parser *p, | 1040 | static int evergreen_packet0_check(struct radeon_cs_parser *p, |
@@ -1347,7 +1156,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1347 | case SQ_LSTMP_RING_BASE: | 1156 | case SQ_LSTMP_RING_BASE: |
1348 | case SQ_PSTMP_RING_BASE: | 1157 | case SQ_PSTMP_RING_BASE: |
1349 | case SQ_VSTMP_RING_BASE: | 1158 | case SQ_VSTMP_RING_BASE: |
1350 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1159 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1351 | if (r) { | 1160 | if (r) { |
1352 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1161 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1353 | "0x%04X\n", reg); | 1162 | "0x%04X\n", reg); |
@@ -1376,7 +1185,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1376 | case DB_Z_INFO: | 1185 | case DB_Z_INFO: |
1377 | track->db_z_info = radeon_get_ib_value(p, idx); | 1186 | track->db_z_info = radeon_get_ib_value(p, idx); |
1378 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | 1187 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
1379 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1188 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1380 | if (r) { | 1189 | if (r) { |
1381 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1190 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1382 | "0x%04X\n", reg); | 1191 | "0x%04X\n", reg); |
@@ -1418,7 +1227,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1418 | track->db_dirty = true; | 1227 | track->db_dirty = true; |
1419 | break; | 1228 | break; |
1420 | case DB_Z_READ_BASE: | 1229 | case DB_Z_READ_BASE: |
1421 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1230 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1422 | if (r) { | 1231 | if (r) { |
1423 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1232 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1424 | "0x%04X\n", reg); | 1233 | "0x%04X\n", reg); |
@@ -1430,7 +1239,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1430 | track->db_dirty = true; | 1239 | track->db_dirty = true; |
1431 | break; | 1240 | break; |
1432 | case DB_Z_WRITE_BASE: | 1241 | case DB_Z_WRITE_BASE: |
1433 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1242 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1434 | if (r) { | 1243 | if (r) { |
1435 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1244 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1436 | "0x%04X\n", reg); | 1245 | "0x%04X\n", reg); |
@@ -1442,7 +1251,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1442 | track->db_dirty = true; | 1251 | track->db_dirty = true; |
1443 | break; | 1252 | break; |
1444 | case DB_STENCIL_READ_BASE: | 1253 | case DB_STENCIL_READ_BASE: |
1445 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1254 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1446 | if (r) { | 1255 | if (r) { |
1447 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1256 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1448 | "0x%04X\n", reg); | 1257 | "0x%04X\n", reg); |
@@ -1454,7 +1263,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1454 | track->db_dirty = true; | 1263 | track->db_dirty = true; |
1455 | break; | 1264 | break; |
1456 | case DB_STENCIL_WRITE_BASE: | 1265 | case DB_STENCIL_WRITE_BASE: |
1457 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1266 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1458 | if (r) { | 1267 | if (r) { |
1459 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1268 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1460 | "0x%04X\n", reg); | 1269 | "0x%04X\n", reg); |
@@ -1477,7 +1286,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1477 | case VGT_STRMOUT_BUFFER_BASE_1: | 1286 | case VGT_STRMOUT_BUFFER_BASE_1: |
1478 | case VGT_STRMOUT_BUFFER_BASE_2: | 1287 | case VGT_STRMOUT_BUFFER_BASE_2: |
1479 | case VGT_STRMOUT_BUFFER_BASE_3: | 1288 | case VGT_STRMOUT_BUFFER_BASE_3: |
1480 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1289 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1481 | if (r) { | 1290 | if (r) { |
1482 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1291 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1483 | "0x%04X\n", reg); | 1292 | "0x%04X\n", reg); |
@@ -1499,7 +1308,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1499 | track->streamout_dirty = true; | 1308 | track->streamout_dirty = true; |
1500 | break; | 1309 | break; |
1501 | case CP_COHER_BASE: | 1310 | case CP_COHER_BASE: |
1502 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1311 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1503 | if (r) { | 1312 | if (r) { |
1504 | dev_warn(p->dev, "missing reloc for CP_COHER_BASE " | 1313 | dev_warn(p->dev, "missing reloc for CP_COHER_BASE " |
1505 | "0x%04X\n", reg); | 1314 | "0x%04X\n", reg); |
@@ -1563,7 +1372,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1563 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; | 1372 | tmp = (reg - CB_COLOR0_INFO) / 0x3c; |
1564 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 1373 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
1565 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | 1374 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
1566 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1375 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1567 | if (r) { | 1376 | if (r) { |
1568 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1377 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1569 | "0x%04X\n", reg); | 1378 | "0x%04X\n", reg); |
@@ -1581,7 +1390,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1581 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; | 1390 | tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; |
1582 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 1391 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
1583 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | 1392 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
1584 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1393 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1585 | if (r) { | 1394 | if (r) { |
1586 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1395 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1587 | "0x%04X\n", reg); | 1396 | "0x%04X\n", reg); |
@@ -1642,7 +1451,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1642 | case CB_COLOR5_ATTRIB: | 1451 | case CB_COLOR5_ATTRIB: |
1643 | case CB_COLOR6_ATTRIB: | 1452 | case CB_COLOR6_ATTRIB: |
1644 | case CB_COLOR7_ATTRIB: | 1453 | case CB_COLOR7_ATTRIB: |
1645 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1454 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1646 | if (r) { | 1455 | if (r) { |
1647 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1456 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1648 | "0x%04X\n", reg); | 1457 | "0x%04X\n", reg); |
@@ -1670,7 +1479,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1670 | case CB_COLOR9_ATTRIB: | 1479 | case CB_COLOR9_ATTRIB: |
1671 | case CB_COLOR10_ATTRIB: | 1480 | case CB_COLOR10_ATTRIB: |
1672 | case CB_COLOR11_ATTRIB: | 1481 | case CB_COLOR11_ATTRIB: |
1673 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1482 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1674 | if (r) { | 1483 | if (r) { |
1675 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1484 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1676 | "0x%04X\n", reg); | 1485 | "0x%04X\n", reg); |
@@ -1703,7 +1512,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1703 | case CB_COLOR6_FMASK: | 1512 | case CB_COLOR6_FMASK: |
1704 | case CB_COLOR7_FMASK: | 1513 | case CB_COLOR7_FMASK: |
1705 | tmp = (reg - CB_COLOR0_FMASK) / 0x3c; | 1514 | tmp = (reg - CB_COLOR0_FMASK) / 0x3c; |
1706 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1515 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1707 | if (r) { | 1516 | if (r) { |
1708 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1517 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1709 | return -EINVAL; | 1518 | return -EINVAL; |
@@ -1720,7 +1529,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1720 | case CB_COLOR6_CMASK: | 1529 | case CB_COLOR6_CMASK: |
1721 | case CB_COLOR7_CMASK: | 1530 | case CB_COLOR7_CMASK: |
1722 | tmp = (reg - CB_COLOR0_CMASK) / 0x3c; | 1531 | tmp = (reg - CB_COLOR0_CMASK) / 0x3c; |
1723 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1532 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1724 | if (r) { | 1533 | if (r) { |
1725 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); | 1534 | dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); |
1726 | return -EINVAL; | 1535 | return -EINVAL; |
@@ -1758,7 +1567,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1758 | case CB_COLOR5_BASE: | 1567 | case CB_COLOR5_BASE: |
1759 | case CB_COLOR6_BASE: | 1568 | case CB_COLOR6_BASE: |
1760 | case CB_COLOR7_BASE: | 1569 | case CB_COLOR7_BASE: |
1761 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1570 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1762 | if (r) { | 1571 | if (r) { |
1763 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1572 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1764 | "0x%04X\n", reg); | 1573 | "0x%04X\n", reg); |
@@ -1774,7 +1583,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1774 | case CB_COLOR9_BASE: | 1583 | case CB_COLOR9_BASE: |
1775 | case CB_COLOR10_BASE: | 1584 | case CB_COLOR10_BASE: |
1776 | case CB_COLOR11_BASE: | 1585 | case CB_COLOR11_BASE: |
1777 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1586 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1778 | if (r) { | 1587 | if (r) { |
1779 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1588 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1780 | "0x%04X\n", reg); | 1589 | "0x%04X\n", reg); |
@@ -1787,7 +1596,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1787 | track->cb_dirty = true; | 1596 | track->cb_dirty = true; |
1788 | break; | 1597 | break; |
1789 | case DB_HTILE_DATA_BASE: | 1598 | case DB_HTILE_DATA_BASE: |
1790 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1599 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1791 | if (r) { | 1600 | if (r) { |
1792 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1601 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1793 | "0x%04X\n", reg); | 1602 | "0x%04X\n", reg); |
@@ -1905,7 +1714,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1905 | case SQ_ALU_CONST_CACHE_LS_13: | 1714 | case SQ_ALU_CONST_CACHE_LS_13: |
1906 | case SQ_ALU_CONST_CACHE_LS_14: | 1715 | case SQ_ALU_CONST_CACHE_LS_14: |
1907 | case SQ_ALU_CONST_CACHE_LS_15: | 1716 | case SQ_ALU_CONST_CACHE_LS_15: |
1908 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1717 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1909 | if (r) { | 1718 | if (r) { |
1910 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1719 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1911 | "0x%04X\n", reg); | 1720 | "0x%04X\n", reg); |
@@ -1919,7 +1728,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1919 | "0x%04X\n", reg); | 1728 | "0x%04X\n", reg); |
1920 | return -EINVAL; | 1729 | return -EINVAL; |
1921 | } | 1730 | } |
1922 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1731 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1923 | if (r) { | 1732 | if (r) { |
1924 | dev_warn(p->dev, "bad SET_CONFIG_REG " | 1733 | dev_warn(p->dev, "bad SET_CONFIG_REG " |
1925 | "0x%04X\n", reg); | 1734 | "0x%04X\n", reg); |
@@ -1933,7 +1742,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1933 | "0x%04X\n", reg); | 1742 | "0x%04X\n", reg); |
1934 | return -EINVAL; | 1743 | return -EINVAL; |
1935 | } | 1744 | } |
1936 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1745 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
1937 | if (r) { | 1746 | if (r) { |
1938 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | 1747 | dev_warn(p->dev, "bad SET_CONTEXT_REG " |
1939 | "0x%04X\n", reg); | 1748 | "0x%04X\n", reg); |
@@ -2018,7 +1827,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2018 | return -EINVAL; | 1827 | return -EINVAL; |
2019 | } | 1828 | } |
2020 | 1829 | ||
2021 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1830 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2022 | if (r) { | 1831 | if (r) { |
2023 | DRM_ERROR("bad SET PREDICATION\n"); | 1832 | DRM_ERROR("bad SET PREDICATION\n"); |
2024 | return -EINVAL; | 1833 | return -EINVAL; |
@@ -2064,7 +1873,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2064 | DRM_ERROR("bad INDEX_BASE\n"); | 1873 | DRM_ERROR("bad INDEX_BASE\n"); |
2065 | return -EINVAL; | 1874 | return -EINVAL; |
2066 | } | 1875 | } |
2067 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1876 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2068 | if (r) { | 1877 | if (r) { |
2069 | DRM_ERROR("bad INDEX_BASE\n"); | 1878 | DRM_ERROR("bad INDEX_BASE\n"); |
2070 | return -EINVAL; | 1879 | return -EINVAL; |
@@ -2091,7 +1900,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2091 | DRM_ERROR("bad DRAW_INDEX\n"); | 1900 | DRM_ERROR("bad DRAW_INDEX\n"); |
2092 | return -EINVAL; | 1901 | return -EINVAL; |
2093 | } | 1902 | } |
2094 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1903 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2095 | if (r) { | 1904 | if (r) { |
2096 | DRM_ERROR("bad DRAW_INDEX\n"); | 1905 | DRM_ERROR("bad DRAW_INDEX\n"); |
2097 | return -EINVAL; | 1906 | return -EINVAL; |
@@ -2119,7 +1928,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2119 | DRM_ERROR("bad DRAW_INDEX_2\n"); | 1928 | DRM_ERROR("bad DRAW_INDEX_2\n"); |
2120 | return -EINVAL; | 1929 | return -EINVAL; |
2121 | } | 1930 | } |
2122 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1931 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2123 | if (r) { | 1932 | if (r) { |
2124 | DRM_ERROR("bad DRAW_INDEX_2\n"); | 1933 | DRM_ERROR("bad DRAW_INDEX_2\n"); |
2125 | return -EINVAL; | 1934 | return -EINVAL; |
@@ -2210,7 +2019,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2210 | DRM_ERROR("bad DISPATCH_INDIRECT\n"); | 2019 | DRM_ERROR("bad DISPATCH_INDIRECT\n"); |
2211 | return -EINVAL; | 2020 | return -EINVAL; |
2212 | } | 2021 | } |
2213 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2022 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2214 | if (r) { | 2023 | if (r) { |
2215 | DRM_ERROR("bad DISPATCH_INDIRECT\n"); | 2024 | DRM_ERROR("bad DISPATCH_INDIRECT\n"); |
2216 | return -EINVAL; | 2025 | return -EINVAL; |
@@ -2231,7 +2040,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2231 | if (idx_value & 0x10) { | 2040 | if (idx_value & 0x10) { |
2232 | uint64_t offset; | 2041 | uint64_t offset; |
2233 | 2042 | ||
2234 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2043 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2235 | if (r) { | 2044 | if (r) { |
2236 | DRM_ERROR("bad WAIT_REG_MEM\n"); | 2045 | DRM_ERROR("bad WAIT_REG_MEM\n"); |
2237 | return -EINVAL; | 2046 | return -EINVAL; |
@@ -2243,6 +2052,9 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2243 | 2052 | ||
2244 | ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc); | 2053 | ib[idx+1] = (ib[idx+1] & 0x3) | (offset & 0xfffffffc); |
2245 | ib[idx+2] = upper_32_bits(offset) & 0xff; | 2054 | ib[idx+2] = upper_32_bits(offset) & 0xff; |
2055 | } else if (idx_value & 0x100) { | ||
2056 | DRM_ERROR("cannot use PFP on REG wait\n"); | ||
2057 | return -EINVAL; | ||
2246 | } | 2058 | } |
2247 | break; | 2059 | break; |
2248 | case PACKET3_CP_DMA: | 2060 | case PACKET3_CP_DMA: |
@@ -2282,7 +2094,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2282 | } | 2094 | } |
2283 | /* src address space is memory */ | 2095 | /* src address space is memory */ |
2284 | if (((info & 0x60000000) >> 29) == 0) { | 2096 | if (((info & 0x60000000) >> 29) == 0) { |
2285 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2097 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2286 | if (r) { | 2098 | if (r) { |
2287 | DRM_ERROR("bad CP DMA SRC\n"); | 2099 | DRM_ERROR("bad CP DMA SRC\n"); |
2288 | return -EINVAL; | 2100 | return -EINVAL; |
@@ -2320,7 +2132,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2320 | return -EINVAL; | 2132 | return -EINVAL; |
2321 | } | 2133 | } |
2322 | if (((info & 0x00300000) >> 20) == 0) { | 2134 | if (((info & 0x00300000) >> 20) == 0) { |
2323 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2135 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2324 | if (r) { | 2136 | if (r) { |
2325 | DRM_ERROR("bad CP DMA DST\n"); | 2137 | DRM_ERROR("bad CP DMA DST\n"); |
2326 | return -EINVAL; | 2138 | return -EINVAL; |
@@ -2354,7 +2166,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2354 | /* 0xffffffff/0x0 is flush all cache flag */ | 2166 | /* 0xffffffff/0x0 is flush all cache flag */ |
2355 | if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || | 2167 | if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || |
2356 | radeon_get_ib_value(p, idx + 2) != 0) { | 2168 | radeon_get_ib_value(p, idx + 2) != 0) { |
2357 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2169 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2358 | if (r) { | 2170 | if (r) { |
2359 | DRM_ERROR("bad SURFACE_SYNC\n"); | 2171 | DRM_ERROR("bad SURFACE_SYNC\n"); |
2360 | return -EINVAL; | 2172 | return -EINVAL; |
@@ -2370,7 +2182,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2370 | if (pkt->count) { | 2182 | if (pkt->count) { |
2371 | uint64_t offset; | 2183 | uint64_t offset; |
2372 | 2184 | ||
2373 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2185 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2374 | if (r) { | 2186 | if (r) { |
2375 | DRM_ERROR("bad EVENT_WRITE\n"); | 2187 | DRM_ERROR("bad EVENT_WRITE\n"); |
2376 | return -EINVAL; | 2188 | return -EINVAL; |
@@ -2391,7 +2203,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2391 | DRM_ERROR("bad EVENT_WRITE_EOP\n"); | 2203 | DRM_ERROR("bad EVENT_WRITE_EOP\n"); |
2392 | return -EINVAL; | 2204 | return -EINVAL; |
2393 | } | 2205 | } |
2394 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2206 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2395 | if (r) { | 2207 | if (r) { |
2396 | DRM_ERROR("bad EVENT_WRITE_EOP\n"); | 2208 | DRM_ERROR("bad EVENT_WRITE_EOP\n"); |
2397 | return -EINVAL; | 2209 | return -EINVAL; |
@@ -2413,7 +2225,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2413 | DRM_ERROR("bad EVENT_WRITE_EOS\n"); | 2225 | DRM_ERROR("bad EVENT_WRITE_EOS\n"); |
2414 | return -EINVAL; | 2226 | return -EINVAL; |
2415 | } | 2227 | } |
2416 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2228 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2417 | if (r) { | 2229 | if (r) { |
2418 | DRM_ERROR("bad EVENT_WRITE_EOS\n"); | 2230 | DRM_ERROR("bad EVENT_WRITE_EOS\n"); |
2419 | return -EINVAL; | 2231 | return -EINVAL; |
@@ -2480,7 +2292,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2480 | switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { | 2292 | switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { |
2481 | case SQ_TEX_VTX_VALID_TEXTURE: | 2293 | case SQ_TEX_VTX_VALID_TEXTURE: |
2482 | /* tex base */ | 2294 | /* tex base */ |
2483 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2295 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2484 | if (r) { | 2296 | if (r) { |
2485 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); | 2297 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); |
2486 | return -EINVAL; | 2298 | return -EINVAL; |
@@ -2511,13 +2323,13 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2511 | 2323 | ||
2512 | if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) && | 2324 | if ((tex_dim == SQ_TEX_DIM_2D_MSAA || tex_dim == SQ_TEX_DIM_2D_ARRAY_MSAA) && |
2513 | !mip_address && | 2325 | !mip_address && |
2514 | !evergreen_cs_packet_next_is_pkt3_nop(p)) { | 2326 | !radeon_cs_packet_next_is_pkt3_nop(p)) { |
2515 | /* MIP_ADDRESS should point to FMASK for an MSAA texture. | 2327 | /* MIP_ADDRESS should point to FMASK for an MSAA texture. |
2516 | * It should be 0 if FMASK is disabled. */ | 2328 | * It should be 0 if FMASK is disabled. */ |
2517 | moffset = 0; | 2329 | moffset = 0; |
2518 | mipmap = NULL; | 2330 | mipmap = NULL; |
2519 | } else { | 2331 | } else { |
2520 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2332 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2521 | if (r) { | 2333 | if (r) { |
2522 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); | 2334 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); |
2523 | return -EINVAL; | 2335 | return -EINVAL; |
@@ -2536,7 +2348,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2536 | { | 2348 | { |
2537 | uint64_t offset64; | 2349 | uint64_t offset64; |
2538 | /* vtx base */ | 2350 | /* vtx base */ |
2539 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2351 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2540 | if (r) { | 2352 | if (r) { |
2541 | DRM_ERROR("bad SET_RESOURCE (vtx)\n"); | 2353 | DRM_ERROR("bad SET_RESOURCE (vtx)\n"); |
2542 | return -EINVAL; | 2354 | return -EINVAL; |
@@ -2618,7 +2430,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2618 | /* Updating memory at DST_ADDRESS. */ | 2430 | /* Updating memory at DST_ADDRESS. */ |
2619 | if (idx_value & 0x1) { | 2431 | if (idx_value & 0x1) { |
2620 | u64 offset; | 2432 | u64 offset; |
2621 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2433 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2622 | if (r) { | 2434 | if (r) { |
2623 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); | 2435 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); |
2624 | return -EINVAL; | 2436 | return -EINVAL; |
@@ -2637,7 +2449,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2637 | /* Reading data from SRC_ADDRESS. */ | 2449 | /* Reading data from SRC_ADDRESS. */ |
2638 | if (((idx_value >> 1) & 0x3) == 2) { | 2450 | if (((idx_value >> 1) & 0x3) == 2) { |
2639 | u64 offset; | 2451 | u64 offset; |
2640 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2452 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2641 | if (r) { | 2453 | if (r) { |
2642 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); | 2454 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); |
2643 | return -EINVAL; | 2455 | return -EINVAL; |
@@ -2662,7 +2474,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2662 | DRM_ERROR("bad MEM_WRITE (invalid count)\n"); | 2474 | DRM_ERROR("bad MEM_WRITE (invalid count)\n"); |
2663 | return -EINVAL; | 2475 | return -EINVAL; |
2664 | } | 2476 | } |
2665 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2477 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2666 | if (r) { | 2478 | if (r) { |
2667 | DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); | 2479 | DRM_ERROR("bad MEM_WRITE (missing reloc)\n"); |
2668 | return -EINVAL; | 2480 | return -EINVAL; |
@@ -2691,7 +2503,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2691 | if (idx_value & 0x1) { | 2503 | if (idx_value & 0x1) { |
2692 | u64 offset; | 2504 | u64 offset; |
2693 | /* SRC is memory. */ | 2505 | /* SRC is memory. */ |
2694 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2506 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2695 | if (r) { | 2507 | if (r) { |
2696 | DRM_ERROR("bad COPY_DW (missing src reloc)\n"); | 2508 | DRM_ERROR("bad COPY_DW (missing src reloc)\n"); |
2697 | return -EINVAL; | 2509 | return -EINVAL; |
@@ -2715,7 +2527,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
2715 | if (idx_value & 0x2) { | 2527 | if (idx_value & 0x2) { |
2716 | u64 offset; | 2528 | u64 offset; |
2717 | /* DST is memory. */ | 2529 | /* DST is memory. */ |
2718 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2530 | r = radeon_cs_packet_next_reloc(p, &reloc, 0); |
2719 | if (r) { | 2531 | if (r) { |
2720 | DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); | 2532 | DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); |
2721 | return -EINVAL; | 2533 | return -EINVAL; |
@@ -2819,7 +2631,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
2819 | p->track = track; | 2631 | p->track = track; |
2820 | } | 2632 | } |
2821 | do { | 2633 | do { |
2822 | r = evergreen_cs_packet_parse(p, &pkt, p->idx); | 2634 | r = radeon_cs_packet_parse(p, &pkt, p->idx); |
2823 | if (r) { | 2635 | if (r) { |
2824 | kfree(p->track); | 2636 | kfree(p->track); |
2825 | p->track = NULL; | 2637 | p->track = NULL; |
@@ -2827,12 +2639,12 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
2827 | } | 2639 | } |
2828 | p->idx += pkt.count + 2; | 2640 | p->idx += pkt.count + 2; |
2829 | switch (pkt.type) { | 2641 | switch (pkt.type) { |
2830 | case PACKET_TYPE0: | 2642 | case RADEON_PACKET_TYPE0: |
2831 | r = evergreen_cs_parse_packet0(p, &pkt); | 2643 | r = evergreen_cs_parse_packet0(p, &pkt); |
2832 | break; | 2644 | break; |
2833 | case PACKET_TYPE2: | 2645 | case RADEON_PACKET_TYPE2: |
2834 | break; | 2646 | break; |
2835 | case PACKET_TYPE3: | 2647 | case RADEON_PACKET_TYPE3: |
2836 | r = evergreen_packet3_check(p, &pkt); | 2648 | r = evergreen_packet3_check(p, &pkt); |
2837 | break; | 2649 | break; |
2838 | default: | 2650 | default: |
@@ -2858,16 +2670,6 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
2858 | return 0; | 2670 | return 0; |
2859 | } | 2671 | } |
2860 | 2672 | ||
2861 | /* | ||
2862 | * DMA | ||
2863 | */ | ||
2864 | |||
2865 | #define GET_DMA_CMD(h) (((h) & 0xf0000000) >> 28) | ||
2866 | #define GET_DMA_COUNT(h) ((h) & 0x000fffff) | ||
2867 | #define GET_DMA_T(h) (((h) & 0x00800000) >> 23) | ||
2868 | #define GET_DMA_NEW(h) (((h) & 0x04000000) >> 26) | ||
2869 | #define GET_DMA_MISC(h) (((h) & 0x0700000) >> 20) | ||
2870 | |||
2871 | /** | 2673 | /** |
2872 | * evergreen_dma_cs_parse() - parse the DMA IB | 2674 | * evergreen_dma_cs_parse() - parse the DMA IB |
2873 | * @p: parser structure holding parsing context. | 2675 | * @p: parser structure holding parsing context. |
@@ -2881,9 +2683,9 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | |||
2881 | { | 2683 | { |
2882 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; | 2684 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; |
2883 | struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc; | 2685 | struct radeon_cs_reloc *src_reloc, *dst_reloc, *dst2_reloc; |
2884 | u32 header, cmd, count, tiled, new_cmd, misc; | 2686 | u32 header, cmd, count, sub_cmd; |
2885 | volatile u32 *ib = p->ib.ptr; | 2687 | volatile u32 *ib = p->ib.ptr; |
2886 | u32 idx, idx_value; | 2688 | u32 idx; |
2887 | u64 src_offset, dst_offset, dst2_offset; | 2689 | u64 src_offset, dst_offset, dst2_offset; |
2888 | int r; | 2690 | int r; |
2889 | 2691 | ||
@@ -2897,9 +2699,7 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | |||
2897 | header = radeon_get_ib_value(p, idx); | 2699 | header = radeon_get_ib_value(p, idx); |
2898 | cmd = GET_DMA_CMD(header); | 2700 | cmd = GET_DMA_CMD(header); |
2899 | count = GET_DMA_COUNT(header); | 2701 | count = GET_DMA_COUNT(header); |
2900 | tiled = GET_DMA_T(header); | 2702 | sub_cmd = GET_DMA_SUB_CMD(header); |
2901 | new_cmd = GET_DMA_NEW(header); | ||
2902 | misc = GET_DMA_MISC(header); | ||
2903 | 2703 | ||
2904 | switch (cmd) { | 2704 | switch (cmd) { |
2905 | case DMA_PACKET_WRITE: | 2705 | case DMA_PACKET_WRITE: |
@@ -2908,19 +2708,27 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | |||
2908 | DRM_ERROR("bad DMA_PACKET_WRITE\n"); | 2708 | DRM_ERROR("bad DMA_PACKET_WRITE\n"); |
2909 | return -EINVAL; | 2709 | return -EINVAL; |
2910 | } | 2710 | } |
2911 | if (tiled) { | 2711 | switch (sub_cmd) { |
2712 | /* tiled */ | ||
2713 | case 8: | ||
2912 | dst_offset = radeon_get_ib_value(p, idx+1); | 2714 | dst_offset = radeon_get_ib_value(p, idx+1); |
2913 | dst_offset <<= 8; | 2715 | dst_offset <<= 8; |
2914 | 2716 | ||
2915 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | 2717 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); |
2916 | p->idx += count + 7; | 2718 | p->idx += count + 7; |
2917 | } else { | 2719 | break; |
2720 | /* linear */ | ||
2721 | case 0: | ||
2918 | dst_offset = radeon_get_ib_value(p, idx+1); | 2722 | dst_offset = radeon_get_ib_value(p, idx+1); |
2919 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; | 2723 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; |
2920 | 2724 | ||
2921 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | 2725 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); |
2922 | ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | 2726 | ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; |
2923 | p->idx += count + 3; | 2727 | p->idx += count + 3; |
2728 | break; | ||
2729 | default: | ||
2730 | DRM_ERROR("bad DMA_PACKET_WRITE [%6d] 0x%08x sub cmd is not 0 or 8\n", idx, header); | ||
2731 | return -EINVAL; | ||
2924 | } | 2732 | } |
2925 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | 2733 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { |
2926 | dev_warn(p->dev, "DMA write buffer too small (%llu %lu)\n", | 2734 | dev_warn(p->dev, "DMA write buffer too small (%llu %lu)\n", |
@@ -2939,338 +2747,330 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p) | |||
2939 | DRM_ERROR("bad DMA_PACKET_COPY\n"); | 2747 | DRM_ERROR("bad DMA_PACKET_COPY\n"); |
2940 | return -EINVAL; | 2748 | return -EINVAL; |
2941 | } | 2749 | } |
2942 | if (tiled) { | 2750 | switch (sub_cmd) { |
2943 | idx_value = radeon_get_ib_value(p, idx + 2); | 2751 | /* Copy L2L, DW aligned */ |
2944 | if (new_cmd) { | 2752 | case 0x00: |
2945 | switch (misc) { | 2753 | /* L2L, dw */ |
2946 | case 0: | 2754 | src_offset = radeon_get_ib_value(p, idx+2); |
2947 | /* L2T, frame to fields */ | 2755 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; |
2948 | if (idx_value & (1 << 31)) { | 2756 | dst_offset = radeon_get_ib_value(p, idx+1); |
2949 | DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n"); | 2757 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; |
2950 | return -EINVAL; | 2758 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { |
2951 | } | 2759 | dev_warn(p->dev, "DMA L2L, dw src buffer too small (%llu %lu)\n", |
2952 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | 2760 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); |
2953 | if (r) { | 2761 | return -EINVAL; |
2954 | DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n"); | 2762 | } |
2955 | return -EINVAL; | 2763 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { |
2956 | } | 2764 | dev_warn(p->dev, "DMA L2L, dw dst buffer too small (%llu %lu)\n", |
2957 | dst_offset = radeon_get_ib_value(p, idx+1); | 2765 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); |
2958 | dst_offset <<= 8; | 2766 | return -EINVAL; |
2959 | dst2_offset = radeon_get_ib_value(p, idx+2); | 2767 | } |
2960 | dst2_offset <<= 8; | 2768 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); |
2961 | src_offset = radeon_get_ib_value(p, idx+8); | 2769 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); |
2962 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32; | 2770 | ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; |
2963 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | 2771 | ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; |
2964 | dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%llu %lu)\n", | 2772 | p->idx += 5; |
2965 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | 2773 | break; |
2966 | return -EINVAL; | 2774 | /* Copy L2T/T2L */ |
2967 | } | 2775 | case 0x08: |
2968 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | 2776 | /* detile bit */ |
2969 | dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%llu %lu)\n", | 2777 | if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) { |
2970 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | 2778 | /* tiled src, linear dst */ |
2971 | return -EINVAL; | 2779 | src_offset = radeon_get_ib_value(p, idx+1); |
2972 | } | 2780 | src_offset <<= 8; |
2973 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | 2781 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); |
2974 | dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%llu %lu)\n", | 2782 | |
2975 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | 2783 | dst_offset = radeon_get_ib_value(p, idx + 7); |
2976 | return -EINVAL; | 2784 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; |
2977 | } | 2785 | ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); |
2978 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | 2786 | ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; |
2979 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8); | ||
2980 | ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2981 | ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
2982 | p->idx += 10; | ||
2983 | break; | ||
2984 | case 1: | ||
2985 | /* L2T, T2L partial */ | ||
2986 | if (p->family < CHIP_CAYMAN) { | ||
2987 | DRM_ERROR("L2T, T2L Partial is cayman only !\n"); | ||
2988 | return -EINVAL; | ||
2989 | } | ||
2990 | /* detile bit */ | ||
2991 | if (idx_value & (1 << 31)) { | ||
2992 | /* tiled src, linear dst */ | ||
2993 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | ||
2994 | |||
2995 | ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2996 | ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
2997 | } else { | ||
2998 | /* linear src, tiled dst */ | ||
2999 | ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3000 | ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3001 | |||
3002 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3003 | } | ||
3004 | p->idx += 12; | ||
3005 | break; | ||
3006 | case 3: | ||
3007 | /* L2T, broadcast */ | ||
3008 | if (idx_value & (1 << 31)) { | ||
3009 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
3010 | return -EINVAL; | ||
3011 | } | ||
3012 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | ||
3013 | if (r) { | ||
3014 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
3015 | return -EINVAL; | ||
3016 | } | ||
3017 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
3018 | dst_offset <<= 8; | ||
3019 | dst2_offset = radeon_get_ib_value(p, idx+2); | ||
3020 | dst2_offset <<= 8; | ||
3021 | src_offset = radeon_get_ib_value(p, idx+8); | ||
3022 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32; | ||
3023 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
3024 | dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", | ||
3025 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3026 | return -EINVAL; | ||
3027 | } | ||
3028 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3029 | dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%llu %lu)\n", | ||
3030 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3031 | return -EINVAL; | ||
3032 | } | ||
3033 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | ||
3034 | dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%llu %lu)\n", | ||
3035 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | ||
3036 | return -EINVAL; | ||
3037 | } | ||
3038 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3039 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8); | ||
3040 | ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3041 | ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3042 | p->idx += 10; | ||
3043 | break; | ||
3044 | case 4: | ||
3045 | /* L2T, T2L */ | ||
3046 | /* detile bit */ | ||
3047 | if (idx_value & (1 << 31)) { | ||
3048 | /* tiled src, linear dst */ | ||
3049 | src_offset = radeon_get_ib_value(p, idx+1); | ||
3050 | src_offset <<= 8; | ||
3051 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | ||
3052 | |||
3053 | dst_offset = radeon_get_ib_value(p, idx+7); | ||
3054 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; | ||
3055 | ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3056 | ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
3057 | } else { | ||
3058 | /* linear src, tiled dst */ | ||
3059 | src_offset = radeon_get_ib_value(p, idx+7); | ||
3060 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; | ||
3061 | ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3062 | ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3063 | |||
3064 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
3065 | dst_offset <<= 8; | ||
3066 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3067 | } | ||
3068 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
3069 | dev_warn(p->dev, "DMA L2T, T2L src buffer too small (%llu %lu)\n", | ||
3070 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3071 | return -EINVAL; | ||
3072 | } | ||
3073 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3074 | dev_warn(p->dev, "DMA L2T, T2L dst buffer too small (%llu %lu)\n", | ||
3075 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3076 | return -EINVAL; | ||
3077 | } | ||
3078 | p->idx += 9; | ||
3079 | break; | ||
3080 | case 5: | ||
3081 | /* T2T partial */ | ||
3082 | if (p->family < CHIP_CAYMAN) { | ||
3083 | DRM_ERROR("L2T, T2L Partial is cayman only !\n"); | ||
3084 | return -EINVAL; | ||
3085 | } | ||
3086 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | ||
3087 | ib[idx+4] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3088 | p->idx += 13; | ||
3089 | break; | ||
3090 | case 7: | ||
3091 | /* L2T, broadcast */ | ||
3092 | if (idx_value & (1 << 31)) { | ||
3093 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
3094 | return -EINVAL; | ||
3095 | } | ||
3096 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | ||
3097 | if (r) { | ||
3098 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
3099 | return -EINVAL; | ||
3100 | } | ||
3101 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
3102 | dst_offset <<= 8; | ||
3103 | dst2_offset = radeon_get_ib_value(p, idx+2); | ||
3104 | dst2_offset <<= 8; | ||
3105 | src_offset = radeon_get_ib_value(p, idx+8); | ||
3106 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32; | ||
3107 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
3108 | dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", | ||
3109 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3110 | return -EINVAL; | ||
3111 | } | ||
3112 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3113 | dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%llu %lu)\n", | ||
3114 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3115 | return -EINVAL; | ||
3116 | } | ||
3117 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | ||
3118 | dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%llu %lu)\n", | ||
3119 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | ||
3120 | return -EINVAL; | ||
3121 | } | ||
3122 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3123 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8); | ||
3124 | ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3125 | ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3126 | p->idx += 10; | ||
3127 | break; | ||
3128 | default: | ||
3129 | DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); | ||
3130 | return -EINVAL; | ||
3131 | } | ||
3132 | } else { | 2787 | } else { |
3133 | switch (misc) { | 2788 | /* linear src, tiled dst */ |
3134 | case 0: | 2789 | src_offset = radeon_get_ib_value(p, idx+7); |
3135 | /* detile bit */ | 2790 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; |
3136 | if (idx_value & (1 << 31)) { | 2791 | ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); |
3137 | /* tiled src, linear dst */ | 2792 | ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; |
3138 | src_offset = radeon_get_ib_value(p, idx+1); | 2793 | |
3139 | src_offset <<= 8; | 2794 | dst_offset = radeon_get_ib_value(p, idx+1); |
3140 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | 2795 | dst_offset <<= 8; |
3141 | 2796 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | |
3142 | dst_offset = radeon_get_ib_value(p, idx+7); | ||
3143 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; | ||
3144 | ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3145 | ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
3146 | } else { | ||
3147 | /* linear src, tiled dst */ | ||
3148 | src_offset = radeon_get_ib_value(p, idx+7); | ||
3149 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; | ||
3150 | ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3151 | ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3152 | |||
3153 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
3154 | dst_offset <<= 8; | ||
3155 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3156 | } | ||
3157 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
3158 | dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", | ||
3159 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3160 | return -EINVAL; | ||
3161 | } | ||
3162 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3163 | dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%llu %lu)\n", | ||
3164 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3165 | return -EINVAL; | ||
3166 | } | ||
3167 | p->idx += 9; | ||
3168 | break; | ||
3169 | default: | ||
3170 | DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); | ||
3171 | return -EINVAL; | ||
3172 | } | ||
3173 | } | 2797 | } |
3174 | } else { | 2798 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { |
3175 | if (new_cmd) { | 2799 | dev_warn(p->dev, "DMA L2T, src buffer too small (%llu %lu)\n", |
3176 | switch (misc) { | 2800 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); |
3177 | case 0: | 2801 | return -EINVAL; |
3178 | /* L2L, byte */ | 2802 | } |
3179 | src_offset = radeon_get_ib_value(p, idx+2); | 2803 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { |
3180 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | 2804 | dev_warn(p->dev, "DMA L2T, dst buffer too small (%llu %lu)\n", |
3181 | dst_offset = radeon_get_ib_value(p, idx+1); | 2805 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); |
3182 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; | 2806 | return -EINVAL; |
3183 | if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) { | 2807 | } |
3184 | dev_warn(p->dev, "DMA L2L, byte src buffer too small (%llu %lu)\n", | 2808 | p->idx += 9; |
3185 | src_offset + count, radeon_bo_size(src_reloc->robj)); | 2809 | break; |
3186 | return -EINVAL; | 2810 | /* Copy L2L, byte aligned */ |
3187 | } | 2811 | case 0x40: |
3188 | if ((dst_offset + count) > radeon_bo_size(dst_reloc->robj)) { | 2812 | /* L2L, byte */ |
3189 | dev_warn(p->dev, "DMA L2L, byte dst buffer too small (%llu %lu)\n", | 2813 | src_offset = radeon_get_ib_value(p, idx+2); |
3190 | dst_offset + count, radeon_bo_size(dst_reloc->robj)); | 2814 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; |
3191 | return -EINVAL; | 2815 | dst_offset = radeon_get_ib_value(p, idx+1); |
3192 | } | 2816 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; |
3193 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xffffffff); | 2817 | if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) { |
3194 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xffffffff); | 2818 | dev_warn(p->dev, "DMA L2L, byte src buffer too small (%llu %lu)\n", |
3195 | ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | 2819 | src_offset + count, radeon_bo_size(src_reloc->robj)); |
3196 | ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | 2820 | return -EINVAL; |
3197 | p->idx += 5; | 2821 | } |
3198 | break; | 2822 | if ((dst_offset + count) > radeon_bo_size(dst_reloc->robj)) { |
3199 | case 1: | 2823 | dev_warn(p->dev, "DMA L2L, byte dst buffer too small (%llu %lu)\n", |
3200 | /* L2L, partial */ | 2824 | dst_offset + count, radeon_bo_size(dst_reloc->robj)); |
3201 | if (p->family < CHIP_CAYMAN) { | 2825 | return -EINVAL; |
3202 | DRM_ERROR("L2L Partial is cayman only !\n"); | 2826 | } |
3203 | return -EINVAL; | 2827 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xffffffff); |
3204 | } | 2828 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xffffffff); |
3205 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset & 0xffffffff); | 2829 | ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; |
3206 | ib[idx+2] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | 2830 | ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; |
3207 | ib[idx+4] += (u32)(dst_reloc->lobj.gpu_offset & 0xffffffff); | 2831 | p->idx += 5; |
3208 | ib[idx+5] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | 2832 | break; |
3209 | 2833 | /* Copy L2L, partial */ | |
3210 | p->idx += 9; | 2834 | case 0x41: |
3211 | break; | 2835 | /* L2L, partial */ |
3212 | case 4: | 2836 | if (p->family < CHIP_CAYMAN) { |
3213 | /* L2L, dw, broadcast */ | 2837 | DRM_ERROR("L2L Partial is cayman only !\n"); |
3214 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | 2838 | return -EINVAL; |
3215 | if (r) { | 2839 | } |
3216 | DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n"); | 2840 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset & 0xffffffff); |
3217 | return -EINVAL; | 2841 | ib[idx+2] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; |
3218 | } | 2842 | ib[idx+4] += (u32)(dst_reloc->lobj.gpu_offset & 0xffffffff); |
3219 | dst_offset = radeon_get_ib_value(p, idx+1); | 2843 | ib[idx+5] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; |
3220 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | 2844 | |
3221 | dst2_offset = radeon_get_ib_value(p, idx+2); | 2845 | p->idx += 9; |
3222 | dst2_offset |= ((u64)(radeon_get_ib_value(p, idx+5) & 0xff)) << 32; | 2846 | break; |
3223 | src_offset = radeon_get_ib_value(p, idx+3); | 2847 | /* Copy L2L, DW aligned, broadcast */ |
3224 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32; | 2848 | case 0x44: |
3225 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | 2849 | /* L2L, dw, broadcast */ |
3226 | dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%llu %lu)\n", | 2850 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); |
3227 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | 2851 | if (r) { |
3228 | return -EINVAL; | 2852 | DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n"); |
3229 | } | 2853 | return -EINVAL; |
3230 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | 2854 | } |
3231 | dev_warn(p->dev, "DMA L2L, dw, broadcast dst buffer too small (%llu %lu)\n", | 2855 | dst_offset = radeon_get_ib_value(p, idx+1); |
3232 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | 2856 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; |
3233 | return -EINVAL; | 2857 | dst2_offset = radeon_get_ib_value(p, idx+2); |
3234 | } | 2858 | dst2_offset |= ((u64)(radeon_get_ib_value(p, idx+5) & 0xff)) << 32; |
3235 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | 2859 | src_offset = radeon_get_ib_value(p, idx+3); |
3236 | dev_warn(p->dev, "DMA L2L, dw, broadcast dst2 buffer too small (%llu %lu)\n", | 2860 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32; |
3237 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | 2861 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { |
3238 | return -EINVAL; | 2862 | dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%llu %lu)\n", |
3239 | } | 2863 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); |
3240 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | 2864 | return -EINVAL; |
3241 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset & 0xfffffffc); | 2865 | } |
3242 | ib[idx+3] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | 2866 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { |
3243 | ib[idx+4] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | 2867 | dev_warn(p->dev, "DMA L2L, dw, broadcast dst buffer too small (%llu %lu)\n", |
3244 | ib[idx+5] += upper_32_bits(dst2_reloc->lobj.gpu_offset) & 0xff; | 2868 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); |
3245 | ib[idx+6] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | 2869 | return -EINVAL; |
3246 | p->idx += 7; | 2870 | } |
3247 | break; | 2871 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { |
3248 | default: | 2872 | dev_warn(p->dev, "DMA L2L, dw, broadcast dst2 buffer too small (%llu %lu)\n", |
3249 | DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); | 2873 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); |
3250 | return -EINVAL; | 2874 | return -EINVAL; |
3251 | } | 2875 | } |
2876 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2877 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2878 | ib[idx+3] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2879 | ib[idx+4] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
2880 | ib[idx+5] += upper_32_bits(dst2_reloc->lobj.gpu_offset) & 0xff; | ||
2881 | ib[idx+6] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
2882 | p->idx += 7; | ||
2883 | break; | ||
2884 | /* Copy L2T Frame to Field */ | ||
2885 | case 0x48: | ||
2886 | if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) { | ||
2887 | DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n"); | ||
2888 | return -EINVAL; | ||
2889 | } | ||
2890 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | ||
2891 | if (r) { | ||
2892 | DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n"); | ||
2893 | return -EINVAL; | ||
2894 | } | ||
2895 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
2896 | dst_offset <<= 8; | ||
2897 | dst2_offset = radeon_get_ib_value(p, idx+2); | ||
2898 | dst2_offset <<= 8; | ||
2899 | src_offset = radeon_get_ib_value(p, idx+8); | ||
2900 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32; | ||
2901 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
2902 | dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%llu %lu)\n", | ||
2903 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
2904 | return -EINVAL; | ||
2905 | } | ||
2906 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
2907 | dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%llu %lu)\n", | ||
2908 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
2909 | return -EINVAL; | ||
2910 | } | ||
2911 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | ||
2912 | dev_warn(p->dev, "DMA L2T, frame to fields buffer too small (%llu %lu)\n", | ||
2913 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | ||
2914 | return -EINVAL; | ||
2915 | } | ||
2916 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
2917 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8); | ||
2918 | ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2919 | ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
2920 | p->idx += 10; | ||
2921 | break; | ||
2922 | /* Copy L2T/T2L, partial */ | ||
2923 | case 0x49: | ||
2924 | /* L2T, T2L partial */ | ||
2925 | if (p->family < CHIP_CAYMAN) { | ||
2926 | DRM_ERROR("L2T, T2L Partial is cayman only !\n"); | ||
2927 | return -EINVAL; | ||
2928 | } | ||
2929 | /* detile bit */ | ||
2930 | if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) { | ||
2931 | /* tiled src, linear dst */ | ||
2932 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | ||
2933 | |||
2934 | ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2935 | ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
2936 | } else { | ||
2937 | /* linear src, tiled dst */ | ||
2938 | ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2939 | ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
2940 | |||
2941 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
2942 | } | ||
2943 | p->idx += 12; | ||
2944 | break; | ||
2945 | /* Copy L2T broadcast */ | ||
2946 | case 0x4b: | ||
2947 | /* L2T, broadcast */ | ||
2948 | if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) { | ||
2949 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
2950 | return -EINVAL; | ||
2951 | } | ||
2952 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | ||
2953 | if (r) { | ||
2954 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
2955 | return -EINVAL; | ||
2956 | } | ||
2957 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
2958 | dst_offset <<= 8; | ||
2959 | dst2_offset = radeon_get_ib_value(p, idx+2); | ||
2960 | dst2_offset <<= 8; | ||
2961 | src_offset = radeon_get_ib_value(p, idx+8); | ||
2962 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32; | ||
2963 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
2964 | dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", | ||
2965 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
2966 | return -EINVAL; | ||
2967 | } | ||
2968 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
2969 | dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%llu %lu)\n", | ||
2970 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
2971 | return -EINVAL; | ||
2972 | } | ||
2973 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | ||
2974 | dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%llu %lu)\n", | ||
2975 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | ||
2976 | return -EINVAL; | ||
2977 | } | ||
2978 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
2979 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8); | ||
2980 | ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2981 | ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
2982 | p->idx += 10; | ||
2983 | break; | ||
2984 | /* Copy L2T/T2L (tile units) */ | ||
2985 | case 0x4c: | ||
2986 | /* L2T, T2L */ | ||
2987 | /* detile bit */ | ||
2988 | if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) { | ||
2989 | /* tiled src, linear dst */ | ||
2990 | src_offset = radeon_get_ib_value(p, idx+1); | ||
2991 | src_offset <<= 8; | ||
2992 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | ||
2993 | |||
2994 | dst_offset = radeon_get_ib_value(p, idx+7); | ||
2995 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; | ||
2996 | ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2997 | ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
3252 | } else { | 2998 | } else { |
3253 | /* L2L, dw */ | 2999 | /* linear src, tiled dst */ |
3254 | src_offset = radeon_get_ib_value(p, idx+2); | 3000 | src_offset = radeon_get_ib_value(p, idx+7); |
3255 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | 3001 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32; |
3002 | ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3003 | ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3004 | |||
3256 | dst_offset = radeon_get_ib_value(p, idx+1); | 3005 | dst_offset = radeon_get_ib_value(p, idx+1); |
3257 | dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32; | 3006 | dst_offset <<= 8; |
3258 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | 3007 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); |
3259 | dev_warn(p->dev, "DMA L2L, dw src buffer too small (%llu %lu)\n", | ||
3260 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3261 | return -EINVAL; | ||
3262 | } | ||
3263 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3264 | dev_warn(p->dev, "DMA L2L, dw dst buffer too small (%llu %lu)\n", | ||
3265 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3266 | return -EINVAL; | ||
3267 | } | ||
3268 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3269 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3270 | ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | ||
3271 | ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3272 | p->idx += 5; | ||
3273 | } | 3008 | } |
3009 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
3010 | dev_warn(p->dev, "DMA L2T, T2L src buffer too small (%llu %lu)\n", | ||
3011 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3012 | return -EINVAL; | ||
3013 | } | ||
3014 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3015 | dev_warn(p->dev, "DMA L2T, T2L dst buffer too small (%llu %lu)\n", | ||
3016 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3017 | return -EINVAL; | ||
3018 | } | ||
3019 | p->idx += 9; | ||
3020 | break; | ||
3021 | /* Copy T2T, partial (tile units) */ | ||
3022 | case 0x4d: | ||
3023 | /* T2T partial */ | ||
3024 | if (p->family < CHIP_CAYMAN) { | ||
3025 | DRM_ERROR("L2T, T2L Partial is cayman only !\n"); | ||
3026 | return -EINVAL; | ||
3027 | } | ||
3028 | ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); | ||
3029 | ib[idx+4] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3030 | p->idx += 13; | ||
3031 | break; | ||
3032 | /* Copy L2T broadcast (tile units) */ | ||
3033 | case 0x4f: | ||
3034 | /* L2T, broadcast */ | ||
3035 | if (radeon_get_ib_value(p, idx + 2) & (1 << 31)) { | ||
3036 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
3037 | return -EINVAL; | ||
3038 | } | ||
3039 | r = r600_dma_cs_next_reloc(p, &dst2_reloc); | ||
3040 | if (r) { | ||
3041 | DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); | ||
3042 | return -EINVAL; | ||
3043 | } | ||
3044 | dst_offset = radeon_get_ib_value(p, idx+1); | ||
3045 | dst_offset <<= 8; | ||
3046 | dst2_offset = radeon_get_ib_value(p, idx+2); | ||
3047 | dst2_offset <<= 8; | ||
3048 | src_offset = radeon_get_ib_value(p, idx+8); | ||
3049 | src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32; | ||
3050 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | ||
3051 | dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", | ||
3052 | src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); | ||
3053 | return -EINVAL; | ||
3054 | } | ||
3055 | if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { | ||
3056 | dev_warn(p->dev, "DMA L2T, broadcast dst buffer too small (%llu %lu)\n", | ||
3057 | dst_offset + (count * 4), radeon_bo_size(dst_reloc->robj)); | ||
3058 | return -EINVAL; | ||
3059 | } | ||
3060 | if ((dst2_offset + (count * 4)) > radeon_bo_size(dst2_reloc->robj)) { | ||
3061 | dev_warn(p->dev, "DMA L2T, broadcast dst2 buffer too small (%llu %lu)\n", | ||
3062 | dst2_offset + (count * 4), radeon_bo_size(dst2_reloc->robj)); | ||
3063 | return -EINVAL; | ||
3064 | } | ||
3065 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); | ||
3066 | ib[idx+2] += (u32)(dst2_reloc->lobj.gpu_offset >> 8); | ||
3067 | ib[idx+8] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
3068 | ib[idx+9] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
3069 | p->idx += 10; | ||
3070 | break; | ||
3071 | default: | ||
3072 | DRM_ERROR("bad DMA_PACKET_COPY [%6d] 0x%08x invalid sub cmd\n", idx, header); | ||
3073 | return -EINVAL; | ||
3274 | } | 3074 | } |
3275 | break; | 3075 | break; |
3276 | case DMA_PACKET_CONSTANT_FILL: | 3076 | case DMA_PACKET_CONSTANT_FILL: |
@@ -3583,19 +3383,19 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
3583 | 3383 | ||
3584 | do { | 3384 | do { |
3585 | pkt.idx = idx; | 3385 | pkt.idx = idx; |
3586 | pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]); | 3386 | pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]); |
3587 | pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]); | 3387 | pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]); |
3588 | pkt.one_reg_wr = 0; | 3388 | pkt.one_reg_wr = 0; |
3589 | switch (pkt.type) { | 3389 | switch (pkt.type) { |
3590 | case PACKET_TYPE0: | 3390 | case RADEON_PACKET_TYPE0: |
3591 | dev_err(rdev->dev, "Packet0 not allowed!\n"); | 3391 | dev_err(rdev->dev, "Packet0 not allowed!\n"); |
3592 | ret = -EINVAL; | 3392 | ret = -EINVAL; |
3593 | break; | 3393 | break; |
3594 | case PACKET_TYPE2: | 3394 | case RADEON_PACKET_TYPE2: |
3595 | idx += 1; | 3395 | idx += 1; |
3596 | break; | 3396 | break; |
3597 | case PACKET_TYPE3: | 3397 | case RADEON_PACKET_TYPE3: |
3598 | pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); | 3398 | pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]); |
3599 | ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); | 3399 | ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); |
3600 | idx += pkt.count + 2; | 3400 | idx += pkt.count + 2; |
3601 | break; | 3401 | break; |
@@ -3623,88 +3423,79 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
3623 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | 3423 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) |
3624 | { | 3424 | { |
3625 | u32 idx = 0; | 3425 | u32 idx = 0; |
3626 | u32 header, cmd, count, tiled, new_cmd, misc; | 3426 | u32 header, cmd, count, sub_cmd; |
3627 | 3427 | ||
3628 | do { | 3428 | do { |
3629 | header = ib->ptr[idx]; | 3429 | header = ib->ptr[idx]; |
3630 | cmd = GET_DMA_CMD(header); | 3430 | cmd = GET_DMA_CMD(header); |
3631 | count = GET_DMA_COUNT(header); | 3431 | count = GET_DMA_COUNT(header); |
3632 | tiled = GET_DMA_T(header); | 3432 | sub_cmd = GET_DMA_SUB_CMD(header); |
3633 | new_cmd = GET_DMA_NEW(header); | ||
3634 | misc = GET_DMA_MISC(header); | ||
3635 | 3433 | ||
3636 | switch (cmd) { | 3434 | switch (cmd) { |
3637 | case DMA_PACKET_WRITE: | 3435 | case DMA_PACKET_WRITE: |
3638 | if (tiled) | 3436 | switch (sub_cmd) { |
3437 | /* tiled */ | ||
3438 | case 8: | ||
3639 | idx += count + 7; | 3439 | idx += count + 7; |
3640 | else | 3440 | break; |
3441 | /* linear */ | ||
3442 | case 0: | ||
3641 | idx += count + 3; | 3443 | idx += count + 3; |
3444 | break; | ||
3445 | default: | ||
3446 | DRM_ERROR("bad DMA_PACKET_WRITE [%6d] 0x%08x sub cmd is not 0 or 8\n", idx, ib->ptr[idx]); | ||
3447 | return -EINVAL; | ||
3448 | } | ||
3642 | break; | 3449 | break; |
3643 | case DMA_PACKET_COPY: | 3450 | case DMA_PACKET_COPY: |
3644 | if (tiled) { | 3451 | switch (sub_cmd) { |
3645 | if (new_cmd) { | 3452 | /* Copy L2L, DW aligned */ |
3646 | switch (misc) { | 3453 | case 0x00: |
3647 | case 0: | 3454 | idx += 5; |
3648 | /* L2T, frame to fields */ | 3455 | break; |
3649 | idx += 10; | 3456 | /* Copy L2T/T2L */ |
3650 | break; | 3457 | case 0x08: |
3651 | case 1: | 3458 | idx += 9; |
3652 | /* L2T, T2L partial */ | 3459 | break; |
3653 | idx += 12; | 3460 | /* Copy L2L, byte aligned */ |
3654 | break; | 3461 | case 0x40: |
3655 | case 3: | 3462 | idx += 5; |
3656 | /* L2T, broadcast */ | 3463 | break; |
3657 | idx += 10; | 3464 | /* Copy L2L, partial */ |
3658 | break; | 3465 | case 0x41: |
3659 | case 4: | 3466 | idx += 9; |
3660 | /* L2T, T2L */ | 3467 | break; |
3661 | idx += 9; | 3468 | /* Copy L2L, DW aligned, broadcast */ |
3662 | break; | 3469 | case 0x44: |
3663 | case 5: | 3470 | idx += 7; |
3664 | /* T2T partial */ | 3471 | break; |
3665 | idx += 13; | 3472 | /* Copy L2T Frame to Field */ |
3666 | break; | 3473 | case 0x48: |
3667 | case 7: | 3474 | idx += 10; |
3668 | /* L2T, broadcast */ | 3475 | break; |
3669 | idx += 10; | 3476 | /* Copy L2T/T2L, partial */ |
3670 | break; | 3477 | case 0x49: |
3671 | default: | 3478 | idx += 12; |
3672 | DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); | 3479 | break; |
3673 | return -EINVAL; | 3480 | /* Copy L2T broadcast */ |
3674 | } | 3481 | case 0x4b: |
3675 | } else { | 3482 | idx += 10; |
3676 | switch (misc) { | 3483 | break; |
3677 | case 0: | 3484 | /* Copy L2T/T2L (tile units) */ |
3678 | idx += 9; | 3485 | case 0x4c: |
3679 | break; | 3486 | idx += 9; |
3680 | default: | 3487 | break; |
3681 | DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); | 3488 | /* Copy T2T, partial (tile units) */ |
3682 | return -EINVAL; | 3489 | case 0x4d: |
3683 | } | 3490 | idx += 13; |
3684 | } | 3491 | break; |
3685 | } else { | 3492 | /* Copy L2T broadcast (tile units) */ |
3686 | if (new_cmd) { | 3493 | case 0x4f: |
3687 | switch (misc) { | 3494 | idx += 10; |
3688 | case 0: | 3495 | break; |
3689 | /* L2L, byte */ | 3496 | default: |
3690 | idx += 5; | 3497 | DRM_ERROR("bad DMA_PACKET_COPY [%6d] 0x%08x invalid sub cmd\n", idx, ib->ptr[idx]); |
3691 | break; | 3498 | return -EINVAL; |
3692 | case 1: | ||
3693 | /* L2L, partial */ | ||
3694 | idx += 9; | ||
3695 | break; | ||
3696 | case 4: | ||
3697 | /* L2L, dw, broadcast */ | ||
3698 | idx += 7; | ||
3699 | break; | ||
3700 | default: | ||
3701 | DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc); | ||
3702 | return -EINVAL; | ||
3703 | } | ||
3704 | } else { | ||
3705 | /* L2L, dw */ | ||
3706 | idx += 5; | ||
3707 | } | ||
3708 | } | 3499 | } |
3709 | break; | 3500 | break; |
3710 | case DMA_PACKET_CONSTANT_FILL: | 3501 | case DMA_PACKET_CONSTANT_FILL: |