1926deccbSFrançois Tigeot /*
2926deccbSFrançois Tigeot * Copyright 2010 Advanced Micro Devices, Inc.
3926deccbSFrançois Tigeot *
4926deccbSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
5926deccbSFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
6926deccbSFrançois Tigeot * to deal in the Software without restriction, including without limitation
7926deccbSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8926deccbSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
9926deccbSFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
10926deccbSFrançois Tigeot *
11926deccbSFrançois Tigeot * The above copyright notice and this permission notice shall be included in
12926deccbSFrançois Tigeot * all copies or substantial portions of the Software.
13926deccbSFrançois Tigeot *
14926deccbSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15926deccbSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16926deccbSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17926deccbSFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18926deccbSFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19926deccbSFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20926deccbSFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE.
21926deccbSFrançois Tigeot *
22926deccbSFrançois Tigeot * Authors: Alex Deucher
23926deccbSFrançois Tigeot */
2457e252bfSMichael Neumann #include <linux/firmware.h>
25fcd4983fSzrj #include <linux/module.h>
26fcd4983fSzrj #include <drm/drmP.h>
27926deccbSFrançois Tigeot #include "radeon.h"
28926deccbSFrançois Tigeot #include "radeon_asic.h"
29c59a5c48SFrançois Tigeot #include "radeon_audio.h"
3083b4b9b9SFrançois Tigeot #include <drm/radeon_drm.h>
31926deccbSFrançois Tigeot #include "nid.h"
32926deccbSFrançois Tigeot #include "atom.h"
33926deccbSFrançois Tigeot #include "ni_reg.h"
34926deccbSFrançois Tigeot #include "cayman_blit_shaders.h"
3557e252bfSMichael Neumann #include "radeon_ucode.h"
3657e252bfSMichael Neumann #include "clearstate_cayman.h"
37926deccbSFrançois Tigeot
38c59a5c48SFrançois Tigeot /*
39c59a5c48SFrançois Tigeot * Indirect registers accessor
40c59a5c48SFrançois Tigeot */
tn_smc_rreg(struct radeon_device * rdev,u32 reg)41c59a5c48SFrançois Tigeot u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
42c59a5c48SFrançois Tigeot {
43c59a5c48SFrançois Tigeot u32 r;
44c59a5c48SFrançois Tigeot
45ec5b6af4SFrançois Tigeot lockmgr(&rdev->smc_idx_lock, LK_EXCLUSIVE);
46c59a5c48SFrançois Tigeot WREG32(TN_SMC_IND_INDEX_0, (reg));
47c59a5c48SFrançois Tigeot r = RREG32(TN_SMC_IND_DATA_0);
48ec5b6af4SFrançois Tigeot lockmgr(&rdev->smc_idx_lock, LK_RELEASE);
49c59a5c48SFrançois Tigeot return r;
50c59a5c48SFrançois Tigeot }
51c59a5c48SFrançois Tigeot
tn_smc_wreg(struct radeon_device * rdev,u32 reg,u32 v)52c59a5c48SFrançois Tigeot void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
53c59a5c48SFrançois Tigeot {
54ec5b6af4SFrançois Tigeot lockmgr(&rdev->smc_idx_lock, LK_EXCLUSIVE);
55c59a5c48SFrançois Tigeot WREG32(TN_SMC_IND_INDEX_0, (reg));
56c59a5c48SFrançois Tigeot WREG32(TN_SMC_IND_DATA_0, (v));
57ec5b6af4SFrançois Tigeot lockmgr(&rdev->smc_idx_lock, LK_RELEASE);
58c59a5c48SFrançois Tigeot }
59c59a5c48SFrançois Tigeot
604cd92098Szrj static const u32 tn_rlc_save_restore_register_list[] =
6157e252bfSMichael Neumann {
6257e252bfSMichael Neumann 0x98fc,
6357e252bfSMichael Neumann 0x98f0,
6457e252bfSMichael Neumann 0x9834,
6557e252bfSMichael Neumann 0x9838,
6657e252bfSMichael Neumann 0x9870,
6757e252bfSMichael Neumann 0x9874,
6857e252bfSMichael Neumann 0x8a14,
6957e252bfSMichael Neumann 0x8b24,
7057e252bfSMichael Neumann 0x8bcc,
7157e252bfSMichael Neumann 0x8b10,
7257e252bfSMichael Neumann 0x8c30,
7357e252bfSMichael Neumann 0x8d00,
7457e252bfSMichael Neumann 0x8d04,
7557e252bfSMichael Neumann 0x8c00,
7657e252bfSMichael Neumann 0x8c04,
7757e252bfSMichael Neumann 0x8c10,
7857e252bfSMichael Neumann 0x8c14,
7957e252bfSMichael Neumann 0x8d8c,
8057e252bfSMichael Neumann 0x8cf0,
8157e252bfSMichael Neumann 0x8e38,
8257e252bfSMichael Neumann 0x9508,
8357e252bfSMichael Neumann 0x9688,
8457e252bfSMichael Neumann 0x9608,
8557e252bfSMichael Neumann 0x960c,
8657e252bfSMichael Neumann 0x9610,
8757e252bfSMichael Neumann 0x9614,
8857e252bfSMichael Neumann 0x88c4,
8957e252bfSMichael Neumann 0x8978,
9057e252bfSMichael Neumann 0x88d4,
9157e252bfSMichael Neumann 0x900c,
9257e252bfSMichael Neumann 0x9100,
9357e252bfSMichael Neumann 0x913c,
9457e252bfSMichael Neumann 0x90e8,
9557e252bfSMichael Neumann 0x9354,
9657e252bfSMichael Neumann 0xa008,
9757e252bfSMichael Neumann 0x98f8,
9857e252bfSMichael Neumann 0x9148,
9957e252bfSMichael Neumann 0x914c,
10057e252bfSMichael Neumann 0x3f94,
10157e252bfSMichael Neumann 0x98f4,
10257e252bfSMichael Neumann 0x9b7c,
10357e252bfSMichael Neumann 0x3f8c,
10457e252bfSMichael Neumann 0x8950,
10557e252bfSMichael Neumann 0x8954,
10657e252bfSMichael Neumann 0x8a18,
10757e252bfSMichael Neumann 0x8b28,
10857e252bfSMichael Neumann 0x9144,
10957e252bfSMichael Neumann 0x3f90,
11057e252bfSMichael Neumann 0x915c,
11157e252bfSMichael Neumann 0x9160,
11257e252bfSMichael Neumann 0x9178,
11357e252bfSMichael Neumann 0x917c,
11457e252bfSMichael Neumann 0x9180,
11557e252bfSMichael Neumann 0x918c,
11657e252bfSMichael Neumann 0x9190,
11757e252bfSMichael Neumann 0x9194,
11857e252bfSMichael Neumann 0x9198,
11957e252bfSMichael Neumann 0x919c,
12057e252bfSMichael Neumann 0x91a8,
12157e252bfSMichael Neumann 0x91ac,
12257e252bfSMichael Neumann 0x91b0,
12357e252bfSMichael Neumann 0x91b4,
12457e252bfSMichael Neumann 0x91b8,
12557e252bfSMichael Neumann 0x91c4,
12657e252bfSMichael Neumann 0x91c8,
12757e252bfSMichael Neumann 0x91cc,
12857e252bfSMichael Neumann 0x91d0,
12957e252bfSMichael Neumann 0x91d4,
13057e252bfSMichael Neumann 0x91e0,
13157e252bfSMichael Neumann 0x91e4,
13257e252bfSMichael Neumann 0x91ec,
13357e252bfSMichael Neumann 0x91f0,
13457e252bfSMichael Neumann 0x91f4,
13557e252bfSMichael Neumann 0x9200,
13657e252bfSMichael Neumann 0x9204,
13757e252bfSMichael Neumann 0x929c,
13857e252bfSMichael Neumann 0x8030,
13957e252bfSMichael Neumann 0x9150,
14057e252bfSMichael Neumann 0x9a60,
14157e252bfSMichael Neumann 0x920c,
14257e252bfSMichael Neumann 0x9210,
14357e252bfSMichael Neumann 0x9228,
14457e252bfSMichael Neumann 0x922c,
14557e252bfSMichael Neumann 0x9244,
14657e252bfSMichael Neumann 0x9248,
14757e252bfSMichael Neumann 0x91e8,
14857e252bfSMichael Neumann 0x9294,
14957e252bfSMichael Neumann 0x9208,
15057e252bfSMichael Neumann 0x9224,
15157e252bfSMichael Neumann 0x9240,
15257e252bfSMichael Neumann 0x9220,
15357e252bfSMichael Neumann 0x923c,
15457e252bfSMichael Neumann 0x9258,
15557e252bfSMichael Neumann 0x9744,
15657e252bfSMichael Neumann 0xa200,
15757e252bfSMichael Neumann 0xa204,
15857e252bfSMichael Neumann 0xa208,
15957e252bfSMichael Neumann 0xa20c,
16057e252bfSMichael Neumann 0x8d58,
16157e252bfSMichael Neumann 0x9030,
16257e252bfSMichael Neumann 0x9034,
16357e252bfSMichael Neumann 0x9038,
16457e252bfSMichael Neumann 0x903c,
16557e252bfSMichael Neumann 0x9040,
16657e252bfSMichael Neumann 0x9654,
16757e252bfSMichael Neumann 0x897c,
16857e252bfSMichael Neumann 0xa210,
16957e252bfSMichael Neumann 0xa214,
17057e252bfSMichael Neumann 0x9868,
17157e252bfSMichael Neumann 0xa02c,
17257e252bfSMichael Neumann 0x9664,
17357e252bfSMichael Neumann 0x9698,
17457e252bfSMichael Neumann 0x949c,
17557e252bfSMichael Neumann 0x8e10,
17657e252bfSMichael Neumann 0x8e18,
17757e252bfSMichael Neumann 0x8c50,
17857e252bfSMichael Neumann 0x8c58,
17957e252bfSMichael Neumann 0x8c60,
18057e252bfSMichael Neumann 0x8c68,
18157e252bfSMichael Neumann 0x89b4,
18257e252bfSMichael Neumann 0x9830,
18357e252bfSMichael Neumann 0x802c,
18457e252bfSMichael Neumann };
18557e252bfSMichael Neumann
18657e252bfSMichael Neumann /* Firmware Names */
18757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
18857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_me.bin");
18957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_mc.bin");
19057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_smc.bin");
19157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BTC_rlc.bin");
19257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
19357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_me.bin");
19457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_mc.bin");
19557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_smc.bin");
19657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
19757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_me.bin");
19857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
19957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_smc.bin");
20057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
20157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
20257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
20357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
20457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
20557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
20657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/ARUBA_me.bin");
20757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
208f43cf1b1SMichael Neumann
209c4ef309bSzrj
210f43cf1b1SMichael Neumann static const u32 cayman_golden_registers2[] =
211f43cf1b1SMichael Neumann {
212f43cf1b1SMichael Neumann 0x3e5c, 0xffffffff, 0x00000000,
213f43cf1b1SMichael Neumann 0x3e48, 0xffffffff, 0x00000000,
214f43cf1b1SMichael Neumann 0x3e4c, 0xffffffff, 0x00000000,
215f43cf1b1SMichael Neumann 0x3e64, 0xffffffff, 0x00000000,
216f43cf1b1SMichael Neumann 0x3e50, 0xffffffff, 0x00000000,
217f43cf1b1SMichael Neumann 0x3e60, 0xffffffff, 0x00000000
218f43cf1b1SMichael Neumann };
219f43cf1b1SMichael Neumann
220f43cf1b1SMichael Neumann static const u32 cayman_golden_registers[] =
221f43cf1b1SMichael Neumann {
222f43cf1b1SMichael Neumann 0x5eb4, 0xffffffff, 0x00000002,
223f43cf1b1SMichael Neumann 0x5e78, 0x8f311ff1, 0x001000f0,
224f43cf1b1SMichael Neumann 0x3f90, 0xffff0000, 0xff000000,
225f43cf1b1SMichael Neumann 0x9148, 0xffff0000, 0xff000000,
226f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000,
227f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000,
228f43cf1b1SMichael Neumann 0xc78, 0x00000080, 0x00000080,
229f43cf1b1SMichael Neumann 0xbd4, 0x70073777, 0x00011003,
230f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000,
231f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x02011003,
232f43cf1b1SMichael Neumann 0x5bc0, 0x00200000, 0x50100000,
233f43cf1b1SMichael Neumann 0x98f8, 0x33773777, 0x02011003,
234f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x76541032,
235f43cf1b1SMichael Neumann 0x7030, 0x31000311, 0x00000011,
236f43cf1b1SMichael Neumann 0x2f48, 0x33773777, 0x42010001,
237f43cf1b1SMichael Neumann 0x6b28, 0x00000010, 0x00000012,
238f43cf1b1SMichael Neumann 0x7728, 0x00000010, 0x00000012,
239f43cf1b1SMichael Neumann 0x10328, 0x00000010, 0x00000012,
240f43cf1b1SMichael Neumann 0x10f28, 0x00000010, 0x00000012,
241f43cf1b1SMichael Neumann 0x11b28, 0x00000010, 0x00000012,
242f43cf1b1SMichael Neumann 0x12728, 0x00000010, 0x00000012,
243f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000,
244f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007,
245f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff,
246f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
247f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000,
248f43cf1b1SMichael Neumann 0x10c, 0x00000001, 0x00010003,
249f43cf1b1SMichael Neumann 0xa02c, 0xffffffff, 0x0000009b,
250f43cf1b1SMichael Neumann 0x913c, 0x0000010f, 0x01000100,
251f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060,
252f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000,
253f43cf1b1SMichael Neumann 0x9508, 0x3700001f, 0x00000002,
254f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210,
255f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082,
256f43cf1b1SMichael Neumann 0x88d0, 0xffffffff, 0x0f40df40,
257f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
258f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000
259f43cf1b1SMichael Neumann };
260f43cf1b1SMichael Neumann
261f43cf1b1SMichael Neumann static const u32 dvst_golden_registers2[] =
262f43cf1b1SMichael Neumann {
263f43cf1b1SMichael Neumann 0x8f8, 0xffffffff, 0,
264f43cf1b1SMichael Neumann 0x8fc, 0x00380000, 0,
265f43cf1b1SMichael Neumann 0x8f8, 0xffffffff, 1,
266f43cf1b1SMichael Neumann 0x8fc, 0x0e000000, 0
267f43cf1b1SMichael Neumann };
268f43cf1b1SMichael Neumann
269f43cf1b1SMichael Neumann static const u32 dvst_golden_registers[] =
270f43cf1b1SMichael Neumann {
271f43cf1b1SMichael Neumann 0x690, 0x3fff3fff, 0x20c00033,
272f43cf1b1SMichael Neumann 0x918c, 0x0fff0fff, 0x00010006,
273f43cf1b1SMichael Neumann 0x91a8, 0x0fff0fff, 0x00010006,
274f43cf1b1SMichael Neumann 0x9150, 0xffffdfff, 0x6e944040,
275f43cf1b1SMichael Neumann 0x917c, 0x0fff0fff, 0x00030002,
276f43cf1b1SMichael Neumann 0x9198, 0x0fff0fff, 0x00030002,
277f43cf1b1SMichael Neumann 0x915c, 0x0fff0fff, 0x00010000,
278f43cf1b1SMichael Neumann 0x3f90, 0xffff0001, 0xff000000,
279f43cf1b1SMichael Neumann 0x9178, 0x0fff0fff, 0x00070000,
280f43cf1b1SMichael Neumann 0x9194, 0x0fff0fff, 0x00070000,
281f43cf1b1SMichael Neumann 0x9148, 0xffff0001, 0xff000000,
282f43cf1b1SMichael Neumann 0x9190, 0x0fff0fff, 0x00090008,
283f43cf1b1SMichael Neumann 0x91ac, 0x0fff0fff, 0x00090008,
284f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000,
285f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000,
286f43cf1b1SMichael Neumann 0x929c, 0x00000fff, 0x00000001,
287f43cf1b1SMichael Neumann 0x55e4, 0xff607fff, 0xfc000100,
288f43cf1b1SMichael Neumann 0x8a18, 0xff000fff, 0x00000100,
289f43cf1b1SMichael Neumann 0x8b28, 0xff000fff, 0x00000100,
290f43cf1b1SMichael Neumann 0x9144, 0xfffc0fff, 0x00000100,
291f43cf1b1SMichael Neumann 0x6ed8, 0x00010101, 0x00010000,
292f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
293f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
294f43cf1b1SMichael Neumann 0x9838, 0xfffffffe, 0x00000000,
295f43cf1b1SMichael Neumann 0xd0c0, 0xff000fff, 0x00000100,
296f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000,
297f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x12010001,
298f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070,
299f43cf1b1SMichael Neumann 0x98f8, 0x73773777, 0x12010001,
300f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x00000010,
301f43cf1b1SMichael Neumann 0x9b7c, 0x00ff0000, 0x00fc0000,
302f43cf1b1SMichael Neumann 0x8030, 0x00001f0f, 0x0000100a,
303f43cf1b1SMichael Neumann 0x2f48, 0x73773777, 0x12010001,
304f43cf1b1SMichael Neumann 0x2408, 0x00030000, 0x000c007f,
305f43cf1b1SMichael Neumann 0x8a14, 0xf000003f, 0x00000007,
306f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff,
307f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
308f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000,
309f43cf1b1SMichael Neumann 0x4d8, 0x00000fff, 0x00000100,
310f43cf1b1SMichael Neumann 0xa008, 0xffffffff, 0x00010000,
311f43cf1b1SMichael Neumann 0x913c, 0xffff03ff, 0x01000100,
312f43cf1b1SMichael Neumann 0x8c00, 0x000000ff, 0x00000003,
313f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060,
314f43cf1b1SMichael Neumann 0x8cf0, 0x1fff1fff, 0x08e00410,
315f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000,
316f43cf1b1SMichael Neumann 0x9508, 0xf700071f, 0x00000002,
317f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210,
318f43cf1b1SMichael Neumann 0x20ef8, 0x01ff01ff, 0x00000002,
319f43cf1b1SMichael Neumann 0x20e98, 0xfffffbff, 0x00200000,
320f43cf1b1SMichael Neumann 0x2015c, 0xffffffff, 0x00000f40,
321f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082,
322f43cf1b1SMichael Neumann 0x8978, 0x3fffffff, 0x04050140,
323f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
324f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000
325f43cf1b1SMichael Neumann };
326f43cf1b1SMichael Neumann
327f43cf1b1SMichael Neumann static const u32 scrapper_golden_registers[] =
328f43cf1b1SMichael Neumann {
329f43cf1b1SMichael Neumann 0x690, 0x3fff3fff, 0x20c00033,
330f43cf1b1SMichael Neumann 0x918c, 0x0fff0fff, 0x00010006,
331f43cf1b1SMichael Neumann 0x918c, 0x0fff0fff, 0x00010006,
332f43cf1b1SMichael Neumann 0x91a8, 0x0fff0fff, 0x00010006,
333f43cf1b1SMichael Neumann 0x91a8, 0x0fff0fff, 0x00010006,
334f43cf1b1SMichael Neumann 0x9150, 0xffffdfff, 0x6e944040,
335f43cf1b1SMichael Neumann 0x9150, 0xffffdfff, 0x6e944040,
336f43cf1b1SMichael Neumann 0x917c, 0x0fff0fff, 0x00030002,
337f43cf1b1SMichael Neumann 0x917c, 0x0fff0fff, 0x00030002,
338f43cf1b1SMichael Neumann 0x9198, 0x0fff0fff, 0x00030002,
339f43cf1b1SMichael Neumann 0x9198, 0x0fff0fff, 0x00030002,
340f43cf1b1SMichael Neumann 0x915c, 0x0fff0fff, 0x00010000,
341f43cf1b1SMichael Neumann 0x915c, 0x0fff0fff, 0x00010000,
342f43cf1b1SMichael Neumann 0x3f90, 0xffff0001, 0xff000000,
343f43cf1b1SMichael Neumann 0x3f90, 0xffff0001, 0xff000000,
344f43cf1b1SMichael Neumann 0x9178, 0x0fff0fff, 0x00070000,
345f43cf1b1SMichael Neumann 0x9178, 0x0fff0fff, 0x00070000,
346f43cf1b1SMichael Neumann 0x9194, 0x0fff0fff, 0x00070000,
347f43cf1b1SMichael Neumann 0x9194, 0x0fff0fff, 0x00070000,
348f43cf1b1SMichael Neumann 0x9148, 0xffff0001, 0xff000000,
349f43cf1b1SMichael Neumann 0x9148, 0xffff0001, 0xff000000,
350f43cf1b1SMichael Neumann 0x9190, 0x0fff0fff, 0x00090008,
351f43cf1b1SMichael Neumann 0x9190, 0x0fff0fff, 0x00090008,
352f43cf1b1SMichael Neumann 0x91ac, 0x0fff0fff, 0x00090008,
353f43cf1b1SMichael Neumann 0x91ac, 0x0fff0fff, 0x00090008,
354f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000,
355f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000,
356f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000,
357f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000,
358f43cf1b1SMichael Neumann 0x929c, 0x00000fff, 0x00000001,
359f43cf1b1SMichael Neumann 0x929c, 0x00000fff, 0x00000001,
360f43cf1b1SMichael Neumann 0x55e4, 0xff607fff, 0xfc000100,
361f43cf1b1SMichael Neumann 0x8a18, 0xff000fff, 0x00000100,
362f43cf1b1SMichael Neumann 0x8a18, 0xff000fff, 0x00000100,
363f43cf1b1SMichael Neumann 0x8b28, 0xff000fff, 0x00000100,
364f43cf1b1SMichael Neumann 0x8b28, 0xff000fff, 0x00000100,
365f43cf1b1SMichael Neumann 0x9144, 0xfffc0fff, 0x00000100,
366f43cf1b1SMichael Neumann 0x9144, 0xfffc0fff, 0x00000100,
367f43cf1b1SMichael Neumann 0x6ed8, 0x00010101, 0x00010000,
368f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
369f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000,
370f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
371f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400,
372f43cf1b1SMichael Neumann 0x9838, 0xfffffffe, 0x00000000,
373f43cf1b1SMichael Neumann 0x9838, 0xfffffffe, 0x00000000,
374f43cf1b1SMichael Neumann 0xd0c0, 0xff000fff, 0x00000100,
375f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000,
376f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000,
377f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x12010001,
378f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x12010001,
379f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070,
380f43cf1b1SMichael Neumann 0x98f8, 0x73773777, 0x12010001,
381f43cf1b1SMichael Neumann 0x98f8, 0x73773777, 0x12010001,
382f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x00000010,
383f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x00000010,
384f43cf1b1SMichael Neumann 0x9b7c, 0x00ff0000, 0x00fc0000,
385f43cf1b1SMichael Neumann 0x9b7c, 0x00ff0000, 0x00fc0000,
386f43cf1b1SMichael Neumann 0x8030, 0x00001f0f, 0x0000100a,
387f43cf1b1SMichael Neumann 0x8030, 0x00001f0f, 0x0000100a,
388f43cf1b1SMichael Neumann 0x2f48, 0x73773777, 0x12010001,
389f43cf1b1SMichael Neumann 0x2f48, 0x73773777, 0x12010001,
390f43cf1b1SMichael Neumann 0x2408, 0x00030000, 0x000c007f,
391f43cf1b1SMichael Neumann 0x8a14, 0xf000003f, 0x00000007,
392f43cf1b1SMichael Neumann 0x8a14, 0xf000003f, 0x00000007,
393f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff,
394f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff,
395f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
396f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000,
397f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000,
398f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000,
399f43cf1b1SMichael Neumann 0x4d8, 0x00000fff, 0x00000100,
400f43cf1b1SMichael Neumann 0x4d8, 0x00000fff, 0x00000100,
401f43cf1b1SMichael Neumann 0xa008, 0xffffffff, 0x00010000,
402f43cf1b1SMichael Neumann 0xa008, 0xffffffff, 0x00010000,
403f43cf1b1SMichael Neumann 0x913c, 0xffff03ff, 0x01000100,
404f43cf1b1SMichael Neumann 0x913c, 0xffff03ff, 0x01000100,
405f43cf1b1SMichael Neumann 0x90e8, 0x001fffff, 0x010400c0,
406f43cf1b1SMichael Neumann 0x8c00, 0x000000ff, 0x00000003,
407f43cf1b1SMichael Neumann 0x8c00, 0x000000ff, 0x00000003,
408f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060,
409f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060,
410f43cf1b1SMichael Neumann 0x8c30, 0x0000000f, 0x00040005,
411f43cf1b1SMichael Neumann 0x8cf0, 0x1fff1fff, 0x08e00410,
412f43cf1b1SMichael Neumann 0x8cf0, 0x1fff1fff, 0x08e00410,
413f43cf1b1SMichael Neumann 0x900c, 0x00ffffff, 0x0017071f,
414f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000,
415f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000,
416f43cf1b1SMichael Neumann 0x9508, 0xf700071f, 0x00000002,
417f43cf1b1SMichael Neumann 0x9508, 0xf700071f, 0x00000002,
418f43cf1b1SMichael Neumann 0x9688, 0x00300000, 0x0017000f,
419f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210,
420f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210,
421f43cf1b1SMichael Neumann 0x20ef8, 0x01ff01ff, 0x00000002,
422f43cf1b1SMichael Neumann 0x20e98, 0xfffffbff, 0x00200000,
423f43cf1b1SMichael Neumann 0x2015c, 0xffffffff, 0x00000f40,
424f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082,
425f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082,
426f43cf1b1SMichael Neumann 0x8978, 0x3fffffff, 0x04050140,
427f43cf1b1SMichael Neumann 0x8978, 0x3fffffff, 0x04050140,
428f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
429f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010,
430f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000,
431f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000
432f43cf1b1SMichael Neumann };
433f43cf1b1SMichael Neumann
ni_init_golden_registers(struct radeon_device * rdev)434f43cf1b1SMichael Neumann static void ni_init_golden_registers(struct radeon_device *rdev)
435f43cf1b1SMichael Neumann {
436f43cf1b1SMichael Neumann switch (rdev->family) {
437f43cf1b1SMichael Neumann case CHIP_CAYMAN:
438f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
439f43cf1b1SMichael Neumann cayman_golden_registers,
440f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(cayman_golden_registers));
441f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
442f43cf1b1SMichael Neumann cayman_golden_registers2,
443f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(cayman_golden_registers2));
444f43cf1b1SMichael Neumann break;
445f43cf1b1SMichael Neumann case CHIP_ARUBA:
446c6f73aabSFrançois Tigeot if ((rdev->pdev->device == 0x9900) ||
447c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9901) ||
448c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9903) ||
449c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9904) ||
450c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9905) ||
451c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9906) ||
452c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9907) ||
453c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9908) ||
454c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9909) ||
455c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990A) ||
456c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990B) ||
457c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990C) ||
458c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990D) ||
459c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990E) ||
460c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990F) ||
461c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9910) ||
462c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9913) ||
463c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9917) ||
464c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9918)) {
465f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
466f43cf1b1SMichael Neumann dvst_golden_registers,
467f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(dvst_golden_registers));
468f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
469f43cf1b1SMichael Neumann dvst_golden_registers2,
470f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(dvst_golden_registers2));
471f43cf1b1SMichael Neumann } else {
472f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
473f43cf1b1SMichael Neumann scrapper_golden_registers,
474f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(scrapper_golden_registers));
475f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev,
476f43cf1b1SMichael Neumann dvst_golden_registers2,
477f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(dvst_golden_registers2));
478f43cf1b1SMichael Neumann }
479f43cf1b1SMichael Neumann break;
480f43cf1b1SMichael Neumann default:
481f43cf1b1SMichael Neumann break;
482f43cf1b1SMichael Neumann }
483f43cf1b1SMichael Neumann }
484f43cf1b1SMichael Neumann
485926deccbSFrançois Tigeot #define BTC_IO_MC_REGS_SIZE 29
486926deccbSFrançois Tigeot
487926deccbSFrançois Tigeot static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
488926deccbSFrançois Tigeot {0x00000077, 0xff010100},
489926deccbSFrançois Tigeot {0x00000078, 0x00000000},
490926deccbSFrançois Tigeot {0x00000079, 0x00001434},
491926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08},
492926deccbSFrançois Tigeot {0x0000007b, 0x00040000},
493926deccbSFrançois Tigeot {0x0000007c, 0x000080c0},
494926deccbSFrançois Tigeot {0x0000007d, 0x09000000},
495926deccbSFrançois Tigeot {0x0000007e, 0x00210404},
496926deccbSFrançois Tigeot {0x00000081, 0x08a8e800},
497926deccbSFrançois Tigeot {0x00000082, 0x00030444},
498926deccbSFrançois Tigeot {0x00000083, 0x00000000},
499926deccbSFrançois Tigeot {0x00000085, 0x00000001},
500926deccbSFrançois Tigeot {0x00000086, 0x00000002},
501926deccbSFrançois Tigeot {0x00000087, 0x48490000},
502926deccbSFrançois Tigeot {0x00000088, 0x20244647},
503926deccbSFrançois Tigeot {0x00000089, 0x00000005},
504926deccbSFrançois Tigeot {0x0000008b, 0x66030000},
505926deccbSFrançois Tigeot {0x0000008c, 0x00006603},
506926deccbSFrançois Tigeot {0x0000008d, 0x00000100},
507926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a},
508926deccbSFrançois Tigeot {0x00000090, 0xff000001},
509926deccbSFrançois Tigeot {0x00000094, 0x00101101},
510926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
511926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
512926deccbSFrançois Tigeot {0x00000097, 0x60010000},
513926deccbSFrançois Tigeot {0x00000098, 0x10010000},
514926deccbSFrançois Tigeot {0x00000099, 0x00006000},
515926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
516926deccbSFrançois Tigeot {0x0000009f, 0x00946a00}
517926deccbSFrançois Tigeot };
518926deccbSFrançois Tigeot
519926deccbSFrançois Tigeot static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
520926deccbSFrançois Tigeot {0x00000077, 0xff010100},
521926deccbSFrançois Tigeot {0x00000078, 0x00000000},
522926deccbSFrançois Tigeot {0x00000079, 0x00001434},
523926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08},
524926deccbSFrançois Tigeot {0x0000007b, 0x00040000},
525926deccbSFrançois Tigeot {0x0000007c, 0x000080c0},
526926deccbSFrançois Tigeot {0x0000007d, 0x09000000},
527926deccbSFrançois Tigeot {0x0000007e, 0x00210404},
528926deccbSFrançois Tigeot {0x00000081, 0x08a8e800},
529926deccbSFrançois Tigeot {0x00000082, 0x00030444},
530926deccbSFrançois Tigeot {0x00000083, 0x00000000},
531926deccbSFrançois Tigeot {0x00000085, 0x00000001},
532926deccbSFrançois Tigeot {0x00000086, 0x00000002},
533926deccbSFrançois Tigeot {0x00000087, 0x48490000},
534926deccbSFrançois Tigeot {0x00000088, 0x20244647},
535926deccbSFrançois Tigeot {0x00000089, 0x00000005},
536926deccbSFrançois Tigeot {0x0000008b, 0x66030000},
537926deccbSFrançois Tigeot {0x0000008c, 0x00006603},
538926deccbSFrançois Tigeot {0x0000008d, 0x00000100},
539926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a},
540926deccbSFrançois Tigeot {0x00000090, 0xff000001},
541926deccbSFrançois Tigeot {0x00000094, 0x00101101},
542926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
543926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
544926deccbSFrançois Tigeot {0x00000097, 0x60010000},
545926deccbSFrançois Tigeot {0x00000098, 0x10010000},
546926deccbSFrançois Tigeot {0x00000099, 0x00006000},
547926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
548926deccbSFrançois Tigeot {0x0000009f, 0x00936a00}
549926deccbSFrançois Tigeot };
550926deccbSFrançois Tigeot
551926deccbSFrançois Tigeot static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
552926deccbSFrançois Tigeot {0x00000077, 0xff010100},
553926deccbSFrançois Tigeot {0x00000078, 0x00000000},
554926deccbSFrançois Tigeot {0x00000079, 0x00001434},
555926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08},
556926deccbSFrançois Tigeot {0x0000007b, 0x00040000},
557926deccbSFrançois Tigeot {0x0000007c, 0x000080c0},
558926deccbSFrançois Tigeot {0x0000007d, 0x09000000},
559926deccbSFrançois Tigeot {0x0000007e, 0x00210404},
560926deccbSFrançois Tigeot {0x00000081, 0x08a8e800},
561926deccbSFrançois Tigeot {0x00000082, 0x00030444},
562926deccbSFrançois Tigeot {0x00000083, 0x00000000},
563926deccbSFrançois Tigeot {0x00000085, 0x00000001},
564926deccbSFrançois Tigeot {0x00000086, 0x00000002},
565926deccbSFrançois Tigeot {0x00000087, 0x48490000},
566926deccbSFrançois Tigeot {0x00000088, 0x20244647},
567926deccbSFrançois Tigeot {0x00000089, 0x00000005},
568926deccbSFrançois Tigeot {0x0000008b, 0x66030000},
569926deccbSFrançois Tigeot {0x0000008c, 0x00006603},
570926deccbSFrançois Tigeot {0x0000008d, 0x00000100},
571926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a},
572926deccbSFrançois Tigeot {0x00000090, 0xff000001},
573926deccbSFrançois Tigeot {0x00000094, 0x00101101},
574926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
575926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
576926deccbSFrançois Tigeot {0x00000097, 0x60010000},
577926deccbSFrançois Tigeot {0x00000098, 0x10010000},
578926deccbSFrançois Tigeot {0x00000099, 0x00006000},
579926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
580926deccbSFrançois Tigeot {0x0000009f, 0x00916a00}
581926deccbSFrançois Tigeot };
582926deccbSFrançois Tigeot
583926deccbSFrançois Tigeot static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
584926deccbSFrançois Tigeot {0x00000077, 0xff010100},
585926deccbSFrançois Tigeot {0x00000078, 0x00000000},
586926deccbSFrançois Tigeot {0x00000079, 0x00001434},
587926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08},
588926deccbSFrançois Tigeot {0x0000007b, 0x00040000},
589926deccbSFrançois Tigeot {0x0000007c, 0x000080c0},
590926deccbSFrançois Tigeot {0x0000007d, 0x09000000},
591926deccbSFrançois Tigeot {0x0000007e, 0x00210404},
592926deccbSFrançois Tigeot {0x00000081, 0x08a8e800},
593926deccbSFrançois Tigeot {0x00000082, 0x00030444},
594926deccbSFrançois Tigeot {0x00000083, 0x00000000},
595926deccbSFrançois Tigeot {0x00000085, 0x00000001},
596926deccbSFrançois Tigeot {0x00000086, 0x00000002},
597926deccbSFrançois Tigeot {0x00000087, 0x48490000},
598926deccbSFrançois Tigeot {0x00000088, 0x20244647},
599926deccbSFrançois Tigeot {0x00000089, 0x00000005},
600926deccbSFrançois Tigeot {0x0000008b, 0x66030000},
601926deccbSFrançois Tigeot {0x0000008c, 0x00006603},
602926deccbSFrançois Tigeot {0x0000008d, 0x00000100},
603926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a},
604926deccbSFrançois Tigeot {0x00000090, 0xff000001},
605926deccbSFrançois Tigeot {0x00000094, 0x00101101},
606926deccbSFrançois Tigeot {0x00000095, 0x00000fff},
607926deccbSFrançois Tigeot {0x00000096, 0x00116fff},
608926deccbSFrançois Tigeot {0x00000097, 0x60010000},
609926deccbSFrançois Tigeot {0x00000098, 0x10010000},
610926deccbSFrançois Tigeot {0x00000099, 0x00006000},
611926deccbSFrançois Tigeot {0x0000009a, 0x00001000},
612926deccbSFrançois Tigeot {0x0000009f, 0x00976b00}
613926deccbSFrançois Tigeot };
614926deccbSFrançois Tigeot
ni_mc_load_microcode(struct radeon_device * rdev)615926deccbSFrançois Tigeot int ni_mc_load_microcode(struct radeon_device *rdev)
616926deccbSFrançois Tigeot {
617926deccbSFrançois Tigeot const __be32 *fw_data;
618926deccbSFrançois Tigeot u32 mem_type, running, blackout = 0;
619926deccbSFrançois Tigeot u32 *io_mc_regs;
620926deccbSFrançois Tigeot int i, ucode_size, regs_size;
621926deccbSFrançois Tigeot
622926deccbSFrançois Tigeot if (!rdev->mc_fw)
623926deccbSFrançois Tigeot return -EINVAL;
624926deccbSFrançois Tigeot
625926deccbSFrançois Tigeot switch (rdev->family) {
626926deccbSFrançois Tigeot case CHIP_BARTS:
627926deccbSFrançois Tigeot io_mc_regs = (u32 *)&barts_io_mc_regs;
628926deccbSFrançois Tigeot ucode_size = BTC_MC_UCODE_SIZE;
629926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE;
630926deccbSFrançois Tigeot break;
631926deccbSFrançois Tigeot case CHIP_TURKS:
632926deccbSFrançois Tigeot io_mc_regs = (u32 *)&turks_io_mc_regs;
633926deccbSFrançois Tigeot ucode_size = BTC_MC_UCODE_SIZE;
634926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE;
635926deccbSFrançois Tigeot break;
636926deccbSFrançois Tigeot case CHIP_CAICOS:
637926deccbSFrançois Tigeot default:
638926deccbSFrançois Tigeot io_mc_regs = (u32 *)&caicos_io_mc_regs;
639926deccbSFrançois Tigeot ucode_size = BTC_MC_UCODE_SIZE;
640926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE;
641926deccbSFrançois Tigeot break;
642926deccbSFrançois Tigeot case CHIP_CAYMAN:
643926deccbSFrançois Tigeot io_mc_regs = (u32 *)&cayman_io_mc_regs;
644926deccbSFrançois Tigeot ucode_size = CAYMAN_MC_UCODE_SIZE;
645926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE;
646926deccbSFrançois Tigeot break;
647926deccbSFrançois Tigeot }
648926deccbSFrançois Tigeot
649926deccbSFrançois Tigeot mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
650926deccbSFrançois Tigeot running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
651926deccbSFrançois Tigeot
652926deccbSFrançois Tigeot if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
653926deccbSFrançois Tigeot if (running) {
654926deccbSFrançois Tigeot blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
655926deccbSFrançois Tigeot WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
656926deccbSFrançois Tigeot }
657926deccbSFrançois Tigeot
658926deccbSFrançois Tigeot /* reset the engine and set to writable */
659926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
660926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
661926deccbSFrançois Tigeot
662926deccbSFrançois Tigeot /* load mc io regs */
663926deccbSFrançois Tigeot for (i = 0; i < regs_size; i++) {
664926deccbSFrançois Tigeot WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
665926deccbSFrançois Tigeot WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
666926deccbSFrançois Tigeot }
667926deccbSFrançois Tigeot /* load the MC ucode */
668926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->mc_fw->data;
669926deccbSFrançois Tigeot for (i = 0; i < ucode_size; i++)
670926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
671926deccbSFrançois Tigeot
672926deccbSFrançois Tigeot /* put the engine back into the active state */
673926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
674926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
675926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
676926deccbSFrançois Tigeot
677926deccbSFrançois Tigeot /* wait for training to complete */
678926deccbSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) {
679926deccbSFrançois Tigeot if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
680926deccbSFrançois Tigeot break;
681c4ef309bSzrj udelay(1);
682926deccbSFrançois Tigeot }
683926deccbSFrançois Tigeot
684926deccbSFrançois Tigeot if (running)
685926deccbSFrançois Tigeot WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
686926deccbSFrançois Tigeot }
687926deccbSFrançois Tigeot
688926deccbSFrançois Tigeot return 0;
689926deccbSFrançois Tigeot }
690926deccbSFrançois Tigeot
ni_init_microcode(struct radeon_device * rdev)691926deccbSFrançois Tigeot int ni_init_microcode(struct radeon_device *rdev)
692926deccbSFrançois Tigeot {
693926deccbSFrançois Tigeot const char *chip_name;
694926deccbSFrançois Tigeot const char *rlc_chip_name;
695926deccbSFrançois Tigeot size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
69657e252bfSMichael Neumann size_t smc_req_size = 0;
697926deccbSFrançois Tigeot char fw_name[30];
698926deccbSFrançois Tigeot int err;
699926deccbSFrançois Tigeot
700926deccbSFrançois Tigeot DRM_DEBUG("\n");
701926deccbSFrançois Tigeot
702926deccbSFrançois Tigeot switch (rdev->family) {
703926deccbSFrançois Tigeot case CHIP_BARTS:
704926deccbSFrançois Tigeot chip_name = "BARTS";
705926deccbSFrançois Tigeot rlc_chip_name = "BTC";
706926deccbSFrançois Tigeot pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
707926deccbSFrançois Tigeot me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
708926deccbSFrançois Tigeot rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
709926deccbSFrançois Tigeot mc_req_size = BTC_MC_UCODE_SIZE * 4;
71057e252bfSMichael Neumann smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4);
711926deccbSFrançois Tigeot break;
712926deccbSFrançois Tigeot case CHIP_TURKS:
713926deccbSFrançois Tigeot chip_name = "TURKS";
714926deccbSFrançois Tigeot rlc_chip_name = "BTC";
715926deccbSFrançois Tigeot pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
716926deccbSFrançois Tigeot me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
717926deccbSFrançois Tigeot rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
718926deccbSFrançois Tigeot mc_req_size = BTC_MC_UCODE_SIZE * 4;
71957e252bfSMichael Neumann smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4);
720926deccbSFrançois Tigeot break;
721926deccbSFrançois Tigeot case CHIP_CAICOS:
722926deccbSFrançois Tigeot chip_name = "CAICOS";
723926deccbSFrançois Tigeot rlc_chip_name = "BTC";
724926deccbSFrançois Tigeot pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
725926deccbSFrançois Tigeot me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
726926deccbSFrançois Tigeot rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
727926deccbSFrançois Tigeot mc_req_size = BTC_MC_UCODE_SIZE * 4;
72857e252bfSMichael Neumann smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4);
729926deccbSFrançois Tigeot break;
730926deccbSFrançois Tigeot case CHIP_CAYMAN:
731926deccbSFrançois Tigeot chip_name = "CAYMAN";
732926deccbSFrançois Tigeot rlc_chip_name = "CAYMAN";
733926deccbSFrançois Tigeot pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
734926deccbSFrançois Tigeot me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
735926deccbSFrançois Tigeot rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
736926deccbSFrançois Tigeot mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
73757e252bfSMichael Neumann smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
738926deccbSFrançois Tigeot break;
739926deccbSFrançois Tigeot case CHIP_ARUBA:
740926deccbSFrançois Tigeot chip_name = "ARUBA";
741926deccbSFrançois Tigeot rlc_chip_name = "ARUBA";
742926deccbSFrançois Tigeot /* pfp/me same size as CAYMAN */
743926deccbSFrançois Tigeot pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
744926deccbSFrançois Tigeot me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
745926deccbSFrançois Tigeot rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
746926deccbSFrançois Tigeot mc_req_size = 0;
747926deccbSFrançois Tigeot break;
748c4ef309bSzrj default: BUG();
749926deccbSFrançois Tigeot }
750926deccbSFrançois Tigeot
751926deccbSFrançois Tigeot DRM_INFO("Loading %s Microcode\n", chip_name);
752926deccbSFrançois Tigeot
753926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
75471187b16SFrançois Tigeot err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
755fcd4983fSzrj if (err)
756926deccbSFrançois Tigeot goto out;
757926deccbSFrançois Tigeot if (rdev->pfp_fw->datasize != pfp_req_size) {
758c4ef309bSzrj printk(KERN_ERR
75957e252bfSMichael Neumann "ni_pfp: Bogus length %zu in firmware \"%s\"\n",
760926deccbSFrançois Tigeot rdev->pfp_fw->datasize, fw_name);
761926deccbSFrançois Tigeot err = -EINVAL;
762926deccbSFrançois Tigeot goto out;
763926deccbSFrançois Tigeot }
764926deccbSFrançois Tigeot
765926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
76671187b16SFrançois Tigeot err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
767fcd4983fSzrj if (err)
768926deccbSFrançois Tigeot goto out;
769926deccbSFrançois Tigeot if (rdev->me_fw->datasize != me_req_size) {
770c4ef309bSzrj printk(KERN_ERR
77157e252bfSMichael Neumann "ni_me: Bogus length %zu in firmware \"%s\"\n",
772926deccbSFrançois Tigeot rdev->me_fw->datasize, fw_name);
773926deccbSFrançois Tigeot err = -EINVAL;
774926deccbSFrançois Tigeot }
775926deccbSFrançois Tigeot
776926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc",
777926deccbSFrançois Tigeot rlc_chip_name);
77871187b16SFrançois Tigeot err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
779fcd4983fSzrj if (err)
780926deccbSFrançois Tigeot goto out;
781926deccbSFrançois Tigeot if (rdev->rlc_fw->datasize != rlc_req_size) {
782c4ef309bSzrj printk(KERN_ERR
783926deccbSFrançois Tigeot "ni_rlc: Bogus length %zu in firmware \"%s\"\n",
784926deccbSFrançois Tigeot rdev->rlc_fw->datasize, fw_name);
785926deccbSFrançois Tigeot err = -EINVAL;
786926deccbSFrançois Tigeot }
787926deccbSFrançois Tigeot
788926deccbSFrançois Tigeot /* no MC ucode on TN */
789926deccbSFrançois Tigeot if (!(rdev->flags & RADEON_IS_IGP)) {
790fcd4983fSzrj ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name);
79171187b16SFrançois Tigeot err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
792fcd4983fSzrj if (err)
793926deccbSFrançois Tigeot goto out;
794926deccbSFrançois Tigeot if (rdev->mc_fw->datasize != mc_req_size) {
795c4ef309bSzrj printk(KERN_ERR
796926deccbSFrançois Tigeot "ni_mc: Bogus length %zu in firmware \"%s\"\n",
797926deccbSFrançois Tigeot rdev->mc_fw->datasize, fw_name);
798926deccbSFrançois Tigeot err = -EINVAL;
799926deccbSFrançois Tigeot }
800926deccbSFrançois Tigeot }
80157e252bfSMichael Neumann
80257e252bfSMichael Neumann if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
80357e252bfSMichael Neumann ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_smc", chip_name);
80471187b16SFrançois Tigeot err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
80557e252bfSMichael Neumann if (err) {
80657e252bfSMichael Neumann printk(KERN_ERR
80757e252bfSMichael Neumann "smc: error loading firmware \"%s\"\n",
80857e252bfSMichael Neumann fw_name);
80957e252bfSMichael Neumann release_firmware(rdev->smc_fw);
81057e252bfSMichael Neumann rdev->smc_fw = NULL;
8114cd92098Szrj err = 0;
81257e252bfSMichael Neumann } else if (rdev->smc_fw->datasize != smc_req_size) {
81357e252bfSMichael Neumann printk(KERN_ERR
81457e252bfSMichael Neumann "ni_smc: Bogus length %zu in firmware \"%s\"\n",
81557e252bfSMichael Neumann rdev->smc_fw->datasize, fw_name);
81657e252bfSMichael Neumann err = -EINVAL;
81757e252bfSMichael Neumann }
81857e252bfSMichael Neumann }
81957e252bfSMichael Neumann
820926deccbSFrançois Tigeot out:
821926deccbSFrançois Tigeot if (err) {
822926deccbSFrançois Tigeot if (err != -EINVAL)
823*a85cb24fSFrançois Tigeot pr_err("ni_cp: Failed to load firmware \"%s\"\n",
824926deccbSFrançois Tigeot fw_name);
825fcd4983fSzrj release_firmware(rdev->pfp_fw);
826926deccbSFrançois Tigeot rdev->pfp_fw = NULL;
827fcd4983fSzrj release_firmware(rdev->me_fw);
828926deccbSFrançois Tigeot rdev->me_fw = NULL;
829fcd4983fSzrj release_firmware(rdev->rlc_fw);
830926deccbSFrançois Tigeot rdev->rlc_fw = NULL;
831fcd4983fSzrj release_firmware(rdev->mc_fw);
832926deccbSFrançois Tigeot rdev->mc_fw = NULL;
833fcd4983fSzrj release_firmware(rdev->smc_fw);
83457e252bfSMichael Neumann rdev->smc_fw = NULL;
83557e252bfSMichael Neumann }
836926deccbSFrançois Tigeot return err;
837926deccbSFrançois Tigeot }
838926deccbSFrançois Tigeot
839926deccbSFrançois Tigeot /**
840926deccbSFrançois Tigeot * ni_fini_microcode - drop the firmwares image references
841926deccbSFrançois Tigeot *
842926deccbSFrançois Tigeot * @rdev: radeon_device pointer
843926deccbSFrançois Tigeot *
844926deccbSFrançois Tigeot * Drop the pfp, me, mc and rlc firmwares image references.
845926deccbSFrançois Tigeot * Called at driver shutdown.
846926deccbSFrançois Tigeot */
ni_fini_microcode(struct radeon_device * rdev)847926deccbSFrançois Tigeot void ni_fini_microcode(struct radeon_device *rdev)
848926deccbSFrançois Tigeot {
849fcd4983fSzrj release_firmware(rdev->pfp_fw);
850926deccbSFrançois Tigeot rdev->pfp_fw = NULL;
851fcd4983fSzrj release_firmware(rdev->me_fw);
852926deccbSFrançois Tigeot rdev->me_fw = NULL;
853fcd4983fSzrj release_firmware(rdev->rlc_fw);
854926deccbSFrançois Tigeot rdev->rlc_fw = NULL;
855fcd4983fSzrj release_firmware(rdev->mc_fw);
856926deccbSFrançois Tigeot rdev->mc_fw = NULL;
8574cd92098Szrj release_firmware(rdev->smc_fw);
8584cd92098Szrj rdev->smc_fw = NULL;
859926deccbSFrançois Tigeot }
860926deccbSFrançois Tigeot
861c59a5c48SFrançois Tigeot /**
862c59a5c48SFrançois Tigeot * cayman_get_allowed_info_register - fetch the register for the info ioctl
863c59a5c48SFrançois Tigeot *
864c59a5c48SFrançois Tigeot * @rdev: radeon_device pointer
865c59a5c48SFrançois Tigeot * @reg: register offset in bytes
866c59a5c48SFrançois Tigeot * @val: register value
867c59a5c48SFrançois Tigeot *
868c59a5c48SFrançois Tigeot * Returns 0 for success or -EINVAL for an invalid register
869c59a5c48SFrançois Tigeot *
870c59a5c48SFrançois Tigeot */
cayman_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)871c59a5c48SFrançois Tigeot int cayman_get_allowed_info_register(struct radeon_device *rdev,
872c59a5c48SFrançois Tigeot u32 reg, u32 *val)
873c59a5c48SFrançois Tigeot {
874c59a5c48SFrançois Tigeot switch (reg) {
875c59a5c48SFrançois Tigeot case GRBM_STATUS:
876c59a5c48SFrançois Tigeot case GRBM_STATUS_SE0:
877c59a5c48SFrançois Tigeot case GRBM_STATUS_SE1:
878c59a5c48SFrançois Tigeot case SRBM_STATUS:
879c59a5c48SFrançois Tigeot case SRBM_STATUS2:
880c59a5c48SFrançois Tigeot case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
881c59a5c48SFrançois Tigeot case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
882c59a5c48SFrançois Tigeot case UVD_STATUS:
883c59a5c48SFrançois Tigeot *val = RREG32(reg);
884c59a5c48SFrançois Tigeot return 0;
885c59a5c48SFrançois Tigeot default:
886c59a5c48SFrançois Tigeot return -EINVAL;
887c59a5c48SFrançois Tigeot }
888c59a5c48SFrançois Tigeot }
889c59a5c48SFrançois Tigeot
tn_get_temp(struct radeon_device * rdev)89057e252bfSMichael Neumann int tn_get_temp(struct radeon_device *rdev)
89157e252bfSMichael Neumann {
89257e252bfSMichael Neumann u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
89357e252bfSMichael Neumann int actual_temp = (temp / 8) - 49;
89457e252bfSMichael Neumann
89557e252bfSMichael Neumann return actual_temp * 1000;
89657e252bfSMichael Neumann }
89757e252bfSMichael Neumann
898926deccbSFrançois Tigeot /*
899926deccbSFrançois Tigeot * Core functions
900926deccbSFrançois Tigeot */
cayman_gpu_init(struct radeon_device * rdev)901926deccbSFrançois Tigeot static void cayman_gpu_init(struct radeon_device *rdev)
902926deccbSFrançois Tigeot {
903926deccbSFrançois Tigeot u32 gb_addr_config = 0;
904926deccbSFrançois Tigeot u32 mc_shared_chmap, mc_arb_ramcfg;
905926deccbSFrançois Tigeot u32 cgts_tcc_disable;
906926deccbSFrançois Tigeot u32 sx_debug_1;
907926deccbSFrançois Tigeot u32 smx_dc_ctl0;
908926deccbSFrançois Tigeot u32 cgts_sm_ctrl_reg;
909926deccbSFrançois Tigeot u32 hdp_host_path_cntl;
910926deccbSFrançois Tigeot u32 tmp;
911926deccbSFrançois Tigeot u32 disabled_rb_mask;
912926deccbSFrançois Tigeot int i, j;
913926deccbSFrançois Tigeot
914926deccbSFrançois Tigeot switch (rdev->family) {
915926deccbSFrançois Tigeot case CHIP_CAYMAN:
916926deccbSFrançois Tigeot rdev->config.cayman.max_shader_engines = 2;
917926deccbSFrançois Tigeot rdev->config.cayman.max_pipes_per_simd = 4;
918926deccbSFrançois Tigeot rdev->config.cayman.max_tile_pipes = 8;
919926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 12;
920926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 4;
921926deccbSFrançois Tigeot rdev->config.cayman.max_texture_channel_caches = 8;
922926deccbSFrançois Tigeot rdev->config.cayman.max_gprs = 256;
923926deccbSFrançois Tigeot rdev->config.cayman.max_threads = 256;
924926deccbSFrançois Tigeot rdev->config.cayman.max_gs_threads = 32;
925926deccbSFrançois Tigeot rdev->config.cayman.max_stack_entries = 512;
926926deccbSFrançois Tigeot rdev->config.cayman.sx_num_of_sets = 8;
927926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 256;
928926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 64;
929926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 192;
930926deccbSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 8;
931926deccbSFrançois Tigeot rdev->config.cayman.sq_num_cf_insts = 2;
932926deccbSFrançois Tigeot
933926deccbSFrançois Tigeot rdev->config.cayman.sc_prim_fifo_size = 0x100;
934926deccbSFrançois Tigeot rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
935926deccbSFrançois Tigeot rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
936926deccbSFrançois Tigeot gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
937926deccbSFrançois Tigeot break;
938926deccbSFrançois Tigeot case CHIP_ARUBA:
939926deccbSFrançois Tigeot default:
940926deccbSFrançois Tigeot rdev->config.cayman.max_shader_engines = 1;
941926deccbSFrançois Tigeot rdev->config.cayman.max_pipes_per_simd = 4;
942926deccbSFrançois Tigeot rdev->config.cayman.max_tile_pipes = 2;
943c6f73aabSFrançois Tigeot if ((rdev->pdev->device == 0x9900) ||
944c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9901) ||
945c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9905) ||
946c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9906) ||
947c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9907) ||
948c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9908) ||
949c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9909) ||
950c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990B) ||
951c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990C) ||
952c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990F) ||
953c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9910) ||
954c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9917) ||
955c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9999) ||
956c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x999C)) {
957926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 6;
958926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 2;
959c6f73aabSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 8;
960c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 256;
961c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 64;
962c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 192;
963c6f73aabSFrançois Tigeot } else if ((rdev->pdev->device == 0x9903) ||
964c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9904) ||
965c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990A) ||
966c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990D) ||
967c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x990E) ||
968c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9913) ||
969c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9918) ||
970c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x999D)) {
971926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 4;
972926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 2;
973c6f73aabSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 8;
974c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 256;
975c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 64;
976c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 192;
977c6f73aabSFrançois Tigeot } else if ((rdev->pdev->device == 0x9919) ||
978c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9990) ||
979c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9991) ||
980c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9994) ||
981c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9995) ||
982c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x9996) ||
983c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x999A) ||
984c6f73aabSFrançois Tigeot (rdev->pdev->device == 0x99A0)) {
985926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 3;
986926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 1;
987c6f73aabSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 4;
988c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 128;
989c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 32;
990c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 96;
991926deccbSFrançois Tigeot } else {
992926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 2;
993926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 1;
994c6f73aabSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 4;
995c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 128;
996c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 32;
997c6f73aabSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 96;
998926deccbSFrançois Tigeot }
999926deccbSFrançois Tigeot rdev->config.cayman.max_texture_channel_caches = 2;
1000926deccbSFrançois Tigeot rdev->config.cayman.max_gprs = 256;
1001926deccbSFrançois Tigeot rdev->config.cayman.max_threads = 256;
1002926deccbSFrançois Tigeot rdev->config.cayman.max_gs_threads = 32;
1003926deccbSFrançois Tigeot rdev->config.cayman.max_stack_entries = 512;
1004926deccbSFrançois Tigeot rdev->config.cayman.sx_num_of_sets = 8;
1005926deccbSFrançois Tigeot rdev->config.cayman.sq_num_cf_insts = 2;
1006926deccbSFrançois Tigeot
1007926deccbSFrançois Tigeot rdev->config.cayman.sc_prim_fifo_size = 0x40;
1008926deccbSFrançois Tigeot rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
1009926deccbSFrançois Tigeot rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
1010926deccbSFrançois Tigeot gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
1011926deccbSFrançois Tigeot break;
1012926deccbSFrançois Tigeot }
1013926deccbSFrançois Tigeot
1014926deccbSFrançois Tigeot /* Initialize HDP */
1015926deccbSFrançois Tigeot for (i = 0, j = 0; i < 32; i++, j += 0x18) {
1016926deccbSFrançois Tigeot WREG32((0x2c14 + j), 0x00000000);
1017926deccbSFrançois Tigeot WREG32((0x2c18 + j), 0x00000000);
1018926deccbSFrançois Tigeot WREG32((0x2c1c + j), 0x00000000);
1019926deccbSFrançois Tigeot WREG32((0x2c20 + j), 0x00000000);
1020926deccbSFrançois Tigeot WREG32((0x2c24 + j), 0x00000000);
1021926deccbSFrançois Tigeot }
1022926deccbSFrançois Tigeot
1023926deccbSFrançois Tigeot WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
1024c59a5c48SFrançois Tigeot WREG32(SRBM_INT_CNTL, 0x1);
1025c59a5c48SFrançois Tigeot WREG32(SRBM_INT_ACK, 0x1);
1026926deccbSFrançois Tigeot
1027926deccbSFrançois Tigeot evergreen_fix_pci_max_read_req_size(rdev);
1028926deccbSFrançois Tigeot
1029926deccbSFrançois Tigeot mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
1030926deccbSFrançois Tigeot mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
1031926deccbSFrançois Tigeot
1032926deccbSFrançois Tigeot tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
1033926deccbSFrançois Tigeot rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
1034926deccbSFrançois Tigeot if (rdev->config.cayman.mem_row_size_in_kb > 4)
1035926deccbSFrançois Tigeot rdev->config.cayman.mem_row_size_in_kb = 4;
1036926deccbSFrançois Tigeot /* XXX use MC settings? */
1037926deccbSFrançois Tigeot rdev->config.cayman.shader_engine_tile_size = 32;
1038926deccbSFrançois Tigeot rdev->config.cayman.num_gpus = 1;
1039926deccbSFrançois Tigeot rdev->config.cayman.multi_gpu_tile_size = 64;
1040926deccbSFrançois Tigeot
1041926deccbSFrançois Tigeot tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
1042926deccbSFrançois Tigeot rdev->config.cayman.num_tile_pipes = (1 << tmp);
1043926deccbSFrançois Tigeot tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
1044926deccbSFrançois Tigeot rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
1045926deccbSFrançois Tigeot tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
1046926deccbSFrançois Tigeot rdev->config.cayman.num_shader_engines = tmp + 1;
1047926deccbSFrançois Tigeot tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
1048926deccbSFrançois Tigeot rdev->config.cayman.num_gpus = tmp + 1;
1049926deccbSFrançois Tigeot tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
1050926deccbSFrançois Tigeot rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
1051926deccbSFrançois Tigeot tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
1052926deccbSFrançois Tigeot rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
1053926deccbSFrançois Tigeot
1054926deccbSFrançois Tigeot
1055926deccbSFrançois Tigeot /* setup tiling info dword. gb_addr_config is not adequate since it does
1056926deccbSFrançois Tigeot * not have bank info, so create a custom tiling dword.
1057926deccbSFrançois Tigeot * bits 3:0 num_pipes
1058926deccbSFrançois Tigeot * bits 7:4 num_banks
1059926deccbSFrançois Tigeot * bits 11:8 group_size
1060926deccbSFrançois Tigeot * bits 15:12 row_size
1061926deccbSFrançois Tigeot */
1062926deccbSFrançois Tigeot rdev->config.cayman.tile_config = 0;
1063926deccbSFrançois Tigeot switch (rdev->config.cayman.num_tile_pipes) {
1064926deccbSFrançois Tigeot case 1:
1065926deccbSFrançois Tigeot default:
1066926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (0 << 0);
1067926deccbSFrançois Tigeot break;
1068926deccbSFrançois Tigeot case 2:
1069926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (1 << 0);
1070926deccbSFrançois Tigeot break;
1071926deccbSFrançois Tigeot case 4:
1072926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (2 << 0);
1073926deccbSFrançois Tigeot break;
1074926deccbSFrançois Tigeot case 8:
1075926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (3 << 0);
1076926deccbSFrançois Tigeot break;
1077926deccbSFrançois Tigeot }
1078926deccbSFrançois Tigeot
1079926deccbSFrançois Tigeot /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
1080926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP)
1081926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 1 << 4;
1082926deccbSFrançois Tigeot else {
1083926deccbSFrançois Tigeot switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
1084926deccbSFrançois Tigeot case 0: /* four banks */
1085926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 0 << 4;
1086926deccbSFrançois Tigeot break;
1087926deccbSFrançois Tigeot case 1: /* eight banks */
1088926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 1 << 4;
1089926deccbSFrançois Tigeot break;
1090926deccbSFrançois Tigeot case 2: /* sixteen banks */
1091926deccbSFrançois Tigeot default:
1092926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 2 << 4;
1093926deccbSFrançois Tigeot break;
1094926deccbSFrançois Tigeot }
1095926deccbSFrançois Tigeot }
1096926deccbSFrançois Tigeot rdev->config.cayman.tile_config |=
1097926deccbSFrançois Tigeot ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
1098926deccbSFrançois Tigeot rdev->config.cayman.tile_config |=
1099926deccbSFrançois Tigeot ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
1100926deccbSFrançois Tigeot
1101926deccbSFrançois Tigeot tmp = 0;
1102926deccbSFrançois Tigeot for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
1103926deccbSFrançois Tigeot u32 rb_disable_bitmap;
1104926deccbSFrançois Tigeot
1105926deccbSFrançois Tigeot WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1106926deccbSFrançois Tigeot WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1107926deccbSFrançois Tigeot rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
1108926deccbSFrançois Tigeot tmp <<= 4;
1109926deccbSFrançois Tigeot tmp |= rb_disable_bitmap;
1110926deccbSFrançois Tigeot }
1111926deccbSFrançois Tigeot /* enabled rb are just the one not disabled :) */
1112926deccbSFrançois Tigeot disabled_rb_mask = tmp;
1113f43cf1b1SMichael Neumann tmp = 0;
1114f43cf1b1SMichael Neumann for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1115f43cf1b1SMichael Neumann tmp |= (1 << i);
1116f43cf1b1SMichael Neumann /* if all the backends are disabled, fix it up here */
1117f43cf1b1SMichael Neumann if ((disabled_rb_mask & tmp) == tmp) {
1118f43cf1b1SMichael Neumann for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1119f43cf1b1SMichael Neumann disabled_rb_mask &= ~(1 << i);
1120f43cf1b1SMichael Neumann }
1121926deccbSFrançois Tigeot
1122c6f73aabSFrançois Tigeot for (i = 0; i < rdev->config.cayman.max_shader_engines; i++) {
1123c6f73aabSFrançois Tigeot u32 simd_disable_bitmap;
1124c6f73aabSFrançois Tigeot
1125c6f73aabSFrançois Tigeot WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1126c6f73aabSFrançois Tigeot WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1127c6f73aabSFrançois Tigeot simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
1128c6f73aabSFrançois Tigeot simd_disable_bitmap |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
1129c6f73aabSFrançois Tigeot tmp <<= 16;
1130c6f73aabSFrançois Tigeot tmp |= simd_disable_bitmap;
1131c6f73aabSFrançois Tigeot }
1132c6f73aabSFrançois Tigeot rdev->config.cayman.active_simds = hweight32(~tmp);
1133c6f73aabSFrançois Tigeot
1134926deccbSFrançois Tigeot WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1135926deccbSFrançois Tigeot WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1136926deccbSFrançois Tigeot
1137926deccbSFrançois Tigeot WREG32(GB_ADDR_CONFIG, gb_addr_config);
1138926deccbSFrançois Tigeot WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
1139f43cf1b1SMichael Neumann if (ASIC_IS_DCE6(rdev))
1140f43cf1b1SMichael Neumann WREG32(DMIF_ADDR_CALC, gb_addr_config);
1141926deccbSFrançois Tigeot WREG32(HDP_ADDR_CONFIG, gb_addr_config);
1142926deccbSFrançois Tigeot WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
1143926deccbSFrançois Tigeot WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
1144f43cf1b1SMichael Neumann WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
1145f43cf1b1SMichael Neumann WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
1146f43cf1b1SMichael Neumann WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
1147926deccbSFrançois Tigeot
1148b403bed8SMichael Neumann if ((rdev->config.cayman.max_backends_per_se == 1) &&
1149b403bed8SMichael Neumann (rdev->flags & RADEON_IS_IGP)) {
11507dcf36dcSFrançois Tigeot if ((disabled_rb_mask & 3) == 2) {
1151ee479021SImre Vadász /* RB1 disabled, RB0 enabled */
1152ee479021SImre Vadász tmp = 0x00000000;
11537dcf36dcSFrançois Tigeot } else {
11547dcf36dcSFrançois Tigeot /* RB0 disabled, RB1 enabled */
11557dcf36dcSFrançois Tigeot tmp = 0x11111111;
1156b403bed8SMichael Neumann }
1157b403bed8SMichael Neumann } else {
1158926deccbSFrançois Tigeot tmp = gb_addr_config & NUM_PIPES_MASK;
1159926deccbSFrançois Tigeot tmp = r6xx_remap_render_backend(rdev, tmp,
1160926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se *
1161926deccbSFrançois Tigeot rdev->config.cayman.max_shader_engines,
1162926deccbSFrançois Tigeot CAYMAN_MAX_BACKENDS, disabled_rb_mask);
1163b403bed8SMichael Neumann }
1164926deccbSFrançois Tigeot WREG32(GB_BACKEND_MAP, tmp);
1165926deccbSFrançois Tigeot
1166926deccbSFrançois Tigeot cgts_tcc_disable = 0xffff0000;
1167926deccbSFrançois Tigeot for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
1168926deccbSFrançois Tigeot cgts_tcc_disable &= ~(1 << (16 + i));
1169926deccbSFrançois Tigeot WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
1170926deccbSFrançois Tigeot WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
1171926deccbSFrançois Tigeot WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
1172926deccbSFrançois Tigeot WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
1173926deccbSFrançois Tigeot
1174926deccbSFrançois Tigeot /* reprogram the shader complex */
1175926deccbSFrançois Tigeot cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
1176926deccbSFrançois Tigeot for (i = 0; i < 16; i++)
1177926deccbSFrançois Tigeot WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
1178926deccbSFrançois Tigeot WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
1179926deccbSFrançois Tigeot
1180926deccbSFrançois Tigeot /* set HW defaults for 3D engine */
1181926deccbSFrançois Tigeot WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
1182926deccbSFrançois Tigeot
1183926deccbSFrançois Tigeot sx_debug_1 = RREG32(SX_DEBUG_1);
1184926deccbSFrançois Tigeot sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1185926deccbSFrançois Tigeot WREG32(SX_DEBUG_1, sx_debug_1);
1186926deccbSFrançois Tigeot
1187926deccbSFrançois Tigeot smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1188926deccbSFrançois Tigeot smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
1189926deccbSFrançois Tigeot smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
1190926deccbSFrançois Tigeot WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1191926deccbSFrançois Tigeot
1192926deccbSFrançois Tigeot WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
1193926deccbSFrançois Tigeot
1194926deccbSFrançois Tigeot /* need to be explicitly zero-ed */
1195926deccbSFrançois Tigeot WREG32(VGT_OFFCHIP_LDS_BASE, 0);
1196926deccbSFrançois Tigeot WREG32(SQ_LSTMP_RING_BASE, 0);
1197926deccbSFrançois Tigeot WREG32(SQ_HSTMP_RING_BASE, 0);
1198926deccbSFrançois Tigeot WREG32(SQ_ESTMP_RING_BASE, 0);
1199926deccbSFrançois Tigeot WREG32(SQ_GSTMP_RING_BASE, 0);
1200926deccbSFrançois Tigeot WREG32(SQ_VSTMP_RING_BASE, 0);
1201926deccbSFrançois Tigeot WREG32(SQ_PSTMP_RING_BASE, 0);
1202926deccbSFrançois Tigeot
1203926deccbSFrançois Tigeot WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
1204926deccbSFrançois Tigeot
1205926deccbSFrançois Tigeot WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
1206926deccbSFrançois Tigeot POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
1207926deccbSFrançois Tigeot SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
1208926deccbSFrançois Tigeot
1209926deccbSFrançois Tigeot WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
1210926deccbSFrançois Tigeot SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
1211926deccbSFrançois Tigeot SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
1212926deccbSFrançois Tigeot
1213926deccbSFrançois Tigeot
1214926deccbSFrançois Tigeot WREG32(VGT_NUM_INSTANCES, 1);
1215926deccbSFrançois Tigeot
1216926deccbSFrançois Tigeot WREG32(CP_PERFMON_CNTL, 0);
1217926deccbSFrançois Tigeot
1218926deccbSFrançois Tigeot WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
1219926deccbSFrançois Tigeot FETCH_FIFO_HIWATER(0x4) |
1220926deccbSFrançois Tigeot DONE_FIFO_HIWATER(0xe0) |
1221926deccbSFrançois Tigeot ALU_UPDATE_FIFO_HIWATER(0x8)));
1222926deccbSFrançois Tigeot
1223926deccbSFrançois Tigeot WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1224926deccbSFrançois Tigeot WREG32(SQ_CONFIG, (VC_ENABLE |
1225926deccbSFrançois Tigeot EXPORT_SRC_C |
1226926deccbSFrançois Tigeot GFX_PRIO(0) |
1227926deccbSFrançois Tigeot CS1_PRIO(0) |
1228926deccbSFrançois Tigeot CS2_PRIO(1)));
1229926deccbSFrançois Tigeot WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1230926deccbSFrançois Tigeot
1231926deccbSFrançois Tigeot WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1232926deccbSFrançois Tigeot FORCE_EOV_MAX_REZ_CNT(255)));
1233926deccbSFrançois Tigeot
1234926deccbSFrançois Tigeot WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1235926deccbSFrançois Tigeot AUTO_INVLD_EN(ES_AND_GS_AUTO));
1236926deccbSFrançois Tigeot
1237926deccbSFrançois Tigeot WREG32(VGT_GS_VERTEX_REUSE, 16);
1238926deccbSFrançois Tigeot WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1239926deccbSFrançois Tigeot
1240926deccbSFrançois Tigeot WREG32(CB_PERF_CTR0_SEL_0, 0);
1241926deccbSFrançois Tigeot WREG32(CB_PERF_CTR0_SEL_1, 0);
1242926deccbSFrançois Tigeot WREG32(CB_PERF_CTR1_SEL_0, 0);
1243926deccbSFrançois Tigeot WREG32(CB_PERF_CTR1_SEL_1, 0);
1244926deccbSFrançois Tigeot WREG32(CB_PERF_CTR2_SEL_0, 0);
1245926deccbSFrançois Tigeot WREG32(CB_PERF_CTR2_SEL_1, 0);
1246926deccbSFrançois Tigeot WREG32(CB_PERF_CTR3_SEL_0, 0);
1247926deccbSFrançois Tigeot WREG32(CB_PERF_CTR3_SEL_1, 0);
1248926deccbSFrançois Tigeot
1249926deccbSFrançois Tigeot tmp = RREG32(HDP_MISC_CNTL);
1250926deccbSFrançois Tigeot tmp |= HDP_FLUSH_INVALIDATE_CACHE;
1251926deccbSFrançois Tigeot WREG32(HDP_MISC_CNTL, tmp);
1252926deccbSFrançois Tigeot
1253926deccbSFrançois Tigeot hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1254926deccbSFrançois Tigeot WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1255926deccbSFrançois Tigeot
1256926deccbSFrançois Tigeot WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1257926deccbSFrançois Tigeot
1258c4ef309bSzrj udelay(50);
125957e252bfSMichael Neumann
126057e252bfSMichael Neumann /* set clockgating golden values on TN */
126157e252bfSMichael Neumann if (rdev->family == CHIP_ARUBA) {
126257e252bfSMichael Neumann tmp = RREG32_CG(CG_CGTT_LOCAL_0);
126357e252bfSMichael Neumann tmp &= ~0x00380000;
126457e252bfSMichael Neumann WREG32_CG(CG_CGTT_LOCAL_0, tmp);
126557e252bfSMichael Neumann tmp = RREG32_CG(CG_CGTT_LOCAL_1);
126657e252bfSMichael Neumann tmp &= ~0x0e000000;
126757e252bfSMichael Neumann WREG32_CG(CG_CGTT_LOCAL_1, tmp);
126857e252bfSMichael Neumann }
1269926deccbSFrançois Tigeot }
1270926deccbSFrançois Tigeot
1271926deccbSFrançois Tigeot /*
1272926deccbSFrançois Tigeot * GART
1273926deccbSFrançois Tigeot */
cayman_pcie_gart_tlb_flush(struct radeon_device * rdev)1274926deccbSFrançois Tigeot void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1275926deccbSFrançois Tigeot {
1276926deccbSFrançois Tigeot /* flush hdp cache */
1277926deccbSFrançois Tigeot WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1278926deccbSFrançois Tigeot
1279926deccbSFrançois Tigeot /* bits 0-7 are the VM contexts0-7 */
1280926deccbSFrançois Tigeot WREG32(VM_INVALIDATE_REQUEST, 1);
1281926deccbSFrançois Tigeot }
1282926deccbSFrançois Tigeot
cayman_pcie_gart_enable(struct radeon_device * rdev)1283926deccbSFrançois Tigeot static int cayman_pcie_gart_enable(struct radeon_device *rdev)
1284926deccbSFrançois Tigeot {
1285926deccbSFrançois Tigeot int i, r;
1286926deccbSFrançois Tigeot
1287926deccbSFrançois Tigeot if (rdev->gart.robj == NULL) {
1288926deccbSFrançois Tigeot dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1289926deccbSFrançois Tigeot return -EINVAL;
1290926deccbSFrançois Tigeot }
1291926deccbSFrançois Tigeot r = radeon_gart_table_vram_pin(rdev);
1292926deccbSFrançois Tigeot if (r)
1293926deccbSFrançois Tigeot return r;
1294926deccbSFrançois Tigeot /* Setup TLB control */
1295926deccbSFrançois Tigeot WREG32(MC_VM_MX_L1_TLB_CNTL,
1296926deccbSFrançois Tigeot (0xA << 7) |
1297926deccbSFrançois Tigeot ENABLE_L1_TLB |
1298926deccbSFrançois Tigeot ENABLE_L1_FRAGMENT_PROCESSING |
1299926deccbSFrançois Tigeot SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1300926deccbSFrançois Tigeot ENABLE_ADVANCED_DRIVER_MODEL |
1301926deccbSFrançois Tigeot SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1302926deccbSFrançois Tigeot /* Setup L2 cache */
1303926deccbSFrançois Tigeot WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1304c6f73aabSFrançois Tigeot ENABLE_L2_FRAGMENT_PROCESSING |
1305926deccbSFrançois Tigeot ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1306926deccbSFrançois Tigeot ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1307926deccbSFrançois Tigeot EFFECTIVE_L2_QUEUE_SIZE(7) |
1308926deccbSFrançois Tigeot CONTEXT1_IDENTITY_ACCESS_MODE(1));
1309926deccbSFrançois Tigeot WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1310926deccbSFrançois Tigeot WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1311c6f73aabSFrançois Tigeot BANK_SELECT(6) |
1312926deccbSFrançois Tigeot L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1313926deccbSFrançois Tigeot /* setup context0 */
1314926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1315926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1316926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1317926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1318926deccbSFrançois Tigeot (u32)(rdev->dummy_page.addr >> 12));
1319926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL2, 0);
1320926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1321926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
1322926deccbSFrançois Tigeot
1323926deccbSFrançois Tigeot WREG32(0x15D4, 0);
1324926deccbSFrançois Tigeot WREG32(0x15D8, 0);
1325926deccbSFrançois Tigeot WREG32(0x15DC, 0);
1326926deccbSFrançois Tigeot
1327926deccbSFrançois Tigeot /* empty context1-7 */
1328926deccbSFrançois Tigeot /* Assign the pt base to something valid for now; the pts used for
1329926deccbSFrançois Tigeot * the VMs are determined by the application and setup and assigned
1330926deccbSFrançois Tigeot * on the fly in the vm part of radeon_gart.c
1331926deccbSFrançois Tigeot */
1332926deccbSFrançois Tigeot for (i = 1; i < 8; i++) {
1333926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
1334c59a5c48SFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
1335c59a5c48SFrançois Tigeot rdev->vm_manager.max_pfn - 1);
1336926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1337c6f73aabSFrançois Tigeot rdev->vm_manager.saved_table_addr[i]);
1338926deccbSFrançois Tigeot }
1339926deccbSFrançois Tigeot
1340926deccbSFrançois Tigeot /* enable context1-7 */
1341926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1342926deccbSFrançois Tigeot (u32)(rdev->dummy_page.addr >> 12));
1343926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL2, 4);
1344926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
1345c6f73aabSFrançois Tigeot PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
1346926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1347926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1348926deccbSFrançois Tigeot DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1349926deccbSFrançois Tigeot DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1350926deccbSFrançois Tigeot PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1351926deccbSFrançois Tigeot PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1352926deccbSFrançois Tigeot VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1353926deccbSFrançois Tigeot VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1354926deccbSFrançois Tigeot READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1355926deccbSFrançois Tigeot READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1356926deccbSFrançois Tigeot WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1357926deccbSFrançois Tigeot WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
1358926deccbSFrançois Tigeot
1359926deccbSFrançois Tigeot cayman_pcie_gart_tlb_flush(rdev);
1360926deccbSFrançois Tigeot DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1361926deccbSFrançois Tigeot (unsigned)(rdev->mc.gtt_size >> 20),
1362926deccbSFrançois Tigeot (unsigned long long)rdev->gart.table_addr);
1363926deccbSFrançois Tigeot rdev->gart.ready = true;
1364926deccbSFrançois Tigeot return 0;
1365926deccbSFrançois Tigeot }
1366926deccbSFrançois Tigeot
cayman_pcie_gart_disable(struct radeon_device * rdev)1367926deccbSFrançois Tigeot static void cayman_pcie_gart_disable(struct radeon_device *rdev)
1368926deccbSFrançois Tigeot {
1369c6f73aabSFrançois Tigeot unsigned i;
1370c6f73aabSFrançois Tigeot
1371c6f73aabSFrançois Tigeot for (i = 1; i < 8; ++i) {
1372c6f73aabSFrançois Tigeot rdev->vm_manager.saved_table_addr[i] = RREG32(
1373c6f73aabSFrançois Tigeot VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2));
1374c6f73aabSFrançois Tigeot }
1375c6f73aabSFrançois Tigeot
1376926deccbSFrançois Tigeot /* Disable all tables */
1377926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL, 0);
1378926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL, 0);
1379926deccbSFrançois Tigeot /* Setup TLB control */
1380926deccbSFrançois Tigeot WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1381926deccbSFrançois Tigeot SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1382926deccbSFrançois Tigeot SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1383926deccbSFrançois Tigeot /* Setup L2 cache */
1384926deccbSFrançois Tigeot WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1385926deccbSFrançois Tigeot ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1386926deccbSFrançois Tigeot EFFECTIVE_L2_QUEUE_SIZE(7) |
1387926deccbSFrançois Tigeot CONTEXT1_IDENTITY_ACCESS_MODE(1));
1388926deccbSFrançois Tigeot WREG32(VM_L2_CNTL2, 0);
1389926deccbSFrançois Tigeot WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1390926deccbSFrançois Tigeot L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1391926deccbSFrançois Tigeot radeon_gart_table_vram_unpin(rdev);
1392926deccbSFrançois Tigeot }
1393926deccbSFrançois Tigeot
cayman_pcie_gart_fini(struct radeon_device * rdev)1394926deccbSFrançois Tigeot static void cayman_pcie_gart_fini(struct radeon_device *rdev)
1395926deccbSFrançois Tigeot {
1396926deccbSFrançois Tigeot cayman_pcie_gart_disable(rdev);
1397926deccbSFrançois Tigeot radeon_gart_table_vram_free(rdev);
1398926deccbSFrançois Tigeot radeon_gart_fini(rdev);
1399926deccbSFrançois Tigeot }
1400926deccbSFrançois Tigeot
cayman_cp_int_cntl_setup(struct radeon_device * rdev,int ring,u32 cp_int_cntl)1401926deccbSFrançois Tigeot void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
1402926deccbSFrançois Tigeot int ring, u32 cp_int_cntl)
1403926deccbSFrançois Tigeot {
1404c59a5c48SFrançois Tigeot WREG32(SRBM_GFX_CNTL, RINGID(ring));
1405926deccbSFrançois Tigeot WREG32(CP_INT_CNTL, cp_int_cntl);
1406926deccbSFrançois Tigeot }
1407926deccbSFrançois Tigeot
1408926deccbSFrançois Tigeot /*
1409926deccbSFrançois Tigeot * CP.
1410926deccbSFrançois Tigeot */
cayman_fence_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)1411926deccbSFrançois Tigeot void cayman_fence_ring_emit(struct radeon_device *rdev,
1412926deccbSFrançois Tigeot struct radeon_fence *fence)
1413926deccbSFrançois Tigeot {
1414926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[fence->ring];
1415926deccbSFrançois Tigeot u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1416c6f73aabSFrançois Tigeot u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
1417c6f73aabSFrançois Tigeot PACKET3_SH_ACTION_ENA;
1418926deccbSFrançois Tigeot
1419926deccbSFrançois Tigeot /* flush read cache over gart for this vmid */
1420926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1421c6f73aabSFrançois Tigeot radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
1422926deccbSFrançois Tigeot radeon_ring_write(ring, 0xFFFFFFFF);
1423926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
1424926deccbSFrançois Tigeot radeon_ring_write(ring, 10); /* poll interval */
1425926deccbSFrançois Tigeot /* EVENT_WRITE_EOP - flush caches, send int */
1426926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1427926deccbSFrançois Tigeot radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
1428c6f73aabSFrançois Tigeot radeon_ring_write(ring, lower_32_bits(addr));
1429926deccbSFrançois Tigeot radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1430926deccbSFrançois Tigeot radeon_ring_write(ring, fence->seq);
1431926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
1432926deccbSFrançois Tigeot }
1433926deccbSFrançois Tigeot
cayman_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)1434926deccbSFrançois Tigeot void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1435926deccbSFrançois Tigeot {
1436926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[ib->ring];
14377dcf36dcSFrançois Tigeot unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
1438c6f73aabSFrançois Tigeot u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
1439c6f73aabSFrançois Tigeot PACKET3_SH_ACTION_ENA;
1440926deccbSFrançois Tigeot
1441926deccbSFrançois Tigeot /* set to DX10/11 mode */
1442926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1443926deccbSFrançois Tigeot radeon_ring_write(ring, 1);
1444926deccbSFrançois Tigeot
1445926deccbSFrançois Tigeot if (ring->rptr_save_reg) {
1446926deccbSFrançois Tigeot uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
1447926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1448926deccbSFrançois Tigeot radeon_ring_write(ring, ((ring->rptr_save_reg -
1449926deccbSFrançois Tigeot PACKET3_SET_CONFIG_REG_START) >> 2));
1450926deccbSFrançois Tigeot radeon_ring_write(ring, next_rptr);
1451926deccbSFrançois Tigeot }
1452926deccbSFrançois Tigeot
1453926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1454926deccbSFrançois Tigeot radeon_ring_write(ring,
1455926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
1456926deccbSFrançois Tigeot (2 << 0) |
1457926deccbSFrançois Tigeot #endif
1458926deccbSFrançois Tigeot (ib->gpu_addr & 0xFFFFFFFC));
1459926deccbSFrançois Tigeot radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
14607dcf36dcSFrançois Tigeot radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
1461926deccbSFrançois Tigeot
1462926deccbSFrançois Tigeot /* flush read cache over gart for this vmid */
1463926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1464c6f73aabSFrançois Tigeot radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
1465926deccbSFrançois Tigeot radeon_ring_write(ring, 0xFFFFFFFF);
1466926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
14677dcf36dcSFrançois Tigeot radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */
1468926deccbSFrançois Tigeot }
1469926deccbSFrançois Tigeot
cayman_cp_enable(struct radeon_device * rdev,bool enable)1470926deccbSFrançois Tigeot static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
1471926deccbSFrançois Tigeot {
1472926deccbSFrançois Tigeot if (enable)
1473926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, 0);
1474926deccbSFrançois Tigeot else {
1475c6f73aabSFrançois Tigeot if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
1476926deccbSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
1477926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
1478926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0);
1479926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1480926deccbSFrançois Tigeot }
1481926deccbSFrançois Tigeot }
1482926deccbSFrançois Tigeot
cayman_gfx_get_rptr(struct radeon_device * rdev,struct radeon_ring * ring)1483c6f73aabSFrançois Tigeot u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
1484c6f73aabSFrançois Tigeot struct radeon_ring *ring)
1485c6f73aabSFrançois Tigeot {
1486c6f73aabSFrançois Tigeot u32 rptr;
1487c6f73aabSFrançois Tigeot
1488c6f73aabSFrançois Tigeot if (rdev->wb.enabled)
1489c6f73aabSFrançois Tigeot rptr = rdev->wb.wb[ring->rptr_offs/4];
1490c6f73aabSFrançois Tigeot else {
1491c6f73aabSFrançois Tigeot if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
1492c6f73aabSFrançois Tigeot rptr = RREG32(CP_RB0_RPTR);
1493c6f73aabSFrançois Tigeot else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
1494c6f73aabSFrançois Tigeot rptr = RREG32(CP_RB1_RPTR);
1495c6f73aabSFrançois Tigeot else
1496c6f73aabSFrançois Tigeot rptr = RREG32(CP_RB2_RPTR);
1497c6f73aabSFrançois Tigeot }
1498c6f73aabSFrançois Tigeot
1499c6f73aabSFrançois Tigeot return rptr;
1500c6f73aabSFrançois Tigeot }
1501c6f73aabSFrançois Tigeot
cayman_gfx_get_wptr(struct radeon_device * rdev,struct radeon_ring * ring)1502c6f73aabSFrançois Tigeot u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
1503c6f73aabSFrançois Tigeot struct radeon_ring *ring)
1504c6f73aabSFrançois Tigeot {
1505c6f73aabSFrançois Tigeot u32 wptr;
1506c6f73aabSFrançois Tigeot
1507c6f73aabSFrançois Tigeot if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
1508c6f73aabSFrançois Tigeot wptr = RREG32(CP_RB0_WPTR);
1509c6f73aabSFrançois Tigeot else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
1510c6f73aabSFrançois Tigeot wptr = RREG32(CP_RB1_WPTR);
1511c6f73aabSFrançois Tigeot else
1512c6f73aabSFrançois Tigeot wptr = RREG32(CP_RB2_WPTR);
1513c6f73aabSFrançois Tigeot
1514c6f73aabSFrançois Tigeot return wptr;
1515c6f73aabSFrançois Tigeot }
1516c6f73aabSFrançois Tigeot
cayman_gfx_set_wptr(struct radeon_device * rdev,struct radeon_ring * ring)1517c6f73aabSFrançois Tigeot void cayman_gfx_set_wptr(struct radeon_device *rdev,
1518c6f73aabSFrançois Tigeot struct radeon_ring *ring)
1519c6f73aabSFrançois Tigeot {
1520c6f73aabSFrançois Tigeot if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
1521c6f73aabSFrançois Tigeot WREG32(CP_RB0_WPTR, ring->wptr);
1522c6f73aabSFrançois Tigeot (void)RREG32(CP_RB0_WPTR);
1523c6f73aabSFrançois Tigeot } else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
1524c6f73aabSFrançois Tigeot WREG32(CP_RB1_WPTR, ring->wptr);
1525c6f73aabSFrançois Tigeot (void)RREG32(CP_RB1_WPTR);
1526c6f73aabSFrançois Tigeot } else {
1527c6f73aabSFrançois Tigeot WREG32(CP_RB2_WPTR, ring->wptr);
1528c6f73aabSFrançois Tigeot (void)RREG32(CP_RB2_WPTR);
1529c6f73aabSFrançois Tigeot }
1530c6f73aabSFrançois Tigeot }
1531c6f73aabSFrançois Tigeot
cayman_cp_load_microcode(struct radeon_device * rdev)1532926deccbSFrançois Tigeot static int cayman_cp_load_microcode(struct radeon_device *rdev)
1533926deccbSFrançois Tigeot {
1534926deccbSFrançois Tigeot const __be32 *fw_data;
1535926deccbSFrançois Tigeot int i;
1536926deccbSFrançois Tigeot
1537926deccbSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw)
1538926deccbSFrançois Tigeot return -EINVAL;
1539926deccbSFrançois Tigeot
1540926deccbSFrançois Tigeot cayman_cp_enable(rdev, false);
1541926deccbSFrançois Tigeot
1542926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->pfp_fw->data;
1543926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0);
1544926deccbSFrançois Tigeot for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
1545926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
1546926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0);
1547926deccbSFrançois Tigeot
1548926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->me_fw->data;
1549926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0);
1550926deccbSFrançois Tigeot for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
1551926deccbSFrançois Tigeot WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
1552926deccbSFrançois Tigeot
1553926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0);
1554926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0);
1555926deccbSFrançois Tigeot WREG32(CP_ME_RAM_RADDR, 0);
1556926deccbSFrançois Tigeot return 0;
1557926deccbSFrançois Tigeot }
1558926deccbSFrançois Tigeot
cayman_cp_start(struct radeon_device * rdev)1559926deccbSFrançois Tigeot static int cayman_cp_start(struct radeon_device *rdev)
1560926deccbSFrançois Tigeot {
1561926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1562926deccbSFrançois Tigeot int r, i;
1563926deccbSFrançois Tigeot
1564926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, 7);
1565926deccbSFrançois Tigeot if (r) {
1566926deccbSFrançois Tigeot DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1567926deccbSFrançois Tigeot return r;
1568926deccbSFrançois Tigeot }
1569926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1570926deccbSFrançois Tigeot radeon_ring_write(ring, 0x1);
1571926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0);
1572926deccbSFrançois Tigeot radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1573926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1574926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
1575926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
1576c6f73aabSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring, false);
1577926deccbSFrançois Tigeot
1578926deccbSFrançois Tigeot cayman_cp_enable(rdev, true);
1579926deccbSFrançois Tigeot
1580926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
1581926deccbSFrançois Tigeot if (r) {
1582926deccbSFrançois Tigeot DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1583926deccbSFrançois Tigeot return r;
1584926deccbSFrançois Tigeot }
1585926deccbSFrançois Tigeot
1586926deccbSFrançois Tigeot /* setup clear context state */
1587926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1588926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
1589926deccbSFrançois Tigeot
1590926deccbSFrançois Tigeot for (i = 0; i < cayman_default_size; i++)
1591926deccbSFrançois Tigeot radeon_ring_write(ring, cayman_default_state[i]);
1592926deccbSFrançois Tigeot
1593926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1594926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
1595926deccbSFrançois Tigeot
1596926deccbSFrançois Tigeot /* set clear context state */
1597926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1598926deccbSFrançois Tigeot radeon_ring_write(ring, 0);
1599926deccbSFrançois Tigeot
1600926deccbSFrançois Tigeot /* SQ_VTX_BASE_VTX_LOC */
1601926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc0026f00);
1602926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000000);
1603926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000000);
1604926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000000);
1605926deccbSFrançois Tigeot
1606926deccbSFrançois Tigeot /* Clear consts */
1607926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc0036f00);
1608926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000bc4);
1609926deccbSFrançois Tigeot radeon_ring_write(ring, 0xffffffff);
1610926deccbSFrançois Tigeot radeon_ring_write(ring, 0xffffffff);
1611926deccbSFrançois Tigeot radeon_ring_write(ring, 0xffffffff);
1612926deccbSFrançois Tigeot
1613926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc0026900);
1614926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000316);
1615926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1616926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000010); /* */
1617926deccbSFrançois Tigeot
1618c6f73aabSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring, false);
1619926deccbSFrançois Tigeot
1620926deccbSFrançois Tigeot /* XXX init other rings */
1621926deccbSFrançois Tigeot
1622926deccbSFrançois Tigeot return 0;
1623926deccbSFrançois Tigeot }
1624926deccbSFrançois Tigeot
cayman_cp_fini(struct radeon_device * rdev)1625926deccbSFrançois Tigeot static void cayman_cp_fini(struct radeon_device *rdev)
1626926deccbSFrançois Tigeot {
1627926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1628926deccbSFrançois Tigeot cayman_cp_enable(rdev, false);
1629926deccbSFrançois Tigeot radeon_ring_fini(rdev, ring);
1630926deccbSFrançois Tigeot radeon_scratch_free(rdev, ring->rptr_save_reg);
1631926deccbSFrançois Tigeot }
1632926deccbSFrançois Tigeot
cayman_cp_resume(struct radeon_device * rdev)1633926deccbSFrançois Tigeot static int cayman_cp_resume(struct radeon_device *rdev)
1634926deccbSFrançois Tigeot {
1635926deccbSFrançois Tigeot static const int ridx[] = {
1636926deccbSFrançois Tigeot RADEON_RING_TYPE_GFX_INDEX,
1637926deccbSFrançois Tigeot CAYMAN_RING_TYPE_CP1_INDEX,
1638926deccbSFrançois Tigeot CAYMAN_RING_TYPE_CP2_INDEX
1639926deccbSFrançois Tigeot };
1640926deccbSFrançois Tigeot static const unsigned cp_rb_cntl[] = {
1641926deccbSFrançois Tigeot CP_RB0_CNTL,
1642926deccbSFrançois Tigeot CP_RB1_CNTL,
1643926deccbSFrançois Tigeot CP_RB2_CNTL,
1644926deccbSFrançois Tigeot };
1645926deccbSFrançois Tigeot static const unsigned cp_rb_rptr_addr[] = {
1646926deccbSFrançois Tigeot CP_RB0_RPTR_ADDR,
1647926deccbSFrançois Tigeot CP_RB1_RPTR_ADDR,
1648926deccbSFrançois Tigeot CP_RB2_RPTR_ADDR
1649926deccbSFrançois Tigeot };
1650926deccbSFrançois Tigeot static const unsigned cp_rb_rptr_addr_hi[] = {
1651926deccbSFrançois Tigeot CP_RB0_RPTR_ADDR_HI,
1652926deccbSFrançois Tigeot CP_RB1_RPTR_ADDR_HI,
1653926deccbSFrançois Tigeot CP_RB2_RPTR_ADDR_HI
1654926deccbSFrançois Tigeot };
1655926deccbSFrançois Tigeot static const unsigned cp_rb_base[] = {
1656926deccbSFrançois Tigeot CP_RB0_BASE,
1657926deccbSFrançois Tigeot CP_RB1_BASE,
1658926deccbSFrançois Tigeot CP_RB2_BASE
1659926deccbSFrançois Tigeot };
1660c6f73aabSFrançois Tigeot static const unsigned cp_rb_rptr[] = {
1661c6f73aabSFrançois Tigeot CP_RB0_RPTR,
1662c6f73aabSFrançois Tigeot CP_RB1_RPTR,
1663c6f73aabSFrançois Tigeot CP_RB2_RPTR
1664c6f73aabSFrançois Tigeot };
1665c6f73aabSFrançois Tigeot static const unsigned cp_rb_wptr[] = {
1666c6f73aabSFrançois Tigeot CP_RB0_WPTR,
1667c6f73aabSFrançois Tigeot CP_RB1_WPTR,
1668c6f73aabSFrançois Tigeot CP_RB2_WPTR
1669c6f73aabSFrançois Tigeot };
1670926deccbSFrançois Tigeot struct radeon_ring *ring;
1671926deccbSFrançois Tigeot int i, r;
1672926deccbSFrançois Tigeot
1673926deccbSFrançois Tigeot /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
1674926deccbSFrançois Tigeot WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
1675926deccbSFrançois Tigeot SOFT_RESET_PA |
1676926deccbSFrançois Tigeot SOFT_RESET_SH |
1677926deccbSFrançois Tigeot SOFT_RESET_VGT |
1678926deccbSFrançois Tigeot SOFT_RESET_SPI |
1679926deccbSFrançois Tigeot SOFT_RESET_SX));
1680926deccbSFrançois Tigeot RREG32(GRBM_SOFT_RESET);
1681c4ef309bSzrj mdelay(15);
1682926deccbSFrançois Tigeot WREG32(GRBM_SOFT_RESET, 0);
1683926deccbSFrançois Tigeot RREG32(GRBM_SOFT_RESET);
1684926deccbSFrançois Tigeot
1685926deccbSFrançois Tigeot WREG32(CP_SEM_WAIT_TIMER, 0x0);
1686926deccbSFrançois Tigeot WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
1687926deccbSFrançois Tigeot
1688926deccbSFrançois Tigeot /* Set the write pointer delay */
1689926deccbSFrançois Tigeot WREG32(CP_RB_WPTR_DELAY, 0);
1690926deccbSFrançois Tigeot
1691926deccbSFrançois Tigeot WREG32(CP_DEBUG, (1 << 27));
1692926deccbSFrançois Tigeot
1693926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */
1694926deccbSFrançois Tigeot WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
1695926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0xff);
1696926deccbSFrançois Tigeot
1697926deccbSFrançois Tigeot for (i = 0; i < 3; ++i) {
1698926deccbSFrançois Tigeot uint32_t rb_cntl;
1699926deccbSFrançois Tigeot uint64_t addr;
1700926deccbSFrançois Tigeot
1701926deccbSFrançois Tigeot /* Set ring buffer size */
1702926deccbSFrançois Tigeot ring = &rdev->ring[ridx[i]];
17034cd92098Szrj rb_cntl = order_base_2(ring->ring_size / 8);
17044cd92098Szrj rb_cntl |= order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8;
1705926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
1706926deccbSFrançois Tigeot rb_cntl |= BUF_SWAP_32BIT;
1707926deccbSFrançois Tigeot #endif
1708926deccbSFrançois Tigeot WREG32(cp_rb_cntl[i], rb_cntl);
1709926deccbSFrançois Tigeot
1710926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */
1711926deccbSFrançois Tigeot addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1712926deccbSFrançois Tigeot WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1713926deccbSFrançois Tigeot WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
1714926deccbSFrançois Tigeot }
1715926deccbSFrançois Tigeot
1716926deccbSFrançois Tigeot /* set the rb base addr, this causes an internal reset of ALL rings */
1717926deccbSFrançois Tigeot for (i = 0; i < 3; ++i) {
1718926deccbSFrançois Tigeot ring = &rdev->ring[ridx[i]];
1719926deccbSFrançois Tigeot WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1720926deccbSFrançois Tigeot }
1721926deccbSFrançois Tigeot
1722926deccbSFrançois Tigeot for (i = 0; i < 3; ++i) {
1723926deccbSFrançois Tigeot /* Initialize the ring buffer's read and write pointers */
1724926deccbSFrançois Tigeot ring = &rdev->ring[ridx[i]];
1725926deccbSFrançois Tigeot WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
1726926deccbSFrançois Tigeot
1727c6f73aabSFrançois Tigeot ring->wptr = 0;
1728c6f73aabSFrançois Tigeot WREG32(cp_rb_rptr[i], 0);
1729c6f73aabSFrançois Tigeot WREG32(cp_rb_wptr[i], ring->wptr);
1730926deccbSFrançois Tigeot
1731c4ef309bSzrj mdelay(1);
1732926deccbSFrançois Tigeot WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1733926deccbSFrançois Tigeot }
1734926deccbSFrançois Tigeot
1735926deccbSFrançois Tigeot /* start the rings */
1736926deccbSFrançois Tigeot cayman_cp_start(rdev);
1737926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1738926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1739926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
1740926deccbSFrançois Tigeot /* this only test cp0 */
1741926deccbSFrançois Tigeot r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
1742926deccbSFrançois Tigeot if (r) {
1743926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1744926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1745926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
1746926deccbSFrançois Tigeot return r;
1747926deccbSFrançois Tigeot }
1748926deccbSFrançois Tigeot
1749c6f73aabSFrançois Tigeot if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
1750c6f73aabSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
1751c6f73aabSFrançois Tigeot
1752926deccbSFrançois Tigeot return 0;
1753926deccbSFrançois Tigeot }
1754926deccbSFrançois Tigeot
cayman_gpu_check_soft_reset(struct radeon_device * rdev)17554cd92098Szrj u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1756926deccbSFrançois Tigeot {
1757b403bed8SMichael Neumann u32 reset_mask = 0;
1758b403bed8SMichael Neumann u32 tmp;
1759926deccbSFrançois Tigeot
1760b403bed8SMichael Neumann /* GRBM_STATUS */
1761b403bed8SMichael Neumann tmp = RREG32(GRBM_STATUS);
1762b403bed8SMichael Neumann if (tmp & (PA_BUSY | SC_BUSY |
1763b403bed8SMichael Neumann SH_BUSY | SX_BUSY |
1764b403bed8SMichael Neumann TA_BUSY | VGT_BUSY |
1765b403bed8SMichael Neumann DB_BUSY | CB_BUSY |
1766b403bed8SMichael Neumann GDS_BUSY | SPI_BUSY |
1767b403bed8SMichael Neumann IA_BUSY | IA_BUSY_NO_DMA))
1768b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GFX;
1769b403bed8SMichael Neumann
1770b403bed8SMichael Neumann if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1771b403bed8SMichael Neumann CP_BUSY | CP_COHERENCY_BUSY))
1772b403bed8SMichael Neumann reset_mask |= RADEON_RESET_CP;
1773b403bed8SMichael Neumann
1774b403bed8SMichael Neumann if (tmp & GRBM_EE_BUSY)
1775b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1776b403bed8SMichael Neumann
1777b403bed8SMichael Neumann /* DMA_STATUS_REG 0 */
1778b403bed8SMichael Neumann tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1779b403bed8SMichael Neumann if (!(tmp & DMA_IDLE))
1780b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA;
1781b403bed8SMichael Neumann
1782b403bed8SMichael Neumann /* DMA_STATUS_REG 1 */
1783b403bed8SMichael Neumann tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1784b403bed8SMichael Neumann if (!(tmp & DMA_IDLE))
1785b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA1;
1786b403bed8SMichael Neumann
1787b403bed8SMichael Neumann /* SRBM_STATUS2 */
1788b403bed8SMichael Neumann tmp = RREG32(SRBM_STATUS2);
1789b403bed8SMichael Neumann if (tmp & DMA_BUSY)
1790b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA;
1791b403bed8SMichael Neumann
1792b403bed8SMichael Neumann if (tmp & DMA1_BUSY)
1793b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA1;
1794b403bed8SMichael Neumann
1795b403bed8SMichael Neumann /* SRBM_STATUS */
1796b403bed8SMichael Neumann tmp = RREG32(SRBM_STATUS);
1797b403bed8SMichael Neumann if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1798b403bed8SMichael Neumann reset_mask |= RADEON_RESET_RLC;
1799b403bed8SMichael Neumann
1800b403bed8SMichael Neumann if (tmp & IH_BUSY)
1801b403bed8SMichael Neumann reset_mask |= RADEON_RESET_IH;
1802b403bed8SMichael Neumann
1803b403bed8SMichael Neumann if (tmp & SEM_BUSY)
1804b403bed8SMichael Neumann reset_mask |= RADEON_RESET_SEM;
1805b403bed8SMichael Neumann
1806b403bed8SMichael Neumann if (tmp & GRBM_RQ_PENDING)
1807b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GRBM;
1808b403bed8SMichael Neumann
1809b403bed8SMichael Neumann if (tmp & VMC_BUSY)
1810b403bed8SMichael Neumann reset_mask |= RADEON_RESET_VMC;
1811b403bed8SMichael Neumann
1812b403bed8SMichael Neumann if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1813b403bed8SMichael Neumann MCC_BUSY | MCD_BUSY))
1814b403bed8SMichael Neumann reset_mask |= RADEON_RESET_MC;
1815b403bed8SMichael Neumann
1816b403bed8SMichael Neumann if (evergreen_is_display_hung(rdev))
1817b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DISPLAY;
1818b403bed8SMichael Neumann
1819b403bed8SMichael Neumann /* VM_L2_STATUS */
1820b403bed8SMichael Neumann tmp = RREG32(VM_L2_STATUS);
1821b403bed8SMichael Neumann if (tmp & L2_BUSY)
1822b403bed8SMichael Neumann reset_mask |= RADEON_RESET_VMC;
1823b403bed8SMichael Neumann
1824b403bed8SMichael Neumann /* Skip MC reset as it's mostly likely not hung, just busy */
1825b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_MC) {
1826b403bed8SMichael Neumann DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1827b403bed8SMichael Neumann reset_mask &= ~RADEON_RESET_MC;
1828b403bed8SMichael Neumann }
1829b403bed8SMichael Neumann
1830b403bed8SMichael Neumann return reset_mask;
1831b403bed8SMichael Neumann }
1832b403bed8SMichael Neumann
cayman_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)1833b403bed8SMichael Neumann static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1834b403bed8SMichael Neumann {
1835b403bed8SMichael Neumann struct evergreen_mc_save save;
1836b403bed8SMichael Neumann u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1837b403bed8SMichael Neumann u32 tmp;
1838b403bed8SMichael Neumann
1839b403bed8SMichael Neumann if (reset_mask == 0)
1840926deccbSFrançois Tigeot return;
1841926deccbSFrançois Tigeot
1842b403bed8SMichael Neumann dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1843b403bed8SMichael Neumann
1844b403bed8SMichael Neumann evergreen_print_gpu_status_regs(rdev);
1845b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1846b403bed8SMichael Neumann RREG32(0x14F8));
1847b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1848b403bed8SMichael Neumann RREG32(0x14D8));
1849b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n",
1850b403bed8SMichael Neumann RREG32(0x14FC));
1851b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1852b403bed8SMichael Neumann RREG32(0x14DC));
1853926deccbSFrançois Tigeot
1854926deccbSFrançois Tigeot /* Disable CP parsing/prefetching */
1855926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1856926deccbSFrançois Tigeot
1857b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA) {
1858b403bed8SMichael Neumann /* dma0 */
1859b403bed8SMichael Neumann tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1860b403bed8SMichael Neumann tmp &= ~DMA_RB_ENABLE;
1861b403bed8SMichael Neumann WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
1862b403bed8SMichael Neumann }
1863b403bed8SMichael Neumann
1864b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA1) {
1865b403bed8SMichael Neumann /* dma1 */
1866b403bed8SMichael Neumann tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1867b403bed8SMichael Neumann tmp &= ~DMA_RB_ENABLE;
1868b403bed8SMichael Neumann WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1869b403bed8SMichael Neumann }
1870b403bed8SMichael Neumann
1871c4ef309bSzrj udelay(50);
1872b403bed8SMichael Neumann
1873b403bed8SMichael Neumann evergreen_mc_stop(rdev, &save);
1874b403bed8SMichael Neumann if (evergreen_mc_wait_for_idle(rdev)) {
1875b403bed8SMichael Neumann dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1876b403bed8SMichael Neumann }
1877b403bed8SMichael Neumann
1878b403bed8SMichael Neumann if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1879b403bed8SMichael Neumann grbm_soft_reset = SOFT_RESET_CB |
1880926deccbSFrançois Tigeot SOFT_RESET_DB |
1881926deccbSFrançois Tigeot SOFT_RESET_GDS |
1882926deccbSFrançois Tigeot SOFT_RESET_PA |
1883926deccbSFrançois Tigeot SOFT_RESET_SC |
1884926deccbSFrançois Tigeot SOFT_RESET_SPI |
1885926deccbSFrançois Tigeot SOFT_RESET_SH |
1886926deccbSFrançois Tigeot SOFT_RESET_SX |
1887926deccbSFrançois Tigeot SOFT_RESET_TC |
1888926deccbSFrançois Tigeot SOFT_RESET_TA |
1889926deccbSFrançois Tigeot SOFT_RESET_VGT |
1890b403bed8SMichael Neumann SOFT_RESET_IA;
1891926deccbSFrançois Tigeot }
1892926deccbSFrançois Tigeot
1893b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_CP) {
1894b403bed8SMichael Neumann grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1895926deccbSFrançois Tigeot
1896b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_GRBM;
1897926deccbSFrançois Tigeot }
1898926deccbSFrançois Tigeot
1899926deccbSFrançois Tigeot if (reset_mask & RADEON_RESET_DMA)
1900b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DMA;
1901b403bed8SMichael Neumann
1902b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA1)
1903b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DMA1;
1904b403bed8SMichael Neumann
1905b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DISPLAY)
1906b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DC;
1907b403bed8SMichael Neumann
1908b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_RLC)
1909b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_RLC;
1910b403bed8SMichael Neumann
1911b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_SEM)
1912b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_SEM;
1913b403bed8SMichael Neumann
1914b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_IH)
1915b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_IH;
1916b403bed8SMichael Neumann
1917b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_GRBM)
1918b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_GRBM;
1919b403bed8SMichael Neumann
1920b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_VMC)
1921b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_VMC;
1922b403bed8SMichael Neumann
1923b403bed8SMichael Neumann if (!(rdev->flags & RADEON_IS_IGP)) {
1924b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_MC)
1925b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_MC;
1926b403bed8SMichael Neumann }
1927b403bed8SMichael Neumann
1928b403bed8SMichael Neumann if (grbm_soft_reset) {
1929b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET);
1930b403bed8SMichael Neumann tmp |= grbm_soft_reset;
1931b403bed8SMichael Neumann dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1932b403bed8SMichael Neumann WREG32(GRBM_SOFT_RESET, tmp);
1933b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET);
1934b403bed8SMichael Neumann
1935c4ef309bSzrj udelay(50);
1936b403bed8SMichael Neumann
1937b403bed8SMichael Neumann tmp &= ~grbm_soft_reset;
1938b403bed8SMichael Neumann WREG32(GRBM_SOFT_RESET, tmp);
1939b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET);
1940b403bed8SMichael Neumann }
1941b403bed8SMichael Neumann
1942b403bed8SMichael Neumann if (srbm_soft_reset) {
1943b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET);
1944b403bed8SMichael Neumann tmp |= srbm_soft_reset;
1945b403bed8SMichael Neumann dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1946b403bed8SMichael Neumann WREG32(SRBM_SOFT_RESET, tmp);
1947b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET);
1948b403bed8SMichael Neumann
1949c4ef309bSzrj udelay(50);
1950b403bed8SMichael Neumann
1951b403bed8SMichael Neumann tmp &= ~srbm_soft_reset;
1952b403bed8SMichael Neumann WREG32(SRBM_SOFT_RESET, tmp);
1953b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET);
1954b403bed8SMichael Neumann }
1955926deccbSFrançois Tigeot
1956926deccbSFrançois Tigeot /* Wait a little for things to settle down */
1957c4ef309bSzrj udelay(50);
1958926deccbSFrançois Tigeot
1959926deccbSFrançois Tigeot evergreen_mc_resume(rdev, &save);
1960c4ef309bSzrj udelay(50);
1961b403bed8SMichael Neumann
1962b403bed8SMichael Neumann evergreen_print_gpu_status_regs(rdev);
1963926deccbSFrançois Tigeot }
1964926deccbSFrançois Tigeot
cayman_asic_reset(struct radeon_device * rdev,bool hard)1965d78d3a22SFrançois Tigeot int cayman_asic_reset(struct radeon_device *rdev, bool hard)
1966926deccbSFrançois Tigeot {
1967b403bed8SMichael Neumann u32 reset_mask;
1968b403bed8SMichael Neumann
1969d78d3a22SFrançois Tigeot if (hard) {
1970d78d3a22SFrançois Tigeot evergreen_gpu_pci_config_reset(rdev);
1971d78d3a22SFrançois Tigeot return 0;
1972d78d3a22SFrançois Tigeot }
1973d78d3a22SFrançois Tigeot
1974b403bed8SMichael Neumann reset_mask = cayman_gpu_check_soft_reset(rdev);
1975b403bed8SMichael Neumann
1976b403bed8SMichael Neumann if (reset_mask)
1977b403bed8SMichael Neumann r600_set_bios_scratch_engine_hung(rdev, true);
1978b403bed8SMichael Neumann
1979b403bed8SMichael Neumann cayman_gpu_soft_reset(rdev, reset_mask);
1980b403bed8SMichael Neumann
1981b403bed8SMichael Neumann reset_mask = cayman_gpu_check_soft_reset(rdev);
1982b403bed8SMichael Neumann
1983c6f73aabSFrançois Tigeot if (reset_mask)
1984c6f73aabSFrançois Tigeot evergreen_gpu_pci_config_reset(rdev);
1985c6f73aabSFrançois Tigeot
1986b403bed8SMichael Neumann r600_set_bios_scratch_engine_hung(rdev, false);
1987b403bed8SMichael Neumann
1988b403bed8SMichael Neumann return 0;
1989b403bed8SMichael Neumann }
1990b403bed8SMichael Neumann
1991b403bed8SMichael Neumann /**
1992b403bed8SMichael Neumann * cayman_gfx_is_lockup - Check if the GFX engine is locked up
1993b403bed8SMichael Neumann *
1994b403bed8SMichael Neumann * @rdev: radeon_device pointer
1995b403bed8SMichael Neumann * @ring: radeon_ring structure holding ring information
1996b403bed8SMichael Neumann *
1997b403bed8SMichael Neumann * Check if the GFX engine is locked up.
1998b403bed8SMichael Neumann * Returns true if the engine appears to be locked up, false if not.
1999b403bed8SMichael Neumann */
cayman_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)2000b403bed8SMichael Neumann bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2001b403bed8SMichael Neumann {
2002b403bed8SMichael Neumann u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
2003b403bed8SMichael Neumann
2004b403bed8SMichael Neumann if (!(reset_mask & (RADEON_RESET_GFX |
2005926deccbSFrançois Tigeot RADEON_RESET_COMPUTE |
2006b403bed8SMichael Neumann RADEON_RESET_CP))) {
2007c6f73aabSFrançois Tigeot radeon_ring_lockup_update(rdev, ring);
2008b403bed8SMichael Neumann return false;
2009b403bed8SMichael Neumann }
2010b403bed8SMichael Neumann return radeon_ring_test_lockup(rdev, ring);
2011926deccbSFrançois Tigeot }
2012926deccbSFrançois Tigeot
cayman_uvd_init(struct radeon_device * rdev)2013d78d3a22SFrançois Tigeot static void cayman_uvd_init(struct radeon_device *rdev)
2014d78d3a22SFrançois Tigeot {
2015d78d3a22SFrançois Tigeot int r;
2016d78d3a22SFrançois Tigeot
2017d78d3a22SFrançois Tigeot if (!rdev->has_uvd)
2018d78d3a22SFrançois Tigeot return;
2019d78d3a22SFrançois Tigeot
2020d78d3a22SFrançois Tigeot r = radeon_uvd_init(rdev);
2021d78d3a22SFrançois Tigeot if (r) {
2022d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
2023d78d3a22SFrançois Tigeot /*
2024d78d3a22SFrançois Tigeot * At this point rdev->uvd.vcpu_bo is NULL which trickles down
2025d78d3a22SFrançois Tigeot * to early fails uvd_v2_2_resume() and thus nothing happens
2026d78d3a22SFrançois Tigeot * there. So it is pointless to try to go through that code
2027d78d3a22SFrançois Tigeot * hence why we disable uvd here.
2028d78d3a22SFrançois Tigeot */
2029d78d3a22SFrançois Tigeot rdev->has_uvd = 0;
2030d78d3a22SFrançois Tigeot return;
2031d78d3a22SFrançois Tigeot }
2032d78d3a22SFrançois Tigeot rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
2033d78d3a22SFrançois Tigeot r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
2034d78d3a22SFrançois Tigeot }
2035d78d3a22SFrançois Tigeot
cayman_uvd_start(struct radeon_device * rdev)2036d78d3a22SFrançois Tigeot static void cayman_uvd_start(struct radeon_device *rdev)
2037d78d3a22SFrançois Tigeot {
2038d78d3a22SFrançois Tigeot int r;
2039d78d3a22SFrançois Tigeot
2040d78d3a22SFrançois Tigeot if (!rdev->has_uvd)
2041d78d3a22SFrançois Tigeot return;
2042d78d3a22SFrançois Tigeot
2043d78d3a22SFrançois Tigeot r = uvd_v2_2_resume(rdev);
2044d78d3a22SFrançois Tigeot if (r) {
2045d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
2046d78d3a22SFrançois Tigeot goto error;
2047d78d3a22SFrançois Tigeot }
2048d78d3a22SFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
2049d78d3a22SFrançois Tigeot if (r) {
2050d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
2051d78d3a22SFrançois Tigeot goto error;
2052d78d3a22SFrançois Tigeot }
2053d78d3a22SFrançois Tigeot return;
2054d78d3a22SFrançois Tigeot
2055d78d3a22SFrançois Tigeot error:
2056d78d3a22SFrançois Tigeot rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2057d78d3a22SFrançois Tigeot }
2058d78d3a22SFrançois Tigeot
cayman_uvd_resume(struct radeon_device * rdev)2059d78d3a22SFrançois Tigeot static void cayman_uvd_resume(struct radeon_device *rdev)
2060d78d3a22SFrançois Tigeot {
2061d78d3a22SFrançois Tigeot struct radeon_ring *ring;
2062d78d3a22SFrançois Tigeot int r;
2063d78d3a22SFrançois Tigeot
2064d78d3a22SFrançois Tigeot if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
2065d78d3a22SFrançois Tigeot return;
2066d78d3a22SFrançois Tigeot
2067d78d3a22SFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
20681dedbd3bSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
2069d78d3a22SFrançois Tigeot if (r) {
2070d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
2071d78d3a22SFrançois Tigeot return;
2072d78d3a22SFrançois Tigeot }
2073d78d3a22SFrançois Tigeot r = uvd_v1_0_init(rdev);
2074d78d3a22SFrançois Tigeot if (r) {
2075d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
2076d78d3a22SFrançois Tigeot return;
2077d78d3a22SFrançois Tigeot }
2078d78d3a22SFrançois Tigeot }
2079d78d3a22SFrançois Tigeot
cayman_vce_init(struct radeon_device * rdev)2080d78d3a22SFrançois Tigeot static void cayman_vce_init(struct radeon_device *rdev)
2081d78d3a22SFrançois Tigeot {
2082d78d3a22SFrançois Tigeot int r;
2083d78d3a22SFrançois Tigeot
2084d78d3a22SFrançois Tigeot /* Only set for CHIP_ARUBA */
2085d78d3a22SFrançois Tigeot if (!rdev->has_vce)
2086d78d3a22SFrançois Tigeot return;
2087d78d3a22SFrançois Tigeot
2088d78d3a22SFrançois Tigeot r = radeon_vce_init(rdev);
2089d78d3a22SFrançois Tigeot if (r) {
2090d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
2091d78d3a22SFrançois Tigeot /*
2092d78d3a22SFrançois Tigeot * At this point rdev->vce.vcpu_bo is NULL which trickles down
2093d78d3a22SFrançois Tigeot * to early fails cayman_vce_start() and thus nothing happens
2094d78d3a22SFrançois Tigeot * there. So it is pointless to try to go through that code
2095d78d3a22SFrançois Tigeot * hence why we disable vce here.
2096d78d3a22SFrançois Tigeot */
2097d78d3a22SFrançois Tigeot rdev->has_vce = 0;
2098d78d3a22SFrançois Tigeot return;
2099d78d3a22SFrançois Tigeot }
2100d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
2101d78d3a22SFrançois Tigeot r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
2102d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
2103d78d3a22SFrançois Tigeot r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
2104d78d3a22SFrançois Tigeot }
2105d78d3a22SFrançois Tigeot
cayman_vce_start(struct radeon_device * rdev)2106d78d3a22SFrançois Tigeot static void cayman_vce_start(struct radeon_device *rdev)
2107d78d3a22SFrançois Tigeot {
2108d78d3a22SFrançois Tigeot int r;
2109d78d3a22SFrançois Tigeot
2110d78d3a22SFrançois Tigeot if (!rdev->has_vce)
2111d78d3a22SFrançois Tigeot return;
2112d78d3a22SFrançois Tigeot
2113d78d3a22SFrançois Tigeot r = radeon_vce_resume(rdev);
2114d78d3a22SFrançois Tigeot if (r) {
2115d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
2116d78d3a22SFrançois Tigeot goto error;
2117d78d3a22SFrançois Tigeot }
2118d78d3a22SFrançois Tigeot r = vce_v1_0_resume(rdev);
2119d78d3a22SFrançois Tigeot if (r) {
2120d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
2121d78d3a22SFrançois Tigeot goto error;
2122d78d3a22SFrançois Tigeot }
2123d78d3a22SFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
2124d78d3a22SFrançois Tigeot if (r) {
2125d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
2126d78d3a22SFrançois Tigeot goto error;
2127d78d3a22SFrançois Tigeot }
2128d78d3a22SFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
2129d78d3a22SFrançois Tigeot if (r) {
2130d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
2131d78d3a22SFrançois Tigeot goto error;
2132d78d3a22SFrançois Tigeot }
2133d78d3a22SFrançois Tigeot return;
2134d78d3a22SFrançois Tigeot
2135d78d3a22SFrançois Tigeot error:
2136d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
2137d78d3a22SFrançois Tigeot rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
2138d78d3a22SFrançois Tigeot }
2139d78d3a22SFrançois Tigeot
cayman_vce_resume(struct radeon_device * rdev)2140d78d3a22SFrançois Tigeot static void cayman_vce_resume(struct radeon_device *rdev)
2141d78d3a22SFrançois Tigeot {
2142d78d3a22SFrançois Tigeot struct radeon_ring *ring;
2143d78d3a22SFrançois Tigeot int r;
2144d78d3a22SFrançois Tigeot
2145d78d3a22SFrançois Tigeot if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
2146d78d3a22SFrançois Tigeot return;
2147d78d3a22SFrançois Tigeot
2148d78d3a22SFrançois Tigeot ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
2149d78d3a22SFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
2150d78d3a22SFrançois Tigeot if (r) {
2151d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
2152d78d3a22SFrançois Tigeot return;
2153d78d3a22SFrançois Tigeot }
2154d78d3a22SFrançois Tigeot ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
2155d78d3a22SFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
2156d78d3a22SFrançois Tigeot if (r) {
2157d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
2158d78d3a22SFrançois Tigeot return;
2159d78d3a22SFrançois Tigeot }
2160d78d3a22SFrançois Tigeot r = vce_v1_0_init(rdev);
2161d78d3a22SFrançois Tigeot if (r) {
2162d78d3a22SFrançois Tigeot dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
2163d78d3a22SFrançois Tigeot return;
2164d78d3a22SFrançois Tigeot }
2165d78d3a22SFrançois Tigeot }
2166d78d3a22SFrançois Tigeot
cayman_startup(struct radeon_device * rdev)2167926deccbSFrançois Tigeot static int cayman_startup(struct radeon_device *rdev)
2168926deccbSFrançois Tigeot {
2169926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2170926deccbSFrançois Tigeot int r;
2171926deccbSFrançois Tigeot
2172926deccbSFrançois Tigeot /* enable pcie gen2 link */
2173926deccbSFrançois Tigeot evergreen_pcie_gen2_enable(rdev);
217457e252bfSMichael Neumann /* enable aspm */
217557e252bfSMichael Neumann evergreen_program_aspm(rdev);
217657e252bfSMichael Neumann
21774cd92098Szrj /* scratch needs to be initialized before MC */
21784cd92098Szrj r = r600_vram_scratch_init(rdev);
21794cd92098Szrj if (r)
21804cd92098Szrj return r;
21814cd92098Szrj
218257e252bfSMichael Neumann evergreen_mc_program(rdev);
2183926deccbSFrançois Tigeot
2184c6f73aabSFrançois Tigeot if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
2185926deccbSFrançois Tigeot r = ni_mc_load_microcode(rdev);
2186926deccbSFrançois Tigeot if (r) {
2187926deccbSFrançois Tigeot DRM_ERROR("Failed to load MC firmware!\n");
2188926deccbSFrançois Tigeot return r;
2189926deccbSFrançois Tigeot }
2190926deccbSFrançois Tigeot }
2191926deccbSFrançois Tigeot
2192926deccbSFrançois Tigeot r = cayman_pcie_gart_enable(rdev);
2193926deccbSFrançois Tigeot if (r)
2194926deccbSFrançois Tigeot return r;
2195926deccbSFrançois Tigeot cayman_gpu_init(rdev);
2196926deccbSFrançois Tigeot
2197926deccbSFrançois Tigeot /* allocate rlc buffers */
2198926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) {
219957e252bfSMichael Neumann rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
22004cd92098Szrj rdev->rlc.reg_list_size =
22014cd92098Szrj (u32)ARRAY_SIZE(tn_rlc_save_restore_register_list);
220257e252bfSMichael Neumann rdev->rlc.cs_data = cayman_cs_data;
220357e252bfSMichael Neumann r = sumo_rlc_init(rdev);
2204926deccbSFrançois Tigeot if (r) {
2205926deccbSFrançois Tigeot DRM_ERROR("Failed to init rlc BOs!\n");
2206926deccbSFrançois Tigeot return r;
2207926deccbSFrançois Tigeot }
2208926deccbSFrançois Tigeot }
2209926deccbSFrançois Tigeot
2210926deccbSFrançois Tigeot /* allocate wb buffer */
2211926deccbSFrançois Tigeot r = radeon_wb_init(rdev);
2212926deccbSFrançois Tigeot if (r)
2213926deccbSFrançois Tigeot return r;
2214926deccbSFrançois Tigeot
2215926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
2216926deccbSFrançois Tigeot if (r) {
2217926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2218926deccbSFrançois Tigeot return r;
2219926deccbSFrançois Tigeot }
2220926deccbSFrançois Tigeot
2221d78d3a22SFrançois Tigeot cayman_uvd_start(rdev);
2222d78d3a22SFrançois Tigeot cayman_vce_start(rdev);
2223c59a5c48SFrançois Tigeot
2224926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
2225926deccbSFrançois Tigeot if (r) {
2226926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2227926deccbSFrançois Tigeot return r;
2228926deccbSFrançois Tigeot }
2229926deccbSFrançois Tigeot
2230926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
2231926deccbSFrançois Tigeot if (r) {
2232926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
2233926deccbSFrançois Tigeot return r;
2234926deccbSFrançois Tigeot }
2235926deccbSFrançois Tigeot
2236926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2237926deccbSFrançois Tigeot if (r) {
2238926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2239926deccbSFrançois Tigeot return r;
2240926deccbSFrançois Tigeot }
2241926deccbSFrançois Tigeot
2242926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2243926deccbSFrançois Tigeot if (r) {
2244926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2245926deccbSFrançois Tigeot return r;
2246926deccbSFrançois Tigeot }
2247926deccbSFrançois Tigeot
2248926deccbSFrançois Tigeot /* Enable IRQ */
2249f43cf1b1SMichael Neumann if (!rdev->irq.installed) {
2250f43cf1b1SMichael Neumann r = radeon_irq_kms_init(rdev);
2251f43cf1b1SMichael Neumann if (r)
2252f43cf1b1SMichael Neumann return r;
2253f43cf1b1SMichael Neumann }
2254f43cf1b1SMichael Neumann
2255926deccbSFrançois Tigeot r = r600_irq_init(rdev);
2256926deccbSFrançois Tigeot if (r) {
2257926deccbSFrançois Tigeot DRM_ERROR("radeon: IH init failed (%d).\n", r);
2258926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev);
2259926deccbSFrançois Tigeot return r;
2260926deccbSFrançois Tigeot }
2261926deccbSFrançois Tigeot evergreen_irq_set(rdev);
2262926deccbSFrançois Tigeot
2263926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
22644cd92098Szrj RADEON_CP_PACKET2);
2265926deccbSFrançois Tigeot if (r)
2266926deccbSFrançois Tigeot return r;
2267926deccbSFrançois Tigeot
2268926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2269926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
22704cd92098Szrj DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2271926deccbSFrançois Tigeot if (r)
2272926deccbSFrançois Tigeot return r;
2273926deccbSFrançois Tigeot
2274926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2275926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
22764cd92098Szrj DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2277926deccbSFrançois Tigeot if (r)
2278926deccbSFrançois Tigeot return r;
2279926deccbSFrançois Tigeot
2280926deccbSFrançois Tigeot r = cayman_cp_load_microcode(rdev);
2281926deccbSFrançois Tigeot if (r)
2282926deccbSFrançois Tigeot return r;
2283926deccbSFrançois Tigeot r = cayman_cp_resume(rdev);
2284926deccbSFrançois Tigeot if (r)
2285926deccbSFrançois Tigeot return r;
2286926deccbSFrançois Tigeot
2287926deccbSFrançois Tigeot r = cayman_dma_resume(rdev);
2288926deccbSFrançois Tigeot if (r)
2289926deccbSFrançois Tigeot return r;
2290926deccbSFrançois Tigeot
2291d78d3a22SFrançois Tigeot cayman_uvd_resume(rdev);
2292d78d3a22SFrançois Tigeot cayman_vce_resume(rdev);
2293c59a5c48SFrançois Tigeot
2294926deccbSFrançois Tigeot r = radeon_ib_pool_init(rdev);
2295926deccbSFrançois Tigeot if (r) {
2296926deccbSFrançois Tigeot dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
2297926deccbSFrançois Tigeot return r;
2298926deccbSFrançois Tigeot }
2299926deccbSFrançois Tigeot
2300926deccbSFrançois Tigeot r = radeon_vm_manager_init(rdev);
2301926deccbSFrançois Tigeot if (r) {
2302926deccbSFrançois Tigeot dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
2303926deccbSFrançois Tigeot return r;
2304926deccbSFrançois Tigeot }
2305926deccbSFrançois Tigeot
2306c59a5c48SFrançois Tigeot r = radeon_audio_init(rdev);
23074cd92098Szrj if (r)
23084cd92098Szrj return r;
2309926deccbSFrançois Tigeot
2310926deccbSFrançois Tigeot return 0;
2311926deccbSFrançois Tigeot }
2312926deccbSFrançois Tigeot
cayman_resume(struct radeon_device * rdev)2313926deccbSFrançois Tigeot int cayman_resume(struct radeon_device *rdev)
2314926deccbSFrançois Tigeot {
2315926deccbSFrançois Tigeot int r;
2316926deccbSFrançois Tigeot
2317926deccbSFrançois Tigeot /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2318926deccbSFrançois Tigeot * posting will perform necessary task to bring back GPU into good
2319926deccbSFrançois Tigeot * shape.
2320926deccbSFrançois Tigeot */
2321926deccbSFrançois Tigeot /* post card */
2322926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context);
2323926deccbSFrançois Tigeot
2324f43cf1b1SMichael Neumann /* init golden registers */
2325f43cf1b1SMichael Neumann ni_init_golden_registers(rdev);
2326f43cf1b1SMichael Neumann
2327c6f73aabSFrançois Tigeot if (rdev->pm.pm_method == PM_METHOD_DPM)
2328c6f73aabSFrançois Tigeot radeon_pm_resume(rdev);
2329c6f73aabSFrançois Tigeot
2330926deccbSFrançois Tigeot rdev->accel_working = true;
2331926deccbSFrançois Tigeot r = cayman_startup(rdev);
2332926deccbSFrançois Tigeot if (r) {
2333926deccbSFrançois Tigeot DRM_ERROR("cayman startup failed on resume\n");
2334926deccbSFrançois Tigeot rdev->accel_working = false;
2335926deccbSFrançois Tigeot return r;
2336926deccbSFrançois Tigeot }
2337926deccbSFrançois Tigeot return r;
2338926deccbSFrançois Tigeot }
2339926deccbSFrançois Tigeot
cayman_suspend(struct radeon_device * rdev)2340926deccbSFrançois Tigeot int cayman_suspend(struct radeon_device *rdev)
2341926deccbSFrançois Tigeot {
2342c6f73aabSFrançois Tigeot radeon_pm_suspend(rdev);
2343c59a5c48SFrançois Tigeot radeon_audio_fini(rdev);
2344b403bed8SMichael Neumann radeon_vm_manager_fini(rdev);
2345926deccbSFrançois Tigeot cayman_cp_enable(rdev, false);
2346926deccbSFrançois Tigeot cayman_dma_stop(rdev);
2347d78d3a22SFrançois Tigeot if (rdev->has_uvd) {
23484cd92098Szrj uvd_v1_0_fini(rdev);
2349f43cf1b1SMichael Neumann radeon_uvd_suspend(rdev);
2350d78d3a22SFrançois Tigeot }
2351926deccbSFrançois Tigeot evergreen_irq_suspend(rdev);
2352926deccbSFrançois Tigeot radeon_wb_disable(rdev);
2353926deccbSFrançois Tigeot cayman_pcie_gart_disable(rdev);
2354926deccbSFrançois Tigeot return 0;
2355926deccbSFrançois Tigeot }
2356926deccbSFrançois Tigeot
2357926deccbSFrançois Tigeot /* Plan is to move initialization in that function and use
2358926deccbSFrançois Tigeot * helper function so that radeon_device_init pretty much
2359926deccbSFrançois Tigeot * do nothing more than calling asic specific function. This
2360926deccbSFrançois Tigeot * should also allow to remove a bunch of callback function
2361926deccbSFrançois Tigeot * like vram_info.
2362926deccbSFrançois Tigeot */
cayman_init(struct radeon_device * rdev)2363926deccbSFrançois Tigeot int cayman_init(struct radeon_device *rdev)
2364926deccbSFrançois Tigeot {
2365926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2366926deccbSFrançois Tigeot int r;
2367926deccbSFrançois Tigeot
2368926deccbSFrançois Tigeot /* Read BIOS */
2369926deccbSFrançois Tigeot if (!radeon_get_bios(rdev)) {
2370926deccbSFrançois Tigeot if (ASIC_IS_AVIVO(rdev))
2371926deccbSFrançois Tigeot return -EINVAL;
2372926deccbSFrançois Tigeot }
2373926deccbSFrançois Tigeot /* Must be an ATOMBIOS */
2374926deccbSFrançois Tigeot if (!rdev->is_atom_bios) {
2375926deccbSFrançois Tigeot dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2376926deccbSFrançois Tigeot return -EINVAL;
2377926deccbSFrançois Tigeot }
2378926deccbSFrançois Tigeot r = radeon_atombios_init(rdev);
2379926deccbSFrançois Tigeot if (r)
2380926deccbSFrançois Tigeot return r;
2381926deccbSFrançois Tigeot
2382926deccbSFrançois Tigeot /* Post card if necessary */
2383926deccbSFrançois Tigeot if (!radeon_card_posted(rdev)) {
2384926deccbSFrançois Tigeot if (!rdev->bios) {
2385926deccbSFrançois Tigeot dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2386926deccbSFrançois Tigeot return -EINVAL;
2387926deccbSFrançois Tigeot }
2388926deccbSFrançois Tigeot DRM_INFO("GPU not posted. posting now...\n");
2389926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context);
2390926deccbSFrançois Tigeot }
2391f43cf1b1SMichael Neumann /* init golden registers */
2392f43cf1b1SMichael Neumann ni_init_golden_registers(rdev);
2393926deccbSFrançois Tigeot /* Initialize scratch registers */
2394926deccbSFrançois Tigeot r600_scratch_init(rdev);
2395926deccbSFrançois Tigeot /* Initialize surface registers */
2396926deccbSFrançois Tigeot radeon_surface_init(rdev);
2397926deccbSFrançois Tigeot /* Initialize clocks */
2398926deccbSFrançois Tigeot radeon_get_clock_info(rdev->ddev);
2399926deccbSFrançois Tigeot /* Fence driver */
2400926deccbSFrançois Tigeot r = radeon_fence_driver_init(rdev);
2401926deccbSFrançois Tigeot if (r)
2402926deccbSFrançois Tigeot return r;
2403926deccbSFrançois Tigeot /* initialize memory controller */
2404926deccbSFrançois Tigeot r = evergreen_mc_init(rdev);
2405926deccbSFrançois Tigeot if (r)
2406926deccbSFrançois Tigeot return r;
2407926deccbSFrançois Tigeot /* Memory manager */
2408926deccbSFrançois Tigeot r = radeon_bo_init(rdev);
2409926deccbSFrançois Tigeot if (r)
2410926deccbSFrançois Tigeot return r;
2411926deccbSFrançois Tigeot
2412c6f73aabSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) {
2413c6f73aabSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
2414c6f73aabSFrançois Tigeot r = ni_init_microcode(rdev);
2415c6f73aabSFrançois Tigeot if (r) {
2416c6f73aabSFrançois Tigeot DRM_ERROR("Failed to load firmware!\n");
2417c6f73aabSFrançois Tigeot return r;
2418c6f73aabSFrançois Tigeot }
2419c6f73aabSFrançois Tigeot }
2420c6f73aabSFrançois Tigeot } else {
2421c6f73aabSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
2422c6f73aabSFrançois Tigeot r = ni_init_microcode(rdev);
2423c6f73aabSFrançois Tigeot if (r) {
2424c6f73aabSFrançois Tigeot DRM_ERROR("Failed to load firmware!\n");
2425c6f73aabSFrançois Tigeot return r;
2426c6f73aabSFrançois Tigeot }
2427c6f73aabSFrançois Tigeot }
2428c6f73aabSFrançois Tigeot }
2429c6f73aabSFrançois Tigeot
2430c6f73aabSFrançois Tigeot /* Initialize power management */
2431c6f73aabSFrançois Tigeot radeon_pm_init(rdev);
2432c6f73aabSFrançois Tigeot
2433926deccbSFrançois Tigeot ring->ring_obj = NULL;
2434926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 1024 * 1024);
2435926deccbSFrançois Tigeot
2436926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2437926deccbSFrançois Tigeot ring->ring_obj = NULL;
2438926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 64 * 1024);
2439926deccbSFrançois Tigeot
2440926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2441926deccbSFrançois Tigeot ring->ring_obj = NULL;
2442926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 64 * 1024);
2443926deccbSFrançois Tigeot
2444d78d3a22SFrançois Tigeot cayman_uvd_init(rdev);
2445d78d3a22SFrançois Tigeot cayman_vce_init(rdev);
2446c59a5c48SFrançois Tigeot
2447926deccbSFrançois Tigeot rdev->ih.ring_obj = NULL;
2448926deccbSFrançois Tigeot r600_ih_ring_init(rdev, 64 * 1024);
2449926deccbSFrançois Tigeot
2450926deccbSFrançois Tigeot r = r600_pcie_gart_init(rdev);
2451926deccbSFrançois Tigeot if (r)
2452926deccbSFrançois Tigeot return r;
2453926deccbSFrançois Tigeot
2454926deccbSFrançois Tigeot rdev->accel_working = true;
2455926deccbSFrançois Tigeot r = cayman_startup(rdev);
2456926deccbSFrançois Tigeot if (r) {
2457926deccbSFrançois Tigeot dev_err(rdev->dev, "disabling GPU acceleration\n");
2458926deccbSFrançois Tigeot cayman_cp_fini(rdev);
2459926deccbSFrançois Tigeot cayman_dma_fini(rdev);
2460926deccbSFrançois Tigeot r600_irq_fini(rdev);
2461926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP)
246257e252bfSMichael Neumann sumo_rlc_fini(rdev);
2463926deccbSFrançois Tigeot radeon_wb_fini(rdev);
2464926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev);
2465926deccbSFrançois Tigeot radeon_vm_manager_fini(rdev);
2466926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev);
2467926deccbSFrançois Tigeot cayman_pcie_gart_fini(rdev);
2468926deccbSFrançois Tigeot rdev->accel_working = false;
2469926deccbSFrançois Tigeot }
2470926deccbSFrançois Tigeot
2471926deccbSFrançois Tigeot /* Don't start up if the MC ucode is missing.
2472926deccbSFrançois Tigeot * The default clocks and voltages before the MC ucode
2473926deccbSFrançois Tigeot * is loaded are not suffient for advanced operations.
2474926deccbSFrançois Tigeot *
2475926deccbSFrançois Tigeot * We can skip this check for TN, because there is no MC
2476926deccbSFrançois Tigeot * ucode.
2477926deccbSFrançois Tigeot */
2478926deccbSFrançois Tigeot if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
2479926deccbSFrançois Tigeot DRM_ERROR("radeon: MC ucode required for NI+.\n");
2480926deccbSFrançois Tigeot return -EINVAL;
2481926deccbSFrançois Tigeot }
2482926deccbSFrançois Tigeot
2483926deccbSFrançois Tigeot return 0;
2484926deccbSFrançois Tigeot }
2485926deccbSFrançois Tigeot
cayman_fini(struct radeon_device * rdev)2486926deccbSFrançois Tigeot void cayman_fini(struct radeon_device *rdev)
2487926deccbSFrançois Tigeot {
2488c6f73aabSFrançois Tigeot radeon_pm_fini(rdev);
2489926deccbSFrançois Tigeot cayman_cp_fini(rdev);
2490926deccbSFrançois Tigeot cayman_dma_fini(rdev);
2491926deccbSFrançois Tigeot r600_irq_fini(rdev);
2492926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP)
249357e252bfSMichael Neumann sumo_rlc_fini(rdev);
2494926deccbSFrançois Tigeot radeon_wb_fini(rdev);
2495926deccbSFrançois Tigeot radeon_vm_manager_fini(rdev);
2496926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev);
2497926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev);
24984cd92098Szrj uvd_v1_0_fini(rdev);
2499f43cf1b1SMichael Neumann radeon_uvd_fini(rdev);
2500d78d3a22SFrançois Tigeot if (rdev->has_vce)
2501c59a5c48SFrançois Tigeot radeon_vce_fini(rdev);
2502926deccbSFrançois Tigeot cayman_pcie_gart_fini(rdev);
2503926deccbSFrançois Tigeot r600_vram_scratch_fini(rdev);
2504926deccbSFrançois Tigeot radeon_gem_fini(rdev);
2505926deccbSFrançois Tigeot radeon_fence_driver_fini(rdev);
2506926deccbSFrançois Tigeot radeon_bo_fini(rdev);
2507926deccbSFrançois Tigeot radeon_atombios_fini(rdev);
2508926deccbSFrançois Tigeot ni_fini_microcode(rdev);
2509c4ef309bSzrj kfree(rdev->bios);
2510926deccbSFrançois Tigeot rdev->bios = NULL;
2511926deccbSFrançois Tigeot }
2512926deccbSFrançois Tigeot
2513926deccbSFrançois Tigeot /*
2514926deccbSFrançois Tigeot * vm
2515926deccbSFrançois Tigeot */
cayman_vm_init(struct radeon_device * rdev)2516926deccbSFrançois Tigeot int cayman_vm_init(struct radeon_device *rdev)
2517926deccbSFrançois Tigeot {
2518926deccbSFrançois Tigeot /* number of VMs */
2519926deccbSFrançois Tigeot rdev->vm_manager.nvm = 8;
2520926deccbSFrançois Tigeot /* base offset of vram pages */
2521926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) {
2522926deccbSFrançois Tigeot u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2523926deccbSFrançois Tigeot tmp <<= 22;
2524926deccbSFrançois Tigeot rdev->vm_manager.vram_base_offset = tmp;
2525926deccbSFrançois Tigeot } else
2526926deccbSFrançois Tigeot rdev->vm_manager.vram_base_offset = 0;
2527926deccbSFrançois Tigeot return 0;
2528926deccbSFrançois Tigeot }
2529926deccbSFrançois Tigeot
cayman_vm_fini(struct radeon_device * rdev)2530926deccbSFrançois Tigeot void cayman_vm_fini(struct radeon_device *rdev)
2531926deccbSFrançois Tigeot {
2532926deccbSFrançois Tigeot }
2533926deccbSFrançois Tigeot
253457e252bfSMichael Neumann /**
253557e252bfSMichael Neumann * cayman_vm_decode_fault - print human readable fault info
253657e252bfSMichael Neumann *
253757e252bfSMichael Neumann * @rdev: radeon_device pointer
253857e252bfSMichael Neumann * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
253957e252bfSMichael Neumann * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
254057e252bfSMichael Neumann *
254157e252bfSMichael Neumann * Print human readable fault information (cayman/TN).
254257e252bfSMichael Neumann */
cayman_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr)254357e252bfSMichael Neumann void cayman_vm_decode_fault(struct radeon_device *rdev,
254457e252bfSMichael Neumann u32 status, u32 addr)
254557e252bfSMichael Neumann {
254657e252bfSMichael Neumann u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
254757e252bfSMichael Neumann u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
254857e252bfSMichael Neumann u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
254957e252bfSMichael Neumann char *block;
255057e252bfSMichael Neumann
255157e252bfSMichael Neumann switch (mc_id) {
255257e252bfSMichael Neumann case 32:
255357e252bfSMichael Neumann case 16:
255457e252bfSMichael Neumann case 96:
255557e252bfSMichael Neumann case 80:
255657e252bfSMichael Neumann case 160:
255757e252bfSMichael Neumann case 144:
255857e252bfSMichael Neumann case 224:
255957e252bfSMichael Neumann case 208:
256057e252bfSMichael Neumann block = "CB";
256157e252bfSMichael Neumann break;
256257e252bfSMichael Neumann case 33:
256357e252bfSMichael Neumann case 17:
256457e252bfSMichael Neumann case 97:
256557e252bfSMichael Neumann case 81:
256657e252bfSMichael Neumann case 161:
256757e252bfSMichael Neumann case 145:
256857e252bfSMichael Neumann case 225:
256957e252bfSMichael Neumann case 209:
257057e252bfSMichael Neumann block = "CB_FMASK";
257157e252bfSMichael Neumann break;
257257e252bfSMichael Neumann case 34:
257357e252bfSMichael Neumann case 18:
257457e252bfSMichael Neumann case 98:
257557e252bfSMichael Neumann case 82:
257657e252bfSMichael Neumann case 162:
257757e252bfSMichael Neumann case 146:
257857e252bfSMichael Neumann case 226:
257957e252bfSMichael Neumann case 210:
258057e252bfSMichael Neumann block = "CB_CMASK";
258157e252bfSMichael Neumann break;
258257e252bfSMichael Neumann case 35:
258357e252bfSMichael Neumann case 19:
258457e252bfSMichael Neumann case 99:
258557e252bfSMichael Neumann case 83:
258657e252bfSMichael Neumann case 163:
258757e252bfSMichael Neumann case 147:
258857e252bfSMichael Neumann case 227:
258957e252bfSMichael Neumann case 211:
259057e252bfSMichael Neumann block = "CB_IMMED";
259157e252bfSMichael Neumann break;
259257e252bfSMichael Neumann case 36:
259357e252bfSMichael Neumann case 20:
259457e252bfSMichael Neumann case 100:
259557e252bfSMichael Neumann case 84:
259657e252bfSMichael Neumann case 164:
259757e252bfSMichael Neumann case 148:
259857e252bfSMichael Neumann case 228:
259957e252bfSMichael Neumann case 212:
260057e252bfSMichael Neumann block = "DB";
260157e252bfSMichael Neumann break;
260257e252bfSMichael Neumann case 37:
260357e252bfSMichael Neumann case 21:
260457e252bfSMichael Neumann case 101:
260557e252bfSMichael Neumann case 85:
260657e252bfSMichael Neumann case 165:
260757e252bfSMichael Neumann case 149:
260857e252bfSMichael Neumann case 229:
260957e252bfSMichael Neumann case 213:
261057e252bfSMichael Neumann block = "DB_HTILE";
261157e252bfSMichael Neumann break;
261257e252bfSMichael Neumann case 38:
261357e252bfSMichael Neumann case 22:
261457e252bfSMichael Neumann case 102:
261557e252bfSMichael Neumann case 86:
261657e252bfSMichael Neumann case 166:
261757e252bfSMichael Neumann case 150:
261857e252bfSMichael Neumann case 230:
261957e252bfSMichael Neumann case 214:
262057e252bfSMichael Neumann block = "SX";
262157e252bfSMichael Neumann break;
262257e252bfSMichael Neumann case 39:
262357e252bfSMichael Neumann case 23:
262457e252bfSMichael Neumann case 103:
262557e252bfSMichael Neumann case 87:
262657e252bfSMichael Neumann case 167:
262757e252bfSMichael Neumann case 151:
262857e252bfSMichael Neumann case 231:
262957e252bfSMichael Neumann case 215:
263057e252bfSMichael Neumann block = "DB_STEN";
263157e252bfSMichael Neumann break;
263257e252bfSMichael Neumann case 40:
263357e252bfSMichael Neumann case 24:
263457e252bfSMichael Neumann case 104:
263557e252bfSMichael Neumann case 88:
263657e252bfSMichael Neumann case 232:
263757e252bfSMichael Neumann case 216:
263857e252bfSMichael Neumann case 168:
263957e252bfSMichael Neumann case 152:
264057e252bfSMichael Neumann block = "TC_TFETCH";
264157e252bfSMichael Neumann break;
264257e252bfSMichael Neumann case 41:
264357e252bfSMichael Neumann case 25:
264457e252bfSMichael Neumann case 105:
264557e252bfSMichael Neumann case 89:
264657e252bfSMichael Neumann case 233:
264757e252bfSMichael Neumann case 217:
264857e252bfSMichael Neumann case 169:
264957e252bfSMichael Neumann case 153:
265057e252bfSMichael Neumann block = "TC_VFETCH";
265157e252bfSMichael Neumann break;
265257e252bfSMichael Neumann case 42:
265357e252bfSMichael Neumann case 26:
265457e252bfSMichael Neumann case 106:
265557e252bfSMichael Neumann case 90:
265657e252bfSMichael Neumann case 234:
265757e252bfSMichael Neumann case 218:
265857e252bfSMichael Neumann case 170:
265957e252bfSMichael Neumann case 154:
266057e252bfSMichael Neumann block = "VC";
266157e252bfSMichael Neumann break;
266257e252bfSMichael Neumann case 112:
266357e252bfSMichael Neumann block = "CP";
266457e252bfSMichael Neumann break;
266557e252bfSMichael Neumann case 113:
266657e252bfSMichael Neumann case 114:
266757e252bfSMichael Neumann block = "SH";
266857e252bfSMichael Neumann break;
266957e252bfSMichael Neumann case 115:
267057e252bfSMichael Neumann block = "VGT";
267157e252bfSMichael Neumann break;
267257e252bfSMichael Neumann case 178:
267357e252bfSMichael Neumann block = "IH";
267457e252bfSMichael Neumann break;
267557e252bfSMichael Neumann case 51:
267657e252bfSMichael Neumann block = "RLC";
267757e252bfSMichael Neumann break;
267857e252bfSMichael Neumann case 55:
267957e252bfSMichael Neumann block = "DMA";
268057e252bfSMichael Neumann break;
268157e252bfSMichael Neumann case 56:
268257e252bfSMichael Neumann block = "HDP";
268357e252bfSMichael Neumann break;
268457e252bfSMichael Neumann default:
268557e252bfSMichael Neumann block = "unknown";
268657e252bfSMichael Neumann break;
268757e252bfSMichael Neumann }
268857e252bfSMichael Neumann
268957e252bfSMichael Neumann printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
269057e252bfSMichael Neumann protections, vmid, addr,
269157e252bfSMichael Neumann (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
269257e252bfSMichael Neumann block, mc_id);
269357e252bfSMichael Neumann }
269457e252bfSMichael Neumann
2695926deccbSFrançois Tigeot /**
2696926deccbSFrançois Tigeot * cayman_vm_flush - vm flush using the CP
2697926deccbSFrançois Tigeot *
2698926deccbSFrançois Tigeot * @rdev: radeon_device pointer
2699926deccbSFrançois Tigeot *
2700926deccbSFrançois Tigeot * Update the page table base and flush the VM TLB
2701926deccbSFrançois Tigeot * using the CP (cayman-si).
2702926deccbSFrançois Tigeot */
cayman_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)27037dcf36dcSFrançois Tigeot void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
27047dcf36dcSFrançois Tigeot unsigned vm_id, uint64_t pd_addr)
2705926deccbSFrançois Tigeot {
27067dcf36dcSFrançois Tigeot radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2), 0));
27077dcf36dcSFrançois Tigeot radeon_ring_write(ring, pd_addr >> 12);
2708926deccbSFrançois Tigeot
2709926deccbSFrançois Tigeot /* flush hdp cache */
2710926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
2711926deccbSFrançois Tigeot radeon_ring_write(ring, 0x1);
2712926deccbSFrançois Tigeot
2713926deccbSFrançois Tigeot /* bits 0-7 are the VM contexts0-7 */
2714926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
27157dcf36dcSFrançois Tigeot radeon_ring_write(ring, 1 << vm_id);
27167dcf36dcSFrançois Tigeot
27177dcf36dcSFrançois Tigeot /* wait for the invalidate to complete */
27187dcf36dcSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
27197dcf36dcSFrançois Tigeot radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */
27207dcf36dcSFrançois Tigeot WAIT_REG_MEM_ENGINE(0))); /* me */
27217dcf36dcSFrançois Tigeot radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
27227dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0);
27237dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0); /* ref */
27247dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0); /* mask */
27257dcf36dcSFrançois Tigeot radeon_ring_write(ring, 0x20); /* poll interval */
2726926deccbSFrançois Tigeot
2727926deccbSFrançois Tigeot /* sync PFP to ME, otherwise we might get invalid PFP reads */
2728926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2729926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0);
2730926deccbSFrançois Tigeot }
2731c59a5c48SFrançois Tigeot
tn_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)2732c59a5c48SFrançois Tigeot int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
2733c59a5c48SFrançois Tigeot {
2734c59a5c48SFrançois Tigeot struct atom_clock_dividers dividers;
2735c59a5c48SFrançois Tigeot int r, i;
2736c59a5c48SFrançois Tigeot
2737c59a5c48SFrançois Tigeot r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2738c59a5c48SFrançois Tigeot ecclk, false, ÷rs);
2739c59a5c48SFrançois Tigeot if (r)
2740c59a5c48SFrançois Tigeot return r;
2741c59a5c48SFrançois Tigeot
2742c59a5c48SFrançois Tigeot for (i = 0; i < 100; i++) {
2743c59a5c48SFrançois Tigeot if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
2744c59a5c48SFrançois Tigeot break;
2745c59a5c48SFrançois Tigeot mdelay(10);
2746c59a5c48SFrançois Tigeot }
2747c59a5c48SFrançois Tigeot if (i == 100)
2748c59a5c48SFrançois Tigeot return -ETIMEDOUT;
2749c59a5c48SFrançois Tigeot
2750c59a5c48SFrançois Tigeot WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK));
2751c59a5c48SFrançois Tigeot
2752c59a5c48SFrançois Tigeot for (i = 0; i < 100; i++) {
2753c59a5c48SFrançois Tigeot if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
2754c59a5c48SFrançois Tigeot break;
2755c59a5c48SFrançois Tigeot mdelay(10);
2756c59a5c48SFrançois Tigeot }
2757c59a5c48SFrançois Tigeot if (i == 100)
2758c59a5c48SFrançois Tigeot return -ETIMEDOUT;
2759c59a5c48SFrançois Tigeot
2760c59a5c48SFrançois Tigeot return 0;
2761c59a5c48SFrançois Tigeot }
2762