From 23d33ba32bad60a17ca26f631d1d2cf6b12662e5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 8 Apr 2013 12:41:32 +0200 Subject: [PATCH] drm/radeon: add set_uvd_clocks callback for ON/LN/TN (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: write clk registers only once! v3: update cg scratch register properly v4: add TN support Signed-off-by: Christian König Reviewed-by: Jerome Glisse Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 47 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/evergreend.h | 10 ++++++++ drivers/gpu/drm/radeon/radeon_asic.c | 2 ++ drivers/gpu/drm/radeon/radeon_asic.h | 1 + 4 files changed, 60 insertions(+) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 18b66ff..bdd3d34 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -84,6 +84,53 @@ void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, } } +static int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock, + u32 cntl_reg, u32 status_reg) +{ + int r, i; + struct atom_clock_dividers dividers; + + r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, + clock, false, ÷rs); + if (r) + return r; + + WREG32_P(cntl_reg, dividers.post_div, ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK)); + + for (i = 0; i < 100; i++) { + if (RREG32(status_reg) & DCLK_STATUS) + break; + mdelay(10); + } + if (i == 100) + return -ETIMEDOUT; + + return 0; +} + +int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) +{ + int r = 0; + u32 cg_scratch = RREG32(CG_SCRATCH1); + + r = sumo_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS); + if (r) + goto done; + cg_scratch &= 0xffff0000; + cg_scratch |= vclk / 100; /* Mhz */ + + r = sumo_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS); + if (r) + goto done; + cg_scratch &= 0x0000ffff; + cg_scratch |= (dclk / 100) << 16; /* Mhz */ + +done: + WREG32(CG_SCRATCH1, cg_scratch); + + return r; +} + void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) { u16 ctl, v; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index c5d873e..b6491a3 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -53,6 +53,16 @@ #define RCU_IND_INDEX 0x100 #define RCU_IND_DATA 0x104 +/* fusion uvd clocks */ +#define CG_DCLK_CNTL 0x610 +# define DCLK_DIVIDER_MASK 0x7f +# define DCLK_DIR_CNTL_EN (1 << 8) +#define CG_DCLK_STATUS 0x614 +# define DCLK_STATUS (1 << 0) +#define CG_VCLK_CNTL 0x618 +#define CG_VCLK_STATUS 0x61c +#define CG_SCRATCH1 0x820 + #define GRBM_GFX_INDEX 0x802C #define INSTANCE_INDEX(x) ((x) << 0) #define SE_INDEX(x) ((x) << 16) diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index a7a7b2b..d3992d9 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1373,6 +1373,7 @@ static struct radeon_asic sumo_asic = { .get_pcie_lanes = NULL, .set_pcie_lanes = NULL, .set_clock_gating = NULL, + .set_uvd_clocks = &sumo_set_uvd_clocks, }, .pflip = { .pre_page_flip = &evergreen_pre_page_flip, @@ -1744,6 +1745,7 @@ static struct radeon_asic trinity_asic = { .get_pcie_lanes = NULL, .set_pcie_lanes = NULL, .set_clock_gating = NULL, + .set_uvd_clocks = &sumo_set_uvd_clocks, }, .pflip = { .pre_page_flip = &evergreen_pre_page_flip, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 515db96..37f28a3 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -459,6 +459,7 @@ extern void evergreen_pm_prepare(struct radeon_device *rdev); extern void evergreen_pm_finish(struct radeon_device *rdev); extern void sumo_pm_init_profile(struct radeon_device *rdev); extern void btc_pm_init_profile(struct radeon_device *rdev); +int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); -- 2.7.4