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