Loading drivers/gpu/drm/radeon/cikd.h +10 −0 Original line number Diff line number Diff line Loading @@ -2029,8 +2029,18 @@ #define VCE_RB_RPTR 0x2018c #define VCE_RB_WPTR 0x20190 #define VCE_CLOCK_GATING_A 0x202f8 # define CGC_CLK_GATE_DLY_TIMER_MASK (0xf << 0) # define CGC_CLK_GATE_DLY_TIMER(x) ((x) << 0) # define CGC_CLK_GATER_OFF_DLY_TIMER_MASK (0xff << 4) # define CGC_CLK_GATER_OFF_DLY_TIMER(x) ((x) << 4) # define CGC_UENC_WAIT_AWAKE (1 << 18) #define VCE_CLOCK_GATING_B 0x202fc #define VCE_CGTT_CLK_OVERRIDE 0x207a0 #define VCE_UENC_CLOCK_GATING 0x207bc # define CLOCK_ON_DELAY_MASK (0xf << 0) # define CLOCK_ON_DELAY(x) ((x) << 0) # define CLOCK_OFF_DELAY_MASK (0xff << 4) # define CLOCK_OFF_DELAY(x) ((x) << 4) #define VCE_UENC_REG_CLOCK_GATING 0x207c0 #define VCE_SYS_INT_EN 0x21300 # define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3) Loading drivers/gpu/drm/radeon/vce_v2_0.c +111 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,115 @@ #include "radeon_asic.h" #include "cikd.h" static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated) { u32 tmp; if (gated) { tmp = RREG32(VCE_CLOCK_GATING_B); tmp |= 0xe70000; WREG32(VCE_CLOCK_GATING_B, tmp); tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp |= 0xff000000; WREG32(VCE_UENC_CLOCK_GATING, tmp); tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); tmp &= ~0x3fc; WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); WREG32(VCE_CGTT_CLK_OVERRIDE, 0); } else { tmp = RREG32(VCE_CLOCK_GATING_B); tmp |= 0xe7; tmp &= ~0xe70000; WREG32(VCE_CLOCK_GATING_B, tmp); tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp |= 0x1fe000; tmp &= ~0xff000000; WREG32(VCE_UENC_CLOCK_GATING, tmp); tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); tmp |= 0x3fc; WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); } } static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated) { u32 orig, tmp; tmp = RREG32(VCE_CLOCK_GATING_B); tmp &= ~0x00060006; if (gated) { tmp |= 0xe10000; } else { tmp |= 0xe1; tmp &= ~0xe10000; } WREG32(VCE_CLOCK_GATING_B, tmp); orig = tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp &= ~0x1fe000; tmp &= ~0xff000000; if (tmp != orig) WREG32(VCE_UENC_CLOCK_GATING, tmp); orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); tmp &= ~0x3fc; if (tmp != orig) WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); if (gated) WREG32(VCE_CGTT_CLK_OVERRIDE, 0); } static void vce_v2_0_disable_cg(struct radeon_device *rdev) { WREG32(VCE_CGTT_CLK_OVERRIDE, 7); } void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable) { bool sw_cg = false; if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { if (sw_cg) vce_v2_0_set_sw_cg(rdev, true); else vce_v2_0_set_dyn_cg(rdev, true); } else { vce_v2_0_disable_cg(rdev); if (sw_cg) vce_v2_0_set_sw_cg(rdev, false); else vce_v2_0_set_dyn_cg(rdev, false); } } static void vce_v2_0_init_cg(struct radeon_device *rdev) { u32 tmp; tmp = RREG32(VCE_CLOCK_GATING_A); tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK); tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4)); tmp |= CGC_UENC_WAIT_AWAKE; WREG32(VCE_CLOCK_GATING_A, tmp); tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK); tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4)); WREG32(VCE_UENC_CLOCK_GATING, tmp); tmp = RREG32(VCE_CLOCK_GATING_B); tmp |= 0x10; tmp &= ~0x100000; WREG32(VCE_CLOCK_GATING_B, tmp); } int vce_v2_0_resume(struct radeon_device *rdev) { uint64_t addr = rdev->vce.gpu_addr; Loading Loading @@ -66,5 +175,7 @@ int vce_v2_0_resume(struct radeon_device *rdev) WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, ~VCE_SYS_INT_TRAP_INTERRUPT_EN); vce_v2_0_init_cg(rdev); return 0; } Loading
drivers/gpu/drm/radeon/cikd.h +10 −0 Original line number Diff line number Diff line Loading @@ -2029,8 +2029,18 @@ #define VCE_RB_RPTR 0x2018c #define VCE_RB_WPTR 0x20190 #define VCE_CLOCK_GATING_A 0x202f8 # define CGC_CLK_GATE_DLY_TIMER_MASK (0xf << 0) # define CGC_CLK_GATE_DLY_TIMER(x) ((x) << 0) # define CGC_CLK_GATER_OFF_DLY_TIMER_MASK (0xff << 4) # define CGC_CLK_GATER_OFF_DLY_TIMER(x) ((x) << 4) # define CGC_UENC_WAIT_AWAKE (1 << 18) #define VCE_CLOCK_GATING_B 0x202fc #define VCE_CGTT_CLK_OVERRIDE 0x207a0 #define VCE_UENC_CLOCK_GATING 0x207bc # define CLOCK_ON_DELAY_MASK (0xf << 0) # define CLOCK_ON_DELAY(x) ((x) << 0) # define CLOCK_OFF_DELAY_MASK (0xff << 4) # define CLOCK_OFF_DELAY(x) ((x) << 4) #define VCE_UENC_REG_CLOCK_GATING 0x207c0 #define VCE_SYS_INT_EN 0x21300 # define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3) Loading
drivers/gpu/drm/radeon/vce_v2_0.c +111 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,115 @@ #include "radeon_asic.h" #include "cikd.h" static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated) { u32 tmp; if (gated) { tmp = RREG32(VCE_CLOCK_GATING_B); tmp |= 0xe70000; WREG32(VCE_CLOCK_GATING_B, tmp); tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp |= 0xff000000; WREG32(VCE_UENC_CLOCK_GATING, tmp); tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); tmp &= ~0x3fc; WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); WREG32(VCE_CGTT_CLK_OVERRIDE, 0); } else { tmp = RREG32(VCE_CLOCK_GATING_B); tmp |= 0xe7; tmp &= ~0xe70000; WREG32(VCE_CLOCK_GATING_B, tmp); tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp |= 0x1fe000; tmp &= ~0xff000000; WREG32(VCE_UENC_CLOCK_GATING, tmp); tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); tmp |= 0x3fc; WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); } } static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated) { u32 orig, tmp; tmp = RREG32(VCE_CLOCK_GATING_B); tmp &= ~0x00060006; if (gated) { tmp |= 0xe10000; } else { tmp |= 0xe1; tmp &= ~0xe10000; } WREG32(VCE_CLOCK_GATING_B, tmp); orig = tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp &= ~0x1fe000; tmp &= ~0xff000000; if (tmp != orig) WREG32(VCE_UENC_CLOCK_GATING, tmp); orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); tmp &= ~0x3fc; if (tmp != orig) WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); if (gated) WREG32(VCE_CGTT_CLK_OVERRIDE, 0); } static void vce_v2_0_disable_cg(struct radeon_device *rdev) { WREG32(VCE_CGTT_CLK_OVERRIDE, 7); } void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable) { bool sw_cg = false; if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { if (sw_cg) vce_v2_0_set_sw_cg(rdev, true); else vce_v2_0_set_dyn_cg(rdev, true); } else { vce_v2_0_disable_cg(rdev); if (sw_cg) vce_v2_0_set_sw_cg(rdev, false); else vce_v2_0_set_dyn_cg(rdev, false); } } static void vce_v2_0_init_cg(struct radeon_device *rdev) { u32 tmp; tmp = RREG32(VCE_CLOCK_GATING_A); tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK); tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4)); tmp |= CGC_UENC_WAIT_AWAKE; WREG32(VCE_CLOCK_GATING_A, tmp); tmp = RREG32(VCE_UENC_CLOCK_GATING); tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK); tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4)); WREG32(VCE_UENC_CLOCK_GATING, tmp); tmp = RREG32(VCE_CLOCK_GATING_B); tmp |= 0x10; tmp &= ~0x100000; WREG32(VCE_CLOCK_GATING_B, tmp); } int vce_v2_0_resume(struct radeon_device *rdev) { uint64_t addr = rdev->vce.gpu_addr; Loading Loading @@ -66,5 +175,7 @@ int vce_v2_0_resume(struct radeon_device *rdev) WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, ~VCE_SYS_INT_TRAP_INTERRUPT_EN); vce_v2_0_init_cg(rdev); return 0; }