drm/radeon/dpm: add vce dpm support for TN
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / radeon / trinity_dpm.c
1 /*
2  * Copyright 2012 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 #include "drmP.h"
25 #include "radeon.h"
26 #include "radeon_asic.h"
27 #include "trinityd.h"
28 #include "r600_dpm.h"
29 #include "trinity_dpm.h"
30 #include <linux/seq_file.h>
31
32 #define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5
33 #define TRINITY_MINIMUM_ENGINE_CLOCK 800
34 #define SCLK_MIN_DIV_INTV_SHIFT     12
35 #define TRINITY_DISPCLK_BYPASS_THRESHOLD 10000
36
37 #ifndef TRINITY_MGCG_SEQUENCE
38 #define TRINITY_MGCG_SEQUENCE  100
39
40 static const u32 trinity_mgcg_shls_default[] =
41 {
42         /* Register, Value, Mask */
43         0x0000802c, 0xc0000000, 0xffffffff,
44         0x00003fc4, 0xc0000000, 0xffffffff,
45         0x00005448, 0x00000100, 0xffffffff,
46         0x000055e4, 0x00000100, 0xffffffff,
47         0x0000160c, 0x00000100, 0xffffffff,
48         0x00008984, 0x06000100, 0xffffffff,
49         0x0000c164, 0x00000100, 0xffffffff,
50         0x00008a18, 0x00000100, 0xffffffff,
51         0x0000897c, 0x06000100, 0xffffffff,
52         0x00008b28, 0x00000100, 0xffffffff,
53         0x00009144, 0x00800200, 0xffffffff,
54         0x00009a60, 0x00000100, 0xffffffff,
55         0x00009868, 0x00000100, 0xffffffff,
56         0x00008d58, 0x00000100, 0xffffffff,
57         0x00009510, 0x00000100, 0xffffffff,
58         0x0000949c, 0x00000100, 0xffffffff,
59         0x00009654, 0x00000100, 0xffffffff,
60         0x00009030, 0x00000100, 0xffffffff,
61         0x00009034, 0x00000100, 0xffffffff,
62         0x00009038, 0x00000100, 0xffffffff,
63         0x0000903c, 0x00000100, 0xffffffff,
64         0x00009040, 0x00000100, 0xffffffff,
65         0x0000a200, 0x00000100, 0xffffffff,
66         0x0000a204, 0x00000100, 0xffffffff,
67         0x0000a208, 0x00000100, 0xffffffff,
68         0x0000a20c, 0x00000100, 0xffffffff,
69         0x00009744, 0x00000100, 0xffffffff,
70         0x00003f80, 0x00000100, 0xffffffff,
71         0x0000a210, 0x00000100, 0xffffffff,
72         0x0000a214, 0x00000100, 0xffffffff,
73         0x000004d8, 0x00000100, 0xffffffff,
74         0x00009664, 0x00000100, 0xffffffff,
75         0x00009698, 0x00000100, 0xffffffff,
76         0x000004d4, 0x00000200, 0xffffffff,
77         0x000004d0, 0x00000000, 0xffffffff,
78         0x000030cc, 0x00000104, 0xffffffff,
79         0x0000d0c0, 0x00000100, 0xffffffff,
80         0x0000d8c0, 0x00000100, 0xffffffff,
81         0x0000951c, 0x00010000, 0xffffffff,
82         0x00009160, 0x00030002, 0xffffffff,
83         0x00009164, 0x00050004, 0xffffffff,
84         0x00009168, 0x00070006, 0xffffffff,
85         0x00009178, 0x00070000, 0xffffffff,
86         0x0000917c, 0x00030002, 0xffffffff,
87         0x00009180, 0x00050004, 0xffffffff,
88         0x0000918c, 0x00010006, 0xffffffff,
89         0x00009190, 0x00090008, 0xffffffff,
90         0x00009194, 0x00070000, 0xffffffff,
91         0x00009198, 0x00030002, 0xffffffff,
92         0x0000919c, 0x00050004, 0xffffffff,
93         0x000091a8, 0x00010006, 0xffffffff,
94         0x000091ac, 0x00090008, 0xffffffff,
95         0x000091b0, 0x00070000, 0xffffffff,
96         0x000091b4, 0x00030002, 0xffffffff,
97         0x000091b8, 0x00050004, 0xffffffff,
98         0x000091c4, 0x00010006, 0xffffffff,
99         0x000091c8, 0x00090008, 0xffffffff,
100         0x000091cc, 0x00070000, 0xffffffff,
101         0x000091d0, 0x00030002, 0xffffffff,
102         0x000091d4, 0x00050004, 0xffffffff,
103         0x000091e0, 0x00010006, 0xffffffff,
104         0x000091e4, 0x00090008, 0xffffffff,
105         0x000091e8, 0x00000000, 0xffffffff,
106         0x000091ec, 0x00070000, 0xffffffff,
107         0x000091f0, 0x00030002, 0xffffffff,
108         0x000091f4, 0x00050004, 0xffffffff,
109         0x00009200, 0x00010006, 0xffffffff,
110         0x00009204, 0x00090008, 0xffffffff,
111         0x00009208, 0x00070000, 0xffffffff,
112         0x0000920c, 0x00030002, 0xffffffff,
113         0x00009210, 0x00050004, 0xffffffff,
114         0x0000921c, 0x00010006, 0xffffffff,
115         0x00009220, 0x00090008, 0xffffffff,
116         0x00009294, 0x00000000, 0xffffffff
117 };
118
119 static const u32 trinity_mgcg_shls_enable[] =
120 {
121         /* Register, Value, Mask */
122         0x0000802c, 0xc0000000, 0xffffffff,
123         0x000008f8, 0x00000000, 0xffffffff,
124         0x000008fc, 0x00000000, 0x000133FF,
125         0x000008f8, 0x00000001, 0xffffffff,
126         0x000008fc, 0x00000000, 0xE00B03FC,
127         0x00009150, 0x96944200, 0xffffffff
128 };
129
130 static const u32 trinity_mgcg_shls_disable[] =
131 {
132         /* Register, Value, Mask */
133         0x0000802c, 0xc0000000, 0xffffffff,
134         0x00009150, 0x00600000, 0xffffffff,
135         0x000008f8, 0x00000000, 0xffffffff,
136         0x000008fc, 0xffffffff, 0x000133FF,
137         0x000008f8, 0x00000001, 0xffffffff,
138         0x000008fc, 0xffffffff, 0xE00B03FC
139 };
140 #endif
141
142 #ifndef TRINITY_SYSLS_SEQUENCE
143 #define TRINITY_SYSLS_SEQUENCE  100
144
145 static const u32 trinity_sysls_default[] =
146 {
147         /* Register, Value, Mask */
148         0x000055e8, 0x00000000, 0xffffffff,
149         0x0000d0bc, 0x00000000, 0xffffffff,
150         0x0000d8bc, 0x00000000, 0xffffffff,
151         0x000015c0, 0x000c1401, 0xffffffff,
152         0x0000264c, 0x000c0400, 0xffffffff,
153         0x00002648, 0x000c0400, 0xffffffff,
154         0x00002650, 0x000c0400, 0xffffffff,
155         0x000020b8, 0x000c0400, 0xffffffff,
156         0x000020bc, 0x000c0400, 0xffffffff,
157         0x000020c0, 0x000c0c80, 0xffffffff,
158         0x0000f4a0, 0x000000c0, 0xffffffff,
159         0x0000f4a4, 0x00680fff, 0xffffffff,
160         0x00002f50, 0x00000404, 0xffffffff,
161         0x000004c8, 0x00000001, 0xffffffff,
162         0x0000641c, 0x00000000, 0xffffffff,
163         0x00000c7c, 0x00000000, 0xffffffff,
164         0x00006dfc, 0x00000000, 0xffffffff
165 };
166
167 static const u32 trinity_sysls_disable[] =
168 {
169         /* Register, Value, Mask */
170         0x0000d0c0, 0x00000000, 0xffffffff,
171         0x0000d8c0, 0x00000000, 0xffffffff,
172         0x000055e8, 0x00000000, 0xffffffff,
173         0x0000d0bc, 0x00000000, 0xffffffff,
174         0x0000d8bc, 0x00000000, 0xffffffff,
175         0x000015c0, 0x00041401, 0xffffffff,
176         0x0000264c, 0x00040400, 0xffffffff,
177         0x00002648, 0x00040400, 0xffffffff,
178         0x00002650, 0x00040400, 0xffffffff,
179         0x000020b8, 0x00040400, 0xffffffff,
180         0x000020bc, 0x00040400, 0xffffffff,
181         0x000020c0, 0x00040c80, 0xffffffff,
182         0x0000f4a0, 0x000000c0, 0xffffffff,
183         0x0000f4a4, 0x00680000, 0xffffffff,
184         0x00002f50, 0x00000404, 0xffffffff,
185         0x000004c8, 0x00000001, 0xffffffff,
186         0x0000641c, 0x00007ffd, 0xffffffff,
187         0x00000c7c, 0x0000ff00, 0xffffffff,
188         0x00006dfc, 0x0000007f, 0xffffffff
189 };
190
191 static const u32 trinity_sysls_enable[] =
192 {
193         /* Register, Value, Mask */
194         0x000055e8, 0x00000001, 0xffffffff,
195         0x0000d0bc, 0x00000100, 0xffffffff,
196         0x0000d8bc, 0x00000100, 0xffffffff,
197         0x000015c0, 0x000c1401, 0xffffffff,
198         0x0000264c, 0x000c0400, 0xffffffff,
199         0x00002648, 0x000c0400, 0xffffffff,
200         0x00002650, 0x000c0400, 0xffffffff,
201         0x000020b8, 0x000c0400, 0xffffffff,
202         0x000020bc, 0x000c0400, 0xffffffff,
203         0x000020c0, 0x000c0c80, 0xffffffff,
204         0x0000f4a0, 0x000000c0, 0xffffffff,
205         0x0000f4a4, 0x00680fff, 0xffffffff,
206         0x00002f50, 0x00000903, 0xffffffff,
207         0x000004c8, 0x00000000, 0xffffffff,
208         0x0000641c, 0x00000000, 0xffffffff,
209         0x00000c7c, 0x00000000, 0xffffffff,
210         0x00006dfc, 0x00000000, 0xffffffff
211 };
212 #endif
213
214 static const u32 trinity_override_mgpg_sequences[] =
215 {
216         /* Register, Value */
217         0x00000200, 0xE030032C,
218         0x00000204, 0x00000FFF,
219         0x00000200, 0xE0300058,
220         0x00000204, 0x00030301,
221         0x00000200, 0xE0300054,
222         0x00000204, 0x500010FF,
223         0x00000200, 0xE0300074,
224         0x00000204, 0x00030301,
225         0x00000200, 0xE0300070,
226         0x00000204, 0x500010FF,
227         0x00000200, 0xE0300090,
228         0x00000204, 0x00030301,
229         0x00000200, 0xE030008C,
230         0x00000204, 0x500010FF,
231         0x00000200, 0xE03000AC,
232         0x00000204, 0x00030301,
233         0x00000200, 0xE03000A8,
234         0x00000204, 0x500010FF,
235         0x00000200, 0xE03000C8,
236         0x00000204, 0x00030301,
237         0x00000200, 0xE03000C4,
238         0x00000204, 0x500010FF,
239         0x00000200, 0xE03000E4,
240         0x00000204, 0x00030301,
241         0x00000200, 0xE03000E0,
242         0x00000204, 0x500010FF,
243         0x00000200, 0xE0300100,
244         0x00000204, 0x00030301,
245         0x00000200, 0xE03000FC,
246         0x00000204, 0x500010FF,
247         0x00000200, 0xE0300058,
248         0x00000204, 0x00030303,
249         0x00000200, 0xE0300054,
250         0x00000204, 0x600010FF,
251         0x00000200, 0xE0300074,
252         0x00000204, 0x00030303,
253         0x00000200, 0xE0300070,
254         0x00000204, 0x600010FF,
255         0x00000200, 0xE0300090,
256         0x00000204, 0x00030303,
257         0x00000200, 0xE030008C,
258         0x00000204, 0x600010FF,
259         0x00000200, 0xE03000AC,
260         0x00000204, 0x00030303,
261         0x00000200, 0xE03000A8,
262         0x00000204, 0x600010FF,
263         0x00000200, 0xE03000C8,
264         0x00000204, 0x00030303,
265         0x00000200, 0xE03000C4,
266         0x00000204, 0x600010FF,
267         0x00000200, 0xE03000E4,
268         0x00000204, 0x00030303,
269         0x00000200, 0xE03000E0,
270         0x00000204, 0x600010FF,
271         0x00000200, 0xE0300100,
272         0x00000204, 0x00030303,
273         0x00000200, 0xE03000FC,
274         0x00000204, 0x600010FF,
275         0x00000200, 0xE0300058,
276         0x00000204, 0x00030303,
277         0x00000200, 0xE0300054,
278         0x00000204, 0x700010FF,
279         0x00000200, 0xE0300074,
280         0x00000204, 0x00030303,
281         0x00000200, 0xE0300070,
282         0x00000204, 0x700010FF,
283         0x00000200, 0xE0300090,
284         0x00000204, 0x00030303,
285         0x00000200, 0xE030008C,
286         0x00000204, 0x700010FF,
287         0x00000200, 0xE03000AC,
288         0x00000204, 0x00030303,
289         0x00000200, 0xE03000A8,
290         0x00000204, 0x700010FF,
291         0x00000200, 0xE03000C8,
292         0x00000204, 0x00030303,
293         0x00000200, 0xE03000C4,
294         0x00000204, 0x700010FF,
295         0x00000200, 0xE03000E4,
296         0x00000204, 0x00030303,
297         0x00000200, 0xE03000E0,
298         0x00000204, 0x700010FF,
299         0x00000200, 0xE0300100,
300         0x00000204, 0x00030303,
301         0x00000200, 0xE03000FC,
302         0x00000204, 0x700010FF,
303         0x00000200, 0xE0300058,
304         0x00000204, 0x00010303,
305         0x00000200, 0xE0300054,
306         0x00000204, 0x800010FF,
307         0x00000200, 0xE0300074,
308         0x00000204, 0x00010303,
309         0x00000200, 0xE0300070,
310         0x00000204, 0x800010FF,
311         0x00000200, 0xE0300090,
312         0x00000204, 0x00010303,
313         0x00000200, 0xE030008C,
314         0x00000204, 0x800010FF,
315         0x00000200, 0xE03000AC,
316         0x00000204, 0x00010303,
317         0x00000200, 0xE03000A8,
318         0x00000204, 0x800010FF,
319         0x00000200, 0xE03000C4,
320         0x00000204, 0x800010FF,
321         0x00000200, 0xE03000C8,
322         0x00000204, 0x00010303,
323         0x00000200, 0xE03000E4,
324         0x00000204, 0x00010303,
325         0x00000200, 0xE03000E0,
326         0x00000204, 0x800010FF,
327         0x00000200, 0xE0300100,
328         0x00000204, 0x00010303,
329         0x00000200, 0xE03000FC,
330         0x00000204, 0x800010FF,
331         0x00000200, 0x0001f198,
332         0x00000204, 0x0003ffff,
333         0x00000200, 0x0001f19C,
334         0x00000204, 0x3fffffff,
335         0x00000200, 0xE030032C,
336         0x00000204, 0x00000000,
337 };
338
339 static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
340                                                    const u32 *seq, u32 count);
341 static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev);
342 static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
343                                              struct radeon_ps *new_rps,
344                                              struct radeon_ps *old_rps);
345
346 static struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
347 {
348         struct trinity_ps *ps = rps->ps_priv;
349
350         return ps;
351 }
352
353 static struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
354 {
355         struct trinity_power_info *pi = rdev->pm.dpm.priv;
356
357         return pi;
358 }
359
360 static void trinity_gfx_powergating_initialize(struct radeon_device *rdev)
361 {
362         struct trinity_power_info *pi = trinity_get_pi(rdev);
363         u32 p, u;
364         u32 value;
365         struct atom_clock_dividers dividers;
366         u32 xclk = radeon_get_xclk(rdev);
367         u32 sssd = 1;
368         int ret;
369         u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
370
371         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
372                                              25000, false, &dividers);
373         if (ret)
374                 return;
375
376         value = RREG32_SMC(GFX_POWER_GATING_CNTL);
377         value &= ~(SSSD_MASK | PDS_DIV_MASK);
378         if (sssd)
379                 value |= SSSD(1);
380         value |= PDS_DIV(dividers.post_div);
381         WREG32_SMC(GFX_POWER_GATING_CNTL, value);
382
383         r600_calculate_u_and_p(500, xclk, 16, &p, &u);
384
385         WREG32(CG_PG_CTRL, SP(p) | SU(u));
386
387         WREG32_P(CG_GIPOTS, CG_GIPOT(p), ~CG_GIPOT_MASK);
388
389         /* XXX double check hw_rev */
390         if (pi->override_dynamic_mgpg && (hw_rev == 0))
391                 trinity_override_dynamic_mg_powergating(rdev);
392
393 }
394
395 #define CGCG_CGTT_LOCAL0_MASK       0xFFFF33FF
396 #define CGCG_CGTT_LOCAL1_MASK       0xFFFB0FFE
397 #define CGTS_SM_CTRL_REG_DISABLE    0x00600000
398 #define CGTS_SM_CTRL_REG_ENABLE     0x96944200
399
400 static void trinity_mg_clockgating_enable(struct radeon_device *rdev,
401                                           bool enable)
402 {
403         u32 local0;
404         u32 local1;
405
406         if (enable) {
407                 local0 = RREG32_CG(CG_CGTT_LOCAL_0);
408                 local1 = RREG32_CG(CG_CGTT_LOCAL_1);
409
410                 WREG32_CG(CG_CGTT_LOCAL_0,
411                           (0x00380000 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
412                 WREG32_CG(CG_CGTT_LOCAL_1,
413                           (0x0E000000 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
414
415                 WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_ENABLE);
416         } else {
417                 WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_DISABLE);
418
419                 local0 = RREG32_CG(CG_CGTT_LOCAL_0);
420                 local1 = RREG32_CG(CG_CGTT_LOCAL_1);
421
422                 WREG32_CG(CG_CGTT_LOCAL_0,
423                           CGCG_CGTT_LOCAL0_MASK | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
424                 WREG32_CG(CG_CGTT_LOCAL_1,
425                           CGCG_CGTT_LOCAL1_MASK | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
426         }
427 }
428
429 static void trinity_mg_clockgating_initialize(struct radeon_device *rdev)
430 {
431         u32 count;
432         const u32 *seq = NULL;
433
434         seq = &trinity_mgcg_shls_default[0];
435         count = sizeof(trinity_mgcg_shls_default) / (3 * sizeof(u32));
436
437         trinity_program_clk_gating_hw_sequence(rdev, seq, count);
438 }
439
440 static void trinity_gfx_clockgating_enable(struct radeon_device *rdev,
441                                            bool enable)
442 {
443         if (enable) {
444                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
445         } else {
446                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
447                 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
448                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
449                 RREG32(GB_ADDR_CONFIG);
450         }
451 }
452
453 static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
454                                                    const u32 *seq, u32 count)
455 {
456         u32 i, length = count * 3;
457
458         for (i = 0; i < length; i += 3)
459                 WREG32_P(seq[i], seq[i+1], ~seq[i+2]);
460 }
461
462 static void trinity_program_override_mgpg_sequences(struct radeon_device *rdev,
463                                                     const u32 *seq, u32 count)
464 {
465         u32  i, length = count * 2;
466
467         for (i = 0; i < length; i += 2)
468                 WREG32(seq[i], seq[i+1]);
469
470 }
471
472 static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev)
473 {
474         u32 count;
475         const u32 *seq = NULL;
476
477         seq = &trinity_override_mgpg_sequences[0];
478         count = sizeof(trinity_override_mgpg_sequences) / (2 * sizeof(u32));
479
480         trinity_program_override_mgpg_sequences(rdev, seq, count);
481 }
482
483 static void trinity_ls_clockgating_enable(struct radeon_device *rdev,
484                                           bool enable)
485 {
486         u32 count;
487         const u32 *seq = NULL;
488
489         if (enable) {
490                 seq = &trinity_sysls_enable[0];
491                 count = sizeof(trinity_sysls_enable) / (3 * sizeof(u32));
492         } else {
493                 seq = &trinity_sysls_disable[0];
494                 count = sizeof(trinity_sysls_disable) / (3 * sizeof(u32));
495         }
496
497         trinity_program_clk_gating_hw_sequence(rdev, seq, count);
498 }
499
500 static void trinity_gfx_powergating_enable(struct radeon_device *rdev,
501                                            bool enable)
502 {
503         if (enable) {
504                 if (RREG32_SMC(CC_SMU_TST_EFUSE1_MISC) & RB_BACKEND_DISABLE_MASK)
505                         WREG32_SMC(SMU_SCRATCH_A, (RREG32_SMC(SMU_SCRATCH_A) | 0x01));
506
507                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
508         } else {
509                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_PWR_DOWN_EN);
510                 RREG32(GB_ADDR_CONFIG);
511         }
512 }
513
514 static void trinity_gfx_dynamic_mgpg_enable(struct radeon_device *rdev,
515                                             bool enable)
516 {
517         u32 value;
518
519         if (enable) {
520                 value = RREG32_SMC(PM_I_CNTL_1);
521                 value &= ~DS_PG_CNTL_MASK;
522                 value |= DS_PG_CNTL(1);
523                 WREG32_SMC(PM_I_CNTL_1, value);
524
525                 value = RREG32_SMC(SMU_S_PG_CNTL);
526                 value &= ~DS_PG_EN_MASK;
527                 value |= DS_PG_EN(1);
528                 WREG32_SMC(SMU_S_PG_CNTL, value);
529         } else {
530                 value = RREG32_SMC(SMU_S_PG_CNTL);
531                 value &= ~DS_PG_EN_MASK;
532                 WREG32_SMC(SMU_S_PG_CNTL, value);
533
534                 value = RREG32_SMC(PM_I_CNTL_1);
535                 value &= ~DS_PG_CNTL_MASK;
536                 WREG32_SMC(PM_I_CNTL_1, value);
537         }
538
539         trinity_gfx_dynamic_mgpg_config(rdev);
540
541 }
542
543 static void trinity_enable_clock_power_gating(struct radeon_device *rdev)
544 {
545         struct trinity_power_info *pi = trinity_get_pi(rdev);
546
547         if (pi->enable_gfx_clock_gating)
548                 sumo_gfx_clockgating_initialize(rdev);
549         if (pi->enable_mg_clock_gating)
550                 trinity_mg_clockgating_initialize(rdev);
551         if (pi->enable_gfx_power_gating)
552                 trinity_gfx_powergating_initialize(rdev);
553         if (pi->enable_mg_clock_gating) {
554                 trinity_ls_clockgating_enable(rdev, true);
555                 trinity_mg_clockgating_enable(rdev, true);
556         }
557         if (pi->enable_gfx_clock_gating)
558                 trinity_gfx_clockgating_enable(rdev, true);
559         if (pi->enable_gfx_dynamic_mgpg)
560                 trinity_gfx_dynamic_mgpg_enable(rdev, true);
561         if (pi->enable_gfx_power_gating)
562                 trinity_gfx_powergating_enable(rdev, true);
563 }
564
565 static void trinity_disable_clock_power_gating(struct radeon_device *rdev)
566 {
567         struct trinity_power_info *pi = trinity_get_pi(rdev);
568
569         if (pi->enable_gfx_power_gating)
570                 trinity_gfx_powergating_enable(rdev, false);
571         if (pi->enable_gfx_dynamic_mgpg)
572                 trinity_gfx_dynamic_mgpg_enable(rdev, false);
573         if (pi->enable_gfx_clock_gating)
574                 trinity_gfx_clockgating_enable(rdev, false);
575         if (pi->enable_mg_clock_gating) {
576                 trinity_mg_clockgating_enable(rdev, false);
577                 trinity_ls_clockgating_enable(rdev, false);
578         }
579 }
580
581 static void trinity_set_divider_value(struct radeon_device *rdev,
582                                       u32 index, u32 sclk)
583 {
584         struct atom_clock_dividers  dividers;
585         int ret;
586         u32 value;
587         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
588
589         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
590                                              sclk, false, &dividers);
591         if (ret)
592                 return;
593
594         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
595         value &= ~CLK_DIVIDER_MASK;
596         value |= CLK_DIVIDER(dividers.post_div);
597         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
598
599         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
600                                              sclk/2, false, &dividers);
601         if (ret)
602                 return;
603
604         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix);
605         value &= ~PD_SCLK_DIVIDER_MASK;
606         value |= PD_SCLK_DIVIDER(dividers.post_div);
607         WREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix, value);
608 }
609
610 static void trinity_set_ds_dividers(struct radeon_device *rdev,
611                                     u32 index, u32 divider)
612 {
613         u32 value;
614         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
615
616         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
617         value &= ~DS_DIV_MASK;
618         value |= DS_DIV(divider);
619         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
620 }
621
622 static void trinity_set_ss_dividers(struct radeon_device *rdev,
623                                     u32 index, u32 divider)
624 {
625         u32 value;
626         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
627
628         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
629         value &= ~DS_SH_DIV_MASK;
630         value |= DS_SH_DIV(divider);
631         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
632 }
633
634 static void trinity_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
635 {
636         struct trinity_power_info *pi = trinity_get_pi(rdev);
637         u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid);
638         u32 value;
639         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
640
641         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
642         value &= ~VID_MASK;
643         value |= VID(vid_7bit);
644         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
645
646         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
647         value &= ~LVRT_MASK;
648         value |= LVRT(0);
649         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
650 }
651
652 static void trinity_set_allos_gnb_slow(struct radeon_device *rdev,
653                                        u32 index, u32 gnb_slow)
654 {
655         u32 value;
656         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
657
658         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
659         value &= ~GNB_SLOW_MASK;
660         value |= GNB_SLOW(gnb_slow);
661         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
662 }
663
664 static void trinity_set_force_nbp_state(struct radeon_device *rdev,
665                                         u32 index, u32 force_nbp_state)
666 {
667         u32 value;
668         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
669
670         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
671         value &= ~FORCE_NBPS1_MASK;
672         value |= FORCE_NBPS1(force_nbp_state);
673         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
674 }
675
676 static void trinity_set_display_wm(struct radeon_device *rdev,
677                                    u32 index, u32 wm)
678 {
679         u32 value;
680         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
681
682         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
683         value &= ~DISPLAY_WM_MASK;
684         value |= DISPLAY_WM(wm);
685         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
686 }
687
688 static void trinity_set_vce_wm(struct radeon_device *rdev,
689                                u32 index, u32 wm)
690 {
691         u32 value;
692         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
693
694         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
695         value &= ~VCE_WM_MASK;
696         value |= VCE_WM(wm);
697         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
698 }
699
700 static void trinity_set_at(struct radeon_device *rdev,
701                            u32 index, u32 at)
702 {
703         u32 value;
704         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
705
706         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix);
707         value &= ~AT_MASK;
708         value |= AT(at);
709         WREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix, value);
710 }
711
712 static void trinity_program_power_level(struct radeon_device *rdev,
713                                         struct trinity_pl *pl, u32 index)
714 {
715         struct trinity_power_info *pi = trinity_get_pi(rdev);
716
717         if (index >= SUMO_MAX_HARDWARE_POWERLEVELS)
718                 return;
719
720         trinity_set_divider_value(rdev, index, pl->sclk);
721         trinity_set_vid(rdev, index, pl->vddc_index);
722         trinity_set_ss_dividers(rdev, index, pl->ss_divider_index);
723         trinity_set_ds_dividers(rdev, index, pl->ds_divider_index);
724         trinity_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
725         trinity_set_force_nbp_state(rdev, index, pl->force_nbp_state);
726         trinity_set_display_wm(rdev, index, pl->display_wm);
727         trinity_set_vce_wm(rdev, index, pl->vce_wm);
728         trinity_set_at(rdev, index, pi->at[index]);
729 }
730
731 static void trinity_power_level_enable_disable(struct radeon_device *rdev,
732                                                u32 index, bool enable)
733 {
734         u32 value;
735         u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
736
737         value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
738         value &= ~STATE_VALID_MASK;
739         if (enable)
740                 value |= STATE_VALID(1);
741         WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
742 }
743
744 static bool trinity_dpm_enabled(struct radeon_device *rdev)
745 {
746         if (RREG32_SMC(SMU_SCLK_DPM_CNTL) & SCLK_DPM_EN(1))
747                 return true;
748         else
749                 return false;
750 }
751
752 static void trinity_start_dpm(struct radeon_device *rdev)
753 {
754         u32 value = RREG32_SMC(SMU_SCLK_DPM_CNTL);
755
756         value &= ~(SCLK_DPM_EN_MASK | SCLK_DPM_BOOT_STATE_MASK | VOLTAGE_CHG_EN_MASK);
757         value |= SCLK_DPM_EN(1) | SCLK_DPM_BOOT_STATE(0) | VOLTAGE_CHG_EN(1);
758         WREG32_SMC(SMU_SCLK_DPM_CNTL, value);
759
760         WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
761         WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~EN);
762
763         trinity_dpm_config(rdev, true);
764 }
765
766 static void trinity_wait_for_dpm_enabled(struct radeon_device *rdev)
767 {
768         int i;
769
770         for (i = 0; i < rdev->usec_timeout; i++) {
771                 if (RREG32(SCLK_PWRMGT_CNTL) & DYNAMIC_PM_EN)
772                         break;
773                 udelay(1);
774         }
775         for (i = 0; i < rdev->usec_timeout; i++) {
776                 if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_STATE_MASK) == 0)
777                         break;
778                 udelay(1);
779         }
780         for (i = 0; i < rdev->usec_timeout; i++) {
781                 if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
782                         break;
783                 udelay(1);
784         }
785 }
786
787 static void trinity_stop_dpm(struct radeon_device *rdev)
788 {
789         u32 sclk_dpm_cntl;
790
791         WREG32_P(CG_CG_VOLTAGE_CNTL, EN, ~EN);
792
793         sclk_dpm_cntl = RREG32_SMC(SMU_SCLK_DPM_CNTL);
794         sclk_dpm_cntl &= ~(SCLK_DPM_EN_MASK | VOLTAGE_CHG_EN_MASK);
795         WREG32_SMC(SMU_SCLK_DPM_CNTL, sclk_dpm_cntl);
796
797         trinity_dpm_config(rdev, false);
798 }
799
800 static void trinity_start_am(struct radeon_device *rdev)
801 {
802         WREG32_P(SCLK_PWRMGT_CNTL, 0, ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
803 }
804
805 static void trinity_reset_am(struct radeon_device *rdev)
806 {
807         WREG32_P(SCLK_PWRMGT_CNTL, RESET_SCLK_CNT | RESET_BUSY_CNT,
808                  ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
809 }
810
811 static void trinity_wait_for_level_0(struct radeon_device *rdev)
812 {
813         int i;
814
815         for (i = 0; i < rdev->usec_timeout; i++) {
816                 if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
817                         break;
818                 udelay(1);
819         }
820 }
821
822 static void trinity_enable_power_level_0(struct radeon_device *rdev)
823 {
824         trinity_power_level_enable_disable(rdev, 0, true);
825 }
826
827 static void trinity_force_level_0(struct radeon_device *rdev)
828 {
829         trinity_dpm_force_state(rdev, 0);
830 }
831
832 static void trinity_unforce_levels(struct radeon_device *rdev)
833 {
834         trinity_dpm_no_forced_level(rdev);
835 }
836
837 static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
838                                                 struct radeon_ps *new_rps,
839                                                 struct radeon_ps *old_rps)
840 {
841         struct trinity_ps *new_ps = trinity_get_ps(new_rps);
842         struct trinity_ps *old_ps = trinity_get_ps(old_rps);
843         u32 i;
844         u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
845
846         for (i = 0; i < new_ps->num_levels; i++) {
847                 trinity_program_power_level(rdev, &new_ps->levels[i], i);
848                 trinity_power_level_enable_disable(rdev, i, true);
849         }
850
851         for (i = new_ps->num_levels; i < n_current_state_levels; i++)
852                 trinity_power_level_enable_disable(rdev, i, false);
853 }
854
855 static void trinity_program_bootup_state(struct radeon_device *rdev)
856 {
857         struct trinity_power_info *pi = trinity_get_pi(rdev);
858         u32 i;
859
860         trinity_program_power_level(rdev, &pi->boot_pl, 0);
861         trinity_power_level_enable_disable(rdev, 0, true);
862
863         for (i = 1; i < 8; i++)
864                 trinity_power_level_enable_disable(rdev, i, false);
865 }
866
867 static void trinity_setup_uvd_clock_table(struct radeon_device *rdev,
868                                           struct radeon_ps *rps)
869 {
870         struct trinity_ps *ps = trinity_get_ps(rps);
871         u32 uvdstates = (ps->vclk_low_divider |
872                          ps->vclk_high_divider << 8 |
873                          ps->dclk_low_divider << 16 |
874                          ps->dclk_high_divider << 24);
875
876         WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates);
877 }
878
879 static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev,
880                                            u32 interval)
881 {
882         u32 p, u;
883         u32 tp = RREG32_SMC(PM_TP);
884         u32 val;
885         u32 xclk = radeon_get_xclk(rdev);
886
887         r600_calculate_u_and_p(interval, xclk, 16, &p, &u);
888
889         val = (p + tp - 1) / tp;
890
891         WREG32_SMC(SMU_UVD_DPM_CNTL, val);
892 }
893
894 static bool trinity_uvd_clocks_zero(struct radeon_ps *rps)
895 {
896         if ((rps->vclk == 0) && (rps->dclk == 0))
897                 return true;
898         else
899                 return false;
900 }
901
902 static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1,
903                                      struct radeon_ps *rps2)
904 {
905         struct trinity_ps *ps1 = trinity_get_ps(rps1);
906         struct trinity_ps *ps2 = trinity_get_ps(rps2);
907
908         if ((rps1->vclk == rps2->vclk) &&
909             (rps1->dclk == rps2->dclk) &&
910             (ps1->vclk_low_divider == ps2->vclk_low_divider) &&
911             (ps1->vclk_high_divider == ps2->vclk_high_divider) &&
912             (ps1->dclk_low_divider == ps2->dclk_low_divider) &&
913             (ps1->dclk_high_divider == ps2->dclk_high_divider))
914                 return true;
915         else
916                 return false;
917 }
918
919 static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
920                                      struct radeon_ps *new_rps,
921                                      struct radeon_ps *old_rps)
922 {
923         struct trinity_power_info *pi = trinity_get_pi(rdev);
924
925         if (pi->enable_gfx_power_gating) {
926                 trinity_gfx_powergating_enable(rdev, false);
927         }
928
929         if (pi->uvd_dpm) {
930                 if (trinity_uvd_clocks_zero(new_rps) &&
931                     !trinity_uvd_clocks_zero(old_rps)) {
932                         trinity_setup_uvd_dpm_interval(rdev, 0);
933                 } else if (!trinity_uvd_clocks_zero(new_rps)) {
934                         trinity_setup_uvd_clock_table(rdev, new_rps);
935
936                         if (trinity_uvd_clocks_zero(old_rps)) {
937                                 u32 tmp = RREG32(CG_MISC_REG);
938                                 tmp &= 0xfffffffd;
939                                 WREG32(CG_MISC_REG, tmp);
940
941                                 radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
942
943                                 trinity_setup_uvd_dpm_interval(rdev, 3000);
944                         }
945                 }
946                 trinity_uvd_dpm_config(rdev);
947         } else {
948                 if (trinity_uvd_clocks_zero(new_rps) ||
949                     trinity_uvd_clocks_equal(new_rps, old_rps))
950                         return;
951
952                 radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
953         }
954
955         if (pi->enable_gfx_power_gating) {
956                 trinity_gfx_powergating_enable(rdev, true);
957         }
958 }
959
960 static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
961                                                        struct radeon_ps *new_rps,
962                                                        struct radeon_ps *old_rps)
963 {
964         struct trinity_ps *new_ps = trinity_get_ps(new_rps);
965         struct trinity_ps *current_ps = trinity_get_ps(new_rps);
966
967         if (new_ps->levels[new_ps->num_levels - 1].sclk >=
968             current_ps->levels[current_ps->num_levels - 1].sclk)
969                 return;
970
971         trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
972 }
973
974 static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
975                                                       struct radeon_ps *new_rps,
976                                                       struct radeon_ps *old_rps)
977 {
978         struct trinity_ps *new_ps = trinity_get_ps(new_rps);
979         struct trinity_ps *current_ps = trinity_get_ps(old_rps);
980
981         if (new_ps->levels[new_ps->num_levels - 1].sclk <
982             current_ps->levels[current_ps->num_levels - 1].sclk)
983                 return;
984
985         trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
986 }
987
988 static void trinity_set_vce_clock(struct radeon_device *rdev,
989                                   struct radeon_ps *new_rps,
990                                   struct radeon_ps *old_rps)
991 {
992         if ((old_rps->evclk != new_rps->evclk) ||
993             (old_rps->ecclk != new_rps->ecclk))
994                 radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk);
995 }
996
997 static void trinity_program_ttt(struct radeon_device *rdev)
998 {
999         struct trinity_power_info *pi = trinity_get_pi(rdev);
1000         u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT);
1001
1002         value &= ~(HT_MASK | LT_MASK);
1003         value |= HT((pi->thermal_auto_throttling + 49) * 8);
1004         value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8);
1005         WREG32_SMC(SMU_SCLK_DPM_TTT, value);
1006 }
1007
1008 static void trinity_enable_att(struct radeon_device *rdev)
1009 {
1010         u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL);
1011
1012         value &= ~SCLK_TT_EN_MASK;
1013         value |= SCLK_TT_EN(1);
1014         WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value);
1015 }
1016
1017 static void trinity_program_sclk_dpm(struct radeon_device *rdev)
1018 {
1019         u32 p, u;
1020         u32 tp = RREG32_SMC(PM_TP);
1021         u32 ni;
1022         u32 xclk = radeon_get_xclk(rdev);
1023         u32 value;
1024
1025         r600_calculate_u_and_p(400, xclk, 16, &p, &u);
1026
1027         ni = (p + tp - 1) / tp;
1028
1029         value = RREG32_SMC(PM_I_CNTL_1);
1030         value &= ~SCLK_DPM_MASK;
1031         value |= SCLK_DPM(ni);
1032         WREG32_SMC(PM_I_CNTL_1, value);
1033 }
1034
1035 static int trinity_set_thermal_temperature_range(struct radeon_device *rdev,
1036                                                  int min_temp, int max_temp)
1037 {
1038         int low_temp = 0 * 1000;
1039         int high_temp = 255 * 1000;
1040
1041         if (low_temp < min_temp)
1042                 low_temp = min_temp;
1043         if (high_temp > max_temp)
1044                 high_temp = max_temp;
1045         if (high_temp < low_temp) {
1046                 DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
1047                 return -EINVAL;
1048         }
1049
1050         WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
1051         WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
1052
1053         rdev->pm.dpm.thermal.min_temp = low_temp;
1054         rdev->pm.dpm.thermal.max_temp = high_temp;
1055
1056         return 0;
1057 }
1058
1059 static void trinity_update_current_ps(struct radeon_device *rdev,
1060                                       struct radeon_ps *rps)
1061 {
1062         struct trinity_ps *new_ps = trinity_get_ps(rps);
1063         struct trinity_power_info *pi = trinity_get_pi(rdev);
1064
1065         pi->current_rps = *rps;
1066         pi->current_ps = *new_ps;
1067         pi->current_rps.ps_priv = &pi->current_ps;
1068 }
1069
1070 static void trinity_update_requested_ps(struct radeon_device *rdev,
1071                                         struct radeon_ps *rps)
1072 {
1073         struct trinity_ps *new_ps = trinity_get_ps(rps);
1074         struct trinity_power_info *pi = trinity_get_pi(rdev);
1075
1076         pi->requested_rps = *rps;
1077         pi->requested_ps = *new_ps;
1078         pi->requested_rps.ps_priv = &pi->requested_ps;
1079 }
1080
1081 void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
1082 {
1083         struct trinity_power_info *pi = trinity_get_pi(rdev);
1084
1085         if (pi->enable_bapm) {
1086                 trinity_acquire_mutex(rdev);
1087                 trinity_dpm_bapm_enable(rdev, enable);
1088                 trinity_release_mutex(rdev);
1089         }
1090 }
1091
1092 int trinity_dpm_enable(struct radeon_device *rdev)
1093 {
1094         struct trinity_power_info *pi = trinity_get_pi(rdev);
1095
1096         trinity_acquire_mutex(rdev);
1097
1098         if (trinity_dpm_enabled(rdev)) {
1099                 trinity_release_mutex(rdev);
1100                 return -EINVAL;
1101         }
1102
1103         trinity_program_bootup_state(rdev);
1104         sumo_program_vc(rdev, 0x00C00033);
1105         trinity_start_am(rdev);
1106         if (pi->enable_auto_thermal_throttling) {
1107                 trinity_program_ttt(rdev);
1108                 trinity_enable_att(rdev);
1109         }
1110         trinity_program_sclk_dpm(rdev);
1111         trinity_start_dpm(rdev);
1112         trinity_wait_for_dpm_enabled(rdev);
1113         trinity_dpm_bapm_enable(rdev, false);
1114         trinity_release_mutex(rdev);
1115
1116         trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1117
1118         return 0;
1119 }
1120
1121 int trinity_dpm_late_enable(struct radeon_device *rdev)
1122 {
1123         int ret;
1124
1125         trinity_acquire_mutex(rdev);
1126         trinity_enable_clock_power_gating(rdev);
1127
1128         if (rdev->irq.installed &&
1129             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1130                 ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
1131                 if (ret) {
1132                         trinity_release_mutex(rdev);
1133                         return ret;
1134                 }
1135                 rdev->irq.dpm_thermal = true;
1136                 radeon_irq_set(rdev);
1137         }
1138         trinity_release_mutex(rdev);
1139
1140         return 0;
1141 }
1142
1143 void trinity_dpm_disable(struct radeon_device *rdev)
1144 {
1145         trinity_acquire_mutex(rdev);
1146         if (!trinity_dpm_enabled(rdev)) {
1147                 trinity_release_mutex(rdev);
1148                 return;
1149         }
1150         trinity_dpm_bapm_enable(rdev, false);
1151         trinity_disable_clock_power_gating(rdev);
1152         sumo_clear_vc(rdev);
1153         trinity_wait_for_level_0(rdev);
1154         trinity_stop_dpm(rdev);
1155         trinity_reset_am(rdev);
1156         trinity_release_mutex(rdev);
1157
1158         if (rdev->irq.installed &&
1159             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
1160                 rdev->irq.dpm_thermal = false;
1161                 radeon_irq_set(rdev);
1162         }
1163
1164         trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
1165 }
1166
1167 static void trinity_get_min_sclk_divider(struct radeon_device *rdev)
1168 {
1169         struct trinity_power_info *pi = trinity_get_pi(rdev);
1170
1171         pi->min_sclk_did =
1172                 (RREG32_SMC(CC_SMU_MISC_FUSES) & MinSClkDid_MASK) >> MinSClkDid_SHIFT;
1173 }
1174
1175 static void trinity_setup_nbp_sim(struct radeon_device *rdev,
1176                                   struct radeon_ps *rps)
1177 {
1178         struct trinity_power_info *pi = trinity_get_pi(rdev);
1179         struct trinity_ps *new_ps = trinity_get_ps(rps);
1180         u32 nbpsconfig;
1181
1182         if (pi->sys_info.nb_dpm_enable) {
1183                 nbpsconfig = RREG32_SMC(NB_PSTATE_CONFIG);
1184                 nbpsconfig &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK | DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
1185                 nbpsconfig |= (Dpm0PgNbPsLo(new_ps->Dpm0PgNbPsLo) |
1186                                Dpm0PgNbPsHi(new_ps->Dpm0PgNbPsHi) |
1187                                DpmXNbPsLo(new_ps->DpmXNbPsLo) |
1188                                DpmXNbPsHi(new_ps->DpmXNbPsHi));
1189                 WREG32_SMC(NB_PSTATE_CONFIG, nbpsconfig);
1190         }
1191 }
1192
1193 int trinity_dpm_force_performance_level(struct radeon_device *rdev,
1194                                         enum radeon_dpm_forced_level level)
1195 {
1196         struct trinity_power_info *pi = trinity_get_pi(rdev);
1197         struct radeon_ps *rps = &pi->current_rps;
1198         struct trinity_ps *ps = trinity_get_ps(rps);
1199         int i, ret;
1200
1201         if (ps->num_levels <= 1)
1202                 return 0;
1203
1204         if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
1205                 /* not supported by the hw */
1206                 return -EINVAL;
1207         } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
1208                 ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1);
1209                 if (ret)
1210                         return ret;
1211         } else {
1212                 for (i = 0; i < ps->num_levels; i++) {
1213                         ret = trinity_dpm_n_levels_disabled(rdev, 0);
1214                         if (ret)
1215                                 return ret;
1216                 }
1217         }
1218
1219         rdev->pm.dpm.forced_level = level;
1220
1221         return 0;
1222 }
1223
1224 int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
1225 {
1226         struct trinity_power_info *pi = trinity_get_pi(rdev);
1227         struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
1228         struct radeon_ps *new_ps = &requested_ps;
1229
1230         trinity_update_requested_ps(rdev, new_ps);
1231
1232         trinity_apply_state_adjust_rules(rdev,
1233                                          &pi->requested_rps,
1234                                          &pi->current_rps);
1235
1236         return 0;
1237 }
1238
1239 int trinity_dpm_set_power_state(struct radeon_device *rdev)
1240 {
1241         struct trinity_power_info *pi = trinity_get_pi(rdev);
1242         struct radeon_ps *new_ps = &pi->requested_rps;
1243         struct radeon_ps *old_ps = &pi->current_rps;
1244
1245         trinity_acquire_mutex(rdev);
1246         if (pi->enable_dpm) {
1247                 if (pi->enable_bapm)
1248                         trinity_dpm_bapm_enable(rdev, rdev->pm.dpm.ac_power);
1249                 trinity_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
1250                 trinity_enable_power_level_0(rdev);
1251                 trinity_force_level_0(rdev);
1252                 trinity_wait_for_level_0(rdev);
1253                 trinity_setup_nbp_sim(rdev, new_ps);
1254                 trinity_program_power_levels_0_to_n(rdev, new_ps, old_ps);
1255                 trinity_force_level_0(rdev);
1256                 trinity_unforce_levels(rdev);
1257                 trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
1258                 trinity_set_vce_clock(rdev, new_ps, old_ps);
1259         }
1260         trinity_release_mutex(rdev);
1261
1262         return 0;
1263 }
1264
1265 void trinity_dpm_post_set_power_state(struct radeon_device *rdev)
1266 {
1267         struct trinity_power_info *pi = trinity_get_pi(rdev);
1268         struct radeon_ps *new_ps = &pi->requested_rps;
1269
1270         trinity_update_current_ps(rdev, new_ps);
1271 }
1272
1273 void trinity_dpm_setup_asic(struct radeon_device *rdev)
1274 {
1275         trinity_acquire_mutex(rdev);
1276         sumo_program_sstp(rdev);
1277         sumo_take_smu_control(rdev, true);
1278         trinity_get_min_sclk_divider(rdev);
1279         trinity_release_mutex(rdev);
1280 }
1281
1282 #if 0
1283 void trinity_dpm_reset_asic(struct radeon_device *rdev)
1284 {
1285         struct trinity_power_info *pi = trinity_get_pi(rdev);
1286
1287         trinity_acquire_mutex(rdev);
1288         if (pi->enable_dpm) {
1289                 trinity_enable_power_level_0(rdev);
1290                 trinity_force_level_0(rdev);
1291                 trinity_wait_for_level_0(rdev);
1292                 trinity_program_bootup_state(rdev);
1293                 trinity_force_level_0(rdev);
1294                 trinity_unforce_levels(rdev);
1295         }
1296         trinity_release_mutex(rdev);
1297 }
1298 #endif
1299
1300 static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev,
1301                                                   u32 vid_2bit)
1302 {
1303         struct trinity_power_info *pi = trinity_get_pi(rdev);
1304         u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
1305         u32 svi_mode = (RREG32_SMC(PM_CONFIG) & SVI_Mode) ? 1 : 0;
1306         u32 step = (svi_mode == 0) ? 1250 : 625;
1307         u32 delta = vid_7bit * step + 50;
1308
1309         if (delta > 155000)
1310                 return 0;
1311
1312         return (155000 - delta) / 100;
1313 }
1314
1315 static void trinity_patch_boot_state(struct radeon_device *rdev,
1316                                      struct trinity_ps *ps)
1317 {
1318         struct trinity_power_info *pi = trinity_get_pi(rdev);
1319
1320         ps->num_levels = 1;
1321         ps->nbps_flags = 0;
1322         ps->bapm_flags = 0;
1323         ps->levels[0] = pi->boot_pl;
1324 }
1325
1326 static u8 trinity_calculate_vce_wm(struct radeon_device *rdev, u32 sclk)
1327 {
1328         if (sclk < 20000)
1329                 return 1;
1330         return 0;
1331 }
1332
1333 static void trinity_construct_boot_state(struct radeon_device *rdev)
1334 {
1335         struct trinity_power_info *pi = trinity_get_pi(rdev);
1336
1337         pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
1338         pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
1339         pi->boot_pl.ds_divider_index = 0;
1340         pi->boot_pl.ss_divider_index = 0;
1341         pi->boot_pl.allow_gnb_slow = 1;
1342         pi->boot_pl.force_nbp_state = 0;
1343         pi->boot_pl.display_wm = 0;
1344         pi->boot_pl.vce_wm = 0;
1345         pi->current_ps.num_levels = 1;
1346         pi->current_ps.levels[0] = pi->boot_pl;
1347 }
1348
1349 static u8 trinity_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
1350                                                   u32 sclk, u32 min_sclk_in_sr)
1351 {
1352         struct trinity_power_info *pi = trinity_get_pi(rdev);
1353         u32 i;
1354         u32 temp;
1355         u32 min = (min_sclk_in_sr > TRINITY_MINIMUM_ENGINE_CLOCK) ?
1356                 min_sclk_in_sr : TRINITY_MINIMUM_ENGINE_CLOCK;
1357
1358         if (sclk < min)
1359                 return 0;
1360
1361         if (!pi->enable_sclk_ds)
1362                 return 0;
1363
1364         for (i = TRINITY_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
1365                 temp = sclk / sumo_get_sleep_divider_from_id(i);
1366                 if (temp >= min || i == 0)
1367                         break;
1368         }
1369
1370         return (u8)i;
1371 }
1372
1373 static u32 trinity_get_valid_engine_clock(struct radeon_device *rdev,
1374                                           u32 lower_limit)
1375 {
1376         struct trinity_power_info *pi = trinity_get_pi(rdev);
1377         u32 i;
1378
1379         for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
1380                 if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
1381                         return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
1382         }
1383
1384         if (i == pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries)
1385                 DRM_ERROR("engine clock out of range!");
1386
1387         return 0;
1388 }
1389
1390 static void trinity_patch_thermal_state(struct radeon_device *rdev,
1391                                         struct trinity_ps *ps,
1392                                         struct trinity_ps *current_ps)
1393 {
1394         struct trinity_power_info *pi = trinity_get_pi(rdev);
1395         u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
1396         u32 current_vddc;
1397         u32 current_sclk;
1398         u32 current_index = 0;
1399
1400         if (current_ps) {
1401                 current_vddc = current_ps->levels[current_index].vddc_index;
1402                 current_sclk = current_ps->levels[current_index].sclk;
1403         } else {
1404                 current_vddc = pi->boot_pl.vddc_index;
1405                 current_sclk = pi->boot_pl.sclk;
1406         }
1407
1408         ps->levels[0].vddc_index = current_vddc;
1409
1410         if (ps->levels[0].sclk > current_sclk)
1411                 ps->levels[0].sclk = current_sclk;
1412
1413         ps->levels[0].ds_divider_index =
1414                 trinity_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
1415         ps->levels[0].ss_divider_index = ps->levels[0].ds_divider_index;
1416         ps->levels[0].allow_gnb_slow = 1;
1417         ps->levels[0].force_nbp_state = 0;
1418         ps->levels[0].display_wm = 0;
1419         ps->levels[0].vce_wm =
1420                 trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
1421 }
1422
1423 static u8 trinity_calculate_display_wm(struct radeon_device *rdev,
1424                                        struct trinity_ps *ps, u32 index)
1425 {
1426         if (ps == NULL || ps->num_levels <= 1)
1427                 return 0;
1428         else if (ps->num_levels == 2) {
1429                 if (index == 0)
1430                         return 0;
1431                 else
1432                         return 1;
1433         } else {
1434                 if (index == 0)
1435                         return 0;
1436                 else if (ps->levels[index].sclk < 30000)
1437                         return 0;
1438                 else
1439                         return 1;
1440         }
1441 }
1442
1443 static u32 trinity_get_uvd_clock_index(struct radeon_device *rdev,
1444                                        struct radeon_ps *rps)
1445 {
1446         struct trinity_power_info *pi = trinity_get_pi(rdev);
1447         u32 i = 0;
1448
1449         for (i = 0; i < 4; i++) {
1450                 if ((rps->vclk == pi->sys_info.uvd_clock_table_entries[i].vclk) &&
1451                     (rps->dclk == pi->sys_info.uvd_clock_table_entries[i].dclk))
1452                     break;
1453         }
1454
1455         if (i >= 4) {
1456                 DRM_ERROR("UVD clock index not found!\n");
1457                 i = 3;
1458         }
1459         return i;
1460 }
1461
1462 static void trinity_adjust_uvd_state(struct radeon_device *rdev,
1463                                      struct radeon_ps *rps)
1464 {
1465         struct trinity_ps *ps = trinity_get_ps(rps);
1466         struct trinity_power_info *pi = trinity_get_pi(rdev);
1467         u32 high_index = 0;
1468         u32 low_index = 0;
1469
1470         if (pi->uvd_dpm && r600_is_uvd_state(rps->class, rps->class2)) {
1471                 high_index = trinity_get_uvd_clock_index(rdev, rps);
1472
1473                 switch(high_index) {
1474                 case 3:
1475                 case 2:
1476                         low_index = 1;
1477                         break;
1478                 case 1:
1479                 case 0:
1480                 default:
1481                         low_index = 0;
1482                         break;
1483                 }
1484
1485                 ps->vclk_low_divider =
1486                         pi->sys_info.uvd_clock_table_entries[high_index].vclk_did;
1487                 ps->dclk_low_divider =
1488                         pi->sys_info.uvd_clock_table_entries[high_index].dclk_did;
1489                 ps->vclk_high_divider =
1490                         pi->sys_info.uvd_clock_table_entries[low_index].vclk_did;
1491                 ps->dclk_high_divider =
1492                         pi->sys_info.uvd_clock_table_entries[low_index].dclk_did;
1493         }
1494 }
1495
1496 static int trinity_get_vce_clock_voltage(struct radeon_device *rdev,
1497                                          u32 evclk, u32 ecclk, u16 *voltage)
1498 {
1499         u32 i;
1500         int ret = -EINVAL;
1501         struct radeon_vce_clock_voltage_dependency_table *table =
1502                 &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
1503
1504         if (((evclk == 0) && (ecclk == 0)) ||
1505             (table && (table->count == 0))) {
1506                 *voltage = 0;
1507                 return 0;
1508         }
1509
1510         for (i = 0; i < table->count; i++) {
1511                 if ((evclk <= table->entries[i].evclk) &&
1512                     (ecclk <= table->entries[i].ecclk)) {
1513                         *voltage = table->entries[i].v;
1514                         ret = 0;
1515                         break;
1516                 }
1517         }
1518
1519         /* if no match return the highest voltage */
1520         if (ret)
1521                 *voltage = table->entries[table->count - 1].v;
1522
1523         return ret;
1524 }
1525
1526 static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
1527                                              struct radeon_ps *new_rps,
1528                                              struct radeon_ps *old_rps)
1529 {
1530         struct trinity_ps *ps = trinity_get_ps(new_rps);
1531         struct trinity_ps *current_ps = trinity_get_ps(old_rps);
1532         struct trinity_power_info *pi = trinity_get_pi(rdev);
1533         u32 min_voltage = 0; /* ??? */
1534         u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
1535         u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
1536         u32 i;
1537         u16 min_vce_voltage;
1538         bool force_high;
1539         u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
1540
1541         if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1542                 return trinity_patch_thermal_state(rdev, ps, current_ps);
1543
1544         trinity_adjust_uvd_state(rdev, new_rps);
1545
1546         if (new_rps->vce_active) {
1547                 new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
1548                 new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
1549         } else {
1550                 new_rps->evclk = 0;
1551                 new_rps->ecclk = 0;
1552         }
1553
1554         for (i = 0; i < ps->num_levels; i++) {
1555                 if (ps->levels[i].vddc_index < min_voltage)
1556                         ps->levels[i].vddc_index = min_voltage;
1557
1558                 if (ps->levels[i].sclk < min_sclk)
1559                         ps->levels[i].sclk =
1560                                 trinity_get_valid_engine_clock(rdev, min_sclk);
1561
1562                 /* patch in vce limits */
1563                 if (new_rps->vce_active) {
1564                         /* sclk */
1565                         if (ps->levels[i].sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
1566                                 ps->levels[i].sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
1567                         /* vddc */
1568                         trinity_get_vce_clock_voltage(rdev, new_rps->evclk, new_rps->ecclk, &min_vce_voltage);
1569                         if (ps->levels[i].vddc_index < min_vce_voltage)
1570                                 ps->levels[i].vddc_index = min_vce_voltage;
1571                 }
1572
1573                 ps->levels[i].ds_divider_index =
1574                         sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
1575
1576                 ps->levels[i].ss_divider_index = ps->levels[i].ds_divider_index;
1577
1578                 ps->levels[i].allow_gnb_slow = 1;
1579                 ps->levels[i].force_nbp_state = 0;
1580                 ps->levels[i].display_wm =
1581                         trinity_calculate_display_wm(rdev, ps, i);
1582                 ps->levels[i].vce_wm =
1583                         trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
1584         }
1585
1586         if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
1587             ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY))
1588                 ps->bapm_flags |= TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE;
1589
1590         if (pi->sys_info.nb_dpm_enable) {
1591                 ps->Dpm0PgNbPsLo = 0x1;
1592                 ps->Dpm0PgNbPsHi = 0x0;
1593                 ps->DpmXNbPsLo = 0x2;
1594                 ps->DpmXNbPsHi = 0x1;
1595
1596                 if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
1597                     ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) {
1598                         force_high = ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) ||
1599                                       ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) &&
1600                                        (pi->sys_info.uma_channel_number == 1)));
1601                         force_high = (num_active_displays >= 3) || force_high;
1602                         ps->Dpm0PgNbPsLo = force_high ? 0x2 : 0x3;
1603                         ps->Dpm0PgNbPsHi = 0x1;
1604                         ps->DpmXNbPsLo = force_high ? 0x2 : 0x3;
1605                         ps->DpmXNbPsHi = 0x2;
1606                         ps->levels[ps->num_levels - 1].allow_gnb_slow = 0;
1607                 }
1608         }
1609 }
1610
1611 static void trinity_cleanup_asic(struct radeon_device *rdev)
1612 {
1613         sumo_take_smu_control(rdev, false);
1614 }
1615
1616 #if 0
1617 static void trinity_pre_display_configuration_change(struct radeon_device *rdev)
1618 {
1619         struct trinity_power_info *pi = trinity_get_pi(rdev);
1620
1621         if (pi->voltage_drop_in_dce)
1622                 trinity_dce_enable_voltage_adjustment(rdev, false);
1623 }
1624 #endif
1625
1626 static void trinity_add_dccac_value(struct radeon_device *rdev)
1627 {
1628         u32 gpu_cac_avrg_cntl_window_size;
1629         u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
1630         u64 disp_clk = rdev->clock.default_dispclk / 100;
1631         u32 dc_cac_value;
1632
1633         gpu_cac_avrg_cntl_window_size =
1634                 (RREG32_SMC(GPU_CAC_AVRG_CNTL) & WINDOW_SIZE_MASK) >> WINDOW_SIZE_SHIFT;
1635
1636         dc_cac_value = (u32)((14213 * disp_clk * disp_clk * (u64)num_active_displays) >>
1637                              (32 - gpu_cac_avrg_cntl_window_size));
1638
1639         WREG32_SMC(DC_CAC_VALUE, dc_cac_value);
1640 }
1641
1642 void trinity_dpm_display_configuration_changed(struct radeon_device *rdev)
1643 {
1644         struct trinity_power_info *pi = trinity_get_pi(rdev);
1645
1646         if (pi->voltage_drop_in_dce)
1647                 trinity_dce_enable_voltage_adjustment(rdev, true);
1648         trinity_add_dccac_value(rdev);
1649 }
1650
1651 union power_info {
1652         struct _ATOM_POWERPLAY_INFO info;
1653         struct _ATOM_POWERPLAY_INFO_V2 info_2;
1654         struct _ATOM_POWERPLAY_INFO_V3 info_3;
1655         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
1656         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
1657         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
1658 };
1659
1660 union pplib_clock_info {
1661         struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
1662         struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
1663         struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
1664         struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
1665 };
1666
1667 union pplib_power_state {
1668         struct _ATOM_PPLIB_STATE v1;
1669         struct _ATOM_PPLIB_STATE_V2 v2;
1670 };
1671
1672 static void trinity_parse_pplib_non_clock_info(struct radeon_device *rdev,
1673                                                struct radeon_ps *rps,
1674                                                struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
1675                                                u8 table_rev)
1676 {
1677         struct trinity_ps *ps = trinity_get_ps(rps);
1678
1679         rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
1680         rps->class = le16_to_cpu(non_clock_info->usClassification);
1681         rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
1682
1683         if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
1684                 rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
1685                 rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
1686         } else {
1687                 rps->vclk = 0;
1688                 rps->dclk = 0;
1689         }
1690
1691         if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
1692                 rdev->pm.dpm.boot_ps = rps;
1693                 trinity_patch_boot_state(rdev, ps);
1694         }
1695         if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
1696                 rdev->pm.dpm.uvd_ps = rps;
1697 }
1698
1699 static void trinity_parse_pplib_clock_info(struct radeon_device *rdev,
1700                                            struct radeon_ps *rps, int index,
1701                                            union pplib_clock_info *clock_info)
1702 {
1703         struct trinity_power_info *pi = trinity_get_pi(rdev);
1704         struct trinity_ps *ps = trinity_get_ps(rps);
1705         struct trinity_pl *pl = &ps->levels[index];
1706         u32 sclk;
1707
1708         sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
1709         sclk |= clock_info->sumo.ucEngineClockHigh << 16;
1710         pl->sclk = sclk;
1711         pl->vddc_index = clock_info->sumo.vddcIndex;
1712
1713         ps->num_levels = index + 1;
1714
1715         if (pi->enable_sclk_ds) {
1716                 pl->ds_divider_index = 5;
1717                 pl->ss_divider_index = 5;
1718         }
1719 }
1720
1721 static int trinity_parse_power_table(struct radeon_device *rdev)
1722 {
1723         struct radeon_mode_info *mode_info = &rdev->mode_info;
1724         struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
1725         union pplib_power_state *power_state;
1726         int i, j, k, non_clock_array_index, clock_array_index;
1727         union pplib_clock_info *clock_info;
1728         struct _StateArray *state_array;
1729         struct _ClockInfoArray *clock_info_array;
1730         struct _NonClockInfoArray *non_clock_info_array;
1731         union power_info *power_info;
1732         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
1733         u16 data_offset;
1734         u8 frev, crev;
1735         u8 *power_state_offset;
1736         struct sumo_ps *ps;
1737
1738         if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
1739                                    &frev, &crev, &data_offset))
1740                 return -EINVAL;
1741         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
1742
1743         state_array = (struct _StateArray *)
1744                 (mode_info->atom_context->bios + data_offset +
1745                  le16_to_cpu(power_info->pplib.usStateArrayOffset));
1746         clock_info_array = (struct _ClockInfoArray *)
1747                 (mode_info->atom_context->bios + data_offset +
1748                  le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
1749         non_clock_info_array = (struct _NonClockInfoArray *)
1750                 (mode_info->atom_context->bios + data_offset +
1751                  le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
1752
1753         rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
1754                                   state_array->ucNumEntries, GFP_KERNEL);
1755         if (!rdev->pm.dpm.ps)
1756                 return -ENOMEM;
1757         power_state_offset = (u8 *)state_array->states;
1758         for (i = 0; i < state_array->ucNumEntries; i++) {
1759                 u8 *idx;
1760                 power_state = (union pplib_power_state *)power_state_offset;
1761                 non_clock_array_index = power_state->v2.nonClockInfoIndex;
1762                 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
1763                         &non_clock_info_array->nonClockInfo[non_clock_array_index];
1764                 if (!rdev->pm.power_state[i].clock_info)
1765                         return -EINVAL;
1766                 ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
1767                 if (ps == NULL) {
1768                         kfree(rdev->pm.dpm.ps);
1769                         return -ENOMEM;
1770                 }
1771                 rdev->pm.dpm.ps[i].ps_priv = ps;
1772                 k = 0;
1773                 idx = (u8 *)&power_state->v2.clockInfoIndex[0];
1774                 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
1775                         clock_array_index = idx[j];
1776                         if (clock_array_index >= clock_info_array->ucNumEntries)
1777                                 continue;
1778                         if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
1779                                 break;
1780                         clock_info = (union pplib_clock_info *)
1781                                 ((u8 *)&clock_info_array->clockInfo[0] +
1782                                  (clock_array_index * clock_info_array->ucEntrySize));
1783                         trinity_parse_pplib_clock_info(rdev,
1784                                                        &rdev->pm.dpm.ps[i], k,
1785                                                        clock_info);
1786                         k++;
1787                 }
1788                 trinity_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
1789                                                    non_clock_info,
1790                                                    non_clock_info_array->ucEntrySize);
1791                 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
1792         }
1793         rdev->pm.dpm.num_ps = state_array->ucNumEntries;
1794
1795         /* fill in the vce power states */
1796         for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
1797                 u32 sclk;
1798                 clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
1799                 clock_info = (union pplib_clock_info *)
1800                         &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
1801                 sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
1802                 sclk |= clock_info->sumo.ucEngineClockHigh << 16;
1803                 rdev->pm.dpm.vce_states[i].sclk = sclk;
1804                 rdev->pm.dpm.vce_states[i].mclk = 0;
1805         }
1806
1807         return 0;
1808 }
1809
1810 union igp_info {
1811         struct _ATOM_INTEGRATED_SYSTEM_INFO info;
1812         struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
1813         struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
1814         struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
1815         struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
1816 };
1817
1818 static u32 trinity_convert_did_to_freq(struct radeon_device *rdev, u8 did)
1819 {
1820         struct trinity_power_info *pi = trinity_get_pi(rdev);
1821         u32 divider;
1822
1823         if (did >= 8 && did <= 0x3f)
1824                 divider = did * 25;
1825         else if (did > 0x3f && did <= 0x5f)
1826                 divider = (did - 64) * 50 + 1600;
1827         else if (did > 0x5f && did <= 0x7e)
1828                 divider = (did - 96) * 100 + 3200;
1829         else if (did == 0x7f)
1830                 divider = 128 * 100;
1831         else
1832                 return 10000;
1833
1834         return ((pi->sys_info.dentist_vco_freq * 100) + (divider - 1)) / divider;
1835 }
1836
1837 static int trinity_parse_sys_info_table(struct radeon_device *rdev)
1838 {
1839         struct trinity_power_info *pi = trinity_get_pi(rdev);
1840         struct radeon_mode_info *mode_info = &rdev->mode_info;
1841         int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
1842         union igp_info *igp_info;
1843         u8 frev, crev;
1844         u16 data_offset;
1845         int i;
1846
1847         if (atom_parse_data_header(mode_info->atom_context, index, NULL,
1848                                    &frev, &crev, &data_offset)) {
1849                 igp_info = (union igp_info *)(mode_info->atom_context->bios +
1850                                               data_offset);
1851
1852                 if (crev != 7) {
1853                         DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
1854                         return -EINVAL;
1855                 }
1856                 pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_7.ulBootUpEngineClock);
1857                 pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_7.ulMinEngineClock);
1858                 pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_7.ulBootUpUMAClock);
1859                 pi->sys_info.dentist_vco_freq = le32_to_cpu(igp_info->info_7.ulDentistVCOFreq);
1860                 pi->sys_info.bootup_nb_voltage_index =
1861                         le16_to_cpu(igp_info->info_7.usBootUpNBVoltage);
1862                 if (igp_info->info_7.ucHtcTmpLmt == 0)
1863                         pi->sys_info.htc_tmp_lmt = 203;
1864                 else
1865                         pi->sys_info.htc_tmp_lmt = igp_info->info_7.ucHtcTmpLmt;
1866                 if (igp_info->info_7.ucHtcHystLmt == 0)
1867                         pi->sys_info.htc_hyst_lmt = 5;
1868                 else
1869                         pi->sys_info.htc_hyst_lmt = igp_info->info_7.ucHtcHystLmt;
1870                 if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
1871                         DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
1872                 }
1873
1874                 if (pi->enable_nbps_policy)
1875                         pi->sys_info.nb_dpm_enable = igp_info->info_7.ucNBDPMEnable;
1876                 else
1877                         pi->sys_info.nb_dpm_enable = 0;
1878
1879                 for (i = 0; i < TRINITY_NUM_NBPSTATES; i++) {
1880                         pi->sys_info.nbp_mclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateMemclkFreq[i]);
1881                         pi->sys_info.nbp_nclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateNClkFreq[i]);
1882                 }
1883
1884                 pi->sys_info.nbp_voltage_index[0] = le16_to_cpu(igp_info->info_7.usNBP0Voltage);
1885                 pi->sys_info.nbp_voltage_index[1] = le16_to_cpu(igp_info->info_7.usNBP1Voltage);
1886                 pi->sys_info.nbp_voltage_index[2] = le16_to_cpu(igp_info->info_7.usNBP2Voltage);
1887                 pi->sys_info.nbp_voltage_index[3] = le16_to_cpu(igp_info->info_7.usNBP3Voltage);
1888
1889                 if (!pi->sys_info.nb_dpm_enable) {
1890                         for (i = 1; i < TRINITY_NUM_NBPSTATES; i++) {
1891                                 pi->sys_info.nbp_mclk[i] = pi->sys_info.nbp_mclk[0];
1892                                 pi->sys_info.nbp_nclk[i] = pi->sys_info.nbp_nclk[0];
1893                                 pi->sys_info.nbp_voltage_index[i] = pi->sys_info.nbp_voltage_index[0];
1894                         }
1895                 }
1896
1897                 pi->sys_info.uma_channel_number = igp_info->info_7.ucUMAChannelNumber;
1898
1899                 sumo_construct_sclk_voltage_mapping_table(rdev,
1900                                                           &pi->sys_info.sclk_voltage_mapping_table,
1901                                                           igp_info->info_7.sAvail_SCLK);
1902                 sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
1903                                                  igp_info->info_7.sAvail_SCLK);
1904
1905                 pi->sys_info.uvd_clock_table_entries[0].vclk_did =
1906                         igp_info->info_7.ucDPMState0VclkFid;
1907                 pi->sys_info.uvd_clock_table_entries[1].vclk_did =
1908                         igp_info->info_7.ucDPMState1VclkFid;
1909                 pi->sys_info.uvd_clock_table_entries[2].vclk_did =
1910                         igp_info->info_7.ucDPMState2VclkFid;
1911                 pi->sys_info.uvd_clock_table_entries[3].vclk_did =
1912                         igp_info->info_7.ucDPMState3VclkFid;
1913
1914                 pi->sys_info.uvd_clock_table_entries[0].dclk_did =
1915                         igp_info->info_7.ucDPMState0DclkFid;
1916                 pi->sys_info.uvd_clock_table_entries[1].dclk_did =
1917                         igp_info->info_7.ucDPMState1DclkFid;
1918                 pi->sys_info.uvd_clock_table_entries[2].dclk_did =
1919                         igp_info->info_7.ucDPMState2DclkFid;
1920                 pi->sys_info.uvd_clock_table_entries[3].dclk_did =
1921                         igp_info->info_7.ucDPMState3DclkFid;
1922
1923                 for (i = 0; i < 4; i++) {
1924                         pi->sys_info.uvd_clock_table_entries[i].vclk =
1925                                 trinity_convert_did_to_freq(rdev,
1926                                                             pi->sys_info.uvd_clock_table_entries[i].vclk_did);
1927                         pi->sys_info.uvd_clock_table_entries[i].dclk =
1928                                 trinity_convert_did_to_freq(rdev,
1929                                                             pi->sys_info.uvd_clock_table_entries[i].dclk_did);
1930                 }
1931
1932
1933
1934         }
1935         return 0;
1936 }
1937
1938 int trinity_dpm_init(struct radeon_device *rdev)
1939 {
1940         struct trinity_power_info *pi;
1941         int ret, i;
1942
1943         pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL);
1944         if (pi == NULL)
1945                 return -ENOMEM;
1946         rdev->pm.dpm.priv = pi;
1947
1948         for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
1949                 pi->at[i] = TRINITY_AT_DFLT;
1950
1951         if (radeon_bapm == -1) {
1952                 /* There are stability issues reported on with
1953                  * bapm enabled when switching between AC and battery
1954                  * power.  At the same time, some MSI boards hang
1955                  * if it's not enabled and dpm is enabled.  Just enable
1956                  * it for MSI boards right now.
1957                  */
1958                 if (rdev->pdev->subsystem_vendor == 0x1462)
1959                         pi->enable_bapm = true;
1960                 else
1961                         pi->enable_bapm = false;
1962         } else if (radeon_bapm == 0) {
1963                 pi->enable_bapm = false;
1964         } else {
1965                 pi->enable_bapm = true;
1966         }
1967         pi->enable_nbps_policy = true;
1968         pi->enable_sclk_ds = true;
1969         pi->enable_gfx_power_gating = true;
1970         pi->enable_gfx_clock_gating = true;
1971         pi->enable_mg_clock_gating = false;
1972         pi->enable_gfx_dynamic_mgpg = false;
1973         pi->override_dynamic_mgpg = false;
1974         pi->enable_auto_thermal_throttling = true;
1975         pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */
1976         pi->uvd_dpm = true; /* ??? */
1977
1978         ret = trinity_parse_sys_info_table(rdev);
1979         if (ret)
1980                 return ret;
1981
1982         trinity_construct_boot_state(rdev);
1983
1984         ret = r600_get_platform_caps(rdev);
1985         if (ret)
1986                 return ret;
1987
1988         ret = r600_parse_extended_power_table(rdev);
1989         if (ret)
1990                 return ret;
1991
1992         ret = trinity_parse_power_table(rdev);
1993         if (ret)
1994                 return ret;
1995
1996         pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
1997         pi->enable_dpm = true;
1998
1999         return 0;
2000 }
2001
2002 void trinity_dpm_print_power_state(struct radeon_device *rdev,
2003                                    struct radeon_ps *rps)
2004 {
2005         int i;
2006         struct trinity_ps *ps = trinity_get_ps(rps);
2007
2008         r600_dpm_print_class_info(rps->class, rps->class2);
2009         r600_dpm_print_cap_info(rps->caps);
2010         printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2011         for (i = 0; i < ps->num_levels; i++) {
2012                 struct trinity_pl *pl = &ps->levels[i];
2013                 printk("\t\tpower level %d    sclk: %u vddc: %u\n",
2014                        i, pl->sclk,
2015                        trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
2016         }
2017         r600_dpm_print_ps_status(rdev, rps);
2018 }
2019
2020 void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2021                                                          struct seq_file *m)
2022 {
2023         struct trinity_power_info *pi = trinity_get_pi(rdev);
2024         struct radeon_ps *rps = &pi->current_rps;
2025         struct trinity_ps *ps = trinity_get_ps(rps);
2026         struct trinity_pl *pl;
2027         u32 current_index =
2028                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
2029                 CURRENT_STATE_SHIFT;
2030
2031         if (current_index >= ps->num_levels) {
2032                 seq_printf(m, "invalid dpm profile %d\n", current_index);
2033         } else {
2034                 pl = &ps->levels[current_index];
2035                 seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2036                 seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
2037                            current_index, pl->sclk,
2038                            trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
2039         }
2040 }
2041
2042 u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev)
2043 {
2044         struct trinity_power_info *pi = trinity_get_pi(rdev);
2045         struct radeon_ps *rps = &pi->current_rps;
2046         struct trinity_ps *ps = trinity_get_ps(rps);
2047         struct trinity_pl *pl;
2048         u32 current_index =
2049                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
2050                 CURRENT_STATE_SHIFT;
2051
2052         if (current_index >= ps->num_levels) {
2053                 return 0;
2054         } else {
2055                 pl = &ps->levels[current_index];
2056                 return pl->sclk;
2057         }
2058 }
2059
2060 u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev)
2061 {
2062         struct trinity_power_info *pi = trinity_get_pi(rdev);
2063
2064         return pi->sys_info.bootup_uma_clk;
2065 }
2066
2067 void trinity_dpm_fini(struct radeon_device *rdev)
2068 {
2069         int i;
2070
2071         trinity_cleanup_asic(rdev); /* ??? */
2072
2073         for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2074                 kfree(rdev->pm.dpm.ps[i].ps_priv);
2075         }
2076         kfree(rdev->pm.dpm.ps);
2077         kfree(rdev->pm.dpm.priv);
2078         r600_free_extended_power_table(rdev);
2079 }
2080
2081 u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low)
2082 {
2083         struct trinity_power_info *pi = trinity_get_pi(rdev);
2084         struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps);
2085
2086         if (low)
2087                 return requested_state->levels[0].sclk;
2088         else
2089                 return requested_state->levels[requested_state->num_levels - 1].sclk;
2090 }
2091
2092 u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low)
2093 {
2094         struct trinity_power_info *pi = trinity_get_pi(rdev);
2095
2096         return pi->sys_info.bootup_uma_clk;
2097 }