blob: cafc3bd78a384927415bd7808d7da6afacefd8eb [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 Deucherf52382d2013-02-15 11:02:50 -0500176extern void evergreen_program_aspm(struct radeon_device *rdev);
Alex Deucher2948f5e2013-04-12 13:52:52 -0400177extern void sumo_rlc_fini(struct radeon_device *rdev);
178extern int sumo_rlc_init(struct radeon_device *rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -0500179
Alex Deucher0af62b02011-01-06 21:19:31 -0500180/* Firmware Names */
181MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
182MODULE_FIRMWARE("radeon/BARTS_me.bin");
183MODULE_FIRMWARE("radeon/BARTS_mc.bin");
Alex Deucher6596afd2013-06-26 00:15:24 -0400184MODULE_FIRMWARE("radeon/BARTS_smc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500185MODULE_FIRMWARE("radeon/BTC_rlc.bin");
186MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
187MODULE_FIRMWARE("radeon/TURKS_me.bin");
188MODULE_FIRMWARE("radeon/TURKS_mc.bin");
Alex Deucher6596afd2013-06-26 00:15:24 -0400189MODULE_FIRMWARE("radeon/TURKS_smc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500190MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
191MODULE_FIRMWARE("radeon/CAICOS_me.bin");
192MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
Alex Deucher6596afd2013-06-26 00:15:24 -0400193MODULE_FIRMWARE("radeon/CAICOS_smc.bin");
Alex Deucher9b8253c2011-03-02 20:07:28 -0500194MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
195MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
196MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
197MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
Alex Deucher69e0b572013-04-12 16:42:42 -0400198MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
Alex Deucherc420c742012-03-20 17:18:39 -0400199MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
200MODULE_FIRMWARE("radeon/ARUBA_me.bin");
201MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -0500202
Alex Deuchera2c96a22013-02-28 17:58:36 -0500203
204static const u32 cayman_golden_registers2[] =
205{
206 0x3e5c, 0xffffffff, 0x00000000,
207 0x3e48, 0xffffffff, 0x00000000,
208 0x3e4c, 0xffffffff, 0x00000000,
209 0x3e64, 0xffffffff, 0x00000000,
210 0x3e50, 0xffffffff, 0x00000000,
211 0x3e60, 0xffffffff, 0x00000000
212};
213
214static const u32 cayman_golden_registers[] =
215{
216 0x5eb4, 0xffffffff, 0x00000002,
217 0x5e78, 0x8f311ff1, 0x001000f0,
218 0x3f90, 0xffff0000, 0xff000000,
219 0x9148, 0xffff0000, 0xff000000,
220 0x3f94, 0xffff0000, 0xff000000,
221 0x914c, 0xffff0000, 0xff000000,
222 0xc78, 0x00000080, 0x00000080,
223 0xbd4, 0x70073777, 0x00011003,
224 0xd02c, 0xbfffff1f, 0x08421000,
225 0xd0b8, 0x73773777, 0x02011003,
226 0x5bc0, 0x00200000, 0x50100000,
227 0x98f8, 0x33773777, 0x02011003,
228 0x98fc, 0xffffffff, 0x76541032,
229 0x7030, 0x31000311, 0x00000011,
230 0x2f48, 0x33773777, 0x42010001,
231 0x6b28, 0x00000010, 0x00000012,
232 0x7728, 0x00000010, 0x00000012,
233 0x10328, 0x00000010, 0x00000012,
234 0x10f28, 0x00000010, 0x00000012,
235 0x11b28, 0x00000010, 0x00000012,
236 0x12728, 0x00000010, 0x00000012,
237 0x240c, 0x000007ff, 0x00000000,
238 0x8a14, 0xf000001f, 0x00000007,
239 0x8b24, 0x3fff3fff, 0x00ff0fff,
240 0x8b10, 0x0000ff0f, 0x00000000,
241 0x28a4c, 0x07ffffff, 0x06000000,
242 0x10c, 0x00000001, 0x00010003,
243 0xa02c, 0xffffffff, 0x0000009b,
244 0x913c, 0x0000010f, 0x01000100,
245 0x8c04, 0xf8ff00ff, 0x40600060,
246 0x28350, 0x00000f01, 0x00000000,
247 0x9508, 0x3700001f, 0x00000002,
248 0x960c, 0xffffffff, 0x54763210,
249 0x88c4, 0x001f3ae3, 0x00000082,
250 0x88d0, 0xffffffff, 0x0f40df40,
251 0x88d4, 0x0000001f, 0x00000010,
252 0x8974, 0xffffffff, 0x00000000
253};
254
255static const u32 dvst_golden_registers2[] =
256{
257 0x8f8, 0xffffffff, 0,
258 0x8fc, 0x00380000, 0,
259 0x8f8, 0xffffffff, 1,
260 0x8fc, 0x0e000000, 0
261};
262
263static const u32 dvst_golden_registers[] =
264{
265 0x690, 0x3fff3fff, 0x20c00033,
266 0x918c, 0x0fff0fff, 0x00010006,
267 0x91a8, 0x0fff0fff, 0x00010006,
268 0x9150, 0xffffdfff, 0x6e944040,
269 0x917c, 0x0fff0fff, 0x00030002,
270 0x9198, 0x0fff0fff, 0x00030002,
271 0x915c, 0x0fff0fff, 0x00010000,
272 0x3f90, 0xffff0001, 0xff000000,
273 0x9178, 0x0fff0fff, 0x00070000,
274 0x9194, 0x0fff0fff, 0x00070000,
275 0x9148, 0xffff0001, 0xff000000,
276 0x9190, 0x0fff0fff, 0x00090008,
277 0x91ac, 0x0fff0fff, 0x00090008,
278 0x3f94, 0xffff0000, 0xff000000,
279 0x914c, 0xffff0000, 0xff000000,
280 0x929c, 0x00000fff, 0x00000001,
281 0x55e4, 0xff607fff, 0xfc000100,
282 0x8a18, 0xff000fff, 0x00000100,
283 0x8b28, 0xff000fff, 0x00000100,
284 0x9144, 0xfffc0fff, 0x00000100,
285 0x6ed8, 0x00010101, 0x00010000,
286 0x9830, 0xffffffff, 0x00000000,
287 0x9834, 0xf00fffff, 0x00000400,
288 0x9838, 0xfffffffe, 0x00000000,
289 0xd0c0, 0xff000fff, 0x00000100,
290 0xd02c, 0xbfffff1f, 0x08421000,
291 0xd0b8, 0x73773777, 0x12010001,
292 0x5bb0, 0x000000f0, 0x00000070,
293 0x98f8, 0x73773777, 0x12010001,
294 0x98fc, 0xffffffff, 0x00000010,
295 0x9b7c, 0x00ff0000, 0x00fc0000,
296 0x8030, 0x00001f0f, 0x0000100a,
297 0x2f48, 0x73773777, 0x12010001,
298 0x2408, 0x00030000, 0x000c007f,
299 0x8a14, 0xf000003f, 0x00000007,
300 0x8b24, 0x3fff3fff, 0x00ff0fff,
301 0x8b10, 0x0000ff0f, 0x00000000,
302 0x28a4c, 0x07ffffff, 0x06000000,
303 0x4d8, 0x00000fff, 0x00000100,
304 0xa008, 0xffffffff, 0x00010000,
305 0x913c, 0xffff03ff, 0x01000100,
306 0x8c00, 0x000000ff, 0x00000003,
307 0x8c04, 0xf8ff00ff, 0x40600060,
308 0x8cf0, 0x1fff1fff, 0x08e00410,
309 0x28350, 0x00000f01, 0x00000000,
310 0x9508, 0xf700071f, 0x00000002,
311 0x960c, 0xffffffff, 0x54763210,
312 0x20ef8, 0x01ff01ff, 0x00000002,
313 0x20e98, 0xfffffbff, 0x00200000,
314 0x2015c, 0xffffffff, 0x00000f40,
315 0x88c4, 0x001f3ae3, 0x00000082,
316 0x8978, 0x3fffffff, 0x04050140,
317 0x88d4, 0x0000001f, 0x00000010,
318 0x8974, 0xffffffff, 0x00000000
319};
320
321static const u32 scrapper_golden_registers[] =
322{
323 0x690, 0x3fff3fff, 0x20c00033,
324 0x918c, 0x0fff0fff, 0x00010006,
325 0x918c, 0x0fff0fff, 0x00010006,
326 0x91a8, 0x0fff0fff, 0x00010006,
327 0x91a8, 0x0fff0fff, 0x00010006,
328 0x9150, 0xffffdfff, 0x6e944040,
329 0x9150, 0xffffdfff, 0x6e944040,
330 0x917c, 0x0fff0fff, 0x00030002,
331 0x917c, 0x0fff0fff, 0x00030002,
332 0x9198, 0x0fff0fff, 0x00030002,
333 0x9198, 0x0fff0fff, 0x00030002,
334 0x915c, 0x0fff0fff, 0x00010000,
335 0x915c, 0x0fff0fff, 0x00010000,
336 0x3f90, 0xffff0001, 0xff000000,
337 0x3f90, 0xffff0001, 0xff000000,
338 0x9178, 0x0fff0fff, 0x00070000,
339 0x9178, 0x0fff0fff, 0x00070000,
340 0x9194, 0x0fff0fff, 0x00070000,
341 0x9194, 0x0fff0fff, 0x00070000,
342 0x9148, 0xffff0001, 0xff000000,
343 0x9148, 0xffff0001, 0xff000000,
344 0x9190, 0x0fff0fff, 0x00090008,
345 0x9190, 0x0fff0fff, 0x00090008,
346 0x91ac, 0x0fff0fff, 0x00090008,
347 0x91ac, 0x0fff0fff, 0x00090008,
348 0x3f94, 0xffff0000, 0xff000000,
349 0x3f94, 0xffff0000, 0xff000000,
350 0x914c, 0xffff0000, 0xff000000,
351 0x914c, 0xffff0000, 0xff000000,
352 0x929c, 0x00000fff, 0x00000001,
353 0x929c, 0x00000fff, 0x00000001,
354 0x55e4, 0xff607fff, 0xfc000100,
355 0x8a18, 0xff000fff, 0x00000100,
356 0x8a18, 0xff000fff, 0x00000100,
357 0x8b28, 0xff000fff, 0x00000100,
358 0x8b28, 0xff000fff, 0x00000100,
359 0x9144, 0xfffc0fff, 0x00000100,
360 0x9144, 0xfffc0fff, 0x00000100,
361 0x6ed8, 0x00010101, 0x00010000,
362 0x9830, 0xffffffff, 0x00000000,
363 0x9830, 0xffffffff, 0x00000000,
364 0x9834, 0xf00fffff, 0x00000400,
365 0x9834, 0xf00fffff, 0x00000400,
366 0x9838, 0xfffffffe, 0x00000000,
367 0x9838, 0xfffffffe, 0x00000000,
368 0xd0c0, 0xff000fff, 0x00000100,
369 0xd02c, 0xbfffff1f, 0x08421000,
370 0xd02c, 0xbfffff1f, 0x08421000,
371 0xd0b8, 0x73773777, 0x12010001,
372 0xd0b8, 0x73773777, 0x12010001,
373 0x5bb0, 0x000000f0, 0x00000070,
374 0x98f8, 0x73773777, 0x12010001,
375 0x98f8, 0x73773777, 0x12010001,
376 0x98fc, 0xffffffff, 0x00000010,
377 0x98fc, 0xffffffff, 0x00000010,
378 0x9b7c, 0x00ff0000, 0x00fc0000,
379 0x9b7c, 0x00ff0000, 0x00fc0000,
380 0x8030, 0x00001f0f, 0x0000100a,
381 0x8030, 0x00001f0f, 0x0000100a,
382 0x2f48, 0x73773777, 0x12010001,
383 0x2f48, 0x73773777, 0x12010001,
384 0x2408, 0x00030000, 0x000c007f,
385 0x8a14, 0xf000003f, 0x00000007,
386 0x8a14, 0xf000003f, 0x00000007,
387 0x8b24, 0x3fff3fff, 0x00ff0fff,
388 0x8b24, 0x3fff3fff, 0x00ff0fff,
389 0x8b10, 0x0000ff0f, 0x00000000,
390 0x8b10, 0x0000ff0f, 0x00000000,
391 0x28a4c, 0x07ffffff, 0x06000000,
392 0x28a4c, 0x07ffffff, 0x06000000,
393 0x4d8, 0x00000fff, 0x00000100,
394 0x4d8, 0x00000fff, 0x00000100,
395 0xa008, 0xffffffff, 0x00010000,
396 0xa008, 0xffffffff, 0x00010000,
397 0x913c, 0xffff03ff, 0x01000100,
398 0x913c, 0xffff03ff, 0x01000100,
399 0x90e8, 0x001fffff, 0x010400c0,
400 0x8c00, 0x000000ff, 0x00000003,
401 0x8c00, 0x000000ff, 0x00000003,
402 0x8c04, 0xf8ff00ff, 0x40600060,
403 0x8c04, 0xf8ff00ff, 0x40600060,
404 0x8c30, 0x0000000f, 0x00040005,
405 0x8cf0, 0x1fff1fff, 0x08e00410,
406 0x8cf0, 0x1fff1fff, 0x08e00410,
407 0x900c, 0x00ffffff, 0x0017071f,
408 0x28350, 0x00000f01, 0x00000000,
409 0x28350, 0x00000f01, 0x00000000,
410 0x9508, 0xf700071f, 0x00000002,
411 0x9508, 0xf700071f, 0x00000002,
412 0x9688, 0x00300000, 0x0017000f,
413 0x960c, 0xffffffff, 0x54763210,
414 0x960c, 0xffffffff, 0x54763210,
415 0x20ef8, 0x01ff01ff, 0x00000002,
416 0x20e98, 0xfffffbff, 0x00200000,
417 0x2015c, 0xffffffff, 0x00000f40,
418 0x88c4, 0x001f3ae3, 0x00000082,
419 0x88c4, 0x001f3ae3, 0x00000082,
420 0x8978, 0x3fffffff, 0x04050140,
421 0x8978, 0x3fffffff, 0x04050140,
422 0x88d4, 0x0000001f, 0x00000010,
423 0x88d4, 0x0000001f, 0x00000010,
424 0x8974, 0xffffffff, 0x00000000,
425 0x8974, 0xffffffff, 0x00000000
426};
427
428static void ni_init_golden_registers(struct radeon_device *rdev)
429{
430 switch (rdev->family) {
431 case CHIP_CAYMAN:
432 radeon_program_register_sequence(rdev,
433 cayman_golden_registers,
434 (const u32)ARRAY_SIZE(cayman_golden_registers));
435 radeon_program_register_sequence(rdev,
436 cayman_golden_registers2,
437 (const u32)ARRAY_SIZE(cayman_golden_registers2));
438 break;
439 case CHIP_ARUBA:
440 if ((rdev->pdev->device == 0x9900) ||
441 (rdev->pdev->device == 0x9901) ||
442 (rdev->pdev->device == 0x9903) ||
443 (rdev->pdev->device == 0x9904) ||
444 (rdev->pdev->device == 0x9905) ||
445 (rdev->pdev->device == 0x9906) ||
446 (rdev->pdev->device == 0x9907) ||
447 (rdev->pdev->device == 0x9908) ||
448 (rdev->pdev->device == 0x9909) ||
449 (rdev->pdev->device == 0x990A) ||
450 (rdev->pdev->device == 0x990B) ||
451 (rdev->pdev->device == 0x990C) ||
452 (rdev->pdev->device == 0x990D) ||
453 (rdev->pdev->device == 0x990E) ||
454 (rdev->pdev->device == 0x990F) ||
455 (rdev->pdev->device == 0x9910) ||
456 (rdev->pdev->device == 0x9913) ||
457 (rdev->pdev->device == 0x9917) ||
458 (rdev->pdev->device == 0x9918)) {
459 radeon_program_register_sequence(rdev,
460 dvst_golden_registers,
461 (const u32)ARRAY_SIZE(dvst_golden_registers));
462 radeon_program_register_sequence(rdev,
463 dvst_golden_registers2,
464 (const u32)ARRAY_SIZE(dvst_golden_registers2));
465 } else {
466 radeon_program_register_sequence(rdev,
467 scrapper_golden_registers,
468 (const u32)ARRAY_SIZE(scrapper_golden_registers));
469 radeon_program_register_sequence(rdev,
470 dvst_golden_registers2,
471 (const u32)ARRAY_SIZE(dvst_golden_registers2));
472 }
473 break;
474 default:
475 break;
476 }
477}
478
Alex Deucher0af62b02011-01-06 21:19:31 -0500479#define BTC_IO_MC_REGS_SIZE 29
480
481static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
482 {0x00000077, 0xff010100},
483 {0x00000078, 0x00000000},
484 {0x00000079, 0x00001434},
485 {0x0000007a, 0xcc08ec08},
486 {0x0000007b, 0x00040000},
487 {0x0000007c, 0x000080c0},
488 {0x0000007d, 0x09000000},
489 {0x0000007e, 0x00210404},
490 {0x00000081, 0x08a8e800},
491 {0x00000082, 0x00030444},
492 {0x00000083, 0x00000000},
493 {0x00000085, 0x00000001},
494 {0x00000086, 0x00000002},
495 {0x00000087, 0x48490000},
496 {0x00000088, 0x20244647},
497 {0x00000089, 0x00000005},
498 {0x0000008b, 0x66030000},
499 {0x0000008c, 0x00006603},
500 {0x0000008d, 0x00000100},
501 {0x0000008f, 0x00001c0a},
502 {0x00000090, 0xff000001},
503 {0x00000094, 0x00101101},
504 {0x00000095, 0x00000fff},
505 {0x00000096, 0x00116fff},
506 {0x00000097, 0x60010000},
507 {0x00000098, 0x10010000},
508 {0x00000099, 0x00006000},
509 {0x0000009a, 0x00001000},
510 {0x0000009f, 0x00946a00}
511};
512
513static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
514 {0x00000077, 0xff010100},
515 {0x00000078, 0x00000000},
516 {0x00000079, 0x00001434},
517 {0x0000007a, 0xcc08ec08},
518 {0x0000007b, 0x00040000},
519 {0x0000007c, 0x000080c0},
520 {0x0000007d, 0x09000000},
521 {0x0000007e, 0x00210404},
522 {0x00000081, 0x08a8e800},
523 {0x00000082, 0x00030444},
524 {0x00000083, 0x00000000},
525 {0x00000085, 0x00000001},
526 {0x00000086, 0x00000002},
527 {0x00000087, 0x48490000},
528 {0x00000088, 0x20244647},
529 {0x00000089, 0x00000005},
530 {0x0000008b, 0x66030000},
531 {0x0000008c, 0x00006603},
532 {0x0000008d, 0x00000100},
533 {0x0000008f, 0x00001c0a},
534 {0x00000090, 0xff000001},
535 {0x00000094, 0x00101101},
536 {0x00000095, 0x00000fff},
537 {0x00000096, 0x00116fff},
538 {0x00000097, 0x60010000},
539 {0x00000098, 0x10010000},
540 {0x00000099, 0x00006000},
541 {0x0000009a, 0x00001000},
542 {0x0000009f, 0x00936a00}
543};
544
545static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
546 {0x00000077, 0xff010100},
547 {0x00000078, 0x00000000},
548 {0x00000079, 0x00001434},
549 {0x0000007a, 0xcc08ec08},
550 {0x0000007b, 0x00040000},
551 {0x0000007c, 0x000080c0},
552 {0x0000007d, 0x09000000},
553 {0x0000007e, 0x00210404},
554 {0x00000081, 0x08a8e800},
555 {0x00000082, 0x00030444},
556 {0x00000083, 0x00000000},
557 {0x00000085, 0x00000001},
558 {0x00000086, 0x00000002},
559 {0x00000087, 0x48490000},
560 {0x00000088, 0x20244647},
561 {0x00000089, 0x00000005},
562 {0x0000008b, 0x66030000},
563 {0x0000008c, 0x00006603},
564 {0x0000008d, 0x00000100},
565 {0x0000008f, 0x00001c0a},
566 {0x00000090, 0xff000001},
567 {0x00000094, 0x00101101},
568 {0x00000095, 0x00000fff},
569 {0x00000096, 0x00116fff},
570 {0x00000097, 0x60010000},
571 {0x00000098, 0x10010000},
572 {0x00000099, 0x00006000},
573 {0x0000009a, 0x00001000},
574 {0x0000009f, 0x00916a00}
575};
576
Alex Deucher9b8253c2011-03-02 20:07:28 -0500577static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
578 {0x00000077, 0xff010100},
579 {0x00000078, 0x00000000},
580 {0x00000079, 0x00001434},
581 {0x0000007a, 0xcc08ec08},
582 {0x0000007b, 0x00040000},
583 {0x0000007c, 0x000080c0},
584 {0x0000007d, 0x09000000},
585 {0x0000007e, 0x00210404},
586 {0x00000081, 0x08a8e800},
587 {0x00000082, 0x00030444},
588 {0x00000083, 0x00000000},
589 {0x00000085, 0x00000001},
590 {0x00000086, 0x00000002},
591 {0x00000087, 0x48490000},
592 {0x00000088, 0x20244647},
593 {0x00000089, 0x00000005},
594 {0x0000008b, 0x66030000},
595 {0x0000008c, 0x00006603},
596 {0x0000008d, 0x00000100},
597 {0x0000008f, 0x00001c0a},
598 {0x00000090, 0xff000001},
599 {0x00000094, 0x00101101},
600 {0x00000095, 0x00000fff},
601 {0x00000096, 0x00116fff},
602 {0x00000097, 0x60010000},
603 {0x00000098, 0x10010000},
604 {0x00000099, 0x00006000},
605 {0x0000009a, 0x00001000},
606 {0x0000009f, 0x00976b00}
607};
608
Alex Deucher755d8192011-03-02 20:07:34 -0500609int ni_mc_load_microcode(struct radeon_device *rdev)
Alex Deucher0af62b02011-01-06 21:19:31 -0500610{
611 const __be32 *fw_data;
612 u32 mem_type, running, blackout = 0;
613 u32 *io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500614 int i, ucode_size, regs_size;
Alex Deucher0af62b02011-01-06 21:19:31 -0500615
616 if (!rdev->mc_fw)
617 return -EINVAL;
618
619 switch (rdev->family) {
620 case CHIP_BARTS:
621 io_mc_regs = (u32 *)&barts_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500622 ucode_size = BTC_MC_UCODE_SIZE;
623 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500624 break;
625 case CHIP_TURKS:
626 io_mc_regs = (u32 *)&turks_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500627 ucode_size = BTC_MC_UCODE_SIZE;
628 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500629 break;
630 case CHIP_CAICOS:
631 default:
632 io_mc_regs = (u32 *)&caicos_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500633 ucode_size = BTC_MC_UCODE_SIZE;
634 regs_size = BTC_IO_MC_REGS_SIZE;
635 break;
636 case CHIP_CAYMAN:
637 io_mc_regs = (u32 *)&cayman_io_mc_regs;
638 ucode_size = CAYMAN_MC_UCODE_SIZE;
639 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500640 break;
641 }
642
643 mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
644 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
645
646 if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
647 if (running) {
648 blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
649 WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
650 }
651
652 /* reset the engine and set to writable */
653 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
654 WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
655
656 /* load mc io regs */
Alex Deucher9b8253c2011-03-02 20:07:28 -0500657 for (i = 0; i < regs_size; i++) {
Alex Deucher0af62b02011-01-06 21:19:31 -0500658 WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
659 WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
660 }
661 /* load the MC ucode */
662 fw_data = (const __be32 *)rdev->mc_fw->data;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500663 for (i = 0; i < ucode_size; i++)
Alex Deucher0af62b02011-01-06 21:19:31 -0500664 WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
665
666 /* put the engine back into the active state */
667 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
668 WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
669 WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
670
671 /* wait for training to complete */
Alex Deucher0e2c9782011-11-02 18:08:25 -0400672 for (i = 0; i < rdev->usec_timeout; i++) {
673 if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
674 break;
675 udelay(1);
676 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500677
678 if (running)
679 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
680 }
681
682 return 0;
683}
684
685int ni_init_microcode(struct radeon_device *rdev)
686{
687 struct platform_device *pdev;
688 const char *chip_name;
689 const char *rlc_chip_name;
690 size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
Alex Deucher6596afd2013-06-26 00:15:24 -0400691 size_t smc_req_size = 0;
Alex Deucher0af62b02011-01-06 21:19:31 -0500692 char fw_name[30];
693 int err;
694
695 DRM_DEBUG("\n");
696
697 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
698 err = IS_ERR(pdev);
699 if (err) {
700 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
701 return -EINVAL;
702 }
703
704 switch (rdev->family) {
705 case CHIP_BARTS:
706 chip_name = "BARTS";
707 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500708 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
709 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
710 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
711 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher6596afd2013-06-26 00:15:24 -0400712 smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4);
Alex Deucher0af62b02011-01-06 21:19:31 -0500713 break;
714 case CHIP_TURKS:
715 chip_name = "TURKS";
716 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500717 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
718 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
719 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
720 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher6596afd2013-06-26 00:15:24 -0400721 smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4);
Alex Deucher0af62b02011-01-06 21:19:31 -0500722 break;
723 case CHIP_CAICOS:
724 chip_name = "CAICOS";
725 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500726 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
727 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
728 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
729 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher6596afd2013-06-26 00:15:24 -0400730 smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4);
Alex Deucher9b8253c2011-03-02 20:07:28 -0500731 break;
732 case CHIP_CAYMAN:
733 chip_name = "CAYMAN";
734 rlc_chip_name = "CAYMAN";
735 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
736 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
737 rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
738 mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
Alex Deucher69e0b572013-04-12 16:42:42 -0400739 smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
Alex Deucher0af62b02011-01-06 21:19:31 -0500740 break;
Alex Deucherc420c742012-03-20 17:18:39 -0400741 case CHIP_ARUBA:
742 chip_name = "ARUBA";
743 rlc_chip_name = "ARUBA";
744 /* pfp/me same size as CAYMAN */
745 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
746 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
747 rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
748 mc_req_size = 0;
749 break;
Alex Deucher0af62b02011-01-06 21:19:31 -0500750 default: BUG();
751 }
752
Alex Deucher0af62b02011-01-06 21:19:31 -0500753 DRM_INFO("Loading %s Microcode\n", chip_name);
754
755 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
756 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
757 if (err)
758 goto out;
759 if (rdev->pfp_fw->size != pfp_req_size) {
760 printk(KERN_ERR
761 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
762 rdev->pfp_fw->size, fw_name);
763 err = -EINVAL;
764 goto out;
765 }
766
767 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
768 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
769 if (err)
770 goto out;
771 if (rdev->me_fw->size != me_req_size) {
772 printk(KERN_ERR
773 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
774 rdev->me_fw->size, fw_name);
775 err = -EINVAL;
776 }
777
778 snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
779 err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
780 if (err)
781 goto out;
782 if (rdev->rlc_fw->size != rlc_req_size) {
783 printk(KERN_ERR
784 "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
785 rdev->rlc_fw->size, fw_name);
786 err = -EINVAL;
787 }
788
Alex Deucherc420c742012-03-20 17:18:39 -0400789 /* no MC ucode on TN */
790 if (!(rdev->flags & RADEON_IS_IGP)) {
791 snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
792 err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
793 if (err)
794 goto out;
795 if (rdev->mc_fw->size != mc_req_size) {
796 printk(KERN_ERR
797 "ni_mc: Bogus length %zu in firmware \"%s\"\n",
798 rdev->mc_fw->size, fw_name);
799 err = -EINVAL;
800 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500801 }
Alex Deucher6596afd2013-06-26 00:15:24 -0400802
Alex Deucher69e0b572013-04-12 16:42:42 -0400803 if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
Alex Deucher6596afd2013-06-26 00:15:24 -0400804 snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
805 err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
806 if (err)
807 goto out;
808 if (rdev->smc_fw->size != smc_req_size) {
809 printk(KERN_ERR
810 "ni_mc: Bogus length %zu in firmware \"%s\"\n",
811 rdev->mc_fw->size, fw_name);
812 err = -EINVAL;
813 }
814 }
815
Alex Deucher0af62b02011-01-06 21:19:31 -0500816out:
817 platform_device_unregister(pdev);
818
819 if (err) {
820 if (err != -EINVAL)
821 printk(KERN_ERR
822 "ni_cp: Failed to load firmware \"%s\"\n",
823 fw_name);
824 release_firmware(rdev->pfp_fw);
825 rdev->pfp_fw = NULL;
826 release_firmware(rdev->me_fw);
827 rdev->me_fw = NULL;
828 release_firmware(rdev->rlc_fw);
829 rdev->rlc_fw = NULL;
830 release_firmware(rdev->mc_fw);
831 rdev->mc_fw = NULL;
832 }
833 return err;
834}
835
Alex Deucher29a15222012-12-14 11:57:36 -0500836int tn_get_temp(struct radeon_device *rdev)
837{
838 u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
839 int actual_temp = (temp / 8) - 49;
840
841 return actual_temp * 1000;
842}
843
Alex Deucherfecf1d02011-03-02 20:07:29 -0500844/*
845 * Core functions
846 */
Alex Deucherfecf1d02011-03-02 20:07:29 -0500847static void cayman_gpu_init(struct radeon_device *rdev)
848{
Alex Deucherfecf1d02011-03-02 20:07:29 -0500849 u32 gb_addr_config = 0;
850 u32 mc_shared_chmap, mc_arb_ramcfg;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500851 u32 cgts_tcc_disable;
852 u32 sx_debug_1;
853 u32 smx_dc_ctl0;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500854 u32 cgts_sm_ctrl_reg;
855 u32 hdp_host_path_cntl;
856 u32 tmp;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400857 u32 disabled_rb_mask;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500858 int i, j;
859
860 switch (rdev->family) {
861 case CHIP_CAYMAN:
Alex Deucherfecf1d02011-03-02 20:07:29 -0500862 rdev->config.cayman.max_shader_engines = 2;
863 rdev->config.cayman.max_pipes_per_simd = 4;
864 rdev->config.cayman.max_tile_pipes = 8;
865 rdev->config.cayman.max_simds_per_se = 12;
866 rdev->config.cayman.max_backends_per_se = 4;
867 rdev->config.cayman.max_texture_channel_caches = 8;
868 rdev->config.cayman.max_gprs = 256;
869 rdev->config.cayman.max_threads = 256;
870 rdev->config.cayman.max_gs_threads = 32;
871 rdev->config.cayman.max_stack_entries = 512;
872 rdev->config.cayman.sx_num_of_sets = 8;
873 rdev->config.cayman.sx_max_export_size = 256;
874 rdev->config.cayman.sx_max_export_pos_size = 64;
875 rdev->config.cayman.sx_max_export_smx_size = 192;
876 rdev->config.cayman.max_hw_contexts = 8;
877 rdev->config.cayman.sq_num_cf_insts = 2;
878
879 rdev->config.cayman.sc_prim_fifo_size = 0x100;
880 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
881 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400882 gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500883 break;
Alex Deucher7b76e472012-03-20 17:18:36 -0400884 case CHIP_ARUBA:
885 default:
886 rdev->config.cayman.max_shader_engines = 1;
887 rdev->config.cayman.max_pipes_per_simd = 4;
888 rdev->config.cayman.max_tile_pipes = 2;
889 if ((rdev->pdev->device == 0x9900) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400890 (rdev->pdev->device == 0x9901) ||
891 (rdev->pdev->device == 0x9905) ||
892 (rdev->pdev->device == 0x9906) ||
893 (rdev->pdev->device == 0x9907) ||
894 (rdev->pdev->device == 0x9908) ||
895 (rdev->pdev->device == 0x9909) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500896 (rdev->pdev->device == 0x990B) ||
897 (rdev->pdev->device == 0x990C) ||
898 (rdev->pdev->device == 0x990F) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400899 (rdev->pdev->device == 0x9910) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500900 (rdev->pdev->device == 0x9917) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400901 (rdev->pdev->device == 0x9999) ||
902 (rdev->pdev->device == 0x999C)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400903 rdev->config.cayman.max_simds_per_se = 6;
904 rdev->config.cayman.max_backends_per_se = 2;
905 } else if ((rdev->pdev->device == 0x9903) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400906 (rdev->pdev->device == 0x9904) ||
907 (rdev->pdev->device == 0x990A) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500908 (rdev->pdev->device == 0x990D) ||
909 (rdev->pdev->device == 0x990E) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400910 (rdev->pdev->device == 0x9913) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400911 (rdev->pdev->device == 0x9918) ||
912 (rdev->pdev->device == 0x999D)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400913 rdev->config.cayman.max_simds_per_se = 4;
914 rdev->config.cayman.max_backends_per_se = 2;
Alex Deucherd430f7d2012-06-05 09:50:28 -0400915 } else if ((rdev->pdev->device == 0x9919) ||
916 (rdev->pdev->device == 0x9990) ||
917 (rdev->pdev->device == 0x9991) ||
918 (rdev->pdev->device == 0x9994) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500919 (rdev->pdev->device == 0x9995) ||
920 (rdev->pdev->device == 0x9996) ||
921 (rdev->pdev->device == 0x999A) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400922 (rdev->pdev->device == 0x99A0)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400923 rdev->config.cayman.max_simds_per_se = 3;
924 rdev->config.cayman.max_backends_per_se = 1;
925 } else {
926 rdev->config.cayman.max_simds_per_se = 2;
927 rdev->config.cayman.max_backends_per_se = 1;
928 }
929 rdev->config.cayman.max_texture_channel_caches = 2;
930 rdev->config.cayman.max_gprs = 256;
931 rdev->config.cayman.max_threads = 256;
932 rdev->config.cayman.max_gs_threads = 32;
933 rdev->config.cayman.max_stack_entries = 512;
934 rdev->config.cayman.sx_num_of_sets = 8;
935 rdev->config.cayman.sx_max_export_size = 256;
936 rdev->config.cayman.sx_max_export_pos_size = 64;
937 rdev->config.cayman.sx_max_export_smx_size = 192;
938 rdev->config.cayman.max_hw_contexts = 8;
939 rdev->config.cayman.sq_num_cf_insts = 2;
940
941 rdev->config.cayman.sc_prim_fifo_size = 0x40;
942 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
943 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400944 gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
Alex Deucher7b76e472012-03-20 17:18:36 -0400945 break;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500946 }
947
948 /* Initialize HDP */
949 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
950 WREG32((0x2c14 + j), 0x00000000);
951 WREG32((0x2c18 + j), 0x00000000);
952 WREG32((0x2c1c + j), 0x00000000);
953 WREG32((0x2c20 + j), 0x00000000);
954 WREG32((0x2c24 + j), 0x00000000);
955 }
956
957 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
958
Alex Deucherd054ac12011-09-01 17:46:15 +0000959 evergreen_fix_pci_max_read_req_size(rdev);
960
Alex Deucherfecf1d02011-03-02 20:07:29 -0500961 mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
962 mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
963
Alex Deucherfecf1d02011-03-02 20:07:29 -0500964 tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
965 rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
966 if (rdev->config.cayman.mem_row_size_in_kb > 4)
967 rdev->config.cayman.mem_row_size_in_kb = 4;
968 /* XXX use MC settings? */
969 rdev->config.cayman.shader_engine_tile_size = 32;
970 rdev->config.cayman.num_gpus = 1;
971 rdev->config.cayman.multi_gpu_tile_size = 64;
972
Alex Deucherfecf1d02011-03-02 20:07:29 -0500973 tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
974 rdev->config.cayman.num_tile_pipes = (1 << tmp);
975 tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
976 rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
977 tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
978 rdev->config.cayman.num_shader_engines = tmp + 1;
979 tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
980 rdev->config.cayman.num_gpus = tmp + 1;
981 tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
982 rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
983 tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
984 rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
985
Alex Deucher416a2bd2012-05-31 19:00:25 -0400986
Alex Deucherfecf1d02011-03-02 20:07:29 -0500987 /* setup tiling info dword. gb_addr_config is not adequate since it does
988 * not have bank info, so create a custom tiling dword.
989 * bits 3:0 num_pipes
990 * bits 7:4 num_banks
991 * bits 11:8 group_size
992 * bits 15:12 row_size
993 */
994 rdev->config.cayman.tile_config = 0;
995 switch (rdev->config.cayman.num_tile_pipes) {
996 case 1:
997 default:
998 rdev->config.cayman.tile_config |= (0 << 0);
999 break;
1000 case 2:
1001 rdev->config.cayman.tile_config |= (1 << 0);
1002 break;
1003 case 4:
1004 rdev->config.cayman.tile_config |= (2 << 0);
1005 break;
1006 case 8:
1007 rdev->config.cayman.tile_config |= (3 << 0);
1008 break;
1009 }
Alex Deucher7b76e472012-03-20 17:18:36 -04001010
1011 /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
1012 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher1f73cca2012-05-24 22:55:15 -04001013 rdev->config.cayman.tile_config |= 1 << 4;
Alex Deucher29d65402012-05-31 18:53:36 -04001014 else {
Alex Deucher5b23c902012-07-31 11:05:11 -04001015 switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
1016 case 0: /* four banks */
Alex Deucher29d65402012-05-31 18:53:36 -04001017 rdev->config.cayman.tile_config |= 0 << 4;
Alex Deucher5b23c902012-07-31 11:05:11 -04001018 break;
1019 case 1: /* eight banks */
1020 rdev->config.cayman.tile_config |= 1 << 4;
1021 break;
1022 case 2: /* sixteen banks */
1023 default:
1024 rdev->config.cayman.tile_config |= 2 << 4;
1025 break;
1026 }
Alex Deucher29d65402012-05-31 18:53:36 -04001027 }
Alex Deucherfecf1d02011-03-02 20:07:29 -05001028 rdev->config.cayman.tile_config |=
Dave Airliecde50832011-05-19 14:14:41 +10001029 ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
Alex Deucherfecf1d02011-03-02 20:07:29 -05001030 rdev->config.cayman.tile_config |=
1031 ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
1032
Alex Deucher416a2bd2012-05-31 19:00:25 -04001033 tmp = 0;
1034 for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
1035 u32 rb_disable_bitmap;
1036
1037 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1038 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1039 rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
1040 tmp <<= 4;
1041 tmp |= rb_disable_bitmap;
1042 }
1043 /* enabled rb are just the one not disabled :) */
1044 disabled_rb_mask = tmp;
Alex Deuchercedb6552013-04-09 10:13:22 -04001045 tmp = 0;
1046 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1047 tmp |= (1 << i);
1048 /* if all the backends are disabled, fix it up here */
1049 if ((disabled_rb_mask & tmp) == tmp) {
1050 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1051 disabled_rb_mask &= ~(1 << i);
1052 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001053
1054 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1055 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1056
Alex Deucherfecf1d02011-03-02 20:07:29 -05001057 WREG32(GB_ADDR_CONFIG, gb_addr_config);
1058 WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
Alex Deucher7c1c7c12013-04-05 10:28:08 -04001059 if (ASIC_IS_DCE6(rdev))
1060 WREG32(DMIF_ADDR_CALC, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001061 WREG32(HDP_ADDR_CONFIG, gb_addr_config);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001062 WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
1063 WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
Christian König9a210592013-04-08 12:41:37 +02001064 WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
1065 WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
1066 WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001067
Alex Deucher8f612b22013-03-11 19:28:39 -04001068 if ((rdev->config.cayman.max_backends_per_se == 1) &&
1069 (rdev->flags & RADEON_IS_IGP)) {
1070 if ((disabled_rb_mask & 3) == 1) {
1071 /* RB0 disabled, RB1 enabled */
1072 tmp = 0x11111111;
1073 } else {
1074 /* RB1 disabled, RB0 enabled */
1075 tmp = 0x00000000;
1076 }
1077 } else {
1078 tmp = gb_addr_config & NUM_PIPES_MASK;
1079 tmp = r6xx_remap_render_backend(rdev, tmp,
1080 rdev->config.cayman.max_backends_per_se *
1081 rdev->config.cayman.max_shader_engines,
1082 CAYMAN_MAX_BACKENDS, disabled_rb_mask);
1083 }
Alex Deucher416a2bd2012-05-31 19:00:25 -04001084 WREG32(GB_BACKEND_MAP, tmp);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001085
Alex Deucher416a2bd2012-05-31 19:00:25 -04001086 cgts_tcc_disable = 0xffff0000;
1087 for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
1088 cgts_tcc_disable &= ~(1 << (16 + i));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001089 WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
1090 WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001091 WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
1092 WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
1093
1094 /* reprogram the shader complex */
1095 cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
1096 for (i = 0; i < 16; i++)
1097 WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
1098 WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
1099
1100 /* set HW defaults for 3D engine */
1101 WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
1102
1103 sx_debug_1 = RREG32(SX_DEBUG_1);
1104 sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1105 WREG32(SX_DEBUG_1, sx_debug_1);
1106
1107 smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1108 smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
Dave Airlie285e0422011-05-09 14:54:33 +10001109 smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
Alex Deucherfecf1d02011-03-02 20:07:29 -05001110 WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1111
1112 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
1113
1114 /* need to be explicitly zero-ed */
1115 WREG32(VGT_OFFCHIP_LDS_BASE, 0);
1116 WREG32(SQ_LSTMP_RING_BASE, 0);
1117 WREG32(SQ_HSTMP_RING_BASE, 0);
1118 WREG32(SQ_ESTMP_RING_BASE, 0);
1119 WREG32(SQ_GSTMP_RING_BASE, 0);
1120 WREG32(SQ_VSTMP_RING_BASE, 0);
1121 WREG32(SQ_PSTMP_RING_BASE, 0);
1122
1123 WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
1124
Dave Airlie285e0422011-05-09 14:54:33 +10001125 WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
1126 POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
1127 SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001128
Dave Airlie285e0422011-05-09 14:54:33 +10001129 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
1130 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
1131 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
Alex Deucherfecf1d02011-03-02 20:07:29 -05001132
1133
1134 WREG32(VGT_NUM_INSTANCES, 1);
1135
1136 WREG32(CP_PERFMON_CNTL, 0);
1137
Dave Airlie285e0422011-05-09 14:54:33 +10001138 WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
Alex Deucherfecf1d02011-03-02 20:07:29 -05001139 FETCH_FIFO_HIWATER(0x4) |
1140 DONE_FIFO_HIWATER(0xe0) |
1141 ALU_UPDATE_FIFO_HIWATER(0x8)));
1142
1143 WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1144 WREG32(SQ_CONFIG, (VC_ENABLE |
1145 EXPORT_SRC_C |
1146 GFX_PRIO(0) |
1147 CS1_PRIO(0) |
1148 CS2_PRIO(1)));
1149 WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1150
1151 WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1152 FORCE_EOV_MAX_REZ_CNT(255)));
1153
1154 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1155 AUTO_INVLD_EN(ES_AND_GS_AUTO));
1156
1157 WREG32(VGT_GS_VERTEX_REUSE, 16);
1158 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1159
1160 WREG32(CB_PERF_CTR0_SEL_0, 0);
1161 WREG32(CB_PERF_CTR0_SEL_1, 0);
1162 WREG32(CB_PERF_CTR1_SEL_0, 0);
1163 WREG32(CB_PERF_CTR1_SEL_1, 0);
1164 WREG32(CB_PERF_CTR2_SEL_0, 0);
1165 WREG32(CB_PERF_CTR2_SEL_1, 0);
1166 WREG32(CB_PERF_CTR3_SEL_0, 0);
1167 WREG32(CB_PERF_CTR3_SEL_1, 0);
1168
Dave Airlie0b65f832011-05-19 14:14:42 +10001169 tmp = RREG32(HDP_MISC_CNTL);
1170 tmp |= HDP_FLUSH_INVALIDATE_CACHE;
1171 WREG32(HDP_MISC_CNTL, tmp);
1172
Alex Deucherfecf1d02011-03-02 20:07:29 -05001173 hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1174 WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1175
1176 WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1177
1178 udelay(50);
1179}
1180
Alex Deucherfa8198e2011-03-02 20:07:30 -05001181/*
1182 * GART
1183 */
1184void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1185{
1186 /* flush hdp cache */
1187 WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1188
1189 /* bits 0-7 are the VM contexts0-7 */
1190 WREG32(VM_INVALIDATE_REQUEST, 1);
1191}
1192
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001193static int cayman_pcie_gart_enable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001194{
Jerome Glisse721604a2012-01-05 22:11:05 -05001195 int i, r;
Alex Deucherfa8198e2011-03-02 20:07:30 -05001196
Jerome Glissec9a1be92011-11-03 11:16:49 -04001197 if (rdev->gart.robj == NULL) {
Alex Deucherfa8198e2011-03-02 20:07:30 -05001198 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1199 return -EINVAL;
1200 }
1201 r = radeon_gart_table_vram_pin(rdev);
1202 if (r)
1203 return r;
1204 radeon_gart_restore(rdev);
1205 /* Setup TLB control */
Jerome Glisse721604a2012-01-05 22:11:05 -05001206 WREG32(MC_VM_MX_L1_TLB_CNTL,
1207 (0xA << 7) |
1208 ENABLE_L1_TLB |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001209 ENABLE_L1_FRAGMENT_PROCESSING |
1210 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
Jerome Glisse721604a2012-01-05 22:11:05 -05001211 ENABLE_ADVANCED_DRIVER_MODEL |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001212 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1213 /* Setup L2 cache */
1214 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1215 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1216 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1217 EFFECTIVE_L2_QUEUE_SIZE(7) |
1218 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1219 WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1220 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1221 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1222 /* setup context0 */
1223 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1224 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1225 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1226 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1227 (u32)(rdev->dummy_page.addr >> 12));
1228 WREG32(VM_CONTEXT0_CNTL2, 0);
1229 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1230 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
Jerome Glisse721604a2012-01-05 22:11:05 -05001231
1232 WREG32(0x15D4, 0);
1233 WREG32(0x15D8, 0);
1234 WREG32(0x15DC, 0);
1235
1236 /* empty context1-7 */
Alex Deucher23d4f1f2012-10-08 09:45:46 -04001237 /* Assign the pt base to something valid for now; the pts used for
1238 * the VMs are determined by the application and setup and assigned
1239 * on the fly in the vm part of radeon_gart.c
1240 */
Jerome Glisse721604a2012-01-05 22:11:05 -05001241 for (i = 1; i < 8; i++) {
1242 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
Alex Deucherc1a7ca02012-10-08 12:15:13 -04001243 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
Jerome Glisse721604a2012-01-05 22:11:05 -05001244 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1245 rdev->gart.table_addr >> 12);
1246 }
1247
1248 /* enable context1-7 */
1249 WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1250 (u32)(rdev->dummy_page.addr >> 12));
Christian Königae133a12012-09-18 15:30:44 -04001251 WREG32(VM_CONTEXT1_CNTL2, 4);
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02001252 WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
Christian Königae133a12012-09-18 15:30:44 -04001253 RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1254 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1255 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1256 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1257 PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1258 PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1259 VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1260 VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1261 READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1262 READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1263 WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1264 WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001265
1266 cayman_pcie_gart_tlb_flush(rdev);
Tormod Voldenfcf4de52011-08-31 21:54:07 +00001267 DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1268 (unsigned)(rdev->mc.gtt_size >> 20),
1269 (unsigned long long)rdev->gart.table_addr);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001270 rdev->gart.ready = true;
1271 return 0;
1272}
1273
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001274static void cayman_pcie_gart_disable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001275{
Alex Deucherfa8198e2011-03-02 20:07:30 -05001276 /* Disable all tables */
1277 WREG32(VM_CONTEXT0_CNTL, 0);
1278 WREG32(VM_CONTEXT1_CNTL, 0);
1279 /* Setup TLB control */
1280 WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1281 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1282 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1283 /* Setup L2 cache */
1284 WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1285 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1286 EFFECTIVE_L2_QUEUE_SIZE(7) |
1287 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1288 WREG32(VM_L2_CNTL2, 0);
1289 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1290 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
Jerome Glissec9a1be92011-11-03 11:16:49 -04001291 radeon_gart_table_vram_unpin(rdev);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001292}
1293
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001294static void cayman_pcie_gart_fini(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001295{
1296 cayman_pcie_gart_disable(rdev);
1297 radeon_gart_table_vram_free(rdev);
1298 radeon_gart_fini(rdev);
1299}
1300
Alex Deucher1b370782011-11-17 20:13:28 -05001301void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
1302 int ring, u32 cp_int_cntl)
1303{
1304 u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;
1305
1306 WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
1307 WREG32(CP_INT_CNTL, cp_int_cntl);
1308}
1309
Alex Deucher0c88a022011-03-02 20:07:31 -05001310/*
1311 * CP.
1312 */
Alex Deucherb40e7e12011-11-17 14:57:50 -05001313void cayman_fence_ring_emit(struct radeon_device *rdev,
1314 struct radeon_fence *fence)
1315{
1316 struct radeon_ring *ring = &rdev->ring[fence->ring];
1317 u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1318
Jerome Glisse721604a2012-01-05 22:11:05 -05001319 /* flush read cache over gart for this vmid */
1320 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1321 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
1322 radeon_ring_write(ring, 0);
Alex Deucherb40e7e12011-11-17 14:57:50 -05001323 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1324 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1325 radeon_ring_write(ring, 0xFFFFFFFF);
1326 radeon_ring_write(ring, 0);
1327 radeon_ring_write(ring, 10); /* poll interval */
1328 /* EVENT_WRITE_EOP - flush caches, send int */
1329 radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1330 radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
1331 radeon_ring_write(ring, addr & 0xffffffff);
1332 radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1333 radeon_ring_write(ring, fence->seq);
1334 radeon_ring_write(ring, 0);
1335}
1336
Jerome Glisse721604a2012-01-05 22:11:05 -05001337void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1338{
Christian König876dc9f2012-05-08 14:24:01 +02001339 struct radeon_ring *ring = &rdev->ring[ib->ring];
Jerome Glisse721604a2012-01-05 22:11:05 -05001340
1341 /* set to DX10/11 mode */
1342 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1343 radeon_ring_write(ring, 1);
Christian König45df6802012-07-06 16:22:55 +02001344
1345 if (ring->rptr_save_reg) {
1346 uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1347 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1348 radeon_ring_write(ring, ((ring->rptr_save_reg -
1349 PACKET3_SET_CONFIG_REG_START) >> 2));
1350 radeon_ring_write(ring, next_rptr);
1351 }
1352
Jerome Glisse721604a2012-01-05 22:11:05 -05001353 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1354 radeon_ring_write(ring,
1355#ifdef __BIG_ENDIAN
1356 (2 << 0) |
1357#endif
1358 (ib->gpu_addr & 0xFFFFFFFC));
1359 radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
Christian König4bf3dd92012-08-06 18:57:44 +02001360 radeon_ring_write(ring, ib->length_dw |
1361 (ib->vm ? (ib->vm->id << 24) : 0));
Jerome Glisse721604a2012-01-05 22:11:05 -05001362
1363 /* flush read cache over gart for this vmid */
1364 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1365 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
Christian König4bf3dd92012-08-06 18:57:44 +02001366 radeon_ring_write(ring, ib->vm ? ib->vm->id : 0);
Jerome Glisse721604a2012-01-05 22:11:05 -05001367 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1368 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1369 radeon_ring_write(ring, 0xFFFFFFFF);
1370 radeon_ring_write(ring, 0);
1371 radeon_ring_write(ring, 10); /* poll interval */
1372}
1373
Christian Königf2ba57b2013-04-08 12:41:29 +02001374void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
1375 struct radeon_ring *ring,
1376 struct radeon_semaphore *semaphore,
1377 bool emit_wait)
1378{
1379 uint64_t addr = semaphore->gpu_addr;
1380
1381 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
1382 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
1383
1384 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
1385 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
1386
1387 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
1388 radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
1389}
1390
Alex Deucher0c88a022011-03-02 20:07:31 -05001391static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1392{
1393 if (enable)
1394 WREG32(CP_ME_CNTL, 0);
1395 else {
Dave Airlie38f1cff2011-03-16 11:34:41 +10001396 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
Alex Deucher0c88a022011-03-02 20:07:31 -05001397 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1398 WREG32(SCRATCH_UMSK, 0);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001399 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001400 }
1401}
1402
1403static int cayman_cp_load_microcode(struct radeon_device *rdev)
1404{
1405 const __be32 *fw_data;
1406 int i;
1407
1408 if (!rdev->me_fw || !rdev->pfp_fw)
1409 return -EINVAL;
1410
1411 cayman_cp_enable(rdev, false);
1412
1413 fw_data = (const __be32 *)rdev->pfp_fw->data;
1414 WREG32(CP_PFP_UCODE_ADDR, 0);
1415 for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
1416 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1417 WREG32(CP_PFP_UCODE_ADDR, 0);
1418
1419 fw_data = (const __be32 *)rdev->me_fw->data;
1420 WREG32(CP_ME_RAM_WADDR, 0);
1421 for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
1422 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1423
1424 WREG32(CP_PFP_UCODE_ADDR, 0);
1425 WREG32(CP_ME_RAM_WADDR, 0);
1426 WREG32(CP_ME_RAM_RADDR, 0);
1427 return 0;
1428}
1429
1430static int cayman_cp_start(struct radeon_device *rdev)
1431{
Christian Könige32eb502011-10-23 12:56:27 +02001432 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher0c88a022011-03-02 20:07:31 -05001433 int r, i;
1434
Christian Könige32eb502011-10-23 12:56:27 +02001435 r = radeon_ring_lock(rdev, ring, 7);
Alex Deucher0c88a022011-03-02 20:07:31 -05001436 if (r) {
1437 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1438 return r;
1439 }
Christian Könige32eb502011-10-23 12:56:27 +02001440 radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1441 radeon_ring_write(ring, 0x1);
1442 radeon_ring_write(ring, 0x0);
1443 radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1444 radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1445 radeon_ring_write(ring, 0);
1446 radeon_ring_write(ring, 0);
1447 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001448
1449 cayman_cp_enable(rdev, true);
1450
Christian Könige32eb502011-10-23 12:56:27 +02001451 r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
Alex Deucher0c88a022011-03-02 20:07:31 -05001452 if (r) {
1453 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1454 return r;
1455 }
1456
1457 /* setup clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001458 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1459 radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001460
1461 for (i = 0; i < cayman_default_size; i++)
Christian Könige32eb502011-10-23 12:56:27 +02001462 radeon_ring_write(ring, cayman_default_state[i]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001463
Christian Könige32eb502011-10-23 12:56:27 +02001464 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1465 radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001466
1467 /* set clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001468 radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1469 radeon_ring_write(ring, 0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001470
1471 /* SQ_VTX_BASE_VTX_LOC */
Christian Könige32eb502011-10-23 12:56:27 +02001472 radeon_ring_write(ring, 0xc0026f00);
1473 radeon_ring_write(ring, 0x00000000);
1474 radeon_ring_write(ring, 0x00000000);
1475 radeon_ring_write(ring, 0x00000000);
Alex Deucher0c88a022011-03-02 20:07:31 -05001476
1477 /* Clear consts */
Christian Könige32eb502011-10-23 12:56:27 +02001478 radeon_ring_write(ring, 0xc0036f00);
1479 radeon_ring_write(ring, 0x00000bc4);
1480 radeon_ring_write(ring, 0xffffffff);
1481 radeon_ring_write(ring, 0xffffffff);
1482 radeon_ring_write(ring, 0xffffffff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001483
Christian Könige32eb502011-10-23 12:56:27 +02001484 radeon_ring_write(ring, 0xc0026900);
1485 radeon_ring_write(ring, 0x00000316);
1486 radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1487 radeon_ring_write(ring, 0x00000010); /* */
Alex Deucher9b91d182011-03-02 20:07:39 -05001488
Christian Könige32eb502011-10-23 12:56:27 +02001489 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001490
1491 /* XXX init other rings */
1492
1493 return 0;
1494}
1495
Alex Deucher755d8192011-03-02 20:07:34 -05001496static void cayman_cp_fini(struct radeon_device *rdev)
1497{
Christian König45df6802012-07-06 16:22:55 +02001498 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05001499 cayman_cp_enable(rdev, false);
Christian König45df6802012-07-06 16:22:55 +02001500 radeon_ring_fini(rdev, ring);
1501 radeon_scratch_free(rdev, ring->rptr_save_reg);
Alex Deucher755d8192011-03-02 20:07:34 -05001502}
1503
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001504static int cayman_cp_resume(struct radeon_device *rdev)
Alex Deucher0c88a022011-03-02 20:07:31 -05001505{
Christian Königb90ca982012-07-04 21:36:53 +02001506 static const int ridx[] = {
1507 RADEON_RING_TYPE_GFX_INDEX,
1508 CAYMAN_RING_TYPE_CP1_INDEX,
1509 CAYMAN_RING_TYPE_CP2_INDEX
1510 };
1511 static const unsigned cp_rb_cntl[] = {
1512 CP_RB0_CNTL,
1513 CP_RB1_CNTL,
1514 CP_RB2_CNTL,
1515 };
1516 static const unsigned cp_rb_rptr_addr[] = {
1517 CP_RB0_RPTR_ADDR,
1518 CP_RB1_RPTR_ADDR,
1519 CP_RB2_RPTR_ADDR
1520 };
1521 static const unsigned cp_rb_rptr_addr_hi[] = {
1522 CP_RB0_RPTR_ADDR_HI,
1523 CP_RB1_RPTR_ADDR_HI,
1524 CP_RB2_RPTR_ADDR_HI
1525 };
1526 static const unsigned cp_rb_base[] = {
1527 CP_RB0_BASE,
1528 CP_RB1_BASE,
1529 CP_RB2_BASE
1530 };
Christian Könige32eb502011-10-23 12:56:27 +02001531 struct radeon_ring *ring;
Christian Königb90ca982012-07-04 21:36:53 +02001532 int i, r;
Alex Deucher0c88a022011-03-02 20:07:31 -05001533
1534 /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
1535 WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
1536 SOFT_RESET_PA |
1537 SOFT_RESET_SH |
1538 SOFT_RESET_VGT |
Jerome Glissea49a50d2011-08-24 20:00:17 +00001539 SOFT_RESET_SPI |
Alex Deucher0c88a022011-03-02 20:07:31 -05001540 SOFT_RESET_SX));
1541 RREG32(GRBM_SOFT_RESET);
1542 mdelay(15);
1543 WREG32(GRBM_SOFT_RESET, 0);
1544 RREG32(GRBM_SOFT_RESET);
1545
Christian König15d33322011-09-15 19:02:22 +02001546 WREG32(CP_SEM_WAIT_TIMER, 0x0);
Alex Deucher11ef3f1f2012-01-20 14:47:43 -05001547 WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001548
1549 /* Set the write pointer delay */
1550 WREG32(CP_RB_WPTR_DELAY, 0);
1551
1552 WREG32(CP_DEBUG, (1 << 27));
1553
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001554 /* set the wb address whether it's enabled or not */
Alex Deucher0c88a022011-03-02 20:07:31 -05001555 WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
Christian Königb90ca982012-07-04 21:36:53 +02001556 WREG32(SCRATCH_UMSK, 0xff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001557
Christian Königb90ca982012-07-04 21:36:53 +02001558 for (i = 0; i < 3; ++i) {
1559 uint32_t rb_cntl;
1560 uint64_t addr;
1561
1562 /* Set ring buffer size */
1563 ring = &rdev->ring[ridx[i]];
1564 rb_cntl = drm_order(ring->ring_size / 8);
1565 rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
1566#ifdef __BIG_ENDIAN
1567 rb_cntl |= BUF_SWAP_32BIT;
1568#endif
1569 WREG32(cp_rb_cntl[i], rb_cntl);
1570
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001571 /* set the wb address whether it's enabled or not */
Christian Königb90ca982012-07-04 21:36:53 +02001572 addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1573 WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1574 WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
Alex Deucher0c88a022011-03-02 20:07:31 -05001575 }
1576
Christian Königb90ca982012-07-04 21:36:53 +02001577 /* set the rb base addr, this causes an internal reset of ALL rings */
1578 for (i = 0; i < 3; ++i) {
1579 ring = &rdev->ring[ridx[i]];
1580 WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1581 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001582
Christian Königb90ca982012-07-04 21:36:53 +02001583 for (i = 0; i < 3; ++i) {
1584 /* Initialize the ring buffer's read and write pointers */
1585 ring = &rdev->ring[ridx[i]];
1586 WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
Alex Deucher0c88a022011-03-02 20:07:31 -05001587
Christian Königb90ca982012-07-04 21:36:53 +02001588 ring->rptr = ring->wptr = 0;
1589 WREG32(ring->rptr_reg, ring->rptr);
1590 WREG32(ring->wptr_reg, ring->wptr);
Alex Deucher0c88a022011-03-02 20:07:31 -05001591
Christian Königb90ca982012-07-04 21:36:53 +02001592 mdelay(1);
1593 WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1594 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001595
1596 /* start the rings */
1597 cayman_cp_start(rdev);
Christian Könige32eb502011-10-23 12:56:27 +02001598 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1599 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1600 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001601 /* this only test cp0 */
Alex Deucherf7128122012-02-23 17:53:45 -05001602 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001603 if (r) {
Christian Könige32eb502011-10-23 12:56:27 +02001604 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1605 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1606 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001607 return r;
1608 }
1609
1610 return 0;
1611}
1612
Alex Deucherf60cbd12012-12-04 15:27:33 -05001613/*
1614 * DMA
1615 * Starting with R600, the GPU has an asynchronous
1616 * DMA engine. The programming model is very similar
1617 * to the 3D engine (ring buffer, IBs, etc.), but the
1618 * DMA controller has it's own packet format that is
1619 * different form the PM4 format used by the 3D engine.
1620 * It supports copying data, writing embedded data,
1621 * solid fills, and a number of other things. It also
1622 * has support for tiling/detiling of buffers.
1623 * Cayman and newer support two asynchronous DMA engines.
1624 */
1625/**
1626 * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
1627 *
1628 * @rdev: radeon_device pointer
1629 * @ib: IB object to schedule
1630 *
1631 * Schedule an IB in the DMA ring (cayman-SI).
1632 */
1633void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
1634 struct radeon_ib *ib)
1635{
1636 struct radeon_ring *ring = &rdev->ring[ib->ring];
1637
1638 if (rdev->wb.enabled) {
1639 u32 next_rptr = ring->wptr + 4;
1640 while ((next_rptr & 7) != 5)
1641 next_rptr++;
1642 next_rptr += 3;
1643 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
1644 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
1645 radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
1646 radeon_ring_write(ring, next_rptr);
1647 }
1648
1649 /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
1650 * Pad as necessary with NOPs.
1651 */
1652 while ((ring->wptr & 7) != 5)
1653 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
1654 radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0));
1655 radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
1656 radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
1657
1658}
1659
1660/**
1661 * cayman_dma_stop - stop the async dma engines
1662 *
1663 * @rdev: radeon_device pointer
1664 *
1665 * Stop the async dma engines (cayman-SI).
1666 */
1667void cayman_dma_stop(struct radeon_device *rdev)
1668{
1669 u32 rb_cntl;
1670
1671 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1672
1673 /* dma0 */
1674 rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1675 rb_cntl &= ~DMA_RB_ENABLE;
1676 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl);
1677
1678 /* dma1 */
1679 rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1680 rb_cntl &= ~DMA_RB_ENABLE;
1681 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl);
1682
1683 rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
1684 rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false;
1685}
1686
1687/**
1688 * cayman_dma_resume - setup and start the async dma engines
1689 *
1690 * @rdev: radeon_device pointer
1691 *
1692 * Set up the DMA ring buffers and enable them. (cayman-SI).
1693 * Returns 0 for success, error for failure.
1694 */
1695int cayman_dma_resume(struct radeon_device *rdev)
1696{
1697 struct radeon_ring *ring;
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001698 u32 rb_cntl, dma_cntl, ib_cntl;
Alex Deucherf60cbd12012-12-04 15:27:33 -05001699 u32 rb_bufsz;
1700 u32 reg_offset, wb_offset;
1701 int i, r;
1702
1703 /* Reset dma */
1704 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
1705 RREG32(SRBM_SOFT_RESET);
1706 udelay(50);
1707 WREG32(SRBM_SOFT_RESET, 0);
1708
1709 for (i = 0; i < 2; i++) {
1710 if (i == 0) {
1711 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
1712 reg_offset = DMA0_REGISTER_OFFSET;
1713 wb_offset = R600_WB_DMA_RPTR_OFFSET;
1714 } else {
1715 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
1716 reg_offset = DMA1_REGISTER_OFFSET;
1717 wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET;
1718 }
1719
1720 WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
1721 WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
1722
1723 /* Set ring buffer size in dwords */
1724 rb_bufsz = drm_order(ring->ring_size / 4);
1725 rb_cntl = rb_bufsz << 1;
1726#ifdef __BIG_ENDIAN
1727 rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE;
1728#endif
1729 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl);
1730
1731 /* Initialize the ring buffer's read and write pointers */
1732 WREG32(DMA_RB_RPTR + reg_offset, 0);
1733 WREG32(DMA_RB_WPTR + reg_offset, 0);
1734
1735 /* set the wb address whether it's enabled or not */
1736 WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset,
1737 upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF);
1738 WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset,
1739 ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC));
1740
1741 if (rdev->wb.enabled)
1742 rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE;
1743
1744 WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);
1745
1746 /* enable DMA IBs */
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001747 ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE;
1748#ifdef __BIG_ENDIAN
1749 ib_cntl |= DMA_IB_SWAP_ENABLE;
1750#endif
1751 WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001752
1753 dma_cntl = RREG32(DMA_CNTL + reg_offset);
1754 dma_cntl &= ~CTXEMPTY_INT_ENABLE;
1755 WREG32(DMA_CNTL + reg_offset, dma_cntl);
1756
1757 ring->wptr = 0;
1758 WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2);
1759
1760 ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2;
1761
1762 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE);
1763
1764 ring->ready = true;
1765
1766 r = radeon_ring_test(rdev, ring->idx, ring);
1767 if (r) {
1768 ring->ready = false;
1769 return r;
1770 }
1771 }
1772
1773 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1774
1775 return 0;
1776}
1777
1778/**
1779 * cayman_dma_fini - tear down the async dma engines
1780 *
1781 * @rdev: radeon_device pointer
1782 *
1783 * Stop the async dma engines and free the rings (cayman-SI).
1784 */
1785void cayman_dma_fini(struct radeon_device *rdev)
1786{
1787 cayman_dma_stop(rdev);
1788 radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
1789 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
1790}
1791
Alex Deucher168757e2013-01-18 19:17:22 -05001792static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1793{
1794 u32 reset_mask = 0;
1795 u32 tmp;
1796
1797 /* GRBM_STATUS */
1798 tmp = RREG32(GRBM_STATUS);
1799 if (tmp & (PA_BUSY | SC_BUSY |
1800 SH_BUSY | SX_BUSY |
1801 TA_BUSY | VGT_BUSY |
1802 DB_BUSY | CB_BUSY |
1803 GDS_BUSY | SPI_BUSY |
1804 IA_BUSY | IA_BUSY_NO_DMA))
1805 reset_mask |= RADEON_RESET_GFX;
1806
1807 if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1808 CP_BUSY | CP_COHERENCY_BUSY))
1809 reset_mask |= RADEON_RESET_CP;
1810
1811 if (tmp & GRBM_EE_BUSY)
1812 reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1813
1814 /* DMA_STATUS_REG 0 */
1815 tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1816 if (!(tmp & DMA_IDLE))
1817 reset_mask |= RADEON_RESET_DMA;
1818
1819 /* DMA_STATUS_REG 1 */
1820 tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1821 if (!(tmp & DMA_IDLE))
1822 reset_mask |= RADEON_RESET_DMA1;
1823
1824 /* SRBM_STATUS2 */
1825 tmp = RREG32(SRBM_STATUS2);
1826 if (tmp & DMA_BUSY)
1827 reset_mask |= RADEON_RESET_DMA;
1828
1829 if (tmp & DMA1_BUSY)
1830 reset_mask |= RADEON_RESET_DMA1;
1831
1832 /* SRBM_STATUS */
1833 tmp = RREG32(SRBM_STATUS);
1834 if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1835 reset_mask |= RADEON_RESET_RLC;
1836
1837 if (tmp & IH_BUSY)
1838 reset_mask |= RADEON_RESET_IH;
1839
1840 if (tmp & SEM_BUSY)
1841 reset_mask |= RADEON_RESET_SEM;
1842
1843 if (tmp & GRBM_RQ_PENDING)
1844 reset_mask |= RADEON_RESET_GRBM;
1845
1846 if (tmp & VMC_BUSY)
1847 reset_mask |= RADEON_RESET_VMC;
1848
1849 if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1850 MCC_BUSY | MCD_BUSY))
1851 reset_mask |= RADEON_RESET_MC;
1852
1853 if (evergreen_is_display_hung(rdev))
1854 reset_mask |= RADEON_RESET_DISPLAY;
1855
1856 /* VM_L2_STATUS */
1857 tmp = RREG32(VM_L2_STATUS);
1858 if (tmp & L2_BUSY)
1859 reset_mask |= RADEON_RESET_VMC;
1860
Alex Deucherd808fc82013-02-28 10:03:08 -05001861 /* Skip MC reset as it's mostly likely not hung, just busy */
1862 if (reset_mask & RADEON_RESET_MC) {
1863 DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1864 reset_mask &= ~RADEON_RESET_MC;
1865 }
1866
Alex Deucher168757e2013-01-18 19:17:22 -05001867 return reset_mask;
1868}
1869
1870static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
Alex Deucher271d6fed2013-01-03 12:48:05 -05001871{
1872 struct evergreen_mc_save save;
Alex Deucher187e3592013-01-18 14:51:38 -05001873 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1874 u32 tmp;
Alex Deucher19fc42e2013-01-14 11:04:39 -05001875
Alex Deucher271d6fed2013-01-03 12:48:05 -05001876 if (reset_mask == 0)
Alex Deucher168757e2013-01-18 19:17:22 -05001877 return;
Alex Deucher271d6fed2013-01-03 12:48:05 -05001878
1879 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1880
Alex Deucher187e3592013-01-18 14:51:38 -05001881 evergreen_print_gpu_status_regs(rdev);
Alex Deucher271d6fed2013-01-03 12:48:05 -05001882 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1883 RREG32(0x14F8));
1884 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1885 RREG32(0x14D8));
1886 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
1887 RREG32(0x14FC));
1888 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1889 RREG32(0x14DC));
1890
Alex Deucher187e3592013-01-18 14:51:38 -05001891 /* Disable CP parsing/prefetching */
1892 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1893
1894 if (reset_mask & RADEON_RESET_DMA) {
1895 /* dma0 */
1896 tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1897 tmp &= ~DMA_RB_ENABLE;
1898 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
Alex Deucher168757e2013-01-18 19:17:22 -05001899 }
Alex Deucher187e3592013-01-18 14:51:38 -05001900
Alex Deucher168757e2013-01-18 19:17:22 -05001901 if (reset_mask & RADEON_RESET_DMA1) {
Alex Deucher187e3592013-01-18 14:51:38 -05001902 /* dma1 */
1903 tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1904 tmp &= ~DMA_RB_ENABLE;
1905 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1906 }
1907
Alex Deucher90fb8772013-01-23 18:59:17 -05001908 udelay(50);
1909
1910 evergreen_mc_stop(rdev, &save);
1911 if (evergreen_mc_wait_for_idle(rdev)) {
1912 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1913 }
1914
Alex Deucher187e3592013-01-18 14:51:38 -05001915 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1916 grbm_soft_reset = SOFT_RESET_CB |
1917 SOFT_RESET_DB |
1918 SOFT_RESET_GDS |
1919 SOFT_RESET_PA |
1920 SOFT_RESET_SC |
1921 SOFT_RESET_SPI |
1922 SOFT_RESET_SH |
1923 SOFT_RESET_SX |
1924 SOFT_RESET_TC |
1925 SOFT_RESET_TA |
1926 SOFT_RESET_VGT |
1927 SOFT_RESET_IA;
1928 }
1929
1930 if (reset_mask & RADEON_RESET_CP) {
1931 grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1932
1933 srbm_soft_reset |= SOFT_RESET_GRBM;
1934 }
Alex Deucher271d6fed2013-01-03 12:48:05 -05001935
1936 if (reset_mask & RADEON_RESET_DMA)
Alex Deucher168757e2013-01-18 19:17:22 -05001937 srbm_soft_reset |= SOFT_RESET_DMA;
1938
1939 if (reset_mask & RADEON_RESET_DMA1)
1940 srbm_soft_reset |= SOFT_RESET_DMA1;
1941
1942 if (reset_mask & RADEON_RESET_DISPLAY)
1943 srbm_soft_reset |= SOFT_RESET_DC;
1944
1945 if (reset_mask & RADEON_RESET_RLC)
1946 srbm_soft_reset |= SOFT_RESET_RLC;
1947
1948 if (reset_mask & RADEON_RESET_SEM)
1949 srbm_soft_reset |= SOFT_RESET_SEM;
1950
1951 if (reset_mask & RADEON_RESET_IH)
1952 srbm_soft_reset |= SOFT_RESET_IH;
1953
1954 if (reset_mask & RADEON_RESET_GRBM)
1955 srbm_soft_reset |= SOFT_RESET_GRBM;
1956
1957 if (reset_mask & RADEON_RESET_VMC)
1958 srbm_soft_reset |= SOFT_RESET_VMC;
1959
Alex Deucher24178ec2013-01-24 15:00:17 -05001960 if (!(rdev->flags & RADEON_IS_IGP)) {
1961 if (reset_mask & RADEON_RESET_MC)
1962 srbm_soft_reset |= SOFT_RESET_MC;
1963 }
Alex Deucher187e3592013-01-18 14:51:38 -05001964
1965 if (grbm_soft_reset) {
1966 tmp = RREG32(GRBM_SOFT_RESET);
1967 tmp |= grbm_soft_reset;
1968 dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1969 WREG32(GRBM_SOFT_RESET, tmp);
1970 tmp = RREG32(GRBM_SOFT_RESET);
1971
1972 udelay(50);
1973
1974 tmp &= ~grbm_soft_reset;
1975 WREG32(GRBM_SOFT_RESET, tmp);
1976 tmp = RREG32(GRBM_SOFT_RESET);
1977 }
1978
1979 if (srbm_soft_reset) {
1980 tmp = RREG32(SRBM_SOFT_RESET);
1981 tmp |= srbm_soft_reset;
1982 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1983 WREG32(SRBM_SOFT_RESET, tmp);
1984 tmp = RREG32(SRBM_SOFT_RESET);
1985
1986 udelay(50);
1987
1988 tmp &= ~srbm_soft_reset;
1989 WREG32(SRBM_SOFT_RESET, tmp);
1990 tmp = RREG32(SRBM_SOFT_RESET);
1991 }
Alex Deucher271d6fed2013-01-03 12:48:05 -05001992
1993 /* Wait a little for things to settle down */
1994 udelay(50);
1995
Alex Deucherb9952a82011-03-02 20:07:33 -05001996 evergreen_mc_resume(rdev, &save);
Alex Deucher187e3592013-01-18 14:51:38 -05001997 udelay(50);
Alex Deucher410a3412013-01-18 13:05:39 -05001998
Alex Deucher187e3592013-01-18 14:51:38 -05001999 evergreen_print_gpu_status_regs(rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -05002000}
2001
2002int cayman_asic_reset(struct radeon_device *rdev)
2003{
Alex Deucher168757e2013-01-18 19:17:22 -05002004 u32 reset_mask;
2005
2006 reset_mask = cayman_gpu_check_soft_reset(rdev);
2007
2008 if (reset_mask)
2009 r600_set_bios_scratch_engine_hung(rdev, true);
2010
2011 cayman_gpu_soft_reset(rdev, reset_mask);
2012
2013 reset_mask = cayman_gpu_check_soft_reset(rdev);
2014
2015 if (!reset_mask)
2016 r600_set_bios_scratch_engine_hung(rdev, false);
2017
2018 return 0;
Alex Deucherb9952a82011-03-02 20:07:33 -05002019}
2020
Alex Deucherf60cbd12012-12-04 15:27:33 -05002021/**
Alex Deucher123bc182013-01-24 11:37:19 -05002022 * cayman_gfx_is_lockup - Check if the GFX engine is locked up
2023 *
2024 * @rdev: radeon_device pointer
2025 * @ring: radeon_ring structure holding ring information
2026 *
2027 * Check if the GFX engine is locked up.
2028 * Returns true if the engine appears to be locked up, false if not.
2029 */
2030bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2031{
2032 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2033
2034 if (!(reset_mask & (RADEON_RESET_GFX |
2035 RADEON_RESET_COMPUTE |
2036 RADEON_RESET_CP))) {
2037 radeon_ring_lockup_update(ring);
2038 return false;
2039 }
2040 /* force CP activities */
2041 radeon_ring_force_activity(rdev, ring);
2042 return radeon_ring_test_lockup(rdev, ring);
2043}
2044
2045/**
Alex Deucherf60cbd12012-12-04 15:27:33 -05002046 * cayman_dma_is_lockup - Check if the DMA engine is locked up
2047 *
2048 * @rdev: radeon_device pointer
2049 * @ring: radeon_ring structure holding ring information
2050 *
Alex Deucher123bc182013-01-24 11:37:19 -05002051 * Check if the async DMA engine is locked up.
Alex Deucherf60cbd12012-12-04 15:27:33 -05002052 * Returns true if the engine appears to be locked up, false if not.
2053 */
2054bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2055{
Alex Deucher123bc182013-01-24 11:37:19 -05002056 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2057 u32 mask;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002058
2059 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
Alex Deucher123bc182013-01-24 11:37:19 -05002060 mask = RADEON_RESET_DMA;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002061 else
Alex Deucher123bc182013-01-24 11:37:19 -05002062 mask = RADEON_RESET_DMA1;
2063
2064 if (!(reset_mask & mask)) {
Alex Deucherf60cbd12012-12-04 15:27:33 -05002065 radeon_ring_lockup_update(ring);
2066 return false;
2067 }
2068 /* force ring activities */
2069 radeon_ring_force_activity(rdev, ring);
2070 return radeon_ring_test_lockup(rdev, ring);
2071}
2072
Alex Deucher755d8192011-03-02 20:07:34 -05002073static int cayman_startup(struct radeon_device *rdev)
2074{
Christian Könige32eb502011-10-23 12:56:27 +02002075 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002076 int r;
2077
Ilija Hadzicb07759b2011-09-20 10:22:58 -04002078 /* enable pcie gen2 link */
2079 evergreen_pcie_gen2_enable(rdev);
Alex Deucherf52382d2013-02-15 11:02:50 -05002080 /* enable aspm */
2081 evergreen_program_aspm(rdev);
Ilija Hadzicb07759b2011-09-20 10:22:58 -04002082
Alex Deucherc420c742012-03-20 17:18:39 -04002083 if (rdev->flags & RADEON_IS_IGP) {
2084 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
2085 r = ni_init_microcode(rdev);
2086 if (r) {
2087 DRM_ERROR("Failed to load firmware!\n");
2088 return r;
2089 }
2090 }
2091 } else {
2092 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
2093 r = ni_init_microcode(rdev);
2094 if (r) {
2095 DRM_ERROR("Failed to load firmware!\n");
2096 return r;
2097 }
2098 }
2099
2100 r = ni_mc_load_microcode(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002101 if (r) {
Alex Deucherc420c742012-03-20 17:18:39 -04002102 DRM_ERROR("Failed to load MC firmware!\n");
Alex Deucher755d8192011-03-02 20:07:34 -05002103 return r;
2104 }
2105 }
Alex Deucher755d8192011-03-02 20:07:34 -05002106
Alex Deucher16cdf042011-10-28 10:30:02 -04002107 r = r600_vram_scratch_init(rdev);
2108 if (r)
2109 return r;
2110
Alex Deucher755d8192011-03-02 20:07:34 -05002111 evergreen_mc_program(rdev);
2112 r = cayman_pcie_gart_enable(rdev);
2113 if (r)
2114 return r;
2115 cayman_gpu_init(rdev);
2116
Alex Deuchercb92d452011-05-25 16:39:00 -04002117 r = evergreen_blit_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002118 if (r) {
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002119 r600_blit_fini(rdev);
Alex Deucher27cd7762012-02-23 17:53:42 -05002120 rdev->asic->copy.copy = NULL;
Alex Deucher755d8192011-03-02 20:07:34 -05002121 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
2122 }
Alex Deucher755d8192011-03-02 20:07:34 -05002123
Alex Deucherc420c742012-03-20 17:18:39 -04002124 /* allocate rlc buffers */
2125 if (rdev->flags & RADEON_IS_IGP) {
Alex Deucher2948f5e2013-04-12 13:52:52 -04002126 rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
2127 rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size;
2128 rdev->rlc.cs_data = cayman_cs_data;
2129 r = sumo_rlc_init(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002130 if (r) {
2131 DRM_ERROR("Failed to init rlc BOs!\n");
2132 return r;
2133 }
2134 }
2135
Alex Deucher755d8192011-03-02 20:07:34 -05002136 /* allocate wb buffer */
2137 r = radeon_wb_init(rdev);
2138 if (r)
2139 return r;
2140
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002141 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
2142 if (r) {
2143 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2144 return r;
2145 }
2146
Christian Königf2ba57b2013-04-08 12:41:29 +02002147 r = rv770_uvd_resume(rdev);
2148 if (!r) {
2149 r = radeon_fence_driver_start_ring(rdev,
2150 R600_RING_TYPE_UVD_INDEX);
2151 if (r)
2152 dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2153 }
2154 if (r)
2155 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2156
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002157 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
2158 if (r) {
2159 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2160 return r;
2161 }
2162
2163 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
2164 if (r) {
2165 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2166 return r;
2167 }
2168
Alex Deucherf60cbd12012-12-04 15:27:33 -05002169 r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2170 if (r) {
2171 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2172 return r;
2173 }
2174
2175 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2176 if (r) {
2177 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2178 return r;
2179 }
2180
Alex Deucher755d8192011-03-02 20:07:34 -05002181 /* Enable IRQ */
Adis Hamziće49f3952013-06-02 16:47:54 +02002182 if (!rdev->irq.installed) {
2183 r = radeon_irq_kms_init(rdev);
2184 if (r)
2185 return r;
2186 }
2187
Alex Deucher755d8192011-03-02 20:07:34 -05002188 r = r600_irq_init(rdev);
2189 if (r) {
2190 DRM_ERROR("radeon: IH init failed (%d).\n", r);
2191 radeon_irq_kms_fini(rdev);
2192 return r;
2193 }
2194 evergreen_irq_set(rdev);
2195
Christian Könige32eb502011-10-23 12:56:27 +02002196 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
Alex Deucher78c55602011-11-17 14:25:56 -05002197 CP_RB0_RPTR, CP_RB0_WPTR,
2198 0, 0xfffff, RADEON_CP_PACKET2);
Alex Deucher755d8192011-03-02 20:07:34 -05002199 if (r)
2200 return r;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002201
2202 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2203 r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
2204 DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
2205 DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
2206 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2207 if (r)
2208 return r;
2209
2210 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2211 r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
2212 DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
2213 DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
2214 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2215 if (r)
2216 return r;
2217
Alex Deucher755d8192011-03-02 20:07:34 -05002218 r = cayman_cp_load_microcode(rdev);
2219 if (r)
2220 return r;
2221 r = cayman_cp_resume(rdev);
2222 if (r)
2223 return r;
2224
Alex Deucherf60cbd12012-12-04 15:27:33 -05002225 r = cayman_dma_resume(rdev);
2226 if (r)
2227 return r;
2228
Christian Königf2ba57b2013-04-08 12:41:29 +02002229 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2230 if (ring->ring_size) {
2231 r = radeon_ring_init(rdev, ring, ring->ring_size,
2232 R600_WB_UVD_RPTR_OFFSET,
2233 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2234 0, 0xfffff, RADEON_CP_PACKET2);
2235 if (!r)
2236 r = r600_uvd_init(rdev);
2237 if (r)
2238 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2239 }
2240
Christian König2898c342012-07-05 11:55:34 +02002241 r = radeon_ib_pool_init(rdev);
2242 if (r) {
2243 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisseb15ba512011-11-15 11:48:34 -05002244 return r;
Christian König2898c342012-07-05 11:55:34 +02002245 }
Jerome Glisseb15ba512011-11-15 11:48:34 -05002246
Christian Königc6105f22012-07-05 14:32:00 +02002247 r = radeon_vm_manager_init(rdev);
2248 if (r) {
2249 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
Jerome Glisse721604a2012-01-05 22:11:05 -05002250 return r;
Christian Königc6105f22012-07-05 14:32:00 +02002251 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002252
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002253 r = r600_audio_init(rdev);
2254 if (r)
2255 return r;
2256
Alex Deucher755d8192011-03-02 20:07:34 -05002257 return 0;
2258}
2259
2260int cayman_resume(struct radeon_device *rdev)
2261{
2262 int r;
2263
2264 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2265 * posting will perform necessary task to bring back GPU into good
2266 * shape.
2267 */
2268 /* post card */
2269 atom_asic_init(rdev->mode_info.atom_context);
2270
Alex Deuchera2c96a22013-02-28 17:58:36 -05002271 /* init golden registers */
2272 ni_init_golden_registers(rdev);
2273
Jerome Glisseb15ba512011-11-15 11:48:34 -05002274 rdev->accel_working = true;
Alex Deucher755d8192011-03-02 20:07:34 -05002275 r = cayman_startup(rdev);
2276 if (r) {
2277 DRM_ERROR("cayman startup failed on resume\n");
Jerome Glisse6b7746e2012-02-20 17:57:20 -05002278 rdev->accel_working = false;
Alex Deucher755d8192011-03-02 20:07:34 -05002279 return r;
2280 }
Alex Deucher755d8192011-03-02 20:07:34 -05002281 return r;
Alex Deucher755d8192011-03-02 20:07:34 -05002282}
2283
2284int cayman_suspend(struct radeon_device *rdev)
2285{
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002286 r600_audio_fini(rdev);
Alex Deucherfa3daf92013-03-11 15:32:26 -04002287 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002288 cayman_cp_enable(rdev, false);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002289 cayman_dma_stop(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002290 r600_uvd_rbc_stop(rdev);
2291 radeon_uvd_suspend(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002292 evergreen_irq_suspend(rdev);
2293 radeon_wb_disable(rdev);
2294 cayman_pcie_gart_disable(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002295 return 0;
2296}
2297
2298/* Plan is to move initialization in that function and use
2299 * helper function so that radeon_device_init pretty much
2300 * do nothing more than calling asic specific function. This
2301 * should also allow to remove a bunch of callback function
2302 * like vram_info.
2303 */
2304int cayman_init(struct radeon_device *rdev)
2305{
Christian Könige32eb502011-10-23 12:56:27 +02002306 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002307 int r;
2308
Alex Deucher755d8192011-03-02 20:07:34 -05002309 /* Read BIOS */
2310 if (!radeon_get_bios(rdev)) {
2311 if (ASIC_IS_AVIVO(rdev))
2312 return -EINVAL;
2313 }
2314 /* Must be an ATOMBIOS */
2315 if (!rdev->is_atom_bios) {
2316 dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2317 return -EINVAL;
2318 }
2319 r = radeon_atombios_init(rdev);
2320 if (r)
2321 return r;
2322
2323 /* Post card if necessary */
2324 if (!radeon_card_posted(rdev)) {
2325 if (!rdev->bios) {
2326 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2327 return -EINVAL;
2328 }
2329 DRM_INFO("GPU not posted. posting now...\n");
2330 atom_asic_init(rdev->mode_info.atom_context);
2331 }
Alex Deuchera2c96a22013-02-28 17:58:36 -05002332 /* init golden registers */
2333 ni_init_golden_registers(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002334 /* Initialize scratch registers */
2335 r600_scratch_init(rdev);
2336 /* Initialize surface registers */
2337 radeon_surface_init(rdev);
2338 /* Initialize clocks */
2339 radeon_get_clock_info(rdev->ddev);
2340 /* Fence driver */
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002341 r = radeon_fence_driver_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002342 if (r)
2343 return r;
2344 /* initialize memory controller */
2345 r = evergreen_mc_init(rdev);
2346 if (r)
2347 return r;
2348 /* Memory manager */
2349 r = radeon_bo_init(rdev);
2350 if (r)
2351 return r;
2352
Christian Könige32eb502011-10-23 12:56:27 +02002353 ring->ring_obj = NULL;
2354 r600_ring_init(rdev, ring, 1024 * 1024);
Alex Deucher755d8192011-03-02 20:07:34 -05002355
Alex Deucherf60cbd12012-12-04 15:27:33 -05002356 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2357 ring->ring_obj = NULL;
2358 r600_ring_init(rdev, ring, 64 * 1024);
2359
2360 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2361 ring->ring_obj = NULL;
2362 r600_ring_init(rdev, ring, 64 * 1024);
2363
Christian Königf2ba57b2013-04-08 12:41:29 +02002364 r = radeon_uvd_init(rdev);
2365 if (!r) {
2366 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2367 ring->ring_obj = NULL;
2368 r600_ring_init(rdev, ring, 4096);
2369 }
2370
Alex Deucher755d8192011-03-02 20:07:34 -05002371 rdev->ih.ring_obj = NULL;
2372 r600_ih_ring_init(rdev, 64 * 1024);
2373
2374 r = r600_pcie_gart_init(rdev);
2375 if (r)
2376 return r;
2377
2378 rdev->accel_working = true;
2379 r = cayman_startup(rdev);
2380 if (r) {
2381 dev_err(rdev->dev, "disabling GPU acceleration\n");
2382 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002383 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002384 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002385 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher2948f5e2013-04-12 13:52:52 -04002386 sumo_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002387 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002388 radeon_ib_pool_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002389 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002390 radeon_irq_kms_fini(rdev);
2391 cayman_pcie_gart_fini(rdev);
2392 rdev->accel_working = false;
2393 }
Alex Deucher755d8192011-03-02 20:07:34 -05002394
2395 /* Don't start up if the MC ucode is missing.
2396 * The default clocks and voltages before the MC ucode
2397 * is loaded are not suffient for advanced operations.
Alex Deucherc420c742012-03-20 17:18:39 -04002398 *
2399 * We can skip this check for TN, because there is no MC
2400 * ucode.
Alex Deucher755d8192011-03-02 20:07:34 -05002401 */
Alex Deucherc420c742012-03-20 17:18:39 -04002402 if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
Alex Deucher755d8192011-03-02 20:07:34 -05002403 DRM_ERROR("radeon: MC ucode required for NI+.\n");
2404 return -EINVAL;
2405 }
2406
2407 return 0;
2408}
2409
2410void cayman_fini(struct radeon_device *rdev)
2411{
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002412 r600_blit_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002413 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002414 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002415 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002416 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher2948f5e2013-04-12 13:52:52 -04002417 sumo_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002418 radeon_wb_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002419 radeon_vm_manager_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002420 radeon_ib_pool_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002421 radeon_irq_kms_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002422 radeon_uvd_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002423 cayman_pcie_gart_fini(rdev);
Alex Deucher16cdf042011-10-28 10:30:02 -04002424 r600_vram_scratch_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002425 radeon_gem_fini(rdev);
2426 radeon_fence_driver_fini(rdev);
2427 radeon_bo_fini(rdev);
2428 radeon_atombios_fini(rdev);
2429 kfree(rdev->bios);
2430 rdev->bios = NULL;
2431}
2432
Jerome Glisse721604a2012-01-05 22:11:05 -05002433/*
2434 * vm
2435 */
2436int cayman_vm_init(struct radeon_device *rdev)
2437{
2438 /* number of VMs */
2439 rdev->vm_manager.nvm = 8;
2440 /* base offset of vram pages */
Alex Deuchere71270f2012-03-20 17:18:38 -04002441 if (rdev->flags & RADEON_IS_IGP) {
2442 u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2443 tmp <<= 22;
2444 rdev->vm_manager.vram_base_offset = tmp;
2445 } else
2446 rdev->vm_manager.vram_base_offset = 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002447 return 0;
2448}
2449
2450void cayman_vm_fini(struct radeon_device *rdev)
2451{
2452}
2453
Christian Königdce34bf2012-09-17 19:36:18 +02002454#define R600_ENTRY_VALID (1 << 0)
Jerome Glisse721604a2012-01-05 22:11:05 -05002455#define R600_PTE_SYSTEM (1 << 1)
2456#define R600_PTE_SNOOPED (1 << 2)
2457#define R600_PTE_READABLE (1 << 5)
2458#define R600_PTE_WRITEABLE (1 << 6)
2459
Christian König089a7862012-08-11 11:54:05 +02002460uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002461{
2462 uint32_t r600_flags = 0;
Christian Königdce34bf2012-09-17 19:36:18 +02002463 r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002464 r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
2465 r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
2466 if (flags & RADEON_VM_PAGE_SYSTEM) {
2467 r600_flags |= R600_PTE_SYSTEM;
2468 r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0;
2469 }
2470 return r600_flags;
2471}
2472
Alex Deucher7a083292012-08-31 13:51:21 -04002473/**
2474 * cayman_vm_set_page - update the page tables using the CP
2475 *
2476 * @rdev: radeon_device pointer
Alex Deucher43f12142013-02-01 17:32:42 +01002477 * @ib: indirect buffer to fill with commands
Christian Königdce34bf2012-09-17 19:36:18 +02002478 * @pe: addr of the page entry
2479 * @addr: dst addr to write into pe
2480 * @count: number of page entries to update
2481 * @incr: increase next addr by incr bytes
2482 * @flags: access flags
Alex Deucher7a083292012-08-31 13:51:21 -04002483 *
Alex Deucher43f12142013-02-01 17:32:42 +01002484 * Update the page tables using the CP (cayman/TN).
Alex Deucher7a083292012-08-31 13:51:21 -04002485 */
Alex Deucher43f12142013-02-01 17:32:42 +01002486void cayman_vm_set_page(struct radeon_device *rdev,
2487 struct radeon_ib *ib,
2488 uint64_t pe,
Christian Königdce34bf2012-09-17 19:36:18 +02002489 uint64_t addr, unsigned count,
2490 uint32_t incr, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002491{
Christian Königdce34bf2012-09-17 19:36:18 +02002492 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002493 uint64_t value;
2494 unsigned ndw;
Jerome Glisse721604a2012-01-05 22:11:05 -05002495
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002496 if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
2497 while (count) {
2498 ndw = 1 + count * 2;
2499 if (ndw > 0x3FFF)
2500 ndw = 0x3FFF;
Christian König089a7862012-08-11 11:54:05 +02002501
Alex Deucher43f12142013-02-01 17:32:42 +01002502 ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw);
2503 ib->ptr[ib->length_dw++] = pe;
2504 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002505 for (; ndw > 1; ndw -= 2, --count, pe += 8) {
2506 if (flags & RADEON_VM_PAGE_SYSTEM) {
2507 value = radeon_vm_map_gart(rdev, addr);
2508 value &= 0xFFFFFFFFFFFFF000ULL;
2509 } else if (flags & RADEON_VM_PAGE_VALID) {
2510 value = addr;
2511 } else {
2512 value = 0;
2513 }
Christian Königf9fdffa2012-10-22 17:42:36 +02002514 addr += incr;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002515 value |= r600_flags;
Alex Deucher43f12142013-02-01 17:32:42 +01002516 ib->ptr[ib->length_dw++] = value;
2517 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Christian Königf9fdffa2012-10-22 17:42:36 +02002518 }
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002519 }
2520 } else {
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002521 if ((flags & RADEON_VM_PAGE_SYSTEM) ||
2522 (count == 1)) {
2523 while (count) {
2524 ndw = count * 2;
2525 if (ndw > 0xFFFFE)
2526 ndw = 0xFFFFE;
Christian Königf9fdffa2012-10-22 17:42:36 +02002527
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002528 /* for non-physically contiguous pages (system) */
2529 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
2530 ib->ptr[ib->length_dw++] = pe;
2531 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2532 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2533 if (flags & RADEON_VM_PAGE_SYSTEM) {
2534 value = radeon_vm_map_gart(rdev, addr);
2535 value &= 0xFFFFFFFFFFFFF000ULL;
2536 } else if (flags & RADEON_VM_PAGE_VALID) {
2537 value = addr;
2538 } else {
2539 value = 0;
2540 }
2541 addr += incr;
2542 value |= r600_flags;
2543 ib->ptr[ib->length_dw++] = value;
2544 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002545 }
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002546 }
2547 while (ib->length_dw & 0x7)
2548 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
2549 } else {
2550 while (count) {
2551 ndw = count * 2;
2552 if (ndw > 0xFFFFE)
2553 ndw = 0xFFFFE;
2554
2555 if (flags & RADEON_VM_PAGE_VALID)
2556 value = addr;
2557 else
2558 value = 0;
2559 /* for physically contiguous pages (vram) */
2560 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
2561 ib->ptr[ib->length_dw++] = pe; /* dst addr */
2562 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2563 ib->ptr[ib->length_dw++] = r600_flags; /* mask */
2564 ib->ptr[ib->length_dw++] = 0;
2565 ib->ptr[ib->length_dw++] = value; /* value */
Alex Deucher43f12142013-02-01 17:32:42 +01002566 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002567 ib->ptr[ib->length_dw++] = incr; /* increment size */
2568 ib->ptr[ib->length_dw++] = 0;
2569 pe += ndw * 4;
2570 addr += (ndw / 2) * incr;
2571 count -= ndw / 2;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002572 }
Christian König2a6f1ab2012-08-11 15:00:30 +02002573 }
Alex Deucher43f12142013-02-01 17:32:42 +01002574 while (ib->length_dw & 0x7)
2575 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
Christian König2a6f1ab2012-08-11 15:00:30 +02002576 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002577}
Christian König9b40e5d2012-08-08 12:22:43 +02002578
Alex Deucher7a083292012-08-31 13:51:21 -04002579/**
2580 * cayman_vm_flush - vm flush using the CP
2581 *
2582 * @rdev: radeon_device pointer
2583 *
2584 * Update the page table base and flush the VM TLB
2585 * using the CP (cayman-si).
2586 */
Alex Deucher498522b2012-10-02 14:43:38 -04002587void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
Christian König9b40e5d2012-08-08 12:22:43 +02002588{
Alex Deucher498522b2012-10-02 14:43:38 -04002589 struct radeon_ring *ring = &rdev->ring[ridx];
Christian König9b40e5d2012-08-08 12:22:43 +02002590
Christian Königee60e292012-08-09 16:21:08 +02002591 if (vm == NULL)
Christian König9b40e5d2012-08-08 12:22:43 +02002592 return;
2593
Christian Königee60e292012-08-09 16:21:08 +02002594 radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02002595 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
Christian Königee60e292012-08-09 16:21:08 +02002596
Christian König9b40e5d2012-08-08 12:22:43 +02002597 /* flush hdp cache */
2598 radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
2599 radeon_ring_write(ring, 0x1);
2600
2601 /* bits 0-7 are the VM contexts0-7 */
2602 radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
Alex Deucher498522b2012-10-02 14:43:38 -04002603 radeon_ring_write(ring, 1 << vm->id);
Christian König58f8cf52012-10-22 17:42:35 +02002604
2605 /* sync PFP to ME, otherwise we might get invalid PFP reads */
2606 radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2607 radeon_ring_write(ring, 0x0);
Alex Deucher0af62b02011-01-06 21:19:31 -05002608}
Alex Deucherf60cbd12012-12-04 15:27:33 -05002609
2610void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
2611{
2612 struct radeon_ring *ring = &rdev->ring[ridx];
2613
2614 if (vm == NULL)
2615 return;
2616
2617 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2618 radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2));
2619 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
2620
2621 /* flush hdp cache */
2622 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2623 radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
2624 radeon_ring_write(ring, 1);
2625
2626 /* bits 0-7 are the VM contexts0-7 */
2627 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2628 radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
2629 radeon_ring_write(ring, 1 << vm->id);
2630}
2631