Merge branch 'vendor/OPENSSH'
[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
34 #define MC_CG_ARB_FREQ_F0           0x0a
35 #define MC_CG_ARB_FREQ_F1           0x0b
36 #define MC_CG_ARB_FREQ_F2           0x0c
37 #define MC_CG_ARB_FREQ_F3           0x0d
38
39 #define MC_CG_SEQ_DRAMCONF_S0       0x05
40 #define MC_CG_SEQ_DRAMCONF_S1       0x06
41 #define MC_CG_SEQ_YCLK_SUSPEND      0x04
42 #define MC_CG_SEQ_YCLK_RESUME       0x0a
43
44 #define SMC_RAM_END 0x8000
45
46 #ifndef BTC_MGCG_SEQUENCE
47 #define BTC_MGCG_SEQUENCE  300
48
49 struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
50 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
51 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
52
53 //********* BARTS **************//
54 static const u32 barts_cgcg_cgls_default[] =
55 {
56         /* Register,   Value,     Mask bits */
57         0x000008f8, 0x00000010, 0xffffffff,
58         0x000008fc, 0x00000000, 0xffffffff,
59         0x000008f8, 0x00000011, 0xffffffff,
60         0x000008fc, 0x00000000, 0xffffffff,
61         0x000008f8, 0x00000012, 0xffffffff,
62         0x000008fc, 0x00000000, 0xffffffff,
63         0x000008f8, 0x00000013, 0xffffffff,
64         0x000008fc, 0x00000000, 0xffffffff,
65         0x000008f8, 0x00000014, 0xffffffff,
66         0x000008fc, 0x00000000, 0xffffffff,
67         0x000008f8, 0x00000015, 0xffffffff,
68         0x000008fc, 0x00000000, 0xffffffff,
69         0x000008f8, 0x00000016, 0xffffffff,
70         0x000008fc, 0x00000000, 0xffffffff,
71         0x000008f8, 0x00000017, 0xffffffff,
72         0x000008fc, 0x00000000, 0xffffffff,
73         0x000008f8, 0x00000018, 0xffffffff,
74         0x000008fc, 0x00000000, 0xffffffff,
75         0x000008f8, 0x00000019, 0xffffffff,
76         0x000008fc, 0x00000000, 0xffffffff,
77         0x000008f8, 0x0000001a, 0xffffffff,
78         0x000008fc, 0x00000000, 0xffffffff,
79         0x000008f8, 0x0000001b, 0xffffffff,
80         0x000008fc, 0x00000000, 0xffffffff,
81         0x000008f8, 0x00000020, 0xffffffff,
82         0x000008fc, 0x00000000, 0xffffffff,
83         0x000008f8, 0x00000021, 0xffffffff,
84         0x000008fc, 0x00000000, 0xffffffff,
85         0x000008f8, 0x00000022, 0xffffffff,
86         0x000008fc, 0x00000000, 0xffffffff,
87         0x000008f8, 0x00000023, 0xffffffff,
88         0x000008fc, 0x00000000, 0xffffffff,
89         0x000008f8, 0x00000024, 0xffffffff,
90         0x000008fc, 0x00000000, 0xffffffff,
91         0x000008f8, 0x00000025, 0xffffffff,
92         0x000008fc, 0x00000000, 0xffffffff,
93         0x000008f8, 0x00000026, 0xffffffff,
94         0x000008fc, 0x00000000, 0xffffffff,
95         0x000008f8, 0x00000027, 0xffffffff,
96         0x000008fc, 0x00000000, 0xffffffff,
97         0x000008f8, 0x00000028, 0xffffffff,
98         0x000008fc, 0x00000000, 0xffffffff,
99         0x000008f8, 0x00000029, 0xffffffff,
100         0x000008fc, 0x00000000, 0xffffffff,
101         0x000008f8, 0x0000002a, 0xffffffff,
102         0x000008fc, 0x00000000, 0xffffffff,
103         0x000008f8, 0x0000002b, 0xffffffff,
104         0x000008fc, 0x00000000, 0xffffffff
105 };
106 #define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
107
108 static const u32 barts_cgcg_cgls_disable[] =
109 {
110         0x000008f8, 0x00000010, 0xffffffff,
111         0x000008fc, 0xffffffff, 0xffffffff,
112         0x000008f8, 0x00000011, 0xffffffff,
113         0x000008fc, 0xffffffff, 0xffffffff,
114         0x000008f8, 0x00000012, 0xffffffff,
115         0x000008fc, 0xffffffff, 0xffffffff,
116         0x000008f8, 0x00000013, 0xffffffff,
117         0x000008fc, 0xffffffff, 0xffffffff,
118         0x000008f8, 0x00000014, 0xffffffff,
119         0x000008fc, 0xffffffff, 0xffffffff,
120         0x000008f8, 0x00000015, 0xffffffff,
121         0x000008fc, 0xffffffff, 0xffffffff,
122         0x000008f8, 0x00000016, 0xffffffff,
123         0x000008fc, 0xffffffff, 0xffffffff,
124         0x000008f8, 0x00000017, 0xffffffff,
125         0x000008fc, 0xffffffff, 0xffffffff,
126         0x000008f8, 0x00000018, 0xffffffff,
127         0x000008fc, 0xffffffff, 0xffffffff,
128         0x000008f8, 0x00000019, 0xffffffff,
129         0x000008fc, 0xffffffff, 0xffffffff,
130         0x000008f8, 0x0000001a, 0xffffffff,
131         0x000008fc, 0xffffffff, 0xffffffff,
132         0x000008f8, 0x0000001b, 0xffffffff,
133         0x000008fc, 0xffffffff, 0xffffffff,
134         0x000008f8, 0x00000020, 0xffffffff,
135         0x000008fc, 0x00000000, 0xffffffff,
136         0x000008f8, 0x00000021, 0xffffffff,
137         0x000008fc, 0x00000000, 0xffffffff,
138         0x000008f8, 0x00000022, 0xffffffff,
139         0x000008fc, 0x00000000, 0xffffffff,
140         0x000008f8, 0x00000023, 0xffffffff,
141         0x000008fc, 0x00000000, 0xffffffff,
142         0x000008f8, 0x00000024, 0xffffffff,
143         0x000008fc, 0x00000000, 0xffffffff,
144         0x000008f8, 0x00000025, 0xffffffff,
145         0x000008fc, 0x00000000, 0xffffffff,
146         0x000008f8, 0x00000026, 0xffffffff,
147         0x000008fc, 0x00000000, 0xffffffff,
148         0x000008f8, 0x00000027, 0xffffffff,
149         0x000008fc, 0x00000000, 0xffffffff,
150         0x000008f8, 0x00000028, 0xffffffff,
151         0x000008fc, 0x00000000, 0xffffffff,
152         0x000008f8, 0x00000029, 0xffffffff,
153         0x000008fc, 0x00000000, 0xffffffff,
154         0x000008f8, 0x0000002a, 0xffffffff,
155         0x000008fc, 0x00000000, 0xffffffff,
156         0x000008f8, 0x0000002b, 0xffffffff,
157         0x000008fc, 0x00000000, 0xffffffff,
158         0x00000644, 0x000f7912, 0x001f4180,
159         0x00000644, 0x000f3812, 0x001f4180
160 };
161 #define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
162
163 static const u32 barts_cgcg_cgls_enable[] =
164 {
165         /* 0x0000c124, 0x84180000, 0x00180000, */
166         0x00000644, 0x000f7892, 0x001f4080,
167         0x000008f8, 0x00000010, 0xffffffff,
168         0x000008fc, 0x00000000, 0xffffffff,
169         0x000008f8, 0x00000011, 0xffffffff,
170         0x000008fc, 0x00000000, 0xffffffff,
171         0x000008f8, 0x00000012, 0xffffffff,
172         0x000008fc, 0x00000000, 0xffffffff,
173         0x000008f8, 0x00000013, 0xffffffff,
174         0x000008fc, 0x00000000, 0xffffffff,
175         0x000008f8, 0x00000014, 0xffffffff,
176         0x000008fc, 0x00000000, 0xffffffff,
177         0x000008f8, 0x00000015, 0xffffffff,
178         0x000008fc, 0x00000000, 0xffffffff,
179         0x000008f8, 0x00000016, 0xffffffff,
180         0x000008fc, 0x00000000, 0xffffffff,
181         0x000008f8, 0x00000017, 0xffffffff,
182         0x000008fc, 0x00000000, 0xffffffff,
183         0x000008f8, 0x00000018, 0xffffffff,
184         0x000008fc, 0x00000000, 0xffffffff,
185         0x000008f8, 0x00000019, 0xffffffff,
186         0x000008fc, 0x00000000, 0xffffffff,
187         0x000008f8, 0x0000001a, 0xffffffff,
188         0x000008fc, 0x00000000, 0xffffffff,
189         0x000008f8, 0x0000001b, 0xffffffff,
190         0x000008fc, 0x00000000, 0xffffffff,
191         0x000008f8, 0x00000020, 0xffffffff,
192         0x000008fc, 0xffffffff, 0xffffffff,
193         0x000008f8, 0x00000021, 0xffffffff,
194         0x000008fc, 0xffffffff, 0xffffffff,
195         0x000008f8, 0x00000022, 0xffffffff,
196         0x000008fc, 0xffffffff, 0xffffffff,
197         0x000008f8, 0x00000023, 0xffffffff,
198         0x000008fc, 0xffffffff, 0xffffffff,
199         0x000008f8, 0x00000024, 0xffffffff,
200         0x000008fc, 0xffffffff, 0xffffffff,
201         0x000008f8, 0x00000025, 0xffffffff,
202         0x000008fc, 0xffffffff, 0xffffffff,
203         0x000008f8, 0x00000026, 0xffffffff,
204         0x000008fc, 0xffffffff, 0xffffffff,
205         0x000008f8, 0x00000027, 0xffffffff,
206         0x000008fc, 0xffffffff, 0xffffffff,
207         0x000008f8, 0x00000028, 0xffffffff,
208         0x000008fc, 0xffffffff, 0xffffffff,
209         0x000008f8, 0x00000029, 0xffffffff,
210         0x000008fc, 0xffffffff, 0xffffffff,
211         0x000008f8, 0x0000002a, 0xffffffff,
212         0x000008fc, 0xffffffff, 0xffffffff,
213         0x000008f8, 0x0000002b, 0xffffffff,
214         0x000008fc, 0xffffffff, 0xffffffff
215 };
216 #define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
217
218 static const u32 barts_mgcg_default[] =
219 {
220         0x0000802c, 0xc0000000, 0xffffffff,
221         0x00005448, 0x00000100, 0xffffffff,
222         0x000055e4, 0x00600100, 0xffffffff,
223         0x0000160c, 0x00000100, 0xffffffff,
224         0x0000c164, 0x00000100, 0xffffffff,
225         0x00008a18, 0x00000100, 0xffffffff,
226         0x0000897c, 0x06000100, 0xffffffff,
227         0x00008b28, 0x00000100, 0xffffffff,
228         0x00009144, 0x00000100, 0xffffffff,
229         0x00009a60, 0x00000100, 0xffffffff,
230         0x00009868, 0x00000100, 0xffffffff,
231         0x00008d58, 0x00000100, 0xffffffff,
232         0x00009510, 0x00000100, 0xffffffff,
233         0x0000949c, 0x00000100, 0xffffffff,
234         0x00009654, 0x00000100, 0xffffffff,
235         0x00009030, 0x00000100, 0xffffffff,
236         0x00009034, 0x00000100, 0xffffffff,
237         0x00009038, 0x00000100, 0xffffffff,
238         0x0000903c, 0x00000100, 0xffffffff,
239         0x00009040, 0x00000100, 0xffffffff,
240         0x0000a200, 0x00000100, 0xffffffff,
241         0x0000a204, 0x00000100, 0xffffffff,
242         0x0000a208, 0x00000100, 0xffffffff,
243         0x0000a20c, 0x00000100, 0xffffffff,
244         0x0000977c, 0x00000100, 0xffffffff,
245         0x00003f80, 0x00000100, 0xffffffff,
246         0x0000a210, 0x00000100, 0xffffffff,
247         0x0000a214, 0x00000100, 0xffffffff,
248         0x000004d8, 0x00000100, 0xffffffff,
249         0x00009784, 0x00000100, 0xffffffff,
250         0x00009698, 0x00000100, 0xffffffff,
251         0x000004d4, 0x00000200, 0xffffffff,
252         0x000004d0, 0x00000000, 0xffffffff,
253         0x000030cc, 0x00000100, 0xffffffff,
254         0x0000d0c0, 0xff000100, 0xffffffff,
255         0x0000802c, 0x40000000, 0xffffffff,
256         0x0000915c, 0x00010000, 0xffffffff,
257         0x00009160, 0x00030002, 0xffffffff,
258         0x00009164, 0x00050004, 0xffffffff,
259         0x00009168, 0x00070006, 0xffffffff,
260         0x00009178, 0x00070000, 0xffffffff,
261         0x0000917c, 0x00030002, 0xffffffff,
262         0x00009180, 0x00050004, 0xffffffff,
263         0x0000918c, 0x00010006, 0xffffffff,
264         0x00009190, 0x00090008, 0xffffffff,
265         0x00009194, 0x00070000, 0xffffffff,
266         0x00009198, 0x00030002, 0xffffffff,
267         0x0000919c, 0x00050004, 0xffffffff,
268         0x000091a8, 0x00010006, 0xffffffff,
269         0x000091ac, 0x00090008, 0xffffffff,
270         0x000091b0, 0x00070000, 0xffffffff,
271         0x000091b4, 0x00030002, 0xffffffff,
272         0x000091b8, 0x00050004, 0xffffffff,
273         0x000091c4, 0x00010006, 0xffffffff,
274         0x000091c8, 0x00090008, 0xffffffff,
275         0x000091cc, 0x00070000, 0xffffffff,
276         0x000091d0, 0x00030002, 0xffffffff,
277         0x000091d4, 0x00050004, 0xffffffff,
278         0x000091e0, 0x00010006, 0xffffffff,
279         0x000091e4, 0x00090008, 0xffffffff,
280         0x000091e8, 0x00000000, 0xffffffff,
281         0x000091ec, 0x00070000, 0xffffffff,
282         0x000091f0, 0x00030002, 0xffffffff,
283         0x000091f4, 0x00050004, 0xffffffff,
284         0x00009200, 0x00010006, 0xffffffff,
285         0x00009204, 0x00090008, 0xffffffff,
286         0x00009208, 0x00070000, 0xffffffff,
287         0x0000920c, 0x00030002, 0xffffffff,
288         0x00009210, 0x00050004, 0xffffffff,
289         0x0000921c, 0x00010006, 0xffffffff,
290         0x00009220, 0x00090008, 0xffffffff,
291         0x00009224, 0x00070000, 0xffffffff,
292         0x00009228, 0x00030002, 0xffffffff,
293         0x0000922c, 0x00050004, 0xffffffff,
294         0x00009238, 0x00010006, 0xffffffff,
295         0x0000923c, 0x00090008, 0xffffffff,
296         0x00009294, 0x00000000, 0xffffffff,
297         0x0000802c, 0x40010000, 0xffffffff,
298         0x0000915c, 0x00010000, 0xffffffff,
299         0x00009160, 0x00030002, 0xffffffff,
300         0x00009164, 0x00050004, 0xffffffff,
301         0x00009168, 0x00070006, 0xffffffff,
302         0x00009178, 0x00070000, 0xffffffff,
303         0x0000917c, 0x00030002, 0xffffffff,
304         0x00009180, 0x00050004, 0xffffffff,
305         0x0000918c, 0x00010006, 0xffffffff,
306         0x00009190, 0x00090008, 0xffffffff,
307         0x00009194, 0x00070000, 0xffffffff,
308         0x00009198, 0x00030002, 0xffffffff,
309         0x0000919c, 0x00050004, 0xffffffff,
310         0x000091a8, 0x00010006, 0xffffffff,
311         0x000091ac, 0x00090008, 0xffffffff,
312         0x000091b0, 0x00070000, 0xffffffff,
313         0x000091b4, 0x00030002, 0xffffffff,
314         0x000091b8, 0x00050004, 0xffffffff,
315         0x000091c4, 0x00010006, 0xffffffff,
316         0x000091c8, 0x00090008, 0xffffffff,
317         0x000091cc, 0x00070000, 0xffffffff,
318         0x000091d0, 0x00030002, 0xffffffff,
319         0x000091d4, 0x00050004, 0xffffffff,
320         0x000091e0, 0x00010006, 0xffffffff,
321         0x000091e4, 0x00090008, 0xffffffff,
322         0x000091e8, 0x00000000, 0xffffffff,
323         0x000091ec, 0x00070000, 0xffffffff,
324         0x000091f0, 0x00030002, 0xffffffff,
325         0x000091f4, 0x00050004, 0xffffffff,
326         0x00009200, 0x00010006, 0xffffffff,
327         0x00009204, 0x00090008, 0xffffffff,
328         0x00009208, 0x00070000, 0xffffffff,
329         0x0000920c, 0x00030002, 0xffffffff,
330         0x00009210, 0x00050004, 0xffffffff,
331         0x0000921c, 0x00010006, 0xffffffff,
332         0x00009220, 0x00090008, 0xffffffff,
333         0x00009224, 0x00070000, 0xffffffff,
334         0x00009228, 0x00030002, 0xffffffff,
335         0x0000922c, 0x00050004, 0xffffffff,
336         0x00009238, 0x00010006, 0xffffffff,
337         0x0000923c, 0x00090008, 0xffffffff,
338         0x00009294, 0x00000000, 0xffffffff,
339         0x0000802c, 0xc0000000, 0xffffffff,
340         0x000008f8, 0x00000010, 0xffffffff,
341         0x000008fc, 0x00000000, 0xffffffff,
342         0x000008f8, 0x00000011, 0xffffffff,
343         0x000008fc, 0x00000000, 0xffffffff,
344         0x000008f8, 0x00000012, 0xffffffff,
345         0x000008fc, 0x00000000, 0xffffffff,
346         0x000008f8, 0x00000013, 0xffffffff,
347         0x000008fc, 0x00000000, 0xffffffff,
348         0x000008f8, 0x00000014, 0xffffffff,
349         0x000008fc, 0x00000000, 0xffffffff,
350         0x000008f8, 0x00000015, 0xffffffff,
351         0x000008fc, 0x00000000, 0xffffffff,
352         0x000008f8, 0x00000016, 0xffffffff,
353         0x000008fc, 0x00000000, 0xffffffff,
354         0x000008f8, 0x00000017, 0xffffffff,
355         0x000008fc, 0x00000000, 0xffffffff,
356         0x000008f8, 0x00000018, 0xffffffff,
357         0x000008fc, 0x00000000, 0xffffffff,
358         0x000008f8, 0x00000019, 0xffffffff,
359         0x000008fc, 0x00000000, 0xffffffff,
360         0x000008f8, 0x0000001a, 0xffffffff,
361         0x000008fc, 0x00000000, 0xffffffff,
362         0x000008f8, 0x0000001b, 0xffffffff,
363         0x000008fc, 0x00000000, 0xffffffff
364 };
365 #define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
366
367 static const u32 barts_mgcg_disable[] =
368 {
369         0x0000802c, 0xc0000000, 0xffffffff,
370         0x000008f8, 0x00000000, 0xffffffff,
371         0x000008fc, 0xffffffff, 0xffffffff,
372         0x000008f8, 0x00000001, 0xffffffff,
373         0x000008fc, 0xffffffff, 0xffffffff,
374         0x000008f8, 0x00000002, 0xffffffff,
375         0x000008fc, 0xffffffff, 0xffffffff,
376         0x000008f8, 0x00000003, 0xffffffff,
377         0x000008fc, 0xffffffff, 0xffffffff,
378         0x00009150, 0x00600000, 0xffffffff
379 };
380 #define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
381
382 static const u32 barts_mgcg_enable[] =
383 {
384         0x0000802c, 0xc0000000, 0xffffffff,
385         0x000008f8, 0x00000000, 0xffffffff,
386         0x000008fc, 0x00000000, 0xffffffff,
387         0x000008f8, 0x00000001, 0xffffffff,
388         0x000008fc, 0x00000000, 0xffffffff,
389         0x000008f8, 0x00000002, 0xffffffff,
390         0x000008fc, 0x00000000, 0xffffffff,
391         0x000008f8, 0x00000003, 0xffffffff,
392         0x000008fc, 0x00000000, 0xffffffff,
393         0x00009150, 0x81944000, 0xffffffff
394 };
395 #define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
396
397 //********* CAICOS **************//
398 static const u32 caicos_cgcg_cgls_default[] =
399 {
400         0x000008f8, 0x00000010, 0xffffffff,
401         0x000008fc, 0x00000000, 0xffffffff,
402         0x000008f8, 0x00000011, 0xffffffff,
403         0x000008fc, 0x00000000, 0xffffffff,
404         0x000008f8, 0x00000012, 0xffffffff,
405         0x000008fc, 0x00000000, 0xffffffff,
406         0x000008f8, 0x00000013, 0xffffffff,
407         0x000008fc, 0x00000000, 0xffffffff,
408         0x000008f8, 0x00000014, 0xffffffff,
409         0x000008fc, 0x00000000, 0xffffffff,
410         0x000008f8, 0x00000015, 0xffffffff,
411         0x000008fc, 0x00000000, 0xffffffff,
412         0x000008f8, 0x00000016, 0xffffffff,
413         0x000008fc, 0x00000000, 0xffffffff,
414         0x000008f8, 0x00000017, 0xffffffff,
415         0x000008fc, 0x00000000, 0xffffffff,
416         0x000008f8, 0x00000018, 0xffffffff,
417         0x000008fc, 0x00000000, 0xffffffff,
418         0x000008f8, 0x00000019, 0xffffffff,
419         0x000008fc, 0x00000000, 0xffffffff,
420         0x000008f8, 0x0000001a, 0xffffffff,
421         0x000008fc, 0x00000000, 0xffffffff,
422         0x000008f8, 0x0000001b, 0xffffffff,
423         0x000008fc, 0x00000000, 0xffffffff,
424         0x000008f8, 0x00000020, 0xffffffff,
425         0x000008fc, 0x00000000, 0xffffffff,
426         0x000008f8, 0x00000021, 0xffffffff,
427         0x000008fc, 0x00000000, 0xffffffff,
428         0x000008f8, 0x00000022, 0xffffffff,
429         0x000008fc, 0x00000000, 0xffffffff,
430         0x000008f8, 0x00000023, 0xffffffff,
431         0x000008fc, 0x00000000, 0xffffffff,
432         0x000008f8, 0x00000024, 0xffffffff,
433         0x000008fc, 0x00000000, 0xffffffff,
434         0x000008f8, 0x00000025, 0xffffffff,
435         0x000008fc, 0x00000000, 0xffffffff,
436         0x000008f8, 0x00000026, 0xffffffff,
437         0x000008fc, 0x00000000, 0xffffffff,
438         0x000008f8, 0x00000027, 0xffffffff,
439         0x000008fc, 0x00000000, 0xffffffff,
440         0x000008f8, 0x00000028, 0xffffffff,
441         0x000008fc, 0x00000000, 0xffffffff,
442         0x000008f8, 0x00000029, 0xffffffff,
443         0x000008fc, 0x00000000, 0xffffffff,
444         0x000008f8, 0x0000002a, 0xffffffff,
445         0x000008fc, 0x00000000, 0xffffffff,
446         0x000008f8, 0x0000002b, 0xffffffff,
447         0x000008fc, 0x00000000, 0xffffffff
448 };
449 #define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
450
451 static const u32 caicos_cgcg_cgls_disable[] =
452 {
453         0x000008f8, 0x00000010, 0xffffffff,
454         0x000008fc, 0xffffffff, 0xffffffff,
455         0x000008f8, 0x00000011, 0xffffffff,
456         0x000008fc, 0xffffffff, 0xffffffff,
457         0x000008f8, 0x00000012, 0xffffffff,
458         0x000008fc, 0xffffffff, 0xffffffff,
459         0x000008f8, 0x00000013, 0xffffffff,
460         0x000008fc, 0xffffffff, 0xffffffff,
461         0x000008f8, 0x00000014, 0xffffffff,
462         0x000008fc, 0xffffffff, 0xffffffff,
463         0x000008f8, 0x00000015, 0xffffffff,
464         0x000008fc, 0xffffffff, 0xffffffff,
465         0x000008f8, 0x00000016, 0xffffffff,
466         0x000008fc, 0xffffffff, 0xffffffff,
467         0x000008f8, 0x00000017, 0xffffffff,
468         0x000008fc, 0xffffffff, 0xffffffff,
469         0x000008f8, 0x00000018, 0xffffffff,
470         0x000008fc, 0xffffffff, 0xffffffff,
471         0x000008f8, 0x00000019, 0xffffffff,
472         0x000008fc, 0xffffffff, 0xffffffff,
473         0x000008f8, 0x0000001a, 0xffffffff,
474         0x000008fc, 0xffffffff, 0xffffffff,
475         0x000008f8, 0x0000001b, 0xffffffff,
476         0x000008fc, 0xffffffff, 0xffffffff,
477         0x000008f8, 0x00000020, 0xffffffff,
478         0x000008fc, 0x00000000, 0xffffffff,
479         0x000008f8, 0x00000021, 0xffffffff,
480         0x000008fc, 0x00000000, 0xffffffff,
481         0x000008f8, 0x00000022, 0xffffffff,
482         0x000008fc, 0x00000000, 0xffffffff,
483         0x000008f8, 0x00000023, 0xffffffff,
484         0x000008fc, 0x00000000, 0xffffffff,
485         0x000008f8, 0x00000024, 0xffffffff,
486         0x000008fc, 0x00000000, 0xffffffff,
487         0x000008f8, 0x00000025, 0xffffffff,
488         0x000008fc, 0x00000000, 0xffffffff,
489         0x000008f8, 0x00000026, 0xffffffff,
490         0x000008fc, 0x00000000, 0xffffffff,
491         0x000008f8, 0x00000027, 0xffffffff,
492         0x000008fc, 0x00000000, 0xffffffff,
493         0x000008f8, 0x00000028, 0xffffffff,
494         0x000008fc, 0x00000000, 0xffffffff,
495         0x000008f8, 0x00000029, 0xffffffff,
496         0x000008fc, 0x00000000, 0xffffffff,
497         0x000008f8, 0x0000002a, 0xffffffff,
498         0x000008fc, 0x00000000, 0xffffffff,
499         0x000008f8, 0x0000002b, 0xffffffff,
500         0x000008fc, 0x00000000, 0xffffffff,
501         0x00000644, 0x000f7912, 0x001f4180,
502         0x00000644, 0x000f3812, 0x001f4180
503 };
504 #define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
505
506 static const u32 caicos_cgcg_cgls_enable[] =
507 {
508         /* 0x0000c124, 0x84180000, 0x00180000, */
509         0x00000644, 0x000f7892, 0x001f4080,
510         0x000008f8, 0x00000010, 0xffffffff,
511         0x000008fc, 0x00000000, 0xffffffff,
512         0x000008f8, 0x00000011, 0xffffffff,
513         0x000008fc, 0x00000000, 0xffffffff,
514         0x000008f8, 0x00000012, 0xffffffff,
515         0x000008fc, 0x00000000, 0xffffffff,
516         0x000008f8, 0x00000013, 0xffffffff,
517         0x000008fc, 0x00000000, 0xffffffff,
518         0x000008f8, 0x00000014, 0xffffffff,
519         0x000008fc, 0x00000000, 0xffffffff,
520         0x000008f8, 0x00000015, 0xffffffff,
521         0x000008fc, 0x00000000, 0xffffffff,
522         0x000008f8, 0x00000016, 0xffffffff,
523         0x000008fc, 0x00000000, 0xffffffff,
524         0x000008f8, 0x00000017, 0xffffffff,
525         0x000008fc, 0x00000000, 0xffffffff,
526         0x000008f8, 0x00000018, 0xffffffff,
527         0x000008fc, 0x00000000, 0xffffffff,
528         0x000008f8, 0x00000019, 0xffffffff,
529         0x000008fc, 0x00000000, 0xffffffff,
530         0x000008f8, 0x0000001a, 0xffffffff,
531         0x000008fc, 0x00000000, 0xffffffff,
532         0x000008f8, 0x0000001b, 0xffffffff,
533         0x000008fc, 0x00000000, 0xffffffff,
534         0x000008f8, 0x00000020, 0xffffffff,
535         0x000008fc, 0xffffffff, 0xffffffff,
536         0x000008f8, 0x00000021, 0xffffffff,
537         0x000008fc, 0xffffffff, 0xffffffff,
538         0x000008f8, 0x00000022, 0xffffffff,
539         0x000008fc, 0xffffffff, 0xffffffff,
540         0x000008f8, 0x00000023, 0xffffffff,
541         0x000008fc, 0xffffffff, 0xffffffff,
542         0x000008f8, 0x00000024, 0xffffffff,
543         0x000008fc, 0xffffffff, 0xffffffff,
544         0x000008f8, 0x00000025, 0xffffffff,
545         0x000008fc, 0xffffffff, 0xffffffff,
546         0x000008f8, 0x00000026, 0xffffffff,
547         0x000008fc, 0xffffffff, 0xffffffff,
548         0x000008f8, 0x00000027, 0xffffffff,
549         0x000008fc, 0xffffffff, 0xffffffff,
550         0x000008f8, 0x00000028, 0xffffffff,
551         0x000008fc, 0xffffffff, 0xffffffff,
552         0x000008f8, 0x00000029, 0xffffffff,
553         0x000008fc, 0xffffffff, 0xffffffff,
554         0x000008f8, 0x0000002a, 0xffffffff,
555         0x000008fc, 0xffffffff, 0xffffffff,
556         0x000008f8, 0x0000002b, 0xffffffff,
557         0x000008fc, 0xffffffff, 0xffffffff
558 };
559 #define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
560
561 static const u32 caicos_mgcg_default[] =
562 {
563         0x0000802c, 0xc0000000, 0xffffffff,
564         0x00005448, 0x00000100, 0xffffffff,
565         0x000055e4, 0x00600100, 0xffffffff,
566         0x0000160c, 0x00000100, 0xffffffff,
567         0x0000c164, 0x00000100, 0xffffffff,
568         0x00008a18, 0x00000100, 0xffffffff,
569         0x0000897c, 0x06000100, 0xffffffff,
570         0x00008b28, 0x00000100, 0xffffffff,
571         0x00009144, 0x00000100, 0xffffffff,
572         0x00009a60, 0x00000100, 0xffffffff,
573         0x00009868, 0x00000100, 0xffffffff,
574         0x00008d58, 0x00000100, 0xffffffff,
575         0x00009510, 0x00000100, 0xffffffff,
576         0x0000949c, 0x00000100, 0xffffffff,
577         0x00009654, 0x00000100, 0xffffffff,
578         0x00009030, 0x00000100, 0xffffffff,
579         0x00009034, 0x00000100, 0xffffffff,
580         0x00009038, 0x00000100, 0xffffffff,
581         0x0000903c, 0x00000100, 0xffffffff,
582         0x00009040, 0x00000100, 0xffffffff,
583         0x0000a200, 0x00000100, 0xffffffff,
584         0x0000a204, 0x00000100, 0xffffffff,
585         0x0000a208, 0x00000100, 0xffffffff,
586         0x0000a20c, 0x00000100, 0xffffffff,
587         0x0000977c, 0x00000100, 0xffffffff,
588         0x00003f80, 0x00000100, 0xffffffff,
589         0x0000a210, 0x00000100, 0xffffffff,
590         0x0000a214, 0x00000100, 0xffffffff,
591         0x000004d8, 0x00000100, 0xffffffff,
592         0x00009784, 0x00000100, 0xffffffff,
593         0x00009698, 0x00000100, 0xffffffff,
594         0x000004d4, 0x00000200, 0xffffffff,
595         0x000004d0, 0x00000000, 0xffffffff,
596         0x000030cc, 0x00000100, 0xffffffff,
597         0x0000d0c0, 0xff000100, 0xffffffff,
598         0x0000915c, 0x00010000, 0xffffffff,
599         0x00009160, 0x00030002, 0xffffffff,
600         0x00009164, 0x00050004, 0xffffffff,
601         0x00009168, 0x00070006, 0xffffffff,
602         0x00009178, 0x00070000, 0xffffffff,
603         0x0000917c, 0x00030002, 0xffffffff,
604         0x00009180, 0x00050004, 0xffffffff,
605         0x0000918c, 0x00010006, 0xffffffff,
606         0x00009190, 0x00090008, 0xffffffff,
607         0x00009194, 0x00070000, 0xffffffff,
608         0x00009198, 0x00030002, 0xffffffff,
609         0x0000919c, 0x00050004, 0xffffffff,
610         0x000091a8, 0x00010006, 0xffffffff,
611         0x000091ac, 0x00090008, 0xffffffff,
612         0x000091e8, 0x00000000, 0xffffffff,
613         0x00009294, 0x00000000, 0xffffffff,
614         0x000008f8, 0x00000010, 0xffffffff,
615         0x000008fc, 0x00000000, 0xffffffff,
616         0x000008f8, 0x00000011, 0xffffffff,
617         0x000008fc, 0x00000000, 0xffffffff,
618         0x000008f8, 0x00000012, 0xffffffff,
619         0x000008fc, 0x00000000, 0xffffffff,
620         0x000008f8, 0x00000013, 0xffffffff,
621         0x000008fc, 0x00000000, 0xffffffff,
622         0x000008f8, 0x00000014, 0xffffffff,
623         0x000008fc, 0x00000000, 0xffffffff,
624         0x000008f8, 0x00000015, 0xffffffff,
625         0x000008fc, 0x00000000, 0xffffffff,
626         0x000008f8, 0x00000016, 0xffffffff,
627         0x000008fc, 0x00000000, 0xffffffff,
628         0x000008f8, 0x00000017, 0xffffffff,
629         0x000008fc, 0x00000000, 0xffffffff,
630         0x000008f8, 0x00000018, 0xffffffff,
631         0x000008fc, 0x00000000, 0xffffffff,
632         0x000008f8, 0x00000019, 0xffffffff,
633         0x000008fc, 0x00000000, 0xffffffff,
634         0x000008f8, 0x0000001a, 0xffffffff,
635         0x000008fc, 0x00000000, 0xffffffff,
636         0x000008f8, 0x0000001b, 0xffffffff,
637         0x000008fc, 0x00000000, 0xffffffff
638 };
639 #define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
640
641 static const u32 caicos_mgcg_disable[] =
642 {
643         0x0000802c, 0xc0000000, 0xffffffff,
644         0x000008f8, 0x00000000, 0xffffffff,
645         0x000008fc, 0xffffffff, 0xffffffff,
646         0x000008f8, 0x00000001, 0xffffffff,
647         0x000008fc, 0xffffffff, 0xffffffff,
648         0x000008f8, 0x00000002, 0xffffffff,
649         0x000008fc, 0xffffffff, 0xffffffff,
650         0x000008f8, 0x00000003, 0xffffffff,
651         0x000008fc, 0xffffffff, 0xffffffff,
652         0x00009150, 0x00600000, 0xffffffff
653 };
654 #define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
655
656 static const u32 caicos_mgcg_enable[] =
657 {
658         0x0000802c, 0xc0000000, 0xffffffff,
659         0x000008f8, 0x00000000, 0xffffffff,
660         0x000008fc, 0x00000000, 0xffffffff,
661         0x000008f8, 0x00000001, 0xffffffff,
662         0x000008fc, 0x00000000, 0xffffffff,
663         0x000008f8, 0x00000002, 0xffffffff,
664         0x000008fc, 0x00000000, 0xffffffff,
665         0x000008f8, 0x00000003, 0xffffffff,
666         0x000008fc, 0x00000000, 0xffffffff,
667         0x00009150, 0x46944040, 0xffffffff
668 };
669 #define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
670
671 //********* TURKS **************//
672 static const u32 turks_cgcg_cgls_default[] =
673 {
674         0x000008f8, 0x00000010, 0xffffffff,
675         0x000008fc, 0x00000000, 0xffffffff,
676         0x000008f8, 0x00000011, 0xffffffff,
677         0x000008fc, 0x00000000, 0xffffffff,
678         0x000008f8, 0x00000012, 0xffffffff,
679         0x000008fc, 0x00000000, 0xffffffff,
680         0x000008f8, 0x00000013, 0xffffffff,
681         0x000008fc, 0x00000000, 0xffffffff,
682         0x000008f8, 0x00000014, 0xffffffff,
683         0x000008fc, 0x00000000, 0xffffffff,
684         0x000008f8, 0x00000015, 0xffffffff,
685         0x000008fc, 0x00000000, 0xffffffff,
686         0x000008f8, 0x00000016, 0xffffffff,
687         0x000008fc, 0x00000000, 0xffffffff,
688         0x000008f8, 0x00000017, 0xffffffff,
689         0x000008fc, 0x00000000, 0xffffffff,
690         0x000008f8, 0x00000018, 0xffffffff,
691         0x000008fc, 0x00000000, 0xffffffff,
692         0x000008f8, 0x00000019, 0xffffffff,
693         0x000008fc, 0x00000000, 0xffffffff,
694         0x000008f8, 0x0000001a, 0xffffffff,
695         0x000008fc, 0x00000000, 0xffffffff,
696         0x000008f8, 0x0000001b, 0xffffffff,
697         0x000008fc, 0x00000000, 0xffffffff,
698         0x000008f8, 0x00000020, 0xffffffff,
699         0x000008fc, 0x00000000, 0xffffffff,
700         0x000008f8, 0x00000021, 0xffffffff,
701         0x000008fc, 0x00000000, 0xffffffff,
702         0x000008f8, 0x00000022, 0xffffffff,
703         0x000008fc, 0x00000000, 0xffffffff,
704         0x000008f8, 0x00000023, 0xffffffff,
705         0x000008fc, 0x00000000, 0xffffffff,
706         0x000008f8, 0x00000024, 0xffffffff,
707         0x000008fc, 0x00000000, 0xffffffff,
708         0x000008f8, 0x00000025, 0xffffffff,
709         0x000008fc, 0x00000000, 0xffffffff,
710         0x000008f8, 0x00000026, 0xffffffff,
711         0x000008fc, 0x00000000, 0xffffffff,
712         0x000008f8, 0x00000027, 0xffffffff,
713         0x000008fc, 0x00000000, 0xffffffff,
714         0x000008f8, 0x00000028, 0xffffffff,
715         0x000008fc, 0x00000000, 0xffffffff,
716         0x000008f8, 0x00000029, 0xffffffff,
717         0x000008fc, 0x00000000, 0xffffffff,
718         0x000008f8, 0x0000002a, 0xffffffff,
719         0x000008fc, 0x00000000, 0xffffffff,
720         0x000008f8, 0x0000002b, 0xffffffff,
721         0x000008fc, 0x00000000, 0xffffffff
722 };
723 #define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
724
725 static const u32 turks_cgcg_cgls_disable[] =
726 {
727         0x000008f8, 0x00000010, 0xffffffff,
728         0x000008fc, 0xffffffff, 0xffffffff,
729         0x000008f8, 0x00000011, 0xffffffff,
730         0x000008fc, 0xffffffff, 0xffffffff,
731         0x000008f8, 0x00000012, 0xffffffff,
732         0x000008fc, 0xffffffff, 0xffffffff,
733         0x000008f8, 0x00000013, 0xffffffff,
734         0x000008fc, 0xffffffff, 0xffffffff,
735         0x000008f8, 0x00000014, 0xffffffff,
736         0x000008fc, 0xffffffff, 0xffffffff,
737         0x000008f8, 0x00000015, 0xffffffff,
738         0x000008fc, 0xffffffff, 0xffffffff,
739         0x000008f8, 0x00000016, 0xffffffff,
740         0x000008fc, 0xffffffff, 0xffffffff,
741         0x000008f8, 0x00000017, 0xffffffff,
742         0x000008fc, 0xffffffff, 0xffffffff,
743         0x000008f8, 0x00000018, 0xffffffff,
744         0x000008fc, 0xffffffff, 0xffffffff,
745         0x000008f8, 0x00000019, 0xffffffff,
746         0x000008fc, 0xffffffff, 0xffffffff,
747         0x000008f8, 0x0000001a, 0xffffffff,
748         0x000008fc, 0xffffffff, 0xffffffff,
749         0x000008f8, 0x0000001b, 0xffffffff,
750         0x000008fc, 0xffffffff, 0xffffffff,
751         0x000008f8, 0x00000020, 0xffffffff,
752         0x000008fc, 0x00000000, 0xffffffff,
753         0x000008f8, 0x00000021, 0xffffffff,
754         0x000008fc, 0x00000000, 0xffffffff,
755         0x000008f8, 0x00000022, 0xffffffff,
756         0x000008fc, 0x00000000, 0xffffffff,
757         0x000008f8, 0x00000023, 0xffffffff,
758         0x000008fc, 0x00000000, 0xffffffff,
759         0x000008f8, 0x00000024, 0xffffffff,
760         0x000008fc, 0x00000000, 0xffffffff,
761         0x000008f8, 0x00000025, 0xffffffff,
762         0x000008fc, 0x00000000, 0xffffffff,
763         0x000008f8, 0x00000026, 0xffffffff,
764         0x000008fc, 0x00000000, 0xffffffff,
765         0x000008f8, 0x00000027, 0xffffffff,
766         0x000008fc, 0x00000000, 0xffffffff,
767         0x000008f8, 0x00000028, 0xffffffff,
768         0x000008fc, 0x00000000, 0xffffffff,
769         0x000008f8, 0x00000029, 0xffffffff,
770         0x000008fc, 0x00000000, 0xffffffff,
771         0x000008f8, 0x0000002a, 0xffffffff,
772         0x000008fc, 0x00000000, 0xffffffff,
773         0x000008f8, 0x0000002b, 0xffffffff,
774         0x000008fc, 0x00000000, 0xffffffff,
775         0x00000644, 0x000f7912, 0x001f4180,
776         0x00000644, 0x000f3812, 0x001f4180
777 };
778 #define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
779
780 static const u32 turks_cgcg_cgls_enable[] =
781 {
782         /* 0x0000c124, 0x84180000, 0x00180000, */
783         0x00000644, 0x000f7892, 0x001f4080,
784         0x000008f8, 0x00000010, 0xffffffff,
785         0x000008fc, 0x00000000, 0xffffffff,
786         0x000008f8, 0x00000011, 0xffffffff,
787         0x000008fc, 0x00000000, 0xffffffff,
788         0x000008f8, 0x00000012, 0xffffffff,
789         0x000008fc, 0x00000000, 0xffffffff,
790         0x000008f8, 0x00000013, 0xffffffff,
791         0x000008fc, 0x00000000, 0xffffffff,
792         0x000008f8, 0x00000014, 0xffffffff,
793         0x000008fc, 0x00000000, 0xffffffff,
794         0x000008f8, 0x00000015, 0xffffffff,
795         0x000008fc, 0x00000000, 0xffffffff,
796         0x000008f8, 0x00000016, 0xffffffff,
797         0x000008fc, 0x00000000, 0xffffffff,
798         0x000008f8, 0x00000017, 0xffffffff,
799         0x000008fc, 0x00000000, 0xffffffff,
800         0x000008f8, 0x00000018, 0xffffffff,
801         0x000008fc, 0x00000000, 0xffffffff,
802         0x000008f8, 0x00000019, 0xffffffff,
803         0x000008fc, 0x00000000, 0xffffffff,
804         0x000008f8, 0x0000001a, 0xffffffff,
805         0x000008fc, 0x00000000, 0xffffffff,
806         0x000008f8, 0x0000001b, 0xffffffff,
807         0x000008fc, 0x00000000, 0xffffffff,
808         0x000008f8, 0x00000020, 0xffffffff,
809         0x000008fc, 0xffffffff, 0xffffffff,
810         0x000008f8, 0x00000021, 0xffffffff,
811         0x000008fc, 0xffffffff, 0xffffffff,
812         0x000008f8, 0x00000022, 0xffffffff,
813         0x000008fc, 0xffffffff, 0xffffffff,
814         0x000008f8, 0x00000023, 0xffffffff,
815         0x000008fc, 0xffffffff, 0xffffffff,
816         0x000008f8, 0x00000024, 0xffffffff,
817         0x000008fc, 0xffffffff, 0xffffffff,
818         0x000008f8, 0x00000025, 0xffffffff,
819         0x000008fc, 0xffffffff, 0xffffffff,
820         0x000008f8, 0x00000026, 0xffffffff,
821         0x000008fc, 0xffffffff, 0xffffffff,
822         0x000008f8, 0x00000027, 0xffffffff,
823         0x000008fc, 0xffffffff, 0xffffffff,
824         0x000008f8, 0x00000028, 0xffffffff,
825         0x000008fc, 0xffffffff, 0xffffffff,
826         0x000008f8, 0x00000029, 0xffffffff,
827         0x000008fc, 0xffffffff, 0xffffffff,
828         0x000008f8, 0x0000002a, 0xffffffff,
829         0x000008fc, 0xffffffff, 0xffffffff,
830         0x000008f8, 0x0000002b, 0xffffffff,
831         0x000008fc, 0xffffffff, 0xffffffff
832 };
833 #define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
834
835 // These are the sequences for turks_mgcg_shls
836 static const u32 turks_mgcg_default[] =
837 {
838         0x0000802c, 0xc0000000, 0xffffffff,
839         0x00005448, 0x00000100, 0xffffffff,
840         0x000055e4, 0x00600100, 0xffffffff,
841         0x0000160c, 0x00000100, 0xffffffff,
842         0x0000c164, 0x00000100, 0xffffffff,
843         0x00008a18, 0x00000100, 0xffffffff,
844         0x0000897c, 0x06000100, 0xffffffff,
845         0x00008b28, 0x00000100, 0xffffffff,
846         0x00009144, 0x00000100, 0xffffffff,
847         0x00009a60, 0x00000100, 0xffffffff,
848         0x00009868, 0x00000100, 0xffffffff,
849         0x00008d58, 0x00000100, 0xffffffff,
850         0x00009510, 0x00000100, 0xffffffff,
851         0x0000949c, 0x00000100, 0xffffffff,
852         0x00009654, 0x00000100, 0xffffffff,
853         0x00009030, 0x00000100, 0xffffffff,
854         0x00009034, 0x00000100, 0xffffffff,
855         0x00009038, 0x00000100, 0xffffffff,
856         0x0000903c, 0x00000100, 0xffffffff,
857         0x00009040, 0x00000100, 0xffffffff,
858         0x0000a200, 0x00000100, 0xffffffff,
859         0x0000a204, 0x00000100, 0xffffffff,
860         0x0000a208, 0x00000100, 0xffffffff,
861         0x0000a20c, 0x00000100, 0xffffffff,
862         0x0000977c, 0x00000100, 0xffffffff,
863         0x00003f80, 0x00000100, 0xffffffff,
864         0x0000a210, 0x00000100, 0xffffffff,
865         0x0000a214, 0x00000100, 0xffffffff,
866         0x000004d8, 0x00000100, 0xffffffff,
867         0x00009784, 0x00000100, 0xffffffff,
868         0x00009698, 0x00000100, 0xffffffff,
869         0x000004d4, 0x00000200, 0xffffffff,
870         0x000004d0, 0x00000000, 0xffffffff,
871         0x000030cc, 0x00000100, 0xffffffff,
872         0x0000d0c0, 0x00000100, 0xffffffff,
873         0x0000915c, 0x00010000, 0xffffffff,
874         0x00009160, 0x00030002, 0xffffffff,
875         0x00009164, 0x00050004, 0xffffffff,
876         0x00009168, 0x00070006, 0xffffffff,
877         0x00009178, 0x00070000, 0xffffffff,
878         0x0000917c, 0x00030002, 0xffffffff,
879         0x00009180, 0x00050004, 0xffffffff,
880         0x0000918c, 0x00010006, 0xffffffff,
881         0x00009190, 0x00090008, 0xffffffff,
882         0x00009194, 0x00070000, 0xffffffff,
883         0x00009198, 0x00030002, 0xffffffff,
884         0x0000919c, 0x00050004, 0xffffffff,
885         0x000091a8, 0x00010006, 0xffffffff,
886         0x000091ac, 0x00090008, 0xffffffff,
887         0x000091b0, 0x00070000, 0xffffffff,
888         0x000091b4, 0x00030002, 0xffffffff,
889         0x000091b8, 0x00050004, 0xffffffff,
890         0x000091c4, 0x00010006, 0xffffffff,
891         0x000091c8, 0x00090008, 0xffffffff,
892         0x000091cc, 0x00070000, 0xffffffff,
893         0x000091d0, 0x00030002, 0xffffffff,
894         0x000091d4, 0x00050004, 0xffffffff,
895         0x000091e0, 0x00010006, 0xffffffff,
896         0x000091e4, 0x00090008, 0xffffffff,
897         0x000091e8, 0x00000000, 0xffffffff,
898         0x000091ec, 0x00070000, 0xffffffff,
899         0x000091f0, 0x00030002, 0xffffffff,
900         0x000091f4, 0x00050004, 0xffffffff,
901         0x00009200, 0x00010006, 0xffffffff,
902         0x00009204, 0x00090008, 0xffffffff,
903         0x00009208, 0x00070000, 0xffffffff,
904         0x0000920c, 0x00030002, 0xffffffff,
905         0x00009210, 0x00050004, 0xffffffff,
906         0x0000921c, 0x00010006, 0xffffffff,
907         0x00009220, 0x00090008, 0xffffffff,
908         0x00009294, 0x00000000, 0xffffffff,
909         0x000008f8, 0x00000010, 0xffffffff,
910         0x000008fc, 0x00000000, 0xffffffff,
911         0x000008f8, 0x00000011, 0xffffffff,
912         0x000008fc, 0x00000000, 0xffffffff,
913         0x000008f8, 0x00000012, 0xffffffff,
914         0x000008fc, 0x00000000, 0xffffffff,
915         0x000008f8, 0x00000013, 0xffffffff,
916         0x000008fc, 0x00000000, 0xffffffff,
917         0x000008f8, 0x00000014, 0xffffffff,
918         0x000008fc, 0x00000000, 0xffffffff,
919         0x000008f8, 0x00000015, 0xffffffff,
920         0x000008fc, 0x00000000, 0xffffffff,
921         0x000008f8, 0x00000016, 0xffffffff,
922         0x000008fc, 0x00000000, 0xffffffff,
923         0x000008f8, 0x00000017, 0xffffffff,
924         0x000008fc, 0x00000000, 0xffffffff,
925         0x000008f8, 0x00000018, 0xffffffff,
926         0x000008fc, 0x00000000, 0xffffffff,
927         0x000008f8, 0x00000019, 0xffffffff,
928         0x000008fc, 0x00000000, 0xffffffff,
929         0x000008f8, 0x0000001a, 0xffffffff,
930         0x000008fc, 0x00000000, 0xffffffff,
931         0x000008f8, 0x0000001b, 0xffffffff,
932         0x000008fc, 0x00000000, 0xffffffff
933 };
934 #define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
935
936 static const u32 turks_mgcg_disable[] =
937 {
938         0x0000802c, 0xc0000000, 0xffffffff,
939         0x000008f8, 0x00000000, 0xffffffff,
940         0x000008fc, 0xffffffff, 0xffffffff,
941         0x000008f8, 0x00000001, 0xffffffff,
942         0x000008fc, 0xffffffff, 0xffffffff,
943         0x000008f8, 0x00000002, 0xffffffff,
944         0x000008fc, 0xffffffff, 0xffffffff,
945         0x000008f8, 0x00000003, 0xffffffff,
946         0x000008fc, 0xffffffff, 0xffffffff,
947         0x00009150, 0x00600000, 0xffffffff
948 };
949 #define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
950
951 static const u32 turks_mgcg_enable[] =
952 {
953         0x0000802c, 0xc0000000, 0xffffffff,
954         0x000008f8, 0x00000000, 0xffffffff,
955         0x000008fc, 0x00000000, 0xffffffff,
956         0x000008f8, 0x00000001, 0xffffffff,
957         0x000008fc, 0x00000000, 0xffffffff,
958         0x000008f8, 0x00000002, 0xffffffff,
959         0x000008fc, 0x00000000, 0xffffffff,
960         0x000008f8, 0x00000003, 0xffffffff,
961         0x000008fc, 0x00000000, 0xffffffff,
962         0x00009150, 0x6e944000, 0xffffffff
963 };
964 #define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
965
966 #endif
967
968 #ifndef BTC_SYSLS_SEQUENCE
969 #define BTC_SYSLS_SEQUENCE  100
970
971
972 //********* BARTS **************//
973 static const u32 barts_sysls_default[] =
974 {
975         /* Register,   Value,     Mask bits */
976         0x000055e8, 0x00000000, 0xffffffff,
977         0x0000d0bc, 0x00000000, 0xffffffff,
978         0x000015c0, 0x000c1401, 0xffffffff,
979         0x0000264c, 0x000c0400, 0xffffffff,
980         0x00002648, 0x000c0400, 0xffffffff,
981         0x00002650, 0x000c0400, 0xffffffff,
982         0x000020b8, 0x000c0400, 0xffffffff,
983         0x000020bc, 0x000c0400, 0xffffffff,
984         0x000020c0, 0x000c0c80, 0xffffffff,
985         0x0000f4a0, 0x000000c0, 0xffffffff,
986         0x0000f4a4, 0x00680fff, 0xffffffff,
987         0x000004c8, 0x00000001, 0xffffffff,
988         0x000064ec, 0x00000000, 0xffffffff,
989         0x00000c7c, 0x00000000, 0xffffffff,
990         0x00006dfc, 0x00000000, 0xffffffff
991 };
992 #define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
993
994 static const u32 barts_sysls_disable[] =
995 {
996         0x000055e8, 0x00000000, 0xffffffff,
997         0x0000d0bc, 0x00000000, 0xffffffff,
998         0x000015c0, 0x00041401, 0xffffffff,
999         0x0000264c, 0x00040400, 0xffffffff,
1000         0x00002648, 0x00040400, 0xffffffff,
1001         0x00002650, 0x00040400, 0xffffffff,
1002         0x000020b8, 0x00040400, 0xffffffff,
1003         0x000020bc, 0x00040400, 0xffffffff,
1004         0x000020c0, 0x00040c80, 0xffffffff,
1005         0x0000f4a0, 0x000000c0, 0xffffffff,
1006         0x0000f4a4, 0x00680000, 0xffffffff,
1007         0x000004c8, 0x00000001, 0xffffffff,
1008         0x000064ec, 0x00007ffd, 0xffffffff,
1009         0x00000c7c, 0x0000ff00, 0xffffffff,
1010         0x00006dfc, 0x0000007f, 0xffffffff
1011 };
1012 #define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
1013
1014 static const u32 barts_sysls_enable[] =
1015 {
1016         0x000055e8, 0x00000001, 0xffffffff,
1017         0x0000d0bc, 0x00000100, 0xffffffff,
1018         0x000015c0, 0x000c1401, 0xffffffff,
1019         0x0000264c, 0x000c0400, 0xffffffff,
1020         0x00002648, 0x000c0400, 0xffffffff,
1021         0x00002650, 0x000c0400, 0xffffffff,
1022         0x000020b8, 0x000c0400, 0xffffffff,
1023         0x000020bc, 0x000c0400, 0xffffffff,
1024         0x000020c0, 0x000c0c80, 0xffffffff,
1025         0x0000f4a0, 0x000000c0, 0xffffffff,
1026         0x0000f4a4, 0x00680fff, 0xffffffff,
1027         0x000004c8, 0x00000000, 0xffffffff,
1028         0x000064ec, 0x00000000, 0xffffffff,
1029         0x00000c7c, 0x00000000, 0xffffffff,
1030         0x00006dfc, 0x00000000, 0xffffffff
1031 };
1032 #define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
1033
1034 //********* CAICOS **************//
1035 static const u32 caicos_sysls_default[] =
1036 {
1037         0x000055e8, 0x00000000, 0xffffffff,
1038         0x0000d0bc, 0x00000000, 0xffffffff,
1039         0x000015c0, 0x000c1401, 0xffffffff,
1040         0x0000264c, 0x000c0400, 0xffffffff,
1041         0x00002648, 0x000c0400, 0xffffffff,
1042         0x00002650, 0x000c0400, 0xffffffff,
1043         0x000020b8, 0x000c0400, 0xffffffff,
1044         0x000020bc, 0x000c0400, 0xffffffff,
1045         0x0000f4a0, 0x000000c0, 0xffffffff,
1046         0x0000f4a4, 0x00680fff, 0xffffffff,
1047         0x000004c8, 0x00000001, 0xffffffff,
1048         0x000064ec, 0x00000000, 0xffffffff,
1049         0x00000c7c, 0x00000000, 0xffffffff,
1050         0x00006dfc, 0x00000000, 0xffffffff
1051 };
1052 #define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
1053
1054 static const u32 caicos_sysls_disable[] =
1055 {
1056         0x000055e8, 0x00000000, 0xffffffff,
1057         0x0000d0bc, 0x00000000, 0xffffffff,
1058         0x000015c0, 0x00041401, 0xffffffff,
1059         0x0000264c, 0x00040400, 0xffffffff,
1060         0x00002648, 0x00040400, 0xffffffff,
1061         0x00002650, 0x00040400, 0xffffffff,
1062         0x000020b8, 0x00040400, 0xffffffff,
1063         0x000020bc, 0x00040400, 0xffffffff,
1064         0x0000f4a0, 0x000000c0, 0xffffffff,
1065         0x0000f4a4, 0x00680000, 0xffffffff,
1066         0x000004c8, 0x00000001, 0xffffffff,
1067         0x000064ec, 0x00007ffd, 0xffffffff,
1068         0x00000c7c, 0x0000ff00, 0xffffffff,
1069         0x00006dfc, 0x0000007f, 0xffffffff
1070 };
1071 #define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
1072
1073 static const u32 caicos_sysls_enable[] =
1074 {
1075         0x000055e8, 0x00000001, 0xffffffff,
1076         0x0000d0bc, 0x00000100, 0xffffffff,
1077         0x000015c0, 0x000c1401, 0xffffffff,
1078         0x0000264c, 0x000c0400, 0xffffffff,
1079         0x00002648, 0x000c0400, 0xffffffff,
1080         0x00002650, 0x000c0400, 0xffffffff,
1081         0x000020b8, 0x000c0400, 0xffffffff,
1082         0x000020bc, 0x000c0400, 0xffffffff,
1083         0x0000f4a0, 0x000000c0, 0xffffffff,
1084         0x0000f4a4, 0x00680fff, 0xffffffff,
1085         0x000064ec, 0x00000000, 0xffffffff,
1086         0x00000c7c, 0x00000000, 0xffffffff,
1087         0x00006dfc, 0x00000000, 0xffffffff,
1088         0x000004c8, 0x00000000, 0xffffffff
1089 };
1090 #define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
1091
1092 //********* TURKS **************//
1093 static const u32 turks_sysls_default[] =
1094 {
1095         0x000055e8, 0x00000000, 0xffffffff,
1096         0x0000d0bc, 0x00000000, 0xffffffff,
1097         0x000015c0, 0x000c1401, 0xffffffff,
1098         0x0000264c, 0x000c0400, 0xffffffff,
1099         0x00002648, 0x000c0400, 0xffffffff,
1100         0x00002650, 0x000c0400, 0xffffffff,
1101         0x000020b8, 0x000c0400, 0xffffffff,
1102         0x000020bc, 0x000c0400, 0xffffffff,
1103         0x000020c0, 0x000c0c80, 0xffffffff,
1104         0x0000f4a0, 0x000000c0, 0xffffffff,
1105         0x0000f4a4, 0x00680fff, 0xffffffff,
1106         0x000004c8, 0x00000001, 0xffffffff,
1107         0x000064ec, 0x00000000, 0xffffffff,
1108         0x00000c7c, 0x00000000, 0xffffffff,
1109         0x00006dfc, 0x00000000, 0xffffffff
1110 };
1111 #define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
1112
1113 static const u32 turks_sysls_disable[] =
1114 {
1115         0x000055e8, 0x00000000, 0xffffffff,
1116         0x0000d0bc, 0x00000000, 0xffffffff,
1117         0x000015c0, 0x00041401, 0xffffffff,
1118         0x0000264c, 0x00040400, 0xffffffff,
1119         0x00002648, 0x00040400, 0xffffffff,
1120         0x00002650, 0x00040400, 0xffffffff,
1121         0x000020b8, 0x00040400, 0xffffffff,
1122         0x000020bc, 0x00040400, 0xffffffff,
1123         0x000020c0, 0x00040c80, 0xffffffff,
1124         0x0000f4a0, 0x000000c0, 0xffffffff,
1125         0x0000f4a4, 0x00680000, 0xffffffff,
1126         0x000004c8, 0x00000001, 0xffffffff,
1127         0x000064ec, 0x00007ffd, 0xffffffff,
1128         0x00000c7c, 0x0000ff00, 0xffffffff,
1129         0x00006dfc, 0x0000007f, 0xffffffff
1130 };
1131 #define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
1132
1133 static const u32 turks_sysls_enable[] =
1134 {
1135         0x000055e8, 0x00000001, 0xffffffff,
1136         0x0000d0bc, 0x00000100, 0xffffffff,
1137         0x000015c0, 0x000c1401, 0xffffffff,
1138         0x0000264c, 0x000c0400, 0xffffffff,
1139         0x00002648, 0x000c0400, 0xffffffff,
1140         0x00002650, 0x000c0400, 0xffffffff,
1141         0x000020b8, 0x000c0400, 0xffffffff,
1142         0x000020bc, 0x000c0400, 0xffffffff,
1143         0x000020c0, 0x000c0c80, 0xffffffff,
1144         0x0000f4a0, 0x000000c0, 0xffffffff,
1145         0x0000f4a4, 0x00680fff, 0xffffffff,
1146         0x000004c8, 0x00000000, 0xffffffff,
1147         0x000064ec, 0x00000000, 0xffffffff,
1148         0x00000c7c, 0x00000000, 0xffffffff,
1149         0x00006dfc, 0x00000000, 0xffffffff
1150 };
1151 #define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
1152
1153 #endif
1154
1155 u32 btc_valid_sclk[40] =
1156 {
1157         5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
1158         55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
1159         105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
1160         155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
1161 };
1162
1163 static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
1164 {
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                 if (rdev->family >= CHIP_CEDAR) {
2752                         seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
2753                                    current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2754                 } else {
2755                         seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u\n",
2756                                    current_index, pl->sclk, pl->mclk, pl->vddc);
2757                 }
2758         }
2759 }
2760
2761 u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
2762 {
2763         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2764         struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2765
2766         if (low)
2767                 return requested_state->low.sclk;
2768         else
2769                 return requested_state->high.sclk;
2770 }
2771
2772 u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
2773 {
2774         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2775         struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2776
2777         if (low)
2778                 return requested_state->low.mclk;
2779         else
2780                 return requested_state->high.mclk;
2781 }