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