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/r300.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index c93bc64707e..b0473120646 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -198,7 +198,7 @@ void r300_fence_ring_emit(struct radeon_device *rdev, radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); radeon_ring_write(rdev, rdev->config.r300.hdp_cntl); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); + radeon_ring_write(rdev, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); radeon_ring_write(rdev, fence->seq); radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); radeon_ring_write(rdev, RADEON_SW_INT_FIRE); @@ -1518,7 +1518,7 @@ int r300_init(struct radeon_device *rdev) /* initialize memory controller */ r300_mc_init(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev); + r = radeon_fence_driver_init(rdev, 1); if (r) return r; r = radeon_irq_kms_init(rdev); -- cgit v1.2.3-70-g09d2 From 7b1f2485db253aaa0081e1c5213533e166130732 Mon Sep 17 00:00:00 2001 From: Christian König 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 +++++++------- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 242 ++++++++++++++-------------- drivers/gpu/drm/radeon/ni.c | 129 ++++++++------- drivers/gpu/drm/radeon/r100.c | 149 +++++++++-------- drivers/gpu/drm/radeon/r200.c | 21 +-- drivers/gpu/drm/radeon/r300.c | 127 ++++++++------- drivers/gpu/drm/radeon/r420.c | 22 +-- drivers/gpu/drm/radeon/r600.c | 201 ++++++++++++----------- drivers/gpu/drm/radeon/r600_blit_kms.c | 221 +++++++++++++------------ drivers/gpu/drm/radeon/radeon.h | 53 +++--- drivers/gpu/drm/radeon/radeon_asic.h | 28 ++-- drivers/gpu/drm/radeon/radeon_cs.c | 2 +- drivers/gpu/drm/radeon/radeon_fence.c | 2 +- drivers/gpu/drm/radeon/radeon_gem.c | 4 +- drivers/gpu/drm/radeon/radeon_pm.c | 13 +- drivers/gpu/drm/radeon/radeon_ring.c | 121 +++++++------- drivers/gpu/drm/radeon/radeon_semaphore.c | 4 +- drivers/gpu/drm/radeon/radeon_test.c | 3 +- drivers/gpu/drm/radeon/rv515.c | 81 +++++----- drivers/gpu/drm/radeon/rv770.c | 11 +- 20 files changed, 812 insertions(+), 745 deletions(-) (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 233cbc0a2b5..fa11a04ae62 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; diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 914e5af8416..75d0a6f0a39 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -49,6 +49,7 @@ static void set_render_target(struct radeon_device *rdev, int format, int w, int h, u64 gpu_addr) { + struct radeon_cp *cp = &rdev->cp; u32 cb_color_info; int pitch, slice; @@ -62,23 +63,23 @@ set_render_target(struct radeon_device *rdev, int format, pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 15)); - radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, pitch); - radeon_ring_write(rdev, slice); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, cb_color_info); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, (w - 1) | ((h - 1) << 16)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 15)); + radeon_ring_write(cp, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, pitch); + radeon_ring_write(cp, slice); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, cb_color_info); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, (w - 1) | ((h - 1) << 16)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); } /* emits 5dw */ @@ -87,6 +88,7 @@ cp_set_surface_sync(struct radeon_device *rdev, u32 sync_type, u32 size, u64 mc_addr) { + struct radeon_cp *cp = &rdev->cp; u32 cp_coher_size; if (size == 0xffffffff) @@ -99,39 +101,40 @@ cp_set_surface_sync(struct radeon_device *rdev, * to the RB directly. For IBs, the CP programs this as part of the * surface_sync packet. */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(rdev, 0); /* CP_COHER_CNTL2 */ + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(cp, 0); /* CP_COHER_CNTL2 */ } - radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(rdev, sync_type); - radeon_ring_write(rdev, cp_coher_size); - radeon_ring_write(rdev, mc_addr >> 8); - radeon_ring_write(rdev, 10); /* poll interval */ + radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(cp, sync_type); + radeon_ring_write(cp, cp_coher_size); + radeon_ring_write(cp, mc_addr >> 8); + radeon_ring_write(cp, 10); /* poll interval */ } /* emits 11dw + 1 surface sync = 16dw */ static void set_shaders(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; u64 gpu_addr; /* VS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 3)); - radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 3)); + radeon_ring_write(cp, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, 2); + radeon_ring_write(cp, 0); /* PS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 4)); - radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, 1); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 2); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 4)); + radeon_ring_write(cp, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, 1); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 2); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); @@ -141,6 +144,7 @@ set_shaders(struct radeon_device *rdev) static void set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) { + struct radeon_cp *cp = &rdev->cp; u32 sq_vtx_constant_word2, sq_vtx_constant_word3; /* high addr, stride */ @@ -155,16 +159,16 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) SQ_VTCX_SEL_Z(SQ_SEL_Z) | SQ_VTCX_SEL_W(SQ_SEL_W); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8)); - radeon_ring_write(rdev, 0x580); - radeon_ring_write(rdev, gpu_addr & 0xffffffff); - radeon_ring_write(rdev, 48 - 1); /* size */ - radeon_ring_write(rdev, sq_vtx_constant_word2); - radeon_ring_write(rdev, sq_vtx_constant_word3); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_BUFFER)); + radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 8)); + radeon_ring_write(cp, 0x580); + radeon_ring_write(cp, gpu_addr & 0xffffffff); + radeon_ring_write(cp, 48 - 1); /* size */ + radeon_ring_write(cp, sq_vtx_constant_word2); + radeon_ring_write(cp, sq_vtx_constant_word3); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_BUFFER)); if ((rdev->family == CHIP_CEDAR) || (rdev->family == CHIP_PALM) || @@ -185,6 +189,7 @@ set_tex_resource(struct radeon_device *rdev, int format, int w, int h, int pitch, u64 gpu_addr, u32 size) { + struct radeon_cp *cp = &rdev->cp; u32 sq_tex_resource_word0, sq_tex_resource_word1; u32 sq_tex_resource_word4, sq_tex_resource_word7; @@ -208,16 +213,16 @@ set_tex_resource(struct radeon_device *rdev, cp_set_surface_sync(rdev, PACKET3_TC_ACTION_ENA, size, gpu_addr); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 8)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, sq_tex_resource_word0); - radeon_ring_write(rdev, sq_tex_resource_word1); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, sq_tex_resource_word4); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, sq_tex_resource_word7); + radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 8)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, sq_tex_resource_word0); + radeon_ring_write(cp, sq_tex_resource_word1); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, sq_tex_resource_word4); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, sq_tex_resource_word7); } /* emits 12 */ @@ -225,6 +230,7 @@ static void set_scissors(struct radeon_device *rdev, int x1, int y1, int x2, int y2) { + struct radeon_cp *cp = &rdev->cp; /* workaround some hw bugs */ if (x2 == 0) x1 = 1; @@ -235,43 +241,44 @@ set_scissors(struct radeon_device *rdev, int x1, int y1, x2 = 2; } - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16)); - radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(cp, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(cp, (x1 << 0) | (y1 << 16)); + radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(cp, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(cp, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); } /* emits 10 */ static void draw_auto(struct radeon_device *rdev) { - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(rdev, DI_PT_RECTLIST); + struct radeon_cp *cp = &rdev->cp; + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(cp, DI_PT_RECTLIST); - radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET3(PACKET3_INDEX_TYPE, 0)); + radeon_ring_write(cp, #ifdef __BIG_ENDIAN (2 << 2) | #endif DI_INDEX_SIZE_16_BIT); - radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); - radeon_ring_write(rdev, 1); + radeon_ring_write(cp, PACKET3(PACKET3_NUM_INSTANCES, 0)); + radeon_ring_write(cp, 1); - radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); - radeon_ring_write(rdev, 3); - radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX); + radeon_ring_write(cp, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); + radeon_ring_write(cp, 3); + radeon_ring_write(cp, DI_SRC_SEL_AUTO_INDEX); } @@ -279,6 +286,7 @@ draw_auto(struct radeon_device *rdev) static void set_default_state(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2, sq_gpr_resource_mgmt_3; u32 sq_thread_resource_mgmt, sq_thread_resource_mgmt_2; u32 sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2, sq_stack_resource_mgmt_3; @@ -292,8 +300,8 @@ set_default_state(struct radeon_device *rdev) int dwords; /* 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); if (rdev->family < CHIP_CAYMAN) { switch (rdev->family) { @@ -550,60 +558,60 @@ set_default_state(struct radeon_device *rdev) NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); /* disable dyn gprs */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(cp, 0); /* setup LDS */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, (SQ_LDS_RESOURCE_MGMT - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(rdev, 0x10001000); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, (SQ_LDS_RESOURCE_MGMT - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(cp, 0x10001000); /* SQ config */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); - radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(rdev, sq_config); - radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); - radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); - radeon_ring_write(rdev, sq_gpr_resource_mgmt_3); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, sq_thread_resource_mgmt); - radeon_ring_write(rdev, sq_thread_resource_mgmt_2); - radeon_ring_write(rdev, sq_stack_resource_mgmt_1); - radeon_ring_write(rdev, sq_stack_resource_mgmt_2); - radeon_ring_write(rdev, sq_stack_resource_mgmt_3); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 11)); + radeon_ring_write(cp, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(cp, sq_config); + radeon_ring_write(cp, sq_gpr_resource_mgmt_1); + radeon_ring_write(cp, sq_gpr_resource_mgmt_2); + radeon_ring_write(cp, sq_gpr_resource_mgmt_3); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, sq_thread_resource_mgmt); + radeon_ring_write(cp, sq_thread_resource_mgmt_2); + radeon_ring_write(cp, sq_stack_resource_mgmt_1); + radeon_ring_write(cp, sq_stack_resource_mgmt_2); + radeon_ring_write(cp, sq_stack_resource_mgmt_3); } /* CONTEXT_CONTROL */ - radeon_ring_write(rdev, 0xc0012800); - radeon_ring_write(rdev, 0x80000000); - radeon_ring_write(rdev, 0x80000000); + radeon_ring_write(cp, 0xc0012800); + radeon_ring_write(cp, 0x80000000); + radeon_ring_write(cp, 0x80000000); /* 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); /* SET_SAMPLER */ - radeon_ring_write(rdev, 0xc0036e00); - radeon_ring_write(rdev, 0x00000000); - radeon_ring_write(rdev, 0x00000012); - radeon_ring_write(rdev, 0x00000000); - radeon_ring_write(rdev, 0x00000000); + radeon_ring_write(cp, 0xc0036e00); + radeon_ring_write(cp, 0x00000000); + radeon_ring_write(cp, 0x00000012); + radeon_ring_write(cp, 0x00000000); + radeon_ring_write(cp, 0x00000000); /* 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); /* emit an IB pointing at default state */ dwords = ALIGN(rdev->r600_blit.state_len, 0x10); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; - radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC); - radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); - radeon_ring_write(rdev, dwords); + radeon_ring_write(cp, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); + radeon_ring_write(cp, gpu_addr & 0xFFFFFFFC); + radeon_ring_write(cp, upper_32_bits(gpu_addr) & 0xFF); + radeon_ring_write(cp, dwords); } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index ef749950db0..636b8c5f579 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1049,63 +1049,64 @@ static int cayman_cp_load_microcode(struct radeon_device *rdev) static int cayman_cp_start(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r, i; - 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.cayman.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.cayman.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); cayman_cp_enable(rdev, true); - r = radeon_ring_lock(rdev, cayman_default_size + 19); + r = radeon_ring_lock(rdev, cp, cayman_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 < cayman_default_size; i++) - radeon_ring_write(rdev, cayman_default_state[i]); + radeon_ring_write(cp, cayman_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); /* XXX init other rings */ @@ -1115,11 +1116,12 @@ static int cayman_cp_start(struct radeon_device *rdev) static void cayman_cp_fini(struct radeon_device *rdev) { cayman_cp_enable(rdev, false); - radeon_ring_fini(rdev); + radeon_ring_fini(rdev, &rdev->cp); } int cayman_cp_resume(struct radeon_device *rdev) { + struct radeon_cp *cp; u32 tmp; u32 rb_bufsz; int r; @@ -1145,7 +1147,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* ring 0 - compute and gfx */ /* Set ring buffer size */ - rb_bufsz = drm_order(rdev->cp.ring_size / 8); + cp = &rdev->cp; + 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; @@ -1154,8 +1157,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - rdev->cp.wptr = 0; - WREG32(CP_RB0_WPTR, rdev->cp.wptr); + cp->wptr = 0; + WREG32(CP_RB0_WPTR, cp->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1172,13 +1175,14 @@ int cayman_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB0_CNTL, tmp); - WREG32(CP_RB0_BASE, rdev->cp.gpu_addr >> 8); + WREG32(CP_RB0_BASE, cp->gpu_addr >> 8); - rdev->cp.rptr = RREG32(CP_RB0_RPTR); + cp->rptr = RREG32(CP_RB0_RPTR); /* ring1 - compute only */ /* Set ring buffer size */ - rb_bufsz = drm_order(rdev->cp1.ring_size / 8); + cp = &rdev->cp1; + 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; @@ -1187,8 +1191,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - rdev->cp1.wptr = 0; - WREG32(CP_RB1_WPTR, rdev->cp1.wptr); + cp->wptr = 0; + WREG32(CP_RB1_WPTR, cp->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1197,13 +1201,14 @@ int cayman_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB1_CNTL, tmp); - WREG32(CP_RB1_BASE, rdev->cp1.gpu_addr >> 8); + WREG32(CP_RB1_BASE, cp->gpu_addr >> 8); - rdev->cp1.rptr = RREG32(CP_RB1_RPTR); + cp->rptr = RREG32(CP_RB1_RPTR); /* ring2 - compute only */ /* Set ring buffer size */ - rb_bufsz = drm_order(rdev->cp2.ring_size / 8); + cp = &rdev->cp2; + 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; @@ -1212,8 +1217,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - rdev->cp2.wptr = 0; - WREG32(CP_RB2_WPTR, rdev->cp2.wptr); + cp->wptr = 0; + WREG32(CP_RB2_WPTR, cp->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1222,9 +1227,9 @@ int cayman_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB2_CNTL, tmp); - WREG32(CP_RB2_BASE, rdev->cp2.gpu_addr >> 8); + WREG32(CP_RB2_BASE, cp->gpu_addr >> 8); - rdev->cp2.rptr = RREG32(CP_RB2_RPTR); + cp->rptr = RREG32(CP_RB2_RPTR); /* start the rings */ cayman_cp_start(rdev); @@ -1232,7 +1237,7 @@ int cayman_cp_resume(struct radeon_device *rdev) rdev->cp1.ready = true; rdev->cp2.ready = true; /* this only test cp0 */ - r = radeon_ring_test(rdev); + r = radeon_ring_test(rdev, &rdev->cp); if (r) { rdev->cp.ready = false; rdev->cp1.ready = false; @@ -1243,7 +1248,7 @@ int cayman_cp_resume(struct radeon_device *rdev) return 0; } -bool cayman_gpu_is_lockup(struct radeon_device *rdev) +bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) { u32 srbm_status; u32 grbm_status; @@ -1256,20 +1261,20 @@ bool cayman_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); } /* XXX deal with CP0,1,2 */ - rdev->cp.rptr = RREG32(CP_RB0_RPTR); - return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); + cp->rptr = RREG32(CP_RB0_RPTR); + return r100_gpu_cp_is_lockup(rdev, lockup, cp); } static int cayman_gpu_soft_reset(struct radeon_device *rdev) @@ -1338,6 +1343,7 @@ int cayman_asic_reset(struct radeon_device *rdev) static int cayman_startup(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; /* enable pcie gen2 link */ @@ -1387,7 +1393,7 @@ static int cayman_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 = cayman_cp_load_microcode(rdev); @@ -1417,7 +1423,7 @@ int cayman_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: failled testing IB (%d).\n", r); return r; @@ -1448,6 +1454,7 @@ int cayman_suspend(struct radeon_device *rdev) */ int cayman_init(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; /* This don't do much */ @@ -1500,8 +1507,8 @@ int cayman_init(struct radeon_device *rdev) if (r) return r; - rdev->cp.ring_obj = NULL; - r600_ring_init(rdev, 1024 * 1024); + cp->ring_obj = NULL; + r600_ring_init(rdev, cp, 1024 * 1024); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); @@ -1527,7 +1534,7 @@ int cayman_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; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 2f18163e5e3..271cee7f817 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -811,30 +811,33 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) void r100_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { + struct radeon_cp *cp = &rdev->cp; + /* We have to make sure that caches are flushed before * CPU might read something from VRAM. */ - radeon_ring_write(rdev, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, RADEON_RB3D_DC_FLUSH_ALL); - radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL); + radeon_ring_write(cp, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, RADEON_RB3D_DC_FLUSH_ALL); + radeon_ring_write(cp, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, RADEON_RB3D_ZC_FLUSH_ALL); /* Wait until IDLE & CLEAN */ - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(rdev, rdev->config.r100.hdp_cntl | + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); + radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(cp, rdev->config.r100.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE); - radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(rdev, rdev->config.r100.hdp_cntl); + radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(cp, rdev->config.r100.hdp_cntl); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(rdev, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); - radeon_ring_write(rdev, fence->seq); - radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); - radeon_ring_write(rdev, RADEON_SW_INT_FIRE); + radeon_ring_write(cp, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); + radeon_ring_write(cp, fence->seq); + radeon_ring_write(cp, PACKET0(RADEON_GEN_INT_STATUS, 0)); + radeon_ring_write(cp, RADEON_SW_INT_FIRE); } void r100_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_cp *cp, struct radeon_semaphore *semaphore, - unsigned ring, bool emit_wait) + bool emit_wait) { /* Unused on older asics, since we don't have semaphores or multiple rings */ BUG(); @@ -846,6 +849,7 @@ int r100_copy_blit(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { + struct radeon_cp *cp = &rdev->cp; uint32_t cur_pages; uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; uint32_t pitch; @@ -863,7 +867,7 @@ int r100_copy_blit(struct radeon_device *rdev, /* Ask for enough room for blit + flush + fence */ ndw = 64 + (10 * num_loops); - r = radeon_ring_lock(rdev, ndw); + r = radeon_ring_lock(rdev, cp, ndw); if (r) { DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); return -EINVAL; @@ -877,8 +881,8 @@ int r100_copy_blit(struct radeon_device *rdev, /* pages are in Y direction - height page width in X direction - width */ - radeon_ring_write(rdev, PACKET3(PACKET3_BITBLT_MULTI, 8)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET3(PACKET3_BITBLT_MULTI, 8)); + radeon_ring_write(cp, RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_SRC_CLIPPING | @@ -890,26 +894,26 @@ int r100_copy_blit(struct radeon_device *rdev, RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - radeon_ring_write(rdev, (pitch << 22) | (src_offset >> 10)); - radeon_ring_write(rdev, (pitch << 22) | (dst_offset >> 10)); - radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(rdev, num_gpu_pages); - radeon_ring_write(rdev, num_gpu_pages); - radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); - } - radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, RADEON_RB2D_DC_FLUSH_ALL); - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, (pitch << 22) | (src_offset >> 10)); + radeon_ring_write(cp, (pitch << 22) | (dst_offset >> 10)); + radeon_ring_write(cp, (0x1fff) | (0x1fff << 16)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, (0x1fff) | (0x1fff << 16)); + radeon_ring_write(cp, num_gpu_pages); + radeon_ring_write(cp, num_gpu_pages); + radeon_ring_write(cp, cur_pages | (stride_pixels << 16)); + } + radeon_ring_write(cp, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, RADEON_RB2D_DC_FLUSH_ALL); + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); if (fence) { r = radeon_fence_emit(rdev, fence); } - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, cp); return r; } @@ -930,19 +934,20 @@ static int r100_cp_wait_for_idle(struct radeon_device *rdev) void r100_ring_start(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; - r = radeon_ring_lock(rdev, 2); + r = radeon_ring_lock(rdev, cp, 2); if (r) { return; } - radeon_ring_write(rdev, PACKET0(RADEON_ISYNC_CNTL, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(RADEON_ISYNC_CNTL, 0)); + radeon_ring_write(cp, RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, cp); } @@ -1043,6 +1048,7 @@ static void r100_cp_load_microcode(struct radeon_device *rdev) int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) { + struct radeon_cp *cp = &rdev->cp; unsigned rb_bufsz; unsigned rb_blksz; unsigned max_fetch; @@ -1068,7 +1074,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; r100_cp_load_microcode(rdev); - r = radeon_ring_init(rdev, ring_size); + r = radeon_ring_init(rdev, cp, ring_size); if (r) { return r; } @@ -1077,7 +1083,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_blksz = 9; /* cp will read 128bytes at a time (4 dwords) */ max_fetch = 1; - rdev->cp.align_mask = 16 - 1; + cp->align_mask = 16 - 1; /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ pre_write_timer = 64; /* Force CP_RB_WPTR write if written more than one time before the @@ -1107,13 +1113,13 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_NO_UPDATE); /* Set ring address */ - DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); - WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); + DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)cp->gpu_addr); + WREG32(RADEON_CP_RB_BASE, cp->gpu_addr); /* Force read & write ptr to 0 */ WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); WREG32(RADEON_CP_RB_RPTR_WR, 0); - rdev->cp.wptr = 0; - WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); + cp->wptr = 0; + WREG32(RADEON_CP_RB_WPTR, cp->wptr); /* set the wb address whether it's enabled or not */ WREG32(R_00070C_CP_RB_RPTR_ADDR, @@ -1129,7 +1135,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_RB_CNTL, tmp); udelay(10); - rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); + cp->rptr = RREG32(RADEON_CP_RB_RPTR); /* Set cp mode to bus mastering & enable cp*/ WREG32(RADEON_CP_CSQ_MODE, REG_SET(RADEON_INDIRECT2_START, indirect2_start) | @@ -1138,12 +1144,12 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); radeon_ring_start(rdev); - r = radeon_ring_test(rdev); + r = radeon_ring_test(rdev, cp); if (r) { DRM_ERROR("radeon: cp isn't working (%d).\n", r); return r; } - rdev->cp.ready = true; + cp->ready = true; radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; } @@ -1155,7 +1161,7 @@ void r100_cp_fini(struct radeon_device *rdev) } /* Disable ring */ r100_cp_disable(rdev); - radeon_ring_fini(rdev); + radeon_ring_fini(rdev, &rdev->cp); DRM_INFO("radeon: cp finalized\n"); } @@ -1173,9 +1179,9 @@ void r100_cp_disable(struct radeon_device *rdev) } } -void r100_cp_commit(struct radeon_device *rdev) +void r100_cp_commit(struct radeon_device *rdev, struct radeon_cp *cp) { - WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); + WREG32(RADEON_CP_RB_WPTR, cp->wptr); (void)RREG32(RADEON_CP_RB_WPTR); } @@ -2160,26 +2166,26 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l return false; } -bool r100_gpu_is_lockup(struct radeon_device *rdev) +bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) { u32 rbbm_status; int r; rbbm_status = RREG32(R_000E40_RBBM_STATUS); if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - r100_gpu_lockup_update(&rdev->config.r100.lockup, &rdev->cp); + r100_gpu_lockup_update(&rdev->config.r100.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(RADEON_CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp); + cp->rptr = RREG32(RADEON_CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, cp); } void r100_bm_disable(struct radeon_device *rdev) @@ -2587,21 +2593,22 @@ static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; + struct radeon_cp *cp = &rdev->cp; uint32_t rdp, wdp; unsigned count, i, j; - radeon_ring_free_size(rdev); + radeon_ring_free_size(rdev, cp); rdp = RREG32(RADEON_CP_RB_RPTR); wdp = RREG32(RADEON_CP_RB_WPTR); - count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask; + count = (rdp + cp->ring_size - wdp) & cp->ptr_mask; seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); - seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); + seq_printf(m, "%u free dwords in ring\n", cp->ring_free_dw); seq_printf(m, "%u dwords in ring\n", count); for (j = 0; j <= count; j++) { - i = (rdp + j) & rdev->cp.ptr_mask; - seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); + i = (rdp + j) & cp->ptr_mask; + seq_printf(m, "r[%04d]=0x%08x\n", i, cp->ring[i]); } return 0; } @@ -3643,7 +3650,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track } } -int r100_ring_test(struct radeon_device *rdev) +int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) { uint32_t scratch; uint32_t tmp = 0; @@ -3656,15 +3663,15 @@ int r100_ring_test(struct radeon_device *rdev) return r; } WREG32(scratch, 0xCAFEDEAD); - r = radeon_ring_lock(rdev, 2); + r = radeon_ring_lock(rdev, cp, 2); if (r) { DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); radeon_scratch_free(rdev, scratch); return r; } - radeon_ring_write(rdev, PACKET0(scratch, 0)); - radeon_ring_write(rdev, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev); + radeon_ring_write(cp, PACKET0(scratch, 0)); + radeon_ring_write(cp, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev, cp); for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(scratch); if (tmp == 0xDEADBEEF) { @@ -3685,9 +3692,11 @@ int r100_ring_test(struct radeon_device *rdev) void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { - radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); - radeon_ring_write(rdev, ib->gpu_addr); - radeon_ring_write(rdev, ib->length_dw); + struct radeon_cp *cp = &rdev->cp; + + radeon_ring_write(cp, PACKET0(RADEON_CP_IB_BASE, 1)); + radeon_ring_write(cp, ib->gpu_addr); + radeon_ring_write(cp, ib->length_dw); } int r100_ib_test(struct radeon_device *rdev) @@ -3704,7 +3713,7 @@ int r100_ib_test(struct radeon_device *rdev) return r; } WREG32(scratch, 0xCAFEDEAD); - r = radeon_ib_get(rdev, &ib); + r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index a1f3ba063c2..d84e633f72f 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -87,6 +87,7 @@ int r200_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { + struct radeon_cp *cp = &rdev->cp; uint32_t size; uint32_t cur_size; int i, num_loops; @@ -95,33 +96,33 @@ int r200_copy_dma(struct radeon_device *rdev, /* radeon pitch is /64 */ size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; num_loops = DIV_ROUND_UP(size, 0x1FFFFF); - r = radeon_ring_lock(rdev, num_loops * 4 + 64); + r = radeon_ring_lock(rdev, cp, num_loops * 4 + 64); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); return r; } /* Must wait for 2D idle & clean before DMA or hangs might happen */ - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, (1 << 16)); + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, (1 << 16)); for (i = 0; i < num_loops; i++) { cur_size = size; if (cur_size > 0x1FFFFF) { cur_size = 0x1FFFFF; } size -= cur_size; - radeon_ring_write(rdev, PACKET0(0x720, 2)); - radeon_ring_write(rdev, src_offset); - radeon_ring_write(rdev, dst_offset); - radeon_ring_write(rdev, cur_size | (1 << 31) | (1 << 30)); + radeon_ring_write(cp, PACKET0(0x720, 2)); + radeon_ring_write(cp, src_offset); + radeon_ring_write(cp, dst_offset); + radeon_ring_write(cp, cur_size | (1 << 31) | (1 << 30)); src_offset += cur_size; dst_offset += cur_size; } - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, RADEON_WAIT_DMA_GUI_IDLE); + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, RADEON_WAIT_DMA_GUI_IDLE); if (fence) { r = radeon_fence_emit(rdev, fence); } - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, cp); return r; } diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index b0473120646..cbb62fc3f2e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -175,37 +175,40 @@ void rv370_pcie_gart_fini(struct radeon_device *rdev) void r300_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { + struct radeon_cp *cp = &rdev->cp; + /* Who ever call radeon_fence_emit should call ring_lock and ask * for enough space (today caller are ib schedule and buffer move) */ /* Write SC register so SC & US assert idle */ - radeon_ring_write(rdev, PACKET0(R300_RE_SCISSORS_TL, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(R300_RE_SCISSORS_BR, 0)); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET0(R300_RE_SCISSORS_TL, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(R300_RE_SCISSORS_BR, 0)); + radeon_ring_write(cp, 0); /* Flush 3D cache */ - radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_RB3D_DC_FLUSH); - radeon_ring_write(rdev, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_ZC_FLUSH); + radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_RB3D_DC_FLUSH); + radeon_ring_write(cp, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_ZC_FLUSH); /* Wait until IDLE & CLEAN */ - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, (RADEON_WAIT_3D_IDLECLEAN | + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, (RADEON_WAIT_3D_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE)); - radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(rdev, rdev->config.r300.hdp_cntl | + radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(cp, rdev->config.r300.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE); - radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(rdev, rdev->config.r300.hdp_cntl); + radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(cp, rdev->config.r300.hdp_cntl); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(rdev, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); - radeon_ring_write(rdev, fence->seq); - radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); - radeon_ring_write(rdev, RADEON_SW_INT_FIRE); + radeon_ring_write(cp, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); + radeon_ring_write(cp, fence->seq); + radeon_ring_write(cp, PACKET0(RADEON_GEN_INT_STATUS, 0)); + radeon_ring_write(cp, RADEON_SW_INT_FIRE); } void r300_ring_start(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; unsigned gb_tile_config; int r; @@ -227,44 +230,44 @@ void r300_ring_start(struct radeon_device *rdev) break; } - r = radeon_ring_lock(rdev, 64); + r = radeon_ring_lock(rdev, cp, 64); if (r) { return; } - radeon_ring_write(rdev, PACKET0(RADEON_ISYNC_CNTL, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(RADEON_ISYNC_CNTL, 0)); + radeon_ring_write(cp, RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_write(rdev, PACKET0(R300_GB_TILE_CONFIG, 0)); - radeon_ring_write(rdev, gb_tile_config); - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(R300_GB_TILE_CONFIG, 0)); + radeon_ring_write(cp, gb_tile_config); + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(rdev, PACKET0(R300_DST_PIPE_CONFIG, 0)); - radeon_ring_write(rdev, R300_PIPE_AUTO_CONFIG); - radeon_ring_write(rdev, PACKET0(R300_GB_SELECT, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(R300_GB_ENABLE, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); - radeon_ring_write(rdev, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_ZC_FLUSH | R300_ZC_FREE); - radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(R300_DST_PIPE_CONFIG, 0)); + radeon_ring_write(cp, R300_PIPE_AUTO_CONFIG); + radeon_ring_write(cp, PACKET0(R300_GB_SELECT, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(R300_GB_ENABLE, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); + radeon_ring_write(cp, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_ZC_FLUSH | R300_ZC_FREE); + radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(cp, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(rdev, PACKET0(R300_GB_AA_CONFIG, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); - radeon_ring_write(rdev, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_ZC_FLUSH | R300_ZC_FREE); - radeon_ring_write(rdev, PACKET0(R300_GB_MSPOS0, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(R300_GB_AA_CONFIG, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); + radeon_ring_write(cp, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_ZC_FLUSH | R300_ZC_FREE); + radeon_ring_write(cp, PACKET0(R300_GB_MSPOS0, 0)); + radeon_ring_write(cp, ((6 << R300_MS_X0_SHIFT) | (6 << R300_MS_Y0_SHIFT) | (6 << R300_MS_X1_SHIFT) | @@ -273,8 +276,8 @@ void r300_ring_start(struct radeon_device *rdev) (6 << R300_MS_Y2_SHIFT) | (6 << R300_MSBD0_Y_SHIFT) | (6 << R300_MSBD0_X_SHIFT))); - radeon_ring_write(rdev, PACKET0(R300_GB_MSPOS1, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(R300_GB_MSPOS1, 0)); + radeon_ring_write(cp, ((6 << R300_MS_X3_SHIFT) | (6 << R300_MS_Y3_SHIFT) | (6 << R300_MS_X4_SHIFT) | @@ -282,16 +285,16 @@ void r300_ring_start(struct radeon_device *rdev) (6 << R300_MS_X5_SHIFT) | (6 << R300_MS_Y5_SHIFT) | (6 << R300_MSBD1_SHIFT))); - radeon_ring_write(rdev, PACKET0(R300_GA_ENHANCE, 0)); - radeon_ring_write(rdev, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); - radeon_ring_write(rdev, PACKET0(R300_GA_POLY_MODE, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(R300_GA_ENHANCE, 0)); + radeon_ring_write(cp, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); + radeon_ring_write(cp, PACKET0(R300_GA_POLY_MODE, 0)); + radeon_ring_write(cp, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE); - radeon_ring_write(rdev, PACKET0(R300_GA_ROUND_MODE, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(R300_GA_ROUND_MODE, 0)); + radeon_ring_write(cp, R300_GEOMETRY_ROUND_NEAREST | R300_COLOR_ROUND_NEAREST); - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, cp); } void r300_errata(struct radeon_device *rdev) @@ -375,26 +378,26 @@ void r300_gpu_init(struct radeon_device *rdev) rdev->num_gb_pipes, rdev->num_z_pipes); } -bool r300_gpu_is_lockup(struct radeon_device *rdev) +bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) { u32 rbbm_status; int r; rbbm_status = RREG32(R_000E40_RBBM_STATUS); if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); + r100_gpu_lockup_update(&rdev->config.r300.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(RADEON_CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); + cp->rptr = RREG32(RADEON_CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, cp); } int r300_asic_reset(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 5dbc378d3c2..4c0af4955f0 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -199,6 +199,8 @@ static void r420_clock_resume(struct radeon_device *rdev) static void r420_cp_errata_init(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; + /* RV410 and R420 can lock up if CP DMA to host memory happens * while the 2D engine is busy. * @@ -206,22 +208,24 @@ static void r420_cp_errata_init(struct radeon_device *rdev) * of the CP init, apparently. */ radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch); - radeon_ring_lock(rdev, 8); - radeon_ring_write(rdev, PACKET0(R300_CP_RESYNC_ADDR, 1)); - radeon_ring_write(rdev, rdev->config.r300.resync_scratch); - radeon_ring_write(rdev, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev); + radeon_ring_lock(rdev, cp, 8); + radeon_ring_write(cp, PACKET0(R300_CP_RESYNC_ADDR, 1)); + radeon_ring_write(cp, rdev->config.r300.resync_scratch); + radeon_ring_write(cp, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev, cp); } static void r420_cp_errata_fini(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; + /* Catch the RESYNC we dispatched all the way back, * at the very beginning of the CP init. */ - radeon_ring_lock(rdev, 8); - radeon_ring_write(rdev, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, R300_RB3D_DC_FINISH); - radeon_ring_unlock_commit(rdev); + radeon_ring_lock(rdev, cp, 8); + radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, R300_RB3D_DC_FINISH); + radeon_ring_unlock_commit(rdev, cp); radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index bd2b3d087b1..eaf57cc7582 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1344,7 +1344,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) return 0; } -bool r600_gpu_is_lockup(struct radeon_device *rdev) +bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) { u32 srbm_status; u32 grbm_status; @@ -1361,19 +1361,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) grbm_status = RREG32(R_008010_GRBM_STATUS); grbm_status2 = RREG32(R_008014_GRBM_STATUS2); if (!G_008010_GUI_ACTIVE(grbm_status)) { - 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(R600_CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); + cp->rptr = RREG32(R600_CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, lockup, cp); } int r600_asic_reset(struct radeon_device *rdev) @@ -2144,27 +2144,28 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) int r600_cp_start(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; 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(cp, PACKET3(PACKET3_ME_INITIALIZE, 5)); + radeon_ring_write(cp, 0x1); if (rdev->family >= CHIP_RV770) { - radeon_ring_write(rdev, 0x0); - radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1); + radeon_ring_write(cp, 0x0); + radeon_ring_write(cp, rdev->config.rv770.max_hw_contexts - 1); } else { - radeon_ring_write(rdev, 0x3); - radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1); + radeon_ring_write(cp, 0x3); + radeon_ring_write(cp, rdev->config.r600.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_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(R_0086D8_CP_ME_CNTL, cp_me); @@ -2173,6 +2174,7 @@ int r600_cp_start(struct radeon_device *rdev) int r600_cp_resume(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; u32 tmp; u32 rb_bufsz; int r; @@ -2184,7 +2186,7 @@ int r600_cp_resume(struct radeon_device *rdev) WREG32(GRBM_SOFT_RESET, 0); /* 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; @@ -2198,8 +2200,8 @@ int r600_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 whether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, @@ -2217,42 +2219,42 @@ int r600_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); r600_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; } -void r600_cp_commit(struct radeon_device *rdev) +void r600_cp_commit(struct radeon_device *rdev, struct radeon_cp *cp) { - WREG32(CP_RB_WPTR, rdev->cp.wptr); + WREG32(CP_RB_WPTR, cp->wptr); (void)RREG32(CP_RB_WPTR); } -void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) +void r600_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size) { u32 rb_bufsz; /* Align ring size */ rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; - rdev->cp.ring_size = ring_size; - rdev->cp.align_mask = 16 - 1; + cp->ring_size = ring_size; + cp->align_mask = 16 - 1; } void r600_cp_fini(struct radeon_device *rdev) { r600_cp_stop(rdev); - radeon_ring_fini(rdev); + radeon_ring_fini(rdev, &rdev->cp); } @@ -2271,7 +2273,7 @@ void r600_scratch_init(struct radeon_device *rdev) } } -int r600_ring_test(struct radeon_device *rdev) +int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) { uint32_t scratch; uint32_t tmp = 0; @@ -2284,16 +2286,16 @@ int r600_ring_test(struct radeon_device *rdev) return r; } WREG32(scratch, 0xCAFEDEAD); - r = radeon_ring_lock(rdev, 3); + r = radeon_ring_lock(rdev, cp, 3); if (r) { - DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); + DRM_ERROR("radeon: cp failed to lock ring %p (%d).\n", cp, r); radeon_scratch_free(rdev, scratch); return r; } - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); - radeon_ring_write(rdev, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); + radeon_ring_write(cp, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev, cp); for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(scratch); if (tmp == 0xDEADBEEF) @@ -2301,10 +2303,10 @@ int r600_ring_test(struct radeon_device *rdev) DRM_UDELAY(1); } if (i < rdev->usec_timeout) { - DRM_INFO("ring test succeeded in %d usecs\n", i); + DRM_INFO("ring test on %p succeeded in %d usecs\n", cp, i); } else { - DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n", - scratch, tmp); + DRM_ERROR("radeon: ring %p test failed (scratch(0x%04X)=0x%08X)\n", + cp, scratch, tmp); r = -EINVAL; } radeon_scratch_free(rdev, scratch); @@ -2314,59 +2316,62 @@ int r600_ring_test(struct radeon_device *rdev) void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { + struct radeon_cp *cp = &rdev->cp; + if (rdev->wb.use_event) { u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + (u64)(rdev->fence_drv[fence->ring].scratch_reg - rdev->scratch.reg_base); /* flush read cache over gart */ - radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); - radeon_ring_write(rdev, 0xFFFFFFFF); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 10); /* poll interval */ + radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(cp, PACKET3_TC_ACTION_ENA | + PACKET3_VC_ACTION_ENA | + PACKET3_SH_ACTION_ENA); + radeon_ring_write(cp, 0xFFFFFFFF); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 10); /* poll interval */ /* EVENT_WRITE_EOP - flush caches, send int */ - radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); - radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); - radeon_ring_write(rdev, addr & 0xffffffff); - radeon_ring_write(rdev, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); - radeon_ring_write(rdev, fence->seq); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); + radeon_ring_write(cp, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); + radeon_ring_write(cp, addr & 0xffffffff); + radeon_ring_write(cp, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); + radeon_ring_write(cp, fence->seq); + radeon_ring_write(cp, 0); } else { /* flush read cache over gart */ - radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(rdev, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); - radeon_ring_write(rdev, 0xFFFFFFFF); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 10); /* poll interval */ - radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); - radeon_ring_write(rdev, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); + radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(cp, PACKET3_TC_ACTION_ENA | + PACKET3_VC_ACTION_ENA | + PACKET3_SH_ACTION_ENA); + radeon_ring_write(cp, 0xFFFFFFFF); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 10); /* poll interval */ + radeon_ring_write(cp, PACKET3(PACKET3_EVENT_WRITE, 0)); + radeon_ring_write(cp, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); /* wait for 3D idle clean */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(cp, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); - radeon_ring_write(rdev, fence->seq); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); + radeon_ring_write(cp, fence->seq); /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ - radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); - radeon_ring_write(rdev, RB_INT_STAT); + radeon_ring_write(cp, PACKET0(CP_INT_STATUS, 0)); + radeon_ring_write(cp, RB_INT_STAT); } } void r600_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_cp *cp, struct radeon_semaphore *semaphore, - unsigned ring, bool emit_wait) + bool emit_wait) { uint64_t addr = semaphore->gpu_addr; unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; - radeon_ring_write(rdev, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - radeon_ring_write(rdev, addr & 0xffffffff); - radeon_ring_write(rdev, (upper_32_bits(addr) & 0xff) | sel); + radeon_ring_write(cp, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); + radeon_ring_write(cp, addr & 0xffffffff); + radeon_ring_write(cp, (upper_32_bits(addr) & 0xff) | sel); } int r600_copy_blit(struct radeon_device *rdev, @@ -2421,6 +2426,7 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) int r600_startup(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; /* enable pcie gen2 link */ @@ -2468,7 +2474,7 @@ int r600_startup(struct radeon_device *rdev) } r600_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 = r600_cp_load_microcode(rdev); @@ -2512,7 +2518,7 @@ int r600_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; @@ -2608,7 +2614,7 @@ int r600_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); @@ -2634,7 +2640,7 @@ int r600_init(struct radeon_device *rdev) dev_err(rdev->dev, "IB initialization failed (%d).\n", r); rdev->accel_working = false; } else { - r = r600_ib_test(rdev); + r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); if (r) { dev_err(rdev->dev, "IB test failed (%d).\n", r); rdev->accel_working = false; @@ -2675,18 +2681,20 @@ void r600_fini(struct radeon_device *rdev) */ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { + struct radeon_cp *cp = &rdev->cp; + /* 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); } -int r600_ib_test(struct radeon_device *rdev) +int r600_ib_test(struct radeon_device *rdev, int ring) { struct radeon_ib *ib; uint32_t scratch; @@ -2700,7 +2708,7 @@ int r600_ib_test(struct radeon_device *rdev) return r; } WREG32(scratch, 0xCAFEDEAD); - r = radeon_ib_get(rdev, &ib); + r = radeon_ib_get(rdev, ring, &ib); if (r) { DRM_ERROR("radeon: failed to get ib (%d).\n", r); return r; @@ -2741,7 +2749,7 @@ int r600_ib_test(struct radeon_device *rdev) DRM_UDELAY(1); } if (i < rdev->usec_timeout) { - DRM_INFO("ib test succeeded in %u usecs\n", i); + DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib->fence->ring, i); } else { DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", scratch, tmp); @@ -3514,21 +3522,22 @@ static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; + struct radeon_cp *cp = &rdev->cp; unsigned count, i, j; - radeon_ring_free_size(rdev); - count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw; + radeon_ring_free_size(rdev, cp); + count = (cp->ring_size / 4) - cp->ring_free_dw; seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR)); seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR)); - seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr); - seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr); - seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); + seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", cp->wptr); + seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", cp->rptr); + seq_printf(m, "%u free dwords in ring\n", cp->ring_free_dw); seq_printf(m, "%u dwords in ring\n", count); - i = rdev->cp.rptr; + i = cp->rptr; for (j = 0; j <= count; j++) { - seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); - i = (i + 1) & rdev->cp.ptr_mask; + seq_printf(m, "r[%04d]=0x%08x\n", i, cp->ring[i]); + i = (i + 1) & cp->ptr_mask; } return 0; } diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index e09d2818f94..39ae19d38c2 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -50,6 +50,7 @@ static void set_render_target(struct radeon_device *rdev, int format, int w, int h, u64 gpu_addr) { + struct radeon_cp *cp = &rdev->cp; u32 cb_color_info; int pitch, slice; @@ -63,38 +64,38 @@ set_render_target(struct radeon_device *rdev, int format, pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, gpu_addr >> 8); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, gpu_addr >> 8); if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) { - radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); - radeon_ring_write(rdev, 2 << 0); + radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); + radeon_ring_write(cp, 2 << 0); } - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, (pitch << 0) | (slice << 10)); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, (pitch << 0) | (slice << 10)); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 0); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, cb_color_info); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, cb_color_info); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 0); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 0); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 0); } /* emits 5dw */ @@ -103,6 +104,7 @@ cp_set_surface_sync(struct radeon_device *rdev, u32 sync_type, u32 size, u64 mc_addr) { + struct radeon_cp *cp = &rdev->cp; u32 cp_coher_size; if (size == 0xffffffff) @@ -110,17 +112,18 @@ cp_set_surface_sync(struct radeon_device *rdev, else cp_coher_size = ((size + 255) >> 8); - radeon_ring_write(rdev, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(rdev, sync_type); - radeon_ring_write(rdev, cp_coher_size); - radeon_ring_write(rdev, mc_addr >> 8); - radeon_ring_write(rdev, 10); /* poll interval */ + radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(cp, sync_type); + radeon_ring_write(cp, cp_coher_size); + radeon_ring_write(cp, mc_addr >> 8); + radeon_ring_write(cp, 10); /* poll interval */ } /* emits 21dw + 1 surface sync = 26dw */ static void set_shaders(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; u64 gpu_addr; u32 sq_pgm_resources; @@ -129,35 +132,35 @@ set_shaders(struct radeon_device *rdev) /* VS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, gpu_addr >> 8); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, sq_pgm_resources); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, sq_pgm_resources); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 0); /* PS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, gpu_addr >> 8); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, sq_pgm_resources | (1 << 28)); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, sq_pgm_resources | (1 << 28)); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 2); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 2); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(rdev, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, 0); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(cp, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, 0); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); @@ -167,6 +170,7 @@ set_shaders(struct radeon_device *rdev) static void set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) { + struct radeon_cp *cp = &rdev->cp; u32 sq_vtx_constant_word2; sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) | @@ -175,15 +179,15 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) sq_vtx_constant_word2 |= SQ_VTXC_ENDIAN_SWAP(SQ_ENDIAN_8IN32); #endif - radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); - radeon_ring_write(rdev, 0x460); - radeon_ring_write(rdev, gpu_addr & 0xffffffff); - radeon_ring_write(rdev, 48 - 1); - radeon_ring_write(rdev, sq_vtx_constant_word2); - radeon_ring_write(rdev, 1 << 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30); + radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 7)); + radeon_ring_write(cp, 0x460); + radeon_ring_write(cp, gpu_addr & 0xffffffff); + radeon_ring_write(cp, 48 - 1); + radeon_ring_write(cp, sq_vtx_constant_word2); + radeon_ring_write(cp, 1 << 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, SQ_TEX_VTX_VALID_BUFFER << 30); if ((rdev->family == CHIP_RV610) || (rdev->family == CHIP_RV620) || @@ -203,6 +207,7 @@ set_tex_resource(struct radeon_device *rdev, int format, int w, int h, int pitch, u64 gpu_addr, u32 size) { + struct radeon_cp *cp = &rdev->cp; uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; if (h < 1) @@ -225,15 +230,15 @@ set_tex_resource(struct radeon_device *rdev, cp_set_surface_sync(rdev, PACKET3_TC_ACTION_ENA, size, gpu_addr); - radeon_ring_write(rdev, PACKET3(PACKET3_SET_RESOURCE, 7)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, sq_tex_resource_word0); - radeon_ring_write(rdev, sq_tex_resource_word1); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, gpu_addr >> 8); - radeon_ring_write(rdev, sq_tex_resource_word4); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, SQ_TEX_VTX_VALID_TEXTURE << 30); + radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 7)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, sq_tex_resource_word0); + radeon_ring_write(cp, sq_tex_resource_word1); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(cp, sq_tex_resource_word4); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, SQ_TEX_VTX_VALID_TEXTURE << 30); } /* emits 12 */ @@ -241,43 +246,45 @@ static void set_scissors(struct radeon_device *rdev, int x1, int y1, int x2, int y2) { - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16)); - radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(rdev, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(rdev, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(rdev, (x2 << 0) | (y2 << 16)); + struct radeon_cp *cp = &rdev->cp; + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(cp, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, (x1 << 0) | (y1 << 16)); + radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); + + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(cp, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); + + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(cp, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); } /* emits 10 */ static void draw_auto(struct radeon_device *rdev) { - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(rdev, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(rdev, DI_PT_RECTLIST); + struct radeon_cp *cp = &rdev->cp; + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(cp, DI_PT_RECTLIST); - radeon_ring_write(rdev, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET3(PACKET3_INDEX_TYPE, 0)); + radeon_ring_write(cp, #ifdef __BIG_ENDIAN (2 << 2) | #endif DI_INDEX_SIZE_16_BIT); - radeon_ring_write(rdev, PACKET3(PACKET3_NUM_INSTANCES, 0)); - radeon_ring_write(rdev, 1); + radeon_ring_write(cp, PACKET3(PACKET3_NUM_INSTANCES, 0)); + radeon_ring_write(cp, 1); - radeon_ring_write(rdev, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); - radeon_ring_write(rdev, 3); - radeon_ring_write(rdev, DI_SRC_SEL_AUTO_INDEX); + radeon_ring_write(cp, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); + radeon_ring_write(cp, 3); + radeon_ring_write(cp, DI_SRC_SEL_AUTO_INDEX); } @@ -285,6 +292,7 @@ draw_auto(struct radeon_device *rdev) static void set_default_state(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; @@ -440,24 +448,24 @@ set_default_state(struct radeon_device *rdev) /* emit an IB pointing at default state */ dwords = ALIGN(rdev->r600_blit.state_len, 0x10); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; - 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 (gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF); - radeon_ring_write(rdev, dwords); + radeon_ring_write(cp, upper_32_bits(gpu_addr) & 0xFF); + radeon_ring_write(cp, dwords); /* SQ config */ - radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 6)); - radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(rdev, sq_config); - radeon_ring_write(rdev, sq_gpr_resource_mgmt_1); - radeon_ring_write(rdev, sq_gpr_resource_mgmt_2); - radeon_ring_write(rdev, sq_thread_resource_mgmt); - radeon_ring_write(rdev, sq_stack_resource_mgmt_1); - radeon_ring_write(rdev, sq_stack_resource_mgmt_2); + radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 6)); + radeon_ring_write(cp, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(cp, sq_config); + radeon_ring_write(cp, sq_gpr_resource_mgmt_1); + radeon_ring_write(cp, sq_gpr_resource_mgmt_2); + radeon_ring_write(cp, sq_thread_resource_mgmt); + radeon_ring_write(cp, sq_stack_resource_mgmt_1); + radeon_ring_write(cp, sq_stack_resource_mgmt_2); } static uint32_t i2f(uint32_t input) @@ -614,7 +622,7 @@ void r600_blit_fini(struct radeon_device *rdev) static int r600_vb_ib_get(struct radeon_device *rdev) { int r; - r = radeon_ib_get(rdev, &rdev->r600_blit.vb_ib); + r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->r600_blit.vb_ib); if (r) { DRM_ERROR("failed to get IB for vertex buffer\n"); return r; @@ -679,6 +687,7 @@ static unsigned r600_blit_create_rect(unsigned num_gpu_pages, int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) { + struct radeon_cp *cp = &rdev->cp; int r; int ring_size; int num_loops = 0; @@ -699,7 +708,7 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) /* calculate number of loops correctly */ ring_size = num_loops * dwords_per_loop; ring_size += rdev->r600_blit.ring_size_common; - r = radeon_ring_lock(rdev, ring_size); + r = radeon_ring_lock(rdev, cp, ring_size); if (r) return r; @@ -718,7 +727,7 @@ void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) if (fence) r = radeon_fence_emit(rdev, fence); - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, &rdev->cp); } void r600_kms_blit_copy(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 6d84c64759e..5bf8603f395 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -230,6 +230,8 @@ void radeon_fence_unref(struct radeon_fence **fence); /* * Semaphores. */ +struct radeon_cp; + struct radeon_semaphore_driver { rwlock_t lock; struct list_head free; @@ -585,7 +587,7 @@ struct r600_blit { void r600_blit_suspend(struct radeon_device *rdev); -int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib); +int radeon_ib_get(struct radeon_device *rdev, int ring, struct radeon_ib **ib); void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); int radeon_ib_pool_init(struct radeon_device *rdev); @@ -593,15 +595,15 @@ void radeon_ib_pool_fini(struct radeon_device *rdev); int radeon_ib_test(struct radeon_device *rdev); extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); /* Ring access between begin & end cannot sleep */ -void radeon_ring_free_size(struct radeon_device *rdev); -int radeon_ring_alloc(struct radeon_device *rdev, unsigned ndw); -int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw); -void radeon_ring_commit(struct radeon_device *rdev); -void radeon_ring_unlock_commit(struct radeon_device *rdev); -void radeon_ring_unlock_undo(struct radeon_device *rdev); -int radeon_ring_test(struct radeon_device *rdev); -int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size); -void radeon_ring_fini(struct radeon_device *rdev); +void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp); +int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw); +int radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw); +void radeon_ring_commit(struct radeon_device *rdev, struct radeon_cp *cp); +void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_cp *cp); +void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_cp *cp); +int radeon_ring_test(struct radeon_device *rdev, struct radeon_cp *cp); +int radeon_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size); +void radeon_ring_fini(struct radeon_device *rdev, struct radeon_cp *cp); /* @@ -930,24 +932,25 @@ struct radeon_asic { int (*resume)(struct radeon_device *rdev); int (*suspend)(struct radeon_device *rdev); void (*vga_set_state)(struct radeon_device *rdev, bool state); - bool (*gpu_is_lockup)(struct radeon_device *rdev); + bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_cp *cp); int (*asic_reset)(struct radeon_device *rdev); void (*gart_tlb_flush)(struct radeon_device *rdev); int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr); int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); void (*cp_fini)(struct radeon_device *rdev); void (*cp_disable)(struct radeon_device *rdev); - void (*cp_commit)(struct radeon_device *rdev); + void (*cp_commit)(struct radeon_device *rdev, struct radeon_cp *cp); void (*ring_start)(struct radeon_device *rdev); - int (*ring_test)(struct radeon_device *rdev); + int (*ring_test)(struct radeon_device *rdev, struct radeon_cp *cp); void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); int (*irq_set)(struct radeon_device *rdev); int (*irq_process)(struct radeon_device *rdev); u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); void (*semaphore_ring_emit)(struct radeon_device *rdev, + struct radeon_cp *cp, struct radeon_semaphore *semaphore, - unsigned ring, bool emit_wait); + bool emit_wait); int (*cs_parse)(struct radeon_cs_parser *p); int (*copy_blit)(struct radeon_device *rdev, uint64_t src_offset, @@ -1279,7 +1282,6 @@ struct radeon_device { struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; struct radeon_semaphore_driver semaphore_drv; struct radeon_cp cp; - /* cayman compute rings */ struct radeon_cp cp1; struct radeon_cp cp2; struct radeon_ib_pool ib_pool; @@ -1463,18 +1465,17 @@ void radeon_atombios_fini(struct radeon_device *rdev); /* * RING helpers. */ - #if DRM_DEBUG_CODE == 0 -static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) +static inline void radeon_ring_write(struct radeon_cp *cp, uint32_t v) { - rdev->cp.ring[rdev->cp.wptr++] = v; - rdev->cp.wptr &= rdev->cp.ptr_mask; - rdev->cp.count_dw--; - rdev->cp.ring_free_dw--; + cp->ring[cp->wptr++] = v; + cp->wptr &= cp->ptr_mask; + cp->count_dw--; + cp->ring_free_dw--; } #else /* With debugging this is just too big to inline */ -void radeon_ring_write(struct radeon_device *rdev, uint32_t v); +void radeon_ring_write(struct radeon_cp *cp, uint32_t v); #endif /* @@ -1486,19 +1487,19 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v); #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) -#define radeon_gpu_is_lockup(rdev) (rdev)->asic->gpu_is_lockup((rdev)) +#define radeon_gpu_is_lockup(rdev, cp) (rdev)->asic->gpu_is_lockup((rdev), (cp)) #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p)) -#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) +#define radeon_cp_commit(rdev, cp) (rdev)->asic->cp_commit((rdev), (cp)) #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) -#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev)) +#define radeon_ring_test(rdev, cp) (rdev)->asic->ring_test((rdev), (cp)) #define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib)) #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) #define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) -#define radeon_semaphore_ring_emit(rdev, semaphore, ring, emit_wait) (rdev)->asic->semaphore_ring_emit((rdev), (semaphore), (ring), (emit_wait)) +#define radeon_semaphore_ring_emit(rdev, cp, semaphore, emit_wait) (rdev)->asic->semaphore_ring_emit((rdev), (cp), (semaphore), (emit_wait)) #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) #define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f)) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 6b589d5ae43..4f844755729 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -58,20 +58,21 @@ void r100_fini(struct radeon_device *rdev); int r100_suspend(struct radeon_device *rdev); int r100_resume(struct radeon_device *rdev); void r100_vga_set_state(struct radeon_device *rdev, bool state); -bool r100_gpu_is_lockup(struct radeon_device *rdev); +bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); int r100_asic_reset(struct radeon_device *rdev); u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); void r100_pci_gart_tlb_flush(struct radeon_device *rdev); int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); -void r100_cp_commit(struct radeon_device *rdev); +void r100_cp_commit(struct radeon_device *rdev, struct radeon_cp *cp); void r100_ring_start(struct radeon_device *rdev); int r100_irq_set(struct radeon_device *rdev); int r100_irq_process(struct radeon_device *rdev); void r100_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence); void r100_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_cp *cp, struct radeon_semaphore *semaphore, - unsigned ring, bool emit_wait); + bool emit_wait); int r100_cs_parse(struct radeon_cs_parser *p); void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); @@ -86,7 +87,7 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, void r100_clear_surface_reg(struct radeon_device *rdev, int reg); void r100_bandwidth_update(struct radeon_device *rdev); void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int r100_ring_test(struct radeon_device *rdev); +int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp); void r100_hpd_init(struct radeon_device *rdev); void r100_hpd_fini(struct radeon_device *rdev); bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -157,7 +158,7 @@ extern int r300_init(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev); extern int r300_resume(struct radeon_device *rdev); -extern bool r300_gpu_is_lockup(struct radeon_device *rdev); +extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); extern int r300_asic_reset(struct radeon_device *rdev); extern void r300_ring_start(struct radeon_device *rdev); extern void r300_fence_ring_emit(struct radeon_device *rdev, @@ -296,7 +297,7 @@ int r600_resume(struct radeon_device *rdev); void r600_vga_set_state(struct radeon_device *rdev, bool state); int r600_wb_init(struct radeon_device *rdev); void r600_wb_fini(struct radeon_device *rdev); -void r600_cp_commit(struct radeon_device *rdev); +void r600_cp_commit(struct radeon_device *rdev, struct radeon_cp *cp); void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); uint32_t r600_pciep_rreg(struct radeon_device *rdev, uint32_t reg); void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); @@ -304,17 +305,18 @@ int r600_cs_parse(struct radeon_cs_parser *p); void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence); void r600_semaphore_ring_emit(struct radeon_device *rdev, + struct radeon_cp *cp, struct radeon_semaphore *semaphore, - unsigned ring, bool emit_wait); -bool r600_gpu_is_lockup(struct radeon_device *rdev); + bool emit_wait); +bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); int r600_asic_reset(struct radeon_device *rdev); int r600_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, uint32_t offset, uint32_t obj_size); void r600_clear_surface_reg(struct radeon_device *rdev, int reg); -int r600_ib_test(struct radeon_device *rdev); +int r600_ib_test(struct radeon_device *rdev, int ring); void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int r600_ring_test(struct radeon_device *rdev); +int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp); int r600_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, unsigned num_gpu_pages, struct radeon_fence *fence); @@ -334,7 +336,7 @@ extern int r600_get_pcie_lanes(struct radeon_device *rdev); bool r600_card_posted(struct radeon_device *rdev); void r600_cp_stop(struct radeon_device *rdev); int r600_cp_start(struct radeon_device *rdev); -void r600_ring_init(struct radeon_device *rdev, unsigned ring_size); +void r600_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size); int r600_cp_resume(struct radeon_device *rdev); void r600_cp_fini(struct radeon_device *rdev); int r600_count_pipe_bits(uint32_t val); @@ -403,7 +405,7 @@ int evergreen_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); int evergreen_suspend(struct radeon_device *rdev); int evergreen_resume(struct radeon_device *rdev); -bool evergreen_gpu_is_lockup(struct radeon_device *rdev); +bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); int evergreen_asic_reset(struct radeon_device *rdev); void evergreen_bandwidth_update(struct radeon_device *rdev); void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); @@ -434,7 +436,7 @@ int cayman_init(struct radeon_device *rdev); void cayman_fini(struct radeon_device *rdev); int cayman_suspend(struct radeon_device *rdev); int cayman_resume(struct radeon_device *rdev); -bool cayman_gpu_is_lockup(struct radeon_device *rdev); +bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); int cayman_asic_reset(struct radeon_device *rdev); #endif diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index aaacadc86ae..09ef48636e5 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -246,7 +246,7 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) radeon_mutex_unlock(&rdev->cs_mutex); return r; } - r = radeon_ib_get(rdev, &parser.ib); + r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &parser.ib); if (r) { DRM_ERROR("Failed to get ib !\n"); radeon_cs_parser_fini(&parser, r); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 086b8a39911..9ed0bb100bc 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -269,7 +269,7 @@ retry: * if we experiencing a lockup the value doesn't change */ if (seq == rdev->fence_drv[fence->ring].last_seq && - radeon_gpu_is_lockup(rdev)) { + radeon_gpu_is_lockup(rdev, &rdev->cp)) { /* good news we believe it's a lockup */ printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index aa1ca2dea42..136772ccfe7 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -160,8 +160,8 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, if (rdev->stollen_vga_memory) args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); args->vram_visible -= radeon_fbdev_total_size(rdev); - args->gart_size = rdev->mc.gtt_size - rdev->cp.ring_size - 4096 - - RADEON_IB_POOL_SIZE*64*1024; + args->gart_size = rdev->mc.gtt_size - 4096 - RADEON_IB_POOL_SIZE*64*1024; + args->gart_size -= rdev->cp.ring_size; return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 19ed2c6c424..73b6714d615 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -252,7 +252,8 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) mutex_lock(&rdev->ddev->struct_mutex); mutex_lock(&rdev->vram_mutex); - mutex_lock(&rdev->cp.mutex); + if (rdev->cp.ring_obj) + mutex_lock(&rdev->cp.mutex); /* gui idle int has issues on older chips it seems */ if (rdev->family >= CHIP_R600) { @@ -268,12 +269,13 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) radeon_irq_set(rdev); } } else { - if (rdev->cp.ready) { + struct radeon_cp *cp = &rdev->cp; + if (cp->ready) { struct radeon_fence *fence; - radeon_ring_alloc(rdev, 64); + radeon_ring_alloc(rdev, cp, 64); radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); radeon_fence_emit(rdev, fence); - radeon_ring_commit(rdev); + radeon_ring_commit(rdev, cp); radeon_fence_wait(fence, false); radeon_fence_unref(&fence); } @@ -307,7 +309,8 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - mutex_unlock(&rdev->cp.mutex); + if (rdev->cp.ring_obj) + mutex_unlock(&rdev->cp.mutex); mutex_unlock(&rdev->vram_mutex); mutex_unlock(&rdev->ddev->struct_mutex); } diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index c232317b1dd..bc8a5807f1a 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -60,17 +60,17 @@ u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) return idx_value; } -void radeon_ring_write(struct radeon_device *rdev, uint32_t v) +void radeon_ring_write(struct radeon_cp *cp, uint32_t v) { #if DRM_DEBUG_CODE - if (rdev->cp.count_dw <= 0) { + if (cp->count_dw <= 0) { DRM_ERROR("radeon: writting more dword to ring than expected !\n"); } #endif - rdev->cp.ring[rdev->cp.wptr++] = v; - rdev->cp.wptr &= rdev->cp.ptr_mask; - rdev->cp.count_dw--; - rdev->cp.ring_free_dw--; + cp->ring[cp->wptr++] = v; + cp->wptr &= cp->ptr_mask; + cp->count_dw--; + cp->ring_free_dw--; } void radeon_ib_bogus_cleanup(struct radeon_device *rdev) @@ -106,14 +106,14 @@ void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib) /* * IB. */ -int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib) +int radeon_ib_get(struct radeon_device *rdev, int ring, struct radeon_ib **ib) { struct radeon_fence *fence; struct radeon_ib *nib; int r = 0, i, c; *ib = NULL; - r = radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); + r = radeon_fence_create(rdev, &fence, ring); if (r) { dev_err(rdev->dev, "failed to create fence for new IB\n"); return r; @@ -178,16 +178,17 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) { + struct radeon_cp *cp = &rdev->cp; int r = 0; - if (!ib->length_dw || !rdev->cp.ready) { + if (!ib->length_dw || !cp->ready) { /* TODO: Nothings in the ib we should report. */ DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); return -EINVAL; } /* 64 dwords should be enough for fence too */ - r = radeon_ring_lock(rdev, 64); + r = radeon_ring_lock(rdev, cp, 64); if (r) { DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); return r; @@ -198,7 +199,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) /* once scheduled IB is considered free and protected by the fence */ ib->free = true; mutex_unlock(&rdev->ib_pool.mutex); - radeon_ring_unlock_commit(rdev); + radeon_ring_unlock_commit(rdev, cp); return 0; } @@ -283,7 +284,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) /* * Ring. */ -void radeon_ring_free_size(struct radeon_device *rdev) +void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp) { if (rdev->wb.enabled) rdev->cp.rptr = le32_to_cpu(rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4]); @@ -294,122 +295,123 @@ void radeon_ring_free_size(struct radeon_device *rdev) rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); } /* This works because ring_size is a power of 2 */ - rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); - rdev->cp.ring_free_dw -= rdev->cp.wptr; - rdev->cp.ring_free_dw &= rdev->cp.ptr_mask; - if (!rdev->cp.ring_free_dw) { - rdev->cp.ring_free_dw = rdev->cp.ring_size / 4; + cp->ring_free_dw = (cp->rptr + (cp->ring_size / 4)); + cp->ring_free_dw -= cp->wptr; + cp->ring_free_dw &= cp->ptr_mask; + if (!cp->ring_free_dw) { + cp->ring_free_dw = cp->ring_size / 4; } } -int radeon_ring_alloc(struct radeon_device *rdev, unsigned ndw) + +int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw) { int r; /* Align requested size with padding so unlock_commit can * pad safely */ - ndw = (ndw + rdev->cp.align_mask) & ~rdev->cp.align_mask; - while (ndw > (rdev->cp.ring_free_dw - 1)) { - radeon_ring_free_size(rdev); - if (ndw < rdev->cp.ring_free_dw) { + ndw = (ndw + cp->align_mask) & ~cp->align_mask; + while (ndw > (cp->ring_free_dw - 1)) { + radeon_ring_free_size(rdev, cp); + if (ndw < cp->ring_free_dw) { break; } r = radeon_fence_wait_next(rdev, RADEON_RING_TYPE_GFX_INDEX); if (r) return r; } - rdev->cp.count_dw = ndw; - rdev->cp.wptr_old = rdev->cp.wptr; + cp->count_dw = ndw; + cp->wptr_old = cp->wptr; return 0; } -int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw) +int radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw) { int r; - mutex_lock(&rdev->cp.mutex); - r = radeon_ring_alloc(rdev, ndw); + mutex_lock(&cp->mutex); + r = radeon_ring_alloc(rdev, cp, ndw); if (r) { - mutex_unlock(&rdev->cp.mutex); + mutex_unlock(&cp->mutex); return r; } return 0; } -void radeon_ring_commit(struct radeon_device *rdev) +void radeon_ring_commit(struct radeon_device *rdev, struct radeon_cp *cp) { unsigned count_dw_pad; unsigned i; /* We pad to match fetch size */ - count_dw_pad = (rdev->cp.align_mask + 1) - - (rdev->cp.wptr & rdev->cp.align_mask); + count_dw_pad = (cp->align_mask + 1) - + (cp->wptr & cp->align_mask); for (i = 0; i < count_dw_pad; i++) { - radeon_ring_write(rdev, 2 << 30); + radeon_ring_write(cp, 2 << 30); } DRM_MEMORYBARRIER(); - radeon_cp_commit(rdev); + radeon_cp_commit(rdev, cp); } -void radeon_ring_unlock_commit(struct radeon_device *rdev) +void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_cp *cp) { - radeon_ring_commit(rdev); - mutex_unlock(&rdev->cp.mutex); + radeon_ring_commit(rdev, cp); + mutex_unlock(&cp->mutex); } -void radeon_ring_unlock_undo(struct radeon_device *rdev) +void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_cp *cp) { - rdev->cp.wptr = rdev->cp.wptr_old; - mutex_unlock(&rdev->cp.mutex); + cp->wptr = cp->wptr_old; + mutex_unlock(&cp->mutex); } -int radeon_ring_init(struct radeon_device *rdev, unsigned ring_size) +int radeon_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size) { int r; - rdev->cp.ring_size = ring_size; + cp->ring_size = ring_size; /* Allocate ring buffer */ - if (rdev->cp.ring_obj == NULL) { - r = radeon_bo_create(rdev, rdev->cp.ring_size, PAGE_SIZE, true, + if (cp->ring_obj == NULL) { + r = radeon_bo_create(rdev, cp->ring_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, - &rdev->cp.ring_obj); + &cp->ring_obj); if (r) { dev_err(rdev->dev, "(%d) ring create failed\n", r); return r; } - r = radeon_bo_reserve(rdev->cp.ring_obj, false); + r = radeon_bo_reserve(cp->ring_obj, false); if (unlikely(r != 0)) return r; - r = radeon_bo_pin(rdev->cp.ring_obj, RADEON_GEM_DOMAIN_GTT, - &rdev->cp.gpu_addr); + r = radeon_bo_pin(cp->ring_obj, RADEON_GEM_DOMAIN_GTT, + &cp->gpu_addr); if (r) { - radeon_bo_unreserve(rdev->cp.ring_obj); + radeon_bo_unreserve(cp->ring_obj); dev_err(rdev->dev, "(%d) ring pin failed\n", r); return r; } - r = radeon_bo_kmap(rdev->cp.ring_obj, - (void **)&rdev->cp.ring); - radeon_bo_unreserve(rdev->cp.ring_obj); + r = radeon_bo_kmap(cp->ring_obj, + (void **)&cp->ring); + radeon_bo_unreserve(cp->ring_obj); if (r) { dev_err(rdev->dev, "(%d) ring map failed\n", r); return r; } } - rdev->cp.ptr_mask = (rdev->cp.ring_size / 4) - 1; - rdev->cp.ring_free_dw = rdev->cp.ring_size / 4; + cp->ptr_mask = (cp->ring_size / 4) - 1; + cp->ring_free_dw = cp->ring_size / 4; return 0; } -void radeon_ring_fini(struct radeon_device *rdev) +void radeon_ring_fini(struct radeon_device *rdev, struct radeon_cp *cp) { int r; struct radeon_bo *ring_obj; - mutex_lock(&rdev->cp.mutex); - ring_obj = rdev->cp.ring_obj; - rdev->cp.ring = NULL; - rdev->cp.ring_obj = NULL; - mutex_unlock(&rdev->cp.mutex); + mutex_lock(&cp->mutex); + ring_obj = cp->ring_obj; + cp->ring = NULL; + cp->ring_obj = NULL; + mutex_unlock(&cp->mutex); if (ring_obj) { r = radeon_bo_reserve(ring_obj, false); @@ -422,7 +424,6 @@ void radeon_ring_fini(struct radeon_device *rdev) } } - /* * Debugfs info */ diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index f7d3104de6d..064694a6782 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c @@ -121,13 +121,13 @@ int radeon_semaphore_create(struct radeon_device *rdev, void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore) { - radeon_semaphore_ring_emit(rdev, semaphore, ring, false); + radeon_semaphore_ring_emit(rdev, &rdev->cp, semaphore, false); } void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore) { - radeon_semaphore_ring_emit(rdev, semaphore, ring, true); + radeon_semaphore_ring_emit(rdev, &rdev->cp, semaphore, true); } void radeon_semaphore_free(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 37f7acb6d5f..ee6c160ffae 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -42,7 +42,8 @@ void radeon_test_moves(struct radeon_device *rdev) /* Number of tests = * (Total GTT - IB pool - writeback page - ring buffers) / test size */ - n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024 - rdev->cp.ring_size; + n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024; + n -= rdev->cp.ring_size; if (rdev->wb.wb_obj) n -= RADEON_GPU_PAGE_SIZE; if (rdev->ih.ring_obj) diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index fd8da02e1ca..8fe13ba8143 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -55,44 +55,45 @@ void rv515_debugfs(struct radeon_device *rdev) void rv515_ring_start(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; - r = radeon_ring_lock(rdev, 64); + r = radeon_ring_lock(rdev, cp, 64); if (r) { return; } - radeon_ring_write(rdev, PACKET0(ISYNC_CNTL, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(ISYNC_CNTL, 0)); + radeon_ring_write(cp, ISYNC_ANY2D_IDLE3D | ISYNC_ANY3D_IDLE2D | ISYNC_WAIT_IDLEGUI | ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_write(rdev, PACKET0(WAIT_UNTIL, 0)); - radeon_ring_write(rdev, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); - radeon_ring_write(rdev, PACKET0(R300_DST_PIPE_CONFIG, 0)); - radeon_ring_write(rdev, R300_PIPE_AUTO_CONFIG); - radeon_ring_write(rdev, PACKET0(GB_SELECT, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(GB_ENABLE, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(R500_SU_REG_DEST, 0)); - radeon_ring_write(rdev, (1 << rdev->num_gb_pipes) - 1); - radeon_ring_write(rdev, PACKET0(VAP_INDEX_OFFSET, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, RB3D_DC_FLUSH | RB3D_DC_FREE); - radeon_ring_write(rdev, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, ZC_FLUSH | ZC_FREE); - radeon_ring_write(rdev, PACKET0(WAIT_UNTIL, 0)); - radeon_ring_write(rdev, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); - radeon_ring_write(rdev, PACKET0(GB_AA_CONFIG, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_write(rdev, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, RB3D_DC_FLUSH | RB3D_DC_FREE); - radeon_ring_write(rdev, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(rdev, ZC_FLUSH | ZC_FREE); - radeon_ring_write(rdev, PACKET0(GB_MSPOS0, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(WAIT_UNTIL, 0)); + radeon_ring_write(cp, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); + radeon_ring_write(cp, PACKET0(R300_DST_PIPE_CONFIG, 0)); + radeon_ring_write(cp, R300_PIPE_AUTO_CONFIG); + radeon_ring_write(cp, PACKET0(GB_SELECT, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(GB_ENABLE, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(R500_SU_REG_DEST, 0)); + radeon_ring_write(cp, (1 << rdev->num_gb_pipes) - 1); + radeon_ring_write(cp, PACKET0(VAP_INDEX_OFFSET, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, RB3D_DC_FLUSH | RB3D_DC_FREE); + radeon_ring_write(cp, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, ZC_FLUSH | ZC_FREE); + radeon_ring_write(cp, PACKET0(WAIT_UNTIL, 0)); + radeon_ring_write(cp, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); + radeon_ring_write(cp, PACKET0(GB_AA_CONFIG, 0)); + radeon_ring_write(cp, 0); + radeon_ring_write(cp, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, RB3D_DC_FLUSH | RB3D_DC_FREE); + radeon_ring_write(cp, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(cp, ZC_FLUSH | ZC_FREE); + radeon_ring_write(cp, PACKET0(GB_MSPOS0, 0)); + radeon_ring_write(cp, ((6 << MS_X0_SHIFT) | (6 << MS_Y0_SHIFT) | (6 << MS_X1_SHIFT) | @@ -101,8 +102,8 @@ void rv515_ring_start(struct radeon_device *rdev) (6 << MS_Y2_SHIFT) | (6 << MSBD0_Y_SHIFT) | (6 << MSBD0_X_SHIFT))); - radeon_ring_write(rdev, PACKET0(GB_MSPOS1, 0)); - radeon_ring_write(rdev, + radeon_ring_write(cp, PACKET0(GB_MSPOS1, 0)); + radeon_ring_write(cp, ((6 << MS_X3_SHIFT) | (6 << MS_Y3_SHIFT) | (6 << MS_X4_SHIFT) | @@ -110,15 +111,15 @@ void rv515_ring_start(struct radeon_device *rdev) (6 << MS_X5_SHIFT) | (6 << MS_Y5_SHIFT) | (6 << MSBD1_SHIFT))); - radeon_ring_write(rdev, PACKET0(GA_ENHANCE, 0)); - radeon_ring_write(rdev, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); - radeon_ring_write(rdev, PACKET0(GA_POLY_MODE, 0)); - radeon_ring_write(rdev, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); - radeon_ring_write(rdev, PACKET0(GA_ROUND_MODE, 0)); - radeon_ring_write(rdev, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); - radeon_ring_write(rdev, PACKET0(0x20C8, 0)); - radeon_ring_write(rdev, 0); - radeon_ring_unlock_commit(rdev); + radeon_ring_write(cp, PACKET0(GA_ENHANCE, 0)); + radeon_ring_write(cp, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); + radeon_ring_write(cp, PACKET0(GA_POLY_MODE, 0)); + radeon_ring_write(cp, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); + radeon_ring_write(cp, PACKET0(GA_ROUND_MODE, 0)); + radeon_ring_write(cp, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); + radeon_ring_write(cp, PACKET0(0x20C8, 0)); + radeon_ring_write(cp, 0); + radeon_ring_unlock_commit(rdev, cp); } int rv515_mc_wait_for_idle(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index be02bee4121..0d0d811fc80 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -357,7 +357,7 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) void r700_cp_fini(struct radeon_device *rdev) { r700_cp_stop(rdev); - radeon_ring_fini(rdev); + radeon_ring_fini(rdev, &rdev->cp); } /* @@ -1043,6 +1043,7 @@ int rv770_mc_init(struct radeon_device *rdev) static int rv770_startup(struct radeon_device *rdev) { + struct radeon_cp *cp = &rdev->cp; int r; /* enable pcie gen2 link */ @@ -1091,7 +1092,7 @@ static int rv770_startup(struct radeon_device *rdev) } r600_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 = rv770_cp_load_microcode(rdev); @@ -1121,7 +1122,7 @@ int rv770_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; @@ -1216,7 +1217,7 @@ int rv770_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); @@ -1242,7 +1243,7 @@ int rv770_init(struct radeon_device *rdev) dev_err(rdev->dev, "IB initialization failed (%d).\n", r); rdev->accel_working = false; } else { - r = r600_ib_test(rdev); + r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); if (r) { dev_err(rdev->dev, "IB test failed (%d).\n", r); rdev->accel_working = false; -- cgit v1.2.3-70-g09d2 From bf85279958da96cb4b11aac89b34f0424c3c120e Mon Sep 17 00:00:00 2001 From: Christian König 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 +++++++------- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 16 +++++++-------- drivers/gpu/drm/radeon/ni.c | 30 ++++++++++++++--------------- drivers/gpu/drm/radeon/r100.c | 18 ++++++++--------- drivers/gpu/drm/radeon/r200.c | 2 +- drivers/gpu/drm/radeon/r300.c | 4 ++-- drivers/gpu/drm/radeon/r420.c | 4 ++-- drivers/gpu/drm/radeon/r600.c | 30 ++++++++++++++--------------- drivers/gpu/drm/radeon/r600_blit_kms.c | 20 +++++++++---------- drivers/gpu/drm/radeon/radeon.h | 6 +++--- drivers/gpu/drm/radeon/radeon_device.c | 3 ++- drivers/gpu/drm/radeon/radeon_fence.c | 4 ++-- drivers/gpu/drm/radeon/radeon_gem.c | 4 +++- drivers/gpu/drm/radeon/radeon_pm.c | 16 +++++++++------ drivers/gpu/drm/radeon/radeon_ring.c | 19 ++++++++++++++++-- drivers/gpu/drm/radeon/radeon_semaphore.c | 4 ++-- drivers/gpu/drm/radeon/radeon_test.c | 3 ++- drivers/gpu/drm/radeon/radeon_ttm.c | 6 +++--- drivers/gpu/drm/radeon/rv515.c | 2 +- drivers/gpu/drm/radeon/rv770.c | 10 +++++----- 20 files changed, 119 insertions(+), 96 deletions(-) (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d1264a7154a..cb198aca9f5 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); diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 75d0a6f0a39..56f5d92cce2 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -49,7 +49,7 @@ static void set_render_target(struct radeon_device *rdev, int format, int w, int h, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 cb_color_info; int pitch, slice; @@ -88,7 +88,7 @@ cp_set_surface_sync(struct radeon_device *rdev, u32 sync_type, u32 size, u64 mc_addr) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 cp_coher_size; if (size == 0xffffffff) @@ -116,7 +116,7 @@ cp_set_surface_sync(struct radeon_device *rdev, static void set_shaders(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u64 gpu_addr; /* VS */ @@ -144,7 +144,7 @@ set_shaders(struct radeon_device *rdev) static void set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_vtx_constant_word2, sq_vtx_constant_word3; /* high addr, stride */ @@ -189,7 +189,7 @@ set_tex_resource(struct radeon_device *rdev, int format, int w, int h, int pitch, u64 gpu_addr, u32 size) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_tex_resource_word0, sq_tex_resource_word1; u32 sq_tex_resource_word4, sq_tex_resource_word7; @@ -230,7 +230,7 @@ static void set_scissors(struct radeon_device *rdev, int x1, int y1, int x2, int y2) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; /* workaround some hw bugs */ if (x2 == 0) x1 = 1; @@ -261,7 +261,7 @@ set_scissors(struct radeon_device *rdev, int x1, int y1, static void draw_auto(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_START) >> 2); radeon_ring_write(cp, DI_PT_RECTLIST); @@ -286,7 +286,7 @@ draw_auto(struct radeon_device *rdev) static void set_default_state(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2, sq_gpr_resource_mgmt_3; u32 sq_thread_resource_mgmt, sq_thread_resource_mgmt_2; u32 sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2, sq_stack_resource_mgmt_3; diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index cc9aaeb104f..2d809e62c4c 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1049,7 +1049,7 @@ static int cayman_cp_load_microcode(struct radeon_device *rdev) static int cayman_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; r = radeon_ring_lock(rdev, cp, 7); @@ -1116,7 +1116,7 @@ static int cayman_cp_start(struct radeon_device *rdev) static void cayman_cp_fini(struct radeon_device *rdev) { cayman_cp_enable(rdev, false); - radeon_ring_fini(rdev, &rdev->cp); + radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); } int cayman_cp_resume(struct radeon_device *rdev) @@ -1147,7 +1147,7 @@ int cayman_cp_resume(struct radeon_device *rdev) /* ring 0 - compute and gfx */ /* Set ring buffer size */ - cp = &rdev->cp; + cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; rb_bufsz = drm_order(cp->ring_size / 8); tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; #ifdef __BIG_ENDIAN @@ -1181,7 +1181,7 @@ int cayman_cp_resume(struct radeon_device *rdev) /* ring1 - compute only */ /* Set ring buffer size */ - cp = &rdev->cp1; + cp = &rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX]; rb_bufsz = drm_order(cp->ring_size / 8); tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; #ifdef __BIG_ENDIAN @@ -1207,7 +1207,7 @@ int cayman_cp_resume(struct radeon_device *rdev) /* ring2 - compute only */ /* Set ring buffer size */ - cp = &rdev->cp2; + cp = &rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX]; rb_bufsz = drm_order(cp->ring_size / 8); tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; #ifdef __BIG_ENDIAN @@ -1233,15 +1233,15 @@ int cayman_cp_resume(struct radeon_device *rdev) /* start the rings */ cayman_cp_start(rdev); - rdev->cp.ready = true; - rdev->cp1.ready = true; - rdev->cp2.ready = true; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = true; + rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX].ready = true; + rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX].ready = true; /* this only test cp0 */ - r = radeon_ring_test(rdev, &rdev->cp); + r = radeon_ring_test(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); if (r) { - rdev->cp.ready = false; - rdev->cp1.ready = false; - rdev->cp2.ready = false; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; + rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; return r; } @@ -1343,7 +1343,7 @@ int cayman_asic_reset(struct radeon_device *rdev) static int cayman_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 */ @@ -1438,7 +1438,7 @@ int cayman_suspend(struct radeon_device *rdev) { /* FIXME: we should wait for ring to be empty */ cayman_cp_enable(rdev, false); - rdev->cp.ready = false; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); cayman_pcie_gart_disable(rdev); @@ -1455,7 +1455,7 @@ int cayman_suspend(struct radeon_device *rdev) */ int cayman_init(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; int r; /* This don't do much */ diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 6c328115e66..6ca20d7bf62 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -811,7 +811,7 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) void r100_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[fence->ring]; /* We have to make sure that caches are flushed before * CPU might read something from VRAM. */ @@ -849,7 +849,7 @@ int r100_copy_blit(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; uint32_t cur_pages; uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; uint32_t pitch; @@ -934,7 +934,7 @@ static int r100_cp_wait_for_idle(struct radeon_device *rdev) void r100_ring_start(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; int r; r = radeon_ring_lock(rdev, cp, 2); @@ -1048,7 +1048,7 @@ static void r100_cp_load_microcode(struct radeon_device *rdev) int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; unsigned rb_bufsz; unsigned rb_blksz; unsigned max_fetch; @@ -1162,7 +1162,7 @@ void r100_cp_fini(struct radeon_device *rdev) } /* Disable ring */ r100_cp_disable(rdev); - radeon_ring_fini(rdev, &rdev->cp); + radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); DRM_INFO("radeon: cp finalized\n"); } @@ -1170,7 +1170,7 @@ void r100_cp_disable(struct radeon_device *rdev) { /* Disable ring */ radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - rdev->cp.ready = false; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; WREG32(RADEON_CP_CSQ_MODE, 0); WREG32(RADEON_CP_CSQ_CNTL, 0); WREG32(R_000770_SCRATCH_UMSK, 0); @@ -2587,7 +2587,7 @@ static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; uint32_t rdp, wdp; unsigned count, i, j; @@ -3686,7 +3686,7 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; radeon_ring_write(cp, PACKET0(RADEON_CP_IB_BASE, 1)); radeon_ring_write(cp, ib->gpu_addr); @@ -3778,7 +3778,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) /* Shutdown CP we shouldn't need to do that but better be safe than * sorry */ - rdev->cp.ready = false; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; WREG32(R_000740_CP_CSQ_CNTL, 0); /* Save few CRTC registers */ diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index d84e633f72f..d59c727a8e0 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -87,7 +87,7 @@ int r200_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; uint32_t size; uint32_t cur_size; int i, num_loops; diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index cbb62fc3f2e..66ff35f394c 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -175,7 +175,7 @@ void rv370_pcie_gart_fini(struct radeon_device *rdev) void r300_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[fence->ring]; /* Who ever call radeon_fence_emit should call ring_lock and ask * for enough space (today caller are ib schedule and buffer move) */ @@ -208,7 +208,7 @@ void r300_fence_ring_emit(struct radeon_device *rdev, void r300_ring_start(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; unsigned gb_tile_config; int r; diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 4c0af4955f0..62e86043699 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -199,7 +199,7 @@ static void r420_clock_resume(struct radeon_device *rdev) static void r420_cp_errata_init(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; /* RV410 and R420 can lock up if CP DMA to host memory happens * while the 2D engine is busy. @@ -217,7 +217,7 @@ static void r420_cp_errata_init(struct radeon_device *rdev) static void r420_cp_errata_fini(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; /* Catch the RESYNC we dispatched all the way back, * at the very beginning of the CP init. diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 59975317674..aaf8cd42943 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2144,7 +2144,7 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) int r600_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; uint32_t cp_me; @@ -2174,7 +2174,7 @@ int r600_cp_start(struct radeon_device *rdev) int r600_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; @@ -2248,7 +2248,7 @@ void r600_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned r void r600_cp_fini(struct radeon_device *rdev) { r600_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->cp); + radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); } @@ -2271,7 +2271,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) { uint32_t scratch; uint32_t tmp = 0; - unsigned i; + unsigned i, ridx = radeon_ring_index(rdev, cp); int r; r = radeon_scratch_get(rdev, &scratch); @@ -2282,7 +2282,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) WREG32(scratch, 0xCAFEDEAD); r = radeon_ring_lock(rdev, cp, 3); if (r) { - DRM_ERROR("radeon: cp failed to lock ring %p (%d).\n", cp, r); + DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r); radeon_scratch_free(rdev, scratch); return r; } @@ -2297,10 +2297,10 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) DRM_UDELAY(1); } if (i < rdev->usec_timeout) { - DRM_INFO("ring test on %p succeeded in %d usecs\n", cp, i); + DRM_INFO("ring test on %d succeeded in %d usecs\n", ridx, i); } else { - DRM_ERROR("radeon: ring %p test failed (scratch(0x%04X)=0x%08X)\n", - cp, scratch, tmp); + DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n", + ridx, scratch, tmp); r = -EINVAL; } radeon_scratch_free(rdev, scratch); @@ -2310,7 +2310,7 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[fence->ring]; if (rdev->wb.use_event) { u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + @@ -2420,7 +2420,7 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) int r600_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 */ @@ -2534,7 +2534,7 @@ int r600_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ r600_cp_stop(rdev); - rdev->cp.ready = false; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); radeon_wb_disable(rdev); r600_pcie_gart_disable(rdev); @@ -2609,8 +2609,8 @@ int r600_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); @@ -2677,7 +2677,7 @@ void r600_fini(struct radeon_device *rdev) */ void r600_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]; /* FIXME: implement */ radeon_ring_write(cp, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); @@ -3518,7 +3518,7 @@ static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; unsigned count, i, j; radeon_ring_free_size(rdev, cp); diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 39ae19d38c2..62dd1c281c7 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -50,7 +50,7 @@ static void set_render_target(struct radeon_device *rdev, int format, int w, int h, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 cb_color_info; int pitch, slice; @@ -104,7 +104,7 @@ cp_set_surface_sync(struct radeon_device *rdev, u32 sync_type, u32 size, u64 mc_addr) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 cp_coher_size; if (size == 0xffffffff) @@ -123,7 +123,7 @@ cp_set_surface_sync(struct radeon_device *rdev, static void set_shaders(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u64 gpu_addr; u32 sq_pgm_resources; @@ -170,7 +170,7 @@ set_shaders(struct radeon_device *rdev) static void set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_vtx_constant_word2; sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) | @@ -207,7 +207,7 @@ set_tex_resource(struct radeon_device *rdev, int format, int w, int h, int pitch, u64 gpu_addr, u32 size) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; if (h < 1) @@ -246,7 +246,7 @@ static void set_scissors(struct radeon_device *rdev, int x1, int y1, int x2, int y2) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); radeon_ring_write(cp, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); radeon_ring_write(cp, (x1 << 0) | (y1 << 16)); @@ -267,7 +267,7 @@ set_scissors(struct radeon_device *rdev, int x1, int y1, static void draw_auto(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); radeon_ring_write(cp, DI_PT_RECTLIST); @@ -292,7 +292,7 @@ draw_auto(struct radeon_device *rdev) static void set_default_state(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; @@ -687,7 +687,7 @@ static unsigned r600_blit_create_rect(unsigned num_gpu_pages, int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; int r; int ring_size; int num_loops = 0; @@ -727,7 +727,7 @@ void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) if (fence) r = radeon_fence_emit(rdev, fence); - radeon_ring_unlock_commit(rdev, &rdev->cp); + radeon_ring_unlock_commit(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); } void r600_kms_blit_copy(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index bbe88ec3951..76c58e9e477 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -547,6 +547,7 @@ struct r600_ih { struct radeon_bo *ring_obj; volatile uint32_t *ring; unsigned rptr; + unsigned rptr_offs; unsigned wptr; unsigned wptr_old; unsigned ring_size; @@ -598,6 +599,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev); int radeon_ib_test(struct radeon_device *rdev); extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); /* Ring access between begin & end cannot sleep */ +int radeon_ring_index(struct radeon_device *rdev, struct radeon_cp *cp); void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp); int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw); int radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw); @@ -1284,9 +1286,7 @@ struct radeon_device { rwlock_t fence_lock; struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; struct radeon_semaphore_driver semaphore_drv; - struct radeon_cp cp; - struct radeon_cp cp1; - struct radeon_cp cp2; + struct radeon_cp cp[RADEON_NUM_RINGS]; struct radeon_ib_pool ib_pool; struct radeon_irq irq; struct radeon_asic *asic; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 36296ad397a..023c156eddd 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -718,7 +718,8 @@ int radeon_device_init(struct radeon_device *rdev, * can recall function without having locking issues */ radeon_mutex_init(&rdev->cs_mutex); mutex_init(&rdev->ib_pool.mutex); - mutex_init(&rdev->cp.mutex); + for (i = 0; i < RADEON_NUM_RINGS; ++i) + mutex_init(&rdev->cp[i].mutex); mutex_init(&rdev->dc_hw_i2c_mutex); if (rdev->family >= CHIP_R600) spin_lock_init(&rdev->ih.lock); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 9ed0bb100bc..86f4eeaeba6 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -84,7 +84,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) return 0; } fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq); - if (!rdev->cp.ready) + if (!rdev->cp[fence->ring].ready) /* FIXME: cp is not running assume everythings is done right * away */ @@ -269,7 +269,7 @@ retry: * if we experiencing a lockup the value doesn't change */ if (seq == rdev->fence_drv[fence->ring].last_seq && - radeon_gpu_is_lockup(rdev, &rdev->cp)) { + radeon_gpu_is_lockup(rdev, &rdev->cp[fence->ring])) { /* good news we believe it's a lockup */ printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 136772ccfe7..1ce8fa71cf7 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -152,6 +152,7 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_info *args = data; struct ttm_mem_type_manager *man; + unsigned i; man = &rdev->mman.bdev.man[TTM_PL_VRAM]; @@ -161,7 +162,8 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, args->vram_visible -= radeon_bo_size(rdev->stollen_vga_memory); args->vram_visible -= radeon_fbdev_total_size(rdev); args->gart_size = rdev->mc.gtt_size - 4096 - RADEON_IB_POOL_SIZE*64*1024; - args->gart_size -= rdev->cp.ring_size; + for(i = 0; i < RADEON_NUM_RINGS; ++i) + args->gart_size -= rdev->cp[i].ring_size; return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 73b6714d615..50b632ac823 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -252,8 +252,10 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) mutex_lock(&rdev->ddev->struct_mutex); mutex_lock(&rdev->vram_mutex); - if (rdev->cp.ring_obj) - mutex_lock(&rdev->cp.mutex); + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + if (rdev->cp[i].ring_obj) + mutex_lock(&rdev->cp[i].mutex); + } /* gui idle int has issues on older chips it seems */ if (rdev->family >= CHIP_R600) { @@ -269,11 +271,11 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) radeon_irq_set(rdev); } } else { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; if (cp->ready) { struct radeon_fence *fence; radeon_ring_alloc(rdev, cp, 64); - radeon_fence_create(rdev, &fence, RADEON_RING_TYPE_GFX_INDEX); + radeon_fence_create(rdev, &fence, radeon_ring_index(rdev, cp)); radeon_fence_emit(rdev, fence); radeon_ring_commit(rdev, cp); radeon_fence_wait(fence, false); @@ -309,8 +311,10 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - if (rdev->cp.ring_obj) - mutex_unlock(&rdev->cp.mutex); + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + if (rdev->cp[i].ring_obj) + mutex_unlock(&rdev->cp[i].mutex); + } mutex_unlock(&rdev->vram_mutex); mutex_unlock(&rdev->ddev->struct_mutex); } diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 209834dbf18..d96b13af5e9 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -178,7 +178,7 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[ib->fence->ring]; int r = 0; if (!ib->length_dw || !cp->ready) { @@ -284,6 +284,21 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) /* * Ring. */ +int radeon_ring_index(struct radeon_device *rdev, struct radeon_cp *cp) +{ + /* r1xx-r5xx only has CP ring */ + if (rdev->family < CHIP_R600) + return RADEON_RING_TYPE_GFX_INDEX; + + if (rdev->family >= CHIP_CAYMAN) { + if (cp == &rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX]) + return CAYMAN_RING_TYPE_CP1_INDEX; + else if (cp == &rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX]) + return CAYMAN_RING_TYPE_CP2_INDEX; + } + return RADEON_RING_TYPE_GFX_INDEX; +} + void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp) { if (rdev->wb.enabled) @@ -312,7 +327,7 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned if (ndw < cp->ring_free_dw) { break; } - r = radeon_fence_wait_next(rdev, RADEON_RING_TYPE_GFX_INDEX); + r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, cp)); if (r) return r; } diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 064694a6782..bf4789eed0b 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c @@ -121,13 +121,13 @@ int radeon_semaphore_create(struct radeon_device *rdev, void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore) { - radeon_semaphore_ring_emit(rdev, &rdev->cp, semaphore, false); + radeon_semaphore_ring_emit(rdev, &rdev->cp[ring], semaphore, false); } void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore) { - radeon_semaphore_ring_emit(rdev, &rdev->cp, semaphore, true); + radeon_semaphore_ring_emit(rdev, &rdev->cp[ring], semaphore, true); } void radeon_semaphore_free(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index ee6c160ffae..160e7df7755 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -43,7 +43,8 @@ void radeon_test_moves(struct radeon_device *rdev) * (Total GTT - IB pool - writeback page - ring buffers) / test size */ n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024; - n -= rdev->cp.ring_size; + for (i = 0; i < RADEON_NUM_RINGS; ++i) + n -= rdev->cp[i].ring_size; if (rdev->wb.wb_obj) n -= RADEON_GPU_PAGE_SIZE; if (rdev->ih.ring_obj) diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 112ecaa6362..0be15bf38d3 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -188,7 +188,7 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, rbo = container_of(bo, struct radeon_bo, tbo); switch (bo->mem.mem_type) { case TTM_PL_VRAM: - if (rbo->rdev->cp.ready == false) + if (rbo->rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready == false) radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); else radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); @@ -255,7 +255,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); return -EINVAL; } - if (!rdev->cp.ready) { + if (!rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready) { DRM_ERROR("Trying to move memory with CP turned off.\n"); return -EINVAL; } @@ -380,7 +380,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, radeon_move_null(bo, new_mem); return 0; } - if (!rdev->cp.ready || rdev->asic->copy == NULL) { + if (!rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready || rdev->asic->copy == NULL) { /* use memcpy */ goto memcpy; } diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 8fe13ba8143..8a935987d02 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -55,7 +55,7 @@ void rv515_debugfs(struct radeon_device *rdev) void rv515_ring_start(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp; + struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; int r; r = radeon_ring_lock(rdev, cp, 64); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index a2c60598d0f..9e4c0418f54 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -357,7 +357,7 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) void r700_cp_fini(struct radeon_device *rdev) { r700_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->cp); + radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); } /* @@ -1043,7 +1043,7 @@ int rv770_mc_init(struct radeon_device *rdev) static int rv770_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 */ @@ -1144,7 +1144,7 @@ int rv770_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; + rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); radeon_wb_disable(rdev); rv770_pcie_gart_disable(rdev); @@ -1217,8 +1217,8 @@ int rv770_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.3-70-g09d2 From e32eb50dbe43862606a51caa94368ec6bd019434 Mon Sep 17 00:00:00 2001 From: Christian König 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 +++++++------- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 250 ++++++++++++++-------------- drivers/gpu/drm/radeon/ni.c | 146 ++++++++-------- drivers/gpu/drm/radeon/r100.c | 162 +++++++++--------- drivers/gpu/drm/radeon/r200.c | 22 +-- drivers/gpu/drm/radeon/r300.c | 128 +++++++------- drivers/gpu/drm/radeon/r420.c | 22 +-- drivers/gpu/drm/radeon/r600.c | 188 ++++++++++----------- drivers/gpu/drm/radeon/r600_blit_kms.c | 228 ++++++++++++------------- drivers/gpu/drm/radeon/radeon.h | 50 +++--- drivers/gpu/drm/radeon/radeon_asic.h | 24 +-- drivers/gpu/drm/radeon/radeon_device.c | 2 +- drivers/gpu/drm/radeon/radeon_fence.c | 4 +- drivers/gpu/drm/radeon/radeon_gem.c | 2 +- drivers/gpu/drm/radeon/radeon_pm.c | 18 +- drivers/gpu/drm/radeon/radeon_ring.c | 136 +++++++-------- drivers/gpu/drm/radeon/radeon_semaphore.c | 4 +- drivers/gpu/drm/radeon/radeon_test.c | 42 ++--- drivers/gpu/drm/radeon/radeon_ttm.c | 6 +- drivers/gpu/drm/radeon/rv515.c | 82 ++++----- drivers/gpu/drm/radeon/rv770.c | 12 +- 21 files changed, 826 insertions(+), 826 deletions(-) (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index cb198aca9f5..b19ace86121 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); diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 56f5d92cce2..2379849515c 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -49,7 +49,7 @@ static void set_render_target(struct radeon_device *rdev, int format, int w, int h, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 cb_color_info; int pitch, slice; @@ -63,23 +63,23 @@ set_render_target(struct radeon_device *rdev, int format, pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 15)); - radeon_ring_write(cp, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, pitch); - radeon_ring_write(cp, slice); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, cb_color_info); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, (w - 1) | ((h - 1) << 16)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 15)); + radeon_ring_write(ring, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, pitch); + radeon_ring_write(ring, slice); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, cb_color_info); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, (w - 1) | ((h - 1) << 16)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); } /* emits 5dw */ @@ -88,7 +88,7 @@ cp_set_surface_sync(struct radeon_device *rdev, u32 sync_type, u32 size, u64 mc_addr) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 cp_coher_size; if (size == 0xffffffff) @@ -101,40 +101,40 @@ cp_set_surface_sync(struct radeon_device *rdev, * to the RB directly. For IBs, the CP programs this as part of the * surface_sync packet. */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(cp, 0); /* CP_COHER_CNTL2 */ + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (0x85e8 - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, 0); /* CP_COHER_CNTL2 */ } - radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(cp, sync_type); - radeon_ring_write(cp, cp_coher_size); - radeon_ring_write(cp, mc_addr >> 8); - radeon_ring_write(cp, 10); /* poll interval */ + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(ring, sync_type); + radeon_ring_write(ring, cp_coher_size); + radeon_ring_write(ring, mc_addr >> 8); + radeon_ring_write(ring, 10); /* poll interval */ } /* emits 11dw + 1 surface sync = 16dw */ static void set_shaders(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]; u64 gpu_addr; /* VS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 3)); - radeon_ring_write(cp, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 3)); + radeon_ring_write(ring, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, 2); + radeon_ring_write(ring, 0); /* PS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 4)); - radeon_ring_write(cp, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, 1); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 2); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 4)); + radeon_ring_write(ring, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, 1); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 2); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); @@ -144,7 +144,7 @@ set_shaders(struct radeon_device *rdev) static void set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_vtx_constant_word2, sq_vtx_constant_word3; /* high addr, stride */ @@ -159,16 +159,16 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) SQ_VTCX_SEL_Z(SQ_SEL_Z) | SQ_VTCX_SEL_W(SQ_SEL_W); - radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 8)); - radeon_ring_write(cp, 0x580); - radeon_ring_write(cp, gpu_addr & 0xffffffff); - radeon_ring_write(cp, 48 - 1); /* size */ - radeon_ring_write(cp, sq_vtx_constant_word2); - radeon_ring_write(cp, sq_vtx_constant_word3); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_BUFFER)); + radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 8)); + radeon_ring_write(ring, 0x580); + radeon_ring_write(ring, gpu_addr & 0xffffffff); + radeon_ring_write(ring, 48 - 1); /* size */ + radeon_ring_write(ring, sq_vtx_constant_word2); + radeon_ring_write(ring, sq_vtx_constant_word3); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, S__SQ_CONSTANT_TYPE(SQ_TEX_VTX_VALID_BUFFER)); if ((rdev->family == CHIP_CEDAR) || (rdev->family == CHIP_PALM) || @@ -189,7 +189,7 @@ set_tex_resource(struct radeon_device *rdev, int format, int w, int h, int pitch, u64 gpu_addr, u32 size) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_tex_resource_word0, sq_tex_resource_word1; u32 sq_tex_resource_word4, sq_tex_resource_word7; @@ -213,16 +213,16 @@ set_tex_resource(struct radeon_device *rdev, cp_set_surface_sync(rdev, PACKET3_TC_ACTION_ENA, size, gpu_addr); - radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 8)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, sq_tex_resource_word0); - radeon_ring_write(cp, sq_tex_resource_word1); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, sq_tex_resource_word4); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, sq_tex_resource_word7); + radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 8)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, sq_tex_resource_word0); + radeon_ring_write(ring, sq_tex_resource_word1); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, sq_tex_resource_word4); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, sq_tex_resource_word7); } /* emits 12 */ @@ -230,7 +230,7 @@ static void set_scissors(struct radeon_device *rdev, int x1, int y1, int x2, int y2) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; /* workaround some hw bugs */ if (x2 == 0) x1 = 1; @@ -241,44 +241,44 @@ set_scissors(struct radeon_device *rdev, int x1, int y1, x2 = 2; } - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(cp, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(cp, (x1 << 0) | (y1 << 16)); - radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(ring, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(ring, (x1 << 0) | (y1 << 16)); + radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(cp, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(ring, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(cp, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); - radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(ring, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2); + radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); } /* emits 10 */ static void draw_auto(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(cp, DI_PT_RECTLIST); + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, DI_PT_RECTLIST); - radeon_ring_write(cp, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET3(PACKET3_INDEX_TYPE, 0)); + radeon_ring_write(ring, #ifdef __BIG_ENDIAN (2 << 2) | #endif DI_INDEX_SIZE_16_BIT); - radeon_ring_write(cp, PACKET3(PACKET3_NUM_INSTANCES, 0)); - radeon_ring_write(cp, 1); + radeon_ring_write(ring, PACKET3(PACKET3_NUM_INSTANCES, 0)); + radeon_ring_write(ring, 1); - radeon_ring_write(cp, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); - radeon_ring_write(cp, 3); - radeon_ring_write(cp, DI_SRC_SEL_AUTO_INDEX); + radeon_ring_write(ring, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); + radeon_ring_write(ring, 3); + radeon_ring_write(ring, DI_SRC_SEL_AUTO_INDEX); } @@ -286,7 +286,7 @@ draw_auto(struct radeon_device *rdev) static void set_default_state(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 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2, sq_gpr_resource_mgmt_3; u32 sq_thread_resource_mgmt, sq_thread_resource_mgmt_2; u32 sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2, sq_stack_resource_mgmt_3; @@ -300,8 +300,8 @@ set_default_state(struct radeon_device *rdev) int dwords; /* 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); if (rdev->family < CHIP_CAYMAN) { switch (rdev->family) { @@ -558,60 +558,60 @@ set_default_state(struct radeon_device *rdev) NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); /* disable dyn gprs */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, 0); /* setup LDS */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, (SQ_LDS_RESOURCE_MGMT - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(cp, 0x10001000); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (SQ_LDS_RESOURCE_MGMT - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, 0x10001000); /* SQ config */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 11)); - radeon_ring_write(cp, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); - radeon_ring_write(cp, sq_config); - radeon_ring_write(cp, sq_gpr_resource_mgmt_1); - radeon_ring_write(cp, sq_gpr_resource_mgmt_2); - radeon_ring_write(cp, sq_gpr_resource_mgmt_3); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, sq_thread_resource_mgmt); - radeon_ring_write(cp, sq_thread_resource_mgmt_2); - radeon_ring_write(cp, sq_stack_resource_mgmt_1); - radeon_ring_write(cp, sq_stack_resource_mgmt_2); - radeon_ring_write(cp, sq_stack_resource_mgmt_3); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 11)); + radeon_ring_write(ring, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, sq_config); + radeon_ring_write(ring, sq_gpr_resource_mgmt_1); + radeon_ring_write(ring, sq_gpr_resource_mgmt_2); + radeon_ring_write(ring, sq_gpr_resource_mgmt_3); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, sq_thread_resource_mgmt); + radeon_ring_write(ring, sq_thread_resource_mgmt_2); + radeon_ring_write(ring, sq_stack_resource_mgmt_1); + radeon_ring_write(ring, sq_stack_resource_mgmt_2); + radeon_ring_write(ring, sq_stack_resource_mgmt_3); } /* CONTEXT_CONTROL */ - radeon_ring_write(cp, 0xc0012800); - radeon_ring_write(cp, 0x80000000); - radeon_ring_write(cp, 0x80000000); + radeon_ring_write(ring, 0xc0012800); + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); /* 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); /* SET_SAMPLER */ - radeon_ring_write(cp, 0xc0036e00); - radeon_ring_write(cp, 0x00000000); - radeon_ring_write(cp, 0x00000012); - radeon_ring_write(cp, 0x00000000); - radeon_ring_write(cp, 0x00000000); + radeon_ring_write(ring, 0xc0036e00); + radeon_ring_write(ring, 0x00000000); + radeon_ring_write(ring, 0x00000012); + radeon_ring_write(ring, 0x00000000); + radeon_ring_write(ring, 0x00000000); /* 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); /* emit an IB pointing at default state */ dwords = ALIGN(rdev->r600_blit.state_len, 0x10); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; - radeon_ring_write(cp, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); - radeon_ring_write(cp, gpu_addr & 0xFFFFFFFC); - radeon_ring_write(cp, upper_32_bits(gpu_addr) & 0xFF); - radeon_ring_write(cp, dwords); + radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); + radeon_ring_write(ring, gpu_addr & 0xFFFFFFFC); + radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xFF); + radeon_ring_write(ring, dwords); } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 7c953579a40..022a606c783 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1049,64 +1049,64 @@ static int cayman_cp_load_microcode(struct radeon_device *rdev) static int cayman_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; - 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.cayman.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.cayman.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); cayman_cp_enable(rdev, true); - r = radeon_ring_lock(rdev, cp, cayman_default_size + 19); + r = radeon_ring_lock(rdev, ring, cayman_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 < cayman_default_size; i++) - radeon_ring_write(cp, cayman_default_state[i]); + radeon_ring_write(ring, cayman_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); /* XXX init other rings */ @@ -1116,12 +1116,12 @@ static int cayman_cp_start(struct radeon_device *rdev) static void cayman_cp_fini(struct radeon_device *rdev) { cayman_cp_enable(rdev, false); - radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); } int cayman_cp_resume(struct radeon_device *rdev) { - struct radeon_cp *cp; + struct radeon_ring *ring; u32 tmp; u32 rb_bufsz; int r; @@ -1147,8 +1147,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* ring 0 - compute and gfx */ /* Set ring buffer size */ - cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; - rb_bufsz = drm_order(cp->ring_size / 8); + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + 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; @@ -1157,8 +1157,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); - cp->wptr = 0; - WREG32(CP_RB0_WPTR, cp->wptr); + ring->wptr = 0; + WREG32(CP_RB0_WPTR, ring->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1175,14 +1175,14 @@ int cayman_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB0_CNTL, tmp); - WREG32(CP_RB0_BASE, cp->gpu_addr >> 8); + WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); - cp->rptr = RREG32(CP_RB0_RPTR); + ring->rptr = RREG32(CP_RB0_RPTR); /* ring1 - compute only */ /* Set ring buffer size */ - cp = &rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX]; - rb_bufsz = drm_order(cp->ring_size / 8); + ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; + 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; @@ -1191,8 +1191,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); - cp->wptr = 0; - WREG32(CP_RB1_WPTR, cp->wptr); + ring->wptr = 0; + WREG32(CP_RB1_WPTR, ring->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1201,14 +1201,14 @@ int cayman_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB1_CNTL, tmp); - WREG32(CP_RB1_BASE, cp->gpu_addr >> 8); + WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); - cp->rptr = RREG32(CP_RB1_RPTR); + ring->rptr = RREG32(CP_RB1_RPTR); /* ring2 - compute only */ /* Set ring buffer size */ - cp = &rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX]; - rb_bufsz = drm_order(cp->ring_size / 8); + ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; + 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; @@ -1217,8 +1217,8 @@ int cayman_cp_resume(struct radeon_device *rdev) /* Initialize the ring buffer's read and write pointers */ WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); - cp->wptr = 0; - WREG32(CP_RB2_WPTR, cp->wptr); + ring->wptr = 0; + WREG32(CP_RB2_WPTR, ring->wptr); /* set the wb address wether it's enabled or not */ WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); @@ -1227,28 +1227,28 @@ int cayman_cp_resume(struct radeon_device *rdev) mdelay(1); WREG32(CP_RB2_CNTL, tmp); - WREG32(CP_RB2_BASE, cp->gpu_addr >> 8); + WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); - cp->rptr = RREG32(CP_RB2_RPTR); + ring->rptr = RREG32(CP_RB2_RPTR); /* start the rings */ cayman_cp_start(rdev); - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = true; - rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; + rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; + rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; /* this only test cp0 */ - r = radeon_ring_test(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); + r = radeon_ring_test(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); if (r) { - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; - rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; - rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; + rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; return r; } return 0; } -bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) +bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { u32 srbm_status; u32 grbm_status; @@ -1261,20 +1261,20 @@ bool cayman_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); } /* XXX deal with CP0,1,2 */ - cp->rptr = RREG32(cp->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, lockup, cp); + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); } static int cayman_gpu_soft_reset(struct radeon_device *rdev) @@ -1343,7 +1343,7 @@ int cayman_asic_reset(struct radeon_device *rdev) static int cayman_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 */ @@ -1393,7 +1393,7 @@ static int cayman_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, CP_RB0_RPTR, CP_RB0_WPTR); if (r) return r; @@ -1438,7 +1438,7 @@ int cayman_suspend(struct radeon_device *rdev) { /* FIXME: we should wait for ring to be empty */ cayman_cp_enable(rdev, false); - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); cayman_pcie_gart_disable(rdev); @@ -1455,7 +1455,7 @@ int cayman_suspend(struct radeon_device *rdev) */ int cayman_init(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; /* This don't do much */ @@ -1508,8 +1508,8 @@ int cayman_init(struct radeon_device *rdev) if (r) return r; - cp->ring_obj = NULL; - r600_ring_init(rdev, cp, 1024 * 1024); + ring->ring_obj = NULL; + r600_ring_init(rdev, ring, 1024 * 1024); rdev->ih.ring_obj = NULL; r600_ih_ring_init(rdev, 64 * 1024); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 6ca20d7bf62..a40e893a7b6 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -811,31 +811,31 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) void r100_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp[fence->ring]; + struct radeon_ring *ring = &rdev->ring[fence->ring]; /* We have to make sure that caches are flushed before * CPU might read something from VRAM. */ - radeon_ring_write(cp, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, RADEON_RB3D_DC_FLUSH_ALL); - radeon_ring_write(cp, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, RADEON_RB3D_ZC_FLUSH_ALL); + radeon_ring_write(ring, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, RADEON_RB3D_DC_FLUSH_ALL); + radeon_ring_write(ring, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, RADEON_RB3D_ZC_FLUSH_ALL); /* Wait until IDLE & CLEAN */ - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(cp, rdev->config.r100.hdp_cntl | + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); + radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(ring, rdev->config.r100.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE); - radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(cp, rdev->config.r100.hdp_cntl); + radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(ring, rdev->config.r100.hdp_cntl); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(cp, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); - radeon_ring_write(cp, fence->seq); - radeon_ring_write(cp, PACKET0(RADEON_GEN_INT_STATUS, 0)); - radeon_ring_write(cp, RADEON_SW_INT_FIRE); + radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); + radeon_ring_write(ring, fence->seq); + radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0)); + radeon_ring_write(ring, RADEON_SW_INT_FIRE); } void r100_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_cp *cp, + struct radeon_ring *ring, struct radeon_semaphore *semaphore, bool emit_wait) { @@ -849,7 +849,7 @@ int r100_copy_blit(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; uint32_t cur_pages; uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; uint32_t pitch; @@ -867,7 +867,7 @@ int r100_copy_blit(struct radeon_device *rdev, /* Ask for enough room for blit + flush + fence */ ndw = 64 + (10 * num_loops); - r = radeon_ring_lock(rdev, cp, ndw); + r = radeon_ring_lock(rdev, ring, ndw); if (r) { DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); return -EINVAL; @@ -881,8 +881,8 @@ int r100_copy_blit(struct radeon_device *rdev, /* pages are in Y direction - height page width in X direction - width */ - radeon_ring_write(cp, PACKET3(PACKET3_BITBLT_MULTI, 8)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET3(PACKET3_BITBLT_MULTI, 8)); + radeon_ring_write(ring, RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_SRC_CLIPPING | @@ -894,26 +894,26 @@ int r100_copy_blit(struct radeon_device *rdev, RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); - radeon_ring_write(cp, (pitch << 22) | (src_offset >> 10)); - radeon_ring_write(cp, (pitch << 22) | (dst_offset >> 10)); - radeon_ring_write(cp, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, (0x1fff) | (0x1fff << 16)); - radeon_ring_write(cp, num_gpu_pages); - radeon_ring_write(cp, num_gpu_pages); - radeon_ring_write(cp, cur_pages | (stride_pixels << 16)); - } - radeon_ring_write(cp, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, RADEON_RB2D_DC_FLUSH_ALL); - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, (pitch << 22) | (src_offset >> 10)); + radeon_ring_write(ring, (pitch << 22) | (dst_offset >> 10)); + radeon_ring_write(ring, (0x1fff) | (0x1fff << 16)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, (0x1fff) | (0x1fff << 16)); + radeon_ring_write(ring, num_gpu_pages); + radeon_ring_write(ring, num_gpu_pages); + radeon_ring_write(ring, cur_pages | (stride_pixels << 16)); + } + radeon_ring_write(ring, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, RADEON_RB2D_DC_FLUSH_ALL); + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_HOST_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); if (fence) { r = radeon_fence_emit(rdev, fence); } - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_unlock_commit(rdev, ring); return r; } @@ -934,20 +934,20 @@ static int r100_cp_wait_for_idle(struct radeon_device *rdev) void r100_ring_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; - r = radeon_ring_lock(rdev, cp, 2); + r = radeon_ring_lock(rdev, ring, 2); if (r) { return; } - radeon_ring_write(cp, PACKET0(RADEON_ISYNC_CNTL, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(RADEON_ISYNC_CNTL, 0)); + radeon_ring_write(ring, RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_unlock_commit(rdev, ring); } @@ -1048,7 +1048,7 @@ static void r100_cp_load_microcode(struct radeon_device *rdev) int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; unsigned rb_bufsz; unsigned rb_blksz; unsigned max_fetch; @@ -1074,7 +1074,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; r100_cp_load_microcode(rdev); - r = radeon_ring_init(rdev, cp, ring_size, RADEON_WB_CP_RPTR_OFFSET, + r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR); if (r) { return r; @@ -1084,7 +1084,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) rb_blksz = 9; /* cp will read 128bytes at a time (4 dwords) */ max_fetch = 1; - cp->align_mask = 16 - 1; + ring->align_mask = 16 - 1; /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ pre_write_timer = 64; /* Force CP_RB_WPTR write if written more than one time before the @@ -1114,13 +1114,13 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_NO_UPDATE); /* Set ring address */ - DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)cp->gpu_addr); - WREG32(RADEON_CP_RB_BASE, cp->gpu_addr); + DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)ring->gpu_addr); + WREG32(RADEON_CP_RB_BASE, ring->gpu_addr); /* Force read & write ptr to 0 */ WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); WREG32(RADEON_CP_RB_RPTR_WR, 0); - cp->wptr = 0; - WREG32(RADEON_CP_RB_WPTR, cp->wptr); + ring->wptr = 0; + WREG32(RADEON_CP_RB_WPTR, ring->wptr); /* set the wb address whether it's enabled or not */ WREG32(R_00070C_CP_RB_RPTR_ADDR, @@ -1136,7 +1136,7 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_RB_CNTL, tmp); udelay(10); - cp->rptr = RREG32(RADEON_CP_RB_RPTR); + ring->rptr = RREG32(RADEON_CP_RB_RPTR); /* Set cp mode to bus mastering & enable cp*/ WREG32(RADEON_CP_CSQ_MODE, REG_SET(RADEON_INDIRECT2_START, indirect2_start) | @@ -1145,12 +1145,12 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); radeon_ring_start(rdev); - r = radeon_ring_test(rdev, cp); + r = radeon_ring_test(rdev, ring); if (r) { DRM_ERROR("radeon: cp isn't working (%d).\n", r); return r; } - cp->ready = true; + ring->ready = true; radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); return 0; } @@ -1162,7 +1162,7 @@ void r100_cp_fini(struct radeon_device *rdev) } /* Disable ring */ r100_cp_disable(rdev); - radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); DRM_INFO("radeon: cp finalized\n"); } @@ -1170,7 +1170,7 @@ void r100_cp_disable(struct radeon_device *rdev) { /* Disable ring */ radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; WREG32(RADEON_CP_CSQ_MODE, 0); WREG32(RADEON_CP_CSQ_CNTL, 0); WREG32(R_000770_SCRATCH_UMSK, 0); @@ -2107,9 +2107,9 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev) return -1; } -void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp) +void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring *ring) { - lockup->last_cp_rptr = cp->rptr; + lockup->last_cp_rptr = ring->rptr; lockup->last_jiffies = jiffies; } @@ -2134,20 +2134,20 @@ void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp * false positive when CP is just gived nothing to do. * **/ -bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp) +bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_ring *ring) { unsigned long cjiffies, elapsed; cjiffies = jiffies; if (!time_after(cjiffies, lockup->last_jiffies)) { /* likely a wrap around */ - lockup->last_cp_rptr = cp->rptr; + lockup->last_cp_rptr = ring->rptr; lockup->last_jiffies = jiffies; return false; } - if (cp->rptr != lockup->last_cp_rptr) { + if (ring->rptr != lockup->last_cp_rptr) { /* CP is still working no lockup */ - lockup->last_cp_rptr = cp->rptr; + lockup->last_cp_rptr = ring->rptr; lockup->last_jiffies = jiffies; return false; } @@ -2160,26 +2160,26 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l return false; } -bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) +bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { u32 rbbm_status; int r; rbbm_status = RREG32(R_000E40_RBBM_STATUS); if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - r100_gpu_lockup_update(&rdev->config.r100.lockup, cp); + r100_gpu_lockup_update(&rdev->config.r100.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->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, cp); + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, ring); } void r100_bm_disable(struct radeon_device *rdev) @@ -2587,22 +2587,22 @@ static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; uint32_t rdp, wdp; unsigned count, i, j; - radeon_ring_free_size(rdev, cp); + radeon_ring_free_size(rdev, ring); rdp = RREG32(RADEON_CP_RB_RPTR); wdp = RREG32(RADEON_CP_RB_WPTR); - count = (rdp + cp->ring_size - wdp) & cp->ptr_mask; + count = (rdp + ring->ring_size - wdp) & ring->ptr_mask; seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); - seq_printf(m, "%u free dwords in ring\n", cp->ring_free_dw); + seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); seq_printf(m, "%u dwords in ring\n", count); for (j = 0; j <= count; j++) { - i = (rdp + j) & cp->ptr_mask; - seq_printf(m, "r[%04d]=0x%08x\n", i, cp->ring[i]); + i = (rdp + j) & ring->ptr_mask; + seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); } return 0; } @@ -3644,7 +3644,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track } } -int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) +int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) { uint32_t scratch; uint32_t tmp = 0; @@ -3657,15 +3657,15 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) return r; } WREG32(scratch, 0xCAFEDEAD); - r = radeon_ring_lock(rdev, cp, 2); + r = radeon_ring_lock(rdev, ring, 2); if (r) { DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); radeon_scratch_free(rdev, scratch); return r; } - radeon_ring_write(cp, PACKET0(scratch, 0)); - radeon_ring_write(cp, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_write(ring, PACKET0(scratch, 0)); + radeon_ring_write(ring, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev, ring); for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(scratch); if (tmp == 0xDEADBEEF) { @@ -3686,11 +3686,11 @@ int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(cp, PACKET0(RADEON_CP_IB_BASE, 1)); - radeon_ring_write(cp, ib->gpu_addr); - radeon_ring_write(cp, ib->length_dw); + radeon_ring_write(ring, PACKET0(RADEON_CP_IB_BASE, 1)); + radeon_ring_write(ring, ib->gpu_addr); + radeon_ring_write(ring, ib->length_dw); } int r100_ib_test(struct radeon_device *rdev) @@ -3778,7 +3778,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) /* Shutdown CP we shouldn't need to do that but better be safe than * sorry */ - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; WREG32(R_000740_CP_CSQ_CNTL, 0); /* Save few CRTC registers */ diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index d59c727a8e0..eba4cbfa78f 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -87,7 +87,7 @@ int r200_copy_dma(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; uint32_t size; uint32_t cur_size; int i, num_loops; @@ -96,33 +96,33 @@ int r200_copy_dma(struct radeon_device *rdev, /* radeon pitch is /64 */ size = num_gpu_pages << RADEON_GPU_PAGE_SHIFT; num_loops = DIV_ROUND_UP(size, 0x1FFFFF); - r = radeon_ring_lock(rdev, cp, num_loops * 4 + 64); + r = radeon_ring_lock(rdev, ring, num_loops * 4 + 64); if (r) { DRM_ERROR("radeon: moving bo (%d).\n", r); return r; } /* Must wait for 2D idle & clean before DMA or hangs might happen */ - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, (1 << 16)); + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, (1 << 16)); for (i = 0; i < num_loops; i++) { cur_size = size; if (cur_size > 0x1FFFFF) { cur_size = 0x1FFFFF; } size -= cur_size; - radeon_ring_write(cp, PACKET0(0x720, 2)); - radeon_ring_write(cp, src_offset); - radeon_ring_write(cp, dst_offset); - radeon_ring_write(cp, cur_size | (1 << 31) | (1 << 30)); + radeon_ring_write(ring, PACKET0(0x720, 2)); + radeon_ring_write(ring, src_offset); + radeon_ring_write(ring, dst_offset); + radeon_ring_write(ring, cur_size | (1 << 31) | (1 << 30)); src_offset += cur_size; dst_offset += cur_size; } - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, RADEON_WAIT_DMA_GUI_IDLE); + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, RADEON_WAIT_DMA_GUI_IDLE); if (fence) { r = radeon_fence_emit(rdev, fence); } - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_unlock_commit(rdev, ring); return r; } diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 66ff35f394c..6a96b31b558 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -175,40 +175,40 @@ void rv370_pcie_gart_fini(struct radeon_device *rdev) void r300_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp[fence->ring]; + struct radeon_ring *ring = &rdev->ring[fence->ring]; /* Who ever call radeon_fence_emit should call ring_lock and ask * for enough space (today caller are ib schedule and buffer move) */ /* Write SC register so SC & US assert idle */ - radeon_ring_write(cp, PACKET0(R300_RE_SCISSORS_TL, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(R300_RE_SCISSORS_BR, 0)); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET0(R300_RE_SCISSORS_TL, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(R300_RE_SCISSORS_BR, 0)); + radeon_ring_write(ring, 0); /* Flush 3D cache */ - radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_RB3D_DC_FLUSH); - radeon_ring_write(cp, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_ZC_FLUSH); + radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_RB3D_DC_FLUSH); + radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_ZC_FLUSH); /* Wait until IDLE & CLEAN */ - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, (RADEON_WAIT_3D_IDLECLEAN | + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, (RADEON_WAIT_3D_IDLECLEAN | RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE)); - radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(cp, rdev->config.r300.hdp_cntl | + radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(ring, rdev->config.r300.hdp_cntl | RADEON_HDP_READ_BUFFER_INVALIDATE); - radeon_ring_write(cp, PACKET0(RADEON_HOST_PATH_CNTL, 0)); - radeon_ring_write(cp, rdev->config.r300.hdp_cntl); + radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); + radeon_ring_write(ring, rdev->config.r300.hdp_cntl); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(cp, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); - radeon_ring_write(cp, fence->seq); - radeon_ring_write(cp, PACKET0(RADEON_GEN_INT_STATUS, 0)); - radeon_ring_write(cp, RADEON_SW_INT_FIRE); + radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); + radeon_ring_write(ring, fence->seq); + radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0)); + radeon_ring_write(ring, RADEON_SW_INT_FIRE); } void r300_ring_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]; unsigned gb_tile_config; int r; @@ -230,44 +230,44 @@ void r300_ring_start(struct radeon_device *rdev) break; } - r = radeon_ring_lock(rdev, cp, 64); + r = radeon_ring_lock(rdev, ring, 64); if (r) { return; } - radeon_ring_write(cp, PACKET0(RADEON_ISYNC_CNTL, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(RADEON_ISYNC_CNTL, 0)); + radeon_ring_write(ring, RADEON_ISYNC_ANY2D_IDLE3D | RADEON_ISYNC_ANY3D_IDLE2D | RADEON_ISYNC_WAIT_IDLEGUI | RADEON_ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_write(cp, PACKET0(R300_GB_TILE_CONFIG, 0)); - radeon_ring_write(cp, gb_tile_config); - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(R300_GB_TILE_CONFIG, 0)); + radeon_ring_write(ring, gb_tile_config); + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(cp, PACKET0(R300_DST_PIPE_CONFIG, 0)); - radeon_ring_write(cp, R300_PIPE_AUTO_CONFIG); - radeon_ring_write(cp, PACKET0(R300_GB_SELECT, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(R300_GB_ENABLE, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); - radeon_ring_write(cp, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_ZC_FLUSH | R300_ZC_FREE); - radeon_ring_write(cp, PACKET0(RADEON_WAIT_UNTIL, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); + radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); + radeon_ring_write(ring, PACKET0(R300_GB_SELECT, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(R300_GB_ENABLE, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); + radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_ZC_FLUSH | R300_ZC_FREE); + radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); + radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); - radeon_ring_write(cp, PACKET0(R300_GB_AA_CONFIG, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); - radeon_ring_write(cp, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_ZC_FLUSH | R300_ZC_FREE); - radeon_ring_write(cp, PACKET0(R300_GB_MSPOS0, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(R300_GB_AA_CONFIG, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_RB3D_DC_FLUSH | R300_RB3D_DC_FREE); + radeon_ring_write(ring, PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_ZC_FLUSH | R300_ZC_FREE); + radeon_ring_write(ring, PACKET0(R300_GB_MSPOS0, 0)); + radeon_ring_write(ring, ((6 << R300_MS_X0_SHIFT) | (6 << R300_MS_Y0_SHIFT) | (6 << R300_MS_X1_SHIFT) | @@ -276,8 +276,8 @@ void r300_ring_start(struct radeon_device *rdev) (6 << R300_MS_Y2_SHIFT) | (6 << R300_MSBD0_Y_SHIFT) | (6 << R300_MSBD0_X_SHIFT))); - radeon_ring_write(cp, PACKET0(R300_GB_MSPOS1, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(R300_GB_MSPOS1, 0)); + radeon_ring_write(ring, ((6 << R300_MS_X3_SHIFT) | (6 << R300_MS_Y3_SHIFT) | (6 << R300_MS_X4_SHIFT) | @@ -285,16 +285,16 @@ void r300_ring_start(struct radeon_device *rdev) (6 << R300_MS_X5_SHIFT) | (6 << R300_MS_Y5_SHIFT) | (6 << R300_MSBD1_SHIFT))); - radeon_ring_write(cp, PACKET0(R300_GA_ENHANCE, 0)); - radeon_ring_write(cp, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); - radeon_ring_write(cp, PACKET0(R300_GA_POLY_MODE, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(R300_GA_ENHANCE, 0)); + radeon_ring_write(ring, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL); + radeon_ring_write(ring, PACKET0(R300_GA_POLY_MODE, 0)); + radeon_ring_write(ring, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE); - radeon_ring_write(cp, PACKET0(R300_GA_ROUND_MODE, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(R300_GA_ROUND_MODE, 0)); + radeon_ring_write(ring, R300_GEOMETRY_ROUND_NEAREST | R300_COLOR_ROUND_NEAREST); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_unlock_commit(rdev, ring); } void r300_errata(struct radeon_device *rdev) @@ -378,26 +378,26 @@ void r300_gpu_init(struct radeon_device *rdev) rdev->num_gb_pipes, rdev->num_z_pipes); } -bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) +bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { u32 rbbm_status; int r; rbbm_status = RREG32(R_000E40_RBBM_STATUS); if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - r100_gpu_lockup_update(&rdev->config.r300.lockup, cp); + r100_gpu_lockup_update(&rdev->config.r300.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(RADEON_CP_RB_RPTR); - return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, cp); + ring->rptr = RREG32(RADEON_CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, ring); } int r300_asic_reset(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 62e86043699..1d3231f3a09 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -199,7 +199,7 @@ static void r420_clock_resume(struct radeon_device *rdev) static void r420_cp_errata_init(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]; /* RV410 and R420 can lock up if CP DMA to host memory happens * while the 2D engine is busy. @@ -208,24 +208,24 @@ static void r420_cp_errata_init(struct radeon_device *rdev) * of the CP init, apparently. */ radeon_scratch_get(rdev, &rdev->config.r300.resync_scratch); - radeon_ring_lock(rdev, cp, 8); - radeon_ring_write(cp, PACKET0(R300_CP_RESYNC_ADDR, 1)); - radeon_ring_write(cp, rdev->config.r300.resync_scratch); - radeon_ring_write(cp, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_lock(rdev, ring, 8); + radeon_ring_write(ring, PACKET0(R300_CP_RESYNC_ADDR, 1)); + radeon_ring_write(ring, rdev->config.r300.resync_scratch); + radeon_ring_write(ring, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev, ring); } static void r420_cp_errata_fini(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]; /* Catch the RESYNC we dispatched all the way back, * at the very beginning of the CP init. */ - radeon_ring_lock(rdev, cp, 8); - radeon_ring_write(cp, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, R300_RB3D_DC_FINISH); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_lock(rdev, ring, 8); + radeon_ring_write(ring, PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, R300_RB3D_DC_FINISH); + radeon_ring_unlock_commit(rdev, ring); radeon_scratch_free(rdev, rdev->config.r300.resync_scratch); } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index aaf8cd42943..d26e7c9f047 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1344,7 +1344,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev) return 0; } -bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) +bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { u32 srbm_status; u32 grbm_status; @@ -1361,19 +1361,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp) grbm_status = RREG32(R_008010_GRBM_STATUS); grbm_status2 = RREG32(R_008014_GRBM_STATUS2); if (!G_008010_GUI_ACTIVE(grbm_status)) { - 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->rptr_reg); - return r100_gpu_cp_is_lockup(rdev, lockup, cp); + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); } int r600_asic_reset(struct radeon_device *rdev) @@ -2144,28 +2144,28 @@ static int r600_cp_load_microcode(struct radeon_device *rdev) int r600_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; 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(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); + radeon_ring_write(ring, 0x1); if (rdev->family >= CHIP_RV770) { - radeon_ring_write(cp, 0x0); - radeon_ring_write(cp, rdev->config.rv770.max_hw_contexts - 1); + radeon_ring_write(ring, 0x0); + radeon_ring_write(ring, rdev->config.rv770.max_hw_contexts - 1); } else { - radeon_ring_write(cp, 0x3); - radeon_ring_write(cp, rdev->config.r600.max_hw_contexts - 1); + radeon_ring_write(ring, 0x3); + radeon_ring_write(ring, rdev->config.r600.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_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(R_0086D8_CP_ME_CNTL, cp_me); @@ -2174,7 +2174,7 @@ int r600_cp_start(struct radeon_device *rdev) int r600_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; @@ -2186,7 +2186,7 @@ int r600_cp_resume(struct radeon_device *rdev) WREG32(GRBM_SOFT_RESET, 0); /* 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; @@ -2200,8 +2200,8 @@ int r600_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 whether it's enabled or not */ WREG32(CP_RB_RPTR_ADDR, @@ -2219,36 +2219,36 @@ int r600_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); r600_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; } -void r600_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size) +void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size) { u32 rb_bufsz; /* Align ring size */ rb_bufsz = drm_order(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; - cp->ring_size = ring_size; - cp->align_mask = 16 - 1; + ring->ring_size = ring_size; + ring->align_mask = 16 - 1; } void r600_cp_fini(struct radeon_device *rdev) { r600_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); } @@ -2267,11 +2267,11 @@ void r600_scratch_init(struct radeon_device *rdev) } } -int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) +int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) { uint32_t scratch; uint32_t tmp = 0; - unsigned i, ridx = radeon_ring_index(rdev, cp); + unsigned i, ridx = radeon_ring_index(rdev, ring); int r; r = radeon_scratch_get(rdev, &scratch); @@ -2280,16 +2280,16 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) return r; } WREG32(scratch, 0xCAFEDEAD); - r = radeon_ring_lock(rdev, cp, 3); + r = radeon_ring_lock(rdev, ring, 3); if (r) { DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ridx, r); radeon_scratch_free(rdev, scratch); return r; } - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); - radeon_ring_write(cp, 0xDEADBEEF); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); + radeon_ring_write(ring, 0xDEADBEEF); + radeon_ring_unlock_commit(rdev, ring); for (i = 0; i < rdev->usec_timeout; i++) { tmp = RREG32(scratch); if (tmp == 0xDEADBEEF) @@ -2310,62 +2310,62 @@ int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp) void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_cp *cp = &rdev->cp[fence->ring]; + struct radeon_ring *ring = &rdev->ring[fence->ring]; if (rdev->wb.use_event) { u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + (u64)(rdev->fence_drv[fence->ring].scratch_reg - rdev->scratch.reg_base); /* flush read cache over gart */ - radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(cp, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); - radeon_ring_write(cp, 0xFFFFFFFF); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 10); /* poll interval */ + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | + PACKET3_VC_ACTION_ENA | + PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, 0xFFFFFFFF); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 10); /* poll interval */ /* EVENT_WRITE_EOP - flush caches, send int */ - radeon_ring_write(cp, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); - radeon_ring_write(cp, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); - radeon_ring_write(cp, addr & 0xffffffff); - radeon_ring_write(cp, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); - radeon_ring_write(cp, fence->seq); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); + radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); + radeon_ring_write(ring, addr & 0xffffffff); + radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); + radeon_ring_write(ring, fence->seq); + radeon_ring_write(ring, 0); } else { /* flush read cache over gart */ - radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(cp, PACKET3_TC_ACTION_ENA | - PACKET3_VC_ACTION_ENA | - PACKET3_SH_ACTION_ENA); - radeon_ring_write(cp, 0xFFFFFFFF); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 10); /* poll interval */ - radeon_ring_write(cp, PACKET3(PACKET3_EVENT_WRITE, 0)); - radeon_ring_write(cp, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | + PACKET3_VC_ACTION_ENA | + PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, 0xFFFFFFFF); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 10); /* poll interval */ + radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE, 0)); + radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0)); /* wait for 3D idle clean */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(cp, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(ring, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); /* Emit fence sequence & fire IRQ */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); - radeon_ring_write(cp, fence->seq); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); + radeon_ring_write(ring, fence->seq); /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ - radeon_ring_write(cp, PACKET0(CP_INT_STATUS, 0)); - radeon_ring_write(cp, RB_INT_STAT); + radeon_ring_write(ring, PACKET0(CP_INT_STATUS, 0)); + radeon_ring_write(ring, RB_INT_STAT); } } void r600_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_cp *cp, + struct radeon_ring *ring, struct radeon_semaphore *semaphore, bool emit_wait) { uint64_t addr = semaphore->gpu_addr; unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; - radeon_ring_write(cp, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - radeon_ring_write(cp, addr & 0xffffffff); - radeon_ring_write(cp, (upper_32_bits(addr) & 0xff) | sel); + radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); + radeon_ring_write(ring, addr & 0xffffffff); + radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); } int r600_copy_blit(struct radeon_device *rdev, @@ -2420,7 +2420,7 @@ void r600_clear_surface_reg(struct radeon_device *rdev, int reg) int r600_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 */ @@ -2468,7 +2468,7 @@ int r600_startup(struct radeon_device *rdev) } r600_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) @@ -2534,7 +2534,7 @@ int r600_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ r600_cp_stop(rdev); - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); radeon_wb_disable(rdev); r600_pcie_gart_disable(rdev); @@ -2609,8 +2609,8 @@ int r600_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); @@ -2677,17 +2677,17 @@ void r600_fini(struct radeon_device *rdev) */ void r600_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]; /* 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); } int r600_ib_test(struct radeon_device *rdev, int ring) @@ -3518,22 +3518,22 @@ static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; unsigned count, i, j; - radeon_ring_free_size(rdev, cp); - count = (cp->ring_size / 4) - cp->ring_free_dw; + radeon_ring_free_size(rdev, ring); + count = (ring->ring_size / 4) - ring->ring_free_dw; seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR)); seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR)); - seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", cp->wptr); - seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", cp->rptr); - seq_printf(m, "%u free dwords in ring\n", cp->ring_free_dw); + seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", ring->wptr); + seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", ring->rptr); + seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); seq_printf(m, "%u dwords in ring\n", count); - i = cp->rptr; + i = ring->rptr; for (j = 0; j <= count; j++) { - seq_printf(m, "r[%04d]=0x%08x\n", i, cp->ring[i]); - i = (i + 1) & cp->ptr_mask; + seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); + i = (i + 1) & ring->ptr_mask; } return 0; } diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index 62dd1c281c7..02a75747029 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -50,7 +50,7 @@ static void set_render_target(struct radeon_device *rdev, int format, int w, int h, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 cb_color_info; int pitch, slice; @@ -64,38 +64,38 @@ set_render_target(struct radeon_device *rdev, int format, pitch = (w / 8) - 1; slice = ((w * h) / 64) - 1; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_BASE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, gpu_addr >> 8); if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770) { - radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); - radeon_ring_write(cp, 2 << 0); + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_BASE_UPDATE, 0)); + radeon_ring_write(ring, 2 << 0); } - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, (pitch << 0) | (slice << 10)); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_SIZE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, (pitch << 0) | (slice << 10)); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_VIEW - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 0); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, cb_color_info); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_INFO - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, cb_color_info); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_TILE - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 0); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_FRAG - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 0); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (CB_COLOR0_MASK - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 0); } /* emits 5dw */ @@ -104,7 +104,7 @@ cp_set_surface_sync(struct radeon_device *rdev, u32 sync_type, u32 size, u64 mc_addr) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 cp_coher_size; if (size == 0xffffffff) @@ -112,18 +112,18 @@ cp_set_surface_sync(struct radeon_device *rdev, else cp_coher_size = ((size + 255) >> 8); - radeon_ring_write(cp, PACKET3(PACKET3_SURFACE_SYNC, 3)); - radeon_ring_write(cp, sync_type); - radeon_ring_write(cp, cp_coher_size); - radeon_ring_write(cp, mc_addr >> 8); - radeon_ring_write(cp, 10); /* poll interval */ + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(ring, sync_type); + radeon_ring_write(ring, cp_coher_size); + radeon_ring_write(ring, mc_addr >> 8); + radeon_ring_write(ring, 10); /* poll interval */ } /* emits 21dw + 1 surface sync = 26dw */ static void set_shaders(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]; u64 gpu_addr; u32 sq_pgm_resources; @@ -132,35 +132,35 @@ set_shaders(struct radeon_device *rdev) /* VS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_START_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, sq_pgm_resources); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_RESOURCES_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, sq_pgm_resources); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_CF_OFFSET_VS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 0); /* PS */ gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.ps_offset; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, gpu_addr >> 8); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_START_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, gpu_addr >> 8); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, sq_pgm_resources | (1 << 28)); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_RESOURCES_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, sq_pgm_resources | (1 << 28)); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 2); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_EXPORTS_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 2); - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); - radeon_ring_write(cp, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, 0); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 1)); + radeon_ring_write(ring, (SQ_PGM_CF_OFFSET_PS - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, 0); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.vs_offset; cp_set_surface_sync(rdev, PACKET3_SH_ACTION_ENA, 512, gpu_addr); @@ -170,7 +170,7 @@ set_shaders(struct radeon_device *rdev) static void set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; u32 sq_vtx_constant_word2; sq_vtx_constant_word2 = SQ_VTXC_BASE_ADDR_HI(upper_32_bits(gpu_addr) & 0xff) | @@ -179,15 +179,15 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) sq_vtx_constant_word2 |= SQ_VTXC_ENDIAN_SWAP(SQ_ENDIAN_8IN32); #endif - radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 7)); - radeon_ring_write(cp, 0x460); - radeon_ring_write(cp, gpu_addr & 0xffffffff); - radeon_ring_write(cp, 48 - 1); - radeon_ring_write(cp, sq_vtx_constant_word2); - radeon_ring_write(cp, 1 << 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, SQ_TEX_VTX_VALID_BUFFER << 30); + radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 7)); + radeon_ring_write(ring, 0x460); + radeon_ring_write(ring, gpu_addr & 0xffffffff); + radeon_ring_write(ring, 48 - 1); + radeon_ring_write(ring, sq_vtx_constant_word2); + radeon_ring_write(ring, 1 << 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, SQ_TEX_VTX_VALID_BUFFER << 30); if ((rdev->family == CHIP_RV610) || (rdev->family == CHIP_RV620) || @@ -207,7 +207,7 @@ set_tex_resource(struct radeon_device *rdev, int format, int w, int h, int pitch, u64 gpu_addr, u32 size) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; uint32_t sq_tex_resource_word0, sq_tex_resource_word1, sq_tex_resource_word4; if (h < 1) @@ -230,15 +230,15 @@ set_tex_resource(struct radeon_device *rdev, cp_set_surface_sync(rdev, PACKET3_TC_ACTION_ENA, size, gpu_addr); - radeon_ring_write(cp, PACKET3(PACKET3_SET_RESOURCE, 7)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, sq_tex_resource_word0); - radeon_ring_write(cp, sq_tex_resource_word1); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, gpu_addr >> 8); - radeon_ring_write(cp, sq_tex_resource_word4); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, SQ_TEX_VTX_VALID_TEXTURE << 30); + radeon_ring_write(ring, PACKET3(PACKET3_SET_RESOURCE, 7)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, sq_tex_resource_word0); + radeon_ring_write(ring, sq_tex_resource_word1); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, gpu_addr >> 8); + radeon_ring_write(ring, sq_tex_resource_word4); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, SQ_TEX_VTX_VALID_TEXTURE << 30); } /* emits 12 */ @@ -246,45 +246,45 @@ static void set_scissors(struct radeon_device *rdev, int x1, int y1, int x2, int y2) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(cp, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, (x1 << 0) | (y1 << 16)); - radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(cp, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); - - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); - radeon_ring_write(cp, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); - radeon_ring_write(cp, (x1 << 0) | (y1 << 16) | (1 << 31)); - radeon_ring_write(cp, (x2 << 0) | (y2 << 16)); + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(ring, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, (x1 << 0) | (y1 << 16)); + radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); + + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(ring, (PA_SC_GENERIC_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); + + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); + radeon_ring_write(ring, (PA_SC_WINDOW_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_OFFSET) >> 2); + radeon_ring_write(ring, (x1 << 0) | (y1 << 16) | (1 << 31)); + radeon_ring_write(ring, (x2 << 0) | (y2 << 16)); } /* emits 10 */ static void draw_auto(struct radeon_device *rdev) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 1)); - radeon_ring_write(cp, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(cp, DI_PT_RECTLIST); + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (VGT_PRIMITIVE_TYPE - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(ring, DI_PT_RECTLIST); - radeon_ring_write(cp, PACKET3(PACKET3_INDEX_TYPE, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET3(PACKET3_INDEX_TYPE, 0)); + radeon_ring_write(ring, #ifdef __BIG_ENDIAN (2 << 2) | #endif DI_INDEX_SIZE_16_BIT); - radeon_ring_write(cp, PACKET3(PACKET3_NUM_INSTANCES, 0)); - radeon_ring_write(cp, 1); + radeon_ring_write(ring, PACKET3(PACKET3_NUM_INSTANCES, 0)); + radeon_ring_write(ring, 1); - radeon_ring_write(cp, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); - radeon_ring_write(cp, 3); - radeon_ring_write(cp, DI_SRC_SEL_AUTO_INDEX); + radeon_ring_write(ring, PACKET3(PACKET3_DRAW_INDEX_AUTO, 1)); + radeon_ring_write(ring, 3); + radeon_ring_write(ring, DI_SRC_SEL_AUTO_INDEX); } @@ -292,7 +292,7 @@ draw_auto(struct radeon_device *rdev) static void set_default_state(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 sq_config, sq_gpr_resource_mgmt_1, sq_gpr_resource_mgmt_2; u32 sq_thread_resource_mgmt, sq_stack_resource_mgmt_1, sq_stack_resource_mgmt_2; int num_ps_gprs, num_vs_gprs, num_temp_gprs, num_gs_gprs, num_es_gprs; @@ -448,24 +448,24 @@ set_default_state(struct radeon_device *rdev) /* emit an IB pointing at default state */ dwords = ALIGN(rdev->r600_blit.state_len, 0x10); gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; - 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 (gpu_addr & 0xFFFFFFFC)); - radeon_ring_write(cp, upper_32_bits(gpu_addr) & 0xFF); - radeon_ring_write(cp, dwords); + radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xFF); + radeon_ring_write(ring, dwords); /* SQ config */ - radeon_ring_write(cp, PACKET3(PACKET3_SET_CONFIG_REG, 6)); - radeon_ring_write(cp, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - radeon_ring_write(cp, sq_config); - radeon_ring_write(cp, sq_gpr_resource_mgmt_1); - radeon_ring_write(cp, sq_gpr_resource_mgmt_2); - radeon_ring_write(cp, sq_thread_resource_mgmt); - radeon_ring_write(cp, sq_stack_resource_mgmt_1); - radeon_ring_write(cp, sq_stack_resource_mgmt_2); + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 6)); + radeon_ring_write(ring, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + radeon_ring_write(ring, sq_config); + radeon_ring_write(ring, sq_gpr_resource_mgmt_1); + radeon_ring_write(ring, sq_gpr_resource_mgmt_2); + radeon_ring_write(ring, sq_thread_resource_mgmt); + radeon_ring_write(ring, sq_stack_resource_mgmt_1); + radeon_ring_write(ring, sq_stack_resource_mgmt_2); } static uint32_t i2f(uint32_t input) @@ -687,7 +687,7 @@ static unsigned r600_blit_create_rect(unsigned num_gpu_pages, int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; int r; int ring_size; int num_loops = 0; @@ -708,7 +708,7 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) /* calculate number of loops correctly */ ring_size = num_loops * dwords_per_loop; ring_size += rdev->r600_blit.ring_size_common; - r = radeon_ring_lock(rdev, cp, ring_size); + r = radeon_ring_lock(rdev, ring, ring_size); if (r) return r; @@ -727,7 +727,7 @@ void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) if (fence) r = radeon_fence_emit(rdev, fence); - radeon_ring_unlock_commit(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_unlock_commit(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); } void r600_kms_blit_copy(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ea0cdf9ad61..014065af60d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -231,7 +231,7 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring); /* * Semaphores. */ -struct radeon_cp; +struct radeon_ring; struct radeon_semaphore_driver { rwlock_t lock; @@ -485,7 +485,7 @@ void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); /* - * CP & ring. + * CP & rings. */ /* max number of rings */ @@ -522,7 +522,7 @@ struct radeon_ib_pool { unsigned head_id; }; -struct radeon_cp { +struct radeon_ring { struct radeon_bo *ring_obj; volatile uint32_t *ring; unsigned rptr; @@ -600,17 +600,17 @@ void radeon_ib_pool_fini(struct radeon_device *rdev); int radeon_ib_test(struct radeon_device *rdev); extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); /* Ring access between begin & end cannot sleep */ -int radeon_ring_index(struct radeon_device *rdev, struct radeon_cp *cp); -void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp); -int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw); -int radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw); -void radeon_ring_commit(struct radeon_device *rdev, struct radeon_cp *cp); -void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_cp *cp); -void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_cp *cp); -int radeon_ring_test(struct radeon_device *rdev, struct radeon_cp *cp); -int radeon_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size, +int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *cp); +void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); +int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); +int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); +void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); +void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); +void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); +int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); +int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg); -void radeon_ring_fini(struct radeon_device *rdev, struct radeon_cp *cp); +void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *cp); /* @@ -915,8 +915,8 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number); */ void radeon_test_moves(struct radeon_device *rdev); void radeon_test_ring_sync(struct radeon_device *rdev, - struct radeon_cp *cpA, - struct radeon_cp *cpB); + struct radeon_ring *cpA, + struct radeon_ring *cpB); void radeon_test_syncing(struct radeon_device *rdev); @@ -943,7 +943,7 @@ struct radeon_asic { int (*resume)(struct radeon_device *rdev); int (*suspend)(struct radeon_device *rdev); void (*vga_set_state)(struct radeon_device *rdev, bool state); - bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_cp *cp); + bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); int (*asic_reset)(struct radeon_device *rdev); void (*gart_tlb_flush)(struct radeon_device *rdev); int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr); @@ -955,11 +955,11 @@ struct radeon_asic { struct { void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence); - void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_cp *cp, + void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, struct radeon_semaphore *semaphore, bool emit_wait); } ring[RADEON_NUM_RINGS]; - int (*ring_test)(struct radeon_device *rdev, struct radeon_cp *cp); + int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); int (*irq_set)(struct radeon_device *rdev); int (*irq_process)(struct radeon_device *rdev); u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); @@ -1293,7 +1293,7 @@ struct radeon_device { rwlock_t fence_lock; struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; struct radeon_semaphore_driver semaphore_drv; - struct radeon_cp cp[RADEON_NUM_RINGS]; + struct radeon_ring ring[RADEON_NUM_RINGS]; struct radeon_ib_pool ib_pool; struct radeon_irq irq; struct radeon_asic *asic; @@ -1476,16 +1476,16 @@ void radeon_atombios_fini(struct radeon_device *rdev); * RING helpers. */ #if DRM_DEBUG_CODE == 0 -static inline void radeon_ring_write(struct radeon_cp *cp, uint32_t v) +static inline void radeon_ring_write(struct radeon_ring *ring, uint32_t v) { - cp->ring[cp->wptr++] = v; - cp->wptr &= cp->ptr_mask; - cp->count_dw--; - cp->ring_free_dw--; + ring->ring[ring->wptr++] = v; + ring->wptr &= ring->ptr_mask; + ring->count_dw--; + ring->ring_free_dw--; } #else /* With debugging this is just too big to inline */ -void radeon_ring_write(struct radeon_cp *cp, uint32_t v); +void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #endif /* diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 4f9ba6d0330..a462fd9a262 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -58,7 +58,7 @@ void r100_fini(struct radeon_device *rdev); int r100_suspend(struct radeon_device *rdev); int r100_resume(struct radeon_device *rdev); void r100_vga_set_state(struct radeon_device *rdev, bool state); -bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); +bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); int r100_asic_reset(struct radeon_device *rdev); u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); void r100_pci_gart_tlb_flush(struct radeon_device *rdev); @@ -69,7 +69,7 @@ int r100_irq_process(struct radeon_device *rdev); void r100_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence); void r100_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_cp *cp, + struct radeon_ring *cp, struct radeon_semaphore *semaphore, bool emit_wait); int r100_cs_parse(struct radeon_cs_parser *p); @@ -86,7 +86,7 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg, void r100_clear_surface_reg(struct radeon_device *rdev, int reg); void r100_bandwidth_update(struct radeon_device *rdev); void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int r100_ring_test(struct radeon_device *rdev, struct radeon_cp *cp); +int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); void r100_hpd_init(struct radeon_device *rdev); void r100_hpd_fini(struct radeon_device *rdev); bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd); @@ -104,10 +104,10 @@ void r100_pci_gart_disable(struct radeon_device *rdev); int r100_debugfs_mc_info_init(struct radeon_device *rdev); int r100_gui_wait_for_idle(struct radeon_device *rdev); void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, - struct radeon_cp *cp); + struct radeon_ring *cp); bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, - struct radeon_cp *cp); + struct radeon_ring *cp); void r100_ib_fini(struct radeon_device *rdev); int r100_ib_init(struct radeon_device *rdev); void r100_irq_disable(struct radeon_device *rdev); @@ -157,7 +157,7 @@ extern int r300_init(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev); extern int r300_resume(struct radeon_device *rdev); -extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); +extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); extern int r300_asic_reset(struct radeon_device *rdev); extern void r300_ring_start(struct radeon_device *rdev); extern void r300_fence_ring_emit(struct radeon_device *rdev, @@ -303,10 +303,10 @@ int r600_cs_parse(struct radeon_cs_parser *p); void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_fence *fence); void r600_semaphore_ring_emit(struct radeon_device *rdev, - struct radeon_cp *cp, + struct radeon_ring *cp, struct radeon_semaphore *semaphore, bool emit_wait); -bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); +bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); int r600_asic_reset(struct radeon_device *rdev); int r600_set_surface_reg(struct radeon_device *rdev, int reg, uint32_t tiling_flags, uint32_t pitch, @@ -314,7 +314,7 @@ int r600_set_surface_reg(struct radeon_device *rdev, int reg, void r600_clear_surface_reg(struct radeon_device *rdev, int reg); int r600_ib_test(struct radeon_device *rdev, int ring); void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); -int r600_ring_test(struct radeon_device *rdev, struct radeon_cp *cp); +int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); int r600_copy_blit(struct radeon_device *rdev, uint64_t src_offset, uint64_t dst_offset, unsigned num_gpu_pages, struct radeon_fence *fence); @@ -334,7 +334,7 @@ extern int r600_get_pcie_lanes(struct radeon_device *rdev); bool r600_card_posted(struct radeon_device *rdev); void r600_cp_stop(struct radeon_device *rdev); int r600_cp_start(struct radeon_device *rdev); -void r600_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size); +void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size); int r600_cp_resume(struct radeon_device *rdev); void r600_cp_fini(struct radeon_device *rdev); int r600_count_pipe_bits(uint32_t val); @@ -403,7 +403,7 @@ int evergreen_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); int evergreen_suspend(struct radeon_device *rdev); int evergreen_resume(struct radeon_device *rdev); -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 *cp); int evergreen_asic_reset(struct radeon_device *rdev); void evergreen_bandwidth_update(struct radeon_device *rdev); void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); @@ -434,7 +434,7 @@ int cayman_init(struct radeon_device *rdev); void cayman_fini(struct radeon_device *rdev); int cayman_suspend(struct radeon_device *rdev); int cayman_resume(struct radeon_device *rdev); -bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_cp *cp); +bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); int cayman_asic_reset(struct radeon_device *rdev); #endif diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index fa36b5368d9..e81c333e0f9 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -719,7 +719,7 @@ int radeon_device_init(struct radeon_device *rdev, radeon_mutex_init(&rdev->cs_mutex); mutex_init(&rdev->ib_pool.mutex); for (i = 0; i < RADEON_NUM_RINGS; ++i) - mutex_init(&rdev->cp[i].mutex); + mutex_init(&rdev->ring[i].mutex); mutex_init(&rdev->dc_hw_i2c_mutex); if (rdev->family >= CHIP_R600) spin_lock_init(&rdev->ih.lock); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 9e7f8921714..809e66e8a86 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -84,7 +84,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) return 0; } fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq); - if (!rdev->cp[fence->ring].ready) + if (!rdev->ring[fence->ring].ready) /* FIXME: cp is not running assume everythings is done right * away */ @@ -269,7 +269,7 @@ retry: * if we experiencing a lockup the value doesn't change */ if (seq == rdev->fence_drv[fence->ring].last_seq && - radeon_gpu_is_lockup(rdev, &rdev->cp[fence->ring])) { + radeon_gpu_is_lockup(rdev, &rdev->ring[fence->ring])) { /* good news we believe it's a lockup */ printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", fence->seq, seq); diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 1ce8fa71cf7..ae321975283 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -163,7 +163,7 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, args->vram_visible -= radeon_fbdev_total_size(rdev); args->gart_size = rdev->mc.gtt_size - 4096 - RADEON_IB_POOL_SIZE*64*1024; for(i = 0; i < RADEON_NUM_RINGS; ++i) - args->gart_size -= rdev->cp[i].ring_size; + args->gart_size -= rdev->ring[i].ring_size; return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index aa4a4a209a6..095148e29a1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -253,8 +253,8 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) mutex_lock(&rdev->ddev->struct_mutex); mutex_lock(&rdev->vram_mutex); for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (rdev->cp[i].ring_obj) - mutex_lock(&rdev->cp[i].mutex); + if (rdev->ring[i].ring_obj) + mutex_lock(&rdev->ring[i].mutex); } /* gui idle int has issues on older chips it seems */ @@ -271,13 +271,13 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) radeon_irq_set(rdev); } } else { - struct radeon_cp *cp = &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]; - if (cp->ready) { + struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; + if (ring->ready) { struct radeon_fence *fence; - radeon_ring_alloc(rdev, cp, 64); - radeon_fence_create(rdev, &fence, radeon_ring_index(rdev, cp)); + radeon_ring_alloc(rdev, ring, 64); + radeon_fence_create(rdev, &fence, radeon_ring_index(rdev, ring)); radeon_fence_emit(rdev, fence); - radeon_ring_commit(rdev, cp); + radeon_ring_commit(rdev, ring); radeon_fence_wait(fence, false); radeon_fence_unref(&fence); } @@ -312,8 +312,8 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (rdev->cp[i].ring_obj) - mutex_unlock(&rdev->cp[i].mutex); + if (rdev->ring[i].ring_obj) + mutex_unlock(&rdev->ring[i].mutex); } mutex_unlock(&rdev->vram_mutex); mutex_unlock(&rdev->ddev->struct_mutex); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index a69cb049d87..52dd22f2596 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -60,17 +60,17 @@ u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) return idx_value; } -void radeon_ring_write(struct radeon_cp *cp, uint32_t v) +void radeon_ring_write(struct radeon_ring *ring, uint32_t v) { #if DRM_DEBUG_CODE - if (cp->count_dw <= 0) { + if (ring->count_dw <= 0) { DRM_ERROR("radeon: writting more dword to ring than expected !\n"); } #endif - cp->ring[cp->wptr++] = v; - cp->wptr &= cp->ptr_mask; - cp->count_dw--; - cp->ring_free_dw--; + ring->ring[ring->wptr++] = v; + ring->wptr &= ring->ptr_mask; + ring->count_dw--; + ring->ring_free_dw--; } void radeon_ib_bogus_cleanup(struct radeon_device *rdev) @@ -178,17 +178,17 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) int radeon_ib_schedule(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]; int r = 0; - if (!ib->length_dw || !cp->ready) { + if (!ib->length_dw || !ring->ready) { /* TODO: Nothings in the ib we should report. */ DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); return -EINVAL; } /* 64 dwords should be enough for fence too */ - r = radeon_ring_lock(rdev, cp, 64); + r = radeon_ring_lock(rdev, ring, 64); if (r) { DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); return r; @@ -199,7 +199,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) /* once scheduled IB is considered free and protected by the fence */ ib->free = true; mutex_unlock(&rdev->ib_pool.mutex); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_unlock_commit(rdev, ring); return 0; } @@ -284,150 +284,150 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) /* * Ring. */ -int radeon_ring_index(struct radeon_device *rdev, struct radeon_cp *cp) +int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) { /* r1xx-r5xx only has CP ring */ if (rdev->family < CHIP_R600) return RADEON_RING_TYPE_GFX_INDEX; if (rdev->family >= CHIP_CAYMAN) { - if (cp == &rdev->cp[CAYMAN_RING_TYPE_CP1_INDEX]) + if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]) return CAYMAN_RING_TYPE_CP1_INDEX; - else if (cp == &rdev->cp[CAYMAN_RING_TYPE_CP2_INDEX]) + else if (ring == &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]) return CAYMAN_RING_TYPE_CP2_INDEX; } return RADEON_RING_TYPE_GFX_INDEX; } -void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_cp *cp) +void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *ring) { if (rdev->wb.enabled) - cp->rptr = le32_to_cpu(rdev->wb.wb[cp->rptr_offs/4]); + ring->rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]); else - cp->rptr = RREG32(cp->rptr_reg); + ring->rptr = RREG32(ring->rptr_reg); /* This works because ring_size is a power of 2 */ - cp->ring_free_dw = (cp->rptr + (cp->ring_size / 4)); - cp->ring_free_dw -= cp->wptr; - cp->ring_free_dw &= cp->ptr_mask; - if (!cp->ring_free_dw) { - cp->ring_free_dw = cp->ring_size / 4; + ring->ring_free_dw = (ring->rptr + (ring->ring_size / 4)); + ring->ring_free_dw -= ring->wptr; + ring->ring_free_dw &= ring->ptr_mask; + if (!ring->ring_free_dw) { + ring->ring_free_dw = ring->ring_size / 4; } } -int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw) +int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) { int r; /* Align requested size with padding so unlock_commit can * pad safely */ - ndw = (ndw + cp->align_mask) & ~cp->align_mask; - while (ndw > (cp->ring_free_dw - 1)) { - radeon_ring_free_size(rdev, cp); - if (ndw < cp->ring_free_dw) { + ndw = (ndw + ring->align_mask) & ~ring->align_mask; + while (ndw > (ring->ring_free_dw - 1)) { + radeon_ring_free_size(rdev, ring); + if (ndw < ring->ring_free_dw) { break; } - r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, cp)); + r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring)); if (r) return r; } - cp->count_dw = ndw; - cp->wptr_old = cp->wptr; + ring->count_dw = ndw; + ring->wptr_old = ring->wptr; return 0; } -int radeon_ring_lock(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ndw) +int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ndw) { int r; - mutex_lock(&cp->mutex); - r = radeon_ring_alloc(rdev, cp, ndw); + mutex_lock(&ring->mutex); + r = radeon_ring_alloc(rdev, ring, ndw); if (r) { - mutex_unlock(&cp->mutex); + mutex_unlock(&ring->mutex); return r; } return 0; } -void radeon_ring_commit(struct radeon_device *rdev, struct radeon_cp *cp) +void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) { unsigned count_dw_pad; unsigned i; /* We pad to match fetch size */ - count_dw_pad = (cp->align_mask + 1) - - (cp->wptr & cp->align_mask); + count_dw_pad = (ring->align_mask + 1) - + (ring->wptr & ring->align_mask); for (i = 0; i < count_dw_pad; i++) { - radeon_ring_write(cp, 2 << 30); + radeon_ring_write(ring, 2 << 30); } DRM_MEMORYBARRIER(); - WREG32(cp->wptr_reg, cp->wptr); - (void)RREG32(cp->wptr_reg); + WREG32(ring->wptr_reg, ring->wptr); + (void)RREG32(ring->wptr_reg); } -void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_cp *cp) +void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) { - radeon_ring_commit(rdev, cp); - mutex_unlock(&cp->mutex); + radeon_ring_commit(rdev, ring); + mutex_unlock(&ring->mutex); } -void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_cp *cp) +void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) { - cp->wptr = cp->wptr_old; - mutex_unlock(&cp->mutex); + ring->wptr = ring->wptr_old; + mutex_unlock(&ring->mutex); } -int radeon_ring_init(struct radeon_device *rdev, struct radeon_cp *cp, unsigned ring_size, +int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg) { int r; - cp->ring_size = ring_size; - cp->rptr_offs = rptr_offs; - cp->rptr_reg = rptr_reg; - cp->wptr_reg = wptr_reg; + ring->ring_size = ring_size; + ring->rptr_offs = rptr_offs; + ring->rptr_reg = rptr_reg; + ring->wptr_reg = wptr_reg; /* Allocate ring buffer */ - if (cp->ring_obj == NULL) { - r = radeon_bo_create(rdev, cp->ring_size, PAGE_SIZE, true, + if (ring->ring_obj == NULL) { + r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, - &cp->ring_obj); + &ring->ring_obj); if (r) { dev_err(rdev->dev, "(%d) ring create failed\n", r); return r; } - r = radeon_bo_reserve(cp->ring_obj, false); + r = radeon_bo_reserve(ring->ring_obj, false); if (unlikely(r != 0)) return r; - r = radeon_bo_pin(cp->ring_obj, RADEON_GEM_DOMAIN_GTT, - &cp->gpu_addr); + r = radeon_bo_pin(ring->ring_obj, RADEON_GEM_DOMAIN_GTT, + &ring->gpu_addr); if (r) { - radeon_bo_unreserve(cp->ring_obj); + radeon_bo_unreserve(ring->ring_obj); dev_err(rdev->dev, "(%d) ring pin failed\n", r); return r; } - r = radeon_bo_kmap(cp->ring_obj, - (void **)&cp->ring); - radeon_bo_unreserve(cp->ring_obj); + r = radeon_bo_kmap(ring->ring_obj, + (void **)&ring->ring); + radeon_bo_unreserve(ring->ring_obj); if (r) { dev_err(rdev->dev, "(%d) ring map failed\n", r); return r; } } - cp->ptr_mask = (cp->ring_size / 4) - 1; - cp->ring_free_dw = cp->ring_size / 4; + ring->ptr_mask = (ring->ring_size / 4) - 1; + ring->ring_free_dw = ring->ring_size / 4; return 0; } -void radeon_ring_fini(struct radeon_device *rdev, struct radeon_cp *cp) +void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) { int r; struct radeon_bo *ring_obj; - mutex_lock(&cp->mutex); - ring_obj = cp->ring_obj; - cp->ring = NULL; - cp->ring_obj = NULL; - mutex_unlock(&cp->mutex); + mutex_lock(&ring->mutex); + ring_obj = ring->ring_obj; + ring->ring = NULL; + ring->ring_obj = NULL; + mutex_unlock(&ring->mutex); if (ring_obj) { r = radeon_bo_reserve(ring_obj, false); diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 80c1a9e010f..f8cf04499a5 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c @@ -121,13 +121,13 @@ int radeon_semaphore_create(struct radeon_device *rdev, void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore) { - radeon_semaphore_ring_emit(rdev, ring, &rdev->cp[ring], semaphore, false); + radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); } void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore) { - radeon_semaphore_ring_emit(rdev, ring, &rdev->cp[ring], semaphore, true); + radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); } void radeon_semaphore_free(struct radeon_device *rdev, diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 5f4d31ef393..3ab4be9e63d 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -44,7 +44,7 @@ void radeon_test_moves(struct radeon_device *rdev) */ n = rdev->mc.gtt_size - RADEON_IB_POOL_SIZE*64*1024; for (i = 0; i < RADEON_NUM_RINGS; ++i) - n -= rdev->cp[i].ring_size; + n -= rdev->ring[i].ring_size; if (rdev->wb.wb_obj) n -= RADEON_GPU_PAGE_SIZE; if (rdev->ih.ring_obj) @@ -236,16 +236,16 @@ out_cleanup: } void radeon_test_ring_sync(struct radeon_device *rdev, - struct radeon_cp *cpA, - struct radeon_cp *cpB) + struct radeon_ring *ringA, + struct radeon_ring *ringB) { struct radeon_fence *fence = NULL; struct radeon_semaphore *semaphore = NULL; - int ringA = radeon_ring_index(rdev, cpA); - int ringB = radeon_ring_index(rdev, cpB); + int ridxA = radeon_ring_index(rdev, ringA); + int ridxB = radeon_ring_index(rdev, ringB); int r; - r = radeon_fence_create(rdev, &fence, ringA); + r = radeon_fence_create(rdev, &fence, ridxA); if (r) { DRM_ERROR("Failed to create sync fence\n"); goto out_cleanup; @@ -257,14 +257,14 @@ void radeon_test_ring_sync(struct radeon_device *rdev, goto out_cleanup; } - r = radeon_ring_lock(rdev, cpA, 64); + r = radeon_ring_lock(rdev, ringA, 64); if (r) { - DRM_ERROR("Failed to lock ring %d\n", ringA); + DRM_ERROR("Failed to lock ring A %d\n", ridxA); goto out_cleanup; } - radeon_semaphore_emit_wait(rdev, ringA, semaphore); + radeon_semaphore_emit_wait(rdev, ridxA, semaphore); radeon_fence_emit(rdev, fence); - radeon_ring_unlock_commit(rdev, cpA); + radeon_ring_unlock_commit(rdev, ringA); mdelay(1000); @@ -273,13 +273,13 @@ void radeon_test_ring_sync(struct radeon_device *rdev, goto out_cleanup; } - r = radeon_ring_lock(rdev, cpB, 64); + r = radeon_ring_lock(rdev, ringB, 64); if (r) { - DRM_ERROR("Failed to lock ring %d\n", ringB); + DRM_ERROR("Failed to lock ring B %p\n", ringB); goto out_cleanup; } - radeon_semaphore_emit_signal(rdev, ringB, semaphore); - radeon_ring_unlock_commit(rdev, cpB); + radeon_semaphore_emit_signal(rdev, ridxB, semaphore); + radeon_ring_unlock_commit(rdev, ringB); r = radeon_fence_wait(fence, false); if (r) { @@ -287,7 +287,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, goto out_cleanup; } - DRM_INFO("Syncing between rings %d and %d seems to work.\n", ringA, ringB); + DRM_INFO("Syncing between rings %d and %d seems to work.\n", ridxA, ridxB); out_cleanup: if (semaphore) @@ -305,20 +305,20 @@ void radeon_test_syncing(struct radeon_device *rdev) int i, j; for (i = 1; i < RADEON_NUM_RINGS; ++i) { - struct radeon_cp *cpA = &rdev->cp[i]; - if (!cpA->ready) + struct radeon_ring *ringA = &rdev->ring[i]; + if (!ringA->ready) continue; for (j = 0; j < i; ++j) { - struct radeon_cp *cpB = &rdev->cp[j]; - if (!cpB->ready) + struct radeon_ring *ringB = &rdev->ring[j]; + if (!ringB->ready) continue; DRM_INFO("Testing syncing between rings %d and %d\n", i, j); - radeon_test_ring_sync(rdev, cpA, cpB); + radeon_test_ring_sync(rdev, ringA, ringB); DRM_INFO("Testing syncing between rings %d and %d\n", j, i); - radeon_test_ring_sync(rdev, cpB, cpA); + radeon_test_ring_sync(rdev, ringB, ringA); } } } diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 0be15bf38d3..b0ebaf893ac 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -188,7 +188,7 @@ static void radeon_evict_flags(struct ttm_buffer_object *bo, rbo = container_of(bo, struct radeon_bo, tbo); switch (bo->mem.mem_type) { case TTM_PL_VRAM: - if (rbo->rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready == false) + if (rbo->rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready == false) radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU); else radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); @@ -255,7 +255,7 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); return -EINVAL; } - if (!rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready) { + if (!rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready) { DRM_ERROR("Trying to move memory with CP turned off.\n"); return -EINVAL; } @@ -380,7 +380,7 @@ static int radeon_bo_move(struct ttm_buffer_object *bo, radeon_move_null(bo, new_mem); return 0; } - if (!rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready || rdev->asic->copy == NULL) { + if (!rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready || rdev->asic->copy == NULL) { /* use memcpy */ goto memcpy; } diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 8a935987d02..beed57c7df9 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -55,45 +55,45 @@ void rv515_debugfs(struct radeon_device *rdev) void rv515_ring_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; - r = radeon_ring_lock(rdev, cp, 64); + r = radeon_ring_lock(rdev, ring, 64); if (r) { return; } - radeon_ring_write(cp, PACKET0(ISYNC_CNTL, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(ISYNC_CNTL, 0)); + radeon_ring_write(ring, ISYNC_ANY2D_IDLE3D | ISYNC_ANY3D_IDLE2D | ISYNC_WAIT_IDLEGUI | ISYNC_CPSCRATCH_IDLEGUI); - radeon_ring_write(cp, PACKET0(WAIT_UNTIL, 0)); - radeon_ring_write(cp, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); - radeon_ring_write(cp, PACKET0(R300_DST_PIPE_CONFIG, 0)); - radeon_ring_write(cp, R300_PIPE_AUTO_CONFIG); - radeon_ring_write(cp, PACKET0(GB_SELECT, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(GB_ENABLE, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(R500_SU_REG_DEST, 0)); - radeon_ring_write(cp, (1 << rdev->num_gb_pipes) - 1); - radeon_ring_write(cp, PACKET0(VAP_INDEX_OFFSET, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, RB3D_DC_FLUSH | RB3D_DC_FREE); - radeon_ring_write(cp, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, ZC_FLUSH | ZC_FREE); - radeon_ring_write(cp, PACKET0(WAIT_UNTIL, 0)); - radeon_ring_write(cp, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); - radeon_ring_write(cp, PACKET0(GB_AA_CONFIG, 0)); - radeon_ring_write(cp, 0); - radeon_ring_write(cp, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, RB3D_DC_FLUSH | RB3D_DC_FREE); - radeon_ring_write(cp, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); - radeon_ring_write(cp, ZC_FLUSH | ZC_FREE); - radeon_ring_write(cp, PACKET0(GB_MSPOS0, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); + radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); + radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); + radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); + radeon_ring_write(ring, PACKET0(GB_SELECT, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(GB_ENABLE, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(R500_SU_REG_DEST, 0)); + radeon_ring_write(ring, (1 << rdev->num_gb_pipes) - 1); + radeon_ring_write(ring, PACKET0(VAP_INDEX_OFFSET, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); + radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); + radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); + radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); + radeon_ring_write(ring, PACKET0(GB_AA_CONFIG, 0)); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); + radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); + radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); + radeon_ring_write(ring, PACKET0(GB_MSPOS0, 0)); + radeon_ring_write(ring, ((6 << MS_X0_SHIFT) | (6 << MS_Y0_SHIFT) | (6 << MS_X1_SHIFT) | @@ -102,8 +102,8 @@ void rv515_ring_start(struct radeon_device *rdev) (6 << MS_Y2_SHIFT) | (6 << MSBD0_Y_SHIFT) | (6 << MSBD0_X_SHIFT))); - radeon_ring_write(cp, PACKET0(GB_MSPOS1, 0)); - radeon_ring_write(cp, + radeon_ring_write(ring, PACKET0(GB_MSPOS1, 0)); + radeon_ring_write(ring, ((6 << MS_X3_SHIFT) | (6 << MS_Y3_SHIFT) | (6 << MS_X4_SHIFT) | @@ -111,15 +111,15 @@ void rv515_ring_start(struct radeon_device *rdev) (6 << MS_X5_SHIFT) | (6 << MS_Y5_SHIFT) | (6 << MSBD1_SHIFT))); - radeon_ring_write(cp, PACKET0(GA_ENHANCE, 0)); - radeon_ring_write(cp, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); - radeon_ring_write(cp, PACKET0(GA_POLY_MODE, 0)); - radeon_ring_write(cp, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); - radeon_ring_write(cp, PACKET0(GA_ROUND_MODE, 0)); - radeon_ring_write(cp, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); - radeon_ring_write(cp, PACKET0(0x20C8, 0)); - radeon_ring_write(cp, 0); - radeon_ring_unlock_commit(rdev, cp); + radeon_ring_write(ring, PACKET0(GA_ENHANCE, 0)); + radeon_ring_write(ring, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); + radeon_ring_write(ring, PACKET0(GA_POLY_MODE, 0)); + radeon_ring_write(ring, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); + radeon_ring_write(ring, PACKET0(GA_ROUND_MODE, 0)); + radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); + radeon_ring_write(ring, PACKET0(0x20C8, 0)); + radeon_ring_write(ring, 0); + radeon_ring_unlock_commit(rdev, ring); } int rv515_mc_wait_for_idle(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 9e4c0418f54..f01603d522b 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -357,7 +357,7 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) void r700_cp_fini(struct radeon_device *rdev) { r700_cp_stop(rdev); - radeon_ring_fini(rdev, &rdev->cp[RADEON_RING_TYPE_GFX_INDEX]); + radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); } /* @@ -1043,7 +1043,7 @@ int rv770_mc_init(struct radeon_device *rdev) static int rv770_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 */ @@ -1092,7 +1092,7 @@ static int rv770_startup(struct radeon_device *rdev) } r600_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; @@ -1144,7 +1144,7 @@ int rv770_suspend(struct radeon_device *rdev) r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); - rdev->cp[RADEON_RING_TYPE_GFX_INDEX].ready = false; + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); radeon_wb_disable(rdev); rv770_pcie_gart_disable(rdev); @@ -1217,8 +1217,8 @@ int rv770_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.3-70-g09d2 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 +++- drivers/gpu/drm/radeon/ni.c | 20 +++++++- drivers/gpu/drm/radeon/r100.c | 8 +++- drivers/gpu/drm/radeon/r300.c | 8 +++- drivers/gpu/drm/radeon/r420.c | 8 +++- drivers/gpu/drm/radeon/r520.c | 8 +++- drivers/gpu/drm/radeon/r600.c | 11 +++-- drivers/gpu/drm/radeon/radeon.h | 5 +- drivers/gpu/drm/radeon/radeon_fence.c | 89 ++++++++++++++++++++--------------- drivers/gpu/drm/radeon/rs400.c | 8 +++- drivers/gpu/drm/radeon/rs600.c | 8 +++- drivers/gpu/drm/radeon/rs690.c | 8 +++- drivers/gpu/drm/radeon/rv515.c | 8 +++- drivers/gpu/drm/radeon/rv770.c | 8 +++- 14 files changed, 152 insertions(+), 53 deletions(-) (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index b19ace86121..ba19b9a697b 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 */ diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 022a606c783..a9b0e615804 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1384,6 +1384,24 @@ static int cayman_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; + } + + r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); + if (r) { + dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); + return r; + } + + r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_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) { @@ -1492,7 +1510,7 @@ int cayman_init(struct radeon_device *rdev) /* Initialize clocks */ radeon_get_clock_info(rdev->ddev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 3); + r = radeon_fence_driver_init(rdev); if (r) return r; /* initialize memory controller */ diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index a40e893a7b6..bed56c7b690 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3916,6 +3916,12 @@ static int r100_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 */ r100_irq_set(rdev); rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -4059,7 +4065,7 @@ int r100_init(struct radeon_device *rdev) /* initialize VRAM */ r100_mc_init(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 6a96b31b558..e2dfae4b40e 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1399,6 +1399,12 @@ static int r300_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 */ r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -1521,7 +1527,7 @@ int r300_init(struct radeon_device *rdev) /* initialize memory controller */ r300_mc_init(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 1d3231f3a09..17ecff1000e 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -258,6 +258,12 @@ static int r420_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 */ r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -391,7 +397,7 @@ int r420_init(struct radeon_device *rdev) r300_mc_init(rdev); r420_debugfs(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) { return r; } diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index cb96a51f7f7..39b31544c6e 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -187,6 +187,12 @@ static int r520_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 */ rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -278,7 +284,7 @@ int r520_init(struct radeon_device *rdev) r520_mc_init(rdev); rv515_debugfs(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 17538926cc4..f2deadfcd88 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2313,8 +2313,7 @@ void r600_fence_ring_emit(struct radeon_device *rdev, struct radeon_ring *ring = &rdev->ring[fence->ring]; if (rdev->wb.use_event) { - u64 addr = rdev->wb.gpu_addr + R600_WB_EVENT_OFFSET + - (u64)(rdev->fence_drv[fence->ring].scratch_reg - rdev->scratch.reg_base); + u64 addr = rdev->fence_drv[fence->ring].gpu_addr; /* flush read cache over gart */ radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | @@ -2459,6 +2458,12 @@ int r600_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) { @@ -2589,7 +2594,7 @@ int r600_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; if (rdev->flags & RADEON_IS_AGP) { diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 014065af60d..5777afb361d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -192,6 +192,8 @@ extern int sumo_get_temp(struct radeon_device *rdev); */ struct radeon_fence_driver { uint32_t scratch_reg; + uint64_t gpu_addr; + volatile uint32_t *cpu_addr; atomic_t seq; uint32_t last_seq; unsigned long last_jiffies; @@ -215,7 +217,8 @@ struct radeon_fence { int ring; }; -int radeon_fence_driver_init(struct radeon_device *rdev, int num_rings); +int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); +int radeon_fence_driver_init(struct radeon_device *rdev); void radeon_fence_driver_fini(struct radeon_device *rdev); int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence, int ring); int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 809e66e8a86..8d626baaa06 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -42,35 +42,22 @@ static void radeon_fence_write(struct radeon_device *rdev, u32 seq, int ring) { - u32 scratch_index; - if (rdev->wb.enabled) { - if (rdev->wb.use_event) - scratch_index = R600_WB_EVENT_OFFSET + - rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base; - else - scratch_index = RADEON_WB_SCRATCH_OFFSET + - rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base; - rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq); - } else + *rdev->fence_drv[ring].cpu_addr = cpu_to_le32(seq); + } else { WREG32(rdev->fence_drv[ring].scratch_reg, seq); + } } static u32 radeon_fence_read(struct radeon_device *rdev, int ring) { u32 seq = 0; - u32 scratch_index; if (rdev->wb.enabled) { - if (rdev->wb.use_event) - scratch_index = R600_WB_EVENT_OFFSET + - rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base; - else - scratch_index = RADEON_WB_SCRATCH_OFFSET + - rdev->fence_drv[ring].scratch_reg - rdev->scratch.reg_base; - seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); - } else + seq = le32_to_cpu(*rdev->fence_drv[ring].cpu_addr); + } else { seq = RREG32(rdev->fence_drv[ring].scratch_reg); + } return seq; } @@ -389,36 +376,61 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) return not_processed; } -int radeon_fence_driver_init(struct radeon_device *rdev, int num_rings) +int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) { unsigned long irq_flags; - int r, ring; + uint64_t index; + int r; - for (ring = 0; ring < num_rings; ring++) { - write_lock_irqsave(&rdev->fence_lock, irq_flags); + write_lock_irqsave(&rdev->fence_lock, irq_flags); + radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); + if (rdev->wb.use_event) { + rdev->fence_drv[ring].scratch_reg = 0; + index = R600_WB_EVENT_OFFSET + ring * 4; + } else { r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg); if (r) { dev_err(rdev->dev, "fence failed to get scratch register\n"); write_unlock_irqrestore(&rdev->fence_lock, irq_flags); return r; } - radeon_fence_write(rdev, 0, ring); - atomic_set(&rdev->fence_drv[ring].seq, 0); - INIT_LIST_HEAD(&rdev->fence_drv[ring].created); - INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted); - INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled); - init_waitqueue_head(&rdev->fence_drv[ring].queue); - rdev->fence_drv[ring].initialized = true; - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + index = RADEON_WB_SCRATCH_OFFSET + + rdev->fence_drv[ring].scratch_reg - + rdev->scratch.reg_base; } - for (ring = num_rings; ring < RADEON_NUM_RINGS; ring++) { - write_lock_irqsave(&rdev->fence_lock, irq_flags); - INIT_LIST_HEAD(&rdev->fence_drv[ring].created); - INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted); - INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled); - rdev->fence_drv[ring].initialized = false; - write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; + rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; + radeon_fence_write(rdev, atomic_read(&rdev->fence_drv[ring].seq), ring); + rdev->fence_drv[ring].initialized = true; + DRM_INFO("fence driver on ring %d use gpu addr 0x%08Lx and cpu addr 0x%p\n", + ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + return 0; +} + +static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) +{ + rdev->fence_drv[ring].scratch_reg = -1; + rdev->fence_drv[ring].cpu_addr = NULL; + rdev->fence_drv[ring].gpu_addr = 0; + atomic_set(&rdev->fence_drv[ring].seq, 0); + INIT_LIST_HEAD(&rdev->fence_drv[ring].created); + INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted); + INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled); + init_waitqueue_head(&rdev->fence_drv[ring].queue); + rdev->fence_drv[ring].initialized = false; +} + +int radeon_fence_driver_init(struct radeon_device *rdev) +{ + unsigned long irq_flags; + int ring; + + write_lock_irqsave(&rdev->fence_lock, irq_flags); + for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { + radeon_fence_driver_init_ring(rdev, ring); } + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); if (radeon_debugfs_fence_init(rdev)) { dev_err(rdev->dev, "fence debugfs file creation failed\n"); } @@ -433,6 +445,7 @@ void radeon_fence_driver_fini(struct radeon_device *rdev) for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { if (!rdev->fence_drv[ring].initialized) continue; + radeon_fence_wait_last(rdev, ring); wake_up_all(&rdev->fence_drv[ring].queue); write_lock_irqsave(&rdev->fence_lock, irq_flags); radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index c71fa16106c..5c86d5161fd 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -410,6 +410,12 @@ static int rs400_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 */ r100_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -516,7 +522,7 @@ int rs400_init(struct radeon_device *rdev) /* initialize memory controller */ rs400_mc_init(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 1c9ab940953..3fe384741fc 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -849,6 +849,12 @@ static int rs600_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 */ rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -962,7 +968,7 @@ int rs600_init(struct radeon_device *rdev) rs600_mc_init(rdev); rs600_debugfs(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 8aa5e7ef2ef..ae941d196d3 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -621,6 +621,12 @@ static int rs690_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 */ rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -735,7 +741,7 @@ int rs690_init(struct radeon_device *rdev) rs690_mc_init(rdev); rv515_debugfs(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index beed57c7df9..21d90d9fe11 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -393,6 +393,12 @@ static int rv515_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 */ rs600_irq_set(rdev); rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); @@ -511,7 +517,7 @@ int rv515_init(struct radeon_device *rdev) rv515_mc_init(rdev); rv515_debugfs(rdev); /* Fence driver */ - r = radeon_fence_driver_init(rdev, 1); + r = radeon_fence_driver_init(rdev); if (r) return r; r = radeon_irq_kms_init(rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index f01603d522b..0a1283d2402 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1083,6 +1083,12 @@ static int rv770_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) { @@ -1196,7 +1202,7 @@ int rv770_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.3-70-g09d2 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/Makefile | 2 +- drivers/gpu/drm/radeon/evergreen.c | 42 +++--- drivers/gpu/drm/radeon/ni.c | 45 +++--- drivers/gpu/drm/radeon/r100.c | 41 +++--- drivers/gpu/drm/radeon/r300.c | 21 ++- drivers/gpu/drm/radeon/r420.c | 21 ++- drivers/gpu/drm/radeon/r520.c | 19 ++- drivers/gpu/drm/radeon/r600.c | 43 +++--- drivers/gpu/drm/radeon/radeon.h | 63 ++++++-- drivers/gpu/drm/radeon/radeon_asic.h | 2 +- drivers/gpu/drm/radeon/radeon_object.h | 20 +++ drivers/gpu/drm/radeon/radeon_ring.c | 254 +++++++++++++-------------------- drivers/gpu/drm/radeon/radeon_sa.c | 189 ++++++++++++++++++++++++ drivers/gpu/drm/radeon/rs400.c | 21 ++- drivers/gpu/drm/radeon/rs600.c | 24 +++- drivers/gpu/drm/radeon/rs690.c | 24 +++- drivers/gpu/drm/radeon/rv515.c | 19 ++- drivers/gpu/drm/radeon/rv770.c | 43 +++--- 18 files changed, 601 insertions(+), 292 deletions(-) create mode 100644 drivers/gpu/drm/radeon/radeon_sa.c (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 94dcdc74604..2139fe893ec 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \ - radeon_semaphore.o + radeon_semaphore.o radeon_sa.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 266d411c6d2..1934728e246 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); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 30562622b94..d89b2ebd5bb 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1453,6 +1453,17 @@ static int cayman_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; } @@ -1467,32 +1478,25 @@ int cayman_resume(struct radeon_device *rdev) /* post card */ atom_asic_init(rdev->mode_info.atom_context); + rdev->accel_working = true; r = cayman_startup(rdev); if (r) { DRM_ERROR("cayman startup failed on resume\n"); return r; } - - r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - DRM_ERROR("radeon: failled testing IB (%d).\n", r); - return r; - } - return r; - } int cayman_suspend(struct radeon_device *rdev) { /* FIXME: we should wait for ring to be empty */ + radeon_ib_pool_suspend(rdev); + r600_blit_suspend(rdev); cayman_cp_enable(rdev, false); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); radeon_wb_disable(rdev); cayman_pcie_gart_disable(rdev); - r600_blit_suspend(rdev); - return 0; } @@ -1567,29 +1571,24 @@ int cayman_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 = cayman_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); cayman_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); + r100_ib_fini(rdev); radeon_irq_kms_fini(rdev); cayman_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; - } - } /* Don't start up if the MC ucode is missing. * The default clocks and voltages before the MC ucode @@ -1609,7 +1608,7 @@ void cayman_fini(struct radeon_device *rdev) cayman_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); cayman_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index d7fd5aa4705..657040b15b0 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3752,28 +3752,10 @@ int r100_ib_test(struct radeon_device *rdev) void r100_ib_fini(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); radeon_ib_pool_fini(rdev); } -int r100_ib_init(struct radeon_device *rdev) -{ - int r; - - r = radeon_ib_pool_init(rdev); - if (r) { - dev_err(rdev->dev, "failed initializing IB pool (%d).\n", r); - r100_ib_fini(rdev); - return r; - } - r = r100_ib_test(rdev); - if (r) { - dev_err(rdev->dev, "failed testing IB (%d).\n", r); - r100_ib_fini(rdev); - return r; - } - return 0; -} - void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) { /* Shutdown CP we shouldn't need to do that but better be safe than @@ -3932,11 +3914,18 @@ static int r100_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } + return 0; } @@ -3959,11 +3948,14 @@ int r100_resume(struct radeon_device *rdev) r100_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return r100_startup(rdev); } int r100_suspend(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); r100_irq_disable(rdev); @@ -4082,7 +4074,14 @@ int r100_init(struct radeon_device *rdev) return r; } r100_set_safe_registers(rdev); + + 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 = r100_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index e2dfae4b40e..8ad5c6475d5 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1414,11 +1414,18 @@ static int r300_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } + return 0; } @@ -1443,11 +1450,14 @@ int r300_resume(struct radeon_device *rdev) r300_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return r300_startup(rdev); } int r300_suspend(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); r100_irq_disable(rdev); @@ -1548,7 +1558,14 @@ int r300_init(struct radeon_device *rdev) return r; } r300_set_reg_safe(rdev); + + 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 = r300_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 17ecff1000e..666e28fe509 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -274,11 +274,18 @@ static int r420_startup(struct radeon_device *rdev) return r; } r420_cp_errata_init(rdev); - r = r100_ib_init(rdev); + + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } + return 0; } @@ -307,11 +314,14 @@ int r420_resume(struct radeon_device *rdev) r420_clock_resume(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return r420_startup(rdev); } int r420_suspend(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); r420_cp_errata_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); @@ -424,7 +434,14 @@ int r420_init(struct radeon_device *rdev) return r; } r420_set_reg_safe(rdev); + + 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 = r420_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 39b31544c6e..4ae1615e752 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -202,9 +202,15 @@ static int r520_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } return 0; @@ -229,6 +235,8 @@ int r520_resume(struct radeon_device *rdev) rv515_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return r520_startup(rdev); } @@ -298,7 +306,14 @@ int r520_init(struct radeon_device *rdev) if (r) return r; rv515_set_safe_registers(rdev); + + 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 = r520_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 0f39cc661a7..951566f1de9 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2486,6 +2486,17 @@ int r600_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; } @@ -2514,18 +2525,13 @@ int r600_resume(struct radeon_device *rdev) /* post card */ atom_asic_init(rdev->mode_info.atom_context); + rdev->accel_working = true; r = r600_startup(rdev); if (r) { DRM_ERROR("r600 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; - } - r = r600_audio_init(rdev); if (r) { DRM_ERROR("radeon: audio resume failed\n"); @@ -2538,13 +2544,14 @@ int r600_resume(struct radeon_device *rdev) int r600_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); + radeon_ib_pool_suspend(rdev); + r600_blit_suspend(rdev); /* FIXME: we should wait for ring to be empty */ r600_cp_stop(rdev); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); radeon_wb_disable(rdev); r600_pcie_gart_disable(rdev); - r600_blit_suspend(rdev); return 0; } @@ -2625,30 +2632,24 @@ int r600_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 = r600_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); r600_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); + r100_ib_fini(rdev); radeon_irq_kms_fini(rdev); r600_pcie_gart_fini(rdev); rdev->accel_working = false; } - if (rdev->accel_working) { - r = radeon_ib_pool_init(rdev); - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } else { - r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "IB test failed (%d).\n", r); - rdev->accel_working = false; - } - } - } r = r600_audio_init(rdev); if (r) @@ -2663,7 +2664,7 @@ void r600_fini(struct radeon_device *rdev) r600_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); r600_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b4c2d0fe34e..f29edbf6296 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -316,6 +316,48 @@ struct radeon_bo_list { u32 tiling_flags; }; +/* sub-allocation manager, it has to be protected by another lock. + * By conception this is an helper for other part of the driver + * like the indirect buffer or semaphore, which both have their + * locking. + * + * Principe is simple, we keep a list of sub allocation in offset + * order (first entry has offset == 0, last entry has the highest + * offset). + * + * When allocating new object we first check if there is room at + * the end total_size - (last_object_offset + last_object_size) >= + * alloc_size. If so we allocate new object there. + * + * When there is not enough room at the end, we start waiting for + * each sub object until we reach object_offset+object_size >= + * alloc_size, this object then become the sub object we return. + * + * Alignment can't be bigger than page size. + * + * Hole are not considered for allocation to keep things simple. + * Assumption is that there won't be hole (all object on same + * alignment). + */ +struct radeon_sa_manager { + struct radeon_bo *bo; + struct list_head sa_bo; + unsigned size; + uint64_t gpu_addr; + void *cpu_ptr; + uint32_t domain; +}; + +struct radeon_sa_bo; + +/* sub-allocation buffer */ +struct radeon_sa_bo { + struct list_head list; + struct radeon_sa_manager *manager; + unsigned offset; + unsigned size; +}; + /* * GEM objects. */ @@ -503,13 +545,12 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); */ struct radeon_ib { - struct list_head list; + struct radeon_sa_bo sa_bo; unsigned idx; + uint32_t length_dw; uint64_t gpu_addr; - struct radeon_fence *fence; uint32_t *ptr; - uint32_t length_dw; - bool free; + struct radeon_fence *fence; }; /* @@ -517,12 +558,11 @@ struct radeon_ib { * mutex protects scheduled_ibs, ready, alloc_bm */ struct radeon_ib_pool { - struct mutex mutex; - struct radeon_bo *robj; - struct list_head bogus_ib; - struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; - bool ready; - unsigned head_id; + struct mutex mutex; + struct radeon_sa_manager sa_manager; + struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; + bool ready; + unsigned head_id; }; struct radeon_ring { @@ -603,8 +643,9 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); int radeon_ib_pool_init(struct radeon_device *rdev); void radeon_ib_pool_fini(struct radeon_device *rdev); +int radeon_ib_pool_start(struct radeon_device *rdev); +int radeon_ib_pool_suspend(struct radeon_device *rdev); int radeon_ib_test(struct radeon_device *rdev); -extern void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib); /* Ring access between begin & end cannot sleep */ int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f0bab787806..c002ed1c448 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -109,7 +109,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_ring *cp); void r100_ib_fini(struct radeon_device *rdev); -int r100_ib_init(struct radeon_device *rdev); +int r100_ib_test(struct radeon_device *rdev); void r100_irq_disable(struct radeon_device *rdev); void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save); void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save); diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index b07f0f9b862..cc236fb128a 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -128,4 +128,24 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem); extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); + +/* + * sub allocation + */ +extern int radeon_sa_bo_manager_init(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager, + unsigned size, u32 domain); +extern void radeon_sa_bo_manager_fini(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager); +extern int radeon_sa_bo_manager_start(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager); +extern int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager); +extern int radeon_sa_bo_new(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager, + struct radeon_sa_bo *sa_bo, + unsigned size, unsigned align); +extern void radeon_sa_bo_free(struct radeon_device *rdev, + struct radeon_sa_bo *sa_bo); + #endif diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 133e2636cea..f6a4fbd102a 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -74,92 +74,90 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v) ring->ring_free_dw--; } -void radeon_ib_bogus_cleanup(struct radeon_device *rdev) -{ - struct radeon_ib *ib, *n; - - list_for_each_entry_safe(ib, n, &rdev->ib_pool.bogus_ib, list) { - list_del(&ib->list); - vfree(ib->ptr); - kfree(ib); - } -} - -void radeon_ib_bogus_add(struct radeon_device *rdev, struct radeon_ib *ib) +/* + * IB. + */ +static bool radeon_ib_try_free(struct radeon_device *rdev, + struct radeon_ib *ib) { - struct radeon_ib *bib; - - bib = kmalloc(sizeof(*bib), GFP_KERNEL); - if (bib == NULL) - return; - bib->ptr = vmalloc(ib->length_dw * 4); - if (bib->ptr == NULL) { - kfree(bib); - return; + bool done = false; + + /* only free ib which have been emited */ + if (ib->fence && ib->fence->emitted) { + if (radeon_fence_signaled(ib->fence)) { + radeon_fence_unref(&ib->fence); + radeon_sa_bo_free(rdev, &ib->sa_bo); + done = true; + } } - memcpy(bib->ptr, ib->ptr, ib->length_dw * 4); - bib->length_dw = ib->length_dw; - mutex_lock(&rdev->ib_pool.mutex); - list_add_tail(&bib->list, &rdev->ib_pool.bogus_ib); - mutex_unlock(&rdev->ib_pool.mutex); + return done; } -/* - * IB. - */ int radeon_ib_get(struct radeon_device *rdev, int ring, struct radeon_ib **ib) { struct radeon_fence *fence; - struct radeon_ib *nib; - int r = 0, i, c; + unsigned cretry = 0; + int r = 0, i, idx; *ib = NULL; + r = radeon_fence_create(rdev, &fence, ring); if (r) { dev_err(rdev->dev, "failed to create fence for new IB\n"); return r; } + mutex_lock(&rdev->ib_pool.mutex); - for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) { - i &= (RADEON_IB_POOL_SIZE - 1); - if (rdev->ib_pool.ibs[i].free) { - nib = &rdev->ib_pool.ibs[i]; - break; - } - } - if (nib == NULL) { - /* This should never happen, it means we allocated all - * IB and haven't scheduled one yet, return EBUSY to - * userspace hoping that on ioctl recall we get better - * luck - */ - dev_err(rdev->dev, "no free indirect buffer !\n"); + idx = rdev->ib_pool.head_id; +retry: + if (cretry > 5) { + dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); mutex_unlock(&rdev->ib_pool.mutex); radeon_fence_unref(&fence); - return -EBUSY; + return -ENOMEM; } - rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1); - nib->free = false; - if (nib->fence) { - mutex_unlock(&rdev->ib_pool.mutex); - r = radeon_fence_wait(nib->fence, false); - if (r) { - dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n", - nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw); - mutex_lock(&rdev->ib_pool.mutex); - nib->free = true; - mutex_unlock(&rdev->ib_pool.mutex); - radeon_fence_unref(&fence); - return r; + cretry++; + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + radeon_ib_try_free(rdev, &rdev->ib_pool.ibs[idx]); + if (rdev->ib_pool.ibs[idx].fence == NULL) { + r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager, + &rdev->ib_pool.ibs[idx].sa_bo, + 64*1024, 64); + if (!r) { + *ib = &rdev->ib_pool.ibs[idx]; + (*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr; + (*ib)->ptr += ((*ib)->sa_bo.offset >> 2); + (*ib)->gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; + (*ib)->gpu_addr += (*ib)->sa_bo.offset; + (*ib)->fence = fence; + /* ib are most likely to be allocated in a ring fashion + * thus rdev->ib_pool.head_id should be the id of the + * oldest ib + */ + rdev->ib_pool.head_id = (1 + idx); + rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); + mutex_unlock(&rdev->ib_pool.mutex); + return 0; + } } - mutex_lock(&rdev->ib_pool.mutex); + idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); + } + /* this should be rare event, ie all ib scheduled none signaled yet. + */ + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + if (rdev->ib_pool.ibs[idx].fence) { + r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false); + if (!r) { + goto retry; + } + /* an error happened */ + break; + } + idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); } - radeon_fence_unref(&nib->fence); - nib->fence = fence; - nib->length_dw = 0; mutex_unlock(&rdev->ib_pool.mutex); - *ib = nib; - return 0; + radeon_fence_unref(&fence); + return r; } void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) @@ -170,10 +168,11 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) if (tmp == NULL) { return; } - if (!tmp->fence->emitted) - radeon_fence_unref(&tmp->fence); mutex_lock(&rdev->ib_pool.mutex); - tmp->free = true; + if (tmp->fence && !tmp->fence->emitted) { + radeon_sa_bo_free(rdev, &tmp->sa_bo); + radeon_fence_unref(&tmp->fence); + } mutex_unlock(&rdev->ib_pool.mutex); } @@ -196,94 +195,73 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) } radeon_ring_ib_execute(rdev, ib->fence->ring, ib); radeon_fence_emit(rdev, ib->fence); - mutex_lock(&rdev->ib_pool.mutex); - /* once scheduled IB is considered free and protected by the fence */ - ib->free = true; - mutex_unlock(&rdev->ib_pool.mutex); radeon_ring_unlock_commit(rdev, ring); return 0; } int radeon_ib_pool_init(struct radeon_device *rdev) { - void *ptr; - uint64_t gpu_addr; - int i; - int r = 0; + int i, r; - if (rdev->ib_pool.robj) + mutex_lock(&rdev->ib_pool.mutex); + if (rdev->ib_pool.ready) { + mutex_unlock(&rdev->ib_pool.mutex); return 0; - INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); - /* Allocate 1M object buffer */ - r = radeon_bo_create(rdev, RADEON_IB_POOL_SIZE*64*1024, - PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, - &rdev->ib_pool.robj); - if (r) { - DRM_ERROR("radeon: failed to ib pool (%d).\n", r); - return r; } - r = radeon_bo_reserve(rdev->ib_pool.robj, false); - if (unlikely(r != 0)) - return r; - r = radeon_bo_pin(rdev->ib_pool.robj, RADEON_GEM_DOMAIN_GTT, &gpu_addr); - if (r) { - radeon_bo_unreserve(rdev->ib_pool.robj); - DRM_ERROR("radeon: failed to pin ib pool (%d).\n", r); - return r; - } - r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr); - radeon_bo_unreserve(rdev->ib_pool.robj); + + r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager, + RADEON_IB_POOL_SIZE*64*1024, + RADEON_GEM_DOMAIN_GTT); if (r) { - DRM_ERROR("radeon: failed to map ib pool (%d).\n", r); + mutex_unlock(&rdev->ib_pool.mutex); return r; } - for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { - unsigned offset; - offset = i * 64 * 1024; - rdev->ib_pool.ibs[i].gpu_addr = gpu_addr + offset; - rdev->ib_pool.ibs[i].ptr = ptr + offset; + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + rdev->ib_pool.ibs[i].fence = NULL; rdev->ib_pool.ibs[i].idx = i; rdev->ib_pool.ibs[i].length_dw = 0; - rdev->ib_pool.ibs[i].free = true; + INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list); } rdev->ib_pool.head_id = 0; rdev->ib_pool.ready = true; DRM_INFO("radeon: ib pool ready.\n"); + if (radeon_debugfs_ib_init(rdev)) { DRM_ERROR("Failed to register debugfs file for IB !\n"); } if (radeon_debugfs_ring_init(rdev)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); } - return r; + mutex_unlock(&rdev->ib_pool.mutex); + return 0; } void radeon_ib_pool_fini(struct radeon_device *rdev) { - int r; - struct radeon_bo *robj; + unsigned i; - if (!rdev->ib_pool.ready) { - return; - } mutex_lock(&rdev->ib_pool.mutex); - radeon_ib_bogus_cleanup(rdev); - robj = rdev->ib_pool.robj; - rdev->ib_pool.robj = NULL; - mutex_unlock(&rdev->ib_pool.mutex); - - if (robj) { - r = radeon_bo_reserve(robj, false); - if (likely(r == 0)) { - radeon_bo_kunmap(robj); - radeon_bo_unpin(robj); - radeon_bo_unreserve(robj); + if (rdev->ib_pool.ready) { + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); + radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); } - radeon_bo_unref(&robj); + radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); + rdev->ib_pool.ready = false; } + mutex_unlock(&rdev->ib_pool.mutex); } +int radeon_ib_pool_start(struct radeon_device *rdev) +{ + return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager); +} + +int radeon_ib_pool_suspend(struct radeon_device *rdev) +{ + return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager); +} /* * Ring. @@ -509,37 +487,8 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void *data) return 0; } -static int radeon_debugfs_ib_bogus_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct radeon_device *rdev = node->info_ent->data; - struct radeon_ib *ib; - unsigned i; - - mutex_lock(&rdev->ib_pool.mutex); - if (list_empty(&rdev->ib_pool.bogus_ib)) { - mutex_unlock(&rdev->ib_pool.mutex); - seq_printf(m, "no bogus IB recorded\n"); - return 0; - } - ib = list_first_entry(&rdev->ib_pool.bogus_ib, struct radeon_ib, list); - list_del_init(&ib->list); - mutex_unlock(&rdev->ib_pool.mutex); - seq_printf(m, "IB size %05u dwords\n", ib->length_dw); - for (i = 0; i < ib->length_dw; i++) { - seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); - } - vfree(ib->ptr); - kfree(ib); - return 0; -} - static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; - -static struct drm_info_list radeon_debugfs_ib_bogus_info_list[] = { - {"radeon_ib_bogus", radeon_debugfs_ib_bogus_info, 0, NULL}, -}; #endif int radeon_debugfs_ring_init(struct radeon_device *rdev) @@ -556,12 +505,7 @@ int radeon_debugfs_ib_init(struct radeon_device *rdev) { #if defined(CONFIG_DEBUG_FS) unsigned i; - int r; - radeon_debugfs_ib_bogus_info_list[0].data = rdev; - r = radeon_debugfs_add_files(rdev, radeon_debugfs_ib_bogus_info_list, 1); - if (r) - return r; for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c new file mode 100644 index 00000000000..4cce47e7dc0 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_sa.c @@ -0,0 +1,189 @@ +/* + * Copyright 2011 Red Hat Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + */ +/* + * Authors: + * Jerome Glisse + */ +#include "drmP.h" +#include "drm.h" +#include "radeon.h" + +int radeon_sa_bo_manager_init(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager, + unsigned size, u32 domain) +{ + int r; + + sa_manager->bo = NULL; + sa_manager->size = size; + sa_manager->domain = domain; + INIT_LIST_HEAD(&sa_manager->sa_bo); + + r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true, + RADEON_GEM_DOMAIN_CPU, &sa_manager->bo); + if (r) { + dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r); + return r; + } + + return r; +} + +void radeon_sa_bo_manager_fini(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager) +{ + struct radeon_sa_bo *sa_bo, *tmp; + + if (!list_empty(&sa_manager->sa_bo)) { + dev_err(rdev->dev, "sa_manager is not empty, clearing anyway\n"); + } + list_for_each_entry_safe(sa_bo, tmp, &sa_manager->sa_bo, list) { + list_del_init(&sa_bo->list); + } + radeon_bo_unref(&sa_manager->bo); + sa_manager->size = 0; +} + +int radeon_sa_bo_manager_start(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager) +{ + int r; + + if (sa_manager->bo == NULL) { + dev_err(rdev->dev, "no bo for sa manager\n"); + return -EINVAL; + } + + /* map the buffer */ + r = radeon_bo_reserve(sa_manager->bo, false); + if (r) { + dev_err(rdev->dev, "(%d) failed to reserve manager bo\n", r); + return r; + } + r = radeon_bo_pin(sa_manager->bo, sa_manager->domain, &sa_manager->gpu_addr); + if (r) { + radeon_bo_unreserve(sa_manager->bo); + dev_err(rdev->dev, "(%d) failed to pin manager bo\n", r); + return r; + } + r = radeon_bo_kmap(sa_manager->bo, &sa_manager->cpu_ptr); + radeon_bo_unreserve(sa_manager->bo); + return r; +} + +int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager) +{ + int r; + + if (sa_manager->bo == NULL) { + dev_err(rdev->dev, "no bo for sa manager\n"); + return -EINVAL; + } + + r = radeon_bo_reserve(sa_manager->bo, false); + if (!r) { + radeon_bo_kunmap(sa_manager->bo); + radeon_bo_unpin(sa_manager->bo); + radeon_bo_unreserve(sa_manager->bo); + } + return r; +} + +/* + * Principe is simple, we keep a list of sub allocation in offset + * order (first entry has offset == 0, last entry has the highest + * offset). + * + * When allocating new object we first check if there is room at + * the end total_size - (last_object_offset + last_object_size) >= + * alloc_size. If so we allocate new object there. + * + * When there is not enough room at the end, we start waiting for + * each sub object until we reach object_offset+object_size >= + * alloc_size, this object then become the sub object we return. + * + * Alignment can't be bigger than page size + */ +int radeon_sa_bo_new(struct radeon_device *rdev, + struct radeon_sa_manager *sa_manager, + struct radeon_sa_bo *sa_bo, + unsigned size, unsigned align) +{ + struct radeon_sa_bo *tmp; + struct list_head *head; + unsigned offset = 0, wasted = 0; + + BUG_ON(align > RADEON_GPU_PAGE_SIZE); + BUG_ON(size > sa_manager->size); + + /* no one ? */ + head = sa_manager->sa_bo.prev; + if (list_empty(&sa_manager->sa_bo)) { + goto out; + } + + /* look for a hole big enough */ + offset = 0; + list_for_each_entry(tmp, &sa_manager->sa_bo, list) { + /* room before this object ? */ + if ((tmp->offset - offset) >= size) { + head = tmp->list.prev; + goto out; + } + offset = tmp->offset + tmp->size; + wasted = offset % align; + if (wasted) { + wasted = align - wasted; + } + offset += wasted; + } + /* room at the end ? */ + head = sa_manager->sa_bo.prev; + tmp = list_entry(head, struct radeon_sa_bo, list); + offset = tmp->offset + tmp->size; + wasted = offset % align; + if (wasted) { + wasted = align - wasted; + } + offset += wasted; + if ((sa_manager->size - offset) < size) { + /* failed to find somethings big enough */ + return -ENOMEM; + } + +out: + sa_bo->manager = sa_manager; + sa_bo->offset = offset; + sa_bo->size = size; + list_add(&sa_bo->list, head); + return 0; +} + +void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo) +{ + list_del_init(&sa_bo->list); +} diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 5c86d5161fd..b0ce84a20a6 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -425,11 +425,18 @@ static int rs400_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } + return 0; } @@ -453,11 +460,14 @@ int rs400_resume(struct radeon_device *rdev) r300_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return rs400_startup(rdev); } int rs400_suspend(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); r100_irq_disable(rdev); @@ -536,7 +546,14 @@ int rs400_init(struct radeon_device *rdev) if (r) return r; r300_set_reg_safe(rdev); + + 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 = rs400_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 8a52cf007ff..ca6d5b6eaaa 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -864,15 +864,21 @@ static int rs600_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = r600_audio_init(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed initializing audio\n"); return r; } - r = r600_audio_init(rdev); + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } @@ -897,11 +903,14 @@ int rs600_resume(struct radeon_device *rdev) rv515_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return rs600_startup(rdev); } int rs600_suspend(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); r600_audio_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); @@ -982,7 +991,14 @@ int rs600_init(struct radeon_device *rdev) if (r) return r; rs600_set_safe_registers(rdev); + + 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 = rs600_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index ae941d196d3..4f24a0fa8c8 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -636,15 +636,21 @@ static int rs690_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = r600_audio_init(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed initializing audio\n"); return r; } - r = r600_audio_init(rdev); + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing audio\n"); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } @@ -669,11 +675,14 @@ int rs690_resume(struct radeon_device *rdev) rv515_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return rs690_startup(rdev); } int rs690_suspend(struct radeon_device *rdev) { + radeon_ib_pool_suspend(rdev); r600_audio_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); @@ -755,7 +764,14 @@ int rs690_init(struct radeon_device *rdev) if (r) return r; rs600_set_safe_registers(rdev); + + 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 = rs690_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 21d90d9fe11..880637fd194 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -408,9 +408,15 @@ static int rv515_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failed initializing CP (%d).\n", r); return r; } - r = r100_ib_init(rdev); + + r = radeon_ib_pool_start(rdev); + if (r) + return r; + + r = r100_ib_test(rdev); if (r) { - dev_err(rdev->dev, "failed initializing IB (%d).\n", r); + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; } return 0; @@ -435,6 +441,8 @@ int rv515_resume(struct radeon_device *rdev) rv515_clock_startup(rdev); /* Initialize surface registers */ radeon_surface_init(rdev); + + rdev->accel_working = true; return rv515_startup(rdev); } @@ -531,7 +539,14 @@ int rv515_init(struct radeon_device *rdev) if (r) return r; rv515_set_safe_registers(rdev); + + 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 = rv515_startup(rdev); if (r) { /* Somethings want wront with the accel init stop accel */ diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index d854fbfa5a5..a1668b659dd 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1110,6 +1110,17 @@ static int rv770_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) { + dev_err(rdev->dev, "IB test failed (%d).\n", r); + rdev->accel_working = false; + return r; + } + return 0; } @@ -1124,18 +1135,13 @@ int rv770_resume(struct radeon_device *rdev) /* post card */ atom_asic_init(rdev->mode_info.atom_context); + rdev->accel_working = true; r = rv770_startup(rdev); if (r) { DRM_ERROR("r600 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; - } - r = r600_audio_init(rdev); if (r) { dev_err(rdev->dev, "radeon: audio init failed\n"); @@ -1149,13 +1155,14 @@ int rv770_resume(struct radeon_device *rdev) int rv770_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); + radeon_ib_pool_suspend(rdev); + r600_blit_suspend(rdev); /* FIXME: we should wait for ring to be empty */ r700_cp_stop(rdev); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; r600_irq_suspend(rdev); radeon_wb_disable(rdev); rv770_pcie_gart_disable(rdev); - r600_blit_suspend(rdev); return 0; } @@ -1234,30 +1241,24 @@ int rv770_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 = rv770_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); rv770_pcie_gart_fini(rdev); rdev->accel_working = false; } - if (rdev->accel_working) { - r = radeon_ib_pool_init(rdev); - if (r) { - dev_err(rdev->dev, "IB initialization failed (%d).\n", r); - rdev->accel_working = false; - } else { - r = r600_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX); - if (r) { - dev_err(rdev->dev, "IB test failed (%d).\n", r); - rdev->accel_working = false; - } - } - } r = r600_audio_init(rdev); if (r) { @@ -1274,7 +1275,7 @@ void rv770_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); rv770_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); -- cgit v1.2.3-70-g09d2 From 721604a15b934f0a8d1909acb8017f029128be2f Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Thu, 5 Jan 2012 22:11:05 -0500 Subject: drm/radeon: GPU virtual memory support v22 Virtual address space are per drm client (opener of /dev/drm). Client are in charge of virtual address space, they need to map bo into it by calling DRM_RADEON_GEM_VA ioctl. First 16M of virtual address space is reserved by the kernel. Once using 2 level page table we should be able to have a small vram memory footprint for each pt (there would be one pt for all gart, one for all vram and then one first level for each virtual address space). Plan include using the sub allocator for a common vm page table area and using memcpy to copy vm page table in & out. Or use a gart object and copy things in & out using dma. v2: agd5f fixes: - Add vram base offset for vram pages. The GPU physical address of a vram page is FB_OFFSET + page offset. FB_OFFSET is 0 on discrete cards and the physical bus address of the stolen memory on integrated chips. - VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR covers all vmid's >= 1 v3: agd5f: - integrate with the semaphore/multi-ring stuff v4: - rebase on top ttm dma & multi-ring stuff - userspace is now in charge of the address space - no more specific cs vm ioctl, instead cs ioctl has a new chunk v5: - properly handle mem == NULL case from move_notify callback - fix the vm cleanup path v6: - fix update of page table to only happen on valid mem placement v7: - add tlb flush for each vm context - add flags to define mapping property (readable, writeable, snooped) - make ring id implicit from ib->fence->ring, up to each asic callback to then do ring specific scheduling if vm ib scheduling function v8: - add query for ib limit and kernel reserved virtual space - rename vm->size to max_pfn (maximum number of page) - update gem_va ioctl to also allow unmap operation - bump kernel version to allow userspace to query for vm support v9: - rebuild page table only when bind and incrementaly depending on bo referenced by cs and that have been moved - allow virtual address space to grow - use sa allocator for vram page table - return invalid when querying vm limit on non cayman GPU - dump vm fault register on lockup v10: agd5f: - Move the vm schedule_ib callback to a standalone function, remove the callback and use the existing ib_execute callback for VM IBs. v11: - rebase on top of lastest Linus v12: agd5f: - remove spurious backslash - set IB vm_id to 0 in radeon_ib_get() v13: agd5f: - fix handling of RADEON_CHUNK_ID_FLAGS v14: - fix va destruction - fix suspend resume - forbid bo to have several different va in same vm v15: - rebase v16: - cleanup left over of vm init/fini v17: agd5f: - cs checker v18: agd5f: - reworks the CS ioctl to better support multiple rings and VM. Rather than adding a new chunk id for VM, just re-use the IB chunk id and add a new flags for VM mode. Also define additional dwords for the flags chunk id to define the what ring we want to use (gfx, compute, uvd, etc.) and the priority. v19: - fix cs fini in weird case of no ib - semi working flush fix for ni - rebase on top of sa allocator changes v20: agd5f: - further CS ioctl cleanups from Christian's comments v21: agd5f: - integrate CS checker improvements v22: agd5f: - final cleanups for release, only allow VM CS on cayman Signed-off-by: Jerome Glisse Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_cs.c | 246 ++++++++++++++++++++- drivers/gpu/drm/radeon/evergreend.h | 65 +++++- drivers/gpu/drm/radeon/ni.c | 160 +++++++++++++- drivers/gpu/drm/radeon/nid.h | 2 + drivers/gpu/drm/radeon/r300.c | 6 +- drivers/gpu/drm/radeon/r600_cs.c | 8 +- drivers/gpu/drm/radeon/radeon.h | 123 ++++++++++- drivers/gpu/drm/radeon/radeon_asic.c | 20 +- drivers/gpu/drm/radeon/radeon_asic.h | 12 + drivers/gpu/drm/radeon/radeon_cs.c | 253 ++++++++++++++++----- drivers/gpu/drm/radeon/radeon_device.c | 4 + drivers/gpu/drm/radeon/radeon_drv.c | 9 +- drivers/gpu/drm/radeon/radeon_gart.c | 388 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_gem.c | 136 ++++++++++++ drivers/gpu/drm/radeon/radeon_kms.c | 47 +++- drivers/gpu/drm/radeon/radeon_object.c | 30 +++ drivers/gpu/drm/radeon/radeon_object.h | 12 + drivers/gpu/drm/radeon/radeon_ring.c | 1 + include/drm/radeon_drm.h | 36 +++ 19 files changed, 1480 insertions(+), 78 deletions(-) (limited to 'drivers/gpu/drm/radeon/r300.c') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index cd4590aae15..f7442e62c03 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -520,7 +520,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) break; case DB_Z_INFO: track->db_z_info = radeon_get_ib_value(p, idx); - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { r = evergreen_cs_packet_next_reloc(p, &reloc); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -649,7 +649,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR7_INFO: tmp = (reg - CB_COLOR0_INFO) / 0x3c; track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { r = evergreen_cs_packet_next_reloc(p, &reloc); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -666,7 +666,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR11_INFO: tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { r = evergreen_cs_packet_next_reloc(p, &reloc); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -1355,7 +1355,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { @@ -1572,3 +1572,241 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) return 0; } +/* vm parser */ +static bool evergreen_vm_reg_valid(u32 reg) +{ + /* context regs are fine */ + if (reg >= 0x28000) + return true; + + /* check config regs */ + switch (reg) { + case GRBM_GFX_INDEX: + case VGT_VTX_VECT_EJECT_REG: + case VGT_CACHE_INVALIDATION: + case VGT_GS_VERTEX_REUSE: + case VGT_PRIMITIVE_TYPE: + case VGT_INDEX_TYPE: + case VGT_NUM_INDICES: + case VGT_NUM_INSTANCES: + case VGT_COMPUTE_DIM_X: + case VGT_COMPUTE_DIM_Y: + case VGT_COMPUTE_DIM_Z: + case VGT_COMPUTE_START_X: + case VGT_COMPUTE_START_Y: + case VGT_COMPUTE_START_Z: + case VGT_COMPUTE_INDEX: + case VGT_COMPUTE_THREAD_GROUP_SIZE: + case VGT_HS_OFFCHIP_PARAM: + case PA_CL_ENHANCE: + case PA_SU_LINE_STIPPLE_VALUE: + case PA_SC_LINE_STIPPLE_STATE: + case PA_SC_ENHANCE: + case SQ_DYN_GPR_CNTL_PS_FLUSH_REQ: + case SQ_DYN_GPR_SIMD_LOCK_EN: + case SQ_CONFIG: + case SQ_GPR_RESOURCE_MGMT_1: + case SQ_GLOBAL_GPR_RESOURCE_MGMT_1: + case SQ_GLOBAL_GPR_RESOURCE_MGMT_2: + case SQ_CONST_MEM_BASE: + case SQ_STATIC_THREAD_MGMT_1: + case SQ_STATIC_THREAD_MGMT_2: + case SQ_STATIC_THREAD_MGMT_3: + case SPI_CONFIG_CNTL: + case SPI_CONFIG_CNTL_1: + case TA_CNTL_AUX: + case DB_DEBUG: + case DB_DEBUG2: + case DB_DEBUG3: + case DB_DEBUG4: + case DB_WATERMARKS: + case TD_PS_BORDER_COLOR_INDEX: + case TD_PS_BORDER_COLOR_RED: + case TD_PS_BORDER_COLOR_GREEN: + case TD_PS_BORDER_COLOR_BLUE: + case TD_PS_BORDER_COLOR_ALPHA: + case TD_VS_BORDER_COLOR_INDEX: + case TD_VS_BORDER_COLOR_RED: + case TD_VS_BORDER_COLOR_GREEN: + case TD_VS_BORDER_COLOR_BLUE: + case TD_VS_BORDER_COLOR_ALPHA: + case TD_GS_BORDER_COLOR_INDEX: + case TD_GS_BORDER_COLOR_RED: + case TD_GS_BORDER_COLOR_GREEN: + case TD_GS_BORDER_COLOR_BLUE: + case TD_GS_BORDER_COLOR_ALPHA: + case TD_HS_BORDER_COLOR_INDEX: + case TD_HS_BORDER_COLOR_RED: + case TD_HS_BORDER_COLOR_GREEN: + case TD_HS_BORDER_COLOR_BLUE: + case TD_HS_BORDER_COLOR_ALPHA: + case TD_LS_BORDER_COLOR_INDEX: + case TD_LS_BORDER_COLOR_RED: + case TD_LS_BORDER_COLOR_GREEN: + case TD_LS_BORDER_COLOR_BLUE: + case TD_LS_BORDER_COLOR_ALPHA: + case TD_CS_BORDER_COLOR_INDEX: + case TD_CS_BORDER_COLOR_RED: + case TD_CS_BORDER_COLOR_GREEN: + case TD_CS_BORDER_COLOR_BLUE: + case TD_CS_BORDER_COLOR_ALPHA: + case SQ_ESGS_RING_SIZE: + case SQ_GSVS_RING_SIZE: + case SQ_ESTMP_RING_SIZE: + case SQ_GSTMP_RING_SIZE: + case SQ_HSTMP_RING_SIZE: + case SQ_LSTMP_RING_SIZE: + case SQ_PSTMP_RING_SIZE: + case SQ_VSTMP_RING_SIZE: + case SQ_ESGS_RING_ITEMSIZE: + case SQ_ESTMP_RING_ITEMSIZE: + case SQ_GSTMP_RING_ITEMSIZE: + case SQ_GSVS_RING_ITEMSIZE: + case SQ_GS_VERT_ITEMSIZE: + case SQ_GS_VERT_ITEMSIZE_1: + case SQ_GS_VERT_ITEMSIZE_2: + case SQ_GS_VERT_ITEMSIZE_3: + case SQ_GSVS_RING_OFFSET_1: + case SQ_GSVS_RING_OFFSET_2: + case SQ_GSVS_RING_OFFSET_3: + case SQ_HSTMP_RING_ITEMSIZE: + case SQ_LSTMP_RING_ITEMSIZE: + case SQ_PSTMP_RING_ITEMSIZE: + case SQ_VSTMP_RING_ITEMSIZE: + case VGT_TF_RING_SIZE: + case SQ_ESGS_RING_BASE: + case SQ_GSVS_RING_BASE: + case SQ_ESTMP_RING_BASE: + case SQ_GSTMP_RING_BASE: + case SQ_HSTMP_RING_BASE: + case SQ_LSTMP_RING_BASE: + case SQ_PSTMP_RING_BASE: + case SQ_VSTMP_RING_BASE: + case CAYMAN_VGT_OFFCHIP_LDS_BASE: + case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: + return true; + default: + return false; + } +} + +static int evergreen_vm_packet3_check(struct radeon_device *rdev, + u32 *ib, struct radeon_cs_packet *pkt) +{ + u32 idx = pkt->idx + 1; + u32 idx_value = ib[idx]; + u32 start_reg, end_reg, reg, i; + + switch (pkt->opcode) { + case PACKET3_NOP: + case PACKET3_SET_BASE: + case PACKET3_CLEAR_STATE: + case PACKET3_INDEX_BUFFER_SIZE: + case PACKET3_DISPATCH_DIRECT: + case PACKET3_DISPATCH_INDIRECT: + case PACKET3_MODE_CONTROL: + case PACKET3_SET_PREDICATION: + case PACKET3_COND_EXEC: + case PACKET3_PRED_EXEC: + case PACKET3_DRAW_INDIRECT: + case PACKET3_DRAW_INDEX_INDIRECT: + case PACKET3_INDEX_BASE: + case PACKET3_DRAW_INDEX_2: + case PACKET3_CONTEXT_CONTROL: + case PACKET3_DRAW_INDEX_OFFSET: + case PACKET3_INDEX_TYPE: + case PACKET3_DRAW_INDEX: + case PACKET3_DRAW_INDEX_AUTO: + case PACKET3_DRAW_INDEX_IMMD: + case PACKET3_NUM_INSTANCES: + case PACKET3_DRAW_INDEX_MULTI_AUTO: + case PACKET3_STRMOUT_BUFFER_UPDATE: + case PACKET3_DRAW_INDEX_OFFSET_2: + case PACKET3_DRAW_INDEX_MULTI_ELEMENT: + case PACKET3_MPEG_INDEX: + case PACKET3_WAIT_REG_MEM: + case PACKET3_MEM_WRITE: + case PACKET3_SURFACE_SYNC: + case PACKET3_EVENT_WRITE: + case PACKET3_EVENT_WRITE_EOP: + case PACKET3_EVENT_WRITE_EOS: + case PACKET3_SET_CONTEXT_REG: + case PACKET3_SET_BOOL_CONST: + case PACKET3_SET_LOOP_CONST: + case PACKET3_SET_RESOURCE: + case PACKET3_SET_SAMPLER: + case PACKET3_SET_CTL_CONST: + case PACKET3_SET_RESOURCE_OFFSET: + case PACKET3_SET_CONTEXT_REG_INDIRECT: + case PACKET3_SET_RESOURCE_INDIRECT: + case CAYMAN_PACKET3_DEALLOC_STATE: + break; + case PACKET3_COND_WRITE: + if (idx_value & 0x100) { + reg = ib[idx + 5] * 4; + if (!evergreen_vm_reg_valid(reg)) + return -EINVAL; + } + break; + case PACKET3_COPY_DW: + if (idx_value & 0x2) { + reg = ib[idx + 3] * 4; + if (!evergreen_vm_reg_valid(reg)) + return -EINVAL; + } + break; + case PACKET3_SET_CONFIG_REG: + start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; + end_reg = 4 * pkt->count + start_reg - 4; + if ((start_reg < PACKET3_SET_CONFIG_REG_START) || + (start_reg >= PACKET3_SET_CONFIG_REG_END) || + (end_reg >= PACKET3_SET_CONFIG_REG_END)) { + DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); + return -EINVAL; + } + for (i = 0; i < pkt->count; i++) { + reg = start_reg + (4 * i); + if (!evergreen_vm_reg_valid(reg)) + return -EINVAL; + } + break; + default: + return -EINVAL; + } + return 0; +} + +int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) +{ + int ret = 0; + u32 idx = 0; + struct radeon_cs_packet pkt; + + do { + pkt.idx = idx; + pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]); + pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]); + pkt.one_reg_wr = 0; + switch (pkt.type) { + case PACKET_TYPE0: + dev_err(rdev->dev, "Packet0 not allowed!\n"); + ret = -EINVAL; + break; + case PACKET_TYPE2: + break; + case PACKET_TYPE3: + pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); + ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); + break; + default: + dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type); + ret = -EINVAL; + break; + } + if (ret) + break; + idx += pkt.count + 2; + } while (idx < ib->length_dw); + + return ret; +} diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index e00039e59a7..b502216d42a 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -242,6 +242,7 @@ #define PA_CL_ENHANCE 0x8A14 #define CLIP_VTX_REORDER_ENA (1 << 0) #define NUM_CLIP_SEQ(x) ((x) << 1) +#define PA_SC_ENHANCE 0x8BF0 #define PA_SC_AA_CONFIG 0x28C04 #define MSAA_NUM_SAMPLES_SHIFT 0 #define MSAA_NUM_SAMPLES_MASK 0x3 @@ -319,6 +320,8 @@ #define SQ_GPR_RESOURCE_MGMT_3 0x8C0C #define NUM_HS_GPRS(x) ((x) << 0) #define NUM_LS_GPRS(x) ((x) << 16) +#define SQ_GLOBAL_GPR_RESOURCE_MGMT_1 0x8C10 +#define SQ_GLOBAL_GPR_RESOURCE_MGMT_2 0x8C14 #define SQ_THREAD_RESOURCE_MGMT 0x8C18 #define NUM_PS_THREADS(x) ((x) << 0) #define NUM_VS_THREADS(x) ((x) << 8) @@ -337,6 +340,10 @@ #define NUM_HS_STACK_ENTRIES(x) ((x) << 0) #define NUM_LS_STACK_ENTRIES(x) ((x) << 16) #define SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 0x8D8C +#define SQ_DYN_GPR_SIMD_LOCK_EN 0x8D94 +#define SQ_STATIC_THREAD_MGMT_1 0x8E20 +#define SQ_STATIC_THREAD_MGMT_2 0x8E24 +#define SQ_STATIC_THREAD_MGMT_3 0x8E28 #define SQ_LDS_RESOURCE_MGMT 0x8E2C #define SQ_MS_FIFO_SIZES 0x8CF0 @@ -691,6 +698,7 @@ #define PACKET3_DRAW_INDEX_MULTI_ELEMENT 0x36 #define PACKET3_MEM_SEMAPHORE 0x39 #define PACKET3_MPEG_INDEX 0x3A +#define PACKET3_COPY_DW 0x3B #define PACKET3_WAIT_REG_MEM 0x3C #define PACKET3_MEM_WRITE 0x3D #define PACKET3_INDIRECT_BUFFER 0x32 @@ -768,6 +776,8 @@ #define SQ_TEX_VTX_VALID_TEXTURE 0x2 #define SQ_TEX_VTX_VALID_BUFFER 0x3 +#define VGT_VTX_VECT_EJECT_REG 0x88b0 + #define SQ_CONST_MEM_BASE 0x8df8 #define SQ_ESGS_RING_BASE 0x8c40 @@ -892,8 +902,27 @@ #define PA_SC_SCREEN_SCISSOR_TL 0x28030 #define PA_SC_GENERIC_SCISSOR_TL 0x28240 #define PA_SC_WINDOW_SCISSOR_TL 0x28204 -#define VGT_PRIMITIVE_TYPE 0x8958 +#define VGT_PRIMITIVE_TYPE 0x8958 +#define VGT_INDEX_TYPE 0x895C + +#define VGT_NUM_INDICES 0x8970 + +#define VGT_COMPUTE_DIM_X 0x8990 +#define VGT_COMPUTE_DIM_Y 0x8994 +#define VGT_COMPUTE_DIM_Z 0x8998 +#define VGT_COMPUTE_START_X 0x899C +#define VGT_COMPUTE_START_Y 0x89A0 +#define VGT_COMPUTE_START_Z 0x89A4 +#define VGT_COMPUTE_INDEX 0x89A8 +#define VGT_COMPUTE_THREAD_GROUP_SIZE 0x89AC +#define VGT_HS_OFFCHIP_PARAM 0x89B0 + +#define DB_DEBUG 0x9830 +#define DB_DEBUG2 0x9834 +#define DB_DEBUG3 0x9838 +#define DB_DEBUG4 0x983C +#define DB_WATERMARKS 0x9854 #define DB_DEPTH_CONTROL 0x28800 #define DB_DEPTH_VIEW 0x28008 #define DB_HTILE_DATA_BASE 0x28014 @@ -1189,8 +1218,40 @@ #define SQ_VTX_CONSTANT_WORD6_0 0x30018 #define SQ_VTX_CONSTANT_WORD7_0 0x3001c +#define TD_PS_BORDER_COLOR_INDEX 0xA400 +#define TD_PS_BORDER_COLOR_RED 0xA404 +#define TD_PS_BORDER_COLOR_GREEN 0xA408 +#define TD_PS_BORDER_COLOR_BLUE 0xA40C +#define TD_PS_BORDER_COLOR_ALPHA 0xA410 +#define TD_VS_BORDER_COLOR_INDEX 0xA414 +#define TD_VS_BORDER_COLOR_RED 0xA418 +#define TD_VS_BORDER_COLOR_GREEN 0xA41C +#define TD_VS_BORDER_COLOR_BLUE 0xA420 +#define TD_VS_BORDER_COLOR_ALPHA 0xA424 +#define TD_GS_BORDER_COLOR_INDEX 0xA428 +#define TD_GS_BORDER_COLOR_RED 0xA42C +#define TD_GS_BORDER_COLOR_GREEN 0xA430 +#define TD_GS_BORDER_COLOR_BLUE 0xA434 +#define TD_GS_BORDER_COLOR_ALPHA 0xA438 +#define TD_HS_BORDER_COLOR_INDEX 0xA43C +#define TD_HS_BORDER_COLOR_RED 0xA440 +#define TD_HS_BORDER_COLOR_GREEN 0xA444 +#define TD_HS_BORDER_COLOR_BLUE 0xA448 +#define TD_HS_BORDER_COLOR_ALPHA 0xA44C +#define TD_LS_BORDER_COLOR_INDEX 0xA450 +#define TD_LS_BORDER_COLOR_RED 0xA454 +#define TD_LS_BORDER_COLOR_GREEN 0xA458 +#define TD_LS_BORDER_COLOR_BLUE 0xA45C +#define TD_LS_BORDER_COLOR_ALPHA 0xA460 +#define TD_CS_BORDER_COLOR_INDEX 0xA464 +#define TD_CS_BORDER_COLOR_RED 0xA468 +#define TD_CS_BORDER_COLOR_GREEN 0xA46C +#define TD_CS_BORDER_COLOR_BLUE 0xA470 +#define TD_CS_BORDER_COLOR_ALPHA 0xA474 + /* cayman 3D regs */ -#define CAYMAN_VGT_OFFCHIP_LDS_BASE 0x89B0 +#define CAYMAN_VGT_OFFCHIP_LDS_BASE 0x89B4 +#define CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS 0x8E48 #define CAYMAN_DB_EQAA 0x28804 #define CAYMAN_DB_DEPTH_INFO 0x2803C #define CAYMAN_PA_SC_AA_CONFIG 0x28BE0 diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index d89b2ebd5bb..32113729540 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -934,7 +934,7 @@ void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev) int cayman_pcie_gart_enable(struct radeon_device *rdev) { - int r; + int i, r; if (rdev->gart.robj == NULL) { dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); @@ -945,9 +945,12 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) return r; radeon_gart_restore(rdev); /* Setup TLB control */ - WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_TLB | + WREG32(MC_VM_MX_L1_TLB_CNTL, + (0xA << 7) | + ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | SYSTEM_ACCESS_MODE_NOT_IN_SYS | + ENABLE_ADVANCED_DRIVER_MODEL | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); /* Setup L2 cache */ WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | @@ -967,9 +970,26 @@ int cayman_pcie_gart_enable(struct radeon_device *rdev) WREG32(VM_CONTEXT0_CNTL2, 0); WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); - /* disable context1-7 */ + + WREG32(0x15D4, 0); + WREG32(0x15D8, 0); + WREG32(0x15DC, 0); + + /* empty context1-7 */ + for (i = 1; i < 8; i++) { + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), 0); + WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), + rdev->gart.table_addr >> 12); + } + + /* enable context1-7 */ + WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, + (u32)(rdev->dummy_page.addr >> 12)); WREG32(VM_CONTEXT1_CNTL2, 0); WREG32(VM_CONTEXT1_CNTL, 0); + WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | + RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); cayman_pcie_gart_tlb_flush(rdev); DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", @@ -1024,7 +1044,10 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, struct radeon_ring *ring = &rdev->ring[fence->ring]; u64 addr = rdev->fence_drv[fence->ring].gpu_addr; - /* flush read cache over gart */ + /* flush read cache over gart for this vmid */ + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, 0); radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); radeon_ring_write(ring, 0xFFFFFFFF); @@ -1039,6 +1062,33 @@ void cayman_fence_ring_emit(struct radeon_device *rdev, radeon_ring_write(ring, 0); } +void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) +{ + struct radeon_ring *ring = &rdev->ring[ib->fence->ring]; + + /* set to DX10/11 mode */ + radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); + radeon_ring_write(ring, 1); + 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(ring, upper_32_bits(ib->gpu_addr) & 0xFF); + radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24)); + + /* flush read cache over gart for this vmid */ + radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); + radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); + radeon_ring_write(ring, ib->vm_id); + radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); + radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); + radeon_ring_write(ring, 0xFFFFFFFF); + radeon_ring_write(ring, 0); + radeon_ring_write(ring, 10); /* poll interval */ +} + static void cayman_cp_enable(struct radeon_device *rdev, bool enable) { if (enable) @@ -1324,6 +1374,15 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) RREG32(GRBM_STATUS_SE1)); dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", RREG32(SRBM_STATUS)); + dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", + RREG32(0x14F8)); + dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", + RREG32(0x14D8)); + dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", + RREG32(0x14FC)); + dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", + RREG32(0x14DC)); + evergreen_mc_stop(rdev, &save); if (evergreen_mc_wait_for_idle(rdev)) { dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); @@ -1354,6 +1413,7 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) (void)RREG32(GRBM_SOFT_RESET); /* Wait a little for things to settle down */ udelay(50); + dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", RREG32(GRBM_STATUS)); dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", @@ -1464,6 +1524,10 @@ static int cayman_startup(struct radeon_device *rdev) return r; } + r = radeon_vm_manager_start(rdev); + if (r) + return r; + return 0; } @@ -1491,6 +1555,7 @@ int cayman_suspend(struct radeon_device *rdev) { /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); + radeon_vm_manager_suspend(rdev); r600_blit_suspend(rdev); cayman_cp_enable(rdev, false); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; @@ -1577,6 +1642,10 @@ int cayman_init(struct radeon_device *rdev) dev_err(rdev->dev, "IB initialization failed (%d).\n", r); rdev->accel_working = false; } + r = radeon_vm_manager_init(rdev); + if (r) { + dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); + } r = cayman_startup(rdev); if (r) { @@ -1585,6 +1654,7 @@ int cayman_init(struct radeon_device *rdev) r600_irq_fini(rdev); radeon_wb_fini(rdev); r100_ib_fini(rdev); + radeon_vm_manager_fini(rdev); radeon_irq_kms_fini(rdev); cayman_pcie_gart_fini(rdev); rdev->accel_working = false; @@ -1608,6 +1678,7 @@ void cayman_fini(struct radeon_device *rdev) cayman_cp_fini(rdev); r600_irq_fini(rdev); radeon_wb_fini(rdev); + radeon_vm_manager_fini(rdev); r100_ib_fini(rdev); radeon_irq_kms_fini(rdev); cayman_pcie_gart_fini(rdev); @@ -1621,3 +1692,84 @@ void cayman_fini(struct radeon_device *rdev) rdev->bios = NULL; } +/* + * vm + */ +int cayman_vm_init(struct radeon_device *rdev) +{ + /* number of VMs */ + rdev->vm_manager.nvm = 8; + /* base offset of vram pages */ + rdev->vm_manager.vram_base_offset = 0; + return 0; +} + +void cayman_vm_fini(struct radeon_device *rdev) +{ +} + +int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id) +{ + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (id << 2), 0); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (id << 2), vm->last_pfn); + WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12); + /* flush hdp cache */ + WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + /* bits 0-7 are the VM contexts0-7 */ + WREG32(VM_INVALIDATE_REQUEST, 1 << id); + return 0; +} + +void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) +{ + WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (vm->id << 2), 0); + WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (vm->id << 2), 0); + WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0); + /* flush hdp cache */ + WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + /* bits 0-7 are the VM contexts0-7 */ + WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); +} + +void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm) +{ + if (vm->id == -1) + return; + + /* flush hdp cache */ + WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); + /* bits 0-7 are the VM contexts0-7 */ + WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id); +} + +#define R600_PTE_VALID (1 << 0) +#define R600_PTE_SYSTEM (1 << 1) +#define R600_PTE_SNOOPED (1 << 2) +#define R600_PTE_READABLE (1 << 5) +#define R600_PTE_WRITEABLE (1 << 6) + +uint32_t cayman_vm_page_flags(struct radeon_device *rdev, + struct radeon_vm *vm, + uint32_t flags) +{ + uint32_t r600_flags = 0; + + r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0; + r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; + r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; + if (flags & RADEON_VM_PAGE_SYSTEM) { + r600_flags |= R600_PTE_SYSTEM; + r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; + } + return r600_flags; +} + +void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, + unsigned pfn, uint64_t addr, uint32_t flags) +{ + void __iomem *ptr = (void *)vm->pt; + + addr = addr & 0xFFFFFFFFFFFFF000ULL; + addr |= flags; + writeq(addr, ptr + (pfn * 8)); +} diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 0d3f52cff2f..f9df2a645e7 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -222,6 +222,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 #define CP_SEM_WAIT_TIMER 0x85BC +#define CP_COHER_CNTL2 0x85E8 #define CP_ME_CNTL 0x86D8 #define CP_ME_HALT (1 << 28) #define CP_PFP_HALT (1 << 26) @@ -458,6 +459,7 @@ #define PACKET3_DISPATCH_DIRECT 0x15 #define PACKET3_DISPATCH_INDIRECT 0x16 #define PACKET3_INDIRECT_BUFFER_END 0x17 +#define PACKET3_MODE_CONTROL 0x18 #define PACKET3_SET_PREDICATION 0x20 #define PACKET3_REG_RMW 0x21 #define PACKET3_COND_EXEC 0x22 diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 8ad5c6475d5..3fc0d29a5f3 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -704,7 +704,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, return r; } - if (p->keep_tiling_flags) { + if (p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) { ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); } else { @@ -768,7 +768,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, /* RB3D_COLORPITCH1 */ /* RB3D_COLORPITCH2 */ /* RB3D_COLORPITCH3 */ - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { r = r100_cs_packet_next_reloc(p, &reloc); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", @@ -853,7 +853,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, break; case 0x4F24: /* ZB_DEPTHPITCH */ - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { r = r100_cs_packet_next_reloc(p, &reloc); if (r) { DRM_ERROR("No reloc for ib[%d]=0x%04X\n", diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index cb1acffd243..38ce5d0427e 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -941,7 +941,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_depth_control = radeon_get_ib_value(p, idx); break; case R_028010_DB_DEPTH_INFO: - if (!p->keep_tiling_flags && + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && r600_cs_packet_next_is_pkt3_nop(p)) { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { @@ -993,7 +993,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_0280B4_CB_COLOR5_INFO: case R_0280B8_CB_COLOR6_INFO: case R_0280BC_CB_COLOR7_INFO: - if (!p->keep_tiling_flags && + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS) && r600_cs_packet_next_is_pkt3_nop(p)) { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { @@ -1293,7 +1293,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, mip_offset <<= 8; word0 = radeon_get_ib_value(p, idx + 0); - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { if (tiling_flags & RADEON_TILING_MACRO) word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); else if (tiling_flags & RADEON_TILING_MICRO) @@ -1625,7 +1625,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - if (!p->keep_tiling_flags) { + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 374f9a4d94e..5e3542384b2 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -118,6 +118,10 @@ extern int radeon_msi; #define CAYMAN_RING_TYPE_CP1_INDEX 1 #define CAYMAN_RING_TYPE_CP2_INDEX 2 +/* hardcode those limit for now */ +#define RADEON_VA_RESERVED_SIZE (8 << 20) +#define RADEON_IB_VM_MAX_SIZE (64 << 10) + /* * Errata workarounds. */ @@ -262,6 +266,21 @@ struct radeon_mman { bool initialized; }; +/* bo virtual address in a specific vm */ +struct radeon_bo_va { + /* bo list is protected by bo being reserved */ + struct list_head bo_list; + /* vm list is protected by vm mutex */ + struct list_head vm_list; + /* constant after initialization */ + struct radeon_vm *vm; + struct radeon_bo *bo; + uint64_t soffset; + uint64_t eoffset; + uint32_t flags; + bool valid; +}; + struct radeon_bo { /* Protected by gem.mutex */ struct list_head list; @@ -275,6 +294,10 @@ struct radeon_bo { u32 tiling_flags; u32 pitch; int surface_reg; + /* list of all virtual address to which this bo + * is associated to + */ + struct list_head va; /* Constant after initialization */ struct radeon_device *rdev; struct drm_gem_object gem_base; @@ -408,6 +431,7 @@ struct radeon_mc; #define RADEON_GPU_PAGE_SIZE 4096 #define RADEON_GPU_PAGE_MASK (RADEON_GPU_PAGE_SIZE - 1) #define RADEON_GPU_PAGE_SHIFT 12 +#define RADEON_GPU_PAGE_ALIGN(a) (((a) + RADEON_GPU_PAGE_MASK) & ~RADEON_GPU_PAGE_MASK) struct radeon_gart { dma_addr_t table_addr; @@ -565,6 +589,7 @@ struct radeon_ib { uint64_t gpu_addr; uint32_t *ptr; struct radeon_fence *fence; + unsigned vm_id; }; /* @@ -601,6 +626,56 @@ struct radeon_ring { u32 nop; }; +/* + * VM + */ +struct radeon_vm { + struct list_head list; + struct list_head va; + int id; + unsigned last_pfn; + u64 pt_gpu_addr; + u64 *pt; + struct radeon_sa_bo sa_bo; + struct mutex mutex; + /* last fence for cs using this vm */ + struct radeon_fence *fence; +}; + +struct radeon_vm_funcs { + int (*init)(struct radeon_device *rdev); + void (*fini)(struct radeon_device *rdev); + /* cs mutex must be lock for schedule_ib */ + int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id); + void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm); + void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm); + uint32_t (*page_flags)(struct radeon_device *rdev, + struct radeon_vm *vm, + uint32_t flags); + void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm, + unsigned pfn, uint64_t addr, uint32_t flags); +}; + +struct radeon_vm_manager { + struct list_head lru_vm; + uint32_t use_bitmap; + struct radeon_sa_manager sa_manager; + uint32_t max_pfn; + /* fields constant after init */ + const struct radeon_vm_funcs *funcs; + /* number of VMIDs */ + unsigned nvm; + /* vram base address for page table entry */ + u64 vram_base_offset; +}; + +/* + * file private structure + */ +struct radeon_fpriv { + struct radeon_vm vm; +}; + /* * R6xx+ IH ring */ @@ -691,12 +766,12 @@ struct radeon_cs_reloc { struct radeon_cs_chunk { uint32_t chunk_id; uint32_t length_dw; - int kpage_idx[2]; - uint32_t *kpage[2]; + int kpage_idx[2]; + uint32_t *kpage[2]; uint32_t *kdata; - void __user *user_ptr; - int last_copied_page; - int last_page_index; + void __user *user_ptr; + int last_copied_page; + int last_page_index; }; struct radeon_cs_parser { @@ -717,11 +792,14 @@ struct radeon_cs_parser { /* indices of various chunks */ int chunk_ib_idx; int chunk_relocs_idx; + int chunk_flags_idx; struct radeon_ib *ib; void *track; unsigned family; int parser_error; - bool keep_tiling_flags; + u32 cs_flags; + u32 ring; + s32 priority; }; extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); @@ -1018,6 +1096,7 @@ struct radeon_asic { struct { void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); + int (*ib_parse)(struct radeon_device *rdev, struct radeon_ib *ib); void (*emit_fence)(struct radeon_device *rdev, struct radeon_fence *fence); void (*emit_semaphore)(struct radeon_device *rdev, struct radeon_ring *cp, struct radeon_semaphore *semaphore, bool emit_wait); @@ -1255,6 +1334,8 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int radeon_gem_va_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); @@ -1404,6 +1485,8 @@ struct radeon_device { /* debugfs */ struct radeon_debugfs debugfs[RADEON_DEBUGFS_MAX_COMPONENTS]; unsigned debugfs_count; + /* virtual memory */ + struct radeon_vm_manager vm_manager; }; int radeon_device_init(struct radeon_device *rdev, @@ -1568,6 +1651,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) #define radeon_ring_test(rdev, cp) (rdev)->asic->ring_test((rdev), (cp)) #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib)) +#define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib)) #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) @@ -1626,6 +1710,33 @@ extern int radeon_resume_kms(struct drm_device *dev); extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); +/* + * vm + */ +int radeon_vm_manager_init(struct radeon_device *rdev); +void radeon_vm_manager_fini(struct radeon_device *rdev); +int radeon_vm_manager_start(struct radeon_device *rdev); +int radeon_vm_manager_suspend(struct radeon_device *rdev); +int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); +void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); +int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); +void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); +int radeon_vm_bo_update_pte(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_bo *bo, + struct ttm_mem_reg *mem); +void radeon_vm_bo_invalidate(struct radeon_device *rdev, + struct radeon_bo *bo); +int radeon_vm_bo_add(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_bo *bo, + uint64_t offset, + uint32_t flags); +int radeon_vm_bo_rmv(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_bo *bo); + + /* * R600 vram scratch functions */ diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 8493d406f5e..123a1969d28 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -952,6 +952,16 @@ static struct radeon_asic btc_asic = { .post_page_flip = &evergreen_post_page_flip, }; +static const struct radeon_vm_funcs cayman_vm_funcs = { + .init = &cayman_vm_init, + .fini = &cayman_vm_fini, + .bind = &cayman_vm_bind, + .unbind = &cayman_vm_unbind, + .tlb_flush = &cayman_vm_tlb_flush, + .page_flags = &cayman_vm_page_flags, + .set_page = &cayman_vm_set_page, +}; + static struct radeon_asic cayman_asic = { .init = &cayman_init, .fini = &cayman_fini, @@ -965,17 +975,20 @@ static struct radeon_asic cayman_asic = { .ring_test = &r600_ring_test, .ring = { [RADEON_RING_TYPE_GFX_INDEX] = { - .ib_execute = &evergreen_ring_ib_execute, + .ib_execute = &cayman_ring_ib_execute, + .ib_parse = &evergreen_ib_parse, .emit_fence = &cayman_fence_ring_emit, .emit_semaphore = &r600_semaphore_ring_emit, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { - .ib_execute = &r600_ring_ib_execute, + .ib_execute = &cayman_ring_ib_execute, + .ib_parse = &evergreen_ib_parse, .emit_fence = &cayman_fence_ring_emit, .emit_semaphore = &r600_semaphore_ring_emit, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { - .ib_execute = &r600_ring_ib_execute, + .ib_execute = &cayman_ring_ib_execute, + .ib_parse = &evergreen_ib_parse, .emit_fence = &cayman_fence_ring_emit, .emit_semaphore = &r600_semaphore_ring_emit, } @@ -1128,6 +1141,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->asic = &cayman_asic; /* set num crtcs */ rdev->num_crtc = 6; + rdev->vm_manager.funcs = &cayman_vm_funcs; break; default: /* FIXME: not supported yet */ diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c002ed1c448..6304aef0d9b 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -438,5 +438,17 @@ int cayman_suspend(struct radeon_device *rdev); int cayman_resume(struct radeon_device *rdev); bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); int cayman_asic_reset(struct radeon_device *rdev); +void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); +int cayman_vm_init(struct radeon_device *rdev); +void cayman_vm_fini(struct radeon_device *rdev); +int cayman_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); +void cayman_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); +void cayman_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); +uint32_t cayman_vm_page_flags(struct radeon_device *rdev, + struct radeon_vm *vm, + uint32_t flags); +void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, + unsigned pfn, uint64_t addr, uint32_t flags); +int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); #endif diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 6559cc45513..4d595403b50 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -90,11 +90,32 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) return radeon_bo_list_validate(&p->validated); } +static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority) +{ + p->priority = priority; + + switch (ring) { + default: + DRM_ERROR("unknown ring id: %d\n", ring); + return -EINVAL; + case RADEON_CS_RING_GFX: + p->ring = RADEON_RING_TYPE_GFX_INDEX; + break; + case RADEON_CS_RING_COMPUTE: + /* for now */ + p->ring = RADEON_RING_TYPE_GFX_INDEX; + break; + } + return 0; +} + int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) { struct drm_radeon_cs *cs = data; uint64_t *chunk_array_ptr; - unsigned size, i, flags = 0; + unsigned size, i; + u32 ring = RADEON_CS_RING_GFX; + s32 priority = 0; if (!cs->num_chunks) { return 0; @@ -104,6 +125,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->idx = 0; p->chunk_ib_idx = -1; p->chunk_relocs_idx = -1; + p->chunk_flags_idx = -1; p->chunks_array = kcalloc(cs->num_chunks, sizeof(uint64_t), GFP_KERNEL); if (p->chunks_array == NULL) { return -ENOMEM; @@ -113,6 +135,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) sizeof(uint64_t)*cs->num_chunks)) { return -EFAULT; } + p->cs_flags = 0; p->nchunks = cs->num_chunks; p->chunks = kcalloc(p->nchunks, sizeof(struct radeon_cs_chunk), GFP_KERNEL); if (p->chunks == NULL) { @@ -141,16 +164,19 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) if (p->chunks[i].length_dw == 0) return -EINVAL; } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS && - !p->chunks[i].length_dw) { - return -EINVAL; + if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { + p->chunk_flags_idx = i; + /* zero length flags aren't useful */ + if (p->chunks[i].length_dw == 0) + return -EINVAL; } p->chunks[i].length_dw = user_chunk.length_dw; p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; - if (p->chunks[i].chunk_id != RADEON_CHUNK_ID_IB) { + if ((p->chunks[i].chunk_id == RADEON_CHUNK_ID_RELOCS) || + (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS)) { size = p->chunks[i].length_dw * sizeof(uint32_t); p->chunks[i].kdata = kmalloc(size, GFP_KERNEL); if (p->chunks[i].kdata == NULL) { @@ -161,29 +187,58 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) return -EFAULT; } if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { - flags = p->chunks[i].kdata[0]; + p->cs_flags = p->chunks[i].kdata[0]; + if (p->chunks[i].length_dw > 1) + ring = p->chunks[i].kdata[1]; + if (p->chunks[i].length_dw > 2) + priority = (s32)p->chunks[i].kdata[2]; } - } else { - p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); - p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (p->chunks[i].kpage[0] == NULL || p->chunks[i].kpage[1] == NULL) { - kfree(p->chunks[i].kpage[0]); - kfree(p->chunks[i].kpage[1]); - return -ENOMEM; - } - p->chunks[i].kpage_idx[0] = -1; - p->chunks[i].kpage_idx[1] = -1; - p->chunks[i].last_copied_page = -1; - p->chunks[i].last_page_index = ((p->chunks[i].length_dw * 4) - 1) / PAGE_SIZE; } } - if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) { - DRM_ERROR("cs IB too big: %d\n", - p->chunks[p->chunk_ib_idx].length_dw); + + if ((p->cs_flags & RADEON_CS_USE_VM) && + (p->rdev->family < CHIP_CAYMAN)) { + DRM_ERROR("VM not supported on asic!\n"); + if (p->chunk_relocs_idx != -1) + kfree(p->chunks[p->chunk_relocs_idx].kdata); + if (p->chunk_flags_idx != -1) + kfree(p->chunks[p->chunk_flags_idx].kdata); return -EINVAL; } - p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0; + if (radeon_cs_get_ring(p, ring, priority)) { + if (p->chunk_relocs_idx != -1) + kfree(p->chunks[p->chunk_relocs_idx].kdata); + if (p->chunk_flags_idx != -1) + kfree(p->chunks[p->chunk_flags_idx].kdata); + return -EINVAL; + } + + + /* deal with non-vm */ + if ((p->chunk_ib_idx != -1) && + ((p->cs_flags & RADEON_CS_USE_VM) == 0) && + (p->chunks[p->chunk_ib_idx].chunk_id == RADEON_CHUNK_ID_IB)) { + if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) { + DRM_ERROR("cs IB too big: %d\n", + p->chunks[p->chunk_ib_idx].length_dw); + return -EINVAL; + } + p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); + p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || + p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { + kfree(p->chunks[p->chunk_ib_idx].kpage[0]); + kfree(p->chunks[p->chunk_ib_idx].kpage[1]); + return -ENOMEM; + } + p->chunks[p->chunk_ib_idx].kpage_idx[0] = -1; + p->chunks[p->chunk_ib_idx].kpage_idx[1] = -1; + p->chunks[p->chunk_ib_idx].last_copied_page = -1; + p->chunks[p->chunk_ib_idx].last_page_index = + ((p->chunks[p->chunk_ib_idx].length_dw * 4) - 1) / PAGE_SIZE; + } + return 0; } @@ -225,11 +280,131 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) radeon_ib_free(parser->rdev, &parser->ib); } +static int radeon_cs_ib_chunk(struct radeon_device *rdev, + struct radeon_cs_parser *parser) +{ + struct radeon_cs_chunk *ib_chunk; + int r; + + if (parser->chunk_ib_idx == -1) + return 0; + + if (parser->cs_flags & RADEON_CS_USE_VM) + return 0; + + ib_chunk = &parser->chunks[parser->chunk_ib_idx]; + /* Copy the packet into the IB, the parser will read from the + * input memory (cached) and write to the IB (which can be + * uncached). + */ + r = radeon_ib_get(rdev, parser->ring, &parser->ib, + ib_chunk->length_dw * 4); + if (r) { + DRM_ERROR("Failed to get ib !\n"); + return r; + } + parser->ib->length_dw = ib_chunk->length_dw; + r = radeon_cs_parse(parser); + if (r || parser->parser_error) { + DRM_ERROR("Invalid command stream !\n"); + return r; + } + r = radeon_cs_finish_pages(parser); + if (r) { + DRM_ERROR("Invalid command stream !\n"); + return r; + } + parser->ib->vm_id = 0; + r = radeon_ib_schedule(rdev, parser->ib); + if (r) { + DRM_ERROR("Failed to schedule IB !\n"); + } + return 0; +} + +static int radeon_bo_vm_update_pte(struct radeon_cs_parser *parser, + struct radeon_vm *vm) +{ + struct radeon_bo_list *lobj; + struct radeon_bo *bo; + int r; + + list_for_each_entry(lobj, &parser->validated, tv.head) { + bo = lobj->bo; + r = radeon_vm_bo_update_pte(parser->rdev, vm, bo, &bo->tbo.mem); + if (r) { + return r; + } + } + return 0; +} + +static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, + struct radeon_cs_parser *parser) +{ + struct radeon_cs_chunk *ib_chunk; + struct radeon_fpriv *fpriv = parser->filp->driver_priv; + struct radeon_vm *vm = &fpriv->vm; + int r; + + if (parser->chunk_ib_idx == -1) + return 0; + + if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) + return 0; + + ib_chunk = &parser->chunks[parser->chunk_ib_idx]; + if (ib_chunk->length_dw > RADEON_IB_VM_MAX_SIZE) { + DRM_ERROR("cs IB too big: %d\n", ib_chunk->length_dw); + return -EINVAL; + } + r = radeon_ib_get(rdev, parser->ring, &parser->ib, + ib_chunk->length_dw * 4); + if (r) { + DRM_ERROR("Failed to get ib !\n"); + return r; + } + parser->ib->length_dw = ib_chunk->length_dw; + /* Copy the packet into the IB */ + if (DRM_COPY_FROM_USER(parser->ib->ptr, ib_chunk->user_ptr, + ib_chunk->length_dw * 4)) { + return -EFAULT; + } + r = radeon_ring_ib_parse(rdev, parser->ring, parser->ib); + if (r) { + return r; + } + + mutex_lock(&vm->mutex); + r = radeon_vm_bind(rdev, vm); + if (r) { + goto out; + } + r = radeon_bo_vm_update_pte(parser, vm); + if (r) { + goto out; + } + parser->ib->vm_id = vm->id; + /* ib pool is bind at 0 in virtual address space to gpu_addr is the + * offset inside the pool bo + */ + parser->ib->gpu_addr = parser->ib->sa_bo.offset; + r = radeon_ib_schedule(rdev, parser->ib); +out: + if (!r) { + if (vm->fence) { + radeon_fence_unref(&vm->fence); + } + vm->fence = radeon_fence_ref(parser->ib->fence); + } + mutex_unlock(&fpriv->vm.mutex); + return r; +} + int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct radeon_device *rdev = dev->dev_private; struct radeon_cs_parser parser; - struct radeon_cs_chunk *ib_chunk; int r; radeon_mutex_lock(&rdev->cs_mutex); @@ -246,15 +421,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) radeon_mutex_unlock(&rdev->cs_mutex); return r; } - ib_chunk = &parser.chunks[parser.chunk_ib_idx]; - r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &parser.ib, - ib_chunk->length_dw * 4); - if (r) { - DRM_ERROR("Failed to get ib !\n"); - radeon_cs_parser_fini(&parser, r); - radeon_mutex_unlock(&rdev->cs_mutex); - return r; - } r = radeon_cs_parser_relocs(&parser); if (r) { if (r != -ERESTARTSYS) @@ -263,28 +429,15 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) radeon_mutex_unlock(&rdev->cs_mutex); return r; } - /* Copy the packet into the IB, the parser will read from the - * input memory (cached) and write to the IB (which can be - * uncached). */ - parser.ib->length_dw = ib_chunk->length_dw; - r = radeon_cs_parse(&parser); - if (r || parser.parser_error) { - DRM_ERROR("Invalid command stream !\n"); - radeon_cs_parser_fini(&parser, r); - radeon_mutex_unlock(&rdev->cs_mutex); - return r; - } - r = radeon_cs_finish_pages(&parser); + r = radeon_cs_ib_chunk(rdev, &parser); if (r) { - DRM_ERROR("Invalid command stream !\n"); - radeon_cs_parser_fini(&parser, r); - radeon_mutex_unlock(&rdev->cs_mutex); - return r; + goto out; } - r = radeon_ib_schedule(rdev, parser.ib); + r = radeon_cs_ib_vm_chunk(rdev, &parser); if (r) { - DRM_ERROR("Failed to schedule IB !\n"); + goto out; } +out: radeon_cs_parser_fini(&parser, r); radeon_mutex_unlock(&rdev->cs_mutex); return r; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 79b08b48729..0afb13bd8dc 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -735,6 +735,10 @@ int radeon_device_init(struct radeon_device *rdev, init_waitqueue_head(&rdev->irq.vblank_queue); init_waitqueue_head(&rdev->irq.idle_queue); INIT_LIST_HEAD(&rdev->semaphore_drv.bo); + /* initialize vm here */ + rdev->vm_manager.use_bitmap = 1; + rdev->vm_manager.max_pfn = 1 << 20; + INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); /* Set asic functions */ r = radeon_asic_init(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index c3ef1d266f8..31da622eef6 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -54,9 +54,10 @@ * 2.10.0 - fusion 2D tiling * 2.11.0 - backend map, initial compute support for the CS checker * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS + * 2.13.0 - virtual memory support */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 12 +#define KMS_DRIVER_MINOR 13 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); @@ -84,6 +85,10 @@ int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, struct drm_file *file_priv); int radeon_gem_object_init(struct drm_gem_object *obj); void radeon_gem_object_free(struct drm_gem_object *obj); +int radeon_gem_object_open(struct drm_gem_object *obj, + struct drm_file *file_priv); +void radeon_gem_object_close(struct drm_gem_object *obj, + struct drm_file *file_priv); extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos); extern struct drm_ioctl_desc radeon_ioctls_kms[]; @@ -350,6 +355,8 @@ static struct drm_driver kms_driver = { .ioctls = radeon_ioctls_kms, .gem_init_object = radeon_gem_object_init, .gem_free_object = radeon_gem_object_free, + .gem_open_object = radeon_gem_object_open, + .gem_close_object = radeon_gem_object_close, .dma_ioctl = radeon_dma_ioctl_kms, .dumb_create = radeon_mode_dumb_create, .dumb_map_offset = radeon_mode_dumb_mmap, diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index a4d98160858..3ef58cab18c 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -276,3 +276,391 @@ void radeon_gart_fini(struct radeon_device *rdev) radeon_dummy_page_fini(rdev); } + +/* + * vm helpers + * + * TODO bind a default page at vm initialization for default address + */ +int radeon_vm_manager_init(struct radeon_device *rdev) +{ + int r; + + /* mark first vm as always in use, it's the system one */ + r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, + rdev->vm_manager.max_pfn * 8, + RADEON_GEM_DOMAIN_VRAM); + if (r) { + dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", + (rdev->vm_manager.max_pfn * 8) >> 10); + return r; + } + return rdev->vm_manager.funcs->init(rdev); +} + +/* cs mutex must be lock */ +static void radeon_vm_unbind_locked(struct radeon_device *rdev, + struct radeon_vm *vm) +{ + struct radeon_bo_va *bo_va; + + if (vm->id == -1) { + return; + } + + /* wait for vm use to end */ + if (vm->fence) { + radeon_fence_wait(vm->fence, false); + radeon_fence_unref(&vm->fence); + } + + /* hw unbind */ + rdev->vm_manager.funcs->unbind(rdev, vm); + rdev->vm_manager.use_bitmap &= ~(1 << vm->id); + list_del_init(&vm->list); + vm->id = -1; + radeon_sa_bo_free(rdev, &vm->sa_bo); + vm->pt = NULL; + + list_for_each_entry(bo_va, &vm->va, vm_list) { + bo_va->valid = false; + } +} + +void radeon_vm_manager_fini(struct radeon_device *rdev) +{ + if (rdev->vm_manager.sa_manager.bo == NULL) + return; + radeon_vm_manager_suspend(rdev); + rdev->vm_manager.funcs->fini(rdev); + radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager); +} + +int radeon_vm_manager_start(struct radeon_device *rdev) +{ + if (rdev->vm_manager.sa_manager.bo == NULL) { + return -EINVAL; + } + return radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); +} + +int radeon_vm_manager_suspend(struct radeon_device *rdev) +{ + struct radeon_vm *vm, *tmp; + + radeon_mutex_lock(&rdev->cs_mutex); + /* unbind all active vm */ + list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { + radeon_vm_unbind_locked(rdev, vm); + } + rdev->vm_manager.funcs->fini(rdev); + radeon_mutex_unlock(&rdev->cs_mutex); + return radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); +} + +/* cs mutex must be lock */ +void radeon_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm) +{ + mutex_lock(&vm->mutex); + radeon_vm_unbind_locked(rdev, vm); + mutex_unlock(&vm->mutex); +} + +/* cs mutex must be lock & vm mutex must be lock */ +int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) +{ + struct radeon_vm *vm_evict; + unsigned i; + int id = -1, r; + + if (vm == NULL) { + return -EINVAL; + } + + if (vm->id != -1) { + /* update lru */ + list_del_init(&vm->list); + list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); + return 0; + } + +retry: + r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, + RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8), + RADEON_GPU_PAGE_SIZE); + if (r) { + if (list_empty(&rdev->vm_manager.lru_vm)) { + return r; + } + vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); + radeon_vm_unbind(rdev, vm_evict); + goto retry; + } + vm->pt = rdev->vm_manager.sa_manager.cpu_ptr; + vm->pt += (vm->sa_bo.offset >> 3); + vm->pt_gpu_addr = rdev->vm_manager.sa_manager.gpu_addr; + vm->pt_gpu_addr += vm->sa_bo.offset; + memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8)); + +retry_id: + /* search for free vm */ + for (i = 0; i < rdev->vm_manager.nvm; i++) { + if (!(rdev->vm_manager.use_bitmap & (1 << i))) { + id = i; + break; + } + } + /* evict vm if necessary */ + if (id == -1) { + vm_evict = list_first_entry(&rdev->vm_manager.lru_vm, struct radeon_vm, list); + radeon_vm_unbind(rdev, vm_evict); + goto retry_id; + } + + /* do hw bind */ + r = rdev->vm_manager.funcs->bind(rdev, vm, id); + if (r) { + radeon_sa_bo_free(rdev, &vm->sa_bo); + return r; + } + rdev->vm_manager.use_bitmap |= 1 << id; + vm->id = id; + list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); + return radeon_vm_bo_update_pte(rdev, vm, rdev->ib_pool.sa_manager.bo, + &rdev->ib_pool.sa_manager.bo->tbo.mem); +} + +/* object have to be reserved */ +int radeon_vm_bo_add(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_bo *bo, + uint64_t offset, + uint32_t flags) +{ + struct radeon_bo_va *bo_va, *tmp; + struct list_head *head; + uint64_t size = radeon_bo_size(bo), last_offset = 0; + unsigned last_pfn; + + bo_va = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); + if (bo_va == NULL) { + return -ENOMEM; + } + bo_va->vm = vm; + bo_va->bo = bo; + bo_va->soffset = offset; + bo_va->eoffset = offset + size; + bo_va->flags = flags; + bo_va->valid = false; + INIT_LIST_HEAD(&bo_va->bo_list); + INIT_LIST_HEAD(&bo_va->vm_list); + /* make sure object fit at this offset */ + if (bo_va->soffset >= bo_va->eoffset) { + kfree(bo_va); + return -EINVAL; + } + + last_pfn = bo_va->eoffset / RADEON_GPU_PAGE_SIZE; + if (last_pfn > rdev->vm_manager.max_pfn) { + kfree(bo_va); + dev_err(rdev->dev, "va above limit (0x%08X > 0x%08X)\n", + last_pfn, rdev->vm_manager.max_pfn); + return -EINVAL; + } + + mutex_lock(&vm->mutex); + if (last_pfn > vm->last_pfn) { + /* grow va space 32M by 32M */ + unsigned align = ((32 << 20) >> 12) - 1; + radeon_mutex_lock(&rdev->cs_mutex); + radeon_vm_unbind_locked(rdev, vm); + radeon_mutex_unlock(&rdev->cs_mutex); + vm->last_pfn = (last_pfn + align) & ~align; + } + head = &vm->va; + last_offset = 0; + list_for_each_entry(tmp, &vm->va, vm_list) { + if (bo_va->soffset >= last_offset && bo_va->eoffset < tmp->soffset) { + /* bo can be added before this one */ + break; + } + if (bo_va->soffset >= tmp->soffset && bo_va->soffset < tmp->eoffset) { + /* bo and tmp overlap, invalid offset */ + kfree(bo_va); + dev_err(rdev->dev, "bo %p va 0x%08X conflict with (bo %p 0x%08X 0x%08X)\n", + bo, (unsigned)bo_va->soffset, tmp->bo, + (unsigned)tmp->soffset, (unsigned)tmp->eoffset); + mutex_unlock(&vm->mutex); + return -EINVAL; + } + last_offset = tmp->eoffset; + head = &tmp->vm_list; + } + list_add(&bo_va->vm_list, head); + list_add_tail(&bo_va->bo_list, &bo->va); + mutex_unlock(&vm->mutex); + return 0; +} + +static u64 radeon_vm_get_addr(struct radeon_device *rdev, + struct ttm_mem_reg *mem, + unsigned pfn) +{ + u64 addr = 0; + + switch (mem->mem_type) { + case TTM_PL_VRAM: + addr = (mem->start << PAGE_SHIFT); + addr += pfn * RADEON_GPU_PAGE_SIZE; + addr += rdev->vm_manager.vram_base_offset; + break; + case TTM_PL_TT: + /* offset inside page table */ + addr = mem->start << PAGE_SHIFT; + addr += pfn * RADEON_GPU_PAGE_SIZE; + addr = addr >> PAGE_SHIFT; + /* page table offset */ + addr = rdev->gart.pages_addr[addr]; + /* in case cpu page size != gpu page size*/ + addr += (pfn * RADEON_GPU_PAGE_SIZE) & (~PAGE_MASK); + break; + default: + break; + } + return addr; +} + +/* object have to be reserved & cs mutex took & vm mutex took */ +int radeon_vm_bo_update_pte(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_bo *bo, + struct ttm_mem_reg *mem) +{ + struct radeon_bo_va *bo_va; + unsigned ngpu_pages, i; + uint64_t addr = 0, pfn; + uint32_t flags; + + /* nothing to do if vm isn't bound */ + if (vm->id == -1) + return 0;; + + bo_va = radeon_bo_va(bo, vm); + if (bo_va == NULL) { + dev_err(rdev->dev, "bo %p not in vm %p\n", bo, vm); + return -EINVAL; + } + + if (bo_va->valid) + return 0; + + ngpu_pages = radeon_bo_ngpu_pages(bo); + bo_va->flags &= ~RADEON_VM_PAGE_VALID; + bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; + if (mem) { + if (mem->mem_type != TTM_PL_SYSTEM) { + bo_va->flags |= RADEON_VM_PAGE_VALID; + bo_va->valid = true; + } + if (mem->mem_type == TTM_PL_TT) { + bo_va->flags |= RADEON_VM_PAGE_SYSTEM; + } + } + pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE; + flags = rdev->vm_manager.funcs->page_flags(rdev, bo_va->vm, bo_va->flags); + for (i = 0, addr = 0; i < ngpu_pages; i++) { + if (mem && bo_va->valid) { + addr = radeon_vm_get_addr(rdev, mem, i); + } + rdev->vm_manager.funcs->set_page(rdev, bo_va->vm, i + pfn, addr, flags); + } + rdev->vm_manager.funcs->tlb_flush(rdev, bo_va->vm); + return 0; +} + +/* object have to be reserved */ +int radeon_vm_bo_rmv(struct radeon_device *rdev, + struct radeon_vm *vm, + struct radeon_bo *bo) +{ + struct radeon_bo_va *bo_va; + + bo_va = radeon_bo_va(bo, vm); + if (bo_va == NULL) + return 0; + + list_del(&bo_va->bo_list); + mutex_lock(&vm->mutex); + radeon_mutex_lock(&rdev->cs_mutex); + radeon_vm_bo_update_pte(rdev, vm, bo, NULL); + radeon_mutex_unlock(&rdev->cs_mutex); + list_del(&bo_va->vm_list); + mutex_lock(&vm->mutex); + + kfree(bo_va); + return 0; +} + +void radeon_vm_bo_invalidate(struct radeon_device *rdev, + struct radeon_bo *bo) +{ + struct radeon_bo_va *bo_va; + + BUG_ON(!atomic_read(&bo->tbo.reserved)); + list_for_each_entry(bo_va, &bo->va, bo_list) { + bo_va->valid = false; + } +} + +int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) +{ + int r; + + vm->id = -1; + vm->fence = NULL; + mutex_init(&vm->mutex); + INIT_LIST_HEAD(&vm->list); + INIT_LIST_HEAD(&vm->va); + vm->last_pfn = 0; + /* map the ib pool buffer at 0 in virtual address space, set + * read only + */ + r = radeon_vm_bo_add(rdev, vm, rdev->ib_pool.sa_manager.bo, 0, + RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); + return r; +} + +void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) +{ + struct radeon_bo_va *bo_va, *tmp; + int r; + + mutex_lock(&vm->mutex); + + radeon_mutex_lock(&rdev->cs_mutex); + radeon_vm_unbind_locked(rdev, vm); + radeon_mutex_unlock(&rdev->cs_mutex); + + /* remove all bo */ + r = radeon_bo_reserve(rdev->ib_pool.sa_manager.bo, false); + if (!r) { + bo_va = radeon_bo_va(rdev->ib_pool.sa_manager.bo, vm); + list_del_init(&bo_va->bo_list); + list_del_init(&bo_va->vm_list); + radeon_bo_unreserve(rdev->ib_pool.sa_manager.bo); + kfree(bo_va); + } + if (!list_empty(&vm->va)) { + dev_err(rdev->dev, "still active bo inside vm\n"); + } + list_for_each_entry_safe(bo_va, tmp, &vm->va, vm_list) { + list_del_init(&bo_va->vm_list); + r = radeon_bo_reserve(bo_va->bo, false); + if (!r) { + list_del_init(&bo_va->bo_list); + radeon_bo_unreserve(bo_va->bo); + kfree(bo_va); + } + } + mutex_unlock(&vm->mutex); +} diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index ae321975283..003eeec1b68 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -142,6 +142,44 @@ void radeon_gem_fini(struct radeon_device *rdev) radeon_bo_force_delete(rdev); } +/* + * Call from drm_gem_handle_create which appear in both new and open ioctl + * case. + */ +int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv) +{ + return 0; +} + +void radeon_gem_object_close(struct drm_gem_object *obj, + struct drm_file *file_priv) +{ + struct radeon_bo *rbo = gem_to_radeon_bo(obj); + struct radeon_device *rdev = rbo->rdev; + struct radeon_fpriv *fpriv = file_priv->driver_priv; + struct radeon_vm *vm = &fpriv->vm; + struct radeon_bo_va *bo_va, *tmp; + + if (rdev->family < CHIP_CAYMAN) { + return; + } + + if (radeon_bo_reserve(rbo, false)) { + return; + } + list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { + if (bo_va->vm == vm) { + /* remove from this vm address space */ + mutex_lock(&vm->mutex); + list_del(&bo_va->vm_list); + mutex_unlock(&vm->mutex); + list_del(&bo_va->bo_list); + kfree(bo_va); + } + } + radeon_bo_unreserve(rbo); +} + /* * GEM ioctls. @@ -354,6 +392,104 @@ out: return r; } +int radeon_gem_va_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + struct drm_radeon_gem_va *args = data; + struct drm_gem_object *gobj; + struct radeon_device *rdev = dev->dev_private; + struct radeon_fpriv *fpriv = filp->driver_priv; + struct radeon_bo *rbo; + struct radeon_bo_va *bo_va; + u32 invalid_flags; + int r = 0; + + /* !! DONT REMOVE !! + * We don't support vm_id yet, to be sure we don't have have broken + * userspace, reject anyone trying to use non 0 value thus moving + * forward we can use those fields without breaking existant userspace + */ + if (args->vm_id) { + args->operation = RADEON_VA_RESULT_ERROR; + return -EINVAL; + } + + if (args->offset < RADEON_VA_RESERVED_SIZE) { + dev_err(&dev->pdev->dev, + "offset 0x%lX is in reserved area 0x%X\n", + (unsigned long)args->offset, + RADEON_VA_RESERVED_SIZE); + args->operation = RADEON_VA_RESULT_ERROR; + return -EINVAL; + } + + /* don't remove, we need to enforce userspace to set the snooped flag + * otherwise we will endup with broken userspace and we won't be able + * to enable this feature without adding new interface + */ + invalid_flags = RADEON_VM_PAGE_VALID | RADEON_VM_PAGE_SYSTEM; + if ((args->flags & invalid_flags)) { + dev_err(&dev->pdev->dev, "invalid flags 0x%08X vs 0x%08X\n", + args->flags, invalid_flags); + args->operation = RADEON_VA_RESULT_ERROR; + return -EINVAL; + } + if (!(args->flags & RADEON_VM_PAGE_SNOOPED)) { + dev_err(&dev->pdev->dev, "only supported snooped mapping for now\n"); + args->operation = RADEON_VA_RESULT_ERROR; + return -EINVAL; + } + + switch (args->operation) { + case RADEON_VA_MAP: + case RADEON_VA_UNMAP: + break; + default: + dev_err(&dev->pdev->dev, "unsupported operation %d\n", + args->operation); + args->operation = RADEON_VA_RESULT_ERROR; + return -EINVAL; + } + + gobj = drm_gem_object_lookup(dev, filp, args->handle); + if (gobj == NULL) { + args->operation = RADEON_VA_RESULT_ERROR; + return -ENOENT; + } + rbo = gem_to_radeon_bo(gobj); + r = radeon_bo_reserve(rbo, false); + if (r) { + args->operation = RADEON_VA_RESULT_ERROR; + drm_gem_object_unreference_unlocked(gobj); + return r; + } + switch (args->operation) { + case RADEON_VA_MAP: + bo_va = radeon_bo_va(rbo, &fpriv->vm); + if (bo_va) { + args->operation = RADEON_VA_RESULT_VA_EXIST; + args->offset = bo_va->soffset; + goto out; + } + r = radeon_vm_bo_add(rdev, &fpriv->vm, rbo, + args->offset, args->flags); + break; + case RADEON_VA_UNMAP: + r = radeon_vm_bo_rmv(rdev, &fpriv->vm, rbo); + break; + default: + break; + } + args->operation = RADEON_VA_RESULT_OK; + if (r) { + args->operation = RADEON_VA_RESULT_ERROR; + } +out: + radeon_bo_unreserve(rbo); + drm_gem_object_unreference_unlocked(gobj); + return r; +} + int radeon_mode_dumb_create(struct drm_file *file_priv, struct drm_device *dev, struct drm_mode_create_dumb *args) diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index be2c1224e68..d3352889a87 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -250,6 +250,18 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return -EINVAL; } break; + case RADEON_INFO_VA_START: + /* this is where we report if vm is supported or not */ + if (rdev->family < CHIP_CAYMAN) + return -EINVAL; + value = RADEON_VA_RESERVED_SIZE; + break; + case RADEON_INFO_IB_VM_MAX_SIZE: + /* this is where we report if vm is supported or not */ + if (rdev->family < CHIP_CAYMAN) + return -EINVAL; + value = RADEON_IB_VM_MAX_SIZE; + break; default: DRM_DEBUG_KMS("Invalid request %d\n", info->request); return -EINVAL; @@ -270,7 +282,6 @@ int radeon_driver_firstopen_kms(struct drm_device *dev) return 0; } - void radeon_driver_lastclose_kms(struct drm_device *dev) { vga_switcheroo_process_delayed_switch(); @@ -278,12 +289,45 @@ void radeon_driver_lastclose_kms(struct drm_device *dev) int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) { + struct radeon_device *rdev = dev->dev_private; + + file_priv->driver_priv = NULL; + + /* new gpu have virtual address space support */ + if (rdev->family >= CHIP_CAYMAN) { + struct radeon_fpriv *fpriv; + int r; + + fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); + if (unlikely(!fpriv)) { + return -ENOMEM; + } + + r = radeon_vm_init(rdev, &fpriv->vm); + if (r) { + radeon_vm_fini(rdev, &fpriv->vm); + kfree(fpriv); + return r; + } + + file_priv->driver_priv = fpriv; + } return 0; } void radeon_driver_postclose_kms(struct drm_device *dev, struct drm_file *file_priv) { + struct radeon_device *rdev = dev->dev_private; + + /* new gpu have virtual address space support */ + if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { + struct radeon_fpriv *fpriv = file_priv->driver_priv; + + radeon_vm_fini(rdev, &fpriv->vm); + kfree(fpriv); + file_priv->driver_priv = NULL; + } } void radeon_driver_preclose_kms(struct drm_device *dev, @@ -451,5 +495,6 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|DRM_UNLOCKED), }; int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 695b4800329..d45df176359 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -46,6 +46,20 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo); * function are calling it. */ +void radeon_bo_clear_va(struct radeon_bo *bo) +{ + struct radeon_bo_va *bo_va, *tmp; + + list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { + /* remove from all vm address space */ + mutex_lock(&bo_va->vm->mutex); + list_del(&bo_va->vm_list); + mutex_unlock(&bo_va->vm->mutex); + list_del(&bo_va->bo_list); + kfree(bo_va); + } +} + static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) { struct radeon_bo *bo; @@ -55,6 +69,7 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) list_del_init(&bo->list); mutex_unlock(&bo->rdev->gem.mutex); radeon_bo_clear_surface_reg(bo); + radeon_bo_clear_va(bo); drm_gem_object_release(&bo->gem_base); kfree(bo); } @@ -134,6 +149,7 @@ retry: bo->gem_base.driver_private = NULL; bo->surface_reg = -1; INIT_LIST_HEAD(&bo->list); + INIT_LIST_HEAD(&bo->va); radeon_ttm_placement_from_domain(bo, domain); /* Kernel allocation are uninterruptible */ mutex_lock(&rdev->vram_mutex); @@ -487,6 +503,7 @@ void radeon_bo_move_notify(struct ttm_buffer_object *bo, return; rbo = container_of(bo, struct radeon_bo, tbo); radeon_bo_check_tiling(rbo, 0, 1); + radeon_vm_bo_invalidate(rbo->rdev, rbo); } int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) @@ -560,3 +577,16 @@ int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) } return 0; } + +/* object have to be reserved */ +struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, struct radeon_vm *vm) +{ + struct radeon_bo_va *bo_va; + + list_for_each_entry(bo_va, &rbo->va, bo_list) { + if (bo_va->vm == vm) { + return bo_va; + } + } + return NULL; +} diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index cc236fb128a..cde43030887 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -83,6 +83,16 @@ static inline bool radeon_bo_is_reserved(struct radeon_bo *bo) return !!atomic_read(&bo->tbo.reserved); } +static inline unsigned radeon_bo_ngpu_pages(struct radeon_bo *bo) +{ + return (bo->tbo.num_pages << PAGE_SHIFT) / RADEON_GPU_PAGE_SIZE; +} + +static inline unsigned radeon_bo_gpu_page_alignment(struct radeon_bo *bo) +{ + return (bo->tbo.mem.page_alignment << PAGE_SHIFT) / RADEON_GPU_PAGE_SIZE; +} + /** * radeon_bo_mmap_offset - return mmap offset of bo * @bo: radeon object for which we query the offset @@ -128,6 +138,8 @@ extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem); extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); +extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, + struct radeon_vm *vm); /* * sub allocation diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 465fb34c197..e8bc70933d1 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -132,6 +132,7 @@ retry: (*ib)->gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; (*ib)->gpu_addr += (*ib)->sa_bo.offset; (*ib)->fence = fence; + (*ib)->vm_id = 0; /* ib are most likely to be allocated in a ring fashion * thus rdev->ib_pool.head_id should be the id of the * oldest ib diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index be94be6d6f1..d7079f42624 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -509,6 +509,7 @@ typedef struct { #define DRM_RADEON_GEM_SET_TILING 0x28 #define DRM_RADEON_GEM_GET_TILING 0x29 #define DRM_RADEON_GEM_BUSY 0x2a +#define DRM_RADEON_GEM_VA 0x2b #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -550,6 +551,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_TILING, struct drm_radeon_gem_set_tiling) #define DRM_IOCTL_RADEON_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_GET_TILING, struct drm_radeon_gem_get_tiling) #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy) +#define DRM_IOCTL_RADEON_GEM_VA DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_VA, struct drm_radeon_gem_va) typedef struct drm_radeon_init { enum { @@ -872,12 +874,42 @@ struct drm_radeon_gem_pwrite { uint64_t data_ptr; }; +#define RADEON_VA_MAP 1 +#define RADEON_VA_UNMAP 2 + +#define RADEON_VA_RESULT_OK 0 +#define RADEON_VA_RESULT_ERROR 1 +#define RADEON_VA_RESULT_VA_EXIST 2 + +#define RADEON_VM_PAGE_VALID (1 << 0) +#define RADEON_VM_PAGE_READABLE (1 << 1) +#define RADEON_VM_PAGE_WRITEABLE (1 << 2) +#define RADEON_VM_PAGE_SYSTEM (1 << 3) +#define RADEON_VM_PAGE_SNOOPED (1 << 4) + +struct drm_radeon_gem_va { + uint32_t handle; + uint32_t operation; + uint32_t vm_id; + uint32_t flags; + uint64_t offset; +}; + #define RADEON_CHUNK_ID_RELOCS 0x01 #define RADEON_CHUNK_ID_IB 0x02 #define RADEON_CHUNK_ID_FLAGS 0x03 /* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */ #define RADEON_CS_KEEP_TILING_FLAGS 0x01 +#define RADEON_CS_USE_VM 0x02 +/* The second dword of RADEON_CHUNK_ID_FLAGS is a uint32 that sets the ring type */ +#define RADEON_CS_RING_GFX 0 +#define RADEON_CS_RING_COMPUTE 1 +/* The third dword of RADEON_CHUNK_ID_FLAGS is a sint32 that sets the priority */ +/* 0 = normal, + = higher priority, - = lower priority */ +struct drm_radeon_cs_ring_priority { + int32_t priority; +}; struct drm_radeon_cs_chunk { uint32_t chunk_id; @@ -916,6 +948,10 @@ struct drm_radeon_cs { #define RADEON_INFO_NUM_TILE_PIPES 0x0b /* tile pipes for r600+ */ #define RADEON_INFO_FUSION_GART_WORKING 0x0c /* fusion writes to GTT were broken before this */ #define RADEON_INFO_BACKEND_MAP 0x0d /* pipe to backend map, needed by mesa */ +/* virtual address start, va < start are reserved by the kernel */ +#define RADEON_INFO_VA_START 0x0e +/* maximum size of ib using the virtual memory cs */ +#define RADEON_INFO_IB_VM_MAX_SIZE 0x0f struct drm_radeon_info { uint32_t request; -- cgit v1.2.3-70-g09d2