xref: /dflybsd-src/sys/dev/drm/radeon/ni.c (revision a85cb24f18e3804e75ab8bcda7692564d0563317)
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, &dividers);
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