From 0fda42ac40ac7edf62ebb750be41a34902d2fdfb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 11 May 2015 22:01:50 +0200 Subject: drm/radeon: implement tn_set_vce_clocks This implements the function to set the vce clocks on TN hardware. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ni.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/nid.h | 7 +++++++ drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 1 + 4 files changed, 40 insertions(+) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index aba2f428c0a8..a6d940fc44e8 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -2554,3 +2554,34 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); radeon_ring_write(ring, 0x0); } + +int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk) +{ + struct atom_clock_dividers dividers; + int r, i; + + r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, + ecclk, false, ÷rs); + if (r) + return r; + + for (i = 0; i < 100; i++) { + if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS) + break; + mdelay(10); + } + if (i == 100) + return -ETIMEDOUT; + + WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK)); + + for (i = 0; i < 100; i++) { + if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS) + break; + mdelay(10); + } + if (i == 100) + return -ETIMEDOUT; + + return 0; +} diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index 3b290838918c..47eb49b77d32 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h @@ -46,6 +46,13 @@ #define DMIF_ADDR_CONFIG 0xBD4 +/* fusion vce clocks */ +#define CG_ECLK_CNTL 0x620 +# define ECLK_DIVIDER_MASK 0x7f +# define ECLK_DIR_CNTL_EN (1 << 8) +#define CG_ECLK_STATUS 0x624 +# define ECLK_STATUS (1 << 0) + /* DCE6 only */ #define DMIF_ADDR_CALC 0xC00 diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 4227b30b5ce6..b37b22bdf579 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1838,6 +1838,7 @@ static struct radeon_asic trinity_asic = { .set_pcie_lanes = NULL, .set_clock_gating = NULL, .set_uvd_clocks = &sumo_set_uvd_clocks, + .set_vce_clocks = &tn_set_vce_clocks, .get_temperature = &tn_get_temp, }, .dpm = { diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 0469d440764b..629f2910a33e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -694,6 +694,7 @@ int trinity_dpm_force_performance_level(struct radeon_device *rdev, void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable); u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev); u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev); +int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk); /* DCE6 - SI */ void dce6_bandwidth_update(struct radeon_device *rdev); -- cgit v1.2.3