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