drm/radeon/si: restructure cg code (v3)
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 8 Aug 2013 23:34:07 +0000 (19:34 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 30 Aug 2013 20:30:49 +0000 (16:30 -0400)
Resturcture clockgating code so that it can be
enabled/disabled from other components such as
dpm.

v2: make function static
v3: add fine grained cg controls

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/sid.h

index 289047e12ef260c9f6533659157ec7c851ce4f61..8cd87bac04869ff13c6fdc55bd9069b5ddf2fdeb 100644 (file)
@@ -159,6 +159,7 @@ extern int radeon_aspm;
 #define RADEON_CG_BLOCK_UVD                    (1 << 3)
 #define RADEON_CG_BLOCK_VCE                    (1 << 4)
 #define RADEON_CG_BLOCK_HDP                    (1 << 5)
+#define RADEON_CG_BLOCK_BIF                    (1 << 6)
 
 /* CG flags */
 #define RADEON_CG_SUPPORT_GFX_MGCG             (1 << 0)
index dcdf5e07490d35d66aceb32dafc6d891a23614e2..3bd96cdb76013489b0780cae5af977755e1cf9e9 100644 (file)
@@ -2340,7 +2340,7 @@ int radeon_asic_init(struct radeon_device *rdev)
                        rdev->cg_flags =
                                RADEON_CG_SUPPORT_GFX_MGCG |
                                RADEON_CG_SUPPORT_GFX_MGLS |
-                               RADEON_CG_SUPPORT_GFX_CGCG |
+                               /*RADEON_CG_SUPPORT_GFX_CGCG |*/
                                RADEON_CG_SUPPORT_GFX_CGLS |
                                RADEON_CG_SUPPORT_GFX_CGTS |
                                RADEON_CG_SUPPORT_GFX_CP_LS |
@@ -2357,7 +2357,7 @@ int radeon_asic_init(struct radeon_device *rdev)
                        rdev->cg_flags =
                                RADEON_CG_SUPPORT_GFX_MGCG |
                                RADEON_CG_SUPPORT_GFX_MGLS |
-                               RADEON_CG_SUPPORT_GFX_CGCG |
+                               /*RADEON_CG_SUPPORT_GFX_CGCG |*/
                                RADEON_CG_SUPPORT_GFX_CGLS |
                                RADEON_CG_SUPPORT_GFX_CGTS |
                                RADEON_CG_SUPPORT_GFX_CP_LS |
@@ -2376,7 +2376,7 @@ int radeon_asic_init(struct radeon_device *rdev)
                        rdev->cg_flags =
                                RADEON_CG_SUPPORT_GFX_MGCG |
                                RADEON_CG_SUPPORT_GFX_MGLS |
-                               RADEON_CG_SUPPORT_GFX_CGCG |
+                               /*RADEON_CG_SUPPORT_GFX_CGCG |*/
                                RADEON_CG_SUPPORT_GFX_CGLS |
                                RADEON_CG_SUPPORT_GFX_CGTS |
                                RADEON_CG_SUPPORT_GFX_CP_LS |
@@ -2397,7 +2397,7 @@ int radeon_asic_init(struct radeon_device *rdev)
                        rdev->cg_flags =
                                RADEON_CG_SUPPORT_GFX_MGCG |
                                RADEON_CG_SUPPORT_GFX_MGLS |
-                               RADEON_CG_SUPPORT_GFX_CGCG |
+                               /*RADEON_CG_SUPPORT_GFX_CGCG |*/
                                RADEON_CG_SUPPORT_GFX_CGLS |
                                RADEON_CG_SUPPORT_GFX_CGTS |
                                RADEON_CG_SUPPORT_GFX_CP_LS |
@@ -2415,7 +2415,7 @@ int radeon_asic_init(struct radeon_device *rdev)
                        rdev->cg_flags =
                                RADEON_CG_SUPPORT_GFX_MGCG |
                                RADEON_CG_SUPPORT_GFX_MGLS |
-                               RADEON_CG_SUPPORT_GFX_CGCG |
+                               /*RADEON_CG_SUPPORT_GFX_CGCG |*/
                                RADEON_CG_SUPPORT_GFX_CGLS |
                                RADEON_CG_SUPPORT_GFX_CGTS |
                                RADEON_CG_SUPPORT_GFX_CP_LS |
index e116128f3d8f91ec6e4df6e187d8a1cbed13bb84..b1d22c704c537cebc236620912d02c9f489b309e 100644 (file)
@@ -4844,7 +4844,7 @@ static void si_enable_dma_pg(struct radeon_device *rdev, bool enable)
        u32 data, orig;
 
        orig = data = RREG32(DMA_PG);
-       if (enable)
+       if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA))
                data |= PG_CNTL_ENABLE;
        else
                data &= ~PG_CNTL_ENABLE;
