Update drm/radeon to Linux 4.7.10 as much as possible...
[dragonfly.git] / sys / dev / drm / radeon / btc_dpm.c
1 /*
2  * Copyright 2011 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  * Authors: Alex Deucher
23  */
24
25 #include <drm/drmP.h>
26 #include "radeon.h"
27 #include "radeon_asic.h"
28 #include "btcd.h"
29 #include "r600_dpm.h"
30 #include "cypress_dpm.h"
31 #include "btc_dpm.h"
32 #include "atom.h"
33 #include <linux/seq_file.h>
34
35 #define MC_CG_ARB_FREQ_F0           0x0a
36 #define MC_CG_ARB_FREQ_F1           0x0b
37 #define MC_CG_ARB_FREQ_F2           0x0c
38 #define MC_CG_ARB_FREQ_F3           0x0d
39
40 #define MC_CG_SEQ_DRAMCONF_S0       0x05
41 #define MC_CG_SEQ_DRAMCONF_S1       0x06
42 #define MC_CG_SEQ_YCLK_SUSPEND      0x04
43 #define MC_CG_SEQ_YCLK_RESUME       0x0a
44
45 #define SMC_RAM_END 0x8000
46
47 #ifndef BTC_MGCG_SEQUENCE
48 #define BTC_MGCG_SEQUENCE  300
49
50 struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
51 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
52 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
53
54 //********* BARTS **************//
55 static const u32 barts_cgcg_cgls_default[] =
56 {
57         /* Register,   Value,     Mask bits */
58         0x000008f8, 0x00000010, 0xffffffff,
59         0x000008fc, 0x00000000, 0xffffffff,
60         0x000008f8, 0x00000011, 0xffffffff,
61         0x000008fc, 0x00000000, 0xffffffff,
62         0x000008f8, 0x00000012, 0xffffffff,
63         0x000008fc, 0x00000000, 0xffffffff,
64         0x000008f8, 0x00000013, 0xffffffff,
65         0x000008fc, 0x00000000, 0xffffffff,
66         0x000008f8, 0x00000014, 0xffffffff,
67         0x000008fc, 0x00000000, 0xffffffff,
68         0x000008f8, 0x00000015, 0xffffffff,
69         0x000008fc, 0x00000000, 0xffffffff,
70         0x000008f8, 0x00000016, 0xffffffff,
71         0x000008fc, 0x00000000, 0xffffffff,
72         0x000008f8, 0x00000017, 0xffffffff,
73         0x000008fc, 0x00000000, 0xffffffff,
74         0x000008f8, 0x00000018, 0xffffffff,
75         0x000008fc, 0x00000000, 0xffffffff,
76         0x000008f8, 0x00000019, 0xffffffff,
77         0x000008fc, 0x00000000, 0xffffffff,
78         0x000008f8, 0x0000001a, 0xffffffff,
79         0x000008fc, 0x00000000, 0xffffffff,
80         0x000008f8, 0x0000001b, 0xffffffff,
81         0x000008fc, 0x00000000, 0xffffffff,
82         0x000008f8, 0x00000020, 0xffffffff,
83         0x000008fc, 0x00000000, 0xffffffff,
84         0x000008f8, 0x00000021, 0xffffffff,
85         0x000008fc, 0x00000000, 0xffffffff,
86         0x000008f8, 0x00000022, 0xffffffff,
87         0x000008fc, 0x00000000, 0xffffffff,
88         0x000008f8, 0x00000023, 0xffffffff,
89         0x000008fc, 0x00000000, 0xffffffff,
90         0x000008f8, 0x00000024, 0xffffffff,
91         0x000008fc, 0x00000000, 0xffffffff,
92         0x000008f8, 0x00000025, 0xffffffff,
93         0x000008fc, 0x00000000, 0xffffffff,
94         0x000008f8, 0x00000026, 0xffffffff,
95         0x000008fc, 0x00000000, 0xffffffff,
96         0x000008f8, 0x00000027, 0xffffffff,
97         0x000008fc, 0x00000000, 0xffffffff,
98         0x000008f8, 0x00000028, 0xffffffff,
99         0x000008fc, 0x00000000, 0xffffffff,
100         0x000008f8, 0x00000029, 0xffffffff,
101         0x000008fc, 0x00000000, 0xffffffff,
102         0x000008f8, 0x0000002a, 0xffffffff,
103         0x000008fc, 0x00000000, 0xffffffff,
104         0x000008f8, 0x0000002b, 0xffffffff,
105         0x000008fc, 0x00000000, 0xffffffff
106 };
107 #define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
108
109 static const u32 barts_cgcg_cgls_disable[] =
110 {
111         0x000008f8, 0x00000010, 0xffffffff,
112         0x000008fc, 0xffffffff, 0xffffffff,
113         0x000008f8, 0x00000011, 0xffffffff,
114         0x000008fc, 0xffffffff, 0xffffffff,
115         0x000008f8, 0x00000012, 0xffffffff,
116         0x000008fc, 0xffffffff, 0xffffffff,
117         0x000008f8, 0x00000013, 0xffffffff,
118         0x000008fc, 0xffffffff, 0xffffffff,
119         0x000008f8, 0x00000014, 0xffffffff,
120         0x000008fc, 0xffffffff, 0xffffffff,
121         0x000008f8, 0x00000015, 0xffffffff,
122         0x000008fc, 0xffffffff, 0xffffffff,
123         0x000008f8, 0x00000016, 0xffffffff,
124         0x000008fc, 0xffffffff, 0xffffffff,
125         0x000008f8, 0x00000017, 0xffffffff,
126         0x000008fc, 0xffffffff, 0xffffffff,
127         0x000008f8, 0x00000018, 0xffffffff,
128         0x000008fc, 0xffffffff, 0xffffffff,
129         0x000008f8, 0x00000019, 0xffffffff,
130         0x000008fc, 0xffffffff, 0xffffffff,
131         0x000008f8, 0x0000001a, 0xffffffff,
132         0x000008fc, 0xffffffff, 0xffffffff,
133         0x000008f8, 0x0000001b, 0xffffffff,
134         0x000008fc, 0xffffffff, 0xffffffff,
135         0x000008f8, 0x00000020, 0xffffffff,
136         0x000008fc, 0x00000000, 0xffffffff,
137         0x000008f8, 0x00000021, 0xffffffff,
138         0x000008fc, 0x00000000, 0xffffffff,
139         0x000008f8, 0x00000022, 0xffffffff,
140         0x000008fc, 0x00000000, 0xffffffff,
141         0x000008f8, 0x00000023, 0xffffffff,
142         0x000008fc, 0x00000000, 0xffffffff,
143         0x000008f8, 0x00000024, 0xffffffff,
144         0x000008fc, 0x00000000, 0xffffffff,
145         0x000008f8, 0x00000025, 0xffffffff,
146         0x000008fc, 0x00000000, 0xffffffff,
147         0x000008f8, 0x00000026, 0xffffffff,
148         0x000008fc, 0x00000000, 0xffffffff,
149         0x000008f8, 0x00000027, 0xffffffff,
150         0x000008fc, 0x00000000, 0xffffffff,
151         0x000008f8, 0x00000028, 0xffffffff,
152         0x000008fc, 0x00000000, 0xffffffff,
153         0x000008f8, 0x00000029, 0xffffffff,
154         0x000008fc, 0x00000000, 0xffffffff,
155         0x000008f8, 0x0000002a, 0xffffffff,
156         0x000008fc, 0x00000000, 0xffffffff,
157         0x000008f8, 0x0000002b, 0xffffffff,
158         0x000008fc, 0x00000000, 0xffffffff,
159         0x00000644, 0x000f7912, 0x001f4180,
160         0x00000644, 0x000f3812, 0x001f4180
161 };
162 #define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
163
164 static const u32 barts_cgcg_cgls_enable[] =
165 {
166         /* 0x0000c124, 0x84180000, 0x00180000, */
167         0x00000644, 0x000f7892, 0x001f4080,
168         0x000008f8, 0x00000010, 0xffffffff,
169         0x000008fc, 0x00000000, 0xffffffff,
170         0x000008f8, 0x00000011, 0xffffffff,
171         0x000008fc, 0x00000000, 0xffffffff,
172         0x000008f8, 0x00000012, 0xffffffff,
173         0x000008fc, 0x00000000, 0xffffffff,
174         0x000008f8, 0x00000013, 0xffffffff,
175         0x000008fc, 0x00000000, 0xffffffff,
176         0x000008f8, 0x00000014, 0xffffffff,
177         0x000008fc, 0x00000000, 0xffffffff,
178         0x000008f8, 0x00000015, 0xffffffff,
179         0x000008fc, 0x00000000, 0xffffffff,
180         0x000008f8, 0x00000016, 0xffffffff,
181         0x000008fc, 0x00000000, 0xffffffff,
182         0x000008f8, 0x00000017, 0xffffffff,
183         0x000008fc, 0x00000000, 0xffffffff,
184         0x000008f8, 0x00000018, 0xffffffff,
185         0x000008fc, 0x00000000, 0xffffffff,
186         0x000008f8, 0x00000019, 0xffffffff,
187         0x000008fc, 0x00000000, 0xffffffff,
188         0x000008f8, 0x0000001a, 0xffffffff,
189         0x000008fc, 0x00000000, 0xffffffff,
190         0x000008f8, 0x0000001b, 0xffffffff,
191         0x000008fc, 0x00000000, 0xffffffff,
192         0x000008f8, 0x00000020, 0xffffffff,
193         0x000008fc, 0xffffffff, 0xffffffff,
194         0x000008f8, 0x00000021, 0xffffffff,
195         0x000008fc, 0xffffffff, 0xffffffff,
196         0x000008f8, 0x00000022, 0xffffffff,
197         0x000008fc, 0xffffffff, 0xffffffff,
198         0x000008f8, 0x00000023, 0xffffffff,
199         0x000008fc, 0xffffffff, 0xffffffff,
200         0x000008f8, 0x00000024, 0xffffffff,
201         0x000008fc, 0xffffffff, 0xffffffff,
202         0x000008f8, 0x00000025, 0xffffffff,
203         0x000008fc, 0xffffffff, 0xffffffff,
204         0x000008f8, 0x00000026, 0xffffffff,
205         0x000008fc, 0xffffffff, 0xffffffff,
206         0x000008f8, 0x00000027, 0xffffffff,
207         0x000008fc, 0xffffffff, 0xffffffff,
208         0x000008f8, 0x00000028, 0xffffffff,
209         0x000008fc, 0xffffffff, 0xffffffff,
210         0x000008f8, 0x00000029, 0xffffffff,
211         0x000008fc, 0xffffffff, 0xffffffff,
212         0x000008f8, 0x0000002a, 0xffffffff,
213         0x000008fc, 0xffffffff, 0xffffffff,
214         0x000008f8, 0x0000002b, 0xffffffff,
215         0x000008fc, 0xffffffff, 0xffffffff
216 };
217 #define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
218
219 static const u32 barts_mgcg_default[] =
220 {
221         0x0000802c, 0xc0000000, 0xffffffff,
222         0x00005448, 0x00000100, 0xffffffff,
223         0x000055e4, 0x00600100, 0xffffffff,
224         0x0000160c, 0x00000100, 0xffffffff,
225         0x0000c164, 0x00000100, 0xffffffff,
226         0x00008a18, 0x00000100, 0xffffffff,
227         0x0000897c, 0x06000100, 0xffffffff,
228         0x00008b28, 0x00000100, 0xffffffff,
229         0x00009144, 0x00000100, 0xffffffff,
230         0x00009a60, 0x00000100, 0xffffffff,
231         0x00009868, 0x00000100, 0xffffffff,
232         0x00008d58, 0x00000100, 0xffffffff,
233         0x00009510, 0x00000100, 0xffffffff,
234         0x0000949c, 0x00000100, 0xffffffff,
235         0x00009654, 0x00000100, 0xffffffff,
236         0x00009030, 0x00000100, 0xffffffff,
237         0x00009034, 0x00000100, 0xffffffff,
238         0x00009038, 0x00000100, 0xffffffff,
239         0x0000903c, 0x00000100, 0xffffffff,
240         0x00009040, 0x00000100, 0xffffffff,
241         0x0000a200, 0x00000100, 0xffffffff,
242         0x0000a204, 0x00000100, 0xffffffff,
243         0x0000a208, 0x00000100, 0xffffffff,
244         0x0000a20c, 0x00000100, 0xffffffff,
245         0x0000977c, 0x00000100, 0xffffffff,
246         0x00003f80, 0x00000100, 0xffffffff,
247         0x0000a210, 0x00000100, 0xffffffff,
248         0x0000a214, 0x00000100, 0xffffffff,
249         0x000004d8, 0x00000100, 0xffffffff,
250         0x00009784, 0x00000100, 0xffffffff,
251         0x00009698, 0x00000100, 0xffffffff,
252         0x000004d4, 0x00000200, 0xffffffff,
253         0x000004d0, 0x00000000, 0xffffffff,
254         0x000030cc, 0x00000100, 0xffffffff,
255         0x0000d0c0, 0xff000100, 0xffffffff,
256         0x0000802c, 0x40000000, 0xffffffff,
257         0x0000915c, 0x00010000, 0xffffffff,
258         0x00009160, 0x00030002, 0xffffffff,
259         0x00009164, 0x00050004, 0xffffffff,
260         0x00009168, 0x00070006, 0xffffffff,
261         0x00009178, 0x00070000, 0xffffffff,
262         0x0000917c, 0x00030002, 0xffffffff,
263         0x00009180, 0x00050004, 0xffffffff,
264         0x0000918c, 0x00010006, 0xffffffff,
265         0x00009190, 0x00090008, 0xffffffff,
266         0x00009194, 0x00070000, 0xffffffff,
267         0x00009198, 0x00030002, 0xffffffff,
268         0x0000919c, 0x00050004, 0xffffffff,
269         0x000091a8, 0x00010006, 0xffffffff,
270         0x000091ac, 0x00090008, 0xffffffff,
271         0x000091b0, 0x00070000, 0xffffffff,
272         0x000091b4, 0x00030002, 0xffffffff,
273         0x000091b8, 0x00050004, 0xffffffff,
274         0x000091c4, 0x00010006, 0xffffffff,
275         0x000091c8, 0x00090008, 0xffffffff,
276         0x000091cc, 0x00070000, 0xffffffff,
277         0x000091d0, 0x00030002, 0xffffffff,
278         0x000091d4, 0x00050004, 0xffffffff,
279         0x000091e0, 0x00010006, 0xffffffff,
280         0x000091e4, 0x00090008, 0xffffffff,
281         0x000091e8, 0x00000000, 0xffffffff,
282         0x000091ec, 0x00070000, 0xffffffff,
283         0x000091f0, 0x00030002, 0xffffffff,
284         0x000091f4, 0x00050004, 0xffffffff,
285         0x00009200, 0x00010006, 0xffffffff,
286         0x00009204, 0x00090008, 0xffffffff,
287         0x00009208, 0x00070000, 0xffffffff,
288         0x0000920c, 0x00030002, 0xffffffff,
289         0x00009210, 0x00050004, 0xffffffff,
290         0x0000921c, 0x00010006, 0xffffffff,
291         0x00009220, 0x00090008, 0xffffffff,
292         0x00009224, 0x00070000, 0xffffffff,
293         0x00009228, 0x00030002, 0xffffffff,
294         0x0000922c, 0x00050004, 0xffffffff,
295         0x00009238, 0x00010006, 0xffffffff,
296         0x0000923c, 0x00090008, 0xffffffff,
297         0x00009294, 0x00000000, 0xffffffff,
298         0x0000802c, 0x40010000, 0xffffffff,
299         0x0000915c, 0x00010000, 0xffffffff,
300         0x00009160, 0x00030002, 0xffffffff,
301         0x00009164, 0x00050004, 0xffffffff,
302         0x00009168, 0x00070006, 0xffffffff,
303         0x00009178, 0x00070000, 0xffffffff,
304         0x0000917c, 0x00030002, 0xffffffff,
305         0x00009180, 0x00050004, 0xffffffff,
306         0x0000918c, 0x00010006, 0xffffffff,
307         0x00009190, 0x00090008, 0xffffffff,
308         0x00009194, 0x00070000, 0xffffffff,
309         0x00009198, 0x00030002, 0xffffffff,
310         0x0000919c, 0x00050004, 0xffffffff,
311         0x000091a8, 0x00010006, 0xffffffff,
312         0x000091ac, 0x00090008, 0xffffffff,
313         0x000091b0, 0x00070000, 0xffffffff,
314         0x000091b4, 0x00030002, 0xffffffff,
315         0x000091b8, 0x00050004, 0xffffffff,
316         0x000091c4, 0x00010006, 0xffffffff,
317         0x000091c8, 0x00090008, 0xffffffff,
318         0x000091cc, 0x00070000, 0xffffffff,
319         0x000091d0, 0x00030002, 0xffffffff,
320         0x000091d4, 0x00050004, 0xffffffff,
321         0x000091e0, 0x00010006, 0xffffffff,
322         0x000091e4, 0x00090008, 0xffffffff,
323         0x000091e8, 0x00000000, 0xffffffff,
324         0x000091ec, 0x00070000, 0xffffffff,
325         0x000091f0, 0x00030002, 0xffffffff,
326         0x000091f4, 0x00050004, 0xffffffff,
327         0x00009200, 0x00010006, 0xffffffff,
328         0x00009204, 0x00090008, 0xffffffff,
329         0x00009208, 0x00070000, 0xffffffff,
330         0x0000920c, 0x00030002, 0xffffffff,
331         0x00009210, 0x00050004, 0xffffffff,
332         0x0000921c, 0x00010006, 0xffffffff,
333         0x00009220, 0x00090008, 0xffffffff,
334         0x00009224, 0x00070000, 0xffffffff,
335         0x00009228, 0x00030002, 0xffffffff,
336         0x0000922c, 0x00050004, 0xffffffff,
337         0x00009238, 0x00010006, 0xffffffff,
338         0x0000923c, 0x00090008, 0xffffffff,
339         0x00009294, 0x00000000, 0xffffffff,
340         0x0000802c, 0xc0000000, 0xffffffff,
341         0x000008f8, 0x00000010, 0xffffffff,
342         0x000008fc, 0x00000000, 0xffffffff,
343         0x000008f8, 0x00000011, 0xffffffff,
344         0x000008fc, 0x00000000, 0xffffffff,
345         0x000008f8, 0x00000012, 0xffffffff,
346         0x000008fc, 0x00000000, 0xffffffff,
347         0x000008f8, 0x00000013, 0xffffffff,
348         0x000008fc, 0x00000000, 0xffffffff,
349         0x000008f8, 0x00000014, 0xffffffff,
350         0x000008fc, 0x00000000, 0xffffffff,
351         0x000008f8, 0x00000015, 0xffffffff,
352         0x000008fc, 0x00000000, 0xffffffff,
353         0x000008f8, 0x00000016, 0xffffffff,
354         0x000008fc, 0x00000000, 0xffffffff,
355         0x000008f8, 0x00000017, 0xffffffff,
356         0x000008fc, 0x00000000, 0xffffffff,
357         0x000008f8, 0x00000018, 0xffffffff,
358         0x000008fc, 0x00000000, 0xffffffff,
359         0x000008f8, 0x00000019, 0xffffffff,
360         0x000008fc, 0x00000000, 0xffffffff,
361         0x000008f8, 0x0000001a, 0xffffffff,
362         0x000008fc, 0x00000000, 0xffffffff,
363         0x000008f8, 0x0000001b, 0xffffffff,
364         0x000008fc, 0x00000000, 0xffffffff
365 };
366 #define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
367
368 static const u32 barts_mgcg_disable[] =
369 {
370         0x0000802c, 0xc0000000, 0xffffffff,
371         0x000008f8, 0x00000000, 0xffffffff,
372         0x000008fc, 0xffffffff, 0xffffffff,
373         0x000008f8, 0x00000001, 0xffffffff,
374         0x000008fc, 0xffffffff, 0xffffffff,
375         0x000008f8, 0x00000002, 0xffffffff,
376         0x000008fc, 0xffffffff, 0xffffffff,
377         0x000008f8, 0x00000003, 0xffffffff,
378         0x000008fc, 0xffffffff, 0xffffffff,
379         0x00009150, 0x00600000, 0xffffffff
380 };
381 #define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
382
383 static const u32 barts_mgcg_enable[] =
384 {
385         0x0000802c, 0xc0000000, 0xffffffff,
386         0x000008f8, 0x00000000, 0xffffffff,
387         0x000008fc, 0x00000000, 0xffffffff,
388         0x000008f8, 0x00000001, 0xffffffff,
389         0x000008fc, 0x00000000, 0xffffffff,
390         0x000008f8, 0x00000002, 0xffffffff,
391         0x000008fc, 0x00000000, 0xffffffff,
392         0x000008f8, 0x00000003, 0xffffffff,
393         0x000008fc, 0x00000000, 0xffffffff,
394         0x00009150, 0x81944000, 0xffffffff
395 };
396 #define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
397
398 //********* CAICOS **************//
399 static const u32 caicos_cgcg_cgls_default[] =
400 {
401         0x000008f8, 0x00000010, 0xffffffff,
402         0x000008fc, 0x00000000, 0xffffffff,
403         0x000008f8, 0x00000011, 0xffffffff,
404         0x000008fc, 0x00000000, 0xffffffff,
405         0x000008f8, 0x00000012, 0xffffffff,
406         0x000008fc, 0x00000000, 0xffffffff,
407         0x000008f8, 0x00000013, 0xffffffff,
408         0x000008fc, 0x00000000, 0xffffffff,
409         0x000008f8, 0x00000014, 0xffffffff,
410         0x000008fc, 0x00000000, 0xffffffff,
411         0x000008f8, 0x00000015, 0xffffffff,
412         0x000008fc, 0x00000000, 0xffffffff,
413         0x000008f8, 0x00000016, 0xffffffff,
414         0x000008fc, 0x00000000, 0xffffffff,
415         0x000008f8, 0x00000017, 0xffffffff,
416         0x000008fc, 0x00000000, 0xffffffff,
417         0x000008f8, 0x00000018, 0xffffffff,
418         0x000008fc, 0x00000000, 0xffffffff,
419         0x000008f8, 0x00000019, 0xffffffff,
420         0x000008fc, 0x00000000, 0xffffffff,
421         0x000008f8, 0x0000001a, 0xffffffff,
422         0x000008fc, 0x00000000, 0xffffffff,
423         0x000008f8, 0x0000001b, 0xffffffff,
424         0x000008fc, 0x00000000, 0xffffffff,
425         0x000008f8, 0x00000020, 0xffffffff,
426         0x000008fc, 0x00000000, 0xffffffff,
427         0x000008f8, 0x00000021, 0xffffffff,
428         0x000008fc, 0x00000000, 0xffffffff,
429         0x000008f8, 0x00000022, 0xffffffff,
430         0x000008fc, 0x00000000, 0xffffffff,
431         0x000008f8, 0x00000023, 0xffffffff,
432         0x000008fc, 0x00000000, 0xffffffff,
433         0x000008f8, 0x00000024, 0xffffffff,
434         0x000008fc, 0x00000000, 0xffffffff,
435         0x000008f8, 0x00000025, 0xffffffff,
436         0x000008fc, 0x00000000, 0xffffffff,
437         0x000008f8, 0x00000026, 0xffffffff,
438         0x000008fc, 0x00000000, 0xffffffff,
439         0x000008f8, 0x00000027, 0xffffffff,
440         0x000008fc, 0x00000000, 0xffffffff,
441         0x000008f8, 0x00000028, 0xffffffff,
442         0x000008fc, 0x00000000, 0xffffffff,
443         0x000008f8, 0x00000029, 0xffffffff,
444         0x000008fc, 0x00000000, 0xffffffff,
445         0x000008f8, 0x0000002a, 0xffffffff,
446         0x000008fc, 0x00000000, 0xffffffff,
447         0x000008f8, 0x0000002b, 0xffffffff,
448         0x000008fc, 0x00000000, 0xffffffff
449 };
450 #define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
451
452 static const u32 caicos_cgcg_cgls_disable[] =
453 {
454         0x000008f8, 0x00000010, 0xffffffff,
455         0x000008fc, 0xffffffff, 0xffffffff,
456         0x000008f8, 0x00000011, 0xffffffff,
457         0x000008fc, 0xffffffff, 0xffffffff,
458         0x000008f8, 0x00000012, 0xffffffff,
459         0x000008fc, 0xffffffff, 0xffffffff,
460         0x000008f8, 0x00000013, 0xffffffff,
461         0x000008fc, 0xffffffff, 0xffffffff,
462         0x000008f8, 0x00000014, 0xffffffff,
463         0x000008fc, 0xffffffff, 0xffffffff,
464         0x000008f8, 0x00000015, 0xffffffff,
465         0x000008fc, 0xffffffff, 0xffffffff,
466         0x000008f8, 0x00000016, 0xffffffff,
467         0x000008fc, 0xffffffff, 0xffffffff,
468         0x000008f8, 0x00000017, 0xffffffff,
469         0x000008fc, 0xffffffff, 0xffffffff,
470         0x000008f8, 0x00000018, 0xffffffff,
471         0x000008fc, 0xffffffff, 0xffffffff,
472         0x000008f8, 0x00000019, 0xffffffff,
473         0x000008fc, 0xffffffff, 0xffffffff,
474         0x000008f8, 0x0000001a, 0xffffffff,
475         0x000008fc, 0xffffffff, 0xffffffff,
476         0x000008f8, 0x0000001b, 0xffffffff,
477         0x000008fc, 0xffffffff, 0xffffffff,
478         0x000008f8, 0x00000020, 0xffffffff,
479         0x000008fc, 0x00000000, 0xffffffff,
480         0x000008f8, 0x00000021, 0xffffffff,
481         0x000008fc, 0x00000000, 0xffffffff,
482         0x000008f8, 0x00000022, 0xffffffff,
483         0x000008fc, 0x00000000, 0xffffffff,
484         0x000008f8, 0x00000023, 0xffffffff,
485         0x000008fc, 0x00000000, 0xffffffff,
486         0x000008f8, 0x00000024, 0xffffffff,
487         0x000008fc, 0x00000000, 0xffffffff,
488         0x000008f8, 0x00000025, 0xffffffff,
489         0x000008fc, 0x00000000, 0xffffffff,
490         0x000008f8, 0x00000026, 0xffffffff,
491         0x000008fc, 0x00000000, 0xffffffff,
492         0x000008f8, 0x00000027, 0xffffffff,
493         0x000008fc, 0x00000000, 0xffffffff,
494         0x000008f8, 0x00000028, 0xffffffff,
495         0x000008fc, 0x00000000, 0xffffffff,
496         0x000008f8, 0x00000029, 0xffffffff,
497         0x000008fc, 0x00000000, 0xffffffff,
498         0x000008f8, 0x0000002a, 0xffffffff,
499         0x000008fc, 0x00000000, 0xffffffff,
500         0x000008f8, 0x0000002b, 0xffffffff,
501         0x000008fc, 0x00000000, 0xffffffff,
502         0x00000644, 0x000f7912, 0x001f4180,
503         0x00000644, 0x000f3812, 0x001f4180
504 };
505 #define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
506
507 static const u32 caicos_cgcg_cgls_enable[] =
508 {
509         /* 0x0000c124, 0x84180000, 0x00180000, */
510         0x00000644, 0x000f7892, 0x001f4080,
511         0x000008f8, 0x00000010, 0xffffffff,
512         0x000008fc, 0x00000000, 0xffffffff,
513         0x000008f8, 0x00000011, 0xffffffff,
514         0x000008fc, 0x00000000, 0xffffffff,
515         0x000008f8, 0x00000012, 0xffffffff,
516         0x000008fc, 0x00000000, 0xffffffff,
517         0x000008f8, 0x00000013, 0xffffffff,
518         0x000008fc, 0x00000000, 0xffffffff,
519         0x000008f8, 0x00000014, 0xffffffff,
520         0x000008fc, 0x00000000, 0xffffffff,
521         0x000008f8, 0x00000015, 0xffffffff,
522         0x000008fc, 0x00000000, 0xffffffff,
523         0x000008f8, 0x00000016, 0xffffffff,
524         0x000008fc, 0x00000000, 0xffffffff,
525         0x000008f8, 0x00000017, 0xffffffff,
526         0x000008fc, 0x00000000, 0xffffffff,
527         0x000008f8, 0x00000018, 0xffffffff,
528         0x000008fc, 0x00000000, 0xffffffff,
529         0x000008f8, 0x00000019, 0xffffffff,
530         0x000008fc, 0x00000000, 0xffffffff,
531         0x000008f8, 0x0000001a, 0xffffffff,
532         0x000008fc, 0x00000000, 0xffffffff,
533         0x000008f8, 0x0000001b, 0xffffffff,
534         0x000008fc, 0x00000000, 0xffffffff,
535         0x000008f8, 0x00000020, 0xffffffff,
536         0x000008fc, 0xffffffff, 0xffffffff,
537         0x000008f8, 0x00000021, 0xffffffff,
538         0x000008fc, 0xffffffff, 0xffffffff,
539         0x000008f8, 0x00000022, 0xffffffff,
540         0x000008fc, 0xffffffff, 0xffffffff,
541         0x000008f8, 0x00000023, 0xffffffff,
542         0x000008fc, 0xffffffff, 0xffffffff,
543         0x000008f8, 0x00000024, 0xffffffff,
544         0x000008fc, 0xffffffff, 0xffffffff,
545         0x000008f8, 0x00000025, 0xffffffff,
546         0x000008fc, 0xffffffff, 0xffffffff,
547         0x000008f8, 0x00000026, 0xffffffff,
548         0x000008fc, 0xffffffff, 0xffffffff,
549         0x000008f8, 0x00000027, 0xffffffff,
550         0x000008fc, 0xffffffff, 0xffffffff,
551         0x000008f8, 0x00000028, 0xffffffff,
552         0x000008fc, 0xffffffff, 0xffffffff,
553         0x000008f8, 0x00000029, 0xffffffff,
554         0x000008fc, 0xffffffff, 0xffffffff,
555         0x000008f8, 0x0000002a, 0xffffffff,
556         0x000008fc, 0xffffffff, 0xffffffff,
557         0x000008f8, 0x0000002b, 0xffffffff,
558         0x000008fc, 0xffffffff, 0xffffffff
559 };
560 #define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
561
562 static const u32 caicos_mgcg_default[] =
563 {
564         0x0000802c, 0xc0000000, 0xffffffff,
565         0x00005448, 0x00000100, 0xffffffff,
566         0x000055e4, 0x00600100, 0xffffffff,
567         0x0000160c, 0x00000100, 0xffffffff,
568         0x0000c164, 0x00000100, 0xffffffff,
569         0x00008a18, 0x00000100, 0xffffffff,
570         0x0000897c, 0x06000100, 0xffffffff,
571         0x00008b28, 0x00000100, 0xffffffff,
572         0x00009144, 0x00000100, 0xffffffff,
573         0x00009a60, 0x00000100, 0xffffffff,
574         0x00009868, 0x00000100, 0xffffffff,
575         0x00008d58, 0x00000100, 0xffffffff,
576         0x00009510, 0x00000100, 0xffffffff,
577         0x0000949c, 0x00000100, 0xffffffff,
578         0x00009654, 0x00000100, 0xffffffff,
579         0x00009030, 0x00000100, 0xffffffff,
580         0x00009034, 0x00000100, 0xffffffff,
581         0x00009038, 0x00000100, 0xffffffff,
582         0x0000903c, 0x00000100, 0xffffffff,
583         0x00009040, 0x00000100, 0xffffffff,
584         0x0000a200, 0x00000100, 0xffffffff,
585         0x0000a204, 0x00000100, 0xffffffff,
586         0x0000a208, 0x00000100, 0xffffffff,
587         0x0000a20c, 0x00000100, 0xffffffff,
588         0x0000977c, 0x00000100, 0xffffffff,
589         0x00003f80, 0x00000100, 0xffffffff,
590         0x0000a210, 0x00000100, 0xffffffff,
591         0x0000a214, 0x00000100, 0xffffffff,
592         0x000004d8, 0x00000100, 0xffffffff,
593         0x00009784, 0x00000100, 0xffffffff,
594         0x00009698, 0x00000100, 0xffffffff,
595         0x000004d4, 0x00000200, 0xffffffff,
596         0x000004d0, 0x00000000, 0xffffffff,
597         0x000030cc, 0x00000100, 0xffffffff,
598         0x0000d0c0, 0xff000100, 0xffffffff,
599         0x0000915c, 0x00010000, 0xffffffff,
600         0x00009160, 0x00030002, 0xffffffff,
601         0x00009164, 0x00050004, 0xffffffff,
602         0x00009168, 0x00070006, 0xffffffff,
603         0x00009178, 0x00070000, 0xffffffff,
604         0x0000917c, 0x00030002, 0xffffffff,
605         0x00009180, 0x00050004, 0xffffffff,
606         0x0000918c, 0x00010006, 0xffffffff,
607         0x00009190, 0x00090008, 0xffffffff,
608         0x00009194, 0x00070000, 0xffffffff,
609         0x00009198, 0x00030002, 0xffffffff,
610         0x0000919c, 0x00050004, 0xffffffff,
611         0x000091a8, 0x00010006, 0xffffffff,
612         0x000091ac, 0x00090008, 0xffffffff,
613         0x000091e8, 0x00000000, 0xffffffff,
614         0x00009294, 0x00000000, 0xffffffff,
615         0x000008f8, 0x00000010, 0xffffffff,
616         0x000008fc, 0x00000000, 0xffffffff,
617         0x000008f8, 0x00000011, 0xffffffff,
618         0x000008fc, 0x00000000, 0xffffffff,
619         0x000008f8, 0x00000012, 0xffffffff,
620         0x000008fc, 0x00000000, 0xffffffff,
621         0x000008f8, 0x00000013, 0xffffffff,
622         0x000008fc, 0x00000000, 0xffffffff,
623         0x000008f8, 0x00000014, 0xffffffff,
624         0x000008fc, 0x00000000, 0xffffffff,
625         0x000008f8, 0x00000015, 0xffffffff,
626         0x000008fc, 0x00000000, 0xffffffff,
627         0x000008f8, 0x00000016, 0xffffffff,
628         0x000008fc, 0x00000000, 0xffffffff,
629         0x000008f8, 0x00000017, 0xffffffff,
630         0x000008fc, 0x00000000, 0xffffffff,
631         0x000008f8, 0x00000018, 0xffffffff,
632         0x000008fc, 0x00000000, 0xffffffff,
633         0x000008f8, 0x00000019, 0xffffffff,
634         0x000008fc, 0x00000000, 0xffffffff,
635         0x000008f8, 0x0000001a, 0xffffffff,
636         0x000008fc, 0x00000000, 0xffffffff,
637         0x000008f8, 0x0000001b, 0xffffffff,
638         0x000008fc, 0x00000000, 0xffffffff
639 };
640 #define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
641
642 static const u32 caicos_mgcg_disable[] =
643 {
644         0x0000802c, 0xc0000000, 0xffffffff,
645         0x000008f8, 0x00000000, 0xffffffff,
646         0x000008fc, 0xffffffff, 0xffffffff,
647         0x000008f8, 0x00000001, 0xffffffff,
648         0x000008fc, 0xffffffff, 0xffffffff,
649         0x000008f8, 0x00000002, 0xffffffff,
650         0x000008fc, 0xffffffff, 0xffffffff,
651         0x000008f8, 0x00000003, 0xffffffff,
652         0x000008fc, 0xffffffff, 0xffffffff,
653         0x00009150, 0x00600000, 0xffffffff
654 };
655 #define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
656
657 static const u32 caicos_mgcg_enable[] =
658 {
659         0x0000802c, 0xc0000000, 0xffffffff,
660         0x000008f8, 0x00000000, 0xffffffff,
661         0x000008fc, 0x00000000, 0xffffffff,
662         0x000008f8, 0x00000001, 0xffffffff,
663         0x000008fc, 0x00000000, 0xffffffff,
664         0x000008f8, 0x00000002, 0xffffffff,
665         0x000008fc, 0x00000000, 0xffffffff,
666         0x000008f8, 0x00000003, 0xffffffff,
667         0x000008fc, 0x00000000, 0xffffffff,
668         0x00009150, 0x46944040, 0xffffffff
669 };
670 #define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
671
672 //********* TURKS **************//
673 static const u32 turks_cgcg_cgls_default[] =
674 {
675         0x000008f8, 0x00000010, 0xffffffff,
676         0x000008fc, 0x00000000, 0xffffffff,
677         0x000008f8, 0x00000011, 0xffffffff,
678         0x000008fc, 0x00000000, 0xffffffff,
679         0x000008f8, 0x00000012, 0xffffffff,
680         0x000008fc, 0x00000000, 0xffffffff,
681         0x000008f8, 0x00000013, 0xffffffff,
682         0x000008fc, 0x00000000, 0xffffffff,
683         0x000008f8, 0x00000014, 0xffffffff,
684         0x000008fc, 0x00000000, 0xffffffff,
685         0x000008f8, 0x00000015, 0xffffffff,
686         0x000008fc, 0x00000000, 0xffffffff,
687         0x000008f8, 0x00000016, 0xffffffff,
688         0x000008fc, 0x00000000, 0xffffffff,
689         0x000008f8, 0x00000017, 0xffffffff,
690         0x000008fc, 0x00000000, 0xffffffff,
691         0x000008f8, 0x00000018, 0xffffffff,
692         0x000008fc, 0x00000000, 0xffffffff,
693         0x000008f8, 0x00000019, 0xffffffff,
694         0x000008fc, 0x00000000, 0xffffffff,
695         0x000008f8, 0x0000001a, 0xffffffff,
696         0x000008fc, 0x00000000, 0xffffffff,
697         0x000008f8, 0x0000001b, 0xffffffff,
698         0x000008fc, 0x00000000, 0xffffffff,
699         0x000008f8, 0x00000020, 0xffffffff,
700         0x000008fc, 0x00000000, 0xffffffff,
701         0x000008f8, 0x00000021, 0xffffffff,
702         0x000008fc, 0x00000000, 0xffffffff,
703         0x000008f8, 0x00000022, 0xffffffff,
704         0x000008fc, 0x00000000, 0xffffffff,
705         0x000008f8, 0x00000023, 0xffffffff,
706         0x000008fc, 0x00000000, 0xffffffff,
707         0x000008f8, 0x00000024, 0xffffffff,
708         0x000008fc, 0x00000000, 0xffffffff,
709         0x000008f8, 0x00000025, 0xffffffff,
710         0x000008fc, 0x00000000, 0xffffffff,
711         0x000008f8, 0x00000026, 0xffffffff,
712         0x000008fc, 0x00000000, 0xffffffff,
713         0x000008f8, 0x00000027, 0xffffffff,
714         0x000008fc, 0x00000000, 0xffffffff,
715         0x000008f8, 0x00000028, 0xffffffff,
716         0x000008fc, 0x00000000, 0xffffffff,
717         0x000008f8, 0x00000029, 0xffffffff,
718         0x000008fc, 0x00000000, 0xffffffff,
719         0x000008f8, 0x0000002a, 0xffffffff,
720         0x000008fc, 0x00000000, 0xffffffff,
721         0x000008f8, 0x0000002b, 0xffffffff,
722         0x000008fc, 0x00000000, 0xffffffff
723 };
724 #define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
725
726 static const u32 turks_cgcg_cgls_disable[] =
727 {
728         0x000008f8, 0x00000010, 0xffffffff,
729         0x000008fc, 0xffffffff, 0xffffffff,
730         0x000008f8, 0x00000011, 0xffffffff,
731         0x000008fc, 0xffffffff, 0xffffffff,
732         0x000008f8, 0x00000012, 0xffffffff,
733         0x000008fc, 0xffffffff, 0xffffffff,
734         0x000008f8, 0x00000013, 0xffffffff,
735         0x000008fc, 0xffffffff, 0xffffffff,
736         0x000008f8, 0x00000014, 0xffffffff,
737         0x000008fc, 0xffffffff, 0xffffffff,
738         0x000008f8, 0x00000015, 0xffffffff,
739         0x000008fc, 0xffffffff, 0xffffffff,
740         0x000008f8, 0x00000016, 0xffffffff,
741         0x000008fc, 0xffffffff, 0xffffffff,
742         0x000008f8, 0x00000017, 0xffffffff,
743         0x000008fc, 0xffffffff, 0xffffffff,
744         0x000008f8, 0x00000018, 0xffffffff,
745         0x000008fc, 0xffffffff, 0xffffffff,
746         0x000008f8, 0x00000019, 0xffffffff,
747         0x000008fc, 0xffffffff, 0xffffffff,
748         0x000008f8, 0x0000001a, 0xffffffff,
749         0x000008fc, 0xffffffff, 0xffffffff,
750         0x000008f8, 0x0000001b, 0xffffffff,
751         0x000008fc, 0xffffffff, 0xffffffff,
752         0x000008f8, 0x00000020, 0xffffffff,
753         0x000008fc, 0x00000000, 0xffffffff,
754         0x000008f8, 0x00000021, 0xffffffff,
755         0x000008fc, 0x00000000, 0xffffffff,
756         0x000008f8, 0x00000022, 0xffffffff,
757         0x000008fc, 0x00000000, 0xffffffff,
758         0x000008f8, 0x00000023, 0xffffffff,
759         0x000008fc, 0x00000000, 0xffffffff,
760         0x000008f8, 0x00000024, 0xffffffff,
761         0x000008fc, 0x00000000, 0xffffffff,
762         0x000008f8, 0x00000025, 0xffffffff,
763         0x000008fc, 0x00000000, 0xffffffff,
764         0x000008f8, 0x00000026, 0xffffffff,
765         0x000008fc, 0x00000000, 0xffffffff,
766         0x000008f8, 0x00000027, 0xffffffff,
767         0x000008fc, 0x00000000, 0xffffffff,
768         0x000008f8, 0x00000028, 0xffffffff,
769         0x000008fc, 0x00000000, 0xffffffff,
770         0x000008f8, 0x00000029, 0xffffffff,
771         0x000008fc, 0x00000000, 0xffffffff,
772         0x000008f8, 0x0000002a, 0xffffffff,
773         0x000008fc, 0x00000000, 0xffffffff,
774         0x000008f8, 0x0000002b, 0xffffffff,
775         0x000008fc, 0x00000000, 0xffffffff,
776         0x00000644, 0x000f7912, 0x001f4180,
777         0x00000644, 0x000f3812, 0x001f4180
778 };
779 #define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
780
781 static const u32 turks_cgcg_cgls_enable[] =
782 {
783         /* 0x0000c124, 0x84180000, 0x00180000, */
784         0x00000644, 0x000f7892, 0x001f4080,
785         0x000008f8, 0x00000010, 0xffffffff,
786         0x000008fc, 0x00000000, 0xffffffff,
787         0x000008f8, 0x00000011, 0xffffffff,
788         0x000008fc, 0x00000000, 0xffffffff,
789         0x000008f8, 0x00000012, 0xffffffff,
790         0x000008fc, 0x00000000, 0xffffffff,
791         0x000008f8, 0x00000013, 0xffffffff,
792         0x000008fc, 0x00000000, 0xffffffff,
793         0x000008f8, 0x00000014, 0xffffffff,
794         0x000008fc, 0x00000000, 0xffffffff,
795         0x000008f8, 0x00000015, 0xffffffff,
796         0x000008fc, 0x00000000, 0xffffffff,
797         0x000008f8, 0x00000016, 0xffffffff,
798         0x000008fc, 0x00000000, 0xffffffff,
799         0x000008f8, 0x00000017, 0xffffffff,
800         0x000008fc, 0x00000000, 0xffffffff,
801         0x000008f8, 0x00000018, 0xffffffff,
802         0x000008fc, 0x00000000, 0xffffffff,
803         0x000008f8, 0x00000019, 0xffffffff,
804         0x000008fc, 0x00000000, 0xffffffff,
805         0x000008f8, 0x0000001a, 0xffffffff,
806         0x000008fc, 0x00000000, 0xffffffff,
807         0x000008f8, 0x0000001b, 0xffffffff,
808         0x000008fc, 0x00000000, 0xffffffff,
809         0x000008f8, 0x00000020, 0xffffffff,
810         0x000008fc, 0xffffffff, 0xffffffff,
811         0x000008f8, 0x00000021, 0xffffffff,
812         0x000008fc, 0xffffffff, 0xffffffff,
813         0x000008f8, 0x00000022, 0xffffffff,
814         0x000008fc, 0xffffffff, 0xffffffff,
815         0x000008f8, 0x00000023, 0xffffffff,
816         0x000008fc, 0xffffffff, 0xffffffff,
817         0x000008f8, 0x00000024, 0xffffffff,
818         0x000008fc, 0xffffffff, 0xffffffff,
819         0x000008f8, 0x00000025, 0xffffffff,
820         0x000008fc, 0xffffffff, 0xffffffff,
821         0x000008f8, 0x00000026, 0xffffffff,
822         0x000008fc, 0xffffffff, 0xffffffff,
823         0x000008f8, 0x00000027, 0xffffffff,
824         0x000008fc, 0xffffffff, 0xffffffff,
825         0x000008f8, 0x00000028, 0xffffffff,
826         0x000008fc, 0xffffffff, 0xffffffff,
827         0x000008f8, 0x00000029, 0xffffffff,
828         0x000008fc, 0xffffffff, 0xffffffff,
829         0x000008f8, 0x0000002a, 0xffffffff,
830         0x000008fc, 0xffffffff, 0xffffffff,
831         0x000008f8, 0x0000002b, 0xffffffff,
832         0x000008fc, 0xffffffff, 0xffffffff
833 };
834 #define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
835
836 // These are the sequences for turks_mgcg_shls
837 static const u32 turks_mgcg_default[] =
838 {
839         0x0000802c, 0xc0000000, 0xffffffff,
840         0x00005448, 0x00000100, 0xffffffff,
841         0x000055e4, 0x00600100, 0xffffffff,
842         0x0000160c, 0x00000100, 0xffffffff,
843         0x0000c164, 0x00000100, 0xffffffff,
844         0x00008a18, 0x00000100, 0xffffffff,
845         0x0000897c, 0x06000100, 0xffffffff,
846         0x00008b28, 0x00000100, 0xffffffff,
847         0x00009144, 0x00000100, 0xffffffff,
848         0x00009a60, 0x00000100, 0xffffffff,
849         0x00009868, 0x00000100, 0xffffffff,
850         0x00008d58, 0x00000100, 0xffffffff,
851         0x00009510, 0x00000100, 0xffffffff,
852         0x0000949c, 0x00000100, 0xffffffff,
853         0x00009654, 0x00000100, 0xffffffff,
854         0x00009030, 0x00000100, 0xffffffff,
855         0x00009034, 0x00000100, 0xffffffff,
856         0x00009038, 0x00000100, 0xffffffff,
857         0x0000903c, 0x00000100, 0xffffffff,
858         0x00009040, 0x00000100, 0xffffffff,
859         0x0000a200, 0x00000100, 0xffffffff,
860         0x0000a204, 0x00000100, 0xffffffff,
861         0x0000a208, 0x00000100, 0xffffffff,
862         0x0000a20c, 0x00000100, 0xffffffff,
863         0x0000977c, 0x00000100, 0xffffffff,
864         0x00003f80, 0x00000100, 0xffffffff,
865         0x0000a210, 0x00000100, 0xffffffff,
866         0x0000a214, 0x00000100, 0xffffffff,
867         0x000004d8, 0x00000100, 0xffffffff,
868         0x00009784, 0x00000100, 0xffffffff,
869         0x00009698, 0x00000100, 0xffffffff,
870         0x000004d4, 0x00000200, 0xffffffff,
871         0x000004d0, 0x00000000, 0xffffffff,
872         0x000030cc, 0x00000100, 0xffffffff,
873         0x0000d0c0, 0x00000100, 0xffffffff,
874         0x0000915c, 0x00010000, 0xffffffff,
875         0x00009160, 0x00030002, 0xffffffff,
876         0x00009164, 0x00050004, 0xffffffff,
877         0x00009168, 0x00070006, 0xffffffff,
878         0x00009178, 0x00070000, 0xffffffff,
879         0x0000917c, 0x00030002, 0xffffffff,
880         0x00009180, 0x00050004, 0xffffffff,
881         0x0000918c, 0x00010006, 0xffffffff,
882         0x00009190, 0x00090008, 0xffffffff,
883         0x00009194, 0x00070000, 0xffffffff,
884         0x00009198, 0x00030002, 0xffffffff,
885         0x0000919c, 0x00050004, 0xffffffff,
886         0x000091a8, 0x00010006, 0xffffffff,
887         0x000091ac, 0x00090008, 0xffffffff,
888         0x000091b0, 0x00070000, 0xffffffff,
889         0x000091b4, 0x00030002, 0xffffffff,
890         0x000091b8, 0x00050004, 0xffffffff,
891         0x000091c4, 0x00010006, 0xffffffff,
892         0x000091c8, 0x00090008, 0xffffffff,
893         0x000091cc, 0x00070000, 0xffffffff,
894         0x000091d0, 0x00030002, 0xffffffff,
895         0x000091d4, 0x00050004, 0xffffffff,
896         0x000091e0, 0x00010006, 0xffffffff,
897         0x000091e4, 0x00090008, 0xffffffff,
898         0x000091e8, 0x00000000, 0xffffffff,
899         0x000091ec, 0x00070000, 0xffffffff,
900         0x000091f0, 0x00030002, 0xffffffff,
901         0x000091f4, 0x00050004, 0xffffffff,
902         0x00009200, 0x00010006, 0xffffffff,
903         0x00009204, 0x00090008, 0xffffffff,
904         0x00009208, 0x00070000, 0xffffffff,
905         0x0000920c, 0x00030002, 0xffffffff,
906         0x00009210, 0x00050004, 0xffffffff,
907         0x0000921c, 0x00010006, 0xffffffff,
908         0x00009220, 0x00090008, 0xffffffff,
909         0x00009294, 0x00000000, 0xffffffff,
910         0x000008f8, 0x00000010, 0xffffffff,
911         0x000008fc, 0x00000000, 0xffffffff,
912         0x000008f8, 0x00000011, 0xffffffff,
913         0x000008fc, 0x00000000, 0xffffffff,
914         0x000008f8, 0x00000012, 0xffffffff,
915         0x000008fc, 0x00000000, 0xffffffff,
916         0x000008f8, 0x00000013, 0xffffffff,
917         0x000008fc, 0x00000000, 0xffffffff,
918         0x000008f8, 0x00000014, 0xffffffff,
919         0x000008fc, 0x00000000, 0xffffffff,
920         0x000008f8, 0x00000015, 0xffffffff,
921         0x000008fc, 0x00000000, 0xffffffff,
922         0x000008f8, 0x00000016, 0xffffffff,
923         0x000008fc, 0x00000000, 0xffffffff,
924         0x000008f8, 0x00000017, 0xffffffff,
925         0x000008fc, 0x00000000, 0xffffffff,
926         0x000008f8, 0x00000018, 0xffffffff,
927         0x000008fc, 0x00000000, 0xffffffff,
928         0x000008f8, 0x00000019, 0xffffffff,
929         0x000008fc, 0x00000000, 0xffffffff,
930         0x000008f8, 0x0000001a, 0xffffffff,
931         0x000008fc, 0x00000000, 0xffffffff,
932         0x000008f8, 0x0000001b, 0xffffffff,
933         0x000008fc, 0x00000000, 0xffffffff
934 };
935 #define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
936
937 static const u32 turks_mgcg_disable[] =
938 {
939         0x0000802c, 0xc0000000, 0xffffffff,
940         0x000008f8, 0x00000000, 0xffffffff,
941         0x000008fc, 0xffffffff, 0xffffffff,
942         0x000008f8, 0x00000001, 0xffffffff,
943         0x000008fc, 0xffffffff, 0xffffffff,
944         0x000008f8, 0x00000002, 0xffffffff,
945         0x000008fc, 0xffffffff, 0xffffffff,
946         0x000008f8, 0x00000003, 0xffffffff,
947         0x000008fc, 0xffffffff, 0xffffffff,
948         0x00009150, 0x00600000, 0xffffffff
949 };
950 #define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
951
952 static const u32 turks_mgcg_enable[] =
953 {
954         0x0000802c, 0xc0000000, 0xffffffff,
955         0x000008f8, 0x00000000, 0xffffffff,
956         0x000008fc, 0x00000000, 0xffffffff,
957         0x000008f8, 0x00000001, 0xffffffff,
958         0x000008fc, 0x00000000, 0xffffffff,
959         0x000008f8, 0x00000002, 0xffffffff,
960         0x000008fc, 0x00000000, 0xffffffff,
961         0x000008f8, 0x00000003, 0xffffffff,
962         0x000008fc, 0x00000000, 0xffffffff,
963         0x00009150, 0x6e944000, 0xffffffff
964 };
965 #define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
966
967 #endif
968
969 #ifndef BTC_SYSLS_SEQUENCE
970 #define BTC_SYSLS_SEQUENCE  100
971
972
973 //********* BARTS **************//
974 static const u32 barts_sysls_default[] =
975 {
976         /* Register,   Value,     Mask bits */
977         0x000055e8, 0x00000000, 0xffffffff,
978         0x0000d0bc, 0x00000000, 0xffffffff,
979         0x000015c0, 0x000c1401, 0xffffffff,
980         0x0000264c, 0x000c0400, 0xffffffff,
981         0x00002648, 0x000c0400, 0xffffffff,
982         0x00002650, 0x000c0400, 0xffffffff,
983         0x000020b8, 0x000c0400, 0xffffffff,
984         0x000020bc, 0x000c0400, 0xffffffff,
985         0x000020c0, 0x000c0c80, 0xffffffff,
986         0x0000f4a0, 0x000000c0, 0xffffffff,
987         0x0000f4a4, 0x00680fff, 0xffffffff,
988         0x000004c8, 0x00000001, 0xffffffff,
989         0x000064ec, 0x00000000, 0xffffffff,
990         0x00000c7c, 0x00000000, 0xffffffff,
991         0x00006dfc, 0x00000000, 0xffffffff
992 };
993 #define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
994
995 static const u32 barts_sysls_disable[] =
996 {
997         0x000055e8, 0x00000000, 0xffffffff,
998         0x0000d0bc, 0x00000000, 0xffffffff,
999         0x000015c0, 0x00041401, 0xffffffff,
1000         0x0000264c, 0x00040400, 0xffffffff,
1001         0x00002648, 0x00040400, 0xffffffff,
1002         0x00002650, 0x00040400, 0xffffffff,
1003         0x000020b8, 0x00040400, 0xffffffff,
1004         0x000020bc, 0x00040400, 0xffffffff,
1005         0x000020c0, 0x00040c80, 0xffffffff,
1006         0x0000f4a0, 0x000000c0, 0xffffffff,
1007         0x0000f4a4, 0x00680000, 0xffffffff,
1008         0x000004c8, 0x00000001, 0xffffffff,
1009         0x000064ec, 0x00007ffd, 0xffffffff,
1010         0x00000c7c, 0x0000ff00, 0xffffffff,
1011         0x00006dfc, 0x0000007f, 0xffffffff
1012 };
1013 #define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
1014
1015 static const u32 barts_sysls_enable[] =
1016 {
1017         0x000055e8, 0x00000001, 0xffffffff,
1018         0x0000d0bc, 0x00000100, 0xffffffff,
1019         0x000015c0, 0x000c1401, 0xffffffff,
1020         0x0000264c, 0x000c0400, 0xffffffff,
1021         0x00002648, 0x000c0400, 0xffffffff,
1022         0x00002650, 0x000c0400, 0xffffffff,
1023         0x000020b8, 0x000c0400, 0xffffffff,
1024         0x000020bc, 0x000c0400, 0xffffffff,
1025         0x000020c0, 0x000c0c80, 0xffffffff,
1026         0x0000f4a0, 0x000000c0, 0xffffffff,
1027         0x0000f4a4, 0x00680fff, 0xffffffff,
1028         0x000004c8, 0x00000000, 0xffffffff,
1029         0x000064ec, 0x00000000, 0xffffffff,
1030         0x00000c7c, 0x00000000, 0xffffffff,
1031         0x00006dfc, 0x00000000, 0xffffffff
1032 };
1033 #define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
1034
1035 //********* CAICOS **************//
1036 static const u32 caicos_sysls_default[] =
1037 {
1038         0x000055e8, 0x00000000, 0xffffffff,
1039         0x0000d0bc, 0x00000000, 0xffffffff,
1040         0x000015c0, 0x000c1401, 0xffffffff,
1041         0x0000264c, 0x000c0400, 0xffffffff,
1042         0x00002648, 0x000c0400, 0xffffffff,
1043         0x00002650, 0x000c0400, 0xffffffff,
1044         0x000020b8, 0x000c0400, 0xffffffff,
1045         0x000020bc, 0x000c0400, 0xffffffff,
1046         0x0000f4a0, 0x000000c0, 0xffffffff,
1047         0x0000f4a4, 0x00680fff, 0xffffffff,
1048         0x000004c8, 0x00000001, 0xffffffff,
1049         0x000064ec, 0x00000000, 0xffffffff,
1050         0x00000c7c, 0x00000000, 0xffffffff,
1051         0x00006dfc, 0x00000000, 0xffffffff
1052 };
1053 #define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
1054
1055 static const u32 caicos_sysls_disable[] =
1056 {
1057         0x000055e8, 0x00000000, 0xffffffff,
1058         0x0000d0bc, 0x00000000, 0xffffffff,
1059         0x000015c0, 0x00041401, 0xffffffff,
1060         0x0000264c, 0x00040400, 0xffffffff,
1061         0x00002648, 0x00040400, 0xffffffff,
1062         0x00002650, 0x00040400, 0xffffffff,
1063         0x000020b8, 0x00040400, 0xffffffff,
1064         0x000020bc, 0x00040400, 0xffffffff,
1065         0x0000f4a0, 0x000000c0, 0xffffffff,
1066         0x0000f4a4, 0x00680000, 0xffffffff,
1067         0x000004c8, 0x00000001, 0xffffffff,
1068         0x000064ec, 0x00007ffd, 0xffffffff,
1069         0x00000c7c, 0x0000ff00, 0xffffffff,
1070         0x00006dfc, 0x0000007f, 0xffffffff
1071 };
1072 #define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
1073
1074 static const u32 caicos_sysls_enable[] =
1075 {
1076         0x000055e8, 0x00000001, 0xffffffff,
1077         0x0000d0bc, 0x00000100, 0xffffffff,
1078         0x000015c0, 0x000c1401, 0xffffffff,
1079         0x0000264c, 0x000c0400, 0xffffffff,
1080         0x00002648, 0x000c0400, 0xffffffff,
1081         0x00002650, 0x000c0400, 0xffffffff,
1082         0x000020b8, 0x000c0400, 0xffffffff,
1083         0x000020bc, 0x000c0400, 0xffffffff,
1084         0x0000f4a0, 0x000000c0, 0xffffffff,
1085         0x0000f4a4, 0x00680fff, 0xffffffff,
1086         0x000064ec, 0x00000000, 0xffffffff,
1087         0x00000c7c, 0x00000000, 0xffffffff,
1088         0x00006dfc, 0x00000000, 0xffffffff,
1089         0x000004c8, 0x00000000, 0xffffffff
1090 };
1091 #define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
1092
1093 //********* TURKS **************//
1094 static const u32 turks_sysls_default[] =
1095 {
1096         0x000055e8, 0x00000000, 0xffffffff,
1097         0x0000d0bc, 0x00000000, 0xffffffff,
1098         0x000015c0, 0x000c1401, 0xffffffff,
1099         0x0000264c, 0x000c0400, 0xffffffff,
1100         0x00002648, 0x000c0400, 0xffffffff,
1101         0x00002650, 0x000c0400, 0xffffffff,
1102         0x000020b8, 0x000c0400, 0xffffffff,
1103         0x000020bc, 0x000c0400, 0xffffffff,
1104         0x000020c0, 0x000c0c80, 0xffffffff,
1105         0x0000f4a0, 0x000000c0, 0xffffffff,
1106         0x0000f4a4, 0x00680fff, 0xffffffff,
1107         0x000004c8, 0x00000001, 0xffffffff,
1108         0x000064ec, 0x00000000, 0xffffffff,
1109         0x00000c7c, 0x00000000, 0xffffffff,
1110         0x00006dfc, 0x00000000, 0xffffffff
1111 };
1112 #define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
1113
1114 static const u32 turks_sysls_disable[] =
1115 {
1116         0x000055e8, 0x00000000, 0xffffffff,
1117         0x0000d0bc, 0x00000000, 0xffffffff,
1118         0x000015c0, 0x00041401, 0xffffffff,
1119         0x0000264c, 0x00040400, 0xffffffff,
1120         0x00002648, 0x00040400, 0xffffffff,
1121         0x00002650, 0x00040400, 0xffffffff,
1122         0x000020b8, 0x00040400, 0xffffffff,
1123         0x000020bc, 0x00040400, 0xffffffff,
1124         0x000020c0, 0x00040c80, 0xffffffff,
1125         0x0000f4a0, 0x000000c0, 0xffffffff,
1126         0x0000f4a4, 0x00680000, 0xffffffff,
1127         0x000004c8, 0x00000001, 0xffffffff,
1128         0x000064ec, 0x00007ffd, 0xffffffff,
1129         0x00000c7c, 0x0000ff00, 0xffffffff,
1130         0x00006dfc, 0x0000007f, 0xffffffff
1131 };
1132 #define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
1133
1134 static const u32 turks_sysls_enable[] =
1135 {
1136         0x000055e8, 0x00000001, 0xffffffff,
1137         0x0000d0bc, 0x00000100, 0xffffffff,
1138         0x000015c0, 0x000c1401, 0xffffffff,
1139         0x0000264c, 0x000c0400, 0xffffffff,
1140         0x00002648, 0x000c0400, 0xffffffff,
1141         0x00002650, 0x000c0400, 0xffffffff,
1142         0x000020b8, 0x000c0400, 0xffffffff,
1143         0x000020bc, 0x000c0400, 0xffffffff,
1144         0x000020c0, 0x000c0c80, 0xffffffff,
1145         0x0000f4a0, 0x000000c0, 0xffffffff,
1146         0x0000f4a4, 0x00680fff, 0xffffffff,
1147         0x000004c8, 0x00000000, 0xffffffff,
1148         0x000064ec, 0x00000000, 0xffffffff,
1149         0x00000c7c, 0x00000000, 0xffffffff,
1150         0x00006dfc, 0x00000000, 0xffffffff
1151 };
1152 #define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
1153
1154 #endif
1155
1156 u32 btc_valid_sclk[40] =
1157 {
1158         5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
1159         55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
1160         105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
1161         155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
1162 };
1163
1164 static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = {
1165         { 10000, 30000, RADEON_SCLK_UP },
1166         { 15000, 30000, RADEON_SCLK_UP },
1167         { 20000, 30000, RADEON_SCLK_UP },
1168         { 25000, 30000, RADEON_SCLK_UP }
1169 };
1170
1171 void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table,
1172                                                      u32 *max_clock)
1173 {
1174         u32 i, clock = 0;
1175
1176         if ((table == NULL) || (table->count == 0)) {
1177                 *max_clock = clock;
1178                 return;
1179         }
1180
1181         for (i = 0; i < table->count; i++) {
1182                 if (clock < table->entries[i].clk)
1183                         clock = table->entries[i].clk;
1184         }
1185         *max_clock = clock;
1186 }
1187
1188 void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
1189                                         u32 clock, u16 max_voltage, u16 *voltage)
1190 {
1191         u32 i;
1192
1193         if ((table == NULL) || (table->count == 0))
1194                 return;
1195
1196         for (i= 0; i < table->count; i++) {
1197                 if (clock <= table->entries[i].clk) {
1198                         if (*voltage < table->entries[i].v)
1199                                 *voltage = (u16)((table->entries[i].v < max_voltage) ?
1200                                                   table->entries[i].v : max_voltage);
1201                         return;
1202                 }
1203         }
1204
1205         *voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
1206 }
1207
1208 static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
1209                                 u32 max_clock, u32 requested_clock)
1210 {
1211         unsigned int i;
1212
1213         if ((clocks == NULL) || (clocks->count == 0))
1214                 return (requested_clock < max_clock) ? requested_clock : max_clock;
1215
1216         for (i = 0; i < clocks->count; i++) {
1217                 if (clocks->values[i] >= requested_clock)
1218                         return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
1219         }
1220
1221         return (clocks->values[clocks->count - 1] < max_clock) ?
1222                 clocks->values[clocks->count - 1] : max_clock;
1223 }
1224
1225 static u32 btc_get_valid_mclk(struct radeon_device *rdev,
1226                               u32 max_mclk, u32 requested_mclk)
1227 {
1228         return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
1229                                     max_mclk, requested_mclk);
1230 }
1231
1232 static u32 btc_get_valid_sclk(struct radeon_device *rdev,
1233                               u32 max_sclk, u32 requested_sclk)
1234 {
1235         return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
1236                                     max_sclk, requested_sclk);
1237 }
1238
1239 void btc_skip_blacklist_clocks(struct radeon_device *rdev,
1240                                const u32 max_sclk, const u32 max_mclk,
1241                                u32 *sclk, u32 *mclk)
1242 {
1243         int i, num_blacklist_clocks;
1244
1245         if ((sclk == NULL) || (mclk == NULL))
1246                 return;
1247
1248         num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
1249
1250         for (i = 0; i < num_blacklist_clocks; i++) {
1251                 if ((btc_blacklist_clocks[i].sclk == *sclk) &&
1252                     (btc_blacklist_clocks[i].mclk == *mclk))
1253                         break;
1254         }
1255
1256         if (i < num_blacklist_clocks) {
1257                 if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
1258                         *sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
1259
1260                         if (*sclk < max_sclk)
1261                                 btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
1262                 }
1263         }
1264 }
1265
1266 void btc_adjust_clock_combinations(struct radeon_device *rdev,
1267                                    const struct radeon_clock_and_voltage_limits *max_limits,
1268                                    struct rv7xx_pl *pl)
1269 {
1270
1271         if ((pl->mclk == 0) || (pl->sclk == 0))
1272                 return;
1273
1274         if (pl->mclk == pl->sclk)
1275                 return;
1276
1277         if (pl->mclk > pl->sclk) {
1278                 if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
1279                         pl->sclk = btc_get_valid_sclk(rdev,
1280                                                       max_limits->sclk,
1281                                                       (pl->mclk +
1282                                                        (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
1283                                                       rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
1284         } else {
1285                 if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
1286                         pl->mclk = btc_get_valid_mclk(rdev,
1287                                                       max_limits->mclk,
1288                                                       pl->sclk -
1289                                                       rdev->pm.dpm.dyn_state.sclk_mclk_delta);
1290         }
1291 }
1292
1293 static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
1294 {
1295         unsigned int i;
1296
1297         for (i = 0; i < table->count; i++) {
1298                 if (voltage <= table->entries[i].value)
1299                         return table->entries[i].value;
1300         }
1301
1302         return table->entries[table->count - 1].value;
1303 }
1304
1305 void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
1306                                    u16 max_vddc, u16 max_vddci,
1307                                    u16 *vddc, u16 *vddci)
1308 {
1309         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1310         u16 new_voltage;
1311
1312         if ((0 == *vddc) || (0 == *vddci))
1313                 return;
1314
1315         if (*vddc > *vddci) {
1316                 if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1317                         new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
1318                                                        (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1319                         *vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
1320                 }
1321         } else {
1322                 if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1323                         new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
1324                                                        (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1325                         *vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
1326                 }
1327         }
1328 }
1329
1330 static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
1331                                              bool enable)
1332 {
1333         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1334         u32 tmp, bif;
1335
1336         tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
1337         if (enable) {
1338                 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
1339                     (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1340                         if (!pi->boot_in_gen2) {
1341                                 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1342                                 bif |= CG_CLIENT_REQ(0xd);
1343                                 WREG32(CG_BIF_REQ_AND_RSP, bif);
1344
1345                                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1346                                 tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
1347                                 tmp |= LC_GEN2_EN_STRAP;
1348
1349                                 tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
1350                                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1351                                 udelay(10);
1352                                 tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
1353                                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1354                         }
1355                 }
1356         } else {
1357                 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
1358                     (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1359                         if (!pi->boot_in_gen2) {
1360                                 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1361                                 bif |= CG_CLIENT_REQ(0xd);
1362                                 WREG32(CG_BIF_REQ_AND_RSP, bif);
1363
1364                                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1365                                 tmp &= ~LC_GEN2_EN_STRAP;
1366                         }
1367                         WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1368                 }
1369         }
1370 }
1371
1372 static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
1373                                          bool enable)
1374 {
1375         btc_enable_bif_dynamic_pcie_gen2(rdev, enable);
1376
1377         if (enable)
1378                 WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
1379         else
1380                 WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
1381 }
1382
1383 static int btc_disable_ulv(struct radeon_device *rdev)
1384 {
1385         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1386
1387         if (eg_pi->ulv.supported) {
1388                 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK)
1389                         return -EINVAL;
1390         }
1391         return 0;
1392 }
1393
1394 static int btc_populate_ulv_state(struct radeon_device *rdev,
1395                                   RV770_SMC_STATETABLE *table)
1396 {
1397         int ret = -EINVAL;
1398         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1399         struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1400
1401         if (ulv_pl->vddc) {
1402                 ret = cypress_convert_power_level_to_smc(rdev,
1403                                                          ulv_pl,
1404                                                          &table->ULVState.levels[0],
1405                                                          PPSMC_DISPLAY_WATERMARK_LOW);
1406                 if (ret == 0) {
1407                         table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
1408                         table->ULVState.levels[0].ACIndex = 1;
1409
1410                         table->ULVState.levels[1] = table->ULVState.levels[0];
1411                         table->ULVState.levels[2] = table->ULVState.levels[0];
1412
1413                         table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC;
1414
1415                         WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT);
1416                         WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT);
1417                 }
1418         }
1419
1420         return ret;
1421 }
1422
1423 static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
1424                                        RV770_SMC_STATETABLE *table)
1425 {
1426         int ret = cypress_populate_smc_acpi_state(rdev, table);
1427
1428         if (ret == 0) {
1429                 table->ACPIState.levels[0].ACIndex = 0;
1430                 table->ACPIState.levels[1].ACIndex = 0;
1431                 table->ACPIState.levels[2].ACIndex = 0;
1432         }
1433
1434         return ret;
1435 }
1436
1437 void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
1438                                   const u32 *sequence, u32 count)
1439 {
1440         u32 i, length = count * 3;
1441         u32 tmp;
1442
1443         for (i = 0; i < length; i+=3) {
1444                 tmp = RREG32(sequence[i]);
1445                 tmp &= ~sequence[i+2];
1446                 tmp |= sequence[i+1] & sequence[i+2];
1447                 WREG32(sequence[i], tmp);
1448         }
1449 }
1450
1451 static void btc_cg_clock_gating_default(struct radeon_device *rdev)
1452 {
1453         u32 count;
1454         const u32 *p = NULL;
1455
1456         if (rdev->family == CHIP_BARTS) {
1457                 p = (const u32 *)&barts_cgcg_cgls_default;
1458                 count = BARTS_CGCG_CGLS_DEFAULT_LENGTH;
1459         } else if (rdev->family == CHIP_TURKS) {
1460                 p = (const u32 *)&turks_cgcg_cgls_default;
1461                 count = TURKS_CGCG_CGLS_DEFAULT_LENGTH;
1462         } else if (rdev->family == CHIP_CAICOS) {
1463                 p = (const u32 *)&caicos_cgcg_cgls_default;
1464                 count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH;
1465         } else
1466                 return;
1467
1468         btc_program_mgcg_hw_sequence(rdev, p, count);
1469 }
1470
1471 static void btc_cg_clock_gating_enable(struct radeon_device *rdev,
1472                                        bool enable)
1473 {
1474         u32 count;
1475         const u32 *p = NULL;
1476
1477         if (enable) {
1478                 if (rdev->family == CHIP_BARTS) {
1479                         p = (const u32 *)&barts_cgcg_cgls_enable;
1480                         count = BARTS_CGCG_CGLS_ENABLE_LENGTH;
1481                 } else if (rdev->family == CHIP_TURKS) {
1482                         p = (const u32 *)&turks_cgcg_cgls_enable;
1483                         count = TURKS_CGCG_CGLS_ENABLE_LENGTH;
1484                 } else if (rdev->family == CHIP_CAICOS) {
1485                         p = (const u32 *)&caicos_cgcg_cgls_enable;
1486                         count = CAICOS_CGCG_CGLS_ENABLE_LENGTH;
1487                 } else
1488                         return;
1489         } else {
1490                 if (rdev->family == CHIP_BARTS) {
1491                         p = (const u32 *)&barts_cgcg_cgls_disable;
1492                         count = BARTS_CGCG_CGLS_DISABLE_LENGTH;
1493                 } else if (rdev->family == CHIP_TURKS) {
1494                         p = (const u32 *)&turks_cgcg_cgls_disable;
1495                         count = TURKS_CGCG_CGLS_DISABLE_LENGTH;
1496                 } else if (rdev->family == CHIP_CAICOS) {
1497                         p = (const u32 *)&caicos_cgcg_cgls_disable;
1498                         count = CAICOS_CGCG_CGLS_DISABLE_LENGTH;
1499                 } else
1500                         return;
1501         }
1502
1503         btc_program_mgcg_hw_sequence(rdev, p, count);
1504 }
1505
1506 static void btc_mg_clock_gating_default(struct radeon_device *rdev)
1507 {
1508         u32 count;
1509         const u32 *p = NULL;
1510
1511         if (rdev->family == CHIP_BARTS) {
1512                 p = (const u32 *)&barts_mgcg_default;
1513                 count = BARTS_MGCG_DEFAULT_LENGTH;
1514         } else if (rdev->family == CHIP_TURKS) {
1515                 p = (const u32 *)&turks_mgcg_default;
1516                 count = TURKS_MGCG_DEFAULT_LENGTH;
1517         } else if (rdev->family == CHIP_CAICOS) {
1518                 p = (const u32 *)&caicos_mgcg_default;
1519                 count = CAICOS_MGCG_DEFAULT_LENGTH;
1520         } else
1521                 return;
1522
1523         btc_program_mgcg_hw_sequence(rdev, p, count);
1524 }
1525
1526 static void btc_mg_clock_gating_enable(struct radeon_device *rdev,
1527                                        bool enable)
1528 {
1529         u32 count;
1530         const u32 *p = NULL;
1531
1532         if (enable) {
1533                 if (rdev->family == CHIP_BARTS) {
1534                         p = (const u32 *)&barts_mgcg_enable;
1535                         count = BARTS_MGCG_ENABLE_LENGTH;
1536                 } else if (rdev->family == CHIP_TURKS) {
1537                         p = (const u32 *)&turks_mgcg_enable;
1538                         count = TURKS_MGCG_ENABLE_LENGTH;
1539                 } else if (rdev->family == CHIP_CAICOS) {
1540                         p = (const u32 *)&caicos_mgcg_enable;
1541                         count = CAICOS_MGCG_ENABLE_LENGTH;
1542                 } else
1543                         return;
1544         } else {
1545                 if (rdev->family == CHIP_BARTS) {
1546                         p = (const u32 *)&barts_mgcg_disable[0];
1547                         count = BARTS_MGCG_DISABLE_LENGTH;
1548                 } else if (rdev->family == CHIP_TURKS) {
1549                         p = (const u32 *)&turks_mgcg_disable[0];
1550                         count = TURKS_MGCG_DISABLE_LENGTH;
1551                 } else if (rdev->family == CHIP_CAICOS) {
1552                         p = (const u32 *)&caicos_mgcg_disable[0];
1553                         count = CAICOS_MGCG_DISABLE_LENGTH;
1554                 } else
1555                         return;
1556         }
1557
1558         btc_program_mgcg_hw_sequence(rdev, p, count);
1559 }
1560
1561 static void btc_ls_clock_gating_default(struct radeon_device *rdev)
1562 {
1563         u32 count;
1564         const u32 *p = NULL;
1565
1566         if (rdev->family == CHIP_BARTS) {
1567                 p = (const u32 *)&barts_sysls_default;
1568                 count = BARTS_SYSLS_DEFAULT_LENGTH;
1569         } else if (rdev->family == CHIP_TURKS) {
1570                 p = (const u32 *)&turks_sysls_default;
1571                 count = TURKS_SYSLS_DEFAULT_LENGTH;
1572         } else if (rdev->family == CHIP_CAICOS) {
1573                 p = (const u32 *)&caicos_sysls_default;
1574                 count = CAICOS_SYSLS_DEFAULT_LENGTH;
1575         } else
1576                 return;
1577
1578         btc_program_mgcg_hw_sequence(rdev, p, count);
1579 }
1580
1581 static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
1582                                        bool enable)
1583 {
1584         u32 count;
1585         const u32 *p = NULL;
1586
1587         if (enable) {
1588                 if (rdev->family == CHIP_BARTS) {
1589                         p = (const u32 *)&barts_sysls_enable;
1590                         count = BARTS_SYSLS_ENABLE_LENGTH;
1591                 } else if (rdev->family == CHIP_TURKS) {
1592                         p = (const u32 *)&turks_sysls_enable;
1593                         count = TURKS_SYSLS_ENABLE_LENGTH;
1594                 } else if (rdev->family == CHIP_CAICOS) {
1595                         p = (const u32 *)&caicos_sysls_enable;
1596                         count = CAICOS_SYSLS_ENABLE_LENGTH;
1597                 } else
1598                         return;
1599         } else {
1600                 if (rdev->family == CHIP_BARTS) {
1601                         p = (const u32 *)&barts_sysls_disable;
1602                         count = BARTS_SYSLS_DISABLE_LENGTH;
1603                 } else if (rdev->family == CHIP_TURKS) {
1604                         p = (const u32 *)&turks_sysls_disable;
1605                         count = TURKS_SYSLS_DISABLE_LENGTH;
1606                 } else if (rdev->family == CHIP_CAICOS) {
1607                         p = (const u32 *)&caicos_sysls_disable;
1608                         count = CAICOS_SYSLS_DISABLE_LENGTH;
1609                 } else
1610                         return;
1611         }
1612
1613         btc_program_mgcg_hw_sequence(rdev, p, count);
1614 }
1615
1616 bool btc_dpm_enabled(struct radeon_device *rdev)
1617 {
1618         if (rv770_is_smc_running(rdev))
1619                 return true;
1620         else
1621                 return false;
1622 }
1623
1624 static int btc_init_smc_table(struct radeon_device *rdev,
1625                               struct radeon_ps *radeon_boot_state)
1626 {
1627         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1628         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1629         RV770_SMC_STATETABLE *table = &pi->smc_statetable;
1630         int ret;
1631
1632         memset(table, 0, sizeof(RV770_SMC_STATETABLE));
1633
1634         cypress_populate_smc_voltage_tables(rdev, table);
1635
1636         switch (rdev->pm.int_thermal_type) {
1637         case THERMAL_TYPE_EVERGREEN:
1638         case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
1639                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
1640                 break;
1641         case THERMAL_TYPE_NONE:
1642                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
1643                 break;
1644         default:
1645                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
1646                 break;
1647         }
1648
1649         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
1650                 table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1651
1652         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
1653                 table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
1654
1655         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
1656                 table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1657
1658         if (pi->mem_gddr5)
1659                 table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1660
1661         ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
1662         if (ret)
1663                 return ret;
1664
1665         if (eg_pi->sclk_deep_sleep)
1666                 WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32),
1667                          ~PSKIP_ON_ALLOW_STOP_HI_MASK);
1668
1669         ret = btc_populate_smc_acpi_state(rdev, table);
1670         if (ret)
1671                 return ret;
1672
1673         if (eg_pi->ulv.supported) {
1674                 ret = btc_populate_ulv_state(rdev, table);
1675                 if (ret)
1676                         eg_pi->ulv.supported = false;
1677         }
1678
1679         table->driverState = table->initialState;
1680
1681         return rv770_copy_bytes_to_smc(rdev,
1682                                        pi->state_table_start,
1683                                        (u8 *)table,
1684                                        sizeof(RV770_SMC_STATETABLE),
1685                                        pi->sram_end);
1686 }
1687
1688 static void btc_set_at_for_uvd(struct radeon_device *rdev,
1689                                struct radeon_ps *radeon_new_state)
1690 {
1691         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1692         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1693         int idx = 0;
1694
1695         if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2))
1696                 idx = 1;
1697
1698         if ((idx == 1) && !eg_pi->smu_uvd_hs) {
1699                 pi->rlp = 10;
1700                 pi->rmp = 100;
1701                 pi->lhp = 100;
1702                 pi->lmp = 10;
1703         } else {
1704                 pi->rlp = eg_pi->ats[idx].rlp;
1705                 pi->rmp = eg_pi->ats[idx].rmp;
1706                 pi->lhp = eg_pi->ats[idx].lhp;
1707                 pi->lmp = eg_pi->ats[idx].lmp;
1708         }
1709
1710 }
1711
1712 void btc_notify_uvd_to_smc(struct radeon_device *rdev,
1713                            struct radeon_ps *radeon_new_state)
1714 {
1715         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1716
1717         if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
1718                 rv770_write_smc_soft_register(rdev,
1719                                               RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
1720                 eg_pi->uvd_enabled = true;
1721         } else {
1722                 rv770_write_smc_soft_register(rdev,
1723                                               RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
1724                 eg_pi->uvd_enabled = false;
1725         }
1726 }
1727
1728 int btc_reset_to_default(struct radeon_device *rdev)
1729 {
1730         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
1731                 return -EINVAL;
1732
1733         return 0;
1734 }
1735
1736 static void btc_stop_smc(struct radeon_device *rdev)
1737 {
1738         int i;
1739
1740         for (i = 0; i < rdev->usec_timeout; i++) {
1741                 if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1)
1742                         break;
1743                 udelay(1);
1744         }
1745         udelay(100);
1746
1747         r7xx_stop_smc(rdev);
1748 }
1749
1750 void btc_read_arb_registers(struct radeon_device *rdev)
1751 {
1752         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1753         struct evergreen_arb_registers *arb_registers =
1754                 &eg_pi->bootup_arb_registers;
1755
1756         arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
1757         arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
1758         arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE);
1759         arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
1760 }
1761
1762
1763 static void btc_set_arb0_registers(struct radeon_device *rdev,
1764                                    struct evergreen_arb_registers *arb_registers)
1765 {
1766         u32 val;
1767
1768         WREG32(MC_ARB_DRAM_TIMING,  arb_registers->mc_arb_dram_timing);
1769         WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2);
1770
1771         val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >>
1772                 POWERMODE0_SHIFT;
1773         WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1774
1775         val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >>
1776                 STATE0_SHIFT;
1777         WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1778 }
1779
1780 static void btc_set_boot_state_timing(struct radeon_device *rdev)
1781 {
1782         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1783
1784         if (eg_pi->ulv.supported)
1785                 btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers);
1786 }
1787
1788 static bool btc_is_state_ulv_compatible(struct radeon_device *rdev,
1789                                         struct radeon_ps *radeon_state)
1790 {
1791         struct rv7xx_ps *state = rv770_get_ps(radeon_state);
1792         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1793         struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1794
1795         if (state->low.mclk != ulv_pl->mclk)
1796                 return false;
1797
1798         if (state->low.vddci != ulv_pl->vddci)
1799                 return false;
1800
1801         /* XXX check minclocks, etc. */
1802
1803         return true;
1804 }
1805
1806
1807 static int btc_set_ulv_dram_timing(struct radeon_device *rdev)
1808 {
1809         u32 val;
1810         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1811         struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1812
1813         radeon_atom_set_engine_dram_timings(rdev,
1814                                             ulv_pl->sclk,
1815                                             ulv_pl->mclk);
1816
1817         val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk);
1818         WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1819
1820         val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk);
1821         WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1822
1823         return 0;
1824 }
1825
1826 static int btc_enable_ulv(struct radeon_device *rdev)
1827 {
1828         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK)
1829                 return -EINVAL;
1830
1831         return 0;
1832 }
1833
1834 static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
1835                                                         struct radeon_ps *radeon_new_state)
1836 {
1837         int ret = 0;
1838         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1839
1840         if (eg_pi->ulv.supported) {
1841                 if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
1842                         // Set ARB[0] to reflect the DRAM timing needed for ULV.
1843                         ret = btc_set_ulv_dram_timing(rdev);
1844                         if (ret == 0)
1845                                 ret = btc_enable_ulv(rdev);
1846                 }
1847         }
1848
1849         return ret;
1850 }
1851
1852 static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
1853 {
1854         bool result = true;
1855
1856         switch (in_reg) {
1857         case MC_SEQ_RAS_TIMING >> 2:
1858                 *out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
1859                 break;
1860         case MC_SEQ_CAS_TIMING >> 2:
1861                 *out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
1862                 break;
1863         case MC_SEQ_MISC_TIMING >> 2:
1864                 *out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
1865                 break;
1866         case MC_SEQ_MISC_TIMING2 >> 2:
1867                 *out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
1868                 break;
1869         case MC_SEQ_RD_CTL_D0 >> 2:
1870                 *out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
1871                 break;
1872         case MC_SEQ_RD_CTL_D1 >> 2:
1873                 *out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
1874                 break;
1875         case MC_SEQ_WR_CTL_D0 >> 2:
1876                 *out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
1877                 break;
1878         case MC_SEQ_WR_CTL_D1 >> 2:
1879                 *out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
1880                 break;
1881         case MC_PMG_CMD_EMRS >> 2:
1882                 *out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1883                 break;
1884         case MC_PMG_CMD_MRS >> 2:
1885                 *out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1886                 break;
1887         case MC_PMG_CMD_MRS1 >> 2:
1888                 *out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1889                 break;
1890         default:
1891                 result = false;
1892                 break;
1893         }
1894
1895         return result;
1896 }
1897
1898 static void btc_set_valid_flag(struct evergreen_mc_reg_table *table)
1899 {
1900         u8 i, j;
1901
1902         for (i = 0; i < table->last; i++) {
1903                 for (j = 1; j < table->num_entries; j++) {
1904                         if (table->mc_reg_table_entry[j-1].mc_data[i] !=
1905                             table->mc_reg_table_entry[j].mc_data[i]) {
1906                                 table->valid_flag |= (1 << i);
1907                                 break;
1908                         }
1909                 }
1910         }
1911 }
1912
1913 static int btc_set_mc_special_registers(struct radeon_device *rdev,
1914                                         struct evergreen_mc_reg_table *table)
1915 {
1916         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1917         u8 i, j, k;
1918         u32 tmp;
1919
1920         for (i = 0, j = table->last; i < table->last; i++) {
1921                 switch (table->mc_reg_address[i].s1) {
1922                 case MC_SEQ_MISC1 >> 2:
1923                         tmp = RREG32(MC_PMG_CMD_EMRS);
1924                         table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
1925                         table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1926                         for (k = 0; k < table->num_entries; k++) {
1927                                 table->mc_reg_table_entry[k].mc_data[j] =
1928                                         ((tmp & 0xffff0000)) |
1929                                         ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
1930                         }
1931                         j++;
1932
1933                         if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1934                                 return -EINVAL;
1935
1936                         tmp = RREG32(MC_PMG_CMD_MRS);
1937                         table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
1938                         table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1939                         for (k = 0; k < table->num_entries; k++) {
1940                                 table->mc_reg_table_entry[k].mc_data[j] =
1941                                         (tmp & 0xffff0000) |
1942                                         (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1943                                 if (!pi->mem_gddr5)
1944                                         table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
1945                         }
1946                         j++;
1947
1948                         if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1949                                 return -EINVAL;
1950                         break;
1951                 case MC_SEQ_RESERVE_M >> 2:
1952                         tmp = RREG32(MC_PMG_CMD_MRS1);
1953                         table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
1954                         table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1955                         for (k = 0; k < table->num_entries; k++) {
1956                                 table->mc_reg_table_entry[k].mc_data[j] =
1957                                         (tmp & 0xffff0000) |
1958                                         (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1959                         }
1960                         j++;
1961
1962                         if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1963                                 return -EINVAL;
1964                         break;
1965                 default:
1966                         break;
1967                 }
1968         }
1969
1970         table->last = j;
1971
1972         return 0;
1973 }
1974
1975 static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table)
1976 {
1977         u32 i;
1978         u16 address;
1979
1980         for (i = 0; i < table->last; i++) {
1981                 table->mc_reg_address[i].s0 =
1982                         btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
1983                         address : table->mc_reg_address[i].s1;
1984         }
1985 }
1986
1987 static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
1988                                        struct evergreen_mc_reg_table *eg_table)
1989 {
1990         u8 i, j;
1991
1992         if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1993                 return -EINVAL;
1994
1995         if (table->num_entries > MAX_AC_TIMING_ENTRIES)
1996                 return -EINVAL;
1997
1998         for (i = 0; i < table->last; i++)
1999                 eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
2000         eg_table->last = table->last;
2001
2002         for (i = 0; i < table->num_entries; i++) {
2003                 eg_table->mc_reg_table_entry[i].mclk_max =
2004                         table->mc_reg_table_entry[i].mclk_max;
2005                 for(j = 0; j < table->last; j++)
2006                         eg_table->mc_reg_table_entry[i].mc_data[j] =
2007                                 table->mc_reg_table_entry[i].mc_data[j];
2008         }
2009         eg_table->num_entries = table->num_entries;
2010
2011         return 0;
2012 }
2013
2014 static int btc_initialize_mc_reg_table(struct radeon_device *rdev)
2015 {
2016         int ret;
2017         struct atom_mc_reg_table *table;
2018         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2019         struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table;
2020         u8 module_index = rv770_get_memory_module_index(rdev);
2021
2022         table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
2023         if (!table)
2024                 return -ENOMEM;
2025
2026         /* Program additional LP registers that are no longer programmed by VBIOS */
2027         WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
2028         WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
2029         WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
2030         WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
2031         WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
2032         WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
2033         WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
2034         WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
2035         WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
2036         WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
2037         WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
2038
2039         ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
2040
2041         if (ret)
2042                 goto init_mc_done;
2043
2044         ret = btc_copy_vbios_mc_reg_table(table, eg_table);
2045
2046         if (ret)
2047                 goto init_mc_done;
2048
2049         btc_set_s0_mc_reg_index(eg_table);
2050         ret = btc_set_mc_special_registers(rdev, eg_table);
2051
2052         if (ret)
2053                 goto init_mc_done;
2054
2055         btc_set_valid_flag(eg_table);
2056
2057 init_mc_done:
2058         kfree(table);
2059
2060         return ret;
2061 }
2062
2063 static void btc_init_stutter_mode(struct radeon_device *rdev)
2064 {
2065         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2066         u32 tmp;
2067
2068         if (pi->mclk_stutter_mode_threshold) {
2069                 if (pi->mem_gddr5) {
2070                         tmp = RREG32(MC_PMG_AUTO_CFG);
2071                         if ((0x200 & tmp) == 0) {
2072                                 tmp = (tmp & 0xfffffc0b) | 0x204;
2073                                 WREG32(MC_PMG_AUTO_CFG, tmp);
2074                         }
2075                 }
2076         }
2077 }
2078
2079 bool btc_dpm_vblank_too_short(struct radeon_device *rdev)
2080 {
2081         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2082         u32 vblank_time = r600_dpm_get_vblank_time(rdev);
2083         u32 switch_limit = pi->mem_gddr5 ? 450 : 100;
2084
2085         if (vblank_time < switch_limit)
2086                 return true;
2087         else
2088                 return false;
2089
2090 }
2091
2092 static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
2093                                          struct radeon_ps *rps)
2094 {
2095         struct rv7xx_ps *ps = rv770_get_ps(rps);
2096         struct radeon_clock_and_voltage_limits *max_limits;
2097         bool disable_mclk_switching;
2098         u32 mclk, sclk;
2099         u16 vddc, vddci;
2100
2101         if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
2102             btc_dpm_vblank_too_short(rdev))
2103                 disable_mclk_switching = true;
2104         else
2105                 disable_mclk_switching = false;
2106
2107         if (rdev->pm.dpm.ac_power)
2108                 max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2109         else
2110                 max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
2111
2112         if (rdev->pm.dpm.ac_power == false) {
2113                 if (ps->high.mclk > max_limits->mclk)
2114                         ps->high.mclk = max_limits->mclk;
2115                 if (ps->high.sclk > max_limits->sclk)
2116                         ps->high.sclk = max_limits->sclk;
2117                 if (ps->high.vddc > max_limits->vddc)
2118                         ps->high.vddc = max_limits->vddc;
2119                 if (ps->high.vddci > max_limits->vddci)
2120                         ps->high.vddci = max_limits->vddci;
2121
2122                 if (ps->medium.mclk > max_limits->mclk)
2123                         ps->medium.mclk = max_limits->mclk;
2124                 if (ps->medium.sclk > max_limits->sclk)
2125                         ps->medium.sclk = max_limits->sclk;
2126                 if (ps->medium.vddc > max_limits->vddc)
2127                         ps->medium.vddc = max_limits->vddc;
2128                 if (ps->medium.vddci > max_limits->vddci)
2129                         ps->medium.vddci = max_limits->vddci;
2130
2131                 if (ps->low.mclk > max_limits->mclk)
2132                         ps->low.mclk = max_limits->mclk;
2133                 if (ps->low.sclk > max_limits->sclk)
2134                         ps->low.sclk = max_limits->sclk;
2135                 if (ps->low.vddc > max_limits->vddc)
2136                         ps->low.vddc = max_limits->vddc;
2137                 if (ps->low.vddci > max_limits->vddci)
2138                         ps->low.vddci = max_limits->vddci;
2139         }
2140
2141         /* XXX validate the min clocks required for display */
2142
2143         if (disable_mclk_switching) {
2144                 sclk = ps->low.sclk;
2145                 mclk = ps->high.mclk;
2146                 vddc = ps->low.vddc;
2147                 vddci = ps->high.vddci;
2148         } else {
2149                 sclk = ps->low.sclk;
2150                 mclk = ps->low.mclk;
2151                 vddc = ps->low.vddc;
2152                 vddci = ps->low.vddci;
2153         }
2154
2155         /* adjusted low state */
2156         ps->low.sclk = sclk;
2157         ps->low.mclk = mclk;
2158         ps->low.vddc = vddc;
2159         ps->low.vddci = vddci;
2160
2161         btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2162                                   &ps->low.sclk, &ps->low.mclk);
2163
2164         /* adjusted medium, high states */
2165         if (ps->medium.sclk < ps->low.sclk)
2166                 ps->medium.sclk = ps->low.sclk;
2167         if (ps->medium.vddc < ps->low.vddc)
2168                 ps->medium.vddc = ps->low.vddc;
2169         if (ps->high.sclk < ps->medium.sclk)
2170                 ps->high.sclk = ps->medium.sclk;
2171         if (ps->high.vddc < ps->medium.vddc)
2172                 ps->high.vddc = ps->medium.vddc;
2173
2174         if (disable_mclk_switching) {
2175                 mclk = ps->low.mclk;
2176                 if (mclk < ps->medium.mclk)
2177                         mclk = ps->medium.mclk;
2178                 if (mclk < ps->high.mclk)
2179                         mclk = ps->high.mclk;
2180                 ps->low.mclk = mclk;
2181                 ps->low.vddci = vddci;
2182                 ps->medium.mclk = mclk;
2183                 ps->medium.vddci = vddci;
2184                 ps->high.mclk = mclk;
2185                 ps->high.vddci = vddci;
2186         } else {
2187                 if (ps->medium.mclk < ps->low.mclk)
2188                         ps->medium.mclk = ps->low.mclk;
2189                 if (ps->medium.vddci < ps->low.vddci)
2190                         ps->medium.vddci = ps->low.vddci;
2191                 if (ps->high.mclk < ps->medium.mclk)
2192                         ps->high.mclk = ps->medium.mclk;
2193                 if (ps->high.vddci < ps->medium.vddci)
2194                         ps->high.vddci = ps->medium.vddci;
2195         }
2196
2197         btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2198                                   &ps->medium.sclk, &ps->medium.mclk);
2199         btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2200                                   &ps->high.sclk, &ps->high.mclk);
2201
2202         btc_adjust_clock_combinations(rdev, max_limits, &ps->low);
2203         btc_adjust_clock_combinations(rdev, max_limits, &ps->medium);
2204         btc_adjust_clock_combinations(rdev, max_limits, &ps->high);
2205
2206         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2207                                            ps->low.sclk, max_limits->vddc, &ps->low.vddc);
2208         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2209                                            ps->low.mclk, max_limits->vddci, &ps->low.vddci);
2210         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2211                                            ps->low.mclk, max_limits->vddc, &ps->low.vddc);
2212         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2213                                            rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
2214
2215         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2216                                            ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
2217         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2218                                            ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
2219         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2220                                            ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
2221         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2222                                            rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
2223
2224         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2225                                            ps->high.sclk, max_limits->vddc, &ps->high.vddc);
2226         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2227                                            ps->high.mclk, max_limits->vddci, &ps->high.vddci);
2228         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2229                                            ps->high.mclk, max_limits->vddc, &ps->high.vddc);
2230         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2231                                            rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
2232
2233         btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2234                                       &ps->low.vddc, &ps->low.vddci);
2235         btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2236                                       &ps->medium.vddc, &ps->medium.vddci);
2237         btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2238                                       &ps->high.vddc, &ps->high.vddci);
2239
2240         if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2241             (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2242             (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc))
2243                 ps->dc_compatible = true;
2244         else
2245                 ps->dc_compatible = false;
2246
2247         if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2248                 ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2249         if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2250                 ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2251         if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2252                 ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2253 }
2254
2255 static void btc_update_current_ps(struct radeon_device *rdev,
2256                                   struct radeon_ps *rps)
2257 {
2258         struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2259         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2260
2261         eg_pi->current_rps = *rps;
2262         eg_pi->current_ps = *new_ps;
2263         eg_pi->current_rps.ps_priv = &eg_pi->current_ps;
2264 }
2265
2266 static void btc_update_requested_ps(struct radeon_device *rdev,
2267                                     struct radeon_ps *rps)
2268 {
2269         struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2270         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2271
2272         eg_pi->requested_rps = *rps;
2273         eg_pi->requested_ps = *new_ps;
2274         eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
2275 }
2276
2277 #if 0
2278 void btc_dpm_reset_asic(struct radeon_device *rdev)
2279 {
2280         rv770_restrict_performance_levels_before_switch(rdev);
2281         btc_disable_ulv(rdev);
2282         btc_set_boot_state_timing(rdev);
2283         rv770_set_boot_state(rdev);
2284 }
2285 #endif
2286
2287 int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
2288 {
2289         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2290         struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
2291         struct radeon_ps *new_ps = &requested_ps;
2292
2293         btc_update_requested_ps(rdev, new_ps);
2294
2295         btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
2296
2297         return 0;
2298 }
2299
2300 int btc_dpm_set_power_state(struct radeon_device *rdev)
2301 {
2302         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2303         struct radeon_ps *new_ps = &eg_pi->requested_rps;
2304         struct radeon_ps *old_ps = &eg_pi->current_rps;
2305         int ret;
2306
2307         ret = btc_disable_ulv(rdev);
2308         btc_set_boot_state_timing(rdev);
2309         ret = rv770_restrict_performance_levels_before_switch(rdev);
2310         if (ret) {
2311                 DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
2312                 return ret;
2313         }
2314         if (eg_pi->pcie_performance_request)
2315                 cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
2316
2317         rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
2318         ret = rv770_halt_smc(rdev);
2319         if (ret) {
2320                 DRM_ERROR("rv770_halt_smc failed\n");
2321                 return ret;
2322         }
2323         btc_set_at_for_uvd(rdev, new_ps);
2324         if (eg_pi->smu_uvd_hs)
2325                 btc_notify_uvd_to_smc(rdev, new_ps);
2326         ret = cypress_upload_sw_state(rdev, new_ps);
2327         if (ret) {
2328                 DRM_ERROR("cypress_upload_sw_state failed\n");
2329                 return ret;
2330         }
2331         if (eg_pi->dynamic_ac_timing) {
2332                 ret = cypress_upload_mc_reg_table(rdev, new_ps);
2333                 if (ret) {
2334                         DRM_ERROR("cypress_upload_mc_reg_table failed\n");
2335                         return ret;
2336                 }
2337         }
2338
2339         cypress_program_memory_timing_parameters(rdev, new_ps);
2340
2341         ret = rv770_resume_smc(rdev);
2342         if (ret) {
2343                 DRM_ERROR("rv770_resume_smc failed\n");
2344                 return ret;
2345         }
2346         ret = rv770_set_sw_state(rdev);
2347         if (ret) {
2348                 DRM_ERROR("rv770_set_sw_state failed\n");
2349                 return ret;
2350         }
2351         rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
2352
2353         if (eg_pi->pcie_performance_request)
2354                 cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
2355
2356         ret = btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);
2357         if (ret) {
2358                 DRM_ERROR("btc_set_power_state_conditionally_enable_ulv failed\n");
2359                 return ret;
2360         }
2361
2362         return 0;
2363 }
2364
2365 void btc_dpm_post_set_power_state(struct radeon_device *rdev)
2366 {
2367         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2368         struct radeon_ps *new_ps = &eg_pi->requested_rps;
2369
2370         btc_update_current_ps(rdev, new_ps);
2371 }
2372
2373 int btc_dpm_enable(struct radeon_device *rdev)
2374 {
2375         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2376         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2377         struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
2378         int ret;
2379
2380         if (pi->gfx_clock_gating)
2381                 btc_cg_clock_gating_default(rdev);
2382
2383         if (btc_dpm_enabled(rdev))
2384                 return -EINVAL;
2385
2386         if (pi->mg_clock_gating)
2387                 btc_mg_clock_gating_default(rdev);
2388
2389         if (eg_pi->ls_clock_gating)
2390                 btc_ls_clock_gating_default(rdev);
2391
2392         if (pi->voltage_control) {
2393                 rv770_enable_voltage_control(rdev, true);
2394                 ret = cypress_construct_voltage_tables(rdev);
2395                 if (ret) {
2396                         DRM_ERROR("cypress_construct_voltage_tables failed\n");
2397                         return ret;
2398                 }
2399         }
2400
2401         if (pi->mvdd_control) {
2402                 ret = cypress_get_mvdd_configuration(rdev);
2403                 if (ret) {
2404                         DRM_ERROR("cypress_get_mvdd_configuration failed\n");
2405                         return ret;
2406                 }
2407         }
2408
2409         if (eg_pi->dynamic_ac_timing) {
2410                 ret = btc_initialize_mc_reg_table(rdev);
2411                 if (ret)
2412                         eg_pi->dynamic_ac_timing = false;
2413         }
2414
2415         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
2416                 rv770_enable_backbias(rdev, true);
2417
2418         if (pi->dynamic_ss)
2419                 cypress_enable_spread_spectrum(rdev, true);
2420
2421         if (pi->thermal_protection)
2422                 rv770_enable_thermal_protection(rdev, true);
2423
2424         rv770_setup_bsp(rdev);
2425         rv770_program_git(rdev);
2426         rv770_program_tp(rdev);
2427         rv770_program_tpp(rdev);
2428         rv770_program_sstp(rdev);
2429         rv770_program_engine_speed_parameters(rdev);
2430         cypress_enable_display_gap(rdev);
2431         rv770_program_vc(rdev);
2432
2433         if (pi->dynamic_pcie_gen2)
2434                 btc_enable_dynamic_pcie_gen2(rdev, true);
2435
2436         ret = rv770_upload_firmware(rdev);
2437         if (ret) {
2438                 DRM_ERROR("rv770_upload_firmware failed\n");
2439                 return ret;
2440         }
2441         ret = cypress_get_table_locations(rdev);
2442         if (ret) {
2443                 DRM_ERROR("cypress_get_table_locations failed\n");
2444                 return ret;
2445         }
2446         ret = btc_init_smc_table(rdev, boot_ps);
2447         if (ret)
2448                 return ret;
2449
2450         if (eg_pi->dynamic_ac_timing) {
2451                 ret = cypress_populate_mc_reg_table(rdev, boot_ps);
2452                 if (ret) {
2453                         DRM_ERROR("cypress_populate_mc_reg_table failed\n");
2454                         return ret;
2455                 }
2456         }
2457
2458         cypress_program_response_times(rdev);
2459         r7xx_start_smc(rdev);
2460         ret = cypress_notify_smc_display_change(rdev, false);
2461         if (ret) {
2462                 DRM_ERROR("cypress_notify_smc_display_change failed\n");
2463                 return ret;
2464         }
2465         cypress_enable_sclk_control(rdev, true);
2466
2467         if (eg_pi->memory_transition)
2468                 cypress_enable_mclk_control(rdev, true);
2469
2470         cypress_start_dpm(rdev);
2471
2472         if (pi->gfx_clock_gating)
2473                 btc_cg_clock_gating_enable(rdev, true);
2474
2475         if (pi->mg_clock_gating)
2476                 btc_mg_clock_gating_enable(rdev, true);
2477
2478         if (eg_pi->ls_clock_gating)
2479                 btc_ls_clock_gating_enable(rdev, true);
2480
2481         rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
2482
2483         btc_init_stutter_mode(rdev);
2484
2485         btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2486
2487         return 0;
2488 };
2489
2490 void btc_dpm_disable(struct radeon_device *rdev)
2491 {
2492         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2493         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2494
2495         if (!btc_dpm_enabled(rdev))
2496                 return;
2497
2498         rv770_clear_vc(rdev);
2499
2500         if (pi->thermal_protection)
2501                 rv770_enable_thermal_protection(rdev, false);
2502
2503         if (pi->dynamic_pcie_gen2)
2504                 btc_enable_dynamic_pcie_gen2(rdev, false);
2505
2506         if (rdev->irq.installed &&
2507             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
2508                 rdev->irq.dpm_thermal = false;
2509                 radeon_irq_set(rdev);
2510         }
2511
2512         if (pi->gfx_clock_gating)
2513                 btc_cg_clock_gating_enable(rdev, false);
2514
2515         if (pi->mg_clock_gating)
2516                 btc_mg_clock_gating_enable(rdev, false);
2517
2518         if (eg_pi->ls_clock_gating)
2519                 btc_ls_clock_gating_enable(rdev, false);
2520
2521         rv770_stop_dpm(rdev);
2522         btc_reset_to_default(rdev);
2523         btc_stop_smc(rdev);
2524         cypress_enable_spread_spectrum(rdev, false);
2525
2526         btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2527 }
2528
2529 void btc_dpm_setup_asic(struct radeon_device *rdev)
2530 {
2531         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2532         int r;
2533
2534         r = ni_mc_load_microcode(rdev);
2535         if (r)
2536                 DRM_ERROR("Failed to load MC firmware!\n");
2537         rv770_get_memory_type(rdev);
2538         rv740_read_clock_registers(rdev);
2539         btc_read_arb_registers(rdev);
2540         rv770_read_voltage_smio_registers(rdev);
2541
2542         if (eg_pi->pcie_performance_request)
2543                 cypress_advertise_gen2_capability(rdev);
2544
2545         rv770_get_pcie_gen2_status(rdev);
2546         rv770_enable_acpi_pm(rdev);
2547 }
2548
2549 int btc_dpm_init(struct radeon_device *rdev)
2550 {
2551         struct rv7xx_power_info *pi;
2552         struct evergreen_power_info *eg_pi;
2553         struct atom_clock_dividers dividers;
2554         int ret;
2555
2556         eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
2557         if (eg_pi == NULL)
2558                 return -ENOMEM;
2559         rdev->pm.dpm.priv = eg_pi;
2560         pi = &eg_pi->rv7xx;
2561
2562         rv770_get_max_vddc(rdev);
2563
2564         eg_pi->ulv.supported = false;
2565         pi->acpi_vddc = 0;
2566         eg_pi->acpi_vddci = 0;
2567         pi->min_vddc_in_table = 0;
2568         pi->max_vddc_in_table = 0;
2569
2570         ret = r600_get_platform_caps(rdev);
2571         if (ret)
2572                 return ret;
2573
2574         ret = rv7xx_parse_power_table(rdev);
2575         if (ret)
2576                 return ret;
2577         ret = r600_parse_extended_power_table(rdev);
2578         if (ret)
2579                 return ret;
2580
2581         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
2582                 kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
2583         if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
2584                 r600_free_extended_power_table(rdev);
2585                 return -ENOMEM;
2586         }
2587         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
2588         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
2589         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
2590         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
2591         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
2592         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
2593         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
2594         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
2595         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
2596
2597         if (rdev->pm.dpm.voltage_response_time == 0)
2598                 rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
2599         if (rdev->pm.dpm.backbias_response_time == 0)
2600                 rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
2601
2602         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2603                                              0, false, &dividers);
2604         if (ret)
2605                 pi->ref_div = dividers.ref_div + 1;
2606         else
2607                 pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
2608
2609         pi->mclk_strobe_mode_threshold = 40000;
2610         pi->mclk_edc_enable_threshold = 40000;
2611         eg_pi->mclk_edc_wr_enable_threshold = 40000;
2612
2613         pi->rlp = RV770_RLP_DFLT;
2614         pi->rmp = RV770_RMP_DFLT;
2615         pi->lhp = RV770_LHP_DFLT;
2616         pi->lmp = RV770_LMP_DFLT;
2617
2618         eg_pi->ats[0].rlp = RV770_RLP_DFLT;
2619         eg_pi->ats[0].rmp = RV770_RMP_DFLT;
2620         eg_pi->ats[0].lhp = RV770_LHP_DFLT;
2621         eg_pi->ats[0].lmp = RV770_LMP_DFLT;
2622
2623         eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
2624         eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
2625         eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
2626         eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
2627
2628         eg_pi->smu_uvd_hs = true;
2629
2630         pi->voltage_control =
2631                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
2632
2633         pi->mvdd_control =
2634                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
2635
2636         eg_pi->vddci_control =
2637                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
2638
2639         rv770_get_engine_memory_ss(rdev);
2640
2641         pi->asi = RV770_ASI_DFLT;
2642         pi->pasi = CYPRESS_HASI_DFLT;
2643         pi->vrc = CYPRESS_VRC_DFLT;
2644
2645         pi->power_gating = false;
2646
2647         pi->gfx_clock_gating = true;
2648
2649         pi->mg_clock_gating = true;
2650         pi->mgcgtssm = true;
2651         eg_pi->ls_clock_gating = false;
2652         eg_pi->sclk_deep_sleep = false;
2653
2654         pi->dynamic_pcie_gen2 = true;
2655
2656         if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
2657                 pi->thermal_protection = true;
2658         else
2659                 pi->thermal_protection = false;
2660
2661         pi->display_gap = true;
2662
2663         if (rdev->flags & RADEON_IS_MOBILITY)
2664                 pi->dcodt = true;
2665         else
2666                 pi->dcodt = false;
2667
2668         pi->ulps = true;
2669
2670         eg_pi->dynamic_ac_timing = true;
2671         eg_pi->abm = true;
2672         eg_pi->mcls = true;
2673         eg_pi->light_sleep = true;
2674         eg_pi->memory_transition = true;
2675 #if defined(CONFIG_ACPI)
2676         eg_pi->pcie_performance_request =
2677                 radeon_acpi_is_pcie_performance_request_supported(rdev);
2678 #else
2679         eg_pi->pcie_performance_request = false;
2680 #endif
2681
2682         if (rdev->family == CHIP_BARTS)
2683                 eg_pi->dll_default_on = true;
2684         else
2685                 eg_pi->dll_default_on = false;
2686
2687         eg_pi->sclk_deep_sleep = false;
2688         if (ASIC_IS_LOMBOK(rdev))
2689                 pi->mclk_stutter_mode_threshold = 30000;
2690         else
2691                 pi->mclk_stutter_mode_threshold = 0;
2692
2693         pi->sram_end = SMC_RAM_END;
2694
2695         rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
2696         rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
2697         rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
2698         rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
2699         rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
2700         rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
2701         rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
2702
2703         if (rdev->family == CHIP_TURKS)
2704                 rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
2705         else
2706                 rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
2707
2708         /* make sure dc limits are valid */
2709         if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
2710             (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
2711                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
2712                         rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2713
2714         return 0;
2715 }
2716
2717 void btc_dpm_fini(struct radeon_device *rdev)
2718 {
2719         int i;
2720
2721         for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2722                 kfree(rdev->pm.dpm.ps[i].ps_priv);
2723         }
2724         kfree(rdev->pm.dpm.ps);
2725         kfree(rdev->pm.dpm.priv);
2726         kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
2727         r600_free_extended_power_table(rdev);
2728 }
2729
2730 void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2731                                                      struct seq_file *m)
2732 {
2733         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2734         struct radeon_ps *rps = &eg_pi->current_rps;
2735         struct rv7xx_ps *ps = rv770_get_ps(rps);
2736         struct rv7xx_pl *pl;
2737         u32 current_index =
2738                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2739                 CURRENT_PROFILE_INDEX_SHIFT;
2740
2741         if (current_index > 2) {
2742                 seq_printf(m, "invalid dpm profile %d\n", current_index);
2743         } else {
2744                 if (current_index == 0)
2745                         pl = &ps->low;
2746                 else if (current_index == 1)
2747                         pl = &ps->medium;
2748                 else /* current_index == 2 */
2749                         pl = &ps->high;
2750                 seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2751                 seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
2752                            current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2753         }
2754 }
2755
2756 u32 btc_dpm_get_current_sclk(struct radeon_device *rdev)
2757 {
2758         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2759         struct radeon_ps *rps = &eg_pi->current_rps;
2760         struct rv7xx_ps *ps = rv770_get_ps(rps);
2761         struct rv7xx_pl *pl;
2762         u32 current_index =
2763                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2764                 CURRENT_PROFILE_INDEX_SHIFT;
2765
2766         if (current_index > 2) {
2767                 return 0;
2768         } else {
2769                 if (current_index == 0)
2770                         pl = &ps->low;
2771                 else if (current_index == 1)
2772                         pl = &ps->medium;
2773                 else /* current_index == 2 */
2774                         pl = &ps->high;
2775                 return pl->sclk;
2776         }
2777 }
2778
2779 u32 btc_dpm_get_current_mclk(struct radeon_device *rdev)
2780 {
2781         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2782         struct radeon_ps *rps = &eg_pi->current_rps;
2783         struct rv7xx_ps *ps = rv770_get_ps(rps);
2784         struct rv7xx_pl *pl;
2785         u32 current_index =
2786                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2787                 CURRENT_PROFILE_INDEX_SHIFT;
2788
2789         if (current_index > 2) {
2790                 return 0;
2791         } else {
2792                 if (current_index == 0)
2793                         pl = &ps->low;
2794                 else if (current_index == 1)
2795                         pl = &ps->medium;
2796                 else /* current_index == 2 */
2797                         pl = &ps->high;
2798                 return pl->mclk;
2799         }
2800 }
2801
2802 u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
2803 {
2804         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2805         struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2806
2807         if (low)
2808                 return requested_state->low.sclk;
2809         else
2810                 return requested_state->high.sclk;
2811 }
2812
2813 u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
2814 {
2815         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2816         struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2817
2818         if (low)
2819                 return requested_state->low.mclk;
2820         else
2821                 return requested_state->high.mclk;
2822 }