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