aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-12-13 12:17:38 -0500
committerAlex Deucher <alexander.deucher@amd.com>2012-12-14 10:45:26 -0500
commitcd459e525f4faeefa0bf78e1bcba3e04496b2cb5 (patch)
treeca8d6d1d855694ce843bdd83d7e48cd00842838f
parentd2ead3eaf8a4bf92129eda69189ce18a6c1cc8bd (diff)
drm/radeon: add VM CS parser support for async DMA on cayman/TN/SI
Allows us to use async DMA from userspace. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c111
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h1
3 files changed, 118 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 0a1ec4e6f15e..9a9d3ae6c188 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -3556,3 +3556,114 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
3556 3556
3557 return ret; 3557 return ret;
3558} 3558}
3559
3560/**
3561 * evergreen_dma_ib_parse() - parse the DMA IB for VM
3562 * @rdev: radeon_device pointer
3563 * @ib: radeon_ib pointer
3564 *
3565 * Parses the DMA IB from the VM CS ioctl
3566 * checks for errors. (Cayman-SI)
3567 * Returns 0 for success and an error on failure.
3568 **/
3569int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
3570{
3571 u32 idx = 0;
3572 u32 header, cmd, count, tiled, new_cmd, misc;
3573
3574 do {
3575 header = ib->ptr[idx];
3576 cmd = GET_DMA_CMD(header);
3577 count = GET_DMA_COUNT(header);
3578 tiled = GET_DMA_T(header);
3579 new_cmd = GET_DMA_NEW(header);
3580 misc = GET_DMA_MISC(header);
3581
3582 switch (cmd) {
3583 case DMA_PACKET_WRITE:
3584 if (tiled)
3585 idx += count + 7;
3586 else
3587 idx += count + 3;
3588 break;
3589 case DMA_PACKET_COPY:
3590 if (tiled) {
3591 if (new_cmd) {
3592 switch (misc) {
3593 case 0:
3594 /* L2T, frame to fields */
3595 idx += 10;
3596 break;
3597 case 1:
3598 /* L2T, T2L partial */
3599 idx += 12;
3600 break;
3601 case 3:
3602 /* L2T, broadcast */
3603 idx += 10;
3604 break;
3605 case 4:
3606 /* L2T, T2L */
3607 idx += 9;
3608 break;
3609 case 5:
3610 /* T2T partial */
3611 idx += 13;
3612 break;
3613 case 7:
3614 /* L2T, broadcast */
3615 idx += 10;
3616 break;
3617 default:
3618 DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
3619 return -EINVAL;
3620 }
3621 } else {
3622 switch (misc) {
3623 case 0:
3624 idx += 9;
3625 break;
3626 default:
3627 DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
3628 return -EINVAL;
3629 }
3630 }
3631 } else {
3632 if (new_cmd) {
3633 switch (misc) {
3634 case 0:
3635 /* L2L, byte */
3636 idx += 5;
3637 break;
3638 case 1:
3639 /* L2L, partial */
3640 idx += 9;
3641 break;
3642 case 4:
3643 /* L2L, dw, broadcast */
3644 idx += 7;
3645 break;
3646 default:
3647 DRM_ERROR("bad DMA_PACKET_COPY misc %u\n", misc);
3648 return -EINVAL;
3649 }
3650 } else {
3651 /* L2L, dw */
3652 idx += 5;
3653 }
3654 }
3655 break;
3656 case DMA_PACKET_CONSTANT_FILL:
3657 idx += 4;
3658 break;
3659 case DMA_PACKET_NOP:
3660 idx += 1;
3661 break;
3662 default:
3663 DRM_ERROR("Unknown packet type %d at %d !\n", cmd, idx);
3664 return -EINVAL;
3665 }
3666 } while (idx < ib->length_dw);
3667
3668 return 0;
3669}
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index ac1d5702144c..596bcbe80ed0 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1484,6 +1484,7 @@ static struct radeon_asic cayman_asic = {
1484 }, 1484 },
1485 [R600_RING_TYPE_DMA_INDEX] = { 1485 [R600_RING_TYPE_DMA_INDEX] = {
1486 .ib_execute = &cayman_dma_ring_ib_execute, 1486 .ib_execute = &cayman_dma_ring_ib_execute,
1487 .ib_parse = &evergreen_dma_ib_parse,
1487 .emit_fence = &evergreen_dma_fence_ring_emit, 1488 .emit_fence = &evergreen_dma_fence_ring_emit,
1488 .emit_semaphore = &r600_dma_semaphore_ring_emit, 1489 .emit_semaphore = &r600_dma_semaphore_ring_emit,
1489 .cs_parse = &evergreen_dma_cs_parse, 1490 .cs_parse = &evergreen_dma_cs_parse,
@@ -1494,6 +1495,7 @@ static struct radeon_asic cayman_asic = {
1494 }, 1495 },
1495 [CAYMAN_RING_TYPE_DMA1_INDEX] = { 1496 [CAYMAN_RING_TYPE_DMA1_INDEX] = {
1496 .ib_execute = &cayman_dma_ring_ib_execute, 1497 .ib_execute = &cayman_dma_ring_ib_execute,
1498 .ib_parse = &evergreen_dma_ib_parse,
1497 .emit_fence = &evergreen_dma_fence_ring_emit, 1499 .emit_fence = &evergreen_dma_fence_ring_emit,
1498 .emit_semaphore = &r600_dma_semaphore_ring_emit, 1500 .emit_semaphore = &r600_dma_semaphore_ring_emit,
1499 .cs_parse = &evergreen_dma_cs_parse, 1501 .cs_parse = &evergreen_dma_cs_parse,
@@ -1609,6 +1611,7 @@ static struct radeon_asic trinity_asic = {
1609 }, 1611 },
1610 [R600_RING_TYPE_DMA_INDEX] = { 1612 [R600_RING_TYPE_DMA_INDEX] = {
1611 .ib_execute = &cayman_dma_ring_ib_execute, 1613 .ib_execute = &cayman_dma_ring_ib_execute,
1614 .ib_parse = &evergreen_dma_ib_parse,
1612 .emit_fence = &evergreen_dma_fence_ring_emit, 1615 .emit_fence = &evergreen_dma_fence_ring_emit,
1613 .emit_semaphore = &r600_dma_semaphore_ring_emit, 1616 .emit_semaphore = &r600_dma_semaphore_ring_emit,
1614 .cs_parse = &evergreen_dma_cs_parse, 1617 .cs_parse = &evergreen_dma_cs_parse,
@@ -1619,6 +1622,7 @@ static struct radeon_asic trinity_asic = {
1619 }, 1622 },
1620 [CAYMAN_RING_TYPE_DMA1_INDEX] = { 1623 [CAYMAN_RING_TYPE_DMA1_INDEX] = {
1621 .ib_execute = &cayman_dma_ring_ib_execute, 1624 .ib_execute = &cayman_dma_ring_ib_execute,
1625 .ib_parse = &evergreen_dma_ib_parse,
1622 .emit_fence = &evergreen_dma_fence_ring_emit, 1626 .emit_fence = &evergreen_dma_fence_ring_emit,
1623 .emit_semaphore = &r600_dma_semaphore_ring_emit, 1627 .emit_semaphore = &r600_dma_semaphore_ring_emit,
1624 .cs_parse = &evergreen_dma_cs_parse, 1628 .cs_parse = &evergreen_dma_cs_parse,
@@ -1734,6 +1738,7 @@ static struct radeon_asic si_asic = {
1734 }, 1738 },
1735 [R600_RING_TYPE_DMA_INDEX] = { 1739 [R600_RING_TYPE_DMA_INDEX] = {
1736 .ib_execute = &cayman_dma_ring_ib_execute, 1740 .ib_execute = &cayman_dma_ring_ib_execute,
1741 .ib_parse = &evergreen_dma_ib_parse,
1737 .emit_fence = &evergreen_dma_fence_ring_emit, 1742 .emit_fence = &evergreen_dma_fence_ring_emit,
1738 .emit_semaphore = &r600_dma_semaphore_ring_emit, 1743 .emit_semaphore = &r600_dma_semaphore_ring_emit,
1739 .cs_parse = NULL, 1744 .cs_parse = NULL,
@@ -1744,6 +1749,7 @@ static struct radeon_asic si_asic = {
1744 }, 1749 },
1745 [CAYMAN_RING_TYPE_DMA1_INDEX] = { 1750 [CAYMAN_RING_TYPE_DMA1_INDEX] = {
1746 .ib_execute = &cayman_dma_ring_ib_execute, 1751 .ib_execute = &cayman_dma_ring_ib_execute,
1752 .ib_parse = &evergreen_dma_ib_parse,
1747 .emit_fence = &evergreen_dma_fence_ring_emit, 1753 .emit_fence = &evergreen_dma_fence_ring_emit,
1748 .emit_semaphore = &r600_dma_semaphore_ring_emit, 1754 .emit_semaphore = &r600_dma_semaphore_ring_emit,
1749 .cs_parse = NULL, 1755 .cs_parse = NULL,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index d2ac64619f37..5f4882cc2152 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -473,6 +473,7 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
473 uint64_t addr, unsigned count, 473 uint64_t addr, unsigned count,
474 uint32_t incr, uint32_t flags); 474 uint32_t incr, uint32_t flags);
475int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); 475int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
476int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib);
476void cayman_dma_ring_ib_execute(struct radeon_device *rdev, 477void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
477 struct radeon_ib *ib); 478 struct radeon_ib *ib);
478bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); 479bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);