diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-04-08 06:41:32 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-04-09 10:31:35 -0400 |
commit | 23d33ba32bad60a17ca26f631d1d2cf6b12662e5 (patch) | |
tree | 86681373847e4831d6c14fb998e259c97493a880 | |
parent | 7062ab67d4c6568ec423da39321423721b925fdc (diff) |
drm/radeon: add set_uvd_clocks callback for ON/LN/TN (v4)
v2: write clk registers only once!
v3: update cg scratch register properly
v4: add TN support
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 1 |
4 files changed, 60 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 18b66ff59dcf..bdd3d3470421 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, | |||
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
87 | static int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock, | ||
88 | u32 cntl_reg, u32 status_reg) | ||
89 | { | ||
90 | int r, i; | ||
91 | struct atom_clock_dividers dividers; | ||
92 | |||
93 | r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, | ||
94 | clock, false, ÷rs); | ||
95 | if (r) | ||
96 | return r; | ||
97 | |||
98 | WREG32_P(cntl_reg, dividers.post_div, ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK)); | ||
99 | |||
100 | for (i = 0; i < 100; i++) { | ||
101 | if (RREG32(status_reg) & DCLK_STATUS) | ||
102 | break; | ||
103 | mdelay(10); | ||
104 | } | ||
105 | if (i == 100) | ||
106 | return -ETIMEDOUT; | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) | ||
112 | { | ||
113 | int r = 0; | ||
114 | u32 cg_scratch = RREG32(CG_SCRATCH1); | ||
115 | |||
116 | r = sumo_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS); | ||
117 | if (r) | ||
118 | goto done; | ||
119 | cg_scratch &= 0xffff0000; | ||
120 | cg_scratch |= vclk / 100; /* Mhz */ | ||
121 | |||
122 | r = sumo_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS); | ||
123 | if (r) | ||
124 | goto done; | ||
125 | cg_scratch &= 0x0000ffff; | ||
126 | cg_scratch |= (dclk / 100) << 16; /* Mhz */ | ||
127 | |||
128 | done: | ||
129 | WREG32(CG_SCRATCH1, cg_scratch); | ||
130 | |||
131 | return r; | ||
132 | } | ||
133 | |||
87 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | 134 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) |
88 | { | 135 | { |
89 | u16 ctl, v; | 136 | u16 ctl, v; |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index c5d873e525c9..b6491a300c5c 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -53,6 +53,16 @@ | |||
53 | #define RCU_IND_INDEX 0x100 | 53 | #define RCU_IND_INDEX 0x100 |
54 | #define RCU_IND_DATA 0x104 | 54 | #define RCU_IND_DATA 0x104 |
55 | 55 | ||
56 | /* fusion uvd clocks */ | ||
57 | #define CG_DCLK_CNTL 0x610 | ||
58 | # define DCLK_DIVIDER_MASK 0x7f | ||
59 | # define DCLK_DIR_CNTL_EN (1 << 8) | ||
60 | #define CG_DCLK_STATUS 0x614 | ||
61 | # define DCLK_STATUS (1 << 0) | ||
62 | #define CG_VCLK_CNTL 0x618 | ||
63 | #define CG_VCLK_STATUS 0x61c | ||
64 | #define CG_SCRATCH1 0x820 | ||
65 | |||
56 | #define GRBM_GFX_INDEX 0x802C | 66 | #define GRBM_GFX_INDEX 0x802C |
57 | #define INSTANCE_INDEX(x) ((x) << 0) | 67 | #define INSTANCE_INDEX(x) ((x) << 0) |
58 | #define SE_INDEX(x) ((x) << 16) | 68 | #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 a7a7b2bc4204..d3992d99bfbb 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 = { | |||
1373 | .get_pcie_lanes = NULL, | 1373 | .get_pcie_lanes = NULL, |
1374 | .set_pcie_lanes = NULL, | 1374 | .set_pcie_lanes = NULL, |
1375 | .set_clock_gating = NULL, | 1375 | .set_clock_gating = NULL, |
1376 | .set_uvd_clocks = &sumo_set_uvd_clocks, | ||
1376 | }, | 1377 | }, |
1377 | .pflip = { | 1378 | .pflip = { |
1378 | .pre_page_flip = &evergreen_pre_page_flip, | 1379 | .pre_page_flip = &evergreen_pre_page_flip, |
@@ -1744,6 +1745,7 @@ static struct radeon_asic trinity_asic = { | |||
1744 | .get_pcie_lanes = NULL, | 1745 | .get_pcie_lanes = NULL, |
1745 | .set_pcie_lanes = NULL, | 1746 | .set_pcie_lanes = NULL, |
1746 | .set_clock_gating = NULL, | 1747 | .set_clock_gating = NULL, |
1748 | .set_uvd_clocks = &sumo_set_uvd_clocks, | ||
1747 | }, | 1749 | }, |
1748 | .pflip = { | 1750 | .pflip = { |
1749 | .pre_page_flip = &evergreen_pre_page_flip, | 1751 | .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 515db96e3e2c..37f28a3e61bd 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); | |||
459 | extern void evergreen_pm_finish(struct radeon_device *rdev); | 459 | extern void evergreen_pm_finish(struct radeon_device *rdev); |
460 | extern void sumo_pm_init_profile(struct radeon_device *rdev); | 460 | extern void sumo_pm_init_profile(struct radeon_device *rdev); |
461 | extern void btc_pm_init_profile(struct radeon_device *rdev); | 461 | extern void btc_pm_init_profile(struct radeon_device *rdev); |
462 | int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); | ||
462 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); | 463 | extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); |
463 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | 464 | extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); |
464 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); | 465 | extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); |