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
= 0;
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 pi
->caps_sclk_ds
= true;
439 pi
->voting_clients
= 0x00c00033;
440 pi
->auto_thermal_throttling_enabled
= true;
441 pi
->bapm_enabled
= false;
442 pi
->disable_nb_ps3_in_battery
= false;
443 pi
->voltage_drop_threshold
= 0;
444 pi
->caps_sclk_throttle_low_notification
= false;
445 pi
->gfx_pg_threshold
= 500;
448 pi
->caps_uvd_pg
= (adev
->pg_flags
& AMDGPU_PG_SUPPORT_UVD
) ? true : false;
449 pi
->caps_uvd_dpm
= true;
451 pi
->caps_vce_pg
= (adev
->pg_flags
& AMDGPU_PG_SUPPORT_VCE
) ? true : false;
452 pi
->caps_vce_dpm
= true;
454 pi
->caps_acp_pg
= (adev
->pg_flags
& AMDGPU_PG_SUPPORT_ACP
) ? true : false;
455 pi
->caps_acp_dpm
= true;
457 pi
->caps_stable_power_state
= false;
458 pi
->nb_dpm_enabled_by_driver
= true;
459 pi
->nb_dpm_enabled
= false;
460 pi
->caps_voltage_island
= false;
461 /* flags which indicate need to upload pptable */
462 pi
->need_pptable_upload
= true;
464 ret
= cz_parse_sys_info_table(adev
);
468 cz_patch_voltage_values(adev
);
469 cz_construct_boot_state(adev
);
471 ret
= cz_parse_power_table(adev
);
475 ret
= cz_process_firmware_header(adev
);
479 pi
->dpm_enabled
= true;
480 pi
->uvd_dynamic_pg
= false;
485 static void cz_dpm_fini(struct amdgpu_device
*adev
)
489 for (i
= 0; i
< adev
->pm
.dpm
.num_ps
; i
++)
490 kfree(adev
->pm
.dpm
.ps
[i
].ps_priv
);
492 kfree(adev
->pm
.dpm
.ps
);
493 kfree(adev
->pm
.dpm
.priv
);
494 amdgpu_free_extended_power_table(adev
);
497 #define ixSMUSVI_NB_CURRENTVID 0xD8230044
498 #define CURRENT_NB_VID_MASK 0xff000000
499 #define CURRENT_NB_VID__SHIFT 24
500 #define ixSMUSVI_GFX_CURRENTVID 0xD8230048
501 #define CURRENT_GFX_VID_MASK 0xff000000
502 #define CURRENT_GFX_VID__SHIFT 24
505 cz_dpm_debugfs_print_current_performance_level(struct amdgpu_device
*adev
,
508 struct cz_power_info
*pi
= cz_get_pi(adev
);
509 struct amdgpu_clock_voltage_dependency_table
*table
=
510 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
511 struct amdgpu_uvd_clock_voltage_dependency_table
*uvd_table
=
512 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
513 struct amdgpu_vce_clock_voltage_dependency_table
*vce_table
=
514 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
515 u32 sclk_index
= REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX
),
516 TARGET_AND_CURRENT_PROFILE_INDEX
, CURR_SCLK_INDEX
);
517 u32 uvd_index
= REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2
),
518 TARGET_AND_CURRENT_PROFILE_INDEX_2
, CURR_UVD_INDEX
);
519 u32 vce_index
= REG_GET_FIELD(RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_2
),
520 TARGET_AND_CURRENT_PROFILE_INDEX_2
, CURR_VCE_INDEX
);
521 u32 sclk
, vclk
, dclk
, ecclk
, tmp
;
524 if (sclk_index
>= NUM_SCLK_LEVELS
) {
525 seq_printf(m
, "invalid sclk dpm profile %d\n", sclk_index
);
527 sclk
= table
->entries
[sclk_index
].clk
;
528 seq_printf(m
, "%u sclk: %u\n", sclk_index
, sclk
);
531 tmp
= (RREG32_SMC(ixSMUSVI_NB_CURRENTVID
) &
532 CURRENT_NB_VID_MASK
) >> CURRENT_NB_VID__SHIFT
;
533 vddnb
= cz_convert_8bit_index_to_voltage(adev
, (u16
)tmp
);
534 tmp
= (RREG32_SMC(ixSMUSVI_GFX_CURRENTVID
) &
535 CURRENT_GFX_VID_MASK
) >> CURRENT_GFX_VID__SHIFT
;
536 vddgfx
= cz_convert_8bit_index_to_voltage(adev
, (u16
)tmp
);
537 seq_printf(m
, "vddnb: %u vddgfx: %u\n", vddnb
, vddgfx
);
539 seq_printf(m
, "uvd %sabled\n", pi
->uvd_power_gated
? "dis" : "en");
540 if (!pi
->uvd_power_gated
) {
541 if (uvd_index
>= CZ_MAX_HARDWARE_POWERLEVELS
) {
542 seq_printf(m
, "invalid uvd dpm level %d\n", uvd_index
);
544 vclk
= uvd_table
->entries
[uvd_index
].vclk
;
545 dclk
= uvd_table
->entries
[uvd_index
].dclk
;
546 seq_printf(m
, "%u uvd vclk: %u dclk: %u\n", uvd_index
, vclk
, dclk
);
550 seq_printf(m
, "vce %sabled\n", pi
->vce_power_gated
? "dis" : "en");
551 if (!pi
->vce_power_gated
) {
552 if (vce_index
>= CZ_MAX_HARDWARE_POWERLEVELS
) {
553 seq_printf(m
, "invalid vce dpm level %d\n", vce_index
);
555 ecclk
= vce_table
->entries
[vce_index
].ecclk
;
556 seq_printf(m
, "%u vce ecclk: %u\n", vce_index
, ecclk
);
561 static void cz_dpm_print_power_state(struct amdgpu_device
*adev
,
562 struct amdgpu_ps
*rps
)
565 struct cz_ps
*ps
= cz_get_ps(rps
);
567 amdgpu_dpm_print_class_info(rps
->class, rps
->class2
);
568 amdgpu_dpm_print_cap_info(rps
->caps
);
570 DRM_INFO("\tuvd vclk: %d dclk: %d\n", rps
->vclk
, rps
->dclk
);
571 for (i
= 0; i
< ps
->num_levels
; i
++) {
572 struct cz_pl
*pl
= &ps
->levels
[i
];
574 DRM_INFO("\t\tpower level %d sclk: %u vddc: %u\n",
576 cz_convert_8bit_index_to_voltage(adev
, pl
->vddc_index
));
579 amdgpu_dpm_print_ps_status(adev
, rps
);
582 static void cz_dpm_set_funcs(struct amdgpu_device
*adev
);
584 static int cz_dpm_early_init(void *handle
)
586 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
588 cz_dpm_set_funcs(adev
);
594 static int cz_dpm_late_init(void *handle
)
596 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
600 /* init the sysfs and debugfs files late */
601 ret
= amdgpu_pm_sysfs_init(adev
);
605 /* powerdown unused blocks for now */
606 cz_dpm_powergate_uvd(adev
, true);
607 cz_dpm_powergate_vce(adev
, true);
613 static int cz_dpm_sw_init(void *handle
)
615 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
617 /* fix me to add thermal support TODO */
619 /* default to balanced state */
620 adev
->pm
.dpm
.state
= POWER_STATE_TYPE_BALANCED
;
621 adev
->pm
.dpm
.user_state
= POWER_STATE_TYPE_BALANCED
;
622 adev
->pm
.dpm
.forced_level
= AMDGPU_DPM_FORCED_LEVEL_AUTO
;
623 adev
->pm
.default_sclk
= adev
->clock
.default_sclk
;
624 adev
->pm
.default_mclk
= adev
->clock
.default_mclk
;
625 adev
->pm
.current_sclk
= adev
->clock
.default_sclk
;
626 adev
->pm
.current_mclk
= adev
->clock
.default_mclk
;
627 adev
->pm
.int_thermal_type
= THERMAL_TYPE_NONE
;
632 mutex_lock(&adev
->pm
.mutex
);
633 ret
= cz_dpm_init(adev
);
635 goto dpm_init_failed
;
637 adev
->pm
.dpm
.current_ps
= adev
->pm
.dpm
.requested_ps
= adev
->pm
.dpm
.boot_ps
;
639 amdgpu_pm_print_power_states(adev
);
641 mutex_unlock(&adev
->pm
.mutex
);
642 DRM_INFO("amdgpu: dpm initialized\n");
648 mutex_unlock(&adev
->pm
.mutex
);
649 DRM_ERROR("amdgpu: dpm initialization failed\n");
654 static int cz_dpm_sw_fini(void *handle
)
656 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
658 mutex_lock(&adev
->pm
.mutex
);
659 amdgpu_pm_sysfs_fini(adev
);
661 mutex_unlock(&adev
->pm
.mutex
);
666 static void cz_reset_ap_mask(struct amdgpu_device
*adev
)
668 struct cz_power_info
*pi
= cz_get_pi(adev
);
670 pi
->active_process_mask
= 0;
674 static int cz_dpm_download_pptable_from_smu(struct amdgpu_device
*adev
,
679 ret
= cz_smu_download_pptable(adev
, table
);
684 static int cz_dpm_upload_pptable_to_smu(struct amdgpu_device
*adev
)
686 struct cz_power_info
*pi
= cz_get_pi(adev
);
687 struct SMU8_Fusion_ClkTable
*clock_table
;
688 struct atom_clock_dividers dividers
;
693 struct amdgpu_clock_voltage_dependency_table
*vddc_table
=
694 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
695 struct amdgpu_clock_voltage_dependency_table
*vddgfx_table
=
696 &adev
->pm
.dpm
.dyn_state
.vddgfx_dependency_on_sclk
;
697 struct amdgpu_uvd_clock_voltage_dependency_table
*uvd_table
=
698 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
699 struct amdgpu_vce_clock_voltage_dependency_table
*vce_table
=
700 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
701 struct amdgpu_clock_voltage_dependency_table
*acp_table
=
702 &adev
->pm
.dpm
.dyn_state
.acp_clock_voltage_dependency_table
;
704 if (!pi
->need_pptable_upload
)
707 ret
= cz_dpm_download_pptable_from_smu(adev
, &table
);
709 DRM_ERROR("amdgpu: Failed to get power play table from SMU!\n");
713 clock_table
= (struct SMU8_Fusion_ClkTable
*)table
;
714 /* patch clock table */
715 if (vddc_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
716 vddgfx_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
717 uvd_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
718 vce_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
||
719 acp_table
->count
> CZ_MAX_HARDWARE_POWERLEVELS
) {
720 DRM_ERROR("amdgpu: Invalid Clock Voltage Dependency Table!\n");
724 for (i
= 0; i
< CZ_MAX_HARDWARE_POWERLEVELS
; i
++) {
727 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].GnbVid
=
728 (i
< vddc_table
->count
) ? (uint8_t)vddc_table
->entries
[i
].v
: 0;
729 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].Frequency
=
730 (i
< vddc_table
->count
) ? vddc_table
->entries
[i
].clk
: 0;
731 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
732 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].Frequency
,
736 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
737 (uint8_t)dividers
.post_divider
;
740 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
741 (i
< vddgfx_table
->count
) ? (uint8_t)vddgfx_table
->entries
[i
].v
: 0;
744 clock_table
->AclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
745 (i
< acp_table
->count
) ? (uint8_t)acp_table
->entries
[i
].v
: 0;
746 clock_table
->AclkBreakdownTable
.ClkLevel
[i
].Frequency
=
747 (i
< acp_table
->count
) ? acp_table
->entries
[i
].clk
: 0;
748 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
749 clock_table
->SclkBreakdownTable
.ClkLevel
[i
].Frequency
,
753 clock_table
->AclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
754 (uint8_t)dividers
.post_divider
;
757 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
758 (i
< uvd_table
->count
) ? (uint8_t)uvd_table
->entries
[i
].v
: 0;
759 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].Frequency
=
760 (i
< uvd_table
->count
) ? uvd_table
->entries
[i
].vclk
: 0;
761 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
762 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].Frequency
,
766 clock_table
->VclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
767 (uint8_t)dividers
.post_divider
;
769 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
770 (i
< uvd_table
->count
) ? (uint8_t)uvd_table
->entries
[i
].v
: 0;
771 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].Frequency
=
772 (i
< uvd_table
->count
) ? uvd_table
->entries
[i
].dclk
: 0;
773 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
774 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].Frequency
,
778 clock_table
->DclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
779 (uint8_t)dividers
.post_divider
;
782 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].GfxVid
=
783 (i
< vce_table
->count
) ? (uint8_t)vce_table
->entries
[i
].v
: 0;
784 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].Frequency
=
785 (i
< vce_table
->count
) ? vce_table
->entries
[i
].ecclk
: 0;
786 ret
= amdgpu_atombios_get_clock_dividers(adev
, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK
,
787 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].Frequency
,
791 clock_table
->EclkBreakdownTable
.ClkLevel
[i
].DfsDid
=
792 (uint8_t)dividers
.post_divider
;
795 /* its time to upload to SMU */
796 ret
= cz_smu_upload_pptable(adev
);
798 DRM_ERROR("amdgpu: Failed to put power play table to SMU!\n");
805 static void cz_init_sclk_limit(struct amdgpu_device
*adev
)
807 struct cz_power_info
*pi
= cz_get_pi(adev
);
808 struct amdgpu_clock_voltage_dependency_table
*table
=
809 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
810 uint32_t clock
= 0, level
;
812 if (!table
|| !table
->count
) {
813 DRM_ERROR("Invalid Voltage Dependency table.\n");
817 pi
->sclk_dpm
.soft_min_clk
= 0;
818 pi
->sclk_dpm
.hard_min_clk
= 0;
819 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxSclkLevel
);
820 level
= cz_get_argument(adev
);
821 if (level
< table
->count
)
822 clock
= table
->entries
[level
].clk
;
824 DRM_ERROR("Invalid SLCK Voltage Dependency table entry.\n");
825 clock
= table
->entries
[table
->count
- 1].clk
;
828 pi
->sclk_dpm
.soft_max_clk
= clock
;
829 pi
->sclk_dpm
.hard_max_clk
= clock
;
833 static void cz_init_uvd_limit(struct amdgpu_device
*adev
)
835 struct cz_power_info
*pi
= cz_get_pi(adev
);
836 struct amdgpu_uvd_clock_voltage_dependency_table
*table
=
837 &adev
->pm
.dpm
.dyn_state
.uvd_clock_voltage_dependency_table
;
838 uint32_t clock
= 0, level
;
840 if (!table
|| !table
->count
) {
841 DRM_ERROR("Invalid Voltage Dependency table.\n");
845 pi
->uvd_dpm
.soft_min_clk
= 0;
846 pi
->uvd_dpm
.hard_min_clk
= 0;
847 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxUvdLevel
);
848 level
= cz_get_argument(adev
);
849 if (level
< table
->count
)
850 clock
= table
->entries
[level
].vclk
;
852 DRM_ERROR("Invalid UVD Voltage Dependency table entry.\n");
853 clock
= table
->entries
[table
->count
- 1].vclk
;
856 pi
->uvd_dpm
.soft_max_clk
= clock
;
857 pi
->uvd_dpm
.hard_max_clk
= clock
;
861 static void cz_init_vce_limit(struct amdgpu_device
*adev
)
863 struct cz_power_info
*pi
= cz_get_pi(adev
);
864 struct amdgpu_vce_clock_voltage_dependency_table
*table
=
865 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
866 uint32_t clock
= 0, level
;
868 if (!table
|| !table
->count
) {
869 DRM_ERROR("Invalid Voltage Dependency table.\n");
873 pi
->vce_dpm
.soft_min_clk
= table
->entries
[0].ecclk
;
874 pi
->vce_dpm
.hard_min_clk
= table
->entries
[0].ecclk
;
875 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxEclkLevel
);
876 level
= cz_get_argument(adev
);
877 if (level
< table
->count
)
878 clock
= table
->entries
[level
].ecclk
;
880 /* future BIOS would fix this error */
881 DRM_ERROR("Invalid VCE Voltage Dependency table entry.\n");
882 clock
= table
->entries
[table
->count
- 1].ecclk
;
885 pi
->vce_dpm
.soft_max_clk
= clock
;
886 pi
->vce_dpm
.hard_max_clk
= clock
;
890 static void cz_init_acp_limit(struct amdgpu_device
*adev
)
892 struct cz_power_info
*pi
= cz_get_pi(adev
);
893 struct amdgpu_clock_voltage_dependency_table
*table
=
894 &adev
->pm
.dpm
.dyn_state
.acp_clock_voltage_dependency_table
;
895 uint32_t clock
= 0, level
;
897 if (!table
|| !table
->count
) {
898 DRM_ERROR("Invalid Voltage Dependency table.\n");
902 pi
->acp_dpm
.soft_min_clk
= 0;
903 pi
->acp_dpm
.hard_min_clk
= 0;
904 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxAclkLevel
);
905 level
= cz_get_argument(adev
);
906 if (level
< table
->count
)
907 clock
= table
->entries
[level
].clk
;
909 DRM_ERROR("Invalid ACP Voltage Dependency table entry.\n");
910 clock
= table
->entries
[table
->count
- 1].clk
;
913 pi
->acp_dpm
.soft_max_clk
= clock
;
914 pi
->acp_dpm
.hard_max_clk
= clock
;
918 static void cz_init_pg_state(struct amdgpu_device
*adev
)
920 struct cz_power_info
*pi
= cz_get_pi(adev
);
922 pi
->uvd_power_gated
= false;
923 pi
->vce_power_gated
= false;
924 pi
->acp_power_gated
= false;
928 static void cz_init_sclk_threshold(struct amdgpu_device
*adev
)
930 struct cz_power_info
*pi
= cz_get_pi(adev
);
932 pi
->low_sclk_interrupt_threshold
= 0;
936 static void cz_dpm_setup_asic(struct amdgpu_device
*adev
)
938 cz_reset_ap_mask(adev
);
939 cz_dpm_upload_pptable_to_smu(adev
);
940 cz_init_sclk_limit(adev
);
941 cz_init_uvd_limit(adev
);
942 cz_init_vce_limit(adev
);
943 cz_init_acp_limit(adev
);
944 cz_init_pg_state(adev
);
945 cz_init_sclk_threshold(adev
);
949 static bool cz_check_smu_feature(struct amdgpu_device
*adev
,
952 uint32_t smu_feature
= 0;
955 ret
= cz_send_msg_to_smc_with_parameter(adev
,
956 PPSMC_MSG_GetFeatureStatus
, 0);
958 DRM_ERROR("Failed to get SMU features from SMC.\n");
961 smu_feature
= cz_get_argument(adev
);
962 if (feature
& smu_feature
)
969 static bool cz_check_for_dpm_enabled(struct amdgpu_device
*adev
)
971 if (cz_check_smu_feature(adev
,
972 SMU_EnabledFeatureScoreboard_SclkDpmOn
))
978 static void cz_program_voting_clients(struct amdgpu_device
*adev
)
980 WREG32_SMC(ixCG_FREQ_TRAN_VOTING_0
, PPCZ_VOTINGRIGHTSCLIENTS_DFLT0
);
983 static void cz_clear_voting_clients(struct amdgpu_device
*adev
)
985 WREG32_SMC(ixCG_FREQ_TRAN_VOTING_0
, 0);
988 static int cz_start_dpm(struct amdgpu_device
*adev
)
993 ret
= cz_send_msg_to_smc_with_parameter(adev
,
994 PPSMC_MSG_EnableAllSmuFeatures
, SCLK_DPM_MASK
);
996 DRM_ERROR("SMU feature: SCLK_DPM enable failed\n");
1004 static int cz_stop_dpm(struct amdgpu_device
*adev
)
1008 if (amdgpu_dpm
&& adev
->pm
.dpm_enabled
) {
1009 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1010 PPSMC_MSG_DisableAllSmuFeatures
, SCLK_DPM_MASK
);
1012 DRM_ERROR("SMU feature: SCLK_DPM disable failed\n");
1020 static uint32_t cz_get_sclk_level(struct amdgpu_device
*adev
,
1021 uint32_t clock
, uint16_t msg
)
1024 struct amdgpu_clock_voltage_dependency_table
*table
=
1025 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
1028 case PPSMC_MSG_SetSclkSoftMin
:
1029 case PPSMC_MSG_SetSclkHardMin
:
1030 for (i
= 0; i
< table
->count
; i
++)
1031 if (clock
<= table
->entries
[i
].clk
)
1033 if (i
== table
->count
)
1034 i
= table
->count
- 1;
1036 case PPSMC_MSG_SetSclkSoftMax
:
1037 case PPSMC_MSG_SetSclkHardMax
:
1038 for (i
= table
->count
- 1; i
>= 0; i
--)
1039 if (clock
>= table
->entries
[i
].clk
)
1051 static uint32_t cz_get_eclk_level(struct amdgpu_device
*adev
,
1052 uint32_t clock
, uint16_t msg
)
1055 struct amdgpu_vce_clock_voltage_dependency_table
*table
=
1056 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
1058 if (table
->count
== 0)
1062 case PPSMC_MSG_SetEclkSoftMin
:
1063 case PPSMC_MSG_SetEclkHardMin
:
1064 for (i
= 0; i
< table
->count
-1; i
++)
1065 if (clock
<= table
->entries
[i
].ecclk
)
1068 case PPSMC_MSG_SetEclkSoftMax
:
1069 case PPSMC_MSG_SetEclkHardMax
:
1070 for (i
= table
->count
- 1; i
> 0; i
--)
1071 if (clock
>= table
->entries
[i
].ecclk
)
1081 static int cz_program_bootup_state(struct amdgpu_device
*adev
)
1083 struct cz_power_info
*pi
= cz_get_pi(adev
);
1084 uint32_t soft_min_clk
= 0;
1085 uint32_t soft_max_clk
= 0;
1088 pi
->sclk_dpm
.soft_min_clk
= pi
->sys_info
.bootup_sclk
;
1089 pi
->sclk_dpm
.soft_max_clk
= pi
->sys_info
.bootup_sclk
;
1091 soft_min_clk
= cz_get_sclk_level(adev
,
1092 pi
->sclk_dpm
.soft_min_clk
,
1093 PPSMC_MSG_SetSclkSoftMin
);
1094 soft_max_clk
= cz_get_sclk_level(adev
,
1095 pi
->sclk_dpm
.soft_max_clk
,
1096 PPSMC_MSG_SetSclkSoftMax
);
1098 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1099 PPSMC_MSG_SetSclkSoftMin
, soft_min_clk
);
1103 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1104 PPSMC_MSG_SetSclkSoftMax
, soft_max_clk
);
1112 static int cz_disable_cgpg(struct amdgpu_device
*adev
)
1118 static int cz_enable_cgpg(struct amdgpu_device
*adev
)
1124 static int cz_program_pt_config_registers(struct amdgpu_device
*adev
)
1129 static void cz_do_enable_didt(struct amdgpu_device
*adev
, bool enable
)
1131 struct cz_power_info
*pi
= cz_get_pi(adev
);
1134 if (pi
->caps_sq_ramping
) {
1135 reg
= RREG32_DIDT(ixDIDT_SQ_CTRL0
);
1137 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 1);
1139 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 0);
1140 WREG32_DIDT(ixDIDT_SQ_CTRL0
, reg
);
1142 if (pi
->caps_db_ramping
) {
1143 reg
= RREG32_DIDT(ixDIDT_DB_CTRL0
);
1145 reg
= REG_SET_FIELD(reg
, DIDT_DB_CTRL0
, DIDT_CTRL_EN
, 1);
1147 reg
= REG_SET_FIELD(reg
, DIDT_DB_CTRL0
, DIDT_CTRL_EN
, 0);
1148 WREG32_DIDT(ixDIDT_DB_CTRL0
, reg
);
1150 if (pi
->caps_td_ramping
) {
1151 reg
= RREG32_DIDT(ixDIDT_TD_CTRL0
);
1153 reg
= REG_SET_FIELD(reg
, DIDT_TD_CTRL0
, DIDT_CTRL_EN
, 1);
1155 reg
= REG_SET_FIELD(reg
, DIDT_TD_CTRL0
, DIDT_CTRL_EN
, 0);
1156 WREG32_DIDT(ixDIDT_TD_CTRL0
, reg
);
1158 if (pi
->caps_tcp_ramping
) {
1159 reg
= RREG32_DIDT(ixDIDT_TCP_CTRL0
);
1161 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 1);
1163 reg
= REG_SET_FIELD(reg
, DIDT_SQ_CTRL0
, DIDT_CTRL_EN
, 0);
1164 WREG32_DIDT(ixDIDT_TCP_CTRL0
, reg
);
1169 static int cz_enable_didt(struct amdgpu_device
*adev
, bool enable
)
1171 struct cz_power_info
*pi
= cz_get_pi(adev
);
1174 if (pi
->caps_sq_ramping
|| pi
->caps_db_ramping
||
1175 pi
->caps_td_ramping
|| pi
->caps_tcp_ramping
) {
1176 if (adev
->gfx
.gfx_current_status
!= AMDGPU_GFX_SAFE_MODE
) {
1177 ret
= cz_disable_cgpg(adev
);
1179 DRM_ERROR("Pre Di/Dt disable cg/pg failed\n");
1182 adev
->gfx
.gfx_current_status
= AMDGPU_GFX_SAFE_MODE
;
1185 ret
= cz_program_pt_config_registers(adev
);
1187 DRM_ERROR("Di/Dt config failed\n");
1190 cz_do_enable_didt(adev
, enable
);
1192 if (adev
->gfx
.gfx_current_status
== AMDGPU_GFX_SAFE_MODE
) {
1193 ret
= cz_enable_cgpg(adev
);
1195 DRM_ERROR("Post Di/Dt enable cg/pg failed\n");
1198 adev
->gfx
.gfx_current_status
= AMDGPU_GFX_NORMAL_MODE
;
1206 static void cz_reset_acp_boot_level(struct amdgpu_device
*adev
)
1210 static void cz_update_current_ps(struct amdgpu_device
*adev
,
1211 struct amdgpu_ps
*rps
)
1213 struct cz_power_info
*pi
= cz_get_pi(adev
);
1214 struct cz_ps
*ps
= cz_get_ps(rps
);
1216 pi
->current_ps
= *ps
;
1217 pi
->current_rps
= *rps
;
1218 pi
->current_rps
.ps_priv
= ps
;
1222 static void cz_update_requested_ps(struct amdgpu_device
*adev
,
1223 struct amdgpu_ps
*rps
)
1225 struct cz_power_info
*pi
= cz_get_pi(adev
);
1226 struct cz_ps
*ps
= cz_get_ps(rps
);
1228 pi
->requested_ps
= *ps
;
1229 pi
->requested_rps
= *rps
;
1230 pi
->requested_rps
.ps_priv
= ps
;
1234 /* PP arbiter support needed TODO */
1235 static void cz_apply_state_adjust_rules(struct amdgpu_device
*adev
,
1236 struct amdgpu_ps
*new_rps
,
1237 struct amdgpu_ps
*old_rps
)
1239 struct cz_ps
*ps
= cz_get_ps(new_rps
);
1240 struct cz_power_info
*pi
= cz_get_pi(adev
);
1241 struct amdgpu_clock_and_voltage_limits
*limits
=
1242 &adev
->pm
.dpm
.dyn_state
.max_clock_voltage_on_ac
;
1243 /* 10kHz memory clock */
1246 ps
->force_high
= false;
1247 ps
->need_dfs_bypass
= true;
1248 pi
->video_start
= new_rps
->dclk
|| new_rps
->vclk
||
1249 new_rps
->evclk
|| new_rps
->ecclk
;
1251 if ((new_rps
->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK
) ==
1252 ATOM_PPLIB_CLASSIFICATION_UI_BATTERY
)
1253 pi
->battery_state
= true;
1255 pi
->battery_state
= false;
1257 if (pi
->caps_stable_power_state
)
1258 mclk
= limits
->mclk
;
1260 if (mclk
> pi
->sys_info
.nbp_memory_clock
[CZ_NUM_NBPMEMORY_CLOCK
- 1])
1261 ps
->force_high
= true;
1265 static int cz_dpm_enable(struct amdgpu_device
*adev
)
1267 const char *chip_name
;
1270 /* renable will hang up SMU, so check first */
1271 if (cz_check_for_dpm_enabled(adev
))
1274 cz_program_voting_clients(adev
);
1276 switch (adev
->asic_type
) {
1278 chip_name
= "carrizo";
1281 chip_name
= "stoney";
1288 ret
= cz_start_dpm(adev
);
1290 DRM_ERROR("%s DPM enable failed\n", chip_name
);
1294 ret
= cz_program_bootup_state(adev
);
1296 DRM_ERROR("%s bootup state program failed\n", chip_name
);
1300 ret
= cz_enable_didt(adev
, true);
1302 DRM_ERROR("%s enable di/dt failed\n", chip_name
);
1306 cz_reset_acp_boot_level(adev
);
1308 cz_update_current_ps(adev
, adev
->pm
.dpm
.boot_ps
);
1313 static int cz_dpm_hw_init(void *handle
)
1315 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1318 mutex_lock(&adev
->pm
.mutex
);
1320 /* smu init only needs to be called at startup, not resume.
1321 * It should be in sw_init, but requires the fw info gathered
1322 * in sw_init from other IP modules.
1324 ret
= cz_smu_init(adev
);
1326 DRM_ERROR("amdgpu: smc initialization failed\n");
1327 mutex_unlock(&adev
->pm
.mutex
);
1331 /* do the actual fw loading */
1332 ret
= cz_smu_start(adev
);
1334 DRM_ERROR("amdgpu: smc start failed\n");
1335 mutex_unlock(&adev
->pm
.mutex
);
1340 adev
->pm
.dpm_enabled
= false;
1341 mutex_unlock(&adev
->pm
.mutex
);
1345 /* cz dpm setup asic */
1346 cz_dpm_setup_asic(adev
);
1349 ret
= cz_dpm_enable(adev
);
1351 adev
->pm
.dpm_enabled
= false;
1353 adev
->pm
.dpm_enabled
= true;
1355 mutex_unlock(&adev
->pm
.mutex
);
1360 static int cz_dpm_disable(struct amdgpu_device
*adev
)
1364 if (!cz_check_for_dpm_enabled(adev
))
1367 ret
= cz_enable_didt(adev
, false);
1369 DRM_ERROR("disable di/dt failed\n");
1373 /* powerup blocks */
1374 cz_dpm_powergate_uvd(adev
, false);
1375 cz_dpm_powergate_vce(adev
, false);
1377 cz_clear_voting_clients(adev
);
1379 cz_update_current_ps(adev
, adev
->pm
.dpm
.boot_ps
);
1384 static int cz_dpm_hw_fini(void *handle
)
1387 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1389 mutex_lock(&adev
->pm
.mutex
);
1391 /* smu fini only needs to be called at teardown, not suspend.
1392 * It should be in sw_fini, but we put it here for symmetry
1397 if (adev
->pm
.dpm_enabled
) {
1398 ret
= cz_dpm_disable(adev
);
1400 adev
->pm
.dpm
.current_ps
=
1401 adev
->pm
.dpm
.requested_ps
=
1402 adev
->pm
.dpm
.boot_ps
;
1405 adev
->pm
.dpm_enabled
= false;
1407 mutex_unlock(&adev
->pm
.mutex
);
1412 static int cz_dpm_suspend(void *handle
)
1415 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1417 if (adev
->pm
.dpm_enabled
) {
1418 mutex_lock(&adev
->pm
.mutex
);
1420 ret
= cz_dpm_disable(adev
);
1422 adev
->pm
.dpm
.current_ps
=
1423 adev
->pm
.dpm
.requested_ps
=
1424 adev
->pm
.dpm
.boot_ps
;
1426 mutex_unlock(&adev
->pm
.mutex
);
1432 static int cz_dpm_resume(void *handle
)
1435 struct amdgpu_device
*adev
= (struct amdgpu_device
*)handle
;
1437 mutex_lock(&adev
->pm
.mutex
);
1439 /* do the actual fw loading */
1440 ret
= cz_smu_start(adev
);
1442 DRM_ERROR("amdgpu: smc start failed\n");
1443 mutex_unlock(&adev
->pm
.mutex
);
1448 adev
->pm
.dpm_enabled
= false;
1449 mutex_unlock(&adev
->pm
.mutex
);
1453 /* cz dpm setup asic */
1454 cz_dpm_setup_asic(adev
);
1457 ret
= cz_dpm_enable(adev
);
1459 adev
->pm
.dpm_enabled
= false;
1461 adev
->pm
.dpm_enabled
= true;
1463 mutex_unlock(&adev
->pm
.mutex
);
1464 /* upon resume, re-compute the clocks */
1465 if (adev
->pm
.dpm_enabled
)
1466 amdgpu_pm_compute_clocks(adev
);
1471 static int cz_dpm_set_clockgating_state(void *handle
,
1472 enum amd_clockgating_state state
)
1477 static int cz_dpm_set_powergating_state(void *handle
,
1478 enum amd_powergating_state state
)
1483 /* borrowed from KV, need future unify */
1484 static int cz_dpm_get_temperature(struct amdgpu_device
*adev
)
1486 int actual_temp
= 0;
1487 uint32_t temp
= RREG32_SMC(0xC0300E0C);
1490 actual_temp
= 1000 * ((temp
/ 8) - 49);
1495 static int cz_dpm_pre_set_power_state(struct amdgpu_device
*adev
)
1497 struct cz_power_info
*pi
= cz_get_pi(adev
);
1498 struct amdgpu_ps requested_ps
= *adev
->pm
.dpm
.requested_ps
;
1499 struct amdgpu_ps
*new_ps
= &requested_ps
;
1501 cz_update_requested_ps(adev
, new_ps
);
1502 cz_apply_state_adjust_rules(adev
, &pi
->requested_rps
,
1508 static int cz_dpm_update_sclk_limit(struct amdgpu_device
*adev
)
1510 struct cz_power_info
*pi
= cz_get_pi(adev
);
1511 struct amdgpu_clock_and_voltage_limits
*limits
=
1512 &adev
->pm
.dpm
.dyn_state
.max_clock_voltage_on_ac
;
1513 uint32_t clock
, stable_ps_clock
= 0;
1515 clock
= pi
->sclk_dpm
.soft_min_clk
;
1517 if (pi
->caps_stable_power_state
) {
1518 stable_ps_clock
= limits
->sclk
* 75 / 100;
1519 if (clock
< stable_ps_clock
)
1520 clock
= stable_ps_clock
;
1523 if (clock
!= pi
->sclk_dpm
.soft_min_clk
) {
1524 pi
->sclk_dpm
.soft_min_clk
= clock
;
1525 cz_send_msg_to_smc_with_parameter(adev
,
1526 PPSMC_MSG_SetSclkSoftMin
,
1527 cz_get_sclk_level(adev
, clock
,
1528 PPSMC_MSG_SetSclkSoftMin
));
1531 if (pi
->caps_stable_power_state
&&
1532 pi
->sclk_dpm
.soft_max_clk
!= clock
) {
1533 pi
->sclk_dpm
.soft_max_clk
= clock
;
1534 cz_send_msg_to_smc_with_parameter(adev
,
1535 PPSMC_MSG_SetSclkSoftMax
,
1536 cz_get_sclk_level(adev
, clock
,
1537 PPSMC_MSG_SetSclkSoftMax
));
1539 cz_send_msg_to_smc_with_parameter(adev
,
1540 PPSMC_MSG_SetSclkSoftMax
,
1541 cz_get_sclk_level(adev
,
1542 pi
->sclk_dpm
.soft_max_clk
,
1543 PPSMC_MSG_SetSclkSoftMax
));
1549 static int cz_dpm_set_deep_sleep_sclk_threshold(struct amdgpu_device
*adev
)
1552 struct cz_power_info
*pi
= cz_get_pi(adev
);
1554 if (pi
->caps_sclk_ds
) {
1555 cz_send_msg_to_smc_with_parameter(adev
,
1556 PPSMC_MSG_SetMinDeepSleepSclk
,
1557 CZ_MIN_DEEP_SLEEP_SCLK
);
1563 /* ?? without dal support, is this still needed in setpowerstate list*/
1564 static int cz_dpm_set_watermark_threshold(struct amdgpu_device
*adev
)
1567 struct cz_power_info
*pi
= cz_get_pi(adev
);
1569 cz_send_msg_to_smc_with_parameter(adev
,
1570 PPSMC_MSG_SetWatermarkFrequency
,
1571 pi
->sclk_dpm
.soft_max_clk
);
1576 static int cz_dpm_enable_nbdpm(struct amdgpu_device
*adev
)
1579 struct cz_power_info
*pi
= cz_get_pi(adev
);
1581 /* also depend on dal NBPStateDisableRequired */
1582 if (pi
->nb_dpm_enabled_by_driver
&& !pi
->nb_dpm_enabled
) {
1583 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1584 PPSMC_MSG_EnableAllSmuFeatures
,
1587 DRM_ERROR("amdgpu: nb dpm enable failed\n");
1590 pi
->nb_dpm_enabled
= true;
1596 static void cz_dpm_nbdpm_lm_pstate_enable(struct amdgpu_device
*adev
,
1600 cz_send_msg_to_smc(adev
, PPSMC_MSG_EnableLowMemoryPstate
);
1602 cz_send_msg_to_smc(adev
, PPSMC_MSG_DisableLowMemoryPstate
);
1606 static int cz_dpm_update_low_memory_pstate(struct amdgpu_device
*adev
)
1609 struct cz_power_info
*pi
= cz_get_pi(adev
);
1610 struct cz_ps
*ps
= &pi
->requested_ps
;
1612 if (pi
->sys_info
.nb_dpm_enable
) {
1614 cz_dpm_nbdpm_lm_pstate_enable(adev
, false);
1616 cz_dpm_nbdpm_lm_pstate_enable(adev
, true);
1622 /* with dpm enabled */
1623 static int cz_dpm_set_power_state(struct amdgpu_device
*adev
)
1627 cz_dpm_update_sclk_limit(adev
);
1628 cz_dpm_set_deep_sleep_sclk_threshold(adev
);
1629 cz_dpm_set_watermark_threshold(adev
);
1630 cz_dpm_enable_nbdpm(adev
);
1631 cz_dpm_update_low_memory_pstate(adev
);
1636 static void cz_dpm_post_set_power_state(struct amdgpu_device
*adev
)
1638 struct cz_power_info
*pi
= cz_get_pi(adev
);
1639 struct amdgpu_ps
*ps
= &pi
->requested_rps
;
1641 cz_update_current_ps(adev
, ps
);
1645 static int cz_dpm_force_highest(struct amdgpu_device
*adev
)
1647 struct cz_power_info
*pi
= cz_get_pi(adev
);
1650 if (pi
->sclk_dpm
.soft_min_clk
!= pi
->sclk_dpm
.soft_max_clk
) {
1651 pi
->sclk_dpm
.soft_min_clk
=
1652 pi
->sclk_dpm
.soft_max_clk
;
1653 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1654 PPSMC_MSG_SetSclkSoftMin
,
1655 cz_get_sclk_level(adev
,
1656 pi
->sclk_dpm
.soft_min_clk
,
1657 PPSMC_MSG_SetSclkSoftMin
));
1665 static int cz_dpm_force_lowest(struct amdgpu_device
*adev
)
1667 struct cz_power_info
*pi
= cz_get_pi(adev
);
1670 if (pi
->sclk_dpm
.soft_max_clk
!= pi
->sclk_dpm
.soft_min_clk
) {
1671 pi
->sclk_dpm
.soft_max_clk
= pi
->sclk_dpm
.soft_min_clk
;
1672 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1673 PPSMC_MSG_SetSclkSoftMax
,
1674 cz_get_sclk_level(adev
,
1675 pi
->sclk_dpm
.soft_max_clk
,
1676 PPSMC_MSG_SetSclkSoftMax
));
1684 static uint32_t cz_dpm_get_max_sclk_level(struct amdgpu_device
*adev
)
1686 struct cz_power_info
*pi
= cz_get_pi(adev
);
1688 if (!pi
->max_sclk_level
) {
1689 cz_send_msg_to_smc(adev
, PPSMC_MSG_GetMaxSclkLevel
);
1690 pi
->max_sclk_level
= cz_get_argument(adev
) + 1;
1693 if (pi
->max_sclk_level
> CZ_MAX_HARDWARE_POWERLEVELS
) {
1694 DRM_ERROR("Invalid max sclk level!\n");
1698 return pi
->max_sclk_level
;
1701 static int cz_dpm_unforce_dpm_levels(struct amdgpu_device
*adev
)
1703 struct cz_power_info
*pi
= cz_get_pi(adev
);
1704 struct amdgpu_clock_voltage_dependency_table
*dep_table
=
1705 &adev
->pm
.dpm
.dyn_state
.vddc_dependency_on_sclk
;
1709 pi
->sclk_dpm
.soft_min_clk
= dep_table
->entries
[0].clk
;
1710 level
= cz_dpm_get_max_sclk_level(adev
) - 1;
1711 if (level
< dep_table
->count
)
1712 pi
->sclk_dpm
.soft_max_clk
= dep_table
->entries
[level
].clk
;
1714 pi
->sclk_dpm
.soft_max_clk
=
1715 dep_table
->entries
[dep_table
->count
- 1].clk
;
1717 /* get min/max sclk soft value
1718 * notify SMU to execute */
1719 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1720 PPSMC_MSG_SetSclkSoftMin
,
1721 cz_get_sclk_level(adev
,
1722 pi
->sclk_dpm
.soft_min_clk
,
1723 PPSMC_MSG_SetSclkSoftMin
));
1727 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1728 PPSMC_MSG_SetSclkSoftMax
,
1729 cz_get_sclk_level(adev
,
1730 pi
->sclk_dpm
.soft_max_clk
,
1731 PPSMC_MSG_SetSclkSoftMax
));
1735 DRM_DEBUG("DPM unforce state min=%d, max=%d.\n",
1736 pi
->sclk_dpm
.soft_min_clk
,
1737 pi
->sclk_dpm
.soft_max_clk
);
1742 static int cz_dpm_force_dpm_level(struct amdgpu_device
*adev
,
1743 enum amdgpu_dpm_forced_level level
)
1748 case AMDGPU_DPM_FORCED_LEVEL_HIGH
:
1749 ret
= cz_dpm_unforce_dpm_levels(adev
);
1752 ret
= cz_dpm_force_highest(adev
);
1756 case AMDGPU_DPM_FORCED_LEVEL_LOW
:
1757 ret
= cz_dpm_unforce_dpm_levels(adev
);
1760 ret
= cz_dpm_force_lowest(adev
);
1764 case AMDGPU_DPM_FORCED_LEVEL_AUTO
:
1765 ret
= cz_dpm_unforce_dpm_levels(adev
);
1773 adev
->pm
.dpm
.forced_level
= level
;
1778 /* fix me, display configuration change lists here
1779 * mostly dal related*/
1780 static void cz_dpm_display_configuration_changed(struct amdgpu_device
*adev
)
1784 static uint32_t cz_dpm_get_sclk(struct amdgpu_device
*adev
, bool low
)
1786 struct cz_power_info
*pi
= cz_get_pi(adev
);
1787 struct cz_ps
*requested_state
= cz_get_ps(&pi
->requested_rps
);
1790 return requested_state
->levels
[0].sclk
;
1792 return requested_state
->levels
[requested_state
->num_levels
- 1].sclk
;
1796 static uint32_t cz_dpm_get_mclk(struct amdgpu_device
*adev
, bool low
)
1798 struct cz_power_info
*pi
= cz_get_pi(adev
);
1800 return pi
->sys_info
.bootup_uma_clk
;
1803 static int cz_enable_uvd_dpm(struct amdgpu_device
*adev
, bool enable
)
1805 struct cz_power_info
*pi
= cz_get_pi(adev
);
1808 if (enable
&& pi
->caps_uvd_dpm
) {
1809 pi
->dpm_flags
|= DPMFlags_UVD_Enabled
;
1810 DRM_DEBUG("UVD DPM Enabled.\n");
1812 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1813 PPSMC_MSG_EnableAllSmuFeatures
, UVD_DPM_MASK
);
1815 pi
->dpm_flags
&= ~DPMFlags_UVD_Enabled
;
1816 DRM_DEBUG("UVD DPM Stopped\n");
1818 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1819 PPSMC_MSG_DisableAllSmuFeatures
, UVD_DPM_MASK
);
1825 static int cz_update_uvd_dpm(struct amdgpu_device
*adev
, bool gate
)
1827 return cz_enable_uvd_dpm(adev
, !gate
);
1831 static void cz_dpm_powergate_uvd(struct amdgpu_device
*adev
, bool gate
)
1833 struct cz_power_info
*pi
= cz_get_pi(adev
);
1836 if (pi
->uvd_power_gated
== gate
)
1839 pi
->uvd_power_gated
= gate
;
1842 if (pi
->caps_uvd_pg
) {
1843 /* disable clockgating so we can properly shut down the block */
1844 ret
= amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
1845 AMD_CG_STATE_UNGATE
);
1846 /* shutdown the UVD block */
1847 ret
= amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
1849 /* XXX: check for errors */
1851 cz_update_uvd_dpm(adev
, gate
);
1852 if (pi
->caps_uvd_pg
)
1853 /* power off the UVD block */
1854 cz_send_msg_to_smc(adev
, PPSMC_MSG_UVDPowerOFF
);
1856 if (pi
->caps_uvd_pg
) {
1857 /* power on the UVD block */
1858 if (pi
->uvd_dynamic_pg
)
1859 cz_send_msg_to_smc_with_parameter(adev
, PPSMC_MSG_UVDPowerON
, 1);
1861 cz_send_msg_to_smc_with_parameter(adev
, PPSMC_MSG_UVDPowerON
, 0);
1862 /* re-init the UVD block */
1863 ret
= amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
1864 AMD_PG_STATE_UNGATE
);
1865 /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */
1866 ret
= amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_UVD
,
1868 /* XXX: check for errors */
1870 cz_update_uvd_dpm(adev
, gate
);
1874 static int cz_enable_vce_dpm(struct amdgpu_device
*adev
, bool enable
)
1876 struct cz_power_info
*pi
= cz_get_pi(adev
);
1879 if (enable
&& pi
->caps_vce_dpm
) {
1880 pi
->dpm_flags
|= DPMFlags_VCE_Enabled
;
1881 DRM_DEBUG("VCE DPM Enabled.\n");
1883 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1884 PPSMC_MSG_EnableAllSmuFeatures
, VCE_DPM_MASK
);
1887 pi
->dpm_flags
&= ~DPMFlags_VCE_Enabled
;
1888 DRM_DEBUG("VCE DPM Stopped\n");
1890 ret
= cz_send_msg_to_smc_with_parameter(adev
,
1891 PPSMC_MSG_DisableAllSmuFeatures
, VCE_DPM_MASK
);
1897 static int cz_update_vce_dpm(struct amdgpu_device
*adev
)
1899 struct cz_power_info
*pi
= cz_get_pi(adev
);
1900 struct amdgpu_vce_clock_voltage_dependency_table
*table
=
1901 &adev
->pm
.dpm
.dyn_state
.vce_clock_voltage_dependency_table
;
1903 /* Stable Pstate is enabled and we need to set the VCE DPM to highest level */
1904 if (pi
->caps_stable_power_state
) {
1905 pi
->vce_dpm
.hard_min_clk
= table
->entries
[table
->count
-1].ecclk
;
1907 } else { /* non-stable p-state cases. without vce.Arbiter.EcclkHardMin */
1908 pi
->vce_dpm
.hard_min_clk
= table
->entries
[0].ecclk
;
1911 cz_send_msg_to_smc_with_parameter(adev
,
1912 PPSMC_MSG_SetEclkHardMin
,
1913 cz_get_eclk_level(adev
,
1914 pi
->vce_dpm
.hard_min_clk
,
1915 PPSMC_MSG_SetEclkHardMin
));
1919 static void cz_dpm_powergate_vce(struct amdgpu_device
*adev
, bool gate
)
1921 struct cz_power_info
*pi
= cz_get_pi(adev
);
1923 if (pi
->caps_vce_pg
) {
1924 if (pi
->vce_power_gated
!= gate
) {
1926 /* disable clockgating so we can properly shut down the block */
1927 amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
1928 AMD_CG_STATE_UNGATE
);
1929 /* shutdown the VCE block */
1930 amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
1933 cz_enable_vce_dpm(adev
, false);
1934 /* TODO: to figure out why vce can't be poweroff. */
1935 /* cz_send_msg_to_smc(adev, PPSMC_MSG_VCEPowerOFF); */
1936 pi
->vce_power_gated
= true;
1938 cz_send_msg_to_smc(adev
, PPSMC_MSG_VCEPowerON
);
1939 pi
->vce_power_gated
= false;
1941 /* re-init the VCE block */
1942 amdgpu_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
1943 AMD_PG_STATE_UNGATE
);
1944 /* enable clockgating. hw will dynamically gate/ungate clocks on the fly */
1945 amdgpu_set_clockgating_state(adev
, AMD_IP_BLOCK_TYPE_VCE
,
1948 cz_update_vce_dpm(adev
);
1949 cz_enable_vce_dpm(adev
, true);
1952 if (! pi
->vce_power_gated
) {
1953 cz_update_vce_dpm(adev
);
1956 } else { /*pi->caps_vce_pg*/
1957 cz_update_vce_dpm(adev
);
1958 cz_enable_vce_dpm(adev
, true);
1964 const struct amd_ip_funcs cz_dpm_ip_funcs
= {
1965 .early_init
= cz_dpm_early_init
,
1966 .late_init
= cz_dpm_late_init
,
1967 .sw_init
= cz_dpm_sw_init
,
1968 .sw_fini
= cz_dpm_sw_fini
,
1969 .hw_init
= cz_dpm_hw_init
,
1970 .hw_fini
= cz_dpm_hw_fini
,
1971 .suspend
= cz_dpm_suspend
,
1972 .resume
= cz_dpm_resume
,
1974 .wait_for_idle
= NULL
,
1976 .print_status
= NULL
,
1977 .set_clockgating_state
= cz_dpm_set_clockgating_state
,
1978 .set_powergating_state
= cz_dpm_set_powergating_state
,
1981 static const struct amdgpu_dpm_funcs cz_dpm_funcs
= {
1982 .get_temperature
= cz_dpm_get_temperature
,
1983 .pre_set_power_state
= cz_dpm_pre_set_power_state
,
1984 .set_power_state
= cz_dpm_set_power_state
,
1985 .post_set_power_state
= cz_dpm_post_set_power_state
,
1986 .display_configuration_changed
= cz_dpm_display_configuration_changed
,
1987 .get_sclk
= cz_dpm_get_sclk
,
1988 .get_mclk
= cz_dpm_get_mclk
,
1989 .print_power_state
= cz_dpm_print_power_state
,
1990 .debugfs_print_current_performance_level
=
1991 cz_dpm_debugfs_print_current_performance_level
,
1992 .force_performance_level
= cz_dpm_force_dpm_level
,
1993 .vblank_too_short
= NULL
,
1994 .powergate_uvd
= cz_dpm_powergate_uvd
,
1995 .powergate_vce
= cz_dpm_powergate_vce
,
1998 static void cz_dpm_set_funcs(struct amdgpu_device
*adev
)
2000 if (NULL
== adev
->pm
.funcs
)
2001 adev
->pm
.funcs
= &cz_dpm_funcs
;