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