diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-amd/0041-drm-radeon-add-support-for-vce-2.0-clock-gating.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-amd/0041-drm-radeon-add-support-for-vce-2.0-clock-gating.patch | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-amd/0041-drm-radeon-add-support-for-vce-2.0-clock-gating.patch b/common/recipes-kernel/linux/linux-amd/0041-drm-radeon-add-support-for-vce-2.0-clock-gating.patch new file mode 100644 index 00000000..03629691 --- /dev/null +++ b/common/recipes-kernel/linux/linux-amd/0041-drm-radeon-add-support-for-vce-2.0-clock-gating.patch @@ -0,0 +1,165 @@ +From e9b1866c0dba795476cc4bdbafa39586ff443b25 Mon Sep 17 00:00:00 2001 +From: Alex Deucher <alexander.deucher@amd.com> +Date: Thu, 5 Sep 2013 15:14:28 -0400 +Subject: [PATCH 41/60] drm/radeon: add support for vce 2.0 clock gating + +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/radeon/cikd.h | 10 ++++ + drivers/gpu/drm/radeon/vce_v2_0.c | 111 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 121 insertions(+) + +diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h +index 481d56e..26114a3 100644 +--- a/drivers/gpu/drm/radeon/cikd.h ++++ b/drivers/gpu/drm/radeon/cikd.h +@@ -1927,8 +1927,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) +diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c +index 4911d1b..1ac7bb8 100644 +--- a/drivers/gpu/drm/radeon/vce_v2_0.c ++++ b/drivers/gpu/drm/radeon/vce_v2_0.c +@@ -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; +@@ -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; + } +-- +1.9.1 + |