Line data Source code
1 : /*
2 : * Copyright 2010 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 : #include <dev/pci/drm/drmP.h>
25 : #include "radeon.h"
26 : #include "radeon_asic.h"
27 : #include "radeon_audio.h"
28 : #include <dev/pci/drm/radeon_drm.h>
29 : #include "nid.h"
30 : #include "atom.h"
31 : #include "ni_reg.h"
32 : #include "cayman_blit_shaders.h"
33 : #include "radeon_ucode.h"
34 : #include "clearstate_cayman.h"
35 :
36 : /*
37 : * Indirect registers accessor
38 : */
39 0 : u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
40 : {
41 : unsigned long flags;
42 : u32 r;
43 :
44 0 : spin_lock_irqsave(&rdev->smc_idx_lock, flags);
45 0 : WREG32(TN_SMC_IND_INDEX_0, (reg));
46 0 : r = RREG32(TN_SMC_IND_DATA_0);
47 0 : spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
48 0 : return r;
49 : }
50 :
51 0 : void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
52 : {
53 : unsigned long flags;
54 :
55 0 : spin_lock_irqsave(&rdev->smc_idx_lock, flags);
56 0 : WREG32(TN_SMC_IND_INDEX_0, (reg));
57 0 : WREG32(TN_SMC_IND_DATA_0, (v));
58 0 : spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
59 0 : }
60 :
61 : static const u32 tn_rlc_save_restore_register_list[] =
62 : {
63 : 0x98fc,
64 : 0x98f0,
65 : 0x9834,
66 : 0x9838,
67 : 0x9870,
68 : 0x9874,
69 : 0x8a14,
70 : 0x8b24,
71 : 0x8bcc,
72 : 0x8b10,
73 : 0x8c30,
74 : 0x8d00,
75 : 0x8d04,
76 : 0x8c00,
77 : 0x8c04,
78 : 0x8c10,
79 : 0x8c14,
80 : 0x8d8c,
81 : 0x8cf0,
82 : 0x8e38,
83 : 0x9508,
84 : 0x9688,
85 : 0x9608,
86 : 0x960c,
87 : 0x9610,
88 : 0x9614,
89 : 0x88c4,
90 : 0x8978,
91 : 0x88d4,
92 : 0x900c,
93 : 0x9100,
94 : 0x913c,
95 : 0x90e8,
96 : 0x9354,
97 : 0xa008,
98 : 0x98f8,
99 : 0x9148,
100 : 0x914c,
101 : 0x3f94,
102 : 0x98f4,
103 : 0x9b7c,
104 : 0x3f8c,
105 : 0x8950,
106 : 0x8954,
107 : 0x8a18,
108 : 0x8b28,
109 : 0x9144,
110 : 0x3f90,
111 : 0x915c,
112 : 0x9160,
113 : 0x9178,
114 : 0x917c,
115 : 0x9180,
116 : 0x918c,
117 : 0x9190,
118 : 0x9194,
119 : 0x9198,
120 : 0x919c,
121 : 0x91a8,
122 : 0x91ac,
123 : 0x91b0,
124 : 0x91b4,
125 : 0x91b8,
126 : 0x91c4,
127 : 0x91c8,
128 : 0x91cc,
129 : 0x91d0,
130 : 0x91d4,
131 : 0x91e0,
132 : 0x91e4,
133 : 0x91ec,
134 : 0x91f0,
135 : 0x91f4,
136 : 0x9200,
137 : 0x9204,
138 : 0x929c,
139 : 0x8030,
140 : 0x9150,
141 : 0x9a60,
142 : 0x920c,
143 : 0x9210,
144 : 0x9228,
145 : 0x922c,
146 : 0x9244,
147 : 0x9248,
148 : 0x91e8,
149 : 0x9294,
150 : 0x9208,
151 : 0x9224,
152 : 0x9240,
153 : 0x9220,
154 : 0x923c,
155 : 0x9258,
156 : 0x9744,
157 : 0xa200,
158 : 0xa204,
159 : 0xa208,
160 : 0xa20c,
161 : 0x8d58,
162 : 0x9030,
163 : 0x9034,
164 : 0x9038,
165 : 0x903c,
166 : 0x9040,
167 : 0x9654,
168 : 0x897c,
169 : 0xa210,
170 : 0xa214,
171 : 0x9868,
172 : 0xa02c,
173 : 0x9664,
174 : 0x9698,
175 : 0x949c,
176 : 0x8e10,
177 : 0x8e18,
178 : 0x8c50,
179 : 0x8c58,
180 : 0x8c60,
181 : 0x8c68,
182 : 0x89b4,
183 : 0x9830,
184 : 0x802c,
185 : };
186 :
187 : extern bool evergreen_is_display_hung(struct radeon_device *rdev);
188 : extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
189 : extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
190 : extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
191 : extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
192 : extern void evergreen_mc_program(struct radeon_device *rdev);
193 : extern void evergreen_irq_suspend(struct radeon_device *rdev);
194 : extern int evergreen_mc_init(struct radeon_device *rdev);
195 : extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
196 : extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
197 : extern void evergreen_program_aspm(struct radeon_device *rdev);
198 : extern void sumo_rlc_fini(struct radeon_device *rdev);
199 : extern int sumo_rlc_init(struct radeon_device *rdev);
200 : extern void evergreen_gpu_pci_config_reset(struct radeon_device *rdev);
201 :
202 : /* Firmware Names */
203 : MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
204 : MODULE_FIRMWARE("radeon/BARTS_me.bin");
205 : MODULE_FIRMWARE("radeon/BARTS_mc.bin");
206 : MODULE_FIRMWARE("radeon/BARTS_smc.bin");
207 : MODULE_FIRMWARE("radeon/BTC_rlc.bin");
208 : MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
209 : MODULE_FIRMWARE("radeon/TURKS_me.bin");
210 : MODULE_FIRMWARE("radeon/TURKS_mc.bin");
211 : MODULE_FIRMWARE("radeon/TURKS_smc.bin");
212 : MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
213 : MODULE_FIRMWARE("radeon/CAICOS_me.bin");
214 : MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
215 : MODULE_FIRMWARE("radeon/CAICOS_smc.bin");
216 : MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
217 : MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
218 : MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
219 : MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
220 : MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
221 : MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
222 : MODULE_FIRMWARE("radeon/ARUBA_me.bin");
223 : MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
224 :
225 :
226 : static const u32 cayman_golden_registers2[] =
227 : {
228 : 0x3e5c, 0xffffffff, 0x00000000,
229 : 0x3e48, 0xffffffff, 0x00000000,
230 : 0x3e4c, 0xffffffff, 0x00000000,
231 : 0x3e64, 0xffffffff, 0x00000000,
232 : 0x3e50, 0xffffffff, 0x00000000,
233 : 0x3e60, 0xffffffff, 0x00000000
234 : };
235 :
236 : static const u32 cayman_golden_registers[] =
237 : {
238 : 0x5eb4, 0xffffffff, 0x00000002,
239 : 0x5e78, 0x8f311ff1, 0x001000f0,
240 : 0x3f90, 0xffff0000, 0xff000000,
241 : 0x9148, 0xffff0000, 0xff000000,
242 : 0x3f94, 0xffff0000, 0xff000000,
243 : 0x914c, 0xffff0000, 0xff000000,
244 : 0xc78, 0x00000080, 0x00000080,
245 : 0xbd4, 0x70073777, 0x00011003,
246 : 0xd02c, 0xbfffff1f, 0x08421000,
247 : 0xd0b8, 0x73773777, 0x02011003,
248 : 0x5bc0, 0x00200000, 0x50100000,
249 : 0x98f8, 0x33773777, 0x02011003,
250 : 0x98fc, 0xffffffff, 0x76541032,
251 : 0x7030, 0x31000311, 0x00000011,
252 : 0x2f48, 0x33773777, 0x42010001,
253 : 0x6b28, 0x00000010, 0x00000012,
254 : 0x7728, 0x00000010, 0x00000012,
255 : 0x10328, 0x00000010, 0x00000012,
256 : 0x10f28, 0x00000010, 0x00000012,
257 : 0x11b28, 0x00000010, 0x00000012,
258 : 0x12728, 0x00000010, 0x00000012,
259 : 0x240c, 0x000007ff, 0x00000000,
260 : 0x8a14, 0xf000001f, 0x00000007,
261 : 0x8b24, 0x3fff3fff, 0x00ff0fff,
262 : 0x8b10, 0x0000ff0f, 0x00000000,
263 : 0x28a4c, 0x07ffffff, 0x06000000,
264 : 0x10c, 0x00000001, 0x00010003,
265 : 0xa02c, 0xffffffff, 0x0000009b,
266 : 0x913c, 0x0000010f, 0x01000100,
267 : 0x8c04, 0xf8ff00ff, 0x40600060,
268 : 0x28350, 0x00000f01, 0x00000000,
269 : 0x9508, 0x3700001f, 0x00000002,
270 : 0x960c, 0xffffffff, 0x54763210,
271 : 0x88c4, 0x001f3ae3, 0x00000082,
272 : 0x88d0, 0xffffffff, 0x0f40df40,
273 : 0x88d4, 0x0000001f, 0x00000010,
274 : 0x8974, 0xffffffff, 0x00000000
275 : };
276 :
277 : static const u32 dvst_golden_registers2[] =
278 : {
279 : 0x8f8, 0xffffffff, 0,
280 : 0x8fc, 0x00380000, 0,
281 : 0x8f8, 0xffffffff, 1,
282 : 0x8fc, 0x0e000000, 0
283 : };
284 :
285 : static const u32 dvst_golden_registers[] =
286 : {
287 : 0x690, 0x3fff3fff, 0x20c00033,
288 : 0x918c, 0x0fff0fff, 0x00010006,
289 : 0x91a8, 0x0fff0fff, 0x00010006,
290 : 0x9150, 0xffffdfff, 0x6e944040,
291 : 0x917c, 0x0fff0fff, 0x00030002,
292 : 0x9198, 0x0fff0fff, 0x00030002,
293 : 0x915c, 0x0fff0fff, 0x00010000,
294 : 0x3f90, 0xffff0001, 0xff000000,
295 : 0x9178, 0x0fff0fff, 0x00070000,
296 : 0x9194, 0x0fff0fff, 0x00070000,
297 : 0x9148, 0xffff0001, 0xff000000,
298 : 0x9190, 0x0fff0fff, 0x00090008,
299 : 0x91ac, 0x0fff0fff, 0x00090008,
300 : 0x3f94, 0xffff0000, 0xff000000,
301 : 0x914c, 0xffff0000, 0xff000000,
302 : 0x929c, 0x00000fff, 0x00000001,
303 : 0x55e4, 0xff607fff, 0xfc000100,
304 : 0x8a18, 0xff000fff, 0x00000100,
305 : 0x8b28, 0xff000fff, 0x00000100,
306 : 0x9144, 0xfffc0fff, 0x00000100,
307 : 0x6ed8, 0x00010101, 0x00010000,
308 : 0x9830, 0xffffffff, 0x00000000,
309 : 0x9834, 0xf00fffff, 0x00000400,
310 : 0x9838, 0xfffffffe, 0x00000000,
311 : 0xd0c0, 0xff000fff, 0x00000100,
312 : 0xd02c, 0xbfffff1f, 0x08421000,
313 : 0xd0b8, 0x73773777, 0x12010001,
314 : 0x5bb0, 0x000000f0, 0x00000070,
315 : 0x98f8, 0x73773777, 0x12010001,
316 : 0x98fc, 0xffffffff, 0x00000010,
317 : 0x9b7c, 0x00ff0000, 0x00fc0000,
318 : 0x8030, 0x00001f0f, 0x0000100a,
319 : 0x2f48, 0x73773777, 0x12010001,
320 : 0x2408, 0x00030000, 0x000c007f,
321 : 0x8a14, 0xf000003f, 0x00000007,
322 : 0x8b24, 0x3fff3fff, 0x00ff0fff,
323 : 0x8b10, 0x0000ff0f, 0x00000000,
324 : 0x28a4c, 0x07ffffff, 0x06000000,
325 : 0x4d8, 0x00000fff, 0x00000100,
326 : 0xa008, 0xffffffff, 0x00010000,
327 : 0x913c, 0xffff03ff, 0x01000100,
328 : 0x8c00, 0x000000ff, 0x00000003,
329 : 0x8c04, 0xf8ff00ff, 0x40600060,
330 : 0x8cf0, 0x1fff1fff, 0x08e00410,
331 : 0x28350, 0x00000f01, 0x00000000,
332 : 0x9508, 0xf700071f, 0x00000002,
333 : 0x960c, 0xffffffff, 0x54763210,
334 : 0x20ef8, 0x01ff01ff, 0x00000002,
335 : 0x20e98, 0xfffffbff, 0x00200000,
336 : 0x2015c, 0xffffffff, 0x00000f40,
337 : 0x88c4, 0x001f3ae3, 0x00000082,
338 : 0x8978, 0x3fffffff, 0x04050140,
339 : 0x88d4, 0x0000001f, 0x00000010,
340 : 0x8974, 0xffffffff, 0x00000000
341 : };
342 :
343 : static const u32 scrapper_golden_registers[] =
344 : {
345 : 0x690, 0x3fff3fff, 0x20c00033,
346 : 0x918c, 0x0fff0fff, 0x00010006,
347 : 0x918c, 0x0fff0fff, 0x00010006,
348 : 0x91a8, 0x0fff0fff, 0x00010006,
349 : 0x91a8, 0x0fff0fff, 0x00010006,
350 : 0x9150, 0xffffdfff, 0x6e944040,
351 : 0x9150, 0xffffdfff, 0x6e944040,
352 : 0x917c, 0x0fff0fff, 0x00030002,
353 : 0x917c, 0x0fff0fff, 0x00030002,
354 : 0x9198, 0x0fff0fff, 0x00030002,
355 : 0x9198, 0x0fff0fff, 0x00030002,
356 : 0x915c, 0x0fff0fff, 0x00010000,
357 : 0x915c, 0x0fff0fff, 0x00010000,
358 : 0x3f90, 0xffff0001, 0xff000000,
359 : 0x3f90, 0xffff0001, 0xff000000,
360 : 0x9178, 0x0fff0fff, 0x00070000,
361 : 0x9178, 0x0fff0fff, 0x00070000,
362 : 0x9194, 0x0fff0fff, 0x00070000,
363 : 0x9194, 0x0fff0fff, 0x00070000,
364 : 0x9148, 0xffff0001, 0xff000000,
365 : 0x9148, 0xffff0001, 0xff000000,
366 : 0x9190, 0x0fff0fff, 0x00090008,
367 : 0x9190, 0x0fff0fff, 0x00090008,
368 : 0x91ac, 0x0fff0fff, 0x00090008,
369 : 0x91ac, 0x0fff0fff, 0x00090008,
370 : 0x3f94, 0xffff0000, 0xff000000,
371 : 0x3f94, 0xffff0000, 0xff000000,
372 : 0x914c, 0xffff0000, 0xff000000,
373 : 0x914c, 0xffff0000, 0xff000000,
374 : 0x929c, 0x00000fff, 0x00000001,
375 : 0x929c, 0x00000fff, 0x00000001,
376 : 0x55e4, 0xff607fff, 0xfc000100,
377 : 0x8a18, 0xff000fff, 0x00000100,
378 : 0x8a18, 0xff000fff, 0x00000100,
379 : 0x8b28, 0xff000fff, 0x00000100,
380 : 0x8b28, 0xff000fff, 0x00000100,
381 : 0x9144, 0xfffc0fff, 0x00000100,
382 : 0x9144, 0xfffc0fff, 0x00000100,
383 : 0x6ed8, 0x00010101, 0x00010000,
384 : 0x9830, 0xffffffff, 0x00000000,
385 : 0x9830, 0xffffffff, 0x00000000,
386 : 0x9834, 0xf00fffff, 0x00000400,
387 : 0x9834, 0xf00fffff, 0x00000400,
388 : 0x9838, 0xfffffffe, 0x00000000,
389 : 0x9838, 0xfffffffe, 0x00000000,
390 : 0xd0c0, 0xff000fff, 0x00000100,
391 : 0xd02c, 0xbfffff1f, 0x08421000,
392 : 0xd02c, 0xbfffff1f, 0x08421000,
393 : 0xd0b8, 0x73773777, 0x12010001,
394 : 0xd0b8, 0x73773777, 0x12010001,
395 : 0x5bb0, 0x000000f0, 0x00000070,
396 : 0x98f8, 0x73773777, 0x12010001,
397 : 0x98f8, 0x73773777, 0x12010001,
398 : 0x98fc, 0xffffffff, 0x00000010,
399 : 0x98fc, 0xffffffff, 0x00000010,
400 : 0x9b7c, 0x00ff0000, 0x00fc0000,
401 : 0x9b7c, 0x00ff0000, 0x00fc0000,
402 : 0x8030, 0x00001f0f, 0x0000100a,
403 : 0x8030, 0x00001f0f, 0x0000100a,
404 : 0x2f48, 0x73773777, 0x12010001,
405 : 0x2f48, 0x73773777, 0x12010001,
406 : 0x2408, 0x00030000, 0x000c007f,
407 : 0x8a14, 0xf000003f, 0x00000007,
408 : 0x8a14, 0xf000003f, 0x00000007,
409 : 0x8b24, 0x3fff3fff, 0x00ff0fff,
410 : 0x8b24, 0x3fff3fff, 0x00ff0fff,
411 : 0x8b10, 0x0000ff0f, 0x00000000,
412 : 0x8b10, 0x0000ff0f, 0x00000000,
413 : 0x28a4c, 0x07ffffff, 0x06000000,
414 : 0x28a4c, 0x07ffffff, 0x06000000,
415 : 0x4d8, 0x00000fff, 0x00000100,
416 : 0x4d8, 0x00000fff, 0x00000100,
417 : 0xa008, 0xffffffff, 0x00010000,
418 : 0xa008, 0xffffffff, 0x00010000,
419 : 0x913c, 0xffff03ff, 0x01000100,
420 : 0x913c, 0xffff03ff, 0x01000100,
421 : 0x90e8, 0x001fffff, 0x010400c0,
422 : 0x8c00, 0x000000ff, 0x00000003,
423 : 0x8c00, 0x000000ff, 0x00000003,
424 : 0x8c04, 0xf8ff00ff, 0x40600060,
425 : 0x8c04, 0xf8ff00ff, 0x40600060,
426 : 0x8c30, 0x0000000f, 0x00040005,
427 : 0x8cf0, 0x1fff1fff, 0x08e00410,
428 : 0x8cf0, 0x1fff1fff, 0x08e00410,
429 : 0x900c, 0x00ffffff, 0x0017071f,
430 : 0x28350, 0x00000f01, 0x00000000,
431 : 0x28350, 0x00000f01, 0x00000000,
432 : 0x9508, 0xf700071f, 0x00000002,
433 : 0x9508, 0xf700071f, 0x00000002,
434 : 0x9688, 0x00300000, 0x0017000f,
435 : 0x960c, 0xffffffff, 0x54763210,
436 : 0x960c, 0xffffffff, 0x54763210,
437 : 0x20ef8, 0x01ff01ff, 0x00000002,
438 : 0x20e98, 0xfffffbff, 0x00200000,
439 : 0x2015c, 0xffffffff, 0x00000f40,
440 : 0x88c4, 0x001f3ae3, 0x00000082,
441 : 0x88c4, 0x001f3ae3, 0x00000082,
442 : 0x8978, 0x3fffffff, 0x04050140,
443 : 0x8978, 0x3fffffff, 0x04050140,
444 : 0x88d4, 0x0000001f, 0x00000010,
445 : 0x88d4, 0x0000001f, 0x00000010,
446 : 0x8974, 0xffffffff, 0x00000000,
447 : 0x8974, 0xffffffff, 0x00000000
448 : };
449 :
450 0 : static void ni_init_golden_registers(struct radeon_device *rdev)
451 : {
452 0 : switch (rdev->family) {
453 : case CHIP_CAYMAN:
454 0 : radeon_program_register_sequence(rdev,
455 : cayman_golden_registers,
456 : (const u32)ARRAY_SIZE(cayman_golden_registers));
457 0 : radeon_program_register_sequence(rdev,
458 : cayman_golden_registers2,
459 : (const u32)ARRAY_SIZE(cayman_golden_registers2));
460 0 : break;
461 : case CHIP_ARUBA:
462 0 : if ((rdev->pdev->device == 0x9900) ||
463 0 : (rdev->pdev->device == 0x9901) ||
464 0 : (rdev->pdev->device == 0x9903) ||
465 0 : (rdev->pdev->device == 0x9904) ||
466 0 : (rdev->pdev->device == 0x9905) ||
467 0 : (rdev->pdev->device == 0x9906) ||
468 0 : (rdev->pdev->device == 0x9907) ||
469 0 : (rdev->pdev->device == 0x9908) ||
470 0 : (rdev->pdev->device == 0x9909) ||
471 0 : (rdev->pdev->device == 0x990A) ||
472 0 : (rdev->pdev->device == 0x990B) ||
473 0 : (rdev->pdev->device == 0x990C) ||
474 0 : (rdev->pdev->device == 0x990D) ||
475 0 : (rdev->pdev->device == 0x990E) ||
476 0 : (rdev->pdev->device == 0x990F) ||
477 0 : (rdev->pdev->device == 0x9910) ||
478 0 : (rdev->pdev->device == 0x9913) ||
479 0 : (rdev->pdev->device == 0x9917) ||
480 0 : (rdev->pdev->device == 0x9918)) {
481 0 : radeon_program_register_sequence(rdev,
482 : dvst_golden_registers,
483 : (const u32)ARRAY_SIZE(dvst_golden_registers));
484 0 : radeon_program_register_sequence(rdev,
485 : dvst_golden_registers2,
486 : (const u32)ARRAY_SIZE(dvst_golden_registers2));
487 0 : } else {
488 0 : radeon_program_register_sequence(rdev,
489 : scrapper_golden_registers,
490 : (const u32)ARRAY_SIZE(scrapper_golden_registers));
491 0 : radeon_program_register_sequence(rdev,
492 : dvst_golden_registers2,
493 : (const u32)ARRAY_SIZE(dvst_golden_registers2));
494 : }
495 : break;
496 : default:
497 : break;
498 : }
499 0 : }
500 :
501 : #define BTC_IO_MC_REGS_SIZE 29
502 :
503 : static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
504 : {0x00000077, 0xff010100},
505 : {0x00000078, 0x00000000},
506 : {0x00000079, 0x00001434},
507 : {0x0000007a, 0xcc08ec08},
508 : {0x0000007b, 0x00040000},
509 : {0x0000007c, 0x000080c0},
510 : {0x0000007d, 0x09000000},
511 : {0x0000007e, 0x00210404},
512 : {0x00000081, 0x08a8e800},
513 : {0x00000082, 0x00030444},
514 : {0x00000083, 0x00000000},
515 : {0x00000085, 0x00000001},
516 : {0x00000086, 0x00000002},
517 : {0x00000087, 0x48490000},
518 : {0x00000088, 0x20244647},
519 : {0x00000089, 0x00000005},
520 : {0x0000008b, 0x66030000},
521 : {0x0000008c, 0x00006603},
522 : {0x0000008d, 0x00000100},
523 : {0x0000008f, 0x00001c0a},
524 : {0x00000090, 0xff000001},
525 : {0x00000094, 0x00101101},
526 : {0x00000095, 0x00000fff},
527 : {0x00000096, 0x00116fff},
528 : {0x00000097, 0x60010000},
529 : {0x00000098, 0x10010000},
530 : {0x00000099, 0x00006000},
531 : {0x0000009a, 0x00001000},
532 : {0x0000009f, 0x00946a00}
533 : };
534 :
535 : static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
536 : {0x00000077, 0xff010100},
537 : {0x00000078, 0x00000000},
538 : {0x00000079, 0x00001434},
539 : {0x0000007a, 0xcc08ec08},
540 : {0x0000007b, 0x00040000},
541 : {0x0000007c, 0x000080c0},
542 : {0x0000007d, 0x09000000},
543 : {0x0000007e, 0x00210404},
544 : {0x00000081, 0x08a8e800},
545 : {0x00000082, 0x00030444},
546 : {0x00000083, 0x00000000},
547 : {0x00000085, 0x00000001},
548 : {0x00000086, 0x00000002},
549 : {0x00000087, 0x48490000},
550 : {0x00000088, 0x20244647},
551 : {0x00000089, 0x00000005},
552 : {0x0000008b, 0x66030000},
553 : {0x0000008c, 0x00006603},
554 : {0x0000008d, 0x00000100},
555 : {0x0000008f, 0x00001c0a},
556 : {0x00000090, 0xff000001},
557 : {0x00000094, 0x00101101},
558 : {0x00000095, 0x00000fff},
559 : {0x00000096, 0x00116fff},
560 : {0x00000097, 0x60010000},
561 : {0x00000098, 0x10010000},
562 : {0x00000099, 0x00006000},
563 : {0x0000009a, 0x00001000},
564 : {0x0000009f, 0x00936a00}
565 : };
566 :
567 : static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
568 : {0x00000077, 0xff010100},
569 : {0x00000078, 0x00000000},
570 : {0x00000079, 0x00001434},
571 : {0x0000007a, 0xcc08ec08},
572 : {0x0000007b, 0x00040000},
573 : {0x0000007c, 0x000080c0},
574 : {0x0000007d, 0x09000000},
575 : {0x0000007e, 0x00210404},
576 : {0x00000081, 0x08a8e800},
577 : {0x00000082, 0x00030444},
578 : {0x00000083, 0x00000000},
579 : {0x00000085, 0x00000001},
580 : {0x00000086, 0x00000002},
581 : {0x00000087, 0x48490000},
582 : {0x00000088, 0x20244647},
583 : {0x00000089, 0x00000005},
584 : {0x0000008b, 0x66030000},
585 : {0x0000008c, 0x00006603},
586 : {0x0000008d, 0x00000100},
587 : {0x0000008f, 0x00001c0a},
588 : {0x00000090, 0xff000001},
589 : {0x00000094, 0x00101101},
590 : {0x00000095, 0x00000fff},
591 : {0x00000096, 0x00116fff},
592 : {0x00000097, 0x60010000},
593 : {0x00000098, 0x10010000},
594 : {0x00000099, 0x00006000},
595 : {0x0000009a, 0x00001000},
596 : {0x0000009f, 0x00916a00}
597 : };
598 :
599 : static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
600 : {0x00000077, 0xff010100},
601 : {0x00000078, 0x00000000},
602 : {0x00000079, 0x00001434},
603 : {0x0000007a, 0xcc08ec08},
604 : {0x0000007b, 0x00040000},
605 : {0x0000007c, 0x000080c0},
606 : {0x0000007d, 0x09000000},
607 : {0x0000007e, 0x00210404},
608 : {0x00000081, 0x08a8e800},
609 : {0x00000082, 0x00030444},
610 : {0x00000083, 0x00000000},
611 : {0x00000085, 0x00000001},
612 : {0x00000086, 0x00000002},
613 : {0x00000087, 0x48490000},
614 : {0x00000088, 0x20244647},
615 : {0x00000089, 0x00000005},
616 : {0x0000008b, 0x66030000},
617 : {0x0000008c, 0x00006603},
618 : {0x0000008d, 0x00000100},
619 : {0x0000008f, 0x00001c0a},
620 : {0x00000090, 0xff000001},
621 : {0x00000094, 0x00101101},
622 : {0x00000095, 0x00000fff},
623 : {0x00000096, 0x00116fff},
624 : {0x00000097, 0x60010000},
625 : {0x00000098, 0x10010000},
626 : {0x00000099, 0x00006000},
627 : {0x0000009a, 0x00001000},
628 : {0x0000009f, 0x00976b00}
629 : };
630 :
631 0 : int ni_mc_load_microcode(struct radeon_device *rdev)
632 : {
633 : const __be32 *fw_data;
634 : u32 mem_type, running, blackout = 0;
635 : u32 *io_mc_regs;
636 : int i, ucode_size, regs_size;
637 :
638 0 : if (!rdev->mc_fw)
639 0 : return -EINVAL;
640 :
641 0 : switch (rdev->family) {
642 : case CHIP_BARTS:
643 : io_mc_regs = (u32 *)&barts_io_mc_regs;
644 : ucode_size = BTC_MC_UCODE_SIZE;
645 : regs_size = BTC_IO_MC_REGS_SIZE;
646 0 : break;
647 : case CHIP_TURKS:
648 : io_mc_regs = (u32 *)&turks_io_mc_regs;
649 : ucode_size = BTC_MC_UCODE_SIZE;
650 : regs_size = BTC_IO_MC_REGS_SIZE;
651 0 : break;
652 : case CHIP_CAICOS:
653 : default:
654 : io_mc_regs = (u32 *)&caicos_io_mc_regs;
655 : ucode_size = BTC_MC_UCODE_SIZE;
656 : regs_size = BTC_IO_MC_REGS_SIZE;
657 0 : break;
658 : case CHIP_CAYMAN:
659 : io_mc_regs = (u32 *)&cayman_io_mc_regs;
660 : ucode_size = CAYMAN_MC_UCODE_SIZE;
661 : regs_size = BTC_IO_MC_REGS_SIZE;
662 0 : break;
663 : }
664 :
665 0 : mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
666 0 : running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
667 :
668 0 : if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
669 0 : if (running) {
670 0 : blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
671 0 : WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
672 0 : }
673 :
674 : /* reset the engine and set to writable */
675 0 : WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
676 0 : WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
677 :
678 : /* load mc io regs */
679 0 : for (i = 0; i < regs_size; i++) {
680 0 : WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
681 0 : WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
682 : }
683 : /* load the MC ucode */
684 0 : fw_data = (const __be32 *)rdev->mc_fw->data;
685 0 : for (i = 0; i < ucode_size; i++)
686 0 : WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
687 :
688 : /* put the engine back into the active state */
689 0 : WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
690 0 : WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
691 0 : WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
692 :
693 : /* wait for training to complete */
694 0 : for (i = 0; i < rdev->usec_timeout; i++) {
695 0 : if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
696 : break;
697 0 : udelay(1);
698 : }
699 :
700 0 : if (running)
701 0 : WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
702 : }
703 :
704 0 : return 0;
705 0 : }
706 :
707 0 : int ni_init_microcode(struct radeon_device *rdev)
708 : {
709 : const char *chip_name;
710 : const char *rlc_chip_name;
711 : size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
712 : size_t smc_req_size = 0;
713 0 : char fw_name[30];
714 : int err;
715 :
716 : DRM_DEBUG("\n");
717 :
718 0 : switch (rdev->family) {
719 : case CHIP_BARTS:
720 : chip_name = "BARTS";
721 : rlc_chip_name = "BTC";
722 : pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
723 : me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
724 : rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
725 : mc_req_size = BTC_MC_UCODE_SIZE * 4;
726 : smc_req_size = roundup2(BARTS_SMC_UCODE_SIZE, 4);
727 0 : break;
728 : case CHIP_TURKS:
729 : chip_name = "TURKS";
730 : rlc_chip_name = "BTC";
731 : pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
732 : me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
733 : rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
734 : mc_req_size = BTC_MC_UCODE_SIZE * 4;
735 : smc_req_size = roundup2(TURKS_SMC_UCODE_SIZE, 4);
736 0 : break;
737 : case CHIP_CAICOS:
738 : chip_name = "CAICOS";
739 : rlc_chip_name = "BTC";
740 : pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
741 : me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
742 : rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
743 : mc_req_size = BTC_MC_UCODE_SIZE * 4;
744 : smc_req_size = roundup2(CAICOS_SMC_UCODE_SIZE, 4);
745 0 : break;
746 : case CHIP_CAYMAN:
747 : chip_name = "CAYMAN";
748 : rlc_chip_name = "CAYMAN";
749 : pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
750 : me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
751 : rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
752 : mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
753 : smc_req_size = roundup2(CAYMAN_SMC_UCODE_SIZE, 4);
754 0 : break;
755 : case CHIP_ARUBA:
756 : chip_name = "ARUBA";
757 : rlc_chip_name = "ARUBA";
758 : /* pfp/me same size as CAYMAN */
759 : pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
760 : me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
761 : rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
762 : mc_req_size = 0;
763 0 : break;
764 0 : default: BUG();
765 : }
766 :
767 : DRM_INFO("Loading %s Microcode\n", chip_name);
768 :
769 0 : snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
770 0 : err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
771 0 : if (err)
772 : goto out;
773 0 : if (rdev->pfp_fw->size != pfp_req_size) {
774 0 : printk(KERN_ERR
775 : "ni_cp: Bogus length %zu in firmware \"%s\"\n",
776 : rdev->pfp_fw->size, fw_name);
777 : err = -EINVAL;
778 0 : goto out;
779 : }
780 :
781 0 : snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
782 0 : err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
783 0 : if (err)
784 : goto out;
785 0 : if (rdev->me_fw->size != me_req_size) {
786 0 : printk(KERN_ERR
787 : "ni_cp: Bogus length %zu in firmware \"%s\"\n",
788 : rdev->me_fw->size, fw_name);
789 : err = -EINVAL;
790 0 : }
791 :
792 0 : snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
793 0 : err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
794 0 : if (err)
795 : goto out;
796 0 : if (rdev->rlc_fw->size != rlc_req_size) {
797 0 : printk(KERN_ERR
798 : "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
799 : rdev->rlc_fw->size, fw_name);
800 : err = -EINVAL;
801 0 : }
802 :
803 : /* no MC ucode on TN */
804 0 : if (!(rdev->flags & RADEON_IS_IGP)) {
805 0 : snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
806 0 : err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
807 0 : if (err)
808 : goto out;
809 0 : if (rdev->mc_fw->size != mc_req_size) {
810 0 : printk(KERN_ERR
811 : "ni_mc: Bogus length %zu in firmware \"%s\"\n",
812 : rdev->mc_fw->size, fw_name);
813 : err = -EINVAL;
814 0 : }
815 : }
816 :
817 0 : if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
818 0 : snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
819 0 : err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
820 0 : if (err) {
821 0 : printk(KERN_ERR
822 : "smc: error loading firmware \"%s\"\n",
823 : fw_name);
824 0 : release_firmware(rdev->smc_fw);
825 0 : rdev->smc_fw = NULL;
826 : err = 0;
827 0 : } else if (rdev->smc_fw->size != smc_req_size) {
828 0 : printk(KERN_ERR
829 : "ni_mc: Bogus length %zu in firmware \"%s\"\n",
830 : rdev->mc_fw->size, fw_name);
831 : err = -EINVAL;
832 0 : }
833 : }
834 :
835 : out:
836 0 : if (err) {
837 0 : if (err != -EINVAL)
838 0 : printk(KERN_ERR
839 : "ni_cp: Failed to load firmware \"%s\"\n",
840 : fw_name);
841 0 : release_firmware(rdev->pfp_fw);
842 0 : rdev->pfp_fw = NULL;
843 0 : release_firmware(rdev->me_fw);
844 0 : rdev->me_fw = NULL;
845 0 : release_firmware(rdev->rlc_fw);
846 0 : rdev->rlc_fw = NULL;
847 0 : release_firmware(rdev->mc_fw);
848 0 : rdev->mc_fw = NULL;
849 0 : }
850 0 : return err;
851 0 : }
852 :
853 : /**
854 : * cayman_get_allowed_info_register - fetch the register for the info ioctl
855 : *
856 : * @rdev: radeon_device pointer
857 : * @reg: register offset in bytes
858 : * @val: register value
859 : *
860 : * Returns 0 for success or -EINVAL for an invalid register
861 : *
862 : */
863 0 : int cayman_get_allowed_info_register(struct radeon_device *rdev,
864 : u32 reg, u32 *val)
865 : {
866 0 : switch (reg) {
867 : case GRBM_STATUS:
868 : case GRBM_STATUS_SE0:
869 : case GRBM_STATUS_SE1:
870 : case SRBM_STATUS:
871 : case SRBM_STATUS2:
872 : case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
873 : case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
874 : case UVD_STATUS:
875 0 : *val = RREG32(reg);
876 0 : return 0;
877 : default:
878 0 : return -EINVAL;
879 : }
880 0 : }
881 :
882 0 : int tn_get_temp(struct radeon_device *rdev)
883 : {
884 0 : u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
885 0 : int actual_temp = (temp / 8) - 49;
886 :
887 0 : return actual_temp * 1000;
888 : }
889 :
890 : /*
891 : * Core functions
892 : */
893 0 : static void cayman_gpu_init(struct radeon_device *rdev)
894 : {
895 : u32 gb_addr_config = 0;
896 : u32 mc_shared_chmap, mc_arb_ramcfg;
897 : u32 cgts_tcc_disable;
898 : u32 sx_debug_1;
899 : u32 smx_dc_ctl0;
900 : u32 cgts_sm_ctrl_reg;
901 : u32 hdp_host_path_cntl;
902 : u32 tmp;
903 : u32 disabled_rb_mask;
904 : int i, j;
905 :
906 0 : switch (rdev->family) {
907 : case CHIP_CAYMAN:
908 0 : rdev->config.cayman.max_shader_engines = 2;
909 0 : rdev->config.cayman.max_pipes_per_simd = 4;
910 0 : rdev->config.cayman.max_tile_pipes = 8;
911 0 : rdev->config.cayman.max_simds_per_se = 12;
912 0 : rdev->config.cayman.max_backends_per_se = 4;
913 0 : rdev->config.cayman.max_texture_channel_caches = 8;
914 0 : rdev->config.cayman.max_gprs = 256;
915 0 : rdev->config.cayman.max_threads = 256;
916 0 : rdev->config.cayman.max_gs_threads = 32;
917 0 : rdev->config.cayman.max_stack_entries = 512;
918 0 : rdev->config.cayman.sx_num_of_sets = 8;
919 0 : rdev->config.cayman.sx_max_export_size = 256;
920 0 : rdev->config.cayman.sx_max_export_pos_size = 64;
921 0 : rdev->config.cayman.sx_max_export_smx_size = 192;
922 0 : rdev->config.cayman.max_hw_contexts = 8;
923 0 : rdev->config.cayman.sq_num_cf_insts = 2;
924 :
925 0 : rdev->config.cayman.sc_prim_fifo_size = 0x100;
926 0 : rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
927 0 : rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
928 : gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
929 0 : break;
930 : case CHIP_ARUBA:
931 : default:
932 0 : rdev->config.cayman.max_shader_engines = 1;
933 0 : rdev->config.cayman.max_pipes_per_simd = 4;
934 0 : rdev->config.cayman.max_tile_pipes = 2;
935 0 : if ((rdev->pdev->device == 0x9900) ||
936 0 : (rdev->pdev->device == 0x9901) ||
937 0 : (rdev->pdev->device == 0x9905) ||
938 0 : (rdev->pdev->device == 0x9906) ||
939 0 : (rdev->pdev->device == 0x9907) ||
940 0 : (rdev->pdev->device == 0x9908) ||
941 0 : (rdev->pdev->device == 0x9909) ||
942 0 : (rdev->pdev->device == 0x990B) ||
943 0 : (rdev->pdev->device == 0x990C) ||
944 0 : (rdev->pdev->device == 0x990F) ||
945 0 : (rdev->pdev->device == 0x9910) ||
946 0 : (rdev->pdev->device == 0x9917) ||
947 0 : (rdev->pdev->device == 0x9999) ||
948 0 : (rdev->pdev->device == 0x999C)) {
949 0 : rdev->config.cayman.max_simds_per_se = 6;
950 0 : rdev->config.cayman.max_backends_per_se = 2;
951 0 : rdev->config.cayman.max_hw_contexts = 8;
952 0 : rdev->config.cayman.sx_max_export_size = 256;
953 0 : rdev->config.cayman.sx_max_export_pos_size = 64;
954 0 : rdev->config.cayman.sx_max_export_smx_size = 192;
955 0 : } else if ((rdev->pdev->device == 0x9903) ||
956 0 : (rdev->pdev->device == 0x9904) ||
957 0 : (rdev->pdev->device == 0x990A) ||
958 0 : (rdev->pdev->device == 0x990D) ||
959 0 : (rdev->pdev->device == 0x990E) ||
960 0 : (rdev->pdev->device == 0x9913) ||
961 0 : (rdev->pdev->device == 0x9918) ||
962 0 : (rdev->pdev->device == 0x999D)) {
963 0 : rdev->config.cayman.max_simds_per_se = 4;
964 0 : rdev->config.cayman.max_backends_per_se = 2;
965 0 : rdev->config.cayman.max_hw_contexts = 8;
966 0 : rdev->config.cayman.sx_max_export_size = 256;
967 0 : rdev->config.cayman.sx_max_export_pos_size = 64;
968 0 : rdev->config.cayman.sx_max_export_smx_size = 192;
969 0 : } else if ((rdev->pdev->device == 0x9919) ||
970 0 : (rdev->pdev->device == 0x9990) ||
971 0 : (rdev->pdev->device == 0x9991) ||
972 0 : (rdev->pdev->device == 0x9994) ||
973 0 : (rdev->pdev->device == 0x9995) ||
974 0 : (rdev->pdev->device == 0x9996) ||
975 0 : (rdev->pdev->device == 0x999A) ||
976 0 : (rdev->pdev->device == 0x99A0)) {
977 0 : rdev->config.cayman.max_simds_per_se = 3;
978 0 : rdev->config.cayman.max_backends_per_se = 1;
979 0 : rdev->config.cayman.max_hw_contexts = 4;
980 0 : rdev->config.cayman.sx_max_export_size = 128;
981 0 : rdev->config.cayman.sx_max_export_pos_size = 32;
982 0 : rdev->config.cayman.sx_max_export_smx_size = 96;
983 0 : } else {
984 0 : rdev->config.cayman.max_simds_per_se = 2;
985 0 : rdev->config.cayman.max_backends_per_se = 1;
986 0 : rdev->config.cayman.max_hw_contexts = 4;
987 0 : rdev->config.cayman.sx_max_export_size = 128;
988 0 : rdev->config.cayman.sx_max_export_pos_size = 32;
989 0 : rdev->config.cayman.sx_max_export_smx_size = 96;
990 : }
991 0 : rdev->config.cayman.max_texture_channel_caches = 2;
992 0 : rdev->config.cayman.max_gprs = 256;
993 0 : rdev->config.cayman.max_threads = 256;
994 0 : rdev->config.cayman.max_gs_threads = 32;
995 0 : rdev->config.cayman.max_stack_entries = 512;
996 0 : rdev->config.cayman.sx_num_of_sets = 8;
997 0 : rdev->config.cayman.sq_num_cf_insts = 2;
998 :
999 0 : rdev->config.cayman.sc_prim_fifo_size = 0x40;
1000 0 : rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
1001 0 : rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
1002 : gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
1003 0 : break;
1004 : }
1005 :
1006 : /* Initialize HDP */
1007 0 : for (i = 0, j = 0; i < 32; i++, j += 0x18) {
1008 0 : WREG32((0x2c14 + j), 0x00000000);
1009 0 : WREG32((0x2c18 + j), 0x00000000);
1010 0 : WREG32((0x2c1c + j), 0x00000000);
1011 0 : WREG32((0x2c20 + j), 0x00000000);
1012 0 : WREG32((0x2c24 + j), 0x00000000);
1013 : }
1014 :
1015 0 : WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
1016 0 : WREG32(SRBM_INT_CNTL, 0x1);
1017 0 : WREG32(SRBM_INT_ACK, 0x1);
1018 :
1019 0 : evergreen_fix_pci_max_read_req_size(rdev);
1020 :
1021 0 : mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
1022 0 : mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
1023 :
1024 0 : tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
1025 0 : rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
1026 0 : if (rdev->config.cayman.mem_row_size_in_kb > 4)
1027 0 : rdev->config.cayman.mem_row_size_in_kb = 4;
1028 : /* XXX use MC settings? */
1029 0 : rdev->config.cayman.shader_engine_tile_size = 32;
1030 0 : rdev->config.cayman.num_gpus = 1;
1031 0 : rdev->config.cayman.multi_gpu_tile_size = 64;
1032 :
1033 0 : tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
1034 0 : rdev->config.cayman.num_tile_pipes = (1 << tmp);
1035 : tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
1036 0 : rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
1037 0 : tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
1038 0 : rdev->config.cayman.num_shader_engines = tmp + 1;
1039 : tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
1040 0 : rdev->config.cayman.num_gpus = tmp + 1;
1041 : tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
1042 0 : rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
1043 0 : tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
1044 0 : rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
1045 :
1046 :
1047 : /* setup tiling info dword. gb_addr_config is not adequate since it does
1048 : * not have bank info, so create a custom tiling dword.
1049 : * bits 3:0 num_pipes
1050 : * bits 7:4 num_banks
1051 : * bits 11:8 group_size
1052 : * bits 15:12 row_size
1053 : */
1054 0 : rdev->config.cayman.tile_config = 0;
1055 0 : switch (rdev->config.cayman.num_tile_pipes) {
1056 : case 1:
1057 : default:
1058 0 : rdev->config.cayman.tile_config |= (0 << 0);
1059 0 : break;
1060 : case 2:
1061 0 : rdev->config.cayman.tile_config |= (1 << 0);
1062 0 : break;
1063 : case 4:
1064 0 : rdev->config.cayman.tile_config |= (2 << 0);
1065 0 : break;
1066 : case 8:
1067 0 : rdev->config.cayman.tile_config |= (3 << 0);
1068 0 : break;
1069 : }
1070 :
1071 : /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
1072 0 : if (rdev->flags & RADEON_IS_IGP)
1073 0 : rdev->config.cayman.tile_config |= 1 << 4;
1074 : else {
1075 0 : switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
1076 : case 0: /* four banks */
1077 0 : rdev->config.cayman.tile_config |= 0 << 4;
1078 0 : break;
1079 : case 1: /* eight banks */
1080 0 : rdev->config.cayman.tile_config |= 1 << 4;
1081 0 : break;
1082 : case 2: /* sixteen banks */
1083 : default:
1084 0 : rdev->config.cayman.tile_config |= 2 << 4;
1085 0 : break;
1086 : }
1087 : }
1088 0 : rdev->config.cayman.tile_config |=
1089 : ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
1090 0 : rdev->config.cayman.tile_config |=
1091 0 : ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
1092 :
1093 : tmp = 0;
1094 0 : for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
1095 : u32 rb_disable_bitmap;
1096 :
1097 0 : WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1098 0 : WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1099 0 : rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
1100 0 : tmp <<= 4;
1101 0 : tmp |= rb_disable_bitmap;
1102 : }
1103 : /* enabled rb are just the one not disabled :) */
1104 : disabled_rb_mask = tmp;
1105 : tmp = 0;
1106 0 : for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1107 0 : tmp |= (1 << i);
1108 : /* if all the backends are disabled, fix it up here */
1109 0 : if ((disabled_rb_mask & tmp) == tmp) {
1110 0 : for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1111 0 : disabled_rb_mask &= ~(1 << i);
1112 : }
1113 :
1114 0 : for (i = 0; i < rdev->config.cayman.max_shader_engines; i++) {
1115 : u32 simd_disable_bitmap;
1116 :
1117 0 : WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1118 0 : WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1119 0 : simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
1120 0 : simd_disable_bitmap |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
1121 0 : tmp <<= 16;
1122 0 : tmp |= simd_disable_bitmap;
1123 : }
1124 0 : rdev->config.cayman.active_simds = hweight32(~tmp);
1125 :
1126 0 : WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1127 0 : WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1128 :
1129 0 : WREG32(GB_ADDR_CONFIG, gb_addr_config);
1130 0 : WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
1131 0 : if (ASIC_IS_DCE6(rdev))
1132 0 : WREG32(DMIF_ADDR_CALC, gb_addr_config);
1133 0 : WREG32(HDP_ADDR_CONFIG, gb_addr_config);
1134 0 : WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
1135 0 : WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
1136 0 : WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
1137 0 : WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
1138 0 : WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
1139 :
1140 0 : if ((rdev->config.cayman.max_backends_per_se == 1) &&
1141 0 : (rdev->flags & RADEON_IS_IGP)) {
1142 0 : if ((disabled_rb_mask & 3) == 2) {
1143 : /* RB1 disabled, RB0 enabled */
1144 : tmp = 0x00000000;
1145 0 : } else {
1146 : /* RB0 disabled, RB1 enabled */
1147 : tmp = 0x11111111;
1148 : }
1149 : } else {
1150 : tmp = gb_addr_config & NUM_PIPES_MASK;
1151 0 : tmp = r6xx_remap_render_backend(rdev, tmp,
1152 0 : rdev->config.cayman.max_backends_per_se *
1153 0 : rdev->config.cayman.max_shader_engines,
1154 : CAYMAN_MAX_BACKENDS, disabled_rb_mask);
1155 : }
1156 0 : WREG32(GB_BACKEND_MAP, tmp);
1157 :
1158 : cgts_tcc_disable = 0xffff0000;
1159 0 : for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
1160 0 : cgts_tcc_disable &= ~(1 << (16 + i));
1161 0 : WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
1162 0 : WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
1163 0 : WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
1164 0 : WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
1165 :
1166 : /* reprogram the shader complex */
1167 0 : cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
1168 0 : for (i = 0; i < 16; i++)
1169 0 : WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
1170 0 : WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
1171 :
1172 : /* set HW defaults for 3D engine */
1173 0 : WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
1174 :
1175 0 : sx_debug_1 = RREG32(SX_DEBUG_1);
1176 0 : sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1177 0 : WREG32(SX_DEBUG_1, sx_debug_1);
1178 :
1179 0 : smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1180 0 : smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
1181 0 : smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
1182 0 : WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1183 :
1184 0 : WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
1185 :
1186 : /* need to be explicitly zero-ed */
1187 0 : WREG32(VGT_OFFCHIP_LDS_BASE, 0);
1188 0 : WREG32(SQ_LSTMP_RING_BASE, 0);
1189 0 : WREG32(SQ_HSTMP_RING_BASE, 0);
1190 0 : WREG32(SQ_ESTMP_RING_BASE, 0);
1191 0 : WREG32(SQ_GSTMP_RING_BASE, 0);
1192 0 : WREG32(SQ_VSTMP_RING_BASE, 0);
1193 0 : WREG32(SQ_PSTMP_RING_BASE, 0);
1194 :
1195 0 : WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
1196 :
1197 0 : WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
1198 : POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
1199 : SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
1200 :
1201 0 : WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
1202 : SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
1203 : SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
1204 :
1205 :
1206 0 : WREG32(VGT_NUM_INSTANCES, 1);
1207 :
1208 0 : WREG32(CP_PERFMON_CNTL, 0);
1209 :
1210 0 : WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
1211 : FETCH_FIFO_HIWATER(0x4) |
1212 : DONE_FIFO_HIWATER(0xe0) |
1213 : ALU_UPDATE_FIFO_HIWATER(0x8)));
1214 :
1215 0 : WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1216 0 : WREG32(SQ_CONFIG, (VC_ENABLE |
1217 : EXPORT_SRC_C |
1218 : GFX_PRIO(0) |
1219 : CS1_PRIO(0) |
1220 : CS2_PRIO(1)));
1221 0 : WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1222 :
1223 0 : WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1224 : FORCE_EOV_MAX_REZ_CNT(255)));
1225 :
1226 0 : WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1227 : AUTO_INVLD_EN(ES_AND_GS_AUTO));
1228 :
1229 0 : WREG32(VGT_GS_VERTEX_REUSE, 16);
1230 0 : WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1231 :
1232 0 : WREG32(CB_PERF_CTR0_SEL_0, 0);
1233 0 : WREG32(CB_PERF_CTR0_SEL_1, 0);
1234 0 : WREG32(CB_PERF_CTR1_SEL_0, 0);
1235 0 : WREG32(CB_PERF_CTR1_SEL_1, 0);
1236 0 : WREG32(CB_PERF_CTR2_SEL_0, 0);
1237 0 : WREG32(CB_PERF_CTR2_SEL_1, 0);
1238 0 : WREG32(CB_PERF_CTR3_SEL_0, 0);
1239 0 : WREG32(CB_PERF_CTR3_SEL_1, 0);
1240 :
1241 0 : tmp = RREG32(HDP_MISC_CNTL);
1242 0 : tmp |= HDP_FLUSH_INVALIDATE_CACHE;
1243 0 : WREG32(HDP_MISC_CNTL, tmp);
1244 :
1245 0 : hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1246 0 : WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1247 :
1248 0 : WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1249 :
1250 0 : udelay(50);
1251 :
1252 : /* set clockgating golden values on TN */
1253 0 : if (rdev->family == CHIP_ARUBA) {
1254 0 : tmp = RREG32_CG(CG_CGTT_LOCAL_0);
1255 0 : tmp &= ~0x00380000;
1256 0 : WREG32_CG(CG_CGTT_LOCAL_0, tmp);
1257 0 : tmp = RREG32_CG(CG_CGTT_LOCAL_1);
1258 0 : tmp &= ~0x0e000000;
1259 0 : WREG32_CG(CG_CGTT_LOCAL_1, tmp);
1260 0 : }
1261 0 : }
1262 :
1263 : /*
1264 : * GART
1265 : */
1266 0 : void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1267 : {
1268 : /* flush hdp cache */
1269 0 : WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1270 :
1271 : /* bits 0-7 are the VM contexts0-7 */
1272 0 : WREG32(VM_INVALIDATE_REQUEST, 1);
1273 0 : }
1274 :
1275 0 : static int cayman_pcie_gart_enable(struct radeon_device *rdev)
1276 : {
1277 : int i, r;
1278 :
1279 0 : if (rdev->gart.robj == NULL) {
1280 0 : dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1281 0 : return -EINVAL;
1282 : }
1283 0 : r = radeon_gart_table_vram_pin(rdev);
1284 0 : if (r)
1285 0 : return r;
1286 : /* Setup TLB control */
1287 0 : WREG32(MC_VM_MX_L1_TLB_CNTL,
1288 : (0xA << 7) |
1289 : ENABLE_L1_TLB |
1290 : ENABLE_L1_FRAGMENT_PROCESSING |
1291 : SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1292 : ENABLE_ADVANCED_DRIVER_MODEL |
1293 : SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1294 : /* Setup L2 cache */
1295 0 : WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1296 : ENABLE_L2_FRAGMENT_PROCESSING |
1297 : ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1298 : ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1299 : EFFECTIVE_L2_QUEUE_SIZE(7) |
1300 : CONTEXT1_IDENTITY_ACCESS_MODE(1));
1301 0 : WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1302 0 : WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1303 : BANK_SELECT(6) |
1304 : L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1305 : /* setup context0 */
1306 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1307 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1308 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1309 0 : WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1310 : (u32)(rdev->dummy_page.addr >> 12));
1311 0 : WREG32(VM_CONTEXT0_CNTL2, 0);
1312 0 : WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1313 : RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
1314 :
1315 0 : WREG32(0x15D4, 0);
1316 0 : WREG32(0x15D8, 0);
1317 0 : WREG32(0x15DC, 0);
1318 :
1319 : /* empty context1-7 */
1320 : /* Assign the pt base to something valid for now; the pts used for
1321 : * the VMs are determined by the application and setup and assigned
1322 : * on the fly in the vm part of radeon_gart.c
1323 : */
1324 0 : for (i = 1; i < 8; i++) {
1325 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
1326 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
1327 : rdev->vm_manager.max_pfn - 1);
1328 0 : WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1329 : rdev->vm_manager.saved_table_addr[i]);
1330 : }
1331 :
1332 : /* enable context1-7 */
1333 0 : WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1334 : (u32)(rdev->dummy_page.addr >> 12));
1335 0 : WREG32(VM_CONTEXT1_CNTL2, 4);
1336 0 : WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
1337 : PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
1338 : RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1339 : RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1340 : DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1341 : DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1342 : PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1343 : PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1344 : VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1345 : VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1346 : READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1347 : READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1348 : WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1349 : WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
1350 :
1351 0 : cayman_pcie_gart_tlb_flush(rdev);
1352 : DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1353 : (unsigned)(rdev->mc.gtt_size >> 20),
1354 : (unsigned long long)rdev->gart.table_addr);
1355 0 : rdev->gart.ready = true;
1356 0 : return 0;
1357 0 : }
1358 :
1359 0 : static void cayman_pcie_gart_disable(struct radeon_device *rdev)
1360 : {
1361 : unsigned i;
1362 :
1363 0 : for (i = 1; i < 8; ++i) {
1364 0 : rdev->vm_manager.saved_table_addr[i] = RREG32(
1365 : VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2));
1366 : }
1367 :
1368 : /* Disable all tables */
1369 0 : WREG32(VM_CONTEXT0_CNTL, 0);
1370 0 : WREG32(VM_CONTEXT1_CNTL, 0);
1371 : /* Setup TLB control */
1372 0 : WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1373 : SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1374 : SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1375 : /* Setup L2 cache */
1376 0 : WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1377 : ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1378 : EFFECTIVE_L2_QUEUE_SIZE(7) |
1379 : CONTEXT1_IDENTITY_ACCESS_MODE(1));
1380 0 : WREG32(VM_L2_CNTL2, 0);
1381 0 : WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1382 : L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1383 0 : radeon_gart_table_vram_unpin(rdev);
1384 0 : }
1385 :
1386 0 : static void cayman_pcie_gart_fini(struct radeon_device *rdev)
1387 : {
1388 0 : cayman_pcie_gart_disable(rdev);
1389 0 : radeon_gart_table_vram_free(rdev);
1390 0 : radeon_gart_fini(rdev);
1391 0 : }
1392 :
1393 0 : void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
1394 : int ring, u32 cp_int_cntl)
1395 : {
1396 0 : WREG32(SRBM_GFX_CNTL, RINGID(ring));
1397 0 : WREG32(CP_INT_CNTL, cp_int_cntl);
1398 0 : }
1399 :
1400 : /*
1401 : * CP.
1402 : */
1403 0 : void cayman_fence_ring_emit(struct radeon_device *rdev,
1404 : struct radeon_fence *fence)
1405 : {
1406 0 : struct radeon_ring *ring = &rdev->ring[fence->ring];
1407 0 : u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1408 : u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
1409 : PACKET3_SH_ACTION_ENA;
1410 :
1411 : /* flush read cache over gart for this vmid */
1412 0 : radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1413 0 : radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
1414 0 : radeon_ring_write(ring, 0xFFFFFFFF);
1415 0 : radeon_ring_write(ring, 0);
1416 0 : radeon_ring_write(ring, 10); /* poll interval */
1417 : /* EVENT_WRITE_EOP - flush caches, send int */
1418 0 : radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1419 0 : radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
1420 0 : radeon_ring_write(ring, lower_32_bits(addr));
1421 0 : radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1422 0 : radeon_ring_write(ring, fence->seq);
1423 0 : radeon_ring_write(ring, 0);
1424 0 : }
1425 :
1426 0 : void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1427 : {
1428 0 : struct radeon_ring *ring = &rdev->ring[ib->ring];
1429 0 : unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
1430 : u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
1431 : PACKET3_SH_ACTION_ENA;
1432 :
1433 : /* set to DX10/11 mode */
1434 0 : radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1435 0 : radeon_ring_write(ring, 1);
1436 :
1437 0 : if (ring->rptr_save_reg) {
1438 0 : uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1439 0 : radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1440 0 : radeon_ring_write(ring, ((ring->rptr_save_reg -
1441 0 : PACKET3_SET_CONFIG_REG_START) >> 2));
1442 0 : radeon_ring_write(ring, next_rptr);
1443 0 : }
1444 :
1445 0 : radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1446 0 : radeon_ring_write(ring,
1447 : #ifdef __BIG_ENDIAN
1448 : (2 << 0) |
1449 : #endif
1450 0 : (ib->gpu_addr & 0xFFFFFFFC));
1451 0 : radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
1452 0 : radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
1453 :
1454 : /* flush read cache over gart for this vmid */
1455 0 : radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1456 0 : radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
1457 0 : radeon_ring_write(ring, 0xFFFFFFFF);
1458 0 : radeon_ring_write(ring, 0);
1459 0 : radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */
1460 0 : }
1461 :
1462 0 : static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1463 : {
1464 0 : if (enable)
1465 0 : WREG32(CP_ME_CNTL, 0);
1466 : else {
1467 0 : if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
1468 0 : radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1469 0 : WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1470 0 : WREG32(SCRATCH_UMSK, 0);
1471 0 : rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1472 : }
1473 0 : }
1474 :
1475 0 : u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
1476 : struct radeon_ring *ring)
1477 : {
1478 : u32 rptr;
1479 :
1480 0 : if (rdev->wb.enabled)
1481 0 : rptr = rdev->wb.wb[ring->rptr_offs/4];
1482 : else {
1483 0 : if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
1484 0 : rptr = RREG32(CP_RB0_RPTR);
1485 0 : else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
1486 0 : rptr = RREG32(CP_RB1_RPTR);
1487 : else
1488 0 : rptr = RREG32(CP_RB2_RPTR);
1489 : }
1490 :
1491 0 : return rptr;
1492 : }
1493 :
1494 0 : u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
1495 : struct radeon_ring *ring)
1496 : {
1497 : u32 wptr;
1498 :
1499 0 : if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
1500 0 : wptr = RREG32(CP_RB0_WPTR);
1501 0 : else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
1502 0 : wptr = RREG32(CP_RB1_WPTR);
1503 : else
1504 0 : wptr = RREG32(CP_RB2_WPTR);
1505 :
1506 0 : return wptr;
1507 : }
1508 :
1509 0 : void cayman_gfx_set_wptr(struct radeon_device *rdev,
1510 : struct radeon_ring *ring)
1511 : {
1512 0 : if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
1513 0 : WREG32(CP_RB0_WPTR, ring->wptr);
1514 0 : (void)RREG32(CP_RB0_WPTR);
1515 0 : } else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
1516 0 : WREG32(CP_RB1_WPTR, ring->wptr);
1517 0 : (void)RREG32(CP_RB1_WPTR);
1518 0 : } else {
1519 0 : WREG32(CP_RB2_WPTR, ring->wptr);
1520 0 : (void)RREG32(CP_RB2_WPTR);
1521 : }
1522 0 : }
1523 :
1524 0 : static int cayman_cp_load_microcode(struct radeon_device *rdev)
1525 : {
1526 : const __be32 *fw_data;
1527 : int i;
1528 :
1529 0 : if (!rdev->me_fw || !rdev->pfp_fw)
1530 0 : return -EINVAL;
1531 :
1532 0 : cayman_cp_enable(rdev, false);
1533 :
1534 0 : fw_data = (const __be32 *)rdev->pfp_fw->data;
1535 0 : WREG32(CP_PFP_UCODE_ADDR, 0);
1536 0 : for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
1537 0 : WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1538 0 : WREG32(CP_PFP_UCODE_ADDR, 0);
1539 :
1540 0 : fw_data = (const __be32 *)rdev->me_fw->data;
1541 0 : WREG32(CP_ME_RAM_WADDR, 0);
1542 0 : for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
1543 0 : WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1544 :
1545 0 : WREG32(CP_PFP_UCODE_ADDR, 0);
1546 0 : WREG32(CP_ME_RAM_WADDR, 0);
1547 0 : WREG32(CP_ME_RAM_RADDR, 0);
1548 0 : return 0;
1549 0 : }
1550 :
1551 0 : static int cayman_cp_start(struct radeon_device *rdev)
1552 : {
1553 0 : struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1554 : int r, i;
1555 :
1556 0 : r = radeon_ring_lock(rdev, ring, 7);
1557 0 : if (r) {
1558 0 : DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1559 0 : return r;
1560 : }
1561 0 : radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1562 0 : radeon_ring_write(ring, 0x1);
1563 0 : radeon_ring_write(ring, 0x0);
1564 0 : radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1565 0 : radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1566 0 : radeon_ring_write(ring, 0);
1567 0 : radeon_ring_write(ring, 0);
1568 0 : radeon_ring_unlock_commit(rdev, ring, false);
1569 :
1570 0 : cayman_cp_enable(rdev, true);
1571 :
1572 0 : r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
1573 0 : if (r) {
1574 0 : DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1575 0 : return r;
1576 : }
1577 :
1578 : /* setup clear context state */
1579 0 : radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1580 0 : radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
1581 :
1582 0 : for (i = 0; i < cayman_default_size; i++)
1583 0 : radeon_ring_write(ring, cayman_default_state[i]);
1584 :
1585 0 : radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1586 0 : radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
1587 :
1588 : /* set clear context state */
1589 0 : radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1590 0 : radeon_ring_write(ring, 0);
1591 :
1592 : /* SQ_VTX_BASE_VTX_LOC */
1593 0 : radeon_ring_write(ring, 0xc0026f00);
1594 0 : radeon_ring_write(ring, 0x00000000);
1595 0 : radeon_ring_write(ring, 0x00000000);
1596 0 : radeon_ring_write(ring, 0x00000000);
1597 :
1598 : /* Clear consts */
1599 0 : radeon_ring_write(ring, 0xc0036f00);
1600 0 : radeon_ring_write(ring, 0x00000bc4);
1601 0 : radeon_ring_write(ring, 0xffffffff);
1602 0 : radeon_ring_write(ring, 0xffffffff);
1603 0 : radeon_ring_write(ring, 0xffffffff);
1604 :
1605 0 : radeon_ring_write(ring, 0xc0026900);
1606 0 : radeon_ring_write(ring, 0x00000316);
1607 0 : radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1608 0 : radeon_ring_write(ring, 0x00000010); /* */
1609 :
1610 0 : radeon_ring_unlock_commit(rdev, ring, false);
1611 :
1612 : /* XXX init other rings */
1613 :
1614 0 : return 0;
1615 0 : }
1616 :
1617 0 : static void cayman_cp_fini(struct radeon_device *rdev)
1618 : {
1619 0 : struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1620 0 : cayman_cp_enable(rdev, false);
1621 0 : radeon_ring_fini(rdev, ring);
1622 0 : radeon_scratch_free(rdev, ring->rptr_save_reg);
1623 0 : }
1624 :
1625 0 : static int cayman_cp_resume(struct radeon_device *rdev)
1626 : {
1627 : static const int ridx[] = {
1628 : RADEON_RING_TYPE_GFX_INDEX,
1629 : CAYMAN_RING_TYPE_CP1_INDEX,
1630 : CAYMAN_RING_TYPE_CP2_INDEX
1631 : };
1632 : static const unsigned cp_rb_cntl[] = {
1633 : CP_RB0_CNTL,
1634 : CP_RB1_CNTL,
1635 : CP_RB2_CNTL,
1636 : };
1637 : static const unsigned cp_rb_rptr_addr[] = {
1638 : CP_RB0_RPTR_ADDR,
1639 : CP_RB1_RPTR_ADDR,
1640 : CP_RB2_RPTR_ADDR
1641 : };
1642 : static const unsigned cp_rb_rptr_addr_hi[] = {
1643 : CP_RB0_RPTR_ADDR_HI,
1644 : CP_RB1_RPTR_ADDR_HI,
1645 : CP_RB2_RPTR_ADDR_HI
1646 : };
1647 : static const unsigned cp_rb_base[] = {
1648 : CP_RB0_BASE,
1649 : CP_RB1_BASE,
1650 : CP_RB2_BASE
1651 : };
1652 : static const unsigned cp_rb_rptr[] = {
1653 : CP_RB0_RPTR,
1654 : CP_RB1_RPTR,
1655 : CP_RB2_RPTR
1656 : };
1657 : static const unsigned cp_rb_wptr[] = {
1658 : CP_RB0_WPTR,
1659 : CP_RB1_WPTR,
1660 : CP_RB2_WPTR
1661 : };
1662 : struct radeon_ring *ring;
1663 : int i, r;
1664 :
1665 : /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
1666 0 : WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
1667 : SOFT_RESET_PA |
1668 : SOFT_RESET_SH |
1669 : SOFT_RESET_VGT |
1670 : SOFT_RESET_SPI |
1671 : SOFT_RESET_SX));
1672 0 : RREG32(GRBM_SOFT_RESET);
1673 0 : mdelay(15);
1674 0 : WREG32(GRBM_SOFT_RESET, 0);
1675 0 : RREG32(GRBM_SOFT_RESET);
1676 :
1677 0 : WREG32(CP_SEM_WAIT_TIMER, 0x0);
1678 0 : WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
1679 :
1680 : /* Set the write pointer delay */
1681 0 : WREG32(CP_RB_WPTR_DELAY, 0);
1682 :
1683 0 : WREG32(CP_DEBUG, (1 << 27));
1684 :
1685 : /* set the wb address whether it's enabled or not */
1686 0 : WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
1687 0 : WREG32(SCRATCH_UMSK, 0xff);
1688 :
1689 0 : for (i = 0; i < 3; ++i) {
1690 : uint32_t rb_cntl;
1691 : uint64_t addr;
1692 :
1693 : /* Set ring buffer size */
1694 0 : ring = &rdev->ring[ridx[i]];
1695 0 : rb_cntl = order_base_2(ring->ring_size / 8);
1696 0 : rb_cntl |= order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8;
1697 : #ifdef __BIG_ENDIAN
1698 : rb_cntl |= BUF_SWAP_32BIT;
1699 : #endif
1700 0 : WREG32(cp_rb_cntl[i], rb_cntl);
1701 :
1702 : /* set the wb address whether it's enabled or not */
1703 0 : addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1704 0 : WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1705 0 : WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
1706 : }
1707 :
1708 : /* set the rb base addr, this causes an internal reset of ALL rings */
1709 0 : for (i = 0; i < 3; ++i) {
1710 0 : ring = &rdev->ring[ridx[i]];
1711 0 : WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1712 : }
1713 :
1714 0 : for (i = 0; i < 3; ++i) {
1715 : /* Initialize the ring buffer's read and write pointers */
1716 0 : ring = &rdev->ring[ridx[i]];
1717 0 : WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
1718 :
1719 0 : ring->wptr = 0;
1720 0 : WREG32(cp_rb_rptr[i], 0);
1721 0 : WREG32(cp_rb_wptr[i], ring->wptr);
1722 :
1723 0 : mdelay(1);
1724 0 : WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1725 : }
1726 :
1727 : /* start the rings */
1728 0 : cayman_cp_start(rdev);
1729 0 : rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1730 0 : rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1731 0 : rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
1732 : /* this only test cp0 */
1733 0 : r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
1734 0 : if (r) {
1735 0 : rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1736 0 : rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1737 0 : rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
1738 0 : return r;
1739 : }
1740 :
1741 0 : if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
1742 0 : radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1743 :
1744 0 : return 0;
1745 0 : }
1746 :
1747 0 : u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1748 : {
1749 : u32 reset_mask = 0;
1750 : u32 tmp;
1751 :
1752 : /* GRBM_STATUS */
1753 0 : tmp = RREG32(GRBM_STATUS);
1754 0 : if (tmp & (PA_BUSY | SC_BUSY |
1755 : SH_BUSY | SX_BUSY |
1756 : TA_BUSY | VGT_BUSY |
1757 : DB_BUSY | CB_BUSY |
1758 : GDS_BUSY | SPI_BUSY |
1759 : IA_BUSY | IA_BUSY_NO_DMA))
1760 0 : reset_mask |= RADEON_RESET_GFX;
1761 :
1762 0 : if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1763 : CP_BUSY | CP_COHERENCY_BUSY))
1764 0 : reset_mask |= RADEON_RESET_CP;
1765 :
1766 0 : if (tmp & GRBM_EE_BUSY)
1767 0 : reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1768 :
1769 : /* DMA_STATUS_REG 0 */
1770 0 : tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1771 0 : if (!(tmp & DMA_IDLE))
1772 0 : reset_mask |= RADEON_RESET_DMA;
1773 :
1774 : /* DMA_STATUS_REG 1 */
1775 0 : tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1776 0 : if (!(tmp & DMA_IDLE))
1777 0 : reset_mask |= RADEON_RESET_DMA1;
1778 :
1779 : /* SRBM_STATUS2 */
1780 0 : tmp = RREG32(SRBM_STATUS2);
1781 0 : if (tmp & DMA_BUSY)
1782 0 : reset_mask |= RADEON_RESET_DMA;
1783 :
1784 0 : if (tmp & DMA1_BUSY)
1785 0 : reset_mask |= RADEON_RESET_DMA1;
1786 :
1787 : /* SRBM_STATUS */
1788 0 : tmp = RREG32(SRBM_STATUS);
1789 0 : if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1790 0 : reset_mask |= RADEON_RESET_RLC;
1791 :
1792 0 : if (tmp & IH_BUSY)
1793 0 : reset_mask |= RADEON_RESET_IH;
1794 :
1795 0 : if (tmp & SEM_BUSY)
1796 0 : reset_mask |= RADEON_RESET_SEM;
1797 :
1798 0 : if (tmp & GRBM_RQ_PENDING)
1799 0 : reset_mask |= RADEON_RESET_GRBM;
1800 :
1801 0 : if (tmp & VMC_BUSY)
1802 0 : reset_mask |= RADEON_RESET_VMC;
1803 :
1804 0 : if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1805 : MCC_BUSY | MCD_BUSY))
1806 0 : reset_mask |= RADEON_RESET_MC;
1807 :
1808 0 : if (evergreen_is_display_hung(rdev))
1809 0 : reset_mask |= RADEON_RESET_DISPLAY;
1810 :
1811 : /* VM_L2_STATUS */
1812 0 : tmp = RREG32(VM_L2_STATUS);
1813 0 : if (tmp & L2_BUSY)
1814 0 : reset_mask |= RADEON_RESET_VMC;
1815 :
1816 : /* Skip MC reset as it's mostly likely not hung, just busy */
1817 0 : if (reset_mask & RADEON_RESET_MC) {
1818 : DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1819 0 : reset_mask &= ~RADEON_RESET_MC;
1820 0 : }
1821 :
1822 0 : return reset_mask;
1823 : }
1824 :
1825 0 : static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1826 : {
1827 0 : struct evergreen_mc_save save;
1828 : u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1829 : u32 tmp;
1830 :
1831 0 : if (reset_mask == 0)
1832 0 : return;
1833 :
1834 : dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1835 :
1836 0 : evergreen_print_gpu_status_regs(rdev);
1837 : dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1838 : RREG32(0x14F8));
1839 : dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1840 : RREG32(0x14D8));
1841 : dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
1842 : RREG32(0x14FC));
1843 : dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1844 : RREG32(0x14DC));
1845 :
1846 : /* Disable CP parsing/prefetching */
1847 0 : WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1848 :
1849 0 : if (reset_mask & RADEON_RESET_DMA) {
1850 : /* dma0 */
1851 0 : tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1852 0 : tmp &= ~DMA_RB_ENABLE;
1853 0 : WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
1854 0 : }
1855 :
1856 0 : if (reset_mask & RADEON_RESET_DMA1) {
1857 : /* dma1 */
1858 0 : tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1859 0 : tmp &= ~DMA_RB_ENABLE;
1860 0 : WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1861 0 : }
1862 :
1863 0 : udelay(50);
1864 :
1865 0 : evergreen_mc_stop(rdev, &save);
1866 0 : if (evergreen_mc_wait_for_idle(rdev)) {
1867 0 : dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1868 0 : }
1869 :
1870 0 : if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1871 : grbm_soft_reset = SOFT_RESET_CB |
1872 : SOFT_RESET_DB |
1873 : SOFT_RESET_GDS |
1874 : SOFT_RESET_PA |
1875 : SOFT_RESET_SC |
1876 : SOFT_RESET_SPI |
1877 : SOFT_RESET_SH |
1878 : SOFT_RESET_SX |
1879 : SOFT_RESET_TC |
1880 : SOFT_RESET_TA |
1881 : SOFT_RESET_VGT |
1882 : SOFT_RESET_IA;
1883 0 : }
1884 :
1885 0 : if (reset_mask & RADEON_RESET_CP) {
1886 0 : grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1887 :
1888 : srbm_soft_reset |= SOFT_RESET_GRBM;
1889 0 : }
1890 :
1891 0 : if (reset_mask & RADEON_RESET_DMA)
1892 0 : srbm_soft_reset |= SOFT_RESET_DMA;
1893 :
1894 0 : if (reset_mask & RADEON_RESET_DMA1)
1895 0 : srbm_soft_reset |= SOFT_RESET_DMA1;
1896 :
1897 0 : if (reset_mask & RADEON_RESET_DISPLAY)
1898 0 : srbm_soft_reset |= SOFT_RESET_DC;
1899 :
1900 0 : if (reset_mask & RADEON_RESET_RLC)
1901 0 : srbm_soft_reset |= SOFT_RESET_RLC;
1902 :
1903 0 : if (reset_mask & RADEON_RESET_SEM)
1904 0 : srbm_soft_reset |= SOFT_RESET_SEM;
1905 :
1906 0 : if (reset_mask & RADEON_RESET_IH)
1907 0 : srbm_soft_reset |= SOFT_RESET_IH;
1908 :
1909 0 : if (reset_mask & RADEON_RESET_GRBM)
1910 0 : srbm_soft_reset |= SOFT_RESET_GRBM;
1911 :
1912 0 : if (reset_mask & RADEON_RESET_VMC)
1913 0 : srbm_soft_reset |= SOFT_RESET_VMC;
1914 :
1915 0 : if (!(rdev->flags & RADEON_IS_IGP)) {
1916 0 : if (reset_mask & RADEON_RESET_MC)
1917 0 : srbm_soft_reset |= SOFT_RESET_MC;
1918 : }
1919 :
1920 0 : if (grbm_soft_reset) {
1921 0 : tmp = RREG32(GRBM_SOFT_RESET);
1922 0 : tmp |= grbm_soft_reset;
1923 : dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1924 0 : WREG32(GRBM_SOFT_RESET, tmp);
1925 0 : tmp = RREG32(GRBM_SOFT_RESET);
1926 :
1927 0 : udelay(50);
1928 :
1929 0 : tmp &= ~grbm_soft_reset;
1930 0 : WREG32(GRBM_SOFT_RESET, tmp);
1931 0 : tmp = RREG32(GRBM_SOFT_RESET);
1932 0 : }
1933 :
1934 0 : if (srbm_soft_reset) {
1935 0 : tmp = RREG32(SRBM_SOFT_RESET);
1936 0 : tmp |= srbm_soft_reset;
1937 : dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1938 0 : WREG32(SRBM_SOFT_RESET, tmp);
1939 0 : tmp = RREG32(SRBM_SOFT_RESET);
1940 :
1941 0 : udelay(50);
1942 :
1943 0 : tmp &= ~srbm_soft_reset;
1944 0 : WREG32(SRBM_SOFT_RESET, tmp);
1945 0 : tmp = RREG32(SRBM_SOFT_RESET);
1946 0 : }
1947 :
1948 : /* Wait a little for things to settle down */
1949 0 : udelay(50);
1950 :
1951 0 : evergreen_mc_resume(rdev, &save);
1952 0 : udelay(50);
1953 :
1954 0 : evergreen_print_gpu_status_regs(rdev);
1955 0 : }
1956 :
1957 0 : int cayman_asic_reset(struct radeon_device *rdev)
1958 : {
1959 : u32 reset_mask;
1960 :
1961 0 : reset_mask = cayman_gpu_check_soft_reset(rdev);
1962 :
1963 0 : if (reset_mask)
1964 0 : r600_set_bios_scratch_engine_hung(rdev, true);
1965 :
1966 0 : cayman_gpu_soft_reset(rdev, reset_mask);
1967 :
1968 0 : reset_mask = cayman_gpu_check_soft_reset(rdev);
1969 :
1970 0 : if (reset_mask)
1971 0 : evergreen_gpu_pci_config_reset(rdev);
1972 :
1973 0 : r600_set_bios_scratch_engine_hung(rdev, false);
1974 :
1975 0 : return 0;
1976 : }
1977 :
1978 : /**
1979 : * cayman_gfx_is_lockup - Check if the GFX engine is locked up
1980 : *
1981 : * @rdev: radeon_device pointer
1982 : * @ring: radeon_ring structure holding ring information
1983 : *
1984 : * Check if the GFX engine is locked up.
1985 : * Returns true if the engine appears to be locked up, false if not.
1986 : */
1987 0 : bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1988 : {
1989 0 : u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
1990 :
1991 0 : if (!(reset_mask & (RADEON_RESET_GFX |
1992 : RADEON_RESET_COMPUTE |
1993 : RADEON_RESET_CP))) {
1994 0 : radeon_ring_lockup_update(rdev, ring);
1995 0 : return false;
1996 : }
1997 0 : return radeon_ring_test_lockup(rdev, ring);
1998 0 : }
1999 :
2000 0 : static int cayman_startup(struct radeon_device *rdev)
2001 : {
2002 0 : struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2003 : int r;
2004 :
2005 : /* enable pcie gen2 link */
2006 0 : evergreen_pcie_gen2_enable(rdev);
2007 : /* enable aspm */
2008 0 : evergreen_program_aspm(rdev);
2009 :
2010 : /* scratch needs to be initialized before MC */
2011 0 : r = r600_vram_scratch_init(rdev);
2012 0 : if (r)
2013 0 : return r;
2014 :
2015 0 : evergreen_mc_program(rdev);
2016 :
2017 0 : if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
2018 0 : r = ni_mc_load_microcode(rdev);
2019 0 : if (r) {
2020 0 : DRM_ERROR("Failed to load MC firmware!\n");
2021 0 : return r;
2022 : }
2023 : }
2024 :
2025 0 : r = cayman_pcie_gart_enable(rdev);
2026 0 : if (r)
2027 0 : return r;
2028 0 : cayman_gpu_init(rdev);
2029 :
2030 : /* allocate rlc buffers */
2031 0 : if (rdev->flags & RADEON_IS_IGP) {
2032 0 : rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
2033 0 : rdev->rlc.reg_list_size =
2034 : (u32)ARRAY_SIZE(tn_rlc_save_restore_register_list);
2035 0 : rdev->rlc.cs_data = cayman_cs_data;
2036 0 : r = sumo_rlc_init(rdev);
2037 0 : if (r) {
2038 0 : DRM_ERROR("Failed to init rlc BOs!\n");
2039 0 : return r;
2040 : }
2041 : }
2042 :
2043 : /* allocate wb buffer */
2044 0 : r = radeon_wb_init(rdev);
2045 0 : if (r)
2046 0 : return r;
2047 :
2048 0 : r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
2049 0 : if (r) {
2050 0 : dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2051 0 : return r;
2052 : }
2053 :
2054 0 : r = uvd_v2_2_resume(rdev);
2055 0 : if (!r) {
2056 0 : r = radeon_fence_driver_start_ring(rdev,
2057 : R600_RING_TYPE_UVD_INDEX);
2058 0 : if (r)
2059 0 : dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2060 : }
2061 0 : if (r)
2062 0 : rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2063 :
2064 0 : if (rdev->family == CHIP_ARUBA) {
2065 0 : r = radeon_vce_resume(rdev);
2066 0 : if (!r)
2067 0 : r = vce_v1_0_resume(rdev);
2068 :
2069 0 : if (!r)
2070 0 : r = radeon_fence_driver_start_ring(rdev,
2071 : TN_RING_TYPE_VCE1_INDEX);
2072 0 : if (!r)
2073 0 : r = radeon_fence_driver_start_ring(rdev,
2074 : TN_RING_TYPE_VCE2_INDEX);
2075 :
2076 0 : if (r) {
2077 0 : dev_err(rdev->dev, "VCE init error (%d).\n", r);
2078 0 : rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
2079 0 : rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
2080 0 : }
2081 : }
2082 :
2083 0 : r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
2084 0 : if (r) {
2085 0 : dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2086 0 : return r;
2087 : }
2088 :
2089 0 : r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
2090 0 : if (r) {
2091 0 : dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2092 0 : return r;
2093 : }
2094 :
2095 0 : r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2096 0 : if (r) {
2097 0 : dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2098 0 : return r;
2099 : }
2100 :
2101 0 : r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2102 0 : if (r) {
2103 0 : dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2104 0 : return r;
2105 : }
2106 :
2107 : /* Enable IRQ */
2108 0 : if (!rdev->irq.installed) {
2109 0 : r = radeon_irq_kms_init(rdev);
2110 0 : if (r)
2111 0 : return r;
2112 : }
2113 :
2114 0 : r = r600_irq_init(rdev);
2115 0 : if (r) {
2116 0 : DRM_ERROR("radeon: IH init failed (%d).\n", r);
2117 0 : radeon_irq_kms_fini(rdev);
2118 0 : return r;
2119 : }
2120 0 : evergreen_irq_set(rdev);
2121 :
2122 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
2123 : RADEON_CP_PACKET2);
2124 0 : if (r)
2125 0 : return r;
2126 :
2127 0 : ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2128 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
2129 : DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2130 0 : if (r)
2131 0 : return r;
2132 :
2133 0 : ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2134 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
2135 : DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2136 0 : if (r)
2137 0 : return r;
2138 :
2139 0 : r = cayman_cp_load_microcode(rdev);
2140 0 : if (r)
2141 0 : return r;
2142 0 : r = cayman_cp_resume(rdev);
2143 0 : if (r)
2144 0 : return r;
2145 :
2146 0 : r = cayman_dma_resume(rdev);
2147 0 : if (r)
2148 0 : return r;
2149 :
2150 0 : ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2151 0 : if (ring->ring_size) {
2152 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
2153 : RADEON_CP_PACKET2);
2154 0 : if (!r)
2155 0 : r = uvd_v1_0_init(rdev);
2156 0 : if (r)
2157 0 : DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2158 : }
2159 :
2160 0 : if (rdev->family == CHIP_ARUBA) {
2161 0 : ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
2162 0 : if (ring->ring_size)
2163 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
2164 :
2165 0 : ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
2166 0 : if (ring->ring_size)
2167 0 : r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
2168 :
2169 0 : if (!r)
2170 0 : r = vce_v1_0_init(rdev);
2171 0 : if (r)
2172 0 : DRM_ERROR("radeon: failed initializing VCE (%d).\n", r);
2173 : }
2174 :
2175 0 : r = radeon_ib_pool_init(rdev);
2176 0 : if (r) {
2177 0 : dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
2178 0 : return r;
2179 : }
2180 :
2181 0 : r = radeon_vm_manager_init(rdev);
2182 0 : if (r) {
2183 0 : dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
2184 0 : return r;
2185 : }
2186 :
2187 0 : r = radeon_audio_init(rdev);
2188 0 : if (r)
2189 0 : return r;
2190 :
2191 0 : return 0;
2192 0 : }
2193 :
2194 0 : int cayman_resume(struct radeon_device *rdev)
2195 : {
2196 : int r;
2197 :
2198 : /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2199 : * posting will perform necessary task to bring back GPU into good
2200 : * shape.
2201 : */
2202 : /* post card */
2203 0 : atom_asic_init(rdev->mode_info.atom_context);
2204 :
2205 : /* init golden registers */
2206 0 : ni_init_golden_registers(rdev);
2207 :
2208 0 : if (rdev->pm.pm_method == PM_METHOD_DPM)
2209 0 : radeon_pm_resume(rdev);
2210 :
2211 0 : rdev->accel_working = true;
2212 0 : r = cayman_startup(rdev);
2213 0 : if (r) {
2214 0 : DRM_ERROR("cayman startup failed on resume\n");
2215 0 : rdev->accel_working = false;
2216 0 : return r;
2217 : }
2218 0 : return r;
2219 0 : }
2220 :
2221 0 : int cayman_suspend(struct radeon_device *rdev)
2222 : {
2223 0 : radeon_pm_suspend(rdev);
2224 0 : radeon_audio_fini(rdev);
2225 0 : radeon_vm_manager_fini(rdev);
2226 0 : cayman_cp_enable(rdev, false);
2227 0 : cayman_dma_stop(rdev);
2228 0 : uvd_v1_0_fini(rdev);
2229 0 : radeon_uvd_suspend(rdev);
2230 0 : evergreen_irq_suspend(rdev);
2231 0 : radeon_wb_disable(rdev);
2232 0 : cayman_pcie_gart_disable(rdev);
2233 0 : return 0;
2234 : }
2235 :
2236 : /* Plan is to move initialization in that function and use
2237 : * helper function so that radeon_device_init pretty much
2238 : * do nothing more than calling asic specific function. This
2239 : * should also allow to remove a bunch of callback function
2240 : * like vram_info.
2241 : */
2242 0 : int cayman_init(struct radeon_device *rdev)
2243 : {
2244 0 : struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2245 : int r;
2246 :
2247 : /* Read BIOS */
2248 0 : if (!radeon_get_bios(rdev)) {
2249 0 : if (ASIC_IS_AVIVO(rdev))
2250 0 : return -EINVAL;
2251 : }
2252 : /* Must be an ATOMBIOS */
2253 0 : if (!rdev->is_atom_bios) {
2254 0 : dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2255 0 : return -EINVAL;
2256 : }
2257 0 : r = radeon_atombios_init(rdev);
2258 0 : if (r)
2259 0 : return r;
2260 :
2261 : /* Post card if necessary */
2262 0 : if (!radeon_card_posted(rdev)) {
2263 0 : if (!rdev->bios) {
2264 0 : dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2265 0 : return -EINVAL;
2266 : }
2267 : DRM_INFO("GPU not posted. posting now...\n");
2268 0 : atom_asic_init(rdev->mode_info.atom_context);
2269 0 : }
2270 : /* init golden registers */
2271 0 : ni_init_golden_registers(rdev);
2272 : /* Initialize scratch registers */
2273 0 : r600_scratch_init(rdev);
2274 : /* Initialize surface registers */
2275 0 : radeon_surface_init(rdev);
2276 : /* Initialize clocks */
2277 0 : radeon_get_clock_info(rdev->ddev);
2278 : /* Fence driver */
2279 0 : r = radeon_fence_driver_init(rdev);
2280 0 : if (r)
2281 0 : return r;
2282 : /* initialize memory controller */
2283 0 : r = evergreen_mc_init(rdev);
2284 0 : if (r)
2285 0 : return r;
2286 : /* Memory manager */
2287 0 : r = radeon_bo_init(rdev);
2288 0 : if (r)
2289 0 : return r;
2290 :
2291 0 : if (rdev->flags & RADEON_IS_IGP) {
2292 0 : if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
2293 0 : r = ni_init_microcode(rdev);
2294 0 : if (r) {
2295 0 : DRM_ERROR("Failed to load firmware!\n");
2296 0 : return r;
2297 : }
2298 : }
2299 : } else {
2300 0 : if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
2301 0 : r = ni_init_microcode(rdev);
2302 0 : if (r) {
2303 0 : DRM_ERROR("Failed to load firmware!\n");
2304 0 : return r;
2305 : }
2306 : }
2307 : }
2308 :
2309 : /* Initialize power management */
2310 0 : radeon_pm_init(rdev);
2311 :
2312 0 : ring->ring_obj = NULL;
2313 0 : r600_ring_init(rdev, ring, 1024 * 1024);
2314 :
2315 0 : ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2316 0 : ring->ring_obj = NULL;
2317 0 : r600_ring_init(rdev, ring, 64 * 1024);
2318 :
2319 0 : ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2320 0 : ring->ring_obj = NULL;
2321 0 : r600_ring_init(rdev, ring, 64 * 1024);
2322 :
2323 0 : r = radeon_uvd_init(rdev);
2324 0 : if (!r) {
2325 0 : ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2326 0 : ring->ring_obj = NULL;
2327 0 : r600_ring_init(rdev, ring, 4096);
2328 0 : }
2329 :
2330 0 : if (rdev->family == CHIP_ARUBA) {
2331 0 : r = radeon_vce_init(rdev);
2332 0 : if (!r) {
2333 0 : ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
2334 0 : ring->ring_obj = NULL;
2335 0 : r600_ring_init(rdev, ring, 4096);
2336 :
2337 0 : ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
2338 0 : ring->ring_obj = NULL;
2339 0 : r600_ring_init(rdev, ring, 4096);
2340 0 : }
2341 : }
2342 :
2343 0 : rdev->ih.ring_obj = NULL;
2344 0 : r600_ih_ring_init(rdev, 64 * 1024);
2345 :
2346 0 : r = r600_pcie_gart_init(rdev);
2347 0 : if (r)
2348 0 : return r;
2349 :
2350 0 : rdev->accel_working = true;
2351 0 : r = cayman_startup(rdev);
2352 0 : if (r) {
2353 0 : dev_err(rdev->dev, "disabling GPU acceleration\n");
2354 0 : cayman_cp_fini(rdev);
2355 0 : cayman_dma_fini(rdev);
2356 0 : r600_irq_fini(rdev);
2357 0 : if (rdev->flags & RADEON_IS_IGP)
2358 0 : sumo_rlc_fini(rdev);
2359 0 : radeon_wb_fini(rdev);
2360 0 : radeon_ib_pool_fini(rdev);
2361 0 : radeon_vm_manager_fini(rdev);
2362 0 : radeon_irq_kms_fini(rdev);
2363 0 : cayman_pcie_gart_fini(rdev);
2364 0 : rdev->accel_working = false;
2365 0 : }
2366 :
2367 : /* Don't start up if the MC ucode is missing.
2368 : * The default clocks and voltages before the MC ucode
2369 : * is loaded are not suffient for advanced operations.
2370 : *
2371 : * We can skip this check for TN, because there is no MC
2372 : * ucode.
2373 : */
2374 0 : if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
2375 0 : DRM_ERROR("radeon: MC ucode required for NI+.\n");
2376 0 : return -EINVAL;
2377 : }
2378 :
2379 0 : return 0;
2380 0 : }
2381 :
2382 0 : void cayman_fini(struct radeon_device *rdev)
2383 : {
2384 0 : radeon_pm_fini(rdev);
2385 0 : cayman_cp_fini(rdev);
2386 0 : cayman_dma_fini(rdev);
2387 0 : r600_irq_fini(rdev);
2388 0 : if (rdev->flags & RADEON_IS_IGP)
2389 0 : sumo_rlc_fini(rdev);
2390 0 : radeon_wb_fini(rdev);
2391 0 : radeon_vm_manager_fini(rdev);
2392 0 : radeon_ib_pool_fini(rdev);
2393 0 : radeon_irq_kms_fini(rdev);
2394 0 : uvd_v1_0_fini(rdev);
2395 0 : radeon_uvd_fini(rdev);
2396 0 : if (rdev->family == CHIP_ARUBA)
2397 0 : radeon_vce_fini(rdev);
2398 0 : cayman_pcie_gart_fini(rdev);
2399 0 : r600_vram_scratch_fini(rdev);
2400 0 : radeon_gem_fini(rdev);
2401 0 : radeon_fence_driver_fini(rdev);
2402 0 : radeon_bo_fini(rdev);
2403 0 : radeon_atombios_fini(rdev);
2404 0 : kfree(rdev->bios);
2405 0 : rdev->bios = NULL;
2406 0 : }
2407 :
2408 : /*
2409 : * vm
2410 : */
2411 0 : int cayman_vm_init(struct radeon_device *rdev)
2412 : {
2413 : /* number of VMs */
2414 0 : rdev->vm_manager.nvm = 8;
2415 : /* base offset of vram pages */
2416 0 : if (rdev->flags & RADEON_IS_IGP) {
2417 0 : u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2418 0 : tmp <<= 22;
2419 0 : rdev->vm_manager.vram_base_offset = tmp;
2420 0 : } else
2421 0 : rdev->vm_manager.vram_base_offset = 0;
2422 0 : return 0;
2423 : }
2424 :
2425 0 : void cayman_vm_fini(struct radeon_device *rdev)
2426 : {
2427 0 : }
2428 :
2429 : /**
2430 : * cayman_vm_decode_fault - print human readable fault info
2431 : *
2432 : * @rdev: radeon_device pointer
2433 : * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
2434 : * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
2435 : *
2436 : * Print human readable fault information (cayman/TN).
2437 : */
2438 0 : void cayman_vm_decode_fault(struct radeon_device *rdev,
2439 : u32 status, u32 addr)
2440 : {
2441 0 : u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
2442 0 : u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
2443 0 : u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
2444 : char *block;
2445 :
2446 0 : switch (mc_id) {
2447 : case 32:
2448 : case 16:
2449 : case 96:
2450 : case 80:
2451 : case 160:
2452 : case 144:
2453 : case 224:
2454 : case 208:
2455 : block = "CB";
2456 0 : break;
2457 : case 33:
2458 : case 17:
2459 : case 97:
2460 : case 81:
2461 : case 161:
2462 : case 145:
2463 : case 225:
2464 : case 209:
2465 : block = "CB_FMASK";
2466 0 : break;
2467 : case 34:
2468 : case 18:
2469 : case 98:
2470 : case 82:
2471 : case 162:
2472 : case 146:
2473 : case 226:
2474 : case 210:
2475 : block = "CB_CMASK";
2476 0 : break;
2477 : case 35:
2478 : case 19:
2479 : case 99:
2480 : case 83:
2481 : case 163:
2482 : case 147:
2483 : case 227:
2484 : case 211:
2485 : block = "CB_IMMED";
2486 0 : break;
2487 : case 36:
2488 : case 20:
2489 : case 100:
2490 : case 84:
2491 : case 164:
2492 : case 148:
2493 : case 228:
2494 : case 212:
2495 : block = "DB";
2496 0 : break;
2497 : case 37:
2498 : case 21:
2499 : case 101:
2500 : case 85:
2501 : case 165:
2502 : case 149:
2503 : case 229:
2504 : case 213:
2505 : block = "DB_HTILE";
2506 0 : break;
2507 : case 38:
2508 : case 22:
2509 : case 102:
2510 : case 86:
2511 : case 166:
2512 : case 150:
2513 : case 230:
2514 : case 214:
2515 : block = "SX";
2516 0 : break;
2517 : case 39:
2518 : case 23:
2519 : case 103:
2520 : case 87:
2521 : case 167:
2522 : case 151:
2523 : case 231:
2524 : case 215:
2525 : block = "DB_STEN";
2526 0 : break;
2527 : case 40:
2528 : case 24:
2529 : case 104:
2530 : case 88:
2531 : case 232:
2532 : case 216:
2533 : case 168:
2534 : case 152:
2535 : block = "TC_TFETCH";
2536 0 : break;
2537 : case 41:
2538 : case 25:
2539 : case 105:
2540 : case 89:
2541 : case 233:
2542 : case 217:
2543 : case 169:
2544 : case 153:
2545 : block = "TC_VFETCH";
2546 0 : break;
2547 : case 42:
2548 : case 26:
2549 : case 106:
2550 : case 90:
2551 : case 234:
2552 : case 218:
2553 : case 170:
2554 : case 154:
2555 : block = "VC";
2556 0 : break;
2557 : case 112:
2558 : block = "CP";
2559 0 : break;
2560 : case 113:
2561 : case 114:
2562 : block = "SH";
2563 0 : break;
2564 : case 115:
2565 : block = "VGT";
2566 0 : break;
2567 : case 178:
2568 : block = "IH";
2569 0 : break;
2570 : case 51:
2571 : block = "RLC";
2572 0 : break;
2573 : case 55:
2574 : block = "DMA";
2575 0 : break;
2576 : case 56:
2577 : block = "HDP";
2578 0 : break;
2579 : default:
2580 : block = "unknown";
2581 0 : break;
2582 : }
2583 :
2584 0 : printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
2585 : protections, vmid, addr,
2586 : (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
2587 : block, mc_id);
2588 0 : }
2589 :
2590 : /**
2591 : * cayman_vm_flush - vm flush using the CP
2592 : *
2593 : * @rdev: radeon_device pointer
2594 : *
2595 : * Update the page table base and flush the VM TLB
2596 : * using the CP (cayman-si).
2597 : */
2598 0 : void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
2599 : unsigned vm_id, uint64_t pd_addr)
2600 : {
2601 0 : radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2), 0));
2602 0 : radeon_ring_write(ring, pd_addr >> 12);
2603 :
2604 : /* flush hdp cache */
2605 0 : radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
2606 0 : radeon_ring_write(ring, 0x1);
2607 :
2608 : /* bits 0-7 are the VM contexts0-7 */
2609 0 : radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
2610 0 : radeon_ring_write(ring, 1 << vm_id);
2611 :
2612 : /* wait for the invalidate to complete */
2613 0 : radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
2614 0 : radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */
2615 : WAIT_REG_MEM_ENGINE(0))); /* me */
2616 0 : radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
2617 0 : radeon_ring_write(ring, 0);
2618 0 : radeon_ring_write(ring, 0); /* ref */
2619 0 : radeon_ring_write(ring, 0); /* mask */
2620 0 : radeon_ring_write(ring, 0x20); /* poll interval */
2621 :
2622 : /* sync PFP to ME, otherwise we might get invalid PFP reads */
2623 0 : radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2624 0 : radeon_ring_write(ring, 0x0);
2625 0 : }
2626 :
2627 0 : int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
2628 : {
2629 0 : struct atom_clock_dividers dividers;
2630 : int r, i;
2631 :
2632 0 : r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2633 : ecclk, false, ÷rs);
2634 0 : if (r)
2635 0 : return r;
2636 :
2637 0 : for (i = 0; i < 100; i++) {
2638 0 : if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
2639 : break;
2640 0 : mdelay(10);
2641 : }
2642 0 : if (i == 100)
2643 0 : return -ETIMEDOUT;
2644 :
2645 0 : WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK));
2646 :
2647 0 : for (i = 0; i < 100; i++) {
2648 0 : if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
2649 : break;
2650 0 : mdelay(10);
2651 : }
2652 0 : if (i == 100)
2653 0 : return -ETIMEDOUT;
2654 :
2655 0 : return 0;
2656 0 : }
|