blob: c73d71340d2742992771af9dd3e72aeba149c665 [file] [log] [blame]
Alex Deucher0af62b02011-01-06 21:19:31 -05001/*
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 <linux/firmware.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
Paul Gortmakere0cd3602011-08-30 11:04:30 -040027#include <linux/module.h>
David Howells760285e2012-10-02 18:01:07 +010028#include <drm/drmP.h>
Alex Deucher0af62b02011-01-06 21:19:31 -050029#include "radeon.h"
30#include "radeon_asic.h"
David Howells760285e2012-10-02 18:01:07 +010031#include <drm/radeon_drm.h>
Alex Deucher0af62b02011-01-06 21:19:31 -050032#include "nid.h"
33#include "atom.h"
34#include "ni_reg.h"
Alex Deucher0c88a022011-03-02 20:07:31 -050035#include "cayman_blit_shaders.h"
Alex Deucher138e4e12013-01-11 15:33:13 -050036#include "radeon_ucode.h"
Alex Deucher2948f5e2013-04-12 13:52:52 -040037#include "clearstate_cayman.h"
38
39static u32 tn_rlc_save_restore_register_list[] =
40{
41 0x98fc,
42 0x98f0,
43 0x9834,
44 0x9838,
45 0x9870,
46 0x9874,
47 0x8a14,
48 0x8b24,
49 0x8bcc,
50 0x8b10,
51 0x8c30,
52 0x8d00,
53 0x8d04,
54 0x8c00,
55 0x8c04,
56 0x8c10,
57 0x8c14,
58 0x8d8c,
59 0x8cf0,
60 0x8e38,
61 0x9508,
62 0x9688,
63 0x9608,
64 0x960c,
65 0x9610,
66 0x9614,
67 0x88c4,
68 0x8978,
69 0x88d4,
70 0x900c,
71 0x9100,
72 0x913c,
73 0x90e8,
74 0x9354,
75 0xa008,
76 0x98f8,
77 0x9148,
78 0x914c,
79 0x3f94,
80 0x98f4,
81 0x9b7c,
82 0x3f8c,
83 0x8950,
84 0x8954,
85 0x8a18,
86 0x8b28,
87 0x9144,
88 0x3f90,
89 0x915c,
90 0x9160,
91 0x9178,
92 0x917c,
93 0x9180,
94 0x918c,
95 0x9190,
96 0x9194,
97 0x9198,
98 0x919c,
99 0x91a8,
100 0x91ac,
101 0x91b0,
102 0x91b4,
103 0x91b8,
104 0x91c4,
105 0x91c8,
106 0x91cc,
107 0x91d0,
108 0x91d4,
109 0x91e0,
110 0x91e4,
111 0x91ec,
112 0x91f0,
113 0x91f4,
114 0x9200,
115 0x9204,
116 0x929c,
117 0x8030,
118 0x9150,
119 0x9a60,
120 0x920c,
121 0x9210,
122 0x9228,
123 0x922c,
124 0x9244,
125 0x9248,
126 0x91e8,
127 0x9294,
128 0x9208,
129 0x9224,
130 0x9240,
131 0x9220,
132 0x923c,
133 0x9258,
134 0x9744,
135 0xa200,
136 0xa204,
137 0xa208,
138 0xa20c,
139 0x8d58,
140 0x9030,
141 0x9034,
142 0x9038,
143 0x903c,
144 0x9040,
145 0x9654,
146 0x897c,
147 0xa210,
148 0xa214,
149 0x9868,
150 0xa02c,
151 0x9664,
152 0x9698,
153 0x949c,
154 0x8e10,
155 0x8e18,
156 0x8c50,
157 0x8c58,
158 0x8c60,
159 0x8c68,
160 0x89b4,
161 0x9830,
162 0x802c,
163};
164static u32 tn_rlc_save_restore_register_list_size = ARRAY_SIZE(tn_rlc_save_restore_register_list);
Alex Deucher0af62b02011-01-06 21:19:31 -0500165
Alex Deucher168757e2013-01-18 19:17:22 -0500166extern bool evergreen_is_display_hung(struct radeon_device *rdev);
Alex Deucher187e3592013-01-18 14:51:38 -0500167extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -0500168extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
169extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
170extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
Alex Deucher755d8192011-03-02 20:07:34 -0500171extern void evergreen_mc_program(struct radeon_device *rdev);
172extern void evergreen_irq_suspend(struct radeon_device *rdev);
173extern int evergreen_mc_init(struct radeon_device *rdev);
Alex Deucherd054ac12011-09-01 17:46:15 +0000174extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
Ilija Hadzicb07759b2011-09-20 10:22:58 -0400175extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
Alex Deucher2948f5e2013-04-12 13:52:52 -0400176extern void sumo_rlc_fini(struct radeon_device *rdev);
177extern int sumo_rlc_init(struct radeon_device *rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -0500178
Alex Deucher0af62b02011-01-06 21:19:31 -0500179/* Firmware Names */
180MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
181MODULE_FIRMWARE("radeon/BARTS_me.bin");
182MODULE_FIRMWARE("radeon/BARTS_mc.bin");
183MODULE_FIRMWARE("radeon/BTC_rlc.bin");
184MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
185MODULE_FIRMWARE("radeon/TURKS_me.bin");
186MODULE_FIRMWARE("radeon/TURKS_mc.bin");
187MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
188MODULE_FIRMWARE("radeon/CAICOS_me.bin");
189MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
Alex Deucher9b8253c2011-03-02 20:07:28 -0500190MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
191MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
192MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
193MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
Alex Deucherc420c742012-03-20 17:18:39 -0400194MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
195MODULE_FIRMWARE("radeon/ARUBA_me.bin");
196MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500197
Alex Deuchera2c96a22013-02-28 17:58:36 -0500198
199static const u32 cayman_golden_registers2[] =
200{
201 0x3e5c, 0xffffffff, 0x00000000,
202 0x3e48, 0xffffffff, 0x00000000,
203 0x3e4c, 0xffffffff, 0x00000000,
204 0x3e64, 0xffffffff, 0x00000000,
205 0x3e50, 0xffffffff, 0x00000000,
206 0x3e60, 0xffffffff, 0x00000000
207};
208
209static const u32 cayman_golden_registers[] =
210{
211 0x5eb4, 0xffffffff, 0x00000002,
212 0x5e78, 0x8f311ff1, 0x001000f0,
213 0x3f90, 0xffff0000, 0xff000000,
214 0x9148, 0xffff0000, 0xff000000,
215 0x3f94, 0xffff0000, 0xff000000,
216 0x914c, 0xffff0000, 0xff000000,
217 0xc78, 0x00000080, 0x00000080,
218 0xbd4, 0x70073777, 0x00011003,
219 0xd02c, 0xbfffff1f, 0x08421000,
220 0xd0b8, 0x73773777, 0x02011003,
221 0x5bc0, 0x00200000, 0x50100000,
222 0x98f8, 0x33773777, 0x02011003,
223 0x98fc, 0xffffffff, 0x76541032,
224 0x7030, 0x31000311, 0x00000011,
225 0x2f48, 0x33773777, 0x42010001,
226 0x6b28, 0x00000010, 0x00000012,
227 0x7728, 0x00000010, 0x00000012,
228 0x10328, 0x00000010, 0x00000012,
229 0x10f28, 0x00000010, 0x00000012,
230 0x11b28, 0x00000010, 0x00000012,
231 0x12728, 0x00000010, 0x00000012,
232 0x240c, 0x000007ff, 0x00000000,
233 0x8a14, 0xf000001f, 0x00000007,
234 0x8b24, 0x3fff3fff, 0x00ff0fff,
235 0x8b10, 0x0000ff0f, 0x00000000,
236 0x28a4c, 0x07ffffff, 0x06000000,
237 0x10c, 0x00000001, 0x00010003,
238 0xa02c, 0xffffffff, 0x0000009b,
239 0x913c, 0x0000010f, 0x01000100,
240 0x8c04, 0xf8ff00ff, 0x40600060,
241 0x28350, 0x00000f01, 0x00000000,
242 0x9508, 0x3700001f, 0x00000002,
243 0x960c, 0xffffffff, 0x54763210,
244 0x88c4, 0x001f3ae3, 0x00000082,
245 0x88d0, 0xffffffff, 0x0f40df40,
246 0x88d4, 0x0000001f, 0x00000010,
247 0x8974, 0xffffffff, 0x00000000
248};
249
250static const u32 dvst_golden_registers2[] =
251{
252 0x8f8, 0xffffffff, 0,
253 0x8fc, 0x00380000, 0,
254 0x8f8, 0xffffffff, 1,
255 0x8fc, 0x0e000000, 0
256};
257
258static const u32 dvst_golden_registers[] =
259{
260 0x690, 0x3fff3fff, 0x20c00033,
261 0x918c, 0x0fff0fff, 0x00010006,
262 0x91a8, 0x0fff0fff, 0x00010006,
263 0x9150, 0xffffdfff, 0x6e944040,
264 0x917c, 0x0fff0fff, 0x00030002,
265 0x9198, 0x0fff0fff, 0x00030002,
266 0x915c, 0x0fff0fff, 0x00010000,
267 0x3f90, 0xffff0001, 0xff000000,
268 0x9178, 0x0fff0fff, 0x00070000,
269 0x9194, 0x0fff0fff, 0x00070000,
270 0x9148, 0xffff0001, 0xff000000,
271 0x9190, 0x0fff0fff, 0x00090008,
272 0x91ac, 0x0fff0fff, 0x00090008,
273 0x3f94, 0xffff0000, 0xff000000,
274 0x914c, 0xffff0000, 0xff000000,
275 0x929c, 0x00000fff, 0x00000001,
276 0x55e4, 0xff607fff, 0xfc000100,
277 0x8a18, 0xff000fff, 0x00000100,
278 0x8b28, 0xff000fff, 0x00000100,
279 0x9144, 0xfffc0fff, 0x00000100,
280 0x6ed8, 0x00010101, 0x00010000,
281 0x9830, 0xffffffff, 0x00000000,
282 0x9834, 0xf00fffff, 0x00000400,
283 0x9838, 0xfffffffe, 0x00000000,
284 0xd0c0, 0xff000fff, 0x00000100,
285 0xd02c, 0xbfffff1f, 0x08421000,
286 0xd0b8, 0x73773777, 0x12010001,
287 0x5bb0, 0x000000f0, 0x00000070,
288 0x98f8, 0x73773777, 0x12010001,
289 0x98fc, 0xffffffff, 0x00000010,
290 0x9b7c, 0x00ff0000, 0x00fc0000,
291 0x8030, 0x00001f0f, 0x0000100a,
292 0x2f48, 0x73773777, 0x12010001,
293 0x2408, 0x00030000, 0x000c007f,
294 0x8a14, 0xf000003f, 0x00000007,
295 0x8b24, 0x3fff3fff, 0x00ff0fff,
296 0x8b10, 0x0000ff0f, 0x00000000,
297 0x28a4c, 0x07ffffff, 0x06000000,
298 0x4d8, 0x00000fff, 0x00000100,
299 0xa008, 0xffffffff, 0x00010000,
300 0x913c, 0xffff03ff, 0x01000100,
301 0x8c00, 0x000000ff, 0x00000003,
302 0x8c04, 0xf8ff00ff, 0x40600060,
303 0x8cf0, 0x1fff1fff, 0x08e00410,
304 0x28350, 0x00000f01, 0x00000000,
305 0x9508, 0xf700071f, 0x00000002,
306 0x960c, 0xffffffff, 0x54763210,
307 0x20ef8, 0x01ff01ff, 0x00000002,
308 0x20e98, 0xfffffbff, 0x00200000,
309 0x2015c, 0xffffffff, 0x00000f40,
310 0x88c4, 0x001f3ae3, 0x00000082,
311 0x8978, 0x3fffffff, 0x04050140,
312 0x88d4, 0x0000001f, 0x00000010,
313 0x8974, 0xffffffff, 0x00000000
314};
315
316static const u32 scrapper_golden_registers[] =
317{
318 0x690, 0x3fff3fff, 0x20c00033,
319 0x918c, 0x0fff0fff, 0x00010006,
320 0x918c, 0x0fff0fff, 0x00010006,
321 0x91a8, 0x0fff0fff, 0x00010006,
322 0x91a8, 0x0fff0fff, 0x00010006,
323 0x9150, 0xffffdfff, 0x6e944040,
324 0x9150, 0xffffdfff, 0x6e944040,
325 0x917c, 0x0fff0fff, 0x00030002,
326 0x917c, 0x0fff0fff, 0x00030002,
327 0x9198, 0x0fff0fff, 0x00030002,
328 0x9198, 0x0fff0fff, 0x00030002,
329 0x915c, 0x0fff0fff, 0x00010000,
330 0x915c, 0x0fff0fff, 0x00010000,
331 0x3f90, 0xffff0001, 0xff000000,
332 0x3f90, 0xffff0001, 0xff000000,
333 0x9178, 0x0fff0fff, 0x00070000,
334 0x9178, 0x0fff0fff, 0x00070000,
335 0x9194, 0x0fff0fff, 0x00070000,
336 0x9194, 0x0fff0fff, 0x00070000,
337 0x9148, 0xffff0001, 0xff000000,
338 0x9148, 0xffff0001, 0xff000000,
339 0x9190, 0x0fff0fff, 0x00090008,
340 0x9190, 0x0fff0fff, 0x00090008,
341 0x91ac, 0x0fff0fff, 0x00090008,
342 0x91ac, 0x0fff0fff, 0x00090008,
343 0x3f94, 0xffff0000, 0xff000000,
344 0x3f94, 0xffff0000, 0xff000000,
345 0x914c, 0xffff0000, 0xff000000,
346 0x914c, 0xffff0000, 0xff000000,
347 0x929c, 0x00000fff, 0x00000001,
348 0x929c, 0x00000fff, 0x00000001,
349 0x55e4, 0xff607fff, 0xfc000100,
350 0x8a18, 0xff000fff, 0x00000100,
351 0x8a18, 0xff000fff, 0x00000100,
352 0x8b28, 0xff000fff, 0x00000100,
353 0x8b28, 0xff000fff, 0x00000100,
354 0x9144, 0xfffc0fff, 0x00000100,
355 0x9144, 0xfffc0fff, 0x00000100,
356 0x6ed8, 0x00010101, 0x00010000,
357 0x9830, 0xffffffff, 0x00000000,
358 0x9830, 0xffffffff, 0x00000000,
359 0x9834, 0xf00fffff, 0x00000400,
360 0x9834, 0xf00fffff, 0x00000400,
361 0x9838, 0xfffffffe, 0x00000000,
362 0x9838, 0xfffffffe, 0x00000000,
363 0xd0c0, 0xff000fff, 0x00000100,
364 0xd02c, 0xbfffff1f, 0x08421000,
365 0xd02c, 0xbfffff1f, 0x08421000,
366 0xd0b8, 0x73773777, 0x12010001,
367 0xd0b8, 0x73773777, 0x12010001,
368 0x5bb0, 0x000000f0, 0x00000070,
369 0x98f8, 0x73773777, 0x12010001,
370 0x98f8, 0x73773777, 0x12010001,
371 0x98fc, 0xffffffff, 0x00000010,
372 0x98fc, 0xffffffff, 0x00000010,
373 0x9b7c, 0x00ff0000, 0x00fc0000,
374 0x9b7c, 0x00ff0000, 0x00fc0000,
375 0x8030, 0x00001f0f, 0x0000100a,
376 0x8030, 0x00001f0f, 0x0000100a,
377 0x2f48, 0x73773777, 0x12010001,
378 0x2f48, 0x73773777, 0x12010001,
379 0x2408, 0x00030000, 0x000c007f,
380 0x8a14, 0xf000003f, 0x00000007,
381 0x8a14, 0xf000003f, 0x00000007,
382 0x8b24, 0x3fff3fff, 0x00ff0fff,
383 0x8b24, 0x3fff3fff, 0x00ff0fff,
384 0x8b10, 0x0000ff0f, 0x00000000,
385 0x8b10, 0x0000ff0f, 0x00000000,
386 0x28a4c, 0x07ffffff, 0x06000000,
387 0x28a4c, 0x07ffffff, 0x06000000,
388 0x4d8, 0x00000fff, 0x00000100,
389 0x4d8, 0x00000fff, 0x00000100,
390 0xa008, 0xffffffff, 0x00010000,
391 0xa008, 0xffffffff, 0x00010000,
392 0x913c, 0xffff03ff, 0x01000100,
393 0x913c, 0xffff03ff, 0x01000100,
394 0x90e8, 0x001fffff, 0x010400c0,
395 0x8c00, 0x000000ff, 0x00000003,
396 0x8c00, 0x000000ff, 0x00000003,
397 0x8c04, 0xf8ff00ff, 0x40600060,
398 0x8c04, 0xf8ff00ff, 0x40600060,
399 0x8c30, 0x0000000f, 0x00040005,
400 0x8cf0, 0x1fff1fff, 0x08e00410,
401 0x8cf0, 0x1fff1fff, 0x08e00410,
402 0x900c, 0x00ffffff, 0x0017071f,
403 0x28350, 0x00000f01, 0x00000000,
404 0x28350, 0x00000f01, 0x00000000,
405 0x9508, 0xf700071f, 0x00000002,
406 0x9508, 0xf700071f, 0x00000002,
407 0x9688, 0x00300000, 0x0017000f,
408 0x960c, 0xffffffff, 0x54763210,
409 0x960c, 0xffffffff, 0x54763210,
410 0x20ef8, 0x01ff01ff, 0x00000002,
411 0x20e98, 0xfffffbff, 0x00200000,
412 0x2015c, 0xffffffff, 0x00000f40,
413 0x88c4, 0x001f3ae3, 0x00000082,
414 0x88c4, 0x001f3ae3, 0x00000082,
415 0x8978, 0x3fffffff, 0x04050140,
416 0x8978, 0x3fffffff, 0x04050140,
417 0x88d4, 0x0000001f, 0x00000010,
418 0x88d4, 0x0000001f, 0x00000010,
419 0x8974, 0xffffffff, 0x00000000,
420 0x8974, 0xffffffff, 0x00000000
421};
422
423static void ni_init_golden_registers(struct radeon_device *rdev)
424{
425 switch (rdev->family) {
426 case CHIP_CAYMAN:
427 radeon_program_register_sequence(rdev,
428 cayman_golden_registers,
429 (const u32)ARRAY_SIZE(cayman_golden_registers));
430 radeon_program_register_sequence(rdev,
431 cayman_golden_registers2,
432 (const u32)ARRAY_SIZE(cayman_golden_registers2));
433 break;
434 case CHIP_ARUBA:
435 if ((rdev->pdev->device == 0x9900) ||
436 (rdev->pdev->device == 0x9901) ||
437 (rdev->pdev->device == 0x9903) ||
438 (rdev->pdev->device == 0x9904) ||
439 (rdev->pdev->device == 0x9905) ||
440 (rdev->pdev->device == 0x9906) ||
441 (rdev->pdev->device == 0x9907) ||
442 (rdev->pdev->device == 0x9908) ||
443 (rdev->pdev->device == 0x9909) ||
444 (rdev->pdev->device == 0x990A) ||
445 (rdev->pdev->device == 0x990B) ||
446 (rdev->pdev->device == 0x990C) ||
447 (rdev->pdev->device == 0x990D) ||
448 (rdev->pdev->device == 0x990E) ||
449 (rdev->pdev->device == 0x990F) ||
450 (rdev->pdev->device == 0x9910) ||
451 (rdev->pdev->device == 0x9913) ||
452 (rdev->pdev->device == 0x9917) ||
453 (rdev->pdev->device == 0x9918)) {
454 radeon_program_register_sequence(rdev,
455 dvst_golden_registers,
456 (const u32)ARRAY_SIZE(dvst_golden_registers));
457 radeon_program_register_sequence(rdev,
458 dvst_golden_registers2,
459 (const u32)ARRAY_SIZE(dvst_golden_registers2));
460 } else {
461 radeon_program_register_sequence(rdev,
462 scrapper_golden_registers,
463 (const u32)ARRAY_SIZE(scrapper_golden_registers));
464 radeon_program_register_sequence(rdev,
465 dvst_golden_registers2,
466 (const u32)ARRAY_SIZE(dvst_golden_registers2));
467 }
468 break;
469 default:
470 break;
471 }
472}
473
Alex Deucher0af62b02011-01-06 21:19:31 -0500474#define BTC_IO_MC_REGS_SIZE 29
475
476static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
477 {0x00000077, 0xff010100},
478 {0x00000078, 0x00000000},
479 {0x00000079, 0x00001434},
480 {0x0000007a, 0xcc08ec08},
481 {0x0000007b, 0x00040000},
482 {0x0000007c, 0x000080c0},
483 {0x0000007d, 0x09000000},
484 {0x0000007e, 0x00210404},
485 {0x00000081, 0x08a8e800},
486 {0x00000082, 0x00030444},
487 {0x00000083, 0x00000000},
488 {0x00000085, 0x00000001},
489 {0x00000086, 0x00000002},
490 {0x00000087, 0x48490000},
491 {0x00000088, 0x20244647},
492 {0x00000089, 0x00000005},
493 {0x0000008b, 0x66030000},
494 {0x0000008c, 0x00006603},
495 {0x0000008d, 0x00000100},
496 {0x0000008f, 0x00001c0a},
497 {0x00000090, 0xff000001},
498 {0x00000094, 0x00101101},
499 {0x00000095, 0x00000fff},
500 {0x00000096, 0x00116fff},
501 {0x00000097, 0x60010000},
502 {0x00000098, 0x10010000},
503 {0x00000099, 0x00006000},
504 {0x0000009a, 0x00001000},
505 {0x0000009f, 0x00946a00}
506};
507
508static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
509 {0x00000077, 0xff010100},
510 {0x00000078, 0x00000000},
511 {0x00000079, 0x00001434},
512 {0x0000007a, 0xcc08ec08},
513 {0x0000007b, 0x00040000},
514 {0x0000007c, 0x000080c0},
515 {0x0000007d, 0x09000000},
516 {0x0000007e, 0x00210404},
517 {0x00000081, 0x08a8e800},
518 {0x00000082, 0x00030444},
519 {0x00000083, 0x00000000},
520 {0x00000085, 0x00000001},
521 {0x00000086, 0x00000002},
522 {0x00000087, 0x48490000},
523 {0x00000088, 0x20244647},
524 {0x00000089, 0x00000005},
525 {0x0000008b, 0x66030000},
526 {0x0000008c, 0x00006603},
527 {0x0000008d, 0x00000100},
528 {0x0000008f, 0x00001c0a},
529 {0x00000090, 0xff000001},
530 {0x00000094, 0x00101101},
531 {0x00000095, 0x00000fff},
532 {0x00000096, 0x00116fff},
533 {0x00000097, 0x60010000},
534 {0x00000098, 0x10010000},
535 {0x00000099, 0x00006000},
536 {0x0000009a, 0x00001000},
537 {0x0000009f, 0x00936a00}
538};
539
540static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
541 {0x00000077, 0xff010100},
542 {0x00000078, 0x00000000},
543 {0x00000079, 0x00001434},
544 {0x0000007a, 0xcc08ec08},
545 {0x0000007b, 0x00040000},
546 {0x0000007c, 0x000080c0},
547 {0x0000007d, 0x09000000},
548 {0x0000007e, 0x00210404},
549 {0x00000081, 0x08a8e800},
550 {0x00000082, 0x00030444},
551 {0x00000083, 0x00000000},
552 {0x00000085, 0x00000001},
553 {0x00000086, 0x00000002},
554 {0x00000087, 0x48490000},
555 {0x00000088, 0x20244647},
556 {0x00000089, 0x00000005},
557 {0x0000008b, 0x66030000},
558 {0x0000008c, 0x00006603},
559 {0x0000008d, 0x00000100},
560 {0x0000008f, 0x00001c0a},
561 {0x00000090, 0xff000001},
562 {0x00000094, 0x00101101},
563 {0x00000095, 0x00000fff},
564 {0x00000096, 0x00116fff},
565 {0x00000097, 0x60010000},
566 {0x00000098, 0x10010000},
567 {0x00000099, 0x00006000},
568 {0x0000009a, 0x00001000},
569 {0x0000009f, 0x00916a00}
570};
571
Alex Deucher9b8253c2011-03-02 20:07:28 -0500572static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
573 {0x00000077, 0xff010100},
574 {0x00000078, 0x00000000},
575 {0x00000079, 0x00001434},
576 {0x0000007a, 0xcc08ec08},
577 {0x0000007b, 0x00040000},
578 {0x0000007c, 0x000080c0},
579 {0x0000007d, 0x09000000},
580 {0x0000007e, 0x00210404},
581 {0x00000081, 0x08a8e800},
582 {0x00000082, 0x00030444},
583 {0x00000083, 0x00000000},
584 {0x00000085, 0x00000001},
585 {0x00000086, 0x00000002},
586 {0x00000087, 0x48490000},
587 {0x00000088, 0x20244647},
588 {0x00000089, 0x00000005},
589 {0x0000008b, 0x66030000},
590 {0x0000008c, 0x00006603},
591 {0x0000008d, 0x00000100},
592 {0x0000008f, 0x00001c0a},
593 {0x00000090, 0xff000001},
594 {0x00000094, 0x00101101},
595 {0x00000095, 0x00000fff},
596 {0x00000096, 0x00116fff},
597 {0x00000097, 0x60010000},
598 {0x00000098, 0x10010000},
599 {0x00000099, 0x00006000},
600 {0x0000009a, 0x00001000},
601 {0x0000009f, 0x00976b00}
602};
603
Alex Deucher755d8192011-03-02 20:07:34 -0500604int ni_mc_load_microcode(struct radeon_device *rdev)
Alex Deucher0af62b02011-01-06 21:19:31 -0500605{
606 const __be32 *fw_data;
607 u32 mem_type, running, blackout = 0;
608 u32 *io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500609 int i, ucode_size, regs_size;
Alex Deucher0af62b02011-01-06 21:19:31 -0500610
611 if (!rdev->mc_fw)
612 return -EINVAL;
613
614 switch (rdev->family) {
615 case CHIP_BARTS:
616 io_mc_regs = (u32 *)&barts_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500617 ucode_size = BTC_MC_UCODE_SIZE;
618 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500619 break;
620 case CHIP_TURKS:
621 io_mc_regs = (u32 *)&turks_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500622 ucode_size = BTC_MC_UCODE_SIZE;
623 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500624 break;
625 case CHIP_CAICOS:
626 default:
627 io_mc_regs = (u32 *)&caicos_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500628 ucode_size = BTC_MC_UCODE_SIZE;
629 regs_size = BTC_IO_MC_REGS_SIZE;
630 break;
631 case CHIP_CAYMAN:
632 io_mc_regs = (u32 *)&cayman_io_mc_regs;
633 ucode_size = CAYMAN_MC_UCODE_SIZE;
634 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500635 break;
636 }
637
638 mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
639 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
640
641 if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
642 if (running) {
643 blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
644 WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
645 }
646
647 /* reset the engine and set to writable */
648 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
649 WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
650
651 /* load mc io regs */
Alex Deucher9b8253c2011-03-02 20:07:28 -0500652 for (i = 0; i < regs_size; i++) {
Alex Deucher0af62b02011-01-06 21:19:31 -0500653 WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
654 WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
655 }
656 /* load the MC ucode */
657 fw_data = (const __be32 *)rdev->mc_fw->data;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500658 for (i = 0; i < ucode_size; i++)
Alex Deucher0af62b02011-01-06 21:19:31 -0500659 WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
660
661 /* put the engine back into the active state */
662 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
663 WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
664 WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
665
666 /* wait for training to complete */
Alex Deucher0e2c9782011-11-02 18:08:25 -0400667 for (i = 0; i < rdev->usec_timeout; i++) {
668 if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
669 break;
670 udelay(1);
671 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500672
673 if (running)
674 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
675 }
676
677 return 0;
678}
679
680int ni_init_microcode(struct radeon_device *rdev)
681{
682 struct platform_device *pdev;
683 const char *chip_name;
684 const char *rlc_chip_name;
685 size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
686 char fw_name[30];
687 int err;
688
689 DRM_DEBUG("\n");
690
691 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
692 err = IS_ERR(pdev);
693 if (err) {
694 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
695 return -EINVAL;
696 }
697
698 switch (rdev->family) {
699 case CHIP_BARTS:
700 chip_name = "BARTS";
701 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500702 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
703 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
704 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
705 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500706 break;
707 case CHIP_TURKS:
708 chip_name = "TURKS";
709 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500710 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
711 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
712 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
713 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500714 break;
715 case CHIP_CAICOS:
716 chip_name = "CAICOS";
717 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500718 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
719 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
720 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
721 mc_req_size = BTC_MC_UCODE_SIZE * 4;
722 break;
723 case CHIP_CAYMAN:
724 chip_name = "CAYMAN";
725 rlc_chip_name = "CAYMAN";
726 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
727 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
728 rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
729 mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500730 break;
Alex Deucherc420c742012-03-20 17:18:39 -0400731 case CHIP_ARUBA:
732 chip_name = "ARUBA";
733 rlc_chip_name = "ARUBA";
734 /* pfp/me same size as CAYMAN */
735 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
736 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
737 rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
738 mc_req_size = 0;
739 break;
Alex Deucher0af62b02011-01-06 21:19:31 -0500740 default: BUG();
741 }
742
Alex Deucher0af62b02011-01-06 21:19:31 -0500743 DRM_INFO("Loading %s Microcode\n", chip_name);
744
745 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
746 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
747 if (err)
748 goto out;
749 if (rdev->pfp_fw->size != pfp_req_size) {
750 printk(KERN_ERR
751 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
752 rdev->pfp_fw->size, fw_name);
753 err = -EINVAL;
754 goto out;
755 }
756
757 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
758 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
759 if (err)
760 goto out;
761 if (rdev->me_fw->size != me_req_size) {
762 printk(KERN_ERR
763 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
764 rdev->me_fw->size, fw_name);
765 err = -EINVAL;
766 }
767
768 snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
769 err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
770 if (err)
771 goto out;
772 if (rdev->rlc_fw->size != rlc_req_size) {
773 printk(KERN_ERR
774 "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
775 rdev->rlc_fw->size, fw_name);
776 err = -EINVAL;
777 }
778
Alex Deucherc420c742012-03-20 17:18:39 -0400779 /* no MC ucode on TN */
780 if (!(rdev->flags & RADEON_IS_IGP)) {
781 snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
782 err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
783 if (err)
784 goto out;
785 if (rdev->mc_fw->size != mc_req_size) {
786 printk(KERN_ERR
787 "ni_mc: Bogus length %zu in firmware \"%s\"\n",
788 rdev->mc_fw->size, fw_name);
789 err = -EINVAL;
790 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500791 }
792out:
793 platform_device_unregister(pdev);
794
795 if (err) {
796 if (err != -EINVAL)
797 printk(KERN_ERR
798 "ni_cp: Failed to load firmware \"%s\"\n",
799 fw_name);
800 release_firmware(rdev->pfp_fw);
801 rdev->pfp_fw = NULL;
802 release_firmware(rdev->me_fw);
803 rdev->me_fw = NULL;
804 release_firmware(rdev->rlc_fw);
805 rdev->rlc_fw = NULL;
806 release_firmware(rdev->mc_fw);
807 rdev->mc_fw = NULL;
808 }
809 return err;
810}
811
Alex Deucher29a15222012-12-14 11:57:36 -0500812int tn_get_temp(struct radeon_device *rdev)
813{
814 u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
815 int actual_temp = (temp / 8) - 49;
816
817 return actual_temp * 1000;
818}
819
Alex Deucherfecf1d02011-03-02 20:07:29 -0500820/*
821 * Core functions
822 */
Alex Deucherfecf1d02011-03-02 20:07:29 -0500823static void cayman_gpu_init(struct radeon_device *rdev)
824{
Alex Deucherfecf1d02011-03-02 20:07:29 -0500825 u32 gb_addr_config = 0;
826 u32 mc_shared_chmap, mc_arb_ramcfg;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500827 u32 cgts_tcc_disable;
828 u32 sx_debug_1;
829 u32 smx_dc_ctl0;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500830 u32 cgts_sm_ctrl_reg;
831 u32 hdp_host_path_cntl;
832 u32 tmp;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400833 u32 disabled_rb_mask;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500834 int i, j;
835
836 switch (rdev->family) {
837 case CHIP_CAYMAN:
Alex Deucherfecf1d02011-03-02 20:07:29 -0500838 rdev->config.cayman.max_shader_engines = 2;
839 rdev->config.cayman.max_pipes_per_simd = 4;
840 rdev->config.cayman.max_tile_pipes = 8;
841 rdev->config.cayman.max_simds_per_se = 12;
842 rdev->config.cayman.max_backends_per_se = 4;
843 rdev->config.cayman.max_texture_channel_caches = 8;
844 rdev->config.cayman.max_gprs = 256;
845 rdev->config.cayman.max_threads = 256;
846 rdev->config.cayman.max_gs_threads = 32;
847 rdev->config.cayman.max_stack_entries = 512;
848 rdev->config.cayman.sx_num_of_sets = 8;
849 rdev->config.cayman.sx_max_export_size = 256;
850 rdev->config.cayman.sx_max_export_pos_size = 64;
851 rdev->config.cayman.sx_max_export_smx_size = 192;
852 rdev->config.cayman.max_hw_contexts = 8;
853 rdev->config.cayman.sq_num_cf_insts = 2;
854
855 rdev->config.cayman.sc_prim_fifo_size = 0x100;
856 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
857 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400858 gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500859 break;
Alex Deucher7b76e472012-03-20 17:18:36 -0400860 case CHIP_ARUBA:
861 default:
862 rdev->config.cayman.max_shader_engines = 1;
863 rdev->config.cayman.max_pipes_per_simd = 4;
864 rdev->config.cayman.max_tile_pipes = 2;
865 if ((rdev->pdev->device == 0x9900) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400866 (rdev->pdev->device == 0x9901) ||
867 (rdev->pdev->device == 0x9905) ||
868 (rdev->pdev->device == 0x9906) ||
869 (rdev->pdev->device == 0x9907) ||
870 (rdev->pdev->device == 0x9908) ||
871 (rdev->pdev->device == 0x9909) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500872 (rdev->pdev->device == 0x990B) ||
873 (rdev->pdev->device == 0x990C) ||
874 (rdev->pdev->device == 0x990F) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400875 (rdev->pdev->device == 0x9910) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500876 (rdev->pdev->device == 0x9917) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400877 (rdev->pdev->device == 0x9999) ||
878 (rdev->pdev->device == 0x999C)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400879 rdev->config.cayman.max_simds_per_se = 6;
880 rdev->config.cayman.max_backends_per_se = 2;
881 } else if ((rdev->pdev->device == 0x9903) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400882 (rdev->pdev->device == 0x9904) ||
883 (rdev->pdev->device == 0x990A) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500884 (rdev->pdev->device == 0x990D) ||
885 (rdev->pdev->device == 0x990E) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400886 (rdev->pdev->device == 0x9913) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400887 (rdev->pdev->device == 0x9918) ||
888 (rdev->pdev->device == 0x999D)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400889 rdev->config.cayman.max_simds_per_se = 4;
890 rdev->config.cayman.max_backends_per_se = 2;
Alex Deucherd430f7d2012-06-05 09:50:28 -0400891 } else if ((rdev->pdev->device == 0x9919) ||
892 (rdev->pdev->device == 0x9990) ||
893 (rdev->pdev->device == 0x9991) ||
894 (rdev->pdev->device == 0x9994) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500895 (rdev->pdev->device == 0x9995) ||
896 (rdev->pdev->device == 0x9996) ||
897 (rdev->pdev->device == 0x999A) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400898 (rdev->pdev->device == 0x99A0)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400899 rdev->config.cayman.max_simds_per_se = 3;
900 rdev->config.cayman.max_backends_per_se = 1;
901 } else {
902 rdev->config.cayman.max_simds_per_se = 2;
903 rdev->config.cayman.max_backends_per_se = 1;
904 }
905 rdev->config.cayman.max_texture_channel_caches = 2;
906 rdev->config.cayman.max_gprs = 256;
907 rdev->config.cayman.max_threads = 256;
908 rdev->config.cayman.max_gs_threads = 32;
909 rdev->config.cayman.max_stack_entries = 512;
910 rdev->config.cayman.sx_num_of_sets = 8;
911 rdev->config.cayman.sx_max_export_size = 256;
912 rdev->config.cayman.sx_max_export_pos_size = 64;
913 rdev->config.cayman.sx_max_export_smx_size = 192;
914 rdev->config.cayman.max_hw_contexts = 8;
915 rdev->config.cayman.sq_num_cf_insts = 2;
916
917 rdev->config.cayman.sc_prim_fifo_size = 0x40;
918 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
919 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400920 gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
Alex Deucher7b76e472012-03-20 17:18:36 -0400921 break;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500922 }
923
924 /* Initialize HDP */
925 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
926 WREG32((0x2c14 + j), 0x00000000);
927 WREG32((0x2c18 + j), 0x00000000);
928 WREG32((0x2c1c + j), 0x00000000);
929 WREG32((0x2c20 + j), 0x00000000);
930 WREG32((0x2c24 + j), 0x00000000);
931 }
932
933 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
934
Alex Deucherd054ac12011-09-01 17:46:15 +0000935 evergreen_fix_pci_max_read_req_size(rdev);
936
Alex Deucherfecf1d02011-03-02 20:07:29 -0500937 mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
938 mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
939
Alex Deucherfecf1d02011-03-02 20:07:29 -0500940 tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
941 rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
942 if (rdev->config.cayman.mem_row_size_in_kb > 4)
943 rdev->config.cayman.mem_row_size_in_kb = 4;
944 /* XXX use MC settings? */
945 rdev->config.cayman.shader_engine_tile_size = 32;
946 rdev->config.cayman.num_gpus = 1;
947 rdev->config.cayman.multi_gpu_tile_size = 64;
948
Alex Deucherfecf1d02011-03-02 20:07:29 -0500949 tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
950 rdev->config.cayman.num_tile_pipes = (1 << tmp);
951 tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
952 rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
953 tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
954 rdev->config.cayman.num_shader_engines = tmp + 1;
955 tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
956 rdev->config.cayman.num_gpus = tmp + 1;
957 tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
958 rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
959 tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
960 rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
961
Alex Deucher416a2bd2012-05-31 19:00:25 -0400962
Alex Deucherfecf1d02011-03-02 20:07:29 -0500963 /* setup tiling info dword. gb_addr_config is not adequate since it does
964 * not have bank info, so create a custom tiling dword.
965 * bits 3:0 num_pipes
966 * bits 7:4 num_banks
967 * bits 11:8 group_size
968 * bits 15:12 row_size
969 */
970 rdev->config.cayman.tile_config = 0;
971 switch (rdev->config.cayman.num_tile_pipes) {
972 case 1:
973 default:
974 rdev->config.cayman.tile_config |= (0 << 0);
975 break;
976 case 2:
977 rdev->config.cayman.tile_config |= (1 << 0);
978 break;
979 case 4:
980 rdev->config.cayman.tile_config |= (2 << 0);
981 break;
982 case 8:
983 rdev->config.cayman.tile_config |= (3 << 0);
984 break;
985 }
Alex Deucher7b76e472012-03-20 17:18:36 -0400986
987 /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
988 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher1f73cca2012-05-24 22:55:15 -0400989 rdev->config.cayman.tile_config |= 1 << 4;
Alex Deucher29d65402012-05-31 18:53:36 -0400990 else {
Alex Deucher5b23c902012-07-31 11:05:11 -0400991 switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
992 case 0: /* four banks */
Alex Deucher29d65402012-05-31 18:53:36 -0400993 rdev->config.cayman.tile_config |= 0 << 4;
Alex Deucher5b23c902012-07-31 11:05:11 -0400994 break;
995 case 1: /* eight banks */
996 rdev->config.cayman.tile_config |= 1 << 4;
997 break;
998 case 2: /* sixteen banks */
999 default:
1000 rdev->config.cayman.tile_config |= 2 << 4;
1001 break;
1002 }
Alex Deucher29d65402012-05-31 18:53:36 -04001003 }
Alex Deucherfecf1d02011-03-02 20:07:29 -05001004 rdev->config.cayman.tile_config |=
Dave Airliecde50832011-05-19 14:14:41 +10001005 ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
Alex Deucherfecf1d02011-03-02 20:07:29 -05001006 rdev->config.cayman.tile_config |=
1007 ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
1008
Alex Deucher416a2bd2012-05-31 19:00:25 -04001009 tmp = 0;
1010 for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
1011 u32 rb_disable_bitmap;
1012
1013 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1014 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1015 rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
1016 tmp <<= 4;
1017 tmp |= rb_disable_bitmap;
1018 }
1019 /* enabled rb are just the one not disabled :) */
1020 disabled_rb_mask = tmp;
Alex Deuchercedb6552013-04-09 10:13:22 -04001021 tmp = 0;
1022 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1023 tmp |= (1 << i);
1024 /* if all the backends are disabled, fix it up here */
1025 if ((disabled_rb_mask & tmp) == tmp) {
1026 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1027 disabled_rb_mask &= ~(1 << i);
1028 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001029
1030 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1031 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1032
Alex Deucherfecf1d02011-03-02 20:07:29 -05001033 WREG32(GB_ADDR_CONFIG, gb_addr_config);
1034 WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
Alex Deucher7c1c7c12013-04-05 10:28:08 -04001035 if (ASIC_IS_DCE6(rdev))
1036 WREG32(DMIF_ADDR_CALC, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001037 WREG32(HDP_ADDR_CONFIG, gb_addr_config);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001038 WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
1039 WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
Christian König9a210592013-04-08 12:41:37 +02001040 WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
1041 WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
1042 WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001043
Alex Deucher8f612b22013-03-11 19:28:39 -04001044 if ((rdev->config.cayman.max_backends_per_se == 1) &&
1045 (rdev->flags & RADEON_IS_IGP)) {
1046 if ((disabled_rb_mask & 3) == 1) {
1047 /* RB0 disabled, RB1 enabled */
1048 tmp = 0x11111111;
1049 } else {
1050 /* RB1 disabled, RB0 enabled */
1051 tmp = 0x00000000;
1052 }
1053 } else {
1054 tmp = gb_addr_config & NUM_PIPES_MASK;
1055 tmp = r6xx_remap_render_backend(rdev, tmp,
1056 rdev->config.cayman.max_backends_per_se *
1057 rdev->config.cayman.max_shader_engines,
1058 CAYMAN_MAX_BACKENDS, disabled_rb_mask);
1059 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001060 WREG32(GB_BACKEND_MAP, tmp);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001061
Alex Deucher416a2bd2012-05-31 19:00:25 -04001062 cgts_tcc_disable = 0xffff0000;
1063 for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
1064 cgts_tcc_disable &= ~(1 << (16 + i));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001065 WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
1066 WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001067 WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
1068 WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
1069
1070 /* reprogram the shader complex */
1071 cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
1072 for (i = 0; i < 16; i++)
1073 WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
1074 WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
1075
1076 /* set HW defaults for 3D engine */
1077 WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
1078
1079 sx_debug_1 = RREG32(SX_DEBUG_1);
1080 sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1081 WREG32(SX_DEBUG_1, sx_debug_1);
1082
1083 smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1084 smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
Dave Airlie285e0422011-05-09 14:54:33 +10001085 smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001086 WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1087
1088 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
1089
1090 /* need to be explicitly zero-ed */
1091 WREG32(VGT_OFFCHIP_LDS_BASE, 0);
1092 WREG32(SQ_LSTMP_RING_BASE, 0);
1093 WREG32(SQ_HSTMP_RING_BASE, 0);
1094 WREG32(SQ_ESTMP_RING_BASE, 0);
1095 WREG32(SQ_GSTMP_RING_BASE, 0);
1096 WREG32(SQ_VSTMP_RING_BASE, 0);
1097 WREG32(SQ_PSTMP_RING_BASE, 0);
1098
1099 WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
1100
Dave Airlie285e0422011-05-09 14:54:33 +10001101 WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
1102 POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
1103 SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001104
Dave Airlie285e0422011-05-09 14:54:33 +10001105 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
1106 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
1107 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001108
1109
1110 WREG32(VGT_NUM_INSTANCES, 1);
1111
1112 WREG32(CP_PERFMON_CNTL, 0);
1113
Dave Airlie285e0422011-05-09 14:54:33 +10001114 WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
Alex Deucherfecf1d02011-03-02 20:07:29 -05001115 FETCH_FIFO_HIWATER(0x4) |
1116 DONE_FIFO_HIWATER(0xe0) |
1117 ALU_UPDATE_FIFO_HIWATER(0x8)));
1118
1119 WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1120 WREG32(SQ_CONFIG, (VC_ENABLE |
1121 EXPORT_SRC_C |
1122 GFX_PRIO(0) |
1123 CS1_PRIO(0) |
1124 CS2_PRIO(1)));
1125 WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1126
1127 WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1128 FORCE_EOV_MAX_REZ_CNT(255)));
1129
1130 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1131 AUTO_INVLD_EN(ES_AND_GS_AUTO));
1132
1133 WREG32(VGT_GS_VERTEX_REUSE, 16);
1134 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1135
1136 WREG32(CB_PERF_CTR0_SEL_0, 0);
1137 WREG32(CB_PERF_CTR0_SEL_1, 0);
1138 WREG32(CB_PERF_CTR1_SEL_0, 0);
1139 WREG32(CB_PERF_CTR1_SEL_1, 0);
1140 WREG32(CB_PERF_CTR2_SEL_0, 0);
1141 WREG32(CB_PERF_CTR2_SEL_1, 0);
1142 WREG32(CB_PERF_CTR3_SEL_0, 0);
1143 WREG32(CB_PERF_CTR3_SEL_1, 0);
1144
Dave Airlie0b65f832011-05-19 14:14:42 +10001145 tmp = RREG32(HDP_MISC_CNTL);
1146 tmp |= HDP_FLUSH_INVALIDATE_CACHE;
1147 WREG32(HDP_MISC_CNTL, tmp);
1148
Alex Deucherfecf1d02011-03-02 20:07:29 -05001149 hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1150 WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1151
1152 WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1153
1154 udelay(50);
1155}
1156
Alex Deucherfa8198e2011-03-02 20:07:30 -05001157/*
1158 * GART
1159 */
1160void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1161{
1162 /* flush hdp cache */
1163 WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1164
1165 /* bits 0-7 are the VM contexts0-7 */
1166 WREG32(VM_INVALIDATE_REQUEST, 1);
1167}
1168
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001169static int cayman_pcie_gart_enable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001170{
Jerome Glisse721604a2012-01-05 22:11:05 -05001171 int i, r;
Alex Deucherfa8198e2011-03-02 20:07:30 -05001172
Jerome Glissec9a1be92011-11-03 11:16:49 -04001173 if (rdev->gart.robj == NULL) {
Alex Deucherfa8198e2011-03-02 20:07:30 -05001174 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1175 return -EINVAL;
1176 }
1177 r = radeon_gart_table_vram_pin(rdev);
1178 if (r)
1179 return r;
1180 radeon_gart_restore(rdev);
1181 /* Setup TLB control */
Jerome Glisse721604a2012-01-05 22:11:05 -05001182 WREG32(MC_VM_MX_L1_TLB_CNTL,
1183 (0xA << 7) |
1184 ENABLE_L1_TLB |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001185 ENABLE_L1_FRAGMENT_PROCESSING |
1186 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
Jerome Glisse721604a2012-01-05 22:11:05 -05001187 ENABLE_ADVANCED_DRIVER_MODEL |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001188 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1189 /* Setup L2 cache */
1190 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1191 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1192 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1193 EFFECTIVE_L2_QUEUE_SIZE(7) |
1194 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1195 WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1196 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1197 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1198 /* setup context0 */
1199 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1200 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1201 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1202 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1203 (u32)(rdev->dummy_page.addr >> 12));
1204 WREG32(VM_CONTEXT0_CNTL2, 0);
1205 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1206 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
Jerome Glisse721604a2012-01-05 22:11:05 -05001207
1208 WREG32(0x15D4, 0);
1209 WREG32(0x15D8, 0);
1210 WREG32(0x15DC, 0);
1211
1212 /* empty context1-7 */
Alex Deucher23d4f1f2012-10-08 09:45:46 -04001213 /* Assign the pt base to something valid for now; the pts used for
1214 * the VMs are determined by the application and setup and assigned
1215 * on the fly in the vm part of radeon_gart.c
1216 */
Jerome Glisse721604a2012-01-05 22:11:05 -05001217 for (i = 1; i < 8; i++) {
1218 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
Alex Deucherc1a7ca02012-10-08 12:15:13 -04001219 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
Jerome Glisse721604a2012-01-05 22:11:05 -05001220 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1221 rdev->gart.table_addr >> 12);
1222 }
1223
1224 /* enable context1-7 */
1225 WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1226 (u32)(rdev->dummy_page.addr >> 12));
Christian Königae133a12012-09-18 15:30:44 -04001227 WREG32(VM_CONTEXT1_CNTL2, 4);
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02001228 WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
Christian Königae133a12012-09-18 15:30:44 -04001229 RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1230 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1231 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1232 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1233 PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1234 PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1235 VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1236 VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1237 READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1238 READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1239 WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1240 WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001241
1242 cayman_pcie_gart_tlb_flush(rdev);
Tormod Voldenfcf4de52011-08-31 21:54:07 +00001243 DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1244 (unsigned)(rdev->mc.gtt_size >> 20),
1245 (unsigned long long)rdev->gart.table_addr);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001246 rdev->gart.ready = true;
1247 return 0;
1248}
1249
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001250static void cayman_pcie_gart_disable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001251{
Alex Deucherfa8198e2011-03-02 20:07:30 -05001252 /* Disable all tables */
1253 WREG32(VM_CONTEXT0_CNTL, 0);
1254 WREG32(VM_CONTEXT1_CNTL, 0);
1255 /* Setup TLB control */
1256 WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1257 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1258 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1259 /* Setup L2 cache */
1260 WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1261 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1262 EFFECTIVE_L2_QUEUE_SIZE(7) |
1263 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1264 WREG32(VM_L2_CNTL2, 0);
1265 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1266 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
Jerome Glissec9a1be92011-11-03 11:16:49 -04001267 radeon_gart_table_vram_unpin(rdev);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001268}
1269
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001270static void cayman_pcie_gart_fini(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001271{
1272 cayman_pcie_gart_disable(rdev);
1273 radeon_gart_table_vram_free(rdev);
1274 radeon_gart_fini(rdev);
1275}
1276
Alex Deucher1b370782011-11-17 20:13:28 -05001277void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
1278 int ring, u32 cp_int_cntl)
1279{
1280 u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;
1281
1282 WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
1283 WREG32(CP_INT_CNTL, cp_int_cntl);
1284}
1285
Alex Deucher0c88a022011-03-02 20:07:31 -05001286/*
1287 * CP.
1288 */
Alex Deucherb40e7e12011-11-17 14:57:50 -05001289void cayman_fence_ring_emit(struct radeon_device *rdev,
1290 struct radeon_fence *fence)
1291{
1292 struct radeon_ring *ring = &rdev->ring[fence->ring];
1293 u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1294
Jerome Glisse721604a2012-01-05 22:11:05 -05001295 /* flush read cache over gart for this vmid */
1296 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1297 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
1298 radeon_ring_write(ring, 0);
Alex Deucherb40e7e12011-11-17 14:57:50 -05001299 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1300 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1301 radeon_ring_write(ring, 0xFFFFFFFF);
1302 radeon_ring_write(ring, 0);
1303 radeon_ring_write(ring, 10); /* poll interval */
1304 /* EVENT_WRITE_EOP - flush caches, send int */
1305 radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1306 radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
1307 radeon_ring_write(ring, addr & 0xffffffff);
1308 radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1309 radeon_ring_write(ring, fence->seq);
1310 radeon_ring_write(ring, 0);
1311}
1312
Jerome Glisse721604a2012-01-05 22:11:05 -05001313void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1314{
Christian König876dc9f2012-05-08 14:24:01 +02001315 struct radeon_ring *ring = &rdev->ring[ib->ring];
Jerome Glisse721604a2012-01-05 22:11:05 -05001316
1317 /* set to DX10/11 mode */
1318 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1319 radeon_ring_write(ring, 1);
Christian König45df6802012-07-06 16:22:55 +02001320
1321 if (ring->rptr_save_reg) {
1322 uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1323 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1324 radeon_ring_write(ring, ((ring->rptr_save_reg -
1325 PACKET3_SET_CONFIG_REG_START) >> 2));
1326 radeon_ring_write(ring, next_rptr);
1327 }
1328
Jerome Glisse721604a2012-01-05 22:11:05 -05001329 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1330 radeon_ring_write(ring,
1331#ifdef __BIG_ENDIAN
1332 (2 << 0) |
1333#endif
1334 (ib->gpu_addr & 0xFFFFFFFC));
1335 radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
Christian König4bf3dd92012-08-06 18:57:44 +02001336 radeon_ring_write(ring, ib->length_dw |
1337 (ib->vm ? (ib->vm->id << 24) : 0));
Jerome Glisse721604a2012-01-05 22:11:05 -05001338
1339 /* flush read cache over gart for this vmid */
1340 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1341 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
Christian König4bf3dd92012-08-06 18:57:44 +02001342 radeon_ring_write(ring, ib->vm ? ib->vm->id : 0);
Jerome Glisse721604a2012-01-05 22:11:05 -05001343 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1344 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1345 radeon_ring_write(ring, 0xFFFFFFFF);
1346 radeon_ring_write(ring, 0);
1347 radeon_ring_write(ring, 10); /* poll interval */
1348}
1349
Christian Königf2ba57b2013-04-08 12:41:29 +02001350void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
1351 struct radeon_ring *ring,
1352 struct radeon_semaphore *semaphore,
1353 bool emit_wait)
1354{
1355 uint64_t addr = semaphore->gpu_addr;
1356
1357 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
1358 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
1359
1360 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
1361 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
1362
1363 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
1364 radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
1365}
1366
Alex Deucher0c88a022011-03-02 20:07:31 -05001367static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1368{
1369 if (enable)
1370 WREG32(CP_ME_CNTL, 0);
1371 else {
Dave Airlie38f1cff2011-03-16 11:34:41 +10001372 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
Alex Deucher0c88a022011-03-02 20:07:31 -05001373 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1374 WREG32(SCRATCH_UMSK, 0);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001375 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001376 }
1377}
1378
1379static int cayman_cp_load_microcode(struct radeon_device *rdev)
1380{
1381 const __be32 *fw_data;
1382 int i;
1383
1384 if (!rdev->me_fw || !rdev->pfp_fw)
1385 return -EINVAL;
1386
1387 cayman_cp_enable(rdev, false);
1388
1389 fw_data = (const __be32 *)rdev->pfp_fw->data;
1390 WREG32(CP_PFP_UCODE_ADDR, 0);
1391 for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
1392 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1393 WREG32(CP_PFP_UCODE_ADDR, 0);
1394
1395 fw_data = (const __be32 *)rdev->me_fw->data;
1396 WREG32(CP_ME_RAM_WADDR, 0);
1397 for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
1398 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1399
1400 WREG32(CP_PFP_UCODE_ADDR, 0);
1401 WREG32(CP_ME_RAM_WADDR, 0);
1402 WREG32(CP_ME_RAM_RADDR, 0);
1403 return 0;
1404}
1405
1406static int cayman_cp_start(struct radeon_device *rdev)
1407{
Christian Könige32eb502011-10-23 12:56:27 +02001408 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher0c88a022011-03-02 20:07:31 -05001409 int r, i;
1410
Christian Könige32eb502011-10-23 12:56:27 +02001411 r = radeon_ring_lock(rdev, ring, 7);
Alex Deucher0c88a022011-03-02 20:07:31 -05001412 if (r) {
1413 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1414 return r;
1415 }
Christian Könige32eb502011-10-23 12:56:27 +02001416 radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1417 radeon_ring_write(ring, 0x1);
1418 radeon_ring_write(ring, 0x0);
1419 radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1420 radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1421 radeon_ring_write(ring, 0);
1422 radeon_ring_write(ring, 0);
1423 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001424
1425 cayman_cp_enable(rdev, true);
1426
Christian Könige32eb502011-10-23 12:56:27 +02001427 r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
Alex Deucher0c88a022011-03-02 20:07:31 -05001428 if (r) {
1429 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1430 return r;
1431 }
1432
1433 /* setup clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001434 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1435 radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001436
1437 for (i = 0; i < cayman_default_size; i++)
Christian Könige32eb502011-10-23 12:56:27 +02001438 radeon_ring_write(ring, cayman_default_state[i]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001439
Christian Könige32eb502011-10-23 12:56:27 +02001440 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1441 radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001442
1443 /* set clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001444 radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1445 radeon_ring_write(ring, 0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001446
1447 /* SQ_VTX_BASE_VTX_LOC */
Christian Könige32eb502011-10-23 12:56:27 +02001448 radeon_ring_write(ring, 0xc0026f00);
1449 radeon_ring_write(ring, 0x00000000);
1450 radeon_ring_write(ring, 0x00000000);
1451 radeon_ring_write(ring, 0x00000000);
Alex Deucher0c88a022011-03-02 20:07:31 -05001452
1453 /* Clear consts */
Christian Könige32eb502011-10-23 12:56:27 +02001454 radeon_ring_write(ring, 0xc0036f00);
1455 radeon_ring_write(ring, 0x00000bc4);
1456 radeon_ring_write(ring, 0xffffffff);
1457 radeon_ring_write(ring, 0xffffffff);
1458 radeon_ring_write(ring, 0xffffffff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001459
Christian Könige32eb502011-10-23 12:56:27 +02001460 radeon_ring_write(ring, 0xc0026900);
1461 radeon_ring_write(ring, 0x00000316);
1462 radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1463 radeon_ring_write(ring, 0x00000010); /* */
Alex Deucher9b91d182011-03-02 20:07:39 -05001464
Christian Könige32eb502011-10-23 12:56:27 +02001465 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001466
1467 /* XXX init other rings */
1468
1469 return 0;
1470}
1471
Alex Deucher755d8192011-03-02 20:07:34 -05001472static void cayman_cp_fini(struct radeon_device *rdev)
1473{
Christian König45df6802012-07-06 16:22:55 +02001474 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05001475 cayman_cp_enable(rdev, false);
Christian König45df6802012-07-06 16:22:55 +02001476 radeon_ring_fini(rdev, ring);
1477 radeon_scratch_free(rdev, ring->rptr_save_reg);
Alex Deucher755d8192011-03-02 20:07:34 -05001478}
1479
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001480static int cayman_cp_resume(struct radeon_device *rdev)
Alex Deucher0c88a022011-03-02 20:07:31 -05001481{
Christian Königb90ca982012-07-04 21:36:53 +02001482 static const int ridx[] = {
1483 RADEON_RING_TYPE_GFX_INDEX,
1484 CAYMAN_RING_TYPE_CP1_INDEX,
1485 CAYMAN_RING_TYPE_CP2_INDEX
1486 };
1487 static const unsigned cp_rb_cntl[] = {
1488 CP_RB0_CNTL,
1489 CP_RB1_CNTL,
1490 CP_RB2_CNTL,
1491 };
1492 static const unsigned cp_rb_rptr_addr[] = {
1493 CP_RB0_RPTR_ADDR,
1494 CP_RB1_RPTR_ADDR,
1495 CP_RB2_RPTR_ADDR
1496 };
1497 static const unsigned cp_rb_rptr_addr_hi[] = {
1498 CP_RB0_RPTR_ADDR_HI,
1499 CP_RB1_RPTR_ADDR_HI,
1500 CP_RB2_RPTR_ADDR_HI
1501 };
1502 static const unsigned cp_rb_base[] = {
1503 CP_RB0_BASE,
1504 CP_RB1_BASE,
1505 CP_RB2_BASE
1506 };
Christian Könige32eb502011-10-23 12:56:27 +02001507 struct radeon_ring *ring;
Christian Königb90ca982012-07-04 21:36:53 +02001508 int i, r;
Alex Deucher0c88a022011-03-02 20:07:31 -05001509
1510 /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
1511 WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
1512 SOFT_RESET_PA |
1513 SOFT_RESET_SH |
1514 SOFT_RESET_VGT |
Jerome Glissea49a50d2011-08-24 20:00:17 +00001515 SOFT_RESET_SPI |
Alex Deucher0c88a022011-03-02 20:07:31 -05001516 SOFT_RESET_SX));
1517 RREG32(GRBM_SOFT_RESET);
1518 mdelay(15);
1519 WREG32(GRBM_SOFT_RESET, 0);
1520 RREG32(GRBM_SOFT_RESET);
1521
Christian König15d33322011-09-15 19:02:22 +02001522 WREG32(CP_SEM_WAIT_TIMER, 0x0);
Alex Deucher11ef3f12012-01-20 14:47:43 -05001523 WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001524
1525 /* Set the write pointer delay */
1526 WREG32(CP_RB_WPTR_DELAY, 0);
1527
1528 WREG32(CP_DEBUG, (1 << 27));
1529
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001530 /* set the wb address whether it's enabled or not */
Alex Deucher0c88a022011-03-02 20:07:31 -05001531 WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
Christian Königb90ca982012-07-04 21:36:53 +02001532 WREG32(SCRATCH_UMSK, 0xff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001533
Christian Königb90ca982012-07-04 21:36:53 +02001534 for (i = 0; i < 3; ++i) {
1535 uint32_t rb_cntl;
1536 uint64_t addr;
1537
1538 /* Set ring buffer size */
1539 ring = &rdev->ring[ridx[i]];
1540 rb_cntl = drm_order(ring->ring_size / 8);
1541 rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
1542#ifdef __BIG_ENDIAN
1543 rb_cntl |= BUF_SWAP_32BIT;
1544#endif
1545 WREG32(cp_rb_cntl[i], rb_cntl);
1546
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001547 /* set the wb address whether it's enabled or not */
Christian Königb90ca982012-07-04 21:36:53 +02001548 addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1549 WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1550 WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
Alex Deucher0c88a022011-03-02 20:07:31 -05001551 }
1552
Christian Königb90ca982012-07-04 21:36:53 +02001553 /* set the rb base addr, this causes an internal reset of ALL rings */
1554 for (i = 0; i < 3; ++i) {
1555 ring = &rdev->ring[ridx[i]];
1556 WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1557 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001558
Christian Königb90ca982012-07-04 21:36:53 +02001559 for (i = 0; i < 3; ++i) {
1560 /* Initialize the ring buffer's read and write pointers */
1561 ring = &rdev->ring[ridx[i]];
1562 WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
Alex Deucher0c88a022011-03-02 20:07:31 -05001563
Christian Königb90ca982012-07-04 21:36:53 +02001564 ring->rptr = ring->wptr = 0;
1565 WREG32(ring->rptr_reg, ring->rptr);
1566 WREG32(ring->wptr_reg, ring->wptr);
Alex Deucher0c88a022011-03-02 20:07:31 -05001567
Christian Königb90ca982012-07-04 21:36:53 +02001568 mdelay(1);
1569 WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1570 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001571
1572 /* start the rings */
1573 cayman_cp_start(rdev);
Christian Könige32eb502011-10-23 12:56:27 +02001574 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1575 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1576 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001577 /* this only test cp0 */
Alex Deucherf7128122012-02-23 17:53:45 -05001578 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001579 if (r) {
Christian Könige32eb502011-10-23 12:56:27 +02001580 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1581 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1582 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001583 return r;
1584 }
1585
1586 return 0;
1587}
1588
Alex Deucherf60cbd12012-12-04 15:27:33 -05001589/*
1590 * DMA
1591 * Starting with R600, the GPU has an asynchronous
1592 * DMA engine. The programming model is very similar
1593 * to the 3D engine (ring buffer, IBs, etc.), but the
1594 * DMA controller has it's own packet format that is
1595 * different form the PM4 format used by the 3D engine.
1596 * It supports copying data, writing embedded data,
1597 * solid fills, and a number of other things. It also
1598 * has support for tiling/detiling of buffers.
1599 * Cayman and newer support two asynchronous DMA engines.
1600 */
1601/**
1602 * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
1603 *
1604 * @rdev: radeon_device pointer
1605 * @ib: IB object to schedule
1606 *
1607 * Schedule an IB in the DMA ring (cayman-SI).
1608 */
1609void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
1610 struct radeon_ib *ib)
1611{
1612 struct radeon_ring *ring = &rdev->ring[ib->ring];
1613
1614 if (rdev->wb.enabled) {
1615 u32 next_rptr = ring->wptr + 4;
1616 while ((next_rptr & 7) != 5)
1617 next_rptr++;
1618 next_rptr += 3;
1619 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
1620 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
1621 radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
1622 radeon_ring_write(ring, next_rptr);
1623 }
1624
1625 /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
1626 * Pad as necessary with NOPs.
1627 */
1628 while ((ring->wptr & 7) != 5)
1629 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
1630 radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0));
1631 radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
1632 radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
1633
1634}
1635
1636/**
1637 * cayman_dma_stop - stop the async dma engines
1638 *
1639 * @rdev: radeon_device pointer
1640 *
1641 * Stop the async dma engines (cayman-SI).
1642 */
1643void cayman_dma_stop(struct radeon_device *rdev)
1644{
1645 u32 rb_cntl;
1646
1647 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1648
1649 /* dma0 */
1650 rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1651 rb_cntl &= ~DMA_RB_ENABLE;
1652 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl);
1653
1654 /* dma1 */
1655 rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1656 rb_cntl &= ~DMA_RB_ENABLE;
1657 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl);
1658
1659 rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
1660 rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false;
1661}
1662
1663/**
1664 * cayman_dma_resume - setup and start the async dma engines
1665 *
1666 * @rdev: radeon_device pointer
1667 *
1668 * Set up the DMA ring buffers and enable them. (cayman-SI).
1669 * Returns 0 for success, error for failure.
1670 */
1671int cayman_dma_resume(struct radeon_device *rdev)
1672{
1673 struct radeon_ring *ring;
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001674 u32 rb_cntl, dma_cntl, ib_cntl;
Alex Deucherf60cbd12012-12-04 15:27:33 -05001675 u32 rb_bufsz;
1676 u32 reg_offset, wb_offset;
1677 int i, r;
1678
1679 /* Reset dma */
1680 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
1681 RREG32(SRBM_SOFT_RESET);
1682 udelay(50);
1683 WREG32(SRBM_SOFT_RESET, 0);
1684
1685 for (i = 0; i < 2; i++) {
1686 if (i == 0) {
1687 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
1688 reg_offset = DMA0_REGISTER_OFFSET;
1689 wb_offset = R600_WB_DMA_RPTR_OFFSET;
1690 } else {
1691 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
1692 reg_offset = DMA1_REGISTER_OFFSET;
1693 wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET;
1694 }
1695
1696 WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
1697 WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
1698
1699 /* Set ring buffer size in dwords */
1700 rb_bufsz = drm_order(ring->ring_size / 4);
1701 rb_cntl = rb_bufsz << 1;
1702#ifdef __BIG_ENDIAN
1703 rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE;
1704#endif
1705 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl);
1706
1707 /* Initialize the ring buffer's read and write pointers */
1708 WREG32(DMA_RB_RPTR + reg_offset, 0);
1709 WREG32(DMA_RB_WPTR + reg_offset, 0);
1710
1711 /* set the wb address whether it's enabled or not */
1712 WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset,
1713 upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF);
1714 WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset,
1715 ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC));
1716
1717 if (rdev->wb.enabled)
1718 rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE;
1719
1720 WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);
1721
1722 /* enable DMA IBs */
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001723 ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE;
1724#ifdef __BIG_ENDIAN
1725 ib_cntl |= DMA_IB_SWAP_ENABLE;
1726#endif
1727 WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001728
1729 dma_cntl = RREG32(DMA_CNTL + reg_offset);
1730 dma_cntl &= ~CTXEMPTY_INT_ENABLE;
1731 WREG32(DMA_CNTL + reg_offset, dma_cntl);
1732
1733 ring->wptr = 0;
1734 WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2);
1735
1736 ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2;
1737
1738 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE);
1739
1740 ring->ready = true;
1741
1742 r = radeon_ring_test(rdev, ring->idx, ring);
1743 if (r) {
1744 ring->ready = false;
1745 return r;
1746 }
1747 }
1748
1749 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1750
1751 return 0;
1752}
1753
1754/**
1755 * cayman_dma_fini - tear down the async dma engines
1756 *
1757 * @rdev: radeon_device pointer
1758 *
1759 * Stop the async dma engines and free the rings (cayman-SI).
1760 */
1761void cayman_dma_fini(struct radeon_device *rdev)
1762{
1763 cayman_dma_stop(rdev);
1764 radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
1765 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
1766}
1767
Alex Deucher168757e2013-01-18 19:17:22 -05001768static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1769{
1770 u32 reset_mask = 0;
1771 u32 tmp;
1772
1773 /* GRBM_STATUS */
1774 tmp = RREG32(GRBM_STATUS);
1775 if (tmp & (PA_BUSY | SC_BUSY |
1776 SH_BUSY | SX_BUSY |
1777 TA_BUSY | VGT_BUSY |
1778 DB_BUSY | CB_BUSY |
1779 GDS_BUSY | SPI_BUSY |
1780 IA_BUSY | IA_BUSY_NO_DMA))
1781 reset_mask |= RADEON_RESET_GFX;
1782
1783 if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1784 CP_BUSY | CP_COHERENCY_BUSY))
1785 reset_mask |= RADEON_RESET_CP;
1786
1787 if (tmp & GRBM_EE_BUSY)
1788 reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1789
1790 /* DMA_STATUS_REG 0 */
1791 tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1792 if (!(tmp & DMA_IDLE))
1793 reset_mask |= RADEON_RESET_DMA;
1794
1795 /* DMA_STATUS_REG 1 */
1796 tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1797 if (!(tmp & DMA_IDLE))
1798 reset_mask |= RADEON_RESET_DMA1;
1799
1800 /* SRBM_STATUS2 */
1801 tmp = RREG32(SRBM_STATUS2);
1802 if (tmp & DMA_BUSY)
1803 reset_mask |= RADEON_RESET_DMA;
1804
1805 if (tmp & DMA1_BUSY)
1806 reset_mask |= RADEON_RESET_DMA1;
1807
1808 /* SRBM_STATUS */
1809 tmp = RREG32(SRBM_STATUS);
1810 if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1811 reset_mask |= RADEON_RESET_RLC;
1812
1813 if (tmp & IH_BUSY)
1814 reset_mask |= RADEON_RESET_IH;
1815
1816 if (tmp & SEM_BUSY)
1817 reset_mask |= RADEON_RESET_SEM;
1818
1819 if (tmp & GRBM_RQ_PENDING)
1820 reset_mask |= RADEON_RESET_GRBM;
1821
1822 if (tmp & VMC_BUSY)
1823 reset_mask |= RADEON_RESET_VMC;
1824
1825 if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1826 MCC_BUSY | MCD_BUSY))
1827 reset_mask |= RADEON_RESET_MC;
1828
1829 if (evergreen_is_display_hung(rdev))
1830 reset_mask |= RADEON_RESET_DISPLAY;
1831
1832 /* VM_L2_STATUS */
1833 tmp = RREG32(VM_L2_STATUS);
1834 if (tmp & L2_BUSY)
1835 reset_mask |= RADEON_RESET_VMC;
1836
Alex Deucherd808fc82013-02-28 10:03:08 -05001837 /* Skip MC reset as it's mostly likely not hung, just busy */
1838 if (reset_mask & RADEON_RESET_MC) {
1839 DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1840 reset_mask &= ~RADEON_RESET_MC;
1841 }
1842
Alex Deucher168757e2013-01-18 19:17:22 -05001843 return reset_mask;
1844}
1845
1846static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
Alex Deucher271d6fe2013-01-03 12:48:05 -05001847{
1848 struct evergreen_mc_save save;
Alex Deucher187e3592013-01-18 14:51:38 -05001849 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1850 u32 tmp;
Alex Deucher19fc42e2013-01-14 11:04:39 -05001851
Alex Deucher271d6fe2013-01-03 12:48:05 -05001852 if (reset_mask == 0)
Alex Deucher168757e2013-01-18 19:17:22 -05001853 return;
Alex Deucher271d6fe2013-01-03 12:48:05 -05001854
1855 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1856
Alex Deucher187e3592013-01-18 14:51:38 -05001857 evergreen_print_gpu_status_regs(rdev);
Alex Deucher271d6fe2013-01-03 12:48:05 -05001858 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1859 RREG32(0x14F8));
1860 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1861 RREG32(0x14D8));
1862 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
1863 RREG32(0x14FC));
1864 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1865 RREG32(0x14DC));
1866
Alex Deucher187e3592013-01-18 14:51:38 -05001867 /* Disable CP parsing/prefetching */
1868 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1869
1870 if (reset_mask & RADEON_RESET_DMA) {
1871 /* dma0 */
1872 tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1873 tmp &= ~DMA_RB_ENABLE;
1874 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
Alex Deucher168757e2013-01-18 19:17:22 -05001875 }
Alex Deucher187e3592013-01-18 14:51:38 -05001876
Alex Deucher168757e2013-01-18 19:17:22 -05001877 if (reset_mask & RADEON_RESET_DMA1) {
Alex Deucher187e3592013-01-18 14:51:38 -05001878 /* dma1 */
1879 tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1880 tmp &= ~DMA_RB_ENABLE;
1881 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1882 }
1883
Alex Deucher90fb8772013-01-23 18:59:17 -05001884 udelay(50);
1885
1886 evergreen_mc_stop(rdev, &save);
1887 if (evergreen_mc_wait_for_idle(rdev)) {
1888 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1889 }
1890
Alex Deucher187e3592013-01-18 14:51:38 -05001891 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1892 grbm_soft_reset = SOFT_RESET_CB |
1893 SOFT_RESET_DB |
1894 SOFT_RESET_GDS |
1895 SOFT_RESET_PA |
1896 SOFT_RESET_SC |
1897 SOFT_RESET_SPI |
1898 SOFT_RESET_SH |
1899 SOFT_RESET_SX |
1900 SOFT_RESET_TC |
1901 SOFT_RESET_TA |
1902 SOFT_RESET_VGT |
1903 SOFT_RESET_IA;
1904 }
1905
1906 if (reset_mask & RADEON_RESET_CP) {
1907 grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1908
1909 srbm_soft_reset |= SOFT_RESET_GRBM;
1910 }
Alex Deucher271d6fe2013-01-03 12:48:05 -05001911
1912 if (reset_mask & RADEON_RESET_DMA)
Alex Deucher168757e2013-01-18 19:17:22 -05001913 srbm_soft_reset |= SOFT_RESET_DMA;
1914
1915 if (reset_mask & RADEON_RESET_DMA1)
1916 srbm_soft_reset |= SOFT_RESET_DMA1;
1917
1918 if (reset_mask & RADEON_RESET_DISPLAY)
1919 srbm_soft_reset |= SOFT_RESET_DC;
1920
1921 if (reset_mask & RADEON_RESET_RLC)
1922 srbm_soft_reset |= SOFT_RESET_RLC;
1923
1924 if (reset_mask & RADEON_RESET_SEM)
1925 srbm_soft_reset |= SOFT_RESET_SEM;
1926
1927 if (reset_mask & RADEON_RESET_IH)
1928 srbm_soft_reset |= SOFT_RESET_IH;
1929
1930 if (reset_mask & RADEON_RESET_GRBM)
1931 srbm_soft_reset |= SOFT_RESET_GRBM;
1932
1933 if (reset_mask & RADEON_RESET_VMC)
1934 srbm_soft_reset |= SOFT_RESET_VMC;
1935
Alex Deucher24178ec2013-01-24 15:00:17 -05001936 if (!(rdev->flags & RADEON_IS_IGP)) {
1937 if (reset_mask & RADEON_RESET_MC)
1938 srbm_soft_reset |= SOFT_RESET_MC;
1939 }
Alex Deucher187e3592013-01-18 14:51:38 -05001940
1941 if (grbm_soft_reset) {
1942 tmp = RREG32(GRBM_SOFT_RESET);
1943 tmp |= grbm_soft_reset;
1944 dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1945 WREG32(GRBM_SOFT_RESET, tmp);
1946 tmp = RREG32(GRBM_SOFT_RESET);
1947
1948 udelay(50);
1949
1950 tmp &= ~grbm_soft_reset;
1951 WREG32(GRBM_SOFT_RESET, tmp);
1952 tmp = RREG32(GRBM_SOFT_RESET);
1953 }
1954
1955 if (srbm_soft_reset) {
1956 tmp = RREG32(SRBM_SOFT_RESET);
1957 tmp |= srbm_soft_reset;
1958 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1959 WREG32(SRBM_SOFT_RESET, tmp);
1960 tmp = RREG32(SRBM_SOFT_RESET);
1961
1962 udelay(50);
1963
1964 tmp &= ~srbm_soft_reset;
1965 WREG32(SRBM_SOFT_RESET, tmp);
1966 tmp = RREG32(SRBM_SOFT_RESET);
1967 }
Alex Deucher271d6fe2013-01-03 12:48:05 -05001968
1969 /* Wait a little for things to settle down */
1970 udelay(50);
1971
Alex Deucherb9952a82011-03-02 20:07:33 -05001972 evergreen_mc_resume(rdev, &save);
Alex Deucher187e3592013-01-18 14:51:38 -05001973 udelay(50);
Alex Deucher410a3412013-01-18 13:05:39 -05001974
Alex Deucher187e3592013-01-18 14:51:38 -05001975 evergreen_print_gpu_status_regs(rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -05001976}
1977
1978int cayman_asic_reset(struct radeon_device *rdev)
1979{
Alex Deucher168757e2013-01-18 19:17:22 -05001980 u32 reset_mask;
1981
1982 reset_mask = cayman_gpu_check_soft_reset(rdev);
1983
1984 if (reset_mask)
1985 r600_set_bios_scratch_engine_hung(rdev, true);
1986
1987 cayman_gpu_soft_reset(rdev, reset_mask);
1988
1989 reset_mask = cayman_gpu_check_soft_reset(rdev);
1990
1991 if (!reset_mask)
1992 r600_set_bios_scratch_engine_hung(rdev, false);
1993
1994 return 0;
Alex Deucherb9952a82011-03-02 20:07:33 -05001995}
1996
Alex Deucherf60cbd12012-12-04 15:27:33 -05001997/**
Alex Deucher123bc182013-01-24 11:37:19 -05001998 * cayman_gfx_is_lockup - Check if the GFX engine is locked up
1999 *
2000 * @rdev: radeon_device pointer
2001 * @ring: radeon_ring structure holding ring information
2002 *
2003 * Check if the GFX engine is locked up.
2004 * Returns true if the engine appears to be locked up, false if not.
2005 */
2006bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2007{
2008 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2009
2010 if (!(reset_mask & (RADEON_RESET_GFX |
2011 RADEON_RESET_COMPUTE |
2012 RADEON_RESET_CP))) {
2013 radeon_ring_lockup_update(ring);
2014 return false;
2015 }
2016 /* force CP activities */
2017 radeon_ring_force_activity(rdev, ring);
2018 return radeon_ring_test_lockup(rdev, ring);
2019}
2020
2021/**
Alex Deucherf60cbd12012-12-04 15:27:33 -05002022 * cayman_dma_is_lockup - Check if the DMA engine is locked up
2023 *
2024 * @rdev: radeon_device pointer
2025 * @ring: radeon_ring structure holding ring information
2026 *
Alex Deucher123bc182013-01-24 11:37:19 -05002027 * Check if the async DMA engine is locked up.
Alex Deucherf60cbd12012-12-04 15:27:33 -05002028 * Returns true if the engine appears to be locked up, false if not.
2029 */
2030bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2031{
Alex Deucher123bc182013-01-24 11:37:19 -05002032 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2033 u32 mask;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002034
2035 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
Alex Deucher123bc182013-01-24 11:37:19 -05002036 mask = RADEON_RESET_DMA;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002037 else
Alex Deucher123bc182013-01-24 11:37:19 -05002038 mask = RADEON_RESET_DMA1;
2039
2040 if (!(reset_mask & mask)) {
Alex Deucherf60cbd12012-12-04 15:27:33 -05002041 radeon_ring_lockup_update(ring);
2042 return false;
2043 }
2044 /* force ring activities */
2045 radeon_ring_force_activity(rdev, ring);
2046 return radeon_ring_test_lockup(rdev, ring);
2047}
2048
Alex Deucher755d8192011-03-02 20:07:34 -05002049static int cayman_startup(struct radeon_device *rdev)
2050{
Christian Könige32eb502011-10-23 12:56:27 +02002051 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002052 int r;
2053
Ilija Hadzicb07759b2011-09-20 10:22:58 -04002054 /* enable pcie gen2 link */
2055 evergreen_pcie_gen2_enable(rdev);
2056
Alex Deucherc420c742012-03-20 17:18:39 -04002057 if (rdev->flags & RADEON_IS_IGP) {
2058 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
2059 r = ni_init_microcode(rdev);
2060 if (r) {
2061 DRM_ERROR("Failed to load firmware!\n");
2062 return r;
2063 }
2064 }
2065 } else {
2066 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
2067 r = ni_init_microcode(rdev);
2068 if (r) {
2069 DRM_ERROR("Failed to load firmware!\n");
2070 return r;
2071 }
2072 }
2073
2074 r = ni_mc_load_microcode(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002075 if (r) {
Alex Deucherc420c742012-03-20 17:18:39 -04002076 DRM_ERROR("Failed to load MC firmware!\n");
Alex Deucher755d8192011-03-02 20:07:34 -05002077 return r;
2078 }
2079 }
Alex Deucher755d8192011-03-02 20:07:34 -05002080
Alex Deucher16cdf042011-10-28 10:30:02 -04002081 r = r600_vram_scratch_init(rdev);
2082 if (r)
2083 return r;
2084
Alex Deucher755d8192011-03-02 20:07:34 -05002085 evergreen_mc_program(rdev);
2086 r = cayman_pcie_gart_enable(rdev);
2087 if (r)
2088 return r;
2089 cayman_gpu_init(rdev);
2090
Alex Deuchercb92d452011-05-25 16:39:00 -04002091 r = evergreen_blit_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002092 if (r) {
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002093 r600_blit_fini(rdev);
Alex Deucher27cd7762012-02-23 17:53:42 -05002094 rdev->asic->copy.copy = NULL;
Alex Deucher755d8192011-03-02 20:07:34 -05002095 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
2096 }
Alex Deucher755d8192011-03-02 20:07:34 -05002097
Alex Deucherc420c742012-03-20 17:18:39 -04002098 /* allocate rlc buffers */
2099 if (rdev->flags & RADEON_IS_IGP) {
Alex Deucher2948f5e2013-04-12 13:52:52 -04002100 rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
2101 rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size;
2102 rdev->rlc.cs_data = cayman_cs_data;
2103 r = sumo_rlc_init(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002104 if (r) {
2105 DRM_ERROR("Failed to init rlc BOs!\n");
2106 return r;
2107 }
2108 }
2109
Alex Deucher755d8192011-03-02 20:07:34 -05002110 /* allocate wb buffer */
2111 r = radeon_wb_init(rdev);
2112 if (r)
2113 return r;
2114
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002115 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
2116 if (r) {
2117 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2118 return r;
2119 }
2120
Christian Königf2ba57b2013-04-08 12:41:29 +02002121 r = rv770_uvd_resume(rdev);
2122 if (!r) {
2123 r = radeon_fence_driver_start_ring(rdev,
2124 R600_RING_TYPE_UVD_INDEX);
2125 if (r)
2126 dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2127 }
2128 if (r)
2129 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2130
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002131 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
2132 if (r) {
2133 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2134 return r;
2135 }
2136
2137 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
2138 if (r) {
2139 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2140 return r;
2141 }
2142
Alex Deucherf60cbd12012-12-04 15:27:33 -05002143 r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2144 if (r) {
2145 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2146 return r;
2147 }
2148
2149 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2150 if (r) {
2151 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2152 return r;
2153 }
2154
Alex Deucher755d8192011-03-02 20:07:34 -05002155 /* Enable IRQ */
Adis Hamziće49f3952013-06-02 16:47:54 +02002156 if (!rdev->irq.installed) {
2157 r = radeon_irq_kms_init(rdev);
2158 if (r)
2159 return r;
2160 }
2161
Alex Deucher755d8192011-03-02 20:07:34 -05002162 r = r600_irq_init(rdev);
2163 if (r) {
2164 DRM_ERROR("radeon: IH init failed (%d).\n", r);
2165 radeon_irq_kms_fini(rdev);
2166 return r;
2167 }
2168 evergreen_irq_set(rdev);
2169
Christian Könige32eb502011-10-23 12:56:27 +02002170 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
Alex Deucher78c55602011-11-17 14:25:56 -05002171 CP_RB0_RPTR, CP_RB0_WPTR,
2172 0, 0xfffff, RADEON_CP_PACKET2);
Alex Deucher755d8192011-03-02 20:07:34 -05002173 if (r)
2174 return r;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002175
2176 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2177 r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
2178 DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
2179 DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
2180 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2181 if (r)
2182 return r;
2183
2184 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2185 r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
2186 DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
2187 DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
2188 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2189 if (r)
2190 return r;
2191
Alex Deucher755d8192011-03-02 20:07:34 -05002192 r = cayman_cp_load_microcode(rdev);
2193 if (r)
2194 return r;
2195 r = cayman_cp_resume(rdev);
2196 if (r)
2197 return r;
2198
Alex Deucherf60cbd12012-12-04 15:27:33 -05002199 r = cayman_dma_resume(rdev);
2200 if (r)
2201 return r;
2202
Christian Königf2ba57b2013-04-08 12:41:29 +02002203 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2204 if (ring->ring_size) {
2205 r = radeon_ring_init(rdev, ring, ring->ring_size,
2206 R600_WB_UVD_RPTR_OFFSET,
2207 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2208 0, 0xfffff, RADEON_CP_PACKET2);
2209 if (!r)
2210 r = r600_uvd_init(rdev);
2211 if (r)
2212 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2213 }
2214
Christian König2898c342012-07-05 11:55:34 +02002215 r = radeon_ib_pool_init(rdev);
2216 if (r) {
2217 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisseb15ba512011-11-15 11:48:34 -05002218 return r;
Christian König2898c342012-07-05 11:55:34 +02002219 }
Jerome Glisseb15ba512011-11-15 11:48:34 -05002220
Christian Königc6105f22012-07-05 14:32:00 +02002221 r = radeon_vm_manager_init(rdev);
2222 if (r) {
2223 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
Jerome Glisse721604a2012-01-05 22:11:05 -05002224 return r;
Christian Königc6105f22012-07-05 14:32:00 +02002225 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002226
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002227 r = r600_audio_init(rdev);
2228 if (r)
2229 return r;
2230
Alex Deucher755d8192011-03-02 20:07:34 -05002231 return 0;
2232}
2233
2234int cayman_resume(struct radeon_device *rdev)
2235{
2236 int r;
2237
2238 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2239 * posting will perform necessary task to bring back GPU into good
2240 * shape.
2241 */
2242 /* post card */
2243 atom_asic_init(rdev->mode_info.atom_context);
2244
Alex Deuchera2c96a22013-02-28 17:58:36 -05002245 /* init golden registers */
2246 ni_init_golden_registers(rdev);
2247
Jerome Glisseb15ba512011-11-15 11:48:34 -05002248 rdev->accel_working = true;
Alex Deucher755d8192011-03-02 20:07:34 -05002249 r = cayman_startup(rdev);
2250 if (r) {
2251 DRM_ERROR("cayman startup failed on resume\n");
Jerome Glisse6b7746e2012-02-20 17:57:20 -05002252 rdev->accel_working = false;
Alex Deucher755d8192011-03-02 20:07:34 -05002253 return r;
2254 }
Alex Deucher755d8192011-03-02 20:07:34 -05002255 return r;
Alex Deucher755d8192011-03-02 20:07:34 -05002256}
2257
2258int cayman_suspend(struct radeon_device *rdev)
2259{
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002260 r600_audio_fini(rdev);
Alex Deucherfa3daf92013-03-11 15:32:26 -04002261 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002262 cayman_cp_enable(rdev, false);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002263 cayman_dma_stop(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002264 r600_uvd_rbc_stop(rdev);
2265 radeon_uvd_suspend(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002266 evergreen_irq_suspend(rdev);
2267 radeon_wb_disable(rdev);
2268 cayman_pcie_gart_disable(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002269 return 0;
2270}
2271
2272/* Plan is to move initialization in that function and use
2273 * helper function so that radeon_device_init pretty much
2274 * do nothing more than calling asic specific function. This
2275 * should also allow to remove a bunch of callback function
2276 * like vram_info.
2277 */
2278int cayman_init(struct radeon_device *rdev)
2279{
Christian Könige32eb502011-10-23 12:56:27 +02002280 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002281 int r;
2282
Alex Deucher755d8192011-03-02 20:07:34 -05002283 /* Read BIOS */
2284 if (!radeon_get_bios(rdev)) {
2285 if (ASIC_IS_AVIVO(rdev))
2286 return -EINVAL;
2287 }
2288 /* Must be an ATOMBIOS */
2289 if (!rdev->is_atom_bios) {
2290 dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2291 return -EINVAL;
2292 }
2293 r = radeon_atombios_init(rdev);
2294 if (r)
2295 return r;
2296
2297 /* Post card if necessary */
2298 if (!radeon_card_posted(rdev)) {
2299 if (!rdev->bios) {
2300 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2301 return -EINVAL;
2302 }
2303 DRM_INFO("GPU not posted. posting now...\n");
2304 atom_asic_init(rdev->mode_info.atom_context);
2305 }
Alex Deuchera2c96a22013-02-28 17:58:36 -05002306 /* init golden registers */
2307 ni_init_golden_registers(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002308 /* Initialize scratch registers */
2309 r600_scratch_init(rdev);
2310 /* Initialize surface registers */
2311 radeon_surface_init(rdev);
2312 /* Initialize clocks */
2313 radeon_get_clock_info(rdev->ddev);
2314 /* Fence driver */
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002315 r = radeon_fence_driver_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002316 if (r)
2317 return r;
2318 /* initialize memory controller */
2319 r = evergreen_mc_init(rdev);
2320 if (r)
2321 return r;
2322 /* Memory manager */
2323 r = radeon_bo_init(rdev);
2324 if (r)
2325 return r;
2326
Christian Könige32eb502011-10-23 12:56:27 +02002327 ring->ring_obj = NULL;
2328 r600_ring_init(rdev, ring, 1024 * 1024);
Alex Deucher755d8192011-03-02 20:07:34 -05002329
Alex Deucherf60cbd12012-12-04 15:27:33 -05002330 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2331 ring->ring_obj = NULL;
2332 r600_ring_init(rdev, ring, 64 * 1024);
2333
2334 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2335 ring->ring_obj = NULL;
2336 r600_ring_init(rdev, ring, 64 * 1024);
2337
Christian Königf2ba57b2013-04-08 12:41:29 +02002338 r = radeon_uvd_init(rdev);
2339 if (!r) {
2340 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2341 ring->ring_obj = NULL;
2342 r600_ring_init(rdev, ring, 4096);
2343 }
2344
Alex Deucher755d8192011-03-02 20:07:34 -05002345 rdev->ih.ring_obj = NULL;
2346 r600_ih_ring_init(rdev, 64 * 1024);
2347
2348 r = r600_pcie_gart_init(rdev);
2349 if (r)
2350 return r;
2351
2352 rdev->accel_working = true;
2353 r = cayman_startup(rdev);
2354 if (r) {
2355 dev_err(rdev->dev, "disabling GPU acceleration\n");
2356 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002357 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002358 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002359 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher2948f5e2013-04-12 13:52:52 -04002360 sumo_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002361 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002362 radeon_ib_pool_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002363 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002364 radeon_irq_kms_fini(rdev);
2365 cayman_pcie_gart_fini(rdev);
2366 rdev->accel_working = false;
2367 }
Alex Deucher755d8192011-03-02 20:07:34 -05002368
2369 /* Don't start up if the MC ucode is missing.
2370 * The default clocks and voltages before the MC ucode
2371 * is loaded are not suffient for advanced operations.
Alex Deucherc420c742012-03-20 17:18:39 -04002372 *
2373 * We can skip this check for TN, because there is no MC
2374 * ucode.
Alex Deucher755d8192011-03-02 20:07:34 -05002375 */
Alex Deucherc420c742012-03-20 17:18:39 -04002376 if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
Alex Deucher755d8192011-03-02 20:07:34 -05002377 DRM_ERROR("radeon: MC ucode required for NI+.\n");
2378 return -EINVAL;
2379 }
2380
2381 return 0;
2382}
2383
2384void cayman_fini(struct radeon_device *rdev)
2385{
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002386 r600_blit_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002387 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002388 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002389 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002390 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher2948f5e2013-04-12 13:52:52 -04002391 sumo_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002392 radeon_wb_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002393 radeon_vm_manager_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002394 radeon_ib_pool_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002395 radeon_irq_kms_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002396 radeon_uvd_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002397 cayman_pcie_gart_fini(rdev);
Alex Deucher16cdf042011-10-28 10:30:02 -04002398 r600_vram_scratch_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002399 radeon_gem_fini(rdev);
2400 radeon_fence_driver_fini(rdev);
2401 radeon_bo_fini(rdev);
2402 radeon_atombios_fini(rdev);
2403 kfree(rdev->bios);
2404 rdev->bios = NULL;
2405}
2406
Jerome Glisse721604a2012-01-05 22:11:05 -05002407/*
2408 * vm
2409 */
2410int cayman_vm_init(struct radeon_device *rdev)
2411{
2412 /* number of VMs */
2413 rdev->vm_manager.nvm = 8;
2414 /* base offset of vram pages */
Alex Deuchere71270f2012-03-20 17:18:38 -04002415 if (rdev->flags & RADEON_IS_IGP) {
2416 u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2417 tmp <<= 22;
2418 rdev->vm_manager.vram_base_offset = tmp;
2419 } else
2420 rdev->vm_manager.vram_base_offset = 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002421 return 0;
2422}
2423
2424void cayman_vm_fini(struct radeon_device *rdev)
2425{
2426}
2427
Christian Königdce34bf2012-09-17 19:36:18 +02002428#define R600_ENTRY_VALID (1 << 0)
Jerome Glisse721604a2012-01-05 22:11:05 -05002429#define R600_PTE_SYSTEM (1 << 1)
2430#define R600_PTE_SNOOPED (1 << 2)
2431#define R600_PTE_READABLE (1 << 5)
2432#define R600_PTE_WRITEABLE (1 << 6)
2433
Christian König089a7862012-08-11 11:54:05 +02002434uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002435{
2436 uint32_t r600_flags = 0;
Christian Königdce34bf2012-09-17 19:36:18 +02002437 r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002438 r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
2439 r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
2440 if (flags & RADEON_VM_PAGE_SYSTEM) {
2441 r600_flags |= R600_PTE_SYSTEM;
2442 r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0;
2443 }
2444 return r600_flags;
2445}
2446
Alex Deucher7a083292012-08-31 13:51:21 -04002447/**
2448 * cayman_vm_set_page - update the page tables using the CP
2449 *
2450 * @rdev: radeon_device pointer
Alex Deucher43f12142013-02-01 17:32:42 +01002451 * @ib: indirect buffer to fill with commands
Christian Königdce34bf2012-09-17 19:36:18 +02002452 * @pe: addr of the page entry
2453 * @addr: dst addr to write into pe
2454 * @count: number of page entries to update
2455 * @incr: increase next addr by incr bytes
2456 * @flags: access flags
Alex Deucher7a083292012-08-31 13:51:21 -04002457 *
Alex Deucher43f12142013-02-01 17:32:42 +01002458 * Update the page tables using the CP (cayman/TN).
Alex Deucher7a083292012-08-31 13:51:21 -04002459 */
Alex Deucher43f12142013-02-01 17:32:42 +01002460void cayman_vm_set_page(struct radeon_device *rdev,
2461 struct radeon_ib *ib,
2462 uint64_t pe,
Christian Königdce34bf2012-09-17 19:36:18 +02002463 uint64_t addr, unsigned count,
2464 uint32_t incr, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002465{
Christian Königdce34bf2012-09-17 19:36:18 +02002466 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002467 uint64_t value;
2468 unsigned ndw;
Jerome Glisse721604a2012-01-05 22:11:05 -05002469
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002470 if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
2471 while (count) {
2472 ndw = 1 + count * 2;
2473 if (ndw > 0x3FFF)
2474 ndw = 0x3FFF;
Christian König089a7862012-08-11 11:54:05 +02002475
Alex Deucher43f12142013-02-01 17:32:42 +01002476 ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw);
2477 ib->ptr[ib->length_dw++] = pe;
2478 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002479 for (; ndw > 1; ndw -= 2, --count, pe += 8) {
2480 if (flags & RADEON_VM_PAGE_SYSTEM) {
2481 value = radeon_vm_map_gart(rdev, addr);
2482 value &= 0xFFFFFFFFFFFFF000ULL;
2483 } else if (flags & RADEON_VM_PAGE_VALID) {
2484 value = addr;
2485 } else {
2486 value = 0;
2487 }
Christian Königf9fdffa2012-10-22 17:42:36 +02002488 addr += incr;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002489 value |= r600_flags;
Alex Deucher43f12142013-02-01 17:32:42 +01002490 ib->ptr[ib->length_dw++] = value;
2491 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Christian Königf9fdffa2012-10-22 17:42:36 +02002492 }
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002493 }
2494 } else {
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002495 if ((flags & RADEON_VM_PAGE_SYSTEM) ||
2496 (count == 1)) {
2497 while (count) {
2498 ndw = count * 2;
2499 if (ndw > 0xFFFFE)
2500 ndw = 0xFFFFE;
Christian Königf9fdffa2012-10-22 17:42:36 +02002501
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002502 /* for non-physically contiguous pages (system) */
2503 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
2504 ib->ptr[ib->length_dw++] = pe;
2505 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2506 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2507 if (flags & RADEON_VM_PAGE_SYSTEM) {
2508 value = radeon_vm_map_gart(rdev, addr);
2509 value &= 0xFFFFFFFFFFFFF000ULL;
2510 } else if (flags & RADEON_VM_PAGE_VALID) {
2511 value = addr;
2512 } else {
2513 value = 0;
2514 }
2515 addr += incr;
2516 value |= r600_flags;
2517 ib->ptr[ib->length_dw++] = value;
2518 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002519 }
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002520 }
2521 while (ib->length_dw & 0x7)
2522 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
2523 } else {
2524 while (count) {
2525 ndw = count * 2;
2526 if (ndw > 0xFFFFE)
2527 ndw = 0xFFFFE;
2528
2529 if (flags & RADEON_VM_PAGE_VALID)
2530 value = addr;
2531 else
2532 value = 0;
2533 /* for physically contiguous pages (vram) */
2534 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
2535 ib->ptr[ib->length_dw++] = pe; /* dst addr */
2536 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2537 ib->ptr[ib->length_dw++] = r600_flags; /* mask */
2538 ib->ptr[ib->length_dw++] = 0;
2539 ib->ptr[ib->length_dw++] = value; /* value */
Alex Deucher43f12142013-02-01 17:32:42 +01002540 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002541 ib->ptr[ib->length_dw++] = incr; /* increment size */
2542 ib->ptr[ib->length_dw++] = 0;
2543 pe += ndw * 4;
2544 addr += (ndw / 2) * incr;
2545 count -= ndw / 2;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002546 }
Christian König2a6f1ab2012-08-11 15:00:30 +02002547 }
Alex Deucher43f12142013-02-01 17:32:42 +01002548 while (ib->length_dw & 0x7)
2549 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
Christian König2a6f1ab2012-08-11 15:00:30 +02002550 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002551}
Christian König9b40e5d2012-08-08 12:22:43 +02002552
Alex Deucher7a083292012-08-31 13:51:21 -04002553/**
2554 * cayman_vm_flush - vm flush using the CP
2555 *
2556 * @rdev: radeon_device pointer
2557 *
2558 * Update the page table base and flush the VM TLB
2559 * using the CP (cayman-si).
2560 */
Alex Deucher498522b2012-10-02 14:43:38 -04002561void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
Christian König9b40e5d2012-08-08 12:22:43 +02002562{
Alex Deucher498522b2012-10-02 14:43:38 -04002563 struct radeon_ring *ring = &rdev->ring[ridx];
Christian König9b40e5d2012-08-08 12:22:43 +02002564
Christian Königee60e292012-08-09 16:21:08 +02002565 if (vm == NULL)
Christian König9b40e5d2012-08-08 12:22:43 +02002566 return;
2567
Christian Königee60e292012-08-09 16:21:08 +02002568 radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02002569 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
Christian Königee60e292012-08-09 16:21:08 +02002570
Christian König9b40e5d2012-08-08 12:22:43 +02002571 /* flush hdp cache */
2572 radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
2573 radeon_ring_write(ring, 0x1);
2574
2575 /* bits 0-7 are the VM contexts0-7 */
2576 radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
Alex Deucher498522b2012-10-02 14:43:38 -04002577 radeon_ring_write(ring, 1 << vm->id);
Christian König58f8cf52012-10-22 17:42:35 +02002578
2579 /* sync PFP to ME, otherwise we might get invalid PFP reads */
2580 radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2581 radeon_ring_write(ring, 0x0);
Alex Deucher0af62b02011-01-06 21:19:31 -05002582}
Alex Deucherf60cbd12012-12-04 15:27:33 -05002583
2584void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
2585{
2586 struct radeon_ring *ring = &rdev->ring[ridx];
2587
2588 if (vm == NULL)
2589 return;
2590
2591 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2592 radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2));
2593 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
2594
2595 /* flush hdp cache */
2596 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2597 radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
2598 radeon_ring_write(ring, 1);
2599
2600 /* bits 0-7 are the VM contexts0-7 */
2601 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2602 radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
2603 radeon_ring_write(ring, 1 << vm->id);
2604}
2605