diff options
| author | Dave Airlie <airlied@redhat.com> | 2012-12-10 17:46:03 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2012-12-10 17:46:03 -0500 |
| commit | a636a9829175987e74ddd28a2e87ed17ff7adfdc (patch) | |
| tree | 1c2f8e4425a1434215c3c5ae89b2f2e874ef2c3d | |
| parent | 97a875cbdf89a4638eea57c2b456c7cc4e3e8b21 (diff) | |
| parent | bf66a786c92488dfc99cc7f19bc9eda7b4c98fa6 (diff) | |
Merge branch 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux into drm-next
Alex writes:
"adds support for the
asynchronous DMA engines on r6xx-SI. These engines are used
for ttm bo moves and VM page table updates currently. They
could also be exposed via the CS ioctl for userspace use,
but I haven't had a chance to add proper CS checker patches
for them yet. These patches have been tested extensively
internally for months, so they should be pretty solid."
* 'drm-next-3.8' of git://people.freedesktop.org/~agd5f/linux:
drm/radeon: use DMA engine for VM page table updates on SI
drm/radeon: add dma engine support for vm pt updates on si (v2)
drm/radeon: use DMA engine for VM page table updates on cayman/TN
drm/radeon: add dma engine support for vm pt updates on ni (v5)
drm/radeon: use async dma for ttm buffer moves on 6xx-SI
drm/radeon/kms: add support for dma rings to radeon_test_moves()
drm/radeon/kms: Add initial support for async DMA on SI
drm/radeon/kms: Add initial support for async DMA on cayman/TN
drm/radeon/kms: Add initial support for async DMA on evergreen
drm/radeon/kms: Add initial support for async DMA on r6xx/r7xx
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 200 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 31 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 341 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/nid.h | 75 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 471 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/r600d.h | 54 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 192 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 30 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_test.c | 37 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 31 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/rv770d.h | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/si.c | 283 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 57 |
14 files changed, 1742 insertions, 101 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 78de2e4097b5..c66251e4a9b9 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, |
| @@ -2403,8 +2404,12 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
| 2403 | CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2404 | CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
| 2404 | cayman_cp_int_cntl_setup(rdev, 1, 0); | 2405 | cayman_cp_int_cntl_setup(rdev, 1, 0); |
| 2405 | cayman_cp_int_cntl_setup(rdev, 2, 0); | 2406 | cayman_cp_int_cntl_setup(rdev, 2, 0); |
| 2407 | tmp = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE; | ||
| 2408 | WREG32(CAYMAN_DMA1_CNTL, tmp); | ||
| 2406 | } else | 2409 | } else |
| 2407 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2410 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
| 2411 | tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE; | ||
| 2412 | WREG32(DMA_CNTL, tmp); | ||
| 2408 | WREG32(GRBM_INT_CNTL, 0); | 2413 | WREG32(GRBM_INT_CNTL, 0); |
| 2409 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2414 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
| 2410 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2415 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
| @@ -2457,6 +2462,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2457 | u32 grbm_int_cntl = 0; | 2462 | u32 grbm_int_cntl = 0; |
| 2458 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | 2463 | 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; | 2464 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; |
| 2465 | u32 dma_cntl, dma_cntl1 = 0; | ||
| 2460 | 2466 | ||
| 2461 | if (!rdev->irq.installed) { | 2467 | if (!rdev->irq.installed) { |
| 2462 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 2468 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
| @@ -2484,6 +2490,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; | 2490 | 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; | 2491 | afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; |
| 2486 | 2492 | ||
| 2493 | dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE; | ||
| 2494 | |||
| 2487 | if (rdev->family >= CHIP_CAYMAN) { | 2495 | if (rdev->family >= CHIP_CAYMAN) { |
| 2488 | /* enable CP interrupts on all rings */ | 2496 | /* enable CP interrupts on all rings */ |
| 2489 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { | 2497 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
| @@ -2506,6 +2514,19 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2506 | } | 2514 | } |
| 2507 | } | 2515 | } |
| 2508 | 2516 | ||
| 2517 | if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) { | ||
| 2518 | DRM_DEBUG("r600_irq_set: sw int dma\n"); | ||
| 2519 | dma_cntl |= TRAP_ENABLE; | ||
| 2520 | } | ||
| 2521 | |||
| 2522 | if (rdev->family >= CHIP_CAYMAN) { | ||
| 2523 | dma_cntl1 = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE; | ||
| 2524 | if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) { | ||
| 2525 | DRM_DEBUG("r600_irq_set: sw int dma1\n"); | ||
| 2526 | dma_cntl1 |= TRAP_ENABLE; | ||
| 2527 | } | ||
| 2528 | } | ||
| 2529 | |||
| 2509 | if (rdev->irq.crtc_vblank_int[0] || | 2530 | if (rdev->irq.crtc_vblank_int[0] || |
| 2510 | atomic_read(&rdev->irq.pflip[0])) { | 2531 | atomic_read(&rdev->irq.pflip[0])) { |
| 2511 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 2532 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
| @@ -2591,6 +2612,12 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
| 2591 | cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); | 2612 | cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); |
| 2592 | } else | 2613 | } else |
| 2593 | WREG32(CP_INT_CNTL, cp_int_cntl); | 2614 | WREG32(CP_INT_CNTL, cp_int_cntl); |
| 2615 | |||
| 2616 | WREG32(DMA_CNTL, dma_cntl); | ||
| 2617 | |||
| 2618 | if (rdev->family >= CHIP_CAYMAN) | ||
| 2619 | WREG32(CAYMAN_DMA1_CNTL, dma_cntl1); | ||
| 2620 | |||
| 2594 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 2621 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
| 2595 | 2622 | ||
| 2596 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 2623 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
| @@ -3126,9 +3153,19 @@ restart_ih: | |||
| 3126 | } else | 3153 | } else |
| 3127 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 3154 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
| 3128 | break; | 3155 | break; |
| 3156 | case 224: /* DMA trap event */ | ||
| 3157 | DRM_DEBUG("IH: DMA trap\n"); | ||
| 3158 | radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); | ||
| 3159 | break; | ||
| 3129 | case 233: /* GUI IDLE */ | 3160 | case 233: /* GUI IDLE */ |
| 3130 | DRM_DEBUG("IH: GUI idle\n"); | 3161 | DRM_DEBUG("IH: GUI idle\n"); |
| 3131 | break; | 3162 | break; |
| 3163 | case 244: /* DMA trap event */ | ||
| 3164 | if (rdev->family >= CHIP_CAYMAN) { | ||
| 3165 | DRM_DEBUG("IH: DMA1 trap\n"); | ||
| 3166 | radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); | ||
| 3167 | } | ||
| 3168 | break; | ||
| 3132 | default: | 3169 | default: |
| 3133 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | 3170 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); |
| 3134 | break; | 3171 | break; |
| @@ -3154,6 +3191,143 @@ restart_ih: | |||
| 3154 | return IRQ_HANDLED; | 3191 | return IRQ_HANDLED; |
| 3155 | } | 3192 | } |
| 3156 | 3193 | ||
| 3194 | /** | ||
| 3195 | * evergreen_dma_fence_ring_emit - emit a fence on the DMA ring | ||
| 3196 | * | ||
| 3197 | * @rdev: radeon_device pointer | ||
| 3198 | * @fence: radeon fence object | ||
| 3199 | * | ||
| 3200 | * Add a DMA fence packet to the ring to write | ||
| 3201 | * the fence seq number and DMA trap packet to generate | ||
| 3202 | * an interrupt if needed (evergreen-SI). | ||
| 3203 | */ | ||
| 3204 | void evergreen_dma_fence_ring_emit(struct radeon_device *rdev, | ||
| 3205 | struct radeon_fence *fence) | ||
| 3206 | { | ||
| 3207 | struct radeon_ring *ring = &rdev->ring[fence->ring]; | ||
| 3208 | u64 addr = rdev->fence_drv[fence->ring].gpu_addr; | ||
| 3209 | /* write the fence */ | ||
| 3210 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_FENCE, 0, 0, 0)); | ||
| 3211 | radeon_ring_write(ring, addr & 0xfffffffc); | ||
| 3212 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff)); | ||
| 3213 | radeon_ring_write(ring, fence->seq); | ||
| 3214 | /* generate an interrupt */ | ||
| 3215 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); | ||
| 3216 | /* flush HDP */ | ||
| 3217 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | ||
| 3218 | radeon_ring_write(ring, (0xf << 16) | HDP_MEM_COHERENCY_FLUSH_CNTL); | ||
| 3219 | radeon_ring_write(ring, 1); | ||
| 3220 | } | ||
| 3221 | |||
| 3222 | /** | ||
| 3223 | * evergreen_dma_ring_ib_execute - schedule an IB on the DMA engine | ||
| 3224 | * | ||
| 3225 | * @rdev: radeon_device pointer | ||
| 3226 | * @ib: IB object to schedule | ||
| 3227 | * | ||
| 3228 | * Schedule an IB in the DMA ring (evergreen). | ||
| 3229 | */ | ||
| 3230 | void evergreen_dma_ring_ib_execute(struct radeon_device *rdev, | ||
| 3231 | struct radeon_ib *ib) | ||