@@ -4868,7 +4868,7 @@ static void si_enable_gfx_cgpg(struct radeon_device *rdev,
 {
        u32 tmp;
 
-       if (enable) {
+       if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_CG)) {
                tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);
                WREG32(RLC_TTOP_D, tmp);
 
@@ -4973,7 +4973,7 @@ static void si_enable_cgcg(struct radeon_device *rdev,
 
        si_enable_gui_idle_interrupt(rdev, enable);
 
-       if (enable) {
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) {
                WREG32(RLC_GCPM_GENERAL_3, 0x00000080);
 
                tmp = si_halt_rlc(rdev);
@@ -5007,16 +5007,18 @@ static void si_enable_mgcg(struct radeon_device *rdev,
 {
        u32 data, orig, tmp = 0;
 
-       if (enable) {
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) {
                orig = data = RREG32(CGTS_SM_CTRL_REG);
                data = 0x96940200;
                if (orig != data)
                        WREG32(CGTS_SM_CTRL_REG, data);
 
-               orig = data = RREG32(CP_MEM_SLP_CNTL);
-               data |= CP_MEM_LS_EN;
-               if (orig != data)
-                       WREG32(CP_MEM_SLP_CNTL, data);
+               if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) {
+                       orig = data = RREG32(CP_MEM_SLP_CNTL);
+                       data |= CP_MEM_LS_EN;
+                       if (orig != data)
+                               WREG32(CP_MEM_SLP_CNTL, data);
+               }
 
                orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
                data &= 0xffffffc0;
@@ -5061,7 +5063,7 @@ static void si_enable_uvd_mgcg(struct radeon_device *rdev,
 {
        u32 orig, data, tmp;
 
-       if (enable) {
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) {
                tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
                tmp |= 0x3fff;
                WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
@@ -5109,7 +5111,7 @@ static void si_enable_mc_ls(struct radeon_device *rdev,
 
        for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
                orig = data = RREG32(mc_cg_registers[i]);
-               if (enable)
+               if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
                        data |= MC_LS_ENABLE;
                else
                        data &= ~MC_LS_ENABLE;
@@ -5118,19 +5120,158 @@ static void si_enable_mc_ls(struct radeon_device *rdev,
        }
 }
 
+static void si_enable_mc_mgcg(struct radeon_device *rdev,
+                              bool enable)
+{
+       int i;
+       u32 orig, data;
+
+       for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
+               orig = data = RREG32(mc_cg_registers[i]);
+               if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG))
+                       data |= MC_CG_ENABLE;
+               else
+                       data &= ~MC_CG_ENABLE;
+               if (data != orig)
+                       WREG32(mc_cg_registers[i], data);
+       }
+}
+
+static void si_enable_dma_mgcg(struct radeon_device *rdev,
+                              bool enable)
+{
+       u32 orig, data, offset;
+       int i;
+
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) {
+               for (i = 0; i < 2; i++) {
+                       if (i == 0)
+                               offset = DMA0_REGISTER_OFFSET;
+                       else
+                               offset = DMA1_REGISTER_OFFSET;
+                       orig = data = RREG32(DMA_POWER_CNTL + offset);
+                       data &= ~MEM_POWER_OVERRIDE;
+                       if (data != orig)
+                               WREG32(DMA_POWER_CNTL + offset, data);
+                       WREG32(DMA_CLK_CTRL + offset, 0x00000100);
+               }
+       } else {
+               for (i = 0; i < 2; i++) {
+                       if (i == 0)
+                               offset = DMA0_REGISTER_OFFSET;
+                       else
+                               offset = DMA1_REGISTER_OFFSET;
+                       orig = data = RREG32(DMA_POWER_CNTL + offset);
+                       data |= MEM_POWER_OVERRIDE;
+                       if (data != orig)
+                               WREG32(DMA_POWER_CNTL + offset, data);
+
+                       orig = data = RREG32(DMA_CLK_CTRL + offset);
+                       data = 0xff000000;
+                       if (data != orig)
+                               WREG32(DMA_CLK_CTRL + offset, data);
+               }
+       }
+}
+
+static void si_enable_bif_mgls(struct radeon_device *rdev,
+                              bool enable)
+{
+       u32 orig, data;
+
+       orig = data = RREG32_PCIE(PCIE_CNTL2);
+
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS))
+               data |= SLV_MEM_LS_EN | MST_MEM_LS_EN |
+                       REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN;
+       else
+               data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN |
+                         REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN);
+
+       if (orig != data)
+               WREG32_PCIE(PCIE_CNTL2, data);
+}
+
+static void si_enable_hdp_mgcg(struct radeon_device *rdev,
+                              bool enable)
+{
+       u32 orig, data;
+
+       orig = data = RREG32(HDP_HOST_PATH_CNTL);
+
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG))
+               data &= ~CLOCK_GATING_DIS;
+       else
+               data |= CLOCK_GATING_DIS;
+
+       if (orig != data)
+               WREG32(HDP_HOST_PATH_CNTL, data);
+}
+
+static void si_enable_hdp_ls(struct radeon_device *rdev,
+                            bool enable)
+{
+       u32 orig, data;
+
+       orig = data = RREG32(HDP_MEM_POWER_LS);
+
+       if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS))
+               data |= HDP_LS_ENABLE;
+       else
+               data &= ~HDP_LS_ENABLE;
+
+       if (orig != data)
+               WREG32(HDP_MEM_POWER_LS, data);
+}
+
+void si_update_cg(struct radeon_device *rdev,
+                 u32 block, bool enable)
+{
+       if (block & RADEON_CG_BLOCK_GFX) {
+               /* order matters! */
+               if (enable) {
+                       si_enable_mgcg(rdev, true);
+                       si_enable_cgcg(rdev, true);
+               } else {
+                       si_enable_cgcg(rdev, false);
+                       si_enable_mgcg(rdev, false);
+               }
+       }
+
+       if (block & RADEON_CG_BLOCK_MC) {
+               si_enable_mc_mgcg(rdev, enable);
+               si_enable_mc_ls(rdev, enable);
+       }
+
+       if (block & RADEON_CG_BLOCK_SDMA) {
+               si_enable_dma_mgcg(rdev, enable);
+       }
+
+       if (block & RADEON_CG_BLOCK_BIF) {
+               si_enable_bif_mgls(rdev, enable);
+       }
+
+       if (block & RADEON_CG_BLOCK_UVD) {
+               if (rdev->has_uvd) {
+                       si_enable_uvd_mgcg(rdev, enable);
+               }
+       }
+
+       if (block & RADEON_CG_BLOCK_HDP) {
+               si_enable_hdp_mgcg(rdev, enable);
+               si_enable_hdp_ls(rdev, enable);
+       }
+}
 
 static void si_init_cg(struct radeon_device *rdev)
 {
-       if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)
-               si_enable_mgcg(rdev, true);
-       if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)
-               si_enable_cgcg(rdev, false/*true*/);
-       /* Disable MC LS on tahiti */
-       if (!(rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
-               si_enable_mc_ls(rdev, false);
+       si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
+                           RADEON_CG_BLOCK_MC |
+                           RADEON_CG_BLOCK_SDMA |
+                           RADEON_CG_BLOCK_BIF |
+                           RADEON_CG_BLOCK_HDP), true);
        if (rdev->has_uvd) {
-               if (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)
-                       si_enable_uvd_mgcg(rdev, true);
+               si_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
                si_init_uvd_internal_cg(rdev);
        }
 }
