Merge tag 'renesas-fixes4-for-v4.13' of https://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / powerplay / hwmgr / rv_hwmgr.c
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 #include "pp_soc15.h"
39
40 #define RAVEN_MAX_DEEPSLEEP_DIVIDER_ID     5
41 #define RAVEN_MINIMUM_ENGINE_CLOCK         800   //8Mhz, the low boundary of engine clock allowed on this chip
42 #define SCLK_MIN_DIV_INTV_SHIFT         12
43 #define RAVEN_DISPCLK_BYPASS_THRESHOLD     10000 //100mhz
44 #define SMC_RAM_END                     0x40000
45
46 static const unsigned long PhwRaven_Magic = (unsigned long) PHM_Rv_Magic;
47 int rv_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
48                 struct pp_display_clock_request *clock_req);
49
50 struct phm_vq_budgeting_record rv_vqtable[] = {
51         /* _TBD
52          * CUs, SSP low, SSP High, Min Sclk Low, Min Sclk, High, AWD/non-AWD, DCLK, ECLK, Sustainable Sclk, Sustainable CUs */
53         { 8, 0, 45, 0, 0, VQ_DisplayConfig_NoneAWD, 80000, 120000, 4, 0 },
54 };
55
56 static struct rv_power_state *cast_rv_ps(struct pp_hw_power_state *hw_ps)
57 {
58         if (PhwRaven_Magic != hw_ps->magic)
59                 return NULL;
60
61         return (struct rv_power_state *)hw_ps;
62 }
63
64 static const struct rv_power_state *cast_const_rv_ps(
65                                 const struct pp_hw_power_state *hw_ps)
66 {
67         if (PhwRaven_Magic != hw_ps->magic)
68                 return NULL;
69
70         return (struct rv_power_state *)hw_ps;
71 }
72
73 static int rv_init_vq_budget_table(struct pp_hwmgr *hwmgr)
74 {
75         uint32_t table_size, i;
76         struct phm_vq_budgeting_table *ptable;
77         uint32_t num_entries = ARRAY_SIZE(rv_vqtable);
78
79         if (hwmgr->dyn_state.vq_budgeting_table != NULL)
80                 return 0;
81
82         table_size = sizeof(struct phm_vq_budgeting_table) +
83                         sizeof(struct phm_vq_budgeting_record) * (num_entries - 1);
84
85         ptable = kzalloc(table_size, GFP_KERNEL);
86         if (NULL == ptable)
87                 return -ENOMEM;
88
89         ptable->numEntries = (uint8_t) num_entries;
90
91         for (i = 0; i < ptable->numEntries; i++) {
92                 ptable->entries[i].ulCUs = rv_vqtable[i].ulCUs;
93                 ptable->entries[i].ulSustainableSOCPowerLimitLow = rv_vqtable[i].ulSustainableSOCPowerLimitLow;
94                 ptable->entries[i].ulSustainableSOCPowerLimitHigh = rv_vqtable[i].ulSustainableSOCPowerLimitHigh;
95                 ptable->entries[i].ulMinSclkLow = rv_vqtable[i].ulMinSclkLow;
96                 ptable->entries[i].ulMinSclkHigh = rv_vqtable[i].ulMinSclkHigh;
97                 ptable->entries[i].ucDispConfig = rv_vqtable[i].ucDispConfig;
98                 ptable->entries[i].ulDClk = rv_vqtable[i].ulDClk;
99                 ptable->entries[i].ulEClk = rv_vqtable[i].ulEClk;
100                 ptable->entries[i].ulSustainableSclk = rv_vqtable[i].ulSustainableSclk;
101                 ptable->entries[i].ulSustainableCUs = rv_vqtable[i].ulSustainableCUs;
102         }
103
104         hwmgr->dyn_state.vq_budgeting_table = ptable;
105
106         return 0;
107 }
108
109 static int rv_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
110 {
111         struct rv_hwmgr *rv_hwmgr = (struct rv_hwmgr *)(hwmgr->backend);
112         struct cgs_system_info sys_info = {0};
113         int result;
114
115         rv_hwmgr->ddi_power_gating_disabled = 0;
116         rv_hwmgr->bapm_enabled = 1;
117         rv_hwmgr->dce_slow_sclk_threshold = 30000;
118         rv_hwmgr->disable_driver_thermal_policy = 1;
119         rv_hwmgr->thermal_auto_throttling_treshold = 0;
120         rv_hwmgr->is_nb_dpm_enabled = 1;
121         rv_hwmgr->dpm_flags = 1;
122         rv_hwmgr->disable_smu_acp_s3_handshake = 1;
123         rv_hwmgr->disable_notify_smu_vpu_recovery = 0;
124         rv_hwmgr->gfx_off_controled_by_driver = false;
125
126         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
127                                         PHM_PlatformCaps_DynamicM3Arbiter);
128
129         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
130                                         PHM_PlatformCaps_UVDPowerGating);
131
132         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
133                                         PHM_PlatformCaps_UVDDynamicPowerGating);
134
135         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
136                                         PHM_PlatformCaps_VCEPowerGating);
137
138         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
139                                         PHM_PlatformCaps_SamuPowerGating);
140
141         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
142                                         PHM_PlatformCaps_ACP);
143
144         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
145                                         PHM_PlatformCaps_SclkDeepSleep);
146
147         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
148                                 PHM_PlatformCaps_GFXDynamicMGPowerGating);
149
150         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
151                                 PHM_PlatformCaps_SclkThrottleLowNotification);
152
153         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
154                                 PHM_PlatformCaps_DisableVoltageIsland);
155
156         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
157                                         PHM_PlatformCaps_DynamicUVDState);
158
159         sys_info.size = sizeof(struct cgs_system_info);
160         sys_info.info_id = CGS_SYSTEM_INFO_PG_FLAGS;
161         result = cgs_query_system_info(hwmgr->device, &sys_info);
162         if (!result) {
163                 if (sys_info.value & AMD_PG_SUPPORT_GFX_DMG)
164                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
165                                       PHM_PlatformCaps_GFXDynamicMGPowerGating);
166         }
167
168         return 0;
169 }
170
171 static int rv_construct_max_power_limits_table(struct pp_hwmgr *hwmgr,
172                         struct phm_clock_and_voltage_limits *table)
173 {
174         return 0;
175 }
176
177 static int rv_init_dynamic_state_adjustment_rule_settings(
178                                                         struct pp_hwmgr *hwmgr)
179 {
180         uint32_t table_size =
181                 sizeof(struct phm_clock_voltage_dependency_table) +
182                 (7 * sizeof(struct phm_clock_voltage_dependency_record));
183
184         struct phm_clock_voltage_dependency_table *table_clk_vlt =
185                                         kzalloc(table_size, GFP_KERNEL);
186
187         if (NULL == table_clk_vlt) {
188                 pr_err("Can not allocate memory!\n");
189                 return -ENOMEM;
190         }
191
192         table_clk_vlt->count = 8;
193         table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_0;
194         table_clk_vlt->entries[0].v = 0;
195         table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_1;
196         table_clk_vlt->entries[1].v = 1;
197         table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_2;
198         table_clk_vlt->entries[2].v = 2;
199         table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_3;
200         table_clk_vlt->entries[3].v = 3;
201         table_clk_vlt->entries[4].clk = PP_DAL_POWERLEVEL_4;
202         table_clk_vlt->entries[4].v = 4;
203         table_clk_vlt->entries[5].clk = PP_DAL_POWERLEVEL_5;
204         table_clk_vlt->entries[5].v = 5;
205         table_clk_vlt->entries[6].clk = PP_DAL_POWERLEVEL_6;
206         table_clk_vlt->entries[6].v = 6;
207         table_clk_vlt->entries[7].clk = PP_DAL_POWERLEVEL_7;
208         table_clk_vlt->entries[7].v = 7;
209         hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
210
211         return 0;
212 }
213
214 static int rv_get_system_info_data(struct pp_hwmgr *hwmgr)
215 {
216         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)hwmgr->backend;
217
218         rv_data->sys_info.htc_hyst_lmt = 5;
219         rv_data->sys_info.htc_tmp_lmt = 203;
220
221         if (rv_data->thermal_auto_throttling_treshold == 0)
222                  rv_data->thermal_auto_throttling_treshold = 203;
223
224         rv_construct_max_power_limits_table (hwmgr,
225                                     &hwmgr->dyn_state.max_clock_voltage_on_ac);
226
227         rv_init_dynamic_state_adjustment_rule_settings(hwmgr);
228
229         return 0;
230 }
231
232 static int rv_construct_boot_state(struct pp_hwmgr *hwmgr)
233 {
234         return 0;
235 }
236
237 static int rv_tf_set_clock_limit(struct pp_hwmgr *hwmgr, void *input,
238                                 void *output, void *storage, int result)
239 {
240         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
241         struct PP_Clocks clocks = {0};
242         struct pp_display_clock_request clock_req;
243
244         clocks.dcefClock = hwmgr->display_config.min_dcef_set_clk;
245         clocks.dcefClockInSR = hwmgr->display_config.min_dcef_deep_sleep_set_clk;
246         clock_req.clock_type = amd_pp_dcf_clock;
247         clock_req.clock_freq_in_khz = clocks.dcefClock * 10;
248
249         if (clocks.dcefClock == 0 && clocks.dcefClockInSR == 0)
250                 clock_req.clock_freq_in_khz = rv_data->dcf_actual_hard_min_freq;
251
252         PP_ASSERT_WITH_CODE(!rv_display_clock_voltage_request(hwmgr, &clock_req),
253                                 "Attempt to set DCF Clock Failed!", return -EINVAL);
254
255         if(rv_data->need_min_deep_sleep_dcefclk && 0 != clocks.dcefClockInSR)
256                 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
257                                         PPSMC_MSG_SetMinDeepSleepDcefclk,
258                                         clocks.dcefClockInSR / 100);
259         /*
260         if(!rv_data->isp_tileA_power_gated || !rv_data->isp_tileB_power_gated) {
261                 if ((hwmgr->ispArbiter.iclk != 0) && (rv_data->ISPActualHardMinFreq != (hwmgr->ispArbiter.iclk / 100) )) {
262                         smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
263                                         PPSMC_MSG_SetHardMinIspclkByFreq, hwmgr->ispArbiter.iclk / 100);
264                         rv_read_arg_from_smc(hwmgr->smumgr, &rv_data->ISPActualHardMinFreq),
265                 }
266         } */
267
268         if((hwmgr->gfx_arbiter.sclk_hard_min != 0) &&
269                 ((hwmgr->gfx_arbiter.sclk_hard_min / 100) != rv_data->soc_actual_hard_min_freq)) {
270                 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
271                                         PPSMC_MSG_SetHardMinSocclkByFreq,
272                                         hwmgr->gfx_arbiter.sclk_hard_min / 100);
273                         rv_read_arg_from_smc(hwmgr->smumgr, &rv_data->soc_actual_hard_min_freq);
274         }
275
276         if ((hwmgr->gfx_arbiter.gfxclk != 0) &&
277                 (rv_data->gfx_actual_soft_min_freq != (hwmgr->gfx_arbiter.gfxclk))) {
278                 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
279                                         PPSMC_MSG_SetMinVideoGfxclkFreq,
280                                         hwmgr->gfx_arbiter.gfxclk / 100);
281                 rv_read_arg_from_smc(hwmgr->smumgr, &rv_data->gfx_actual_soft_min_freq);
282         }
283
284         if ((hwmgr->gfx_arbiter.fclk != 0) &&
285                 (rv_data->fabric_actual_soft_min_freq != (hwmgr->gfx_arbiter.fclk / 100))) {
286                 smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
287                                         PPSMC_MSG_SetMinVideoFclkFreq,
288                                         hwmgr->gfx_arbiter.fclk / 100);
289                 rv_read_arg_from_smc(hwmgr->smumgr, &rv_data->fabric_actual_soft_min_freq);
290         }
291
292         return 0;
293 }
294
295 static int rv_tf_set_num_active_display(struct pp_hwmgr *hwmgr, void *input,
296                                 void *output, void *storage, int result)
297 {
298         uint32_t  num_of_active_displays = 0;
299         struct cgs_display_info info = {0};
300
301         cgs_get_active_displays_info(hwmgr->device, &info);
302         num_of_active_displays = info.display_count;
303
304         smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
305                                 PPSMC_MSG_SetDisplayCount,
306                                 num_of_active_displays);
307         return 0;
308 }
309
310 static const struct phm_master_table_item rv_set_power_state_list[] = {
311         { NULL, rv_tf_set_clock_limit },
312         { NULL, rv_tf_set_num_active_display },
313         { }
314 };
315
316 static const struct phm_master_table_header rv_set_power_state_master = {
317         0,
318         PHM_MasterTableFlag_None,
319         rv_set_power_state_list
320 };
321
322 static int rv_tf_init_power_gate_state(struct pp_hwmgr *hwmgr, void *input,
323                                 void *output, void *storage, int result)
324 {
325         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
326
327         rv_data->vcn_power_gated = true;
328         rv_data->isp_tileA_power_gated = true;
329         rv_data->isp_tileB_power_gated = true;
330
331         return 0;
332 }
333
334 static const struct phm_master_table_item rv_setup_asic_list[] = {
335         { .tableFunction = rv_tf_init_power_gate_state },
336         { }
337 };
338
339 static const struct phm_master_table_header rv_setup_asic_master = {
340         0,
341         PHM_MasterTableFlag_None,
342         rv_setup_asic_list
343 };
344
345 static int rv_tf_reset_cc6_data(struct pp_hwmgr *hwmgr,
346                                         void *input, void *output,
347                                         void *storage, int result)
348 {
349         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
350
351         rv_data->separation_time = 0;
352         rv_data->cc6_disable = false;
353         rv_data->pstate_disable = false;
354         rv_data->cc6_setting_changed = false;
355
356         return 0;
357 }
358
359 static const struct phm_master_table_item rv_power_down_asic_list[] = {
360         { .tableFunction = rv_tf_reset_cc6_data },
361         { }
362 };
363
364 static const struct phm_master_table_header rv_power_down_asic_master = {
365         0,
366         PHM_MasterTableFlag_None,
367         rv_power_down_asic_list
368 };
369
370
371 static int rv_tf_disable_gfx_off(struct pp_hwmgr *hwmgr,
372                                                 void *input, void *output,
373                                                 void *storage, int result)
374 {
375         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
376
377         if (rv_data->gfx_off_controled_by_driver)
378                 smum_send_msg_to_smc(hwmgr->smumgr,
379                                                 PPSMC_MSG_DisableGfxOff);
380
381         return 0;
382 }
383
384 static const struct phm_master_table_item rv_disable_dpm_list[] = {
385         {NULL, rv_tf_disable_gfx_off},
386         { },
387 };
388
389
390 static const struct phm_master_table_header rv_disable_dpm_master = {
391         0,
392         PHM_MasterTableFlag_None,
393         rv_disable_dpm_list
394 };
395
396 static int rv_tf_enable_gfx_off(struct pp_hwmgr *hwmgr,
397                                                 void *input, void *output,
398                                                 void *storage, int result)
399 {
400         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
401
402         if (rv_data->gfx_off_controled_by_driver)
403                 smum_send_msg_to_smc(hwmgr->smumgr,
404                                                 PPSMC_MSG_EnableGfxOff);
405
406         return 0;
407 }
408
409 static const struct phm_master_table_item rv_enable_dpm_list[] = {
410         {NULL, rv_tf_enable_gfx_off},
411         { },
412 };
413
414 static const struct phm_master_table_header rv_enable_dpm_master = {
415         0,
416         PHM_MasterTableFlag_None,
417         rv_enable_dpm_list
418 };
419
420 static int rv_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
421                                 struct pp_power_state  *prequest_ps,
422                         const struct pp_power_state *pcurrent_ps)
423 {
424         return 0;
425 }
426
427 /* temporary hardcoded clock voltage breakdown tables */
428 DpmClock_t VddDcfClk[]= {
429         { 300, 2600},
430         { 600, 3200},
431         { 600, 3600},
432 };
433
434 DpmClock_t VddSocClk[]= {
435         { 478, 2600},
436         { 722, 3200},
437         { 722, 3600},
438 };
439
440 DpmClock_t VddFClk[]= {
441         { 400, 2600},
442         {1200, 3200},
443         {1200, 3600},
444 };
445
446 DpmClock_t VddDispClk[]= {
447         { 435, 2600},
448         { 661, 3200},
449         {1086, 3600},
450 };
451
452 DpmClock_t VddDppClk[]= {
453         { 435, 2600},
454         { 661, 3200},
455         { 661, 3600},
456 };
457
458 DpmClock_t VddPhyClk[]= {
459         { 540, 2600},
460         { 810, 3200},
461         { 810, 3600},
462 };
463
464 static int rv_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr,
465                         struct rv_voltage_dependency_table **pptable,
466                         uint32_t num_entry, DpmClock_t *pclk_dependency_table)
467 {
468         uint32_t table_size, i;
469         struct rv_voltage_dependency_table *ptable;
470
471         table_size = sizeof(uint32_t) + sizeof(struct rv_voltage_dependency_table) * num_entry;
472         ptable = kzalloc(table_size, GFP_KERNEL);
473
474         if (NULL == ptable)
475                 return -ENOMEM;
476
477         ptable->count = num_entry;
478
479         for (i = 0; i < ptable->count; i++) {
480                 ptable->entries[i].clk         = pclk_dependency_table->Freq * 100;
481                 ptable->entries[i].vol         = pclk_dependency_table->Vol;
482                 pclk_dependency_table++;
483         }
484
485         *pptable = ptable;
486
487         return 0;
488 }
489
490
491 static int rv_populate_clock_table(struct pp_hwmgr *hwmgr)
492 {
493         int result;
494
495         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
496         DpmClocks_t  *table = &(rv_data->clock_table);
497         struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
498
499         result = rv_copy_table_from_smc(hwmgr->smumgr, (uint8_t *)table, CLOCKTABLE);
500
501         PP_ASSERT_WITH_CODE((0 == result),
502                         "Attempt to copy clock table from smc failed",
503                         return result);
504
505         if (0 == result && table->DcefClocks[0].Freq != 0) {
506                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dcefclk,
507                                                 NUM_DCEFCLK_DPM_LEVELS,
508                                                 &rv_data->clock_table.DcefClocks[0]);
509                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_socclk,
510                                                 NUM_SOCCLK_DPM_LEVELS,
511                                                 &rv_data->clock_table.SocClocks[0]);
512                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_fclk,
513                                                 NUM_FCLK_DPM_LEVELS,
514                                                 &rv_data->clock_table.FClocks[0]);
515                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_mclk,
516                                                 NUM_MEMCLK_DPM_LEVELS,
517                                                 &rv_data->clock_table.MemClocks[0]);
518         } else {
519                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dcefclk,
520                                                 ARRAY_SIZE(VddDcfClk),
521                                                 &VddDcfClk[0]);
522                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_socclk,
523                                                 ARRAY_SIZE(VddSocClk),
524                                                 &VddSocClk[0]);
525                 rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_fclk,
526                                                 ARRAY_SIZE(VddFClk),
527                                                 &VddFClk[0]);
528         }
529         rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dispclk,
530                                         ARRAY_SIZE(VddDispClk),
531                                         &VddDispClk[0]);
532         rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dppclk,
533                                         ARRAY_SIZE(VddDppClk), &VddDppClk[0]);
534         rv_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_phyclk,
535                                         ARRAY_SIZE(VddPhyClk), &VddPhyClk[0]);
536
537         return 0;
538 }
539
540 static int rv_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
541 {
542         int result = 0;
543         struct rv_hwmgr *data;
544
545         data = kzalloc(sizeof(struct rv_hwmgr), GFP_KERNEL);
546         if (data == NULL)
547                 return -ENOMEM;
548
549         hwmgr->backend = data;
550
551         result = rv_initialize_dpm_defaults(hwmgr);
552         if (result != 0) {
553                 pr_err("rv_initialize_dpm_defaults failed\n");
554                 return result;
555         }
556
557         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
558                 PHM_PlatformCaps_PowerPlaySupport);
559
560         rv_populate_clock_table(hwmgr);
561
562         result = rv_get_system_info_data(hwmgr);
563         if (result != 0) {
564                 pr_err("rv_get_system_info_data failed\n");
565                 return result;
566         }
567
568         rv_construct_boot_state(hwmgr);
569
570         result = phm_construct_table(hwmgr, &rv_setup_asic_master,
571                                 &(hwmgr->setup_asic));
572         if (result != 0) {
573                 pr_err("Fail to construct setup ASIC\n");
574                 return result;
575         }
576
577         result = phm_construct_table(hwmgr, &rv_power_down_asic_master,
578                                 &(hwmgr->power_down_asic));
579         if (result != 0) {
580                 pr_err("Fail to construct power down ASIC\n");
581                 return result;
582         }
583
584         result = phm_construct_table(hwmgr, &rv_set_power_state_master,
585                                 &(hwmgr->set_power_state));
586         if (result != 0) {
587                 pr_err("Fail to construct set_power_state\n");
588                 return result;
589         }
590
591         result = phm_construct_table(hwmgr, &rv_disable_dpm_master,
592                                 &(hwmgr->disable_dynamic_state_management));
593         if (result != 0) {
594                 pr_err("Fail to disable_dynamic_state\n");
595                 return result;
596         }
597         result = phm_construct_table(hwmgr, &rv_enable_dpm_master,
598                                 &(hwmgr->enable_dynamic_state_management));
599         if (result != 0) {
600                 pr_err("Fail to enable_dynamic_state\n");
601                 return result;
602         }
603
604         hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
605                                                 RAVEN_MAX_HARDWARE_POWERLEVELS;
606
607         hwmgr->platform_descriptor.hardwarePerformanceLevels =
608                                                 RAVEN_MAX_HARDWARE_POWERLEVELS;
609
610         hwmgr->platform_descriptor.vbiosInterruptId = 0;
611
612         hwmgr->platform_descriptor.clockStep.engineClock = 500;
613
614         hwmgr->platform_descriptor.clockStep.memoryClock = 500;
615
616         hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
617
618         rv_init_vq_budget_table(hwmgr);
619
620         return result;
621 }
622
623 static int rv_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
624 {
625         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
626         struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
627
628         phm_destroy_table(hwmgr, &(hwmgr->set_power_state));
629         phm_destroy_table(hwmgr, &(hwmgr->enable_dynamic_state_management));
630         phm_destroy_table(hwmgr, &(hwmgr->disable_dynamic_state_management));
631         phm_destroy_table(hwmgr, &(hwmgr->power_down_asic));
632         phm_destroy_table(hwmgr, &(hwmgr->setup_asic));
633
634         if (pinfo->vdd_dep_on_dcefclk) {
635                 kfree(pinfo->vdd_dep_on_dcefclk);
636                 pinfo->vdd_dep_on_dcefclk = NULL;
637         }
638         if (pinfo->vdd_dep_on_socclk) {
639                 kfree(pinfo->vdd_dep_on_socclk);
640                 pinfo->vdd_dep_on_socclk = NULL;
641         }
642         if (pinfo->vdd_dep_on_fclk) {
643                 kfree(pinfo->vdd_dep_on_fclk);
644                 pinfo->vdd_dep_on_fclk = NULL;
645         }
646         if (pinfo->vdd_dep_on_dispclk) {
647                 kfree(pinfo->vdd_dep_on_dispclk);
648                 pinfo->vdd_dep_on_dispclk = NULL;
649         }
650         if (pinfo->vdd_dep_on_dppclk) {
651                 kfree(pinfo->vdd_dep_on_dppclk);
652                 pinfo->vdd_dep_on_dppclk = NULL;
653         }
654         if (pinfo->vdd_dep_on_phyclk) {
655                 kfree(pinfo->vdd_dep_on_phyclk);
656                 pinfo->vdd_dep_on_phyclk = NULL;
657         }
658
659         if (NULL != hwmgr->dyn_state.vddc_dep_on_dal_pwrl) {
660                 kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
661                 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
662         }
663
664         if (NULL != hwmgr->dyn_state.vq_budgeting_table) {
665                 kfree(hwmgr->dyn_state.vq_budgeting_table);
666                 hwmgr->dyn_state.vq_budgeting_table = NULL;
667         }
668
669         kfree(hwmgr->backend);
670         hwmgr->backend = NULL;
671
672         return 0;
673 }
674
675 static int rv_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
676                                 enum amd_dpm_forced_level level)
677 {
678         return 0;
679 }
680
681 static int rv_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
682 {
683         return 0;
684 }
685
686 static int rv_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
687 {
688         return 0;
689 }
690
691 static int rv_dpm_patch_boot_state(struct pp_hwmgr *hwmgr,
692                                         struct pp_hw_power_state *hw_ps)
693 {
694         return 0;
695 }
696
697 static int rv_dpm_get_pp_table_entry_callback(
698                                                      struct pp_hwmgr *hwmgr,
699                                            struct pp_hw_power_state *hw_ps,
700                                                           unsigned int index,
701                                                      const void *clock_info)
702 {
703         struct rv_power_state *rv_ps = cast_rv_ps(hw_ps);
704
705         const ATOM_PPLIB_CZ_CLOCK_INFO *rv_clock_info = clock_info;
706
707         struct phm_clock_voltage_dependency_table *table =
708                                     hwmgr->dyn_state.vddc_dependency_on_sclk;
709         uint8_t clock_info_index = rv_clock_info->index;
710
711         if (clock_info_index > (uint8_t)(hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1))
712                 clock_info_index = (uint8_t)(hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1);
713
714         rv_ps->levels[index].engine_clock = table->entries[clock_info_index].clk;
715         rv_ps->levels[index].vddc_index = (uint8_t)table->entries[clock_info_index].v;
716
717         rv_ps->level = index + 1;
718
719         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
720                 rv_ps->levels[index].ds_divider_index = 5;
721                 rv_ps->levels[index].ss_divider_index = 5;
722         }
723
724         return 0;
725 }
726
727 static int rv_dpm_get_num_of_pp_table_entries(struct pp_hwmgr *hwmgr)
728 {
729         int result;
730         unsigned long ret = 0;
731
732         result = pp_tables_get_num_of_entries(hwmgr, &ret);
733
734         return result ? 0 : ret;
735 }
736
737 static int rv_dpm_get_pp_table_entry(struct pp_hwmgr *hwmgr,
738                     unsigned long entry, struct pp_power_state *ps)
739 {
740         int result;
741         struct rv_power_state *rv_ps;
742
743         ps->hardware.magic = PhwRaven_Magic;
744
745         rv_ps = cast_rv_ps(&(ps->hardware));
746
747         result = pp_tables_get_entry(hwmgr, entry, ps,
748                         rv_dpm_get_pp_table_entry_callback);
749
750         rv_ps->uvd_clocks.vclk = ps->uvd_clocks.VCLK;
751         rv_ps->uvd_clocks.dclk = ps->uvd_clocks.DCLK;
752
753         return result;
754 }
755
756 static int rv_get_power_state_size(struct pp_hwmgr *hwmgr)
757 {
758         return sizeof(struct rv_power_state);
759 }
760
761 static int rv_set_cpu_power_state(struct pp_hwmgr *hwmgr)
762 {
763         return 0;
764 }
765
766
767 static int rv_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time,
768                         bool cc6_disable, bool pstate_disable, bool pstate_switch_disable)
769 {
770         return 0;
771 }
772
773 static int rv_get_dal_power_level(struct pp_hwmgr *hwmgr,
774                 struct amd_pp_simple_clock_info *info)
775 {
776         return -EINVAL;
777 }
778
779 static int rv_force_clock_level(struct pp_hwmgr *hwmgr,
780                 enum pp_clock_type type, uint32_t mask)
781 {
782         return 0;
783 }
784
785 static int rv_print_clock_levels(struct pp_hwmgr *hwmgr,
786                 enum pp_clock_type type, char *buf)
787 {
788         return 0;
789 }
790
791 static int rv_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
792                                 PHM_PerformanceLevelDesignation designation, uint32_t index,
793                                 PHM_PerformanceLevel *level)
794 {
795         const struct rv_power_state *ps;
796         struct rv_hwmgr *data;
797         uint32_t level_index;
798         uint32_t i;
799         uint32_t vol_dep_record_index = 0;
800
801         if (level == NULL || hwmgr == NULL || state == NULL)
802                 return -EINVAL;
803
804         data = (struct rv_hwmgr *)(hwmgr->backend);
805         ps = cast_const_rv_ps(state);
806
807         level_index = index > ps->level - 1 ? ps->level - 1 : index;
808         level->coreClock = ps->levels[level_index].engine_clock;
809
810         if (designation == PHM_PerformanceLevelDesignation_PowerContainment) {
811                 for (i = 1; i < ps->level; i++) {
812                         if (ps->levels[i].engine_clock > data->dce_slow_sclk_threshold) {
813                                 level->coreClock = ps->levels[i].engine_clock;
814                                 break;
815                         }
816                 }
817         }
818
819         if (level_index == 0) {
820                 vol_dep_record_index = data->clock_vol_info.vdd_dep_on_fclk->count - 1;
821                 level->memory_clock =
822                         data->clock_vol_info.vdd_dep_on_fclk->entries[vol_dep_record_index].clk;
823         } else
824                 level->memory_clock = data->clock_vol_info.vdd_dep_on_fclk->entries[0].clk;
825
826         level->nonLocalMemoryFreq = 0;
827         level->nonLocalMemoryWidth = 0;
828
829         return 0;
830 }
831
832 static int rv_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr,
833         const struct pp_hw_power_state *state, struct pp_clock_info *clock_info)
834 {
835         const struct rv_power_state *ps = cast_const_rv_ps(state);
836
837         clock_info->min_eng_clk = ps->levels[0].engine_clock / (1 << (ps->levels[0].ss_divider_index));
838         clock_info->max_eng_clk = ps->levels[ps->level - 1].engine_clock / (1 << (ps->levels[ps->level - 1].ss_divider_index));
839
840         return 0;
841 }
842
843 #define MEM_FREQ_LOW_LATENCY        25000
844 #define MEM_FREQ_HIGH_LATENCY       80000
845 #define MEM_LATENCY_HIGH            245
846 #define MEM_LATENCY_LOW             35
847 #define MEM_LATENCY_ERR             0xFFFF
848
849
850 static uint32_t rv_get_mem_latency(struct pp_hwmgr *hwmgr,
851                 uint32_t clock)
852 {
853         if (clock >= MEM_FREQ_LOW_LATENCY &&
854                         clock < MEM_FREQ_HIGH_LATENCY)
855                 return MEM_LATENCY_HIGH;
856         else if (clock >= MEM_FREQ_HIGH_LATENCY)
857                 return MEM_LATENCY_LOW;
858         else
859                 return MEM_LATENCY_ERR;
860 }
861
862 static int rv_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
863                 enum amd_pp_clock_type type,
864                 struct pp_clock_levels_with_latency *clocks)
865 {
866         uint32_t i;
867         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
868         struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
869         struct rv_voltage_dependency_table *pclk_vol_table;
870         bool latency_required = false;
871
872         if (pinfo == NULL)
873                 return -EINVAL;
874
875         switch (type) {
876         case amd_pp_mem_clock:
877                 pclk_vol_table = pinfo->vdd_dep_on_mclk;
878                 latency_required = true;
879                 break;
880         case amd_pp_f_clock:
881                 pclk_vol_table = pinfo->vdd_dep_on_fclk;
882                 latency_required = true;
883                 break;
884         case amd_pp_dcf_clock:
885                 pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
886                 break;
887         case amd_pp_disp_clock:
888                 pclk_vol_table = pinfo->vdd_dep_on_dispclk;
889                 break;
890         case amd_pp_phy_clock:
891                 pclk_vol_table = pinfo->vdd_dep_on_phyclk;
892                 break;
893         case amd_pp_dpp_clock:
894                 pclk_vol_table = pinfo->vdd_dep_on_dppclk;
895         default:
896                 return -EINVAL;
897         }
898
899         if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
900                 return -EINVAL;
901
902         clocks->num_levels = 0;
903         for (i = 0; i < pclk_vol_table->count; i++) {
904                 clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
905                 clocks->data[i].latency_in_us = latency_required ?
906                                                 rv_get_mem_latency(hwmgr,
907                                                 pclk_vol_table->entries[i].clk) :
908                                                 0;
909                 clocks->num_levels++;
910         }
911
912         return 0;
913 }
914
915 static int rv_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
916                 enum amd_pp_clock_type type,
917                 struct pp_clock_levels_with_voltage *clocks)
918 {
919         uint32_t i;
920         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
921         struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
922         struct rv_voltage_dependency_table *pclk_vol_table = NULL;
923
924         if (pinfo == NULL)
925                 return -EINVAL;
926
927         switch (type) {
928         case amd_pp_mem_clock:
929                 pclk_vol_table = pinfo->vdd_dep_on_mclk;
930                 break;
931         case amd_pp_f_clock:
932                 pclk_vol_table = pinfo->vdd_dep_on_fclk;
933                 break;
934         case amd_pp_dcf_clock:
935                 pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
936                 break;
937         case amd_pp_soc_clock:
938                 pclk_vol_table = pinfo->vdd_dep_on_socclk;
939                 break;
940         default:
941                 return -EINVAL;
942         }
943
944         if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
945                 return -EINVAL;
946
947         clocks->num_levels = 0;
948         for (i = 0; i < pclk_vol_table->count; i++) {
949                 clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
950                 clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol;
951                 clocks->num_levels++;
952         }
953
954         return 0;
955 }
956
957 int rv_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
958                 struct pp_display_clock_request *clock_req)
959 {
960         int result = 0;
961         struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
962         enum amd_pp_clock_type clk_type = clock_req->clock_type;
963         uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
964         PPSMC_Msg        msg;
965
966         switch (clk_type) {
967         case amd_pp_dcf_clock:
968                 if (clk_freq == rv_data->dcf_actual_hard_min_freq)
969                         return 0;
970                 msg =  PPSMC_MSG_SetHardMinDcefclkByFreq;
971                 rv_data->dcf_actual_hard_min_freq = clk_freq;
972                 break;
973         case amd_pp_soc_clock:
974                  msg = PPSMC_MSG_SetHardMinSocclkByFreq;
975                 break;
976         case amd_pp_f_clock:
977                 if (clk_freq == rv_data->f_actual_hard_min_freq)
978                         return 0;
979                 rv_data->f_actual_hard_min_freq = clk_freq;
980                 msg = PPSMC_MSG_SetHardMinFclkByFreq;
981                 break;
982         default:
983                 pr_info("[DisplayClockVoltageRequest]Invalid Clock Type!");
984                 return -EINVAL;
985         }
986
987         result = smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, msg,
988                                                         clk_freq);
989
990         return result;
991 }
992
993 static int rv_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks)
994 {
995         return -EINVAL;
996 }
997
998 static int rv_thermal_get_temperature(struct pp_hwmgr *hwmgr)
999 {
1000         uint32_t reg_offset = soc15_get_register_offset(THM_HWID, 0,
1001                         mmTHM_TCON_CUR_TMP_BASE_IDX, mmTHM_TCON_CUR_TMP);
1002         uint32_t reg_value = cgs_read_register(hwmgr->device, reg_offset);
1003         int cur_temp =
1004                 (reg_value & THM_TCON_CUR_TMP__CUR_TEMP_MASK) >> THM_TCON_CUR_TMP__CUR_TEMP__SHIFT;
1005
1006         if (cur_temp & THM_TCON_CUR_TMP__CUR_TEMP_RANGE_SEL_MASK)
1007                 cur_temp = ((cur_temp / 8) - 49) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
1008         else
1009                 cur_temp = (cur_temp / 8) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
1010
1011         return cur_temp;
1012 }
1013
1014 static int rv_read_sensor(struct pp_hwmgr *hwmgr, int idx,
1015                           void *value, int *size)
1016 {
1017         switch (idx) {
1018         case AMDGPU_PP_SENSOR_GPU_TEMP:
1019                 *((uint32_t *)value) = rv_thermal_get_temperature(hwmgr);
1020                 return 0;
1021         default:
1022                 return -EINVAL;
1023         }
1024 }
1025
1026 static const struct pp_hwmgr_func rv_hwmgr_funcs = {
1027         .backend_init = rv_hwmgr_backend_init,
1028         .backend_fini = rv_hwmgr_backend_fini,
1029         .asic_setup = NULL,
1030         .apply_state_adjust_rules = rv_apply_state_adjust_rules,
1031         .force_dpm_level = rv_dpm_force_dpm_level,
1032         .get_power_state_size = rv_get_power_state_size,
1033         .powerdown_uvd = NULL,
1034         .powergate_uvd = NULL,
1035         .powergate_vce = NULL,
1036         .get_mclk = rv_dpm_get_mclk,
1037         .get_sclk = rv_dpm_get_sclk,
1038         .patch_boot_state = rv_dpm_patch_boot_state,
1039         .get_pp_table_entry = rv_dpm_get_pp_table_entry,
1040         .get_num_of_pp_table_entries = rv_dpm_get_num_of_pp_table_entries,
1041         .set_cpu_power_state = rv_set_cpu_power_state,
1042         .store_cc6_data = rv_store_cc6_data,
1043         .force_clock_level = rv_force_clock_level,
1044         .print_clock_levels = rv_print_clock_levels,
1045         .get_dal_power_level = rv_get_dal_power_level,
1046         .get_performance_level = rv_get_performance_level,
1047         .get_current_shallow_sleep_clocks = rv_get_current_shallow_sleep_clocks,
1048         .get_clock_by_type_with_latency = rv_get_clock_by_type_with_latency,
1049         .get_clock_by_type_with_voltage = rv_get_clock_by_type_with_voltage,
1050         .get_max_high_clocks = rv_get_max_high_clocks,
1051         .read_sensor = rv_read_sensor,
1052 };
1053
1054 int rv_init_function_pointers(struct pp_hwmgr *hwmgr)
1055 {
1056         hwmgr->hwmgr_func = &rv_hwmgr_funcs;
1057         hwmgr->pptable_func = &pptable_funcs;
1058         return 0;
1059 }