MAINTAINERS: mmc: Move the mmc tree to kernel.org
[cascardo/linux.git] / drivers / gpu / drm / amd / powerplay / hwmgr / 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 "linux/delay.h"
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <drm/amdgpu_drm.h>
28 #include "cgs_common.h"
29 #include "power_state.h"
30 #include "hwmgr.h"
31 #include "pppcielanes.h"
32 #include "pp_debug.h"
33 #include "ppatomctrl.h"
34 #include "ppsmc.h"
35
36 #define VOLTAGE_SCALE               4
37
38 extern int cz_hwmgr_init(struct pp_hwmgr *hwmgr);
39 extern int tonga_hwmgr_init(struct pp_hwmgr *hwmgr);
40 extern int fiji_hwmgr_init(struct pp_hwmgr *hwmgr);
41 extern int polaris10_hwmgr_init(struct pp_hwmgr *hwmgr);
42
43 int hwmgr_init(struct amd_pp_init *pp_init, struct pp_instance *handle)
44 {
45         struct pp_hwmgr *hwmgr;
46
47         if ((handle == NULL) || (pp_init == NULL))
48                 return -EINVAL;
49
50         hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL);
51         if (hwmgr == NULL)
52                 return -ENOMEM;
53
54         handle->hwmgr = hwmgr;
55         hwmgr->smumgr = handle->smu_mgr;
56         hwmgr->device = pp_init->device;
57         hwmgr->chip_family = pp_init->chip_family;
58         hwmgr->chip_id = pp_init->chip_id;
59         hwmgr->hw_revision = pp_init->rev_id;
60         hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
61         hwmgr->power_source = PP_PowerSource_AC;
62         hwmgr->powercontainment_enabled = pp_init->powercontainment_enabled;
63
64         switch (hwmgr->chip_family) {
65         case AMDGPU_FAMILY_CZ:
66                 cz_hwmgr_init(hwmgr);
67                 break;
68         case AMDGPU_FAMILY_VI:
69                 switch (hwmgr->chip_id) {
70                 case CHIP_TONGA:
71                         tonga_hwmgr_init(hwmgr);
72                         break;
73                 case CHIP_FIJI:
74                         fiji_hwmgr_init(hwmgr);
75                         break;
76                 case CHIP_POLARIS11:
77                 case CHIP_POLARIS10:
78                         polaris10_hwmgr_init(hwmgr);
79                         break;
80                 default:
81                         return -EINVAL;
82                 }
83                 break;
84         default:
85                 return -EINVAL;
86         }
87
88         phm_init_dynamic_caps(hwmgr);
89
90         return 0;
91 }
92
93 int hwmgr_fini(struct pp_hwmgr *hwmgr)
94 {
95         if (hwmgr == NULL || hwmgr->ps == NULL)
96                 return -EINVAL;
97
98         /* do hwmgr finish*/
99         kfree(hwmgr->hardcode_pp_table);
100
101         kfree(hwmgr->backend);
102
103         kfree(hwmgr->start_thermal_controller.function_list);
104
105         kfree(hwmgr->set_temperature_range.function_list);
106
107         kfree(hwmgr->ps);
108         kfree(hwmgr);
109         return 0;
110 }
111
112 int hw_init_power_state_table(struct pp_hwmgr *hwmgr)
113 {
114         int result;
115         unsigned int i;
116         unsigned int table_entries;
117         struct pp_power_state *state;
118         int size;
119
120         if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
121                 return -EINVAL;
122
123         if (hwmgr->hwmgr_func->get_power_state_size == NULL)
124                 return -EINVAL;
125
126         hwmgr->num_ps = table_entries = hwmgr->hwmgr_func->get_num_of_pp_table_entries(hwmgr);
127
128         hwmgr->ps_size = size = hwmgr->hwmgr_func->get_power_state_size(hwmgr) +
129                                           sizeof(struct pp_power_state);
130
131         hwmgr->ps = kzalloc(size * table_entries, GFP_KERNEL);
132
133         if (hwmgr->ps == NULL)
134                 return -ENOMEM;
135
136         state = hwmgr->ps;
137
138         for (i = 0; i < table_entries; i++) {
139                 result = hwmgr->hwmgr_func->get_pp_table_entry(hwmgr, i, state);
140
141                 if (state->classification.flags & PP_StateClassificationFlag_Boot) {
142                         hwmgr->boot_ps = state;
143                         hwmgr->current_ps = hwmgr->request_ps = state;
144                 }
145
146                 state->id = i + 1; /* assigned unique num for every power state id */
147
148                 if (state->classification.flags & PP_StateClassificationFlag_Uvd)
149                         hwmgr->uvd_ps = state;
150                 state = (struct pp_power_state *)((unsigned long)state + size);
151         }
152
153         return 0;
154 }
155
156
157 /**
158  * Returns once the part of the register indicated by the mask has
159  * reached the given value.
160  */
161 int phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index,
162                          uint32_t value, uint32_t mask)
163 {
164         uint32_t i;
165         uint32_t cur_value;
166
167         if (hwmgr == NULL || hwmgr->device == NULL) {
168                 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
169                 return -EINVAL;
170         }
171
172         for (i = 0; i < hwmgr->usec_timeout; i++) {
173                 cur_value = cgs_read_register(hwmgr->device, index);
174                 if ((cur_value & mask) == (value & mask))
175                         break;
176                 udelay(1);
177         }
178
179         /* timeout means wrong logic*/
180         if (i == hwmgr->usec_timeout)
181                 return -1;
182         return 0;
183 }
184
185 int phm_wait_for_register_unequal(struct pp_hwmgr *hwmgr,
186                                 uint32_t index, uint32_t value, uint32_t mask)
187 {
188         uint32_t i;
189         uint32_t cur_value;
190
191         if (hwmgr == NULL || hwmgr->device == NULL) {
192                 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
193                 return -EINVAL;
194         }
195
196         for (i = 0; i < hwmgr->usec_timeout; i++) {
197                 cur_value = cgs_read_register(hwmgr->device, index);
198                 if ((cur_value & mask) != (value & mask))
199                         break;
200                 udelay(1);
201         }
202
203         /* timeout means wrong logic*/
204         if (i == hwmgr->usec_timeout)
205                 return -1;
206         return 0;
207 }
208
209
210 /**
211  * Returns once the part of the register indicated by the mask has
212  * reached the given value.The indirect space is described by giving
213  * the memory-mapped index of the indirect index register.
214  */
215 void phm_wait_on_indirect_register(struct pp_hwmgr *hwmgr,
216                                 uint32_t indirect_port,
217                                 uint32_t index,
218                                 uint32_t value,
219                                 uint32_t mask)
220 {
221         if (hwmgr == NULL || hwmgr->device == NULL) {
222                 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
223                 return;
224         }
225
226         cgs_write_register(hwmgr->device, indirect_port, index);
227         phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
228 }
229
230 void phm_wait_for_indirect_register_unequal(struct pp_hwmgr *hwmgr,
231                                         uint32_t indirect_port,
232                                         uint32_t index,
233                                         uint32_t value,
234                                         uint32_t mask)
235 {
236         if (hwmgr == NULL || hwmgr->device == NULL) {
237                 printk(KERN_ERR "[ powerplay ] Invalid Hardware Manager!");
238                 return;
239         }
240
241         cgs_write_register(hwmgr->device, indirect_port, index);
242         phm_wait_for_register_unequal(hwmgr, indirect_port + 1,
243                                       value, mask);
244 }
245
246 bool phm_cf_want_uvd_power_gating(struct pp_hwmgr *hwmgr)
247 {
248         return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDPowerGating);
249 }
250
251 bool phm_cf_want_vce_power_gating(struct pp_hwmgr *hwmgr)
252 {
253         return phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEPowerGating);
254 }
255
256
257 int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table)
258 {
259         uint32_t i, j;
260         uint16_t vvalue;
261         bool found = false;
262         struct pp_atomctrl_voltage_table *table;
263
264         PP_ASSERT_WITH_CODE((NULL != vol_table),
265                         "Voltage Table empty.", return -EINVAL);
266
267         table = kzalloc(sizeof(struct pp_atomctrl_voltage_table),
268                         GFP_KERNEL);
269
270         if (NULL == table)
271                 return -EINVAL;
272
273         table->mask_low = vol_table->mask_low;
274         table->phase_delay = vol_table->phase_delay;
275
276         for (i = 0; i < vol_table->count; i++) {
277                 vvalue = vol_table->entries[i].value;
278                 found = false;
279
280                 for (j = 0; j < table->count; j++) {
281                         if (vvalue == table->entries[j].value) {
282                                 found = true;
283                                 break;
284                         }
285                 }
286
287                 if (!found) {
288                         table->entries[table->count].value = vvalue;
289                         table->entries[table->count].smio_low =
290                                         vol_table->entries[i].smio_low;
291                         table->count++;
292                 }
293         }
294
295         memcpy(vol_table, table, sizeof(struct pp_atomctrl_voltage_table));
296         kfree(table);
297
298         return 0;
299 }
300
301 int phm_get_svi2_mvdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
302                 phm_ppt_v1_clock_voltage_dependency_table *dep_table)
303 {
304         uint32_t i;
305         int result;
306
307         PP_ASSERT_WITH_CODE((0 != dep_table->count),
308                         "Voltage Dependency Table empty.", return -EINVAL);
309
310         PP_ASSERT_WITH_CODE((NULL != vol_table),
311                         "vol_table empty.", return -EINVAL);
312
313         vol_table->mask_low = 0;
314         vol_table->phase_delay = 0;
315         vol_table->count = dep_table->count;
316
317         for (i = 0; i < dep_table->count; i++) {
318                 vol_table->entries[i].value = dep_table->entries[i].mvdd;
319                 vol_table->entries[i].smio_low = 0;
320         }
321
322         result = phm_trim_voltage_table(vol_table);
323         PP_ASSERT_WITH_CODE((0 == result),
324                         "Failed to trim MVDD table.", return result);
325
326         return 0;
327 }
328
329 int phm_get_svi2_vddci_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
330                 phm_ppt_v1_clock_voltage_dependency_table *dep_table)
331 {
332         uint32_t i;
333         int result;
334
335         PP_ASSERT_WITH_CODE((0 != dep_table->count),
336                         "Voltage Dependency Table empty.", return -EINVAL);
337
338         PP_ASSERT_WITH_CODE((NULL != vol_table),
339                         "vol_table empty.", return -EINVAL);
340
341         vol_table->mask_low = 0;
342         vol_table->phase_delay = 0;
343         vol_table->count = dep_table->count;
344
345         for (i = 0; i < dep_table->count; i++) {
346                 vol_table->entries[i].value = dep_table->entries[i].vddci;
347                 vol_table->entries[i].smio_low = 0;
348         }
349
350         result = phm_trim_voltage_table(vol_table);
351         PP_ASSERT_WITH_CODE((0 == result),
352                         "Failed to trim VDDCI table.", return result);
353
354         return 0;
355 }
356
357 int phm_get_svi2_vdd_voltage_table(struct pp_atomctrl_voltage_table *vol_table,
358                 phm_ppt_v1_voltage_lookup_table *lookup_table)
359 {
360         int i = 0;
361
362         PP_ASSERT_WITH_CODE((0 != lookup_table->count),
363                         "Voltage Lookup Table empty.", return -EINVAL);
364
365         PP_ASSERT_WITH_CODE((NULL != vol_table),
366                         "vol_table empty.", return -EINVAL);
367
368         vol_table->mask_low = 0;
369         vol_table->phase_delay = 0;
370
371         vol_table->count = lookup_table->count;
372
373         for (i = 0; i < vol_table->count; i++) {
374                 vol_table->entries[i].value = lookup_table->entries[i].us_vdd;
375                 vol_table->entries[i].smio_low = 0;
376         }
377
378         return 0;
379 }
380
381 void phm_trim_voltage_table_to_fit_state_table(uint32_t max_vol_steps,
382                                 struct pp_atomctrl_voltage_table *vol_table)
383 {
384         unsigned int i, diff;
385
386         if (vol_table->count <= max_vol_steps)
387                 return;
388
389         diff = vol_table->count - max_vol_steps;
390
391         for (i = 0; i < max_vol_steps; i++)
392                 vol_table->entries[i] = vol_table->entries[i + diff];
393
394         vol_table->count = max_vol_steps;
395
396         return;
397 }
398
399 int phm_reset_single_dpm_table(void *table,
400                                 uint32_t count, int max)
401 {
402         int i;
403
404         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
405
406         PP_ASSERT_WITH_CODE(count <= max,
407                         "Fatal error, can not set up single DPM table entries to exceed max number!",
408                            );
409
410         dpm_table->count = count;
411         for (i = 0; i < max; i++)
412                 dpm_table->dpm_level[i].enabled = false;
413
414         return 0;
415 }
416
417 void phm_setup_pcie_table_entry(
418         void *table,
419         uint32_t index, uint32_t pcie_gen,
420         uint32_t pcie_lanes)
421 {
422         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
423         dpm_table->dpm_level[index].value = pcie_gen;
424         dpm_table->dpm_level[index].param1 = pcie_lanes;
425         dpm_table->dpm_level[index].enabled = 1;
426 }
427
428 int32_t phm_get_dpm_level_enable_mask_value(void *table)
429 {
430         int32_t i;
431         int32_t mask = 0;
432         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
433
434         for (i = dpm_table->count; i > 0; i--) {
435                 mask = mask << 1;
436                 if (dpm_table->dpm_level[i - 1].enabled)
437                         mask |= 0x1;
438                 else
439                         mask &= 0xFFFFFFFE;
440         }
441
442         return mask;
443 }
444
445 uint8_t phm_get_voltage_index(
446                 struct phm_ppt_v1_voltage_lookup_table *lookup_table, uint16_t voltage)
447 {
448         uint8_t count = (uint8_t) (lookup_table->count);
449         uint8_t i;
450
451         PP_ASSERT_WITH_CODE((NULL != lookup_table),
452                         "Lookup Table empty.", return 0);
453         PP_ASSERT_WITH_CODE((0 != count),
454                         "Lookup Table empty.", return 0);
455
456         for (i = 0; i < lookup_table->count; i++) {
457                 /* find first voltage equal or bigger than requested */
458                 if (lookup_table->entries[i].us_vdd >= voltage)
459                         return i;
460         }
461         /* voltage is bigger than max voltage in the table */
462         return i - 1;
463 }
464
465 uint16_t phm_find_closest_vddci(struct pp_atomctrl_voltage_table *vddci_table, uint16_t vddci)
466 {
467         uint32_t  i;
468
469         for (i = 0; i < vddci_table->count; i++) {
470                 if (vddci_table->entries[i].value >= vddci)
471                         return vddci_table->entries[i].value;
472         }
473
474         PP_ASSERT_WITH_CODE(false,
475                         "VDDCI is larger than max VDDCI in VDDCI Voltage Table!",
476                         return vddci_table->entries[i-1].value);
477 }
478
479 int phm_find_boot_level(void *table,
480                 uint32_t value, uint32_t *boot_level)
481 {
482         int result = -EINVAL;
483         uint32_t i;
484         struct vi_dpm_table *dpm_table = (struct vi_dpm_table *)table;
485
486         for (i = 0; i < dpm_table->count; i++) {
487                 if (value == dpm_table->dpm_level[i].value) {
488                         *boot_level = i;
489                         result = 0;
490                 }
491         }
492
493         return result;
494 }
495
496 int phm_get_sclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
497         phm_ppt_v1_voltage_lookup_table *lookup_table,
498         uint16_t virtual_voltage_id, int32_t *sclk)
499 {
500         uint8_t entryId;
501         uint8_t voltageId;
502         struct phm_ppt_v1_information *table_info =
503                         (struct phm_ppt_v1_information *)(hwmgr->pptable);
504
505         PP_ASSERT_WITH_CODE(lookup_table->count != 0, "Lookup table is empty", return -EINVAL);
506
507         /* search for leakage voltage ID 0xff01 ~ 0xff08 and sckl */
508         for (entryId = 0; entryId < table_info->vdd_dep_on_sclk->count; entryId++) {
509                 voltageId = table_info->vdd_dep_on_sclk->entries[entryId].vddInd;
510                 if (lookup_table->entries[voltageId].us_vdd == virtual_voltage_id)
511                         break;
512         }
513
514         PP_ASSERT_WITH_CODE(entryId < table_info->vdd_dep_on_sclk->count,
515                         "Can't find requested voltage id in vdd_dep_on_sclk table!",
516                         return -EINVAL;
517                         );
518
519         *sclk = table_info->vdd_dep_on_sclk->entries[entryId].clk;
520
521         return 0;
522 }
523
524 /**
525  * Initialize Dynamic State Adjustment Rule Settings
526  *
527  * @param    hwmgr  the address of the powerplay hardware manager.
528  */
529 int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr)
530 {
531         uint32_t table_size;
532         struct phm_clock_voltage_dependency_table *table_clk_vlt;
533         struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable);
534
535         /* initialize vddc_dep_on_dal_pwrl table */
536         table_size = sizeof(uint32_t) + 4 * sizeof(struct phm_clock_voltage_dependency_record);
537         table_clk_vlt = kzalloc(table_size, GFP_KERNEL);
538
539         if (NULL == table_clk_vlt) {
540                 printk(KERN_ERR "[ powerplay ] Can not allocate space for vddc_dep_on_dal_pwrl! \n");
541                 return -ENOMEM;
542         } else {
543                 table_clk_vlt->count = 4;
544                 table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_ULTRALOW;
545                 table_clk_vlt->entries[0].v = 0;
546                 table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_LOW;
547                 table_clk_vlt->entries[1].v = 720;
548                 table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_NOMINAL;
549                 table_clk_vlt->entries[2].v = 810;
550                 table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_PERFORMANCE;
551                 table_clk_vlt->entries[3].v = 900;
552                 pptable_info->vddc_dep_on_dal_pwrl = table_clk_vlt;
553                 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
554         }
555
556         return 0;
557 }
558
559 int phm_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
560 {
561         if (NULL != hwmgr->dyn_state.vddc_dep_on_dal_pwrl) {
562                 kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
563                 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
564         }
565
566         if (NULL != hwmgr->backend) {
567                 kfree(hwmgr->backend);
568                 hwmgr->backend = NULL;
569         }
570
571         return 0;
572 }
573
574 uint32_t phm_get_lowest_enabled_level(struct pp_hwmgr *hwmgr, uint32_t mask)
575 {
576         uint32_t level = 0;
577
578         while (0 == (mask & (1 << level)))
579                 level++;
580
581         return level;
582 }
583
584 void phm_apply_dal_min_voltage_request(struct pp_hwmgr *hwmgr)
585 {
586         struct phm_ppt_v1_information *table_info =
587                         (struct phm_ppt_v1_information *)hwmgr->pptable;
588         struct phm_clock_voltage_dependency_table *table =
589                                 table_info->vddc_dep_on_dal_pwrl;
590         struct phm_ppt_v1_clock_voltage_dependency_table *vddc_table;
591         enum PP_DAL_POWERLEVEL dal_power_level = hwmgr->dal_power_level;
592         uint32_t req_vddc = 0, req_volt, i;
593
594         if (!table || table->count <= 0
595                 || dal_power_level < PP_DAL_POWERLEVEL_ULTRALOW
596                 || dal_power_level > PP_DAL_POWERLEVEL_PERFORMANCE)
597                 return;
598
599         for (i = 0; i < table->count; i++) {
600                 if (dal_power_level == table->entries[i].clk) {
601                         req_vddc = table->entries[i].v;
602                         break;
603                 }
604         }
605
606         vddc_table = table_info->vdd_dep_on_sclk;
607         for (i = 0; i < vddc_table->count; i++) {
608                 if (req_vddc <= vddc_table->entries[i].vddc) {
609                         req_volt = (((uint32_t)vddc_table->entries[i].vddc) * VOLTAGE_SCALE);
610                         smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
611                                         PPSMC_MSG_VddC_Request, req_volt);
612                         return;
613                 }
614         }
615         printk(KERN_ERR "DAL requested level can not"
616                         " found a available voltage in VDDC DPM Table \n");
617 }