diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cypress_dpm.c | 2105 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/cypress_dpm.h | 134 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 22 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_smc.h | 67 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 305 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_acpi.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ucode.h | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770_dpm.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770_dpm.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770_smc.c | 109 |
16 files changed, 2877 insertions, 10 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index c97753d3d970..7092c96295b3 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -78,7 +78,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
78 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ | 78 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ |
79 | si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \ | 79 | si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \ |
80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ | 80 | r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \ |
81 | rv770_smc.o | 81 | rv770_smc.o cypress_dpm.o |
82 | 82 | ||
83 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 83 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
84 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 84 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c new file mode 100644 index 000000000000..91434acfe4b8 --- /dev/null +++ b/drivers/gpu/drm/radeon/cypress_dpm.c | |||
@@ -0,0 +1,2105 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Alex Deucher | ||
23 | */ | ||
24 | |||
25 | #include "drmP.h" | ||
26 | #include "radeon.h" | ||
27 | #include "evergreend.h" | ||
28 | #include "r600_dpm.h" | ||
29 | #include "cypress_dpm.h" | ||
30 | #include "atom.h" | ||
31 | |||
32 | #define SMC_RAM_END 0x8000 | ||
33 | |||
34 | #define MC_CG_ARB_FREQ_F0 0x0a | ||
35 | #define MC_CG_ARB_FREQ_F1 0x0b | ||
36 | #define MC_CG_ARB_FREQ_F2 0x0c | ||
37 | #define MC_CG_ARB_FREQ_F3 0x0d | ||
38 | |||
39 | #define MC_CG_SEQ_DRAMCONF_S0 0x05 | ||
40 | #define MC_CG_SEQ_DRAMCONF_S1 0x06 | ||
41 | #define MC_CG_SEQ_YCLK_SUSPEND 0x04 | ||
42 | #define MC_CG_SEQ_YCLK_RESUME 0x0a | ||
43 | |||
44 | struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps); | ||
45 | struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); | ||
46 | struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev); | ||
47 | |||
48 | static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev, | ||
49 | u32 memory_clock, bool strobe_mode); | ||
50 | |||
51 | static void cypress_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, | ||
52 | bool enable) | ||
53 | { | ||
54 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
55 | u32 tmp, bif; | ||
56 | |||
57 | tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); | ||
58 | if (enable) { | ||
59 | if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
60 | (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
61 | if (!pi->boot_in_gen2) { | ||
62 | bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK; | ||
63 | bif |= CG_CLIENT_REQ(0xd); | ||
64 | WREG32(CG_BIF_REQ_AND_RSP, bif); | ||
65 | |||
66 | tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK; | ||
67 | tmp |= LC_HW_VOLTAGE_IF_CONTROL(1); | ||
68 | tmp |= LC_GEN2_EN_STRAP; | ||
69 | |||
70 | tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
71 | WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp); | ||
72 | udelay(10); | ||
73 | tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
74 | WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp); | ||
75 | } | ||
76 | } | ||
77 | } else { | ||
78 | if (!pi->boot_in_gen2) { | ||
79 | tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK; | ||
80 | tmp &= ~LC_GEN2_EN_STRAP; | ||
81 | } | ||
82 | if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) || | ||
83 | (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) | ||
84 | WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static void cypress_enable_dynamic_pcie_gen2(struct radeon_device *rdev, | ||
89 | bool enable) | ||
90 | { | ||
91 | cypress_enable_bif_dynamic_pcie_gen2(rdev, enable); | ||
92 | |||
93 | if (enable) | ||
94 | WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE); | ||
95 | else | ||
96 | WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE); | ||
97 | } | ||
98 | |||
99 | #if 0 | ||
100 | static int cypress_enter_ulp_state(struct radeon_device *rdev) | ||
101 | { | ||
102 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
103 | |||
104 | if (pi->gfx_clock_gating) { | ||
105 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN); | ||
106 | WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON); | ||
107 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON); | ||
108 | |||
109 | RREG32(GB_ADDR_CONFIG); | ||
110 | } | ||
111 | |||
112 | WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower), | ||
113 | ~HOST_SMC_MSG_MASK); | ||
114 | |||
115 | udelay(7000); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | #endif | ||
120 | |||
121 | static void cypress_gfx_clock_gating_enable(struct radeon_device *rdev, | ||
122 | bool enable) | ||
123 | { | ||
124 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
125 | |||
126 | if (enable) { | ||
127 | if (eg_pi->light_sleep) { | ||
128 | WREG32(GRBM_GFX_INDEX, 0xC0000000); | ||
129 | |||
130 | WREG32_CG(CG_CGLS_TILE_0, 0xFFFFFFFF); | ||
131 | WREG32_CG(CG_CGLS_TILE_1, 0xFFFFFFFF); | ||
132 | WREG32_CG(CG_CGLS_TILE_2, 0xFFFFFFFF); | ||
133 | WREG32_CG(CG_CGLS_TILE_3, 0xFFFFFFFF); | ||
134 | WREG32_CG(CG_CGLS_TILE_4, 0xFFFFFFFF); | ||
135 | WREG32_CG(CG_CGLS_TILE_5, 0xFFFFFFFF); | ||
136 | WREG32_CG(CG_CGLS_TILE_6, 0xFFFFFFFF); | ||
137 | WREG32_CG(CG_CGLS_TILE_7, 0xFFFFFFFF); | ||
138 | WREG32_CG(CG_CGLS_TILE_8, 0xFFFFFFFF); | ||
139 | WREG32_CG(CG_CGLS_TILE_9, 0xFFFFFFFF); | ||
140 | WREG32_CG(CG_CGLS_TILE_10, 0xFFFFFFFF); | ||
141 | WREG32_CG(CG_CGLS_TILE_11, 0xFFFFFFFF); | ||
142 | |||
143 | WREG32_P(SCLK_PWRMGT_CNTL, DYN_LIGHT_SLEEP_EN, ~DYN_LIGHT_SLEEP_EN); | ||
144 | } | ||
145 | WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN); | ||
146 | } else { | ||
147 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN); | ||
148 | WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON); | ||
149 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON); | ||
150 | RREG32(GB_ADDR_CONFIG); | ||
151 | |||
152 | if (eg_pi->light_sleep) { | ||
153 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_LIGHT_SLEEP_EN); | ||
154 | |||
155 | WREG32(GRBM_GFX_INDEX, 0xC0000000); | ||
156 | |||
157 | WREG32_CG(CG_CGLS_TILE_0, 0); | ||
158 | WREG32_CG(CG_CGLS_TILE_1, 0); | ||
159 | WREG32_CG(CG_CGLS_TILE_2, 0); | ||
160 | WREG32_CG(CG_CGLS_TILE_3, 0); | ||
161 | WREG32_CG(CG_CGLS_TILE_4, 0); | ||
162 | WREG32_CG(CG_CGLS_TILE_5, 0); | ||
163 | WREG32_CG(CG_CGLS_TILE_6, 0); | ||
164 | WREG32_CG(CG_CGLS_TILE_7, 0); | ||
165 | WREG32_CG(CG_CGLS_TILE_8, 0); | ||
166 | WREG32_CG(CG_CGLS_TILE_9, 0); | ||
167 | WREG32_CG(CG_CGLS_TILE_10, 0); | ||
168 | WREG32_CG(CG_CGLS_TILE_11, 0); | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static void cypress_mg_clock_gating_enable(struct radeon_device *rdev, | ||
174 | bool enable) | ||
175 | { | ||
176 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
177 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
178 | |||
179 | if (enable) { | ||
180 | u32 cgts_sm_ctrl_reg; | ||
181 | |||
182 | if (rdev->family == CHIP_CEDAR) | ||
183 | cgts_sm_ctrl_reg = CEDAR_MGCGCGTSSMCTRL_DFLT; | ||
184 | else if (rdev->family == CHIP_REDWOOD) | ||
185 | cgts_sm_ctrl_reg = REDWOOD_MGCGCGTSSMCTRL_DFLT; | ||
186 | else | ||
187 | cgts_sm_ctrl_reg = CYPRESS_MGCGCGTSSMCTRL_DFLT; | ||
188 | |||
189 | WREG32(GRBM_GFX_INDEX, 0xC0000000); | ||
190 | |||
191 | WREG32_CG(CG_CGTT_LOCAL_0, CYPRESS_MGCGTTLOCAL0_DFLT); | ||
192 | WREG32_CG(CG_CGTT_LOCAL_1, CYPRESS_MGCGTTLOCAL1_DFLT & 0xFFFFCFFF); | ||
193 | WREG32_CG(CG_CGTT_LOCAL_2, CYPRESS_MGCGTTLOCAL2_DFLT); | ||
194 | WREG32_CG(CG_CGTT_LOCAL_3, CYPRESS_MGCGTTLOCAL3_DFLT); | ||
195 | |||
196 | if (pi->mgcgtssm) | ||
197 | WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg); | ||
198 | |||
199 | if (eg_pi->mcls) { | ||
200 | WREG32_P(MC_CITF_MISC_RD_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
201 | WREG32_P(MC_CITF_MISC_WR_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
202 | WREG32_P(MC_CITF_MISC_VM_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
203 | WREG32_P(MC_HUB_MISC_HUB_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
204 | WREG32_P(MC_HUB_MISC_VM_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
205 | WREG32_P(MC_HUB_MISC_SIP_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
206 | WREG32_P(MC_XPB_CLK_GAT, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
207 | WREG32_P(VM_L2_CG, MEM_LS_ENABLE, ~MEM_LS_ENABLE); | ||
208 | } | ||
209 | } else { | ||
210 | WREG32(GRBM_GFX_INDEX, 0xC0000000); | ||
211 | |||
212 | WREG32_CG(CG_CGTT_LOCAL_0, 0xFFFFFFFF); | ||
213 | WREG32_CG(CG_CGTT_LOCAL_1, 0xFFFFFFFF); | ||
214 | WREG32_CG(CG_CGTT_LOCAL_2, 0xFFFFFFFF); | ||
215 | WREG32_CG(CG_CGTT_LOCAL_3, 0xFFFFFFFF); | ||
216 | |||
217 | if (pi->mgcgtssm) | ||
218 | WREG32(CGTS_SM_CTRL_REG, 0x81f44bc0); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | void cypress_enable_spread_spectrum(struct radeon_device *rdev, | ||
223 | bool enable) | ||
224 | { | ||
225 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
226 | |||
227 | if (enable) { | ||
228 | if (pi->sclk_ss) | ||
229 | WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN); | ||
230 | |||
231 | if (pi->mclk_ss) | ||
232 | WREG32_P(MPLL_CNTL_MODE, SS_SSEN, ~SS_SSEN); | ||
233 | } else { | ||
234 | WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN); | ||
235 | WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN); | ||
236 | WREG32_P(MPLL_CNTL_MODE, 0, ~SS_SSEN); | ||
237 | WREG32_P(MPLL_CNTL_MODE, 0, ~SS_DSMODE_EN); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | void cypress_start_dpm(struct radeon_device *rdev) | ||
242 | { | ||
243 | WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN); | ||
244 | } | ||
245 | |||
246 | void cypress_enable_sclk_control(struct radeon_device *rdev, | ||
247 | bool enable) | ||
248 | { | ||
249 | if (enable) | ||
250 | WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF); | ||
251 | else | ||
252 | WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF); | ||
253 | } | ||
254 | |||
255 | void cypress_enable_mclk_control(struct radeon_device *rdev, | ||
256 | bool enable) | ||
257 | { | ||
258 | if (enable) | ||
259 | WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF); | ||
260 | else | ||
261 | WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF); | ||
262 | } | ||
263 | |||
264 | int cypress_notify_smc_display_change(struct radeon_device *rdev, | ||
265 | bool has_display) | ||
266 | { | ||
267 | PPSMC_Msg msg = has_display ? | ||
268 | (PPSMC_Msg)PPSMC_MSG_HasDisplay : (PPSMC_Msg)PPSMC_MSG_NoDisplay; | ||
269 | |||
270 | if (rv770_send_msg_to_smc(rdev, msg) != PPSMC_Result_OK) | ||
271 | return -EINVAL; | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | void cypress_program_response_times(struct radeon_device *rdev) | ||
277 | { | ||
278 | u32 reference_clock; | ||
279 | u32 mclk_switch_limit; | ||
280 | |||
281 | reference_clock = radeon_get_xclk(rdev); | ||
282 | mclk_switch_limit = (460 * reference_clock) / 100; | ||
283 | |||
284 | rv770_write_smc_soft_register(rdev, | ||
285 | RV770_SMC_SOFT_REGISTER_mclk_switch_lim, | ||
286 | mclk_switch_limit); | ||
287 | |||
288 | rv770_write_smc_soft_register(rdev, | ||
289 | RV770_SMC_SOFT_REGISTER_mvdd_chg_time, 1); | ||
290 | |||
291 | rv770_write_smc_soft_register(rdev, | ||
292 | RV770_SMC_SOFT_REGISTER_mc_block_delay, 0xAA); | ||
293 | |||
294 | rv770_program_response_times(rdev); | ||
295 | |||
296 | if (ASIC_IS_LOMBOK(rdev)) | ||
297 | rv770_write_smc_soft_register(rdev, | ||
298 | RV770_SMC_SOFT_REGISTER_is_asic_lombok, 1); | ||
299 | |||
300 | } | ||
301 | |||
302 | static int cypress_pcie_performance_request(struct radeon_device *rdev, | ||
303 | u8 perf_req, bool advertise) | ||
304 | { | ||
305 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
306 | u32 tmp; | ||
307 | |||
308 | udelay(10); | ||
309 | tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); | ||
310 | if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) && (tmp & LC_CURRENT_DATA_RATE)) | ||
311 | return 0; | ||
312 | |||
313 | #if defined(CONFIG_ACPI) | ||
314 | if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) || | ||
315 | (perf_req == PCIE_PERF_REQ_PECI_GEN2)) { | ||
316 | eg_pi->pcie_performance_request_registered = true; | ||
317 | return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise); | ||
318 | } else if ((perf_req == PCIE_PERF_REQ_REMOVE_REGISTRY) && | ||
319 | eg_pi->pcie_performance_request_registered) { | ||
320 | eg_pi->pcie_performance_request_registered = false; | ||
321 | return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise); | ||
322 | } | ||
323 | #endif | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | void cypress_advertise_gen2_capability(struct radeon_device *rdev) | ||
329 | { | ||
330 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
331 | u32 tmp; | ||
332 | |||
333 | #if defined(CONFIG_ACPI) | ||
334 | radeon_acpi_pcie_notify_device_ready(rdev); | ||
335 | #endif | ||
336 | |||
337 | tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); | ||
338 | |||
339 | if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
340 | (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) | ||
341 | pi->pcie_gen2 = true; | ||
342 | else | ||
343 | pi->pcie_gen2 = false; | ||
344 | |||
345 | if (!pi->pcie_gen2) | ||
346 | cypress_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, true); | ||
347 | |||
348 | } | ||
349 | |||
350 | static u32 cypress_get_maximum_link_speed(struct radeon_ps *radeon_state) | ||
351 | { | ||
352 | struct rv7xx_ps *state = rv770_get_ps(radeon_state); | ||
353 | |||
354 | if (state->high.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) | ||
355 | return 1; | ||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | void cypress_notify_link_speed_change_after_state_change(struct radeon_device *rdev) | ||
360 | { | ||
361 | struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; | ||
362 | struct radeon_ps *radeon_current_state = rdev->pm.dpm.current_ps; | ||
363 | u32 pcie_link_speed_target = cypress_get_maximum_link_speed(radeon_new_state); | ||
364 | u32 pcie_link_speed_current = cypress_get_maximum_link_speed(radeon_current_state); | ||
365 | u8 request; | ||
366 | |||
367 | if (pcie_link_speed_target < pcie_link_speed_current) { | ||
368 | if (pcie_link_speed_target == 0) | ||
369 | request = PCIE_PERF_REQ_PECI_GEN1; | ||
370 | else if (pcie_link_speed_target == 1) | ||
371 | request = PCIE_PERF_REQ_PECI_GEN2; | ||
372 | else | ||
373 | request = PCIE_PERF_REQ_PECI_GEN3; | ||
374 | |||
375 | cypress_pcie_performance_request(rdev, request, false); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | void cypress_notify_link_speed_change_before_state_change(struct radeon_device *rdev) | ||
380 | { | ||
381 | struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; | ||
382 | struct radeon_ps *radeon_current_state = rdev->pm.dpm.current_ps; | ||
383 | u32 pcie_link_speed_target = cypress_get_maximum_link_speed(radeon_new_state); | ||
384 | u32 pcie_link_speed_current = cypress_get_maximum_link_speed(radeon_current_state); | ||
385 | u8 request; | ||
386 | |||
387 | if (pcie_link_speed_target > pcie_link_speed_current) { | ||
388 | if (pcie_link_speed_target == 0) | ||
389 | request = PCIE_PERF_REQ_PECI_GEN1; | ||
390 | else if (pcie_link_speed_target == 1) | ||
391 | request = PCIE_PERF_REQ_PECI_GEN2; | ||
392 | else | ||
393 | request = PCIE_PERF_REQ_PECI_GEN3; | ||
394 | |||
395 | cypress_pcie_performance_request(rdev, request, false); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | static int cypress_populate_voltage_value(struct radeon_device *rdev, | ||
400 | struct atom_voltage_table *table, | ||
401 | u16 value, RV770_SMC_VOLTAGE_VALUE *voltage) | ||
402 | { | ||
403 | unsigned int i; | ||
404 | |||
405 | for (i = 0; i < table->count; i++) { | ||
406 | if (value <= table->entries[i].value) { | ||
407 | voltage->index = (u8)i; | ||
408 | voltage->value = cpu_to_be16(table->entries[i].value); | ||
409 | break; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | if (i == table->count) | ||
414 | return -EINVAL; | ||
415 | |||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk) | ||
420 | { | ||
421 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
422 | u8 result = 0; | ||
423 | bool strobe_mode = false; | ||
424 | |||
425 | if (pi->mem_gddr5) { | ||
426 | if (mclk <= pi->mclk_strobe_mode_threshold) | ||
427 | strobe_mode = true; | ||
428 | result = cypress_get_mclk_frequency_ratio(rdev, mclk, strobe_mode); | ||
429 | |||
430 | if (strobe_mode) | ||
431 | result |= SMC_STROBE_ENABLE; | ||
432 | } | ||
433 | |||
434 | return result; | ||
435 | } | ||
436 | |||
437 | static u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf) | ||
438 | { | ||
439 | u32 ref_clk = rdev->clock.mpll.reference_freq; | ||
440 | u32 vco = clkf * ref_clk; | ||
441 | |||
442 | /* 100 Mhz ref clk */ | ||
443 | if (ref_clk == 10000) { | ||
444 | if (vco > 500000) | ||
445 | return 0xC6; | ||
446 | if (vco > 400000) | ||
447 | return 0x9D; | ||
448 | if (vco > 330000) | ||
449 | return 0x6C; | ||
450 | if (vco > 250000) | ||
451 | return 0x2B; | ||
452 | if (vco > 160000) | ||
453 | return 0x5B; | ||
454 | if (vco > 120000) | ||
455 | return 0x0A; | ||
456 | return 0x4B; | ||
457 | } | ||
458 | |||
459 | /* 27 Mhz ref clk */ | ||
460 | if (vco > 250000) | ||
461 | return 0x8B; | ||
462 | if (vco > 200000) | ||
463 | return 0xCC; | ||
464 | if (vco > 150000) | ||
465 | return 0x9B; | ||
466 | return 0x6B; | ||
467 | } | ||
468 | |||
469 | static int cypress_populate_mclk_value(struct radeon_device *rdev, | ||
470 | u32 engine_clock, u32 memory_clock, | ||
471 | RV7XX_SMC_MCLK_VALUE *mclk, | ||
472 | bool strobe_mode, bool dll_state_on) | ||
473 | { | ||
474 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
475 | |||
476 | u32 mpll_ad_func_cntl = | ||
477 | pi->clk_regs.rv770.mpll_ad_func_cntl; | ||
478 | u32 mpll_ad_func_cntl_2 = | ||
479 | pi->clk_regs.rv770.mpll_ad_func_cntl_2; | ||
480 | u32 mpll_dq_func_cntl = | ||
481 | pi->clk_regs.rv770.mpll_dq_func_cntl; | ||
482 | u32 mpll_dq_func_cntl_2 = | ||
483 | pi->clk_regs.rv770.mpll_dq_func_cntl_2; | ||
484 | u32 mclk_pwrmgt_cntl = | ||
485 | pi->clk_regs.rv770.mclk_pwrmgt_cntl; | ||
486 | u32 dll_cntl = | ||
487 | pi->clk_regs.rv770.dll_cntl; | ||
488 | u32 mpll_ss1 = pi->clk_regs.rv770.mpll_ss1; | ||
489 | u32 mpll_ss2 = pi->clk_regs.rv770.mpll_ss2; | ||
490 | struct atom_clock_dividers dividers; | ||
491 | u32 ibias; | ||
492 | u32 dll_speed; | ||
493 | int ret; | ||
494 | u32 mc_seq_misc7; | ||
495 | |||
496 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM, | ||
497 | memory_clock, strobe_mode, ÷rs); | ||
498 | if (ret) | ||
499 | return ret; | ||
500 | |||
501 | if (!strobe_mode) { | ||
502 | mc_seq_misc7 = RREG32(MC_SEQ_MISC7); | ||
503 | |||
504 | if(mc_seq_misc7 & 0x8000000) | ||
505 | dividers.post_div = 1; | ||
506 | } | ||
507 | |||
508 | ibias = cypress_map_clkf_to_ibias(rdev, dividers.whole_fb_div); | ||
509 | |||
510 | mpll_ad_func_cntl &= ~(CLKR_MASK | | ||
511 | YCLK_POST_DIV_MASK | | ||
512 | CLKF_MASK | | ||
513 | CLKFRAC_MASK | | ||
514 | IBIAS_MASK); | ||
515 | mpll_ad_func_cntl |= CLKR(dividers.ref_div); | ||
516 | mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div); | ||
517 | mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div); | ||
518 | mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div); | ||
519 | mpll_ad_func_cntl |= IBIAS(ibias); | ||
520 | |||
521 | if (dividers.vco_mode) | ||
522 | mpll_ad_func_cntl_2 |= VCO_MODE; | ||
523 | else | ||
524 | mpll_ad_func_cntl_2 &= ~VCO_MODE; | ||
525 | |||
526 | if (pi->mem_gddr5) { | ||
527 | mpll_dq_func_cntl &= ~(CLKR_MASK | | ||
528 | YCLK_POST_DIV_MASK | | ||
529 | CLKF_MASK | | ||
530 | CLKFRAC_MASK | | ||
531 | IBIAS_MASK); | ||
532 | mpll_dq_func_cntl |= CLKR(dividers.ref_div); | ||
533 | mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div); | ||
534 | mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div); | ||
535 | mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div); | ||
536 | mpll_dq_func_cntl |= IBIAS(ibias); | ||
537 | |||
538 | if (strobe_mode) | ||
539 | mpll_dq_func_cntl &= ~PDNB; | ||
540 | else | ||
541 | mpll_dq_func_cntl |= PDNB; | ||
542 | |||
543 | if (dividers.vco_mode) | ||
544 | mpll_dq_func_cntl_2 |= VCO_MODE; | ||
545 | else | ||
546 | mpll_dq_func_cntl_2 &= ~VCO_MODE; | ||
547 | } | ||
548 | |||
549 | if (pi->mclk_ss) { | ||
550 | struct radeon_atom_ss ss; | ||
551 | u32 vco_freq = memory_clock * dividers.post_div; | ||
552 | |||
553 | if (radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
554 | ASIC_INTERNAL_MEMORY_SS, vco_freq)) { | ||
555 | u32 reference_clock = rdev->clock.mpll.reference_freq; | ||
556 | u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); | ||
557 | u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); | ||
558 | u32 clk_v = ss.percentage * | ||
559 | (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); | ||
560 | |||
561 | mpll_ss1 &= ~CLKV_MASK; | ||
562 | mpll_ss1 |= CLKV(clk_v); | ||
563 | |||
564 | mpll_ss2 &= ~CLKS_MASK; | ||
565 | mpll_ss2 |= CLKS(clk_s); | ||
566 | } | ||
567 | } | ||
568 | |||
569 | dll_speed = rv740_get_dll_speed(pi->mem_gddr5, | ||
570 | memory_clock); | ||
571 | |||
572 | mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK; | ||
573 | mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed); | ||
574 | if (dll_state_on) | ||
575 | mclk_pwrmgt_cntl |= (MRDCKA0_PDNB | | ||
576 | MRDCKA1_PDNB | | ||
577 | MRDCKB0_PDNB | | ||
578 | MRDCKB1_PDNB | | ||
579 | MRDCKC0_PDNB | | ||
580 | MRDCKC1_PDNB | | ||
581 | MRDCKD0_PDNB | | ||
582 | MRDCKD1_PDNB); | ||
583 | else | ||
584 | mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB | | ||
585 | MRDCKA1_PDNB | | ||
586 | MRDCKB0_PDNB | | ||
587 | MRDCKB1_PDNB | | ||
588 | MRDCKC0_PDNB | | ||
589 | MRDCKC1_PDNB | | ||
590 | MRDCKD0_PDNB | | ||
591 | MRDCKD1_PDNB); | ||
592 | |||
593 | mclk->mclk770.mclk_value = cpu_to_be32(memory_clock); | ||
594 | mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl); | ||
595 | mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2); | ||
596 | mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl); | ||
597 | mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2); | ||
598 | mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl); | ||
599 | mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl); | ||
600 | mclk->mclk770.vMPLL_SS = cpu_to_be32(mpll_ss1); | ||
601 | mclk->mclk770.vMPLL_SS2 = cpu_to_be32(mpll_ss2); | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev, | ||
607 | u32 memory_clock, bool strobe_mode) | ||
608 | { | ||
609 | u8 mc_para_index; | ||
610 | |||
611 | if (rdev->family >= CHIP_BARTS) { | ||
612 | if (strobe_mode) { | ||
613 | if (memory_clock < 10000) | ||
614 | mc_para_index = 0x00; | ||
615 | else if (memory_clock > 47500) | ||
616 | mc_para_index = 0x0f; | ||
617 | else | ||
618 | mc_para_index = (u8)((memory_clock - 10000) / 2500); | ||
619 | } else { | ||
620 | if (memory_clock < 65000) | ||
621 | mc_para_index = 0x00; | ||
622 | else if (memory_clock > 135000) | ||
623 | mc_para_index = 0x0f; | ||
624 | else | ||
625 | mc_para_index = (u8)((memory_clock - 60000) / 5000); | ||
626 | } | ||
627 | } else { | ||
628 | if (strobe_mode) { | ||
629 | if (memory_clock < 10000) | ||
630 | mc_para_index = 0x00; | ||
631 | else if (memory_clock > 47500) | ||
632 | mc_para_index = 0x0f; | ||
633 | else | ||
634 | mc_para_index = (u8)((memory_clock - 10000) / 2500); | ||
635 | } else { | ||
636 | if (memory_clock < 40000) | ||
637 | mc_para_index = 0x00; | ||
638 | else if (memory_clock > 115000) | ||
639 | mc_para_index = 0x0f; | ||
640 | else | ||
641 | mc_para_index = (u8)((memory_clock - 40000) / 5000); | ||
642 | } | ||
643 | } | ||
644 | return mc_para_index; | ||
645 | } | ||
646 | |||
647 | static int cypress_populate_mvdd_value(struct radeon_device *rdev, | ||
648 | u32 mclk, | ||
649 | RV770_SMC_VOLTAGE_VALUE *voltage) | ||
650 | { | ||
651 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
652 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
653 | |||
654 | if (!pi->mvdd_control) { | ||
655 | voltage->index = eg_pi->mvdd_high_index; | ||
656 | voltage->value = cpu_to_be16(MVDD_HIGH_VALUE); | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | if (mclk <= pi->mvdd_split_frequency) { | ||
661 | voltage->index = eg_pi->mvdd_low_index; | ||
662 | voltage->value = cpu_to_be16(MVDD_LOW_VALUE); | ||
663 | } else { | ||
664 | voltage->index = eg_pi->mvdd_high_index; | ||
665 | voltage->value = cpu_to_be16(MVDD_HIGH_VALUE); | ||
666 | } | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | int cypress_convert_power_level_to_smc(struct radeon_device *rdev, | ||
672 | struct rv7xx_pl *pl, | ||
673 | RV770_SMC_HW_PERFORMANCE_LEVEL *level, | ||
674 | u8 watermark_level) | ||
675 | { | ||
676 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
677 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
678 | int ret; | ||
679 | bool dll_state_on; | ||
680 | |||
681 | level->gen2PCIE = pi->pcie_gen2 ? | ||
682 | ((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0; | ||
683 | level->gen2XSP = (pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0; | ||
684 | level->backbias = (pl->flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? 1 : 0; | ||
685 | level->displayWatermark = watermark_level; | ||
686 | |||
687 | ret = rv740_populate_sclk_value(rdev, pl->sclk, &level->sclk); | ||
688 | if (ret) | ||
689 | return ret; | ||
690 | |||
691 | level->mcFlags = 0; | ||
692 | if (pi->mclk_stutter_mode_threshold && | ||
693 | (pl->mclk <= pi->mclk_stutter_mode_threshold)) { | ||
694 | level->mcFlags |= SMC_MC_STUTTER_EN; | ||
695 | if (eg_pi->sclk_deep_sleep) | ||
696 | level->stateFlags |= PPSMC_STATEFLAG_AUTO_PULSE_SKIP; | ||
697 | else | ||
698 | level->stateFlags &= ~PPSMC_STATEFLAG_AUTO_PULSE_SKIP; | ||
699 | } | ||
700 | |||
701 | if (pi->mem_gddr5) { | ||
702 | if (pl->mclk > pi->mclk_edc_enable_threshold) | ||
703 | level->mcFlags |= SMC_MC_EDC_RD_FLAG; | ||
704 | |||
705 | if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold) | ||
706 | level->mcFlags |= SMC_MC_EDC_WR_FLAG; | ||
707 | |||
708 | level->strobeMode = cypress_get_strobe_mode_settings(rdev, pl->mclk); | ||
709 | |||
710 | if (level->strobeMode & SMC_STROBE_ENABLE) { | ||
711 | if (cypress_get_mclk_frequency_ratio(rdev, pl->mclk, true) >= | ||
712 | ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf)) | ||
713 | dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false; | ||
714 | else | ||
715 | dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false; | ||
716 | } else | ||
717 | dll_state_on = eg_pi->dll_default_on; | ||
718 | |||
719 | ret = cypress_populate_mclk_value(rdev, | ||
720 | pl->sclk, | ||
721 | pl->mclk, | ||
722 | &level->mclk, | ||
723 | (level->strobeMode & SMC_STROBE_ENABLE) != 0, | ||
724 | dll_state_on); | ||
725 | } else { | ||
726 | ret = cypress_populate_mclk_value(rdev, | ||
727 | pl->sclk, | ||
728 | pl->mclk, | ||
729 | &level->mclk, | ||
730 | true, | ||
731 | true); | ||
732 | } | ||
733 | if (ret) | ||
734 | return ret; | ||
735 | |||
736 | ret = cypress_populate_voltage_value(rdev, | ||
737 | &eg_pi->vddc_voltage_table, | ||
738 | pl->vddc, | ||
739 | &level->vddc); | ||
740 | if (ret) | ||
741 | return ret; | ||
742 | |||
743 | if (eg_pi->vddci_control) { | ||
744 | ret = cypress_populate_voltage_value(rdev, | ||
745 | &eg_pi->vddci_voltage_table, | ||
746 | pl->vddci, | ||
747 | &level->vddci); | ||
748 | if (ret) | ||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | ret = cypress_populate_mvdd_value(rdev, pl->mclk, &level->mvdd); | ||
753 | |||
754 | return ret; | ||
755 | } | ||
756 | |||
757 | static int cypress_convert_power_state_to_smc(struct radeon_device *rdev, | ||
758 | struct radeon_ps *radeon_state, | ||
759 | RV770_SMC_SWSTATE *smc_state) | ||
760 | { | ||
761 | struct rv7xx_ps *state = rv770_get_ps(radeon_state); | ||
762 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
763 | int ret; | ||
764 | |||
765 | if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC)) | ||
766 | smc_state->flags |= PPSMC_SWSTATE_FLAG_DC; | ||
767 | |||
768 | ret = cypress_convert_power_level_to_smc(rdev, | ||
769 | &state->low, | ||
770 | &smc_state->levels[0], | ||
771 | PPSMC_DISPLAY_WATERMARK_LOW); | ||
772 | if (ret) | ||
773 | return ret; | ||
774 | |||
775 | ret = cypress_convert_power_level_to_smc(rdev, | ||
776 | &state->medium, | ||
777 | &smc_state->levels[1], | ||
778 | PPSMC_DISPLAY_WATERMARK_LOW); | ||
779 | if (ret) | ||
780 | return ret; | ||
781 | |||
782 | ret = cypress_convert_power_level_to_smc(rdev, | ||
783 | &state->high, | ||
784 | &smc_state->levels[2], | ||
785 | PPSMC_DISPLAY_WATERMARK_HIGH); | ||
786 | if (ret) | ||
787 | return ret; | ||
788 | |||
789 | smc_state->levels[0].arbValue = MC_CG_ARB_FREQ_F1; | ||
790 | smc_state->levels[1].arbValue = MC_CG_ARB_FREQ_F2; | ||
791 | smc_state->levels[2].arbValue = MC_CG_ARB_FREQ_F3; | ||
792 | |||
793 | if (eg_pi->dynamic_ac_timing) { | ||
794 | smc_state->levels[0].ACIndex = 2; | ||
795 | smc_state->levels[1].ACIndex = 3; | ||
796 | smc_state->levels[2].ACIndex = 4; | ||
797 | } else { | ||
798 | smc_state->levels[0].ACIndex = 0; | ||
799 | smc_state->levels[1].ACIndex = 0; | ||
800 | smc_state->levels[2].ACIndex = 0; | ||
801 | } | ||
802 | |||
803 | rv770_populate_smc_sp(rdev, radeon_state, smc_state); | ||
804 | |||
805 | return rv770_populate_smc_t(rdev, radeon_state, smc_state); | ||
806 | } | ||
807 | |||
808 | static void cypress_convert_mc_registers(struct evergreen_mc_reg_entry *entry, | ||
809 | SMC_Evergreen_MCRegisterSet *data, | ||
810 | u32 num_entries, u32 valid_flag) | ||
811 | { | ||
812 | u32 i, j; | ||
813 | |||
814 | for (i = 0, j = 0; j < num_entries; j++) { | ||
815 | if (valid_flag & (1 << j)) { | ||
816 | data->value[i] = cpu_to_be32(entry->mc_data[j]); | ||
817 | i++; | ||
818 | } | ||
819 | } | ||
820 | } | ||
821 | |||
822 | static void cypress_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev, | ||
823 | struct rv7xx_pl *pl, | ||
824 | SMC_Evergreen_MCRegisterSet *mc_reg_table_data) | ||
825 | { | ||
826 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
827 | u32 i = 0; | ||
828 | |||
829 | for (i = 0; i < eg_pi->mc_reg_table.num_entries; i++) { | ||
830 | if (pl->mclk <= | ||
831 | eg_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max) | ||
832 | break; | ||
833 | } | ||
834 | |||
835 | if ((i == eg_pi->mc_reg_table.num_entries) && (i > 0)) | ||
836 | --i; | ||
837 | |||
838 | cypress_convert_mc_registers(&eg_pi->mc_reg_table.mc_reg_table_entry[i], | ||
839 | mc_reg_table_data, | ||
840 | eg_pi->mc_reg_table.last, | ||
841 | eg_pi->mc_reg_table.valid_flag); | ||
842 | } | ||
843 | |||
844 | static void cypress_convert_mc_reg_table_to_smc(struct radeon_device *rdev, | ||
845 | struct radeon_ps *radeon_state, | ||
846 | SMC_Evergreen_MCRegisters *mc_reg_table) | ||
847 | { | ||
848 | struct rv7xx_ps *state = rv770_get_ps(radeon_state); | ||
849 | |||
850 | cypress_convert_mc_reg_table_entry_to_smc(rdev, | ||
851 | &state->low, | ||
852 | &mc_reg_table->data[2]); | ||
853 | cypress_convert_mc_reg_table_entry_to_smc(rdev, | ||
854 | &state->medium, | ||
855 | &mc_reg_table->data[3]); | ||
856 | cypress_convert_mc_reg_table_entry_to_smc(rdev, | ||
857 | &state->high, | ||
858 | &mc_reg_table->data[4]); | ||
859 | } | ||
860 | |||
861 | int cypress_upload_sw_state(struct radeon_device *rdev) | ||
862 | { | ||
863 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
864 | struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; | ||
865 | u16 address = pi->state_table_start + | ||
866 | offsetof(RV770_SMC_STATETABLE, driverState); | ||
867 | RV770_SMC_SWSTATE state = { 0 }; | ||
868 | int ret; | ||
869 | |||
870 | ret = cypress_convert_power_state_to_smc(rdev, radeon_new_state, &state); | ||
871 | if (ret) | ||
872 | return ret; | ||
873 | |||
874 | return rv770_copy_bytes_to_smc(rdev, address, (u8 *)&state, | ||
875 | sizeof(RV770_SMC_SWSTATE), | ||
876 | pi->sram_end); | ||
877 | } | ||
878 | |||
879 | int cypress_upload_mc_reg_table(struct radeon_device *rdev) | ||
880 | { | ||
881 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
882 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
883 | struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; | ||
884 | SMC_Evergreen_MCRegisters mc_reg_table = { 0 }; | ||
885 | u16 address; | ||
886 | |||
887 | cypress_convert_mc_reg_table_to_smc(rdev, radeon_new_state, &mc_reg_table); | ||
888 | |||
889 | address = eg_pi->mc_reg_table_start + | ||
890 | (u16)offsetof(SMC_Evergreen_MCRegisters, data[2]); | ||
891 | |||
892 | return rv770_copy_bytes_to_smc(rdev, address, | ||
893 | (u8 *)&mc_reg_table.data[2], | ||
894 | sizeof(SMC_Evergreen_MCRegisterSet) * 3, | ||
895 | pi->sram_end); | ||
896 | } | ||
897 | |||
898 | u32 cypress_calculate_burst_time(struct radeon_device *rdev, | ||
899 | u32 engine_clock, u32 memory_clock) | ||
900 | { | ||
901 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
902 | u32 multiplier = pi->mem_gddr5 ? 1 : 2; | ||
903 | u32 result = (4 * multiplier * engine_clock) / (memory_clock / 2); | ||
904 | u32 burst_time; | ||
905 | |||
906 | if (result <= 4) | ||
907 | burst_time = 0; | ||
908 | else if (result < 8) | ||
909 | burst_time = result - 4; | ||
910 | else { | ||
911 | burst_time = result / 2 ; | ||
912 | if (burst_time > 18) | ||
913 | burst_time = 18; | ||
914 | } | ||
915 | |||
916 | return burst_time; | ||
917 | } | ||
918 | |||
919 | void cypress_program_memory_timing_parameters(struct radeon_device *rdev) | ||
920 | { | ||
921 | struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps; | ||
922 | struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state); | ||
923 | u32 mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME); | ||
924 | |||
925 | mc_arb_burst_time &= ~(STATE1_MASK | STATE2_MASK | STATE3_MASK); | ||
926 | |||
927 | mc_arb_burst_time |= STATE1(cypress_calculate_burst_time(rdev, | ||
928 | new_state->low.sclk, | ||
929 | new_state->low.mclk)); | ||
930 | mc_arb_burst_time |= STATE2(cypress_calculate_burst_time(rdev, | ||
931 | new_state->medium.sclk, | ||
932 | new_state->medium.mclk)); | ||
933 | mc_arb_burst_time |= STATE3(cypress_calculate_burst_time(rdev, | ||
934 | new_state->high.sclk, | ||
935 | new_state->high.mclk)); | ||
936 | |||
937 | rv730_program_memory_timing_parameters(rdev, radeon_new_state); | ||
938 | |||
939 | WREG32(MC_ARB_BURST_TIME, mc_arb_burst_time); | ||
940 | } | ||
941 | |||
942 | static void cypress_populate_mc_reg_addresses(struct radeon_device *rdev, | ||
943 | SMC_Evergreen_MCRegisters *mc_reg_table) | ||
944 | { | ||
945 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
946 | u32 i, j; | ||
947 | |||
948 | for (i = 0, j = 0; j < eg_pi->mc_reg_table.last; j++) { | ||
949 | if (eg_pi->mc_reg_table.valid_flag & (1 << j)) { | ||
950 | mc_reg_table->address[i].s0 = | ||
951 | cpu_to_be16(eg_pi->mc_reg_table.mc_reg_address[j].s0); | ||
952 | mc_reg_table->address[i].s1 = | ||
953 | cpu_to_be16(eg_pi->mc_reg_table.mc_reg_address[j].s1); | ||
954 | i++; | ||
955 | } | ||
956 | } | ||
957 | |||
958 | mc_reg_table->last = (u8)i; | ||
959 | } | ||
960 | |||
961 | static void cypress_set_mc_reg_address_table(struct radeon_device *rdev) | ||
962 | { | ||
963 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
964 | u32 i = 0; | ||
965 | |||
966 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RAS_TIMING_LP >> 2; | ||
967 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RAS_TIMING >> 2; | ||
968 | i++; | ||
969 | |||
970 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_CAS_TIMING_LP >> 2; | ||
971 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_CAS_TIMING >> 2; | ||
972 | i++; | ||
973 | |||
974 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC_TIMING_LP >> 2; | ||
975 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC_TIMING >> 2; | ||
976 | i++; | ||
977 | |||
978 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC_TIMING2_LP >> 2; | ||
979 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC_TIMING2 >> 2; | ||
980 | i++; | ||
981 | |||
982 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RD_CTL_D0_LP >> 2; | ||
983 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RD_CTL_D0 >> 2; | ||
984 | i++; | ||
985 | |||
986 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RD_CTL_D1_LP >> 2; | ||
987 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RD_CTL_D1 >> 2; | ||
988 | i++; | ||
989 | |||
990 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_WR_CTL_D0_LP >> 2; | ||
991 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_WR_CTL_D0 >> 2; | ||
992 | i++; | ||
993 | |||
994 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_WR_CTL_D1_LP >> 2; | ||
995 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_WR_CTL_D1 >> 2; | ||
996 | i++; | ||
997 | |||
998 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2; | ||
999 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_PMG_CMD_EMRS >> 2; | ||
1000 | i++; | ||
1001 | |||
1002 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2; | ||
1003 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_PMG_CMD_MRS >> 2; | ||
1004 | i++; | ||
1005 | |||
1006 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2; | ||
1007 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_PMG_CMD_MRS1 >> 2; | ||
1008 | i++; | ||
1009 | |||
1010 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC1 >> 2; | ||
1011 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC1 >> 2; | ||
1012 | i++; | ||
1013 | |||
1014 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_RESERVE_M >> 2; | ||
1015 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_RESERVE_M >> 2; | ||
1016 | i++; | ||
1017 | |||
1018 | eg_pi->mc_reg_table.mc_reg_address[i].s0 = MC_SEQ_MISC3 >> 2; | ||
1019 | eg_pi->mc_reg_table.mc_reg_address[i].s1 = MC_SEQ_MISC3 >> 2; | ||
1020 | i++; | ||
1021 | |||
1022 | eg_pi->mc_reg_table.last = (u8)i; | ||
1023 | } | ||
1024 | |||
1025 | static void cypress_retrieve_ac_timing_for_one_entry(struct radeon_device *rdev, | ||
1026 | struct evergreen_mc_reg_entry *entry) | ||
1027 | { | ||
1028 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1029 | u32 i; | ||
1030 | |||
1031 | for (i = 0; i < eg_pi->mc_reg_table.last; i++) | ||
1032 | entry->mc_data[i] = | ||
1033 | RREG32(eg_pi->mc_reg_table.mc_reg_address[i].s1 << 2); | ||
1034 | |||
1035 | } | ||
1036 | |||
1037 | static void cypress_retrieve_ac_timing_for_all_ranges(struct radeon_device *rdev, | ||
1038 | struct atom_memory_clock_range_table *range_table) | ||
1039 | { | ||
1040 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1041 | u32 i, j; | ||
1042 | |||
1043 | for (i = 0; i < range_table->num_entries; i++) { | ||
1044 | eg_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max = | ||
1045 | range_table->mclk[i]; | ||
1046 | radeon_atom_set_ac_timing(rdev, range_table->mclk[i]); | ||
1047 | cypress_retrieve_ac_timing_for_one_entry(rdev, | ||
1048 | &eg_pi->mc_reg_table.mc_reg_table_entry[i]); | ||
1049 | } | ||
1050 | |||
1051 | eg_pi->mc_reg_table.num_entries = range_table->num_entries; | ||
1052 | eg_pi->mc_reg_table.valid_flag = 0; | ||
1053 | |||
1054 | for (i = 0; i < eg_pi->mc_reg_table.last; i++) { | ||
1055 | for (j = 1; j < range_table->num_entries; j++) { | ||
1056 | if (eg_pi->mc_reg_table.mc_reg_table_entry[j-1].mc_data[i] != | ||
1057 | eg_pi->mc_reg_table.mc_reg_table_entry[j].mc_data[i]) { | ||
1058 | eg_pi->mc_reg_table.valid_flag |= (1 << i); | ||
1059 | break; | ||
1060 | } | ||
1061 | } | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | static int cypress_initialize_mc_reg_table(struct radeon_device *rdev) | ||
1066 | { | ||
1067 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1068 | u8 module_index = rv770_get_memory_module_index(rdev); | ||
1069 | struct atom_memory_clock_range_table range_table = { 0 }; | ||
1070 | int ret; | ||
1071 | |||
1072 | ret = radeon_atom_get_mclk_range_table(rdev, | ||
1073 | pi->mem_gddr5, | ||
1074 | module_index, &range_table); | ||
1075 | if (ret) | ||
1076 | return ret; | ||
1077 | |||
1078 | cypress_retrieve_ac_timing_for_all_ranges(rdev, &range_table); | ||
1079 | |||
1080 | return 0; | ||
1081 | } | ||
1082 | |||
1083 | static void cypress_wait_for_mc_sequencer(struct radeon_device *rdev, u8 value) | ||
1084 | { | ||
1085 | u32 i, j; | ||
1086 | u32 channels = 2; | ||
1087 | |||
1088 | if ((rdev->family == CHIP_CYPRESS) || | ||
1089 | (rdev->family == CHIP_HEMLOCK)) | ||
1090 | channels = 4; | ||
1091 | else if (rdev->family == CHIP_CEDAR) | ||
1092 | channels = 1; | ||
1093 | |||
1094 | for (i = 0; i < channels; i++) { | ||
1095 | if ((rdev->family == CHIP_CYPRESS) || | ||
1096 | (rdev->family == CHIP_HEMLOCK)) { | ||
1097 | WREG32_P(MC_CONFIG_MCD, MC_RD_ENABLE_MCD(i), ~MC_RD_ENABLE_MCD_MASK); | ||
1098 | WREG32_P(MC_CG_CONFIG_MCD, MC_RD_ENABLE_MCD(i), ~MC_RD_ENABLE_MCD_MASK); | ||
1099 | } else { | ||
1100 | WREG32_P(MC_CONFIG, MC_RD_ENABLE(i), ~MC_RD_ENABLE_MASK); | ||
1101 | WREG32_P(MC_CG_CONFIG, MC_RD_ENABLE(i), ~MC_RD_ENABLE_MASK); | ||
1102 | } | ||
1103 | for (j = 0; j < rdev->usec_timeout; j++) { | ||
1104 | if (((RREG32(MC_SEQ_CG) & CG_SEQ_RESP_MASK) >> CG_SEQ_RESP_SHIFT) == value) | ||
1105 | break; | ||
1106 | udelay(1); | ||
1107 | } | ||
1108 | } | ||
1109 | } | ||
1110 | |||
1111 | static void cypress_force_mc_use_s1(struct radeon_device *rdev) | ||
1112 | { | ||
1113 | struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps; | ||
1114 | struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state); | ||
1115 | u32 strobe_mode; | ||
1116 | u32 mc_seq_cg; | ||
1117 | int i; | ||
1118 | |||
1119 | if (RREG32(MC_SEQ_STATUS_M) & PMG_PWRSTATE) | ||
1120 | return; | ||
1121 | |||
1122 | radeon_atom_set_ac_timing(rdev, boot_state->low.mclk); | ||
1123 | radeon_mc_wait_for_idle(rdev); | ||
1124 | |||
1125 | if ((rdev->family == CHIP_CYPRESS) || | ||
1126 | (rdev->family == CHIP_HEMLOCK)) { | ||
1127 | WREG32(MC_CONFIG_MCD, 0xf); | ||
1128 | WREG32(MC_CG_CONFIG_MCD, 0xf); | ||
1129 | } else { | ||
1130 | WREG32(MC_CONFIG, 0xf); | ||
1131 | WREG32(MC_CG_CONFIG, 0xf); | ||
1132 | } | ||
1133 | |||
1134 | for (i = 0; i < rdev->num_crtc; i++) | ||
1135 | radeon_wait_for_vblank(rdev, i); | ||
1136 | |||
1137 | WREG32(MC_SEQ_CG, MC_CG_SEQ_YCLK_SUSPEND); | ||
1138 | cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_SUSPEND); | ||
1139 | |||
1140 | strobe_mode = cypress_get_strobe_mode_settings(rdev, | ||
1141 | boot_state->low.mclk); | ||
1142 | |||
1143 | mc_seq_cg = CG_SEQ_REQ(MC_CG_SEQ_DRAMCONF_S1); | ||
1144 | mc_seq_cg |= SEQ_CG_RESP(strobe_mode); | ||
1145 | WREG32(MC_SEQ_CG, mc_seq_cg); | ||
1146 | |||
1147 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
1148 | if (RREG32(MC_SEQ_STATUS_M) & PMG_PWRSTATE) | ||
1149 | break; | ||
1150 | udelay(1); | ||
1151 | } | ||
1152 | |||
1153 | mc_seq_cg &= ~CG_SEQ_REQ_MASK; | ||
1154 | mc_seq_cg |= CG_SEQ_REQ(MC_CG_SEQ_YCLK_RESUME); | ||
1155 | WREG32(MC_SEQ_CG, mc_seq_cg); | ||
1156 | |||
1157 | cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_RESUME); | ||
1158 | } | ||
1159 | |||
1160 | static void cypress_copy_ac_timing_from_s1_to_s0(struct radeon_device *rdev) | ||
1161 | { | ||
1162 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1163 | u32 value; | ||
1164 | u32 i; | ||
1165 | |||
1166 | for (i = 0; i < eg_pi->mc_reg_table.last; i++) { | ||
1167 | value = RREG32(eg_pi->mc_reg_table.mc_reg_address[i].s1 << 2); | ||
1168 | WREG32(eg_pi->mc_reg_table.mc_reg_address[i].s0 << 2, value); | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | static void cypress_force_mc_use_s0(struct radeon_device *rdev) | ||
1173 | { | ||
1174 | struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps; | ||
1175 | struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state); | ||
1176 | u32 strobe_mode; | ||
1177 | u32 mc_seq_cg; | ||
1178 | int i; | ||
1179 | |||
1180 | cypress_copy_ac_timing_from_s1_to_s0(rdev); | ||
1181 | radeon_mc_wait_for_idle(rdev); | ||
1182 | |||
1183 | if ((rdev->family == CHIP_CYPRESS) || | ||
1184 | (rdev->family == CHIP_HEMLOCK)) { | ||
1185 | WREG32(MC_CONFIG_MCD, 0xf); | ||
1186 | WREG32(MC_CG_CONFIG_MCD, 0xf); | ||
1187 | } else { | ||
1188 | WREG32(MC_CONFIG, 0xf); | ||
1189 | WREG32(MC_CG_CONFIG, 0xf); | ||
1190 | } | ||
1191 | |||
1192 | for (i = 0; i < rdev->num_crtc; i++) | ||
1193 | radeon_wait_for_vblank(rdev, i); | ||
1194 | |||
1195 | WREG32(MC_SEQ_CG, MC_CG_SEQ_YCLK_SUSPEND); | ||
1196 | cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_SUSPEND); | ||
1197 | |||
1198 | strobe_mode = cypress_get_strobe_mode_settings(rdev, | ||
1199 | boot_state->low.mclk); | ||
1200 | |||
1201 | mc_seq_cg = CG_SEQ_REQ(MC_CG_SEQ_DRAMCONF_S0); | ||
1202 | mc_seq_cg |= SEQ_CG_RESP(strobe_mode); | ||
1203 | WREG32(MC_SEQ_CG, mc_seq_cg); | ||
1204 | |||
1205 | for (i = 0; i < rdev->usec_timeout; i++) { | ||
1206 | if (!(RREG32(MC_SEQ_STATUS_M) & PMG_PWRSTATE)) | ||
1207 | break; | ||
1208 | udelay(1); | ||
1209 | } | ||
1210 | |||
1211 | mc_seq_cg &= ~CG_SEQ_REQ_MASK; | ||
1212 | mc_seq_cg |= CG_SEQ_REQ(MC_CG_SEQ_YCLK_RESUME); | ||
1213 | WREG32(MC_SEQ_CG, mc_seq_cg); | ||
1214 | |||
1215 | cypress_wait_for_mc_sequencer(rdev, MC_CG_SEQ_YCLK_RESUME); | ||
1216 | } | ||
1217 | |||
1218 | static int cypress_populate_initial_mvdd_value(struct radeon_device *rdev, | ||
1219 | RV770_SMC_VOLTAGE_VALUE *voltage) | ||
1220 | { | ||
1221 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1222 | |||
1223 | voltage->index = eg_pi->mvdd_high_index; | ||
1224 | voltage->value = cpu_to_be16(MVDD_HIGH_VALUE); | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | int cypress_populate_smc_initial_state(struct radeon_device *rdev, | ||
1230 | struct radeon_ps *radeon_initial_state, | ||
1231 | RV770_SMC_STATETABLE *table) | ||
1232 | { | ||
1233 | struct rv7xx_ps *initial_state = rv770_get_ps(radeon_initial_state); | ||
1234 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1235 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1236 | u32 a_t; | ||
1237 | |||
1238 | table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = | ||
1239 | cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl); | ||
1240 | table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = | ||
1241 | cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl_2); | ||
1242 | table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = | ||
1243 | cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl); | ||
1244 | table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = | ||
1245 | cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl_2); | ||
1246 | table->initialState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = | ||
1247 | cpu_to_be32(pi->clk_regs.rv770.mclk_pwrmgt_cntl); | ||
1248 | table->initialState.levels[0].mclk.mclk770.vDLL_CNTL = | ||
1249 | cpu_to_be32(pi->clk_regs.rv770.dll_cntl); | ||
1250 | |||
1251 | table->initialState.levels[0].mclk.mclk770.vMPLL_SS = | ||
1252 | cpu_to_be32(pi->clk_regs.rv770.mpll_ss1); | ||
1253 | table->initialState.levels[0].mclk.mclk770.vMPLL_SS2 = | ||
1254 | cpu_to_be32(pi->clk_regs.rv770.mpll_ss2); | ||
1255 | |||
1256 | table->initialState.levels[0].mclk.mclk770.mclk_value = | ||
1257 | cpu_to_be32(initial_state->low.mclk); | ||
1258 | |||
1259 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = | ||
1260 | cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl); | ||
1261 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = | ||
1262 | cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_2); | ||
1263 | table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = | ||
1264 | cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_3); | ||
1265 | table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM = | ||
1266 | cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum); | ||
1267 | table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 = | ||
1268 | cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum_2); | ||
1269 | |||
1270 | table->initialState.levels[0].sclk.sclk_value = | ||
1271 | cpu_to_be32(initial_state->low.sclk); | ||
1272 | |||
1273 | table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0; | ||
1274 | |||
1275 | table->initialState.levels[0].ACIndex = 0; | ||
1276 | |||
1277 | cypress_populate_voltage_value(rdev, | ||
1278 | &eg_pi->vddc_voltage_table, | ||
1279 | initial_state->low.vddc, | ||
1280 | &table->initialState.levels[0].vddc); | ||
1281 | |||
1282 | if (eg_pi->vddci_control) | ||
1283 | cypress_populate_voltage_value(rdev, | ||
1284 | &eg_pi->vddci_voltage_table, | ||
1285 | initial_state->low.vddci, | ||
1286 | &table->initialState.levels[0].vddci); | ||
1287 | |||
1288 | cypress_populate_initial_mvdd_value(rdev, | ||
1289 | &table->initialState.levels[0].mvdd); | ||
1290 | |||
1291 | a_t = CG_R(0xffff) | CG_L(0); | ||
1292 | table->initialState.levels[0].aT = cpu_to_be32(a_t); | ||
1293 | |||
1294 | table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp); | ||
1295 | |||
1296 | |||
1297 | if (pi->boot_in_gen2) | ||
1298 | table->initialState.levels[0].gen2PCIE = 1; | ||
1299 | else | ||
1300 | table->initialState.levels[0].gen2PCIE = 0; | ||
1301 | if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) | ||
1302 | table->initialState.levels[0].gen2XSP = 1; | ||
1303 | else | ||
1304 | table->initialState.levels[0].gen2XSP = 0; | ||
1305 | |||
1306 | if (pi->mem_gddr5) { | ||
1307 | table->initialState.levels[0].strobeMode = | ||
1308 | cypress_get_strobe_mode_settings(rdev, | ||
1309 | initial_state->low.mclk); | ||
1310 | |||
1311 | if (initial_state->low.mclk > pi->mclk_edc_enable_threshold) | ||
1312 | table->initialState.levels[0].mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG; | ||
1313 | else | ||
1314 | table->initialState.levels[0].mcFlags = 0; | ||
1315 | } | ||
1316 | |||
1317 | table->initialState.levels[1] = table->initialState.levels[0]; | ||
1318 | table->initialState.levels[2] = table->initialState.levels[0]; | ||
1319 | |||
1320 | table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC; | ||
1321 | |||
1322 | return 0; | ||
1323 | } | ||
1324 | |||
1325 | int cypress_populate_smc_acpi_state(struct radeon_device *rdev, | ||
1326 | RV770_SMC_STATETABLE *table) | ||
1327 | { | ||
1328 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1329 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1330 | u32 mpll_ad_func_cntl = | ||
1331 | pi->clk_regs.rv770.mpll_ad_func_cntl; | ||
1332 | u32 mpll_ad_func_cntl_2 = | ||
1333 | pi->clk_regs.rv770.mpll_ad_func_cntl_2; | ||
1334 | u32 mpll_dq_func_cntl = | ||
1335 | pi->clk_regs.rv770.mpll_dq_func_cntl; | ||
1336 | u32 mpll_dq_func_cntl_2 = | ||
1337 | pi->clk_regs.rv770.mpll_dq_func_cntl_2; | ||
1338 | u32 spll_func_cntl = | ||
1339 | pi->clk_regs.rv770.cg_spll_func_cntl; | ||
1340 | u32 spll_func_cntl_2 = | ||
1341 | pi->clk_regs.rv770.cg_spll_func_cntl_2; | ||
1342 | u32 spll_func_cntl_3 = | ||
1343 | pi->clk_regs.rv770.cg_spll_func_cntl_3; | ||
1344 | u32 mclk_pwrmgt_cntl = | ||
1345 | pi->clk_regs.rv770.mclk_pwrmgt_cntl; | ||
1346 | u32 dll_cntl = | ||
1347 | pi->clk_regs.rv770.dll_cntl; | ||
1348 | |||
1349 | table->ACPIState = table->initialState; | ||
1350 | |||
1351 | table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC; | ||
1352 | |||
1353 | if (pi->acpi_vddc) { | ||
1354 | cypress_populate_voltage_value(rdev, | ||
1355 | &eg_pi->vddc_voltage_table, | ||
1356 | pi->acpi_vddc, | ||
1357 | &table->ACPIState.levels[0].vddc); | ||
1358 | if (pi->pcie_gen2) { | ||
1359 | if (pi->acpi_pcie_gen2) | ||
1360 | table->ACPIState.levels[0].gen2PCIE = 1; | ||
1361 | else | ||
1362 | table->ACPIState.levels[0].gen2PCIE = 0; | ||
1363 | } else | ||
1364 | table->ACPIState.levels[0].gen2PCIE = 0; | ||
1365 | if (pi->acpi_pcie_gen2) | ||
1366 | table->ACPIState.levels[0].gen2XSP = 1; | ||
1367 | else | ||
1368 | table->ACPIState.levels[0].gen2XSP = 0; | ||
1369 | } else { | ||
1370 | cypress_populate_voltage_value(rdev, | ||
1371 | &eg_pi->vddc_voltage_table, | ||
1372 | pi->min_vddc_in_table, | ||
1373 | &table->ACPIState.levels[0].vddc); | ||
1374 | table->ACPIState.levels[0].gen2PCIE = 0; | ||
1375 | } | ||
1376 | |||
1377 | if (eg_pi->acpi_vddci) { | ||
1378 | if (eg_pi->vddci_control) { | ||
1379 | cypress_populate_voltage_value(rdev, | ||
1380 | &eg_pi->vddci_voltage_table, | ||
1381 | eg_pi->acpi_vddci, | ||
1382 | &table->ACPIState.levels[0].vddci); | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1386 | mpll_ad_func_cntl &= ~PDNB; | ||
1387 | |||
1388 | mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN; | ||
1389 | |||
1390 | if (pi->mem_gddr5) | ||
1391 | mpll_dq_func_cntl &= ~PDNB; | ||
1392 | mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN | BYPASS; | ||
1393 | |||
1394 | mclk_pwrmgt_cntl |= (MRDCKA0_RESET | | ||
1395 | MRDCKA1_RESET | | ||
1396 | MRDCKB0_RESET | | ||
1397 | MRDCKB1_RESET | | ||
1398 | MRDCKC0_RESET | | ||
1399 | MRDCKC1_RESET | | ||
1400 | MRDCKD0_RESET | | ||
1401 | MRDCKD1_RESET); | ||
1402 | |||
1403 | mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB | | ||
1404 | MRDCKA1_PDNB | | ||
1405 | MRDCKB0_PDNB | | ||
1406 | MRDCKB1_PDNB | | ||
1407 | MRDCKC0_PDNB | | ||
1408 | MRDCKC1_PDNB | | ||
1409 | MRDCKD0_PDNB | | ||
1410 | MRDCKD1_PDNB); | ||
1411 | |||
1412 | dll_cntl |= (MRDCKA0_BYPASS | | ||
1413 | MRDCKA1_BYPASS | | ||
1414 | MRDCKB0_BYPASS | | ||
1415 | MRDCKB1_BYPASS | | ||
1416 | MRDCKC0_BYPASS | | ||
1417 | MRDCKC1_BYPASS | | ||
1418 | MRDCKD0_BYPASS | | ||
1419 | MRDCKD1_BYPASS); | ||
1420 | |||
1421 | /* evergreen only */ | ||
1422 | if (rdev->family <= CHIP_HEMLOCK) | ||
1423 | spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN; | ||
1424 | |||
1425 | spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK; | ||
1426 | spll_func_cntl_2 |= SCLK_MUX_SEL(4); | ||
1427 | |||
1428 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = | ||
1429 | cpu_to_be32(mpll_ad_func_cntl); | ||
1430 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = | ||
1431 | cpu_to_be32(mpll_ad_func_cntl_2); | ||
1432 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = | ||
1433 | cpu_to_be32(mpll_dq_func_cntl); | ||
1434 | table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = | ||
1435 | cpu_to_be32(mpll_dq_func_cntl_2); | ||
1436 | table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = | ||
1437 | cpu_to_be32(mclk_pwrmgt_cntl); | ||
1438 | table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl); | ||
1439 | |||
1440 | table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0; | ||
1441 | |||
1442 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = | ||
1443 | cpu_to_be32(spll_func_cntl); | ||
1444 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = | ||
1445 | cpu_to_be32(spll_func_cntl_2); | ||
1446 | table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = | ||
1447 | cpu_to_be32(spll_func_cntl_3); | ||
1448 | |||
1449 | table->ACPIState.levels[0].sclk.sclk_value = 0; | ||
1450 | |||
1451 | cypress_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd); | ||
1452 | |||
1453 | if (eg_pi->dynamic_ac_timing) | ||
1454 | table->ACPIState.levels[0].ACIndex = 1; | ||
1455 | |||
1456 | table->ACPIState.levels[1] = table->ACPIState.levels[0]; | ||
1457 | table->ACPIState.levels[2] = table->ACPIState.levels[0]; | ||
1458 | |||
1459 | return 0; | ||
1460 | } | ||
1461 | |||
1462 | static void cypress_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, | ||
1463 | struct atom_voltage_table *voltage_table) | ||
1464 | { | ||
1465 | unsigned int i, diff; | ||
1466 | |||
1467 | if (voltage_table->count <= MAX_NO_VREG_STEPS) | ||
1468 | return; | ||
1469 | |||
1470 | diff = voltage_table->count - MAX_NO_VREG_STEPS; | ||
1471 | |||
1472 | for (i= 0; i < MAX_NO_VREG_STEPS; i++) | ||
1473 | voltage_table->entries[i] = voltage_table->entries[i + diff]; | ||
1474 | |||
1475 | voltage_table->count = MAX_NO_VREG_STEPS; | ||
1476 | } | ||
1477 | |||
1478 | int cypress_construct_voltage_tables(struct radeon_device *rdev) | ||
1479 | { | ||
1480 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1481 | int ret; | ||
1482 | |||
1483 | ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, | ||
1484 | &eg_pi->vddc_voltage_table); | ||
1485 | if (ret) | ||
1486 | return ret; | ||
1487 | |||
1488 | if (eg_pi->vddc_voltage_table.count > MAX_NO_VREG_STEPS) | ||
1489 | cypress_trim_voltage_table_to_fit_state_table(rdev, | ||
1490 | &eg_pi->vddc_voltage_table); | ||
1491 | |||
1492 | if (eg_pi->vddci_control) { | ||
1493 | ret = radeon_atom_get_voltage_table(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, | ||
1494 | &eg_pi->vddci_voltage_table); | ||
1495 | if (ret) | ||
1496 | return ret; | ||
1497 | |||
1498 | if (eg_pi->vddci_voltage_table.count > MAX_NO_VREG_STEPS) | ||
1499 | cypress_trim_voltage_table_to_fit_state_table(rdev, | ||
1500 | &eg_pi->vddci_voltage_table); | ||
1501 | } | ||
1502 | |||
1503 | return 0; | ||
1504 | } | ||
1505 | |||
1506 | static void cypress_populate_smc_voltage_table(struct radeon_device *rdev, | ||
1507 | struct atom_voltage_table *voltage_table, | ||
1508 | RV770_SMC_STATETABLE *table) | ||
1509 | { | ||
1510 | unsigned int i; | ||
1511 | |||
1512 | for (i = 0; i < voltage_table->count; i++) { | ||
1513 | table->highSMIO[i] = 0; | ||
1514 | table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low); | ||
1515 | } | ||
1516 | } | ||
1517 | |||
1518 | int cypress_populate_smc_voltage_tables(struct radeon_device *rdev, | ||
1519 | RV770_SMC_STATETABLE *table) | ||
1520 | { | ||
1521 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1522 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1523 | unsigned char i; | ||
1524 | |||
1525 | if (eg_pi->vddc_voltage_table.count) { | ||
1526 | cypress_populate_smc_voltage_table(rdev, | ||
1527 | &eg_pi->vddc_voltage_table, | ||
1528 | table); | ||
1529 | |||
1530 | table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDC] = 0; | ||
1531 | table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDC] = | ||
1532 | cpu_to_be32(eg_pi->vddc_voltage_table.mask_low); | ||
1533 | |||
1534 | for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) { | ||
1535 | if (pi->max_vddc_in_table <= | ||
1536 | eg_pi->vddc_voltage_table.entries[i].value) { | ||
1537 | table->maxVDDCIndexInPPTable = i; | ||
1538 | break; | ||
1539 | } | ||
1540 | } | ||
1541 | } | ||
1542 | |||
1543 | if (eg_pi->vddci_voltage_table.count) { | ||
1544 | cypress_populate_smc_voltage_table(rdev, | ||
1545 | &eg_pi->vddci_voltage_table, | ||
1546 | table); | ||
1547 | |||
1548 | table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDCI] = 0; | ||
1549 | table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDCI] = | ||
1550 | cpu_to_be32(eg_pi->vddc_voltage_table.mask_low); | ||
1551 | } | ||
1552 | |||
1553 | return 0; | ||
1554 | } | ||
1555 | |||
1556 | static u32 cypress_get_mclk_split_point(struct atom_memory_info *memory_info) | ||
1557 | { | ||
1558 | if ((memory_info->mem_type == MEM_TYPE_GDDR3) || | ||
1559 | (memory_info->mem_type == MEM_TYPE_DDR3)) | ||
1560 | return 30000; | ||
1561 | |||
1562 | return 0; | ||
1563 | } | ||
1564 | |||
1565 | int cypress_get_mvdd_configuration(struct radeon_device *rdev) | ||
1566 | { | ||
1567 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1568 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1569 | u8 module_index; | ||
1570 | struct atom_memory_info memory_info; | ||
1571 | u32 tmp = RREG32(GENERAL_PWRMGT); | ||
1572 | |||
1573 | if (!(tmp & BACKBIAS_PAD_EN)) { | ||
1574 | eg_pi->mvdd_high_index = 0; | ||
1575 | eg_pi->mvdd_low_index = 1; | ||
1576 | pi->mvdd_control = false; | ||
1577 | return 0; | ||
1578 | } | ||
1579 | |||
1580 | if (tmp & BACKBIAS_VALUE) | ||
1581 | eg_pi->mvdd_high_index = 1; | ||
1582 | else | ||
1583 | eg_pi->mvdd_high_index = 0; | ||
1584 | |||
1585 | eg_pi->mvdd_low_index = | ||
1586 | (eg_pi->mvdd_high_index == 0) ? 1 : 0; | ||
1587 | |||
1588 | module_index = rv770_get_memory_module_index(rdev); | ||
1589 | |||
1590 | if (radeon_atom_get_memory_info(rdev, module_index, &memory_info)) { | ||
1591 | pi->mvdd_control = false; | ||
1592 | return 0; | ||
1593 | } | ||
1594 | |||
1595 | pi->mvdd_split_frequency = | ||
1596 | cypress_get_mclk_split_point(&memory_info); | ||
1597 | |||
1598 | if (pi->mvdd_split_frequency == 0) { | ||
1599 | pi->mvdd_control = false; | ||
1600 | return 0; | ||
1601 | } | ||
1602 | |||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | static int cypress_init_smc_table(struct radeon_device *rdev) | ||
1607 | { | ||
1608 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1609 | struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps; | ||
1610 | RV770_SMC_STATETABLE *table = &pi->smc_statetable; | ||
1611 | int ret; | ||
1612 | |||
1613 | memset(table, 0, sizeof(RV770_SMC_STATETABLE)); | ||
1614 | |||
1615 | cypress_populate_smc_voltage_tables(rdev, table); | ||
1616 | |||
1617 | switch (rdev->pm.int_thermal_type) { | ||
1618 | case THERMAL_TYPE_EVERGREEN: | ||
1619 | case THERMAL_TYPE_EMC2103_WITH_INTERNAL: | ||
1620 | table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL; | ||
1621 | break; | ||
1622 | case THERMAL_TYPE_NONE: | ||
1623 | table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE; | ||
1624 | break; | ||
1625 | default: | ||
1626 | table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL; | ||
1627 | break; | ||
1628 | } | ||
1629 | |||
1630 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC) | ||
1631 | table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; | ||
1632 | |||
1633 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) | ||
1634 | table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT; | ||
1635 | |||
1636 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC) | ||
1637 | table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC; | ||
1638 | |||
1639 | if (pi->mem_gddr5) | ||
1640 | table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5; | ||
1641 | |||
1642 | ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table); | ||
1643 | if (ret) | ||
1644 | return ret; | ||
1645 | |||
1646 | ret = cypress_populate_smc_acpi_state(rdev, table); | ||
1647 | if (ret) | ||
1648 | return ret; | ||
1649 | |||
1650 | table->driverState = table->initialState; | ||
1651 | |||
1652 | return rv770_copy_bytes_to_smc(rdev, | ||
1653 | pi->state_table_start, | ||
1654 | (u8 *)table, sizeof(RV770_SMC_STATETABLE), | ||
1655 | pi->sram_end); | ||
1656 | } | ||
1657 | |||
1658 | int cypress_populate_mc_reg_table(struct radeon_device *rdev) | ||
1659 | { | ||
1660 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1661 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1662 | struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps; | ||
1663 | struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state); | ||
1664 | SMC_Evergreen_MCRegisters mc_reg_table = { 0 }; | ||
1665 | |||
1666 | rv770_write_smc_soft_register(rdev, | ||
1667 | RV770_SMC_SOFT_REGISTER_seq_index, 1); | ||
1668 | |||
1669 | cypress_populate_mc_reg_addresses(rdev, &mc_reg_table); | ||
1670 | |||
1671 | cypress_convert_mc_reg_table_entry_to_smc(rdev, | ||
1672 | &boot_state->low, | ||
1673 | &mc_reg_table.data[0]); | ||
1674 | |||
1675 | cypress_convert_mc_registers(&eg_pi->mc_reg_table.mc_reg_table_entry[0], | ||
1676 | &mc_reg_table.data[1], eg_pi->mc_reg_table.last, | ||
1677 | eg_pi->mc_reg_table.valid_flag); | ||
1678 | |||
1679 | cypress_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, &mc_reg_table); | ||
1680 | |||
1681 | return rv770_copy_bytes_to_smc(rdev, eg_pi->mc_reg_table_start, | ||
1682 | (u8 *)&mc_reg_table, sizeof(SMC_Evergreen_MCRegisters), | ||
1683 | pi->sram_end); | ||
1684 | } | ||
1685 | |||
1686 | int cypress_get_table_locations(struct radeon_device *rdev) | ||
1687 | { | ||
1688 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1689 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1690 | u32 tmp; | ||
1691 | int ret; | ||
1692 | |||
1693 | ret = rv770_read_smc_sram_dword(rdev, | ||
1694 | EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION + | ||
1695 | EVERGREEN_SMC_FIRMWARE_HEADER_stateTable, | ||
1696 | &tmp, pi->sram_end); | ||
1697 | if (ret) | ||
1698 | return ret; | ||
1699 | |||
1700 | pi->state_table_start = (u16)tmp; | ||
1701 | |||
1702 | ret = rv770_read_smc_sram_dword(rdev, | ||
1703 | EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION + | ||
1704 | EVERGREEN_SMC_FIRMWARE_HEADER_softRegisters, | ||
1705 | &tmp, pi->sram_end); | ||
1706 | if (ret) | ||
1707 | return ret; | ||
1708 | |||
1709 | pi->soft_regs_start = (u16)tmp; | ||
1710 | |||
1711 | ret = rv770_read_smc_sram_dword(rdev, | ||
1712 | EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION + | ||
1713 | EVERGREEN_SMC_FIRMWARE_HEADER_mcRegisterTable, | ||
1714 | &tmp, pi->sram_end); | ||
1715 | if (ret) | ||
1716 | return ret; | ||
1717 | |||
1718 | eg_pi->mc_reg_table_start = (u16)tmp; | ||
1719 | |||
1720 | return 0; | ||
1721 | } | ||
1722 | |||
1723 | void cypress_enable_display_gap(struct radeon_device *rdev) | ||
1724 | { | ||
1725 | u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL); | ||
1726 | |||
1727 | tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK); | ||
1728 | tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) | | ||
1729 | DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE)); | ||
1730 | |||
1731 | tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK); | ||
1732 | tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) | | ||
1733 | DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE)); | ||
1734 | WREG32(CG_DISPLAY_GAP_CNTL, tmp); | ||
1735 | } | ||
1736 | |||
1737 | static void cypress_program_display_gap(struct radeon_device *rdev) | ||
1738 | { | ||
1739 | u32 tmp, pipe; | ||
1740 | int i; | ||
1741 | |||
1742 | tmp = RREG32(CG_DISPLAY_GAP_CNTL) & ~(DISP1_GAP_MASK | DISP2_GAP_MASK); | ||
1743 | if (rdev->pm.dpm.new_active_crtc_count > 0) | ||
1744 | tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM); | ||
1745 | else | ||
1746 | tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE); | ||
1747 | |||
1748 | if (rdev->pm.dpm.new_active_crtc_count > 1) | ||
1749 | tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM); | ||
1750 | else | ||
1751 | tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE); | ||
1752 | |||
1753 | WREG32(CG_DISPLAY_GAP_CNTL, tmp); | ||
1754 | |||
1755 | tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG); | ||
1756 | pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT; | ||
1757 | |||
1758 | if ((rdev->pm.dpm.new_active_crtc_count > 0) && | ||
1759 | (!(rdev->pm.dpm.new_active_crtcs & (1 << pipe)))) { | ||
1760 | /* find the first active crtc */ | ||
1761 | for (i = 0; i < rdev->num_crtc; i++) { | ||
1762 | if (rdev->pm.dpm.new_active_crtcs & (1 << i)) | ||
1763 | break; | ||
1764 | } | ||
1765 | if (i == rdev->num_crtc) | ||
1766 | pipe = 0; | ||
1767 | else | ||
1768 | pipe = i; | ||
1769 | |||
1770 | tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK; | ||
1771 | tmp |= DCCG_DISP1_SLOW_SELECT(pipe); | ||
1772 | WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp); | ||
1773 | } | ||
1774 | |||
1775 | cypress_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0); | ||
1776 | } | ||
1777 | |||
1778 | void cypress_dpm_setup_asic(struct radeon_device *rdev) | ||
1779 | { | ||
1780 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1781 | |||
1782 | rv740_read_clock_registers(rdev); | ||
1783 | rv770_read_voltage_smio_registers(rdev); | ||
1784 | rv770_get_max_vddc(rdev); | ||
1785 | rv770_get_memory_type(rdev); | ||
1786 | |||
1787 | if (eg_pi->pcie_performance_request) | ||
1788 | eg_pi->pcie_performance_request_registered = false; | ||
1789 | |||
1790 | if (eg_pi->pcie_performance_request) | ||
1791 | cypress_advertise_gen2_capability(rdev); | ||
1792 | |||
1793 | rv770_get_pcie_gen2_status(rdev); | ||
1794 | |||
1795 | rv770_enable_acpi_pm(rdev); | ||
1796 | } | ||
1797 | |||
1798 | int cypress_dpm_enable(struct radeon_device *rdev) | ||
1799 | { | ||
1800 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1801 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1802 | |||
1803 | if (pi->gfx_clock_gating) | ||
1804 | rv770_restore_cgcg(rdev); | ||
1805 | |||
1806 | if (rv770_dpm_enabled(rdev)) | ||
1807 | return -EINVAL; | ||
1808 | |||
1809 | if (pi->voltage_control) { | ||
1810 | rv770_enable_voltage_control(rdev, true); | ||
1811 | cypress_construct_voltage_tables(rdev); | ||
1812 | } | ||
1813 | |||
1814 | if (pi->mvdd_control) | ||
1815 | cypress_get_mvdd_configuration(rdev); | ||
1816 | |||
1817 | if (eg_pi->dynamic_ac_timing) { | ||
1818 | cypress_set_mc_reg_address_table(rdev); | ||
1819 | cypress_force_mc_use_s0(rdev); | ||
1820 | cypress_initialize_mc_reg_table(rdev); | ||
1821 | cypress_force_mc_use_s1(rdev); | ||
1822 | } | ||
1823 | |||
1824 | if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS) | ||
1825 | rv770_enable_backbias(rdev, true); | ||
1826 | |||
1827 | if (pi->dynamic_ss) | ||
1828 | cypress_enable_spread_spectrum(rdev, true); | ||
1829 | |||
1830 | if (pi->thermal_protection) | ||
1831 | rv770_enable_thermal_protection(rdev, true); | ||
1832 | |||
1833 | rv770_setup_bsp(rdev); | ||
1834 | rv770_program_git(rdev); | ||
1835 | rv770_program_tp(rdev); | ||
1836 | rv770_program_tpp(rdev); | ||
1837 | rv770_program_sstp(rdev); | ||
1838 | rv770_program_engine_speed_parameters(rdev); | ||
1839 | cypress_enable_display_gap(rdev); | ||
1840 | rv770_program_vc(rdev); | ||
1841 | |||
1842 | if (pi->dynamic_pcie_gen2) | ||
1843 | cypress_enable_dynamic_pcie_gen2(rdev, true); | ||
1844 | |||
1845 | if (rv770_upload_firmware(rdev)) | ||
1846 | return -EINVAL; | ||
1847 | |||
1848 | cypress_get_table_locations(rdev); | ||
1849 | |||
1850 | if (cypress_init_smc_table(rdev)) | ||
1851 | return -EINVAL; | ||
1852 | |||
1853 | if (eg_pi->dynamic_ac_timing) | ||
1854 | cypress_populate_mc_reg_table(rdev); | ||
1855 | |||
1856 | cypress_program_response_times(rdev); | ||
1857 | |||
1858 | r7xx_start_smc(rdev); | ||
1859 | |||
1860 | cypress_notify_smc_display_change(rdev, false); | ||
1861 | |||
1862 | cypress_enable_sclk_control(rdev, true); | ||
1863 | |||
1864 | if (eg_pi->memory_transition) | ||
1865 | cypress_enable_mclk_control(rdev, true); | ||
1866 | |||
1867 | cypress_start_dpm(rdev); | ||
1868 | |||
1869 | if (pi->gfx_clock_gating) | ||
1870 | cypress_gfx_clock_gating_enable(rdev, true); | ||
1871 | |||
1872 | if (pi->mg_clock_gating) | ||
1873 | cypress_mg_clock_gating_enable(rdev, true); | ||
1874 | |||
1875 | if (rdev->irq.installed && | ||
1876 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { | ||
1877 | PPSMC_Result result; | ||
1878 | |||
1879 | rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); | ||
1880 | rdev->irq.dpm_thermal = true; | ||
1881 | radeon_irq_set(rdev); | ||
1882 | result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); | ||
1883 | |||
1884 | if (result != PPSMC_Result_OK) | ||
1885 | DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); | ||
1886 | } | ||
1887 | |||
1888 | rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); | ||
1889 | |||
1890 | return 0; | ||
1891 | } | ||
1892 | |||
1893 | void cypress_dpm_disable(struct radeon_device *rdev) | ||
1894 | { | ||
1895 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | ||
1896 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1897 | |||
1898 | if (!rv770_dpm_enabled(rdev)) | ||
1899 | return; | ||
1900 | |||
1901 | rv770_clear_vc(rdev); | ||
1902 | |||
1903 | if (pi->thermal_protection) | ||
1904 | rv770_enable_thermal_protection(rdev, false); | ||
1905 | |||
1906 | if (pi->dynamic_pcie_gen2) | ||
1907 | cypress_enable_dynamic_pcie_gen2(rdev, false); | ||
1908 | |||
1909 | if (rdev->irq.installed && | ||
1910 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { | ||
1911 | rdev->irq.dpm_thermal = false; | ||
1912 | radeon_irq_set(rdev); | ||
1913 | } | ||
1914 | |||
1915 | if (pi->gfx_clock_gating) | ||
1916 | cypress_gfx_clock_gating_enable(rdev, false); | ||
1917 | |||
1918 | if (pi->mg_clock_gating) | ||
1919 | cypress_mg_clock_gating_enable(rdev, false); | ||
1920 | |||
1921 | rv770_stop_dpm(rdev); | ||
1922 | r7xx_stop_smc(rdev); | ||
1923 | |||
1924 | cypress_enable_spread_spectrum(rdev, false); | ||
1925 | |||
1926 | if (eg_pi->dynamic_ac_timing) | ||
1927 | cypress_force_mc_use_s1(rdev); | ||
1928 | |||
1929 | rv770_reset_smio_status(rdev); | ||
1930 | } | ||
1931 | |||
1932 | int cypress_dpm_set_power_state(struct radeon_device *rdev) | ||
1933 | { | ||
1934 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
1935 | |||
1936 | rv770_restrict_performance_levels_before_switch(rdev); | ||
1937 | |||
1938 | if (eg_pi->pcie_performance_request) | ||
1939 | cypress_notify_link_speed_change_before_state_change(rdev); | ||
1940 | |||
1941 | rv770_halt_smc(rdev); | ||
1942 | cypress_upload_sw_state(rdev); | ||
1943 | |||
1944 | if (eg_pi->dynamic_ac_timing) | ||
1945 | cypress_upload_mc_reg_table(rdev); | ||
1946 | |||
1947 | cypress_program_memory_timing_parameters(rdev); | ||
1948 | |||
1949 | rv770_resume_smc(rdev); | ||
1950 | rv770_set_sw_state(rdev); | ||
1951 | |||
1952 | if (eg_pi->pcie_performance_request) | ||
1953 | cypress_notify_link_speed_change_after_state_change(rdev); | ||
1954 | |||
1955 | rv770_unrestrict_performance_levels_after_switch(rdev); | ||
1956 | |||
1957 | return 0; | ||
1958 | } | ||
1959 | |||
1960 | void cypress_dpm_reset_asic(struct radeon_device *rdev) | ||
1961 | { | ||
1962 | rv770_restrict_performance_levels_before_switch(rdev); | ||
1963 | rv770_set_boot_state(rdev); | ||
1964 | } | ||
1965 | |||
1966 | void cypress_dpm_display_configuration_changed(struct radeon_device *rdev) | ||
1967 | { | ||
1968 | cypress_program_display_gap(rdev); | ||
1969 | } | ||
1970 | |||
1971 | int cypress_dpm_init(struct radeon_device *rdev) | ||
1972 | { | ||
1973 | struct rv7xx_power_info *pi; | ||
1974 | struct evergreen_power_info *eg_pi; | ||
1975 | int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info); | ||
1976 | uint16_t data_offset, size; | ||
1977 | uint8_t frev, crev; | ||
1978 | struct atom_clock_dividers dividers; | ||
1979 | int ret; | ||
1980 | |||
1981 | eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL); | ||
1982 | if (eg_pi == NULL) | ||
1983 | return -ENOMEM; | ||
1984 | rdev->pm.dpm.priv = eg_pi; | ||
1985 | pi = &eg_pi->rv7xx; | ||
1986 | |||
1987 | rv770_get_max_vddc(rdev); | ||
1988 | |||
1989 | eg_pi->ulv.supported = false; | ||
1990 | pi->acpi_vddc = 0; | ||
1991 | eg_pi->acpi_vddci = 0; | ||
1992 | pi->min_vddc_in_table = 0; | ||
1993 | pi->max_vddc_in_table = 0; | ||
1994 | |||
1995 | ret = rv7xx_parse_power_table(rdev); | ||
1996 | if (ret) | ||
1997 | return ret; | ||
1998 | |||
1999 | if (rdev->pm.dpm.voltage_response_time == 0) | ||
2000 | rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT; | ||
2001 | if (rdev->pm.dpm.backbias_response_time == 0) | ||
2002 | rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT; | ||
2003 | |||
2004 | ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, | ||
2005 | 0, false, ÷rs); | ||
2006 | if (ret) | ||
2007 | pi->ref_div = dividers.ref_div + 1; | ||
2008 | else | ||
2009 | pi->ref_div = R600_REFERENCEDIVIDER_DFLT; | ||
2010 | |||
2011 | pi->mclk_strobe_mode_threshold = 40000; | ||
2012 | pi->mclk_edc_enable_threshold = 40000; | ||
2013 | eg_pi->mclk_edc_wr_enable_threshold = 40000; | ||
2014 | |||
2015 | pi->voltage_control = | ||
2016 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC); | ||
2017 | |||
2018 | pi->mvdd_control = | ||
2019 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC); | ||
2020 | |||
2021 | eg_pi->vddci_control = | ||
2022 | radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI); | ||
2023 | |||
2024 | if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size, | ||
2025 | &frev, &crev, &data_offset)) { | ||
2026 | pi->sclk_ss = true; | ||
2027 | pi->mclk_ss = true; | ||
2028 | pi->dynamic_ss = true; | ||
2029 | } else { | ||
2030 | pi->sclk_ss = false; | ||
2031 | pi->mclk_ss = false; | ||
2032 | pi->dynamic_ss = true; | ||
2033 | } | ||
2034 | |||
2035 | pi->asi = RV770_ASI_DFLT; | ||
2036 | pi->pasi = CYPRESS_HASI_DFLT; | ||
2037 | pi->vrc = CYPRESS_VRC_DFLT; | ||
2038 | |||
2039 | pi->power_gating = false; | ||
2040 | |||
2041 | if ((rdev->family == CHIP_CYPRESS) || | ||
2042 | (rdev->family == CHIP_HEMLOCK)) | ||
2043 | pi->gfx_clock_gating = false; | ||
2044 | else | ||
2045 | pi->gfx_clock_gating = true; | ||
2046 | |||
2047 | pi->mg_clock_gating = true; | ||
2048 | pi->mgcgtssm = true; | ||
2049 | eg_pi->ls_clock_gating = false; | ||
2050 | eg_pi->sclk_deep_sleep = false; | ||
2051 | |||
2052 | pi->dynamic_pcie_gen2 = true; | ||
2053 | |||
2054 | if (pi->gfx_clock_gating && | ||
2055 | (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)) | ||
2056 | pi->thermal_protection = true; | ||
2057 | else | ||
2058 | pi->thermal_protection = false; | ||
2059 | |||
2060 | pi->display_gap = true; | ||
2061 | |||
2062 | if (rdev->flags & RADEON_IS_MOBILITY) | ||
2063 | pi->dcodt = true; | ||
2064 | else | ||
2065 | pi->dcodt = false; | ||
2066 | |||
2067 | pi->ulps = true; | ||
2068 | |||
2069 | eg_pi->dynamic_ac_timing = true; | ||
2070 | eg_pi->abm = true; | ||
2071 | eg_pi->mcls = true; | ||
2072 | eg_pi->light_sleep = true; | ||
2073 | eg_pi->memory_transition = true; | ||
2074 | #if defined(CONFIG_ACPI) | ||
2075 | eg_pi->pcie_performance_request = | ||
2076 | radeon_acpi_is_pcie_performance_request_supported(rdev); | ||
2077 | #else | ||
2078 | eg_pi->pcie_performance_request = false; | ||
2079 | #endif | ||
2080 | |||
2081 | if ((rdev->family == CHIP_CYPRESS) || | ||
2082 | (rdev->family == CHIP_HEMLOCK) || | ||
2083 | (rdev->family == CHIP_JUNIPER)) | ||
2084 | eg_pi->dll_default_on = true; | ||
2085 | else | ||
2086 | eg_pi->dll_default_on = false; | ||
2087 | |||
2088 | eg_pi->sclk_deep_sleep = false; | ||
2089 | pi->mclk_stutter_mode_threshold = 0; | ||
2090 | |||
2091 | pi->sram_end = SMC_RAM_END; | ||
2092 | |||
2093 | return 0; | ||
2094 | } | ||
2095 | |||
2096 | void cypress_dpm_fini(struct radeon_device *rdev) | ||
2097 | { | ||
2098 | int i; | ||
2099 | |||
2100 | for (i = 0; i < rdev->pm.dpm.num_ps; i++) { | ||
2101 | kfree(rdev->pm.dpm.ps[i].ps_priv); | ||
2102 | } | ||
2103 | kfree(rdev->pm.dpm.ps); | ||
2104 | kfree(rdev->pm.dpm.priv); | ||
2105 | } | ||
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.h b/drivers/gpu/drm/radeon/cypress_dpm.h new file mode 100644 index 000000000000..6cc3d3f7ae13 --- /dev/null +++ b/drivers/gpu/drm/radeon/cypress_dpm.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | #ifndef __CYPRESS_DPM_H__ | ||
24 | #define __CYPRESS_DPM_H__ | ||
25 | |||
26 | #include "rv770_dpm.h" | ||
27 | #include "evergreen_smc.h" | ||
28 | |||
29 | struct evergreen_mc_reg_entry { | ||
30 | u32 mclk_max; | ||
31 | u32 mc_data[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE]; | ||
32 | }; | ||
33 | |||
34 | struct evergreen_mc_reg_table { | ||
35 | u8 last; | ||
36 | u8 num_entries; | ||
37 | u16 valid_flag; | ||
38 | struct evergreen_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES]; | ||
39 | SMC_Evergreen_MCRegisterAddress mc_reg_address[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE]; | ||
40 | }; | ||
41 | |||
42 | struct evergreen_ulv_param { | ||
43 | bool supported; | ||
44 | struct rv7xx_pl *pl; | ||
45 | }; | ||
46 | |||
47 | struct evergreen_arb_registers { | ||
48 | u32 mc_arb_dram_timing; | ||
49 | u32 mc_arb_dram_timing2; | ||
50 | u32 mc_arb_rfsh_rate; | ||
51 | u32 mc_arb_burst_time; | ||
52 | }; | ||
53 | |||
54 | struct evergreen_power_info { | ||
55 | /* must be first! */ | ||
56 | struct rv7xx_power_info rv7xx; | ||
57 | /* flags */ | ||
58 | bool vddci_control; | ||
59 | bool dynamic_ac_timing; | ||
60 | bool abm; | ||
61 | bool mcls; | ||
62 | bool light_sleep; | ||
63 | bool memory_transition; | ||
64 | bool pcie_performance_request; | ||
65 | bool pcie_performance_request_registered; | ||
66 | bool sclk_deep_sleep; | ||
67 | bool dll_default_on; | ||
68 | bool ls_clock_gating; | ||
69 | /* stored values */ | ||
70 | u16 acpi_vddci; | ||
71 | u8 mvdd_high_index; | ||
72 | u8 mvdd_low_index; | ||
73 | u32 mclk_edc_wr_enable_threshold; | ||
74 | struct evergreen_mc_reg_table mc_reg_table; | ||
75 | struct atom_voltage_table vddc_voltage_table; | ||
76 | struct atom_voltage_table vddci_voltage_table; | ||
77 | struct evergreen_arb_registers bootup_arb_registers; | ||
78 | struct evergreen_ulv_param ulv; | ||
79 | /* smc offsets */ | ||
80 | u16 mc_reg_table_start; | ||
81 | }; | ||
82 | |||
83 | #define CYPRESS_HASI_DFLT 400000 | ||
84 | #define CYPRESS_MGCGTTLOCAL0_DFLT 0x00000000 | ||
85 | #define CYPRESS_MGCGTTLOCAL1_DFLT 0x00000000 | ||
86 | #define CYPRESS_MGCGTTLOCAL2_DFLT 0x00000000 | ||
87 | #define CYPRESS_MGCGTTLOCAL3_DFLT 0x00000000 | ||
88 | #define CYPRESS_MGCGCGTSSMCTRL_DFLT 0x81944bc0 | ||
89 | #define REDWOOD_MGCGCGTSSMCTRL_DFLT 0x6e944040 | ||
90 | #define CEDAR_MGCGCGTSSMCTRL_DFLT 0x46944040 | ||
91 | #define CYPRESS_VRC_DFLT 0xC00033 | ||
92 | |||
93 | #define PCIE_PERF_REQ_REMOVE_REGISTRY 0 | ||
94 | #define PCIE_PERF_REQ_FORCE_LOWPOWER 1 | ||
95 | #define PCIE_PERF_REQ_PECI_GEN1 2 | ||
96 | #define PCIE_PERF_REQ_PECI_GEN2 3 | ||
97 | #define PCIE_PERF_REQ_PECI_GEN3 4 | ||
98 | |||
99 | int cypress_convert_power_level_to_smc(struct radeon_device *rdev, | ||
100 | struct rv7xx_pl *pl, | ||
101 | RV770_SMC_HW_PERFORMANCE_LEVEL *level, | ||
102 | u8 watermark_level); | ||
103 | int cypress_populate_smc_acpi_state(struct radeon_device *rdev, | ||
104 | RV770_SMC_STATETABLE *table); | ||
105 | int cypress_populate_smc_voltage_tables(struct radeon_device *rdev, | ||
106 | RV770_SMC_STATETABLE *table); | ||
107 | int cypress_populate_smc_initial_state(struct radeon_device *rdev, | ||
108 | struct radeon_ps *radeon_initial_state, | ||
109 | RV770_SMC_STATETABLE *table); | ||
110 | u32 cypress_calculate_burst_time(struct radeon_device *rdev, | ||
111 | u32 engine_clock, u32 memory_clock); | ||
112 | void cypress_notify_link_speed_change_before_state_change(struct radeon_device *rdev); | ||
113 | int cypress_upload_sw_state(struct radeon_device *rdev); | ||
114 | int cypress_upload_mc_reg_table(struct radeon_device *rdev); | ||
115 | void cypress_program_memory_timing_parameters(struct radeon_device *rdev); | ||
116 | void cypress_notify_link_speed_change_after_state_change(struct radeon_device *rdev); | ||
117 | int cypress_construct_voltage_tables(struct radeon_device *rdev); | ||
118 | int cypress_get_mvdd_configuration(struct radeon_device *rdev); | ||
119 | void cypress_enable_spread_spectrum(struct radeon_device *rdev, | ||
120 | bool enable); | ||
121 | void cypress_enable_display_gap(struct radeon_device *rdev); | ||
122 | int cypress_get_table_locations(struct radeon_device *rdev); | ||
123 | int cypress_populate_mc_reg_table(struct radeon_device *rdev); | ||
124 | void cypress_program_response_times(struct radeon_device *rdev); | ||
125 | int cypress_notify_smc_display_change(struct radeon_device *rdev, | ||
126 | bool has_display); | ||
127 | void cypress_enable_sclk_control(struct radeon_device *rdev, | ||
128 | bool enable); | ||
129 | void cypress_enable_mclk_control(struct radeon_device *rdev, | ||
130 | bool enable); | ||
131 | void cypress_start_dpm(struct radeon_device *rdev); | ||
132 | void cypress_advertise_gen2_capability(struct radeon_device *rdev); | ||
133 | |||
134 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 63a1e6ec7f5a..54d1d736dee2 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -4167,6 +4167,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
4167 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | 4167 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; |
4168 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; | 4168 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; |
4169 | u32 dma_cntl, dma_cntl1 = 0; | 4169 | u32 dma_cntl, dma_cntl1 = 0; |
4170 | u32 thermal_int = 0; | ||
4170 | 4171 | ||
4171 | if (!rdev->irq.installed) { | 4172 | if (!rdev->irq.installed) { |
4172 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 4173 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -4186,6 +4187,8 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
4186 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4187 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4187 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4188 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4188 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 4189 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
4190 | thermal_int = RREG32(CG_THERMAL_INT) & | ||
4191 | ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); | ||
4189 | 4192 | ||
4190 | afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | 4193 | afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; |
4191 | afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | 4194 | afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; |
@@ -4231,6 +4234,11 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
4231 | } | 4234 | } |
4232 | } | 4235 | } |
4233 | 4236 | ||
4237 | if (rdev->irq.dpm_thermal) { | ||
4238 | DRM_DEBUG("dpm thermal\n"); | ||
4239 | thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; | ||
4240 | } | ||
4241 | |||
4234 | if (rdev->irq.crtc_vblank_int[0] || | 4242 | if (rdev->irq.crtc_vblank_int[0] || |
4235 | atomic_read(&rdev->irq.pflip[0])) { | 4243 | atomic_read(&rdev->irq.pflip[0])) { |
4236 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); | 4244 | DRM_DEBUG("evergreen_irq_set: vblank 0\n"); |
@@ -4352,6 +4360,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
4352 | WREG32(DC_HPD4_INT_CONTROL, hpd4); | 4360 | WREG32(DC_HPD4_INT_CONTROL, hpd4); |
4353 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | 4361 | WREG32(DC_HPD5_INT_CONTROL, hpd5); |
4354 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | 4362 | WREG32(DC_HPD6_INT_CONTROL, hpd6); |
4363 | WREG32(CG_THERMAL_INT, thermal_int); | ||
4355 | 4364 | ||
4356 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1); | 4365 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1); |
4357 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2); | 4366 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2); |
@@ -4543,6 +4552,7 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
4543 | u32 ring_index; | 4552 | u32 ring_index; |
4544 | bool queue_hotplug = false; | 4553 | bool queue_hotplug = false; |
4545 | bool queue_hdmi = false; | 4554 | bool queue_hdmi = false; |
4555 | bool queue_thermal = false; | ||
4546 | 4556 | ||
4547 | if (!rdev->ih.enabled || rdev->shutdown) | 4557 | if (!rdev->ih.enabled || rdev->shutdown) |
4548 | return IRQ_NONE; | 4558 | return IRQ_NONE; |
@@ -4864,6 +4874,16 @@ restart_ih: | |||
4864 | DRM_DEBUG("IH: DMA trap\n"); | 4874 | DRM_DEBUG("IH: DMA trap\n"); |
4865 | radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); | 4875 | radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); |
4866 | break; | 4876 | break; |
4877 | case 230: /* thermal low to high */ | ||
4878 | DRM_DEBUG("IH: thermal low to high\n"); | ||
4879 | rdev->pm.dpm.thermal.high_to_low = false; | ||
4880 | queue_thermal = true; | ||
4881 | break; | ||
4882 | case 231: /* thermal high to low */ | ||
4883 | DRM_DEBUG("IH: thermal high to low\n"); | ||
4884 | rdev->pm.dpm.thermal.high_to_low = true; | ||
4885 | queue_thermal = true; | ||
4886 | break; | ||
4867 | case 233: /* GUI IDLE */ | 4887 | case 233: /* GUI IDLE */ |
4868 | DRM_DEBUG("IH: GUI idle\n"); | 4888 | DRM_DEBUG("IH: GUI idle\n"); |
4869 | break; | 4889 | break; |
@@ -4886,6 +4906,8 @@ restart_ih: | |||
4886 | schedule_work(&rdev->hotplug_work); | 4906 | schedule_work(&rdev->hotplug_work); |
4887 | if (queue_hdmi) | 4907 | if (queue_hdmi) |
4888 | schedule_work(&rdev->audio_work); | 4908 | schedule_work(&rdev->audio_work); |
4909 | if (queue_thermal && rdev->pm.dpm_enabled) | ||
4910 | schedule_work(&rdev->pm.dpm.thermal.work); | ||
4889 | rdev->ih.rptr = rptr; | 4911 | rdev->ih.rptr = rptr; |
4890 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 4912 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
4891 | atomic_set(&rdev->ih.lock, 0); | 4913 | atomic_set(&rdev->ih.lock, 0); |
diff --git a/drivers/gpu/drm/radeon/evergreen_smc.h b/drivers/gpu/drm/radeon/evergreen_smc.h new file mode 100644 index 000000000000..76ada8cfe902 --- /dev/null +++ b/drivers/gpu/drm/radeon/evergreen_smc.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | #ifndef __EVERGREEN_SMC_H__ | ||
24 | #define __EVERGREEN_SMC_H__ | ||
25 | |||
26 | #include "rv770_smc.h" | ||
27 | |||
28 | #pragma pack(push, 1) | ||
29 | |||
30 | #define SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE 16 | ||
31 | |||
32 | struct SMC_Evergreen_MCRegisterAddress | ||
33 | { | ||
34 | uint16_t s0; | ||
35 | uint16_t s1; | ||
36 | }; | ||
37 | |||
38 | typedef struct SMC_Evergreen_MCRegisterAddress SMC_Evergreen_MCRegisterAddress; | ||
39 | |||
40 | |||
41 | struct SMC_Evergreen_MCRegisterSet | ||
42 | { | ||
43 | uint32_t value[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE]; | ||
44 | }; | ||
45 | |||
46 | typedef struct SMC_Evergreen_MCRegisterSet SMC_Evergreen_MCRegisterSet; | ||
47 | |||
48 | struct SMC_Evergreen_MCRegisters | ||
49 | { | ||
50 | uint8_t last; | ||
51 | uint8_t reserved[3]; | ||
52 | SMC_Evergreen_MCRegisterAddress address[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE]; | ||
53 | SMC_Evergreen_MCRegisterSet data[5]; | ||
54 | }; | ||
55 | |||
56 | typedef struct SMC_Evergreen_MCRegisters SMC_Evergreen_MCRegisters; | ||
57 | |||
58 | #define EVERGREEN_SMC_FIRMWARE_HEADER_LOCATION 0x100 | ||
59 | |||
60 | #define EVERGREEN_SMC_FIRMWARE_HEADER_softRegisters 0x0 | ||
61 | #define EVERGREEN_SMC_FIRMWARE_HEADER_stateTable 0xC | ||
62 | #define EVERGREEN_SMC_FIRMWARE_HEADER_mcRegisterTable 0x20 | ||
63 | |||
64 | |||
65 | #pragma pack(pop) | ||
66 | |||
67 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 8603b7cf31a7..93b91a38200a 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -48,6 +48,293 @@ | |||
48 | #define SUMO_GB_ADDR_CONFIG_GOLDEN 0x02010002 | 48 | #define SUMO_GB_ADDR_CONFIG_GOLDEN 0x02010002 |
49 | #define SUMO2_GB_ADDR_CONFIG_GOLDEN 0x02010002 | 49 | #define SUMO2_GB_ADDR_CONFIG_GOLDEN 0x02010002 |
50 | 50 | ||
51 | /* pm registers */ | ||
52 | #define SMC_MSG 0x20c | ||
53 | #define HOST_SMC_MSG(x) ((x) << 0) | ||
54 | #define HOST_SMC_MSG_MASK (0xff << 0) | ||
55 | #define HOST_SMC_MSG_SHIFT 0 | ||
56 | #define HOST_SMC_RESP(x) ((x) << 8) | ||
57 | #define HOST_SMC_RESP_MASK (0xff << 8) | ||
58 | #define HOST_SMC_RESP_SHIFT 8 | ||
59 | #define SMC_HOST_MSG(x) ((x) << 16) | ||
60 | #define SMC_HOST_MSG_MASK (0xff << 16) | ||
61 | #define SMC_HOST_MSG_SHIFT 16 | ||
62 | #define SMC_HOST_RESP(x) ((x) << 24) | ||
63 | #define SMC_HOST_RESP_MASK (0xff << 24) | ||
64 | #define SMC_HOST_RESP_SHIFT 24 | ||
65 | |||
66 | #define DCCG_DISP_SLOW_SELECT_REG 0x4fc | ||
67 | #define DCCG_DISP1_SLOW_SELECT(x) ((x) << 0) | ||
68 | #define DCCG_DISP1_SLOW_SELECT_MASK (7 << 0) | ||
69 | #define DCCG_DISP1_SLOW_SELECT_SHIFT 0 | ||
70 | #define DCCG_DISP2_SLOW_SELECT(x) ((x) << 4) | ||
71 | #define DCCG_DISP2_SLOW_SELECT_MASK (7 << 4) | ||
72 | #define DCCG_DISP2_SLOW_SELECT_SHIFT 4 | ||
73 | |||
74 | #define CG_SPLL_FUNC_CNTL 0x600 | ||
75 | #define SPLL_RESET (1 << 0) | ||
76 | #define SPLL_SLEEP (1 << 1) | ||
77 | #define SPLL_BYPASS_EN (1 << 3) | ||
78 | #define SPLL_REF_DIV(x) ((x) << 4) | ||
79 | #define SPLL_REF_DIV_MASK (0x3f << 4) | ||
80 | #define SPLL_PDIV_A(x) ((x) << 20) | ||
81 | #define SPLL_PDIV_A_MASK (0x7f << 20) | ||
82 | #define CG_SPLL_FUNC_CNTL_2 0x604 | ||
83 | #define SCLK_MUX_SEL(x) ((x) << 0) | ||
84 | #define SCLK_MUX_SEL_MASK (0x1ff << 0) | ||
85 | #define CG_SPLL_FUNC_CNTL_3 0x608 | ||
86 | #define SPLL_FB_DIV(x) ((x) << 0) | ||
87 | #define SPLL_FB_DIV_MASK (0x3ffffff << 0) | ||
88 | #define SPLL_DITHEN (1 << 28) | ||
89 | |||
90 | #define MPLL_CNTL_MODE 0x61c | ||
91 | # define SS_SSEN (1 << 24) | ||
92 | # define SS_DSMODE_EN (1 << 25) | ||
93 | |||
94 | #define MPLL_AD_FUNC_CNTL 0x624 | ||
95 | #define CLKF(x) ((x) << 0) | ||
96 | #define CLKF_MASK (0x7f << 0) | ||
97 | #define CLKR(x) ((x) << 7) | ||
98 | #define CLKR_MASK (0x1f << 7) | ||
99 | #define CLKFRAC(x) ((x) << 12) | ||
100 | #define CLKFRAC_MASK (0x1f << 12) | ||
101 | #define YCLK_POST_DIV(x) ((x) << 17) | ||
102 | #define YCLK_POST_DIV_MASK (3 << 17) | ||
103 | #define IBIAS(x) ((x) << 20) | ||
104 | #define IBIAS_MASK (0x3ff << 20) | ||
105 | #define RESET (1 << 30) | ||
106 | #define PDNB (1 << 31) | ||
107 | #define MPLL_AD_FUNC_CNTL_2 0x628 | ||
108 | #define BYPASS (1 << 19) | ||
109 | #define BIAS_GEN_PDNB (1 << 24) | ||
110 | #define RESET_EN (1 << 25) | ||
111 | #define VCO_MODE (1 << 29) | ||
112 | #define MPLL_DQ_FUNC_CNTL 0x62c | ||
113 | #define MPLL_DQ_FUNC_CNTL_2 0x630 | ||
114 | |||
115 | #define GENERAL_PWRMGT 0x63c | ||
116 | # define GLOBAL_PWRMGT_EN (1 << 0) | ||
117 | # define STATIC_PM_EN (1 << 1) | ||
118 | # define THERMAL_PROTECTION_DIS (1 << 2) | ||
119 | # define THERMAL_PROTECTION_TYPE (1 << 3) | ||
120 | # define ENABLE_GEN2PCIE (1 << 4) | ||
121 | # define ENABLE_GEN2XSP (1 << 5) | ||
122 | # define SW_SMIO_INDEX(x) ((x) << 6) | ||
123 | # define SW_SMIO_INDEX_MASK (3 << 6) | ||
124 | # define SW_SMIO_INDEX_SHIFT 6 | ||
125 | # define LOW_VOLT_D2_ACPI (1 << 8) | ||
126 | # define LOW_VOLT_D3_ACPI (1 << 9) | ||
127 | # define VOLT_PWRMGT_EN (1 << 10) | ||
128 | # define BACKBIAS_PAD_EN (1 << 18) | ||
129 | # define BACKBIAS_VALUE (1 << 19) | ||
130 | # define DYN_SPREAD_SPECTRUM_EN (1 << 23) | ||
131 | # define AC_DC_SW (1 << 24) | ||
132 | |||
133 | #define SCLK_PWRMGT_CNTL 0x644 | ||
134 | # define SCLK_PWRMGT_OFF (1 << 0) | ||
135 | # define SCLK_LOW_D1 (1 << 1) | ||
136 | # define FIR_RESET (1 << 4) | ||
137 | # define FIR_FORCE_TREND_SEL (1 << 5) | ||
138 | # define FIR_TREND_MODE (1 << 6) | ||
139 | # define DYN_GFX_CLK_OFF_EN (1 << 7) | ||
140 | # define GFX_CLK_FORCE_ON (1 << 8) | ||
141 | # define GFX_CLK_REQUEST_OFF (1 << 9) | ||
142 | # define GFX_CLK_FORCE_OFF (1 << 10) | ||
143 | # define GFX_CLK_OFF_ACPI_D1 (1 << 11) | ||
144 | # define GFX_CLK_OFF_ACPI_D2 (1 << 12) | ||
145 | # define GFX_CLK_OFF_ACPI_D3 (1 << 13) | ||
146 | # define DYN_LIGHT_SLEEP_EN (1 << 14) | ||
147 | #define MCLK_PWRMGT_CNTL 0x648 | ||
148 | # define DLL_SPEED(x) ((x) << 0) | ||
149 | # define DLL_SPEED_MASK (0x1f << 0) | ||
150 | # define MPLL_PWRMGT_OFF (1 << 5) | ||
151 | # define DLL_READY (1 << 6) | ||
152 | # define MC_INT_CNTL (1 << 7) | ||
153 | # define MRDCKA0_PDNB (1 << 8) | ||
154 | # define MRDCKA1_PDNB (1 << 9) | ||
155 | # define MRDCKB0_PDNB (1 << 10) | ||
156 | # define MRDCKB1_PDNB (1 << 11) | ||
157 | # define MRDCKC0_PDNB (1 << 12) | ||
158 | # define MRDCKC1_PDNB (1 << 13) | ||
159 | # define MRDCKD0_PDNB (1 << 14) | ||
160 | # define MRDCKD1_PDNB (1 << 15) | ||
161 | # define MRDCKA0_RESET (1 << 16) | ||
162 | # define MRDCKA1_RESET (1 << 17) | ||
163 | # define MRDCKB0_RESET (1 << 18) | ||
164 | # define MRDCKB1_RESET (1 << 19) | ||
165 | # define MRDCKC0_RESET (1 << 20) | ||
166 | # define MRDCKC1_RESET (1 << 21) | ||
167 | # define MRDCKD0_RESET (1 << 22) | ||
168 | # define MRDCKD1_RESET (1 << 23) | ||
169 | # define DLL_READY_READ (1 << 24) | ||
170 | # define USE_DISPLAY_GAP (1 << 25) | ||
171 | # define USE_DISPLAY_URGENT_NORMAL (1 << 26) | ||
172 | # define MPLL_TURNOFF_D2 (1 << 28) | ||
173 | #define DLL_CNTL 0x64c | ||
174 | # define MRDCKA0_BYPASS (1 << 24) | ||
175 | # define MRDCKA1_BYPASS (1 << 25) | ||
176 | # define MRDCKB0_BYPASS (1 << 26) | ||
177 | # define MRDCKB1_BYPASS (1 << 27) | ||
178 | # define MRDCKC0_BYPASS (1 << 28) | ||
179 | # define MRDCKC1_BYPASS (1 << 29) | ||
180 | # define MRDCKD0_BYPASS (1 << 30) | ||
181 | # define MRDCKD1_BYPASS (1 << 31) | ||
182 | |||
183 | #define CG_AT 0x6d4 | ||
184 | # define CG_R(x) ((x) << 0) | ||
185 | # define CG_R_MASK (0xffff << 0) | ||
186 | # define CG_L(x) ((x) << 16) | ||
187 | # define CG_L_MASK (0xffff << 16) | ||
188 | |||
189 | #define CG_DISPLAY_GAP_CNTL 0x714 | ||
190 | # define DISP1_GAP(x) ((x) << 0) | ||
191 | # define DISP1_GAP_MASK (3 << 0) | ||
192 | # define DISP2_GAP(x) ((x) << 2) | ||
193 | # define DISP2_GAP_MASK (3 << 2) | ||
194 | # define VBI_TIMER_COUNT(x) ((x) << 4) | ||
195 | # define VBI_TIMER_COUNT_MASK (0x3fff << 4) | ||
196 | # define VBI_TIMER_UNIT(x) ((x) << 20) | ||
197 | # define VBI_TIMER_UNIT_MASK (7 << 20) | ||
198 | # define DISP1_GAP_MCHG(x) ((x) << 24) | ||
199 | # define DISP1_GAP_MCHG_MASK (3 << 24) | ||
200 | # define DISP2_GAP_MCHG(x) ((x) << 26) | ||
201 | # define DISP2_GAP_MCHG_MASK (3 << 26) | ||
202 | |||
203 | #define CG_BIF_REQ_AND_RSP 0x7f4 | ||
204 | #define CG_CLIENT_REQ(x) ((x) << 0) | ||
205 | #define CG_CLIENT_REQ_MASK (0xff << 0) | ||
206 | #define CG_CLIENT_REQ_SHIFT 0 | ||
207 | #define CG_CLIENT_RESP(x) ((x) << 8) | ||
208 | #define CG_CLIENT_RESP_MASK (0xff << 8) | ||
209 | #define CG_CLIENT_RESP_SHIFT 8 | ||
210 | #define CLIENT_CG_REQ(x) ((x) << 16) | ||
211 | #define CLIENT_CG_REQ_MASK (0xff << 16) | ||
212 | #define CLIENT_CG_REQ_SHIFT 16 | ||
213 | #define CLIENT_CG_RESP(x) ((x) << 24) | ||
214 | #define CLIENT_CG_RESP_MASK (0xff << 24) | ||
215 | #define CLIENT_CG_RESP_SHIFT 24 | ||
216 | |||
217 | #define CG_SPLL_SPREAD_SPECTRUM 0x790 | ||
218 | #define SSEN (1 << 0) | ||
219 | #define CG_SPLL_SPREAD_SPECTRUM_2 0x794 | ||
220 | |||
221 | #define MPLL_SS1 0x85c | ||
222 | #define CLKV(x) ((x) << 0) | ||
223 | #define CLKV_MASK (0x3ffffff << 0) | ||
224 | #define MPLL_SS2 0x860 | ||
225 | #define CLKS(x) ((x) << 0) | ||
226 | #define CLKS_MASK (0xfff << 0) | ||
227 | |||
228 | #define CG_IND_ADDR 0x8f8 | ||
229 | #define CG_IND_DATA 0x8fc | ||
230 | /* CGIND regs */ | ||
231 | #define CG_CGTT_LOCAL_0 0x00 | ||
232 | #define CG_CGTT_LOCAL_1 0x01 | ||
233 | #define CG_CGTT_LOCAL_2 0x02 | ||
234 | #define CG_CGTT_LOCAL_3 0x03 | ||
235 | #define CG_CGLS_TILE_0 0x20 | ||
236 | #define CG_CGLS_TILE_1 0x21 | ||
237 | #define CG_CGLS_TILE_2 0x22 | ||
238 | #define CG_CGLS_TILE_3 0x23 | ||
239 | #define CG_CGLS_TILE_4 0x24 | ||
240 | #define CG_CGLS_TILE_5 0x25 | ||
241 | #define CG_CGLS_TILE_6 0x26 | ||
242 | #define CG_CGLS_TILE_7 0x27 | ||
243 | #define CG_CGLS_TILE_8 0x28 | ||
244 | #define CG_CGLS_TILE_9 0x29 | ||
245 | #define CG_CGLS_TILE_10 0x2a | ||
246 | #define CG_CGLS_TILE_11 0x2b | ||
247 | |||
248 | #define VM_L2_CG 0x15c0 | ||
249 | |||
250 | #define MC_CONFIG 0x2000 | ||
251 | |||
252 | #define MC_CONFIG_MCD 0x20a0 | ||
253 | #define MC_CG_CONFIG_MCD 0x20a4 | ||
254 | #define MC_RD_ENABLE_MCD(x) ((x) << 8) | ||
255 | #define MC_RD_ENABLE_MCD_MASK (7 << 8) | ||
256 | |||
257 | #define MC_HUB_MISC_HUB_CG 0x20b8 | ||
258 | #define MC_HUB_MISC_VM_CG 0x20bc | ||
259 | #define MC_HUB_MISC_SIP_CG 0x20c0 | ||
260 | |||
261 | #define MC_XPB_CLK_GAT 0x2478 | ||
262 | |||
263 | #define MC_CG_CONFIG 0x25bc | ||
264 | #define MC_RD_ENABLE(x) ((x) << 4) | ||
265 | #define MC_RD_ENABLE_MASK (3 << 4) | ||
266 | |||
267 | #define MC_CITF_MISC_RD_CG 0x2648 | ||
268 | #define MC_CITF_MISC_WR_CG 0x264c | ||
269 | #define MC_CITF_MISC_VM_CG 0x2650 | ||
270 | # define MEM_LS_ENABLE (1 << 19) | ||
271 | |||
272 | #define MC_ARB_BURST_TIME 0x2808 | ||
273 | #define STATE0(x) ((x) << 0) | ||
274 | #define STATE0_MASK (0x1f << 0) | ||
275 | #define STATE1(x) ((x) << 5) | ||
276 | #define STATE1_MASK (0x1f << 5) | ||
277 | #define STATE2(x) ((x) << 10) | ||
278 | #define STATE2_MASK (0x1f << 10) | ||
279 | #define STATE3(x) ((x) << 15) | ||
280 | #define STATE3_MASK (0x1f << 15) | ||
281 | |||
282 | #define MC_SEQ_RAS_TIMING 0x28a0 | ||
283 | #define MC_SEQ_CAS_TIMING 0x28a4 | ||
284 | #define MC_SEQ_MISC_TIMING 0x28a8 | ||
285 | #define MC_SEQ_MISC_TIMING2 0x28ac | ||
286 | |||
287 | #define MC_SEQ_RD_CTL_D0 0x28b4 | ||
288 | #define MC_SEQ_RD_CTL_D1 0x28b8 | ||
289 | #define MC_SEQ_WR_CTL_D0 0x28bc | ||
290 | #define MC_SEQ_WR_CTL_D1 0x28c0 | ||
291 | |||
292 | #define MC_SEQ_STATUS_M 0x29f4 | ||
293 | # define PMG_PWRSTATE (1 << 16) | ||
294 | |||
295 | #define MC_SEQ_MISC1 0x2a04 | ||
296 | #define MC_SEQ_RESERVE_M 0x2a08 | ||
297 | #define MC_PMG_CMD_EMRS 0x2a0c | ||
298 | |||
299 | #define MC_SEQ_MISC3 0x2a2c | ||
300 | |||
301 | #define MC_SEQ_MISC5 0x2a54 | ||
302 | #define MC_SEQ_MISC6 0x2a58 | ||
303 | |||
304 | #define MC_SEQ_MISC7 0x2a64 | ||
305 | |||
306 | #define MC_SEQ_CG 0x2a68 | ||
307 | #define CG_SEQ_REQ(x) ((x) << 0) | ||
308 | #define CG_SEQ_REQ_MASK (0xff << 0) | ||
309 | #define CG_SEQ_REQ_SHIFT 0 | ||
310 | #define CG_SEQ_RESP(x) ((x) << 8) | ||
311 | #define CG_SEQ_RESP_MASK (0xff << 8) | ||
312 | #define CG_SEQ_RESP_SHIFT 8 | ||
313 | #define SEQ_CG_REQ(x) ((x) << 16) | ||
314 | #define SEQ_CG_REQ_MASK (0xff << 16) | ||
315 | #define SEQ_CG_REQ_SHIFT 16 | ||
316 | #define SEQ_CG_RESP(x) ((x) << 24) | ||
317 | #define SEQ_CG_RESP_MASK (0xff << 24) | ||
318 | #define SEQ_CG_RESP_SHIFT 24 | ||
319 | #define MC_SEQ_RAS_TIMING_LP 0x2a6c | ||
320 | #define MC_SEQ_CAS_TIMING_LP 0x2a70 | ||
321 | #define MC_SEQ_MISC_TIMING_LP 0x2a74 | ||
322 | #define MC_SEQ_MISC_TIMING2_LP 0x2a78 | ||
323 | #define MC_SEQ_WR_CTL_D0_LP 0x2a7c | ||
324 | #define MC_SEQ_WR_CTL_D1_LP 0x2a80 | ||
325 | #define MC_SEQ_PMG_CMD_EMRS_LP 0x2a84 | ||
326 | #define MC_SEQ_PMG_CMD_MRS_LP 0x2a88 | ||
327 | |||
328 | #define MC_PMG_CMD_MRS 0x2aac | ||
329 | |||
330 | #define MC_SEQ_RD_CTL_D0_LP 0x2b1c | ||
331 | #define MC_SEQ_RD_CTL_D1_LP 0x2b20 | ||
332 | |||
333 | #define MC_PMG_CMD_MRS1 0x2b44 | ||
334 | #define MC_SEQ_PMG_CMD_MRS1_LP 0x2b48 | ||
335 | |||
336 | #define CGTS_SM_CTRL_REG 0x9150 | ||
337 | |||
51 | /* Registers */ | 338 | /* Registers */ |
52 | 339 | ||
53 | #define RCU_IND_INDEX 0x100 | 340 | #define RCU_IND_INDEX 0x100 |
@@ -522,6 +809,20 @@ | |||
522 | #define CG_THERMAL_CTRL 0x72c | 809 | #define CG_THERMAL_CTRL 0x72c |
523 | #define TOFFSET_MASK 0x00003FE0 | 810 | #define TOFFSET_MASK 0x00003FE0 |
524 | #define TOFFSET_SHIFT 5 | 811 | #define TOFFSET_SHIFT 5 |
812 | #define DIG_THERM_DPM(x) ((x) << 14) | ||
813 | #define DIG_THERM_DPM_MASK 0x003FC000 | ||
814 | #define DIG_THERM_DPM_SHIFT 14 | ||
815 | |||
816 | #define CG_THERMAL_INT 0x734 | ||
817 | #define DIG_THERM_INTH(x) ((x) << 8) | ||
818 | #define DIG_THERM_INTH_MASK 0x0000FF00 | ||
819 | #define DIG_THERM_INTH_SHIFT 8 | ||
820 | #define DIG_THERM_INTL(x) ((x) << 16) | ||
821 | #define DIG_THERM_INTL_MASK 0x00FF0000 | ||
822 | #define DIG_THERM_INTL_SHIFT 16 | ||
823 | #define THERM_INT_MASK_HIGH (1 << 24) | ||
824 | #define THERM_INT_MASK_LOW (1 << 25) | ||
825 | |||
525 | #define CG_MULT_THERMAL_STATUS 0x740 | 826 | #define CG_MULT_THERMAL_STATUS 0x740 |
526 | #define ASIC_T(x) ((x) << 16) | 827 | #define ASIC_T(x) ((x) << 16) |
527 | #define ASIC_T_MASK 0x07FF0000 | 828 | #define ASIC_T_MASK 0x07FF0000 |
@@ -529,6 +830,7 @@ | |||
529 | #define CG_TS0_STATUS 0x760 | 830 | #define CG_TS0_STATUS 0x760 |
530 | #define TS0_ADC_DOUT_MASK 0x000003FF | 831 | #define TS0_ADC_DOUT_MASK 0x000003FF |
531 | #define TS0_ADC_DOUT_SHIFT 0 | 832 | #define TS0_ADC_DOUT_SHIFT 0 |
833 | |||
532 | /* APU */ | 834 | /* APU */ |
533 | #define CG_THERMAL_STATUS 0x678 | 835 | #define CG_THERMAL_STATUS 0x678 |
534 | 836 | ||
@@ -1039,6 +1341,9 @@ | |||
1039 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) | 1341 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK (0x3 << 8) |
1040 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 | 1342 | # define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT 3 |
1041 | # define LC_CURRENT_DATA_RATE (1 << 11) | 1343 | # define LC_CURRENT_DATA_RATE (1 << 11) |
1344 | # define LC_HW_VOLTAGE_IF_CONTROL(x) ((x) << 12) | ||
1345 | # define LC_HW_VOLTAGE_IF_CONTROL_MASK (3 << 12) | ||
1346 | # define LC_HW_VOLTAGE_IF_CONTROL_SHIFT 12 | ||
1042 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) | 1347 | # define LC_VOLTAGE_TIMER_SEL_MASK (0xf << 14) |
1043 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) | 1348 | # define LC_CLR_FAILED_SPD_CHANGE_CNT (1 << 21) |
1044 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) | 1349 | # define LC_OTHER_SIDE_EVER_SENT_GEN2 (1 << 23) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a27d746386ae..2d3655f7f41e 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -70,15 +70,19 @@ MODULE_FIRMWARE("radeon/R700_rlc.bin"); | |||
70 | MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); | 70 | MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); |
71 | MODULE_FIRMWARE("radeon/CEDAR_me.bin"); | 71 | MODULE_FIRMWARE("radeon/CEDAR_me.bin"); |
72 | MODULE_FIRMWARE("radeon/CEDAR_rlc.bin"); | 72 | MODULE_FIRMWARE("radeon/CEDAR_rlc.bin"); |
73 | MODULE_FIRMWARE("radeon/CEDAR_smc.bin"); | ||
73 | MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin"); | 74 | MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin"); |
74 | MODULE_FIRMWARE("radeon/REDWOOD_me.bin"); | 75 | MODULE_FIRMWARE("radeon/REDWOOD_me.bin"); |
75 | MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin"); | 76 | MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin"); |
77 | MODULE_FIRMWARE("radeon/REDWOOD_smc.bin"); | ||
76 | MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin"); | 78 | MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin"); |
77 | MODULE_FIRMWARE("radeon/JUNIPER_me.bin"); | 79 | MODULE_FIRMWARE("radeon/JUNIPER_me.bin"); |
78 | MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); | 80 | MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); |
81 | MODULE_FIRMWARE("radeon/JUNIPER_smc.bin"); | ||
79 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); | 82 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); |
80 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); | 83 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); |
81 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); | 84 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); |
85 | MODULE_FIRMWARE("radeon/CYPRESS_smc.bin"); | ||
82 | MODULE_FIRMWARE("radeon/PALM_pfp.bin"); | 86 | MODULE_FIRMWARE("radeon/PALM_pfp.bin"); |
83 | MODULE_FIRMWARE("radeon/PALM_me.bin"); | 87 | MODULE_FIRMWARE("radeon/PALM_me.bin"); |
84 | MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); | 88 | MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); |
@@ -2214,19 +2218,27 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2214 | case CHIP_CEDAR: | 2218 | case CHIP_CEDAR: |
2215 | chip_name = "CEDAR"; | 2219 | chip_name = "CEDAR"; |
2216 | rlc_chip_name = "CEDAR"; | 2220 | rlc_chip_name = "CEDAR"; |
2221 | smc_chip_name = "CEDAR"; | ||
2222 | smc_req_size = ALIGN(CEDAR_SMC_UCODE_SIZE, 4); | ||
2217 | break; | 2223 | break; |
2218 | case CHIP_REDWOOD: | 2224 | case CHIP_REDWOOD: |
2219 | chip_name = "REDWOOD"; | 2225 | chip_name = "REDWOOD"; |
2220 | rlc_chip_name = "REDWOOD"; | 2226 | rlc_chip_name = "REDWOOD"; |
2227 | smc_chip_name = "REDWOOD"; | ||
2228 | smc_req_size = ALIGN(REDWOOD_SMC_UCODE_SIZE, 4); | ||
2221 | break; | 2229 | break; |
2222 | case CHIP_JUNIPER: | 2230 | case CHIP_JUNIPER: |
2223 | chip_name = "JUNIPER"; | 2231 | chip_name = "JUNIPER"; |
2224 | rlc_chip_name = "JUNIPER"; | 2232 | rlc_chip_name = "JUNIPER"; |
2233 | smc_chip_name = "JUNIPER"; | ||
2234 | smc_req_size = ALIGN(JUNIPER_SMC_UCODE_SIZE, 4); | ||
2225 | break; | 2235 | break; |
2226 | case CHIP_CYPRESS: | 2236 | case CHIP_CYPRESS: |
2227 | case CHIP_HEMLOCK: | 2237 | case CHIP_HEMLOCK: |
2228 | chip_name = "CYPRESS"; | 2238 | chip_name = "CYPRESS"; |
2229 | rlc_chip_name = "CYPRESS"; | 2239 | rlc_chip_name = "CYPRESS"; |
2240 | smc_chip_name = "CYPRESS"; | ||
2241 | smc_req_size = ALIGN(CYPRESS_SMC_UCODE_SIZE, 4); | ||
2230 | break; | 2242 | break; |
2231 | case CHIP_PALM: | 2243 | case CHIP_PALM: |
2232 | chip_name = "PALM"; | 2244 | chip_name = "PALM"; |
@@ -2293,7 +2305,7 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2293 | err = -EINVAL; | 2305 | err = -EINVAL; |
2294 | } | 2306 | } |
2295 | 2307 | ||
2296 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 2308 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) { |
2297 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); | 2309 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name); |
2298 | err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev); | 2310 | err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev); |
2299 | if (err) | 2311 | if (err) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 7221ff43fdc8..5d4731b66e7d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -2131,6 +2131,15 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); | |||
2131 | #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN)) | 2131 | #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN)) |
2132 | #define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE)) | 2132 | #define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE)) |
2133 | 2133 | ||
2134 | #define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \ | ||
2135 | (rdev->ddev->pdev->device == 0x6850) || \ | ||
2136 | (rdev->ddev->pdev->device == 0x6858) || \ | ||
2137 | (rdev->ddev->pdev->device == 0x6859) || \ | ||
2138 | (rdev->ddev->pdev->device == 0x6840) || \ | ||
2139 | (rdev->ddev->pdev->device == 0x6841) || \ | ||
2140 | (rdev->ddev->pdev->device == 0x6842) || \ | ||
2141 | (rdev->ddev->pdev->device == 0x6843)) | ||
2142 | |||
2134 | /* | 2143 | /* |
2135 | * BIOS helpers. | 2144 | * BIOS helpers. |
2136 | */ | 2145 | */ |
@@ -2358,6 +2367,10 @@ extern int ni_mc_load_microcode(struct radeon_device *rdev); | |||
2358 | #if defined(CONFIG_ACPI) | 2367 | #if defined(CONFIG_ACPI) |
2359 | extern int radeon_acpi_init(struct radeon_device *rdev); | 2368 | extern int radeon_acpi_init(struct radeon_device *rdev); |
2360 | extern void radeon_acpi_fini(struct radeon_device *rdev); | 2369 | extern void radeon_acpi_fini(struct radeon_device *rdev); |
2370 | extern bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev); | ||
2371 | extern int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, | ||
2372 | u8 ref_req, bool advertise); | ||
2373 | extern int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev); | ||
2361 | #else | 2374 | #else |
2362 | static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } | 2375 | static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } |
2363 | static inline void radeon_acpi_fini(struct radeon_device *rdev) { } | 2376 | static inline void radeon_acpi_fini(struct radeon_device *rdev) { } |
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 196d28d99570..87419a4c25ac 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
@@ -78,6 +78,29 @@ struct atcs_verify_interface { | |||
78 | u32 function_bits; /* supported functions bit vector */ | 78 | u32 function_bits; /* supported functions bit vector */ |
79 | } __packed; | 79 | } __packed; |
80 | 80 | ||
81 | bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev) | ||
82 | { | ||
83 | /* XXX: query ATIF */ | ||
84 | |||
85 | return false; | ||
86 | } | ||
87 | |||
88 | int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev) | ||
89 | { | ||
90 | /* XXX: call appropriate ATIF method */ | ||
91 | |||
92 | return -EINVAL; | ||
93 | |||
94 | } | ||
95 | |||
96 | int radeon_acpi_pcie_performance_request(struct radeon_device *rdev, | ||
97 | u8 ref_req, bool advertise) | ||
98 | { | ||
99 | /* XXX: call appropriate ATIF method */ | ||
100 | |||
101 | return -EINVAL; | ||
102 | } | ||
103 | |||
81 | /* Call the ATIF method | 104 | /* Call the ATIF method |
82 | */ | 105 | */ |
83 | /** | 106 | /** |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 2c18a796d351..4ca134bef689 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1494,6 +1494,18 @@ static struct radeon_asic evergreen_asic = { | |||
1494 | .set_uvd_clocks = &evergreen_set_uvd_clocks, | 1494 | .set_uvd_clocks = &evergreen_set_uvd_clocks, |
1495 | .get_temperature = &evergreen_get_temp, | 1495 | .get_temperature = &evergreen_get_temp, |
1496 | }, | 1496 | }, |
1497 | .dpm = { | ||
1498 | .init = &cypress_dpm_init, | ||
1499 | .setup_asic = &cypress_dpm_setup_asic, | ||
1500 | .enable = &cypress_dpm_enable, | ||
1501 | .disable = &cypress_dpm_disable, | ||
1502 | .set_power_state = &cypress_dpm_set_power_state, | ||
1503 | .display_configuration_changed = &cypress_dpm_display_configuration_changed, | ||
1504 | .fini = &cypress_dpm_fini, | ||
1505 | .get_sclk = &rv770_dpm_get_sclk, | ||
1506 | .get_mclk = &rv770_dpm_get_mclk, | ||
1507 | .print_power_state = &rv770_dpm_print_power_state, | ||
1508 | }, | ||
1497 | .pflip = { | 1509 | .pflip = { |
1498 | .pre_page_flip = &evergreen_pre_page_flip, | 1510 | .pre_page_flip = &evergreen_pre_page_flip, |
1499 | .page_flip = &evergreen_page_flip, | 1511 | .page_flip = &evergreen_page_flip, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index ad668a533848..c9a17e0a5f91 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -529,6 +529,13 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
529 | int evergreen_get_temp(struct radeon_device *rdev); | 529 | int evergreen_get_temp(struct radeon_device *rdev); |
530 | int sumo_get_temp(struct radeon_device *rdev); | 530 | int sumo_get_temp(struct radeon_device *rdev); |
531 | int tn_get_temp(struct radeon_device *rdev); | 531 | int tn_get_temp(struct radeon_device *rdev); |
532 | int cypress_dpm_init(struct radeon_device *rdev); | ||
533 | void cypress_dpm_setup_asic(struct radeon_device *rdev); | ||
534 | int cypress_dpm_enable(struct radeon_device *rdev); | ||
535 | void cypress_dpm_disable(struct radeon_device *rdev); | ||
536 | int cypress_dpm_set_power_state(struct radeon_device *rdev); | ||
537 | void cypress_dpm_display_configuration_changed(struct radeon_device *rdev); | ||
538 | void cypress_dpm_fini(struct radeon_device *rdev); | ||
532 | 539 | ||
533 | /* | 540 | /* |
534 | * cayman | 541 | * cayman |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 09eef285f27b..e1d07969f5f0 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -1041,6 +1041,11 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1041 | case CHIP_RV730: | 1041 | case CHIP_RV730: |
1042 | case CHIP_RV710: | 1042 | case CHIP_RV710: |
1043 | case CHIP_RV740: | 1043 | case CHIP_RV740: |
1044 | case CHIP_CEDAR: | ||
1045 | case CHIP_REDWOOD: | ||
1046 | case CHIP_JUNIPER: | ||
1047 | case CHIP_CYPRESS: | ||
1048 | case CHIP_HEMLOCK: | ||
1044 | if (radeon_dpm == 1) | 1049 | if (radeon_dpm == 1) |
1045 | rdev->pm.pm_method = PM_METHOD_DPM; | 1050 | rdev->pm.pm_method = PM_METHOD_DPM; |
1046 | else | 1051 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index 19105455330d..cb9c8135875d 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h | |||
@@ -65,4 +65,24 @@ | |||
65 | #define RV740_SMC_INT_VECTOR_START 0xffc0 | 65 | #define RV740_SMC_INT_VECTOR_START 0xffc0 |
66 | #define RV740_SMC_INT_VECTOR_SIZE 0x0040 | 66 | #define RV740_SMC_INT_VECTOR_SIZE 0x0040 |
67 | 67 | ||
68 | #define CEDAR_SMC_UCODE_START 0x0100 | ||
69 | #define CEDAR_SMC_UCODE_SIZE 0x5d50 | ||
70 | #define CEDAR_SMC_INT_VECTOR_START 0xffc0 | ||
71 | #define CEDAR_SMC_INT_VECTOR_SIZE 0x0040 | ||
72 | |||
73 | #define REDWOOD_SMC_UCODE_START 0x0100 | ||
74 | #define REDWOOD_SMC_UCODE_SIZE 0x5f0a | ||
75 | #define REDWOOD_SMC_INT_VECTOR_START 0xffc0 | ||
76 | #define REDWOOD_SMC_INT_VECTOR_SIZE 0x0040 | ||
77 | |||
78 | #define JUNIPER_SMC_UCODE_START 0x0100 | ||
79 | #define JUNIPER_SMC_UCODE_SIZE 0x5f1f | ||
80 | #define JUNIPER_SMC_INT_VECTOR_START 0xffc0 | ||
81 | #define JUNIPER_SMC_INT_VECTOR_SIZE 0x0040 | ||
82 | |||
83 | #define CYPRESS_SMC_UCODE_START 0x0100 | ||
84 | #define CYPRESS_SMC_UCODE_SIZE 0x61f7 | ||
85 | #define CYPRESS_SMC_INT_VECTOR_START 0xffc0 | ||
86 | #define CYPRESS_SMC_INT_VECTOR_SIZE 0x0040 | ||
87 | |||
68 | #endif | 88 | #endif |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 232b2fdf57eb..d15e7157a4bf 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "rv770d.h" | 27 | #include "rv770d.h" |
28 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
29 | #include "rv770_dpm.h" | 29 | #include "rv770_dpm.h" |
30 | #include "cypress_dpm.h" | ||
30 | #include "atom.h" | 31 | #include "atom.h" |
31 | 32 | ||
32 | #define MC_CG_ARB_FREQ_F0 0x0a | 33 | #define MC_CG_ARB_FREQ_F0 0x0a |
@@ -56,6 +57,13 @@ struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev) | |||
56 | return pi; | 57 | return pi; |
57 | } | 58 | } |
58 | 59 | ||
60 | struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev) | ||
61 | { | ||
62 | struct evergreen_power_info *pi = rdev->pm.dpm.priv; | ||
63 | |||
64 | return pi; | ||
65 | } | ||
66 | |||
59 | static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, | 67 | static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, |
60 | bool enable) | 68 | bool enable) |
61 | { | 69 | { |
@@ -1806,8 +1814,8 @@ void rv770_enable_auto_throttle_source(struct radeon_device *rdev, | |||
1806 | } | 1814 | } |
1807 | } | 1815 | } |
1808 | 1816 | ||
1809 | static int rv770_set_thermal_temperature_range(struct radeon_device *rdev, | 1817 | int rv770_set_thermal_temperature_range(struct radeon_device *rdev, |
1810 | int min_temp, int max_temp) | 1818 | int min_temp, int max_temp) |
1811 | { | 1819 | { |
1812 | int low_temp = 0 * 1000; | 1820 | int low_temp = 0 * 1000; |
1813 | int high_temp = 255 * 1000; | 1821 | int high_temp = 255 * 1000; |
@@ -2057,6 +2065,7 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2057 | union pplib_clock_info *clock_info) | 2065 | union pplib_clock_info *clock_info) |
2058 | { | 2066 | { |
2059 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 2067 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
2068 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
2060 | struct rv7xx_ps *ps = rv770_get_ps(rps); | 2069 | struct rv7xx_ps *ps = rv770_get_ps(rps); |
2061 | u32 sclk, mclk; | 2070 | u32 sclk, mclk; |
2062 | u16 vddc; | 2071 | u16 vddc; |
@@ -2075,13 +2084,24 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2075 | break; | 2084 | break; |
2076 | } | 2085 | } |
2077 | 2086 | ||
2078 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); | 2087 | if (rdev->family >= CHIP_CEDAR) { |
2079 | sclk |= clock_info->r600.ucEngineClockHigh << 16; | 2088 | sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); |
2080 | mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); | 2089 | sclk |= clock_info->evergreen.ucEngineClockHigh << 16; |
2081 | mclk |= clock_info->r600.ucMemoryClockHigh << 16; | 2090 | mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow); |
2091 | mclk |= clock_info->evergreen.ucMemoryClockHigh << 16; | ||
2092 | |||
2093 | pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC); | ||
2094 | pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI); | ||
2095 | pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags); | ||
2096 | } else { | ||
2097 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); | ||
2098 | sclk |= clock_info->r600.ucEngineClockHigh << 16; | ||
2099 | mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); | ||
2100 | mclk |= clock_info->r600.ucMemoryClockHigh << 16; | ||
2082 | 2101 | ||
2083 | pl->vddc = le16_to_cpu(clock_info->r600.usVDDC); | 2102 | pl->vddc = le16_to_cpu(clock_info->r600.usVDDC); |
2084 | pl->flags = le32_to_cpu(clock_info->r600.ulFlags); | 2103 | pl->flags = le32_to_cpu(clock_info->r600.ulFlags); |
2104 | } | ||
2085 | 2105 | ||
2086 | pl->mclk = mclk; | 2106 | pl->mclk = mclk; |
2087 | pl->sclk = sclk; | 2107 | pl->sclk = sclk; |
@@ -2094,12 +2114,21 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2094 | 2114 | ||
2095 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { | 2115 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { |
2096 | pi->acpi_vddc = pl->vddc; | 2116 | pi->acpi_vddc = pl->vddc; |
2117 | if (rdev->family >= CHIP_CEDAR) | ||
2118 | eg_pi->acpi_vddci = pl->vddci; | ||
2097 | if (ps->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) | 2119 | if (ps->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) |
2098 | pi->acpi_pcie_gen2 = true; | 2120 | pi->acpi_pcie_gen2 = true; |
2099 | else | 2121 | else |
2100 | pi->acpi_pcie_gen2 = false; | 2122 | pi->acpi_pcie_gen2 = false; |
2101 | } | 2123 | } |
2102 | 2124 | ||
2125 | if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) { | ||
2126 | if (rdev->family >= CHIP_BARTS) { | ||
2127 | eg_pi->ulv.supported = true; | ||
2128 | eg_pi->ulv.pl = pl; | ||
2129 | } | ||
2130 | } | ||
2131 | |||
2103 | if (pi->min_vddc_in_table > pl->vddc) | 2132 | if (pi->min_vddc_in_table > pl->vddc) |
2104 | pi->min_vddc_in_table = pl->vddc; | 2133 | pi->min_vddc_in_table = pl->vddc; |
2105 | 2134 | ||
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h index 0f33f9bb244f..8cd878397f54 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.h +++ b/drivers/gpu/drm/radeon/rv770_dpm.h | |||
@@ -270,4 +270,8 @@ int rv770_read_smc_soft_register(struct radeon_device *rdev, | |||
270 | int rv770_write_smc_soft_register(struct radeon_device *rdev, | 270 | int rv770_write_smc_soft_register(struct radeon_device *rdev, |
271 | u16 reg_offset, u32 value); | 271 | u16 reg_offset, u32 value); |
272 | 272 | ||
273 | /* thermal */ | ||
274 | int rv770_set_thermal_temperature_range(struct radeon_device *rdev, | ||
275 | int min_temp, int max_temp); | ||
276 | |||
273 | #endif | 277 | #endif |
diff --git a/drivers/gpu/drm/radeon/rv770_smc.c b/drivers/gpu/drm/radeon/rv770_smc.c index 8e071530fe9d..168aedbffa7e 100644 --- a/drivers/gpu/drm/radeon/rv770_smc.c +++ b/drivers/gpu/drm/radeon/rv770_smc.c | |||
@@ -114,6 +114,86 @@ static const u8 rv740_smc_int_vectors[] = | |||
114 | 0x03, 0x51, 0x03, 0x51 | 114 | 0x03, 0x51, 0x03, 0x51 |
115 | }; | 115 | }; |
116 | 116 | ||
117 | static const u8 cedar_smc_int_vectors[] = | ||
118 | { | ||
119 | 0x0B, 0x05, 0x0B, 0x05, | ||
120 | 0x0B, 0x05, 0x0B, 0x05, | ||
121 | 0x0B, 0x05, 0x0B, 0x05, | ||
122 | 0x0B, 0x05, 0x0B, 0x05, | ||
123 | 0x0B, 0x05, 0x0B, 0x05, | ||
124 | 0x0B, 0x05, 0x0B, 0x05, | ||
125 | 0x0B, 0x05, 0x0B, 0x05, | ||
126 | 0x0B, 0x05, 0x0B, 0x05, | ||
127 | 0x0B, 0x05, 0x0B, 0x05, | ||
128 | 0x0B, 0x05, 0x0B, 0x05, | ||
129 | 0x0B, 0x05, 0x0B, 0x05, | ||
130 | 0x0B, 0x05, 0x0B, 0x05, | ||
131 | 0x0B, 0x05, 0x11, 0x8B, | ||
132 | 0x0B, 0x20, 0x0B, 0x05, | ||
133 | 0x04, 0xF6, 0x04, 0xF6, | ||
134 | 0x04, 0xF6, 0x04, 0xF6 | ||
135 | }; | ||
136 | |||
137 | static const u8 redwood_smc_int_vectors[] = | ||
138 | { | ||
139 | 0x0B, 0x05, 0x0B, 0x05, | ||
140 | 0x0B, 0x05, 0x0B, 0x05, | ||
141 | 0x0B, 0x05, 0x0B, 0x05, | ||
142 | 0x0B, 0x05, 0x0B, 0x05, | ||
143 | 0x0B, 0x05, 0x0B, 0x05, | ||
144 | 0x0B, 0x05, 0x0B, 0x05, | ||
145 | 0x0B, 0x05, 0x0B, 0x05, | ||
146 | 0x0B, 0x05, 0x0B, 0x05, | ||
147 | 0x0B, 0x05, 0x0B, 0x05, | ||
148 | 0x0B, 0x05, 0x0B, 0x05, | ||
149 | 0x0B, 0x05, 0x0B, 0x05, | ||
150 | 0x0B, 0x05, 0x0B, 0x05, | ||
151 | 0x0B, 0x05, 0x11, 0x8B, | ||
152 | 0x0B, 0x20, 0x0B, 0x05, | ||
153 | 0x04, 0xF6, 0x04, 0xF6, | ||
154 | 0x04, 0xF6, 0x04, 0xF6 | ||
155 | }; | ||
156 | |||
157 | static const u8 juniper_smc_int_vectors[] = | ||
158 | { | ||
159 | 0x0B, 0x05, 0x0B, 0x05, | ||
160 | 0x0B, 0x05, 0x0B, 0x05, | ||
161 | 0x0B, 0x05, 0x0B, 0x05, | ||
162 | 0x0B, 0x05, 0x0B, 0x05, | ||
163 | 0x0B, 0x05, 0x0B, 0x05, | ||
164 | 0x0B, 0x05, 0x0B, 0x05, | ||
165 | 0x0B, 0x05, 0x0B, 0x05, | ||
166 | 0x0B, 0x05, 0x0B, 0x05, | ||
167 | 0x0B, 0x05, 0x0B, 0x05, | ||
168 | 0x0B, 0x05, 0x0B, 0x05, | ||
169 | 0x0B, 0x05, 0x0B, 0x05, | ||
170 | 0x0B, 0x05, 0x0B, 0x05, | ||
171 | 0x0B, 0x05, 0x11, 0x8B, | ||
172 | 0x0B, 0x20, 0x0B, 0x05, | ||
173 | 0x04, 0xF6, 0x04, 0xF6, | ||
174 | 0x04, 0xF6, 0x04, 0xF6 | ||
175 | }; | ||
176 | |||
177 | static const u8 cypress_smc_int_vectors[] = | ||
178 | { | ||
179 | 0x0B, 0x05, 0x0B, 0x05, | ||
180 | 0x0B, 0x05, 0x0B, 0x05, | ||
181 | 0x0B, 0x05, 0x0B, 0x05, | ||
182 | 0x0B, 0x05, 0x0B, 0x05, | ||
183 | 0x0B, 0x05, 0x0B, 0x05, | ||
184 | 0x0B, 0x05, 0x0B, 0x05, | ||
185 | 0x0B, 0x05, 0x0B, 0x05, | ||
186 | 0x0B, 0x05, 0x0B, 0x05, | ||
187 | 0x0B, 0x05, 0x0B, 0x05, | ||
188 | 0x0B, 0x05, 0x0B, 0x05, | ||
189 | 0x0B, 0x05, 0x0B, 0x05, | ||
190 | 0x0B, 0x05, 0x0B, 0x05, | ||
191 | 0x0B, 0x05, 0x11, 0x8B, | ||
192 | 0x0B, 0x20, 0x0B, 0x05, | ||
193 | 0x04, 0xF6, 0x04, 0xF6, | ||
194 | 0x04, 0xF6, 0x04, 0xF6 | ||
195 | }; | ||
196 | |||
117 | int rv770_set_smc_sram_address(struct radeon_device *rdev, | 197 | int rv770_set_smc_sram_address(struct radeon_device *rdev, |
118 | u16 smc_address, u16 limit) | 198 | u16 smc_address, u16 limit) |
119 | { | 199 | { |
@@ -354,6 +434,35 @@ int rv770_load_smc_ucode(struct radeon_device *rdev, | |||
354 | int_vect_start_address = RV740_SMC_INT_VECTOR_START; | 434 | int_vect_start_address = RV740_SMC_INT_VECTOR_START; |
355 | int_vect_size = RV740_SMC_INT_VECTOR_SIZE; | 435 | int_vect_size = RV740_SMC_INT_VECTOR_SIZE; |
356 | break; | 436 | break; |
437 | case CHIP_CEDAR: | ||
438 | ucode_start_address = CEDAR_SMC_UCODE_START; | ||
439 | ucode_size = CEDAR_SMC_UCODE_SIZE; | ||
440 | int_vect = (const u8 *)&cedar_smc_int_vectors; | ||
441 | int_vect_start_address = CEDAR_SMC_INT_VECTOR_START; | ||
442 | int_vect_size = CEDAR_SMC_INT_VECTOR_SIZE; | ||
443 | break; | ||
444 | case CHIP_REDWOOD: | ||
445 | ucode_start_address = REDWOOD_SMC_UCODE_START; | ||
446 | ucode_size = REDWOOD_SMC_UCODE_SIZE; | ||
447 | int_vect = (const u8 *)&redwood_smc_int_vectors; | ||
448 | int_vect_start_address = REDWOOD_SMC_INT_VECTOR_START; | ||
449 | int_vect_size = REDWOOD_SMC_INT_VECTOR_SIZE; | ||
450 | break; | ||
451 | case CHIP_JUNIPER: | ||
452 | ucode_start_address = JUNIPER_SMC_UCODE_START; | ||
453 | ucode_size = JUNIPER_SMC_UCODE_SIZE; | ||
454 | int_vect = (const u8 *)&juniper_smc_int_vectors; | ||
455 | int_vect_start_address = JUNIPER_SMC_INT_VECTOR_START; | ||
456 | int_vect_size = JUNIPER_SMC_INT_VECTOR_SIZE; | ||
457 | break; | ||
458 | case CHIP_CYPRESS: | ||
459 | case CHIP_HEMLOCK: | ||
460 | ucode_start_address = CYPRESS_SMC_UCODE_START; | ||
461 | ucode_size = CYPRESS_SMC_UCODE_SIZE; | ||
462 | int_vect = (const u8 *)&cypress_smc_int_vectors; | ||
463 | int_vect_start_address = CYPRESS_SMC_INT_VECTOR_START; | ||
464 | int_vect_size = CYPRESS_SMC_INT_VECTOR_SIZE; | ||
465 | break; | ||
357 | default: | 466 | default: |
358 | DRM_ERROR("unknown asic in smc ucode loader\n"); | 467 | DRM_ERROR("unknown asic in smc ucode loader\n"); |
359 | BUG(); | 468 | BUG(); |