2 * Copyright 2014 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
24 #include <linux/firmware.h>
25 #include <linux/seq_file.h>
28 #include "amdgpu_pm.h"
29 #include "amdgpu_atombios.h"
32 #include "amdgpu_dpm.h"
37 #include "smu/smu_8_0_d.h"
38 #include "smu/smu_8_0_sh_mask.h"
39 #include "gca/gfx_8_0_d.h"
40 #include "gca/gfx_8_0_sh_mask.h"
41 #include "gmc/gmc_8_1_d.h"
42 #include "bif/bif_5_1_d.h"
45 static void cz_dpm_powergate_uvd(struct amdgpu_device
*adev
, bool gate
);
46 static void cz_dpm_powergate_vce(struct amdgpu_device
*adev
, bool gate
);
48 static struct cz_ps
*cz_get_ps(struct amdgpu_ps
*rps
)
50 struct cz_ps
*ps
= rps
->ps_priv
;
55 static struct cz_power_info
*cz_get_pi(struct amdgpu_device
*adev
)
57 struct cz_power_info
*pi
= adev
->pm
.dpm
.priv
;
62 static uint16_t cz_convert_8bit_index_to_voltage(struct amdgpu_device
*adev
,
65 uint16_t tmp
= 6200 - voltage
* 25;
70 static void cz_construct_max_power_limits_table(struct amdgpu_device
*adev
,
71 struct amdgpu_clock_and_voltage_limits
*table
)
73 struct cz_power_info
*pi
= cz_get_pi(adev
);
74 struct amdgpu_clock_voltage_dependency_table
*dep_table
=
75 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
77 if (dep_table
->count
> 0) {
78 table
->sclk
= dep_table
->entries
[dep_table
->count
- 1].clk
;
79 table
->vddc
= cz_convert_8bit_index_to_voltage(adev
,
80 dep_table
->entries
[dep_table
->count
- 1].v
);
83 table
->mclk
= pi
->sys_info
.nbp_memory_clock
[0];
88 struct _ATOM_INTEGRATED_SYSTEM_INFO info
;
89 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7
;
90 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8
;
91 struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_9 info_9
;
94 static int cz_parse_sys_info_table(struct amdgpu_device
*adev
)
96 struct cz_power_info
*pi
= cz_get_pi(adev
);
97 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
98 int index
= GetIndexIntoMasterTable(DATA
, IntegratedSystemInfo
);
99 union igp_info
*igp_info
;
104 if (amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, NULL
,
105 &frev
, &crev
, &data_offset
)) {
106 igp_info
= (union igp_info
*)(mode_info
->atom_context
->bios
+
110 DRM_ERROR("Unsupported IGP table: %d %d\n", frev
, crev
);
113 pi
->sys_info
.bootup_sclk
=
114 le32_to_cpu(igp_info
->info_9
.ulBootUpEngineClock
);
115 pi
->sys_info
.bootup_uma_clk
=
116 le32_to_cpu(igp_info
->info_9
.ulBootUpUMAClock
);
117 pi
->sys_info
.dentist_vco_freq
=
118 le32_to_cpu(igp_info
->info_9
.ulDentistVCOFreq
);
119 pi
->sys_info
.bootup_nb_voltage_index
=
120 le16_to_cpu(igp_info
->info_9
.usBootUpNBVoltage
);
122 if (igp_info
->info_9
.ucHtcTmpLmt
== 0)
123 pi
->sys_info
.htc_tmp_lmt
= 203;
125 pi
->sys_info
.htc_tmp_lmt
= igp_info
->info_9
.ucHtcTmpLmt
;
127 if (igp_info
->info_9
.ucHtcHystLmt
== 0)
128 pi
->sys_info
.htc_hyst_lmt
= 5;
130 pi
->sys_info
.htc_hyst_lmt
= igp_info
->info_9
.ucHtcHystLmt
;
132 if (pi
->sys_info
.htc_tmp_lmt
<= pi
->sys_info
.htc_hyst_lmt
) {
133 DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
137 if (le32_to_cpu(igp_info
->info_9
.ulSystemConfig
) & (1 << 3) &&
138 pi
->enable_nb_ps_policy
)
139 pi
->sys_info
.nb_dpm_enable
= true;
141 pi
->sys_info
.nb_dpm_enable
= false;
143 for (i
= 0; i
< CZ_NUM_NBPSTATES
; i
++) {
144 if (i
< CZ_NUM_NBPMEMORY_CLOCK
)
145 pi
->sys_info
.nbp_memory_clock
[i
] =
146 le32_to_cpu(igp_info
->info_9
.ulNbpStateMemclkFreq
[i
]);
147 pi
->sys_info
.nbp_n_clock
[i
] =
148 le32_to_cpu(igp_info
->info_9
.ulNbpStateNClkFreq
[i
]);
151 for (i
= 0; i
< CZ_MAX_DISPLAY_CLOCK_LEVEL
; i
++)
152 pi
->sys_info
.display_clock
[i
] =
153 le32_to_cpu(igp_info
->info_9
.sDispClkVoltageMapping
[i
].ulMaximumSupportedCLK
);
155 for (i
= 0; i
< CZ_NUM_NBPSTATES
; i
++)
156 pi
->sys_info
.nbp_voltage_index
[i
] =
157 le32_to_cpu(igp_info
->info_9
.usNBPStateVoltage
[i
]);
159 if (le32_to_cpu(igp_info
->info_9
.ulGPUCapInfo
) &
160 SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS
)
161 pi
->caps_enable_dfs_bypass
= true;
163 pi
->sys_info
.uma_channel_number
=
164 igp_info
->info_9
.ucUMAChannelNumber
;
166 cz_construct_max_power_limits_table(adev
,
167 &adev
->pm
.dpm
.dyn_state
.max_clock_voltage_on_ac
);
173 static void cz_patch_voltage_values(struct amdgpu_device
*adev
)
176 struct amdgpu_uvd_clock_voltage_dependency_table
*uvd_table
=
177 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
178 struct amdgpu_vce_clock_voltage_dependency_table
*vce_table
=
179 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
180 struct amdgpu_clock_voltage_dependency_table
*acp_table
=
181 &adev
->pm
.dpm
.dyn_state
.acp_clock_voltage_dependency_table
;
183 if (uvd_table
->count
) {
184 for (i
= 0; i
< uvd_table
->count
; i
++)
185 uvd_table
->entries
[i
].v
=
186 cz_convert_8bit_index_to_voltage(adev
,
187 uvd_table
->entries
[i
].v
);
190 if (vce_table
->count
) {
191 for (i
= 0; i
< vce_table
->count
; i
++)
192 vce_table
->entries
[i
].v
=
193 cz_convert_8bit_index_to_voltage(adev
,
194 vce_table
->entries
[i
].v
);
197 if (acp_table
->count
) {
198 for (i
= 0; i
< acp_table
->count
; i
++)
199 acp_table
->entries
[i
].v
=
200 cz_convert_8bit_index_to_voltage(adev
,
201 acp_table
->entries
[i
].v
);
206 static void cz_construct_boot_state(struct amdgpu_device
*adev
)
208 struct cz_power_info
*pi
= cz_get_pi(adev
);
210 pi
->boot_pl
.sclk
= pi
->sys_info
.bootup_sclk
;
211 pi
->boot_pl
.vddc_index
= pi
->sys_info
.bootup_nb_voltage_index
;
212 pi
->boot_pl
.ds_divider_index
= 0;
213 pi
->boot_pl
.ss_divider_index
= 0;
214 pi
->boot_pl
.allow_gnb_slow
= 1;
215 pi
->boot_pl
.force_nbp_state
= 0;
216 pi
->boot_pl
.display_wm
= 0;
217 pi
->boot_pl
.vce_wm
= 0;
221 static void cz_patch_boot_state(struct amdgpu_device
*adev
,
224 struct cz_power_info
*pi
= cz_get_pi(adev
);
227 ps
->levels
[0] = pi
->boot_pl
;
230 union pplib_clock_info
{
231 struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen
;
232 struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo
;
233 struct _ATOM_PPLIB_CZ_CLOCK_INFO carrizo
;
236 static void cz_parse_pplib_clock_info(struct amdgpu_device
*adev
,
237 struct amdgpu_ps
*rps
, int index
,
238 union pplib_clock_info
*clock_info
)
240 struct cz_power_info
*pi
= cz_get_pi(adev
);
241 struct cz_ps
*ps
= cz_get_ps(rps
);
242 struct cz_pl
*pl
= &ps
->levels
[index
];
243 struct amdgpu_clock_voltage_dependency_table
*table
=
244 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
246 pl
->sclk
= table
->entries
[clock_info
->carrizo
.index
].clk
;
247 pl
->vddc_index
= table
->entries
[clock_info
->carrizo
.index
].v
;
249 ps
->num_levels
= index
+ 1;
251 if (pi
->caps_sclk_ds
) {
252 pl
->ds_divider_index
= 5;
253 pl
->ss_divider_index
= 5;
258 static void cz_parse_pplib_non_clock_info(struct amdgpu_device
*adev
,
259 struct amdgpu_ps
*rps
,
260 struct _ATOM_PPLIB_NONCLOCK_INFO
*non_clock_info
,
263 struct cz_ps
*ps
= cz_get_ps(rps
);
265 rps
->caps
= le32_to_cpu(non_clock_info
->ulCapsAndSettings
);
266 rps
->class = le16_to_cpu(non_clock_info
->usClassification
);
267 rps
->class2
= le16_to_cpu(non_clock_info
->usClassification2
);
269 if (ATOM_PPLIB_NONCLOCKINFO_VER1
< table_rev
) {
270 rps
->vclk
= le32_to_cpu(non_clock_info
->ulVCLK
);
271 rps
->dclk
= le32_to_cpu(non_clock_info
->ulDCLK
);
277 if (rps
->class & ATOM_PPLIB_CLASSIFICATION_BOOT
) {
278 adev
->pm
.dpm
.boot_ps
= rps
;
279 cz_patch_boot_state(adev
, ps
);
281 if (rps
->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE
)
282 adev
->pm
.dpm
.uvd_ps
= rps
;
287 struct _ATOM_PPLIB_POWERPLAYTABLE pplib
;
288 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2
;
289 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3
;
290 struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4
;
291 struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5
;
294 union pplib_power_state
{
295 struct _ATOM_PPLIB_STATE v1
;
296 struct _ATOM_PPLIB_STATE_V2 v2
;
299 static int cz_parse_power_table(struct amdgpu_device
*adev
)
301 struct amdgpu_mode_info
*mode_info
= &adev
->mode_info
;
302 struct _ATOM_PPLIB_NONCLOCK_INFO
*non_clock_info
;
303 union pplib_power_state
*power_state
;
304 int i
, j
, k
, non_clock_array_index
, clock_array_index
;
305 union pplib_clock_info
*clock_info
;
306 struct _StateArray
*state_array
;
307 struct _ClockInfoArray
*clock_info_array
;
308 struct _NonClockInfoArray
*non_clock_info_array
;
309 union power_info
*power_info
;
310 int index
= GetIndexIntoMasterTable(DATA
, PowerPlayInfo
);
313 u8
*power_state_offset
;
316 if (!amdgpu_atom_parse_data_header(mode_info
->atom_context
, index
, NULL
,
317 &frev
, &crev
, &data_offset
))
319 power_info
= (union power_info
*)(mode_info
->atom_context
->bios
+ data_offset
);
321 state_array
= (struct _StateArray
*)
322 (mode_info
->atom_context
->bios
+ data_offset
+
323 le16_to_cpu(power_info
->pplib
.usStateArrayOffset
));
324 clock_info_array
= (struct _ClockInfoArray
*)
325 (mode_info
->atom_context
->bios
+ data_offset
+
326 le16_to_cpu(power_info
->pplib
.usClockInfoArrayOffset
));
327 non_clock_info_array
= (struct _NonClockInfoArray
*)
328 (mode_info
->atom_context
->bios
+ data_offset
+
329 le16_to_cpu(power_info
->pplib
.usNonClockInfoArrayOffset
));
331 adev
->pm
.dpm
.ps
= kzalloc(sizeof(struct amdgpu_ps
) *
332 state_array
->ucNumEntries
, GFP_KERNEL
);
334 if (!adev
->pm
.dpm
.ps
)
337 power_state_offset
= (u8
*)state_array
->states
;
338 adev
->pm
.dpm
.platform_caps
=
339 le32_to_cpu(power_info
->pplib
.ulPlatformCaps
);
340 adev
->pm
.dpm
.backbias_response_time
=
341 le16_to_cpu(power_info
->pplib
.usBackbiasTime
);
342 adev
->pm
.dpm
.voltage_response_time
=
343 le16_to_cpu(power_info
->pplib
.usVoltageTime
);
345 for (i
= 0; i
< state_array
->ucNumEntries
; i
++) {
346 power_state
= (union pplib_power_state
*)power_state_offset
;
347 non_clock_array_index
= power_state
->v2
.nonClockInfoIndex
;
348 non_clock_info
= (struct _ATOM_PPLIB_NONCLOCK_INFO
*)
349 &non_clock_info_array
->nonClockInfo
[non_clock_array_index
];
351 ps
= kzalloc(sizeof(struct cz_ps
), GFP_KERNEL
);
353 kfree(adev
->pm
.dpm
.ps
);
357 adev
->pm
.dpm
.ps
[i
].ps_priv
= ps
;
359 for (j
= 0; j
< power_state
->v2
.ucNumDPMLevels
; j
++) {
360 clock_array_index
= power_state
->v2
.clockInfoIndex
[j
];
361 if (clock_array_index
>= clock_info_array
->ucNumEntries
)
363 if (k
>= CZ_MAX_HARDWARE_POWERLEVELS
)
365 clock_info
= (union pplib_clock_info
*)
366 &clock_info_array
->clockInfo
[clock_array_index
*
367 clock_info_array
->ucEntrySize
];
368 cz_parse_pplib_clock_info(adev
, &adev
->pm
.dpm
.ps
[i
],
372 cz_parse_pplib_non_clock_info(adev
, &adev
->pm
.dpm
.ps
[i
],
374 non_clock_info_array
->ucEntrySize
);
375 power_state_offset
+= 2 + power_state
->v2
.ucNumDPMLevels
;
377 adev
->pm
.dpm
.num_ps
= state_array
->ucNumEntries
;
382 static int cz_process_firmware_header(struct amdgpu_device
*adev
)
384 struct cz_power_info
*pi
= cz_get_pi(adev
);
388 ret
= cz_read_smc_sram_dword(adev
, SMU8_FIRMWARE_HEADER_LOCATION
+
389 offsetof(struct SMU8_Firmware_Header
,
394 pi
->dpm_table_start
= tmp
;
399 static int cz_dpm_init(struct amdgpu_device
*adev
)
401 struct cz_power_info
*pi
;
404 pi
= kzalloc(sizeof(struct cz_power_info
), GFP_KERNEL
);
408 adev
->pm
.dpm
.priv
= pi
;
410 ret
= amdgpu_get_platform_caps(adev
);
414 ret
= amdgpu_parse_extended_power_table(adev
);
418 pi
->sram_end
= SMC_RAM_END
;
420 /* set up DPM defaults */
421 for (i
= 0; i
< CZ_MAX_HARDWARE_POWERLEVELS
; i
++)
422 pi
->active_target
[i
] = CZ_AT_DFLT
;
424 pi
->mgcg_cgtt_local0
= 0x0;
425 pi
->mgcg_cgtt_local1
= 0x0;
426 pi
->clock_slow_down_step
= 25000;
427 pi
->skip_clock_slow_down
= 1;
428 pi
->enable_nb_ps_policy
= false;
429 pi
->caps_power_containment
= true;
431 pi
->didt_enabled
= false;
432 if (pi
->didt_enabled
) {
433 pi
->caps_sq_ramping
= true;
434 pi
->caps_db_ramping
= true;
435 pi
->caps_td_ramping
= true;
436 pi
->caps_tcp_ramping
= true;
438 if (amdgpu_sclk_deep_sleep_en
)
439 pi
->caps_sclk_ds
= true;
441 pi
->caps_sclk_ds
= false;
443 pi
->voting_clients
= 0x00c00033;
444 pi
->auto_thermal_throttling_enabled
= true;
445 pi
->bapm_enabled
= false;
446 pi
->disable_nb_ps3_in_battery
= false;
447 pi
->voltage_drop_threshold
= 0;
448 pi
->caps_sclk_throttle_low_notification
= false;
449 pi
->gfx_pg_threshold
= 500;
452 pi
->caps_uvd_pg
= (adev
->pg_flags
& AMD_PG_SUPPORT_UVD
) ? true : false;
453 pi
->caps_uvd_dpm
= true;
455 pi
->caps_vce_pg
= (adev
->pg_flags
& AMD_PG_SUPPORT_VCE
) ? true : false;
456 pi
->caps_vce_dpm
= true;
458 pi
->caps_acp_pg
= (adev
->pg_flags
& AMD_PG_SUPPORT_ACP
) ? true : false;
459 pi
->caps_acp_dpm
= true;
461 pi
->caps_stable_power_state
= false;
462 pi
->nb_dpm_enabled_by_driver
= true;
463 pi
->nb_dpm_enabled
= false;
464 pi
->caps_voltage_island
= false;
465 /* flags which indicate need to upload pptable */
466 pi
->need_pptable_upload
= true;
468 ret
= cz_parse_sys_info_table(adev
);
472 cz_patch_voltage_values(adev
);
473 cz_construct_boot_state(adev
);
475 ret
= cz_parse_power_table(adev
);
479 ret
= cz_process_firmware_header(adev
);
483 pi
->dpm_enabled
= true;
484 pi
->uvd_dynamic_pg
= false;
489 static void cz_dpm_fini(struct amdgpu_device
*adev
)
493 for (i
= 0; i
< adev
->pm
.dpm
.num_ps
; i
++)
494 kfree(adev
->pm
.dpm
.ps
[i
].ps_priv
);
496 kfree(adev
->pm
.dpm
.ps
);
497 kfree(adev
->pm
.dpm
.priv
);
498 amdgpu_free_extended_power_table(adev
);
501 #define ixSMUSVI_NB_CURRENTVID 0xD8230044
502 #define CURRENT_NB_VID_MASK 0xff000000
503 #define CURRENT_NB_VID__SHIFT 24
504 #define ixSMUSVI_GFX_CURRENTVID 0xD8230048
505 #define CURRENT_GFX_VID_MASK 0xff000000
506 #define CURRENT_GFX_VID__SHIFT 24
509 cz_dpm_debugfs_print_current_performance_level(struct amdgpu_device
*adev
,
512 struct cz_power_info
*pi
= cz_get_pi(adev
);
513 struct amdgpu_clock_voltage_dependency_table
*table
=
514 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
515 struct amdgpu_uvd_clock_voltage_dependency_table
*uvd_table
=
516 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
517 struct amdgpu_vce_clock_voltage_dependency_table
*vce_table
=
518 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
519 u32 sclk_index
= REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX
),
520 TARGET_AND_CURRENT_PROFILE_INDEX
, CURR_SCLK_INDEX
);
521 u32 uvd_index
= REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2
),
522 TARGET_AND_CURRENT_PROFILE_INDEX_2
, CURR_UVD_INDEX
);
523 u32 vce_index
= REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2
),
524 TARGET_AND_CURRENT_PROFILE_INDEX_2
, CURR_VCE_INDEX
);
525 u32 sclk
, vclk
, dclk
, ecclk
, tmp
;
528 if (sclk_index
>= NUM_SCLK_LEVELS
) {
529 seq_printf(m
, "invalid sclk dpm profile %d\n", sclk_index
);
531 sclk
= table
->entries
[sclk_index
].clk
;
532 seq_printf(m
, "%u sclk: %u\n", sclk_index
, sclk
);
535 tmp
= (RREG32_SMC(ixSMUSVI_NB_CURRENTVID
) &
536 CURRENT_NB_VID_MASK
) >> CURRENT_NB_VID__SHIFT
;
537 vddnb
= cz_convert_8bit_index_to_voltage(adev
, (u16
)tmp
);
538 tmp
= (RREG32_SMC(ixSMUSVI_GFX_CURRENTVID
) &
539 CURRENT_GFX_VID_MASK
) >> CURRENT_GFX_VID__SHIFT
;
540 vddgfx
= cz_convert_8bit_index_to_voltage(adev
, (u16
)tmp
);
541 seq_printf(m
, "vddnb: %u vddgfx: %u\n", vddnb
, vddgfx
);
543 seq_printf(m
, "uvd %sabled\n", pi
->uvd_power_gated
? "dis" : "en");
544 if (!pi
->uvd_power_gated
) {
545 if (uvd_index
>= CZ_MAX_HARDWARE_POWERLEVELS
) {
546 seq_printf(m
, "invalid uvd dpm level %d\n", uvd_index
);
548 vclk
= uvd_table
->entries
[uvd_index
].vclk
;
549 dclk
= uvd_table
->entries
[uvd_index
].dclk
;
550 seq_printf(m
, "%u uvd vclk: %u dclk: %u\n", uvd_index
, vclk
, dclk
);
554 seq_printf(m
, "vce %sabled\n", pi
->vce_power_gated
? "dis" : "en");
555 if (!pi
->vce_power_gated
) {
556 if (vce_index
>= CZ_MAX_HARDWARE_POWERLEVELS
) {
557 seq_printf(m
, "invalid vce dpm level %d\n", vce_index
);
559 ecclk
= vce_table
->entries
[vce_index
].ecclk
;
560 seq_printf(m
, "%u vce ecclk: %u\n", vce_index
, ecclk
);
565 static void cz_dpm_print_power_state(struct amdgpu_device
*adev
,
566 struct amdgpu_ps
*rps
)
569 struct cz_ps
*ps
= cz_get_ps(rps
);
571 amdgpu_dpm_print_class_info(rps
->class, rps
->class2
);
572 amdgpu_dpm_print_cap_info(rps
->caps
);
574 DRM_INFO("\tuvd vclk: %d dclk: %d\n", rps
->vclk
, rps
->dclk
);
575 for (i
= 0; i
< ps
->num_levels
; i
++) {
576 struct cz_pl
*pl
= &ps
->levels
[i
];
578 DRM_INFO("\t\tpower level %d sclk: %u vddc: %u\n",
580 cz_convert_8bit_index_to_voltage(adev
, pl
->vddc_index
));
583 amdgpu_dpm_print_ps_status(adev
, rps
);
586 static void cz_dpm_set_funcs(struct amdgpu_device
*adev
);
588 static int cz_dpm_early_init(void *handle
)
590 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
592 cz_dpm_set_funcs(adev
);
598 static int cz_dpm_late_init(void *handle
)
600 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
604 /* init the sysfs and debugfs files late */
605 ret
= amdgpu_pm_sysfs_init(adev
);
609 /* powerdown unused blocks for now */
610 cz_dpm_powergate_uvd(adev
, true);
611 cz_dpm_powergate_vce(adev
, true);
617 static int cz_dpm_sw_init(void *handle
)
619 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
621 /* fix me to add thermal support TODO */
623 /* default to balanced state */
624 adev
->pm
.dpm
.state
= POWER_STATE_TYPE_BALANCED
;
625 adev
->pm
.dpm
.user_state
= POWER_STATE_TYPE_BALANCED
;
626 adev
->pm
.dpm
.forced_level
= AMDGPU_DPM_FORCED_LEVEL_AUTO
;
627 adev
->pm
.default_sclk
= adev
->clock
.default_sclk
;
628 adev
->pm
.default_mclk
= adev
->clock
.default_mclk
;
629 adev
->pm
.current_sclk
= adev
->clock
.default_sclk
;
630 adev
->pm
.current_mclk
= adev
->clock
.default_mclk
;
631 adev
->pm
.int_thermal_type
= THERMAL_TYPE_NONE
;
636 mutex_lock(&adev
->pm
.mutex
);
637 ret
= cz_dpm_init(adev
);
639 goto dpm_init_failed
;
641 adev
->pm
.dpm
.current_ps
= adev
->pm
.dpm
.requested_ps
= adev
->pm
.dpm
.boot_ps
;
643 amdgpu_pm_print_power_states(adev
);
645 mutex_unlock(&adev
->pm
.mutex
);
646 DRM_INFO("amdgpu: dpm initialized\n");
652 mutex_unlock(&adev
->pm
.mutex
);
653 DRM_ERROR("amdgpu: dpm initialization failed\n");
658 static int cz_dpm_sw_fini(void *handle
)
660 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
662 mutex_lock(&adev
->pm
.mutex
);
663 amdgpu_pm_sysfs_fini(adev
);
665 mutex_unlock(&adev
->pm
.mutex
);
670 static void cz_reset_ap_mask(struct amdgpu_device
*adev
)
672 struct cz_power_info
*pi
= cz_get_pi(adev
);
674 pi
->active_process_mask
= 0;
678 static int cz_dpm_download_pptable_from_smu(struct amdgpu_device
*adev
,
683 ret
= cz_smu_download_pptable(adev
, table
);
688 static int cz_dpm_upload_pptable_to_smu(struct amdgpu_device
*adev
)
690 struct cz_power_info
*pi
= cz_get_pi(adev
);
691 struct SMU8_Fusion_ClkTable
*clock_table
;
692 struct atom_clock_dividers dividers
;
697 struct amdgpu_clock_voltage_dependency_table
*vddc_table
=
698 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
699 struct amdgpu_clock_voltage_dependency_table
*vddgfx_table
=
700 &adev
->pm
.dpm
.dyn_state
.vddgfx_dependency_on_sclk
;
701 struct amdgpu_uvd_clock_voltage_dependency_table
*uvd_table
=
702 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
703 struct amdgpu_vce_clock_voltage_dependency_table
*vce_table
=
704 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
705 struct amdgpu_clock_voltage_dependency_table
*acp_table
=
706 &adev
->pm
.dpm
.dyn_state
.acp_clock_voltage_dependency_table
;
708 if (!pi
->need_pptable_upload
)
711 ret
= cz_dpm_download_pptable_from_smu(adev
, &table
);
713 DRM_ERROR("amdgpu: Failed to get power play table from SMU!\n");
717 clock_table
= (struct SMU8_Fusion_ClkTable
*)table
;
718 /* patch clock table */
719 if (vddc_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
720 vddgfx_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
721 uvd_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
722 vce_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
723 acp_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
) {
724 DRM_ERROR("amdgpu: Invalid Clock Voltage Dependency Table!\n");
728 for (i
= 0; i
< CZ_MAX_HARDWARE_POWERLEVELS
; i
++) {
731 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].GnbVid
=
732 (i
< vddc_table
->count
) ? (uint8_t)vddc_table
->entries
[i
].v
: 0;
733 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].Frequency
=
734 (i
< vddc_table
->count
) ? vddc_table
->entries
[i
].clk
: 0;
735 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
736 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].Frequency
,
740 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
741 (uint8_t)dividers
.post_divider
;
744 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
745 (i
< vddgfx_table
->count
) ? (uint8_t)vddgfx_table
->entries
[i
].v
: 0;
748 clock_table
->AclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
749 (i
< acp_table
->count
) ? (uint8_t)acp_table
->entries
[i
].v
: 0;
750 clock_table
->AclkBreakdownTable
.ClkLevel
[i
].Frequency
=
751 (i
< acp_table
->count
) ? acp_table
->entries
[i
].clk
: 0;
752 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
753 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].Frequency
,
757 clock_table
->AclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
758 (uint8_t)dividers
.post_divider
;
761 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
762 (i
< uvd_table
->count
) ? (uint8_t)uvd_table
->entries
[i
].v
: 0;
763 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].Frequency
=
764 (i
< uvd_table
->count
) ? uvd_table
->entries
[i
].vclk
: 0;
765 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
766 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].Frequency
,
770 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
771 (uint8_t)dividers
.post_divider
;
773 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
774 (i
< uvd_table
->count
) ? (uint8_t)uvd_table
->entries
[i
].v
: 0;
775 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].Frequency
=
776 (i
< uvd_table
->count
) ? uvd_table
->entries
[i
].dclk
: 0;
777 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
778 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].Frequency
,
782 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
783 (uint8_t)dividers
.post_divider
;
786 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
787 (i
< vce_table
->count
) ? (uint8_t)vce_table
->entries
[i
].v
: 0;
788 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].Frequency
=
789 (i
< vce_table
->count
) ? vce_table
->entries
[i
].ecclk
: 0;
790 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
791 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].Frequency
,
795 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
796 (uint8_t)dividers
.post_divider
;
799 /* its time to upload to SMU */
800 ret
= cz_smu_upload_pptable(adev
);
802 DRM_ERROR("amdgpu: Failed to put power play table to SMU!\n");
809 static void cz_init_sclk_limit(struct amdgpu_device
*adev
)
811 struct cz_power_info
*pi
= cz_get_pi(adev
);
812 struct amdgpu_clock_voltage_dependency_table
*table
=
813 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
814 uint32_t clock
= 0, level
;
816 if (!table
|| !table
->count
) {
817 DRM_ERROR("Invalid Voltage Dependency table.\n");
821 pi
->sclk_dpm
.soft_min_clk
= 0;
822 pi
->sclk_dpm
.hard_min_clk
= 0;
823 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxSclkLevel
);
824 level
= cz_get_argument(adev
);
825 if (level
< table
->count
)
826 clock
= table
->entries
[level
].clk
;
828 DRM_ERROR("Invalid SLCK Voltage Dependency table entry.\n");
829 clock
= table
->entries
[table
->count
- 1].clk
;
832 pi
->sclk_dpm
.soft_max_clk
= clock
;
833 pi
->sclk_dpm
.hard_max_clk
= clock
;
837 static void cz_init_uvd_limit(struct amdgpu_device
*adev
)
839 struct cz_power_info
*pi
= cz_get_pi(adev
);
840 struct amdgpu_uvd_clock_voltage_dependency_table
*table
=
841 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
842 uint32_t clock
= 0, level
;
844 if (!table
|| !table
->count
) {
845 DRM_ERROR("Invalid Voltage Dependency table.\n");
849 pi
->uvd_dpm
.soft_min_clk
= 0;
850 pi
->uvd_dpm
.hard_min_clk
= 0;
851 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxUvdLevel
);
852 level
= cz_get_argument(adev
);
853 if (level
< table
->count
)
854 clock
= table
->entries
[level
].vclk
;
856 DRM_ERROR("Invalid UVD Voltage Dependency table entry.\n");
857 clock
= table
->entries
[table
->count
- 1].vclk
;
860 pi
->uvd_dpm
.soft_max_clk
= clock
;
861 pi
->uvd_dpm
.hard_max_clk
= clock
;
865 static void cz_init_vce_limit(struct amdgpu_device
*adev
)
867 struct cz_power_info
*pi
= cz_get_pi(adev
);
868 struct amdgpu_vce_clock_voltage_dependency_table
*table
=
869 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
870 uint32_t clock
= 0, level
;
872 if (!table
|| !table
->count
) {
873 DRM_ERROR("Invalid Voltage Dependency table.\n");
877 pi
->vce_dpm
.soft_min_clk
= table
->entries
[0].ecclk
;
878 pi
->vce_dpm
.hard_min_clk
= table
->entries
[0].ecclk
;
879 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxEclkLevel
);
880 level
= cz_get_argument(adev
);
881 if (level
< table
->count
)
882 clock
= table
->entries
[level
].ecclk
;
884 /* future BIOS would fix this error */
885 DRM_ERROR("Invalid VCE Voltage Dependency table entry.\n");
886 clock
= table
->entries
[table
->count
- 1].ecclk
;
889 pi
->vce_dpm
.soft_max_clk
= clock
;
890 pi
->vce_dpm
.hard_max_clk
= clock
;
894 static void cz_init_acp_limit(struct amdgpu_device
*adev
)
896 struct cz_power_info
*pi
= cz_get_pi(adev
);
897 struct amdgpu_clock_voltage_dependency_table
*table
=
898 &adev
->pm
.dpm
.dyn_state
.acp_clock_voltage_dependency_table
;
899 uint32_t clock
= 0, level
;
901 if (!table
|| !table
->count
) {
902 DRM_ERROR("Invalid Voltage Dependency table.\n");
906 pi
->acp_dpm
.soft_min_clk
= 0;
907 pi
->acp_dpm
.hard_min_clk
= 0;
908 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxAclkLevel
);
909 level
= cz_get_argument(adev
);
910 if (level
< table
->count
)
911 clock
= table
->entries
[level
].clk
;
913 DRM_ERROR("Invalid ACP Voltage Dependency table entry.\n");
914 clock
= table
->entries
[table
->count
- 1].clk
;
917 pi
->acp_dpm
.soft_max_clk
= clock
;
918 pi
->acp_dpm
.hard_max_clk
= clock
;
922 static void cz_init_pg_state(struct amdgpu_device
*adev
)
924 struct cz_power_info
*pi
= cz_get_pi(adev
);
926 pi
->uvd_power_gated
= false;
927 pi
->vce_power_gated
= false;
928 pi
->acp_power_gated
= false;
932 static void cz_init_sclk_threshold(struct amdgpu_device
*adev
)
934 struct cz_power_info
*pi
= cz_get_pi(adev
);
936 pi
->low_sclk_interrupt_threshold
= 0;
940 static void cz_dpm_setup_asic(struct amdgpu_device
*adev
)
942 cz_reset_ap_mask(adev
);
943 cz_dpm_upload_pptable_to_smu(adev
);
944 cz_init_sclk_limit(adev
);
945 cz_init_uvd_limit(adev
);
946 cz_init_vce_limit(adev
);
947 cz_init_acp_limit(adev
);
948 cz_init_pg_state(adev
);
949 cz_init_sclk_threshold(adev
);
953 static bool cz_check_smu_feature(struct amdgpu_device
*adev
,
956 uint32_t smu_feature
= 0;
959 ret
= cz_send_msg_to_smc_with_parameter(adev
,
960 PPSMC_MSG_GetFeatureStatus
, 0);
962 DRM_ERROR("Failed to get SMU features from SMC.\n");
965 smu_feature
= cz_get_argument(adev
);
966 if (feature
& smu_feature
)
973 static bool cz_check_for_dpm_enabled(struct amdgpu_device
*adev
)
975 if (cz_check_smu_feature(adev
,
976 SMU_EnabledFeatureScoreboard_SclkDpmOn
))
982 static void cz_program_voting_clients(struct amdgpu_device
*adev
)
984 WREG32_SMC(ixCG_FREQ_TRAN_VOTING_0
, PPCZ_VOTINGRIGHTSCLIENTS_DFLT0
);
987 static void cz_clear_voting_clients(struct amdgpu_device
*adev
)
989 WREG32_SMC(ixCG_FREQ_TRAN_VOTING_0
, 0);
992 static int cz_start_dpm(struct amdgpu_device
*adev
)
997 ret
= cz_send_msg_to_smc_with_parameter(adev
,
998 PPSMC_MSG_EnableAllSmuFeatures
, SCLK_DPM_MASK
);
1000 DRM_ERROR("SMU feature: SCLK_DPM enable failed\n");
1008 static int cz_stop_dpm(struct amdgpu_device
*adev
)
1012 if (amdgpu_dpm
&& adev
->pm
.dpm_enabled
) {
1013 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1014 PPSMC_MSG_DisableAllSmuFeatures
, SCLK_DPM_MASK
);
1016 DRM_ERROR("SMU feature: SCLK_DPM disable failed\n");
1024 static uint32_t cz_get_sclk_level(struct amdgpu_device
*adev
,
1025 uint32_t clock
, uint16_t msg
)
1028 struct amdgpu_clock_voltage_dependency_table
*table
=
1029 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
1032 case PPSMC_MSG_SetSclkSoftMin
:
1033 case PPSMC_MSG_SetSclkHardMin
:
1034 for (i
= 0; i
< table
->count
; i
++)
1035 if (clock
<= table
->entries
[i
].clk
)
1037 if (i
== table
->count
)
1038 i
= table
->count
- 1;
1040 case PPSMC_MSG_SetSclkSoftMax
:
1041 case PPSMC_MSG_SetSclkHardMax
:
1042 for (i
= table
->count
- 1; i
>= 0; i
--)
1043 if (clock
>= table
->entries
[i
].clk
)
1055 static uint32_t cz_get_eclk_level(struct amdgpu_device
*adev
,
1056 uint32_t clock
, uint16_t msg
)
1059 struct amdgpu_vce_clock_voltage_dependency_table
*table
=
1060 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
1062 if (table
->count
== 0)
1066 case PPSMC_MSG_SetEclkSoftMin
:
1067 case PPSMC_MSG_SetEclkHardMin
:
1068 for (i
= 0; i
< table
->count
-1; i
++)
1069 if (clock
<= table
->entries
[i
].ecclk
)
1072 case PPSMC_MSG_SetEclkSoftMax
:
1073 case PPSMC_MSG_SetEclkHardMax
:
1074 for (i
= table
->count
- 1; i
> 0; i
--)
1075 if (clock
>= table
->entries
[i
].ecclk
)
1085 static uint32_t cz_get_uvd_level(struct amdgpu_device
*adev
,
1086 uint32_t clock
, uint16_t msg
)
1089 struct amdgpu_uvd_clock_voltage_dependency_table
*table
=
1090 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
1093 case PPSMC_MSG_SetUvdSoftMin
:
1094 case PPSMC_MSG_SetUvdHardMin
:
1095 for (i
= 0; i
< table
->count
; i
++)
1096 if (clock
<= table
->entries
[i
].vclk
)
1098 if (i
== table
->count
)
1099 i
= table
->count
- 1;
1101 case PPSMC_MSG_SetUvdSoftMax
:
1102 case PPSMC_MSG_SetUvdHardMax
:
1103 for (i
= table
->count
- 1; i
>= 0; i
--)
1104 if (clock
>= table
->entries
[i
].vclk
)
1116 static int cz_program_bootup_state(struct amdgpu_device
*adev
)
1118 struct cz_power_info
*pi
= cz_get_pi(adev
);
1119 uint32_t soft_min_clk
= 0;
1120 uint32_t soft_max_clk
= 0;
1123 pi
->sclk_dpm
.soft_min_clk
= pi
->sys_info
.bootup_sclk
;
1124 pi
->sclk_dpm
.soft_max_clk
= pi
->sys_info
.bootup_sclk
;
1126 soft_min_clk
= cz_get_sclk_level(adev
,
1127 pi
->sclk_dpm
.soft_min_clk
,
1128 PPSMC_MSG_SetSclkSoftMin
);
1129 soft_max_clk
= cz_get_sclk_level(adev
,
1130 pi
->sclk_dpm
.soft_max_clk
,
1131 PPSMC_MSG_SetSclkSoftMax
);
1133 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1134 PPSMC_MSG_SetSclkSoftMin
, soft_min_clk
);
1138 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1139 PPSMC_MSG_SetSclkSoftMax
, soft_max_clk
);
1147 static int cz_disable_cgpg(struct amdgpu_device
*adev
)
1153 static int cz_enable_cgpg(struct amdgpu_device
*adev
)
1159 static int cz_program_pt_config_registers(struct amdgpu_device
*adev
)
1164 static void cz_do_enable_didt(struct amdgpu_device
*adev
, bool enable
)
1166 struct cz_power_info
*pi
= cz_get_pi(adev
);
1169 if (pi
->caps_sq_ramping
) {
1170 reg
= RREG32_DIDT(ixDIDT_SQ_CTRL0
);
1172 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 1);
1174 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 0);
1175 WREG32_DIDT(ixDIDT_SQ_CTRL0
, reg
);
1177 if (pi
->caps_db_ramping
) {
1178 reg
= RREG32_DIDT(ixDIDT_DB_CTRL0
);
1180 reg
= REG_SET_FIELD(reg
, DIDT_DB_CTRL0
, DIDT_CTRL_EN
, 1);
1182 reg
= REG_SET_FIELD(reg
, DIDT_DB_CTRL0
, DIDT_CTRL_EN
, 0);
1183 WREG32_DIDT(ixDIDT_DB_CTRL0
, reg
);
1185 if (pi
->caps_td_ramping
) {
1186 reg
= RREG32_DIDT(ixDIDT_TD_CTRL0
);
1188 reg
= REG_SET_FIELD(reg
, DIDT_TD_CTRL0
, DIDT_CTRL_EN
, 1);
1190 reg
= REG_SET_FIELD(reg
, DIDT_TD_CTRL0
, DIDT_CTRL_EN
, 0);
1191 WREG32_DIDT(ixDIDT_TD_CTRL0
, reg
);
1193 if (pi
->caps_tcp_ramping
) {
1194 reg
= RREG32_DIDT(ixDIDT_TCP_CTRL0
);
1196 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 1);
1198 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 0);
1199 WREG32_DIDT(ixDIDT_TCP_CTRL0
, reg
);
1204 static int cz_enable_didt(struct amdgpu_device
*adev
, bool enable
)
1206 struct cz_power_info
*pi
= cz_get_pi(adev
);
1209 if (pi
->caps_sq_ramping
|| pi
->caps_db_ramping
||
1210 pi
->caps_td_ramping
|| pi
->caps_tcp_ramping
) {
1211 if (adev
->gfx
.gfx_current_status
!= AMDGPU_GFX_SAFE_MODE
) {
1212 ret
= cz_disable_cgpg(adev
);
1214 DRM_ERROR("Pre Di/Dt disable cg/pg failed\n");
1217 adev
->gfx
.gfx_current_status
= AMDGPU_GFX_SAFE_MODE
;
1220 ret
= cz_program_pt_config_registers(adev
);
1222 DRM_ERROR("Di/Dt config failed\n");
1225 cz_do_enable_didt(adev
, enable
);
1227 if (adev
->gfx
.gfx_current_status
== AMDGPU_GFX_SAFE_MODE
) {
1228 ret
= cz_enable_cgpg(adev
);
1230 DRM_ERROR("Post Di/Dt enable cg/pg failed\n");
1233 adev
->gfx
.gfx_current_status
= AMDGPU_GFX_NORMAL_MODE
;
1241 static void cz_reset_acp_boot_level(struct amdgpu_device
*adev
)
1245 static void cz_update_current_ps(struct amdgpu_device
*adev
,
1246 struct amdgpu_ps
*rps
)
1248 struct cz_power_info
*pi
= cz_get_pi(adev
);
1249 struct cz_ps
*ps
= cz_get_ps(rps
);
1251 pi
->current_ps
= *ps
;
1252 pi
->current_rps
= *rps
;
1253 pi
->current_rps
.ps_priv
= ps
;
1257 static void cz_update_requested_ps(struct amdgpu_device
*adev
,
1258 struct amdgpu_ps
*rps
)
1260 struct cz_power_info
*pi
= cz_get_pi(adev
);
1261 struct cz_ps
*ps
= cz_get_ps(rps
);
1263 pi
->requested_ps
= *ps
;
1264 pi
->requested_rps
= *rps
;
1265 pi
->requested_rps
.ps_priv
= ps
;
1269 /* PP arbiter support needed TODO */
1270 static void cz_apply_state_adjust_rules(struct amdgpu_device
*adev
,
1271 struct amdgpu_ps
*new_rps
,
1272 struct amdgpu_ps
*old_rps
)
1274 struct cz_ps
*ps
= cz_get_ps(new_rps
);
1275 struct cz_power_info
*pi
= cz_get_pi(adev
);
1276 struct amdgpu_clock_and_voltage_limits
*limits
=
1277 &adev
->pm
.dpm
.dyn_state
.max_clock_voltage_on_ac
;
1278 /* 10kHz memory clock */
1281 ps
->force_high
= false;
1282 ps
->need_dfs_bypass
= true;
1283 pi
->video_start
= new_rps
->dclk
|| new_rps
->vclk
||
1284 new_rps
->evclk
|| new_rps
->ecclk
;
1286 if ((new_rps
->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK
) ==
1287 ATOM_PPLIB_CLASSIFICATION_UI_BATTERY
)
1288 pi
->battery_state
= true;
1290 pi
->battery_state
= false;
1292 if (pi
->caps_stable_power_state
)
1293 mclk
= limits
->mclk
;
1295 if (mclk
> pi
->sys_info
.nbp_memory_clock
[CZ_NUM_NBPMEMORY_CLOCK
- 1])
1296 ps
->force_high
= true;
1300 static int cz_dpm_enable(struct amdgpu_device
*adev
)
1302 const char *chip_name
;
1305 /* renable will hang up SMU, so check first */
1306 if (cz_check_for_dpm_enabled(adev
))
1309 cz_program_voting_clients(adev
);
1311 switch (adev
->asic_type
) {
1313 chip_name
= "carrizo";
1316 chip_name
= "stoney";
1323 ret
= cz_start_dpm(adev
);
1325 DRM_ERROR("%s DPM enable failed\n", chip_name
);
1329 ret
= cz_program_bootup_state(adev
);
1331 DRM_ERROR("%s bootup state program failed\n", chip_name
);
1335 ret
= cz_enable_didt(adev
, true);
1337 DRM_ERROR("%s enable di/dt failed\n", chip_name
);
1341 cz_reset_acp_boot_level(adev
);
1343 cz_update_current_ps(adev
, adev
->pm
.dpm
.boot_ps
);
1348 static int cz_dpm_hw_init(void *handle
)
1350 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1353 mutex_lock(&adev
->pm
.mutex
);
1355 /* smu init only needs to be called at startup, not resume.
1356 * It should be in sw_init, but requires the fw info gathered
1357 * in sw_init from other IP modules.
1359 ret
= cz_smu_init(adev
);
1361 DRM_ERROR("amdgpu: smc initialization failed\n");
1362 mutex_unlock(&adev
->pm
.mutex
);
1366 /* do the actual fw loading */
1367 ret
= cz_smu_start(adev
);
1369 DRM_ERROR("amdgpu: smc start failed\n");
1370 mutex_unlock(&adev
->pm
.mutex
);
1375 adev
->pm
.dpm_enabled
= false;
1376 mutex_unlock(&adev
->pm
.mutex
);
1380 /* cz dpm setup asic */
1381 cz_dpm_setup_asic(adev
);
1384 ret
= cz_dpm_enable(adev
);
1386 adev
->pm
.dpm_enabled
= false;
1388 adev
->pm
.dpm_enabled
= true;
1390 mutex_unlock(&adev
->pm
.mutex
);
1395 static int cz_dpm_disable(struct amdgpu_device
*adev
)
1399 if (!cz_check_for_dpm_enabled(adev
))
1402 ret
= cz_enable_didt(adev
, false);
1404 DRM_ERROR("disable di/dt failed\n");
1408 /* powerup blocks */
1409 cz_dpm_powergate_uvd(adev
, false);
1410 cz_dpm_powergate_vce(adev
, false);
1412 cz_clear_voting_clients(adev
);
1414 cz_update_current_ps(adev
, adev
->pm
.dpm
.boot_ps
);
1419 static int cz_dpm_hw_fini(void *handle
)
1422 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1424 mutex_lock(&adev
->pm
.mutex
);
1426 /* smu fini only needs to be called at teardown, not suspend.
1427 * It should be in sw_fini, but we put it here for symmetry
1432 if (adev
->pm
.dpm_enabled
) {
1433 ret
= cz_dpm_disable(adev
);
1435 adev
->pm
.dpm
.current_ps
=
1436 adev
->pm
.dpm
.requested_ps
=
1437 adev
->pm
.dpm
.boot_ps
;
1440 adev
->pm
.dpm_enabled
= false;
1442 mutex_unlock(&adev
->pm
.mutex
);
1447 static int cz_dpm_suspend(void *handle
)
1450 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1452 if (adev
->pm
.dpm_enabled
) {
1453 mutex_lock(&adev
->pm
.mutex
);
1455 ret
= cz_dpm_disable(adev
);
1457 adev
->pm
.dpm
.current_ps
=
1458 adev
->pm
.dpm
.requested_ps
=
1459 adev
->pm
.dpm
.boot_ps
;
1461 mutex_unlock(&adev
->pm
.mutex
);
1467 static int cz_dpm_resume(void *handle
)
1470 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1472 mutex_lock(&adev
->pm
.mutex
);
1474 /* do the actual fw loading */
1475 ret
= cz_smu_start(adev
);
1477 DRM_ERROR("amdgpu: smc start failed\n");
1478 mutex_unlock(&adev
->pm
.mutex
);
1483 adev
->pm
.dpm_enabled
= false;
1484 mutex_unlock(&adev
->pm
.mutex
);
1488 /* cz dpm setup asic */
1489 cz_dpm_setup_asic(adev
);
1492 ret
= cz_dpm_enable(adev
);
1494 adev
->pm
.dpm_enabled
= false;
1496 adev
->pm
.dpm_enabled
= true;
1498 mutex_unlock(&adev
->pm
.mutex
);
1499 /* upon resume, re-compute the clocks */
1500 if (adev
->pm
.dpm_enabled
)
1501 amdgpu_pm_compute_clocks(adev
);
1506 static int cz_dpm_set_clockgating_state(void *handle
,
1507 enum amd_clockgating_state state
)
1512 static int cz_dpm_set_powergating_state(void *handle
,
1513 enum amd_powergating_state state
)
1518 /* borrowed from KV, need future unify */
1519 static int cz_dpm_get_temperature(struct amdgpu_device
*adev
)
1521 int actual_temp
= 0;
1522 uint32_t temp
= RREG32_SMC(0xC0300E0C);
1525 actual_temp
= 1000 * ((temp
/ 8) - 49);
1530 static int cz_dpm_pre_set_power_state(struct amdgpu_device
*adev
)
1532 struct cz_power_info
*pi
= cz_get_pi(adev
);
1533 struct amdgpu_ps requested_ps
= *adev
->pm
.dpm
.requested_ps
;
1534 struct amdgpu_ps
*new_ps
= &requested_ps
;
1536 cz_update_requested_ps(adev
, new_ps
);
1537 cz_apply_state_adjust_rules(adev
, &pi
->requested_rps
,
1543 static int cz_dpm_update_sclk_limit(struct amdgpu_device
*adev
)
1545 struct cz_power_info
*pi
= cz_get_pi(adev
);
1546 struct amdgpu_clock_and_voltage_limits
*limits
=
1547 &adev
->pm
.dpm
.dyn_state
.max_clock_voltage_on_ac
;
1548 uint32_t clock
, stable_ps_clock
= 0;
1550 clock
= pi
->sclk_dpm
.soft_min_clk
;
1552 if (pi
->caps_stable_power_state
) {
1553 stable_ps_clock
= limits
->sclk
* 75 / 100;
1554 if (clock
< stable_ps_clock
)
1555 clock
= stable_ps_clock
;
1558 if (clock
!= pi
->sclk_dpm
.soft_min_clk
) {
1559 pi
->sclk_dpm
.soft_min_clk
= clock
;
1560 cz_send_msg_to_smc_with_parameter(adev
,
1561 PPSMC_MSG_SetSclkSoftMin
,
1562 cz_get_sclk_level(adev
, clock
,
1563 PPSMC_MSG_SetSclkSoftMin
));
1566 if (pi
->caps_stable_power_state
&&
1567 pi
->sclk_dpm
.soft_max_clk
!= clock
) {
1568 pi
->sclk_dpm
.soft_max_clk
= clock
;
1569 cz_send_msg_to_smc_with_parameter(adev
,
1570 PPSMC_MSG_SetSclkSoftMax
,
1571 cz_get_sclk_level(adev
, clock
,
1572 PPSMC_MSG_SetSclkSoftMax
));
1574 cz_send_msg_to_smc_with_parameter(adev
,
1575 PPSMC_MSG_SetSclkSoftMax
,
1576 cz_get_sclk_level(adev
,
1577 pi
->sclk_dpm
.soft_max_clk
,
1578 PPSMC_MSG_SetSclkSoftMax
));
1584 static int cz_dpm_set_deep_sleep_sclk_threshold(struct amdgpu_device
*adev
)
1586 struct cz_power_info
*pi
= cz_get_pi(adev
);
1588 if (pi
->caps_sclk_ds
) {
1589 cz_send_msg_to_smc_with_parameter(adev
,
1590 PPSMC_MSG_SetMinDeepSleepSclk
,
1591 CZ_MIN_DEEP_SLEEP_SCLK
);
1597 /* ?? without dal support, is this still needed in setpowerstate list*/
1598 static int cz_dpm_set_watermark_threshold(struct amdgpu_device
*adev
)
1600 struct cz_power_info
*pi
= cz_get_pi(adev
);
1602 cz_send_msg_to_smc_with_parameter(adev
,
1603 PPSMC_MSG_SetWatermarkFrequency
,
1604 pi
->sclk_dpm
.soft_max_clk
);
1609 static int cz_dpm_enable_nbdpm(struct amdgpu_device
*adev
)
1612 struct cz_power_info
*pi
= cz_get_pi(adev
);
1614 /* also depend on dal NBPStateDisableRequired */
1615 if (pi
->nb_dpm_enabled_by_driver
&& !pi
->nb_dpm_enabled
) {
1616 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1617 PPSMC_MSG_EnableAllSmuFeatures
,
1620 DRM_ERROR("amdgpu: nb dpm enable failed\n");
1623 pi
->nb_dpm_enabled
= true;
1629 static void cz_dpm_nbdpm_lm_pstate_enable(struct amdgpu_device
*adev
,
1633 cz_send_msg_to_smc(adev
, PPSMC_MSG_EnableLowMemoryPstate
);
1635 cz_send_msg_to_smc(adev
, PPSMC_MSG_DisableLowMemoryPstate
);
1639 static int cz_dpm_update_low_memory_pstate(struct amdgpu_device
*adev
)
1641 struct cz_power_info
*pi
= cz_get_pi(adev
);
1642 struct cz_ps
*ps
= &pi
->requested_ps
;
1644 if (pi
->sys_info
.nb_dpm_enable
) {
1646 cz_dpm_nbdpm_lm_pstate_enable(adev
, false);
1648 cz_dpm_nbdpm_lm_pstate_enable(adev
, true);
1654 /* with dpm enabled */
1655 static int cz_dpm_set_power_state(struct amdgpu_device
*adev
)
1657 cz_dpm_update_sclk_limit(adev
);
1658 cz_dpm_set_deep_sleep_sclk_threshold(adev
);
1659 cz_dpm_set_watermark_threshold(adev
);
1660 cz_dpm_enable_nbdpm(adev
);
1661 cz_dpm_update_low_memory_pstate(adev
);
1666 static void cz_dpm_post_set_power_state(struct amdgpu_device
*adev
)
1668 struct cz_power_info
*pi
= cz_get_pi(adev
);
1669 struct amdgpu_ps
*ps
= &pi
->requested_rps
;
1671 cz_update_current_ps(adev
, ps
);
1675 static int cz_dpm_force_highest(struct amdgpu_device
*adev
)
1677 struct cz_power_info
*pi
= cz_get_pi(adev
);
1680 if (pi
->sclk_dpm
.soft_min_clk
!= pi
->sclk_dpm
.soft_max_clk
) {
1681 pi
->sclk_dpm
.soft_min_clk
=
1682 pi
->sclk_dpm
.soft_max_clk
;
1683 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1684 PPSMC_MSG_SetSclkSoftMin
,
1685 cz_get_sclk_level(adev
,
1686 pi
->sclk_dpm
.soft_min_clk
,
1687 PPSMC_MSG_SetSclkSoftMin
));
1695 static int cz_dpm_force_lowest(struct amdgpu_device
*adev
)
1697 struct cz_power_info
*pi
= cz_get_pi(adev
);
1700 if (pi
->sclk_dpm
.soft_max_clk
!= pi
->sclk_dpm
.soft_min_clk
) {
1701 pi
->sclk_dpm
.soft_max_clk
= pi
->sclk_dpm
.soft_min_clk
;
1702 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1703 PPSMC_MSG_SetSclkSoftMax
,
1704 cz_get_sclk_level(adev
,
1705 pi
->sclk_dpm
.soft_max_clk
,
1706 PPSMC_MSG_SetSclkSoftMax
));
1714 static uint32_t cz_dpm_get_max_sclk_level(struct amdgpu_device
*adev
)
1716 struct cz_power_info
*pi
= cz_get_pi(adev
);
1718 if (!pi
->max_sclk_level
) {
1719 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxSclkLevel
);
1720 pi
->max_sclk_level
= cz_get_argument(adev
) + 1;
1723 if (pi
->max_sclk_level
> CZ_MAX_HARDWARE_POWERLEVELS
) {
1724 DRM_ERROR("Invalid max sclk level!\n");
1728 return pi
->max_sclk_level
;
1731 static int cz_dpm_unforce_dpm_levels(struct amdgpu_device
*adev
)
1733 struct cz_power_info
*pi
= cz_get_pi(adev
);
1734 struct amdgpu_clock_voltage_dependency_table
*dep_table
=
1735 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
1739 pi
->sclk_dpm
.soft_min_clk
= dep_table
->entries
[0].clk
;
1740 level
= cz_dpm_get_max_sclk_level(adev
) - 1;
1741 if (level
< dep_table
->count
)
1742 pi
->sclk_dpm
.soft_max_clk
= dep_table
->entries
[level
].clk
;
1744 pi
->sclk_dpm
.soft_max_clk
=
1745 dep_table
->entries
[dep_table
->count
- 1].clk
;
1747 /* get min/max sclk soft value
1748 * notify SMU to execute */
1749 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1750 PPSMC_MSG_SetSclkSoftMin
,
1751 cz_get_sclk_level(adev
,
1752 pi
->sclk_dpm
.soft_min_clk
,
1753 PPSMC_MSG_SetSclkSoftMin
));
1757 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1758 PPSMC_MSG_SetSclkSoftMax
,
1759 cz_get_sclk_level(adev
,
1760 pi
->sclk_dpm
.soft_max_clk
,
1761 PPSMC_MSG_SetSclkSoftMax
));
1765 DRM_DEBUG("DPM unforce state min=%d, max=%d.\n",
1766 pi
->sclk_dpm
.soft_min_clk
,
1767 pi
->sclk_dpm
.soft_max_clk
);
1772 static int cz_dpm_uvd_force_highest(struct amdgpu_device
*adev
)
1774 struct cz_power_info
*pi
= cz_get_pi(adev
);
1777 if (pi
->uvd_dpm
.soft_min_clk
!= pi
->uvd_dpm
.soft_max_clk
) {
1778 pi
->uvd_dpm
.soft_min_clk
=
1779 pi
->uvd_dpm
.soft_max_clk
;
1780 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1781 PPSMC_MSG_SetUvdSoftMin
,
1782 cz_get_uvd_level(adev
,
1783 pi
->uvd_dpm
.soft_min_clk
,
1784 PPSMC_MSG_SetUvdSoftMin
));
1792 static int cz_dpm_uvd_force_lowest(struct amdgpu_device
*adev
)
1794 struct cz_power_info
*pi
= cz_get_pi(adev
);
1797 if (pi
->uvd_dpm
.soft_max_clk
!= pi
->uvd_dpm
.soft_min_clk
) {
1798 pi
->uvd_dpm
.soft_max_clk
= pi
->uvd_dpm
.soft_min_clk
;
1799 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1800 PPSMC_MSG_SetUvdSoftMax
,
1801 cz_get_uvd_level(adev
,
1802 pi
->uvd_dpm
.soft_max_clk
,
1803 PPSMC_MSG_SetUvdSoftMax
));
1811 static uint32_t cz_dpm_get_max_uvd_level(struct amdgpu_device
*adev
)
1813 struct cz_power_info
*pi
= cz_get_pi(adev
);
1815 if (!pi
->max_uvd_level
) {
1816 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxUvdLevel
);
1817 pi
->max_uvd_level
= cz_get_argument(adev
) + 1;
1820 if (pi
->max_uvd_level
> CZ_MAX_HARDWARE_POWERLEVELS
) {
1821 DRM_ERROR("Invalid max uvd level!\n");
1825 return pi
->max_uvd_level
;
1828 static int cz_dpm_unforce_uvd_dpm_levels(struct amdgpu_device
*adev
)
1830 struct cz_power_info
*pi
= cz_get_pi(adev
);
1831 struct amdgpu_uvd_clock_voltage_dependency_table
*dep_table
=
1832 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
1836 pi
->uvd_dpm
.soft_min_clk
= dep_table
->entries
[0].vclk
;
1837 level
= cz_dpm_get_max_uvd_level(adev
) - 1;
1838 if (level
< dep_table
->count
)
1839 pi
->uvd_dpm
.soft_max_clk
= dep_table
->entries
[level
].vclk
;
1841 pi
->uvd_dpm
.soft_max_clk
=
1842 dep_table
->entries
[dep_table
->count
- 1].vclk
;
1844 /* get min/max sclk soft value
1845 * notify SMU to execute */
1846 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1847 PPSMC_MSG_SetUvdSoftMin
,
1848 cz_get_uvd_level(adev
,
1849 pi
->uvd_dpm
.soft_min_clk
,
1850 PPSMC_MSG_SetUvdSoftMin
));
1854 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1855 PPSMC_MSG_SetUvdSoftMax
,
1856 cz_get_uvd_level(adev
,
1857 pi
->uvd_dpm
.soft_max_clk
,
1858 PPSMC_MSG_SetUvdSoftMax
));
1862 DRM_DEBUG("DPM uvd unforce state min=%d, max=%d.\n",
1863 pi
->uvd_dpm
.soft_min_clk
,
1864 pi
->uvd_dpm
.soft_max_clk
);
1869 static int cz_dpm_vce_force_highest(struct amdgpu_device
*adev
)
1871 struct cz_power_info
*pi
= cz_get_pi(adev
);
1874 if (pi
->vce_dpm
.soft_min_clk
!= pi
->vce_dpm
.soft_max_clk
) {
1875 pi
->vce_dpm
.soft_min_clk
=
1876 pi
->vce_dpm
.soft_max_clk
;
1877 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1878 PPSMC_MSG_SetEclkSoftMin
,
1879 cz_get_eclk_level(adev
,
1880 pi
->vce_dpm
.soft_min_clk
,
1881 PPSMC_MSG_SetEclkSoftMin
));
1889 static int cz_dpm_vce_force_lowest(struct amdgpu_device
*adev
)
1891 struct cz_power_info
*pi
= cz_get_pi(adev
);
1894 if (pi
->vce_dpm
.soft_max_clk
!= pi
->vce_dpm
.soft_min_clk
) {
1895 pi
->vce_dpm
.soft_max_clk
= pi
->vce_dpm
.soft_min_clk
;
1896 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1897 PPSMC_MSG_SetEclkSoftMax
,
1898 cz_get_uvd_level(adev
,
1899 pi
->vce_dpm
.soft_max_clk
,
1900 PPSMC_MSG_SetEclkSoftMax
));
1908 static uint32_t cz_dpm_get_max_vce_level(struct amdgpu_device
*adev
)
1910 struct cz_power_info
*pi
= cz_get_pi(adev
);
1912 if (!pi
->max_vce_level
) {
1913 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxEclkLevel
);
1914 pi
->max_vce_level
= cz_get_argument(adev
) + 1;
1917 if (pi
->max_vce_level
> CZ_MAX_HARDWARE_POWERLEVELS
) {
1918 DRM_ERROR("Invalid max vce level!\n");
1922 return pi
->max_vce_level
;
1925 static int cz_dpm_unforce_vce_dpm_levels(struct amdgpu_device
*adev
)
1927 struct cz_power_info
*pi
= cz_get_pi(adev
);
1928 struct amdgpu_vce_clock_voltage_dependency_table
*dep_table
=
1929 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
1933 pi
->vce_dpm
.soft_min_clk
= dep_table
->entries
[0].ecclk
;
1934 level
= cz_dpm_get_max_vce_level(adev
) - 1;
1935 if (level
< dep_table
->count
)
1936 pi
->vce_dpm
.soft_max_clk
= dep_table
->entries
[level
].ecclk
;
1938 pi
->vce_dpm
.soft_max_clk
=
1939 dep_table
->entries
[dep_table
->count
- 1].ecclk
;
1941 /* get min/max sclk soft value
1942 * notify SMU to execute */
1943 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1944 PPSMC_MSG_SetEclkSoftMin
,
1945 cz_get_eclk_level(adev
,
1946 pi
->vce_dpm
.soft_min_clk
,
1947 PPSMC_MSG_SetEclkSoftMin
));
1951 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1952 PPSMC_MSG_SetEclkSoftMax
,
1953 cz_get_eclk_level(adev
,
1954 pi
->vce_dpm
.soft_max_clk
,
1955 PPSMC_MSG_SetEclkSoftMax
));
1959 DRM_DEBUG("DPM vce unforce state min=%d, max=%d.\n",
1960 pi
->vce_dpm
.soft_min_clk
,
1961 pi
->vce_dpm
.soft_max_clk
);
1966 static int cz_dpm_force_dpm_level(struct amdgpu_device
*adev
,
1967 enum amdgpu_dpm_forced_level level
)
1972 case AMDGPU_DPM_FORCED_LEVEL_HIGH
:
1974 ret
= cz_dpm_unforce_dpm_levels(adev
);
1977 ret
= cz_dpm_force_highest(adev
);
1982 ret
= cz_dpm_unforce_uvd_dpm_levels(adev
);
1985 ret
= cz_dpm_uvd_force_highest(adev
);
1990 ret
= cz_dpm_unforce_vce_dpm_levels(adev
);
1993 ret
= cz_dpm_vce_force_highest(adev
);
1997 case AMDGPU_DPM_FORCED_LEVEL_LOW
:
1999 ret
= cz_dpm_unforce_dpm_levels(adev
);
2002 ret
= cz_dpm_force_lowest(adev
);
2007 ret
= cz_dpm_unforce_uvd_dpm_levels(adev
);
2010 ret
= cz_dpm_uvd_force_lowest(adev
);
2015 ret
= cz_dpm_unforce_vce_dpm_levels(adev
);
2018 ret
= cz_dpm_vce_force_lowest(adev
);
2022 case AMDGPU_DPM_FORCED_LEVEL_AUTO
:
2024 ret
= cz_dpm_unforce_dpm_levels(adev
);
2029 ret
= cz_dpm_unforce_uvd_dpm_levels(adev
);
2034 ret
= cz_dpm_unforce_vce_dpm_levels(adev
);
2042 adev
->pm
.dpm
.forced_level
= level
;
2047 /* fix me, display configuration change lists here
2048 * mostly dal related*/
2049 static void cz_dpm_display_configuration_changed(struct amdgpu_device
*adev
)
2053 static uint32_t cz_dpm_get_sclk(struct amdgpu_device
*adev
, bool low
)
2055 struct cz_power_info
*pi
= cz_get_pi(adev
);
2056 struct cz_ps
*requested_state
= cz_get_ps(&pi
->requested_rps
);
2059 return requested_state
->levels
[0].sclk
;
2061 return requested_state
->levels
[requested_state
->num_levels
- 1].sclk
;
2065 static uint32_t cz_dpm_get_mclk(struct amdgpu_device
*adev
, bool low
)
2067 struct cz_power_info
*pi
= cz_get_pi(adev
);
2069 return pi
->sys_info
.bootup_uma_clk
;
2072 static int cz_enable_uvd_dpm(struct amdgpu_device
*adev
, bool enable
)
2074 struct cz_power_info
*pi
= cz_get_pi(adev
);
2077 if (enable
&& pi
->caps_uvd_dpm
) {
2078 pi
->dpm_flags
|= DPMFlags_UVD_Enabled
;
2079 DRM_DEBUG("UVD DPM Enabled.\n");
2081 ret
= cz_send_msg_to_smc_with_parameter(adev
,
2082 PPSMC_MSG_EnableAllSmuFeatures
, UVD_DPM_MASK
);
2084 pi
->dpm_flags
&= ~DPMFlags_UVD_Enabled
;
2085 DRM_DEBUG("UVD DPM Stopped\n");
2087 ret
= cz_send_msg_to_smc_with_parameter(adev
,
2088 PPSMC_MSG_DisableAllSmuFeatures
, UVD_DPM_MASK
);
2094 static int cz_update_uvd_dpm(struct amdgpu_device
*adev
, bool gate
)
2096 return cz_enable_uvd_dpm(adev
, !gate
);
2100 static void cz_dpm_powergate_uvd(struct amdgpu_device
*adev
, bool gate
)
2102 struct cz_power_info
*pi
= cz_get_pi(adev
);
2105 if (pi
->uvd_power_gated
== gate
)
2108 pi
->uvd_power_gated
= gate
;
2111 if (pi
->caps_uvd_pg
) {
2112 /* disable clockgating so we can properly shut down the block */
2113 ret
= amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
2114 AMD_CG_STATE_UNGATE
);
2116 DRM_ERROR("UVD DPM Power Gating failed to set clockgating state\n");
2120 /* shutdown the UVD block */
2121 ret
= amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
2125 DRM_ERROR("UVD DPM Power Gating failed to set powergating state\n");
2129 cz_update_uvd_dpm(adev
, gate
);
2130 if (pi
->caps_uvd_pg
) {
2131 /* power off the UVD block */
2132 ret
= cz_send_msg_to_smc(adev
, PPSMC_MSG_UVDPowerOFF
);
2134 DRM_ERROR("UVD DPM Power Gating failed to send SMU PowerOFF message\n");
2139 if (pi
->caps_uvd_pg
) {
2140 /* power on the UVD block */
2141 if (pi
->uvd_dynamic_pg
)
2142 ret
= cz_send_msg_to_smc_with_parameter(adev
, PPSMC_MSG_UVDPowerON
, 1);
2144 ret
= cz_send_msg_to_smc_with_parameter(adev
, PPSMC_MSG_UVDPowerON
, 0);
2147 DRM_ERROR("UVD DPM Power Gating Failed to send SMU PowerON message\n");
2151 /* re-init the UVD block */
2152 ret
= amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
2153 AMD_PG_STATE_UNGATE
);
2156 DRM_ERROR("UVD DPM Power Gating Failed to set powergating state\n");
2160 /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */
2161 ret
= amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
2164 DRM_ERROR("UVD DPM Power Gating Failed to set clockgating state\n");
2168 cz_update_uvd_dpm(adev
, gate
);
2172 static int cz_enable_vce_dpm(struct amdgpu_device
*adev
, bool enable
)
2174 struct cz_power_info
*pi
= cz_get_pi(adev
);
2177 if (enable
&& pi
->caps_vce_dpm
) {
2178 pi
->dpm_flags
|= DPMFlags_VCE_Enabled
;
2179 DRM_DEBUG("VCE DPM Enabled.\n");
2181 ret
= cz_send_msg_to_smc_with_parameter(adev
,
2182 PPSMC_MSG_EnableAllSmuFeatures
, VCE_DPM_MASK
);
2185 pi
->dpm_flags
&= ~DPMFlags_VCE_Enabled
;
2186 DRM_DEBUG("VCE DPM Stopped\n");
2188 ret
= cz_send_msg_to_smc_with_parameter(adev
,
2189 PPSMC_MSG_DisableAllSmuFeatures
, VCE_DPM_MASK
);
2195 static int cz_update_vce_dpm(struct amdgpu_device
*adev
)
2197 struct cz_power_info
*pi
= cz_get_pi(adev
);
2198 struct amdgpu_vce_clock_voltage_dependency_table
*table
=
2199 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
2201 /* Stable Pstate is enabled and we need to set the VCE DPM to highest level */
2202 if (pi
->caps_stable_power_state
) {
2203 pi
->vce_dpm
.hard_min_clk
= table
->entries
[table
->count
-1].ecclk
;
2205 } else { /* non-stable p-state cases. without vce.Arbiter.EcclkHardMin */
2206 /* leave it as set by user */
2207 /*pi->vce_dpm.hard_min_clk = table->entries[0].ecclk;*/
2210 cz_send_msg_to_smc_with_parameter(adev
,
2211 PPSMC_MSG_SetEclkHardMin
,
2212 cz_get_eclk_level(adev
,
2213 pi
->vce_dpm
.hard_min_clk
,
2214 PPSMC_MSG_SetEclkHardMin
));
2218 static void cz_dpm_powergate_vce(struct amdgpu_device
*adev
, bool gate
)
2220 struct cz_power_info
*pi
= cz_get_pi(adev
);
2222 if (pi
->caps_vce_pg
) {
2223 if (pi
->vce_power_gated
!= gate
) {
2225 /* disable clockgating so we can properly shut down the block */
2226 amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
2227 AMD_CG_STATE_UNGATE
);
2228 /* shutdown the VCE block */
2229 amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
2232 cz_enable_vce_dpm(adev
, false);
2233 cz_send_msg_to_smc(adev
, PPSMC_MSG_VCEPowerOFF
);
2234 pi
->vce_power_gated
= true;
2236 cz_send_msg_to_smc(adev
, PPSMC_MSG_VCEPowerON
);
2237 pi
->vce_power_gated
= false;
2239 /* re-init the VCE block */
2240 amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
2241 AMD_PG_STATE_UNGATE
);
2242 /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */
2243 amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
2246 cz_update_vce_dpm(adev
);
2247 cz_enable_vce_dpm(adev
, true);
2250 if (! pi
->vce_power_gated
) {
2251 cz_update_vce_dpm(adev
);
2254 } else { /*pi->caps_vce_pg*/
2255 pi
->vce_power_gated
= gate
;
2256 cz_update_vce_dpm(adev
);
2257 cz_enable_vce_dpm(adev
, !gate
);
2261 const struct amd_ip_funcs cz_dpm_ip_funcs
= {
2263 .early_init
= cz_dpm_early_init
,
2264 .late_init
= cz_dpm_late_init
,
2265 .sw_init
= cz_dpm_sw_init
,
2266 .sw_fini
= cz_dpm_sw_fini
,
2267 .hw_init
= cz_dpm_hw_init
,
2268 .hw_fini
= cz_dpm_hw_fini
,
2269 .suspend
= cz_dpm_suspend
,
2270 .resume
= cz_dpm_resume
,
2272 .wait_for_idle
= NULL
,
2274 .set_clockgating_state
= cz_dpm_set_clockgating_state
,
2275 .set_powergating_state
= cz_dpm_set_powergating_state
,
2278 static const struct amdgpu_dpm_funcs cz_dpm_funcs
= {
2279 .get_temperature
= cz_dpm_get_temperature
,
2280 .pre_set_power_state
= cz_dpm_pre_set_power_state
,
2281 .set_power_state
= cz_dpm_set_power_state
,
2282 .post_set_power_state
= cz_dpm_post_set_power_state
,
2283 .display_configuration_changed
= cz_dpm_display_configuration_changed
,
2284 .get_sclk
= cz_dpm_get_sclk
,
2285 .get_mclk
= cz_dpm_get_mclk
,
2286 .print_power_state
= cz_dpm_print_power_state
,
2287 .debugfs_print_current_performance_level
=
2288 cz_dpm_debugfs_print_current_performance_level
,
2289 .force_performance_level
= cz_dpm_force_dpm_level
,
2290 .vblank_too_short
= NULL
,
2291 .powergate_uvd
= cz_dpm_powergate_uvd
,
2292 .powergate_vce
= cz_dpm_powergate_vce
,
2295 static void cz_dpm_set_funcs(struct amdgpu_device
*adev
)
2297 if (NULL
== adev
->pm
.funcs
)
2298 adev
->pm
.funcs
= &cz_dpm_funcs
;