drm/radeon/si: restructure cg code (v3)

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>
This commit is contained in:
Alex Deucher 2013-08-08 19:34:07 -04:00
parent 0116e1efaf
commit e16866ecfb
4 changed files with 192 additions and 34 deletions

View 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)

View 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 |

View 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);

View file

@ -581,6 +581,7 @@
#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
@ -588,6 +589,8 @@
#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
@ -1354,6 +1357,7 @@
/* 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 */
@ -1703,6 +1707,10 @@
# 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