Necessary for proper gfx/rlc/smu handshaking. Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> --- drivers/gpu/drm/radeon/evergreen.c | 35 ++++++++++++++++++++++++++--------- drivers/gpu/drm/radeon/ni.c | 29 ++++++++++++++++++++++++++--- drivers/gpu/drm/radeon/nid.h | 3 +++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 0e0fb07..b7f3a18 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -205,8 +205,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); void evergreen_pcie_gen2_enable(struct radeon_device *rdev); void evergreen_program_aspm(struct radeon_device *rdev); -extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, - int ring, u32 cp_int_cntl); +extern void cayman_cp_int_cntl_select(struct radeon_device *rdev, + int ring); extern void cayman_vm_decode_fault(struct radeon_device *rdev, u32 status, u32 addr); void cik_init_cp_pg_table(struct radeon_device *rdev); @@ -4419,10 +4419,14 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) u32 tmp; if (rdev->family >= CHIP_CAYMAN) { - cayman_cp_int_cntl_setup(rdev, 0, - CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); - cayman_cp_int_cntl_setup(rdev, 1, 0); - cayman_cp_int_cntl_setup(rdev, 2, 0); + mutex_lock(&rdev->grbm_idx_mutex); + cayman_cp_int_cntl_select(rdev, 0); + WREG32(CP_INT_CNTL, 0); + cayman_cp_int_cntl_select(rdev, 1); + WREG32(CP_INT_CNTL, 0); + cayman_cp_int_cntl_select(rdev, 2); + WREG32(CP_INT_CNTL, 0); + mutex_unlock(&rdev->grbm_idx_mutex); tmp = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE; WREG32(CAYMAN_DMA1_CNTL, tmp); } else @@ -4519,19 +4523,27 @@ int evergreen_irq_set(struct radeon_device *rdev) dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE; if (rdev->family >= CHIP_CAYMAN) { + mutex_lock(&rdev->grbm_idx_mutex); /* enable CP interrupts on all rings */ + cayman_cp_int_cntl_select(rdev, 0); + cp_int_cntl = RREG32(CP_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); cp_int_cntl |= TIME_STAMP_INT_ENABLE; } + cayman_cp_int_cntl_select(rdev, 1); + cp_int_cntl1 = RREG32(CP_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) { DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; } + cayman_cp_int_cntl_select(rdev, 2); + cp_int_cntl2 = RREG32(CP_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) { DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; } + mutex_unlock(&rdev->grbm_idx_mutex); } else { cp_int_cntl = RREG32(CP_INT_CNTL) & ~(RB_INT_ENABLE | TIME_STAMP_INT_ENABLE); if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { @@ -4639,9 +4651,14 @@ int evergreen_irq_set(struct radeon_device *rdev) } if (rdev->family >= CHIP_CAYMAN) { - cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); - cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1); - cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); + mutex_lock(&rdev->grbm_idx_mutex); + cayman_cp_int_cntl_select(rdev, 0); + WREG32(CP_INT_CNTL, cp_int_cntl); + cayman_cp_int_cntl_select(rdev, 1); + WREG32(CP_INT_CNTL, cp_int_cntl1); + cayman_cp_int_cntl_select(rdev, 2); + WREG32(CP_INT_CNTL, cp_int_cntl2); + mutex_unlock(&rdev->grbm_idx_mutex); } else WREG32(CP_INT_CNTL, cp_int_cntl); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 6de9d363..2b2e177 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1393,13 +1393,12 @@ static void cayman_pcie_gart_fini(struct radeon_device *rdev) radeon_gart_fini(rdev); } -void cayman_cp_int_cntl_setup(struct radeon_device *rdev, - int ring, u32 cp_int_cntl) +void cayman_cp_int_cntl_select(struct radeon_device *rdev, + int ring) { u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3; WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3)); - WREG32(CP_INT_CNTL, cp_int_cntl); } /* @@ -1619,6 +1618,26 @@ static int cayman_cp_start(struct radeon_device *rdev) return 0; } +static void cayman_enable_gui_idle_interrupt(struct radeon_device *rdev, + bool enable) +{ + u32 tmp; + + mutex_lock(&rdev->grbm_idx_mutex); + cayman_cp_int_cntl_select(rdev, 0); + tmp = RREG32(CP_INT_CNTL); + if (enable) + tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); + else + tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); + WREG32(CP_INT_CNTL, tmp); + mutex_unlock(&rdev->grbm_idx_mutex); + + if (!enable) + /* read a gfx register */ + tmp = RREG32(DB_DEPTH_INFO); +} + static void cayman_cp_fini(struct radeon_device *rdev) { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; @@ -1679,6 +1698,8 @@ static int cayman_cp_resume(struct radeon_device *rdev) WREG32(GRBM_SOFT_RESET, 0); RREG32(GRBM_SOFT_RESET); + cayman_enable_gui_idle_interrupt(rdev, false); + WREG32(CP_SEM_WAIT_TIMER, 0x0); WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); @@ -1743,6 +1764,8 @@ static int cayman_cp_resume(struct radeon_device *rdev) return r; } + cayman_enable_gui_idle_interrupt(rdev, true); + if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 47eb49b..90df28c 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -1141,6 +1141,9 @@ #define UVD_RBC_RB_WPTR 0xF694 #define UVD_STATUS 0xf6bc + +#define DB_DEPTH_INFO 0x2803C + /* * PM4 */ -- 1.8.3.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel