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

Reply via email to