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