diff options
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cs.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 1 | ||||
-rw-r--r-- | include/drm/radeon_drm.h | 1 |
4 files changed, 52 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 972f1679d1c9..f467fe5edf09 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -632,6 +632,7 @@ struct radeon_ib { | |||
632 | uint32_t *ptr; | 632 | uint32_t *ptr; |
633 | struct radeon_fence *fence; | 633 | struct radeon_fence *fence; |
634 | unsigned vm_id; | 634 | unsigned vm_id; |
635 | bool is_const_ib; | ||
635 | }; | 636 | }; |
636 | 637 | ||
637 | /* | 638 | /* |
@@ -836,7 +837,9 @@ struct radeon_cs_parser { | |||
836 | int chunk_ib_idx; | 837 | int chunk_ib_idx; |
837 | int chunk_relocs_idx; | 838 | int chunk_relocs_idx; |
838 | int chunk_flags_idx; | 839 | int chunk_flags_idx; |
840 | int chunk_const_ib_idx; | ||
839 | struct radeon_ib *ib; | 841 | struct radeon_ib *ib; |
842 | struct radeon_ib *const_ib; | ||
840 | void *track; | 843 | void *track; |
841 | unsigned family; | 844 | unsigned family; |
842 | int parser_error; | 845 | int parser_error; |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index d9d9f5a59c42..087bd5053774 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -170,6 +170,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
170 | p->chunk_ib_idx = -1; | 170 | p->chunk_ib_idx = -1; |
171 | p->chunk_relocs_idx = -1; | 171 | p->chunk_relocs_idx = -1; |
172 | p->chunk_flags_idx = -1; | 172 | p->chunk_flags_idx = -1; |
173 | p->chunk_const_ib_idx = -1; | ||
173 | p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); | 174 | p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); |
174 | if (p->chunks_array == NULL) { | 175 | if (p->chunks_array == NULL) { |
175 | return -ENOMEM; | 176 | return -ENOMEM; |
@@ -208,6 +209,12 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
208 | if (p->chunks[i].length_dw == 0) | 209 | if (p->chunks[i].length_dw == 0) |
209 | return -EINVAL; | 210 | return -EINVAL; |
210 | } | 211 | } |
212 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_CONST_IB) { | ||
213 | p->chunk_const_ib_idx = i; | ||
214 | /* zero length CONST IB isn't useful */ | ||
215 | if (p->chunks[i].length_dw == 0) | ||
216 | return -EINVAL; | ||
217 | } | ||
211 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { | 218 | if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { |
212 | p->chunk_flags_idx = i; | 219 | p->chunk_flags_idx = i; |
213 | /* zero length flags aren't useful */ | 220 | /* zero length flags aren't useful */ |
@@ -389,6 +396,32 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
389 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 396 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
390 | return 0; | 397 | return 0; |
391 | 398 | ||
399 | if ((rdev->family >= CHIP_TAHITI) && | ||
400 | (parser->chunk_const_ib_idx != -1)) { | ||
401 | ib_chunk = &parser->chunks[parser->chunk_const_ib_idx]; | ||
402 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | ||
403 | DRM_ERROR("cs IB CONST too big: %d\n", ib_chunk->length_dw); | ||
404 | return -EINVAL; | ||
405 | } | ||
406 | r = radeon_ib_get(rdev, parser->ring, &parser->const_ib, | ||
407 | ib_chunk->length_dw * 4); | ||
408 | if (r) { | ||
409 | DRM_ERROR("Failed to get const ib !\n"); | ||
410 | return r; | ||
411 | } | ||
412 | parser->const_ib->is_const_ib = true; | ||
413 | parser->const_ib->length_dw = ib_chunk->length_dw; | ||
414 | /* Copy the packet into the IB */ | ||
415 | if (DRM_COPY_FROM_USER(parser->const_ib->ptr, ib_chunk->user_ptr, | ||
416 | ib_chunk->length_dw * 4)) { | ||
417 | return -EFAULT; | ||
418 | } | ||
419 | r = radeon_ring_ib_parse(rdev, parser->ring, parser->const_ib); | ||
420 | if (r) { | ||
421 | return r; | ||
422 | } | ||
423 | } | ||
424 | |||
392 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; | 425 | ib_chunk = &parser->chunks[parser->chunk_ib_idx]; |
393 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { | 426 | if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { |
394 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); | 427 | DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); |
@@ -424,11 +457,25 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
424 | if (r) { | 457 | if (r) { |
425 | DRM_ERROR("Failed to synchronize rings !\n"); | 458 | DRM_ERROR("Failed to synchronize rings !\n"); |
426 | } | 459 | } |
460 | |||
461 | if ((rdev->family >= CHIP_TAHITI) && | ||
462 | (parser->chunk_const_ib_idx != -1)) { | ||
463 | parser->const_ib->vm_id = vm->id; | ||
464 | /* ib pool is bind at 0 in virtual address space to gpu_addr is the | ||
465 | * offset inside the pool bo | ||
466 | */ | ||
467 | parser->const_ib->gpu_addr = parser->const_ib->sa_bo.offset; | ||
468 | r = radeon_ib_schedule(rdev, parser->const_ib); | ||
469 | if (r) | ||
470 | goto out; | ||
471 | } | ||
472 | |||
427 | parser->ib->vm_id = vm->id; | 473 | parser->ib->vm_id = vm->id; |
428 | /* ib pool is bind at 0 in virtual address space to gpu_addr is the | 474 | /* ib pool is bind at 0 in virtual address space to gpu_addr is the |
429 | * offset inside the pool bo | 475 | * offset inside the pool bo |
430 | */ | 476 | */ |
431 | parser->ib->gpu_addr = parser->ib->sa_bo.offset; | 477 | parser->ib->gpu_addr = parser->ib->sa_bo.offset; |
478 | parser->ib->is_const_ib = false; | ||
432 | r = radeon_ib_schedule(rdev, parser->ib); | 479 | r = radeon_ib_schedule(rdev, parser->ib); |
433 | out: | 480 | out: |
434 | if (!r) { | 481 | if (!r) { |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 30566201dffb..cc33b3d7c33b 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -133,6 +133,7 @@ retry: | |||
133 | (*ib)->gpu_addr += (*ib)->sa_bo.offset; | 133 | (*ib)->gpu_addr += (*ib)->sa_bo.offset; |
134 | (*ib)->fence = fence; | 134 | (*ib)->fence = fence; |
135 | (*ib)->vm_id = 0; | 135 | (*ib)->vm_id = 0; |
136 | (*ib)->is_const_ib = false; | ||
136 | /* ib are most likely to be allocated in a ring fashion | 137 | /* ib are most likely to be allocated in a ring fashion |
137 | * thus rdev->ib_pool.head_id should be the id of the | 138 | * thus rdev->ib_pool.head_id should be the id of the |
138 | * oldest ib | 139 | * oldest ib |
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 6cde931d8e68..7c491b4bcf65 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h | |||
@@ -908,6 +908,7 @@ struct drm_radeon_gem_va { | |||
908 | #define RADEON_CHUNK_ID_RELOCS 0x01 | 908 | #define RADEON_CHUNK_ID_RELOCS 0x01 |
909 | #define RADEON_CHUNK_ID_IB 0x02 | 909 | #define RADEON_CHUNK_ID_IB 0x02 |
910 | #define RADEON_CHUNK_ID_FLAGS 0x03 | 910 | #define RADEON_CHUNK_ID_FLAGS 0x03 |
911 | #define RADEON_CHUNK_ID_CONST_IB 0x04 | ||
911 | 912 | ||
912 | /* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */ | 913 | /* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */ |
913 | #define RADEON_CS_KEEP_TILING_FLAGS 0x01 | 914 | #define RADEON_CS_KEEP_TILING_FLAGS 0x01 |