diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2012-12-04 15:25:59 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-12-10 16:53:29 -0500 |
commit | 233d1ad59a2895e348259bb6f9f4528a75ea7752 (patch) | |
tree | 6539a16accaf1d0293b0a236db2cfdc27c22e083 /drivers | |
parent | 4d75658bffea78f0c6f82fd46df1ec983ccacdf0 (diff) |
drm/radeon/kms: Add initial support for async DMA on evergreen
Pretty similar to 6xx/7xx except the count field increased in the
packet header and the max IB size increased.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 181 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 29 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 8 |
4 files changed, 248 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 78de2e4097b5..68206df3d5d2 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2034,6 +2034,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
2034 | WREG32(GB_ADDR_CONFIG, gb_addr_config); | 2034 | WREG32(GB_ADDR_CONFIG, gb_addr_config); |
2035 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); | 2035 | WREG32(DMIF_ADDR_CONFIG, gb_addr_config); |
2036 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); | 2036 | WREG32(HDP_ADDR_CONFIG, gb_addr_config); |
2037 | WREG32(DMA_TILING_CONFIG, gb_addr_config); | ||
2037 | 2038 | ||
2038 | tmp = gb_addr_config & NUM_PIPES_MASK; | 2039 | tmp = gb_addr_config & NUM_PIPES_MASK; |
2039 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, | 2040 | tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, |
@@ -2405,6 +2406,8 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
2405 | cayman_cp_int_cntl_setup(rdev, 2, 0); | 2406 | cayman_cp_int_cntl_setup(rdev, 2, 0); |
2406 | } else | 2407 | } else |
2407 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2408 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
2409 | tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE; | ||
2410 | WREG32(DMA_CNTL, tmp); | ||
2408 | WREG32(GRBM_INT_CNTL, 0); | 2411 | WREG32(GRBM_INT_CNTL, 0); |
2409 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2412 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
2410 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2413 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
@@ -2457,6 +2460,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2457 | u32 grbm_int_cntl = 0; | 2460 | u32 grbm_int_cntl = 0; |
2458 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | 2461 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; |
2459 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; | 2462 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; |
2463 | u32 dma_cntl; | ||
2460 | 2464 | ||
2461 | if (!rdev->irq.installed) { | 2465 | if (!rdev->irq.installed) { |
2462 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 2466 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -2484,6 +2488,8 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2484 | afmt5 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | 2488 | afmt5 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; |
2485 | afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | 2489 | afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; |
2486 | 2490 | ||
2491 | dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE; | ||
2492 | |||
2487 | if (rdev->family >= CHIP_CAYMAN) { | 2493 | if (rdev->family >= CHIP_CAYMAN) { |
2488 | /* enable CP interrupts on all rings */ | 2494 | /* enable CP interrupts on all rings */ |
2489 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { | 2495 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
@@ -2506,6 +2512,11 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2506 | } | 2512 | } |
2507 | } | 2513 | } |
2508 | 2514 | ||
2515 | if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) { | ||
2516 | DRM_DEBUG("r600_irq_set: sw int dma\n"); | ||
2517 | dma_cntl |= TRAP_ENABLE; | ||
2518 | } | ||
2519 | |||
2509 | if (rdev->irq.crtc_vblank_int[0] || | 2520 | if (rdev->irq.crtc_vblank_int[0] || |
2510 | atomic_read(&rdev->irq.pflip[0])) { | 2521 | atomic_read(&rdev->irq.pflip[0])) { |
2511 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 2522 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
@@ -2591,6 +2602,9 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2591 | cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); | 2602 | cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); |
2592 | } else | 2603 | } else |
2593 | WREG32(CP_INT_CNTL, cp_int_cntl); | 2604 | WREG32(CP_INT_CNTL, cp_int_cntl); |
2605 | |||
2606 | WREG32(DMA_CNTL, dma_cntl); | ||
2607 | |||
2594 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 2608 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
2595 | 2609 | ||
2596 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 2610 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
@@ -3126,6 +3140,10 @@ restart_ih: | |||
3126 | } else | 3140 | } else |
3127 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 3141 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
3128 | break; | 3142 | break; |
3143 | case 224: /* DMA trap event */ | ||
3144 | DRM_DEBUG("IH: DMA trap\n"); | ||
3145 | radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); | ||
3146 | break; | ||
3129 | case 233: /* GUI IDLE */ | 3147 | case 233: /* GUI IDLE */ |
3130 | DRM_DEBUG("IH: GUI idle\n"); | 3148 | DRM_DEBUG("IH: GUI idle\n"); |
3131 | break; | 3149 | break; |
@@ -3154,6 +3172,143 @@ restart_ih: | |||
3154 | return IRQ_HANDLED; | 3172 | return IRQ_HANDLED; |
3155 | } | 3173 | } |
3156 | 3174 | ||
3175 | /** | ||
3176 | * evergreen_dma_fence_ring_emit - emit a fence on the DMA ring | ||
3177 | * | ||
3178 | * @rdev: radeon_device pointer | ||
3179 | * @fence: radeon fence object | ||
3180 | * | ||
3181 | * Add a DMA fence packet to the ring to write | ||
3182 | * the fence seq number and DMA trap packet to generate | ||
3183 | * an interrupt if needed (evergreen-SI). | ||
3184 | */ | ||
3185 | void evergreen_dma_fence_ring_emit(struct radeon_device *rdev, | ||
3186 | struct radeon_fence *fence) | ||
3187 | { | ||
3188 | struct radeon_ring *ring = &rdev->ring[fence->ring]; | ||
3189 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; | ||
3190 | /* write the fence */ | ||
3191 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0)); | ||
3192 | radeon_ring_write(ring, addr & 0xfffffffc); | ||
3193 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff)); | ||
3194 | radeon_ring_write(ring, fence->seq); | ||
3195 | /* generate an interrupt */ | ||
3196 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); | ||
3197 | /* flush HDP */ | ||
3198 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | ||
3199 | radeon_ring_write(ring, (0xf << 16) | HDP_MEM_COHERENCY_FLUSH_CNTL); | ||
3200 | radeon_ring_write(ring, 1); | ||
3201 | } | ||
3202 | |||
3203 | /** | ||
3204 | * evergreen_dma_ring_ib_execute - schedule an IB on the DMA engine | ||
3205 | * | ||
3206 | * @rdev: radeon_device pointer | ||
3207 | * @ib: IB object to schedule | ||
3208 | * | ||
3209 | * Schedule an IB in the DMA ring (evergreen). | ||
3210 | */ | ||
3211 | void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, | ||
3212 | struct radeon_ib *ib) | ||
3213 | { | ||
3214 | struct radeon_ring *ring = &rdev->ring[ib->ring]; | ||
3215 | |||
3216 | if (rdev->wb.enabled) { | ||
3217 | u32 next_rptr = ring->wptr + 4; | ||
3218 | while ((next_rptr & 7) != 5) | ||
3219 | next_rptr++; | ||
3220 | next_rptr += 3; | ||
3221 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); | ||
3222 | radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); | ||
3223 | radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff); | ||
3224 | radeon_ring_write(ring, next_rptr); | ||
3225 | } | ||
3226 | |||
3227 | /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring. | ||
3228 | * Pad as necessary with NOPs. | ||
3229 | */ | ||
3230 | while ((ring->wptr & 7) != 5) | ||
3231 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | ||
3232 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_INDIRECT_BUFFER, 0, 0, 0)); | ||
3233 | radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0)); | ||
3234 | radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF)); | ||
3235 | |||
3236 | } | ||
3237 | |||
3238 | /** | ||
3239 | * evergreen_copy_dma - copy pages using the DMA engine | ||
3240 | * | ||
3241 | * @rdev: radeon_device pointer | ||
3242 | * @src_offset: src GPU address | ||
3243 | * @dst_offset: dst GPU address | ||
3244 | * @num_gpu_pages: number of GPU pages to xfer | ||
3245 | * @fence: radeon fence object | ||
3246 | * | ||
3247 | * Copy GPU paging using the DMA engine (evergreen-cayman). | ||
3248 | * Used by the radeon ttm implementation to move pages if | ||
3249 | * registered as the asic copy callback. | ||
3250 | */ | ||
3251 | int evergreen_copy_dma(struct radeon_device *rdev, | ||
3252 | uint64_t src_offset, uint64_t dst_offset, | ||
3253 | unsigned num_gpu_pages, | ||
3254 | struct radeon_fence **fence) | ||
3255 | { | ||
3256 | struct radeon_semaphore *sem = NULL; | ||
3257 | int ring_index = rdev->asic->copy.dma_ring_index; | ||
3258 | struct radeon_ring *ring = &rdev->ring[ring_index]; | ||
3259 | u32 size_in_dw, cur_size_in_dw; | ||
3260 | int i, num_loops; | ||
3261 | int r = 0; | ||
3262 | |||
3263 | r = radeon_semaphore_create(rdev, &sem); | ||
3264 | if (r) { | ||
3265 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
3266 | return r; | ||
3267 | } | ||
3268 | |||
3269 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | ||
3270 | num_loops = DIV_ROUND_UP(size_in_dw, 0xfffff); | ||
3271 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 11); | ||
3272 | if (r) { | ||
3273 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
3274 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3275 | return r; | ||
3276 | } | ||
3277 | |||
3278 | if (radeon_fence_need_sync(*fence, ring->idx)) { | ||
3279 | radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, | ||
3280 | ring->idx); | ||
3281 | radeon_fence_note_sync(*fence, ring->idx); | ||
3282 | } else { | ||
3283 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3284 | } | ||
3285 | |||
3286 | for (i = 0; i < num_loops; i++) { | ||
3287 | cur_size_in_dw = size_in_dw; | ||
3288 | if (cur_size_in_dw > 0xFFFFF) | ||
3289 | cur_size_in_dw = 0xFFFFF; | ||
3290 | size_in_dw -= cur_size_in_dw; | ||
3291 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); | ||
3292 | radeon_ring_write(ring, dst_offset & 0xfffffffc); | ||
3293 | radeon_ring_write(ring, src_offset & 0xfffffffc); | ||
3294 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); | ||
3295 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); | ||
3296 | src_offset += cur_size_in_dw * 4; | ||
3297 | dst_offset += cur_size_in_dw * 4; | ||
3298 | } | ||
3299 | |||
3300 | r = radeon_fence_emit(rdev, fence, ring->idx); | ||
3301 | if (r) { | ||
3302 | radeon_ring_unlock_undo(rdev, ring); | ||
3303 | return r; | ||
3304 | } | ||
3305 | |||
3306 | radeon_ring_unlock_commit(rdev, ring); | ||
3307 | radeon_semaphore_free(rdev, &sem, *fence); | ||
3308 | |||
3309 | return r; | ||
3310 | } | ||
3311 | |||
3157 | static int evergreen_startup(struct radeon_device *rdev) | 3312 | static int evergreen_startup(struct radeon_device *rdev) |
3158 | { | 3313 | { |
3159 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | 3314 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
@@ -3217,6 +3372,12 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
3217 | return r; | 3372 | return r; |
3218 | } | 3373 | } |
3219 | 3374 | ||
3375 | r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); | ||
3376 | if (r) { | ||
3377 | dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); | ||
3378 | return r; | ||
3379 | } | ||
3380 | |||
3220 | /* Enable IRQ */ | 3381 | /* Enable IRQ */ |
3221 | r = r600_irq_init(rdev); | 3382 | r = r600_irq_init(rdev); |
3222 | if (r) { | 3383 | if (r) { |
@@ -3231,12 +3392,23 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
3231 | 0, 0xfffff, RADEON_CP_PACKET2); | 3392 | 0, 0xfffff, RADEON_CP_PACKET2); |
3232 | if (r) | 3393 | if (r) |
3233 | return r; | 3394 | return r; |
3395 | |||
3396 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; | ||
3397 | r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, | ||
3398 | DMA_RB_RPTR, DMA_RB_WPTR, | ||
3399 | 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); | ||
3400 | if (r) | ||
3401 | return r; | ||
3402 | |||
3234 | r = evergreen_cp_load_microcode(rdev); | 3403 | r = evergreen_cp_load_microcode(rdev); |
3235 | if (r) | 3404 | if (r) |
3236 | return r; | 3405 | return r; |
3237 | r = evergreen_cp_resume(rdev); | 3406 | r = evergreen_cp_resume(rdev); |
3238 | if (r) | 3407 | if (r) |
3239 | return r; | 3408 | return r; |
3409 | r = r600_dma_resume(rdev); | ||
3410 | if (r) | ||
3411 | return r; | ||
3240 | 3412 | ||
3241 | r = radeon_ib_pool_init(rdev); | 3413 | r = radeon_ib_pool_init(rdev); |
3242 | if (r) { | 3414 | if (r) { |
@@ -3283,11 +3455,9 @@ int evergreen_resume(struct radeon_device *rdev) | |||
3283 | 3455 | ||
3284 | int evergreen_suspend(struct radeon_device *rdev) | 3456 | int evergreen_suspend(struct radeon_device *rdev) |
3285 | { | 3457 | { |
3286 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; | ||
3287 | |||
3288 | r600_audio_fini(rdev); | 3458 | r600_audio_fini(rdev); |
3289 | r700_cp_stop(rdev); | 3459 | r700_cp_stop(rdev); |
3290 | ring->ready = false; | 3460 | r600_dma_stop(rdev); |
3291 | evergreen_irq_suspend(rdev); | 3461 | evergreen_irq_suspend(rdev); |
3292 | radeon_wb_disable(rdev); | 3462 | radeon_wb_disable(rdev); |
3293 | evergreen_pcie_gart_disable(rdev); | 3463 | evergreen_pcie_gart_disable(rdev); |
@@ -3364,6 +3534,9 @@ int evergreen_init(struct radeon_device *rdev) | |||
3364 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; | 3534 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; |
3365 | r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); | 3535 | r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); |
3366 | 3536 | ||
3537 | rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL; | ||
3538 | r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024); | ||
3539 | |||
3367 | rdev->ih.ring_obj = NULL; | 3540 | rdev->ih.ring_obj = NULL; |
3368 | r600_ih_ring_init(rdev, 64 * 1024); | 3541 | r600_ih_ring_init(rdev, 64 * 1024); |
3369 | 3542 | ||
@@ -3376,6 +3549,7 @@ int evergreen_init(struct radeon_device *rdev) | |||
3376 | if (r) { | 3549 | if (r) { |
3377 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 3550 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
3378 | r700_cp_fini(rdev); | 3551 | r700_cp_fini(rdev); |
3552 | r600_dma_fini(rdev); | ||
3379 | r600_irq_fini(rdev); | 3553 | r600_irq_fini(rdev); |
3380 | radeon_wb_fini(rdev); | 3554 | radeon_wb_fini(rdev); |
3381 | radeon_ib_pool_fini(rdev); | 3555 | radeon_ib_pool_fini(rdev); |
@@ -3403,6 +3577,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3403 | r600_audio_fini(rdev); | 3577 | r600_audio_fini(rdev); |
3404 | r600_blit_fini(rdev); | 3578 | r600_blit_fini(rdev); |
3405 | r700_cp_fini(rdev); | 3579 | r700_cp_fini(rdev); |
3580 | r600_dma_fini(rdev); | ||
3406 | r600_irq_fini(rdev); | 3581 | r600_irq_fini(rdev); |
3407 | radeon_wb_fini(rdev); | 3582 | radeon_wb_fini(rdev); |
3408 | radeon_ib_pool_fini(rdev); | 3583 | radeon_ib_pool_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index cae7ab4219ef..92d1f4521caf 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -905,6 +905,35 @@ | |||
905 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) | 905 | # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) |
906 | # define DC_HPDx_EN (1 << 28) | 906 | # define DC_HPDx_EN (1 << 28) |
907 | 907 | ||
908 | /* ASYNC DMA */ | ||
909 | #define DMA_RB_RPTR 0xd008 | ||
910 | #define DMA_RB_WPTR 0xd00c | ||
911 | |||
912 | #define DMA_CNTL 0xd02c | ||
913 | # define TRAP_ENABLE (1 << 0) | ||
914 | # define SEM_INCOMPLETE_INT_ENABLE (1 << 1) | ||
915 | # define SEM_WAIT_INT_ENABLE (1 << 2) | ||
916 | # define DATA_SWAP_ENABLE (1 << 3) | ||
917 | # define FENCE_SWAP_ENABLE (1 << 4) | ||
918 | # define CTXEMPTY_INT_ENABLE (1 << 28) | ||
919 | #define DMA_TILING_CONFIG 0xD0B8 | ||
920 | |||
921 | /* async DMA packets */ | ||
922 | #define DMA_PACKET(cmd, t, s, n) ((((cmd) & 0xF) << 28) | \ | ||
923 | (((t) & 0x1) << 23) | \ | ||
924 | (((s) & 0x1) << 22) | \ | ||
925 | (((n) & 0xFFFFF) << 0)) | ||
926 | /* async DMA Packet types */ | ||
927 | #define DMA_PACKET_WRITE 0x2 | ||
928 | #define DMA_PACKET_COPY 0x3 | ||
929 | #define DMA_PACKET_INDIRECT_BUFFER 0x4 | ||
930 | #define DMA_PACKET_SEMAPHORE 0x5 | ||
931 | #define DMA_PACKET_FENCE 0x6 | ||
932 | #define DMA_PACKET_TRAP 0x7 | ||
933 | #define DMA_PACKET_SRBM_WRITE 0x9 | ||
934 | #define DMA_PACKET_CONSTANT_FILL 0xd | ||
935 | #define DMA_PACKET_NOP 0xf | ||
936 | |||
908 | /* PCIE link stuff */ | 937 | /* PCIE link stuff */ |
909 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ | 938 | #define PCIE_LC_TRAINING_CNTL 0xa1 /* PCIE_P */ |
910 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ | 939 | #define PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE_P */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 3cf9b29fb53f..1dd8d927e035 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1199,6 +1199,15 @@ static struct radeon_asic evergreen_asic = { | |||
1199 | .ring_test = &r600_ring_test, | 1199 | .ring_test = &r600_ring_test, |
1200 | .ib_test = &r600_ib_test, | 1200 | .ib_test = &r600_ib_test, |
1201 | .is_lockup = &evergreen_gpu_is_lockup, | 1201 | .is_lockup = &evergreen_gpu_is_lockup, |
1202 | }, | ||
1203 | [R600_RING_TYPE_DMA_INDEX] = { | ||
1204 | .ib_execute = &evergreen_dma_ring_ib_execute, | ||
1205 | .emit_fence = &evergreen_dma_fence_ring_emit, | ||
1206 | .emit_semaphore = &r600_dma_semaphore_ring_emit, | ||
1207 | .cs_parse = NULL, | ||
1208 | .ring_test = &r600_dma_ring_test, | ||
1209 | .ib_test = &r600_dma_ib_test, | ||
1210 | .is_lockup = &r600_dma_is_lockup, | ||
1202 | } | 1211 | } |
1203 | }, | 1212 | }, |
1204 | .irq = { | 1213 | .irq = { |
@@ -1215,8 +1224,8 @@ static struct radeon_asic evergreen_asic = { | |||
1215 | .copy = { | 1224 | .copy = { |
1216 | .blit = &r600_copy_blit, | 1225 | .blit = &r600_copy_blit, |
1217 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1226 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1218 | .dma = NULL, | 1227 | .dma = &evergreen_copy_dma, |
1219 | .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1228 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
1220 | .copy = &r600_copy_blit, | 1229 | .copy = &r600_copy_blit, |
1221 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1230 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1222 | }, | 1231 | }, |
@@ -1275,6 +1284,15 @@ static struct radeon_asic sumo_asic = { | |||
1275 | .ib_test = &r600_ib_test, | 1284 | .ib_test = &r600_ib_test, |
1276 | .is_lockup = &evergreen_gpu_is_lockup, | 1285 | .is_lockup = &evergreen_gpu_is_lockup, |
1277 | }, | 1286 | }, |
1287 | [R600_RING_TYPE_DMA_INDEX] = { | ||
1288 | .ib_execute = &evergreen_dma_ring_ib_execute, | ||
1289 | .emit_fence = &evergreen_dma_fence_ring_emit, | ||
1290 | .emit_semaphore = &r600_dma_semaphore_ring_emit, | ||
1291 | .cs_parse = NULL, | ||
1292 | .ring_test = &r600_dma_ring_test, | ||
1293 | .ib_test = &r600_dma_ib_test, | ||
1294 | .is_lockup = &r600_dma_is_lockup, | ||
1295 | } | ||
1278 | }, | 1296 | }, |
1279 | .irq = { | 1297 | .irq = { |
1280 | .set = &evergreen_irq_set, | 1298 | .set = &evergreen_irq_set, |
@@ -1290,8 +1308,8 @@ static struct radeon_asic sumo_asic = { | |||
1290 | .copy = { | 1308 | .copy = { |
1291 | .blit = &r600_copy_blit, | 1309 | .blit = &r600_copy_blit, |
1292 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1310 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1293 | .dma = NULL, | 1311 | .dma = &evergreen_copy_dma, |
1294 | .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1312 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
1295 | .copy = &r600_copy_blit, | 1313 | .copy = &r600_copy_blit, |
1296 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1314 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1297 | }, | 1315 | }, |
@@ -1349,6 +1367,15 @@ static struct radeon_asic btc_asic = { | |||
1349 | .ring_test = &r600_ring_test, | 1367 | .ring_test = &r600_ring_test, |
1350 | .ib_test = &r600_ib_test, | 1368 | .ib_test = &r600_ib_test, |
1351 | .is_lockup = &evergreen_gpu_is_lockup, | 1369 | .is_lockup = &evergreen_gpu_is_lockup, |
1370 | }, | ||
1371 | [R600_RING_TYPE_DMA_INDEX] = { | ||
1372 | .ib_execute = &evergreen_dma_ring_ib_execute, | ||
1373 | .emit_fence = &evergreen_dma_fence_ring_emit, | ||
1374 | .emit_semaphore = &r600_dma_semaphore_ring_emit, | ||
1375 | .cs_parse = NULL, | ||
1376 | .ring_test = &r600_dma_ring_test, | ||
1377 | .ib_test = &r600_dma_ib_test, | ||
1378 | .is_lockup = &r600_dma_is_lockup, | ||
1352 | } | 1379 | } |
1353 | }, | 1380 | }, |
1354 | .irq = { | 1381 | .irq = { |
@@ -1365,8 +1392,8 @@ static struct radeon_asic btc_asic = { | |||
1365 | .copy = { | 1392 | .copy = { |
1366 | .blit = &r600_copy_blit, | 1393 | .blit = &r600_copy_blit, |
1367 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1394 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1368 | .dma = NULL, | 1395 | .dma = &evergreen_copy_dma, |
1369 | .dma_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1396 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
1370 | .copy = &r600_copy_blit, | 1397 | .copy = &r600_copy_blit, |
1371 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1398 | .copy_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1372 | }, | 1399 | }, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 70a5b1f0e43e..7a2705d0a4d9 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -441,6 +441,14 @@ extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc); | |||
441 | void evergreen_disable_interrupt_state(struct radeon_device *rdev); | 441 | void evergreen_disable_interrupt_state(struct radeon_device *rdev); |
442 | int evergreen_blit_init(struct radeon_device *rdev); | 442 | int evergreen_blit_init(struct radeon_device *rdev); |
443 | int evergreen_mc_wait_for_idle(struct radeon_device *rdev); | 443 | int evergreen_mc_wait_for_idle(struct radeon_device *rdev); |
444 | void evergreen_dma_fence_ring_emit(struct radeon_device *rdev, | ||
445 | struct radeon_fence *fence); | ||
446 | void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, | ||
447 | struct radeon_ib *ib); | ||
448 | int evergreen_copy_dma(struct radeon_device *rdev, | ||
449 | uint64_t src_offset, uint64_t dst_offset, | ||
450 | unsigned num_gpu_pages, | ||
451 | struct radeon_fence **fence); | ||
444 | 452 | ||
445 | /* | 453 | /* |
446 | * cayman | 454 | * cayman |