blob: f88946160854c4775f59d9069654edd23680f7c2 [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 Deucher0af62b02011-01-06 21:19:31 -050036
Alex Deucher168757e2013-01-18 19:17:22 -050037extern bool evergreen_is_display_hung(struct radeon_device *rdev);
Alex Deucher187e3592013-01-18 14:51:38 -050038extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -050039extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
40extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
41extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
Alex Deucher755d8192011-03-02 20:07:34 -050042extern void evergreen_mc_program(struct radeon_device *rdev);
43extern void evergreen_irq_suspend(struct radeon_device *rdev);
44extern int evergreen_mc_init(struct radeon_device *rdev);
Alex Deucherd054ac12011-09-01 17:46:15 +000045extern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
Ilija Hadzicb07759b2011-09-20 10:22:58 -040046extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
Alex Deucherc420c742012-03-20 17:18:39 -040047extern void si_rlc_fini(struct radeon_device *rdev);
48extern int si_rlc_init(struct radeon_device *rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -050049
Alex Deucher0af62b02011-01-06 21:19:31 -050050#define EVERGREEN_PFP_UCODE_SIZE 1120
51#define EVERGREEN_PM4_UCODE_SIZE 1376
52#define EVERGREEN_RLC_UCODE_SIZE 768
53#define BTC_MC_UCODE_SIZE 6024
54
Alex Deucher9b8253c2011-03-02 20:07:28 -050055#define CAYMAN_PFP_UCODE_SIZE 2176
56#define CAYMAN_PM4_UCODE_SIZE 2176
57#define CAYMAN_RLC_UCODE_SIZE 1024
58#define CAYMAN_MC_UCODE_SIZE 6037
59
Alex Deucherc420c742012-03-20 17:18:39 -040060#define ARUBA_RLC_UCODE_SIZE 1536
61
Alex Deucher0af62b02011-01-06 21:19:31 -050062/* Firmware Names */
63MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
64MODULE_FIRMWARE("radeon/BARTS_me.bin");
65MODULE_FIRMWARE("radeon/BARTS_mc.bin");
66MODULE_FIRMWARE("radeon/BTC_rlc.bin");
67MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
68MODULE_FIRMWARE("radeon/TURKS_me.bin");
69MODULE_FIRMWARE("radeon/TURKS_mc.bin");
70MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
71MODULE_FIRMWARE("radeon/CAICOS_me.bin");
72MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
Alex Deucher9b8253c2011-03-02 20:07:28 -050073MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
74MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
75MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
76MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
Alex Deucherc420c742012-03-20 17:18:39 -040077MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
78MODULE_FIRMWARE("radeon/ARUBA_me.bin");
79MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
Alex Deucher0af62b02011-01-06 21:19:31 -050080
Alex Deuchera2c96a22013-02-28 17:58:36 -050081
82static const u32 cayman_golden_registers2[] =
83{
84 0x3e5c, 0xffffffff, 0x00000000,
85 0x3e48, 0xffffffff, 0x00000000,
86 0x3e4c, 0xffffffff, 0x00000000,
87 0x3e64, 0xffffffff, 0x00000000,
88 0x3e50, 0xffffffff, 0x00000000,
89 0x3e60, 0xffffffff, 0x00000000
90};
91
92static const u32 cayman_golden_registers[] =
93{
94 0x5eb4, 0xffffffff, 0x00000002,
95 0x5e78, 0x8f311ff1, 0x001000f0,
96 0x3f90, 0xffff0000, 0xff000000,
97 0x9148, 0xffff0000, 0xff000000,
98 0x3f94, 0xffff0000, 0xff000000,
99 0x914c, 0xffff0000, 0xff000000,
100 0xc78, 0x00000080, 0x00000080,
101 0xbd4, 0x70073777, 0x00011003,
102 0xd02c, 0xbfffff1f, 0x08421000,
103 0xd0b8, 0x73773777, 0x02011003,
104 0x5bc0, 0x00200000, 0x50100000,
105 0x98f8, 0x33773777, 0x02011003,
106 0x98fc, 0xffffffff, 0x76541032,
107 0x7030, 0x31000311, 0x00000011,
108 0x2f48, 0x33773777, 0x42010001,
109 0x6b28, 0x00000010, 0x00000012,
110 0x7728, 0x00000010, 0x00000012,
111 0x10328, 0x00000010, 0x00000012,
112 0x10f28, 0x00000010, 0x00000012,
113 0x11b28, 0x00000010, 0x00000012,
114 0x12728, 0x00000010, 0x00000012,
115 0x240c, 0x000007ff, 0x00000000,
116 0x8a14, 0xf000001f, 0x00000007,
117 0x8b24, 0x3fff3fff, 0x00ff0fff,
118 0x8b10, 0x0000ff0f, 0x00000000,
119 0x28a4c, 0x07ffffff, 0x06000000,
120 0x10c, 0x00000001, 0x00010003,
121 0xa02c, 0xffffffff, 0x0000009b,
122 0x913c, 0x0000010f, 0x01000100,
123 0x8c04, 0xf8ff00ff, 0x40600060,
124 0x28350, 0x00000f01, 0x00000000,
125 0x9508, 0x3700001f, 0x00000002,
126 0x960c, 0xffffffff, 0x54763210,
127 0x88c4, 0x001f3ae3, 0x00000082,
128 0x88d0, 0xffffffff, 0x0f40df40,
129 0x88d4, 0x0000001f, 0x00000010,
130 0x8974, 0xffffffff, 0x00000000
131};
132
133static const u32 dvst_golden_registers2[] =
134{
135 0x8f8, 0xffffffff, 0,
136 0x8fc, 0x00380000, 0,
137 0x8f8, 0xffffffff, 1,
138 0x8fc, 0x0e000000, 0
139};
140
141static const u32 dvst_golden_registers[] =
142{
143 0x690, 0x3fff3fff, 0x20c00033,
144 0x918c, 0x0fff0fff, 0x00010006,
145 0x91a8, 0x0fff0fff, 0x00010006,
146 0x9150, 0xffffdfff, 0x6e944040,
147 0x917c, 0x0fff0fff, 0x00030002,
148 0x9198, 0x0fff0fff, 0x00030002,
149 0x915c, 0x0fff0fff, 0x00010000,
150 0x3f90, 0xffff0001, 0xff000000,
151 0x9178, 0x0fff0fff, 0x00070000,
152 0x9194, 0x0fff0fff, 0x00070000,
153 0x9148, 0xffff0001, 0xff000000,
154 0x9190, 0x0fff0fff, 0x00090008,
155 0x91ac, 0x0fff0fff, 0x00090008,
156 0x3f94, 0xffff0000, 0xff000000,
157 0x914c, 0xffff0000, 0xff000000,
158 0x929c, 0x00000fff, 0x00000001,
159 0x55e4, 0xff607fff, 0xfc000100,
160 0x8a18, 0xff000fff, 0x00000100,
161 0x8b28, 0xff000fff, 0x00000100,
162 0x9144, 0xfffc0fff, 0x00000100,
163 0x6ed8, 0x00010101, 0x00010000,
164 0x9830, 0xffffffff, 0x00000000,
165 0x9834, 0xf00fffff, 0x00000400,
166 0x9838, 0xfffffffe, 0x00000000,
167 0xd0c0, 0xff000fff, 0x00000100,
168 0xd02c, 0xbfffff1f, 0x08421000,
169 0xd0b8, 0x73773777, 0x12010001,
170 0x5bb0, 0x000000f0, 0x00000070,
171 0x98f8, 0x73773777, 0x12010001,
172 0x98fc, 0xffffffff, 0x00000010,
173 0x9b7c, 0x00ff0000, 0x00fc0000,
174 0x8030, 0x00001f0f, 0x0000100a,
175 0x2f48, 0x73773777, 0x12010001,
176 0x2408, 0x00030000, 0x000c007f,
177 0x8a14, 0xf000003f, 0x00000007,
178 0x8b24, 0x3fff3fff, 0x00ff0fff,
179 0x8b10, 0x0000ff0f, 0x00000000,
180 0x28a4c, 0x07ffffff, 0x06000000,
181 0x4d8, 0x00000fff, 0x00000100,
182 0xa008, 0xffffffff, 0x00010000,
183 0x913c, 0xffff03ff, 0x01000100,
184 0x8c00, 0x000000ff, 0x00000003,
185 0x8c04, 0xf8ff00ff, 0x40600060,
186 0x8cf0, 0x1fff1fff, 0x08e00410,
187 0x28350, 0x00000f01, 0x00000000,
188 0x9508, 0xf700071f, 0x00000002,
189 0x960c, 0xffffffff, 0x54763210,
190 0x20ef8, 0x01ff01ff, 0x00000002,
191 0x20e98, 0xfffffbff, 0x00200000,
192 0x2015c, 0xffffffff, 0x00000f40,
193 0x88c4, 0x001f3ae3, 0x00000082,
194 0x8978, 0x3fffffff, 0x04050140,
195 0x88d4, 0x0000001f, 0x00000010,
196 0x8974, 0xffffffff, 0x00000000
197};
198
199static const u32 scrapper_golden_registers[] =
200{
201 0x690, 0x3fff3fff, 0x20c00033,
202 0x918c, 0x0fff0fff, 0x00010006,
203 0x918c, 0x0fff0fff, 0x00010006,
204 0x91a8, 0x0fff0fff, 0x00010006,
205 0x91a8, 0x0fff0fff, 0x00010006,
206 0x9150, 0xffffdfff, 0x6e944040,
207 0x9150, 0xffffdfff, 0x6e944040,
208 0x917c, 0x0fff0fff, 0x00030002,
209 0x917c, 0x0fff0fff, 0x00030002,
210 0x9198, 0x0fff0fff, 0x00030002,
211 0x9198, 0x0fff0fff, 0x00030002,
212 0x915c, 0x0fff0fff, 0x00010000,
213 0x915c, 0x0fff0fff, 0x00010000,
214 0x3f90, 0xffff0001, 0xff000000,
215 0x3f90, 0xffff0001, 0xff000000,
216 0x9178, 0x0fff0fff, 0x00070000,
217 0x9178, 0x0fff0fff, 0x00070000,
218 0x9194, 0x0fff0fff, 0x00070000,
219 0x9194, 0x0fff0fff, 0x00070000,
220 0x9148, 0xffff0001, 0xff000000,
221 0x9148, 0xffff0001, 0xff000000,
222 0x9190, 0x0fff0fff, 0x00090008,
223 0x9190, 0x0fff0fff, 0x00090008,
224 0x91ac, 0x0fff0fff, 0x00090008,
225 0x91ac, 0x0fff0fff, 0x00090008,
226 0x3f94, 0xffff0000, 0xff000000,
227 0x3f94, 0xffff0000, 0xff000000,
228 0x914c, 0xffff0000, 0xff000000,
229 0x914c, 0xffff0000, 0xff000000,
230 0x929c, 0x00000fff, 0x00000001,
231 0x929c, 0x00000fff, 0x00000001,
232 0x55e4, 0xff607fff, 0xfc000100,
233 0x8a18, 0xff000fff, 0x00000100,
234 0x8a18, 0xff000fff, 0x00000100,
235 0x8b28, 0xff000fff, 0x00000100,
236 0x8b28, 0xff000fff, 0x00000100,
237 0x9144, 0xfffc0fff, 0x00000100,
238 0x9144, 0xfffc0fff, 0x00000100,
239 0x6ed8, 0x00010101, 0x00010000,
240 0x9830, 0xffffffff, 0x00000000,
241 0x9830, 0xffffffff, 0x00000000,
242 0x9834, 0xf00fffff, 0x00000400,
243 0x9834, 0xf00fffff, 0x00000400,
244 0x9838, 0xfffffffe, 0x00000000,
245 0x9838, 0xfffffffe, 0x00000000,
246 0xd0c0, 0xff000fff, 0x00000100,
247 0xd02c, 0xbfffff1f, 0x08421000,
248 0xd02c, 0xbfffff1f, 0x08421000,
249 0xd0b8, 0x73773777, 0x12010001,
250 0xd0b8, 0x73773777, 0x12010001,
251 0x5bb0, 0x000000f0, 0x00000070,
252 0x98f8, 0x73773777, 0x12010001,
253 0x98f8, 0x73773777, 0x12010001,
254 0x98fc, 0xffffffff, 0x00000010,
255 0x98fc, 0xffffffff, 0x00000010,
256 0x9b7c, 0x00ff0000, 0x00fc0000,
257 0x9b7c, 0x00ff0000, 0x00fc0000,
258 0x8030, 0x00001f0f, 0x0000100a,
259 0x8030, 0x00001f0f, 0x0000100a,
260 0x2f48, 0x73773777, 0x12010001,
261 0x2f48, 0x73773777, 0x12010001,
262 0x2408, 0x00030000, 0x000c007f,
263 0x8a14, 0xf000003f, 0x00000007,
264 0x8a14, 0xf000003f, 0x00000007,
265 0x8b24, 0x3fff3fff, 0x00ff0fff,
266 0x8b24, 0x3fff3fff, 0x00ff0fff,
267 0x8b10, 0x0000ff0f, 0x00000000,
268 0x8b10, 0x0000ff0f, 0x00000000,
269 0x28a4c, 0x07ffffff, 0x06000000,
270 0x28a4c, 0x07ffffff, 0x06000000,
271 0x4d8, 0x00000fff, 0x00000100,
272 0x4d8, 0x00000fff, 0x00000100,
273 0xa008, 0xffffffff, 0x00010000,
274 0xa008, 0xffffffff, 0x00010000,
275 0x913c, 0xffff03ff, 0x01000100,
276 0x913c, 0xffff03ff, 0x01000100,
277 0x90e8, 0x001fffff, 0x010400c0,
278 0x8c00, 0x000000ff, 0x00000003,
279 0x8c00, 0x000000ff, 0x00000003,
280 0x8c04, 0xf8ff00ff, 0x40600060,
281 0x8c04, 0xf8ff00ff, 0x40600060,
282 0x8c30, 0x0000000f, 0x00040005,
283 0x8cf0, 0x1fff1fff, 0x08e00410,
284 0x8cf0, 0x1fff1fff, 0x08e00410,
285 0x900c, 0x00ffffff, 0x0017071f,
286 0x28350, 0x00000f01, 0x00000000,
287 0x28350, 0x00000f01, 0x00000000,
288 0x9508, 0xf700071f, 0x00000002,
289 0x9508, 0xf700071f, 0x00000002,
290 0x9688, 0x00300000, 0x0017000f,
291 0x960c, 0xffffffff, 0x54763210,
292 0x960c, 0xffffffff, 0x54763210,
293 0x20ef8, 0x01ff01ff, 0x00000002,
294 0x20e98, 0xfffffbff, 0x00200000,
295 0x2015c, 0xffffffff, 0x00000f40,
296 0x88c4, 0x001f3ae3, 0x00000082,
297 0x88c4, 0x001f3ae3, 0x00000082,
298 0x8978, 0x3fffffff, 0x04050140,
299 0x8978, 0x3fffffff, 0x04050140,
300 0x88d4, 0x0000001f, 0x00000010,
301 0x88d4, 0x0000001f, 0x00000010,
302 0x8974, 0xffffffff, 0x00000000,
303 0x8974, 0xffffffff, 0x00000000
304};
305
306static void ni_init_golden_registers(struct radeon_device *rdev)
307{
308 switch (rdev->family) {
309 case CHIP_CAYMAN:
310 radeon_program_register_sequence(rdev,
311 cayman_golden_registers,
312 (const u32)ARRAY_SIZE(cayman_golden_registers));
313 radeon_program_register_sequence(rdev,
314 cayman_golden_registers2,
315 (const u32)ARRAY_SIZE(cayman_golden_registers2));
316 break;
317 case CHIP_ARUBA:
318 if ((rdev->pdev->device == 0x9900) ||
319 (rdev->pdev->device == 0x9901) ||
320 (rdev->pdev->device == 0x9903) ||
321 (rdev->pdev->device == 0x9904) ||
322 (rdev->pdev->device == 0x9905) ||
323 (rdev->pdev->device == 0x9906) ||
324 (rdev->pdev->device == 0x9907) ||
325 (rdev->pdev->device == 0x9908) ||
326 (rdev->pdev->device == 0x9909) ||
327 (rdev->pdev->device == 0x990A) ||
328 (rdev->pdev->device == 0x990B) ||
329 (rdev->pdev->device == 0x990C) ||
330 (rdev->pdev->device == 0x990D) ||
331 (rdev->pdev->device == 0x990E) ||
332 (rdev->pdev->device == 0x990F) ||
333 (rdev->pdev->device == 0x9910) ||
334 (rdev->pdev->device == 0x9913) ||
335 (rdev->pdev->device == 0x9917) ||
336 (rdev->pdev->device == 0x9918)) {
337 radeon_program_register_sequence(rdev,
338 dvst_golden_registers,
339 (const u32)ARRAY_SIZE(dvst_golden_registers));
340 radeon_program_register_sequence(rdev,
341 dvst_golden_registers2,
342 (const u32)ARRAY_SIZE(dvst_golden_registers2));
343 } else {
344 radeon_program_register_sequence(rdev,
345 scrapper_golden_registers,
346 (const u32)ARRAY_SIZE(scrapper_golden_registers));
347 radeon_program_register_sequence(rdev,
348 dvst_golden_registers2,
349 (const u32)ARRAY_SIZE(dvst_golden_registers2));
350 }
351 break;
352 default:
353 break;
354 }
355}
356
Alex Deucher0af62b02011-01-06 21:19:31 -0500357#define BTC_IO_MC_REGS_SIZE 29
358
359static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
360 {0x00000077, 0xff010100},
361 {0x00000078, 0x00000000},
362 {0x00000079, 0x00001434},
363 {0x0000007a, 0xcc08ec08},
364 {0x0000007b, 0x00040000},
365 {0x0000007c, 0x000080c0},
366 {0x0000007d, 0x09000000},
367 {0x0000007e, 0x00210404},
368 {0x00000081, 0x08a8e800},
369 {0x00000082, 0x00030444},
370 {0x00000083, 0x00000000},
371 {0x00000085, 0x00000001},
372 {0x00000086, 0x00000002},
373 {0x00000087, 0x48490000},
374 {0x00000088, 0x20244647},
375 {0x00000089, 0x00000005},
376 {0x0000008b, 0x66030000},
377 {0x0000008c, 0x00006603},
378 {0x0000008d, 0x00000100},
379 {0x0000008f, 0x00001c0a},
380 {0x00000090, 0xff000001},
381 {0x00000094, 0x00101101},
382 {0x00000095, 0x00000fff},
383 {0x00000096, 0x00116fff},
384 {0x00000097, 0x60010000},
385 {0x00000098, 0x10010000},
386 {0x00000099, 0x00006000},
387 {0x0000009a, 0x00001000},
388 {0x0000009f, 0x00946a00}
389};
390
391static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
392 {0x00000077, 0xff010100},
393 {0x00000078, 0x00000000},
394 {0x00000079, 0x00001434},
395 {0x0000007a, 0xcc08ec08},
396 {0x0000007b, 0x00040000},
397 {0x0000007c, 0x000080c0},
398 {0x0000007d, 0x09000000},
399 {0x0000007e, 0x00210404},
400 {0x00000081, 0x08a8e800},
401 {0x00000082, 0x00030444},
402 {0x00000083, 0x00000000},
403 {0x00000085, 0x00000001},
404 {0x00000086, 0x00000002},
405 {0x00000087, 0x48490000},
406 {0x00000088, 0x20244647},
407 {0x00000089, 0x00000005},
408 {0x0000008b, 0x66030000},
409 {0x0000008c, 0x00006603},
410 {0x0000008d, 0x00000100},
411 {0x0000008f, 0x00001c0a},
412 {0x00000090, 0xff000001},
413 {0x00000094, 0x00101101},
414 {0x00000095, 0x00000fff},
415 {0x00000096, 0x00116fff},
416 {0x00000097, 0x60010000},
417 {0x00000098, 0x10010000},
418 {0x00000099, 0x00006000},
419 {0x0000009a, 0x00001000},
420 {0x0000009f, 0x00936a00}
421};
422
423static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
424 {0x00000077, 0xff010100},
425 {0x00000078, 0x00000000},
426 {0x00000079, 0x00001434},
427 {0x0000007a, 0xcc08ec08},
428 {0x0000007b, 0x00040000},
429 {0x0000007c, 0x000080c0},
430 {0x0000007d, 0x09000000},
431 {0x0000007e, 0x00210404},
432 {0x00000081, 0x08a8e800},
433 {0x00000082, 0x00030444},
434 {0x00000083, 0x00000000},
435 {0x00000085, 0x00000001},
436 {0x00000086, 0x00000002},
437 {0x00000087, 0x48490000},
438 {0x00000088, 0x20244647},
439 {0x00000089, 0x00000005},
440 {0x0000008b, 0x66030000},
441 {0x0000008c, 0x00006603},
442 {0x0000008d, 0x00000100},
443 {0x0000008f, 0x00001c0a},
444 {0x00000090, 0xff000001},
445 {0x00000094, 0x00101101},
446 {0x00000095, 0x00000fff},
447 {0x00000096, 0x00116fff},
448 {0x00000097, 0x60010000},
449 {0x00000098, 0x10010000},
450 {0x00000099, 0x00006000},
451 {0x0000009a, 0x00001000},
452 {0x0000009f, 0x00916a00}
453};
454
Alex Deucher9b8253c2011-03-02 20:07:28 -0500455static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
456 {0x00000077, 0xff010100},
457 {0x00000078, 0x00000000},
458 {0x00000079, 0x00001434},
459 {0x0000007a, 0xcc08ec08},
460 {0x0000007b, 0x00040000},
461 {0x0000007c, 0x000080c0},
462 {0x0000007d, 0x09000000},
463 {0x0000007e, 0x00210404},
464 {0x00000081, 0x08a8e800},
465 {0x00000082, 0x00030444},
466 {0x00000083, 0x00000000},
467 {0x00000085, 0x00000001},
468 {0x00000086, 0x00000002},
469 {0x00000087, 0x48490000},
470 {0x00000088, 0x20244647},
471 {0x00000089, 0x00000005},
472 {0x0000008b, 0x66030000},
473 {0x0000008c, 0x00006603},
474 {0x0000008d, 0x00000100},
475 {0x0000008f, 0x00001c0a},
476 {0x00000090, 0xff000001},
477 {0x00000094, 0x00101101},
478 {0x00000095, 0x00000fff},
479 {0x00000096, 0x00116fff},
480 {0x00000097, 0x60010000},
481 {0x00000098, 0x10010000},
482 {0x00000099, 0x00006000},
483 {0x0000009a, 0x00001000},
484 {0x0000009f, 0x00976b00}
485};
486
Alex Deucher755d8192011-03-02 20:07:34 -0500487int ni_mc_load_microcode(struct radeon_device *rdev)
Alex Deucher0af62b02011-01-06 21:19:31 -0500488{
489 const __be32 *fw_data;
490 u32 mem_type, running, blackout = 0;
491 u32 *io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500492 int i, ucode_size, regs_size;
Alex Deucher0af62b02011-01-06 21:19:31 -0500493
494 if (!rdev->mc_fw)
495 return -EINVAL;
496
497 switch (rdev->family) {
498 case CHIP_BARTS:
499 io_mc_regs = (u32 *)&barts_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500500 ucode_size = BTC_MC_UCODE_SIZE;
501 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500502 break;
503 case CHIP_TURKS:
504 io_mc_regs = (u32 *)&turks_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500505 ucode_size = BTC_MC_UCODE_SIZE;
506 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500507 break;
508 case CHIP_CAICOS:
509 default:
510 io_mc_regs = (u32 *)&caicos_io_mc_regs;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500511 ucode_size = BTC_MC_UCODE_SIZE;
512 regs_size = BTC_IO_MC_REGS_SIZE;
513 break;
514 case CHIP_CAYMAN:
515 io_mc_regs = (u32 *)&cayman_io_mc_regs;
516 ucode_size = CAYMAN_MC_UCODE_SIZE;
517 regs_size = BTC_IO_MC_REGS_SIZE;
Alex Deucher0af62b02011-01-06 21:19:31 -0500518 break;
519 }
520
521 mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
522 running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
523
524 if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
525 if (running) {
526 blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
527 WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
528 }
529
530 /* reset the engine and set to writable */
531 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
532 WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
533
534 /* load mc io regs */
Alex Deucher9b8253c2011-03-02 20:07:28 -0500535 for (i = 0; i < regs_size; i++) {
Alex Deucher0af62b02011-01-06 21:19:31 -0500536 WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
537 WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
538 }
539 /* load the MC ucode */
540 fw_data = (const __be32 *)rdev->mc_fw->data;
Alex Deucher9b8253c2011-03-02 20:07:28 -0500541 for (i = 0; i < ucode_size; i++)
Alex Deucher0af62b02011-01-06 21:19:31 -0500542 WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
543
544 /* put the engine back into the active state */
545 WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
546 WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
547 WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
548
549 /* wait for training to complete */
Alex Deucher0e2c9782011-11-02 18:08:25 -0400550 for (i = 0; i < rdev->usec_timeout; i++) {
551 if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
552 break;
553 udelay(1);
554 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500555
556 if (running)
557 WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
558 }
559
560 return 0;
561}
562
563int ni_init_microcode(struct radeon_device *rdev)
564{
565 struct platform_device *pdev;
566 const char *chip_name;
567 const char *rlc_chip_name;
568 size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
569 char fw_name[30];
570 int err;
571
572 DRM_DEBUG("\n");
573
574 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
575 err = IS_ERR(pdev);
576 if (err) {
577 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
578 return -EINVAL;
579 }
580
581 switch (rdev->family) {
582 case CHIP_BARTS:
583 chip_name = "BARTS";
584 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500585 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
586 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
587 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
588 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500589 break;
590 case CHIP_TURKS:
591 chip_name = "TURKS";
592 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500593 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
594 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
595 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
596 mc_req_size = BTC_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500597 break;
598 case CHIP_CAICOS:
599 chip_name = "CAICOS";
600 rlc_chip_name = "BTC";
Alex Deucher9b8253c2011-03-02 20:07:28 -0500601 pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
602 me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
603 rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
604 mc_req_size = BTC_MC_UCODE_SIZE * 4;
605 break;
606 case CHIP_CAYMAN:
607 chip_name = "CAYMAN";
608 rlc_chip_name = "CAYMAN";
609 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
610 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
611 rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
612 mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
Alex Deucher0af62b02011-01-06 21:19:31 -0500613 break;
Alex Deucherc420c742012-03-20 17:18:39 -0400614 case CHIP_ARUBA:
615 chip_name = "ARUBA";
616 rlc_chip_name = "ARUBA";
617 /* pfp/me same size as CAYMAN */
618 pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
619 me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
620 rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
621 mc_req_size = 0;
622 break;
Alex Deucher0af62b02011-01-06 21:19:31 -0500623 default: BUG();
624 }
625
Alex Deucher0af62b02011-01-06 21:19:31 -0500626 DRM_INFO("Loading %s Microcode\n", chip_name);
627
628 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
629 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
630 if (err)
631 goto out;
632 if (rdev->pfp_fw->size != pfp_req_size) {
633 printk(KERN_ERR
634 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
635 rdev->pfp_fw->size, fw_name);
636 err = -EINVAL;
637 goto out;
638 }
639
640 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
641 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
642 if (err)
643 goto out;
644 if (rdev->me_fw->size != me_req_size) {
645 printk(KERN_ERR
646 "ni_cp: Bogus length %zu in firmware \"%s\"\n",
647 rdev->me_fw->size, fw_name);
648 err = -EINVAL;
649 }
650
651 snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
652 err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
653 if (err)
654 goto out;
655 if (rdev->rlc_fw->size != rlc_req_size) {
656 printk(KERN_ERR
657 "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
658 rdev->rlc_fw->size, fw_name);
659 err = -EINVAL;
660 }
661
Alex Deucherc420c742012-03-20 17:18:39 -0400662 /* no MC ucode on TN */
663 if (!(rdev->flags & RADEON_IS_IGP)) {
664 snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
665 err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
666 if (err)
667 goto out;
668 if (rdev->mc_fw->size != mc_req_size) {
669 printk(KERN_ERR
670 "ni_mc: Bogus length %zu in firmware \"%s\"\n",
671 rdev->mc_fw->size, fw_name);
672 err = -EINVAL;
673 }
Alex Deucher0af62b02011-01-06 21:19:31 -0500674 }
675out:
676 platform_device_unregister(pdev);
677
678 if (err) {
679 if (err != -EINVAL)
680 printk(KERN_ERR
681 "ni_cp: Failed to load firmware \"%s\"\n",
682 fw_name);
683 release_firmware(rdev->pfp_fw);
684 rdev->pfp_fw = NULL;
685 release_firmware(rdev->me_fw);
686 rdev->me_fw = NULL;
687 release_firmware(rdev->rlc_fw);
688 rdev->rlc_fw = NULL;
689 release_firmware(rdev->mc_fw);
690 rdev->mc_fw = NULL;
691 }
692 return err;
693}
694
Alex Deucher29a15222012-12-14 11:57:36 -0500695int tn_get_temp(struct radeon_device *rdev)
696{
697 u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
698 int actual_temp = (temp / 8) - 49;
699
700 return actual_temp * 1000;
701}
702
Alex Deucherfecf1d02011-03-02 20:07:29 -0500703/*
704 * Core functions
705 */
Alex Deucherfecf1d02011-03-02 20:07:29 -0500706static void cayman_gpu_init(struct radeon_device *rdev)
707{
Alex Deucherfecf1d02011-03-02 20:07:29 -0500708 u32 gb_addr_config = 0;
709 u32 mc_shared_chmap, mc_arb_ramcfg;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500710 u32 cgts_tcc_disable;
711 u32 sx_debug_1;
712 u32 smx_dc_ctl0;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500713 u32 cgts_sm_ctrl_reg;
714 u32 hdp_host_path_cntl;
715 u32 tmp;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400716 u32 disabled_rb_mask;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500717 int i, j;
718
719 switch (rdev->family) {
720 case CHIP_CAYMAN:
Alex Deucherfecf1d02011-03-02 20:07:29 -0500721 rdev->config.cayman.max_shader_engines = 2;
722 rdev->config.cayman.max_pipes_per_simd = 4;
723 rdev->config.cayman.max_tile_pipes = 8;
724 rdev->config.cayman.max_simds_per_se = 12;
725 rdev->config.cayman.max_backends_per_se = 4;
726 rdev->config.cayman.max_texture_channel_caches = 8;
727 rdev->config.cayman.max_gprs = 256;
728 rdev->config.cayman.max_threads = 256;
729 rdev->config.cayman.max_gs_threads = 32;
730 rdev->config.cayman.max_stack_entries = 512;
731 rdev->config.cayman.sx_num_of_sets = 8;
732 rdev->config.cayman.sx_max_export_size = 256;
733 rdev->config.cayman.sx_max_export_pos_size = 64;
734 rdev->config.cayman.sx_max_export_smx_size = 192;
735 rdev->config.cayman.max_hw_contexts = 8;
736 rdev->config.cayman.sq_num_cf_insts = 2;
737
738 rdev->config.cayman.sc_prim_fifo_size = 0x100;
739 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
740 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400741 gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500742 break;
Alex Deucher7b76e472012-03-20 17:18:36 -0400743 case CHIP_ARUBA:
744 default:
745 rdev->config.cayman.max_shader_engines = 1;
746 rdev->config.cayman.max_pipes_per_simd = 4;
747 rdev->config.cayman.max_tile_pipes = 2;
748 if ((rdev->pdev->device == 0x9900) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400749 (rdev->pdev->device == 0x9901) ||
750 (rdev->pdev->device == 0x9905) ||
751 (rdev->pdev->device == 0x9906) ||
752 (rdev->pdev->device == 0x9907) ||
753 (rdev->pdev->device == 0x9908) ||
754 (rdev->pdev->device == 0x9909) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500755 (rdev->pdev->device == 0x990B) ||
756 (rdev->pdev->device == 0x990C) ||
757 (rdev->pdev->device == 0x990F) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400758 (rdev->pdev->device == 0x9910) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500759 (rdev->pdev->device == 0x9917) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400760 (rdev->pdev->device == 0x9999) ||
761 (rdev->pdev->device == 0x999C)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400762 rdev->config.cayman.max_simds_per_se = 6;
763 rdev->config.cayman.max_backends_per_se = 2;
764 } else if ((rdev->pdev->device == 0x9903) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400765 (rdev->pdev->device == 0x9904) ||
766 (rdev->pdev->device == 0x990A) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500767 (rdev->pdev->device == 0x990D) ||
768 (rdev->pdev->device == 0x990E) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400769 (rdev->pdev->device == 0x9913) ||
Alex Deucher62d1f922013-04-25 14:06:05 -0400770 (rdev->pdev->device == 0x9918) ||
771 (rdev->pdev->device == 0x999D)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400772 rdev->config.cayman.max_simds_per_se = 4;
773 rdev->config.cayman.max_backends_per_se = 2;
Alex Deucherd430f7d2012-06-05 09:50:28 -0400774 } else if ((rdev->pdev->device == 0x9919) ||
775 (rdev->pdev->device == 0x9990) ||
776 (rdev->pdev->device == 0x9991) ||
777 (rdev->pdev->device == 0x9994) ||
Alex Deuchere4d17062013-03-08 13:44:15 -0500778 (rdev->pdev->device == 0x9995) ||
779 (rdev->pdev->device == 0x9996) ||
780 (rdev->pdev->device == 0x999A) ||
Alex Deucherd430f7d2012-06-05 09:50:28 -0400781 (rdev->pdev->device == 0x99A0)) {
Alex Deucher7b76e472012-03-20 17:18:36 -0400782 rdev->config.cayman.max_simds_per_se = 3;
783 rdev->config.cayman.max_backends_per_se = 1;
784 } else {
785 rdev->config.cayman.max_simds_per_se = 2;
786 rdev->config.cayman.max_backends_per_se = 1;
787 }
788 rdev->config.cayman.max_texture_channel_caches = 2;
789 rdev->config.cayman.max_gprs = 256;
790 rdev->config.cayman.max_threads = 256;
791 rdev->config.cayman.max_gs_threads = 32;
792 rdev->config.cayman.max_stack_entries = 512;
793 rdev->config.cayman.sx_num_of_sets = 8;
794 rdev->config.cayman.sx_max_export_size = 256;
795 rdev->config.cayman.sx_max_export_pos_size = 64;
796 rdev->config.cayman.sx_max_export_smx_size = 192;
797 rdev->config.cayman.max_hw_contexts = 8;
798 rdev->config.cayman.sq_num_cf_insts = 2;
799
800 rdev->config.cayman.sc_prim_fifo_size = 0x40;
801 rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
802 rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
Alex Deucher416a2bd2012-05-31 19:00:25 -0400803 gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
Alex Deucher7b76e472012-03-20 17:18:36 -0400804 break;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500805 }
806
807 /* Initialize HDP */
808 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
809 WREG32((0x2c14 + j), 0x00000000);
810 WREG32((0x2c18 + j), 0x00000000);
811 WREG32((0x2c1c + j), 0x00000000);
812 WREG32((0x2c20 + j), 0x00000000);
813 WREG32((0x2c24 + j), 0x00000000);
814 }
815
816 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
817
Alex Deucherd054ac12011-09-01 17:46:15 +0000818 evergreen_fix_pci_max_read_req_size(rdev);
819
Alex Deucherfecf1d02011-03-02 20:07:29 -0500820 mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
821 mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
822
Alex Deucherfecf1d02011-03-02 20:07:29 -0500823 tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
824 rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
825 if (rdev->config.cayman.mem_row_size_in_kb > 4)
826 rdev->config.cayman.mem_row_size_in_kb = 4;
827 /* XXX use MC settings? */
828 rdev->config.cayman.shader_engine_tile_size = 32;
829 rdev->config.cayman.num_gpus = 1;
830 rdev->config.cayman.multi_gpu_tile_size = 64;
831
Alex Deucherfecf1d02011-03-02 20:07:29 -0500832 tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
833 rdev->config.cayman.num_tile_pipes = (1 << tmp);
834 tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
835 rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
836 tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
837 rdev->config.cayman.num_shader_engines = tmp + 1;
838 tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
839 rdev->config.cayman.num_gpus = tmp + 1;
840 tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
841 rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
842 tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
843 rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
844
Alex Deucher416a2bd2012-05-31 19:00:25 -0400845
Alex Deucherfecf1d02011-03-02 20:07:29 -0500846 /* setup tiling info dword. gb_addr_config is not adequate since it does
847 * not have bank info, so create a custom tiling dword.
848 * bits 3:0 num_pipes
849 * bits 7:4 num_banks
850 * bits 11:8 group_size
851 * bits 15:12 row_size
852 */
853 rdev->config.cayman.tile_config = 0;
854 switch (rdev->config.cayman.num_tile_pipes) {
855 case 1:
856 default:
857 rdev->config.cayman.tile_config |= (0 << 0);
858 break;
859 case 2:
860 rdev->config.cayman.tile_config |= (1 << 0);
861 break;
862 case 4:
863 rdev->config.cayman.tile_config |= (2 << 0);
864 break;
865 case 8:
866 rdev->config.cayman.tile_config |= (3 << 0);
867 break;
868 }
Alex Deucher7b76e472012-03-20 17:18:36 -0400869
870 /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
871 if (rdev->flags & RADEON_IS_IGP)
Alex Deucher1f73cca2012-05-24 22:55:15 -0400872 rdev->config.cayman.tile_config |= 1 << 4;
Alex Deucher29d65402012-05-31 18:53:36 -0400873 else {
Alex Deucher5b23c902012-07-31 11:05:11 -0400874 switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
875 case 0: /* four banks */
Alex Deucher29d65402012-05-31 18:53:36 -0400876 rdev->config.cayman.tile_config |= 0 << 4;
Alex Deucher5b23c902012-07-31 11:05:11 -0400877 break;
878 case 1: /* eight banks */
879 rdev->config.cayman.tile_config |= 1 << 4;
880 break;
881 case 2: /* sixteen banks */
882 default:
883 rdev->config.cayman.tile_config |= 2 << 4;
884 break;
885 }
Alex Deucher29d65402012-05-31 18:53:36 -0400886 }
Alex Deucherfecf1d02011-03-02 20:07:29 -0500887 rdev->config.cayman.tile_config |=
Dave Airliecde50832011-05-19 14:14:41 +1000888 ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
Alex Deucherfecf1d02011-03-02 20:07:29 -0500889 rdev->config.cayman.tile_config |=
890 ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
891
Alex Deucher416a2bd2012-05-31 19:00:25 -0400892 tmp = 0;
893 for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
894 u32 rb_disable_bitmap;
895
896 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
897 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
898 rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
899 tmp <<= 4;
900 tmp |= rb_disable_bitmap;
901 }
902 /* enabled rb are just the one not disabled :) */
903 disabled_rb_mask = tmp;
Alex Deuchercedb6552013-04-09 10:13:22 -0400904 tmp = 0;
905 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
906 tmp |= (1 << i);
907 /* if all the backends are disabled, fix it up here */
908 if ((disabled_rb_mask & tmp) == tmp) {
909 for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
910 disabled_rb_mask &= ~(1 << i);
911 }
Alex Deucher416a2bd2012-05-31 19:00:25 -0400912
913 WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
914 WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
915
Alex Deucherfecf1d02011-03-02 20:07:29 -0500916 WREG32(GB_ADDR_CONFIG, gb_addr_config);
917 WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
Alex Deucher7c1c7c12013-04-05 10:28:08 -0400918 if (ASIC_IS_DCE6(rdev))
919 WREG32(DMIF_ADDR_CALC, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -0500920 WREG32(HDP_ADDR_CONFIG, gb_addr_config);
Alex Deucherf60cbd12012-12-04 15:27:33 -0500921 WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
922 WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
Christian König9a210592013-04-08 12:41:37 +0200923 WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
924 WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
925 WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
Alex Deucherfecf1d02011-03-02 20:07:29 -0500926
Alex Deucher8f612b22013-03-11 19:28:39 -0400927 if ((rdev->config.cayman.max_backends_per_se == 1) &&
928 (rdev->flags & RADEON_IS_IGP)) {
929 if ((disabled_rb_mask & 3) == 1) {
930 /* RB0 disabled, RB1 enabled */
931 tmp = 0x11111111;
932 } else {
933 /* RB1 disabled, RB0 enabled */
934 tmp = 0x00000000;
935 }
936 } else {
937 tmp = gb_addr_config & NUM_PIPES_MASK;
938 tmp = r6xx_remap_render_backend(rdev, tmp,
939 rdev->config.cayman.max_backends_per_se *
940 rdev->config.cayman.max_shader_engines,
941 CAYMAN_MAX_BACKENDS, disabled_rb_mask);
942 }
Alex Deucher416a2bd2012-05-31 19:00:25 -0400943 WREG32(GB_BACKEND_MAP, tmp);
Alex Deucherfecf1d02011-03-02 20:07:29 -0500944
Alex Deucher416a2bd2012-05-31 19:00:25 -0400945 cgts_tcc_disable = 0xffff0000;
946 for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
947 cgts_tcc_disable &= ~(1 << (16 + i));
Alex Deucherfecf1d02011-03-02 20:07:29 -0500948 WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
949 WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
Alex Deucherfecf1d02011-03-02 20:07:29 -0500950 WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
951 WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
952
953 /* reprogram the shader complex */
954 cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
955 for (i = 0; i < 16; i++)
956 WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
957 WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
958
959 /* set HW defaults for 3D engine */
960 WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
961
962 sx_debug_1 = RREG32(SX_DEBUG_1);
963 sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
964 WREG32(SX_DEBUG_1, sx_debug_1);
965
966 smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
967 smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
Dave Airlie285e0422011-05-09 14:54:33 +1000968 smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
Alex Deucherfecf1d02011-03-02 20:07:29 -0500969 WREG32(SMX_DC_CTL0, smx_dc_ctl0);
970
971 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
972
973 /* need to be explicitly zero-ed */
974 WREG32(VGT_OFFCHIP_LDS_BASE, 0);
975 WREG32(SQ_LSTMP_RING_BASE, 0);
976 WREG32(SQ_HSTMP_RING_BASE, 0);
977 WREG32(SQ_ESTMP_RING_BASE, 0);
978 WREG32(SQ_GSTMP_RING_BASE, 0);
979 WREG32(SQ_VSTMP_RING_BASE, 0);
980 WREG32(SQ_PSTMP_RING_BASE, 0);
981
982 WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
983
Dave Airlie285e0422011-05-09 14:54:33 +1000984 WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
985 POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
986 SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
Alex Deucherfecf1d02011-03-02 20:07:29 -0500987
Dave Airlie285e0422011-05-09 14:54:33 +1000988 WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
989 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
990 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
Alex Deucherfecf1d02011-03-02 20:07:29 -0500991
992
993 WREG32(VGT_NUM_INSTANCES, 1);
994
995 WREG32(CP_PERFMON_CNTL, 0);
996
Dave Airlie285e0422011-05-09 14:54:33 +1000997 WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
Alex Deucherfecf1d02011-03-02 20:07:29 -0500998 FETCH_FIFO_HIWATER(0x4) |
999 DONE_FIFO_HIWATER(0xe0) |
1000 ALU_UPDATE_FIFO_HIWATER(0x8)));
1001
1002 WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1003 WREG32(SQ_CONFIG, (VC_ENABLE |
1004 EXPORT_SRC_C |
1005 GFX_PRIO(0) |
1006 CS1_PRIO(0) |
1007 CS2_PRIO(1)));
1008 WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1009
1010 WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1011 FORCE_EOV_MAX_REZ_CNT(255)));
1012
1013 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1014 AUTO_INVLD_EN(ES_AND_GS_AUTO));
1015
1016 WREG32(VGT_GS_VERTEX_REUSE, 16);
1017 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1018
1019 WREG32(CB_PERF_CTR0_SEL_0, 0);
1020 WREG32(CB_PERF_CTR0_SEL_1, 0);
1021 WREG32(CB_PERF_CTR1_SEL_0, 0);
1022 WREG32(CB_PERF_CTR1_SEL_1, 0);
1023 WREG32(CB_PERF_CTR2_SEL_0, 0);
1024 WREG32(CB_PERF_CTR2_SEL_1, 0);
1025 WREG32(CB_PERF_CTR3_SEL_0, 0);
1026 WREG32(CB_PERF_CTR3_SEL_1, 0);
1027
Dave Airlie0b65f832011-05-19 14:14:42 +10001028 tmp = RREG32(HDP_MISC_CNTL);
1029 tmp |= HDP_FLUSH_INVALIDATE_CACHE;
1030 WREG32(HDP_MISC_CNTL, tmp);
1031
Alex Deucherfecf1d02011-03-02 20:07:29 -05001032 hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1033 WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1034
1035 WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1036
1037 udelay(50);
1038}
1039
Alex Deucherfa8198e2011-03-02 20:07:30 -05001040/*
1041 * GART
1042 */
1043void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1044{
1045 /* flush hdp cache */
1046 WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1047
1048 /* bits 0-7 are the VM contexts0-7 */
1049 WREG32(VM_INVALIDATE_REQUEST, 1);
1050}
1051
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001052static int cayman_pcie_gart_enable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001053{
Jerome Glisse721604a2012-01-05 22:11:05 -05001054 int i, r;
Alex Deucherfa8198e2011-03-02 20:07:30 -05001055
Jerome Glissec9a1be92011-11-03 11:16:49 -04001056 if (rdev->gart.robj == NULL) {
Alex Deucherfa8198e2011-03-02 20:07:30 -05001057 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1058 return -EINVAL;
1059 }
1060 r = radeon_gart_table_vram_pin(rdev);
1061 if (r)
1062 return r;
1063 radeon_gart_restore(rdev);
1064 /* Setup TLB control */
Jerome Glisse721604a2012-01-05 22:11:05 -05001065 WREG32(MC_VM_MX_L1_TLB_CNTL,
1066 (0xA << 7) |
1067 ENABLE_L1_TLB |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001068 ENABLE_L1_FRAGMENT_PROCESSING |
1069 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
Jerome Glisse721604a2012-01-05 22:11:05 -05001070 ENABLE_ADVANCED_DRIVER_MODEL |
Alex Deucherfa8198e2011-03-02 20:07:30 -05001071 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1072 /* Setup L2 cache */
1073 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1074 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1075 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1076 EFFECTIVE_L2_QUEUE_SIZE(7) |
1077 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1078 WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1079 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1080 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1081 /* setup context0 */
1082 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1083 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1084 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1085 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1086 (u32)(rdev->dummy_page.addr >> 12));
1087 WREG32(VM_CONTEXT0_CNTL2, 0);
1088 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1089 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
Jerome Glisse721604a2012-01-05 22:11:05 -05001090
1091 WREG32(0x15D4, 0);
1092 WREG32(0x15D8, 0);
1093 WREG32(0x15DC, 0);
1094
1095 /* empty context1-7 */
Alex Deucher23d4f1f2012-10-08 09:45:46 -04001096 /* Assign the pt base to something valid for now; the pts used for
1097 * the VMs are determined by the application and setup and assigned
1098 * on the fly in the vm part of radeon_gart.c
1099 */
Jerome Glisse721604a2012-01-05 22:11:05 -05001100 for (i = 1; i < 8; i++) {
1101 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
Alex Deucherc1a7ca02012-10-08 12:15:13 -04001102 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn);
Jerome Glisse721604a2012-01-05 22:11:05 -05001103 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1104 rdev->gart.table_addr >> 12);
1105 }
1106
1107 /* enable context1-7 */
1108 WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1109 (u32)(rdev->dummy_page.addr >> 12));
Christian Königae133a12012-09-18 15:30:44 -04001110 WREG32(VM_CONTEXT1_CNTL2, 4);
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02001111 WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
Christian Königae133a12012-09-18 15:30:44 -04001112 RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1113 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1114 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1115 DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1116 PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1117 PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1118 VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1119 VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1120 READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1121 READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1122 WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1123 WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001124
1125 cayman_pcie_gart_tlb_flush(rdev);
Tormod Voldenfcf4de52011-08-31 21:54:07 +00001126 DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1127 (unsigned)(rdev->mc.gtt_size >> 20),
1128 (unsigned long long)rdev->gart.table_addr);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001129 rdev->gart.ready = true;
1130 return 0;
1131}
1132
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001133static void cayman_pcie_gart_disable(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001134{
Alex Deucherfa8198e2011-03-02 20:07:30 -05001135 /* Disable all tables */
1136 WREG32(VM_CONTEXT0_CNTL, 0);
1137 WREG32(VM_CONTEXT1_CNTL, 0);
1138 /* Setup TLB control */
1139 WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1140 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1141 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1142 /* Setup L2 cache */
1143 WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1144 ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1145 EFFECTIVE_L2_QUEUE_SIZE(7) |
1146 CONTEXT1_IDENTITY_ACCESS_MODE(1));
1147 WREG32(VM_L2_CNTL2, 0);
1148 WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1149 L2_CACHE_BIGK_FRAGMENT_SIZE(6));
Jerome Glissec9a1be92011-11-03 11:16:49 -04001150 radeon_gart_table_vram_unpin(rdev);
Alex Deucherfa8198e2011-03-02 20:07:30 -05001151}
1152
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001153static void cayman_pcie_gart_fini(struct radeon_device *rdev)
Alex Deucherfa8198e2011-03-02 20:07:30 -05001154{
1155 cayman_pcie_gart_disable(rdev);
1156 radeon_gart_table_vram_free(rdev);
1157 radeon_gart_fini(rdev);
1158}
1159
Alex Deucher1b370782011-11-17 20:13:28 -05001160void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
1161 int ring, u32 cp_int_cntl)
1162{
1163 u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;
1164
1165 WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
1166 WREG32(CP_INT_CNTL, cp_int_cntl);
1167}
1168
Alex Deucher0c88a022011-03-02 20:07:31 -05001169/*
1170 * CP.
1171 */
Alex Deucherb40e7e12011-11-17 14:57:50 -05001172void cayman_fence_ring_emit(struct radeon_device *rdev,
1173 struct radeon_fence *fence)
1174{
1175 struct radeon_ring *ring = &rdev->ring[fence->ring];
1176 u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1177
Jerome Glisse721604a2012-01-05 22:11:05 -05001178 /* flush read cache over gart for this vmid */
1179 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1180 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
1181 radeon_ring_write(ring, 0);
Alex Deucherb40e7e12011-11-17 14:57:50 -05001182 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1183 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1184 radeon_ring_write(ring, 0xFFFFFFFF);
1185 radeon_ring_write(ring, 0);
1186 radeon_ring_write(ring, 10); /* poll interval */
1187 /* EVENT_WRITE_EOP - flush caches, send int */
1188 radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1189 radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
1190 radeon_ring_write(ring, addr & 0xffffffff);
1191 radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1192 radeon_ring_write(ring, fence->seq);
1193 radeon_ring_write(ring, 0);
1194}
1195
Jerome Glisse721604a2012-01-05 22:11:05 -05001196void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1197{
Christian König876dc9f2012-05-08 14:24:01 +02001198 struct radeon_ring *ring = &rdev->ring[ib->ring];
Jerome Glisse721604a2012-01-05 22:11:05 -05001199
1200 /* set to DX10/11 mode */
1201 radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1202 radeon_ring_write(ring, 1);
Christian König45df6802012-07-06 16:22:55 +02001203
1204 if (ring->rptr_save_reg) {
1205 uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1206 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1207 radeon_ring_write(ring, ((ring->rptr_save_reg -
1208 PACKET3_SET_CONFIG_REG_START) >> 2));
1209 radeon_ring_write(ring, next_rptr);
1210 }
1211
Jerome Glisse721604a2012-01-05 22:11:05 -05001212 radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1213 radeon_ring_write(ring,
1214#ifdef __BIG_ENDIAN
1215 (2 << 0) |
1216#endif
1217 (ib->gpu_addr & 0xFFFFFFFC));
1218 radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
Christian König4bf3dd92012-08-06 18:57:44 +02001219 radeon_ring_write(ring, ib->length_dw |
1220 (ib->vm ? (ib->vm->id << 24) : 0));
Jerome Glisse721604a2012-01-05 22:11:05 -05001221
1222 /* flush read cache over gart for this vmid */
1223 radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1224 radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
Christian König4bf3dd92012-08-06 18:57:44 +02001225 radeon_ring_write(ring, ib->vm ? ib->vm->id : 0);
Jerome Glisse721604a2012-01-05 22:11:05 -05001226 radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1227 radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA);
1228 radeon_ring_write(ring, 0xFFFFFFFF);
1229 radeon_ring_write(ring, 0);
1230 radeon_ring_write(ring, 10); /* poll interval */
1231}
1232
Christian Königf2ba57b2013-04-08 12:41:29 +02001233void cayman_uvd_semaphore_emit(struct radeon_device *rdev,
1234 struct radeon_ring *ring,
1235 struct radeon_semaphore *semaphore,
1236 bool emit_wait)
1237{
1238 uint64_t addr = semaphore->gpu_addr;
1239
1240 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0));
1241 radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF);
1242
1243 radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0));
1244 radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF);
1245
1246 radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0));
1247 radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0));
1248}
1249
Alex Deucher0c88a022011-03-02 20:07:31 -05001250static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1251{
1252 if (enable)
1253 WREG32(CP_ME_CNTL, 0);
1254 else {
Dave Airlie38f1cff2011-03-16 11:34:41 +10001255 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
Alex Deucher0c88a022011-03-02 20:07:31 -05001256 WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1257 WREG32(SCRATCH_UMSK, 0);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001258 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001259 }
1260}
1261
1262static int cayman_cp_load_microcode(struct radeon_device *rdev)
1263{
1264 const __be32 *fw_data;
1265 int i;
1266
1267 if (!rdev->me_fw || !rdev->pfp_fw)
1268 return -EINVAL;
1269
1270 cayman_cp_enable(rdev, false);
1271
1272 fw_data = (const __be32 *)rdev->pfp_fw->data;
1273 WREG32(CP_PFP_UCODE_ADDR, 0);
1274 for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
1275 WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1276 WREG32(CP_PFP_UCODE_ADDR, 0);
1277
1278 fw_data = (const __be32 *)rdev->me_fw->data;
1279 WREG32(CP_ME_RAM_WADDR, 0);
1280 for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
1281 WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1282
1283 WREG32(CP_PFP_UCODE_ADDR, 0);
1284 WREG32(CP_ME_RAM_WADDR, 0);
1285 WREG32(CP_ME_RAM_RADDR, 0);
1286 return 0;
1287}
1288
1289static int cayman_cp_start(struct radeon_device *rdev)
1290{
Christian Könige32eb502011-10-23 12:56:27 +02001291 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher0c88a022011-03-02 20:07:31 -05001292 int r, i;
1293
Christian Könige32eb502011-10-23 12:56:27 +02001294 r = radeon_ring_lock(rdev, ring, 7);
Alex Deucher0c88a022011-03-02 20:07:31 -05001295 if (r) {
1296 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1297 return r;
1298 }
Christian Könige32eb502011-10-23 12:56:27 +02001299 radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1300 radeon_ring_write(ring, 0x1);
1301 radeon_ring_write(ring, 0x0);
1302 radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1303 radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1304 radeon_ring_write(ring, 0);
1305 radeon_ring_write(ring, 0);
1306 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001307
1308 cayman_cp_enable(rdev, true);
1309
Christian Könige32eb502011-10-23 12:56:27 +02001310 r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
Alex Deucher0c88a022011-03-02 20:07:31 -05001311 if (r) {
1312 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1313 return r;
1314 }
1315
1316 /* setup clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001317 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1318 radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001319
1320 for (i = 0; i < cayman_default_size; i++)
Christian Könige32eb502011-10-23 12:56:27 +02001321 radeon_ring_write(ring, cayman_default_state[i]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001322
Christian Könige32eb502011-10-23 12:56:27 +02001323 radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1324 radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
Alex Deucher0c88a022011-03-02 20:07:31 -05001325
1326 /* set clear context state */
Christian Könige32eb502011-10-23 12:56:27 +02001327 radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1328 radeon_ring_write(ring, 0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001329
1330 /* SQ_VTX_BASE_VTX_LOC */
Christian Könige32eb502011-10-23 12:56:27 +02001331 radeon_ring_write(ring, 0xc0026f00);
1332 radeon_ring_write(ring, 0x00000000);
1333 radeon_ring_write(ring, 0x00000000);
1334 radeon_ring_write(ring, 0x00000000);
Alex Deucher0c88a022011-03-02 20:07:31 -05001335
1336 /* Clear consts */
Christian Könige32eb502011-10-23 12:56:27 +02001337 radeon_ring_write(ring, 0xc0036f00);
1338 radeon_ring_write(ring, 0x00000bc4);
1339 radeon_ring_write(ring, 0xffffffff);
1340 radeon_ring_write(ring, 0xffffffff);
1341 radeon_ring_write(ring, 0xffffffff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001342
Christian Könige32eb502011-10-23 12:56:27 +02001343 radeon_ring_write(ring, 0xc0026900);
1344 radeon_ring_write(ring, 0x00000316);
1345 radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1346 radeon_ring_write(ring, 0x00000010); /* */
Alex Deucher9b91d182011-03-02 20:07:39 -05001347
Christian Könige32eb502011-10-23 12:56:27 +02001348 radeon_ring_unlock_commit(rdev, ring);
Alex Deucher0c88a022011-03-02 20:07:31 -05001349
1350 /* XXX init other rings */
1351
1352 return 0;
1353}
1354
Alex Deucher755d8192011-03-02 20:07:34 -05001355static void cayman_cp_fini(struct radeon_device *rdev)
1356{
Christian König45df6802012-07-06 16:22:55 +02001357 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05001358 cayman_cp_enable(rdev, false);
Christian König45df6802012-07-06 16:22:55 +02001359 radeon_ring_fini(rdev, ring);
1360 radeon_scratch_free(rdev, ring->rptr_save_reg);
Alex Deucher755d8192011-03-02 20:07:34 -05001361}
1362
Lauri Kasanen1109ca02012-08-31 13:43:50 -04001363static int cayman_cp_resume(struct radeon_device *rdev)
Alex Deucher0c88a022011-03-02 20:07:31 -05001364{
Christian Königb90ca982012-07-04 21:36:53 +02001365 static const int ridx[] = {
1366 RADEON_RING_TYPE_GFX_INDEX,
1367 CAYMAN_RING_TYPE_CP1_INDEX,
1368 CAYMAN_RING_TYPE_CP2_INDEX
1369 };
1370 static const unsigned cp_rb_cntl[] = {
1371 CP_RB0_CNTL,
1372 CP_RB1_CNTL,
1373 CP_RB2_CNTL,
1374 };
1375 static const unsigned cp_rb_rptr_addr[] = {
1376 CP_RB0_RPTR_ADDR,
1377 CP_RB1_RPTR_ADDR,
1378 CP_RB2_RPTR_ADDR
1379 };
1380 static const unsigned cp_rb_rptr_addr_hi[] = {
1381 CP_RB0_RPTR_ADDR_HI,
1382 CP_RB1_RPTR_ADDR_HI,
1383 CP_RB2_RPTR_ADDR_HI
1384 };
1385 static const unsigned cp_rb_base[] = {
1386 CP_RB0_BASE,
1387 CP_RB1_BASE,
1388 CP_RB2_BASE
1389 };
Christian Könige32eb502011-10-23 12:56:27 +02001390 struct radeon_ring *ring;
Christian Königb90ca982012-07-04 21:36:53 +02001391 int i, r;
Alex Deucher0c88a022011-03-02 20:07:31 -05001392
1393 /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
1394 WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
1395 SOFT_RESET_PA |
1396 SOFT_RESET_SH |
1397 SOFT_RESET_VGT |
Jerome Glissea49a50d2011-08-24 20:00:17 +00001398 SOFT_RESET_SPI |
Alex Deucher0c88a022011-03-02 20:07:31 -05001399 SOFT_RESET_SX));
1400 RREG32(GRBM_SOFT_RESET);
1401 mdelay(15);
1402 WREG32(GRBM_SOFT_RESET, 0);
1403 RREG32(GRBM_SOFT_RESET);
1404
Christian König15d33322011-09-15 19:02:22 +02001405 WREG32(CP_SEM_WAIT_TIMER, 0x0);
Alex Deucher11ef3f12012-01-20 14:47:43 -05001406 WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
Alex Deucher0c88a022011-03-02 20:07:31 -05001407
1408 /* Set the write pointer delay */
1409 WREG32(CP_RB_WPTR_DELAY, 0);
1410
1411 WREG32(CP_DEBUG, (1 << 27));
1412
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001413 /* set the wb address whether it's enabled or not */
Alex Deucher0c88a022011-03-02 20:07:31 -05001414 WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
Christian Königb90ca982012-07-04 21:36:53 +02001415 WREG32(SCRATCH_UMSK, 0xff);
Alex Deucher0c88a022011-03-02 20:07:31 -05001416
Christian Königb90ca982012-07-04 21:36:53 +02001417 for (i = 0; i < 3; ++i) {
1418 uint32_t rb_cntl;
1419 uint64_t addr;
1420
1421 /* Set ring buffer size */
1422 ring = &rdev->ring[ridx[i]];
1423 rb_cntl = drm_order(ring->ring_size / 8);
1424 rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8;
1425#ifdef __BIG_ENDIAN
1426 rb_cntl |= BUF_SWAP_32BIT;
1427#endif
1428 WREG32(cp_rb_cntl[i], rb_cntl);
1429
Adam Buchbinder48fc7f72012-09-19 21:48:00 -04001430 /* set the wb address whether it's enabled or not */
Christian Königb90ca982012-07-04 21:36:53 +02001431 addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1432 WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1433 WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
Alex Deucher0c88a022011-03-02 20:07:31 -05001434 }
1435
Christian Königb90ca982012-07-04 21:36:53 +02001436 /* set the rb base addr, this causes an internal reset of ALL rings */
1437 for (i = 0; i < 3; ++i) {
1438 ring = &rdev->ring[ridx[i]];
1439 WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1440 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001441
Christian Königb90ca982012-07-04 21:36:53 +02001442 for (i = 0; i < 3; ++i) {
1443 /* Initialize the ring buffer's read and write pointers */
1444 ring = &rdev->ring[ridx[i]];
1445 WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
Alex Deucher0c88a022011-03-02 20:07:31 -05001446
Christian Königb90ca982012-07-04 21:36:53 +02001447 ring->rptr = ring->wptr = 0;
1448 WREG32(ring->rptr_reg, ring->rptr);
1449 WREG32(ring->wptr_reg, ring->wptr);
Alex Deucher0c88a022011-03-02 20:07:31 -05001450
Christian Königb90ca982012-07-04 21:36:53 +02001451 mdelay(1);
1452 WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1453 }
Alex Deucher0c88a022011-03-02 20:07:31 -05001454
1455 /* start the rings */
1456 cayman_cp_start(rdev);
Christian Könige32eb502011-10-23 12:56:27 +02001457 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1458 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1459 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001460 /* this only test cp0 */
Alex Deucherf7128122012-02-23 17:53:45 -05001461 r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
Alex Deucher0c88a022011-03-02 20:07:31 -05001462 if (r) {
Christian Könige32eb502011-10-23 12:56:27 +02001463 rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1464 rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1465 rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
Alex Deucher0c88a022011-03-02 20:07:31 -05001466 return r;
1467 }
1468
1469 return 0;
1470}
1471
Alex Deucherf60cbd12012-12-04 15:27:33 -05001472/*
1473 * DMA
1474 * Starting with R600, the GPU has an asynchronous
1475 * DMA engine. The programming model is very similar
1476 * to the 3D engine (ring buffer, IBs, etc.), but the
1477 * DMA controller has it's own packet format that is
1478 * different form the PM4 format used by the 3D engine.
1479 * It supports copying data, writing embedded data,
1480 * solid fills, and a number of other things. It also
1481 * has support for tiling/detiling of buffers.
1482 * Cayman and newer support two asynchronous DMA engines.
1483 */
1484/**
1485 * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine
1486 *
1487 * @rdev: radeon_device pointer
1488 * @ib: IB object to schedule
1489 *
1490 * Schedule an IB in the DMA ring (cayman-SI).
1491 */
1492void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
1493 struct radeon_ib *ib)
1494{
1495 struct radeon_ring *ring = &rdev->ring[ib->ring];
1496
1497 if (rdev->wb.enabled) {
1498 u32 next_rptr = ring->wptr + 4;
1499 while ((next_rptr & 7) != 5)
1500 next_rptr++;
1501 next_rptr += 3;
1502 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1));
1503 radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
1504 radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff);
1505 radeon_ring_write(ring, next_rptr);
1506 }
1507
1508 /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
1509 * Pad as necessary with NOPs.
1510 */
1511 while ((ring->wptr & 7) != 5)
1512 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
1513 radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0));
1514 radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
1515 radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
1516
1517}
1518
1519/**
1520 * cayman_dma_stop - stop the async dma engines
1521 *
1522 * @rdev: radeon_device pointer
1523 *
1524 * Stop the async dma engines (cayman-SI).
1525 */
1526void cayman_dma_stop(struct radeon_device *rdev)
1527{
1528 u32 rb_cntl;
1529
1530 radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1531
1532 /* dma0 */
1533 rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1534 rb_cntl &= ~DMA_RB_ENABLE;
1535 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl);
1536
1537 /* dma1 */
1538 rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1539 rb_cntl &= ~DMA_RB_ENABLE;
1540 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl);
1541
1542 rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false;
1543 rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false;
1544}
1545
1546/**
1547 * cayman_dma_resume - setup and start the async dma engines
1548 *
1549 * @rdev: radeon_device pointer
1550 *
1551 * Set up the DMA ring buffers and enable them. (cayman-SI).
1552 * Returns 0 for success, error for failure.
1553 */
1554int cayman_dma_resume(struct radeon_device *rdev)
1555{
1556 struct radeon_ring *ring;
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001557 u32 rb_cntl, dma_cntl, ib_cntl;
Alex Deucherf60cbd12012-12-04 15:27:33 -05001558 u32 rb_bufsz;
1559 u32 reg_offset, wb_offset;
1560 int i, r;
1561
1562 /* Reset dma */
1563 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
1564 RREG32(SRBM_SOFT_RESET);
1565 udelay(50);
1566 WREG32(SRBM_SOFT_RESET, 0);
1567
1568 for (i = 0; i < 2; i++) {
1569 if (i == 0) {
1570 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
1571 reg_offset = DMA0_REGISTER_OFFSET;
1572 wb_offset = R600_WB_DMA_RPTR_OFFSET;
1573 } else {
1574 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
1575 reg_offset = DMA1_REGISTER_OFFSET;
1576 wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET;
1577 }
1578
1579 WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0);
1580 WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0);
1581
1582 /* Set ring buffer size in dwords */
1583 rb_bufsz = drm_order(ring->ring_size / 4);
1584 rb_cntl = rb_bufsz << 1;
1585#ifdef __BIG_ENDIAN
1586 rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE;
1587#endif
1588 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl);
1589
1590 /* Initialize the ring buffer's read and write pointers */
1591 WREG32(DMA_RB_RPTR + reg_offset, 0);
1592 WREG32(DMA_RB_WPTR + reg_offset, 0);
1593
1594 /* set the wb address whether it's enabled or not */
1595 WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset,
1596 upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF);
1597 WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset,
1598 ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC));
1599
1600 if (rdev->wb.enabled)
1601 rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE;
1602
1603 WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8);
1604
1605 /* enable DMA IBs */
Michel Dänzerb3dfcb22013-01-24 19:02:01 +01001606 ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE;
1607#ifdef __BIG_ENDIAN
1608 ib_cntl |= DMA_IB_SWAP_ENABLE;
1609#endif
1610 WREG32(DMA_IB_CNTL + reg_offset, ib_cntl);
Alex Deucherf60cbd12012-12-04 15:27:33 -05001611
1612 dma_cntl = RREG32(DMA_CNTL + reg_offset);
1613 dma_cntl &= ~CTXEMPTY_INT_ENABLE;
1614 WREG32(DMA_CNTL + reg_offset, dma_cntl);
1615
1616 ring->wptr = 0;
1617 WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2);
1618
1619 ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2;
1620
1621 WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE);
1622
1623 ring->ready = true;
1624
1625 r = radeon_ring_test(rdev, ring->idx, ring);
1626 if (r) {
1627 ring->ready = false;
1628 return r;
1629 }
1630 }
1631
1632 radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1633
1634 return 0;
1635}
1636
1637/**
1638 * cayman_dma_fini - tear down the async dma engines
1639 *
1640 * @rdev: radeon_device pointer
1641 *
1642 * Stop the async dma engines and free the rings (cayman-SI).
1643 */
1644void cayman_dma_fini(struct radeon_device *rdev)
1645{
1646 cayman_dma_stop(rdev);
1647 radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]);
1648 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
1649}
1650
Alex Deucher168757e2013-01-18 19:17:22 -05001651static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1652{
1653 u32 reset_mask = 0;
1654 u32 tmp;
1655
1656 /* GRBM_STATUS */
1657 tmp = RREG32(GRBM_STATUS);
1658 if (tmp & (PA_BUSY | SC_BUSY |
1659 SH_BUSY | SX_BUSY |
1660 TA_BUSY | VGT_BUSY |
1661 DB_BUSY | CB_BUSY |
1662 GDS_BUSY | SPI_BUSY |
1663 IA_BUSY | IA_BUSY_NO_DMA))
1664 reset_mask |= RADEON_RESET_GFX;
1665
1666 if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1667 CP_BUSY | CP_COHERENCY_BUSY))
1668 reset_mask |= RADEON_RESET_CP;
1669
1670 if (tmp & GRBM_EE_BUSY)
1671 reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1672
1673 /* DMA_STATUS_REG 0 */
1674 tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1675 if (!(tmp & DMA_IDLE))
1676 reset_mask |= RADEON_RESET_DMA;
1677
1678 /* DMA_STATUS_REG 1 */
1679 tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1680 if (!(tmp & DMA_IDLE))
1681 reset_mask |= RADEON_RESET_DMA1;
1682
1683 /* SRBM_STATUS2 */
1684 tmp = RREG32(SRBM_STATUS2);
1685 if (tmp & DMA_BUSY)
1686 reset_mask |= RADEON_RESET_DMA;
1687
1688 if (tmp & DMA1_BUSY)
1689 reset_mask |= RADEON_RESET_DMA1;
1690
1691 /* SRBM_STATUS */
1692 tmp = RREG32(SRBM_STATUS);
1693 if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1694 reset_mask |= RADEON_RESET_RLC;
1695
1696 if (tmp & IH_BUSY)
1697 reset_mask |= RADEON_RESET_IH;
1698
1699 if (tmp & SEM_BUSY)
1700 reset_mask |= RADEON_RESET_SEM;
1701
1702 if (tmp & GRBM_RQ_PENDING)
1703 reset_mask |= RADEON_RESET_GRBM;
1704
1705 if (tmp & VMC_BUSY)
1706 reset_mask |= RADEON_RESET_VMC;
1707
1708 if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1709 MCC_BUSY | MCD_BUSY))
1710 reset_mask |= RADEON_RESET_MC;
1711
1712 if (evergreen_is_display_hung(rdev))
1713 reset_mask |= RADEON_RESET_DISPLAY;
1714
1715 /* VM_L2_STATUS */
1716 tmp = RREG32(VM_L2_STATUS);
1717 if (tmp & L2_BUSY)
1718 reset_mask |= RADEON_RESET_VMC;
1719
Alex Deucherd808fc82013-02-28 10:03:08 -05001720 /* Skip MC reset as it's mostly likely not hung, just busy */
1721 if (reset_mask & RADEON_RESET_MC) {
1722 DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1723 reset_mask &= ~RADEON_RESET_MC;
1724 }
1725
Alex Deucher168757e2013-01-18 19:17:22 -05001726 return reset_mask;
1727}
1728
1729static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
Alex Deucher271d6fe2013-01-03 12:48:05 -05001730{
1731 struct evergreen_mc_save save;
Alex Deucher187e3592013-01-18 14:51:38 -05001732 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1733 u32 tmp;
Alex Deucher19fc42e2013-01-14 11:04:39 -05001734
Alex Deucher271d6fe2013-01-03 12:48:05 -05001735 if (reset_mask == 0)
Alex Deucher168757e2013-01-18 19:17:22 -05001736 return;
Alex Deucher271d6fe2013-01-03 12:48:05 -05001737
1738 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1739
Alex Deucher187e3592013-01-18 14:51:38 -05001740 evergreen_print_gpu_status_regs(rdev);
Alex Deucher271d6fe2013-01-03 12:48:05 -05001741 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1742 RREG32(0x14F8));
1743 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1744 RREG32(0x14D8));
1745 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
1746 RREG32(0x14FC));
1747 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1748 RREG32(0x14DC));
1749
Alex Deucher187e3592013-01-18 14:51:38 -05001750 /* Disable CP parsing/prefetching */
1751 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1752
1753 if (reset_mask & RADEON_RESET_DMA) {
1754 /* dma0 */
1755 tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1756 tmp &= ~DMA_RB_ENABLE;
1757 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
Alex Deucher168757e2013-01-18 19:17:22 -05001758 }
Alex Deucher187e3592013-01-18 14:51:38 -05001759
Alex Deucher168757e2013-01-18 19:17:22 -05001760 if (reset_mask & RADEON_RESET_DMA1) {
Alex Deucher187e3592013-01-18 14:51:38 -05001761 /* dma1 */
1762 tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1763 tmp &= ~DMA_RB_ENABLE;
1764 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1765 }
1766
Alex Deucher90fb8772013-01-23 18:59:17 -05001767 udelay(50);
1768
1769 evergreen_mc_stop(rdev, &save);
1770 if (evergreen_mc_wait_for_idle(rdev)) {
1771 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1772 }
1773
Alex Deucher187e3592013-01-18 14:51:38 -05001774 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1775 grbm_soft_reset = SOFT_RESET_CB |
1776 SOFT_RESET_DB |
1777 SOFT_RESET_GDS |
1778 SOFT_RESET_PA |
1779 SOFT_RESET_SC |
1780 SOFT_RESET_SPI |
1781 SOFT_RESET_SH |
1782 SOFT_RESET_SX |
1783 SOFT_RESET_TC |
1784 SOFT_RESET_TA |
1785 SOFT_RESET_VGT |
1786 SOFT_RESET_IA;
1787 }
1788
1789 if (reset_mask & RADEON_RESET_CP) {
1790 grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1791
1792 srbm_soft_reset |= SOFT_RESET_GRBM;
1793 }
Alex Deucher271d6fe2013-01-03 12:48:05 -05001794
1795 if (reset_mask & RADEON_RESET_DMA)
Alex Deucher168757e2013-01-18 19:17:22 -05001796 srbm_soft_reset |= SOFT_RESET_DMA;
1797
1798 if (reset_mask & RADEON_RESET_DMA1)
1799 srbm_soft_reset |= SOFT_RESET_DMA1;
1800
1801 if (reset_mask & RADEON_RESET_DISPLAY)
1802 srbm_soft_reset |= SOFT_RESET_DC;
1803
1804 if (reset_mask & RADEON_RESET_RLC)
1805 srbm_soft_reset |= SOFT_RESET_RLC;
1806
1807 if (reset_mask & RADEON_RESET_SEM)
1808 srbm_soft_reset |= SOFT_RESET_SEM;
1809
1810 if (reset_mask & RADEON_RESET_IH)
1811 srbm_soft_reset |= SOFT_RESET_IH;
1812
1813 if (reset_mask & RADEON_RESET_GRBM)
1814 srbm_soft_reset |= SOFT_RESET_GRBM;
1815
1816 if (reset_mask & RADEON_RESET_VMC)
1817 srbm_soft_reset |= SOFT_RESET_VMC;
1818
Alex Deucher24178ec2013-01-24 15:00:17 -05001819 if (!(rdev->flags & RADEON_IS_IGP)) {
1820 if (reset_mask & RADEON_RESET_MC)
1821 srbm_soft_reset |= SOFT_RESET_MC;
1822 }
Alex Deucher187e3592013-01-18 14:51:38 -05001823
1824 if (grbm_soft_reset) {
1825 tmp = RREG32(GRBM_SOFT_RESET);
1826 tmp |= grbm_soft_reset;
1827 dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1828 WREG32(GRBM_SOFT_RESET, tmp);
1829 tmp = RREG32(GRBM_SOFT_RESET);
1830
1831 udelay(50);
1832
1833 tmp &= ~grbm_soft_reset;
1834 WREG32(GRBM_SOFT_RESET, tmp);
1835 tmp = RREG32(GRBM_SOFT_RESET);
1836 }
1837
1838 if (srbm_soft_reset) {
1839 tmp = RREG32(SRBM_SOFT_RESET);
1840 tmp |= srbm_soft_reset;
1841 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1842 WREG32(SRBM_SOFT_RESET, tmp);
1843 tmp = RREG32(SRBM_SOFT_RESET);
1844
1845 udelay(50);
1846
1847 tmp &= ~srbm_soft_reset;
1848 WREG32(SRBM_SOFT_RESET, tmp);
1849 tmp = RREG32(SRBM_SOFT_RESET);
1850 }
Alex Deucher271d6fe2013-01-03 12:48:05 -05001851
1852 /* Wait a little for things to settle down */
1853 udelay(50);
1854
Alex Deucherb9952a82011-03-02 20:07:33 -05001855 evergreen_mc_resume(rdev, &save);
Alex Deucher187e3592013-01-18 14:51:38 -05001856 udelay(50);
Alex Deucher410a3412013-01-18 13:05:39 -05001857
Alex Deucher187e3592013-01-18 14:51:38 -05001858 evergreen_print_gpu_status_regs(rdev);
Alex Deucherb9952a82011-03-02 20:07:33 -05001859}
1860
1861int cayman_asic_reset(struct radeon_device *rdev)
1862{
Alex Deucher168757e2013-01-18 19:17:22 -05001863 u32 reset_mask;
1864
1865 reset_mask = cayman_gpu_check_soft_reset(rdev);
1866
1867 if (reset_mask)
1868 r600_set_bios_scratch_engine_hung(rdev, true);
1869
1870 cayman_gpu_soft_reset(rdev, reset_mask);
1871
1872 reset_mask = cayman_gpu_check_soft_reset(rdev);
1873
1874 if (!reset_mask)
1875 r600_set_bios_scratch_engine_hung(rdev, false);
1876
1877 return 0;
Alex Deucherb9952a82011-03-02 20:07:33 -05001878}
1879
Alex Deucherf60cbd12012-12-04 15:27:33 -05001880/**
Alex Deucher123bc182013-01-24 11:37:19 -05001881 * cayman_gfx_is_lockup - Check if the GFX engine is locked up
1882 *
1883 * @rdev: radeon_device pointer
1884 * @ring: radeon_ring structure holding ring information
1885 *
1886 * Check if the GFX engine is locked up.
1887 * Returns true if the engine appears to be locked up, false if not.
1888 */
1889bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1890{
1891 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
1892
1893 if (!(reset_mask & (RADEON_RESET_GFX |
1894 RADEON_RESET_COMPUTE |
1895 RADEON_RESET_CP))) {
1896 radeon_ring_lockup_update(ring);
1897 return false;
1898 }
1899 /* force CP activities */
1900 radeon_ring_force_activity(rdev, ring);
1901 return radeon_ring_test_lockup(rdev, ring);
1902}
1903
1904/**
Alex Deucherf60cbd12012-12-04 15:27:33 -05001905 * cayman_dma_is_lockup - Check if the DMA engine is locked up
1906 *
1907 * @rdev: radeon_device pointer
1908 * @ring: radeon_ring structure holding ring information
1909 *
Alex Deucher123bc182013-01-24 11:37:19 -05001910 * Check if the async DMA engine is locked up.
Alex Deucherf60cbd12012-12-04 15:27:33 -05001911 * Returns true if the engine appears to be locked up, false if not.
1912 */
1913bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1914{
Alex Deucher123bc182013-01-24 11:37:19 -05001915 u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
1916 u32 mask;
Alex Deucherf60cbd12012-12-04 15:27:33 -05001917
1918 if (ring->idx == R600_RING_TYPE_DMA_INDEX)
Alex Deucher123bc182013-01-24 11:37:19 -05001919 mask = RADEON_RESET_DMA;
Alex Deucherf60cbd12012-12-04 15:27:33 -05001920 else
Alex Deucher123bc182013-01-24 11:37:19 -05001921 mask = RADEON_RESET_DMA1;
1922
1923 if (!(reset_mask & mask)) {
Alex Deucherf60cbd12012-12-04 15:27:33 -05001924 radeon_ring_lockup_update(ring);
1925 return false;
1926 }
1927 /* force ring activities */
1928 radeon_ring_force_activity(rdev, ring);
1929 return radeon_ring_test_lockup(rdev, ring);
1930}
1931
Alex Deucher755d8192011-03-02 20:07:34 -05001932static int cayman_startup(struct radeon_device *rdev)
1933{
Christian Könige32eb502011-10-23 12:56:27 +02001934 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05001935 int r;
1936
Ilija Hadzicb07759b2011-09-20 10:22:58 -04001937 /* enable pcie gen2 link */
1938 evergreen_pcie_gen2_enable(rdev);
1939
Alex Deucherc420c742012-03-20 17:18:39 -04001940 if (rdev->flags & RADEON_IS_IGP) {
1941 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1942 r = ni_init_microcode(rdev);
1943 if (r) {
1944 DRM_ERROR("Failed to load firmware!\n");
1945 return r;
1946 }
1947 }
1948 } else {
1949 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
1950 r = ni_init_microcode(rdev);
1951 if (r) {
1952 DRM_ERROR("Failed to load firmware!\n");
1953 return r;
1954 }
1955 }
1956
1957 r = ni_mc_load_microcode(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05001958 if (r) {
Alex Deucherc420c742012-03-20 17:18:39 -04001959 DRM_ERROR("Failed to load MC firmware!\n");
Alex Deucher755d8192011-03-02 20:07:34 -05001960 return r;
1961 }
1962 }
Alex Deucher755d8192011-03-02 20:07:34 -05001963
Alex Deucher16cdf042011-10-28 10:30:02 -04001964 r = r600_vram_scratch_init(rdev);
1965 if (r)
1966 return r;
1967
Alex Deucher755d8192011-03-02 20:07:34 -05001968 evergreen_mc_program(rdev);
1969 r = cayman_pcie_gart_enable(rdev);
1970 if (r)
1971 return r;
1972 cayman_gpu_init(rdev);
1973
Alex Deuchercb92d452011-05-25 16:39:00 -04001974 r = evergreen_blit_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05001975 if (r) {
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04001976 r600_blit_fini(rdev);
Alex Deucher27cd7762012-02-23 17:53:42 -05001977 rdev->asic->copy.copy = NULL;
Alex Deucher755d8192011-03-02 20:07:34 -05001978 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
1979 }
Alex Deucher755d8192011-03-02 20:07:34 -05001980
Alex Deucherc420c742012-03-20 17:18:39 -04001981 /* allocate rlc buffers */
1982 if (rdev->flags & RADEON_IS_IGP) {
1983 r = si_rlc_init(rdev);
1984 if (r) {
1985 DRM_ERROR("Failed to init rlc BOs!\n");
1986 return r;
1987 }
1988 }
1989
Alex Deucher755d8192011-03-02 20:07:34 -05001990 /* allocate wb buffer */
1991 r = radeon_wb_init(rdev);
1992 if (r)
1993 return r;
1994
Jerome Glisse30eb77f2011-11-20 20:45:34 +00001995 r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
1996 if (r) {
1997 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
1998 return r;
1999 }
2000
Christian Königf2ba57b2013-04-08 12:41:29 +02002001 r = rv770_uvd_resume(rdev);
2002 if (!r) {
2003 r = radeon_fence_driver_start_ring(rdev,
2004 R600_RING_TYPE_UVD_INDEX);
2005 if (r)
2006 dev_err(rdev->dev, "UVD fences init error (%d).\n", r);
2007 }
2008 if (r)
2009 rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2010
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002011 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
2012 if (r) {
2013 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2014 return r;
2015 }
2016
2017 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
2018 if (r) {
2019 dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2020 return r;
2021 }
2022
Alex Deucherf60cbd12012-12-04 15:27:33 -05002023 r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2024 if (r) {
2025 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2026 return r;
2027 }
2028
2029 r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2030 if (r) {
2031 dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2032 return r;
2033 }
2034
Alex Deucher755d8192011-03-02 20:07:34 -05002035 /* Enable IRQ */
Adis Hamziće49f3952013-06-02 16:47:54 +02002036 if (!rdev->irq.installed) {
2037 r = radeon_irq_kms_init(rdev);
2038 if (r)
2039 return r;
2040 }
2041
Alex Deucher755d8192011-03-02 20:07:34 -05002042 r = r600_irq_init(rdev);
2043 if (r) {
2044 DRM_ERROR("radeon: IH init failed (%d).\n", r);
2045 radeon_irq_kms_fini(rdev);
2046 return r;
2047 }
2048 evergreen_irq_set(rdev);
2049
Christian Könige32eb502011-10-23 12:56:27 +02002050 r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
Alex Deucher78c55602011-11-17 14:25:56 -05002051 CP_RB0_RPTR, CP_RB0_WPTR,
2052 0, 0xfffff, RADEON_CP_PACKET2);
Alex Deucher755d8192011-03-02 20:07:34 -05002053 if (r)
2054 return r;
Alex Deucherf60cbd12012-12-04 15:27:33 -05002055
2056 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2057 r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
2058 DMA_RB_RPTR + DMA0_REGISTER_OFFSET,
2059 DMA_RB_WPTR + DMA0_REGISTER_OFFSET,
2060 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2061 if (r)
2062 return r;
2063
2064 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2065 r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
2066 DMA_RB_RPTR + DMA1_REGISTER_OFFSET,
2067 DMA_RB_WPTR + DMA1_REGISTER_OFFSET,
2068 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2069 if (r)
2070 return r;
2071
Alex Deucher755d8192011-03-02 20:07:34 -05002072 r = cayman_cp_load_microcode(rdev);
2073 if (r)
2074 return r;
2075 r = cayman_cp_resume(rdev);
2076 if (r)
2077 return r;
2078
Alex Deucherf60cbd12012-12-04 15:27:33 -05002079 r = cayman_dma_resume(rdev);
2080 if (r)
2081 return r;
2082
Christian Königf2ba57b2013-04-08 12:41:29 +02002083 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2084 if (ring->ring_size) {
2085 r = radeon_ring_init(rdev, ring, ring->ring_size,
2086 R600_WB_UVD_RPTR_OFFSET,
2087 UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR,
2088 0, 0xfffff, RADEON_CP_PACKET2);
2089 if (!r)
2090 r = r600_uvd_init(rdev);
2091 if (r)
2092 DRM_ERROR("radeon: failed initializing UVD (%d).\n", r);
2093 }
2094
Christian König2898c342012-07-05 11:55:34 +02002095 r = radeon_ib_pool_init(rdev);
2096 if (r) {
2097 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisseb15ba512011-11-15 11:48:34 -05002098 return r;
Christian König2898c342012-07-05 11:55:34 +02002099 }
Jerome Glisseb15ba512011-11-15 11:48:34 -05002100
Christian Königc6105f22012-07-05 14:32:00 +02002101 r = radeon_vm_manager_init(rdev);
2102 if (r) {
2103 dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
Jerome Glisse721604a2012-01-05 22:11:05 -05002104 return r;
Christian Königc6105f22012-07-05 14:32:00 +02002105 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002106
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002107 r = r600_audio_init(rdev);
2108 if (r)
2109 return r;
2110
Alex Deucher755d8192011-03-02 20:07:34 -05002111 return 0;
2112}
2113
2114int cayman_resume(struct radeon_device *rdev)
2115{
2116 int r;
2117
2118 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2119 * posting will perform necessary task to bring back GPU into good
2120 * shape.
2121 */
2122 /* post card */
2123 atom_asic_init(rdev->mode_info.atom_context);
2124
Alex Deuchera2c96a22013-02-28 17:58:36 -05002125 /* init golden registers */
2126 ni_init_golden_registers(rdev);
2127
Jerome Glisseb15ba512011-11-15 11:48:34 -05002128 rdev->accel_working = true;
Alex Deucher755d8192011-03-02 20:07:34 -05002129 r = cayman_startup(rdev);
2130 if (r) {
2131 DRM_ERROR("cayman startup failed on resume\n");
Jerome Glisse6b7746e2012-02-20 17:57:20 -05002132 rdev->accel_working = false;
Alex Deucher755d8192011-03-02 20:07:34 -05002133 return r;
2134 }
Alex Deucher755d8192011-03-02 20:07:34 -05002135 return r;
Alex Deucher755d8192011-03-02 20:07:34 -05002136}
2137
2138int cayman_suspend(struct radeon_device *rdev)
2139{
Rafał Miłecki6b53a052012-06-11 12:34:01 +02002140 r600_audio_fini(rdev);
Alex Deucherfa3daf92013-03-11 15:32:26 -04002141 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002142 cayman_cp_enable(rdev, false);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002143 cayman_dma_stop(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002144 r600_uvd_rbc_stop(rdev);
2145 radeon_uvd_suspend(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002146 evergreen_irq_suspend(rdev);
2147 radeon_wb_disable(rdev);
2148 cayman_pcie_gart_disable(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002149 return 0;
2150}
2151
2152/* Plan is to move initialization in that function and use
2153 * helper function so that radeon_device_init pretty much
2154 * do nothing more than calling asic specific function. This
2155 * should also allow to remove a bunch of callback function
2156 * like vram_info.
2157 */
2158int cayman_init(struct radeon_device *rdev)
2159{
Christian Könige32eb502011-10-23 12:56:27 +02002160 struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
Alex Deucher755d8192011-03-02 20:07:34 -05002161 int r;
2162
Alex Deucher755d8192011-03-02 20:07:34 -05002163 /* Read BIOS */
2164 if (!radeon_get_bios(rdev)) {
2165 if (ASIC_IS_AVIVO(rdev))
2166 return -EINVAL;
2167 }
2168 /* Must be an ATOMBIOS */
2169 if (!rdev->is_atom_bios) {
2170 dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2171 return -EINVAL;
2172 }
2173 r = radeon_atombios_init(rdev);
2174 if (r)
2175 return r;
2176
2177 /* Post card if necessary */
2178 if (!radeon_card_posted(rdev)) {
2179 if (!rdev->bios) {
2180 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2181 return -EINVAL;
2182 }
2183 DRM_INFO("GPU not posted. posting now...\n");
2184 atom_asic_init(rdev->mode_info.atom_context);
2185 }
Alex Deuchera2c96a22013-02-28 17:58:36 -05002186 /* init golden registers */
2187 ni_init_golden_registers(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002188 /* Initialize scratch registers */
2189 r600_scratch_init(rdev);
2190 /* Initialize surface registers */
2191 radeon_surface_init(rdev);
2192 /* Initialize clocks */
2193 radeon_get_clock_info(rdev->ddev);
2194 /* Fence driver */
Jerome Glisse30eb77f2011-11-20 20:45:34 +00002195 r = radeon_fence_driver_init(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002196 if (r)
2197 return r;
2198 /* initialize memory controller */
2199 r = evergreen_mc_init(rdev);
2200 if (r)
2201 return r;
2202 /* Memory manager */
2203 r = radeon_bo_init(rdev);
2204 if (r)
2205 return r;
2206
Christian Könige32eb502011-10-23 12:56:27 +02002207 ring->ring_obj = NULL;
2208 r600_ring_init(rdev, ring, 1024 * 1024);
Alex Deucher755d8192011-03-02 20:07:34 -05002209
Alex Deucherf60cbd12012-12-04 15:27:33 -05002210 ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2211 ring->ring_obj = NULL;
2212 r600_ring_init(rdev, ring, 64 * 1024);
2213
2214 ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2215 ring->ring_obj = NULL;
2216 r600_ring_init(rdev, ring, 64 * 1024);
2217
Christian Königf2ba57b2013-04-08 12:41:29 +02002218 r = radeon_uvd_init(rdev);
2219 if (!r) {
2220 ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
2221 ring->ring_obj = NULL;
2222 r600_ring_init(rdev, ring, 4096);
2223 }
2224
Alex Deucher755d8192011-03-02 20:07:34 -05002225 rdev->ih.ring_obj = NULL;
2226 r600_ih_ring_init(rdev, 64 * 1024);
2227
2228 r = r600_pcie_gart_init(rdev);
2229 if (r)
2230 return r;
2231
2232 rdev->accel_working = true;
2233 r = cayman_startup(rdev);
2234 if (r) {
2235 dev_err(rdev->dev, "disabling GPU acceleration\n");
2236 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002237 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002238 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002239 if (rdev->flags & RADEON_IS_IGP)
2240 si_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002241 radeon_wb_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002242 radeon_ib_pool_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002243 radeon_vm_manager_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002244 radeon_irq_kms_fini(rdev);
2245 cayman_pcie_gart_fini(rdev);
2246 rdev->accel_working = false;
2247 }
Alex Deucher755d8192011-03-02 20:07:34 -05002248
2249 /* Don't start up if the MC ucode is missing.
2250 * The default clocks and voltages before the MC ucode
2251 * is loaded are not suffient for advanced operations.
Alex Deucherc420c742012-03-20 17:18:39 -04002252 *
2253 * We can skip this check for TN, because there is no MC
2254 * ucode.
Alex Deucher755d8192011-03-02 20:07:34 -05002255 */
Alex Deucherc420c742012-03-20 17:18:39 -04002256 if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
Alex Deucher755d8192011-03-02 20:07:34 -05002257 DRM_ERROR("radeon: MC ucode required for NI+.\n");
2258 return -EINVAL;
2259 }
2260
2261 return 0;
2262}
2263
2264void cayman_fini(struct radeon_device *rdev)
2265{
Ilija Hadzicfb3d9e92011-10-12 23:29:41 -04002266 r600_blit_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002267 cayman_cp_fini(rdev);
Alex Deucherf60cbd12012-12-04 15:27:33 -05002268 cayman_dma_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002269 r600_irq_fini(rdev);
Alex Deucherc420c742012-03-20 17:18:39 -04002270 if (rdev->flags & RADEON_IS_IGP)
2271 si_rlc_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002272 radeon_wb_fini(rdev);
Jerome Glisse721604a2012-01-05 22:11:05 -05002273 radeon_vm_manager_fini(rdev);
Christian König2898c342012-07-05 11:55:34 +02002274 radeon_ib_pool_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002275 radeon_irq_kms_fini(rdev);
Christian Königf2ba57b2013-04-08 12:41:29 +02002276 radeon_uvd_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002277 cayman_pcie_gart_fini(rdev);
Alex Deucher16cdf042011-10-28 10:30:02 -04002278 r600_vram_scratch_fini(rdev);
Alex Deucher755d8192011-03-02 20:07:34 -05002279 radeon_gem_fini(rdev);
2280 radeon_fence_driver_fini(rdev);
2281 radeon_bo_fini(rdev);
2282 radeon_atombios_fini(rdev);
2283 kfree(rdev->bios);
2284 rdev->bios = NULL;
2285}
2286
Jerome Glisse721604a2012-01-05 22:11:05 -05002287/*
2288 * vm
2289 */
2290int cayman_vm_init(struct radeon_device *rdev)
2291{
2292 /* number of VMs */
2293 rdev->vm_manager.nvm = 8;
2294 /* base offset of vram pages */
Alex Deuchere71270f2012-03-20 17:18:38 -04002295 if (rdev->flags & RADEON_IS_IGP) {
2296 u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2297 tmp <<= 22;
2298 rdev->vm_manager.vram_base_offset = tmp;
2299 } else
2300 rdev->vm_manager.vram_base_offset = 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002301 return 0;
2302}
2303
2304void cayman_vm_fini(struct radeon_device *rdev)
2305{
2306}
2307
Christian Königdce34bf2012-09-17 19:36:18 +02002308#define R600_ENTRY_VALID (1 << 0)
Jerome Glisse721604a2012-01-05 22:11:05 -05002309#define R600_PTE_SYSTEM (1 << 1)
2310#define R600_PTE_SNOOPED (1 << 2)
2311#define R600_PTE_READABLE (1 << 5)
2312#define R600_PTE_WRITEABLE (1 << 6)
2313
Christian König089a7862012-08-11 11:54:05 +02002314uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002315{
2316 uint32_t r600_flags = 0;
Christian Königdce34bf2012-09-17 19:36:18 +02002317 r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0;
Jerome Glisse721604a2012-01-05 22:11:05 -05002318 r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0;
2319 r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0;
2320 if (flags & RADEON_VM_PAGE_SYSTEM) {
2321 r600_flags |= R600_PTE_SYSTEM;
2322 r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0;
2323 }
2324 return r600_flags;
2325}
2326
Alex Deucher7a083292012-08-31 13:51:21 -04002327/**
2328 * cayman_vm_set_page - update the page tables using the CP
2329 *
2330 * @rdev: radeon_device pointer
Alex Deucher43f12142013-02-01 17:32:42 +01002331 * @ib: indirect buffer to fill with commands
Christian Königdce34bf2012-09-17 19:36:18 +02002332 * @pe: addr of the page entry
2333 * @addr: dst addr to write into pe
2334 * @count: number of page entries to update
2335 * @incr: increase next addr by incr bytes
2336 * @flags: access flags
Alex Deucher7a083292012-08-31 13:51:21 -04002337 *
Alex Deucher43f12142013-02-01 17:32:42 +01002338 * Update the page tables using the CP (cayman/TN).
Alex Deucher7a083292012-08-31 13:51:21 -04002339 */
Alex Deucher43f12142013-02-01 17:32:42 +01002340void cayman_vm_set_page(struct radeon_device *rdev,
2341 struct radeon_ib *ib,
2342 uint64_t pe,
Christian Königdce34bf2012-09-17 19:36:18 +02002343 uint64_t addr, unsigned count,
2344 uint32_t incr, uint32_t flags)
Jerome Glisse721604a2012-01-05 22:11:05 -05002345{
Christian Königdce34bf2012-09-17 19:36:18 +02002346 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002347 uint64_t value;
2348 unsigned ndw;
Jerome Glisse721604a2012-01-05 22:11:05 -05002349
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002350 if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) {
2351 while (count) {
2352 ndw = 1 + count * 2;
2353 if (ndw > 0x3FFF)
2354 ndw = 0x3FFF;
Christian König089a7862012-08-11 11:54:05 +02002355
Alex Deucher43f12142013-02-01 17:32:42 +01002356 ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw);
2357 ib->ptr[ib->length_dw++] = pe;
2358 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002359 for (; ndw > 1; ndw -= 2, --count, pe += 8) {
2360 if (flags & RADEON_VM_PAGE_SYSTEM) {
2361 value = radeon_vm_map_gart(rdev, addr);
2362 value &= 0xFFFFFFFFFFFFF000ULL;
2363 } else if (flags & RADEON_VM_PAGE_VALID) {
2364 value = addr;
2365 } else {
2366 value = 0;
2367 }
Christian Königf9fdffa2012-10-22 17:42:36 +02002368 addr += incr;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002369 value |= r600_flags;
Alex Deucher43f12142013-02-01 17:32:42 +01002370 ib->ptr[ib->length_dw++] = value;
2371 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Christian Königf9fdffa2012-10-22 17:42:36 +02002372 }
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002373 }
2374 } else {
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002375 if ((flags & RADEON_VM_PAGE_SYSTEM) ||
2376 (count == 1)) {
2377 while (count) {
2378 ndw = count * 2;
2379 if (ndw > 0xFFFFE)
2380 ndw = 0xFFFFE;
Christian Königf9fdffa2012-10-22 17:42:36 +02002381
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002382 /* for non-physically contiguous pages (system) */
2383 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
2384 ib->ptr[ib->length_dw++] = pe;
2385 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2386 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2387 if (flags & RADEON_VM_PAGE_SYSTEM) {
2388 value = radeon_vm_map_gart(rdev, addr);
2389 value &= 0xFFFFFFFFFFFFF000ULL;
2390 } else if (flags & RADEON_VM_PAGE_VALID) {
2391 value = addr;
2392 } else {
2393 value = 0;
2394 }
2395 addr += incr;
2396 value |= r600_flags;
2397 ib->ptr[ib->length_dw++] = value;
2398 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002399 }
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002400 }
2401 while (ib->length_dw & 0x7)
2402 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
2403 } else {
2404 while (count) {
2405 ndw = count * 2;
2406 if (ndw > 0xFFFFE)
2407 ndw = 0xFFFFE;
2408
2409 if (flags & RADEON_VM_PAGE_VALID)
2410 value = addr;
2411 else
2412 value = 0;
2413 /* for physically contiguous pages (vram) */
2414 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
2415 ib->ptr[ib->length_dw++] = pe; /* dst addr */
2416 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2417 ib->ptr[ib->length_dw++] = r600_flags; /* mask */
2418 ib->ptr[ib->length_dw++] = 0;
2419 ib->ptr[ib->length_dw++] = value; /* value */
Alex Deucher43f12142013-02-01 17:32:42 +01002420 ib->ptr[ib->length_dw++] = upper_32_bits(value);
Alex Deucher2ab91ad2013-04-16 10:42:15 -04002421 ib->ptr[ib->length_dw++] = incr; /* increment size */
2422 ib->ptr[ib->length_dw++] = 0;
2423 pe += ndw * 4;
2424 addr += (ndw / 2) * incr;
2425 count -= ndw / 2;
Alex Deucher3b6b59b2012-10-22 12:19:01 -04002426 }
Christian König2a6f1ab2012-08-11 15:00:30 +02002427 }
Alex Deucher43f12142013-02-01 17:32:42 +01002428 while (ib->length_dw & 0x7)
2429 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
Christian König2a6f1ab2012-08-11 15:00:30 +02002430 }
Jerome Glisse721604a2012-01-05 22:11:05 -05002431}
Christian König9b40e5d2012-08-08 12:22:43 +02002432
Alex Deucher7a083292012-08-31 13:51:21 -04002433/**
2434 * cayman_vm_flush - vm flush using the CP
2435 *
2436 * @rdev: radeon_device pointer
2437 *
2438 * Update the page table base and flush the VM TLB
2439 * using the CP (cayman-si).
2440 */
Alex Deucher498522b2012-10-02 14:43:38 -04002441void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
Christian König9b40e5d2012-08-08 12:22:43 +02002442{
Alex Deucher498522b2012-10-02 14:43:38 -04002443 struct radeon_ring *ring = &rdev->ring[ridx];
Christian König9b40e5d2012-08-08 12:22:43 +02002444
Christian Königee60e292012-08-09 16:21:08 +02002445 if (vm == NULL)
Christian König9b40e5d2012-08-08 12:22:43 +02002446 return;
2447
Christian Königee60e292012-08-09 16:21:08 +02002448 radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0));
Dmitry Cherkasovfa87e622012-09-17 19:36:19 +02002449 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
Christian Königee60e292012-08-09 16:21:08 +02002450
Christian König9b40e5d2012-08-08 12:22:43 +02002451 /* flush hdp cache */
2452 radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
2453 radeon_ring_write(ring, 0x1);
2454
2455 /* bits 0-7 are the VM contexts0-7 */
2456 radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
Alex Deucher498522b2012-10-02 14:43:38 -04002457 radeon_ring_write(ring, 1 << vm->id);
Christian König58f8cf52012-10-22 17:42:35 +02002458
2459 /* sync PFP to ME, otherwise we might get invalid PFP reads */
2460 radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2461 radeon_ring_write(ring, 0x0);
Alex Deucher0af62b02011-01-06 21:19:31 -05002462}
Alex Deucherf60cbd12012-12-04 15:27:33 -05002463
2464void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
2465{
2466 struct radeon_ring *ring = &rdev->ring[ridx];
2467
2468 if (vm == NULL)
2469 return;
2470
2471 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2472 radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2));
2473 radeon_ring_write(ring, vm->pd_gpu_addr >> 12);
2474
2475 /* flush hdp cache */
2476 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2477 radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2));
2478 radeon_ring_write(ring, 1);
2479
2480 /* bits 0-7 are the VM contexts0-7 */
2481 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0));
2482 radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2));
2483 radeon_ring_write(ring, 1 << vm->id);
2484}
2485