aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-06-26 00:33:35 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-06-27 19:15:22 -0400
commitdc50ba7f9a6d9a920409892c7f30bce266067345 (patch)
tree17e9dc618117ceacf39c2f2e29907792cdedc598 /drivers
parent66229b200598a3b66b839d1759ff3f5b17ac5639 (diff)
drm/radeon/kms: add dpm support for evergreen (v4)
This adds dpm support for evergreen asics. This includes: - clockgating - dynamic engine clock scaling - dynamic memory clock scaling - dynamic voltage scaling - dynamic pcie gen1/gen2 switching (requires additional acpi support) Set radeon.dpm=1 to enable. v2: reduce stack usage, rename ulv struct v3: fix thermal interrupt check notices by Jerome v4: fix state enable Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.c2105
-rw-r--r--drivers/gpu/drm/radeon/cypress_dpm.h134
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c22
-rw-r--r--drivers/gpu/drm/radeon/evergreen_smc.h67
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h305
-rw-r--r--drivers/gpu/drm/radeon/r600.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon.h13
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_ucode.h20
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.c45
-rw-r--r--drivers/gpu/drm/radeon/rv770_dpm.h4
-rw-r--r--drivers/gpu/drm/radeon/rv770_smc.c109
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
83radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 83radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
84radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 84radeon-$(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
44struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
45struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
46struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
47
48static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
49 u32 memory_clock, bool strobe_mode);
50
51static 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
88static 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
100static 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
121static 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
173static 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
222void 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
241void cypress_start_dpm(struct radeon_device *rdev)
242{
243 WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
244}
245
246void 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
255void 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
264int 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
276void 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
302static 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
328void 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
350static 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
359void 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
379void 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
399static 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
419static 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
437static 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
469static 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, &dividers);
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
606static 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
647static 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
671int 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
757static 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
808static 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
822static 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
844static 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
861int 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
879int 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
898u32 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
919void 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
942static 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
961static 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
1025static 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
1037static 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
1065static 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
1083static 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
1111static 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
1160static 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
1172static 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
1218static 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
1229int 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
1325int 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
1462static 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
1478int 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
1506static 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
1518int 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
1556static 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
1565int 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
1606static 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
1658int 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
1686int 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
1723void 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
1737static 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
1778void 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
1798int 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
1893void 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
1932int 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
1960void 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
1966void cypress_dpm_display_configuration_changed(struct radeon_device *rdev)
1967{
1968 cypress_program_display_gap(rdev);
1969}
1970
1971int 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, &dividers);
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
2096void 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
29struct evergreen_mc_reg_entry {
30 u32 mclk_max;
31 u32 mc_data[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE];
32};
33
34struct 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
42struct evergreen_ulv_param {
43 bool supported;
44 struct rv7xx_pl *pl;
45};
46
47struct 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
54struct 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
99int 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);
103int cypress_populate_smc_acpi_state(struct radeon_device *rdev,
104 RV770_SMC_STATETABLE *table);
105int cypress_populate_smc_voltage_tables(struct radeon_device *rdev,
106 RV770_SMC_STATETABLE *table);
107int cypress_populate_smc_initial_state(struct radeon_device *rdev,
108 struct radeon_ps *radeon_initial_state,
109 RV770_SMC_STATETABLE *table);
110u32 cypress_calculate_burst_time(struct radeon_device *rdev,
111 u32 engine_clock, u32 memory_clock);
112void cypress_notify_link_speed_change_before_state_change(struct radeon_device *rdev);
113int cypress_upload_sw_state(struct radeon_device *rdev);
114int cypress_upload_mc_reg_table(struct radeon_device *rdev);
115void cypress_program_memory_timing_parameters(struct radeon_device *rdev);
116void cypress_notify_link_speed_change_after_state_change(struct radeon_device *rdev);
117int cypress_construct_voltage_tables(struct radeon_device *rdev);
118int cypress_get_mvdd_configuration(struct radeon_device *rdev);
119void cypress_enable_spread_spectrum(struct radeon_device *rdev,
120 bool enable);
121void cypress_enable_display_gap(struct radeon_device *rdev);
122int cypress_get_table_locations(struct radeon_device *rdev);
123int cypress_populate_mc_reg_table(struct radeon_device *rdev);
124void cypress_program_response_times(struct radeon_device *rdev);
125int cypress_notify_smc_display_change(struct radeon_device *rdev,
126 bool has_display);
127void cypress_enable_sclk_control(struct radeon_device *rdev,
128 bool enable);
129void cypress_enable_mclk_control(struct radeon_device *rdev,
130 bool enable);
131void cypress_start_dpm(struct radeon_device *rdev);
132void 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
32struct SMC_Evergreen_MCRegisterAddress
33{
34 uint16_t s0;
35 uint16_t s1;
36};
37
38typedef struct SMC_Evergreen_MCRegisterAddress SMC_Evergreen_MCRegisterAddress;
39
40
41struct SMC_Evergreen_MCRegisterSet
42{
43 uint32_t value[SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE];
44};
45
46typedef struct SMC_Evergreen_MCRegisterSet SMC_Evergreen_MCRegisterSet;
47
48struct 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
56typedef 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");
70MODULE_FIRMWARE("radeon/CEDAR_pfp.bin"); 70MODULE_FIRMWARE("radeon/CEDAR_pfp.bin");
71MODULE_FIRMWARE("radeon/CEDAR_me.bin"); 71MODULE_FIRMWARE("radeon/CEDAR_me.bin");
72MODULE_FIRMWARE("radeon/CEDAR_rlc.bin"); 72MODULE_FIRMWARE("radeon/CEDAR_rlc.bin");
73MODULE_FIRMWARE("radeon/CEDAR_smc.bin");
73MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin"); 74MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin");
74MODULE_FIRMWARE("radeon/REDWOOD_me.bin"); 75MODULE_FIRMWARE("radeon/REDWOOD_me.bin");
75MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin"); 76MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin");
77MODULE_FIRMWARE("radeon/REDWOOD_smc.bin");
76MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin"); 78MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin");
77MODULE_FIRMWARE("radeon/JUNIPER_me.bin"); 79MODULE_FIRMWARE("radeon/JUNIPER_me.bin");
78MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); 80MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin");
81MODULE_FIRMWARE("radeon/JUNIPER_smc.bin");
79MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); 82MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin");
80MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); 83MODULE_FIRMWARE("radeon/CYPRESS_me.bin");
81MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); 84MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin");
85MODULE_FIRMWARE("radeon/CYPRESS_smc.bin");
82MODULE_FIRMWARE("radeon/PALM_pfp.bin"); 86MODULE_FIRMWARE("radeon/PALM_pfp.bin");
83MODULE_FIRMWARE("radeon/PALM_me.bin"); 87MODULE_FIRMWARE("radeon/PALM_me.bin");
84MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); 88MODULE_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)
2359extern int radeon_acpi_init(struct radeon_device *rdev); 2368extern int radeon_acpi_init(struct radeon_device *rdev);
2360extern void radeon_acpi_fini(struct radeon_device *rdev); 2369extern void radeon_acpi_fini(struct radeon_device *rdev);
2370extern bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev);
2371extern int radeon_acpi_pcie_performance_request(struct radeon_device *rdev,
2372 u8 ref_req, bool advertise);
2373extern int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev);
2361#else 2374#else
2362static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; } 2375static inline int radeon_acpi_init(struct radeon_device *rdev) { return 0; }
2363static inline void radeon_acpi_fini(struct radeon_device *rdev) { } 2376static 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
81bool radeon_acpi_is_pcie_performance_request_supported(struct radeon_device *rdev)
82{
83 /* XXX: query ATIF */
84
85 return false;
86}
87
88int radeon_acpi_pcie_notify_device_ready(struct radeon_device *rdev)
89{
90 /* XXX: call appropriate ATIF method */
91
92 return -EINVAL;
93
94}
95
96int 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
529int evergreen_get_temp(struct radeon_device *rdev); 529int evergreen_get_temp(struct radeon_device *rdev);
530int sumo_get_temp(struct radeon_device *rdev); 530int sumo_get_temp(struct radeon_device *rdev);
531int tn_get_temp(struct radeon_device *rdev); 531int tn_get_temp(struct radeon_device *rdev);
532int cypress_dpm_init(struct radeon_device *rdev);
533void cypress_dpm_setup_asic(struct radeon_device *rdev);
534int cypress_dpm_enable(struct radeon_device *rdev);
535void cypress_dpm_disable(struct radeon_device *rdev);
536int cypress_dpm_set_power_state(struct radeon_device *rdev);
537void cypress_dpm_display_configuration_changed(struct radeon_device *rdev);
538void 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
60struct 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
59static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev, 67static 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
1809static int rv770_set_thermal_temperature_range(struct radeon_device *rdev, 1817int 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,
270int rv770_write_smc_soft_register(struct radeon_device *rdev, 270int 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 */
274int 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
117static 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
137static 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
157static 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
177static 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
117int rv770_set_smc_sram_address(struct radeon_device *rdev, 197int 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();