diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-12-13 12:17:38 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-12-14 10:45:26 -0500 |
commit | cd459e525f4faeefa0bf78e1bcba3e04496b2cb5 (patch) | |
tree | ca8d6d1d855694ce843bdd83d7e48cd00842838f | |
parent | d2ead3eaf8a4bf92129eda69189ce18a6c1cc8bd (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.c | 111 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 1 |
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 | **/ | ||
3569 | int 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); |
475 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 475 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
476 | int evergreen_dma_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | ||
476 | void cayman_dma_ring_ib_execute(struct radeon_device *rdev, | 477 | void cayman_dma_ring_ib_execute(struct radeon_device *rdev, |
477 | struct radeon_ib *ib); | 478 | struct radeon_ib *ib); |
478 | bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | 479 | bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring); |