blob: 74077626256a8701cae0d0d77702c2e9d05030c1 [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");
Alex Deucher6596afd2013-06-26 00:15:24 -0400183MODULE_FIRMWARE("radeon/BARTS_smc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500184MODULE_FIRMWARE("radeon/BTC_rlc.bin");
185MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
186MODULE_FIRMWARE("radeon/TURKS_me.bin");
187MODULE_FIRMWARE("radeon/TURKS_mc.bin");
Alex Deucher6596afd2013-06-26 00:15:24 -0400188MODULE_FIRMWARE("radeon/TURKS_smc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500189MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
190MODULE_FIRMWARE("radeon/CAICOS_me.bin");
191MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
Alex Deucher6596afd2013-06-26 00:15:24 -0400192MODULE_FIRMWARE("radeon/CAICOS_smc.bin");
Alex Deucher9b8253c2011-03-02 20:07:28 -0500193MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
194MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
195MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
196MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
Alex Deucherc420c742012-03-20 17:18:39 -0400197MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
198MODULE_FIRMWARE("radeon/ARUBA_me.bin");
199MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500200
Alex Deuchera2c96a22013-02-28 17:58:36 -0500201
202static const u32 cayman_golden_registers2[] =
203{
204 0x3e5c, 0xffffffff, 0x00000000,
205 0x3e48, 0xffffffff, 0x00000000,
206 0x3e4c, 0xffffffff, 0x00000000,
207 0x3e64, 0xffffffff, 0x00000000,
208 0x3e50, 0xffffffff, 0x00000000,
209 0x3e60, 0xffffffff, 0x00000000
210};
211
212static const u32 cayman_golden_registers[] =
213{
214 0x5eb4, 0xffffffff, 0x00000002,
215 0x5e78, 0x8f311ff1, 0x001000f0,
216 0x3f90, 0xffff0000, 0xff000000,
217 0x9148, 0xffff0000, 0xff000000,
218 0x3f94, 0xffff0000, 0xff000000,
219 0x914c, 0xffff0000, 0xff000000,
220 0xc78, 0x00000080, 0x00000080,
221 0xbd4, 0x70073777, 0x00011003,
222 0xd02c, 0xbfffff1f, 0x08421000,
223 0xd0b8, 0x73773777, 0x02011003,
224 0x5bc0, 0x00200000, 0x50100000,
225 0x98f8, 0x33773777, 0x02011003,
226 0x98fc, 0xffffffff, 0x76541032,
227 0x7030, 0x31000311, 0x00000011,
228 0x2f48, 0x33773777, 0x42010001,
229 0x6b28, 0x00000010, 0x00000012,
230 0x7728, 0x00000010, 0x00000012,
231 0x10328, 0x00000010, 0x00000012,
232 0x10f28, 0x00000010, 0x00000012,
233 0x11b28, 0x00000010, 0x00000012,
234 0x12728, 0x00000010, 0x00000012,
235 0x240c, 0x000007ff, 0x00000000,
236 0x8a14, 0xf000001f, 0x00000007,
237 0x8b24, 0x3fff3fff, 0x00ff0fff,
238 0x8b10, 0x0000ff0f, 0x00000000,
239 0x28a4c, 0x07ffffff, 0x06000000,
240 0x10c, 0x00000001, 0x00010003,
241 0xa02c, 0xffffffff, 0x0000009b,
242 0x913c, 0x0000010f, 0x01000100,
243 0x8c04, 0xf8ff00ff, 0x40600060,
244 0x28350, 0x00000f01, 0x00000000,
245 0x9508, 0x3700001f, 0x00000002,
246 0x960c, 0xffffffff, 0x54763210,
247 0x88c4, 0x001f3ae3, 0x00000082,
248 0x88d0, 0xffffffff, 0x0f40df40,
249 0x88d4, 0x0000001f, 0x00000010,
250 0x8974, 0xffffffff, 0x00000000
251};
252
253static const u32 dvst_golden_registers2[] =
254{
255 0x8f8, 0xffffffff, 0,
256 0x8fc, 0x00380000, 0,
257 0x8f8, 0xffffffff, 1,
258 0x8fc, 0x0e000000, 0
259};
260
261static const u32 dvst_golden_registers[] =
262{
263 0x690, 0x3fff3fff, 0x20c00033,
264 0x918c, 0x0fff0fff, 0x00010006,
265 0x91a8, 0x0fff0fff, 0x00010006,
266 0x9150, 0xffffdfff, 0x6e944040,
267 0x917c, 0x0fff0fff, 0x00030002,
268 0x9198, 0x0fff0fff, 0x00030002,
269 0x915c, 0x0fff0fff, 0x00010000,
270 0x3f90, 0xffff0001, 0xff000000,
271 0x9178, 0x0fff0fff, 0x00070000,
272 0x9194, 0x0fff0fff, 0x00070000,
273 0x9148, 0xffff0001, 0xff000000,
274 0x9190, 0x0fff0fff, 0x00090008,
275 0x91ac, 0x0fff0fff, 0x00090008,
276 0x3f94, 0xffff0000, 0xff000000,
277 0x914c, 0xffff0000, 0xff000000,
278 0x929c, 0x00000fff, 0x00000001,
279 0x55e4, 0xff607fff, 0xfc000100,
280 0x8a18, 0xff000fff, 0x00000100,
281 0x8b28, 0xff000fff, 0x00000100,
282 0x9144, 0xfffc0fff, 0x00000100,
283 0x6ed8, 0x00010101, 0x00010000,
284 0x9830, 0xffffffff, 0x00000000,
285 0x9834, 0xf00fffff, 0x00000400,
286 0x9838, 0xfffffffe, 0x00000000,
287 0xd0c0, 0xff000fff, 0x00000100,
288 0xd02c, 0xbfffff1f, 0x08421000,
289 0xd0b8, 0x73773777, 0x12010001,
290 0x5bb0, 0x000000f0, 0x00000070,
291 0x98f8, 0x73773777, 0x12010001,
292 0x98fc, 0xffffffff, 0x00000010,
293 0x9b7c, 0x00ff0000, 0x00fc0000,
294 0x8030, 0x00001f0f, 0x0000100a,
295 0x2f48, 0x73773777, 0x12010001,
296 0x2408, 0x00030000, 0x000c007f,
297 0x8a14, 0xf000003f, 0x00000007,
298 0x8b24, 0x3fff3fff, 0x00ff0fff,
299 0x8b10, 0x0000ff0f, 0x00000000,
300 0x28a4c, 0x07ffffff, 0x06000000,
301 0x4d8, 0x00000fff, 0x00000100,
302 0xa008, 0xffffffff, 0x00010000,
303 0x913c, 0xffff03ff, 0x01000100,
304 0x8c00, 0x000000ff, 0x00000003,
305 0x8c04, 0xf8ff00ff, 0x40600060,
306 0x8cf0, 0x1fff1fff, 0x08e00410,
307 0x28350, 0x00000f01, 0x00000000,
308 0x9508, 0xf700071f, 0x00000002,
309 0x960c, 0xffffffff, 0x54763210,
310 0x20ef8, 0x01ff01ff, 0x00000002,
311 0x20e98, 0xfffffbff, 0x00200000,
312 0x2015c, 0xffffffff, 0x00000f40,
313 0x88c4, 0x001f3ae3, 0x00000082,
314 0x8978, 0x3fffffff, 0x04050140,
315 0x88d4, 0x0000001f, 0x00000010,
316 0x8974, 0xffffffff, 0x00000000
317};
318
319static const u32 scrapper_golden_registers[] =
320{
321 0x690, 0x3fff3fff, 0x20c00033,
322 0x918c, 0x0fff0fff, 0x00010006,
323 0x918c, 0x0fff0fff, 0x00010006,
324 0x91a8, 0x0fff0fff, 0x00010006,
325 0x91a8, 0x0fff0fff, 0x00010006,
326 0x9150, 0xffffdfff, 0x6e944040,
327 0x9150, 0xffffdfff, 0x6e944040,
328 0x917c, 0x0fff0fff, 0x00030002,
329 0x917c, 0x0fff0fff, 0x00030002,
330 0x9198, 0x0fff0fff, 0x00030002,
331 0x9198, 0x0fff0fff, 0x00030002,
332 0x915c, 0x0fff0fff, 0x00010000,
333 0x915c, 0x0fff0fff, 0x00010000,
334 0x3f90, 0xffff0001, 0xff000000,
335 0x3f90, 0xffff0001, 0xff000000,
336 0x9178, 0x0fff0fff, 0x00070000,
337 0x9178, 0x0fff0fff, 0x00070000,
338 0x9194, 0x0fff0fff, 0x00070000,
339 0x9194, 0x0fff0fff, 0x00070000,
340 0x9148, 0xffff0001, 0xff000000,
341 0x9148, 0xffff0001, 0xff000000,
342 0x9190, 0x0fff0fff, 0x00090008,
343 0x9190, 0x0fff0fff, 0x00090008,
344 0x91ac, 0x0fff0fff, 0x00090008,
345 0x91ac, 0x0fff0fff, 0x00090008,
346 0x3f94, 0xffff0000, 0xff000000,
347 0x3f94, 0xffff0000, 0xff000000,
348 0x914c, 0xffff0000, 0xff000000,
349 0x914c, 0xffff0000, 0xff000000,
350 0x929c, 0x00000fff, 0x00000001,
351 0x929c, 0x00000fff, 0x00000001,
352 0x55e4, 0xff607fff, 0xfc000100,
353 0x8a18, 0xff000fff, 0x00000100,
354 0x8a18, 0xff000fff, 0x00000100,
355 0x8b28, 0xff000fff, 0x00000100,
356 0x8b28, 0xff000fff, 0x00000100,
357 0x9144, 0xfffc0fff, 0x00000100,
358 0x9144, 0xfffc0fff, 0x00000100,
359 0x6ed8, 0x00010101, 0x00010000,
360 0x9830, 0xffffffff, 0x00000000,
361 0x9830, 0xffffffff, 0x00000000,
362 0x9834, 0xf00fffff, 0x00000400,
363 0x9834, 0xf00fffff, 0x00000400,
364 0x9838, 0xfffffffe, 0x00000000,
365 0x9838, 0xfffffffe, 0x00000000,
366 0xd0c0, 0xff000fff, 0x00000100,
367 0xd02c, 0xbfffff1f, 0x08421000,
368 0xd02c, 0xbfffff1f, 0x08421000,
369 0xd0b8, 0x73773777, 0x12010001,
370 0xd0b8, 0x73773777, 0x12010001,
371 0x5bb0, 0x000000f0, 0x00000070,
372 0x98f8, 0x73773777, 0x12010001,
373 0x98f8, 0x73773777, 0x12010001,
374 0x98fc, 0xffffffff, 0x00000010,
375 0x98fc, 0xffffffff, 0x00000010,
376 0x9b7c, 0x00ff0000, 0x00fc0000,
377 0x9b7c, 0x00ff0000, 0x00fc0000,
378 0x8030, 0x00001f0f, 0x0000100a,
379 0x8030, 0x00001f0f, 0x0000100a,
380 0x2f48, 0x73773777, 0x12010001,
381 0x2f48, 0x73773777, 0x12010001,
382 0x2408, 0x00030000, 0x000c007f,
383 0x8a14, 0xf000003f, 0x00000007,
384 0x8a14, 0xf000003f, 0x00000007,
385 0x8b24, 0x3fff3fff, 0x00ff0fff,
386 0x8b24, 0x3fff3fff, 0x00ff0fff,
387 0x8b10, 0x0000ff0f, 0x00000000,
388 0x8b10, 0x0000ff0f, 0x00000000,
389 0x28a4c, 0x07ffffff, 0x06000000,
390 0x28a4c, 0x07ffffff, 0x06000000,
391 0x4d8, 0x00000fff, 0x00000100,
392 0x4d8, 0x00000fff, 0x00000100,
393 0xa008, 0xffffffff, 0x00010000,
394 0xa008, 0xffffffff, 0x00010000,
395 0x913c, 0xffff03ff, 0x01000100,
396 0x913c, 0xffff03ff, 0x01000100,
397 0x90e8, 0x001fffff, 0x010400c0,
398 0x8c00, 0x000000ff, 0x00000003,
399 0x8c00, 0x000000ff, 0x00000003,
400 0x8c04, 0xf8ff00ff, 0x40600060,
401 0x8c04, 0xf8ff00ff, 0x40600060,
402 0x8c30, 0x0000000f, 0x00040005,
403 0x8cf0, 0x1fff1fff, 0x08e00410,
404 0x8cf0, 0x1fff1fff, 0x08e00410,
405 0x900c, 0x00ffffff, 0x0017071f,
406 0x28350, 0x00000f01, 0x00000000,
407 0x28350, 0x00000f01, 0x00000000,
408 0x9508, 0xf700071f, 0x00000002,
409 0x9508, 0xf700071f, 0x00000002,
410 0x9688, 0x00300000, 0x0017000f,
411 0x960c, 0xffffffff, 0x54763210,
412 0x960c, 0xffffffff, 0x54763210,
413 0x20ef8, 0x01ff01ff, 0x00000002,
414 0x20e98, 0xfffffbff, 0x00200000,
415 0x2015c, 0xffffffff, 0x00000f40,
416 0x88c4, 0x001f3ae3, 0x00000082,
417 0x88c4, 0x001f3ae3, 0x00000082,
418 0x8978, 0x3fffffff, 0x04050140,
419 0x8978, 0x3fffffff, 0x04050140,
420 0x88d4, 0x0000001f, 0x00000010,
421 0x88d4, 0x0000001f, 0x00000010,
422 0x8974, 0xffffffff, 0x00000000,
423 0x8974, 0xffffffff, 0x00000000
424};
425
426static void ni_init_golden_registers(struct radeon_device *rdev)
427{
428 switch (rdev->family) {
429 case CHIP_CAYMAN:
430 radeon_program_register_sequence(rdev,
431 cayman_golden_registers,
432 (const u32)ARRAY_SIZE(cayman_golden_registers));
433 radeon_program_register_sequence(rdev,
434 cayman_golden_registers2,
435 (const u32)ARRAY_SIZE(cayman_golden_registers2));
436 break;
437 case CHIP_ARUBA:
438 if ((rdev->pdev->device == 0x9900) ||
439 (rdev->pdev->device == 0x9901) ||
440 (rdev->pdev->device == 0x9903) ||
441 (rdev->pdev->device == 0x9904) ||
442 (rdev->pdev->device == 0x9905) ||
443 (rdev->pdev->device == 0x9906) ||
444 (rdev->pdev->device == 0x9907) ||
445 (rdev->pdev->device == 0x9908) ||
446 (rdev->pdev->device == 0x9909) ||
447 (rdev->pdev->device == 0x990A) ||
448 (rdev->pdev->device == 0x990B) ||
449 (rdev->pdev->device == 0x990C) ||
450 (rdev->pdev->device == 0x990D) ||
451 (rdev->pdev->device == 0x990E) ||
452 (rdev->pdev->device == 0x990F) ||
453 (rdev->pdev->device == 0x9910) ||
454 (rdev->pdev->device == 0x9913) ||
455 (rdev->pdev->device == 0x9917) ||
456 (rdev->pdev->device == 0x9918)) {
457 radeon_program_register_sequence(rdev,
458 dvst_golden_registers,
459 (const u32)ARRAY_SIZE(dvst_golden_registers));
460 radeon_program_register_sequence(rdev,
461 dvst_golden_registers2,
462 (const u32)ARRAY_SIZE(dvst_golden_registers2));
463 } else {
464 radeon_program_register_sequence(rdev,
465 scrapper_golden_registers,
466 (const u32)ARRAY_SIZE(scrapper_golden_registers));
467 radeon_program_register_sequence(rdev,
468 dvst_golden_registers2,
469 (const u32)ARRAY_SIZE(dvst_golden_registers2));
470 }
471 break;
472 default:
473 break;
474 }
475}
476
Alex Deucher0af62b02011-01-06 21:19:31 -0500477#define BTC_IO_MC_REGS_SIZE 29
478
479static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
480 {0x00000077, 0xff010100},
481 {0x00000078, 0x00000000},
482 {0x00000079, 0x00001434},
483 {0x0000007a, 0xcc08ec08},
484 {0x0000007b, 0x00040000},
485 {0x0000007c, 0x000080c0},
486 {0x0000007d, 0x09000000},
487 {0x0000007e, 0x00210404},
488 {0x00000081, 0x08a8e800},
489 {0x00000082, 0x00030444},
490 {0x00000083, 0x00000000},
491 {0x00000085, 0x00000001},
492 {0x00000086, 0x00000002},
493 {0x00000087, 0x48490000},
494 {0x00000088, 0x20244647},
495 {0x00000089, 0x00000005},
496 {0x0000008b, 0x66030000},
497 {0x0000008c, 0x00006603},
498 {0x0000008d, 0x00000100},
499 {0x0000008f, 0x00001c0a},
500 {0x00000090, 0xff000001},
501 {0x00000094, 0x00101101},
502 {0x00000095, 0x00000fff},
503 {0x00000096, 0x00116fff},
504 {0x00000097, 0x60010000},
505 {0x00000098, 0x10010000},
506 {0x00000099, 0x00006000},
507 {0x0000009a, 0x00001000},
508 {0x0000009f, 0x00946a00}
509};
510
511static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
512 {0x00000077, 0xff010100},
513 {0x00000078, 0x00000000},
514 {0x00000079, 0x00001434},
515 {0x0000007a, 0xcc08ec08},
516 {0x0000007b, 0x00040000},
517 {0x0000007c, 0x000080c0},
518 {0x0000007d, 0x09000000},
519 {0x0000007e, 0x00210404},
520 {0x00000081, 0x08a8e800},
521 {0x00000082, 0x00030444},
522 {0x00000083, 0x00000000},
523 {0x00000085, 0x00000001},
524 {0x00000086, 0x00000002},
525 {0x00000087, 0x48490000},
526 {0x00000088, 0x20244647},
527 {0x00000089, 0x00000005},
528 {0x0000008b, 0x66030000},
529 {0x0000008c, 0x00006603},
530 {0x0000008d, 0x00000100},
531 {0x0000008f, 0x00001c0a},
532 {0x00000090, 0xff000001},
533 {0x00000094, 0x00101101},
534 {0x00000095, 0x00000fff},
535 {0x00000096, 0x00116fff},
536 {0x00000097, 0x60010000},
537 {0x00000098, 0x10010000},
538 {0x00000099, 0x00006000},
539 {0x0000009a, 0x00001000},
540 {0x0000009f, 0x00936a00}
541};
542
543static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
544 {0x00000077, 0xff010100},
545 {0x00000078, 0x00000000},
546 {0x00000079, 0x00001434},
547 {0x0000007a, 0xcc08ec08},
548 {0x0000007b, 0x00040000},
549 {0x0000007c, 0x000080c0},
550 {0x0000007d, 0x09000000},
551 {0x0000007e, 0x00210404},
552 {0x00000081, 0x08a8e800},
553 {0x00000082, 0x00030444},
554 {0x00000083, 0x00000000},
555 {0x00000085, 0x00000001},
556 {0x00000086, 0x00000002},
557 {0x00000087, 0x48490000},
558 {0x00000088, 0x20244647},
559 {0x00000089, 0x00000005},
560 {0x0000008b, 0x66030000},
561 {0x0000008c, 0x00006603},
562 {0x0000008d, 0x00000100},
563 {0x0000008f, 0x00001c0a},
564 {0x00000090, 0xff000001},
565 {0x00000094, 0x00101101},
566 {0x00000095, 0x00000fff},
567 {0x00000096, 0x00116fff},
568 {0x00000097, 0x60010000},
569 {0x00000098, 0x10010000},
570 {0x00000099, 0x00006000},
571 {0x0000009a, 0x00001000},
572 {0x0000009f, 0x00916a00}
573};
574
Alex Deucher9b8253c2011-03-02 20:07:28 -0500575static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
576 {0x00000077, 0xff010100},
577 {0x00000078, 0x00000000},
578 {0x00000079, 0x00001434},
579 {0x0000007a, 0xcc08ec08},
580 {0x0000007b, 0x00040000},
581 {0x0000007c, 0x000080c0},
582 {0x0000007d, 0x09000000},
583 {0x0000007e, 0x00210404},
584 {0x00000081, 0x08a8e800},
585 {0x00000082, 0x00030444},
586 {0x00000083, 0x00000000},
587 {0x00000085, 0x00000001},
588 {0x00000086, 0x00000002},
589 {0x00000087, 0x48490000},
590 {0x00000088, 0x20244647},
591 {0x00000089, 0x00000005},
592 {0x0000008b, 0x66030000},
593 {0x0000008c, 0x00006603},
594 {0x0000008d, 0x00000100},
595 {0x0000008f, 0x00001c0a},
596 {0x00000090, 0xff000001},
597 {0x00000094, 0x00101101},
598 {0x00000095, 0x00000fff},
599 {0x00000096, 0x00116fff},
600 {0x00000097, 0x60010000},
601 {0x00000098, 0x10010000},
602 {0x00000099, 0x00006000},
603 {0x0000009a, 0x00001000},
604 {0x0000009f, 0x00976b00}
605};
606
Alex Deucher755d8192011-03-02 20:07:34 -0500607int ni_mc_load_microcode(struct radeon_device *rdev)
Alex Deucher0af62b02011-01-06 21:19:31 -0500608{
609 const __be32 *fw_data;
610 u32 mem_type, running, blackout = 0;
611 u32 *io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500612 int i, ucode_size, regs_size;
Alex Deucher0af62b02011-01-06 21:19:31 -0500613
614 if (!rdev->mc_fw)
615 return -EINVAL;
616
617 switch (rdev->family) {
618 case CHIP_BARTS:
619 io_mc_regs = (u32 *)&barts_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500620 ucode_size = BTC_MC_UCODE_SIZE;
621 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500622 break;
623 case CHIP_TURKS:
624 io_mc_regs = (u32 *)&turks_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500625 ucode_size = BTC_MC_UCODE_SIZE;
626 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500627 break;
628 case CHIP_CAICOS:
629 default:
630 io_mc_regs = (u32 *)&caicos_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500631 ucode_size = BTC_MC_UCODE_SIZE;
632 regs_size = BTC_IO_MC_REGS_SIZE;
633 break;
634 case CHIP_CAYMAN:
635 io_mc_regs = (u32 *)&cayman_io_mc_regs;
636 ucode_size = CAYMAN_MC_UCODE_SIZE;
637 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500638 break;
639 }
640
641 mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
642 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
643
644 if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
645 if (running) {
646 blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
647 WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
648 }
649
650 /* reset the engine and set to writable */
651 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
652 WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
653
654 /* load mc io regs */
Alex Deucher9b8253c2011-03-02 20:07:28 -0500655 for (i = 0; i < regs_size; i++) {
Alex Deucher0af62b02011-01-06 21:19:31 -0500656 WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
657 WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
658 }
659 /* load the MC ucode */
660 fw_data = (const __be32 *)rdev->mc_fw->data;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500661 for (i = 0; i < ucode_size; i++)
Alex Deucher0af62b02011-01-06 21:19:31 -0500662 WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
663
664 /* put the engine back into the active state */
665 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
666 WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
667 WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
668
669 /* wait for training to complete */
Alex Deucher0e2c9782011-11-02 18:08:25 -0400670 for (i = 0; i < rdev->usec_timeout; i++) {
671 if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
672 break;
673 udelay(1);
674 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500675
676 if (running)
677 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
678 }
679
680 return 0;
681}
682
683int ni_init_microcode(struct radeon_device *rdev)
684{
685 struct platform_device *pdev;
686 const char *chip_name;
687 const char *rlc_chip_name;
688 size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
Alex Deucher6596afd2013-06-26 00:15:24 -0400689 size_t smc_req_size = 0;
Alex Deucher0af62b02011-01-06 21:19:31 -0500690 char fw_name[30];
691 int err;
692
693 DRM_DEBUG("\n");
694
695 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
696 err = IS_ERR(pdev);
697 if (err) {
698 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
699 return -EINVAL;
700 }
701
702 switch (rdev->family) {
703 case CHIP_BARTS:
704 chip_name = "BARTS";
705 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500706 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
707 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
708 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
709 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher6596afd2013-06-26 00:15:24 -0400710 smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4);
Alex Deucher0af62b02011-01-06 21:19:31 -0500711 break;
712 case CHIP_TURKS:
713 chip_name = "TURKS";
714 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500715 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
716 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
717 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
718 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher6596afd2013-06-26 00:15:24 -0400719 smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4);
Alex Deucher0af62b02011-01-06 21:19:31 -0500720 break;
721 case CHIP_CAICOS:
722 chip_name = "CAICOS";
723 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500724 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
725 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
726 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
727 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher6596afd2013-06-26 00:15:24 -0400728 smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4);
Alex Deucher9b8253c2011-03-02 20:07:28 -0500729 break;
730 case CHIP_CAYMAN:
731 chip_name = "CAYMAN";
732 rlc_chip_name = "CAYMAN";
733 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
734 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
735 rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
736 mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500737 break;
Alex Deucherc420c742012-03-20 17:18:39 -0400738 case CHIP_ARUBA:
739 chip_name = "ARUBA";
740 rlc_chip_name = "ARUBA";
741 /* pfp/me same size as CAYMAN */
742 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
743 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
744 rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
745 mc_req_size = 0;
746 break;
Alex Deucher0af62b02011-01-06 21:19:31 -0500747 default: BUG();
748 }
749
Alex Deucher0af62b02011-01-06 21:19:31 -0500750 DRM_INFO("Loading %s Microcode\n", chip_name);
751
752 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
753 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
754 if (err)
755 goto out;
756 if (rdev->pfp_fw->size != pfp_req_size) {
757 printk(KERN_ERR
758 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
759 rdev->pfp_fw->size, fw_name);
760 err = -EINVAL;
761 goto out;
762 }
763
764 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
765 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
766 if (err)
767 goto out;
768 if (rdev->me_fw->size != me_req_size) {
769 printk(KERN_ERR
770 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
771 rdev->me_fw->size, fw_name);
772 err = -EINVAL;
773 }
774
775 snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
776 err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
777 if (err)
778 goto out;
779 if (rdev->rlc_fw->size != rlc_req_size) {
780 printk(KERN_ERR
781 "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
782 rdev->rlc_fw->size, fw_name);
783 err = -EINVAL;
784 }
785
Alex Deucherc420c742012-03-20 17:18:39 -0400786 /* no MC ucode on TN */
787 if (!(rdev->flags & RADEON_IS_IGP)) {
788 snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
789 err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
790 if (err)
791 goto out;
792 if (rdev->mc_fw->size != mc_req_size) {
793 printk(KERN_ERR
794 "ni_mc: Bogus length %zu in firmware \"%s\"\n",
795 rdev->mc_fw->size, fw_name);
796 err = -EINVAL;
797 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500798 }
Alex Deucher6596afd2013-06-26 00:15:24 -0400799
800 if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAICOS)) {
801 snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
802 err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
803 if (err)
804 goto out;
805 if (rdev->smc_fw->size != smc_req_size) {
806 printk(KERN_ERR
807 "ni_mc: Bogus length %zu in firmware \"%s\"\n",
808 rdev->mc_fw->size, fw_name);
809 err = -EINVAL;
810 }
811 }
812
Alex Deucher0af62b02011-01-06 21:19:31 -0500813out:
814 platform_device_unregister(pdev);
815
816 if (err) {
817 if (err != -EINVAL)
818 printk(KERN_ERR
819 "ni_cp: Failed to load firmware \"%s\"\n",
820 fw_name);
821 release_firmware(rdev->pfp_fw);
822 rdev->pfp_fw = NULL;
823 release_firmware(rdev->me_fw);
824 rdev->me_fw = NULL;
825 release_firmware(rdev->rlc_fw);
826 rdev->rlc_fw = NULL;
827 release_firmware(rdev->mc_fw);
828 rdev->mc_fw = NULL;
829 }
830 return err;
831}
832
Alex Deucher29a15222012-12-14 11:57:36 -0500833int tn_get_temp(struct radeon_device *rdev)
834{
835 u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
836 int actual_temp = (temp / 8) - 49;
837
838 return actual_temp * 1000;
839}
840
Alex Deucherfecf1d02011-03-02 20:07:29 -0500841/*
842 * Core functions
843 */
Alex Deucherfecf1d02011-03-02 20:07:29 -0500844static void cayman_gpu_init(struct radeon_device *rdev)
845{
Alex Deucherfecf1d02011-03-02 20:07:29 -0500846 u32 gb_addr_config = 0;
847 u32 mc_shared_chmap, mc_arb_ramcfg;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500848 u32 cgts_tcc_disable;
849 u32 sx_debug_1;
850 u32 smx_dc_ctl0;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500851 u32 cgts_sm_ctrl_reg;
852 u32 hdp_host_path_cntl;
853 u32 tmp;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400854 u32 disabled_rb_mask;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500855 int i, j;
856
857 switch (rdev->family) {
858 case CHIP_CAYMAN:
Alex Deucherfecf1d02011-03-02 20:07:29 -0500859 rdev->config.cayman.max_shader_engines = 2;
860 rdev->config.cayman.max_pipes_per_simd = 4;
861 rdev->config.cayman.max_tile_pipes = 8;
862 rdev->config.cayman.max_simds_per_se = 12;
863 rdev->config.cayman.max_backends_per_se = 4;
864 rdev->config.cayman.max_texture_channel_caches = 8;
865 rdev->config.cayman.max_gprs = 256;
866 rdev->config.cayman.max_threads = 256;
867 rdev->config.cayman.max_gs_threads = 32;
868 rdev->config.cayman.max_stack_entries = 512;
869 rdev->config.cayman.sx_num_of_sets = 8;
870 rdev->config.cayman.sx_max_export_size = 256;
871 rdev->config.cayman.sx_max_export_pos_size = 64;
872 rdev->config.cayman.sx_max_export_smx_size = 192;
873 rdev->config.cayman.max_hw_contexts = 8;
874 rdev->config.cayman.sq_num_cf_insts = 2;
875
876 rdev->config.cayman.sc_prim_fifo_size = 0x100;
877 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
878 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400879 gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500880 break;
Alex Deucher7b76e472012-03-20 17:18:36 -0400881 case CHIP_ARUBA:
882 default:
883 rdev->config.cayman.max_shader_engines = 1;
884 rdev->config.cayman.max_pipes_per_simd = 4;
885 rdev->config.cayman.max_tile_pipes = 2;
886 if ((rdev->pdev->device == 0x9900) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400887 (rdev->pdev->device == 0x9901) ||
888 (rdev->pdev->device == 0x9905) ||
889 (rdev->pdev->device == 0x9906) ||
890 (rdev->pdev->device == 0x9907) ||
891 (rdev->pdev->device == 0x9908) ||
892 (rdev->pdev->device == 0x9909) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500893 (rdev->pdev->device == 0x990B) ||
894 (rdev->pdev->device == 0x990C) ||
895 (rdev->pdev->device == 0x990F) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400896 (rdev->pdev->device == 0x9910) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500897 (rdev->pdev->device == 0x9917) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400898 (rdev->pdev->device == 0x9999) ||
899 (rdev->pdev->device == 0x999C)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400900 rdev->config.cayman.max_simds_per_se = 6;
901 rdev->config.cayman.max_backends_per_se = 2;
902 } else if ((rdev->pdev->device == 0x9903) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400903 (rdev->pdev->device == 0x9904) ||
904 (rdev->pdev->device == 0x990A) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500905 (rdev->pdev->device == 0x990D) ||
906 (rdev->pdev->device == 0x990E) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400907 (rdev->pdev->device == 0x9913) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400908 (rdev->pdev->device == 0x9918) ||
909 (rdev->pdev->device == 0x999D)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400910 rdev->config.cayman.max_simds_per_se = 4;
911 rdev->config.cayman.max_backends_per_se = 2;
Alex Deucherd430f7d2012-06-05 09:50:28 -0400912 } else if ((rdev->pdev->device == 0x9919) ||
913 (rdev->pdev->device == 0x9990) ||
914 (rdev->pdev->device == 0x9991) ||
915 (rdev->pdev->device == 0x9994) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500916 (rdev->pdev->device == 0x9995) ||
917 (rdev->pdev->device == 0x9996) ||
918 (rdev->pdev->device == 0x999A) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400919 (rdev->pdev->device == 0x99A0)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400920 rdev->config.cayman.max_simds_per_se = 3;
921 rdev->config.cayman.max_backends_per_se = 1;
922 } else {
923 rdev->config.cayman.max_simds_per_se = 2;
924 rdev->config.cayman.max_backends_per_se = 1;
925 }
926 rdev->config.cayman.max_texture_channel_caches = 2;
927 rdev->config.cayman.max_gprs = 256;
928 rdev->config.cayman.max_threads = 256;
929 rdev->config.cayman.max_gs_threads = 32;
930 rdev->config.cayman.max_stack_entries = 512;
931 rdev->config.cayman.sx_num_of_sets = 8;
932 rdev->config.cayman.sx_max_export_size = 256;
933 rdev->config.cayman.sx_max_export_pos_size = 64;
934 rdev->config.cayman.sx_max_export_smx_size = 192;
935 rdev->config.cayman.max_hw_contexts = 8;
936 rdev->config.cayman.sq_num_cf_insts = 2;
937
938 rdev->config.cayman.sc_prim_fifo_size = 0x40;
939 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
940 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400941 gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
Alex Deucher7b76e472012-03-20 17:18:36 -0400942 break;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500943 }
944
945 /* Initialize HDP */
946 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
947 WREG32((0x2c14 + j), 0x00000000);
948 WREG32((0x2c18 + j), 0x00000000);
949 WREG32((0x2c1c + j), 0x00000000);
950 WREG32((0x2c20 + j), 0x00000000);
951 WREG32((0x2c24 + j), 0x00000000);
952 }
953
954 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
955
Alex Deucherd054ac12011-09-01 17:46:15 +0000956 evergreen_fix_pci_max_read_req_size(rdev);
957
Alex Deucherfecf1d02011-03-02 20:07:29 -0500958 mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
959 mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
960
Alex Deucherfecf1d02011-03-02 20:07:29 -0500961 tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
962 rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
963 if (rdev->config.cayman.mem_row_size_in_kb > 4)
964 rdev->config.cayman.mem_row_size_in_kb = 4;
965 /* XXX use MC settings? */
966 rdev->config.cayman.shader_engine_tile_size = 32;
967 rdev->config.cayman.num_gpus = 1;
968 rdev->config.cayman.multi_gpu_tile_size = 64;
969
Alex Deucherfecf1d02011-03-02 20:07:29 -0500970 tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
971 rdev->config.cayman.num_tile_pipes = (1 << tmp);
972 tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
973 rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
974 tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
975 rdev->config.cayman.num_shader_engines = tmp + 1;
976 tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
977 rdev->config.cayman.num_gpus = tmp + 1;
978 tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
979 rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
980 tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
981 rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
982
Alex Deucher416a2bd2012-05-31 19:00:25 -0400983
Alex Deucherfecf1d02011-03-02 20:07:29 -0500984 /* setup tiling info dword. gb_addr_config is not adequate since it does
985 * not have bank info, so create a custom tiling dword.
986 * bits 3:0 num_pipes
987 * bits 7:4 num_banks
988 * bits 11:8 group_size
989 * bits 15:12 row_size
990 */
991 rdev->config.cayman.tile_config = 0;
992 switch (rdev->config.cayman.num_tile_pipes) {
993 case 1:
994 default:
995 rdev->config.cayman.tile_config |= (0 << 0);
996 break;
997 case 2:
998 rdev->config.cayman.tile_config |= (1 << 0);
999 break;
1000 case 4:
1001 rdev->config.cayman.tile_config |= (2 << 0);
1002 break;
1003 case 8:
1004 rdev->config.cayman.tile_config |= (3 << 0);
1005 break;
1006 }
Alex Deucher7b76e472012-03-20 17:18:36 -04001007
1008 /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
1009 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher1f73cca2012-05-24 22:55:15 -04001010 rdev->config.cayman.tile_config |= 1 << 4;
Alex Deucher29d65402012-05-31 18:53:36 -04001011 else {
Alex Deucher5b23c902012-07-31 11:05:11 -04001012 switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
1013 case 0: /* four banks */
Alex Deucher29d65402012-05-31 18:53:36 -04001014 rdev->config.cayman.tile_config |= 0 << 4;
Alex Deucher5b23c902012-07-31 11:05:11 -04001015 break;
1016 case 1: /* eight banks */
1017 rdev->config.cayman.tile_config |= 1 << 4;
1018 break;
1019 case 2: /* sixteen banks */
1020 default:
1021 rdev->config.cayman.tile_config |= 2 << 4;
1022 break;
1023 }
Alex Deucher29d65402012-05-31 18:53:36 -04001024 }
Alex Deucherfecf1d02011-03-02 20:07:29 -05001025 rdev->config.cayman.tile_config |=
Dave Airliecde50832011-05-19 14:14:41 +10001026 ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
Alex Deucherfecf1d02011-03-02 20:07:29 -05001027 rdev->config.cayman.tile_config |=
1028 ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
1029
Alex Deucher416a2bd2012-05-31 19:00:25 -04001030 tmp = 0;
1031 for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
1032 u32 rb_disable_bitmap;
1033
1034 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1035 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1036 rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
1037 tmp <<= 4;
1038 tmp |= rb_disable_bitmap;
1039 }
1040 /* enabled rb are just the one not disabled :) */
1041 disabled_rb_mask = tmp;
Alex Deuchercedb6552013-04-09 10:13:22 -04001042 tmp = 0;
1043 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1044 tmp |= (1 << i);
1045 /* if all the backends are disabled, fix it up here */
1046 if ((disabled_rb_mask & tmp) == tmp) {
1047 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1048 disabled_rb_mask &= ~(1 << i);
1049 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001050
1051 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1052 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1053
Alex Deucherfecf1d02011-03-02 20:07:29 -05001054 WREG32(GB_ADDR_CONFIG, gb_addr_config);
1055 WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
Alex Deucher7c1c7c12013-04-05 10:28:08 -04001056 if (ASIC_IS_DCE6(rdev))
1057 WREG32(DMIF_ADDR_CALC, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001058 WREG32(HDP_ADDR_CONFIG, gb_addr_config);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001059 WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
1060 WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
Christian König9a210592013-04-08 12:41:37 +02001061 WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
1062 WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
1063 WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001064
Alex Deucher8f612b22013-03-11 19:28:39 -04001065 if ((rdev->config.cayman.max_backends_per_se == 1) &&
1066 (rdev->flags & RADEON_IS_IGP)) {
1067 if ((disabled_rb_mask & 3) == 1) {
1068 /* RB0 disabled, RB1 enabled */
1069 tmp = 0x11111111;
1070 } else {
1071 /* RB1 disabled, RB0 enabled */
1072 tmp = 0x00000000;
1073 }
1074 } else {
1075 tmp = gb_addr_config & NUM_PIPES_MASK;
1076 tmp = r6xx_remap_render_backend(rdev, tmp,
1077 rdev->config.cayman.max_backends_per_se *
1078 rdev->config.cayman.max_shader_engines,
1079 CAYMAN_MAX_BACKENDS, disabled_rb_mask);
1080 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001081 WREG32(GB_BACKEND_MAP, tmp);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001082
Alex Deucher416a2bd2012-05-31 19:00:25 -04001083 cgts_tcc_disable = 0xffff0000;
1084 for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
1085 cgts_tcc_disable &= ~(1 << (16 + i));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001086 WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
1087 WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001088 WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
1089 WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
1090
1091 /* reprogram the shader complex */
1092 cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
1093 for (i = 0; i < 16; i++)
1094 WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
1095 WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
1096
1097 /* set HW defaults for 3D engine */
1098 WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
1099
1100 sx_debug_1 = RREG32(SX_DEBUG_1);
1101 sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1102 WREG32(SX_DEBUG_1, sx_debug_1);
1103
1104 smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1105 smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
Dave Airlie285e0422011-05-09 14:54:33 +10001106 smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001107 WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1108
1109 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
1110
1111 /* need to be explicitly zero-ed */
1112 WREG32(VGT_OFFCHIP_LDS_BASE, 0);
1113 WREG32(SQ_LSTMP_RING_BASE, 0);
1114 WREG32(SQ_HSTMP_RING_BASE, 0);
1115 WREG32(SQ_ESTMP_RING_BASE, 0);
1116 WREG32(SQ_GSTMP_RING_BASE, 0);
1117 WREG32(SQ_VSTMP_RING_BASE, 0);
1118 WREG32(SQ_PSTMP_RING_BASE, 0);
1119
1120 WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
1121
Dave Airlie285e0422011-05-09 14:54:33 +10001122 WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
1123 POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
1124 SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001125
Dave Airlie285e0422011-05-09 14:54:33 +10001126 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
1127 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
1128 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001129
1130
1131 WREG32(VGT_NUM_INSTANCES, 1);
1132
1133 WREG32(CP_PERFMON_CNTL, 0);
1134
Dave Airlie285e0422011-05-09 14:54:33 +10001135 WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
Alex Deucherfecf1d02011-03-02 20:07:29 -05001136 FETCH_FIFO_HIWATER(0x4) |
1137 DONE_FIFO_HIWATER(0xe0) |
1138 ALU_UPDATE_FIFO_HIWATER(0x8)));
1139
1140 WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1141 WREG32(SQ_CONFIG, (VC_ENABLE |
1142 EXPORT_SRC_C |
1143 GFX_PRIO(0) |
1144 CS1_PRIO(0) |
1145 CS2_PRIO(1)));
1146 WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1147
1148 WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1149 FORCE_EOV_MAX_REZ_CNT(255)));
1150
1151 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1152 AUTO_INVLD_EN(ES_AND_GS_AUTO));
1153
1154 WREG32(VGT_GS_VERTEX_REUSE, 16);
1155 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1156
1157 WREG32(CB_PERF_CTR0_SEL_0, 0);
1158 WREG32(CB_PERF_CTR0_SEL_1, 0);
1159 WREG32(CB_PERF_CTR1_SEL_0, 0);
1160 WREG32(CB_PERF_CTR1_SEL_1, 0);
1161 WREG32(CB_PERF_CTR2_SEL_0, 0);
1162 WREG32(CB_PERF_CTR2_SEL_1, 0);
1163 WREG32(CB_PERF_CTR3_SEL_0, 0);
1164 WREG32(CB_PERF_CTR3_SEL_1, 0);
1165
Dave Airlie0b65f832011-05-19 14:14:42 +10001166 tmp = RREG32(HDP_MISC_CNTL);
1167 tmp |= HDP_FLUSH_INVALIDATE_CACHE;
1168 WREG32(HDP_MISC_CNTL, tmp);
1169
Alex Deucherfecf1d02011-03-02 20:07:29 -05001170 hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1171 WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1172
1173 WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1174
1175 udelay(50);
1176}
1177
Alex Deucherfa8198e2011-03-02 20:07:30 -05001178/*
1179 * GART
1180 */
1181void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1182{
1183 /* flush hdp cache */
1184 WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1185
1186 /* bits 0-7 are the VM contexts0-7 */
1187 WREG32(VM_INVALIDATE_REQUEST, 1);
1188}
1189
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001190static int cayman_pcie_gart_enable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001191{
Jerome Glisse721604a2012-01-05 22:11:05 -05001192 int i, r;
Alex Deucherfa8198e2011-03-02 20:07:30 -05001193
Jerome Glissec9a1be92011-11-03 11:16:49 -04001194 if (rdev->gart.robj == NULL) {
Alex Deucherfa8198e2011-03-02 20:07:30 -05001195 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1196 return -EINVAL;
1197 }
1198 r = radeon_gart_table_vram_pin(rdev);
1199 if (r)
1200 return r;
1201 radeon_gart_restore(rdev);
1202 /* Setup TLB control */
Jerome Glisse721604a2012-01-05 22:11:05 -05001203 WREG32(MC_VM_MX_L1_TLB_CNTL,
1204 (0xA << 7) |
1205 ENABLE_L1_TLB |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001206 ENABLE_L1_FRAGMENT_PROCESSING |
1207 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
Jerome Glisse721604a2012-01-05 22:11:05 -05001208 ENABLE_ADVANCED_DRIVER_MODEL |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001209 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1210 /* Setup L2 cache */
1211 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1212 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1213 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1214 EFFECTIVE_L2_QUEUE_SIZE(7) |
1215 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1216 WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1217 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1218 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1219 /* setup context0 */
1220 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1221 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1222 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1223 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1224 (u32)(rdev->dummy_page.addr >> 12));
1225 WREG32(VM_CONTEXT0_CNTL2, 0);
1226 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1227 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
Jerome Glisse721604a2012-01-05 22:11:05 -05001228
1229 WREG32(0x15D4, 0);
1230 WREG32(0x15D8, 0);
1231 WREG32(0x15DC, 0);
1232
1233 /* empty context1-7 */
Alex Deucher23d4f1f2012-10-08 09:45:46 -04001234 /* Assign the pt base to something valid for now; the pts used for
1235 * the VMs are determined by the application and setup and assigned
1236 * on the fly in the vm part of radeon_gart.c
1237 */
Jerome Glisse721604a2012-01-05 22:11:05 -05001238 for (i = 1; i < 8; i++) {
1239 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
Alex Deucherc1a7ca02012-10-08 12:15:13 -04001240 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
Jerome Glisse721604a2012-01-05 22:11:05 -05001241 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1242 rdev->gart.table_addr >> 12);
1243 }
1244
1245 /* enable context1-7 */
1246 WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1247 (u32)(rdev->dummy_page.addr >> 12));
Christian Königae133a12012-09-18 15:30:44 -04001248 WREG32(VM_CONTEXT1_CNTL2, 4);
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02001249 WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
Christian Königae133a12012-09-18 15:30:44 -04001250 RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1251 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1252 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1253 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1254 PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1255 PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1256 VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1257 VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1258 READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1259 READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1260 WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1261 WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001262
1263 cayman_pcie_gart_tlb_flush(rdev);
Tormod Voldenfcf4de52011-08-31 21:54:07 +00001264 DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1265 (unsigned)(rdev->mc.gtt_size >> 20),
1266 (unsigned long long)rdev->gart.table_addr);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001267 rdev->gart.ready = true;
1268 return 0;
1269}
1270
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001271static void cayman_pcie_gart_disable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001272{
Alex Deucherfa8198e2011-03-02 20:07:30 -05001273 /* Disable all tables */
1274 WREG32(VM_CONTEXT0_CNTL, 0);
1275 WREG32(VM_CONTEXT1_CNTL, 0);
1276 /* Setup TLB control */
1277 WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1278 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1279 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1280 /* Setup L2 cache */
1281 WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1282 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1283 EFFECTIVE_L2_QUEUE_SIZE(7) |
1284 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1285 WREG32(VM_L2_CNTL2, 0);
1286 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1287 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
Jerome Glissec9a1be92011-11-03 11:16:49 -04001288 radeon_gart_table_vram_unpin(rdev);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001289}
1290
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001291static void cayman_pcie_gart_fini(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001292{
1293 cayman_pcie_gart_disable(rdev);
1294 radeon_gart_table_vram_free(rdev);
1295 radeon_gart_fini(rdev);
1296}
1297
Alex Deucher1b370782011-11-17 20:13:28 -05001298void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
1299 int ring, u32 cp_int_cntl)
1300{
1301 u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;
1302
1303 WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
1304 WREG32(CP_INT_CNTL, cp_int_cntl);
1305}
1306
Alex Deucher0c88a022011-03-02 20:07:31 -05001307/*
1308 * CP.
1309 */
Alex Deucherb40e7e12011-11-17 14:57:50 -05001310void cayman_fence_ring_emit(struct radeon_device *rdev,
1311 struct radeon_fence *fence)
1312{
1313 struct radeon_ring *ring = &rdev->ring[fence->ring];
1314 u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1315
Jerome Glisse721604a2012-01-05 22:11:05 -05001316 /* flush read cache over gart for this vmid */
1317 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1318 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
1319 radeon_ring_write(ring, 0);
Alex Deucherb40e7e12011-11-17 14:57:50 -05001320 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1321 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1322 radeon_ring_write(ring, 0xFFFFFFFF);
1323 radeon_ring_write(ring, 0);
1324 radeon_ring_write(ring, 10); /* poll interval */
1325 /* EVENT_WRITE_EOP - flush caches, send int */
1326 radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1327 radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
1328 radeon_ring_write(ring, addr & 0xffffffff);
1329 radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1330 radeon_ring_write(ring, fence->seq);
1331 radeon_ring_write(ring, 0);
1332}
1333
Jerome Glisse721604a2012-01-05 22:11:05 -05001334void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1335{
Christian König876dc9f2012-05-08 14:24:01 +02001336 struct radeon_ring *ring = &rdev->ring[ib->ring];
Jerome Glisse721604a2012-01-05 22:11:05 -05001337
1338 /* set to DX10/11 mode */
1339 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1340 radeon_ring_write(ring, 1);
Christian König45df6802012-07-06 16:22:55 +02001341
1342 if (ring->rptr_save_reg) {
1343 uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1344 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1345 radeon_ring_write(ring, ((ring->rptr_save_reg -
1346 PACKET3_SET_CONFIG_REG_START) >> 2));
1347 radeon_ring_write(ring, next_rptr);
1348 }
1349
Jerome Glisse721604a2012-01-05 22:11:05 -05001350 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1351 radeon_ring_write(ring,
1352#ifdef __BIG_ENDIAN
1353 (2 << 0) |
1354#endif
1355 (ib->gpu_addr & 0xFFFFFFFC));
1356 radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
Christian König4bf3dd92012-08-06 18:57:44 +02001357 radeon_ring_write(ring, ib->length_dw |
1358 (ib->vm ? (ib->vm->id << 24) : 0));
Jerome Glisse721604a2012-01-05 22:11:05 -05001359
1360 /* flush read cache over gart for this vmid */
1361 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1362 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
Christian König4bf3dd92012-08-06 18:57:44 +02001363 radeon_ring_write(ring, ib->vm ? ib->vm->id : 0);
Jerome Glisse721604a2012-01-05 22:11:05 -05001364 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1365 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1366 radeon_ring_write(ring, 0xFFFFFFFF);
1367 radeon_ring_write(ring, 0);
1368 radeon_ring_write(ring, 10); /* poll interval */
1369}
1370
Christian Königf2ba57b2013-04-08 12:41:29 +02001371void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
1372 struct radeon_ring *ring,
1373 struct radeon_semaphore *semaphore,
1374 bool emit_wait)
1375{
1376 uint64_t addr = semaphore->gpu_addr;
1377
1378 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
1379 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
1380
1381 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
1382 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
1383
1384 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
1385 radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
1386}
1387
Alex Deucher0c88a022011-03-02 20:07:31 -05001388static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1389{
1390 if (enable)
1391 WREG32(CP_ME_CNTL, 0);
1392 else {
Dave Airlie38f1cff2011-03-16 11:34:41 +10001393 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
Alex Deucher0c88a022011-03-02 20:07:31 -05001394 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1395 WREG32(SCRATCH_UMSK, 0);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001396 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001397 }
1398}
1399
1400static int cayman_cp_load_microcode(struct radeon_device *rdev)
1401{
1402 const __be32 *fw_data;
1403 int i;
1404
1405 if (!rdev->me_fw || !rdev->pfp_fw)
1406 return -EINVAL;
1407
1408 cayman_cp_enable(rdev, false);
1409
1410 fw_data = (const __be32 *)rdev->pfp_fw->data;
1411 WREG32(CP_PFP_UCODE_ADDR, 0);
1412 for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
1413 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1414 WREG32(CP_PFP_UCODE_ADDR, 0);
1415
1416 fw_data = (const __be32 *)rdev->me_fw->data;
1417 WREG32(CP_ME_RAM_WADDR, 0);
1418 for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
1419 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1420
1421 WREG32(CP_PFP_UCODE_ADDR, 0);
1422 WREG32(CP_ME_RAM_WADDR, 0);
1423 WREG32(CP_ME_RAM_RADDR, 0);
1424 return 0;
1425}
1426
1427static int cayman_cp_start(struct radeon_device *rdev)
1428{
Christian Könige32eb502011-10-23 12:56:27 +02001429 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher0c88a022011-03-02 20:07:31 -05001430 int r, i;
1431
Christian Könige32eb502011-10-23 12:56:27 +02001432 r = radeon_ring_lock(rdev, ring, 7);
Alex Deucher0c88a022011-03-02 20:07:31 -05001433 if (r) {
1434 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1435 return r;
1436 }
Christian Könige32eb502011-10-23 12:56:27 +02001437 radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1438 radeon_ring_write(ring, 0x1);
1439 radeon_ring_write(ring, 0x0);
1440 radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1441 radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1442 radeon_ring_write(ring, 0);
1443 radeon_ring_write(ring, 0);
1444 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001445
1446 cayman_cp_enable(rdev, true);
1447
Christian Könige32eb502011-10-23 12:56:27 +02001448 r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
Alex Deucher0c88a022011-03-02 20:07:31 -05001449 if (r) {
1450 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1451 return r;
1452 }
1453
1454 /* setup clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001455 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1456 radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001457
1458 for (i = 0; i < cayman_default_size; i++)
Christian Könige32eb502011-10-23 12:56:27 +02001459 radeon_ring_write(ring, cayman_default_state[i]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001460
Christian Könige32eb502011-10-23 12:56:27 +02001461 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1462 radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001463
1464 /* set clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001465 radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1466 radeon_ring_write(ring, 0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001467
1468 /* SQ_VTX_BASE_VTX_LOC */
Christian Könige32eb502011-10-23 12:56:27 +02001469 radeon_ring_write(ring, 0xc0026f00);
1470 radeon_ring_write(ring, 0x00000000);
1471 radeon_ring_write(ring, 0x00000000);
1472 radeon_ring_write(ring, 0x00000000);
Alex Deucher0c88a022011-03-02 20:07:31 -05001473
1474 /* Clear consts */
Christian Könige32eb502011-10-23 12:56:27 +02001475 radeon_ring_write(ring, 0xc0036f00);
1476 radeon_ring_write(ring, 0x00000bc4);
1477 radeon_ring_write(ring, 0xffffffff);
1478 radeon_ring_write(ring, 0xffffffff);
1479 radeon_ring_write(ring, 0xffffffff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001480
Christian Könige32eb502011-10-23 12:56:27 +02001481 radeon_ring_write(ring, 0xc0026900);
1482 radeon_ring_write(ring, 0x00000316);
1483 radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1484 radeon_ring_write(ring, 0x00000010); /* */
Alex Deucher9b91d182011-03-02 20:07:39 -05001485
Christian Könige32eb502011-10-23 12:56:27 +02001486 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001487
1488 /* XXX init other rings */
1489
1490 return 0;
1491}
1492
Alex Deucher755d8192011-03-02 20:07:34 -05001493static void cayman_cp_fini(struct radeon_device *rdev)
1494{
Christian König45df6802012-07-06 16:22:55 +02001495 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05001496 cayman_cp_enable(rdev, false);
Christian König45df6802012-07-06 16:22:55 +02001497 radeon_ring_fini(rdev, ring);
1498 radeon_scratch_free(rdev, ring->rptr_save_reg);
Alex Deucher755d8192011-03-02 20:07:34 -05001499}
1500
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001501static int cayman_cp_resume(struct radeon_device *rdev)
Alex Deucher0c88a022011-03-02 20:07:31 -05001502{
Christian Königb90ca982012-07-04 21:36:53 +02001503 static const int ridx[] = {
1504 RADEON_RING_TYPE_GFX_INDEX,
1505 CAYMAN_RING_TYPE_CP1_INDEX,
1506 CAYMAN_RING_TYPE_CP2_INDEX
1507 };
1508 static const unsigned cp_rb_cntl[] = {
1509 CP_RB0_CNTL,
1510 CP_RB1_CNTL,
1511 CP_RB2_CNTL,
1512 };
1513 static const unsigned cp_rb_rptr_addr[] = {
1514 CP_RB0_RPTR_ADDR,
1515 CP_RB1_RPTR_ADDR,
1516 CP_RB2_RPTR_ADDR
1517 };
1518 static const unsigned cp_rb_rptr_addr_hi[] = {
1519 CP_RB0_RPTR_ADDR_HI,
1520 CP_RB1_RPTR_ADDR_HI,
1521 CP_RB2_RPTR_ADDR_HI
1522 };
1523 static const unsigned cp_rb_base[] = {
1524 CP_RB0_BASE,
1525 CP_RB1_BASE,
1526 CP_RB2_BASE
1527 };
Christian Könige32eb502011-10-23 12:56:27 +02001528 struct radeon_ring *ring;
Christian Königb90ca982012-07-04 21:36:53 +02001529 int i, r;
Alex Deucher0c88a022011-03-02 20:07:31 -05001530
1531 /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
1532 WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
1533 SOFT_RESET_PA |
1534 SOFT_RESET_SH |
1535 SOFT_RESET_VGT |
Jerome Glissea49a50d2011-08-24 20:00:17 +00001536 SOFT_RESET_SPI |
Alex Deucher0c88a022011-03-02 20:07:31 -05001537 SOFT_RESET_SX));
1538 RREG32(GRBM_SOFT_RESET);
1539 mdelay(15);
1540 WREG32(GRBM_SOFT_RESET, 0);
1541 RREG32(GRBM_SOFT_RESET);
1542
Christian König15d33322011-09-15 19:02:22 +02001543 WREG32(CP_SEM_WAIT_TIMER, 0x0);
Alex Deucher11ef3f12012-01-20 14:47:43 -05001544 WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001545
1546 /* Set the write pointer delay */
1547 WREG32(CP_RB_WPTR_DELAY, 0);
1548
1549 WREG32(CP_DEBUG, (1 << 27));
1550
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001551 /* set the wb address whether it's enabled or not */
Alex Deucher0c88a022011-03-02 20:07:31 -05001552 WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
Christian Königb90ca982012-07-04 21:36:53 +02001553 WREG32(SCRATCH_UMSK, 0xff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001554
Christian Königb90ca982012-07-04 21:36:53 +02001555 for (i = 0; i < 3; ++i) {
1556 uint32_t rb_cntl;
1557 uint64_t addr;
1558
1559 /* Set ring buffer size */
1560 ring = &rdev->ring[ridx[i]];
1561 rb_cntl = drm_order(ring->ring_size / 8);
1562 rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
1563#ifdef __BIG_ENDIAN
1564 rb_cntl |= BUF_SWAP_32BIT;
1565#endif
1566 WREG32(cp_rb_cntl[i], rb_cntl);
1567
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001568 /* set the wb address whether it's enabled or not */
Christian Königb90ca982012-07-04 21:36:53 +02001569 addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1570 WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1571 WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
Alex Deucher0c88a022011-03-02 20:07:31 -05001572 }
1573
Christian Königb90ca982012-07-04 21:36:53 +02001574 /* set the rb base addr, this causes an internal reset of ALL rings */
1575 for (i = 0; i < 3; ++i) {
1576 ring = &rdev->ring[ridx[i]];
1577 WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1578 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001579
Christian Königb90ca982012-07-04 21:36:53 +02001580 for (i = 0; i < 3; ++i) {
1581 /* Initialize the ring buffer's read and write pointers */
1582 ring = &rdev->ring[ridx[i]];
1583 WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
Alex Deucher0c88a022011-03-02 20:07:31 -05001584
Christian Königb90ca982012-07-04 21:36:53 +02001585 ring->rptr = ring->wptr = 0;
1586 WREG32(ring->rptr_reg, ring->rptr);
1587 WREG32(ring->wptr_reg, ring->wptr);
Alex Deucher0c88a022011-03-02 20:07:31 -05001588
Christian Königb90ca982012-07-04 21:36:53 +02001589 mdelay(1);
1590 WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1591 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001592
1593 /* start the rings */
1594 cayman_cp_start(rdev);
Christian Könige32eb502011-10-23 12:56:27 +02001595 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1596 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1597 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001598 /* this only test cp0 */
Alex Deucherf7128122012-02-23 17:53:45 -05001599 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001600 if (r) {
Christian Könige32eb502011-10-23 12:56:27 +02001601 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1602 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1603 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001604 return r;
1605 }
1606
1607 return 0;
1608}
1609
Alex Deucherf60cbd12012-12-04 15:27:33 -05001610/*
1611 * DMA
1612 * Starting with R600, the GPU has an asynchronous
1613 * DMA engine. The programming model is very similar
1614 * to the 3D engine (ring buffer, IBs, etc.), but the
1615 * DMA controller has it's own packet format that is
1616 * different form the PM4 format used by the 3D engine.
1617 * It supports copying data, writing embedded data,
1618 * solid fills, and a number of other things. It also
1619 * has support for tiling/detiling of buffers.
1620 * Cayman and newer support two asynchronous DMA engines.
1621 */
1622/**
1623 * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
1624 *
1625 * @rdev: radeon_device pointer
1626 * @ib: IB object to schedule
1627 *
1628 * Schedule an IB in the DMA ring (cayman-SI).
1629 */
1630void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
1631 struct radeon_ib *ib)
1632{
1633 struct radeon_ring *ring = &rdev->ring[ib->ring];
1634
1635 if (rdev->wb.enabled) {
1636 u32 next_rptr = ring->wptr + 4;
1637 while ((next_rptr & 7) != 5)
1638 next_rptr++;
1639 next_rptr += 3;
1640 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
1641 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
1642 radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
1643 radeon_ring_write(ring, next_rptr);
1644 }
1645
1646 /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
1647 * Pad as necessary with NOPs.
1648 */
1649 while ((ring->wptr & 7) != 5)
1650 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
1651 radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0));
1652 radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
1653 radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
1654
1655}
1656
1657/**
1658 * cayman_dma_stop - stop the async dma engines
1659 *
1660 * @rdev: radeon_device pointer
1661 *
1662 * Stop the async dma engines (cayman-SI).
1663 */
1664void cayman_dma_stop(struct radeon_device *rdev)
1665{
1666 u32 rb_cntl;
1667
1668 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1669
1670 /* dma0 */
1671 rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1672 rb_cntl &= ~DMA_RB_ENABLE;
1673 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl);
1674
1675 /* dma1 */
1676 rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1677 rb_cntl &= ~DMA_RB_ENABLE;
1678 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl);
1679
1680 rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
1681 rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false;
1682}
1683
1684/**
1685 * cayman_dma_resume - setup and start the async dma engines
1686 *
1687 * @rdev: radeon_device pointer
1688 *
1689 * Set up the DMA ring buffers and enable them. (cayman-SI).
1690 * Returns 0 for success, error for failure.
1691 */
1692int cayman_dma_resume(struct radeon_device *rdev)
1693{
1694 struct radeon_ring *ring;
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001695 u32 rb_cntl, dma_cntl, ib_cntl;
Alex Deucherf60cbd12012-12-04 15:27:33 -05001696 u32 rb_bufsz;
1697 u32 reg_offset, wb_offset;
1698 int i, r;
1699
1700 /* Reset dma */
1701 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
1702 RREG32(SRBM_SOFT_RESET);
1703 udelay(50);
1704 WREG32(SRBM_SOFT_RESET, 0);
1705
1706 for (i = 0; i < 2; i++) {
1707 if (i == 0) {
1708 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
1709 reg_offset = DMA0_REGISTER_OFFSET;
1710 wb_offset = R600_WB_DMA_RPTR_OFFSET;
1711 } else {
1712 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
1713 reg_offset = DMA1_REGISTER_OFFSET;
1714 wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET;
1715 }
1716
1717 WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
1718 WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
1719
1720 /* Set ring buffer size in dwords */
1721 rb_bufsz = drm_order(ring->ring_size / 4);
1722 rb_cntl = rb_bufsz << 1;
1723#ifdef __BIG_ENDIAN
1724 rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE;
1725#endif
1726 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl);
1727
1728 /* Initialize the ring buffer's read and write pointers */
1729 WREG32(DMA_RB_RPTR + reg_offset, 0);
1730 WREG32(DMA_RB_WPTR + reg_offset, 0);
1731
1732 /* set the wb address whether it's enabled or not */
1733 WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset,
1734 upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF);
1735 WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset,
1736 ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC));
1737
1738 if (rdev->wb.enabled)
1739 rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE;
1740
1741 WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);
1742
1743 /* enable DMA IBs */
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001744 ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE;
1745#ifdef __BIG_ENDIAN
1746 ib_cntl |= DMA_IB_SWAP_ENABLE;
1747#endif
1748 WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001749
1750 dma_cntl = RREG32(DMA_CNTL + reg_offset);
1751 dma_cntl &= ~CTXEMPTY_INT_ENABLE;
1752 WREG32(DMA_CNTL + reg_offset, dma_cntl);
1753
1754 ring->wptr = 0;
1755 WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2);
1756
1757 ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2;
1758
1759 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE);
1760
1761 ring->ready = true;
1762
1763 r = radeon_ring_test(rdev, ring->idx, ring);
1764 if (r) {
1765 ring->ready = false;
1766 return r;
1767 }
1768 }
1769
1770 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1771
1772 return 0;
1773}
1774
1775/**
1776 * cayman_dma_fini - tear down the async dma engines
1777 *
1778 * @rdev: radeon_device pointer
1779 *
1780 * Stop the async dma engines and free the rings (cayman-SI).
1781 */
1782void cayman_dma_fini(struct radeon_device *rdev)
1783{
1784 cayman_dma_stop(rdev);
1785 radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
1786 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
1787}
1788
Alex Deucher168757e2013-01-18 19:17:22 -05001789static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1790{
1791 u32 reset_mask = 0;
1792 u32 tmp;
1793
1794 /* GRBM_STATUS */
1795 tmp = RREG32(GRBM_STATUS);
1796 if (tmp & (PA_BUSY | SC_BUSY |
1797 SH_BUSY | SX_BUSY |
1798 TA_BUSY | VGT_BUSY |
1799 DB_BUSY | CB_BUSY |
1800 GDS_BUSY | SPI_BUSY |
1801 IA_BUSY | IA_BUSY_NO_DMA))
1802 reset_mask |= RADEON_RESET_GFX;
1803
1804 if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1805 CP_BUSY | CP_COHERENCY_BUSY))
1806 reset_mask |= RADEON_RESET_CP;
1807
1808 if (tmp & GRBM_EE_BUSY)
1809 reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1810
1811 /* DMA_STATUS_REG 0 */
1812 tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1813 if (!(tmp & DMA_IDLE))
1814 reset_mask |= RADEON_RESET_DMA;
1815
1816 /* DMA_STATUS_REG 1 */
1817 tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1818 if (!(tmp & DMA_IDLE))
1819 reset_mask |= RADEON_RESET_DMA1;
1820
1821 /* SRBM_STATUS2 */
1822 tmp = RREG32(SRBM_STATUS2);
1823 if (tmp & DMA_BUSY)
1824 reset_mask |= RADEON_RESET_DMA;
1825
1826 if (tmp & DMA1_BUSY)
1827 reset_mask |= RADEON_RESET_DMA1;
1828
1829 /* SRBM_STATUS */
1830 tmp = RREG32(SRBM_STATUS);
1831 if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1832 reset_mask |= RADEON_RESET_RLC;
1833
1834 if (tmp & IH_BUSY)
1835 reset_mask |= RADEON_RESET_IH;
1836
1837 if (tmp & SEM_BUSY)
1838 reset_mask |= RADEON_RESET_SEM;
1839
1840 if (tmp & GRBM_RQ_PENDING)
1841 reset_mask |= RADEON_RESET_GRBM;
1842
1843 if (tmp & VMC_BUSY)
1844 reset_mask |= RADEON_RESET_VMC;
1845
1846 if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1847 MCC_BUSY | MCD_BUSY))
1848 reset_mask |= RADEON_RESET_MC;
1849
1850 if (evergreen_is_display_hung(rdev))
1851 reset_mask |= RADEON_RESET_DISPLAY;
1852
1853 /* VM_L2_STATUS */
1854 tmp = RREG32(VM_L2_STATUS);
1855 if (tmp & L2_BUSY)
1856 reset_mask |= RADEON_RESET_VMC;
1857
Alex Deucherd808fc82013-02-28 10:03:08 -05001858 /* Skip MC reset as it's mostly likely not hung, just busy */
1859 if (reset_mask & RADEON_RESET_MC) {
1860 DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1861 reset_mask &= ~RADEON_RESET_MC;
1862 }
1863
Alex Deucher168757e2013-01-18 19:17:22 -05001864 return reset_mask;
1865}
1866
1867static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
Alex Deucher271d6fe2013-01-03 12:48:05 -05001868{
1869 struct evergreen_mc_save save;
Alex Deucher187e3592013-01-18 14:51:38 -05001870 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1871 u32 tmp;
Alex Deucher19fc42e2013-01-14 11:04:39 -05001872
Alex Deucher271d6fe2013-01-03 12:48:05 -05001873 if (reset_mask == 0)
Alex Deucher168757e2013-01-18 19:17:22 -05001874 return;
Alex Deucher271d6fe2013-01-03 12:48:05 -05001875
1876 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1877
Alex Deucher187e3592013-01-18 14:51:38 -05001878 evergreen_print_gpu_status_regs(rdev);
Alex Deucher271d6fe2013-01-03 12:48:05 -05001879 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1880 RREG32(0x14F8));
1881 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1882 RREG32(0x14D8));
1883 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
1884 RREG32(0x14FC));
1885 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1886 RREG32(0x14DC));
1887
Alex Deucher187e3592013-01-18 14:51:38 -05001888 /* Disable CP parsing/prefetching */
1889 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1890
1891 if (reset_mask & RADEON_RESET_DMA) {
1892 /* dma0 */
1893 tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1894 tmp &= ~DMA_RB_ENABLE;
1895 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
Alex Deucher168757e2013-01-18 19:17:22 -05001896 }
Alex Deucher187e3592013-01-18 14:51:38 -05001897
Alex Deucher168757e2013-01-18 19:17:22 -05001898 if (reset_mask & RADEON_RESET_DMA1) {
Alex Deucher187e3592013-01-18 14:51:38 -05001899 /* dma1 */
1900 tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1901 tmp &= ~DMA_RB_ENABLE;
1902 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1903 }
1904
Alex Deucher90fb8772013-01-23 18:59:17 -05001905 udelay(50);
1906
1907 evergreen_mc_stop(rdev, &save);
1908 if (evergreen_mc_wait_for_idle(rdev)) {
1909 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1910 }
1911
Alex Deucher187e3592013-01-18 14:51:38 -05001912 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1913 grbm_soft_reset = SOFT_RESET_CB |
1914 SOFT_RESET_DB |
1915 SOFT_RESET_GDS |
1916 SOFT_RESET_PA |
1917 SOFT_RESET_SC |
1918 SOFT_RESET_SPI |
1919 SOFT_RESET_SH |
1920 SOFT_RESET_SX |
1921 SOFT_RESET_TC |
1922 SOFT_RESET_TA |
1923 SOFT_RESET_VGT |
1924 SOFT_RESET_IA;
1925 }
1926
1927 if (reset_mask & RADEON_RESET_CP) {
1928 grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1929
1930 srbm_soft_reset |= SOFT_RESET_GRBM;
1931 }
Alex Deucher271d6fe2013-01-03 12:48:05 -05001932
1933 if (reset_mask & RADEON_RESET_DMA)
Alex Deucher168757e2013-01-18 19:17:22 -05001934 srbm_soft_reset |= SOFT_RESET_DMA;
1935
1936 if (reset_mask & RADEON_RESET_DMA1)
1937 srbm_soft_reset |= SOFT_RESET_DMA1;
1938
1939 if (reset_mask & RADEON_RESET_DISPLAY)
1940 srbm_soft_reset |= SOFT_RESET_DC;
1941
1942 if (reset_mask & RADEON_RESET_RLC)
1943 srbm_soft_reset |= SOFT_RESET_RLC;
1944
1945 if (reset_mask & RADEON_RESET_SEM)
1946 srbm_soft_reset |= SOFT_RESET_SEM;
1947
1948 if (reset_mask & RADEON_RESET_IH)
1949 srbm_soft_reset |= SOFT_RESET_IH;
1950
1951 if (reset_mask & RADEON_RESET_GRBM)
1952 srbm_soft_reset |= SOFT_RESET_GRBM;
1953
1954 if (reset_mask & RADEON_RESET_VMC)
1955 srbm_soft_reset |= SOFT_RESET_VMC;
1956
Alex Deucher24178ec2013-01-24 15:00:17 -05001957 if (!(rdev->flags & RADEON_IS_IGP)) {
1958 if (reset_mask & RADEON_RESET_MC)
1959 srbm_soft_reset |= SOFT_RESET_MC;
1960 }
Alex Deucher187e3592013-01-18 14:51:38 -05001961
1962 if (grbm_soft_reset) {
1963 tmp = RREG32(GRBM_SOFT_RESET);
1964 tmp |= grbm_soft_reset;
1965 dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1966 WREG32(GRBM_SOFT_RESET, tmp);
1967 tmp = RREG32(GRBM_SOFT_RESET);
1968
1969 udelay(50);
1970
1971 tmp &= ~grbm_soft_reset;
1972 WREG32(GRBM_SOFT_RESET, tmp);
1973 tmp = RREG32(GRBM_SOFT_RESET);
1974 }
1975
1976 if (srbm_soft_reset) {
1977 tmp = RREG32(SRBM_SOFT_RESET);
1978 tmp |= srbm_soft_reset;
1979 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1980 WREG32(SRBM_SOFT_RESET, tmp);
1981 tmp = RREG32(SRBM_SOFT_RESET);
1982
1983 udelay(50);
1984
1985 tmp &= ~srbm_soft_reset;
1986 WREG32(SRBM_SOFT_RESET, tmp);
1987 tmp = RREG32(SRBM_SOFT_RESET);
1988 }
Alex Deucher271d6fe2013-01-03 12:48:05 -05001989
1990 /* Wait a little for things to settle down */
1991 udelay(50);
1992
Alex Deucherb9952a82011-03-02 20:07:33 -05001993 evergreen_mc_resume(rdev, &save);
Alex Deucher187e3592013-01-18 14:51:38 -05001994 udelay(50);
Alex Deucher410a3412013-01-18 13:05:39 -05001995
Alex Deucher187e3592013-01-18 14:51:38 -05001996 evergreen_print_gpu_status_regs(rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -05001997}
1998
1999int cayman_asic_reset(struct radeon_device *rdev)
2000{
Alex Deucher168757e2013-01-18 19:17:22 -05002001 u32 reset_mask;
2002
2003 reset_mask = cayman_gpu_check_soft_reset(rdev);
2004
2005 if (reset_mask)
2006 r600_set_bios_scratch_engine_hung(rdev, true);
2007
2008 cayman_gpu_soft_reset(rdev, reset_mask);
2009
2010 reset_mask = cayman_gpu_check_soft_reset(rdev);
2011
2012 if (!reset_mask)
2013 r600_set_bios_scratch_engine_hung(rdev, false);
2014
2015 return 0;
Alex Deucherb9952a82011-03-02 20:07:33 -05002016}
2017
Alex Deucherf60cbd12012-12-04 15:27:33 -05002018/**
Alex Deucher123bc182013-01-24 11:37:19 -05002019 * cayman_gfx_is_lockup - Check if the GFX engine is locked up
2020 *
2021 * @rdev: radeon_device pointer
2022 * @ring: radeon_ring structure holding ring information
2023 *
2024 * Check if the GFX engine is locked up.
2025 * Returns true if the engine appears to be locked up, false if not.
2026 */
2027bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2028{
2029 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2030
2031 if (!(reset_mask & (RADEON_RESET_GFX |
2032 RADEON_RESET_COMPUTE |
2033 RADEON_RESET_CP))) {
2034 radeon_ring_lockup_update(ring);
2035 return false;
2036 }
2037 /* force CP activities */
2038 radeon_ring_force_activity(rdev, ring);
2039 return radeon_ring_test_lockup(rdev, ring);
2040}
2041
2042/**
Alex Deucherf60cbd12012-12-04 15:27:33 -05002043 * cayman_dma_is_lockup - Check if the DMA engine is locked up
2044 *
2045 * @rdev: radeon_device pointer
2046 * @ring: radeon_ring structure holding ring information
2047 *
Alex Deucher123bc182013-01-24 11:37:19 -05002048 * Check if the async DMA engine is locked up.
Alex Deucherf60cbd12012-12-04 15:27:33 -05002049 * Returns true if the engine appears to be locked up, false if not.
2050 */
2051bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2052{
Alex Deucher123bc182013-01-24 11:37:19 -05002053 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2054 u32 mask;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002055
2056 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
Alex Deucher123bc182013-01-24 11:37:19 -05002057 mask = RADEON_RESET_DMA;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002058 else
Alex Deucher123bc182013-01-24 11:37:19 -05002059 mask = RADEON_RESET_DMA1;
2060
2061 if (!(reset_mask & mask)) {
Alex Deucherf60cbd12012-12-04 15:27:33 -05002062 radeon_ring_lockup_update(ring);
2063 return false;
2064 }
2065 /* force ring activities */
2066 radeon_ring_force_activity(rdev, ring);
2067 return radeon_ring_test_lockup(rdev, ring);
2068}
2069
Alex Deucher755d8192011-03-02 20:07:34 -05002070static int cayman_startup(struct radeon_device *rdev)
2071{
Christian Könige32eb502011-10-23 12:56:27 +02002072 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002073 int r;
2074
Ilija Hadzicb07759b2011-09-20 10:22:58 -04002075 /* enable pcie gen2 link */
2076 evergreen_pcie_gen2_enable(rdev);
2077
Alex Deucherc420c742012-03-20 17:18:39 -04002078 if (rdev->flags & RADEON_IS_IGP) {
2079 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
2080 r = ni_init_microcode(rdev);
2081 if (r) {
2082 DRM_ERROR("Failed to load firmware!\n");
2083 return r;
2084 }
2085 }
2086 } else {
2087 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
2088 r = ni_init_microcode(rdev);
2089 if (r) {
2090 DRM_ERROR("Failed to load firmware!\n");
2091 return r;
2092 }
2093 }
2094
2095 r = ni_mc_load_microcode(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002096 if (r) {
Alex Deucherc420c742012-03-20 17:18:39 -04002097 DRM_ERROR("Failed to load MC firmware!\n");
Alex Deucher755d8192011-03-02 20:07:34 -05002098 return r;
2099 }
2100 }
Alex Deucher755d8192011-03-02 20:07:34 -05002101
Alex Deucher16cdf042011-10-28 10:30:02 -04002102 r = r600_vram_scratch_init(rdev);
2103 if (r)
2104 return r;
2105
Alex Deucher755d8192011-03-02 20:07:34 -05002106 evergreen_mc_program(rdev);
2107 r = cayman_pcie_gart_enable(rdev);
2108 if (r)
2109 return r;
2110 cayman_gpu_init(rdev);
2111
Alex Deuchercb92d452011-05-25 16:39:00 -04002112 r = evergreen_blit_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002113 if (r) {
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002114 r600_blit_fini(rdev);
Alex Deucher27cd7762012-02-23 17:53:42 -05002115 rdev->asic->copy.copy = NULL;
Alex Deucher755d8192011-03-02 20:07:34 -05002116 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
2117 }
Alex Deucher755d8192011-03-02 20:07:34 -05002118
Alex Deucherc420c742012-03-20 17:18:39 -04002119 /* allocate rlc buffers */
2120 if (rdev->flags & RADEON_IS_IGP) {
Alex Deucher2948f5e2013-04-12 13:52:52 -04002121 rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
2122 rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size;
2123 rdev->rlc.cs_data = cayman_cs_data;
2124 r = sumo_rlc_init(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002125 if (r) {
2126 DRM_ERROR("Failed to init rlc BOs!\n");
2127 return r;
2128 }
2129 }
2130
Alex Deucher755d8192011-03-02 20:07:34 -05002131 /* allocate wb buffer */
2132 r = radeon_wb_init(rdev);
2133 if (r)
2134 return r;
2135
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002136 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
2137 if (r) {
2138 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2139 return r;
2140 }
2141
Christian Königf2ba57b2013-04-08 12:41:29 +02002142 r = rv770_uvd_resume(rdev);
2143 if (!r) {
2144 r = radeon_fence_driver_start_ring(rdev,
2145 R600_RING_TYPE_UVD_INDEX);
2146 if (r)
2147 dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2148 }
2149 if (r)
2150 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2151
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002152 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
2153 if (r) {
2154 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2155 return r;
2156 }
2157
2158 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
2159 if (r) {
2160 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2161 return r;
2162 }
2163
Alex Deucherf60cbd12012-12-04 15:27:33 -05002164 r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2165 if (r) {
2166 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2167 return r;
2168 }
2169
2170 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2171 if (r) {
2172 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2173 return r;
2174 }
2175
Alex Deucher755d8192011-03-02 20:07:34 -05002176 /* Enable IRQ */
Adis Hamziće49f3952013-06-02 16:47:54 +02002177 if (!rdev->irq.installed) {
2178 r = radeon_irq_kms_init(rdev);
2179 if (r)
2180 return r;
2181 }
2182
Alex Deucher755d8192011-03-02 20:07:34 -05002183 r = r600_irq_init(rdev);
2184 if (r) {
2185 DRM_ERROR("radeon: IH init failed (%d).\n", r);
2186 radeon_irq_kms_fini(rdev);
2187 return r;
2188 }
2189 evergreen_irq_set(rdev);
2190
Christian Könige32eb502011-10-23 12:56:27 +02002191 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
Alex Deucher78c55602011-11-17 14:25:56 -05002192 CP_RB0_RPTR, CP_RB0_WPTR,
2193 0, 0xfffff, RADEON_CP_PACKET2);
Alex Deucher755d8192011-03-02 20:07:34 -05002194 if (r)
2195 return r;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002196
2197 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2198 r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
2199 DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
2200 DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
2201 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2202 if (r)
2203 return r;
2204
2205 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2206 r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
2207 DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
2208 DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
2209 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2210 if (r)
2211 return r;
2212
Alex Deucher755d8192011-03-02 20:07:34 -05002213 r = cayman_cp_load_microcode(rdev);
2214 if (r)
2215 return r;
2216 r = cayman_cp_resume(rdev);
2217 if (r)
2218 return r;
2219
Alex Deucherf60cbd12012-12-04 15:27:33 -05002220 r = cayman_dma_resume(rdev);
2221 if (r)
2222 return r;
2223
Christian Königf2ba57b2013-04-08 12:41:29 +02002224 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2225 if (ring->ring_size) {
2226 r = radeon_ring_init(rdev, ring, ring->ring_size,
2227 R600_WB_UVD_RPTR_OFFSET,
2228 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2229 0, 0xfffff, RADEON_CP_PACKET2);
2230 if (!r)
2231 r = r600_uvd_init(rdev);
2232 if (r)
2233 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2234 }
2235
Christian König2898c342012-07-05 11:55:34 +02002236 r = radeon_ib_pool_init(rdev);
2237 if (r) {
2238 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisseb15ba512011-11-15 11:48:34 -05002239 return r;
Christian König2898c342012-07-05 11:55:34 +02002240 }
Jerome Glisseb15ba512011-11-15 11:48:34 -05002241
Christian Königc6105f22012-07-05 14:32:00 +02002242 r = radeon_vm_manager_init(rdev);
2243 if (r) {
2244 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
Jerome Glisse721604a2012-01-05 22:11:05 -05002245 return r;
Christian Königc6105f22012-07-05 14:32:00 +02002246 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002247
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002248 r = r600_audio_init(rdev);
2249 if (r)
2250 return r;
2251
Alex Deucher755d8192011-03-02 20:07:34 -05002252 return 0;
2253}
2254
2255int cayman_resume(struct radeon_device *rdev)
2256{
2257 int r;
2258
2259 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2260 * posting will perform necessary task to bring back GPU into good
2261 * shape.
2262 */
2263 /* post card */
2264 atom_asic_init(rdev->mode_info.atom_context);
2265
Alex Deuchera2c96a22013-02-28 17:58:36 -05002266 /* init golden registers */
2267 ni_init_golden_registers(rdev);
2268
Jerome Glisseb15ba512011-11-15 11:48:34 -05002269 rdev->accel_working = true;
Alex Deucher755d8192011-03-02 20:07:34 -05002270 r = cayman_startup(rdev);
2271 if (r) {
2272 DRM_ERROR("cayman startup failed on resume\n");
Jerome Glisse6b7746e2012-02-20 17:57:20 -05002273 rdev->accel_working = false;
Alex Deucher755d8192011-03-02 20:07:34 -05002274 return r;
2275 }
Alex Deucher755d8192011-03-02 20:07:34 -05002276 return r;
Alex Deucher755d8192011-03-02 20:07:34 -05002277}
2278
2279int cayman_suspend(struct radeon_device *rdev)
2280{
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002281 r600_audio_fini(rdev);
Alex Deucherfa3daf92013-03-11 15:32:26 -04002282 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002283 cayman_cp_enable(rdev, false);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002284 cayman_dma_stop(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002285 r600_uvd_rbc_stop(rdev);
2286 radeon_uvd_suspend(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002287 evergreen_irq_suspend(rdev);
2288 radeon_wb_disable(rdev);
2289 cayman_pcie_gart_disable(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002290 return 0;
2291}
2292
2293/* Plan is to move initialization in that function and use
2294 * helper function so that radeon_device_init pretty much
2295 * do nothing more than calling asic specific function. This
2296 * should also allow to remove a bunch of callback function
2297 * like vram_info.
2298 */
2299int cayman_init(struct radeon_device *rdev)
2300{
Christian Könige32eb502011-10-23 12:56:27 +02002301 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002302 int r;
2303
Alex Deucher755d8192011-03-02 20:07:34 -05002304 /* Read BIOS */
2305 if (!radeon_get_bios(rdev)) {
2306 if (ASIC_IS_AVIVO(rdev))
2307 return -EINVAL;
2308 }
2309 /* Must be an ATOMBIOS */
2310 if (!rdev->is_atom_bios) {
2311 dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2312 return -EINVAL;
2313 }
2314 r = radeon_atombios_init(rdev);
2315 if (r)
2316 return r;
2317
2318 /* Post card if necessary */
2319 if (!radeon_card_posted(rdev)) {
2320 if (!rdev->bios) {
2321 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2322 return -EINVAL;
2323 }
2324 DRM_INFO("GPU not posted. posting now...\n");
2325 atom_asic_init(rdev->mode_info.atom_context);
2326 }
Alex Deuchera2c96a22013-02-28 17:58:36 -05002327 /* init golden registers */
2328 ni_init_golden_registers(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002329 /* Initialize scratch registers */
2330 r600_scratch_init(rdev);
2331 /* Initialize surface registers */
2332 radeon_surface_init(rdev);
2333 /* Initialize clocks */
2334 radeon_get_clock_info(rdev->ddev);
2335 /* Fence driver */
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002336 r = radeon_fence_driver_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002337 if (r)
2338 return r;
2339 /* initialize memory controller */
2340 r = evergreen_mc_init(rdev);
2341 if (r)
2342 return r;
2343 /* Memory manager */
2344 r = radeon_bo_init(rdev);
2345 if (r)
2346 return r;
2347
Christian Könige32eb502011-10-23 12:56:27 +02002348 ring->ring_obj = NULL;
2349 r600_ring_init(rdev, ring, 1024 * 1024);
Alex Deucher755d8192011-03-02 20:07:34 -05002350
Alex Deucherf60cbd12012-12-04 15:27:33 -05002351 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2352 ring->ring_obj = NULL;
2353 r600_ring_init(rdev, ring, 64 * 1024);
2354
2355 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2356 ring->ring_obj = NULL;
2357 r600_ring_init(rdev, ring, 64 * 1024);
2358
Christian Königf2ba57b2013-04-08 12:41:29 +02002359 r = radeon_uvd_init(rdev);
2360 if (!r) {
2361 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2362 ring->ring_obj = NULL;
2363 r600_ring_init(rdev, ring, 4096);
2364 }
2365
Alex Deucher755d8192011-03-02 20:07:34 -05002366 rdev->ih.ring_obj = NULL;
2367 r600_ih_ring_init(rdev, 64 * 1024);
2368
2369 r = r600_pcie_gart_init(rdev);
2370 if (r)
2371 return r;
2372
2373 rdev->accel_working = true;
2374 r = cayman_startup(rdev);
2375 if (r) {
2376 dev_err(rdev->dev, "disabling GPU acceleration\n");
2377 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002378 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002379 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002380 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher2948f5e2013-04-12 13:52:52 -04002381 sumo_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002382 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002383 radeon_ib_pool_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002384 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002385 radeon_irq_kms_fini(rdev);
2386 cayman_pcie_gart_fini(rdev);
2387 rdev->accel_working = false;
2388 }
Alex Deucher755d8192011-03-02 20:07:34 -05002389
2390 /* Don't start up if the MC ucode is missing.
2391 * The default clocks and voltages before the MC ucode
2392 * is loaded are not suffient for advanced operations.
Alex Deucherc420c742012-03-20 17:18:39 -04002393 *
2394 * We can skip this check for TN, because there is no MC
2395 * ucode.
Alex Deucher755d8192011-03-02 20:07:34 -05002396 */
Alex Deucherc420c742012-03-20 17:18:39 -04002397 if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
Alex Deucher755d8192011-03-02 20:07:34 -05002398 DRM_ERROR("radeon: MC ucode required for NI+.\n");
2399 return -EINVAL;
2400 }
2401
2402 return 0;
2403}
2404
2405void cayman_fini(struct radeon_device *rdev)
2406{
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002407 r600_blit_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002408 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002409 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002410 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002411 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher2948f5e2013-04-12 13:52:52 -04002412 sumo_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002413 radeon_wb_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002414 radeon_vm_manager_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002415 radeon_ib_pool_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002416 radeon_irq_kms_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002417 radeon_uvd_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002418 cayman_pcie_gart_fini(rdev);
Alex Deucher16cdf042011-10-28 10:30:02 -04002419 r600_vram_scratch_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002420 radeon_gem_fini(rdev);
2421 radeon_fence_driver_fini(rdev);
2422 radeon_bo_fini(rdev);
2423 radeon_atombios_fini(rdev);
2424 kfree(rdev->bios);
2425 rdev->bios = NULL;
2426}
2427
Jerome Glisse721604a2012-01-05 22:11:05 -05002428/*
2429 * vm
2430 */
2431int cayman_vm_init(struct radeon_device *rdev)
2432{
2433 /* number of VMs */
2434 rdev->vm_manager.nvm = 8;
2435 /* base offset of vram pages */
Alex Deuchere71270f2012-03-20 17:18:38 -04002436 if (rdev->flags & RADEON_IS_IGP) {
2437 u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2438 tmp <<= 22;
2439 rdev->vm_manager.vram_base_offset = tmp;
2440 } else
2441 rdev->vm_manager.vram_base_offset = 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002442 return 0;
2443}
2444
2445void cayman_vm_fini(struct radeon_device *rdev)
2446{
2447}
2448
Christian Königdce34bf2012-09-17 19:36:18 +02002449#define R600_ENTRY_VALID (1 << 0)
Jerome Glisse721604a2012-01-05 22:11:05 -05002450#define R600_PTE_SYSTEM (1 << 1)
2451#define R600_PTE_SNOOPED (1 << 2)
2452#define R600_PTE_READABLE (1 << 5)
2453#define R600_PTE_WRITEABLE (1 << 6)
2454
Christian König089a7862012-08-11 11:54:05 +02002455uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002456{
2457 uint32_t r600_flags = 0;
Christian Königdce34bf2012-09-17 19:36:18 +02002458 r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002459 r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
2460 r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
2461 if (flags & RADEON_VM_PAGE_SYSTEM) {
2462 r600_flags |= R600_PTE_SYSTEM;
2463 r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0;
2464 }
2465 return r600_flags;
2466}
2467
Alex Deucher7a083292012-08-31 13:51:21 -04002468/**
2469 * cayman_vm_set_page - update the page tables using the CP
2470 *
2471 * @rdev: radeon_device pointer
Alex Deucher43f12142013-02-01 17:32:42 +01002472 * @ib: indirect buffer to fill with commands
Christian Königdce34bf2012-09-17 19:36:18 +02002473 * @pe: addr of the page entry
2474 * @addr: dst addr to write into pe
2475 * @count: number of page entries to update
2476 * @incr: increase next addr by incr bytes
2477 * @flags: access flags
Alex Deucher7a083292012-08-31 13:51:21 -04002478 *
Alex Deucher43f12142013-02-01 17:32:42 +01002479 * Update the page tables using the CP (cayman/TN).
Alex Deucher7a083292012-08-31 13:51:21 -04002480 */
Alex Deucher43f12142013-02-01 17:32:42 +01002481void cayman_vm_set_page(struct radeon_device *rdev,
2482 struct radeon_ib *ib,
2483 uint64_t pe,
Christian Königdce34bf2012-09-17 19:36:18 +02002484 uint64_t addr, unsigned count,
2485 uint32_t incr, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002486{
Christian Königdce34bf2012-09-17 19:36:18 +02002487 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002488 uint64_t value;
2489 unsigned ndw;
Jerome Glisse721604a2012-01-05 22:11:05 -05002490
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002491 if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
2492 while (count) {
2493 ndw = 1 + count * 2;
2494 if (ndw > 0x3FFF)
2495 ndw = 0x3FFF;
Christian König089a7862012-08-11 11:54:05 +02002496
Alex Deucher43f12142013-02-01 17:32:42 +01002497 ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw);
2498 ib->ptr[ib->length_dw++] = pe;
2499 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002500 for (; ndw > 1; ndw -= 2, --count, pe += 8) {
2501 if (flags & RADEON_VM_PAGE_SYSTEM) {
2502 value = radeon_vm_map_gart(rdev, addr);
2503 value &= 0xFFFFFFFFFFFFF000ULL;
2504 } else if (flags & RADEON_VM_PAGE_VALID) {
2505 value = addr;
2506 } else {
2507 value = 0;
2508 }
Christian Königf9fdffa2012-10-22 17:42:36 +02002509 addr += incr;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002510 value |= r600_flags;
Alex Deucher43f12142013-02-01 17:32:42 +01002511 ib->ptr[ib->length_dw++] = value;
2512 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Christian Königf9fdffa2012-10-22 17:42:36 +02002513 }
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002514 }
2515 } else {
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002516 if ((flags & RADEON_VM_PAGE_SYSTEM) ||
2517 (count == 1)) {
2518 while (count) {
2519 ndw = count * 2;
2520 if (ndw > 0xFFFFE)
2521 ndw = 0xFFFFE;
Christian Königf9fdffa2012-10-22 17:42:36 +02002522
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002523 /* for non-physically contiguous pages (system) */
2524 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
2525 ib->ptr[ib->length_dw++] = pe;
2526 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2527 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2528 if (flags & RADEON_VM_PAGE_SYSTEM) {
2529 value = radeon_vm_map_gart(rdev, addr);
2530 value &= 0xFFFFFFFFFFFFF000ULL;
2531 } else if (flags & RADEON_VM_PAGE_VALID) {
2532 value = addr;
2533 } else {
2534 value = 0;
2535 }
2536 addr += incr;
2537 value |= r600_flags;
2538 ib->ptr[ib->length_dw++] = value;
2539 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002540 }
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002541 }
2542 while (ib->length_dw & 0x7)
2543 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
2544 } else {
2545 while (count) {
2546 ndw = count * 2;
2547 if (ndw > 0xFFFFE)
2548 ndw = 0xFFFFE;
2549
2550 if (flags & RADEON_VM_PAGE_VALID)
2551 value = addr;
2552 else
2553 value = 0;
2554 /* for physically contiguous pages (vram) */
2555 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
2556 ib->ptr[ib->length_dw++] = pe; /* dst addr */
2557 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2558 ib->ptr[ib->length_dw++] = r600_flags; /* mask */
2559 ib->ptr[ib->length_dw++] = 0;
2560 ib->ptr[ib->length_dw++] = value; /* value */
Alex Deucher43f12142013-02-01 17:32:42 +01002561 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002562 ib->ptr[ib->length_dw++] = incr; /* increment size */
2563 ib->ptr[ib->length_dw++] = 0;
2564 pe += ndw * 4;
2565 addr += (ndw / 2) * incr;
2566 count -= ndw / 2;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002567 }
Christian König2a6f1ab2012-08-11 15:00:30 +02002568 }
Alex Deucher43f12142013-02-01 17:32:42 +01002569 while (ib->length_dw & 0x7)
2570 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
Christian König2a6f1ab2012-08-11 15:00:30 +02002571 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002572}
Christian König9b40e5d2012-08-08 12:22:43 +02002573
Alex Deucher7a083292012-08-31 13:51:21 -04002574/**
2575 * cayman_vm_flush - vm flush using the CP
2576 *
2577 * @rdev: radeon_device pointer
2578 *
2579 * Update the page table base and flush the VM TLB
2580 * using the CP (cayman-si).
2581 */
Alex Deucher498522b2012-10-02 14:43:38 -04002582void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
Christian König9b40e5d2012-08-08 12:22:43 +02002583{
Alex Deucher498522b2012-10-02 14:43:38 -04002584 struct radeon_ring *ring = &rdev->ring[ridx];
Christian König9b40e5d2012-08-08 12:22:43 +02002585
Christian Königee60e292012-08-09 16:21:08 +02002586 if (vm == NULL)
Christian König9b40e5d2012-08-08 12:22:43 +02002587 return;
2588
Christian Königee60e292012-08-09 16:21:08 +02002589 radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02002590 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
Christian Königee60e292012-08-09 16:21:08 +02002591
Christian König9b40e5d2012-08-08 12:22:43 +02002592 /* flush hdp cache */
2593 radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
2594 radeon_ring_write(ring, 0x1);
2595
2596 /* bits 0-7 are the VM contexts0-7 */
2597 radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
Alex Deucher498522b2012-10-02 14:43:38 -04002598 radeon_ring_write(ring, 1 << vm->id);
Christian König58f8cf52012-10-22 17:42:35 +02002599
2600 /* sync PFP to ME, otherwise we might get invalid PFP reads */
2601 radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2602 radeon_ring_write(ring, 0x0);
Alex Deucher0af62b02011-01-06 21:19:31 -05002603}
Alex Deucherf60cbd12012-12-04 15:27:33 -05002604
2605void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
2606{
2607 struct radeon_ring *ring = &rdev->ring[ridx];
2608
2609 if (vm == NULL)
2610 return;
2611
2612 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2613 radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2));
2614 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
2615
2616 /* flush hdp cache */
2617 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2618 radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
2619 radeon_ring_write(ring, 1);
2620
2621 /* bits 0-7 are the VM contexts0-7 */
2622 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2623 radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
2624 radeon_ring_write(ring, 1 << vm->id);
2625}
2626