@@ -5138,13 +5279,20 @@ static void si_init_cg(struct radeon_device *rdev)
 static void si_fini_cg(struct radeon_device *rdev)
 {
        if (rdev->has_uvd) {
-               if (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)
-                       si_enable_uvd_mgcg(rdev, false);
+               si_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
        }
-       if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)
-               si_enable_cgcg(rdev, false);
-       if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)
-               si_enable_mgcg(rdev, false);
+       si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
+                           RADEON_CG_BLOCK_MC |
+                           RADEON_CG_BLOCK_SDMA |
+                           RADEON_CG_BLOCK_BIF |
+                           RADEON_CG_BLOCK_HDP), false);
+}
+
+void si_update_pg(struct radeon_device *rdev,
+                 bool enable)
+{
+       si_enable_dma_pg(rdev, enable);
+       si_enable_gfx_cgpg(rdev, enable);
 }
 
 static void si_init_pg(struct radeon_device *rdev)
@@ -5152,13 +5300,12 @@ static void si_init_pg(struct radeon_device *rdev)
        if (rdev->pg_flags) {
                if (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA) {
                        si_init_dma_pg(rdev);
-                       si_enable_dma_pg(rdev, true);
                }
                si_init_ao_cu_mask(rdev);
                if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_CG) {
                        si_init_gfx_cgpg(rdev);
-                       si_enable_gfx_cgpg(rdev, true);
                }
