[PATCH 3/3] drm/radeon/cayman/tn: only enable CP gui idle interrupts after CP is set up
Alex Deucher
alexdeucher at gmail.com
Wed Jul 8 10:46:04 PDT 2015
Necessary for proper gfx/rlc/smu handshaking.
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
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
More information about the dri-devel
mailing list