diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-12-04 15:28:18 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-12-10 16:53:41 -0500 |
commit | 8c5fd7efcc5c037bdfbf6d90639fcdc499824bbd (patch) | |
tree | df076f525c6c3a41a81a74002b85263c81bb9917 /drivers/gpu | |
parent | f60cbd117a416830d5a7effc208eab8470a19167 (diff) |
drm/radeon/kms: Add initial support for async DMA on SI
Pretty much the same as cayman. Some changes to the copy
packets.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 179 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 47 |
5 files changed, 254 insertions, 5 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 38b6fa374053..5d68346b2c01 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -797,6 +797,10 @@ void r600_dma_stop(struct radeon_device *rdev); | |||
797 | int r600_dma_resume(struct radeon_device *rdev); | 797 | int r600_dma_resume(struct radeon_device *rdev); |
798 | void r600_dma_fini(struct radeon_device *rdev); | 798 | void r600_dma_fini(struct radeon_device *rdev); |
799 | 799 | ||
800 | void cayman_dma_stop(struct radeon_device *rdev); | ||
801 | int cayman_dma_resume(struct radeon_device *rdev); | ||
802 | void cayman_dma_fini(struct radeon_device *rdev); | ||
803 | |||
800 | /* | 804 | /* |
801 | * CS. | 805 | * CS. |
802 | */ | 806 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 8cf8ae86973c..d455bcb655c2 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1731,6 +1731,26 @@ static struct radeon_asic si_asic = { | |||
1731 | .ib_test = &r600_ib_test, | 1731 | .ib_test = &r600_ib_test, |
1732 | .is_lockup = &si_gpu_is_lockup, | 1732 | .is_lockup = &si_gpu_is_lockup, |
1733 | .vm_flush = &si_vm_flush, | 1733 | .vm_flush = &si_vm_flush, |
1734 | }, | ||
1735 | [R600_RING_TYPE_DMA_INDEX] = { | ||
1736 | .ib_execute = &cayman_dma_ring_ib_execute, | ||
1737 | .emit_fence = &evergreen_dma_fence_ring_emit, | ||
1738 | .emit_semaphore = &r600_dma_semaphore_ring_emit, | ||
1739 | .cs_parse = NULL, | ||
1740 | .ring_test = &r600_dma_ring_test, | ||
1741 | .ib_test = &r600_dma_ib_test, | ||
1742 | .is_lockup = &cayman_dma_is_lockup, | ||
1743 | .vm_flush = &si_dma_vm_flush, | ||
1744 | }, | ||
1745 | [CAYMAN_RING_TYPE_DMA1_INDEX] = { | ||
1746 | .ib_execute = &cayman_dma_ring_ib_execute, | ||
1747 | .emit_fence = &evergreen_dma_fence_ring_emit, | ||
1748 | .emit_semaphore = &r600_dma_semaphore_ring_emit, | ||
1749 | .cs_parse = NULL, | ||
1750 | .ring_test = &r600_dma_ring_test, | ||
1751 | .ib_test = &r600_dma_ib_test, | ||
1752 | .is_lockup = &cayman_dma_is_lockup, | ||
1753 | .vm_flush = &si_dma_vm_flush, | ||
1734 | } | 1754 | } |
1735 | }, | 1755 | }, |
1736 | .irq = { | 1756 | .irq = { |
@@ -1747,8 +1767,8 @@ static struct radeon_asic si_asic = { | |||
1747 | .copy = { | 1767 | .copy = { |
1748 | .blit = NULL, | 1768 | .blit = NULL, |
1749 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1769 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1750 | .dma = NULL, | 1770 | .dma = &si_copy_dma, |
1751 | .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1771 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
1752 | .copy = NULL, | 1772 | .copy = NULL, |
1753 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1773 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1754 | }, | 1774 | }, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c2988f706524..ae56673d2410 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -501,5 +501,10 @@ void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, | |||
501 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | 501 | void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); |
502 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 502 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
503 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | 503 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); |
504 | int si_copy_dma(struct radeon_device *rdev, | ||
505 | uint64_t src_offset, uint64_t dst_offset, | ||
506 | unsigned num_gpu_pages, | ||
507 | struct radeon_fence **fence); | ||
508 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm); | ||
504 | 509 | ||
505 | #endif | 510 | #endif |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c4d9eb623ce5..93f7171e6bcd 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -1660,6 +1660,8 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
1660 | WREG32(GB_ADDR_CONFIG, gb_addr_config); | 1660 | WREG32(GB_ADDR_CONFIG, gb_addr_config); |
1661 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 1661 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
1662 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); | 1662 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); |
1663 | WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); | ||
1664 | WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); | ||
1663 | 1665 | ||
1664 | si_tiling_mode_table_init(rdev); | 1666 | si_tiling_mode_table_init(rdev); |
1665 | 1667 | ||
@@ -1836,6 +1838,9 @@ static void si_cp_enable(struct radeon_device *rdev, bool enable) | |||
1836 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | 1838 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
1837 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT)); | 1839 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT)); |
1838 | WREG32(SCRATCH_UMSK, 0); | 1840 | WREG32(SCRATCH_UMSK, 0); |
1841 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | ||
1842 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; | ||
1843 | rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; | ||
1839 | } | 1844 | } |
1840 | udelay(50); | 1845 | udelay(50); |
1841 | } | 1846 | } |
@@ -2891,6 +2896,32 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | |||
2891 | radeon_ring_write(ring, 0x0); | 2896 | radeon_ring_write(ring, 0x0); |
2892 | } | 2897 | } |
2893 | 2898 | ||
2899 | void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) | ||
2900 | { | ||
2901 | struct radeon_ring *ring = &rdev->ring[ridx]; | ||
2902 | |||
2903 | if (vm == NULL) | ||
2904 | return; | ||
2905 | |||
2906 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | ||
2907 | if (vm->id < 8) { | ||
2908 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); | ||
2909 | } else { | ||
2910 | radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2)) >> 2)); | ||
2911 | } | ||
2912 | radeon_ring_write(ring, vm->pd_gpu_addr >> 12); | ||
2913 | |||
2914 | /* flush hdp cache */ | ||
2915 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | ||
2916 | radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2)); | ||
2917 | radeon_ring_write(ring, 1); | ||
2918 | |||
2919 | /* bits 0-7 are the VM contexts0-7 */ | ||
2920 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0)); | ||
2921 | radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); | ||
2922 | radeon_ring_write(ring, 1 << vm->id); | ||
2923 | } | ||
2924 | |||
2894 | /* | 2925 | /* |
2895 | * RLC | 2926 | * RLC |
2896 | */ | 2927 | */ |
@@ -3059,6 +3090,10 @@ static void si_disable_interrupt_state(struct radeon_device *rdev) | |||
3059 | WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 3090 | WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
3060 | WREG32(CP_INT_CNTL_RING1, 0); | 3091 | WREG32(CP_INT_CNTL_RING1, 0); |
3061 | WREG32(CP_INT_CNTL_RING2, 0); | 3092 | WREG32(CP_INT_CNTL_RING2, 0); |
3093 | tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; | ||
3094 | WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp); | ||
3095 | tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; | ||
3096 | WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp); | ||
3062 | WREG32(GRBM_INT_CNTL, 0); | 3097 | WREG32(GRBM_INT_CNTL, 0); |
3063 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 3098 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
3064 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 3099 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
@@ -3178,6 +3213,7 @@ int si_irq_set(struct radeon_device *rdev) | |||
3178 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 3213 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
3179 | u32 grbm_int_cntl = 0; | 3214 | u32 grbm_int_cntl = 0; |
3180 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | 3215 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; |
3216 | u32 dma_cntl, dma_cntl1; | ||
3181 | 3217 | ||
3182 | if (!rdev->irq.installed) { | 3218 | if (!rdev->irq.installed) { |
3183 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 3219 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -3198,6 +3234,9 @@ int si_irq_set(struct radeon_device *rdev) | |||
3198 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3234 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3199 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3235 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3200 | 3236 | ||
3237 | dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; | ||
3238 | dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; | ||
3239 | |||
3201 | /* enable CP interrupts on all rings */ | 3240 | /* enable CP interrupts on all rings */ |
3202 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { | 3241 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
3203 | DRM_DEBUG("si_irq_set: sw int gfx\n"); | 3242 | DRM_DEBUG("si_irq_set: sw int gfx\n"); |
@@ -3211,6 +3250,15 @@ int si_irq_set(struct radeon_device *rdev) | |||
3211 | DRM_DEBUG("si_irq_set: sw int cp2\n"); | 3250 | DRM_DEBUG("si_irq_set: sw int cp2\n"); |
3212 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; | 3251 | cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; |
3213 | } | 3252 | } |
3253 | if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) { | ||
3254 | DRM_DEBUG("si_irq_set: sw int dma\n"); | ||
3255 | dma_cntl |= TRAP_ENABLE; | ||
3256 | } | ||
3257 | |||
3258 | if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) { | ||
3259 | DRM_DEBUG("si_irq_set: sw int dma1\n"); | ||
3260 | dma_cntl1 |= TRAP_ENABLE; | ||
3261 | } | ||
3214 | if (rdev->irq.crtc_vblank_int[0] || | 3262 | if (rdev->irq.crtc_vblank_int[0] || |
3215 | atomic_read(&rdev->irq.pflip[0])) { | 3263 | atomic_read(&rdev->irq.pflip[0])) { |
3216 | DRM_DEBUG("si_irq_set: vblank 0\n"); | 3264 | DRM_DEBUG("si_irq_set: vblank 0\n"); |
@@ -3270,6 +3318,9 @@ int si_irq_set(struct radeon_device *rdev) | |||
3270 | WREG32(CP_INT_CNTL_RING1, cp_int_cntl1); | 3318 | WREG32(CP_INT_CNTL_RING1, cp_int_cntl1); |
3271 | WREG32(CP_INT_CNTL_RING2, cp_int_cntl2); | 3319 | WREG32(CP_INT_CNTL_RING2, cp_int_cntl2); |
3272 | 3320 | ||
3321 | WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl); | ||
3322 | WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1); | ||
3323 | |||
3273 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 3324 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
3274 | 3325 | ||
3275 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 3326 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
@@ -3728,9 +3779,17 @@ restart_ih: | |||
3728 | break; | 3779 | break; |
3729 | } | 3780 | } |
3730 | break; | 3781 | break; |
3782 | case 224: /* DMA trap event */ | ||
3783 | DRM_DEBUG("IH: DMA trap\n"); | ||
3784 | radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); | ||
3785 | break; | ||
3731 | case 233: /* GUI IDLE */ | 3786 | case 233: /* GUI IDLE */ |
3732 | DRM_DEBUG("IH: GUI idle\n"); | 3787 | DRM_DEBUG("IH: GUI idle\n"); |
3733 | break; | 3788 | break; |
3789 | case 244: /* DMA trap event */ | ||
3790 | DRM_DEBUG("IH: DMA1 trap\n"); | ||
3791 | radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); | ||
3792 | break; | ||
3734 | default: | 3793 | default: |
3735 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 3794 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
3736 | break; | 3795 | break; |
@@ -3754,6 +3813,80 @@ restart_ih: | |||
3754 | return IRQ_HANDLED; | 3813 | return IRQ_HANDLED; |
3755 | } | 3814 | } |
3756 | 3815 | ||
3816 | /** | ||
3817 | * si_copy_dma - copy pages using the DMA engine | ||
3818 | * | ||
3819 | * @rdev: radeon_device pointer | ||
3820 | * @src_offset: src GPU address | ||
3821 | * @dst_offset: dst GPU address | ||
3822 | * @num_gpu_pages: number of GPU pages to xfer | ||
3823 | * @fence: radeon fence object | ||
3824 | * | ||
3825 | * Copy GPU paging using the DMA engine (SI). | ||
3826 | * Used by the radeon ttm implementation to move pages if | ||
3827 | * registered as the asic copy callback. | ||
3828 | */ | ||
3829 | int si_copy_dma(struct radeon_device *rdev, | ||
3830 | uint64_t src_offset, uint64_t dst_offset, | ||
3831 | unsigned num_gpu_pages, | ||
3832 | struct radeon_fence **fence) | ||
3833 | { | ||
3834 | struct radeon_semaphore *sem = NULL; | ||
3835 | int ring_index = rdev->asic->copy.dma_ring_index; | ||
3836 | struct radeon_ring *ring = &rdev->ring[ring_index]; | ||
3837 | u32 size_in_bytes, cur_size_in_bytes; | ||
3838 | int i, num_loops; | ||
3839 | int r = 0; | ||
3840 | |||
3841 | r = radeon_semaphore_create(rdev, &sem); | ||
3842 | if (r) { | ||
3843 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
3844 | return r; | ||
3845 | } | ||
3846 | |||
3847 | size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); | ||
3848 | num_loops = DIV_ROUND_UP(size_in_bytes, 0xfffff); | ||
3849 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); | ||
3850 | if (r) { | ||
3851 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
3852 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3853 | return r; | ||
3854 | } | ||
3855 | |||
3856 | if (radeon_fence_need_sync(*fence, ring->idx)) { | ||
3857 | radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, | ||
3858 | ring->idx); | ||
3859 | radeon_fence_note_sync(*fence, ring->idx); | ||
3860 | } else { | ||
3861 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3862 | } | ||
3863 | |||
3864 | for (i = 0; i < num_loops; i++) { | ||
3865 | cur_size_in_bytes = size_in_bytes; | ||
3866 | if (cur_size_in_bytes > 0xFFFFF) | ||
3867 | cur_size_in_bytes = 0xFFFFF; | ||
3868 | size_in_bytes -= cur_size_in_bytes; | ||
3869 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 1, 0, 0, cur_size_in_bytes)); | ||
3870 | radeon_ring_write(ring, dst_offset & 0xffffffff); | ||
3871 | radeon_ring_write(ring, src_offset & 0xffffffff); | ||
3872 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); | ||
3873 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); | ||
3874 | src_offset += cur_size_in_bytes; | ||
3875 | dst_offset += cur_size_in_bytes; | ||
3876 | } | ||
3877 | |||
3878 | r = radeon_fence_emit(rdev, fence, ring->idx); | ||
3879 | if (r) { | ||
3880 | radeon_ring_unlock_undo(rdev, ring); | ||
3881 | return r; | ||
3882 | } | ||
3883 | |||
3884 | radeon_ring_unlock_commit(rdev, ring); | ||
3885 | radeon_semaphore_free(rdev, &sem, *fence); | ||
3886 | |||
3887 | return r; | ||
3888 | } | ||
3889 | |||
3757 | /* | 3890 | /* |
3758 | * startup/shutdown callbacks | 3891 | * startup/shutdown callbacks |
3759 | */ | 3892 | */ |
@@ -3825,6 +3958,18 @@ static int si_startup(struct radeon_device *rdev) | |||
3825 | return r; | 3958 | return r; |
3826 | } | 3959 | } |
3827 | 3960 | ||
3961 | r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); | ||
3962 | if (r) { | ||
3963 | dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); | ||
3964 | return r; | ||
3965 | } | ||
3966 | |||
3967 | r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); | ||
3968 | if (r) { | ||
3969 | dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); | ||
3970 | return r; | ||
3971 | } | ||
3972 | |||
3828 | /* Enable IRQ */ | 3973 | /* Enable IRQ */ |
3829 | r = si_irq_init(rdev); | 3974 | r = si_irq_init(rdev); |
3830 | if (r) { | 3975 | if (r) { |
@@ -3855,6 +4000,22 @@ static int si_startup(struct radeon_device *rdev) | |||
3855 | if (r) | 4000 | if (r) |
3856 | return r; | 4001 | return r; |
3857 | 4002 | ||
4003 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; | ||
4004 | r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, | ||
4005 | DMA_RB_RPTR + DMA0_REGISTER_OFFSET, | ||
4006 | DMA_RB_WPTR + DMA0_REGISTER_OFFSET, | ||
4007 | 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0)); | ||
4008 | if (r) | ||
4009 | return r; | ||
4010 | |||
4011 | ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; | ||
4012 | r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, | ||
4013 | DMA_RB_RPTR + DMA1_REGISTER_OFFSET, | ||
4014 | DMA_RB_WPTR + DMA1_REGISTER_OFFSET, | ||
4015 | 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0)); | ||
4016 | if (r) | ||
4017 | return r; | ||
4018 | |||
3858 | r = si_cp_load_microcode(rdev); | 4019 | r = si_cp_load_microcode(rdev); |
3859 | if (r) | 4020 | if (r) |
3860 | return r; | 4021 | return r; |
@@ -3862,6 +4023,10 @@ static int si_startup(struct radeon_device *rdev) | |||
3862 | if (r) | 4023 | if (r) |
3863 | return r; | 4024 | return r; |
3864 | 4025 | ||
4026 | r = cayman_dma_resume(rdev); | ||
4027 | if (r) | ||
4028 | return r; | ||
4029 | |||
3865 | r = radeon_ib_pool_init(rdev); | 4030 | r = radeon_ib_pool_init(rdev); |
3866 | if (r) { | 4031 | if (r) { |
3867 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); | 4032 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
@@ -3903,9 +4068,7 @@ int si_resume(struct radeon_device *rdev) | |||
3903 | int si_suspend(struct radeon_device *rdev) | 4068 | int si_suspend(struct radeon_device *rdev) |
3904 | { | 4069 | { |
3905 | si_cp_enable(rdev, false); | 4070 | si_cp_enable(rdev, false); |
3906 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; | 4071 | cayman_dma_stop(rdev); |
3907 | rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; | ||
3908 | rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; | ||
3909 | si_irq_suspend(rdev); | 4072 | si_irq_suspend(rdev); |
3910 | radeon_wb_disable(rdev); | 4073 | radeon_wb_disable(rdev); |
3911 | si_pcie_gart_disable(rdev); | 4074 | si_pcie_gart_disable(rdev); |
@@ -3983,6 +4146,14 @@ int si_init(struct radeon_device *rdev) | |||
3983 | ring->ring_obj = NULL; | 4146 | ring->ring_obj = NULL; |
3984 | r600_ring_init(rdev, ring, 1024 * 1024); | 4147 | r600_ring_init(rdev, ring, 1024 * 1024); |
3985 | 4148 | ||
4149 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; | ||
4150 | ring->ring_obj = NULL; | ||
4151 | r600_ring_init(rdev, ring, 64 * 1024); | ||
4152 | |||
4153 | ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; | ||
4154 | ring->ring_obj = NULL; | ||
4155 | r600_ring_init(rdev, ring, 64 * 1024); | ||
4156 | |||
3986 | rdev->ih.ring_obj = NULL; | 4157 | rdev->ih.ring_obj = NULL; |
3987 | r600_ih_ring_init(rdev, 64 * 1024); | 4158 | r600_ih_ring_init(rdev, 64 * 1024); |
3988 | 4159 | ||
@@ -3995,6 +4166,7 @@ int si_init(struct radeon_device *rdev) | |||
3995 | if (r) { | 4166 | if (r) { |
3996 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 4167 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
3997 | si_cp_fini(rdev); | 4168 | si_cp_fini(rdev); |
4169 | cayman_dma_fini(rdev); | ||
3998 | si_irq_fini(rdev); | 4170 | si_irq_fini(rdev); |
3999 | si_rlc_fini(rdev); | 4171 | si_rlc_fini(rdev); |
4000 | radeon_wb_fini(rdev); | 4172 | radeon_wb_fini(rdev); |
@@ -4023,6 +4195,7 @@ void si_fini(struct radeon_device *rdev) | |||
4023 | r600_blit_fini(rdev); | 4195 | r600_blit_fini(rdev); |
4024 | #endif | 4196 | #endif |
4025 | si_cp_fini(rdev); | 4197 | si_cp_fini(rdev); |
4198 | cayman_dma_fini(rdev); | ||
4026 | si_irq_fini(rdev); | 4199 | si_irq_fini(rdev); |
4027 | si_rlc_fini(rdev); | 4200 | si_rlc_fini(rdev); |
4028 | radeon_wb_fini(rdev); | 4201 | radeon_wb_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 53b4d4535fd2..0acd32759c7c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -936,4 +936,51 @@ | |||
936 | #define PACKET3_WAIT_ON_AVAIL_BUFFER 0x8A | 936 | #define PACKET3_WAIT_ON_AVAIL_BUFFER 0x8A |
937 | #define PACKET3_SWITCH_BUFFER 0x8B | 937 | #define PACKET3_SWITCH_BUFFER 0x8B |
938 | 938 | ||
939 | /* ASYNC DMA - first instance at 0xd000, second at 0xd800 */ | ||
940 | #define DMA0_REGISTER_OFFSET 0x0 /* not a register */ | ||
941 | #define DMA1_REGISTER_OFFSET 0x800 /* not a register */ | ||
942 | |||
943 | #define DMA_RB_CNTL 0xd000 | ||
944 | # define DMA_RB_ENABLE (1 << 0) | ||
945 | # define DMA_RB_SIZE(x) ((x) << 1) /* log2 */ | ||
946 | # define DMA_RB_SWAP_ENABLE (1 << 9) /* 8IN32 */ | ||
947 | # define DMA_RPTR_WRITEBACK_ENABLE (1 << 12) | ||
948 | # define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */ | ||
949 | # define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */ | ||
950 | #define DMA_RB_BASE 0xd004 | ||
951 | #define DMA_RB_RPTR 0xd008 | ||
952 | #define DMA_RB_WPTR 0xd00c | ||
953 | |||
954 | #define DMA_RB_RPTR_ADDR_HI 0xd01c | ||
955 | #define DMA_RB_RPTR_ADDR_LO 0xd020 | ||
956 | |||
957 | #define DMA_IB_CNTL 0xd024 | ||
958 | # define DMA_IB_ENABLE (1 << 0) | ||
959 | # define DMA_IB_SWAP_ENABLE (1 << 4) | ||
960 | #define DMA_IB_RPTR 0xd028 | ||
961 | #define DMA_CNTL 0xd02c | ||
962 | # define TRAP_ENABLE (1 << 0) | ||
963 | # define SEM_INCOMPLETE_INT_ENABLE (1 << 1) | ||
964 | # define SEM_WAIT_INT_ENABLE (1 << 2) | ||
965 | # define DATA_SWAP_ENABLE (1 << 3) | ||
966 | # define FENCE_SWAP_ENABLE (1 << 4) | ||
967 | # define CTXEMPTY_INT_ENABLE (1 << 28) | ||
968 | #define DMA_TILING_CONFIG 0xd0b8 | ||
969 | |||
970 | #define DMA_PACKET(cmd, b, t, s, n) ((((cmd) & 0xF) << 28) | \ | ||
971 | (((b) & 0x1) << 26) | \ | ||
972 | (((t) & 0x1) << 23) | \ | ||
973 | (((s) & 0x1) << 22) | \ | ||
974 | (((n) & 0xFFFFF) << 0)) | ||
975 | /* async DMA Packet types */ | ||
976 | #define DMA_PACKET_WRITE 0x2 | ||
977 | #define DMA_PACKET_COPY 0x3 | ||
978 | #define DMA_PACKET_INDIRECT_BUFFER 0x4 | ||
979 | #define DMA_PACKET_SEMAPHORE 0x5 | ||
980 | #define DMA_PACKET_FENCE 0x6 | ||
981 | #define DMA_PACKET_TRAP 0x7 | ||
982 | #define DMA_PACKET_SRBM_WRITE 0x9 | ||
983 | #define DMA_PACKET_CONSTANT_FILL 0xd | ||
984 | #define DMA_PACKET_NOP 0xf | ||
985 | |||
939 | #endif | 986 | #endif |