+               si_update_pg(rdev, false);
        } else {
                WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
                WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
@@ -6308,6 +6455,8 @@ int si_suspend(struct radeon_device *rdev)
                uvd_v1_0_fini(rdev);
                radeon_uvd_suspend(rdev);
        }
+       si_fini_pg(rdev);
+       si_fini_cg(rdev);
        si_irq_suspend(rdev);
        radeon_wb_disable(rdev);
        si_pcie_gart_disable(rdev);
@@ -6439,10 +6588,10 @@ void si_fini(struct radeon_device *rdev)
 {
        si_cp_fini(rdev);
        cayman_dma_fini(rdev);
+       si_fini_pg(rdev);
+       si_fini_cg(rdev);
        si_irq_fini(rdev);
        sumo_rlc_fini(rdev);
-       si_fini_cg(rdev);
-       si_fini_pg(rdev);
        radeon_wb_fini(rdev);
        radeon_vm_manager_fini(rdev);
        radeon_ib_pool_fini(rdev);
index 968cf699c29e7c118f47c657741a53521edddd52..91dae16fddc4fd96fc2fbbf97242eb87a64016fd 100644 (file)
 #define                CLKS_MASK                               (0xfff << 0)
 
 #define        HDP_HOST_PATH_CNTL                              0x2C00
+#define        CLOCK_GATING_DIS                        (1 << 23)
 #define        HDP_NONSURFACE_BASE                             0x2C04
 #define        HDP_NONSURFACE_INFO                             0x2C08
 #define        HDP_NONSURFACE_SIZE                             0x2C0C
 #define HDP_ADDR_CONFIG                                0x2F48
 #define HDP_MISC_CNTL                                  0x2F4C
 #define        HDP_FLUSH_INVALIDATE_CACHE                      (1 << 0)
+#define HDP_MEM_POWER_LS                               0x2F50
+#define        HDP_LS_ENABLE                           (1 << 0)
 
 #define ATC_MISC_CG                                    0x3350
 
 /* PCIE registers idx/data 0x30/0x34 */
 #define PCIE_CNTL2                                        0x1c /* PCIE */
 #       define SLV_MEM_LS_EN                              (1 << 16)
+#       define SLV_MEM_AGGRESSIVE_LS_EN                   (1 << 17)
 #       define MST_MEM_LS_EN                              (1 << 18)
 #       define REPLAY_MEM_LS_EN                           (1 << 19)
 #define PCIE_LC_STATUS1                                   0x28 /* PCIE */
 #       define DMA_IDLE                                   (1 << 0)
 #define DMA_TILING_CONFIG                                0xd0b8
 
+#define        DMA_POWER_CNTL                                  0xd0bc
+#       define MEM_POWER_OVERRIDE                       (1 << 8)
+#define        DMA_CLK_CTRL                                    0xd0c0
+
 #define        DMA_PG                                          0xd0d4
 #      define PG_CNTL_ENABLE                           (1 << 0)
 #define        DMA_PGFSM_CONFIG                                0xd0d8