blob: e115a071b5d024d73314357ada06510751ccbffb [file] [log] [blame]
Jammy Zhou3bace352015-07-21 21:18:15 +08001/*
2 * Copyright 2015 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23#ifndef _HWMGR_H_
24#define _HWMGR_H_
25
Rex Zhu28a18ba2015-09-23 15:14:38 +080026#include <linux/seq_file.h>
Jammy Zhou3bace352015-07-21 21:18:15 +080027#include "amd_powerplay.h"
28#include "pp_instance.h"
29#include "hardwaremanager.h"
30#include "pp_power_source.h"
yanyang1c82baa22015-08-18 15:28:32 +080031#include "hwmgr_ppt.h"
Jammy Zhou3bace352015-07-21 21:18:15 +080032
33struct pp_instance;
34struct pp_hwmgr;
35struct pp_hw_power_state;
36struct pp_power_state;
37struct PP_VCEState;
Rex Zhuc28eae22015-10-16 11:46:51 +080038struct phm_fan_speed_info;
Jammy Zhou3bace352015-07-21 21:18:15 +080039
40enum PP_Result {
41 PP_Result_TableImmediateExit = 0x13,
42};
43
44#define PCIE_PERF_REQ_REMOVE_REGISTRY 0
45#define PCIE_PERF_REQ_FORCE_LOWPOWER 1
46#define PCIE_PERF_REQ_GEN1 2
47#define PCIE_PERF_REQ_GEN2 3
48#define PCIE_PERF_REQ_GEN3 4
49
50enum PHM_BackEnd_Magic {
51 PHM_Dummy_Magic = 0xAA5555AA,
52 PHM_RV770_Magic = 0xDCBAABCD,
53 PHM_Kong_Magic = 0x239478DF,
54 PHM_NIslands_Magic = 0x736C494E,
55 PHM_Sumo_Magic = 0x8339FA11,
56 PHM_SIslands_Magic = 0x369431AC,
57 PHM_Trinity_Magic = 0x96751873,
58 PHM_CIslands_Magic = 0x38AC78B0,
59 PHM_Kv_Magic = 0xDCBBABC0,
60 PHM_VIslands_Magic = 0x20130307,
61 PHM_Cz_Magic = 0x67DCBA25
62};
63
64enum PP_DAL_POWERLEVEL {
65 PP_DAL_POWERLEVEL_INVALID = 0,
66 PP_DAL_POWERLEVEL_ULTRALOW,
67 PP_DAL_POWERLEVEL_LOW,
68 PP_DAL_POWERLEVEL_NOMINAL,
69 PP_DAL_POWERLEVEL_PERFORMANCE,
70
71 PP_DAL_POWERLEVEL_0 = PP_DAL_POWERLEVEL_ULTRALOW,
72 PP_DAL_POWERLEVEL_1 = PP_DAL_POWERLEVEL_LOW,
73 PP_DAL_POWERLEVEL_2 = PP_DAL_POWERLEVEL_NOMINAL,
74 PP_DAL_POWERLEVEL_3 = PP_DAL_POWERLEVEL_PERFORMANCE,
75 PP_DAL_POWERLEVEL_4 = PP_DAL_POWERLEVEL_3+1,
76 PP_DAL_POWERLEVEL_5 = PP_DAL_POWERLEVEL_4+1,
77 PP_DAL_POWERLEVEL_6 = PP_DAL_POWERLEVEL_5+1,
78 PP_DAL_POWERLEVEL_7 = PP_DAL_POWERLEVEL_6+1,
79};
80
81#define PHM_PCIE_POWERGATING_TARGET_GFX 0
82#define PHM_PCIE_POWERGATING_TARGET_DDI 1
83#define PHM_PCIE_POWERGATING_TARGET_PLLCASCADE 2
84#define PHM_PCIE_POWERGATING_TARGET_PHY 3
85
86typedef int (*phm_table_function)(struct pp_hwmgr *hwmgr, void *input,
87 void *output, void *storage, int result);
88
89typedef bool (*phm_check_function)(struct pp_hwmgr *hwmgr);
90
Rex Zhu28a18ba2015-09-23 15:14:38 +080091struct phm_set_power_state_input {
92 const struct pp_hw_power_state *pcurrent_state;
93 const struct pp_hw_power_state *pnew_state;
94};
95
Jammy Zhou3bace352015-07-21 21:18:15 +080096struct phm_acp_arbiter {
97 uint32_t acpclk;
98};
99
100struct phm_uvd_arbiter {
101 uint32_t vclk;
102 uint32_t dclk;
103 uint32_t vclk_ceiling;
104 uint32_t dclk_ceiling;
105};
106
107struct phm_vce_arbiter {
108 uint32_t evclk;
109 uint32_t ecclk;
110};
111
112struct phm_gfx_arbiter {
113 uint32_t sclk;
114 uint32_t mclk;
115 uint32_t sclk_over_drive;
116 uint32_t mclk_over_drive;
117 uint32_t sclk_threshold;
118 uint32_t num_cus;
119};
120
121/* Entries in the master tables */
122struct phm_master_table_item {
123 phm_check_function isFunctionNeededInRuntimeTable;
124 phm_table_function tableFunction;
125};
126
127enum phm_master_table_flag {
128 PHM_MasterTableFlag_None = 0,
129 PHM_MasterTableFlag_ExitOnError = 1,
130};
131
132/* The header of the master tables */
133struct phm_master_table_header {
134 uint32_t storage_size;
135 uint32_t flags;
136 struct phm_master_table_item *master_list;
137};
138
139struct phm_runtime_table_header {
140 uint32_t storage_size;
141 bool exit_error;
142 phm_table_function *function_list;
143};
144
145struct phm_clock_array {
146 uint32_t count;
147 uint32_t values[1];
148};
149
150struct phm_clock_voltage_dependency_record {
151 uint32_t clk;
152 uint32_t v;
153};
154
155struct phm_vceclock_voltage_dependency_record {
156 uint32_t ecclk;
157 uint32_t evclk;
158 uint32_t v;
159};
160
161struct phm_uvdclock_voltage_dependency_record {
162 uint32_t vclk;
163 uint32_t dclk;
164 uint32_t v;
165};
166
167struct phm_samuclock_voltage_dependency_record {
168 uint32_t samclk;
169 uint32_t v;
170};
171
172struct phm_acpclock_voltage_dependency_record {
173 uint32_t acpclk;
174 uint32_t v;
175};
176
177struct phm_clock_voltage_dependency_table {
178 uint32_t count; /* Number of entries. */
179 struct phm_clock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
180};
181
182struct phm_phase_shedding_limits_record {
183 uint32_t Voltage;
184 uint32_t Sclk;
185 uint32_t Mclk;
186};
187
188
189extern int phm_dispatch_table(struct pp_hwmgr *hwmgr,
190 struct phm_runtime_table_header *rt_table,
191 void *input, void *output);
192
193extern int phm_construct_table(struct pp_hwmgr *hwmgr,
194 struct phm_master_table_header *master_table,
195 struct phm_runtime_table_header *rt_table);
196
197extern int phm_destroy_table(struct pp_hwmgr *hwmgr,
198 struct phm_runtime_table_header *rt_table);
199
200
201struct phm_uvd_clock_voltage_dependency_record {
202 uint32_t vclk;
203 uint32_t dclk;
204 uint32_t v;
205};
206
207struct phm_uvd_clock_voltage_dependency_table {
208 uint8_t count;
209 struct phm_uvd_clock_voltage_dependency_record entries[1];
210};
211
212struct phm_acp_clock_voltage_dependency_record {
213 uint32_t acpclk;
214 uint32_t v;
215};
216
217struct phm_acp_clock_voltage_dependency_table {
218 uint32_t count;
219 struct phm_acp_clock_voltage_dependency_record entries[1];
220};
221
222struct phm_vce_clock_voltage_dependency_record {
223 uint32_t ecclk;
224 uint32_t evclk;
225 uint32_t v;
226};
227
228struct phm_phase_shedding_limits_table {
229 uint32_t count;
230 struct phm_phase_shedding_limits_record entries[1];
231};
232
233struct phm_vceclock_voltage_dependency_table {
234 uint8_t count; /* Number of entries. */
235 struct phm_vceclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
236};
237
238struct phm_uvdclock_voltage_dependency_table {
239 uint8_t count; /* Number of entries. */
240 struct phm_uvdclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
241};
242
243struct phm_samuclock_voltage_dependency_table {
244 uint8_t count; /* Number of entries. */
245 struct phm_samuclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
246};
247
248struct phm_acpclock_voltage_dependency_table {
249 uint32_t count; /* Number of entries. */
250 struct phm_acpclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
251};
252
253struct phm_vce_clock_voltage_dependency_table {
254 uint8_t count;
255 struct phm_vce_clock_voltage_dependency_record entries[1];
256};
257
258struct pp_hwmgr_func {
259 int (*backend_init)(struct pp_hwmgr *hw_mgr);
260 int (*backend_fini)(struct pp_hwmgr *hw_mgr);
261 int (*asic_setup)(struct pp_hwmgr *hw_mgr);
262 int (*get_power_state_size)(struct pp_hwmgr *hw_mgr);
Rex Zhu28a18ba2015-09-23 15:14:38 +0800263
264 int (*apply_state_adjust_rules)(struct pp_hwmgr *hwmgr,
265 struct pp_power_state *prequest_ps,
266 const struct pp_power_state *pcurrent_ps);
267
268 int (*force_dpm_level)(struct pp_hwmgr *hw_mgr,
269 enum amd_dpm_forced_level level);
270
271 int (*dynamic_state_management_enable)(
272 struct pp_hwmgr *hw_mgr);
273
274 int (*patch_boot_state)(struct pp_hwmgr *hwmgr,
275 struct pp_hw_power_state *hw_ps);
276
277 int (*get_pp_table_entry)(struct pp_hwmgr *hwmgr,
278 unsigned long, struct pp_power_state *);
Jammy Zhou3bace352015-07-21 21:18:15 +0800279 int (*get_num_of_pp_table_entries)(struct pp_hwmgr *hwmgr);
Rex Zhu28a18ba2015-09-23 15:14:38 +0800280 int (*powerdown_uvd)(struct pp_hwmgr *hwmgr);
281 int (*powergate_vce)(struct pp_hwmgr *hwmgr, bool bgate);
282 int (*powergate_uvd)(struct pp_hwmgr *hwmgr, bool bgate);
283 int (*get_mclk)(struct pp_hwmgr *hwmgr, bool low);
284 int (*get_sclk)(struct pp_hwmgr *hwmgr, bool low);
285 int (*power_state_set)(struct pp_hwmgr *hwmgr,
286 const void *state);
287 void (*print_current_perforce_level)(struct pp_hwmgr *hwmgr,
288 struct seq_file *m);
289 int (*enable_clock_power_gating)(struct pp_hwmgr *hwmgr);
Rex Zhue8c7de52015-10-16 14:51:09 +0800290 int (*notify_smc_display_config_after_ps_adjustment)(struct pp_hwmgr *hwmgr);
291 int (*display_config_changed)(struct pp_hwmgr *hwmgr);
Rex Zhub1132012015-09-30 13:28:49 +0800292 int (*disable_clock_power_gating)(struct pp_hwmgr *hwmgr);
293 int (*update_clock_gatings)(struct pp_hwmgr *hwmgr,
294 const uint32_t *msg_id);
Rex Zhuc28eae22015-10-16 11:46:51 +0800295 int (*set_max_fan_rpm_output)(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm);
296 int (*set_max_fan_pwm_output)(struct pp_hwmgr *hwmgr, uint16_t us_max_fan_pwm);
297 int (*get_temperature)(struct pp_hwmgr *hwmgr);
298 int (*stop_thermal_controller)(struct pp_hwmgr *hwmgr);
299 int (*get_fan_speed_info)(struct pp_hwmgr *hwmgr, struct phm_fan_speed_info *fan_speed_info);
300 int (*set_fan_control_mode)(struct pp_hwmgr *hwmgr, uint32_t mode);
301 int (*get_fan_control_mode)(struct pp_hwmgr *hwmgr);
302 int (*set_fan_speed_percent)(struct pp_hwmgr *hwmgr, uint32_t percent);
303 int (*get_fan_speed_percent)(struct pp_hwmgr *hwmgr, uint32_t *speed);
304 int (*set_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t percent);
305 int (*get_fan_speed_rpm)(struct pp_hwmgr *hwmgr, uint32_t *speed);
306 int (*reset_fan_speed_to_default)(struct pp_hwmgr *hwmgr);
307 int (*uninitialize_thermal_controller)(struct pp_hwmgr *hwmgr);
308 int (*register_internal_thermal_interrupt)(struct pp_hwmgr *hwmgr,
309 const void *thermal_interrupt_info);
Rex Zhu09b4c872015-11-04 11:07:34 +0800310 bool (*check_smc_update_required_for_display_configuration)(struct pp_hwmgr *hwmgr);
311 int (*check_states_equal)(struct pp_hwmgr *hwmgr,
312 const struct pp_hw_power_state *pstate1,
313 const struct pp_hw_power_state *pstate2,
314 bool *equal);
Jammy Zhou3bace352015-07-21 21:18:15 +0800315};
316
317struct pp_table_func {
318 int (*pptable_init)(struct pp_hwmgr *hw_mgr);
319 int (*pptable_fini)(struct pp_hwmgr *hw_mgr);
320 int (*pptable_get_number_of_vce_state_table_entries)(struct pp_hwmgr *hw_mgr);
321 int (*pptable_get_vce_state_table_entry)(
322 struct pp_hwmgr *hwmgr,
323 unsigned long i,
324 struct PP_VCEState *vce_state,
325 void **clock_info,
326 unsigned long *flag);
327};
328
329union phm_cac_leakage_record {
330 struct {
331 uint16_t Vddc; /* in CI, we use it for StdVoltageHiSidd */
332 uint32_t Leakage; /* in CI, we use it for StdVoltageLoSidd */
333 };
334 struct {
335 uint16_t Vddc1;
336 uint16_t Vddc2;
337 uint16_t Vddc3;
338 };
339};
340
341struct phm_cac_leakage_table {
342 uint32_t count;
343 union phm_cac_leakage_record entries[1];
344};
345
346struct phm_samu_clock_voltage_dependency_record {
347 uint32_t samclk;
348 uint32_t v;
349};
350
351
352struct phm_samu_clock_voltage_dependency_table {
353 uint8_t count;
354 struct phm_samu_clock_voltage_dependency_record entries[1];
355};
356
357struct phm_cac_tdp_table {
358 uint16_t usTDP;
359 uint16_t usConfigurableTDP;
360 uint16_t usTDC;
361 uint16_t usBatteryPowerLimit;
362 uint16_t usSmallPowerLimit;
363 uint16_t usLowCACLeakage;
364 uint16_t usHighCACLeakage;
365 uint16_t usMaximumPowerDeliveryLimit;
366 uint16_t usOperatingTempMinLimit;
367 uint16_t usOperatingTempMaxLimit;
368 uint16_t usOperatingTempStep;
369 uint16_t usOperatingTempHyst;
370 uint16_t usDefaultTargetOperatingTemp;
371 uint16_t usTargetOperatingTemp;
372 uint16_t usPowerTuneDataSetID;
373 uint16_t usSoftwareShutdownTemp;
374 uint16_t usClockStretchAmount;
375 uint16_t usTemperatureLimitHotspot;
376 uint16_t usTemperatureLimitLiquid1;
377 uint16_t usTemperatureLimitLiquid2;
378 uint16_t usTemperatureLimitVrVddc;
379 uint16_t usTemperatureLimitVrMvdd;
380 uint16_t usTemperatureLimitPlx;
381 uint8_t ucLiquid1_I2C_address;
382 uint8_t ucLiquid2_I2C_address;
383 uint8_t ucLiquid_I2C_Line;
384 uint8_t ucVr_I2C_address;
385 uint8_t ucVr_I2C_Line;
386 uint8_t ucPlx_I2C_address;
387 uint8_t ucPlx_I2C_Line;
388};
389
390struct phm_ppm_table {
391 uint8_t ppm_design;
392 uint16_t cpu_core_number;
393 uint32_t platform_tdp;
394 uint32_t small_ac_platform_tdp;
395 uint32_t platform_tdc;
396 uint32_t small_ac_platform_tdc;
397 uint32_t apu_tdp;
398 uint32_t dgpu_tdp;
399 uint32_t dgpu_ulv_power;
400 uint32_t tj_max;
401};
402
403struct phm_vq_budgeting_record {
404 uint32_t ulCUs;
405 uint32_t ulSustainableSOCPowerLimitLow;
406 uint32_t ulSustainableSOCPowerLimitHigh;
407 uint32_t ulMinSclkLow;
408 uint32_t ulMinSclkHigh;
409 uint8_t ucDispConfig;
410 uint32_t ulDClk;
411 uint32_t ulEClk;
412 uint32_t ulSustainableSclk;
413 uint32_t ulSustainableCUs;
414};
415
416struct phm_vq_budgeting_table {
417 uint8_t numEntries;
418 struct phm_vq_budgeting_record entries[1];
419};
420
421struct phm_clock_and_voltage_limits {
422 uint32_t sclk;
423 uint32_t mclk;
424 uint16_t vddc;
425 uint16_t vddci;
426 uint16_t vddgfx;
427};
428
yanyang1c82baa22015-08-18 15:28:32 +0800429/* Structure to hold PPTable information */
Jammy Zhou3bace352015-07-21 21:18:15 +0800430
yanyang1c82baa22015-08-18 15:28:32 +0800431struct phm_ppt_v1_information {
432 struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_sclk;
433 struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_mclk;
434 struct phm_clock_array *valid_sclk_values;
435 struct phm_clock_array *valid_mclk_values;
436 struct phm_clock_and_voltage_limits max_clock_voltage_on_dc;
437 struct phm_clock_and_voltage_limits max_clock_voltage_on_ac;
438 struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;
439 struct phm_ppm_table *ppm_parameter_table;
440 struct phm_cac_tdp_table *cac_dtp_table;
441 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_dep_table;
442 struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
443 struct phm_ppt_v1_voltage_lookup_table *vddgfx_lookup_table;
444 struct phm_ppt_v1_pcie_table *pcie_table;
445 uint16_t us_ulv_voltage_offset;
446};
Jammy Zhou3bace352015-07-21 21:18:15 +0800447
448struct phm_dynamic_state_info {
449 struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk;
450 struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk;
451 struct phm_clock_voltage_dependency_table *vddc_dependency_on_mclk;
452 struct phm_clock_voltage_dependency_table *mvdd_dependency_on_mclk;
453 struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;
454 struct phm_clock_array *valid_sclk_values;
455 struct phm_clock_array *valid_mclk_values;
456 struct phm_clock_and_voltage_limits max_clock_voltage_on_dc;
457 struct phm_clock_and_voltage_limits max_clock_voltage_on_ac;
458 uint32_t mclk_sclk_ratio;
459 uint32_t sclk_mclk_delta;
460 uint32_t vddc_vddci_delta;
461 uint32_t min_vddc_for_pcie_gen2;
462 struct phm_cac_leakage_table *cac_leakage_table;
463 struct phm_phase_shedding_limits_table *vddc_phase_shed_limits_table;
464
465 struct phm_vce_clock_voltage_dependency_table
Alex Deucher9c0bad92015-11-13 23:51:40 -0500466 *vce_clock_voltage_dependency_table;
Jammy Zhou3bace352015-07-21 21:18:15 +0800467 struct phm_uvd_clock_voltage_dependency_table
Alex Deucher9c0bad92015-11-13 23:51:40 -0500468 *uvd_clock_voltage_dependency_table;
Jammy Zhou3bace352015-07-21 21:18:15 +0800469 struct phm_acp_clock_voltage_dependency_table
470 *acp_clock_voltage_dependency_table;
471 struct phm_samu_clock_voltage_dependency_table
472 *samu_clock_voltage_dependency_table;
473
474 struct phm_ppm_table *ppm_parameter_table;
475 struct phm_cac_tdp_table *cac_dtp_table;
476 struct phm_clock_voltage_dependency_table *vdd_gfx_dependency_on_sclk;
477 struct phm_vq_budgeting_table *vq_budgeting_table;
478};
479
yanyang1c82baa22015-08-18 15:28:32 +0800480struct pp_fan_info {
481 bool bNoFan;
482 uint8_t ucTachometerPulsesPerRevolution;
483 uint32_t ulMinRPM;
484 uint32_t ulMaxRPM;
485};
486
487struct pp_advance_fan_control_parameters {
488 uint16_t usTMin; /* The temperature, in 0.01 centigrades, below which we just run at a minimal PWM. */
489 uint16_t usTMed; /* The middle temperature where we change slopes. */
490 uint16_t usTHigh; /* The high temperature for setting the second slope. */
491 uint16_t usPWMMin; /* The minimum PWM value in percent (0.01% increments). */
492 uint16_t usPWMMed; /* The PWM value (in percent) at TMed. */
493 uint16_t usPWMHigh; /* The PWM value at THigh. */
494 uint8_t ucTHyst; /* Temperature hysteresis. Integer. */
495 uint32_t ulCycleDelay; /* The time between two invocations of the fan control routine in microseconds. */
496 uint16_t usTMax; /* The max temperature */
497 uint8_t ucFanControlMode;
498 uint16_t usFanPWMMinLimit;
499 uint16_t usFanPWMMaxLimit;
500 uint16_t usFanPWMStep;
501 uint16_t usDefaultMaxFanPWM;
502 uint16_t usFanOutputSensitivity;
503 uint16_t usDefaultFanOutputSensitivity;
504 uint16_t usMaxFanPWM; /* The max Fan PWM value for Fuzzy Fan Control feature */
505 uint16_t usFanRPMMinLimit; /* Minimum limit range in percentage, need to calculate based on minRPM/MaxRpm */
506 uint16_t usFanRPMMaxLimit; /* Maximum limit range in percentage, usually set to 100% by default */
507 uint16_t usFanRPMStep; /* Step increments/decerements, in percent */
508 uint16_t usDefaultMaxFanRPM; /* The max Fan RPM value for Fuzzy Fan Control feature, default from PPTable */
509 uint16_t usMaxFanRPM; /* The max Fan RPM value for Fuzzy Fan Control feature, user defined */
510 uint16_t usFanCurrentLow; /* Low current */
511 uint16_t usFanCurrentHigh; /* High current */
512 uint16_t usFanRPMLow; /* Low RPM */
513 uint16_t usFanRPMHigh; /* High RPM */
514 uint32_t ulMinFanSCLKAcousticLimit; /* Minimum Fan Controller SCLK Frequency Acoustic Limit. */
515 uint8_t ucTargetTemperature; /* Advanced fan controller target temperature. */
516 uint8_t ucMinimumPWMLimit; /* The minimum PWM that the advanced fan controller can set. This should be set to the highest PWM that will run the fan at its lowest RPM. */
517 uint16_t usFanGainEdge; /* The following is added for Fiji */
518 uint16_t usFanGainHotspot;
519 uint16_t usFanGainLiquid;
520 uint16_t usFanGainVrVddc;
521 uint16_t usFanGainVrMvdd;
522 uint16_t usFanGainPlx;
523 uint16_t usFanGainHbm;
524};
525
526struct pp_thermal_controller_info {
527 uint8_t ucType;
528 uint8_t ucI2cLine;
529 uint8_t ucI2cAddress;
530 struct pp_fan_info fanInfo;
531 struct pp_advance_fan_control_parameters advanceFanControlParameters;
532};
533
534struct phm_microcode_version_info {
535 uint32_t SMC;
536 uint32_t DMCU;
537 uint32_t MC;
538 uint32_t NB;
539};
540
541/**
542 * The main hardware manager structure.
543 */
Jammy Zhou3bace352015-07-21 21:18:15 +0800544struct pp_hwmgr {
545 uint32_t chip_family;
546 uint32_t chip_id;
547 uint32_t hw_revision;
548 uint32_t sub_sys_id;
549 uint32_t sub_vendor_id;
550
551 void *device;
552 struct pp_smumgr *smumgr;
553 const void *soft_pp_table;
Alex Deucher9c0bad92015-11-13 23:51:40 -0500554 bool need_pp_table_upload;
Jammy Zhou3bace352015-07-21 21:18:15 +0800555 enum amd_dpm_forced_level dpm_level;
Rex Zhu28a18ba2015-09-23 15:14:38 +0800556 bool block_hw_access;
Jammy Zhou3bace352015-07-21 21:18:15 +0800557 struct phm_gfx_arbiter gfx_arbiter;
558 struct phm_acp_arbiter acp_arbiter;
559 struct phm_uvd_arbiter uvd_arbiter;
560 struct phm_vce_arbiter vce_arbiter;
561 uint32_t usec_timeout;
562 void *pptable;
563 struct phm_platform_descriptor platform_descriptor;
564 void *backend;
565 enum PP_DAL_POWERLEVEL dal_power_level;
566 struct phm_dynamic_state_info dyn_state;
567 struct phm_runtime_table_header setup_asic;
568 struct phm_runtime_table_header disable_dynamic_state_management;
569 struct phm_runtime_table_header enable_dynamic_state_management;
Rex Zhu28a18ba2015-09-23 15:14:38 +0800570 struct phm_runtime_table_header set_power_state;
571 struct phm_runtime_table_header enable_clock_power_gatings;
Rex Zhue8c7de52015-10-16 14:51:09 +0800572 struct phm_runtime_table_header display_configuration_changed;
Rex Zhuc28eae22015-10-16 11:46:51 +0800573 struct phm_runtime_table_header start_thermal_controller;
574 struct phm_runtime_table_header set_temperature_range;
Jammy Zhou3bace352015-07-21 21:18:15 +0800575 const struct pp_hwmgr_func *hwmgr_func;
576 const struct pp_table_func *pptable_func;
577 struct pp_power_state *ps;
578 enum pp_power_source power_source;
579 uint32_t num_ps;
yanyang1c82baa22015-08-18 15:28:32 +0800580 struct pp_thermal_controller_info thermal_controller;
Rex Zhuc28eae22015-10-16 11:46:51 +0800581 bool fan_ctrl_is_in_default_mode;
582 uint32_t fan_ctrl_default_mode;
583 uint32_t tmin;
yanyang1c82baa22015-08-18 15:28:32 +0800584 struct phm_microcode_version_info microcode_version_info;
Jammy Zhou3bace352015-07-21 21:18:15 +0800585 uint32_t ps_size;
586 struct pp_power_state *current_ps;
587 struct pp_power_state *request_ps;
588 struct pp_power_state *boot_ps;
589 struct pp_power_state *uvd_ps;
590};
591
592
593extern int hwmgr_init(struct amd_pp_init *pp_init,
594 struct pp_instance *handle);
595
596extern int hwmgr_fini(struct pp_hwmgr *hwmgr);
597
598extern int hw_init_power_state_table(struct pp_hwmgr *hwmgr);
599
600extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
601 uint32_t value, uint32_t mask);
602
603extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
604 uint32_t index, uint32_t value, uint32_t mask);
605
yanyang1c82baa22015-08-18 15:28:32 +0800606extern uint32_t phm_read_indirect_register(struct pp_hwmgr *hwmgr,
607 uint32_t indirect_port, uint32_t index);
Jammy Zhou3bace352015-07-21 21:18:15 +0800608
yanyang1c82baa22015-08-18 15:28:32 +0800609extern void phm_write_indirect_register(struct pp_hwmgr *hwmgr,
610 uint32_t indirect_port,
611 uint32_t index,
612 uint32_t value);
Jammy Zhou3bace352015-07-21 21:18:15 +0800613
614extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
615 uint32_t indirect_port,
616 uint32_t index,
617 uint32_t value,
618 uint32_t mask);
619
620extern void phm_wait_for_indirect_register_unequal(
621 struct pp_hwmgr *hwmgr,
622 uint32_t indirect_port,
623 uint32_t index,
624 uint32_t value,
625 uint32_t mask);
626
Rex Zhu28a18ba2015-09-23 15:14:38 +0800627bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr);
628bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr);
Rex Zhuc28eae22015-10-16 11:46:51 +0800629bool phm_cf_want_microcode_fan_ctrl(struct pp_hwmgr *hwmgr);
Rex Zhu28a18ba2015-09-23 15:14:38 +0800630
631#define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU
632
Jammy Zhou3bace352015-07-21 21:18:15 +0800633#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
634#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK
635
636#define PHM_SET_FIELD(origval, reg, field, fieldval) \
637 (((origval) & ~PHM_FIELD_MASK(reg, field)) | \
638 (PHM_FIELD_MASK(reg, field) & ((fieldval) << PHM_FIELD_SHIFT(reg, field))))
639
640#define PHM_GET_FIELD(value, reg, field) \
641 (((value) & PHM_FIELD_MASK(reg, field)) >> \
642 PHM_FIELD_SHIFT(reg, field))
643
644
645#define PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, index, value, mask) \
646 phm_wait_on_register(hwmgr, index, value, mask)
647
648#define PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, index, value, mask) \
649 phm_wait_for_register_unequal(hwmgr, index, value, mask)
650
651#define PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
652 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX, index, value, mask)
653
654#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask) \
655 phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX, index, value, mask)
656
657#define PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
658 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX_0, index, value, mask)
659
660#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask) \
661 phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX_0, index, value, mask)
662
663/* Operations on named registers. */
664
665#define PHM_WAIT_REGISTER(hwmgr, reg, value, mask) \
666 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
667
668#define PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, value, mask) \
669 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
670
671#define PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
672 PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
673
674#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask) \
675 PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
676
677#define PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
678 PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
679
680#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask) \
681 PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
682
683/* Operations on named fields. */
684
685#define PHM_READ_FIELD(device, reg, field) \
686 PHM_GET_FIELD(cgs_read_register(device, mm##reg), reg, field)
687
688#define PHM_READ_INDIRECT_FIELD(device, port, reg, field) \
689 PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
690 reg, field)
691
692#define PHM_READ_VFPF_INDIRECT_FIELD(device, port, reg, field) \
693 PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
694 reg, field)
695
696#define PHM_WRITE_FIELD(device, reg, field, fieldval) \
697 cgs_write_register(device, mm##reg, PHM_SET_FIELD( \
698 cgs_read_register(device, mm##reg), reg, field, fieldval))
699
700#define PHM_WRITE_INDIRECT_FIELD(device, port, reg, field, fieldval) \
701 cgs_write_ind_register(device, port, ix##reg, \
702 PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
703 reg, field, fieldval))
704
705#define PHM_WRITE_VFPF_INDIRECT_FIELD(device, port, reg, field, fieldval) \
706 cgs_write_ind_register(device, port, ix##reg, \
707 PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
708 reg, field, fieldval))
709
710#define PHM_WAIT_FIELD(hwmgr, reg, field, fieldval) \
711 PHM_WAIT_REGISTER(hwmgr, reg, (fieldval) \
712 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
713
714#define PHM_WAIT_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
715 PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
716 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
717
718#define PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
719 PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
720 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
721
722#define PHM_WAIT_FIELD_UNEQUAL(hwmgr, reg, field, fieldval) \
723 PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, (fieldval) \
724 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
725
726#define PHM_WAIT_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
727 PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval) \
728 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
729
730#define PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
731 PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval) \
732 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
733
734/* Operations on arrays of registers & fields. */
735
736#define PHM_READ_ARRAY_REGISTER(device, reg, offset) \
737 cgs_read_register(device, mm##reg + (offset))
738
739#define PHM_WRITE_ARRAY_REGISTER(device, reg, offset, value) \
740 cgs_write_register(device, mm##reg + (offset), value)
741
742#define PHM_WAIT_ARRAY_REGISTER(hwmgr, reg, offset, value, mask) \
743 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
744
745#define PHM_WAIT_ARRAY_REGISTER_UNEQUAL(hwmgr, reg, offset, value, mask) \
746 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
747
748#define PHM_READ_ARRAY_FIELD(hwmgr, reg, offset, field) \
749 PHM_GET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), reg, field)
750
751#define PHM_WRITE_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue) \
752 PHM_WRITE_ARRAY_REGISTER(hwmgr->device, reg, offset, \
753 PHM_SET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), \
754 reg, field, fieldvalue))
755
756#define PHM_WAIT_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue) \
757 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), \
758 (fieldvalue) << PHM_FIELD_SHIFT(reg, field), \
759 PHM_FIELD_MASK(reg, field))
760
761#define PHM_WAIT_ARRAY_FIELD_UNEQUAL(hwmgr, reg, offset, field, fieldvalue) \
762 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), \
763 (fieldvalue) << PHM_FIELD_SHIFT(reg, field), \
764 PHM_FIELD_MASK(reg, field))
765
766#endif /* _HWMGR_H_ */