]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/gpu/drm/radeon/btc_dpm.c
Merge tag 'v3.10' into drm-intel-fixes
[linux-imx.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_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
1172                                         u32 clock, u16 max_voltage, u16 *voltage)
1173 {
1174         u32 i;
1175
1176         if ((table == NULL) || (table->count == 0))
1177                 return;
1178
1179         for (i= 0; i < table->count; i++) {
1180                 if (clock <= table->entries[i].clk) {
1181                         if (*voltage < table->entries[i].v)
1182                                 *voltage = (u16)((table->entries[i].v < max_voltage) ?
1183                                                   table->entries[i].v : max_voltage);
1184                         return;
1185                 }
1186         }
1187
1188         *voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
1189 }
1190
1191 static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
1192                                 u32 max_clock, u32 requested_clock)
1193 {
1194         unsigned int i;
1195
1196         if ((clocks == NULL) || (clocks->count == 0))
1197                 return (requested_clock < max_clock) ? requested_clock : max_clock;
1198
1199         for (i = 0; i < clocks->count; i++) {
1200                 if (clocks->values[i] >= requested_clock)
1201                         return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
1202         }
1203
1204         return (clocks->values[clocks->count - 1] < max_clock) ?
1205                 clocks->values[clocks->count - 1] : max_clock;
1206 }
1207
1208 static u32 btc_get_valid_mclk(struct radeon_device *rdev,
1209                               u32 max_mclk, u32 requested_mclk)
1210 {
1211         return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
1212                                     max_mclk, requested_mclk);
1213 }
1214
1215 static u32 btc_get_valid_sclk(struct radeon_device *rdev,
1216                               u32 max_sclk, u32 requested_sclk)
1217 {
1218         return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
1219                                     max_sclk, requested_sclk);
1220 }
1221
1222 void btc_skip_blacklist_clocks(struct radeon_device *rdev,
1223                                const u32 max_sclk, const u32 max_mclk,
1224                                u32 *sclk, u32 *mclk)
1225 {
1226         int i, num_blacklist_clocks;
1227
1228         if ((sclk == NULL) || (mclk == NULL))
1229                 return;
1230
1231         num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
1232
1233         for (i = 0; i < num_blacklist_clocks; i++) {
1234                 if ((btc_blacklist_clocks[i].sclk == *sclk) &&
1235                     (btc_blacklist_clocks[i].mclk == *mclk))
1236                         break;
1237         }
1238
1239         if (i < num_blacklist_clocks) {
1240                 if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
1241                         *sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
1242
1243                         if (*sclk < max_sclk)
1244                                 btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
1245                 }
1246         }
1247 }
1248
1249 void btc_adjust_clock_combinations(struct radeon_device *rdev,
1250                                    const struct radeon_clock_and_voltage_limits *max_limits,
1251                                    struct rv7xx_pl *pl)
1252 {
1253
1254         if ((pl->mclk == 0) || (pl->sclk == 0))
1255                 return;
1256
1257         if (pl->mclk == pl->sclk)
1258                 return;
1259
1260         if (pl->mclk > pl->sclk) {
1261                 if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
1262                         pl->sclk = btc_get_valid_sclk(rdev,
1263                                                       max_limits->sclk,
1264                                                       (pl->mclk +
1265                                                        (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
1266                                                       rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
1267         } else {
1268                 if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
1269                         pl->mclk = btc_get_valid_mclk(rdev,
1270                                                       max_limits->mclk,
1271                                                       pl->sclk -
1272                                                       rdev->pm.dpm.dyn_state.sclk_mclk_delta);
1273         }
1274 }
1275
1276 static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
1277 {
1278         unsigned int i;
1279
1280         for (i = 0; i < table->count; i++) {
1281                 if (voltage <= table->entries[i].value)
1282                         return table->entries[i].value;
1283         }
1284
1285         return table->entries[table->count - 1].value;
1286 }
1287
1288 void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
1289                                    u16 max_vddc, u16 max_vddci,
1290                                    u16 *vddc, u16 *vddci)
1291 {
1292         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1293         u16 new_voltage;
1294
1295         if ((0 == *vddc) || (0 == *vddci))
1296                 return;
1297
1298         if (*vddc > *vddci) {
1299                 if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1300                         new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
1301                                                        (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1302                         *vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
1303                 }
1304         } else {
1305                 if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1306                         new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
1307                                                        (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1308                         *vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
1309                 }
1310         }
1311 }
1312
1313 static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
1314                                              bool enable)
1315 {
1316         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1317         u32 tmp, bif;
1318
1319         tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
1320         if (enable) {
1321                 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
1322                     (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1323                         if (!pi->boot_in_gen2) {
1324                                 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1325                                 bif |= CG_CLIENT_REQ(0xd);
1326                                 WREG32(CG_BIF_REQ_AND_RSP, bif);
1327
1328                                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1329                                 tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
1330                                 tmp |= LC_GEN2_EN_STRAP;
1331
1332                                 tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
1333                                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1334                                 udelay(10);
1335                                 tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
1336                                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1337                         }
1338                 }
1339         } else {
1340                 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
1341                     (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1342                         if (!pi->boot_in_gen2) {
1343                                 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1344                                 bif |= CG_CLIENT_REQ(0xd);
1345                                 WREG32(CG_BIF_REQ_AND_RSP, bif);
1346
1347                                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1348                                 tmp &= ~LC_GEN2_EN_STRAP;
1349                         }
1350                         WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1351                 }
1352         }
1353 }
1354
1355 static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
1356                                          bool enable)
1357 {
1358         btc_enable_bif_dynamic_pcie_gen2(rdev, enable);
1359
1360         if (enable)
1361                 WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
1362         else
1363                 WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
1364 }
1365
1366 static int btc_disable_ulv(struct radeon_device *rdev)
1367 {
1368         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1369
1370         if (eg_pi->ulv.supported) {
1371                 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK)
1372                         return -EINVAL;
1373         }
1374         return 0;
1375 }
1376
1377 static int btc_populate_ulv_state(struct radeon_device *rdev,
1378                                   RV770_SMC_STATETABLE *table)
1379 {
1380         int ret = -EINVAL;
1381         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1382         struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1383
1384         if (ulv_pl->vddc) {
1385                 ret = cypress_convert_power_level_to_smc(rdev,
1386                                                          ulv_pl,
1387                                                          &table->ULVState.levels[0],
1388                                                          PPSMC_DISPLAY_WATERMARK_LOW);
1389                 if (ret == 0) {
1390                         table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
1391                         table->ULVState.levels[0].ACIndex = 1;
1392
1393                         table->ULVState.levels[1] = table->ULVState.levels[0];
1394                         table->ULVState.levels[2] = table->ULVState.levels[0];
1395
1396                         table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC;
1397
1398                         WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT);
1399                         WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT);
1400                 }
1401         }
1402
1403         return ret;
1404 }
1405
1406 static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
1407                                        RV770_SMC_STATETABLE *table)
1408 {
1409         int ret = cypress_populate_smc_acpi_state(rdev, table);
1410
1411         if (ret == 0) {
1412                 table->ACPIState.levels[0].ACIndex = 0;
1413                 table->ACPIState.levels[1].ACIndex = 0;
1414                 table->ACPIState.levels[2].ACIndex = 0;
1415         }
1416
1417         return ret;
1418 }
1419
1420 void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
1421                                   const u32 *sequence, u32 count)
1422 {
1423         u32 i, length = count * 3;
1424         u32 tmp;
1425
1426         for (i = 0; i < length; i+=3) {
1427                 tmp = RREG32(sequence[i]);
1428                 tmp &= ~sequence[i+2];
1429                 tmp |= sequence[i+1] & sequence[i+2];
1430                 WREG32(sequence[i], tmp);
1431         }
1432 }
1433
1434 static void btc_cg_clock_gating_default(struct radeon_device *rdev)
1435 {
1436         u32 count;
1437         const u32 *p = NULL;
1438
1439         if (rdev->family == CHIP_BARTS) {
1440                 p = (const u32 *)&barts_cgcg_cgls_default;
1441                 count = BARTS_CGCG_CGLS_DEFAULT_LENGTH;
1442         } else if (rdev->family == CHIP_TURKS) {
1443                 p = (const u32 *)&turks_cgcg_cgls_default;
1444                 count = TURKS_CGCG_CGLS_DEFAULT_LENGTH;
1445         } else if (rdev->family == CHIP_CAICOS) {
1446                 p = (const u32 *)&caicos_cgcg_cgls_default;
1447                 count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH;
1448         } else
1449                 return;
1450
1451         btc_program_mgcg_hw_sequence(rdev, p, count);
1452 }
1453
1454 static void btc_cg_clock_gating_enable(struct radeon_device *rdev,
1455                                        bool enable)
1456 {
1457         u32 count;
1458         const u32 *p = NULL;
1459
1460         if (enable) {
1461                 if (rdev->family == CHIP_BARTS) {
1462                         p = (const u32 *)&barts_cgcg_cgls_enable;
1463                         count = BARTS_CGCG_CGLS_ENABLE_LENGTH;
1464                 } else if (rdev->family == CHIP_TURKS) {
1465                         p = (const u32 *)&turks_cgcg_cgls_enable;
1466                         count = TURKS_CGCG_CGLS_ENABLE_LENGTH;
1467                 } else if (rdev->family == CHIP_CAICOS) {
1468                         p = (const u32 *)&caicos_cgcg_cgls_enable;
1469                         count = CAICOS_CGCG_CGLS_ENABLE_LENGTH;
1470                 } else
1471                         return;
1472         } else {
1473                 if (rdev->family == CHIP_BARTS) {
1474                         p = (const u32 *)&barts_cgcg_cgls_disable;
1475                         count = BARTS_CGCG_CGLS_DISABLE_LENGTH;
1476                 } else if (rdev->family == CHIP_TURKS) {
1477                         p = (const u32 *)&turks_cgcg_cgls_disable;
1478                         count = TURKS_CGCG_CGLS_DISABLE_LENGTH;
1479                 } else if (rdev->family == CHIP_CAICOS) {
1480                         p = (const u32 *)&caicos_cgcg_cgls_disable;
1481                         count = CAICOS_CGCG_CGLS_DISABLE_LENGTH;
1482                 } else
1483                         return;
1484         }
1485
1486         btc_program_mgcg_hw_sequence(rdev, p, count);
1487 }
1488
1489 static void btc_mg_clock_gating_default(struct radeon_device *rdev)
1490 {
1491         u32 count;
1492         const u32 *p = NULL;
1493
1494         if (rdev->family == CHIP_BARTS) {
1495                 p = (const u32 *)&barts_mgcg_default;
1496                 count = BARTS_MGCG_DEFAULT_LENGTH;
1497         } else if (rdev->family == CHIP_TURKS) {
1498                 p = (const u32 *)&turks_mgcg_default;
1499                 count = TURKS_MGCG_DEFAULT_LENGTH;
1500         } else if (rdev->family == CHIP_CAICOS) {
1501                 p = (const u32 *)&caicos_mgcg_default;
1502                 count = CAICOS_MGCG_DEFAULT_LENGTH;
1503         } else
1504                 return;
1505
1506         btc_program_mgcg_hw_sequence(rdev, p, count);
1507 }
1508
1509 static void btc_mg_clock_gating_enable(struct radeon_device *rdev,
1510                                        bool enable)
1511 {
1512         u32 count;
1513         const u32 *p = NULL;
1514
1515         if (enable) {
1516                 if (rdev->family == CHIP_BARTS) {
1517                         p = (const u32 *)&barts_mgcg_enable;
1518                         count = BARTS_MGCG_ENABLE_LENGTH;
1519                 } else if (rdev->family == CHIP_TURKS) {
1520                         p = (const u32 *)&turks_mgcg_enable;
1521                         count = TURKS_MGCG_ENABLE_LENGTH;
1522                 } else if (rdev->family == CHIP_CAICOS) {
1523                         p = (const u32 *)&caicos_mgcg_enable;
1524                         count = CAICOS_MGCG_ENABLE_LENGTH;
1525                 } else
1526                         return;
1527         } else {
1528                 if (rdev->family == CHIP_BARTS) {
1529                         p = (const u32 *)&barts_mgcg_disable[0];
1530                         count = BARTS_MGCG_DISABLE_LENGTH;
1531                 } else if (rdev->family == CHIP_TURKS) {
1532                         p = (const u32 *)&turks_mgcg_disable[0];
1533                         count = TURKS_MGCG_DISABLE_LENGTH;
1534                 } else if (rdev->family == CHIP_CAICOS) {
1535                         p = (const u32 *)&caicos_mgcg_disable[0];
1536                         count = CAICOS_MGCG_DISABLE_LENGTH;
1537                 } else
1538                         return;
1539         }
1540
1541         btc_program_mgcg_hw_sequence(rdev, p, count);
1542 }
1543
1544 static void btc_ls_clock_gating_default(struct radeon_device *rdev)
1545 {
1546         u32 count;
1547         const u32 *p = NULL;
1548
1549         if (rdev->family == CHIP_BARTS) {
1550                 p = (const u32 *)&barts_sysls_default;
1551                 count = BARTS_SYSLS_DEFAULT_LENGTH;
1552         } else if (rdev->family == CHIP_TURKS) {
1553                 p = (const u32 *)&turks_sysls_default;
1554                 count = TURKS_SYSLS_DEFAULT_LENGTH;
1555         } else if (rdev->family == CHIP_CAICOS) {
1556                 p = (const u32 *)&caicos_sysls_default;
1557                 count = CAICOS_SYSLS_DEFAULT_LENGTH;
1558         } else
1559                 return;
1560
1561         btc_program_mgcg_hw_sequence(rdev, p, count);
1562 }
1563
1564 static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
1565                                        bool enable)
1566 {
1567         u32 count;
1568         const u32 *p = NULL;
1569
1570         if (enable) {
1571                 if (rdev->family == CHIP_BARTS) {
1572                         p = (const u32 *)&barts_sysls_enable;
1573                         count = BARTS_SYSLS_ENABLE_LENGTH;
1574                 } else if (rdev->family == CHIP_TURKS) {
1575                         p = (const u32 *)&turks_sysls_enable;
1576                         count = TURKS_SYSLS_ENABLE_LENGTH;
1577                 } else if (rdev->family == CHIP_CAICOS) {
1578                         p = (const u32 *)&caicos_sysls_enable;
1579                         count = CAICOS_SYSLS_ENABLE_LENGTH;
1580                 } else
1581                         return;
1582         } else {
1583                 if (rdev->family == CHIP_BARTS) {
1584                         p = (const u32 *)&barts_sysls_disable;
1585                         count = BARTS_SYSLS_DISABLE_LENGTH;
1586                 } else if (rdev->family == CHIP_TURKS) {
1587                         p = (const u32 *)&turks_sysls_disable;
1588                         count = TURKS_SYSLS_DISABLE_LENGTH;
1589                 } else if (rdev->family == CHIP_CAICOS) {
1590                         p = (const u32 *)&caicos_sysls_disable;
1591                         count = CAICOS_SYSLS_DISABLE_LENGTH;
1592                 } else
1593                         return;
1594         }
1595
1596         btc_program_mgcg_hw_sequence(rdev, p, count);
1597 }
1598
1599 bool btc_dpm_enabled(struct radeon_device *rdev)
1600 {
1601         if (rv770_is_smc_running(rdev))
1602                 return true;
1603         else
1604                 return false;
1605 }
1606
1607 static int btc_init_smc_table(struct radeon_device *rdev,
1608                               struct radeon_ps *radeon_boot_state)
1609 {
1610         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1611         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1612         RV770_SMC_STATETABLE *table = &pi->smc_statetable;
1613         int ret;
1614
1615         memset(table, 0, sizeof(RV770_SMC_STATETABLE));
1616
1617         cypress_populate_smc_voltage_tables(rdev, table);
1618
1619         switch (rdev->pm.int_thermal_type) {
1620         case THERMAL_TYPE_EVERGREEN:
1621         case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
1622                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
1623                 break;
1624         case THERMAL_TYPE_NONE:
1625                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
1626                 break;
1627         default:
1628                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
1629                 break;
1630         }
1631
1632         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
1633                 table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1634
1635         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
1636                 table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
1637
1638         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
1639                 table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1640
1641         if (pi->mem_gddr5)
1642                 table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1643
1644         ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
1645         if (ret)
1646                 return ret;
1647
1648         if (eg_pi->sclk_deep_sleep)
1649                 WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32),
1650                          ~PSKIP_ON_ALLOW_STOP_HI_MASK);
1651
1652         ret = btc_populate_smc_acpi_state(rdev, table);
1653         if (ret)
1654                 return ret;
1655
1656         if (eg_pi->ulv.supported) {
1657                 ret = btc_populate_ulv_state(rdev, table);
1658                 if (ret)
1659                         eg_pi->ulv.supported = false;
1660         }
1661
1662         table->driverState = table->initialState;
1663
1664         return rv770_copy_bytes_to_smc(rdev,
1665                                        pi->state_table_start,
1666                                        (u8 *)table,
1667                                        sizeof(RV770_SMC_STATETABLE),
1668                                        pi->sram_end);
1669 }
1670
1671 static void btc_set_at_for_uvd(struct radeon_device *rdev,
1672                                struct radeon_ps *radeon_new_state)
1673 {
1674         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1675         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1676         int idx = 0;
1677
1678         if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2))
1679                 idx = 1;
1680
1681         if ((idx == 1) && !eg_pi->smu_uvd_hs) {
1682                 pi->rlp = 10;
1683                 pi->rmp = 100;
1684                 pi->lhp = 100;
1685                 pi->lmp = 10;
1686         } else {
1687                 pi->rlp = eg_pi->ats[idx].rlp;
1688                 pi->rmp = eg_pi->ats[idx].rmp;
1689                 pi->lhp = eg_pi->ats[idx].lhp;
1690                 pi->lmp = eg_pi->ats[idx].lmp;
1691         }
1692
1693 }
1694
1695 void btc_notify_uvd_to_smc(struct radeon_device *rdev,
1696                            struct radeon_ps *radeon_new_state)
1697 {
1698         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1699
1700         if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
1701                 rv770_write_smc_soft_register(rdev,
1702                                               RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
1703                 eg_pi->uvd_enabled = true;
1704         } else {
1705                 rv770_write_smc_soft_register(rdev,
1706                                               RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
1707                 eg_pi->uvd_enabled = false;
1708         }
1709 }
1710
1711 int btc_reset_to_default(struct radeon_device *rdev)
1712 {
1713         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
1714                 return -EINVAL;
1715
1716         return 0;
1717 }
1718
1719 static void btc_stop_smc(struct radeon_device *rdev)
1720 {
1721         int i;
1722
1723         for (i = 0; i < rdev->usec_timeout; i++) {
1724                 if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1)
1725                         break;
1726                 udelay(1);
1727         }
1728         udelay(100);
1729
1730         r7xx_stop_smc(rdev);
1731 }
1732
1733 void btc_read_arb_registers(struct radeon_device *rdev)
1734 {
1735         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1736         struct evergreen_arb_registers *arb_registers =
1737                 &eg_pi->bootup_arb_registers;
1738
1739         arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
1740         arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
1741         arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE);
1742         arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
1743 }
1744
1745
1746 static void btc_set_arb0_registers(struct radeon_device *rdev,
1747                                    struct evergreen_arb_registers *arb_registers)
1748 {
1749         u32 val;
1750
1751         WREG32(MC_ARB_DRAM_TIMING,  arb_registers->mc_arb_dram_timing);
1752         WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2);
1753
1754         val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >>
1755                 POWERMODE0_SHIFT;
1756         WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1757
1758         val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >>
1759                 STATE0_SHIFT;
1760         WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1761 }
1762
1763 static void btc_set_boot_state_timing(struct radeon_device *rdev)
1764 {
1765         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1766
1767         if (eg_pi->ulv.supported)
1768                 btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers);
1769 }
1770
1771 static bool btc_is_state_ulv_compatible(struct radeon_device *rdev,
1772                                         struct radeon_ps *radeon_state)
1773 {
1774         struct rv7xx_ps *state = rv770_get_ps(radeon_state);
1775         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1776         struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1777
1778         if (state->low.mclk != ulv_pl->mclk)
1779                 return false;
1780
1781         if (state->low.vddci != ulv_pl->vddci)
1782                 return false;
1783
1784         /* XXX check minclocks, etc. */
1785
1786         return true;
1787 }
1788
1789
1790 static int btc_set_ulv_dram_timing(struct radeon_device *rdev)
1791 {
1792         u32 val;
1793         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1794         struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1795
1796         radeon_atom_set_engine_dram_timings(rdev,
1797                                             ulv_pl->sclk,
1798                                             ulv_pl->mclk);
1799
1800         val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk);
1801         WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1802
1803         val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk);
1804         WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1805
1806         return 0;
1807 }
1808
1809 static int btc_enable_ulv(struct radeon_device *rdev)
1810 {
1811         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK)
1812                 return -EINVAL;
1813
1814         return 0;
1815 }
1816
1817 static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
1818                                                         struct radeon_ps *radeon_new_state)
1819 {
1820         int ret = 0;
1821         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1822
1823         if (eg_pi->ulv.supported) {
1824                 if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
1825                         // Set ARB[0] to reflect the DRAM timing needed for ULV.
1826                         ret = btc_set_ulv_dram_timing(rdev);
1827                         if (ret == 0)
1828                                 ret = btc_enable_ulv(rdev);
1829                 }
1830         }
1831
1832         return ret;
1833 }
1834
1835 static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
1836 {
1837         bool result = true;
1838
1839         switch (in_reg) {
1840         case MC_SEQ_RAS_TIMING >> 2:
1841                 *out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
1842                 break;
1843         case MC_SEQ_CAS_TIMING >> 2:
1844                 *out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
1845                 break;
1846         case MC_SEQ_MISC_TIMING >> 2:
1847                 *out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
1848                 break;
1849         case MC_SEQ_MISC_TIMING2 >> 2:
1850                 *out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
1851                 break;
1852         case MC_SEQ_RD_CTL_D0 >> 2:
1853                 *out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
1854                 break;
1855         case MC_SEQ_RD_CTL_D1 >> 2:
1856                 *out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
1857                 break;
1858         case MC_SEQ_WR_CTL_D0 >> 2:
1859                 *out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
1860                 break;
1861         case MC_SEQ_WR_CTL_D1 >> 2:
1862                 *out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
1863                 break;
1864         case MC_PMG_CMD_EMRS >> 2:
1865                 *out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1866                 break;
1867         case MC_PMG_CMD_MRS >> 2:
1868                 *out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1869                 break;
1870         case MC_PMG_CMD_MRS1 >> 2:
1871                 *out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1872                 break;
1873         default:
1874                 result = false;
1875                 break;
1876         }
1877
1878         return result;
1879 }
1880
1881 static void btc_set_valid_flag(struct evergreen_mc_reg_table *table)
1882 {
1883         u8 i, j;
1884
1885         for (i = 0; i < table->last; i++) {
1886                 for (j = 1; j < table->num_entries; j++) {
1887                         if (table->mc_reg_table_entry[j-1].mc_data[i] !=
1888                             table->mc_reg_table_entry[j].mc_data[i]) {
1889                                 table->valid_flag |= (1 << i);
1890                                 break;
1891                         }
1892                 }
1893         }
1894 }
1895
1896 static int btc_set_mc_special_registers(struct radeon_device *rdev,
1897                                         struct evergreen_mc_reg_table *table)
1898 {
1899         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1900         u8 i, j, k;
1901         u32 tmp;
1902
1903         for (i = 0, j = table->last; i < table->last; i++) {
1904                 switch (table->mc_reg_address[i].s1) {
1905                 case MC_SEQ_MISC1 >> 2:
1906                         tmp = RREG32(MC_PMG_CMD_EMRS);
1907                         table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
1908                         table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1909                         for (k = 0; k < table->num_entries; k++) {
1910                                 table->mc_reg_table_entry[k].mc_data[j] =
1911                                         ((tmp & 0xffff0000)) |
1912                                         ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
1913                         }
1914                         j++;
1915
1916                         if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1917                                 return -EINVAL;
1918
1919                         tmp = RREG32(MC_PMG_CMD_MRS);
1920                         table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
1921                         table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1922                         for (k = 0; k < table->num_entries; k++) {
1923                                 table->mc_reg_table_entry[k].mc_data[j] =
1924                                         (tmp & 0xffff0000) |
1925                                         (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1926                                 if (!pi->mem_gddr5)
1927                                         table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
1928                         }
1929                         j++;
1930
1931                         if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1932                                 return -EINVAL;
1933                         break;
1934                 case MC_SEQ_RESERVE_M >> 2:
1935                         tmp = RREG32(MC_PMG_CMD_MRS1);
1936                         table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
1937                         table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1938                         for (k = 0; k < table->num_entries; k++) {
1939                                 table->mc_reg_table_entry[k].mc_data[j] =
1940                                         (tmp & 0xffff0000) |
1941                                         (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1942                         }
1943                         j++;
1944
1945                         if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1946                                 return -EINVAL;
1947                         break;
1948                 default:
1949                         break;
1950                 }
1951         }
1952
1953         table->last = j;
1954
1955         return 0;
1956 }
1957
1958 static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table)
1959 {
1960         u32 i;
1961         u16 address;
1962
1963         for (i = 0; i < table->last; i++) {
1964                 table->mc_reg_address[i].s0 =
1965                         btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
1966                         address : table->mc_reg_address[i].s1;
1967         }
1968 }
1969
1970 static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
1971                                        struct evergreen_mc_reg_table *eg_table)
1972 {
1973         u8 i, j;
1974
1975         if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1976                 return -EINVAL;
1977
1978         if (table->num_entries > MAX_AC_TIMING_ENTRIES)
1979                 return -EINVAL;
1980
1981         for (i = 0; i < table->last; i++)
1982                 eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
1983         eg_table->last = table->last;
1984
1985         for (i = 0; i < table->num_entries; i++) {
1986                 eg_table->mc_reg_table_entry[i].mclk_max =
1987                         table->mc_reg_table_entry[i].mclk_max;
1988                 for(j = 0; j < table->last; j++)
1989                         eg_table->mc_reg_table_entry[i].mc_data[j] =
1990                                 table->mc_reg_table_entry[i].mc_data[j];
1991         }
1992         eg_table->num_entries = table->num_entries;
1993
1994         return 0;
1995 }
1996
1997 static int btc_initialize_mc_reg_table(struct radeon_device *rdev)
1998 {
1999         int ret;
2000         struct atom_mc_reg_table *table;
2001         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2002         struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table;
2003         u8 module_index = rv770_get_memory_module_index(rdev);
2004
2005         table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
2006         if (!table)
2007                 return -ENOMEM;
2008
2009         /* Program additional LP registers that are no longer programmed by VBIOS */
2010         WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
2011         WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
2012         WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
2013         WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
2014         WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
2015         WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
2016         WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
2017         WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
2018         WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
2019         WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
2020         WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
2021
2022         ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
2023
2024         if (ret)
2025                 goto init_mc_done;
2026
2027         ret = btc_copy_vbios_mc_reg_table(table, eg_table);
2028
2029         if (ret)
2030                 goto init_mc_done;
2031
2032         btc_set_s0_mc_reg_index(eg_table);
2033         ret = btc_set_mc_special_registers(rdev, eg_table);
2034
2035         if (ret)
2036                 goto init_mc_done;
2037
2038         btc_set_valid_flag(eg_table);
2039
2040 init_mc_done:
2041         kfree(table);
2042
2043         return ret;
2044 }
2045
2046 static void btc_init_stutter_mode(struct radeon_device *rdev)
2047 {
2048         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2049         u32 tmp;
2050
2051         if (pi->mclk_stutter_mode_threshold) {
2052                 if (pi->mem_gddr5) {
2053                         tmp = RREG32(MC_PMG_AUTO_CFG);
2054                         if ((0x200 & tmp) == 0) {
2055                                 tmp = (tmp & 0xfffffc0b) | 0x204;
2056                                 WREG32(MC_PMG_AUTO_CFG, tmp);
2057                         }
2058                 }
2059         }
2060 }
2061
2062 static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
2063                                          struct radeon_ps *rps)
2064 {
2065         struct rv7xx_ps *ps = rv770_get_ps(rps);
2066         struct radeon_clock_and_voltage_limits *max_limits;
2067         bool disable_mclk_switching;
2068         u32 mclk, sclk;
2069         u16 vddc, vddci;
2070
2071         if (rdev->pm.dpm.new_active_crtc_count > 1)
2072                 disable_mclk_switching = true;
2073         else
2074                 disable_mclk_switching = false;
2075
2076         if (rdev->pm.dpm.ac_power)
2077                 max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2078         else
2079                 max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
2080
2081         if (rdev->pm.dpm.ac_power == false) {
2082                 if (ps->high.mclk > max_limits->mclk)
2083                         ps->high.mclk = max_limits->mclk;
2084                 if (ps->high.sclk > max_limits->sclk)
2085                         ps->high.sclk = max_limits->sclk;
2086                 if (ps->high.vddc > max_limits->vddc)
2087                         ps->high.vddc = max_limits->vddc;
2088                 if (ps->high.vddci > max_limits->vddci)
2089                         ps->high.vddci = max_limits->vddci;
2090
2091                 if (ps->medium.mclk > max_limits->mclk)
2092                         ps->medium.mclk = max_limits->mclk;
2093                 if (ps->medium.sclk > max_limits->sclk)
2094                         ps->medium.sclk = max_limits->sclk;
2095                 if (ps->medium.vddc > max_limits->vddc)
2096                         ps->medium.vddc = max_limits->vddc;
2097                 if (ps->medium.vddci > max_limits->vddci)
2098                         ps->medium.vddci = max_limits->vddci;
2099
2100                 if (ps->low.mclk > max_limits->mclk)
2101                         ps->low.mclk = max_limits->mclk;
2102                 if (ps->low.sclk > max_limits->sclk)
2103                         ps->low.sclk = max_limits->sclk;
2104                 if (ps->low.vddc > max_limits->vddc)
2105                         ps->low.vddc = max_limits->vddc;
2106                 if (ps->low.vddci > max_limits->vddci)
2107                         ps->low.vddci = max_limits->vddci;
2108         }
2109
2110         /* XXX validate the min clocks required for display */
2111
2112         if (disable_mclk_switching) {
2113                 sclk = ps->low.sclk;
2114                 mclk = ps->high.mclk;
2115                 vddc = ps->low.vddc;
2116                 vddci = ps->high.vddci;
2117         } else {
2118                 sclk = ps->low.sclk;
2119                 mclk = ps->low.mclk;
2120                 vddc = ps->low.vddc;
2121                 vddci = ps->low.vddci;
2122         }
2123
2124         /* adjusted low state */
2125         ps->low.sclk = sclk;
2126         ps->low.mclk = mclk;
2127         ps->low.vddc = vddc;
2128         ps->low.vddci = vddci;
2129
2130         btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2131                                   &ps->low.sclk, &ps->low.mclk);
2132
2133         /* adjusted medium, high states */
2134         if (ps->medium.sclk < ps->low.sclk)
2135                 ps->medium.sclk = ps->low.sclk;
2136         if (ps->medium.vddc < ps->low.vddc)
2137                 ps->medium.vddc = ps->low.vddc;
2138         if (ps->high.sclk < ps->medium.sclk)
2139                 ps->high.sclk = ps->medium.sclk;
2140         if (ps->high.vddc < ps->medium.vddc)
2141                 ps->high.vddc = ps->medium.vddc;
2142
2143         if (disable_mclk_switching) {
2144                 mclk = ps->low.mclk;
2145                 if (mclk < ps->medium.mclk)
2146                         mclk = ps->medium.mclk;
2147                 if (mclk < ps->high.mclk)
2148                         mclk = ps->high.mclk;
2149                 ps->low.mclk = mclk;
2150                 ps->low.vddci = vddci;
2151                 ps->medium.mclk = mclk;
2152                 ps->medium.vddci = vddci;
2153                 ps->high.mclk = mclk;
2154                 ps->high.vddci = vddci;
2155         } else {
2156                 if (ps->medium.mclk < ps->low.mclk)
2157                         ps->medium.mclk = ps->low.mclk;
2158                 if (ps->medium.vddci < ps->low.vddci)
2159                         ps->medium.vddci = ps->low.vddci;
2160                 if (ps->high.mclk < ps->medium.mclk)
2161                         ps->high.mclk = ps->medium.mclk;
2162                 if (ps->high.vddci < ps->medium.vddci)
2163                         ps->high.vddci = ps->medium.vddci;
2164         }
2165
2166         btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2167                                   &ps->medium.sclk, &ps->medium.mclk);
2168         btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2169                                   &ps->high.sclk, &ps->high.mclk);
2170
2171         btc_adjust_clock_combinations(rdev, max_limits, &ps->low);
2172         btc_adjust_clock_combinations(rdev, max_limits, &ps->medium);
2173         btc_adjust_clock_combinations(rdev, max_limits, &ps->high);
2174
2175         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2176                                            ps->low.sclk, max_limits->vddc, &ps->low.vddc);
2177         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2178                                            ps->low.mclk, max_limits->vddci, &ps->low.vddci);
2179         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2180                                            ps->low.mclk, max_limits->vddc, &ps->low.vddc);
2181         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2182                                            rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
2183
2184         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2185                                            ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
2186         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2187                                            ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
2188         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2189                                            ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
2190         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2191                                            rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
2192
2193         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2194                                            ps->high.sclk, max_limits->vddc, &ps->high.vddc);
2195         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2196                                            ps->high.mclk, max_limits->vddci, &ps->high.vddci);
2197         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2198                                            ps->high.mclk, max_limits->vddc, &ps->high.vddc);
2199         btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2200                                            rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
2201
2202         btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2203                                       &ps->low.vddc, &ps->low.vddci);
2204         btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2205                                       &ps->medium.vddc, &ps->medium.vddci);
2206         btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2207                                       &ps->high.vddc, &ps->high.vddci);
2208
2209         if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2210             (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2211             (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc))
2212                 ps->dc_compatible = true;
2213         else
2214                 ps->dc_compatible = false;
2215
2216         if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2217                 ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2218         if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2219                 ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2220         if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2221                 ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2222 }
2223
2224 static void btc_update_current_ps(struct radeon_device *rdev,
2225                                   struct radeon_ps *rps)
2226 {
2227         struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2228         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2229
2230         eg_pi->current_rps = *rps;
2231         eg_pi->current_ps = *new_ps;
2232         eg_pi->current_rps.ps_priv = &eg_pi->current_ps;
2233 }
2234
2235 static void btc_update_requested_ps(struct radeon_device *rdev,
2236                                     struct radeon_ps *rps)
2237 {
2238         struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2239         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2240
2241         eg_pi->requested_rps = *rps;
2242         eg_pi->requested_ps = *new_ps;
2243         eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
2244 }
2245
2246 void btc_dpm_reset_asic(struct radeon_device *rdev)
2247 {
2248         rv770_restrict_performance_levels_before_switch(rdev);
2249         btc_disable_ulv(rdev);
2250         btc_set_boot_state_timing(rdev);
2251         rv770_set_boot_state(rdev);
2252 }
2253
2254 int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
2255 {
2256         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2257         struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
2258         struct radeon_ps *new_ps = &requested_ps;
2259
2260         btc_update_requested_ps(rdev, new_ps);
2261
2262         btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
2263
2264         return 0;
2265 }
2266
2267 int btc_dpm_set_power_state(struct radeon_device *rdev)
2268 {
2269         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2270         struct radeon_ps *new_ps = &eg_pi->requested_rps;
2271         struct radeon_ps *old_ps = &eg_pi->current_rps;
2272         int ret;
2273
2274         ret = btc_disable_ulv(rdev);
2275         btc_set_boot_state_timing(rdev);
2276         ret = rv770_restrict_performance_levels_before_switch(rdev);
2277         if (ret) {
2278                 DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
2279                 return ret;
2280         }
2281         if (eg_pi->pcie_performance_request)
2282                 cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
2283
2284         rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
2285         ret = rv770_halt_smc(rdev);
2286         if (ret) {
2287                 DRM_ERROR("rv770_halt_smc failed\n");
2288                 return ret;
2289         }
2290         btc_set_at_for_uvd(rdev, new_ps);
2291         if (eg_pi->smu_uvd_hs)
2292                 btc_notify_uvd_to_smc(rdev, new_ps);
2293         ret = cypress_upload_sw_state(rdev, new_ps);
2294         if (ret) {
2295                 DRM_ERROR("cypress_upload_sw_state failed\n");
2296                 return ret;
2297         }
2298         if (eg_pi->dynamic_ac_timing) {
2299                 ret = cypress_upload_mc_reg_table(rdev, new_ps);
2300                 if (ret) {
2301                         DRM_ERROR("cypress_upload_mc_reg_table failed\n");
2302                         return ret;
2303                 }
2304         }
2305
2306         cypress_program_memory_timing_parameters(rdev, new_ps);
2307
2308         ret = rv770_resume_smc(rdev);
2309         if (ret) {
2310                 DRM_ERROR("rv770_resume_smc failed\n");
2311                 return ret;
2312         }
2313         ret = rv770_set_sw_state(rdev);
2314         if (ret) {
2315                 DRM_ERROR("rv770_set_sw_state failed\n");
2316                 return ret;
2317         }
2318         rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
2319
2320         if (eg_pi->pcie_performance_request)
2321                 cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
2322
2323         ret = btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);
2324         if (ret) {
2325                 DRM_ERROR("btc_set_power_state_conditionally_enable_ulv failed\n");
2326                 return ret;
2327         }
2328
2329 #if 0
2330         /* XXX */
2331         ret = rv770_unrestrict_performance_levels_after_switch(rdev);
2332         if (ret) {
2333                 DRM_ERROR("rv770_unrestrict_performance_levels_after_switch failed\n");
2334                 return ret;
2335         }
2336 #endif
2337
2338         return 0;
2339 }
2340
2341 void btc_dpm_post_set_power_state(struct radeon_device *rdev)
2342 {
2343         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2344         struct radeon_ps *new_ps = &eg_pi->requested_rps;
2345
2346         btc_update_current_ps(rdev, new_ps);
2347 }
2348
2349 int btc_dpm_enable(struct radeon_device *rdev)
2350 {
2351         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2352         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2353         struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
2354         int ret;
2355
2356         if (pi->gfx_clock_gating)
2357                 btc_cg_clock_gating_default(rdev);
2358
2359         if (btc_dpm_enabled(rdev))
2360                 return -EINVAL;
2361
2362         if (pi->mg_clock_gating)
2363                 btc_mg_clock_gating_default(rdev);
2364
2365         if (eg_pi->ls_clock_gating)
2366                 btc_ls_clock_gating_default(rdev);
2367
2368         if (pi->voltage_control) {
2369                 rv770_enable_voltage_control(rdev, true);
2370                 ret = cypress_construct_voltage_tables(rdev);
2371                 if (ret) {
2372                         DRM_ERROR("cypress_construct_voltage_tables failed\n");
2373                         return ret;
2374                 }
2375         }
2376
2377         if (pi->mvdd_control) {
2378                 ret = cypress_get_mvdd_configuration(rdev);
2379                 if (ret) {
2380                         DRM_ERROR("cypress_get_mvdd_configuration failed\n");
2381                         return ret;
2382                 }
2383         }
2384
2385         if (eg_pi->dynamic_ac_timing) {
2386                 ret = btc_initialize_mc_reg_table(rdev);
2387                 if (ret)
2388                         eg_pi->dynamic_ac_timing = false;
2389         }
2390
2391         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
2392                 rv770_enable_backbias(rdev, true);
2393
2394         if (pi->dynamic_ss)
2395                 cypress_enable_spread_spectrum(rdev, true);
2396
2397         if (pi->thermal_protection)
2398                 rv770_enable_thermal_protection(rdev, true);
2399
2400         rv770_setup_bsp(rdev);
2401         rv770_program_git(rdev);
2402         rv770_program_tp(rdev);
2403         rv770_program_tpp(rdev);
2404         rv770_program_sstp(rdev);
2405         rv770_program_engine_speed_parameters(rdev);
2406         cypress_enable_display_gap(rdev);
2407         rv770_program_vc(rdev);
2408
2409         if (pi->dynamic_pcie_gen2)
2410                 btc_enable_dynamic_pcie_gen2(rdev, true);
2411
2412         ret = rv770_upload_firmware(rdev);
2413         if (ret) {
2414                 DRM_ERROR("rv770_upload_firmware failed\n");
2415                 return ret;
2416         }
2417         ret = cypress_get_table_locations(rdev);
2418         if (ret) {
2419                 DRM_ERROR("cypress_get_table_locations failed\n");
2420                 return ret;
2421         }
2422         ret = btc_init_smc_table(rdev, boot_ps);
2423         if (ret)
2424                 return ret;
2425
2426         if (eg_pi->dynamic_ac_timing) {
2427                 ret = cypress_populate_mc_reg_table(rdev, boot_ps);
2428                 if (ret) {
2429                         DRM_ERROR("cypress_populate_mc_reg_table failed\n");
2430                         return ret;
2431                 }
2432         }
2433
2434         cypress_program_response_times(rdev);
2435         r7xx_start_smc(rdev);
2436         ret = cypress_notify_smc_display_change(rdev, false);
2437         if (ret) {
2438                 DRM_ERROR("cypress_notify_smc_display_change failed\n");
2439                 return ret;
2440         }
2441         cypress_enable_sclk_control(rdev, true);
2442
2443         if (eg_pi->memory_transition)
2444                 cypress_enable_mclk_control(rdev, true);
2445
2446         cypress_start_dpm(rdev);
2447
2448         if (pi->gfx_clock_gating)
2449                 btc_cg_clock_gating_enable(rdev, true);
2450
2451         if (pi->mg_clock_gating)
2452                 btc_mg_clock_gating_enable(rdev, true);
2453
2454         if (eg_pi->ls_clock_gating)
2455                 btc_ls_clock_gating_enable(rdev, true);
2456
2457         if (rdev->irq.installed &&
2458             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
2459                 PPSMC_Result result;
2460
2461                 ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
2462                 if (ret)
2463                         return ret;
2464                 rdev->irq.dpm_thermal = true;
2465                 radeon_irq_set(rdev);
2466                 result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
2467
2468                 if (result != PPSMC_Result_OK)
2469                         DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
2470         }
2471
2472         rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
2473
2474         btc_init_stutter_mode(rdev);
2475
2476         btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2477
2478         return 0;
2479 };
2480
2481 void btc_dpm_disable(struct radeon_device *rdev)
2482 {
2483         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2484         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2485
2486         if (!btc_dpm_enabled(rdev))
2487                 return;
2488
2489         rv770_clear_vc(rdev);
2490
2491         if (pi->thermal_protection)
2492                 rv770_enable_thermal_protection(rdev, false);
2493
2494         if (pi->dynamic_pcie_gen2)
2495                 btc_enable_dynamic_pcie_gen2(rdev, false);
2496
2497         if (rdev->irq.installed &&
2498             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
2499                 rdev->irq.dpm_thermal = false;
2500                 radeon_irq_set(rdev);
2501         }
2502
2503         if (pi->gfx_clock_gating)
2504                 btc_cg_clock_gating_enable(rdev, false);
2505
2506         if (pi->mg_clock_gating)
2507                 btc_mg_clock_gating_enable(rdev, false);
2508
2509         if (eg_pi->ls_clock_gating)
2510                 btc_ls_clock_gating_enable(rdev, false);
2511
2512         rv770_stop_dpm(rdev);
2513         btc_reset_to_default(rdev);
2514         btc_stop_smc(rdev);
2515         cypress_enable_spread_spectrum(rdev, false);
2516
2517         btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2518 }
2519
2520 void btc_dpm_setup_asic(struct radeon_device *rdev)
2521 {
2522         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2523
2524         rv770_get_memory_type(rdev);
2525         rv740_read_clock_registers(rdev);
2526         btc_read_arb_registers(rdev);
2527         rv770_read_voltage_smio_registers(rdev);
2528
2529         if (eg_pi->pcie_performance_request)
2530                 cypress_advertise_gen2_capability(rdev);
2531
2532         rv770_get_pcie_gen2_status(rdev);
2533         rv770_enable_acpi_pm(rdev);
2534 }
2535
2536 int btc_dpm_init(struct radeon_device *rdev)
2537 {
2538         struct rv7xx_power_info *pi;
2539         struct evergreen_power_info *eg_pi;
2540         int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
2541         u16 data_offset, size;
2542         u8 frev, crev;
2543         struct atom_clock_dividers dividers;
2544         int ret;
2545
2546         eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
2547         if (eg_pi == NULL)
2548                 return -ENOMEM;
2549         rdev->pm.dpm.priv = eg_pi;
2550         pi = &eg_pi->rv7xx;
2551
2552         rv770_get_max_vddc(rdev);
2553
2554         eg_pi->ulv.supported = false;
2555         pi->acpi_vddc = 0;
2556         eg_pi->acpi_vddci = 0;
2557         pi->min_vddc_in_table = 0;
2558         pi->max_vddc_in_table = 0;
2559
2560         ret = rv7xx_parse_power_table(rdev);
2561         if (ret)
2562                 return ret;
2563         ret = r600_parse_extended_power_table(rdev);
2564         if (ret)
2565                 return ret;
2566
2567         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
2568                 kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
2569         if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
2570                 r600_free_extended_power_table(rdev);
2571                 return -ENOMEM;
2572         }
2573         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
2574         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
2575         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
2576         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
2577         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
2578         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
2579         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
2580         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
2581         rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
2582
2583         if (rdev->pm.dpm.voltage_response_time == 0)
2584                 rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
2585         if (rdev->pm.dpm.backbias_response_time == 0)
2586                 rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
2587
2588         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2589                                              0, false, &dividers);
2590         if (ret)
2591                 pi->ref_div = dividers.ref_div + 1;
2592         else
2593                 pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
2594
2595         pi->mclk_strobe_mode_threshold = 40000;
2596         pi->mclk_edc_enable_threshold = 40000;
2597         eg_pi->mclk_edc_wr_enable_threshold = 40000;
2598
2599         pi->rlp = RV770_RLP_DFLT;
2600         pi->rmp = RV770_RMP_DFLT;
2601         pi->lhp = RV770_LHP_DFLT;
2602         pi->lmp = RV770_LMP_DFLT;
2603
2604         eg_pi->ats[0].rlp = RV770_RLP_DFLT;
2605         eg_pi->ats[0].rmp = RV770_RMP_DFLT;
2606         eg_pi->ats[0].lhp = RV770_LHP_DFLT;
2607         eg_pi->ats[0].lmp = RV770_LMP_DFLT;
2608
2609         eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
2610         eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
2611         eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
2612         eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
2613
2614         eg_pi->smu_uvd_hs = true;
2615
2616         pi->voltage_control =
2617                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
2618
2619         pi->mvdd_control =
2620                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
2621
2622         eg_pi->vddci_control =
2623                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
2624
2625         if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
2626                                    &frev, &crev, &data_offset)) {
2627                 pi->sclk_ss = true;
2628                 pi->mclk_ss = true;
2629                 pi->dynamic_ss = true;
2630         } else {
2631                 pi->sclk_ss = false;
2632                 pi->mclk_ss = false;
2633                 pi->dynamic_ss = true;
2634         }
2635
2636         pi->asi = RV770_ASI_DFLT;
2637         pi->pasi = CYPRESS_HASI_DFLT;
2638         pi->vrc = CYPRESS_VRC_DFLT;
2639
2640         pi->power_gating = false;
2641
2642         pi->gfx_clock_gating = true;
2643
2644         pi->mg_clock_gating = true;
2645         pi->mgcgtssm = true;
2646         eg_pi->ls_clock_gating = false;
2647         eg_pi->sclk_deep_sleep = false;
2648
2649         pi->dynamic_pcie_gen2 = true;
2650
2651         if (pi->gfx_clock_gating &&
2652             (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
2653                 pi->thermal_protection = true;
2654         else
2655                 pi->thermal_protection = false;
2656
2657         pi->display_gap = true;
2658
2659         if (rdev->flags & RADEON_IS_MOBILITY)
2660                 pi->dcodt = true;
2661         else
2662                 pi->dcodt = false;
2663
2664         pi->ulps = true;
2665
2666         eg_pi->dynamic_ac_timing = true;
2667         eg_pi->abm = true;
2668         eg_pi->mcls = true;
2669         eg_pi->light_sleep = true;
2670         eg_pi->memory_transition = true;
2671 #if defined(CONFIG_ACPI)
2672         eg_pi->pcie_performance_request =
2673                 radeon_acpi_is_pcie_performance_request_supported(rdev);
2674 #else
2675         eg_pi->pcie_performance_request = false;
2676 #endif
2677
2678         if (rdev->family == CHIP_BARTS)
2679                 eg_pi->dll_default_on = true;
2680         else
2681                 eg_pi->dll_default_on = false;
2682
2683         eg_pi->sclk_deep_sleep = false;
2684         if (ASIC_IS_LOMBOK(rdev))
2685                 pi->mclk_stutter_mode_threshold = 30000;
2686         else
2687                 pi->mclk_stutter_mode_threshold = 0;
2688
2689         pi->sram_end = SMC_RAM_END;
2690
2691         rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
2692         rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
2693         rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
2694         rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
2695         rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
2696         rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
2697         rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
2698
2699         if (rdev->family == CHIP_TURKS)
2700                 rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
2701         else
2702                 rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
2703
2704         return 0;
2705 }
2706
2707 void btc_dpm_fini(struct radeon_device *rdev)
2708 {
2709         int i;
2710
2711         for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2712                 kfree(rdev->pm.dpm.ps[i].ps_priv);
2713         }
2714         kfree(rdev->pm.dpm.ps);
2715         kfree(rdev->pm.dpm.priv);
2716         kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
2717         r600_free_extended_power_table(rdev);
2718 }
2719
2720 u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
2721 {
2722         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2723         struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2724
2725         if (low)
2726                 return requested_state->low.sclk;
2727         else
2728                 return requested_state->high.sclk;
2729 }
2730
2731 u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
2732 {
2733         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2734         struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2735
2736         if (low)
2737                 return requested_state->low.mclk;
2738         else
2739                 return requested_state->high.mclk;
2740 }