aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_cs.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-03-20 17:18:14 -0400
committerDave Airlie <airlied@redhat.com>2012-03-21 02:55:53 -0400
commitdfcf5f36529d69eb35f4fdedfa6f244c5249698c (patch)
treeda1fc31a5ef8d53c63786121f16f29fe3b12a92a /drivers/gpu/drm/radeon/radeon_cs.c
parentd2800ee59ed28a5eaf3a4a8645feca040eacf7df (diff)
drm/radeon/kms: add support for the CONST IB to the CS ioctl
This adds a new chunk id to the CS ioctl to support the INDIRECT_BUFFER_CONST packet. On SI, the CP adds a new engine called the CE (Constant Engine) which runs simulatenously with the DE (Drawing Engine, formerly called the ME). This allows the CP to process two related IBs simultaneously. The CE is tasked with loading the constant data (constant buffers, resource descriptors, samplers, etc.) while the DE loads context register state and issues drawing commands. It's up to the userspace application to sychronize the CE and the DE using special synchronization packets. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c47
1 files changed, 47 insertions, 0 deletions
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);
433out: 480out:
434 if (!r) { 481 if (!r) {