From 69d2ae574b3a4b35e4970d8dec0bd598cfbe68a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 7 Dec 2011 23:32:24 +0100 Subject: drm/radeon/kms: support for audio on Evergreen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e4c384b9511c..a7da8d437161 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3069,6 +3069,12 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) { + DRM_ERROR("radeon: audio init failed\n"); + return r; + } + return 0; } @@ -3100,12 +3106,19 @@ int evergreen_resume(struct radeon_device *rdev) return r; } + r = r600_audio_init(rdev); + if (r) { + DRM_ERROR("radeon: audio resume failed\n"); + return r; + } + return r; } int evergreen_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); rdev->cp.ready = false; @@ -3225,6 +3238,7 @@ int evergreen_init(struct radeon_device *rdev) void evergreen_fini(struct radeon_device *rdev) { + r600_audio_fini(rdev); r600_blit_fini(rdev); r700_cp_fini(rdev); r600_irq_fini(rdev); -- cgit v1.2.1 From 7465280c076d6440e5908c158c83b542dc063a30 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 25 Aug 2011 13:39:48 -0400 Subject: drm/radeon/kms: add support for multiple fence queues v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For supporting multiple CP ring buffers, async DMA engines and UVD. We still need a way to synchronize between engines. v2 initialize unused fence driver ring to avoid issue in suspend/unload Signed-off-by: Alex Deucher Signed-off-by: Christian König Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 5e00d1670aa9..1c7af5654336 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3018,11 +3018,11 @@ restart_ih: case 177: /* CP_INT in IB1 */ case 178: /* CP_INT in IB2 */ DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); - radeon_fence_process(rdev); + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); break; case 181: /* CP EOP event */ DRM_DEBUG("IH: CP EOP\n"); - radeon_fence_process(rdev); + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); break; case 233: /* GUI IDLE */ DRM_DEBUG("IH: GUI idle\n"); @@ -3221,7 +3221,7 @@ int evergreen_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); /* Fence driver */ - r = radeon_fence_driver_init(rdev); + r = radeon_fence_driver_init(rdev, 1); if (r) return r; /* initialize AGP */ -- cgit v1.2.1 From 15d3332f31afd571a6d23971dbc8d8db2856e661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 15 Sep 2011 19:02:22 +0200 Subject: drm/radeon/kms: add support for semaphores v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are used to sync between rings, while fences sync between a ring and the cpu. v2 Fix radeon_semaphore_driver_fini when no semaphore were allocated. v3 Initialize list early on to avoid issue in case or early error Signed-off-by: Christian König Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 1c7af5654336..233cbc0a2b59 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1448,7 +1448,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) tmp |= BUF_SWAP_32BIT; #endif WREG32(CP_RB_CNTL, tmp); - WREG32(CP_SEM_WAIT_TIMER, 0x4); + WREG32(CP_SEM_WAIT_TIMER, 0x0); /* Set the write pointer delay */ WREG32(CP_RB_WPTR_DELAY, 0); @@ -3290,6 +3290,7 @@ void evergreen_fini(struct radeon_device *rdev) evergreen_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); + radeon_semaphore_driver_fini(rdev); radeon_fence_driver_fini(rdev); radeon_agp_fini(rdev); radeon_bo_fini(rdev); -- cgit v1.2.1 From 7b1f2485db253aaa0081e1c5213533e166130732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 23 Sep 2011 15:11:23 +0200 Subject: drm/radeon: make all functions work with multiple rings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Give all asic and radeon_ring_* functions a radeon_cp parameter, so they know the ring to work with. Signed-off-by: Christian König Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 123 ++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 58 deletions(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 233cbc0a2b59..fa11a04ae62e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1311,18 +1311,20 @@ void evergreen_mc_program(struct radeon_device *rdev) */ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { + struct radeon_cp *cp = &rdev->cp; + /* set to DX10/11 mode */ - radeon_ring_write(rdev, PACKET3(PACKET3_MODE_CONTROL, 0)); - radeon_ring_write(rdev, 1); + radeon_ring_write(cp, PACKET3(PACKET3_MODE_CONTROL, 0)); + radeon_ring_write(cp, 1); /* FIXME: implement */ - radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); + radeon_ring_write(cp, #ifdef __BIG_ENDIAN (2 << 0) | #endif (ib->gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF); - radeon_ring_write(rdev, ib->length_dw); + radeon_ring_write(cp, upper_32_bits(ib->gpu_addr) & 0xFF); + radeon_ring_write(cp, ib->length_dw); } @@ -1360,71 +1362,73 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) static int evergreen_cp_start(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r, i; uint32_t cp_me; - r = radeon_ring_lock(rdev, 7); + r = radeon_ring_lock(rdev, cp, 7); if (r) { DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); return r; } - radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5)); - radeon_ring_write(rdev, 0x1); - radeon_ring_write(rdev, 0x0); - radeon_ring_write(rdev, rdev->config.evergreen.max_hw_contexts - 1); - radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_unlock_commit(rdev); + radeon_ring_write(cp, PACKET3(PACKET3_ME_INITIALIZE, 5)); + radeon_ring_write(cp, 0x1); + radeon_ring_write(cp, 0x0); + radeon_ring_write(cp, rdev->config.evergreen.max_hw_contexts - 1); + radeon_ring_write(cp, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_unlock_commit(rdev, cp); cp_me = 0xff; WREG32(CP_ME_CNTL, cp_me); - r = radeon_ring_lock(rdev, evergreen_default_size + 19); + r = radeon_ring_lock(rdev, cp, evergreen_default_size + 19); if (r) { DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); return r; } /* setup clear context state */ - radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(rdev, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); + radeon_ring_write(cp, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); + radeon_ring_write(cp, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); for (i = 0; i < evergreen_default_size; i++) - radeon_ring_write(rdev, evergreen_default_state[i]); + radeon_ring_write(cp, evergreen_default_state[i]); - radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(rdev, PACKET3_PREAMBLE_END_CLEAR_STATE); + radeon_ring_write(cp, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); + radeon_ring_write(cp, PACKET3_PREAMBLE_END_CLEAR_STATE); /* set clear context state */ - radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_CLEAR_STATE, 0)); + radeon_ring_write(cp, 0); /* SQ_VTX_BASE_VTX_LOC */ - radeon_ring_write(rdev, 0xc0026f00); - radeon_ring_write(rdev, 0x00000000); - radeon_ring_write(rdev, 0x00000000); - radeon_ring_write(rdev, 0x00000000); + radeon_ring_write(cp, 0xc0026f00); + radeon_ring_write(cp, 0x00000000); + radeon_ring_write(cp, 0x00000000); + radeon_ring_write(cp, 0x00000000); /* Clear consts */ - radeon_ring_write(rdev, 0xc0036f00); - radeon_ring_write(rdev, 0x00000bc4); - radeon_ring_write(rdev, 0xffffffff); - radeon_ring_write(rdev, 0xffffffff); - radeon_ring_write(rdev, 0xffffffff); + radeon_ring_write(cp, 0xc0036f00); + radeon_ring_write(cp, 0x00000bc4); + radeon_ring_write(cp, 0xffffffff); + radeon_ring_write(cp, 0xffffffff); + radeon_ring_write(cp, 0xffffffff); - radeon_ring_write(rdev, 0xc0026900); - radeon_ring_write(rdev, 0x00000316); - radeon_ring_write(rdev, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - radeon_ring_write(rdev, 0x00000010); /* */ + radeon_ring_write(cp, 0xc0026900); + radeon_ring_write(cp, 0x00000316); + radeon_ring_write(cp, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ + radeon_ring_write(cp, 0x00000010); /* */ - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, cp); return 0; } int evergreen_cp_resume(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; u32 tmp; u32 rb_bufsz; int r; @@ -1442,7 +1446,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) RREG32(GRBM_SOFT_RESET); /* Set ring buffer size */ - rb_bufsz = drm_order(rdev->cp.ring_size / 8); + rb_bufsz = drm_order(cp->ring_size / 8); tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; #ifdef __BIG_ENDIAN tmp |= BUF_SWAP_32BIT; @@ -1456,8 +1460,8 @@ int evergreen_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); WREG32(CP_RB_RPTR_WR, 0); - rdev->cp.wptr = 0; - WREG32(CP_RB_WPTR, rdev->cp.wptr); + cp->wptr = 0; + WREG32(CP_RB_WPTR, cp->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, @@ -1475,16 +1479,16 @@ int evergreen_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB_CNTL, tmp); - WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8); + WREG32(CP_RB_BASE, cp->gpu_addr >> 8); WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); - rdev->cp.rptr = RREG32(CP_RB_RPTR); + cp->rptr = RREG32(CP_RB_RPTR); evergreen_cp_start(rdev); - rdev->cp.ready = true; - r = radeon_ring_test(rdev); + cp->ready = true; + r = radeon_ring_test(rdev, cp); if (r) { - rdev->cp.ready = false; + cp->ready = false; return r; } return 0; @@ -2353,7 +2357,7 @@ int evergreen_mc_init(struct radeon_device *rdev) return 0; } -bool evergreen_gpu_is_lockup(struct radeon_device *rdev) +bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) { u32 srbm_status; u32 grbm_status; @@ -2366,19 +2370,19 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev) grbm_status_se0 = RREG32(GRBM_STATUS_SE0); grbm_status_se1 = RREG32(GRBM_STATUS_SE1); if (!(grbm_status & GUI_ACTIVE)) { - r100_gpu_lockup_update(lockup, &rdev->cp); + r100_gpu_lockup_update(lockup, cp); return false; } /* force CP activities */ - r = radeon_ring_lock(rdev, 2); + r = radeon_ring_lock(rdev, cp, 2); if (!r) { /* PACKET2 NOP */ - radeon_ring_write(rdev, 0x80000000); - radeon_ring_write(rdev, 0x80000000); - radeon_ring_unlock_commit(rdev); + radeon_ring_write(cp, 0x80000000); + radeon_ring_write(cp, 0x80000000); + radeon_ring_unlock_commit(rdev, cp); } - rdev->cp.rptr = RREG32(CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); + cp->rptr = RREG32(CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, lockup, cp); } static int evergreen_gpu_soft_reset(struct radeon_device *rdev) @@ -3052,6 +3056,7 @@ restart_ih: static int evergreen_startup(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; /* enable pcie gen2 link */ @@ -3115,7 +3120,7 @@ static int evergreen_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, rdev->cp.ring_size); + r = radeon_ring_init(rdev, cp, cp->ring_size); if (r) return r; r = evergreen_cp_load_microcode(rdev); @@ -3150,7 +3155,7 @@ int evergreen_resume(struct radeon_device *rdev) return r; } - r = r600_ib_test(rdev); + r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); if (r) { DRM_ERROR("radeon: failed testing IB (%d).\n", r); return r; @@ -3162,9 +3167,11 @@ int evergreen_resume(struct radeon_device *rdev) int evergreen_suspend(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; + /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); - rdev->cp.ready = false; + cp->ready = false; evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); evergreen_pcie_gart_disable(rdev); @@ -3244,7 +3251,7 @@ int evergreen_init(struct radeon_device *rdev) return r; rdev->cp.ring_obj = NULL; - r600_ring_init(rdev, 1024 * 1024); + r600_ring_init(rdev, &rdev->cp, 1024 * 1024); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); @@ -3270,7 +3277,7 @@ int evergreen_init(struct radeon_device *rdev) DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); rdev->accel_working = false; } - r = r600_ib_test(rdev); + r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); if (r) { DRM_ERROR("radeon: failed testing IB (%d).\n", r); rdev->accel_working = false; -- cgit v1.2.1 From 5596a9db156107b01ceb7db4d50cc091117da627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 13 Oct 2011 12:48:45 +0200 Subject: drm/radeon: make ring rptr and wptr register offsets variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every ring seems to have the concept of read and write pointers. Make the register offset variable so we can use the functions for different types of rings. Signed-off-by: Christian König Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index fa11a04ae62e..d1264a7154a6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3120,7 +3120,8 @@ static int evergreen_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, cp, cp->ring_size); + r = radeon_ring_init(rdev, cp, cp->ring_size, RADEON_WB_CP_RPTR_OFFSET, + R600_CP_RB_RPTR, R600_CP_RB_WPTR); if (r) return r; r = evergreen_cp_load_microcode(rdev); -- cgit v1.2.1 From bf85279958da96cb4b11aac89b34f0424c3c120e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 13 Oct 2011 13:19:22 +0200 Subject: drm/radeon: make cp variable an array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace cp, cp1 and cp2 members with just an array of radeon_cp structs. Signed-off-by: Christian König Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d1264a7154a6..cb198aca9f5a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1311,7 +1311,7 @@ void evergreen_mc_program(struct radeon_device *rdev) */ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[ib->fence->ring]; /* set to DX10/11 mode */ radeon_ring_write(cp, PACKET3(PACKET3_MODE_CONTROL, 0)); @@ -1362,7 +1362,7 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) static int evergreen_cp_start(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; int r, i; uint32_t cp_me; @@ -1428,7 +1428,7 @@ static int evergreen_cp_start(struct radeon_device *rdev) int evergreen_cp_resume(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 tmp; u32 rb_bufsz; int r; @@ -3056,7 +3056,7 @@ restart_ih: static int evergreen_startup(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; int r; /* enable pcie gen2 link */ @@ -3168,7 +3168,7 @@ int evergreen_resume(struct radeon_device *rdev) int evergreen_suspend(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); @@ -3251,8 +3251,8 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; - rdev->cp.ring_obj = NULL; - r600_ring_init(rdev, &rdev->cp, 1024 * 1024); + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit v1.2.1 From e32eb50dbe43862606a51caa94368ec6bd019434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 23 Oct 2011 12:56:27 +0200 Subject: drm/radeon: rename struct radeon_cp to radeon_ring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That naming seems to make more sense, since we not only want to run PM4 rings with it. Signed-off-by: Christian König Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 124 ++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 62 deletions(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index cb198aca9f5a..b19ace86121e 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1311,20 +1311,20 @@ void evergreen_mc_program(struct radeon_device *rdev) */ void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { - struct radeon_cp *cp = &rdev->cp[ib->fence->ring]; + struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; /* set to DX10/11 mode */ - radeon_ring_write(cp, PACKET3(PACKET3_MODE_CONTROL, 0)); - radeon_ring_write(cp, 1); + radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); + radeon_ring_write(ring, 1); /* FIXME: implement */ - radeon_ring_write(cp, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); + radeon_ring_write(ring, #ifdef __BIG_ENDIAN (2 << 0) | #endif (ib->gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(cp, upper_32_bits(ib->gpu_addr) & 0xFF); - radeon_ring_write(cp, ib->length_dw); + radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); + radeon_ring_write(ring, ib->length_dw); } @@ -1362,73 +1362,73 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev) static int evergreen_cp_start(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; int r, i; uint32_t cp_me; - r = radeon_ring_lock(rdev, cp, 7); + r = radeon_ring_lock(rdev, ring, 7); if (r) { DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); return r; } - radeon_ring_write(cp, PACKET3(PACKET3_ME_INITIALIZE, 5)); - radeon_ring_write(cp, 0x1); - radeon_ring_write(cp, 0x0); - radeon_ring_write(cp, rdev->config.evergreen.max_hw_contexts - 1); - radeon_ring_write(cp, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); + radeon_ring_write(ring, 0x1); + radeon_ring_write(ring, 0x0); + radeon_ring_write(ring, rdev->config.evergreen.max_hw_contexts - 1); + radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_unlock_commit(rdev, ring); cp_me = 0xff; WREG32(CP_ME_CNTL, cp_me); - r = radeon_ring_lock(rdev, cp, evergreen_default_size + 19); + r = radeon_ring_lock(rdev, ring, evergreen_default_size + 19); if (r) { DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); return r; } /* setup clear context state */ - radeon_ring_write(cp, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(cp, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); + radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); + radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); for (i = 0; i < evergreen_default_size; i++) - radeon_ring_write(cp, evergreen_default_state[i]); + radeon_ring_write(ring, evergreen_default_state[i]); - radeon_ring_write(cp, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); - radeon_ring_write(cp, PACKET3_PREAMBLE_END_CLEAR_STATE); + radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); + radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); /* set clear context state */ - radeon_ring_write(cp, PACKET3(PACKET3_CLEAR_STATE, 0)); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); + radeon_ring_write(ring, 0); /* SQ_VTX_BASE_VTX_LOC */ - radeon_ring_write(cp, 0xc0026f00); - radeon_ring_write(cp, 0x00000000); - radeon_ring_write(cp, 0x00000000); - radeon_ring_write(cp, 0x00000000); + radeon_ring_write(ring, 0xc0026f00); + radeon_ring_write(ring, 0x00000000); + radeon_ring_write(ring, 0x00000000); + radeon_ring_write(ring, 0x00000000); /* Clear consts */ - radeon_ring_write(cp, 0xc0036f00); - radeon_ring_write(cp, 0x00000bc4); - radeon_ring_write(cp, 0xffffffff); - radeon_ring_write(cp, 0xffffffff); - radeon_ring_write(cp, 0xffffffff); + radeon_ring_write(ring, 0xc0036f00); + radeon_ring_write(ring, 0x00000bc4); + radeon_ring_write(ring, 0xffffffff); + radeon_ring_write(ring, 0xffffffff); + radeon_ring_write(ring, 0xffffffff); - radeon_ring_write(cp, 0xc0026900); - radeon_ring_write(cp, 0x00000316); - radeon_ring_write(cp, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ - radeon_ring_write(cp, 0x00000010); /* */ + radeon_ring_write(ring, 0xc0026900); + radeon_ring_write(ring, 0x00000316); + radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ + radeon_ring_write(ring, 0x00000010); /* */ - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_unlock_commit(rdev, ring); return 0; } int evergreen_cp_resume(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 tmp; u32 rb_bufsz; int r; @@ -1446,7 +1446,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) RREG32(GRBM_SOFT_RESET); /* Set ring buffer size */ - rb_bufsz = drm_order(cp->ring_size / 8); + rb_bufsz = drm_order(ring->ring_size / 8); tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; #ifdef __BIG_ENDIAN tmp |= BUF_SWAP_32BIT; @@ -1460,8 +1460,8 @@ int evergreen_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); WREG32(CP_RB_RPTR_WR, 0); - cp->wptr = 0; - WREG32(CP_RB_WPTR, cp->wptr); + ring->wptr = 0; + WREG32(CP_RB_WPTR, ring->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, @@ -1479,16 +1479,16 @@ int evergreen_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB_CNTL, tmp); - WREG32(CP_RB_BASE, cp->gpu_addr >> 8); + WREG32(CP_RB_BASE, ring->gpu_addr >> 8); WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); - cp->rptr = RREG32(CP_RB_RPTR); + ring->rptr = RREG32(CP_RB_RPTR); evergreen_cp_start(rdev); - cp->ready = true; - r = radeon_ring_test(rdev, cp); + ring->ready = true; + r = radeon_ring_test(rdev, ring); if (r) { - cp->ready = false; + ring->ready = false; return r; } return 0; @@ -2357,7 +2357,7 @@ int evergreen_mc_init(struct radeon_device *rdev) return 0; } -bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) +bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { u32 srbm_status; u32 grbm_status; @@ -2370,19 +2370,19 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) grbm_status_se0 = RREG32(GRBM_STATUS_SE0); grbm_status_se1 = RREG32(GRBM_STATUS_SE1); if (!(grbm_status & GUI_ACTIVE)) { - r100_gpu_lockup_update(lockup, cp); + r100_gpu_lockup_update(lockup, ring); return false; } /* force CP activities */ - r = radeon_ring_lock(rdev, cp, 2); + r = radeon_ring_lock(rdev, ring, 2); if (!r) { /* PACKET2 NOP */ - radeon_ring_write(cp, 0x80000000); - radeon_ring_write(cp, 0x80000000); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); } - cp->rptr = RREG32(CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, lockup, cp); + ring->rptr = RREG32(CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); } static int evergreen_gpu_soft_reset(struct radeon_device *rdev) @@ -3056,7 +3056,7 @@ restart_ih: static int evergreen_startup(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; int r; /* enable pcie gen2 link */ @@ -3120,7 +3120,7 @@ static int evergreen_startup(struct radeon_device *rdev) } evergreen_irq_set(rdev); - r = radeon_ring_init(rdev, cp, cp->ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, R600_CP_RB_RPTR, R600_CP_RB_WPTR); if (r) return r; @@ -3168,11 +3168,11 @@ int evergreen_resume(struct radeon_device *rdev) int evergreen_suspend(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); - cp->ready = false; + ring->ready = false; evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); evergreen_pcie_gart_disable(rdev); @@ -3251,8 +3251,8 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; - r600_ring_init(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; + r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); -- cgit v1.2.1 From 30eb77f4e6ba20f797af4ff79807fae7cb67429e Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 20 Nov 2011 20:45:34 +0000 Subject: drm/radeon: precompute fence cpu/gpu addr once v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a start fence driver helper function which will be call once for each ring and will compute cpu/gpu addr for fence depending on wether to use wb buffer or scratch reg. This patch replace initialize fence driver separately which was broken in regard of GPU lockup. The fence list for created, emited, signaled must be initialize once and only from the asic init callback not from the startup call back which is call from the gpu reset. v2: With this in place we no longer need to know the number of rings in fence_driver_init, also writing to the scratch reg before knowing its offset is a bad idea. v3: rebase on top of change to previous patch in the serie Signed-off-by: Christian König Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index b19ace86121e..ba19b9a697b0 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3111,6 +3111,12 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; + r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); + return r; + } + /* Enable IRQ */ r = r600_irq_init(rdev); if (r) { @@ -3229,7 +3235,7 @@ int evergreen_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; /* initialize AGP */ -- cgit v1.2.1 From 78c5560a08114d7bbbce04cee1628049a22ea104 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 17 Nov 2011 14:25:56 -0500 Subject: drm/radeon/kms: add some new ring params to better handle other ring types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some rptr/wptrs fields have different offsets and not all rings are pm4 so add a new nop field. Signed-off-by: Alex Deucher Signed-off-by: Christian König Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ba19b9a697b0..6ff1180c7321 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3127,7 +3127,8 @@ static int evergreen_startup(struct radeon_device *rdev) evergreen_irq_set(rdev); r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, - R600_CP_RB_RPTR, R600_CP_RB_WPTR); + R600_CP_RB_RPTR, R600_CP_RB_WPTR, + 0, 0xfffff, RADEON_CP_PACKET2); if (r) return r; r = evergreen_cp_load_microcode(rdev); -- cgit v1.2.1 From 1b37078b7ddf35cab12ac6544187e3636d50c0dc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 17 Nov 2011 20:13:28 -0500 Subject: drm/radeon/kms: add support for per-ring fence interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alex Deucher Signed-off-by: Christian König Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 58 +++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 6ff1180c7321..266d411c6d2b 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -40,6 +40,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); void evergreen_pcie_gen2_enable(struct radeon_device *rdev); +extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, + int ring, u32 cp_int_cntl); void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) { @@ -2474,7 +2476,13 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) { u32 tmp; - WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); + if (rdev->family >= CHIP_CAYMAN) { + cayman_cp_int_cntl_setup(rdev, 0, + CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); + cayman_cp_int_cntl_setup(rdev, 1, 0); + cayman_cp_int_cntl_setup(rdev, 2, 0); + } else + WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); WREG32(GRBM_INT_CNTL, 0); WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); @@ -2519,6 +2527,7 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) int evergreen_irq_set(struct radeon_device *rdev) { u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; + u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; u32 grbm_int_cntl = 0; @@ -2543,11 +2552,28 @@ int evergreen_irq_set(struct radeon_device *rdev) hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; - if (rdev->irq.sw_int) { - DRM_DEBUG("evergreen_irq_set: sw int\n"); - cp_int_cntl |= RB_INT_ENABLE; - cp_int_cntl |= TIME_STAMP_INT_ENABLE; + if (rdev->family >= CHIP_CAYMAN) { + /* enable CP interrupts on all rings */ + if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { + DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); + cp_int_cntl |= TIME_STAMP_INT_ENABLE; + } + if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) { + DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); + cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; + } + if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) { + DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); + cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; + } + } else { + if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { + DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); + cp_int_cntl |= RB_INT_ENABLE; + cp_int_cntl |= TIME_STAMP_INT_ENABLE; + } } + if (rdev->irq.crtc_vblank_int[0] || rdev->irq.pflip[0]) { DRM_DEBUG("evergreen_irq_set: vblank 0\n"); @@ -2607,7 +2633,12 @@ int evergreen_irq_set(struct radeon_device *rdev) grbm_int_cntl |= GUI_IDLE_INT_ENABLE; } - WREG32(CP_INT_CNTL, cp_int_cntl); + if (rdev->family >= CHIP_CAYMAN) { + cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); + cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1); + cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); + } else + WREG32(CP_INT_CNTL, cp_int_cntl); WREG32(GRBM_INT_CNTL, grbm_int_cntl); WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); @@ -3026,7 +3057,20 @@ restart_ih: break; case 181: /* CP EOP event */ DRM_DEBUG("IH: CP EOP\n"); - radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); + if (rdev->family >= CHIP_CAYMAN) { + switch (src_data) { + case 0: + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); + break; + case 1: + radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); + break; + case 2: + radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); + break; + } + } else + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); break; case 233: /* GUI IDLE */ DRM_DEBUG("IH: GUI idle\n"); -- cgit v1.2.1 From b15ba51207e54245409d6f46e20dab36f906eed1 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Tue, 15 Nov 2011 11:48:34 -0500 Subject: drm/radeon: introduce a sub allocator and convert ib pool to it v4 Somewhat specializaed sub-allocator designed to perform sub-allocation for command buffer not only for current cs ioctl but for future command submission ioctl as well. Patch also convert current ib pool to use the sub allocator. Idea is that ib poll buffer can be share with other command buffer submission not having 64K granularity. v2 Harmonize pool handling and add suspend/resume callback to pin/unpin sa bo (tested on rv280, rv370, r420, rv515, rv610, rv710, redwood, cayman, rs480, rs690, rs880) v3 Simplify allocator v4 Fix radeon_ib_get error path to properly free fence Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 42 ++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'drivers/gpu/drm/radeon/evergreen.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 266d411c6d2b..1934728e2465 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3182,6 +3182,17 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); + if (r) { + DRM_ERROR("radeon: failed testing IB (%d).\n", r); + rdev->accel_working = false; + return r; + } + return 0; } @@ -3201,18 +3212,13 @@ int evergreen_resume(struct radeon_device *rdev) /* post card */ atom_asic_init(rdev->mode_info.atom_context); + rdev->accel_working = true; r = evergreen_startup(rdev); if (r) { DRM_ERROR("evergreen startup failed on resume\n"); return r; } - r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d).\n", r); - return r; - } - return r; } @@ -3222,12 +3228,13 @@ int evergreen_suspend(struct radeon_device *rdev) struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; /* FIXME: we should wait for ring to be empty */ + radeon_ib_pool_suspend(rdev); + r600_blit_suspend(rdev); r700_cp_stop(rdev); ring->ready = false; evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); evergreen_pcie_gart_disable(rdev); - r600_blit_suspend(rdev); return 0; } @@ -3312,29 +3319,24 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r; + r = radeon_ib_pool_init(rdev); rdev->accel_working = true; + if (r) { + dev_err(rdev->dev, "IB initialization failed (%d).\n", r); + rdev->accel_working = false; + } + r = evergreen_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); r700_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); + r100_ib_fini(rdev); radeon_irq_kms_fini(rdev); evergreen_pcie_gart_fini(rdev); rdev->accel_working = false; } - if (rdev->accel_working) { - r = radeon_ib_pool_init(rdev); - if (r) { - DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r); - rdev->accel_working = false; - } - r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - DRM_ERROR("radeon: failed testing IB (%d).\n", r); - rdev->accel_working = false; - } - } return 0; } @@ -3344,7 +3346,7 @@ void evergreen_fini(struct radeon_device *rdev) r700_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); - radeon_ib_pool_fini(rdev); + r100_ib_fini(rdev); radeon_irq_kms_fini(rdev); evergreen_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); -- cgit v1.2.1