diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-07-20 00:07:56 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2019-07-20 00:07:56 -0400 |
commit | c39f2d9db0fd81ea20bb5cce9b3f082ca63753e2 (patch) | |
tree | 8e80ed5601b4fb8880a2ca8e08802bc8b1f850bd /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |
parent | 597473720f4dc69749542bfcfed4a927a43d935e (diff) | |
parent | 771a081e44a9baa1991ef011cc453ef425591740 (diff) |
Merge branch 'next' into for-linus
Prepare second round of input updates for 5.3 merge window.
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 152 |
1 files changed, 128 insertions, 24 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 52a5e4fdc95b..2f6239b6be6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -215,6 +215,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs | |||
215 | case AMDGPU_CHUNK_ID_SYNCOBJ_IN: | 215 | case AMDGPU_CHUNK_ID_SYNCOBJ_IN: |
216 | case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: | 216 | case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: |
217 | case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES: | 217 | case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES: |
218 | case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT: | ||
219 | case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL: | ||
218 | break; | 220 | break; |
219 | 221 | ||
220 | default: | 222 | default: |
@@ -804,9 +806,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, | |||
804 | ttm_eu_backoff_reservation(&parser->ticket, | 806 | ttm_eu_backoff_reservation(&parser->ticket, |
805 | &parser->validated); | 807 | &parser->validated); |
806 | 808 | ||
807 | for (i = 0; i < parser->num_post_dep_syncobjs; i++) | 809 | for (i = 0; i < parser->num_post_deps; i++) { |
808 | drm_syncobj_put(parser->post_dep_syncobjs[i]); | 810 | drm_syncobj_put(parser->post_deps[i].syncobj); |
809 | kfree(parser->post_dep_syncobjs); | 811 | kfree(parser->post_deps[i].chain); |
812 | } | ||
813 | kfree(parser->post_deps); | ||
810 | 814 | ||
811 | dma_fence_put(parser->fence); | 815 | dma_fence_put(parser->fence); |
812 | 816 | ||
@@ -1117,13 +1121,18 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, | |||
1117 | } | 1121 | } |
1118 | 1122 | ||
1119 | static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, | 1123 | static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, |
1120 | uint32_t handle) | 1124 | uint32_t handle, u64 point, |
1125 | u64 flags) | ||
1121 | { | 1126 | { |
1122 | int r; | ||
1123 | struct dma_fence *fence; | 1127 | struct dma_fence *fence; |
1124 | r = drm_syncobj_find_fence(p->filp, handle, 0, 0, &fence); | 1128 | int r; |
1125 | if (r) | 1129 | |
1130 | r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence); | ||
1131 | if (r) { | ||
1132 | DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n", | ||
1133 | handle, point, r); | ||
1126 | return r; | 1134 | return r; |
1135 | } | ||
1127 | 1136 | ||
1128 | r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true); | 1137 | r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true); |
1129 | dma_fence_put(fence); | 1138 | dma_fence_put(fence); |
@@ -1134,46 +1143,118 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, | |||
1134 | static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p, | 1143 | static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p, |
1135 | struct amdgpu_cs_chunk *chunk) | 1144 | struct amdgpu_cs_chunk *chunk) |
1136 | { | 1145 | { |
1146 | struct drm_amdgpu_cs_chunk_sem *deps; | ||
1137 | unsigned num_deps; | 1147 | unsigned num_deps; |
1138 | int i, r; | 1148 | int i, r; |
1139 | struct drm_amdgpu_cs_chunk_sem *deps; | ||
1140 | 1149 | ||
1141 | deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; | 1150 | deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; |
1142 | num_deps = chunk->length_dw * 4 / | 1151 | num_deps = chunk->length_dw * 4 / |
1143 | sizeof(struct drm_amdgpu_cs_chunk_sem); | 1152 | sizeof(struct drm_amdgpu_cs_chunk_sem); |
1153 | for (i = 0; i < num_deps; ++i) { | ||
1154 | r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle, | ||
1155 | 0, 0); | ||
1156 | if (r) | ||
1157 | return r; | ||
1158 | } | ||
1159 | |||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1144 | 1163 | ||
1164 | static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser *p, | ||
1165 | struct amdgpu_cs_chunk *chunk) | ||
1166 | { | ||
1167 | struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps; | ||
1168 | unsigned num_deps; | ||
1169 | int i, r; | ||
1170 | |||
1171 | syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata; | ||
1172 | num_deps = chunk->length_dw * 4 / | ||
1173 | sizeof(struct drm_amdgpu_cs_chunk_syncobj); | ||
1145 | for (i = 0; i < num_deps; ++i) { | 1174 | for (i = 0; i < num_deps; ++i) { |
1146 | r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle); | 1175 | r = amdgpu_syncobj_lookup_and_add_to_sync(p, |
1176 | syncobj_deps[i].handle, | ||
1177 | syncobj_deps[i].point, | ||
1178 | syncobj_deps[i].flags); | ||
1147 | if (r) | 1179 | if (r) |
1148 | return r; | 1180 | return r; |
1149 | } | 1181 | } |
1182 | |||
1150 | return 0; | 1183 | return 0; |
1151 | } | 1184 | } |
1152 | 1185 | ||
1153 | static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p, | 1186 | static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p, |
1154 | struct amdgpu_cs_chunk *chunk) | 1187 | struct amdgpu_cs_chunk *chunk) |
1155 | { | 1188 | { |
1189 | struct drm_amdgpu_cs_chunk_sem *deps; | ||
1156 | unsigned num_deps; | 1190 | unsigned num_deps; |
1157 | int i; | 1191 | int i; |
1158 | struct drm_amdgpu_cs_chunk_sem *deps; | 1192 | |
1159 | deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; | 1193 | deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; |
1160 | num_deps = chunk->length_dw * 4 / | 1194 | num_deps = chunk->length_dw * 4 / |
1161 | sizeof(struct drm_amdgpu_cs_chunk_sem); | 1195 | sizeof(struct drm_amdgpu_cs_chunk_sem); |
1162 | 1196 | ||
1163 | p->post_dep_syncobjs = kmalloc_array(num_deps, | 1197 | p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps), |
1164 | sizeof(struct drm_syncobj *), | 1198 | GFP_KERNEL); |
1165 | GFP_KERNEL); | 1199 | p->num_post_deps = 0; |
1166 | p->num_post_dep_syncobjs = 0; | ||
1167 | 1200 | ||
1168 | if (!p->post_dep_syncobjs) | 1201 | if (!p->post_deps) |
1169 | return -ENOMEM; | 1202 | return -ENOMEM; |
1170 | 1203 | ||
1204 | |||
1171 | for (i = 0; i < num_deps; ++i) { | 1205 | for (i = 0; i < num_deps; ++i) { |
1172 | p->post_dep_syncobjs[i] = drm_syncobj_find(p->filp, deps[i].handle); | 1206 | p->post_deps[i].syncobj = |
1173 | if (!p->post_dep_syncobjs[i]) | 1207 | drm_syncobj_find(p->filp, deps[i].handle); |
1208 | if (!p->post_deps[i].syncobj) | ||
1174 | return -EINVAL; | 1209 | return -EINVAL; |
1175 | p->num_post_dep_syncobjs++; | 1210 | p->post_deps[i].chain = NULL; |
1211 | p->post_deps[i].point = 0; | ||
1212 | p->num_post_deps++; | ||
1176 | } | 1213 | } |
1214 | |||
1215 | return 0; | ||
1216 | } | ||
1217 | |||
1218 | |||
1219 | static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p, | ||
1220 | struct amdgpu_cs_chunk | ||
1221 | *chunk) | ||
1222 | { | ||
1223 | struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps; | ||
1224 | unsigned num_deps; | ||
1225 | int i; | ||
1226 | |||
1227 | syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata; | ||
1228 | num_deps = chunk->length_dw * 4 / | ||
1229 | sizeof(struct drm_amdgpu_cs_chunk_syncobj); | ||
1230 | |||
1231 | p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps), | ||
1232 | GFP_KERNEL); | ||
1233 | p->num_post_deps = 0; | ||
1234 | |||
1235 | if (!p->post_deps) | ||
1236 | return -ENOMEM; | ||
1237 | |||
1238 | for (i = 0; i < num_deps; ++i) { | ||
1239 | struct amdgpu_cs_post_dep *dep = &p->post_deps[i]; | ||
1240 | |||
1241 | dep->chain = NULL; | ||
1242 | if (syncobj_deps[i].point) { | ||
1243 | dep->chain = kmalloc(sizeof(*dep->chain), GFP_KERNEL); | ||
1244 | if (!dep->chain) | ||
1245 | return -ENOMEM; | ||
1246 | } | ||
1247 | |||
1248 | dep->syncobj = drm_syncobj_find(p->filp, | ||
1249 | syncobj_deps[i].handle); | ||
1250 | if (!dep->syncobj) { | ||
1251 | kfree(dep->chain); | ||
1252 | return -EINVAL; | ||
1253 | } | ||
1254 | dep->point = syncobj_deps[i].point; | ||
1255 | p->num_post_deps++; | ||
1256 | } | ||
1257 | |||
1177 | return 0; | 1258 | return 0; |
1178 | } | 1259 | } |
1179 | 1260 | ||
@@ -1187,19 +1268,33 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, | |||
1187 | 1268 | ||
1188 | chunk = &p->chunks[i]; | 1269 | chunk = &p->chunks[i]; |
1189 | 1270 | ||
1190 | if (chunk->chunk_id == AMDGPU_CHUNK_ID_DEPENDENCIES || | 1271 | switch (chunk->chunk_id) { |
1191 | chunk->chunk_id == AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES) { | 1272 | case AMDGPU_CHUNK_ID_DEPENDENCIES: |
1273 | case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES: | ||
1192 | r = amdgpu_cs_process_fence_dep(p, chunk); | 1274 | r = amdgpu_cs_process_fence_dep(p, chunk); |
1193 | if (r) | 1275 | if (r) |
1194 | return r; | 1276 | return r; |
1195 | } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) { | 1277 | break; |
1278 | case AMDGPU_CHUNK_ID_SYNCOBJ_IN: | ||
1196 | r = amdgpu_cs_process_syncobj_in_dep(p, chunk); | 1279 | r = amdgpu_cs_process_syncobj_in_dep(p, chunk); |
1197 | if (r) | 1280 | if (r) |
1198 | return r; | 1281 | return r; |
1199 | } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) { | 1282 | break; |
1283 | case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: | ||
1200 | r = amdgpu_cs_process_syncobj_out_dep(p, chunk); | 1284 | r = amdgpu_cs_process_syncobj_out_dep(p, chunk); |
1201 | if (r) | 1285 | if (r) |
1202 | return r; | 1286 | return r; |
1287 | break; | ||
1288 | case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT: | ||
1289 | r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk); | ||
1290 | if (r) | ||
1291 | return r; | ||
1292 | break; | ||
1293 | case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL: | ||
1294 | r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk); | ||
1295 | if (r) | ||
1296 | return r; | ||
1297 | break; | ||
1203 | } | 1298 | } |
1204 | } | 1299 | } |
1205 | 1300 | ||
@@ -1210,8 +1305,17 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) | |||
1210 | { | 1305 | { |
1211 | int i; | 1306 | int i; |
1212 | 1307 | ||
1213 | for (i = 0; i < p->num_post_dep_syncobjs; ++i) | 1308 | for (i = 0; i < p->num_post_deps; ++i) { |
1214 | drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence); | 1309 | if (p->post_deps[i].chain && p->post_deps[i].point) { |
1310 | drm_syncobj_add_point(p->post_deps[i].syncobj, | ||
1311 | p->post_deps[i].chain, | ||
1312 | p->fence, p->post_deps[i].point); | ||
1313 | p->post_deps[i].chain = NULL; | ||
1314 | } else { | ||
1315 | drm_syncobj_replace_fence(p->post_deps[i].syncobj, | ||
1316 | p->fence); | ||
1317 | } | ||
1318 | } | ||
1215 | } | 1319 | } |
1216 | 1320 | ||
1217 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, | 1321 | static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, |