aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vc4/vc4_validate.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_validate.c')
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c54
1 files changed, 24 insertions, 30 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index da6f1e138e8d..3de8f11595c0 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -348,10 +348,11 @@ static int
348validate_tile_binning_config(VALIDATE_ARGS) 348validate_tile_binning_config(VALIDATE_ARGS)
349{ 349{
350 struct drm_device *dev = exec->exec_bo->base.dev; 350 struct drm_device *dev = exec->exec_bo->base.dev;
351 struct vc4_bo *tile_bo; 351 struct vc4_dev *vc4 = to_vc4_dev(dev);
352 uint8_t flags; 352 uint8_t flags;
353 uint32_t tile_state_size, tile_alloc_size; 353 uint32_t tile_state_size;
354 uint32_t tile_count; 354 uint32_t tile_count, bin_addr;
355 int bin_slot;
355 356
356 if (exec->found_tile_binning_mode_config_packet) { 357 if (exec->found_tile_binning_mode_config_packet) {
357 DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n"); 358 DRM_ERROR("Duplicate VC4_PACKET_TILE_BINNING_MODE_CONFIG\n");
@@ -377,13 +378,28 @@ validate_tile_binning_config(VALIDATE_ARGS)
377 return -EINVAL; 378 return -EINVAL;
378 } 379 }
379 380
381 bin_slot = vc4_v3d_get_bin_slot(vc4);
382 if (bin_slot < 0) {
383 if (bin_slot != -EINTR && bin_slot != -ERESTARTSYS) {
384 DRM_ERROR("Failed to allocate binner memory: %d\n",
385 bin_slot);
386 }
387 return bin_slot;
388 }
389
390 /* The slot we allocated will only be used by this job, and is
391 * free when the job completes rendering.
392 */
393 exec->bin_slots |= BIT(bin_slot);
394 bin_addr = vc4->bin_bo->base.paddr + bin_slot * vc4->bin_alloc_size;
395
380 /* The tile state data array is 48 bytes per tile, and we put it at 396 /* The tile state data array is 48 bytes per tile, and we put it at
381 * the start of a BO containing both it and the tile alloc. 397 * the start of a BO containing both it and the tile alloc.
382 */ 398 */
383 tile_state_size = 48 * tile_count; 399 tile_state_size = 48 * tile_count;
384 400
385 /* Since the tile alloc array will follow us, align. */ 401 /* Since the tile alloc array will follow us, align. */
386 exec->tile_alloc_offset = roundup(tile_state_size, 4096); 402 exec->tile_alloc_offset = bin_addr + roundup(tile_state_size, 4096);
387 403
388 *(uint8_t *)(validated + 14) = 404 *(uint8_t *)(validated + 14) =
389 ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK | 405 ((flags & ~(VC4_BIN_CONFIG_ALLOC_INIT_BLOCK_SIZE_MASK |
@@ -394,35 +410,13 @@ validate_tile_binning_config(VALIDATE_ARGS)
394 VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128, 410 VC4_SET_FIELD(VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE_128,
395 VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE)); 411 VC4_BIN_CONFIG_ALLOC_BLOCK_SIZE));
396 412
397 /* Initial block size. */
398 tile_alloc_size = 32 * tile_count;
399
400 /*
401 * The initial allocation gets rounded to the next 256 bytes before
402 * the hardware starts fulfilling further allocations.
403 */
404 tile_alloc_size = roundup(tile_alloc_size, 256);
405
406 /* Add space for the extra allocations. This is what gets used first,
407 * before overflow memory. It must have at least 4096 bytes, but we
408 * want to avoid overflow memory usage if possible.
409 */
410 tile_alloc_size += 1024 * 1024;
411
412 tile_bo = vc4_bo_create(dev, exec->tile_alloc_offset + tile_alloc_size,
413 true);
414 exec->tile_bo = &tile_bo->base;
415 if (IS_ERR(exec->tile_bo))
416 return PTR_ERR(exec->tile_bo);
417 list_add_tail(&tile_bo->unref_head, &exec->unref_list);
418
419 /* tile alloc address. */ 413 /* tile alloc address. */
420 *(uint32_t *)(validated + 0) = (exec->tile_bo->paddr + 414 *(uint32_t *)(validated + 0) = exec->tile_alloc_offset;
421 exec->tile_alloc_offset);
422 /* tile alloc size. */ 415 /* tile alloc size. */
423 *(uint32_t *)(validated + 4) = tile_alloc_size; 416 *(uint32_t *)(validated + 4) = (bin_addr + vc4->bin_alloc_size -
417 exec->tile_alloc_offset);
424 /* tile state address. */ 418 /* tile state address. */
425 *(uint32_t *)(validated + 8) = exec->tile_bo->paddr; 419 *(uint32_t *)(validated + 8) = bin_addr;
426 420
427 return 0; 421 return 0;
428} 422}