blob: 2370a72a99cdea8618b2a4186db076f6d5739efd [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;
38
39enum PP_Result {
40 PP_Result_TableImmediateExit = 0x13,
41};
42
43#define PCIE_PERF_REQ_REMOVE_REGISTRY 0
44#define PCIE_PERF_REQ_FORCE_LOWPOWER 1
45#define PCIE_PERF_REQ_GEN1 2
46#define PCIE_PERF_REQ_GEN2 3
47#define PCIE_PERF_REQ_GEN3 4
48
49enum PHM_BackEnd_Magic {
50 PHM_Dummy_Magic = 0xAA5555AA,
51 PHM_RV770_Magic = 0xDCBAABCD,
52 PHM_Kong_Magic = 0x239478DF,
53 PHM_NIslands_Magic = 0x736C494E,
54 PHM_Sumo_Magic = 0x8339FA11,
55 PHM_SIslands_Magic = 0x369431AC,
56 PHM_Trinity_Magic = 0x96751873,
57 PHM_CIslands_Magic = 0x38AC78B0,
58 PHM_Kv_Magic = 0xDCBBABC0,
59 PHM_VIslands_Magic = 0x20130307,
60 PHM_Cz_Magic = 0x67DCBA25
61};
62
63enum PP_DAL_POWERLEVEL {
64 PP_DAL_POWERLEVEL_INVALID = 0,
65 PP_DAL_POWERLEVEL_ULTRALOW,
66 PP_DAL_POWERLEVEL_LOW,
67 PP_DAL_POWERLEVEL_NOMINAL,
68 PP_DAL_POWERLEVEL_PERFORMANCE,
69
70 PP_DAL_POWERLEVEL_0 = PP_DAL_POWERLEVEL_ULTRALOW,
71 PP_DAL_POWERLEVEL_1 = PP_DAL_POWERLEVEL_LOW,
72 PP_DAL_POWERLEVEL_2 = PP_DAL_POWERLEVEL_NOMINAL,
73 PP_DAL_POWERLEVEL_3 = PP_DAL_POWERLEVEL_PERFORMANCE,
74 PP_DAL_POWERLEVEL_4 = PP_DAL_POWERLEVEL_3+1,
75 PP_DAL_POWERLEVEL_5 = PP_DAL_POWERLEVEL_4+1,
76 PP_DAL_POWERLEVEL_6 = PP_DAL_POWERLEVEL_5+1,
77 PP_DAL_POWERLEVEL_7 = PP_DAL_POWERLEVEL_6+1,
78};
79
80#define PHM_PCIE_POWERGATING_TARGET_GFX 0
81#define PHM_PCIE_POWERGATING_TARGET_DDI 1
82#define PHM_PCIE_POWERGATING_TARGET_PLLCASCADE 2
83#define PHM_PCIE_POWERGATING_TARGET_PHY 3
84
85typedef int (*phm_table_function)(struct pp_hwmgr *hwmgr, void *input,
86 void *output, void *storage, int result);
87
88typedef bool (*phm_check_function)(struct pp_hwmgr *hwmgr);
89
Rex Zhu28a18ba2015-09-23 15:14:38 +080090struct phm_set_power_state_input {
91 const struct pp_hw_power_state *pcurrent_state;
92 const struct pp_hw_power_state *pnew_state;
93};
94
Jammy Zhou3bace352015-07-21 21:18:15 +080095struct phm_acp_arbiter {
96 uint32_t acpclk;
97};
98
99struct phm_uvd_arbiter {
100 uint32_t vclk;
101 uint32_t dclk;
102 uint32_t vclk_ceiling;
103 uint32_t dclk_ceiling;
104};
105
106struct phm_vce_arbiter {
107 uint32_t evclk;
108 uint32_t ecclk;
109};
110
111struct phm_gfx_arbiter {
112 uint32_t sclk;
113 uint32_t mclk;
114 uint32_t sclk_over_drive;
115 uint32_t mclk_over_drive;
116 uint32_t sclk_threshold;
117 uint32_t num_cus;
118};
119
120/* Entries in the master tables */
121struct phm_master_table_item {
122 phm_check_function isFunctionNeededInRuntimeTable;
123 phm_table_function tableFunction;
124};
125
126enum phm_master_table_flag {
127 PHM_MasterTableFlag_None = 0,
128 PHM_MasterTableFlag_ExitOnError = 1,
129};
130
131/* The header of the master tables */
132struct phm_master_table_header {
133 uint32_t storage_size;
134 uint32_t flags;
135 struct phm_master_table_item *master_list;
136};
137
138struct phm_runtime_table_header {
139 uint32_t storage_size;
140 bool exit_error;
141 phm_table_function *function_list;
142};
143
144struct phm_clock_array {
145 uint32_t count;
146 uint32_t values[1];
147};
148
149struct phm_clock_voltage_dependency_record {
150 uint32_t clk;
151 uint32_t v;
152};
153
154struct phm_vceclock_voltage_dependency_record {
155 uint32_t ecclk;
156 uint32_t evclk;
157 uint32_t v;
158};
159
160struct phm_uvdclock_voltage_dependency_record {
161 uint32_t vclk;
162 uint32_t dclk;
163 uint32_t v;
164};
165
166struct phm_samuclock_voltage_dependency_record {
167 uint32_t samclk;
168 uint32_t v;
169};
170
171struct phm_acpclock_voltage_dependency_record {
172 uint32_t acpclk;
173 uint32_t v;
174};
175
176struct phm_clock_voltage_dependency_table {
177 uint32_t count; /* Number of entries. */
178 struct phm_clock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
179};
180
181struct phm_phase_shedding_limits_record {
182 uint32_t Voltage;
183 uint32_t Sclk;
184 uint32_t Mclk;
185};
186
187
188extern int phm_dispatch_table(struct pp_hwmgr *hwmgr,
189 struct phm_runtime_table_header *rt_table,
190 void *input, void *output);
191
192extern int phm_construct_table(struct pp_hwmgr *hwmgr,
193 struct phm_master_table_header *master_table,
194 struct phm_runtime_table_header *rt_table);
195
196extern int phm_destroy_table(struct pp_hwmgr *hwmgr,
197 struct phm_runtime_table_header *rt_table);
198
199
200struct phm_uvd_clock_voltage_dependency_record {
201 uint32_t vclk;
202 uint32_t dclk;
203 uint32_t v;
204};
205
206struct phm_uvd_clock_voltage_dependency_table {
207 uint8_t count;
208 struct phm_uvd_clock_voltage_dependency_record entries[1];
209};
210
211struct phm_acp_clock_voltage_dependency_record {
212 uint32_t acpclk;
213 uint32_t v;
214};
215
216struct phm_acp_clock_voltage_dependency_table {
217 uint32_t count;
218 struct phm_acp_clock_voltage_dependency_record entries[1];
219};
220
221struct phm_vce_clock_voltage_dependency_record {
222 uint32_t ecclk;
223 uint32_t evclk;
224 uint32_t v;
225};
226
227struct phm_phase_shedding_limits_table {
228 uint32_t count;
229 struct phm_phase_shedding_limits_record entries[1];
230};
231
232struct phm_vceclock_voltage_dependency_table {
233 uint8_t count; /* Number of entries. */
234 struct phm_vceclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
235};
236
237struct phm_uvdclock_voltage_dependency_table {
238 uint8_t count; /* Number of entries. */
239 struct phm_uvdclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
240};
241
242struct phm_samuclock_voltage_dependency_table {
243 uint8_t count; /* Number of entries. */
244 struct phm_samuclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
245};
246
247struct phm_acpclock_voltage_dependency_table {
248 uint32_t count; /* Number of entries. */
249 struct phm_acpclock_voltage_dependency_record entries[1]; /* Dynamically allocate count entries. */
250};
251
252struct phm_vce_clock_voltage_dependency_table {
253 uint8_t count;
254 struct phm_vce_clock_voltage_dependency_record entries[1];
255};
256
257struct pp_hwmgr_func {
258 int (*backend_init)(struct pp_hwmgr *hw_mgr);
259 int (*backend_fini)(struct pp_hwmgr *hw_mgr);
260 int (*asic_setup)(struct pp_hwmgr *hw_mgr);
261 int (*get_power_state_size)(struct pp_hwmgr *hw_mgr);
Rex Zhu28a18ba2015-09-23 15:14:38 +0800262
263 int (*apply_state_adjust_rules)(struct pp_hwmgr *hwmgr,
264 struct pp_power_state *prequest_ps,
265 const struct pp_power_state *pcurrent_ps);
266
267 int (*force_dpm_level)(struct pp_hwmgr *hw_mgr,
268 enum amd_dpm_forced_level level);
269
270 int (*dynamic_state_management_enable)(
271 struct pp_hwmgr *hw_mgr);
272
273 int (*patch_boot_state)(struct pp_hwmgr *hwmgr,
274 struct pp_hw_power_state *hw_ps);
275
276 int (*get_pp_table_entry)(struct pp_hwmgr *hwmgr,
277 unsigned long, struct pp_power_state *);
Jammy Zhou3bace352015-07-21 21:18:15 +0800278 int (*get_num_of_pp_table_entries)(struct pp_hwmgr *hwmgr);
Rex Zhu28a18ba2015-09-23 15:14:38 +0800279 int (*powerdown_uvd)(struct pp_hwmgr *hwmgr);
280 int (*powergate_vce)(struct pp_hwmgr *hwmgr, bool bgate);
281 int (*powergate_uvd)(struct pp_hwmgr *hwmgr, bool bgate);
282 int (*get_mclk)(struct pp_hwmgr *hwmgr, bool low);
283 int (*get_sclk)(struct pp_hwmgr *hwmgr, bool low);
284 int (*power_state_set)(struct pp_hwmgr *hwmgr,
285 const void *state);
286 void (*print_current_perforce_level)(struct pp_hwmgr *hwmgr,
287 struct seq_file *m);
288 int (*enable_clock_power_gating)(struct pp_hwmgr *hwmgr);
Rex Zhue8c7de52015-10-16 14:51:09 +0800289 int (*notify_smc_display_config_after_ps_adjustment)(struct pp_hwmgr *hwmgr);
290 int (*display_config_changed)(struct pp_hwmgr *hwmgr);
Jammy Zhou3bace352015-07-21 21:18:15 +0800291};
292
293struct pp_table_func {
294 int (*pptable_init)(struct pp_hwmgr *hw_mgr);
295 int (*pptable_fini)(struct pp_hwmgr *hw_mgr);
296 int (*pptable_get_number_of_vce_state_table_entries)(struct pp_hwmgr *hw_mgr);
297 int (*pptable_get_vce_state_table_entry)(
298 struct pp_hwmgr *hwmgr,
299 unsigned long i,
300 struct PP_VCEState *vce_state,
301 void **clock_info,
302 unsigned long *flag);
303};
304
305union phm_cac_leakage_record {
306 struct {
307 uint16_t Vddc; /* in CI, we use it for StdVoltageHiSidd */
308 uint32_t Leakage; /* in CI, we use it for StdVoltageLoSidd */
309 };
310 struct {
311 uint16_t Vddc1;
312 uint16_t Vddc2;
313 uint16_t Vddc3;
314 };
315};
316
317struct phm_cac_leakage_table {
318 uint32_t count;
319 union phm_cac_leakage_record entries[1];
320};
321
322struct phm_samu_clock_voltage_dependency_record {
323 uint32_t samclk;
324 uint32_t v;
325};
326
327
328struct phm_samu_clock_voltage_dependency_table {
329 uint8_t count;
330 struct phm_samu_clock_voltage_dependency_record entries[1];
331};
332
333struct phm_cac_tdp_table {
334 uint16_t usTDP;
335 uint16_t usConfigurableTDP;
336 uint16_t usTDC;
337 uint16_t usBatteryPowerLimit;
338 uint16_t usSmallPowerLimit;
339 uint16_t usLowCACLeakage;
340 uint16_t usHighCACLeakage;
341 uint16_t usMaximumPowerDeliveryLimit;
342 uint16_t usOperatingTempMinLimit;
343 uint16_t usOperatingTempMaxLimit;
344 uint16_t usOperatingTempStep;
345 uint16_t usOperatingTempHyst;
346 uint16_t usDefaultTargetOperatingTemp;
347 uint16_t usTargetOperatingTemp;
348 uint16_t usPowerTuneDataSetID;
349 uint16_t usSoftwareShutdownTemp;
350 uint16_t usClockStretchAmount;
351 uint16_t usTemperatureLimitHotspot;
352 uint16_t usTemperatureLimitLiquid1;
353 uint16_t usTemperatureLimitLiquid2;
354 uint16_t usTemperatureLimitVrVddc;
355 uint16_t usTemperatureLimitVrMvdd;
356 uint16_t usTemperatureLimitPlx;
357 uint8_t ucLiquid1_I2C_address;
358 uint8_t ucLiquid2_I2C_address;
359 uint8_t ucLiquid_I2C_Line;
360 uint8_t ucVr_I2C_address;
361 uint8_t ucVr_I2C_Line;
362 uint8_t ucPlx_I2C_address;
363 uint8_t ucPlx_I2C_Line;
364};
365
366struct phm_ppm_table {
367 uint8_t ppm_design;
368 uint16_t cpu_core_number;
369 uint32_t platform_tdp;
370 uint32_t small_ac_platform_tdp;
371 uint32_t platform_tdc;
372 uint32_t small_ac_platform_tdc;
373 uint32_t apu_tdp;
374 uint32_t dgpu_tdp;
375 uint32_t dgpu_ulv_power;
376 uint32_t tj_max;
377};
378
379struct phm_vq_budgeting_record {
380 uint32_t ulCUs;
381 uint32_t ulSustainableSOCPowerLimitLow;
382 uint32_t ulSustainableSOCPowerLimitHigh;
383 uint32_t ulMinSclkLow;
384 uint32_t ulMinSclkHigh;
385 uint8_t ucDispConfig;
386 uint32_t ulDClk;
387 uint32_t ulEClk;
388 uint32_t ulSustainableSclk;
389 uint32_t ulSustainableCUs;
390};
391
392struct phm_vq_budgeting_table {
393 uint8_t numEntries;
394 struct phm_vq_budgeting_record entries[1];
395};
396
397struct phm_clock_and_voltage_limits {
398 uint32_t sclk;
399 uint32_t mclk;
400 uint16_t vddc;
401 uint16_t vddci;
402 uint16_t vddgfx;
403};
404
yanyang1c82baa22015-08-18 15:28:32 +0800405/* Structure to hold PPTable information */
Jammy Zhou3bace352015-07-21 21:18:15 +0800406
yanyang1c82baa22015-08-18 15:28:32 +0800407struct phm_ppt_v1_information {
408 struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_sclk;
409 struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_mclk;
410 struct phm_clock_array *valid_sclk_values;
411 struct phm_clock_array *valid_mclk_values;
412 struct phm_clock_and_voltage_limits max_clock_voltage_on_dc;
413 struct phm_clock_and_voltage_limits max_clock_voltage_on_ac;
414 struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;
415 struct phm_ppm_table *ppm_parameter_table;
416 struct phm_cac_tdp_table *cac_dtp_table;
417 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_dep_table;
418 struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
419 struct phm_ppt_v1_voltage_lookup_table *vddgfx_lookup_table;
420 struct phm_ppt_v1_pcie_table *pcie_table;
421 uint16_t us_ulv_voltage_offset;
422};
Jammy Zhou3bace352015-07-21 21:18:15 +0800423
424struct phm_dynamic_state_info {
425 struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk;
426 struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk;
427 struct phm_clock_voltage_dependency_table *vddc_dependency_on_mclk;
428 struct phm_clock_voltage_dependency_table *mvdd_dependency_on_mclk;
429 struct phm_clock_voltage_dependency_table *vddc_dep_on_dal_pwrl;
430 struct phm_clock_array *valid_sclk_values;
431 struct phm_clock_array *valid_mclk_values;
432 struct phm_clock_and_voltage_limits max_clock_voltage_on_dc;
433 struct phm_clock_and_voltage_limits max_clock_voltage_on_ac;
434 uint32_t mclk_sclk_ratio;
435 uint32_t sclk_mclk_delta;
436 uint32_t vddc_vddci_delta;
437 uint32_t min_vddc_for_pcie_gen2;
438 struct phm_cac_leakage_table *cac_leakage_table;
439 struct phm_phase_shedding_limits_table *vddc_phase_shed_limits_table;
440
441 struct phm_vce_clock_voltage_dependency_table
442 *vce_clocl_voltage_dependency_table;
443 struct phm_uvd_clock_voltage_dependency_table
444 *uvd_clocl_voltage_dependency_table;
445 struct phm_acp_clock_voltage_dependency_table
446 *acp_clock_voltage_dependency_table;
447 struct phm_samu_clock_voltage_dependency_table
448 *samu_clock_voltage_dependency_table;
449
450 struct phm_ppm_table *ppm_parameter_table;
451 struct phm_cac_tdp_table *cac_dtp_table;
452 struct phm_clock_voltage_dependency_table *vdd_gfx_dependency_on_sclk;
453 struct phm_vq_budgeting_table *vq_budgeting_table;
454};
455
yanyang1c82baa22015-08-18 15:28:32 +0800456struct pp_fan_info {
457 bool bNoFan;
458 uint8_t ucTachometerPulsesPerRevolution;
459 uint32_t ulMinRPM;
460 uint32_t ulMaxRPM;
461};
462
463struct pp_advance_fan_control_parameters {
464 uint16_t usTMin; /* The temperature, in 0.01 centigrades, below which we just run at a minimal PWM. */
465 uint16_t usTMed; /* The middle temperature where we change slopes. */
466 uint16_t usTHigh; /* The high temperature for setting the second slope. */
467 uint16_t usPWMMin; /* The minimum PWM value in percent (0.01% increments). */
468 uint16_t usPWMMed; /* The PWM value (in percent) at TMed. */
469 uint16_t usPWMHigh; /* The PWM value at THigh. */
470 uint8_t ucTHyst; /* Temperature hysteresis. Integer. */
471 uint32_t ulCycleDelay; /* The time between two invocations of the fan control routine in microseconds. */
472 uint16_t usTMax; /* The max temperature */
473 uint8_t ucFanControlMode;
474 uint16_t usFanPWMMinLimit;
475 uint16_t usFanPWMMaxLimit;
476 uint16_t usFanPWMStep;
477 uint16_t usDefaultMaxFanPWM;
478 uint16_t usFanOutputSensitivity;
479 uint16_t usDefaultFanOutputSensitivity;
480 uint16_t usMaxFanPWM; /* The max Fan PWM value for Fuzzy Fan Control feature */
481 uint16_t usFanRPMMinLimit; /* Minimum limit range in percentage, need to calculate based on minRPM/MaxRpm */
482 uint16_t usFanRPMMaxLimit; /* Maximum limit range in percentage, usually set to 100% by default */
483 uint16_t usFanRPMStep; /* Step increments/decerements, in percent */
484 uint16_t usDefaultMaxFanRPM; /* The max Fan RPM value for Fuzzy Fan Control feature, default from PPTable */
485 uint16_t usMaxFanRPM; /* The max Fan RPM value for Fuzzy Fan Control feature, user defined */
486 uint16_t usFanCurrentLow; /* Low current */
487 uint16_t usFanCurrentHigh; /* High current */
488 uint16_t usFanRPMLow; /* Low RPM */
489 uint16_t usFanRPMHigh; /* High RPM */
490 uint32_t ulMinFanSCLKAcousticLimit; /* Minimum Fan Controller SCLK Frequency Acoustic Limit. */
491 uint8_t ucTargetTemperature; /* Advanced fan controller target temperature. */
492 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. */
493 uint16_t usFanGainEdge; /* The following is added for Fiji */
494 uint16_t usFanGainHotspot;
495 uint16_t usFanGainLiquid;
496 uint16_t usFanGainVrVddc;
497 uint16_t usFanGainVrMvdd;
498 uint16_t usFanGainPlx;
499 uint16_t usFanGainHbm;
500};
501
502struct pp_thermal_controller_info {
503 uint8_t ucType;
504 uint8_t ucI2cLine;
505 uint8_t ucI2cAddress;
506 struct pp_fan_info fanInfo;
507 struct pp_advance_fan_control_parameters advanceFanControlParameters;
508};
509
510struct phm_microcode_version_info {
511 uint32_t SMC;
512 uint32_t DMCU;
513 uint32_t MC;
514 uint32_t NB;
515};
516
517/**
518 * The main hardware manager structure.
519 */
Jammy Zhou3bace352015-07-21 21:18:15 +0800520struct pp_hwmgr {
521 uint32_t chip_family;
522 uint32_t chip_id;
523 uint32_t hw_revision;
524 uint32_t sub_sys_id;
525 uint32_t sub_vendor_id;
526
527 void *device;
528 struct pp_smumgr *smumgr;
529 const void *soft_pp_table;
530 enum amd_dpm_forced_level dpm_level;
Rex Zhu28a18ba2015-09-23 15:14:38 +0800531 bool block_hw_access;
Jammy Zhou3bace352015-07-21 21:18:15 +0800532 struct phm_gfx_arbiter gfx_arbiter;
533 struct phm_acp_arbiter acp_arbiter;
534 struct phm_uvd_arbiter uvd_arbiter;
535 struct phm_vce_arbiter vce_arbiter;
536 uint32_t usec_timeout;
537 void *pptable;
538 struct phm_platform_descriptor platform_descriptor;
539 void *backend;
540 enum PP_DAL_POWERLEVEL dal_power_level;
541 struct phm_dynamic_state_info dyn_state;
542 struct phm_runtime_table_header setup_asic;
543 struct phm_runtime_table_header disable_dynamic_state_management;
544 struct phm_runtime_table_header enable_dynamic_state_management;
Rex Zhu28a18ba2015-09-23 15:14:38 +0800545 struct phm_runtime_table_header set_power_state;
546 struct phm_runtime_table_header enable_clock_power_gatings;
Rex Zhue8c7de52015-10-16 14:51:09 +0800547 struct phm_runtime_table_header display_configuration_changed;
Jammy Zhou3bace352015-07-21 21:18:15 +0800548 const struct pp_hwmgr_func *hwmgr_func;
549 const struct pp_table_func *pptable_func;
550 struct pp_power_state *ps;
551 enum pp_power_source power_source;
552 uint32_t num_ps;
yanyang1c82baa22015-08-18 15:28:32 +0800553 struct pp_thermal_controller_info thermal_controller;
554 struct phm_microcode_version_info microcode_version_info;
Jammy Zhou3bace352015-07-21 21:18:15 +0800555 uint32_t ps_size;
556 struct pp_power_state *current_ps;
557 struct pp_power_state *request_ps;
558 struct pp_power_state *boot_ps;
559 struct pp_power_state *uvd_ps;
560};
561
562
563extern int hwmgr_init(struct amd_pp_init *pp_init,
564 struct pp_instance *handle);
565
566extern int hwmgr_fini(struct pp_hwmgr *hwmgr);
567
568extern int hw_init_power_state_table(struct pp_hwmgr *hwmgr);
569
570extern int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
571 uint32_t value, uint32_t mask);
572
573extern int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
574 uint32_t index, uint32_t value, uint32_t mask);
575
yanyang1c82baa22015-08-18 15:28:32 +0800576extern uint32_t phm_read_indirect_register(struct pp_hwmgr *hwmgr,
577 uint32_t indirect_port, uint32_t index);
Jammy Zhou3bace352015-07-21 21:18:15 +0800578
yanyang1c82baa22015-08-18 15:28:32 +0800579extern void phm_write_indirect_register(struct pp_hwmgr *hwmgr,
580 uint32_t indirect_port,
581 uint32_t index,
582 uint32_t value);
Jammy Zhou3bace352015-07-21 21:18:15 +0800583
584extern void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
585 uint32_t indirect_port,
586 uint32_t index,
587 uint32_t value,
588 uint32_t mask);
589
590extern void phm_wait_for_indirect_register_unequal(
591 struct pp_hwmgr *hwmgr,
592 uint32_t indirect_port,
593 uint32_t index,
594 uint32_t value,
595 uint32_t mask);
596
Rex Zhu28a18ba2015-09-23 15:14:38 +0800597bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr);
598bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr);
599
600#define PHM_ENTIRE_REGISTER_MASK 0xFFFFFFFFU
601
Jammy Zhou3bace352015-07-21 21:18:15 +0800602#define PHM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
603#define PHM_FIELD_MASK(reg, field) reg##__##field##_MASK
604
605#define PHM_SET_FIELD(origval, reg, field, fieldval) \
606 (((origval) & ~PHM_FIELD_MASK(reg, field)) | \
607 (PHM_FIELD_MASK(reg, field) & ((fieldval) << PHM_FIELD_SHIFT(reg, field))))
608
609#define PHM_GET_FIELD(value, reg, field) \
610 (((value) & PHM_FIELD_MASK(reg, field)) >> \
611 PHM_FIELD_SHIFT(reg, field))
612
613
614#define PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, index, value, mask) \
615 phm_wait_on_register(hwmgr, index, value, mask)
616
617#define PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, index, value, mask) \
618 phm_wait_for_register_unequal(hwmgr, index, value, mask)
619
620#define PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
621 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX, index, value, mask)
622
623#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask) \
624 phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX, index, value, mask)
625
626#define PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, index, value, mask) \
627 phm_wait_on_indirect_register(hwmgr, mm##port##_INDEX_0, index, value, mask)
628
629#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, index, value, mask) \
630 phm_wait_for_indirect_register_unequal(hwmgr, mm##port##_INDEX_0, index, value, mask)
631
632/* Operations on named registers. */
633
634#define PHM_WAIT_REGISTER(hwmgr, reg, value, mask) \
635 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
636
637#define PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, value, mask) \
638 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg, value, mask)
639
640#define PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
641 PHM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
642
643#define PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask) \
644 PHM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
645
646#define PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, value, mask) \
647 PHM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
648
649#define PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, value, mask) \
650 PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, port, ix##reg, value, mask)
651
652/* Operations on named fields. */
653
654#define PHM_READ_FIELD(device, reg, field) \
655 PHM_GET_FIELD(cgs_read_register(device, mm##reg), reg, field)
656
657#define PHM_READ_INDIRECT_FIELD(device, port, reg, field) \
658 PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
659 reg, field)
660
661#define PHM_READ_VFPF_INDIRECT_FIELD(device, port, reg, field) \
662 PHM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
663 reg, field)
664
665#define PHM_WRITE_FIELD(device, reg, field, fieldval) \
666 cgs_write_register(device, mm##reg, PHM_SET_FIELD( \
667 cgs_read_register(device, mm##reg), reg, field, fieldval))
668
669#define PHM_WRITE_INDIRECT_FIELD(device, port, reg, field, fieldval) \
670 cgs_write_ind_register(device, port, ix##reg, \
671 PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
672 reg, field, fieldval))
673
674#define PHM_WRITE_VFPF_INDIRECT_FIELD(device, port, reg, field, fieldval) \
675 cgs_write_ind_register(device, port, ix##reg, \
676 PHM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
677 reg, field, fieldval))
678
679#define PHM_WAIT_FIELD(hwmgr, reg, field, fieldval) \
680 PHM_WAIT_REGISTER(hwmgr, reg, (fieldval) \
681 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
682
683#define PHM_WAIT_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
684 PHM_WAIT_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
685 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
686
687#define PHM_WAIT_VFPF_INDIRECT_FIELD(hwmgr, port, reg, field, fieldval) \
688 PHM_WAIT_VFPF_INDIRECT_REGISTER(hwmgr, port, reg, (fieldval) \
689 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
690
691#define PHM_WAIT_FIELD_UNEQUAL(hwmgr, reg, field, fieldval) \
692 PHM_WAIT_REGISTER_UNEQUAL(hwmgr, reg, (fieldval) \
693 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
694
695#define PHM_WAIT_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
696 PHM_WAIT_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval) \
697 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
698
699#define PHM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(hwmgr, port, reg, field, fieldval) \
700 PHM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(hwmgr, port, reg, (fieldval) \
701 << PHM_FIELD_SHIFT(reg, field), PHM_FIELD_MASK(reg, field))
702
703/* Operations on arrays of registers & fields. */
704
705#define PHM_READ_ARRAY_REGISTER(device, reg, offset) \
706 cgs_read_register(device, mm##reg + (offset))
707
708#define PHM_WRITE_ARRAY_REGISTER(device, reg, offset, value) \
709 cgs_write_register(device, mm##reg + (offset), value)
710
711#define PHM_WAIT_ARRAY_REGISTER(hwmgr, reg, offset, value, mask) \
712 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
713
714#define PHM_WAIT_ARRAY_REGISTER_UNEQUAL(hwmgr, reg, offset, value, mask) \
715 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), value, mask)
716
717#define PHM_READ_ARRAY_FIELD(hwmgr, reg, offset, field) \
718 PHM_GET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), reg, field)
719
720#define PHM_WRITE_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue) \
721 PHM_WRITE_ARRAY_REGISTER(hwmgr->device, reg, offset, \
722 PHM_SET_FIELD(PHM_READ_ARRAY_REGISTER(hwmgr->device, reg, offset), \
723 reg, field, fieldvalue))
724
725#define PHM_WAIT_ARRAY_FIELD(hwmgr, reg, offset, field, fieldvalue) \
726 PHM_WAIT_REGISTER_GIVEN_INDEX(hwmgr, mm##reg + (offset), \
727 (fieldvalue) << PHM_FIELD_SHIFT(reg, field), \
728 PHM_FIELD_MASK(reg, field))
729
730#define PHM_WAIT_ARRAY_FIELD_UNEQUAL(hwmgr, reg, offset, field, fieldvalue) \
731 PHM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(hwmgr, mm##reg + (offset), \
732 (fieldvalue) << PHM_FIELD_SHIFT(reg, field), \
733 PHM_FIELD_MASK(reg, field))
734
735#endif /* _HWMGR_H_ */