diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2017-05-11 16:38:38 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-05-24 17:41:52 -0400 |
commit | a960d61cbd62544c04adb4fe6513577601ff4535 (patch) | |
tree | 11e9603c10acd5c9af4d2c1633609b4735ce8b09 /drivers/gpu/drm | |
parent | 4fa483e5b30bbc334d7335df95bcc5d8c062e9de (diff) |
drm/amd/powerplay: add raven support in hwmgr. (v2)
hwmgr handles the GPU power state management.
v2: squash in updates (Alex)
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 974 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h | 295 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 18 |
8 files changed, 1291 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c index 781e53dcf128..3e3ca03bd344 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventmgr.c | |||
@@ -42,8 +42,8 @@ static int pem_init(struct pp_eventmgr *eventmgr) | |||
42 | /* Call initialization event */ | 42 | /* Call initialization event */ |
43 | result = pem_handle_event(eventmgr, AMD_PP_EVENT_INITIALIZE, &event_data); | 43 | result = pem_handle_event(eventmgr, AMD_PP_EVENT_INITIALIZE, &event_data); |
44 | 44 | ||
45 | if (0 != result) | 45 | /* if (0 != result) |
46 | return result; | 46 | return result; */ |
47 | 47 | ||
48 | /* Register interrupt callback functions */ | 48 | /* Register interrupt callback functions */ |
49 | result = pem_register_interrupts(eventmgr); | 49 | result = pem_register_interrupts(eventmgr); |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile index 4edcd51df9ef..f0277c16c2bf 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/Makefile | |||
@@ -9,7 +9,7 @@ HARDWARE_MGR = hwmgr.o processpptables.o functiontables.o \ | |||
9 | smu7_hwmgr.o smu7_powertune.o smu7_thermal.o \ | 9 | smu7_hwmgr.o smu7_powertune.o smu7_thermal.o \ |
10 | smu7_clockpowergating.o \ | 10 | smu7_clockpowergating.o \ |
11 | vega10_processpptables.o vega10_hwmgr.o vega10_powertune.o \ | 11 | vega10_processpptables.o vega10_hwmgr.o vega10_powertune.o \ |
12 | vega10_thermal.o pp_overdriver.o | 12 | vega10_thermal.o pp_overdriver.o rv_hwmgr.o |
13 | 13 | ||
14 | AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) | 14 | AMD_PP_HWMGR = $(addprefix $(AMD_PP_PATH)/hwmgr/,$(HARDWARE_MGR)) |
15 | 15 | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index ff4ae3de6bb6..27fe108823ee 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c | |||
@@ -115,6 +115,15 @@ int hwmgr_early_init(struct pp_instance *handle) | |||
115 | return -EINVAL; | 115 | return -EINVAL; |
116 | } | 116 | } |
117 | break; | 117 | break; |
118 | case AMDGPU_FAMILY_RV: | ||
119 | switch (hwmgr->chip_id) { | ||
120 | case CHIP_RAVEN: | ||
121 | rv_init_function_pointers(hwmgr); | ||
122 | break; | ||
123 | default: | ||
124 | return -EINVAL; | ||
125 | } | ||
126 | break; | ||
118 | default: | 127 | default: |
119 | return -EINVAL; | 128 | return -EINVAL; |
120 | } | 129 | } |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c index ed6c934927fb..7138cf9e96d4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c | |||
@@ -1015,6 +1015,10 @@ static int init_overdrive_limits(struct pp_hwmgr *hwmgr, | |||
1015 | hwmgr->platform_descriptor.overdriveLimit.memoryClock = 0; | 1015 | hwmgr->platform_descriptor.overdriveLimit.memoryClock = 0; |
1016 | hwmgr->platform_descriptor.minOverdriveVDDC = 0; | 1016 | hwmgr->platform_descriptor.minOverdriveVDDC = 0; |
1017 | hwmgr->platform_descriptor.maxOverdriveVDDC = 0; | 1017 | hwmgr->platform_descriptor.maxOverdriveVDDC = 0; |
1018 | hwmgr->platform_descriptor.overdriveVDDCStep = 0; | ||
1019 | |||
1020 | if (hwmgr->chip_id == CHIP_RAVEN) | ||
1021 | return 0; | ||
1018 | 1022 | ||
1019 | /* We assume here that fw_info is unchanged if this call fails.*/ | 1023 | /* We assume here that fw_info is unchanged if this call fails.*/ |
1020 | fw_info = cgs_atom_get_data_table(hwmgr->device, | 1024 | fw_info = cgs_atom_get_data_table(hwmgr->device, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c new file mode 100644 index 000000000000..fe7082a34cc7 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | |||
@@ -0,0 +1,974 @@ | |||
1 | /* | ||
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 | #include "pp_debug.h" | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include "atom-types.h" | ||
28 | #include "atombios.h" | ||
29 | #include "processpptables.h" | ||
30 | #include "cgs_common.h" | ||
31 | #include "smumgr.h" | ||
32 | #include "hwmgr.h" | ||
33 | #include "hardwaremanager.h" | ||
34 | #include "rv_ppsmc.h" | ||
35 | #include "rv_hwmgr.h" | ||
36 | #include "power_state.h" | ||
37 | #include "rv_smumgr.h" | ||
38 | |||
39 | #define RAVEN_MAX_DEEPSLEEP_DIVIDER_ID 5 | ||
40 | #define RAVEN_MINIMUM_ENGINE_CLOCK 800 //8Mhz, the low boundary of engine clock allowed on this chip | ||
41 | #define SCLK_MIN_DIV_INTV_SHIFT 12 | ||
42 | #define RAVEN_DISPCLK_BYPASS_THRESHOLD 10000 //100mhz | ||
43 | #define SMC_RAM_END 0x40000 | ||
44 | |||
45 | |||
46 | static const unsigned long PhwRaven_Magic = (unsigned long) PHM_Cz_Magic; | ||
47 | |||
48 | struct phm_vq_budgeting_record rv_vqtable[] = { | ||
49 | /* _TBD | ||
50 | * CUs, SSP low, SSP High, Min Sclk Low, Min Sclk, High, AWD/non-AWD, DCLK, ECLK, Sustainable Sclk, Sustainable CUs */ | ||
51 | { 8, 0, 45, 0, 0, VQ_DisplayConfig_NoneAWD, 80000, 120000, 4, 0 }, | ||
52 | }; | ||
53 | |||
54 | static struct rv_power_state *cast_rv_ps(struct pp_hw_power_state *hw_ps) | ||
55 | { | ||
56 | if (PhwRaven_Magic != hw_ps->magic) | ||
57 | return NULL; | ||
58 | |||
59 | return (struct rv_power_state *)hw_ps; | ||
60 | } | ||
61 | |||
62 | static const struct rv_power_state *cast_const_rv_ps( | ||
63 | const struct pp_hw_power_state *hw_ps) | ||
64 | { | ||
65 | if (PhwRaven_Magic != hw_ps->magic) | ||
66 | return NULL; | ||
67 | |||
68 | return (struct rv_power_state *)hw_ps; | ||
69 | } | ||
70 | |||
71 | static int rv_init_vq_budget_table(struct pp_hwmgr *hwmgr) | ||
72 | { | ||
73 | uint32_t table_size, i; | ||
74 | struct phm_vq_budgeting_table *ptable; | ||
75 | uint32_t num_entries = (sizeof(rv_vqtable) / sizeof(*rv_vqtable)); | ||
76 | |||
77 | if (hwmgr->dyn_state.vq_budgeting_table != NULL) | ||
78 | return 0; | ||
79 | |||
80 | table_size = sizeof(struct phm_vq_budgeting_table) + | ||
81 | sizeof(struct phm_vq_budgeting_record) * (num_entries - 1); | ||
82 | |||
83 | ptable = kzalloc(table_size, GFP_KERNEL); | ||
84 | if (NULL == ptable) | ||
85 | return -ENOMEM; | ||
86 | |||
87 | ptable->numEntries = (uint8_t) num_entries; | ||
88 | |||
89 | for (i = 0; i < ptable->numEntries; i++) { | ||
90 | ptable->entries[i].ulCUs = rv_vqtable[i].ulCUs; | ||
91 | ptable->entries[i].ulSustainableSOCPowerLimitLow = rv_vqtable[i].ulSustainableSOCPowerLimitLow; | ||
92 | ptable->entries[i].ulSustainableSOCPowerLimitHigh = rv_vqtable[i].ulSustainableSOCPowerLimitHigh; | ||
93 | ptable->entries[i].ulMinSclkLow = rv_vqtable[i].ulMinSclkLow; | ||
94 | ptable->entries[i].ulMinSclkHigh = rv_vqtable[i].ulMinSclkHigh; | ||
95 | ptable->entries[i].ucDispConfig = rv_vqtable[i].ucDispConfig; | ||
96 | ptable->entries[i].ulDClk = rv_vqtable[i].ulDClk; | ||
97 | ptable->entries[i].ulEClk = rv_vqtable[i].ulEClk; | ||
98 | ptable->entries[i].ulSustainableSclk = rv_vqtable[i].ulSustainableSclk; | ||
99 | ptable->entries[i].ulSustainableCUs = rv_vqtable[i].ulSustainableCUs; | ||
100 | } | ||
101 | |||
102 | hwmgr->dyn_state.vq_budgeting_table = ptable; | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int rv_initialize_dpm_defaults(struct pp_hwmgr *hwmgr) | ||
108 | { | ||
109 | struct rv_hwmgr *rv_hwmgr = (struct rv_hwmgr *)(hwmgr->backend); | ||
110 | struct cgs_system_info sys_info = {0}; | ||
111 | int result; | ||
112 | |||
113 | rv_hwmgr->ddi_power_gating_disabled = 0; | ||
114 | rv_hwmgr->bapm_enabled = 1; | ||
115 | rv_hwmgr->dce_slow_sclk_threshold = 30000; | ||
116 | rv_hwmgr->disable_driver_thermal_policy = 1; | ||
117 | rv_hwmgr->thermal_auto_throttling_treshold = 0; | ||
118 | rv_hwmgr->is_nb_dpm_enabled = 1; | ||
119 | rv_hwmgr->dpm_flags = 1; | ||
120 | rv_hwmgr->disable_smu_acp_s3_handshake = 1; | ||
121 | rv_hwmgr->disable_notify_smu_vpu_recovery = 0; | ||
122 | rv_hwmgr->gfx_off_controled_by_driver = false; | ||
123 | |||
124 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
125 | PHM_PlatformCaps_DynamicM3Arbiter); | ||
126 | |||
127 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
128 | PHM_PlatformCaps_UVDPowerGating); | ||
129 | |||
130 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
131 | PHM_PlatformCaps_UVDDynamicPowerGating); | ||
132 | |||
133 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
134 | PHM_PlatformCaps_VCEPowerGating); | ||
135 | |||
136 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
137 | PHM_PlatformCaps_SamuPowerGating); | ||
138 | |||
139 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
140 | PHM_PlatformCaps_ACP); | ||
141 | |||
142 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
143 | PHM_PlatformCaps_SclkDeepSleep); | ||
144 | |||
145 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
146 | PHM_PlatformCaps_GFXDynamicMGPowerGating); | ||
147 | |||
148 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
149 | PHM_PlatformCaps_SclkThrottleLowNotification); | ||
150 | |||
151 | phm_cap_unset(hwmgr->platform_descriptor.platformCaps, | ||
152 | PHM_PlatformCaps_DisableVoltageIsland); | ||
153 | |||
154 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | ||
155 | PHM_PlatformCaps_DynamicUVDState); | ||
156 | |||
157 | sys_info.size = sizeof(struct cgs_system_info); | ||
158 | sys_info.info_id = CGS_SYSTEM_INFO_PG_FLAGS; | ||
159 | result = cgs_query_system_info(hwmgr->device, &sys_info); | ||
160 | if (!result) { | ||
161 | if (sys_info.value & AMD_PG_SUPPORT_GFX_DMG) | ||
162 | phm_cap_set(hwmgr->platform_descriptor.platformCaps, | ||
163 | PHM_PlatformCaps_GFXDynamicMGPowerGating); | ||
164 | } | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int rv_construct_max_power_limits_table(struct pp_hwmgr *hwmgr, | ||
170 | struct phm_clock_and_voltage_limits *table) | ||
171 | { | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int rv_init_dynamic_state_adjustment_rule_settings( | ||
176 | struct pp_hwmgr *hwmgr) | ||
177 | { | ||
178 | uint32_t table_size = | ||
179 | sizeof(struct phm_clock_voltage_dependency_table) + | ||
180 | (7 * sizeof(struct phm_clock_voltage_dependency_record)); | ||
181 | |||
182 | struct phm_clock_voltage_dependency_table *table_clk_vlt = | ||
183 | kzalloc(table_size, GFP_KERNEL); | ||
184 | |||
185 | if (NULL == table_clk_vlt) { | ||
186 | pr_err("Can not allocate memory!\n"); | ||
187 | return -ENOMEM; | ||
188 | } | ||
189 | |||
190 | table_clk_vlt->count = 8; | ||
191 | table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_0; | ||
192 | table_clk_vlt->entries[0].v = 0; | ||
193 | table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_1; | ||
194 | table_clk_vlt->entries[1].v = 1; | ||
195 | table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_2; | ||
196 | table_clk_vlt->entries[2].v = 2; | ||
197 | table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_3; | ||
198 | table_clk_vlt->entries[3].v = 3; | ||
199 | table_clk_vlt->entries[4].clk = PP_DAL_POWERLEVEL_4; | ||
200 | table_clk_vlt->entries[4].v = 4; | ||
201 | table_clk_vlt->entries[5].clk = PP_DAL_POWERLEVEL_5; | ||
202 | table_clk_vlt->entries[5].v = 5; | ||
203 | table_clk_vlt->entries[6].clk = PP_DAL_POWERLEVEL_6; | ||
204 | table_clk_vlt->entries[6].v = 6; | ||
205 | table_clk_vlt->entries[7].clk = PP_DAL_POWERLEVEL_7; | ||
206 | table_clk_vlt->entries[7].v = 7; | ||
207 | hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt; | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int rv_get_system_info_data(struct pp_hwmgr *hwmgr) | ||
213 | { | ||
214 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)hwmgr->backend; | ||
215 | |||
216 | rv_data->sys_info.htc_hyst_lmt = 5; | ||
217 | rv_data->sys_info.htc_tmp_lmt = 203; | ||
218 | |||
219 | if (rv_data->thermal_auto_throttling_treshold == 0) | ||
220 | rv_data->thermal_auto_throttling_treshold = 203; | ||
221 | |||
222 | rv_construct_max_power_limits_table (hwmgr, | ||
223 | &hwmgr->dyn_state.max_clock_voltage_on_ac); | ||
224 | |||
225 | rv_init_dynamic_state_adjustment_rule_settings(hwmgr); | ||
226 | |||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int rv_construct_boot_state(struct pp_hwmgr *hwmgr) | ||
231 | { | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int rv_tf_set_isp_clock_limit(struct pp_hwmgr *hwmgr, void *input, | ||
236 | void *output, void *storage, int result) | ||
237 | { | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int rv_tf_set_num_active_display(struct pp_hwmgr *hwmgr, void *input, | ||
242 | void *output, void *storage, int result) | ||
243 | { | ||
244 | uint32_t num_of_active_displays = 0; | ||
245 | struct cgs_display_info info = {0}; | ||
246 | |||
247 | cgs_get_active_displays_info(hwmgr->device, &info); | ||
248 | num_of_active_displays = info.display_count; | ||
249 | |||
250 | smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, | ||
251 | PPSMC_MSG_SetDisplayCount, | ||
252 | num_of_active_displays); | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static const struct phm_master_table_item rv_set_power_state_list[] = { | ||
257 | { NULL, rv_tf_set_isp_clock_limit }, | ||
258 | { NULL, rv_tf_set_num_active_display }, | ||
259 | { } | ||
260 | }; | ||
261 | |||
262 | static const struct phm_master_table_header rv_set_power_state_master = { | ||
263 | 0, | ||
264 | PHM_MasterTableFlag_None, | ||
265 | rv_set_power_state_list | ||
266 | }; | ||
267 | |||
268 | static int rv_tf_init_power_gate_state(struct pp_hwmgr *hwmgr, void *input, | ||
269 | void *output, void *storage, int result) | ||
270 | { | ||
271 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
272 | |||
273 | rv_data->vcn_power_gated = true; | ||
274 | rv_data->isp_tileA_power_gated = true; | ||
275 | rv_data->isp_tileB_power_gated = true; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static const struct phm_master_table_item rv_setup_asic_list[] = { | ||
281 | { .tableFunction = rv_tf_init_power_gate_state }, | ||
282 | { } | ||
283 | }; | ||
284 | |||
285 | static const struct phm_master_table_header rv_setup_asic_master = { | ||
286 | 0, | ||
287 | PHM_MasterTableFlag_None, | ||
288 | rv_setup_asic_list | ||
289 | }; | ||
290 | |||
291 | static int rv_tf_reset_cc6_data(struct pp_hwmgr *hwmgr, | ||
292 | void *input, void *output, | ||
293 | void *storage, int result) | ||
294 | { | ||
295 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
296 | |||
297 | rv_data->separation_time = 0; | ||
298 | rv_data->cc6_disable = false; | ||
299 | rv_data->pstate_disable = false; | ||
300 | rv_data->cc6_setting_changed = false; | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static const struct phm_master_table_item rv_power_down_asic_list[] = { | ||
306 | { .tableFunction = rv_tf_reset_cc6_data }, | ||
307 | { } | ||
308 | }; | ||
309 | |||
310 | static const struct phm_master_table_header rv_power_down_asic_master = { | ||
311 | 0, | ||
312 | PHM_MasterTableFlag_None, | ||
313 | rv_power_down_asic_list | ||
314 | }; | ||
315 | |||
316 | |||
317 | static int rv_tf_disable_gfx_off(struct pp_hwmgr *hwmgr, | ||
318 | void *input, void *output, | ||
319 | void *storage, int result) | ||
320 | { | ||
321 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
322 | |||
323 | if (rv_data->gfx_off_controled_by_driver) | ||
324 | smum_send_msg_to_smc(hwmgr->smumgr, | ||
325 | PPSMC_MSG_DisableGfxOff); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static const struct phm_master_table_item rv_disable_dpm_list[] = { | ||
331 | {NULL, rv_tf_disable_gfx_off}, | ||
332 | { }, | ||
333 | }; | ||
334 | |||
335 | |||
336 | static const struct phm_master_table_header rv_disable_dpm_master = { | ||
337 | 0, | ||
338 | PHM_MasterTableFlag_None, | ||
339 | rv_disable_dpm_list | ||
340 | }; | ||
341 | |||
342 | static int rv_tf_enable_gfx_off(struct pp_hwmgr *hwmgr, | ||
343 | void *input, void *output, | ||
344 | void *storage, int result) | ||
345 | { | ||
346 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
347 | |||
348 | if (rv_data->gfx_off_controled_by_driver) | ||
349 | smum_send_msg_to_smc(hwmgr->smumgr, | ||
350 | PPSMC_MSG_EnableGfxOff); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | static const struct phm_master_table_item rv_enable_dpm_list[] = { | ||
356 | {NULL, rv_tf_enable_gfx_off}, | ||
357 | { }, | ||
358 | }; | ||
359 | |||
360 | static const struct phm_master_table_header rv_enable_dpm_master = { | ||
361 | 0, | ||
362 | PHM_MasterTableFlag_None, | ||
363 | rv_enable_dpm_list | ||
364 | }; | ||
365 | |||
366 | static int rv_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, | ||
367 | struct pp_power_state *prequest_ps, | ||
368 | const struct pp_power_state *pcurrent_ps) | ||
369 | { | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | /* temporary hardcoded clock voltage breakdown tables */ | ||
374 | DpmClock_t VddDcfClk[]= { | ||
375 | { 300, 2600}, | ||
376 | { 600, 3200}, | ||
377 | { 600, 3600}, | ||
378 | }; | ||
379 | |||
380 | DpmClock_t VddSocClk[]= { | ||
381 | { 478, 2600}, | ||
382 | { 722, 3200}, | ||
383 | { 722, 3600}, | ||
384 | }; | ||
385 | |||
386 | DpmClock_t VddFClk[]= { | ||
387 | { 400, 2600}, | ||
388 | {1200, 3200}, | ||
389 | {1200, 3600}, | ||
390 | }; | ||
391 | |||
392 | DpmClock_t VddDispClk[]= { | ||
393 | { 435, 2600}, | ||
394 | { 661, 3200}, | ||
395 | {1086, 3600}, | ||
396 | }; | ||
397 | |||
398 | DpmClock_t VddDppClk[]= { | ||
399 | { 435, 2600}, | ||
400 | { 661, 3200}, | ||
401 | { 661, 3600}, | ||
402 | }; | ||
403 | |||
404 | DpmClock_t VddPhyClk[]= { | ||
405 | { 540, 2600}, | ||
406 | { 810, 3200}, | ||
407 | { 810, 3600}, | ||
408 | }; | ||
409 | |||
410 | static int rv_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr, | ||
411 | struct rv_voltage_dependency_table **pptable, | ||
412 | uint32_t num_entry, DpmClock_t *pclk_dependency_table) | ||
413 | { | ||
414 | uint32_t table_size, i; | ||
415 | struct rv_voltage_dependency_table *ptable; | ||
416 | |||
417 | table_size = sizeof(uint32_t) + sizeof(struct rv_voltage_dependency_table) * num_entry; | ||
418 | ptable = kzalloc(table_size, GFP_KERNEL); | ||
419 | |||
420 | if (NULL == ptable) | ||
421 | return -ENOMEM; | ||
422 | |||
423 | ptable->count = num_entry; | ||
424 | |||
425 | for (i = 0; i < ptable->count; i++) { | ||
426 | ptable->entries[i].clk = pclk_dependency_table->Freq * 100; | ||
427 | ptable->entries[i].vol = pclk_dependency_table->Vol; | ||
428 | pclk_dependency_table++; | ||
429 | } | ||
430 | |||
431 | *pptable = ptable; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | |||
437 | static int rv_populate_clock_table(struct pp_hwmgr *hwmgr) | ||
438 | { | ||
439 | int result; | ||
440 | |||
441 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
442 | DpmClocks_t *table = &(rv_data->clock_table); | ||
443 | struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info); | ||
444 | |||
445 | result = rv_copy_table_from_smc(hwmgr->smumgr, (uint8_t *)table, CLOCKTABLE); | ||
446 | |||
447 | PP_ASSERT_WITH_CODE((0 == result), | ||
448 | "Attempt to copy clock table from smc failed", | ||
449 | return result); | ||
450 | |||
451 | if (0 == result && table->DcefClocks[0].Freq != 0) { | ||
452 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dcefclk, | ||
453 | NUM_DCEFCLK_DPM_LEVELS, | ||
454 | &rv_data->clock_table.DcefClocks[0]); | ||
455 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_socclk, | ||
456 | NUM_SOCCLK_DPM_LEVELS, | ||
457 | &rv_data->clock_table.SocClocks[0]); | ||
458 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_fclk, | ||
459 | NUM_FCLK_DPM_LEVELS, | ||
460 | &rv_data->clock_table.FClocks[0]); | ||
461 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_mclk, | ||
462 | NUM_MEMCLK_DPM_LEVELS, | ||
463 | &rv_data->clock_table.MemClocks[0]); | ||
464 | } else { | ||
465 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dcefclk, | ||
466 | sizeof(VddDcfClk)/sizeof(*VddDcfClk), &VddDcfClk[0]); | ||
467 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_socclk, | ||
468 | sizeof(VddSocClk)/sizeof(*VddSocClk), &VddSocClk[0]); | ||
469 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_fclk, | ||
470 | sizeof(VddFClk)/sizeof(*VddFClk), &VddFClk[0]); | ||
471 | } | ||
472 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dispclk, | ||
473 | sizeof(VddDispClk)/sizeof(*VddDispClk), &VddDispClk[0]); | ||
474 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dppclk, | ||
475 | sizeof(VddDppClk)/sizeof(*VddDppClk), &VddDppClk[0]); | ||
476 | rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_phyclk, | ||
477 | sizeof(VddPhyClk)/sizeof(*VddPhyClk), &VddPhyClk[0]); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int rv_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | ||
483 | { | ||
484 | int result = 0; | ||
485 | struct rv_hwmgr *data; | ||
486 | |||
487 | data = kzalloc(sizeof(struct rv_hwmgr), GFP_KERNEL); | ||
488 | if (data == NULL) | ||
489 | return -ENOMEM; | ||
490 | |||
491 | hwmgr->backend = data; | ||
492 | |||
493 | result = rv_initialize_dpm_defaults(hwmgr); | ||
494 | if (result != 0) { | ||
495 | pr_err("rv_initialize_dpm_defaults failed\n"); | ||
496 | return result; | ||
497 | } | ||
498 | |||
499 | rv_populate_clock_table(hwmgr); | ||
500 | |||
501 | result = rv_get_system_info_data(hwmgr); | ||
502 | if (result != 0) { | ||
503 | pr_err("rv_get_system_info_data failed\n"); | ||
504 | return result; | ||
505 | } | ||
506 | |||
507 | rv_construct_boot_state(hwmgr); | ||
508 | |||
509 | result = phm_construct_table(hwmgr, &rv_setup_asic_master, | ||
510 | &(hwmgr->setup_asic)); | ||
511 | if (result != 0) { | ||
512 | pr_err("Fail to construct setup ASIC\n"); | ||
513 | return result; | ||
514 | } | ||
515 | |||
516 | result = phm_construct_table(hwmgr, &rv_power_down_asic_master, | ||
517 | &(hwmgr->power_down_asic)); | ||
518 | if (result != 0) { | ||
519 | pr_err("Fail to construct power down ASIC\n"); | ||
520 | return result; | ||
521 | } | ||
522 | |||
523 | result = phm_construct_table(hwmgr, &rv_set_power_state_master, | ||
524 | &(hwmgr->set_power_state)); | ||
525 | if (result != 0) { | ||
526 | pr_err("Fail to construct set_power_state\n"); | ||
527 | return result; | ||
528 | } | ||
529 | |||
530 | result = phm_construct_table(hwmgr, &rv_disable_dpm_master, | ||
531 | &(hwmgr->disable_dynamic_state_management)); | ||
532 | if (result != 0) { | ||
533 | pr_err("Fail to disable_dynamic_state\n"); | ||
534 | return result; | ||
535 | } | ||
536 | result = phm_construct_table(hwmgr, &rv_enable_dpm_master, | ||
537 | &(hwmgr->enable_dynamic_state_management)); | ||
538 | if (result != 0) { | ||
539 | pr_err("Fail to enable_dynamic_state\n"); | ||
540 | return result; | ||
541 | } | ||
542 | |||
543 | hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = | ||
544 | RAVEN_MAX_HARDWARE_POWERLEVELS; | ||
545 | |||
546 | hwmgr->platform_descriptor.hardwarePerformanceLevels = | ||
547 | RAVEN_MAX_HARDWARE_POWERLEVELS; | ||
548 | |||
549 | hwmgr->platform_descriptor.vbiosInterruptId = 0; | ||
550 | |||
551 | hwmgr->platform_descriptor.clockStep.engineClock = 500; | ||
552 | |||
553 | hwmgr->platform_descriptor.clockStep.memoryClock = 500; | ||
554 | |||
555 | hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50; | ||
556 | |||
557 | rv_init_vq_budget_table(hwmgr); | ||
558 | return result; | ||
559 | } | ||
560 | |||
561 | static int rv_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) | ||
562 | { | ||
563 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
564 | struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info); | ||
565 | |||
566 | phm_destroy_table(hwmgr, &(hwmgr->set_power_state)); | ||
567 | phm_destroy_table(hwmgr, &(hwmgr->enable_dynamic_state_management)); | ||
568 | phm_destroy_table(hwmgr, &(hwmgr->disable_dynamic_state_management)); | ||
569 | phm_destroy_table(hwmgr, &(hwmgr->power_down_asic)); | ||
570 | phm_destroy_table(hwmgr, &(hwmgr->setup_asic)); | ||
571 | |||
572 | if (pinfo->vdd_dep_on_dcefclk) { | ||
573 | kfree(pinfo->vdd_dep_on_dcefclk); | ||
574 | pinfo->vdd_dep_on_dcefclk = NULL; | ||
575 | } | ||
576 | if (pinfo->vdd_dep_on_socclk) { | ||
577 | kfree(pinfo->vdd_dep_on_socclk); | ||
578 | pinfo->vdd_dep_on_socclk = NULL; | ||
579 | } | ||
580 | if (pinfo->vdd_dep_on_fclk) { | ||
581 | kfree(pinfo->vdd_dep_on_fclk); | ||
582 | pinfo->vdd_dep_on_fclk = NULL; | ||
583 | } | ||
584 | if (pinfo->vdd_dep_on_dispclk) { | ||
585 | kfree(pinfo->vdd_dep_on_dispclk); | ||
586 | pinfo->vdd_dep_on_dispclk = NULL; | ||
587 | } | ||
588 | if (pinfo->vdd_dep_on_dppclk) { | ||
589 | kfree(pinfo->vdd_dep_on_dppclk); | ||
590 | pinfo->vdd_dep_on_dppclk = NULL; | ||
591 | } | ||
592 | if (pinfo->vdd_dep_on_phyclk) { | ||
593 | kfree(pinfo->vdd_dep_on_phyclk); | ||
594 | pinfo->vdd_dep_on_phyclk = NULL; | ||
595 | } | ||
596 | |||
597 | kfree(hwmgr->backend); | ||
598 | hwmgr->backend = NULL; | ||
599 | |||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | static int rv_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, | ||
604 | enum amd_dpm_forced_level level) | ||
605 | { | ||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static int rv_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low) | ||
610 | { | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int rv_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low) | ||
615 | { | ||
616 | return 0; | ||
617 | } | ||
618 | |||
619 | static int rv_dpm_patch_boot_state(struct pp_hwmgr *hwmgr, | ||
620 | struct pp_hw_power_state *hw_ps) | ||
621 | { | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static int rv_dpm_get_pp_table_entry_callback( | ||
626 | struct pp_hwmgr *hwmgr, | ||
627 | struct pp_hw_power_state *hw_ps, | ||
628 | unsigned int index, | ||
629 | const void *clock_info) | ||
630 | { | ||
631 | struct rv_power_state *rv_ps = cast_rv_ps(hw_ps); | ||
632 | |||
633 | const ATOM_PPLIB_CZ_CLOCK_INFO *rv_clock_info = clock_info; | ||
634 | |||
635 | struct phm_clock_voltage_dependency_table *table = | ||
636 | hwmgr->dyn_state.vddc_dependency_on_sclk; | ||
637 | uint8_t clock_info_index = rv_clock_info->index; | ||
638 | |||
639 | if (clock_info_index > (uint8_t)(hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1)) | ||
640 | clock_info_index = (uint8_t)(hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1); | ||
641 | |||
642 | rv_ps->levels[index].engine_clock = table->entries[clock_info_index].clk; | ||
643 | rv_ps->levels[index].vddc_index = (uint8_t)table->entries[clock_info_index].v; | ||
644 | |||
645 | rv_ps->level = index + 1; | ||
646 | |||
647 | if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) { | ||
648 | rv_ps->levels[index].ds_divider_index = 5; | ||
649 | rv_ps->levels[index].ss_divider_index = 5; | ||
650 | } | ||
651 | |||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int rv_dpm_get_num_of_pp_table_entries(struct pp_hwmgr *hwmgr) | ||
656 | { | ||
657 | int result; | ||
658 | unsigned long ret = 0; | ||
659 | |||
660 | result = pp_tables_get_num_of_entries(hwmgr, &ret); | ||
661 | |||
662 | return result ? 0 : ret; | ||
663 | } | ||
664 | |||
665 | static int rv_dpm_get_pp_table_entry(struct pp_hwmgr *hwmgr, | ||
666 | unsigned long entry, struct pp_power_state *ps) | ||
667 | { | ||
668 | int result; | ||
669 | struct rv_power_state *rv_ps; | ||
670 | |||
671 | ps->hardware.magic = PhwRaven_Magic; | ||
672 | |||
673 | rv_ps = cast_rv_ps(&(ps->hardware)); | ||
674 | |||
675 | result = pp_tables_get_entry(hwmgr, entry, ps, | ||
676 | rv_dpm_get_pp_table_entry_callback); | ||
677 | |||
678 | rv_ps->uvd_clocks.vclk = ps->uvd_clocks.VCLK; | ||
679 | rv_ps->uvd_clocks.dclk = ps->uvd_clocks.DCLK; | ||
680 | |||
681 | return result; | ||
682 | } | ||
683 | |||
684 | static int rv_get_power_state_size(struct pp_hwmgr *hwmgr) | ||
685 | { | ||
686 | return sizeof(struct rv_power_state); | ||
687 | } | ||
688 | |||
689 | static int rv_set_cpu_power_state(struct pp_hwmgr *hwmgr) | ||
690 | { | ||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | |||
695 | static int rv_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time, | ||
696 | bool cc6_disable, bool pstate_disable, bool pstate_switch_disable) | ||
697 | { | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static int rv_get_dal_power_level(struct pp_hwmgr *hwmgr, | ||
702 | struct amd_pp_simple_clock_info *info) | ||
703 | { | ||
704 | return -EINVAL; | ||
705 | } | ||
706 | |||
707 | static int rv_force_clock_level(struct pp_hwmgr *hwmgr, | ||
708 | enum pp_clock_type type, uint32_t mask) | ||
709 | { | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | static int rv_print_clock_levels(struct pp_hwmgr *hwmgr, | ||
714 | enum pp_clock_type type, char *buf) | ||
715 | { | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static int rv_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, | ||
720 | PHM_PerformanceLevelDesignation designation, uint32_t index, | ||
721 | PHM_PerformanceLevel *level) | ||
722 | { | ||
723 | const struct rv_power_state *ps; | ||
724 | struct rv_hwmgr *data; | ||
725 | uint32_t level_index; | ||
726 | uint32_t i; | ||
727 | |||
728 | if (level == NULL || hwmgr == NULL || state == NULL) | ||
729 | return -EINVAL; | ||
730 | |||
731 | data = (struct rv_hwmgr *)(hwmgr->backend); | ||
732 | ps = cast_const_rv_ps(state); | ||
733 | |||
734 | level_index = index > ps->level - 1 ? ps->level - 1 : index; | ||
735 | level->coreClock = ps->levels[level_index].engine_clock; | ||
736 | |||
737 | if (designation == PHM_PerformanceLevelDesignation_PowerContainment) { | ||
738 | for (i = 1; i < ps->level; i++) { | ||
739 | if (ps->levels[i].engine_clock > data->dce_slow_sclk_threshold) { | ||
740 | level->coreClock = ps->levels[i].engine_clock; | ||
741 | break; | ||
742 | } | ||
743 | } | ||
744 | } | ||
745 | |||
746 | level->nonLocalMemoryFreq = 0; | ||
747 | level->nonLocalMemoryWidth = 0; | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | static int rv_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr, | ||
753 | const struct pp_hw_power_state *state, struct pp_clock_info *clock_info) | ||
754 | { | ||
755 | const struct rv_power_state *ps = cast_const_rv_ps(state); | ||
756 | |||
757 | clock_info->min_eng_clk = ps->levels[0].engine_clock / (1 << (ps->levels[0].ss_divider_index)); | ||
758 | clock_info->max_eng_clk = ps->levels[ps->level - 1].engine_clock / (1 << (ps->levels[ps->level - 1].ss_divider_index)); | ||
759 | |||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | #define MEM_FREQ_LOW_LATENCY 25000 | ||
764 | #define MEM_FREQ_HIGH_LATENCY 80000 | ||
765 | #define MEM_LATENCY_HIGH 245 | ||
766 | #define MEM_LATENCY_LOW 35 | ||
767 | #define MEM_LATENCY_ERR 0xFFFF | ||
768 | |||
769 | |||
770 | static uint32_t rv_get_mem_latency(struct pp_hwmgr *hwmgr, | ||
771 | uint32_t clock) | ||
772 | { | ||
773 | if (clock >= MEM_FREQ_LOW_LATENCY && | ||
774 | clock < MEM_FREQ_HIGH_LATENCY) | ||
775 | return MEM_LATENCY_HIGH; | ||
776 | else if (clock >= MEM_FREQ_HIGH_LATENCY) | ||
777 | return MEM_LATENCY_LOW; | ||
778 | else | ||
779 | return MEM_LATENCY_ERR; | ||
780 | } | ||
781 | |||
782 | static void rv_get_memclocks(struct pp_hwmgr *hwmgr, | ||
783 | struct pp_clock_levels_with_latency *clocks) | ||
784 | { | ||
785 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
786 | struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info); | ||
787 | struct rv_voltage_dependency_table *pmclk_table; | ||
788 | uint32_t i; | ||
789 | |||
790 | pmclk_table = pinfo->vdd_dep_on_mclk; | ||
791 | clocks->num_levels = 0; | ||
792 | |||
793 | for (i = 0; i < pmclk_table->count; i++) { | ||
794 | if (pmclk_table->entries[i].clk) { | ||
795 | clocks->data[clocks->num_levels].clocks_in_khz = | ||
796 | pmclk_table->entries[i].clk; | ||
797 | clocks->data[clocks->num_levels].latency_in_us = | ||
798 | rv_get_mem_latency(hwmgr, | ||
799 | pmclk_table->entries[i].clk); | ||
800 | clocks->num_levels++; | ||
801 | } | ||
802 | } | ||
803 | } | ||
804 | |||
805 | static void rv_get_dcefclocks(struct pp_hwmgr *hwmgr, | ||
806 | struct pp_clock_levels_with_latency *clocks) | ||
807 | { | ||
808 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
809 | struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info); | ||
810 | struct rv_voltage_dependency_table *pdcef_table; | ||
811 | uint32_t i; | ||
812 | |||
813 | pdcef_table = pinfo->vdd_dep_on_dcefclk; | ||
814 | for (i = 0; i < pdcef_table->count; i++) { | ||
815 | clocks->data[i].clocks_in_khz = pdcef_table->entries[i].clk; | ||
816 | clocks->data[i].latency_in_us = 0; | ||
817 | } | ||
818 | clocks->num_levels = pdcef_table->count; | ||
819 | } | ||
820 | |||
821 | static void rv_get_socclocks(struct pp_hwmgr *hwmgr, | ||
822 | struct pp_clock_levels_with_latency *clocks) | ||
823 | { | ||
824 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
825 | struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info); | ||
826 | struct rv_voltage_dependency_table *psoc_table; | ||
827 | uint32_t i; | ||
828 | |||
829 | psoc_table = pinfo->vdd_dep_on_socclk; | ||
830 | |||
831 | for (i = 0; i < psoc_table->count; i++) { | ||
832 | clocks->data[i].clocks_in_khz = psoc_table->entries[i].clk; | ||
833 | clocks->data[i].latency_in_us = 0; | ||
834 | } | ||
835 | clocks->num_levels = psoc_table->count; | ||
836 | } | ||
837 | |||
838 | static int rv_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr, | ||
839 | enum amd_pp_clock_type type, | ||
840 | struct pp_clock_levels_with_latency *clocks) | ||
841 | { | ||
842 | switch (type) { | ||
843 | case amd_pp_mem_clock: | ||
844 | rv_get_memclocks(hwmgr, clocks); | ||
845 | break; | ||
846 | case amd_pp_dcef_clock: | ||
847 | rv_get_dcefclocks(hwmgr, clocks); | ||
848 | break; | ||
849 | case amd_pp_soc_clock: | ||
850 | rv_get_socclocks(hwmgr, clocks); | ||
851 | break; | ||
852 | default: | ||
853 | return -1; | ||
854 | } | ||
855 | |||
856 | return 0; | ||
857 | } | ||
858 | |||
859 | static int rv_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr, | ||
860 | enum amd_pp_clock_type type, | ||
861 | struct pp_clock_levels_with_voltage *clocks) | ||
862 | { | ||
863 | uint32_t i; | ||
864 | struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend); | ||
865 | struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info); | ||
866 | struct rv_voltage_dependency_table *pclk_vol_table; | ||
867 | |||
868 | switch (type) { | ||
869 | case amd_pp_mem_clock: | ||
870 | pclk_vol_table = pinfo->vdd_dep_on_mclk; | ||
871 | break; | ||
872 | case amd_pp_dcef_clock: | ||
873 | pclk_vol_table = pinfo->vdd_dep_on_dcefclk; | ||
874 | break; | ||
875 | case amd_pp_disp_clock: | ||
876 | pclk_vol_table = pinfo->vdd_dep_on_dispclk; | ||
877 | break; | ||
878 | case amd_pp_phy_clock: | ||
879 | pclk_vol_table = pinfo->vdd_dep_on_phyclk; | ||
880 | break; | ||
881 | case amd_pp_dpp_clock: | ||
882 | pclk_vol_table = pinfo->vdd_dep_on_dppclk; | ||
883 | default: | ||
884 | return -EINVAL; | ||
885 | } | ||
886 | |||
887 | if (pclk_vol_table->count == 0) | ||
888 | return -EINVAL; | ||
889 | |||
890 | for (i = 0; i < pclk_vol_table->count; i++) { | ||
891 | clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk; | ||
892 | clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol; | ||
893 | clocks->num_levels++; | ||
894 | } | ||
895 | |||
896 | clocks->num_levels = pclk_vol_table->count; | ||
897 | |||
898 | return 0; | ||
899 | } | ||
900 | |||
901 | int rv_display_clock_voltage_request(struct pp_hwmgr *hwmgr, | ||
902 | struct pp_display_clock_request *clock_req) | ||
903 | { | ||
904 | int result = 0; | ||
905 | enum amd_pp_clock_type clk_type = clock_req->clock_type; | ||
906 | uint32_t clk_freq = clock_req->clock_freq_in_khz / 100; | ||
907 | PPSMC_Msg msg; | ||
908 | |||
909 | switch (clk_type) { | ||
910 | case amd_pp_dcef_clock: | ||
911 | msg = PPSMC_MSG_SetHardMinDcefclkByFreq; | ||
912 | break; | ||
913 | case amd_pp_soc_clock: | ||
914 | msg = PPSMC_MSG_SetHardMinSocclkByFreq; | ||
915 | break; | ||
916 | case amd_pp_mem_clock: | ||
917 | msg = PPSMC_MSG_SetHardMinFclkByFreq; | ||
918 | break; | ||
919 | default: | ||
920 | pr_info("[DisplayClockVoltageRequest]Invalid Clock Type!"); | ||
921 | return -EINVAL; | ||
922 | } | ||
923 | |||
924 | result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg, | ||
925 | clk_freq); | ||
926 | |||
927 | return result; | ||
928 | } | ||
929 | |||
930 | static int rv_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks) | ||
931 | { | ||
932 | return -EINVAL; | ||
933 | } | ||
934 | |||
935 | static int rv_read_sensor(struct pp_hwmgr *hwmgr, int idx, | ||
936 | void *value, int *size) | ||
937 | { | ||
938 | return -EINVAL; | ||
939 | } | ||
940 | |||
941 | static const struct pp_hwmgr_func rv_hwmgr_funcs = { | ||
942 | .backend_init = rv_hwmgr_backend_init, | ||
943 | .backend_fini = rv_hwmgr_backend_fini, | ||
944 | .asic_setup = NULL, | ||
945 | .apply_state_adjust_rules = rv_apply_state_adjust_rules, | ||
946 | .force_dpm_level = rv_dpm_force_dpm_level, | ||
947 | .get_power_state_size = rv_get_power_state_size, | ||
948 | .powerdown_uvd = NULL, | ||
949 | .powergate_uvd = NULL, | ||
950 | .powergate_vce = NULL, | ||
951 | .get_mclk = rv_dpm_get_mclk, | ||
952 | .get_sclk = rv_dpm_get_sclk, | ||
953 | .patch_boot_state = rv_dpm_patch_boot_state, | ||
954 | .get_pp_table_entry = rv_dpm_get_pp_table_entry, | ||
955 | .get_num_of_pp_table_entries = rv_dpm_get_num_of_pp_table_entries, | ||
956 | .set_cpu_power_state = rv_set_cpu_power_state, | ||
957 | .store_cc6_data = rv_store_cc6_data, | ||
958 | .force_clock_level = rv_force_clock_level, | ||
959 | .print_clock_levels = rv_print_clock_levels, | ||
960 | .get_dal_power_level = rv_get_dal_power_level, | ||
961 | .get_performance_level = rv_get_performance_level, | ||
962 | .get_current_shallow_sleep_clocks = rv_get_current_shallow_sleep_clocks, | ||
963 | .get_clock_by_type_with_latency = rv_get_clock_by_type_with_latency, | ||
964 | .get_clock_by_type_with_voltage = rv_get_clock_by_type_with_voltage, | ||
965 | .get_max_high_clocks = rv_get_max_high_clocks, | ||
966 | .read_sensor = rv_read_sensor, | ||
967 | }; | ||
968 | |||
969 | int rv_init_function_pointers(struct pp_hwmgr *hwmgr) | ||
970 | { | ||
971 | hwmgr->hwmgr_func = &rv_hwmgr_funcs; | ||
972 | hwmgr->pptable_func = &pptable_funcs; | ||
973 | return 0; | ||
974 | } | ||
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h new file mode 100644 index 000000000000..673369131e08 --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.h | |||
@@ -0,0 +1,295 @@ | |||
1 | /* | ||
2 | * Copyright 2017 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 | |||
24 | #ifndef RAVEN_HWMGR_H | ||
25 | #define RAVEN_HWMGR_H | ||
26 | |||
27 | #include "hwmgr.h" | ||
28 | #include "rv_inc.h" | ||
29 | #include "smu10_driver_if.h" | ||
30 | #include "rv_ppsmc.h" | ||
31 | |||
32 | |||
33 | #define RAVEN_MAX_HARDWARE_POWERLEVELS 8 | ||
34 | #define PHMRAVEN_DYNCLK_NUMBER_OF_TREND_COEFFICIENTS 15 | ||
35 | |||
36 | #define DPMFlags_SCLK_Enabled 0x00000001 | ||
37 | #define DPMFlags_UVD_Enabled 0x00000002 | ||
38 | #define DPMFlags_VCE_Enabled 0x00000004 | ||
39 | #define DPMFlags_ACP_Enabled 0x00000008 | ||
40 | #define DPMFlags_ForceHighestValid 0x40000000 | ||
41 | |||
42 | /* Do not change the following, it is also defined in SMU8.h */ | ||
43 | #define SMU_EnabledFeatureScoreboard_AcpDpmOn 0x00000001 | ||
44 | #define SMU_EnabledFeatureScoreboard_SclkDpmOn 0x00200000 | ||
45 | #define SMU_EnabledFeatureScoreboard_UvdDpmOn 0x01000000 | ||
46 | #define SMU_EnabledFeatureScoreboard_VceDpmOn 0x02000000 | ||
47 | |||
48 | #define SMU_PHYID_SHIFT 8 | ||
49 | |||
50 | #define RAVEN_PCIE_POWERGATING_TARGET_GFX 0 | ||
51 | #define RAVEN_PCIE_POWERGATING_TARGET_DDI 1 | ||
52 | #define RAVEN_PCIE_POWERGATING_TARGET_PLLCASCADE 2 | ||
53 | #define RAVEN_PCIE_POWERGATING_TARGET_PHY 3 | ||
54 | |||
55 | enum VQ_TYPE { | ||
56 | CLOCK_TYPE_DCLK = 0L, | ||
57 | CLOCK_TYPE_ECLK, | ||
58 | CLOCK_TYPE_SCLK, | ||
59 | CLOCK_TYPE_CCLK, | ||
60 | VQ_GFX_CU | ||
61 | }; | ||
62 | |||
63 | #define SUSTAINABLE_SCLK_MASK 0x00ffffff | ||
64 | #define SUSTAINABLE_SCLK_SHIFT 0 | ||
65 | #define SUSTAINABLE_CU_MASK 0xff000000 | ||
66 | #define SUSTAINABLE_CU_SHIFT 24 | ||
67 | |||
68 | struct rv_dpm_entry { | ||
69 | uint32_t soft_min_clk; | ||
70 | uint32_t hard_min_clk; | ||
71 | uint32_t soft_max_clk; | ||
72 | uint32_t hard_max_clk; | ||
73 | }; | ||
74 | |||
75 | struct rv_power_level { | ||
76 | uint32_t engine_clock; | ||
77 | uint8_t vddc_index; | ||
78 | uint8_t ds_divider_index; | ||
79 | uint8_t ss_divider_index; | ||
80 | uint8_t allow_gnb_slow; | ||
81 | uint8_t force_nbp_state; | ||
82 | uint8_t display_wm; | ||
83 | uint8_t vce_wm; | ||
84 | uint8_t num_simd_to_powerdown; | ||
85 | uint8_t hysteresis_up; | ||
86 | uint8_t rsv[3]; | ||
87 | }; | ||
88 | |||
89 | /*used for the nbpsFlags field in rv_power state*/ | ||
90 | #define RAVEN_POWERSTATE_FLAGS_NBPS_FORCEHIGH (1<<0) | ||
91 | #define RAVEN_POWERSTATE_FLAGS_NBPS_LOCKTOHIGH (1<<1) | ||
92 | #define RAVEN_POWERSTATE_FLAGS_NBPS_LOCKTOLOW (1<<2) | ||
93 | |||
94 | #define RAVEN_POWERSTATE_FLAGS_BAPM_DISABLE (1<<0) | ||
95 | |||
96 | struct rv_uvd_clocks { | ||
97 | uint32_t vclk; | ||
98 | uint32_t dclk; | ||
99 | uint32_t vclk_low_divider; | ||
100 | uint32_t vclk_high_divider; | ||
101 | uint32_t dclk_low_divider; | ||
102 | uint32_t dclk_high_divider; | ||
103 | }; | ||
104 | |||
105 | struct pp_disable_nbpslo_flags { | ||
106 | union { | ||
107 | struct { | ||
108 | uint32_t entry : 1; | ||
109 | uint32_t display : 1; | ||
110 | uint32_t driver: 1; | ||
111 | uint32_t vce : 1; | ||
112 | uint32_t uvd : 1; | ||
113 | uint32_t acp : 1; | ||
114 | uint32_t reserved: 26; | ||
115 | } bits; | ||
116 | uint32_t u32All; | ||
117 | }; | ||
118 | }; | ||
119 | |||
120 | |||
121 | enum rv_pstate_previous_action { | ||
122 | DO_NOTHING = 1, | ||
123 | FORCE_HIGH, | ||
124 | CANCEL_FORCE_HIGH | ||
125 | }; | ||
126 | |||
127 | struct rv_power_state { | ||
128 | unsigned int magic; | ||
129 | uint32_t level; | ||
130 | struct rv_uvd_clocks uvd_clocks; | ||
131 | uint32_t evclk; | ||
132 | uint32_t ecclk; | ||
133 | uint32_t samclk; | ||
134 | uint32_t acpclk; | ||
135 | bool need_dfs_bypass; | ||
136 | |||
137 | uint32_t nbps_flags; | ||
138 | uint32_t bapm_flags; | ||
139 | uint8_t dpm0_pg_nbps_low; | ||
140 | uint8_t dpm0_pg_nbps_high; | ||
141 | uint8_t dpm_x_nbps_low; | ||
142 | uint8_t dpm_x_nbps_high; | ||
143 | |||
144 | enum rv_pstate_previous_action action; | ||
145 | |||
146 | struct rv_power_level levels[RAVEN_MAX_HARDWARE_POWERLEVELS]; | ||
147 | struct pp_disable_nbpslo_flags nbpslo_flags; | ||
148 | }; | ||
149 | |||
150 | #define RAVEN_NUM_NBPSTATES 4 | ||
151 | #define RAVEN_NUM_NBPMEMORYCLOCK 2 | ||
152 | |||
153 | |||
154 | struct rv_display_phy_info_entry { | ||
155 | uint8_t phy_present; | ||
156 | uint8_t active_lane_mapping; | ||
157 | uint8_t display_config_type; | ||
158 | uint8_t active_num_of_lanes; | ||
159 | }; | ||
160 | |||
161 | #define RAVEN_MAX_DISPLAYPHY_IDS 10 | ||
162 | |||
163 | struct rv_display_phy_info { | ||
164 | bool display_phy_access_initialized; | ||
165 | struct rv_display_phy_info_entry entries[RAVEN_MAX_DISPLAYPHY_IDS]; | ||
166 | }; | ||
167 | |||
168 | #define MAX_DISPLAY_CLOCK_LEVEL 8 | ||
169 | |||
170 | struct rv_system_info{ | ||
171 | uint8_t htc_tmp_lmt; | ||
172 | uint8_t htc_hyst_lmt; | ||
173 | }; | ||
174 | |||
175 | #define MAX_REGULAR_DPM_NUMBER 8 | ||
176 | |||
177 | struct rv_mclk_latency_entries { | ||
178 | uint32_t frequency; | ||
179 | uint32_t latency; | ||
180 | }; | ||
181 | |||
182 | struct rv_mclk_latency_table { | ||
183 | uint32_t count; | ||
184 | struct rv_mclk_latency_entries entries[MAX_REGULAR_DPM_NUMBER]; | ||
185 | }; | ||
186 | |||
187 | struct rv_clock_voltage_dependency_record { | ||
188 | uint32_t clk; | ||
189 | uint32_t vol; | ||
190 | }; | ||
191 | |||
192 | |||
193 | struct rv_voltage_dependency_table { | ||
194 | uint32_t count; | ||
195 | struct rv_clock_voltage_dependency_record entries[1]; | ||
196 | }; | ||
197 | |||
198 | struct rv_clock_voltage_information { | ||
199 | struct rv_voltage_dependency_table *vdd_dep_on_dcefclk; | ||
200 | struct rv_voltage_dependency_table *vdd_dep_on_socclk; | ||
201 | struct rv_voltage_dependency_table *vdd_dep_on_fclk; | ||
202 | struct rv_voltage_dependency_table *vdd_dep_on_mclk; | ||
203 | struct rv_voltage_dependency_table *vdd_dep_on_dispclk; | ||
204 | struct rv_voltage_dependency_table *vdd_dep_on_dppclk; | ||
205 | struct rv_voltage_dependency_table *vdd_dep_on_phyclk; | ||
206 | }; | ||
207 | |||
208 | struct rv_hwmgr { | ||
209 | uint32_t disable_driver_thermal_policy; | ||
210 | uint32_t thermal_auto_throttling_treshold; | ||
211 | struct rv_system_info sys_info; | ||
212 | struct rv_mclk_latency_table mclk_latency_table; | ||
213 | |||
214 | uint32_t ddi_power_gating_disabled; | ||
215 | |||
216 | struct rv_display_phy_info_entry display_phy_info; | ||
217 | uint32_t dce_slow_sclk_threshold; | ||
218 | |||
219 | bool disp_clk_bypass; | ||
220 | bool disp_clk_bypass_pending; | ||
221 | uint32_t bapm_enabled; | ||
222 | |||
223 | bool video_start; | ||
224 | bool battery_state; | ||
225 | |||
226 | uint32_t is_nb_dpm_enabled; | ||
227 | uint32_t is_voltage_island_enabled; | ||
228 | uint32_t disable_smu_acp_s3_handshake; | ||
229 | uint32_t disable_notify_smu_vpu_recovery; | ||
230 | bool in_vpu_recovery; | ||
231 | bool pg_acp_init; | ||
232 | uint8_t disp_config; | ||
233 | |||
234 | /* PowerTune */ | ||
235 | uint32_t power_containment_features; | ||
236 | bool cac_enabled; | ||
237 | bool disable_uvd_power_tune_feature; | ||
238 | bool enable_bapm_feature; | ||
239 | bool enable_tdc_limit_feature; | ||
240 | |||
241 | |||
242 | /* SMC SRAM Address of firmware header tables */ | ||
243 | uint32_t sram_end; | ||
244 | uint32_t dpm_table_start; | ||
245 | uint32_t soft_regs_start; | ||
246 | |||
247 | /* start of SMU7_Fusion_DpmTable */ | ||
248 | |||
249 | uint8_t uvd_level_count; | ||
250 | uint8_t vce_level_count; | ||
251 | uint8_t acp_level_count; | ||
252 | uint8_t samu_level_count; | ||
253 | |||
254 | uint32_t fps_high_threshold; | ||
255 | uint32_t fps_low_threshold; | ||
256 | |||
257 | uint32_t dpm_flags; | ||
258 | struct rv_dpm_entry sclk_dpm; | ||
259 | struct rv_dpm_entry uvd_dpm; | ||
260 | struct rv_dpm_entry vce_dpm; | ||
261 | struct rv_dpm_entry acp_dpm; | ||
262 | bool acp_power_up_no_dsp; | ||
263 | |||
264 | uint32_t max_sclk_level; | ||
265 | uint32_t num_of_clk_entries; | ||
266 | |||
267 | /* CPU Power State */ | ||
268 | uint32_t separation_time; | ||
269 | bool cc6_disable; | ||
270 | bool pstate_disable; | ||
271 | bool cc6_setting_changed; | ||
272 | |||
273 | uint32_t ulTotalActiveCUs; | ||
274 | |||
275 | bool isp_tileA_power_gated; | ||
276 | bool isp_tileB_power_gated; | ||
277 | uint32_t isp_actual_hard_min_freq; | ||
278 | uint32_t soc_actual_hard_min_freq; | ||
279 | |||
280 | bool vcn_power_gated; | ||
281 | bool vcn_dpg_mode; | ||
282 | |||
283 | bool gfx_off_controled_by_driver; | ||
284 | Watermarks_t water_marks_table; | ||
285 | struct rv_clock_voltage_information clock_vol_info; | ||
286 | DpmClocks_t clock_table; | ||
287 | |||
288 | uint32_t active_process_mask; | ||
289 | }; | ||
290 | |||
291 | struct pp_hwmgr; | ||
292 | |||
293 | int rv_init_function_pointers(struct pp_hwmgr *hwmgr); | ||
294 | |||
295 | #endif | ||
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index 4e39f35bb745..a62948b802a8 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h | |||
@@ -273,7 +273,8 @@ enum amd_pp_clock_type { | |||
273 | amd_pp_dcef_clock, | 273 | amd_pp_dcef_clock, |
274 | amd_pp_soc_clock, | 274 | amd_pp_soc_clock, |
275 | amd_pp_pixel_clock, | 275 | amd_pp_pixel_clock, |
276 | amd_pp_phy_clock | 276 | amd_pp_phy_clock, |
277 | amd_pp_dpp_clock | ||
277 | }; | 278 | }; |
278 | 279 | ||
279 | #define MAX_NUM_CLOCKS 16 | 280 | #define MAX_NUM_CLOCKS 16 |
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index 3e2ea040d029..35cb26fbb27b 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | |||
@@ -612,17 +612,6 @@ struct phm_ppt_v2_information { | |||
612 | uint8_t uc_dcef_dpm_voltage_mode; | 612 | uint8_t uc_dcef_dpm_voltage_mode; |
613 | }; | 613 | }; |
614 | 614 | ||
615 | struct phm_ppt_v3_information { | ||
616 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_sclk; | ||
617 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_mclk; | ||
618 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_socclk; | ||
619 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_dcefclk; | ||
620 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_pixclk; | ||
621 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_dispclk; | ||
622 | struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_on_phyclk; | ||
623 | }; | ||
624 | |||
625 | |||
626 | struct phm_dynamic_state_info { | 615 | struct phm_dynamic_state_info { |
627 | struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk; | 616 | struct phm_clock_voltage_dependency_table *vddc_dependency_on_sclk; |
628 | struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk; | 617 | struct phm_clock_voltage_dependency_table *vddci_dependency_on_mclk; |
@@ -638,7 +627,7 @@ struct phm_dynamic_state_info { | |||
638 | uint32_t vddc_vddci_delta; | 627 | uint32_t vddc_vddci_delta; |
639 | uint32_t min_vddc_for_pcie_gen2; | 628 | uint32_t min_vddc_for_pcie_gen2; |
640 | struct phm_cac_leakage_table *cac_leakage_table; | 629 | struct phm_cac_leakage_table *cac_leakage_table; |
641 | struct phm_phase_shedding_limits_table *vddc_phase_shed_limits_table; | 630 | struct phm_phase_shedding_limits_table *vddc_phase_shed_limits_table; |
642 | 631 | ||
643 | struct phm_vce_clock_voltage_dependency_table | 632 | struct phm_vce_clock_voltage_dependency_table |
644 | *vce_clock_voltage_dependency_table; | 633 | *vce_clock_voltage_dependency_table; |
@@ -651,8 +640,8 @@ struct phm_dynamic_state_info { | |||
651 | 640 | ||
652 | struct phm_ppm_table *ppm_parameter_table; | 641 | struct phm_ppm_table *ppm_parameter_table; |
653 | struct phm_cac_tdp_table *cac_dtp_table; | 642 | struct phm_cac_tdp_table *cac_dtp_table; |
654 | struct phm_clock_voltage_dependency_table *vdd_gfx_dependency_on_sclk; | 643 | struct phm_clock_voltage_dependency_table *vdd_gfx_dependency_on_sclk; |
655 | struct phm_vq_budgeting_table *vq_budgeting_table; | 644 | struct phm_vq_budgeting_table *vq_budgeting_table; |
656 | }; | 645 | }; |
657 | 646 | ||
658 | struct pp_fan_info { | 647 | struct pp_fan_info { |
@@ -836,6 +825,7 @@ extern void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr); | |||
836 | 825 | ||
837 | extern int smu7_init_function_pointers(struct pp_hwmgr *hwmgr); | 826 | extern int smu7_init_function_pointers(struct pp_hwmgr *hwmgr); |
838 | extern int vega10_hwmgr_init(struct pp_hwmgr *hwmgr); | 827 | extern int vega10_hwmgr_init(struct pp_hwmgr *hwmgr); |
828 | extern int rv_init_function_pointers(struct pp_hwmgr *hwmgr); | ||
839 | 829 | ||
840 | extern int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, | 830 | extern int phm_get_voltage_evv_on_sclk(struct pp_hwmgr *hwmgr, uint8_t voltage_type, |
841 | uint32_t sclk, uint16_t id, uint16_t *voltage); | 831 | uint32_t sclk, uint16_t id, uint16_t *voltage); |