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 |
