xref: /openbmc/linux/drivers/gpu/drm/radeon/ni.c (revision ecc23d0a422a3118fcf6e4f0a46e17a6c2047b02)
10af62b01SAlex Deucher /*
20af62b01SAlex Deucher  * Copyright 2010 Advanced Micro Devices, Inc.
30af62b01SAlex Deucher  *
40af62b01SAlex Deucher  * Permission is hereby granted, free of charge, to any person obtaining a
50af62b01SAlex Deucher  * copy of this software and associated documentation files (the "Software"),
60af62b01SAlex Deucher  * to deal in the Software without restriction, including without limitation
70af62b01SAlex Deucher  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
80af62b01SAlex Deucher  * and/or sell copies of the Software, and to permit persons to whom the
90af62b01SAlex Deucher  * Software is furnished to do so, subject to the following conditions:
100af62b01SAlex Deucher  *
110af62b01SAlex Deucher  * The above copyright notice and this permission notice shall be included in
120af62b01SAlex Deucher  * all copies or substantial portions of the Software.
130af62b01SAlex Deucher  *
140af62b01SAlex Deucher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
150af62b01SAlex Deucher  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
160af62b01SAlex Deucher  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
170af62b01SAlex Deucher  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
180af62b01SAlex Deucher  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
190af62b01SAlex Deucher  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
200af62b01SAlex Deucher  * OTHER DEALINGS IN THE SOFTWARE.
210af62b01SAlex Deucher  *
220af62b01SAlex Deucher  * Authors: Alex Deucher
230af62b01SAlex Deucher  */
24c182615fSSam Ravnborg 
250af62b01SAlex Deucher #include <linux/firmware.h>
26e0cd3608SPaul Gortmaker #include <linux/module.h>
272ef79416SThomas Zimmermann #include <linux/pci.h>
282ef79416SThomas Zimmermann #include <linux/slab.h>
29c182615fSSam Ravnborg 
30c182615fSSam Ravnborg #include <drm/radeon_drm.h>
31c182615fSSam Ravnborg 
32c182615fSSam Ravnborg #include "atom.h"
33c182615fSSam Ravnborg #include "cayman_blit_shaders.h"
34c182615fSSam Ravnborg #include "clearstate_cayman.h"
354fe1999eSLee Jones #include "evergreen.h"
36ef072392SLee Jones #include "ni.h"
37c182615fSSam Ravnborg #include "ni_reg.h"
38c182615fSSam Ravnborg #include "nid.h"
390af62b01SAlex Deucher #include "radeon.h"
400af62b01SAlex Deucher #include "radeon_asic.h"
41bfc1f97dSSlava Grigorev #include "radeon_audio.h"
42138e4e16SAlex Deucher #include "radeon_ucode.h"
432948f5e6SAlex Deucher 
449e5acbc2SDenys Vlasenko /*
459e5acbc2SDenys Vlasenko  * Indirect registers accessor
469e5acbc2SDenys Vlasenko  */
tn_smc_rreg(struct radeon_device * rdev,u32 reg)479e5acbc2SDenys Vlasenko u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
489e5acbc2SDenys Vlasenko {
499e5acbc2SDenys Vlasenko 	unsigned long flags;
509e5acbc2SDenys Vlasenko 	u32 r;
519e5acbc2SDenys Vlasenko 
529e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->smc_idx_lock, flags);
539e5acbc2SDenys Vlasenko 	WREG32(TN_SMC_IND_INDEX_0, (reg));
549e5acbc2SDenys Vlasenko 	r = RREG32(TN_SMC_IND_DATA_0);
559e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
569e5acbc2SDenys Vlasenko 	return r;
579e5acbc2SDenys Vlasenko }
589e5acbc2SDenys Vlasenko 
tn_smc_wreg(struct radeon_device * rdev,u32 reg,u32 v)599e5acbc2SDenys Vlasenko void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
609e5acbc2SDenys Vlasenko {
619e5acbc2SDenys Vlasenko 	unsigned long flags;
629e5acbc2SDenys Vlasenko 
639e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->smc_idx_lock, flags);
649e5acbc2SDenys Vlasenko 	WREG32(TN_SMC_IND_INDEX_0, (reg));
659e5acbc2SDenys Vlasenko 	WREG32(TN_SMC_IND_DATA_0, (v));
669e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
679e5acbc2SDenys Vlasenko }
689e5acbc2SDenys Vlasenko 
691fd11777SAlex Deucher static const u32 tn_rlc_save_restore_register_list[] =
702948f5e6SAlex Deucher {
712948f5e6SAlex Deucher 	0x98fc,
722948f5e6SAlex Deucher 	0x98f0,
732948f5e6SAlex Deucher 	0x9834,
742948f5e6SAlex Deucher 	0x9838,
752948f5e6SAlex Deucher 	0x9870,
762948f5e6SAlex Deucher 	0x9874,
772948f5e6SAlex Deucher 	0x8a14,
782948f5e6SAlex Deucher 	0x8b24,
792948f5e6SAlex Deucher 	0x8bcc,
802948f5e6SAlex Deucher 	0x8b10,
812948f5e6SAlex Deucher 	0x8c30,
822948f5e6SAlex Deucher 	0x8d00,
832948f5e6SAlex Deucher 	0x8d04,
842948f5e6SAlex Deucher 	0x8c00,
852948f5e6SAlex Deucher 	0x8c04,
862948f5e6SAlex Deucher 	0x8c10,
872948f5e6SAlex Deucher 	0x8c14,
882948f5e6SAlex Deucher 	0x8d8c,
892948f5e6SAlex Deucher 	0x8cf0,
902948f5e6SAlex Deucher 	0x8e38,
912948f5e6SAlex Deucher 	0x9508,
922948f5e6SAlex Deucher 	0x9688,
932948f5e6SAlex Deucher 	0x9608,
942948f5e6SAlex Deucher 	0x960c,
952948f5e6SAlex Deucher 	0x9610,
962948f5e6SAlex Deucher 	0x9614,
972948f5e6SAlex Deucher 	0x88c4,
982948f5e6SAlex Deucher 	0x8978,
992948f5e6SAlex Deucher 	0x88d4,
1002948f5e6SAlex Deucher 	0x900c,
1012948f5e6SAlex Deucher 	0x9100,
1022948f5e6SAlex Deucher 	0x913c,
1032948f5e6SAlex Deucher 	0x90e8,
1042948f5e6SAlex Deucher 	0x9354,
1052948f5e6SAlex Deucher 	0xa008,
1062948f5e6SAlex Deucher 	0x98f8,
1072948f5e6SAlex Deucher 	0x9148,
1082948f5e6SAlex Deucher 	0x914c,
1092948f5e6SAlex Deucher 	0x3f94,
1102948f5e6SAlex Deucher 	0x98f4,
1112948f5e6SAlex Deucher 	0x9b7c,
1122948f5e6SAlex Deucher 	0x3f8c,
1132948f5e6SAlex Deucher 	0x8950,
1142948f5e6SAlex Deucher 	0x8954,
1152948f5e6SAlex Deucher 	0x8a18,
1162948f5e6SAlex Deucher 	0x8b28,
1172948f5e6SAlex Deucher 	0x9144,
1182948f5e6SAlex Deucher 	0x3f90,
1192948f5e6SAlex Deucher 	0x915c,
1202948f5e6SAlex Deucher 	0x9160,
1212948f5e6SAlex Deucher 	0x9178,
1222948f5e6SAlex Deucher 	0x917c,
1232948f5e6SAlex Deucher 	0x9180,
1242948f5e6SAlex Deucher 	0x918c,
1252948f5e6SAlex Deucher 	0x9190,
1262948f5e6SAlex Deucher 	0x9194,
1272948f5e6SAlex Deucher 	0x9198,
1282948f5e6SAlex Deucher 	0x919c,
1292948f5e6SAlex Deucher 	0x91a8,
1302948f5e6SAlex Deucher 	0x91ac,
1312948f5e6SAlex Deucher 	0x91b0,
1322948f5e6SAlex Deucher 	0x91b4,
1332948f5e6SAlex Deucher 	0x91b8,
1342948f5e6SAlex Deucher 	0x91c4,
1352948f5e6SAlex Deucher 	0x91c8,
1362948f5e6SAlex Deucher 	0x91cc,
1372948f5e6SAlex Deucher 	0x91d0,
1382948f5e6SAlex Deucher 	0x91d4,
1392948f5e6SAlex Deucher 	0x91e0,
1402948f5e6SAlex Deucher 	0x91e4,
1412948f5e6SAlex Deucher 	0x91ec,
1422948f5e6SAlex Deucher 	0x91f0,
1432948f5e6SAlex Deucher 	0x91f4,
1442948f5e6SAlex Deucher 	0x9200,
1452948f5e6SAlex Deucher 	0x9204,
1462948f5e6SAlex Deucher 	0x929c,
1472948f5e6SAlex Deucher 	0x8030,
1482948f5e6SAlex Deucher 	0x9150,
1492948f5e6SAlex Deucher 	0x9a60,
1502948f5e6SAlex Deucher 	0x920c,
1512948f5e6SAlex Deucher 	0x9210,
1522948f5e6SAlex Deucher 	0x9228,
1532948f5e6SAlex Deucher 	0x922c,
1542948f5e6SAlex Deucher 	0x9244,
1552948f5e6SAlex Deucher 	0x9248,
1562948f5e6SAlex Deucher 	0x91e8,
1572948f5e6SAlex Deucher 	0x9294,
1582948f5e6SAlex Deucher 	0x9208,
1592948f5e6SAlex Deucher 	0x9224,
1602948f5e6SAlex Deucher 	0x9240,
1612948f5e6SAlex Deucher 	0x9220,
1622948f5e6SAlex Deucher 	0x923c,
1632948f5e6SAlex Deucher 	0x9258,
1642948f5e6SAlex Deucher 	0x9744,
1652948f5e6SAlex Deucher 	0xa200,
1662948f5e6SAlex Deucher 	0xa204,
1672948f5e6SAlex Deucher 	0xa208,
1682948f5e6SAlex Deucher 	0xa20c,
1692948f5e6SAlex Deucher 	0x8d58,
1702948f5e6SAlex Deucher 	0x9030,
1712948f5e6SAlex Deucher 	0x9034,
1722948f5e6SAlex Deucher 	0x9038,
1732948f5e6SAlex Deucher 	0x903c,
1742948f5e6SAlex Deucher 	0x9040,
1752948f5e6SAlex Deucher 	0x9654,
1762948f5e6SAlex Deucher 	0x897c,
1772948f5e6SAlex Deucher 	0xa210,
1782948f5e6SAlex Deucher 	0xa214,
1792948f5e6SAlex Deucher 	0x9868,
1802948f5e6SAlex Deucher 	0xa02c,
1812948f5e6SAlex Deucher 	0x9664,
1822948f5e6SAlex Deucher 	0x9698,
1832948f5e6SAlex Deucher 	0x949c,
1842948f5e6SAlex Deucher 	0x8e10,
1852948f5e6SAlex Deucher 	0x8e18,
1862948f5e6SAlex Deucher 	0x8c50,
1872948f5e6SAlex Deucher 	0x8c58,
1882948f5e6SAlex Deucher 	0x8c60,
1892948f5e6SAlex Deucher 	0x8c68,
1902948f5e6SAlex Deucher 	0x89b4,
1912948f5e6SAlex Deucher 	0x9830,
1922948f5e6SAlex Deucher 	0x802c,
1932948f5e6SAlex Deucher };
1940af62b01SAlex Deucher 
1950af62b01SAlex Deucher /* Firmware Names */
1960af62b01SAlex Deucher MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
1970af62b01SAlex Deucher MODULE_FIRMWARE("radeon/BARTS_me.bin");
1980af62b01SAlex Deucher MODULE_FIRMWARE("radeon/BARTS_mc.bin");
1996596afd4SAlex Deucher MODULE_FIRMWARE("radeon/BARTS_smc.bin");
2000af62b01SAlex Deucher MODULE_FIRMWARE("radeon/BTC_rlc.bin");
2010af62b01SAlex Deucher MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
2020af62b01SAlex Deucher MODULE_FIRMWARE("radeon/TURKS_me.bin");
2030af62b01SAlex Deucher MODULE_FIRMWARE("radeon/TURKS_mc.bin");
2046596afd4SAlex Deucher MODULE_FIRMWARE("radeon/TURKS_smc.bin");
2050af62b01SAlex Deucher MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
2060af62b01SAlex Deucher MODULE_FIRMWARE("radeon/CAICOS_me.bin");
2070af62b01SAlex Deucher MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
2086596afd4SAlex Deucher MODULE_FIRMWARE("radeon/CAICOS_smc.bin");
2099b8253ceSAlex Deucher MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
2109b8253ceSAlex Deucher MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
2119b8253ceSAlex Deucher MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
2129b8253ceSAlex Deucher MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
21369e0b57aSAlex Deucher MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
214c420c745SAlex Deucher MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
215c420c745SAlex Deucher MODULE_FIRMWARE("radeon/ARUBA_me.bin");
216c420c745SAlex Deucher MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
2170af62b01SAlex Deucher 
218a2c96a21SAlex Deucher 
219a2c96a21SAlex Deucher static const u32 cayman_golden_registers2[] =
220a2c96a21SAlex Deucher {
221a2c96a21SAlex Deucher 	0x3e5c, 0xffffffff, 0x00000000,
222a2c96a21SAlex Deucher 	0x3e48, 0xffffffff, 0x00000000,
223a2c96a21SAlex Deucher 	0x3e4c, 0xffffffff, 0x00000000,
224a2c96a21SAlex Deucher 	0x3e64, 0xffffffff, 0x00000000,
225a2c96a21SAlex Deucher 	0x3e50, 0xffffffff, 0x00000000,
226a2c96a21SAlex Deucher 	0x3e60, 0xffffffff, 0x00000000
227a2c96a21SAlex Deucher };
228a2c96a21SAlex Deucher 
229a2c96a21SAlex Deucher static const u32 cayman_golden_registers[] =
230a2c96a21SAlex Deucher {
231a2c96a21SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
232a2c96a21SAlex Deucher 	0x5e78, 0x8f311ff1, 0x001000f0,
233a2c96a21SAlex Deucher 	0x3f90, 0xffff0000, 0xff000000,
234a2c96a21SAlex Deucher 	0x9148, 0xffff0000, 0xff000000,
235a2c96a21SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
236a2c96a21SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
237a2c96a21SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
238a2c96a21SAlex Deucher 	0xbd4, 0x70073777, 0x00011003,
239a2c96a21SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
240a2c96a21SAlex Deucher 	0xd0b8, 0x73773777, 0x02011003,
241a2c96a21SAlex Deucher 	0x5bc0, 0x00200000, 0x50100000,
242a2c96a21SAlex Deucher 	0x98f8, 0x33773777, 0x02011003,
243a2c96a21SAlex Deucher 	0x98fc, 0xffffffff, 0x76541032,
244a2c96a21SAlex Deucher 	0x7030, 0x31000311, 0x00000011,
245a2c96a21SAlex Deucher 	0x2f48, 0x33773777, 0x42010001,
246a2c96a21SAlex Deucher 	0x6b28, 0x00000010, 0x00000012,
247a2c96a21SAlex Deucher 	0x7728, 0x00000010, 0x00000012,
248a2c96a21SAlex Deucher 	0x10328, 0x00000010, 0x00000012,
249a2c96a21SAlex Deucher 	0x10f28, 0x00000010, 0x00000012,
250a2c96a21SAlex Deucher 	0x11b28, 0x00000010, 0x00000012,
251a2c96a21SAlex Deucher 	0x12728, 0x00000010, 0x00000012,
252a2c96a21SAlex Deucher 	0x240c, 0x000007ff, 0x00000000,
253a2c96a21SAlex Deucher 	0x8a14, 0xf000001f, 0x00000007,
254a2c96a21SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
255a2c96a21SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
256a2c96a21SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
257a2c96a21SAlex Deucher 	0x10c, 0x00000001, 0x00010003,
258a2c96a21SAlex Deucher 	0xa02c, 0xffffffff, 0x0000009b,
259a2c96a21SAlex Deucher 	0x913c, 0x0000010f, 0x01000100,
260a2c96a21SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
261a2c96a21SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
262a2c96a21SAlex Deucher 	0x9508, 0x3700001f, 0x00000002,
263a2c96a21SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
264a2c96a21SAlex Deucher 	0x88c4, 0x001f3ae3, 0x00000082,
265a2c96a21SAlex Deucher 	0x88d0, 0xffffffff, 0x0f40df40,
266a2c96a21SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
267a2c96a21SAlex Deucher 	0x8974, 0xffffffff, 0x00000000
268a2c96a21SAlex Deucher };
269a2c96a21SAlex Deucher 
270a2c96a21SAlex Deucher static const u32 dvst_golden_registers2[] =
271a2c96a21SAlex Deucher {
272a2c96a21SAlex Deucher 	0x8f8, 0xffffffff, 0,
273a2c96a21SAlex Deucher 	0x8fc, 0x00380000, 0,
274a2c96a21SAlex Deucher 	0x8f8, 0xffffffff, 1,
275a2c96a21SAlex Deucher 	0x8fc, 0x0e000000, 0
276a2c96a21SAlex Deucher };
277a2c96a21SAlex Deucher 
278a2c96a21SAlex Deucher static const u32 dvst_golden_registers[] =
279a2c96a21SAlex Deucher {
280a2c96a21SAlex Deucher 	0x690, 0x3fff3fff, 0x20c00033,
281a2c96a21SAlex Deucher 	0x918c, 0x0fff0fff, 0x00010006,
282a2c96a21SAlex Deucher 	0x91a8, 0x0fff0fff, 0x00010006,
283a2c96a21SAlex Deucher 	0x9150, 0xffffdfff, 0x6e944040,
284a2c96a21SAlex Deucher 	0x917c, 0x0fff0fff, 0x00030002,
285a2c96a21SAlex Deucher 	0x9198, 0x0fff0fff, 0x00030002,
286a2c96a21SAlex Deucher 	0x915c, 0x0fff0fff, 0x00010000,
287a2c96a21SAlex Deucher 	0x3f90, 0xffff0001, 0xff000000,
288a2c96a21SAlex Deucher 	0x9178, 0x0fff0fff, 0x00070000,
289a2c96a21SAlex Deucher 	0x9194, 0x0fff0fff, 0x00070000,
290a2c96a21SAlex Deucher 	0x9148, 0xffff0001, 0xff000000,
291a2c96a21SAlex Deucher 	0x9190, 0x0fff0fff, 0x00090008,
292a2c96a21SAlex Deucher 	0x91ac, 0x0fff0fff, 0x00090008,
293a2c96a21SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
294a2c96a21SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
295a2c96a21SAlex Deucher 	0x929c, 0x00000fff, 0x00000001,
296a2c96a21SAlex Deucher 	0x55e4, 0xff607fff, 0xfc000100,
297a2c96a21SAlex Deucher 	0x8a18, 0xff000fff, 0x00000100,
298a2c96a21SAlex Deucher 	0x8b28, 0xff000fff, 0x00000100,
299a2c96a21SAlex Deucher 	0x9144, 0xfffc0fff, 0x00000100,
300a2c96a21SAlex Deucher 	0x6ed8, 0x00010101, 0x00010000,
301a2c96a21SAlex Deucher 	0x9830, 0xffffffff, 0x00000000,
302a2c96a21SAlex Deucher 	0x9834, 0xf00fffff, 0x00000400,
303a2c96a21SAlex Deucher 	0x9838, 0xfffffffe, 0x00000000,
304a2c96a21SAlex Deucher 	0xd0c0, 0xff000fff, 0x00000100,
305a2c96a21SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
306a2c96a21SAlex Deucher 	0xd0b8, 0x73773777, 0x12010001,
307a2c96a21SAlex Deucher 	0x5bb0, 0x000000f0, 0x00000070,
308a2c96a21SAlex Deucher 	0x98f8, 0x73773777, 0x12010001,
309a2c96a21SAlex Deucher 	0x98fc, 0xffffffff, 0x00000010,
310a2c96a21SAlex Deucher 	0x9b7c, 0x00ff0000, 0x00fc0000,
311a2c96a21SAlex Deucher 	0x8030, 0x00001f0f, 0x0000100a,
312a2c96a21SAlex Deucher 	0x2f48, 0x73773777, 0x12010001,
313a2c96a21SAlex Deucher 	0x2408, 0x00030000, 0x000c007f,
314a2c96a21SAlex Deucher 	0x8a14, 0xf000003f, 0x00000007,
315a2c96a21SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
316a2c96a21SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
317a2c96a21SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
318a2c96a21SAlex Deucher 	0x4d8, 0x00000fff, 0x00000100,
319a2c96a21SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
320a2c96a21SAlex Deucher 	0x913c, 0xffff03ff, 0x01000100,
321a2c96a21SAlex Deucher 	0x8c00, 0x000000ff, 0x00000003,
322a2c96a21SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
323a2c96a21SAlex Deucher 	0x8cf0, 0x1fff1fff, 0x08e00410,
324a2c96a21SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
325a2c96a21SAlex Deucher 	0x9508, 0xf700071f, 0x00000002,
326a2c96a21SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
327a2c96a21SAlex Deucher 	0x20ef8, 0x01ff01ff, 0x00000002,
328a2c96a21SAlex Deucher 	0x20e98, 0xfffffbff, 0x00200000,
329a2c96a21SAlex Deucher 	0x2015c, 0xffffffff, 0x00000f40,
330a2c96a21SAlex Deucher 	0x88c4, 0x001f3ae3, 0x00000082,
331a2c96a21SAlex Deucher 	0x8978, 0x3fffffff, 0x04050140,
332a2c96a21SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
333a2c96a21SAlex Deucher 	0x8974, 0xffffffff, 0x00000000
334a2c96a21SAlex Deucher };
335a2c96a21SAlex Deucher 
336a2c96a21SAlex Deucher static const u32 scrapper_golden_registers[] =
337a2c96a21SAlex Deucher {
338a2c96a21SAlex Deucher 	0x690, 0x3fff3fff, 0x20c00033,
339a2c96a21SAlex Deucher 	0x918c, 0x0fff0fff, 0x00010006,
340a2c96a21SAlex Deucher 	0x918c, 0x0fff0fff, 0x00010006,
341a2c96a21SAlex Deucher 	0x91a8, 0x0fff0fff, 0x00010006,
342a2c96a21SAlex Deucher 	0x91a8, 0x0fff0fff, 0x00010006,
343a2c96a21SAlex Deucher 	0x9150, 0xffffdfff, 0x6e944040,
344a2c96a21SAlex Deucher 	0x9150, 0xffffdfff, 0x6e944040,
345a2c96a21SAlex Deucher 	0x917c, 0x0fff0fff, 0x00030002,
346a2c96a21SAlex Deucher 	0x917c, 0x0fff0fff, 0x00030002,
347a2c96a21SAlex Deucher 	0x9198, 0x0fff0fff, 0x00030002,
348a2c96a21SAlex Deucher 	0x9198, 0x0fff0fff, 0x00030002,
349a2c96a21SAlex Deucher 	0x915c, 0x0fff0fff, 0x00010000,
350a2c96a21SAlex Deucher 	0x915c, 0x0fff0fff, 0x00010000,
351a2c96a21SAlex Deucher 	0x3f90, 0xffff0001, 0xff000000,
352a2c96a21SAlex Deucher 	0x3f90, 0xffff0001, 0xff000000,
353a2c96a21SAlex Deucher 	0x9178, 0x0fff0fff, 0x00070000,
354a2c96a21SAlex Deucher 	0x9178, 0x0fff0fff, 0x00070000,
355a2c96a21SAlex Deucher 	0x9194, 0x0fff0fff, 0x00070000,
356a2c96a21SAlex Deucher 	0x9194, 0x0fff0fff, 0x00070000,
357a2c96a21SAlex Deucher 	0x9148, 0xffff0001, 0xff000000,
358a2c96a21SAlex Deucher 	0x9148, 0xffff0001, 0xff000000,
359a2c96a21SAlex Deucher 	0x9190, 0x0fff0fff, 0x00090008,
360a2c96a21SAlex Deucher 	0x9190, 0x0fff0fff, 0x00090008,
361a2c96a21SAlex Deucher 	0x91ac, 0x0fff0fff, 0x00090008,
362a2c96a21SAlex Deucher 	0x91ac, 0x0fff0fff, 0x00090008,
363a2c96a21SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
364a2c96a21SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
365a2c96a21SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
366a2c96a21SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
367a2c96a21SAlex Deucher 	0x929c, 0x00000fff, 0x00000001,
368a2c96a21SAlex Deucher 	0x929c, 0x00000fff, 0x00000001,
369a2c96a21SAlex Deucher 	0x55e4, 0xff607fff, 0xfc000100,
370a2c96a21SAlex Deucher 	0x8a18, 0xff000fff, 0x00000100,
371a2c96a21SAlex Deucher 	0x8a18, 0xff000fff, 0x00000100,
372a2c96a21SAlex Deucher 	0x8b28, 0xff000fff, 0x00000100,
373a2c96a21SAlex Deucher 	0x8b28, 0xff000fff, 0x00000100,
374a2c96a21SAlex Deucher 	0x9144, 0xfffc0fff, 0x00000100,
375a2c96a21SAlex Deucher 	0x9144, 0xfffc0fff, 0x00000100,
376a2c96a21SAlex Deucher 	0x6ed8, 0x00010101, 0x00010000,
377a2c96a21SAlex Deucher 	0x9830, 0xffffffff, 0x00000000,
378a2c96a21SAlex Deucher 	0x9830, 0xffffffff, 0x00000000,
379a2c96a21SAlex Deucher 	0x9834, 0xf00fffff, 0x00000400,
380a2c96a21SAlex Deucher 	0x9834, 0xf00fffff, 0x00000400,
381a2c96a21SAlex Deucher 	0x9838, 0xfffffffe, 0x00000000,
382a2c96a21SAlex Deucher 	0x9838, 0xfffffffe, 0x00000000,
383a2c96a21SAlex Deucher 	0xd0c0, 0xff000fff, 0x00000100,
384a2c96a21SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
385a2c96a21SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
386a2c96a21SAlex Deucher 	0xd0b8, 0x73773777, 0x12010001,
387a2c96a21SAlex Deucher 	0xd0b8, 0x73773777, 0x12010001,
388a2c96a21SAlex Deucher 	0x5bb0, 0x000000f0, 0x00000070,
389a2c96a21SAlex Deucher 	0x98f8, 0x73773777, 0x12010001,
390a2c96a21SAlex Deucher 	0x98f8, 0x73773777, 0x12010001,
391a2c96a21SAlex Deucher 	0x98fc, 0xffffffff, 0x00000010,
392a2c96a21SAlex Deucher 	0x98fc, 0xffffffff, 0x00000010,
393a2c96a21SAlex Deucher 	0x9b7c, 0x00ff0000, 0x00fc0000,
394a2c96a21SAlex Deucher 	0x9b7c, 0x00ff0000, 0x00fc0000,
395a2c96a21SAlex Deucher 	0x8030, 0x00001f0f, 0x0000100a,
396a2c96a21SAlex Deucher 	0x8030, 0x00001f0f, 0x0000100a,
397a2c96a21SAlex Deucher 	0x2f48, 0x73773777, 0x12010001,
398a2c96a21SAlex Deucher 	0x2f48, 0x73773777, 0x12010001,
399a2c96a21SAlex Deucher 	0x2408, 0x00030000, 0x000c007f,
400a2c96a21SAlex Deucher 	0x8a14, 0xf000003f, 0x00000007,
401a2c96a21SAlex Deucher 	0x8a14, 0xf000003f, 0x00000007,
402a2c96a21SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
403a2c96a21SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
404a2c96a21SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
405a2c96a21SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
406a2c96a21SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
407a2c96a21SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
408a2c96a21SAlex Deucher 	0x4d8, 0x00000fff, 0x00000100,
409a2c96a21SAlex Deucher 	0x4d8, 0x00000fff, 0x00000100,
410a2c96a21SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
411a2c96a21SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
412a2c96a21SAlex Deucher 	0x913c, 0xffff03ff, 0x01000100,
413a2c96a21SAlex Deucher 	0x913c, 0xffff03ff, 0x01000100,
414a2c96a21SAlex Deucher 	0x90e8, 0x001fffff, 0x010400c0,
415a2c96a21SAlex Deucher 	0x8c00, 0x000000ff, 0x00000003,
416a2c96a21SAlex Deucher 	0x8c00, 0x000000ff, 0x00000003,
417a2c96a21SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
418a2c96a21SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
419a2c96a21SAlex Deucher 	0x8c30, 0x0000000f, 0x00040005,
420a2c96a21SAlex Deucher 	0x8cf0, 0x1fff1fff, 0x08e00410,
421a2c96a21SAlex Deucher 	0x8cf0, 0x1fff1fff, 0x08e00410,
422a2c96a21SAlex Deucher 	0x900c, 0x00ffffff, 0x0017071f,
423a2c96a21SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
424a2c96a21SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
425a2c96a21SAlex Deucher 	0x9508, 0xf700071f, 0x00000002,
426a2c96a21SAlex Deucher 	0x9508, 0xf700071f, 0x00000002,
427a2c96a21SAlex Deucher 	0x9688, 0x00300000, 0x0017000f,
428a2c96a21SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
429a2c96a21SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
430a2c96a21SAlex Deucher 	0x20ef8, 0x01ff01ff, 0x00000002,
431a2c96a21SAlex Deucher 	0x20e98, 0xfffffbff, 0x00200000,
432a2c96a21SAlex Deucher 	0x2015c, 0xffffffff, 0x00000f40,
433a2c96a21SAlex Deucher 	0x88c4, 0x001f3ae3, 0x00000082,
434a2c96a21SAlex Deucher 	0x88c4, 0x001f3ae3, 0x00000082,
435a2c96a21SAlex Deucher 	0x8978, 0x3fffffff, 0x04050140,
436a2c96a21SAlex Deucher 	0x8978, 0x3fffffff, 0x04050140,
437a2c96a21SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
438a2c96a21SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
439a2c96a21SAlex Deucher 	0x8974, 0xffffffff, 0x00000000,
440a2c96a21SAlex Deucher 	0x8974, 0xffffffff, 0x00000000
441a2c96a21SAlex Deucher };
442a2c96a21SAlex Deucher 
ni_init_golden_registers(struct radeon_device * rdev)443a2c96a21SAlex Deucher static void ni_init_golden_registers(struct radeon_device *rdev)
444a2c96a21SAlex Deucher {
445a2c96a21SAlex Deucher 	switch (rdev->family) {
446a2c96a21SAlex Deucher 	case CHIP_CAYMAN:
447a2c96a21SAlex Deucher 		radeon_program_register_sequence(rdev,
448a2c96a21SAlex Deucher 						 cayman_golden_registers,
449a2c96a21SAlex Deucher 						 (const u32)ARRAY_SIZE(cayman_golden_registers));
450a2c96a21SAlex Deucher 		radeon_program_register_sequence(rdev,
451a2c96a21SAlex Deucher 						 cayman_golden_registers2,
452a2c96a21SAlex Deucher 						 (const u32)ARRAY_SIZE(cayman_golden_registers2));
453a2c96a21SAlex Deucher 		break;
454a2c96a21SAlex Deucher 	case CHIP_ARUBA:
455a2c96a21SAlex Deucher 		if ((rdev->pdev->device == 0x9900) ||
456a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9901) ||
457a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9903) ||
458a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9904) ||
459a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9905) ||
460a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9906) ||
461a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9907) ||
462a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9908) ||
463a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9909) ||
464a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x990A) ||
465a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x990B) ||
466a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x990C) ||
467a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x990D) ||
468a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x990E) ||
469a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x990F) ||
470a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9910) ||
471a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9913) ||
472a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9917) ||
473a2c96a21SAlex Deucher 		    (rdev->pdev->device == 0x9918)) {
474a2c96a21SAlex Deucher 			radeon_program_register_sequence(rdev,
475a2c96a21SAlex Deucher 							 dvst_golden_registers,
476a2c96a21SAlex Deucher 							 (const u32)ARRAY_SIZE(dvst_golden_registers));
477a2c96a21SAlex Deucher 			radeon_program_register_sequence(rdev,
478a2c96a21SAlex Deucher 							 dvst_golden_registers2,
479a2c96a21SAlex Deucher 							 (const u32)ARRAY_SIZE(dvst_golden_registers2));
480a2c96a21SAlex Deucher 		} else {
481a2c96a21SAlex Deucher 			radeon_program_register_sequence(rdev,
482a2c96a21SAlex Deucher 							 scrapper_golden_registers,
483a2c96a21SAlex Deucher 							 (const u32)ARRAY_SIZE(scrapper_golden_registers));
484a2c96a21SAlex Deucher 			radeon_program_register_sequence(rdev,
485a2c96a21SAlex Deucher 							 dvst_golden_registers2,
486a2c96a21SAlex Deucher 							 (const u32)ARRAY_SIZE(dvst_golden_registers2));
487a2c96a21SAlex Deucher 		}
488a2c96a21SAlex Deucher 		break;
489a2c96a21SAlex Deucher 	default:
490a2c96a21SAlex Deucher 		break;
491a2c96a21SAlex Deucher 	}
492a2c96a21SAlex Deucher }
493a2c96a21SAlex Deucher 
4940af62b01SAlex Deucher #define BTC_IO_MC_REGS_SIZE 29
4950af62b01SAlex Deucher 
4960af62b01SAlex Deucher static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
4970af62b01SAlex Deucher 	{0x00000077, 0xff010100},
4980af62b01SAlex Deucher 	{0x00000078, 0x00000000},
4990af62b01SAlex Deucher 	{0x00000079, 0x00001434},
5000af62b01SAlex Deucher 	{0x0000007a, 0xcc08ec08},
5010af62b01SAlex Deucher 	{0x0000007b, 0x00040000},
5020af62b01SAlex Deucher 	{0x0000007c, 0x000080c0},
5030af62b01SAlex Deucher 	{0x0000007d, 0x09000000},
5040af62b01SAlex Deucher 	{0x0000007e, 0x00210404},
5050af62b01SAlex Deucher 	{0x00000081, 0x08a8e800},
5060af62b01SAlex Deucher 	{0x00000082, 0x00030444},
5070af62b01SAlex Deucher 	{0x00000083, 0x00000000},
5080af62b01SAlex Deucher 	{0x00000085, 0x00000001},
5090af62b01SAlex Deucher 	{0x00000086, 0x00000002},
5100af62b01SAlex Deucher 	{0x00000087, 0x48490000},
5110af62b01SAlex Deucher 	{0x00000088, 0x20244647},
5120af62b01SAlex Deucher 	{0x00000089, 0x00000005},
5130af62b01SAlex Deucher 	{0x0000008b, 0x66030000},
5140af62b01SAlex Deucher 	{0x0000008c, 0x00006603},
5150af62b01SAlex Deucher 	{0x0000008d, 0x00000100},
5160af62b01SAlex Deucher 	{0x0000008f, 0x00001c0a},
5170af62b01SAlex Deucher 	{0x00000090, 0xff000001},
5180af62b01SAlex Deucher 	{0x00000094, 0x00101101},
5190af62b01SAlex Deucher 	{0x00000095, 0x00000fff},
5200af62b01SAlex Deucher 	{0x00000096, 0x00116fff},
5210af62b01SAlex Deucher 	{0x00000097, 0x60010000},
5220af62b01SAlex Deucher 	{0x00000098, 0x10010000},
5230af62b01SAlex Deucher 	{0x00000099, 0x00006000},
5240af62b01SAlex Deucher 	{0x0000009a, 0x00001000},
5250af62b01SAlex Deucher 	{0x0000009f, 0x00946a00}
5260af62b01SAlex Deucher };
5270af62b01SAlex Deucher 
5280af62b01SAlex Deucher static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
5290af62b01SAlex Deucher 	{0x00000077, 0xff010100},
5300af62b01SAlex Deucher 	{0x00000078, 0x00000000},
5310af62b01SAlex Deucher 	{0x00000079, 0x00001434},
5320af62b01SAlex Deucher 	{0x0000007a, 0xcc08ec08},
5330af62b01SAlex Deucher 	{0x0000007b, 0x00040000},
5340af62b01SAlex Deucher 	{0x0000007c, 0x000080c0},
5350af62b01SAlex Deucher 	{0x0000007d, 0x09000000},
5360af62b01SAlex Deucher 	{0x0000007e, 0x00210404},
5370af62b01SAlex Deucher 	{0x00000081, 0x08a8e800},
5380af62b01SAlex Deucher 	{0x00000082, 0x00030444},
5390af62b01SAlex Deucher 	{0x00000083, 0x00000000},
5400af62b01SAlex Deucher 	{0x00000085, 0x00000001},
5410af62b01SAlex Deucher 	{0x00000086, 0x00000002},
5420af62b01SAlex Deucher 	{0x00000087, 0x48490000},
5430af62b01SAlex Deucher 	{0x00000088, 0x20244647},
5440af62b01SAlex Deucher 	{0x00000089, 0x00000005},
5450af62b01SAlex Deucher 	{0x0000008b, 0x66030000},
5460af62b01SAlex Deucher 	{0x0000008c, 0x00006603},
5470af62b01SAlex Deucher 	{0x0000008d, 0x00000100},
5480af62b01SAlex Deucher 	{0x0000008f, 0x00001c0a},
5490af62b01SAlex Deucher 	{0x00000090, 0xff000001},
5500af62b01SAlex Deucher 	{0x00000094, 0x00101101},
5510af62b01SAlex Deucher 	{0x00000095, 0x00000fff},
5520af62b01SAlex Deucher 	{0x00000096, 0x00116fff},
5530af62b01SAlex Deucher 	{0x00000097, 0x60010000},
5540af62b01SAlex Deucher 	{0x00000098, 0x10010000},
5550af62b01SAlex Deucher 	{0x00000099, 0x00006000},
5560af62b01SAlex Deucher 	{0x0000009a, 0x00001000},
5570af62b01SAlex Deucher 	{0x0000009f, 0x00936a00}
5580af62b01SAlex Deucher };
5590af62b01SAlex Deucher 
5600af62b01SAlex Deucher static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
5610af62b01SAlex Deucher 	{0x00000077, 0xff010100},
5620af62b01SAlex Deucher 	{0x00000078, 0x00000000},
5630af62b01SAlex Deucher 	{0x00000079, 0x00001434},
5640af62b01SAlex Deucher 	{0x0000007a, 0xcc08ec08},
5650af62b01SAlex Deucher 	{0x0000007b, 0x00040000},
5660af62b01SAlex Deucher 	{0x0000007c, 0x000080c0},
5670af62b01SAlex Deucher 	{0x0000007d, 0x09000000},
5680af62b01SAlex Deucher 	{0x0000007e, 0x00210404},
5690af62b01SAlex Deucher 	{0x00000081, 0x08a8e800},
5700af62b01SAlex Deucher 	{0x00000082, 0x00030444},
5710af62b01SAlex Deucher 	{0x00000083, 0x00000000},
5720af62b01SAlex Deucher 	{0x00000085, 0x00000001},
5730af62b01SAlex Deucher 	{0x00000086, 0x00000002},
5740af62b01SAlex Deucher 	{0x00000087, 0x48490000},
5750af62b01SAlex Deucher 	{0x00000088, 0x20244647},
5760af62b01SAlex Deucher 	{0x00000089, 0x00000005},
5770af62b01SAlex Deucher 	{0x0000008b, 0x66030000},
5780af62b01SAlex Deucher 	{0x0000008c, 0x00006603},
5790af62b01SAlex Deucher 	{0x0000008d, 0x00000100},
5800af62b01SAlex Deucher 	{0x0000008f, 0x00001c0a},
5810af62b01SAlex Deucher 	{0x00000090, 0xff000001},
5820af62b01SAlex Deucher 	{0x00000094, 0x00101101},
5830af62b01SAlex Deucher 	{0x00000095, 0x00000fff},
5840af62b01SAlex Deucher 	{0x00000096, 0x00116fff},
5850af62b01SAlex Deucher 	{0x00000097, 0x60010000},
5860af62b01SAlex Deucher 	{0x00000098, 0x10010000},
5870af62b01SAlex Deucher 	{0x00000099, 0x00006000},
5880af62b01SAlex Deucher 	{0x0000009a, 0x00001000},
5890af62b01SAlex Deucher 	{0x0000009f, 0x00916a00}
5900af62b01SAlex Deucher };
5910af62b01SAlex Deucher 
5929b8253ceSAlex Deucher static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
5939b8253ceSAlex Deucher 	{0x00000077, 0xff010100},
5949b8253ceSAlex Deucher 	{0x00000078, 0x00000000},
5959b8253ceSAlex Deucher 	{0x00000079, 0x00001434},
5969b8253ceSAlex Deucher 	{0x0000007a, 0xcc08ec08},
5979b8253ceSAlex Deucher 	{0x0000007b, 0x00040000},
5989b8253ceSAlex Deucher 	{0x0000007c, 0x000080c0},
5999b8253ceSAlex Deucher 	{0x0000007d, 0x09000000},
6009b8253ceSAlex Deucher 	{0x0000007e, 0x00210404},
6019b8253ceSAlex Deucher 	{0x00000081, 0x08a8e800},
6029b8253ceSAlex Deucher 	{0x00000082, 0x00030444},
6039b8253ceSAlex Deucher 	{0x00000083, 0x00000000},
6049b8253ceSAlex Deucher 	{0x00000085, 0x00000001},
6059b8253ceSAlex Deucher 	{0x00000086, 0x00000002},
6069b8253ceSAlex Deucher 	{0x00000087, 0x48490000},
6079b8253ceSAlex Deucher 	{0x00000088, 0x20244647},
6089b8253ceSAlex Deucher 	{0x00000089, 0x00000005},
6099b8253ceSAlex Deucher 	{0x0000008b, 0x66030000},
6109b8253ceSAlex Deucher 	{0x0000008c, 0x00006603},
6119b8253ceSAlex Deucher 	{0x0000008d, 0x00000100},
6129b8253ceSAlex Deucher 	{0x0000008f, 0x00001c0a},
6139b8253ceSAlex Deucher 	{0x00000090, 0xff000001},
6149b8253ceSAlex Deucher 	{0x00000094, 0x00101101},
6159b8253ceSAlex Deucher 	{0x00000095, 0x00000fff},
6169b8253ceSAlex Deucher 	{0x00000096, 0x00116fff},
6179b8253ceSAlex Deucher 	{0x00000097, 0x60010000},
6189b8253ceSAlex Deucher 	{0x00000098, 0x10010000},
6199b8253ceSAlex Deucher 	{0x00000099, 0x00006000},
6209b8253ceSAlex Deucher 	{0x0000009a, 0x00001000},
6219b8253ceSAlex Deucher 	{0x0000009f, 0x00976b00}
6229b8253ceSAlex Deucher };
6239b8253ceSAlex Deucher 
ni_mc_load_microcode(struct radeon_device * rdev)624755d819eSAlex Deucher int ni_mc_load_microcode(struct radeon_device *rdev)
6250af62b01SAlex Deucher {
6260af62b01SAlex Deucher 	const __be32 *fw_data;
6270af62b01SAlex Deucher 	u32 mem_type, running, blackout = 0;
6280af62b01SAlex Deucher 	u32 *io_mc_regs;
6299b8253ceSAlex Deucher 	int i, ucode_size, regs_size;
6300af62b01SAlex Deucher 
6310af62b01SAlex Deucher 	if (!rdev->mc_fw)
6320af62b01SAlex Deucher 		return -EINVAL;
6330af62b01SAlex Deucher 
6340af62b01SAlex Deucher 	switch (rdev->family) {
6350af62b01SAlex Deucher 	case CHIP_BARTS:
6360af62b01SAlex Deucher 		io_mc_regs = (u32 *)&barts_io_mc_regs;
6379b8253ceSAlex Deucher 		ucode_size = BTC_MC_UCODE_SIZE;
6389b8253ceSAlex Deucher 		regs_size = BTC_IO_MC_REGS_SIZE;
6390af62b01SAlex Deucher 		break;
6400af62b01SAlex Deucher 	case CHIP_TURKS:
6410af62b01SAlex Deucher 		io_mc_regs = (u32 *)&turks_io_mc_regs;
6429b8253ceSAlex Deucher 		ucode_size = BTC_MC_UCODE_SIZE;
6439b8253ceSAlex Deucher 		regs_size = BTC_IO_MC_REGS_SIZE;
6440af62b01SAlex Deucher 		break;
6450af62b01SAlex Deucher 	case CHIP_CAICOS:
6460af62b01SAlex Deucher 	default:
6470af62b01SAlex Deucher 		io_mc_regs = (u32 *)&caicos_io_mc_regs;
6489b8253ceSAlex Deucher 		ucode_size = BTC_MC_UCODE_SIZE;
6499b8253ceSAlex Deucher 		regs_size = BTC_IO_MC_REGS_SIZE;
6509b8253ceSAlex Deucher 		break;
6519b8253ceSAlex Deucher 	case CHIP_CAYMAN:
6529b8253ceSAlex Deucher 		io_mc_regs = (u32 *)&cayman_io_mc_regs;
6539b8253ceSAlex Deucher 		ucode_size = CAYMAN_MC_UCODE_SIZE;
6549b8253ceSAlex Deucher 		regs_size = BTC_IO_MC_REGS_SIZE;
6550af62b01SAlex Deucher 		break;
6560af62b01SAlex Deucher 	}
6570af62b01SAlex Deucher 
6580af62b01SAlex Deucher 	mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
6590af62b01SAlex Deucher 	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
6600af62b01SAlex Deucher 
6610af62b01SAlex Deucher 	if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
6620af62b01SAlex Deucher 		if (running) {
6630af62b01SAlex Deucher 			blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
6640af62b01SAlex Deucher 			WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
6650af62b01SAlex Deucher 		}
6660af62b01SAlex Deucher 
6670af62b01SAlex Deucher 		/* reset the engine and set to writable */
6680af62b01SAlex Deucher 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
6690af62b01SAlex Deucher 		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
6700af62b01SAlex Deucher 
6710af62b01SAlex Deucher 		/* load mc io regs */
6729b8253ceSAlex Deucher 		for (i = 0; i < regs_size; i++) {
6730af62b01SAlex Deucher 			WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
6740af62b01SAlex Deucher 			WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
6750af62b01SAlex Deucher 		}
6760af62b01SAlex Deucher 		/* load the MC ucode */
6770af62b01SAlex Deucher 		fw_data = (const __be32 *)rdev->mc_fw->data;
6789b8253ceSAlex Deucher 		for (i = 0; i < ucode_size; i++)
6790af62b01SAlex Deucher 			WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
6800af62b01SAlex Deucher 
6810af62b01SAlex Deucher 		/* put the engine back into the active state */
6820af62b01SAlex Deucher 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
6830af62b01SAlex Deucher 		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
6840af62b01SAlex Deucher 		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
6850af62b01SAlex Deucher 
6860af62b01SAlex Deucher 		/* wait for training to complete */
6870e2c978eSAlex Deucher 		for (i = 0; i < rdev->usec_timeout; i++) {
6880e2c978eSAlex Deucher 			if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
6890e2c978eSAlex Deucher 				break;
6900e2c978eSAlex Deucher 			udelay(1);
6910e2c978eSAlex Deucher 		}
6920af62b01SAlex Deucher 
6930af62b01SAlex Deucher 		if (running)
6940af62b01SAlex Deucher 			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
6950af62b01SAlex Deucher 	}
6960af62b01SAlex Deucher 
6970af62b01SAlex Deucher 	return 0;
6980af62b01SAlex Deucher }
6990af62b01SAlex Deucher 
ni_init_microcode(struct radeon_device * rdev)7000af62b01SAlex Deucher int ni_init_microcode(struct radeon_device *rdev)
7010af62b01SAlex Deucher {
7020af62b01SAlex Deucher 	const char *chip_name;
7030af62b01SAlex Deucher 	const char *rlc_chip_name;
7040af62b01SAlex Deucher 	size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
7056596afd4SAlex Deucher 	size_t smc_req_size = 0;
7060af62b01SAlex Deucher 	char fw_name[30];
7070af62b01SAlex Deucher 	int err;
7080af62b01SAlex Deucher 
7090af62b01SAlex Deucher 	DRM_DEBUG("\n");
7100af62b01SAlex Deucher 
7110af62b01SAlex Deucher 	switch (rdev->family) {
7120af62b01SAlex Deucher 	case CHIP_BARTS:
7130af62b01SAlex Deucher 		chip_name = "BARTS";
7140af62b01SAlex Deucher 		rlc_chip_name = "BTC";
7150af62b01SAlex Deucher 		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
7160af62b01SAlex Deucher 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
7170af62b01SAlex Deucher 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
7180af62b01SAlex Deucher 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
7196596afd4SAlex Deucher 		smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4);
7209b8253ceSAlex Deucher 		break;
7219b8253ceSAlex Deucher 	case CHIP_TURKS:
7229b8253ceSAlex Deucher 		chip_name = "TURKS";
7239b8253ceSAlex Deucher 		rlc_chip_name = "BTC";
7249b8253ceSAlex Deucher 		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
7259b8253ceSAlex Deucher 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
7269b8253ceSAlex Deucher 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
7279b8253ceSAlex Deucher 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
7286596afd4SAlex Deucher 		smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4);
7299b8253ceSAlex Deucher 		break;
7309b8253ceSAlex Deucher 	case CHIP_CAICOS:
7319b8253ceSAlex Deucher 		chip_name = "CAICOS";
7329b8253ceSAlex Deucher 		rlc_chip_name = "BTC";
7339b8253ceSAlex Deucher 		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
7349b8253ceSAlex Deucher 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
7359b8253ceSAlex Deucher 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
7369b8253ceSAlex Deucher 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
7376596afd4SAlex Deucher 		smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4);
7389b8253ceSAlex Deucher 		break;
7399b8253ceSAlex Deucher 	case CHIP_CAYMAN:
7409b8253ceSAlex Deucher 		chip_name = "CAYMAN";
7419b8253ceSAlex Deucher 		rlc_chip_name = "CAYMAN";
7429b8253ceSAlex Deucher 		pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
7439b8253ceSAlex Deucher 		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
7449b8253ceSAlex Deucher 		rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
7459b8253ceSAlex Deucher 		mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
74669e0b57aSAlex Deucher 		smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
7479b8253ceSAlex Deucher 		break;
748c420c745SAlex Deucher 	case CHIP_ARUBA:
749c420c745SAlex Deucher 		chip_name = "ARUBA";
750c420c745SAlex Deucher 		rlc_chip_name = "ARUBA";
751c420c745SAlex Deucher 		/* pfp/me same size as CAYMAN */
752c420c745SAlex Deucher 		pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
753c420c745SAlex Deucher 		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
754c420c745SAlex Deucher 		rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
755c420c745SAlex Deucher 		mc_req_size = 0;
756c420c745SAlex Deucher 		break;
7579b8253ceSAlex Deucher 	default: BUG();
7589b8253ceSAlex Deucher 	}
7590af62b01SAlex Deucher 
7600af62b01SAlex Deucher 	DRM_INFO("Loading %s Microcode\n", chip_name);
7610af62b01SAlex Deucher 
7620af62b01SAlex Deucher 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
7630a168933SJerome Glisse 	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
7640af62b01SAlex Deucher 	if (err)
7650af62b01SAlex Deucher 		goto out;
7660af62b01SAlex Deucher 	if (rdev->pfp_fw->size != pfp_req_size) {
7677ca85295SJoe Perches 		pr_err("ni_cp: Bogus length %zu in firmware \"%s\"\n",
7680af62b01SAlex Deucher 		       rdev->pfp_fw->size, fw_name);
7690af62b01SAlex Deucher 		err = -EINVAL;
7700af62b01SAlex Deucher 		goto out;
7710af62b01SAlex Deucher 	}
7720af62b01SAlex Deucher 
7730af62b01SAlex Deucher 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
7740a168933SJerome Glisse 	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
7750af62b01SAlex Deucher 	if (err)
7760af62b01SAlex Deucher 		goto out;
7770af62b01SAlex Deucher 	if (rdev->me_fw->size != me_req_size) {
7787ca85295SJoe Perches 		pr_err("ni_cp: Bogus length %zu in firmware \"%s\"\n",
7790af62b01SAlex Deucher 		       rdev->me_fw->size, fw_name);
7800af62b01SAlex Deucher 		err = -EINVAL;
7810af62b01SAlex Deucher 	}
7820af62b01SAlex Deucher 
7830af62b01SAlex Deucher 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
7840a168933SJerome Glisse 	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
7850af62b01SAlex Deucher 	if (err)
7860af62b01SAlex Deucher 		goto out;
7870af62b01SAlex Deucher 	if (rdev->rlc_fw->size != rlc_req_size) {
7887ca85295SJoe Perches 		pr_err("ni_rlc: Bogus length %zu in firmware \"%s\"\n",
7890af62b01SAlex Deucher 		       rdev->rlc_fw->size, fw_name);
7900af62b01SAlex Deucher 		err = -EINVAL;
7910af62b01SAlex Deucher 	}
7920af62b01SAlex Deucher 
793c420c745SAlex Deucher 	/* no MC ucode on TN */
794c420c745SAlex Deucher 	if (!(rdev->flags & RADEON_IS_IGP)) {
7950af62b01SAlex Deucher 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
7960a168933SJerome Glisse 		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
7970af62b01SAlex Deucher 		if (err)
7980af62b01SAlex Deucher 			goto out;
7990af62b01SAlex Deucher 		if (rdev->mc_fw->size != mc_req_size) {
8007ca85295SJoe Perches 			pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n",
8010af62b01SAlex Deucher 			       rdev->mc_fw->size, fw_name);
8020af62b01SAlex Deucher 			err = -EINVAL;
8030af62b01SAlex Deucher 		}
804c420c745SAlex Deucher 	}
8056596afd4SAlex Deucher 
80669e0b57aSAlex Deucher 	if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
8076596afd4SAlex Deucher 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
8080a168933SJerome Glisse 		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
8098a53fa23SAlex Deucher 		if (err) {
8107ca85295SJoe Perches 			pr_err("smc: error loading firmware \"%s\"\n", fw_name);
8118a53fa23SAlex Deucher 			release_firmware(rdev->smc_fw);
8128a53fa23SAlex Deucher 			rdev->smc_fw = NULL;
813d8367112SAlex Deucher 			err = 0;
8148a53fa23SAlex Deucher 		} else if (rdev->smc_fw->size != smc_req_size) {
8157ca85295SJoe Perches 			pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n",
8166fc5fb8eSNikita Zhandarovich 			       rdev->smc_fw->size, fw_name);
8176596afd4SAlex Deucher 			err = -EINVAL;
8186596afd4SAlex Deucher 		}
8196596afd4SAlex Deucher 	}
8206596afd4SAlex Deucher 
8210af62b01SAlex Deucher out:
8220af62b01SAlex Deucher 	if (err) {
8230af62b01SAlex Deucher 		if (err != -EINVAL)
8247ca85295SJoe Perches 			pr_err("ni_cp: Failed to load firmware \"%s\"\n",
8250af62b01SAlex Deucher 			       fw_name);
8260af62b01SAlex Deucher 		release_firmware(rdev->pfp_fw);
8270af62b01SAlex Deucher 		rdev->pfp_fw = NULL;
8280af62b01SAlex Deucher 		release_firmware(rdev->me_fw);
8290af62b01SAlex Deucher 		rdev->me_fw = NULL;
8300af62b01SAlex Deucher 		release_firmware(rdev->rlc_fw);
8310af62b01SAlex Deucher 		rdev->rlc_fw = NULL;
8320af62b01SAlex Deucher 		release_firmware(rdev->mc_fw);
8330af62b01SAlex Deucher 		rdev->mc_fw = NULL;
8340af62b01SAlex Deucher 	}
8350af62b01SAlex Deucher 	return err;
8360af62b01SAlex Deucher }
8370af62b01SAlex Deucher 
838e66582f9SAlex Deucher /**
839e66582f9SAlex Deucher  * cayman_get_allowed_info_register - fetch the register for the info ioctl
840e66582f9SAlex Deucher  *
841e66582f9SAlex Deucher  * @rdev: radeon_device pointer
842e66582f9SAlex Deucher  * @reg: register offset in bytes
843e66582f9SAlex Deucher  * @val: register value
844e66582f9SAlex Deucher  *
845e66582f9SAlex Deucher  * Returns 0 for success or -EINVAL for an invalid register
846e66582f9SAlex Deucher  *
847e66582f9SAlex Deucher  */
cayman_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)848e66582f9SAlex Deucher int cayman_get_allowed_info_register(struct radeon_device *rdev,
849e66582f9SAlex Deucher 				     u32 reg, u32 *val)
850e66582f9SAlex Deucher {
851e66582f9SAlex Deucher 	switch (reg) {
852e66582f9SAlex Deucher 	case GRBM_STATUS:
853e66582f9SAlex Deucher 	case GRBM_STATUS_SE0:
854e66582f9SAlex Deucher 	case GRBM_STATUS_SE1:
855e66582f9SAlex Deucher 	case SRBM_STATUS:
856e66582f9SAlex Deucher 	case SRBM_STATUS2:
857e66582f9SAlex Deucher 	case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
858e66582f9SAlex Deucher 	case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
859e66582f9SAlex Deucher 	case UVD_STATUS:
860e66582f9SAlex Deucher 		*val = RREG32(reg);
861e66582f9SAlex Deucher 		return 0;
862e66582f9SAlex Deucher 	default:
863e66582f9SAlex Deucher 		return -EINVAL;
864e66582f9SAlex Deucher 	}
865e66582f9SAlex Deucher }
866e66582f9SAlex Deucher 
tn_get_temp(struct radeon_device * rdev)86729a15221SAlex Deucher int tn_get_temp(struct radeon_device *rdev)
86829a15221SAlex Deucher {
86929a15221SAlex Deucher 	u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
87029a15221SAlex Deucher 	int actual_temp = (temp / 8) - 49;
87129a15221SAlex Deucher 
87229a15221SAlex Deucher 	return actual_temp * 1000;
87329a15221SAlex Deucher }
87429a15221SAlex Deucher 
875fecf1d07SAlex Deucher /*
876fecf1d07SAlex Deucher  * Core functions
877fecf1d07SAlex Deucher  */
cayman_gpu_init(struct radeon_device * rdev)878fecf1d07SAlex Deucher static void cayman_gpu_init(struct radeon_device *rdev)
879fecf1d07SAlex Deucher {
880fecf1d07SAlex Deucher 	u32 gb_addr_config = 0;
881880d8dfcSLee Jones 	u32 mc_arb_ramcfg;
882fecf1d07SAlex Deucher 	u32 cgts_tcc_disable;
883fecf1d07SAlex Deucher 	u32 sx_debug_1;
884fecf1d07SAlex Deucher 	u32 smx_dc_ctl0;
885fecf1d07SAlex Deucher 	u32 cgts_sm_ctrl_reg;
886fecf1d07SAlex Deucher 	u32 hdp_host_path_cntl;
887fecf1d07SAlex Deucher 	u32 tmp;
888416a2bd2SAlex Deucher 	u32 disabled_rb_mask;
889fecf1d07SAlex Deucher 	int i, j;
890fecf1d07SAlex Deucher 
891fecf1d07SAlex Deucher 	switch (rdev->family) {
892fecf1d07SAlex Deucher 	case CHIP_CAYMAN:
893fecf1d07SAlex Deucher 		rdev->config.cayman.max_shader_engines = 2;
894fecf1d07SAlex Deucher 		rdev->config.cayman.max_pipes_per_simd = 4;
895fecf1d07SAlex Deucher 		rdev->config.cayman.max_tile_pipes = 8;
896fecf1d07SAlex Deucher 		rdev->config.cayman.max_simds_per_se = 12;
897fecf1d07SAlex Deucher 		rdev->config.cayman.max_backends_per_se = 4;
898fecf1d07SAlex Deucher 		rdev->config.cayman.max_texture_channel_caches = 8;
899fecf1d07SAlex Deucher 		rdev->config.cayman.max_gprs = 256;
900fecf1d07SAlex Deucher 		rdev->config.cayman.max_threads = 256;
901fecf1d07SAlex Deucher 		rdev->config.cayman.max_gs_threads = 32;
902fecf1d07SAlex Deucher 		rdev->config.cayman.max_stack_entries = 512;
903fecf1d07SAlex Deucher 		rdev->config.cayman.sx_num_of_sets = 8;
904fecf1d07SAlex Deucher 		rdev->config.cayman.sx_max_export_size = 256;
905fecf1d07SAlex Deucher 		rdev->config.cayman.sx_max_export_pos_size = 64;
906fecf1d07SAlex Deucher 		rdev->config.cayman.sx_max_export_smx_size = 192;
907fecf1d07SAlex Deucher 		rdev->config.cayman.max_hw_contexts = 8;
908fecf1d07SAlex Deucher 		rdev->config.cayman.sq_num_cf_insts = 2;
909fecf1d07SAlex Deucher 
910fecf1d07SAlex Deucher 		rdev->config.cayman.sc_prim_fifo_size = 0x100;
911fecf1d07SAlex Deucher 		rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
912fecf1d07SAlex Deucher 		rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
913416a2bd2SAlex Deucher 		gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
914fecf1d07SAlex Deucher 		break;
9157b76e479SAlex Deucher 	case CHIP_ARUBA:
9167b76e479SAlex Deucher 	default:
9177b76e479SAlex Deucher 		rdev->config.cayman.max_shader_engines = 1;
9187b76e479SAlex Deucher 		rdev->config.cayman.max_pipes_per_simd = 4;
9197b76e479SAlex Deucher 		rdev->config.cayman.max_tile_pipes = 2;
9207b76e479SAlex Deucher 		if ((rdev->pdev->device == 0x9900) ||
921d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9901) ||
922d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9905) ||
923d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9906) ||
924d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9907) ||
925d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9908) ||
926d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9909) ||
927e4d17063SAlex Deucher 		    (rdev->pdev->device == 0x990B) ||
928e4d17063SAlex Deucher 		    (rdev->pdev->device == 0x990C) ||
929e4d17063SAlex Deucher 		    (rdev->pdev->device == 0x990F) ||
930d430f7dbSAlex Deucher 		    (rdev->pdev->device == 0x9910) ||
931e4d17063SAlex Deucher 		    (rdev->pdev->device == 0x9917) ||
93262d1f92eSAlex Deucher 		    (rdev->pdev->device == 0x9999) ||
93362d1f92eSAlex Deucher 		    (rdev->pdev->device == 0x999C)) {
9347b76e479SAlex Deucher 			rdev->config.cayman.max_simds_per_se = 6;
9357b76e479SAlex Deucher 			rdev->config.cayman.max_backends_per_se = 2;
936e2f6c88fSAlex Deucher 			rdev->config.cayman.max_hw_contexts = 8;
937e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_size = 256;
938e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_pos_size = 64;
939e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_smx_size = 192;
9407b76e479SAlex Deucher 		} else if ((rdev->pdev->device == 0x9903) ||
941d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x9904) ||
942d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x990A) ||
943e4d17063SAlex Deucher 			   (rdev->pdev->device == 0x990D) ||
944e4d17063SAlex Deucher 			   (rdev->pdev->device == 0x990E) ||
945d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x9913) ||
94662d1f92eSAlex Deucher 			   (rdev->pdev->device == 0x9918) ||
94762d1f92eSAlex Deucher 			   (rdev->pdev->device == 0x999D)) {
9487b76e479SAlex Deucher 			rdev->config.cayman.max_simds_per_se = 4;
9497b76e479SAlex Deucher 			rdev->config.cayman.max_backends_per_se = 2;
950e2f6c88fSAlex Deucher 			rdev->config.cayman.max_hw_contexts = 8;
951e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_size = 256;
952e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_pos_size = 64;
953e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_smx_size = 192;
954d430f7dbSAlex Deucher 		} else if ((rdev->pdev->device == 0x9919) ||
955d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x9990) ||
956d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x9991) ||
957d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x9994) ||
958e4d17063SAlex Deucher 			   (rdev->pdev->device == 0x9995) ||
959e4d17063SAlex Deucher 			   (rdev->pdev->device == 0x9996) ||
960e4d17063SAlex Deucher 			   (rdev->pdev->device == 0x999A) ||
961d430f7dbSAlex Deucher 			   (rdev->pdev->device == 0x99A0)) {
9627b76e479SAlex Deucher 			rdev->config.cayman.max_simds_per_se = 3;
9637b76e479SAlex Deucher 			rdev->config.cayman.max_backends_per_se = 1;
964e2f6c88fSAlex Deucher 			rdev->config.cayman.max_hw_contexts = 4;
965e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_size = 128;
966e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_pos_size = 32;
967e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_smx_size = 96;
9687b76e479SAlex Deucher 		} else {
9697b76e479SAlex Deucher 			rdev->config.cayman.max_simds_per_se = 2;
9707b76e479SAlex Deucher 			rdev->config.cayman.max_backends_per_se = 1;
971e2f6c88fSAlex Deucher 			rdev->config.cayman.max_hw_contexts = 4;
972e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_size = 128;
973e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_pos_size = 32;
974e2f6c88fSAlex Deucher 			rdev->config.cayman.sx_max_export_smx_size = 96;
9757b76e479SAlex Deucher 		}
9767b76e479SAlex Deucher 		rdev->config.cayman.max_texture_channel_caches = 2;
9777b76e479SAlex Deucher 		rdev->config.cayman.max_gprs = 256;
9787b76e479SAlex Deucher 		rdev->config.cayman.max_threads = 256;
9797b76e479SAlex Deucher 		rdev->config.cayman.max_gs_threads = 32;
9807b76e479SAlex Deucher 		rdev->config.cayman.max_stack_entries = 512;
9817b76e479SAlex Deucher 		rdev->config.cayman.sx_num_of_sets = 8;
9827b76e479SAlex Deucher 		rdev->config.cayman.sq_num_cf_insts = 2;
9837b76e479SAlex Deucher 
9847b76e479SAlex Deucher 		rdev->config.cayman.sc_prim_fifo_size = 0x40;
9857b76e479SAlex Deucher 		rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
9867b76e479SAlex Deucher 		rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
987416a2bd2SAlex Deucher 		gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
9887b76e479SAlex Deucher 		break;
989fecf1d07SAlex Deucher 	}
990fecf1d07SAlex Deucher 
991fecf1d07SAlex Deucher 	/* Initialize HDP */
992fecf1d07SAlex Deucher 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
993fecf1d07SAlex Deucher 		WREG32((0x2c14 + j), 0x00000000);
994fecf1d07SAlex Deucher 		WREG32((0x2c18 + j), 0x00000000);
995fecf1d07SAlex Deucher 		WREG32((0x2c1c + j), 0x00000000);
996fecf1d07SAlex Deucher 		WREG32((0x2c20 + j), 0x00000000);
997fecf1d07SAlex Deucher 		WREG32((0x2c24 + j), 0x00000000);
998fecf1d07SAlex Deucher 	}
999fecf1d07SAlex Deucher 
1000fecf1d07SAlex Deucher 	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
1001acc1522aSChristian König 	WREG32(SRBM_INT_CNTL, 0x1);
1002acc1522aSChristian König 	WREG32(SRBM_INT_ACK, 0x1);
1003fecf1d07SAlex Deucher 
1004d054ac16SAlex Deucher 	evergreen_fix_pci_max_read_req_size(rdev);
1005d054ac16SAlex Deucher 
1006880d8dfcSLee Jones 	RREG32(MC_SHARED_CHMAP);
1007fecf1d07SAlex Deucher 	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
1008fecf1d07SAlex Deucher 
1009fecf1d07SAlex Deucher 	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
1010fecf1d07SAlex Deucher 	rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
1011fecf1d07SAlex Deucher 	if (rdev->config.cayman.mem_row_size_in_kb > 4)
1012fecf1d07SAlex Deucher 		rdev->config.cayman.mem_row_size_in_kb = 4;
1013fecf1d07SAlex Deucher 	/* XXX use MC settings? */
1014fecf1d07SAlex Deucher 	rdev->config.cayman.shader_engine_tile_size = 32;
1015fecf1d07SAlex Deucher 	rdev->config.cayman.num_gpus = 1;
1016fecf1d07SAlex Deucher 	rdev->config.cayman.multi_gpu_tile_size = 64;
1017fecf1d07SAlex Deucher 
1018fecf1d07SAlex Deucher 	tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
1019fecf1d07SAlex Deucher 	rdev->config.cayman.num_tile_pipes = (1 << tmp);
1020fecf1d07SAlex Deucher 	tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
1021fecf1d07SAlex Deucher 	rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
1022fecf1d07SAlex Deucher 	tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
1023fecf1d07SAlex Deucher 	rdev->config.cayman.num_shader_engines = tmp + 1;
1024fecf1d07SAlex Deucher 	tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
1025fecf1d07SAlex Deucher 	rdev->config.cayman.num_gpus = tmp + 1;
1026fecf1d07SAlex Deucher 	tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
1027fecf1d07SAlex Deucher 	rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
1028fecf1d07SAlex Deucher 	tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
1029fecf1d07SAlex Deucher 	rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
1030fecf1d07SAlex Deucher 
1031416a2bd2SAlex Deucher 
1032fecf1d07SAlex Deucher 	/* setup tiling info dword.  gb_addr_config is not adequate since it does
1033fecf1d07SAlex Deucher 	 * not have bank info, so create a custom tiling dword.
1034fecf1d07SAlex Deucher 	 * bits 3:0   num_pipes
1035fecf1d07SAlex Deucher 	 * bits 7:4   num_banks
1036fecf1d07SAlex Deucher 	 * bits 11:8  group_size
1037fecf1d07SAlex Deucher 	 * bits 15:12 row_size
1038fecf1d07SAlex Deucher 	 */
1039fecf1d07SAlex Deucher 	rdev->config.cayman.tile_config = 0;
1040fecf1d07SAlex Deucher 	switch (rdev->config.cayman.num_tile_pipes) {
1041fecf1d07SAlex Deucher 	case 1:
1042fecf1d07SAlex Deucher 	default:
1043fecf1d07SAlex Deucher 		rdev->config.cayman.tile_config |= (0 << 0);
1044fecf1d07SAlex Deucher 		break;
1045fecf1d07SAlex Deucher 	case 2:
1046fecf1d07SAlex Deucher 		rdev->config.cayman.tile_config |= (1 << 0);
1047fecf1d07SAlex Deucher 		break;
1048fecf1d07SAlex Deucher 	case 4:
1049fecf1d07SAlex Deucher 		rdev->config.cayman.tile_config |= (2 << 0);
1050fecf1d07SAlex Deucher 		break;
1051fecf1d07SAlex Deucher 	case 8:
1052fecf1d07SAlex Deucher 		rdev->config.cayman.tile_config |= (3 << 0);
1053fecf1d07SAlex Deucher 		break;
1054fecf1d07SAlex Deucher 	}
10557b76e479SAlex Deucher 
10567b76e479SAlex Deucher 	/* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
10577b76e479SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP)
10581f73cca7SAlex Deucher 		rdev->config.cayman.tile_config |= 1 << 4;
105929d65406SAlex Deucher 	else {
10605b23c904SAlex Deucher 		switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
10615b23c904SAlex Deucher 		case 0: /* four banks */
106229d65406SAlex Deucher 			rdev->config.cayman.tile_config |= 0 << 4;
10635b23c904SAlex Deucher 			break;
10645b23c904SAlex Deucher 		case 1: /* eight banks */
10655b23c904SAlex Deucher 			rdev->config.cayman.tile_config |= 1 << 4;
10665b23c904SAlex Deucher 			break;
10675b23c904SAlex Deucher 		case 2: /* sixteen banks */
10685b23c904SAlex Deucher 		default:
10695b23c904SAlex Deucher 			rdev->config.cayman.tile_config |= 2 << 4;
10705b23c904SAlex Deucher 			break;
10715b23c904SAlex Deucher 		}
107229d65406SAlex Deucher 	}
1073fecf1d07SAlex Deucher 	rdev->config.cayman.tile_config |=
1074cde5083bSDave Airlie 		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
1075fecf1d07SAlex Deucher 	rdev->config.cayman.tile_config |=
1076fecf1d07SAlex Deucher 		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
1077fecf1d07SAlex Deucher 
1078416a2bd2SAlex Deucher 	tmp = 0;
1079416a2bd2SAlex Deucher 	for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
1080416a2bd2SAlex Deucher 		u32 rb_disable_bitmap;
1081416a2bd2SAlex Deucher 
1082416a2bd2SAlex Deucher 		WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1083416a2bd2SAlex Deucher 		WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
1084416a2bd2SAlex Deucher 		rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
1085416a2bd2SAlex Deucher 		tmp <<= 4;
1086416a2bd2SAlex Deucher 		tmp |= rb_disable_bitmap;
1087416a2bd2SAlex Deucher 	}
1088416a2bd2SAlex Deucher 	/* enabled rb are just the one not disabled :) */
1089416a2bd2SAlex Deucher 	disabled_rb_mask = tmp;
1090cedb655aSAlex Deucher 	tmp = 0;
1091cedb655aSAlex Deucher 	for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1092cedb655aSAlex Deucher 		tmp |= (1 << i);
1093cedb655aSAlex Deucher 	/* if all the backends are disabled, fix it up here */
1094cedb655aSAlex Deucher 	if ((disabled_rb_mask & tmp) == tmp) {
1095cedb655aSAlex Deucher 		for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
1096cedb655aSAlex Deucher 			disabled_rb_mask &= ~(1 << i);
1097cedb655aSAlex Deucher 	}
1098416a2bd2SAlex Deucher 
109965fcf668SAlex Deucher 	for (i = 0; i < rdev->config.cayman.max_shader_engines; i++) {
110065fcf668SAlex Deucher 		u32 simd_disable_bitmap;
110165fcf668SAlex Deucher 
110265fcf668SAlex Deucher 		WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
110365fcf668SAlex Deucher 		WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
110465fcf668SAlex Deucher 		simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
110565fcf668SAlex Deucher 		simd_disable_bitmap |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
110665fcf668SAlex Deucher 		tmp <<= 16;
110765fcf668SAlex Deucher 		tmp |= simd_disable_bitmap;
110865fcf668SAlex Deucher 	}
110965fcf668SAlex Deucher 	rdev->config.cayman.active_simds = hweight32(~tmp);
111065fcf668SAlex Deucher 
1111416a2bd2SAlex Deucher 	WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1112416a2bd2SAlex Deucher 	WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
1113416a2bd2SAlex Deucher 
1114fecf1d07SAlex Deucher 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
1115fecf1d07SAlex Deucher 	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
11167c1c7c18SAlex Deucher 	if (ASIC_IS_DCE6(rdev))
11177c1c7c18SAlex Deucher 		WREG32(DMIF_ADDR_CALC, gb_addr_config);
1118fecf1d07SAlex Deucher 	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
1119f60cbd11SAlex Deucher 	WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
1120f60cbd11SAlex Deucher 	WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
11219a21059dSChristian König 	WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
11229a21059dSChristian König 	WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
11239a21059dSChristian König 	WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
1124fecf1d07SAlex Deucher 
11258f612b23SAlex Deucher 	if ((rdev->config.cayman.max_backends_per_se == 1) &&
11268f612b23SAlex Deucher 	    (rdev->flags & RADEON_IS_IGP)) {
1127dbfb00c3SAlex Deucher 		if ((disabled_rb_mask & 3) == 2) {
11288f612b23SAlex Deucher 			/* RB1 disabled, RB0 enabled */
11298f612b23SAlex Deucher 			tmp = 0x00000000;
1130dbfb00c3SAlex Deucher 		} else {
1131dbfb00c3SAlex Deucher 			/* RB0 disabled, RB1 enabled */
1132dbfb00c3SAlex Deucher 			tmp = 0x11111111;
11338f612b23SAlex Deucher 		}
11348f612b23SAlex Deucher 	} else {
1135416a2bd2SAlex Deucher 		tmp = gb_addr_config & NUM_PIPES_MASK;
1136416a2bd2SAlex Deucher 		tmp = r6xx_remap_render_backend(rdev, tmp,
1137416a2bd2SAlex Deucher 						rdev->config.cayman.max_backends_per_se *
1138416a2bd2SAlex Deucher 						rdev->config.cayman.max_shader_engines,
1139416a2bd2SAlex Deucher 						CAYMAN_MAX_BACKENDS, disabled_rb_mask);
11408f612b23SAlex Deucher 	}
11418159e509SDave Airlie 	rdev->config.cayman.backend_map = tmp;
1142416a2bd2SAlex Deucher 	WREG32(GB_BACKEND_MAP, tmp);
1143fecf1d07SAlex Deucher 
1144416a2bd2SAlex Deucher 	cgts_tcc_disable = 0xffff0000;
1145416a2bd2SAlex Deucher 	for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
1146416a2bd2SAlex Deucher 		cgts_tcc_disable &= ~(1 << (16 + i));
1147fecf1d07SAlex Deucher 	WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
1148fecf1d07SAlex Deucher 	WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
1149fecf1d07SAlex Deucher 	WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
1150fecf1d07SAlex Deucher 	WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
1151fecf1d07SAlex Deucher 
1152fecf1d07SAlex Deucher 	/* reprogram the shader complex */
1153fecf1d07SAlex Deucher 	cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
1154fecf1d07SAlex Deucher 	for (i = 0; i < 16; i++)
1155fecf1d07SAlex Deucher 		WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
1156fecf1d07SAlex Deucher 	WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
1157fecf1d07SAlex Deucher 
1158fecf1d07SAlex Deucher 	/* set HW defaults for 3D engine */
1159fecf1d07SAlex Deucher 	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
1160fecf1d07SAlex Deucher 
1161fecf1d07SAlex Deucher 	sx_debug_1 = RREG32(SX_DEBUG_1);
1162fecf1d07SAlex Deucher 	sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
1163fecf1d07SAlex Deucher 	WREG32(SX_DEBUG_1, sx_debug_1);
1164fecf1d07SAlex Deucher 
1165fecf1d07SAlex Deucher 	smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
1166fecf1d07SAlex Deucher 	smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
1167285e042dSDave Airlie 	smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
1168fecf1d07SAlex Deucher 	WREG32(SMX_DC_CTL0, smx_dc_ctl0);
1169fecf1d07SAlex Deucher 
1170fecf1d07SAlex Deucher 	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
1171fecf1d07SAlex Deucher 
1172fecf1d07SAlex Deucher 	/* need to be explicitly zero-ed */
1173fecf1d07SAlex Deucher 	WREG32(VGT_OFFCHIP_LDS_BASE, 0);
1174fecf1d07SAlex Deucher 	WREG32(SQ_LSTMP_RING_BASE, 0);
1175fecf1d07SAlex Deucher 	WREG32(SQ_HSTMP_RING_BASE, 0);
1176fecf1d07SAlex Deucher 	WREG32(SQ_ESTMP_RING_BASE, 0);
1177fecf1d07SAlex Deucher 	WREG32(SQ_GSTMP_RING_BASE, 0);
1178fecf1d07SAlex Deucher 	WREG32(SQ_VSTMP_RING_BASE, 0);
1179fecf1d07SAlex Deucher 	WREG32(SQ_PSTMP_RING_BASE, 0);
1180fecf1d07SAlex Deucher 
1181fecf1d07SAlex Deucher 	WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
1182fecf1d07SAlex Deucher 
1183285e042dSDave Airlie 	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
1184285e042dSDave Airlie 					POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
1185285e042dSDave Airlie 					SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
1186fecf1d07SAlex Deucher 
1187285e042dSDave Airlie 	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
1188285e042dSDave Airlie 				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
1189285e042dSDave Airlie 				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
1190fecf1d07SAlex Deucher 
1191fecf1d07SAlex Deucher 
1192fecf1d07SAlex Deucher 	WREG32(VGT_NUM_INSTANCES, 1);
1193fecf1d07SAlex Deucher 
1194fecf1d07SAlex Deucher 	WREG32(CP_PERFMON_CNTL, 0);
1195fecf1d07SAlex Deucher 
1196285e042dSDave Airlie 	WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
1197fecf1d07SAlex Deucher 				  FETCH_FIFO_HIWATER(0x4) |
1198fecf1d07SAlex Deucher 				  DONE_FIFO_HIWATER(0xe0) |
1199fecf1d07SAlex Deucher 				  ALU_UPDATE_FIFO_HIWATER(0x8)));
1200fecf1d07SAlex Deucher 
1201fecf1d07SAlex Deucher 	WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
1202fecf1d07SAlex Deucher 	WREG32(SQ_CONFIG, (VC_ENABLE |
1203fecf1d07SAlex Deucher 			   EXPORT_SRC_C |
1204fecf1d07SAlex Deucher 			   GFX_PRIO(0) |
1205fecf1d07SAlex Deucher 			   CS1_PRIO(0) |
1206fecf1d07SAlex Deucher 			   CS2_PRIO(1)));
1207fecf1d07SAlex Deucher 	WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
1208fecf1d07SAlex Deucher 
1209fecf1d07SAlex Deucher 	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
1210fecf1d07SAlex Deucher 					  FORCE_EOV_MAX_REZ_CNT(255)));
1211fecf1d07SAlex Deucher 
1212fecf1d07SAlex Deucher 	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
1213fecf1d07SAlex Deucher 	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
1214fecf1d07SAlex Deucher 
1215fecf1d07SAlex Deucher 	WREG32(VGT_GS_VERTEX_REUSE, 16);
1216fecf1d07SAlex Deucher 	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1217fecf1d07SAlex Deucher 
1218fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR0_SEL_0, 0);
1219fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR0_SEL_1, 0);
1220fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR1_SEL_0, 0);
1221fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR1_SEL_1, 0);
1222fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR2_SEL_0, 0);
1223fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR2_SEL_1, 0);
1224fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR3_SEL_0, 0);
1225fecf1d07SAlex Deucher 	WREG32(CB_PERF_CTR3_SEL_1, 0);
1226fecf1d07SAlex Deucher 
12270b65f83fSDave Airlie 	tmp = RREG32(HDP_MISC_CNTL);
12280b65f83fSDave Airlie 	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
12290b65f83fSDave Airlie 	WREG32(HDP_MISC_CNTL, tmp);
12300b65f83fSDave Airlie 
1231fecf1d07SAlex Deucher 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
1232fecf1d07SAlex Deucher 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
1233fecf1d07SAlex Deucher 
1234fecf1d07SAlex Deucher 	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
1235fecf1d07SAlex Deucher 
1236fecf1d07SAlex Deucher 	udelay(50);
12378ba10463SAlex Deucher 
12388ba10463SAlex Deucher 	/* set clockgating golden values on TN */
12398ba10463SAlex Deucher 	if (rdev->family == CHIP_ARUBA) {
12408ba10463SAlex Deucher 		tmp = RREG32_CG(CG_CGTT_LOCAL_0);
12418ba10463SAlex Deucher 		tmp &= ~0x00380000;
12428ba10463SAlex Deucher 		WREG32_CG(CG_CGTT_LOCAL_0, tmp);
12438ba10463SAlex Deucher 		tmp = RREG32_CG(CG_CGTT_LOCAL_1);
12448ba10463SAlex Deucher 		tmp &= ~0x0e000000;
12458ba10463SAlex Deucher 		WREG32_CG(CG_CGTT_LOCAL_1, tmp);
12468ba10463SAlex Deucher 	}
1247fecf1d07SAlex Deucher }
1248fecf1d07SAlex Deucher 
1249fa8198eaSAlex Deucher /*
1250fa8198eaSAlex Deucher  * GART
1251fa8198eaSAlex Deucher  */
cayman_pcie_gart_tlb_flush(struct radeon_device * rdev)1252fa8198eaSAlex Deucher void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
1253fa8198eaSAlex Deucher {
1254fa8198eaSAlex Deucher 	/* flush hdp cache */
1255fa8198eaSAlex Deucher 	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
1256fa8198eaSAlex Deucher 
1257fa8198eaSAlex Deucher 	/* bits 0-7 are the VM contexts0-7 */
1258fa8198eaSAlex Deucher 	WREG32(VM_INVALIDATE_REQUEST, 1);
1259fa8198eaSAlex Deucher }
1260fa8198eaSAlex Deucher 
cayman_pcie_gart_enable(struct radeon_device * rdev)12611109ca09SLauri Kasanen static int cayman_pcie_gart_enable(struct radeon_device *rdev)
1262fa8198eaSAlex Deucher {
1263721604a1SJerome Glisse 	int i, r;
1264fa8198eaSAlex Deucher 
1265c9a1be96SJerome Glisse 	if (rdev->gart.robj == NULL) {
1266fa8198eaSAlex Deucher 		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
1267fa8198eaSAlex Deucher 		return -EINVAL;
1268fa8198eaSAlex Deucher 	}
1269fa8198eaSAlex Deucher 	r = radeon_gart_table_vram_pin(rdev);
1270fa8198eaSAlex Deucher 	if (r)
1271fa8198eaSAlex Deucher 		return r;
1272fa8198eaSAlex Deucher 	/* Setup TLB control */
1273721604a1SJerome Glisse 	WREG32(MC_VM_MX_L1_TLB_CNTL,
1274721604a1SJerome Glisse 	       (0xA << 7) |
1275721604a1SJerome Glisse 	       ENABLE_L1_TLB |
1276fa8198eaSAlex Deucher 	       ENABLE_L1_FRAGMENT_PROCESSING |
1277fa8198eaSAlex Deucher 	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1278721604a1SJerome Glisse 	       ENABLE_ADVANCED_DRIVER_MODEL |
1279fa8198eaSAlex Deucher 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1280fa8198eaSAlex Deucher 	/* Setup L2 cache */
1281fa8198eaSAlex Deucher 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
1282ec3dbbcbSChristian König 	       ENABLE_L2_FRAGMENT_PROCESSING |
1283fa8198eaSAlex Deucher 	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1284fa8198eaSAlex Deucher 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1285fa8198eaSAlex Deucher 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
1286fa8198eaSAlex Deucher 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
1287fa8198eaSAlex Deucher 	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
1288fa8198eaSAlex Deucher 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1289ec3dbbcbSChristian König 	       BANK_SELECT(6) |
1290fa8198eaSAlex Deucher 	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1291fa8198eaSAlex Deucher 	/* setup context0 */
1292fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
12937c0411d2SChristian König 	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
1294fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
1295fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
1296fa8198eaSAlex Deucher 			(u32)(rdev->dummy_page.addr >> 12));
1297fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT0_CNTL2, 0);
1298fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
1299fa8198eaSAlex Deucher 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
1300721604a1SJerome Glisse 
1301721604a1SJerome Glisse 	WREG32(0x15D4, 0);
1302721604a1SJerome Glisse 	WREG32(0x15D8, 0);
1303721604a1SJerome Glisse 	WREG32(0x15DC, 0);
1304721604a1SJerome Glisse 
1305721604a1SJerome Glisse 	/* empty context1-7 */
130623d4f1f2SAlex Deucher 	/* Assign the pt base to something valid for now; the pts used for
130723d4f1f2SAlex Deucher 	 * the VMs are determined by the application and setup and assigned
130823d4f1f2SAlex Deucher 	 * on the fly in the vm part of radeon_gart.c
130923d4f1f2SAlex Deucher 	 */
1310721604a1SJerome Glisse 	for (i = 1; i < 8; i++) {
1311721604a1SJerome Glisse 		WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
1312607d4806SChristian König 		WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
1313607d4806SChristian König 			rdev->vm_manager.max_pfn - 1);
1314721604a1SJerome Glisse 		WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
1315054e01d6SChristian König 		       rdev->vm_manager.saved_table_addr[i]);
1316721604a1SJerome Glisse 	}
1317721604a1SJerome Glisse 
1318721604a1SJerome Glisse 	/* enable context1-7 */
1319721604a1SJerome Glisse 	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
1320721604a1SJerome Glisse 	       (u32)(rdev->dummy_page.addr >> 12));
1321ae133a11SChristian König 	WREG32(VM_CONTEXT1_CNTL2, 4);
1322fa87e62dSDmitry Cherkasov 	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
13234510fb98SChristian König 				PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
1324ae133a11SChristian König 				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1325ae133a11SChristian König 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1326ae133a11SChristian König 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1327ae133a11SChristian König 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
1328ae133a11SChristian König 				PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
1329ae133a11SChristian König 				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
1330ae133a11SChristian König 				VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
1331ae133a11SChristian König 				VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
1332ae133a11SChristian König 				READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
1333ae133a11SChristian König 				READ_PROTECTION_FAULT_ENABLE_DEFAULT |
1334ae133a11SChristian König 				WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
1335ae133a11SChristian König 				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
1336fa8198eaSAlex Deucher 
1337fa8198eaSAlex Deucher 	cayman_pcie_gart_tlb_flush(rdev);
1338fcf4de5aSTormod Volden 	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
1339fcf4de5aSTormod Volden 		 (unsigned)(rdev->mc.gtt_size >> 20),
1340fcf4de5aSTormod Volden 		 (unsigned long long)rdev->gart.table_addr);
1341fa8198eaSAlex Deucher 	rdev->gart.ready = true;
1342fa8198eaSAlex Deucher 	return 0;
1343fa8198eaSAlex Deucher }
1344fa8198eaSAlex Deucher 
cayman_pcie_gart_disable(struct radeon_device * rdev)13451109ca09SLauri Kasanen static void cayman_pcie_gart_disable(struct radeon_device *rdev)
1346fa8198eaSAlex Deucher {
1347054e01d6SChristian König 	unsigned i;
1348054e01d6SChristian König 
1349054e01d6SChristian König 	for (i = 1; i < 8; ++i) {
1350054e01d6SChristian König 		rdev->vm_manager.saved_table_addr[i] = RREG32(
1351054e01d6SChristian König 			VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2));
1352054e01d6SChristian König 	}
1353054e01d6SChristian König 
1354fa8198eaSAlex Deucher 	/* Disable all tables */
1355fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT0_CNTL, 0);
1356fa8198eaSAlex Deucher 	WREG32(VM_CONTEXT1_CNTL, 0);
1357fa8198eaSAlex Deucher 	/* Setup TLB control */
1358fa8198eaSAlex Deucher 	WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
1359fa8198eaSAlex Deucher 	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
1360fa8198eaSAlex Deucher 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
1361fa8198eaSAlex Deucher 	/* Setup L2 cache */
1362fa8198eaSAlex Deucher 	WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
1363fa8198eaSAlex Deucher 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
1364fa8198eaSAlex Deucher 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
1365fa8198eaSAlex Deucher 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
1366fa8198eaSAlex Deucher 	WREG32(VM_L2_CNTL2, 0);
1367fa8198eaSAlex Deucher 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
1368fa8198eaSAlex Deucher 	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
1369c9a1be96SJerome Glisse 	radeon_gart_table_vram_unpin(rdev);
1370fa8198eaSAlex Deucher }
1371fa8198eaSAlex Deucher 
cayman_pcie_gart_fini(struct radeon_device * rdev)13721109ca09SLauri Kasanen static void cayman_pcie_gart_fini(struct radeon_device *rdev)
1373fa8198eaSAlex Deucher {
1374fa8198eaSAlex Deucher 	cayman_pcie_gart_disable(rdev);
1375fa8198eaSAlex Deucher 	radeon_gart_table_vram_free(rdev);
1376fa8198eaSAlex Deucher 	radeon_gart_fini(rdev);
1377fa8198eaSAlex Deucher }
1378fa8198eaSAlex Deucher 
cayman_cp_int_cntl_setup(struct radeon_device * rdev,int ring,u32 cp_int_cntl)13791b37078bSAlex Deucher void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
13801b37078bSAlex Deucher 			      int ring, u32 cp_int_cntl)
13811b37078bSAlex Deucher {
1382537b4b46SLucas Stach 	WREG32(SRBM_GFX_CNTL, RINGID(ring));
13831b37078bSAlex Deucher 	WREG32(CP_INT_CNTL, cp_int_cntl);
13841b37078bSAlex Deucher }
13851b37078bSAlex Deucher 
13860c88a02eSAlex Deucher /*
13870c88a02eSAlex Deucher  * CP.
13880c88a02eSAlex Deucher  */
cayman_fence_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)1389b40e7e16SAlex Deucher void cayman_fence_ring_emit(struct radeon_device *rdev,
1390b40e7e16SAlex Deucher 			    struct radeon_fence *fence)
1391b40e7e16SAlex Deucher {
1392b40e7e16SAlex Deucher 	struct radeon_ring *ring = &rdev->ring[fence->ring];
1393b40e7e16SAlex Deucher 	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
139410e9ffaeSAlex Deucher 	u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
139510e9ffaeSAlex Deucher 		PACKET3_SH_ACTION_ENA;
1396b40e7e16SAlex Deucher 
1397721604a1SJerome Glisse 	/* flush read cache over gart for this vmid */
1398b40e7e16SAlex Deucher 	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
139910e9ffaeSAlex Deucher 	radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
1400b40e7e16SAlex Deucher 	radeon_ring_write(ring, 0xFFFFFFFF);
1401b40e7e16SAlex Deucher 	radeon_ring_write(ring, 0);
1402b40e7e16SAlex Deucher 	radeon_ring_write(ring, 10); /* poll interval */
1403b40e7e16SAlex Deucher 	/* EVENT_WRITE_EOP - flush caches, send int */
1404b40e7e16SAlex Deucher 	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
1405b40e7e16SAlex Deucher 	radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
14065e167cdbSChristian König 	radeon_ring_write(ring, lower_32_bits(addr));
1407b40e7e16SAlex Deucher 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
1408b40e7e16SAlex Deucher 	radeon_ring_write(ring, fence->seq);
1409b40e7e16SAlex Deucher 	radeon_ring_write(ring, 0);
1410b40e7e16SAlex Deucher }
1411b40e7e16SAlex Deucher 
cayman_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)1412721604a1SJerome Glisse void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
1413721604a1SJerome Glisse {
1414876dc9f3SChristian König 	struct radeon_ring *ring = &rdev->ring[ib->ring];
14157c42bc1aSChristian König 	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
141610e9ffaeSAlex Deucher 	u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
141710e9ffaeSAlex Deucher 		PACKET3_SH_ACTION_ENA;
1418721604a1SJerome Glisse 
1419721604a1SJerome Glisse 	/* set to DX10/11 mode */
1420721604a1SJerome Glisse 	radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
1421721604a1SJerome Glisse 	radeon_ring_write(ring, 1);
142245df6803SChristian König 
142345df6803SChristian König 	if (ring->rptr_save_reg) {
142445df6803SChristian König 		uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
142545df6803SChristian König 		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
142645df6803SChristian König 		radeon_ring_write(ring, ((ring->rptr_save_reg -
142745df6803SChristian König 					  PACKET3_SET_CONFIG_REG_START) >> 2));
142845df6803SChristian König 		radeon_ring_write(ring, next_rptr);
142945df6803SChristian König 	}
143045df6803SChristian König 
1431721604a1SJerome Glisse 	radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
1432721604a1SJerome Glisse 	radeon_ring_write(ring,
1433721604a1SJerome Glisse #ifdef __BIG_ENDIAN
1434721604a1SJerome Glisse 			  (2 << 0) |
1435721604a1SJerome Glisse #endif
1436721604a1SJerome Glisse 			  (ib->gpu_addr & 0xFFFFFFFC));
1437721604a1SJerome Glisse 	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
14387c42bc1aSChristian König 	radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
1439721604a1SJerome Glisse 
1440721604a1SJerome Glisse 	/* flush read cache over gart for this vmid */
1441721604a1SJerome Glisse 	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
144210e9ffaeSAlex Deucher 	radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
1443721604a1SJerome Glisse 	radeon_ring_write(ring, 0xFFFFFFFF);
1444721604a1SJerome Glisse 	radeon_ring_write(ring, 0);
14457c42bc1aSChristian König 	radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */
1446721604a1SJerome Glisse }
1447721604a1SJerome Glisse 
cayman_cp_enable(struct radeon_device * rdev,bool enable)14480c88a02eSAlex Deucher static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
14490c88a02eSAlex Deucher {
14500c88a02eSAlex Deucher 	if (enable)
14510c88a02eSAlex Deucher 		WREG32(CP_ME_CNTL, 0);
14520c88a02eSAlex Deucher 	else {
145350efa51aSAlex Deucher 		if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
145438f1cff0SDave Airlie 			radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
14550c88a02eSAlex Deucher 		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
14560c88a02eSAlex Deucher 		WREG32(SCRATCH_UMSK, 0);
1457f60cbd11SAlex Deucher 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
14580c88a02eSAlex Deucher 	}
14590c88a02eSAlex Deucher }
14600c88a02eSAlex Deucher 
cayman_gfx_get_rptr(struct radeon_device * rdev,struct radeon_ring * ring)1461ea31bf69SAlex Deucher u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
1462ea31bf69SAlex Deucher 			struct radeon_ring *ring)
1463ea31bf69SAlex Deucher {
1464ea31bf69SAlex Deucher 	u32 rptr;
1465ea31bf69SAlex Deucher 
1466ea31bf69SAlex Deucher 	if (rdev->wb.enabled)
1467ea31bf69SAlex Deucher 		rptr = rdev->wb.wb[ring->rptr_offs/4];
1468ea31bf69SAlex Deucher 	else {
1469ea31bf69SAlex Deucher 		if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
1470ea31bf69SAlex Deucher 			rptr = RREG32(CP_RB0_RPTR);
1471ea31bf69SAlex Deucher 		else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
1472ea31bf69SAlex Deucher 			rptr = RREG32(CP_RB1_RPTR);
1473ea31bf69SAlex Deucher 		else
1474ea31bf69SAlex Deucher 			rptr = RREG32(CP_RB2_RPTR);
1475ea31bf69SAlex Deucher 	}
1476ea31bf69SAlex Deucher 
1477ea31bf69SAlex Deucher 	return rptr;
1478ea31bf69SAlex Deucher }
1479ea31bf69SAlex Deucher 
cayman_gfx_get_wptr(struct radeon_device * rdev,struct radeon_ring * ring)1480ea31bf69SAlex Deucher u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
1481ea31bf69SAlex Deucher 			struct radeon_ring *ring)
1482ea31bf69SAlex Deucher {
1483ea31bf69SAlex Deucher 	u32 wptr;
1484ea31bf69SAlex Deucher 
1485ea31bf69SAlex Deucher 	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
1486ea31bf69SAlex Deucher 		wptr = RREG32(CP_RB0_WPTR);
1487ea31bf69SAlex Deucher 	else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
1488ea31bf69SAlex Deucher 		wptr = RREG32(CP_RB1_WPTR);
1489ea31bf69SAlex Deucher 	else
1490ea31bf69SAlex Deucher 		wptr = RREG32(CP_RB2_WPTR);
1491ea31bf69SAlex Deucher 
1492ea31bf69SAlex Deucher 	return wptr;
1493ea31bf69SAlex Deucher }
1494ea31bf69SAlex Deucher 
cayman_gfx_set_wptr(struct radeon_device * rdev,struct radeon_ring * ring)1495ea31bf69SAlex Deucher void cayman_gfx_set_wptr(struct radeon_device *rdev,
1496ea31bf69SAlex Deucher 			 struct radeon_ring *ring)
1497ea31bf69SAlex Deucher {
1498ea31bf69SAlex Deucher 	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
1499ea31bf69SAlex Deucher 		WREG32(CP_RB0_WPTR, ring->wptr);
1500ea31bf69SAlex Deucher 		(void)RREG32(CP_RB0_WPTR);
1501ea31bf69SAlex Deucher 	} else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
1502ea31bf69SAlex Deucher 		WREG32(CP_RB1_WPTR, ring->wptr);
1503ea31bf69SAlex Deucher 		(void)RREG32(CP_RB1_WPTR);
1504ea31bf69SAlex Deucher 	} else {
1505ea31bf69SAlex Deucher 		WREG32(CP_RB2_WPTR, ring->wptr);
1506ea31bf69SAlex Deucher 		(void)RREG32(CP_RB2_WPTR);
1507ea31bf69SAlex Deucher 	}
1508ea31bf69SAlex Deucher }
1509ea31bf69SAlex Deucher 
cayman_cp_load_microcode(struct radeon_device * rdev)15100c88a02eSAlex Deucher static int cayman_cp_load_microcode(struct radeon_device *rdev)
15110c88a02eSAlex Deucher {
15120c88a02eSAlex Deucher 	const __be32 *fw_data;
15130c88a02eSAlex Deucher 	int i;
15140c88a02eSAlex Deucher 
15150c88a02eSAlex Deucher 	if (!rdev->me_fw || !rdev->pfp_fw)
15160c88a02eSAlex Deucher 		return -EINVAL;
15170c88a02eSAlex Deucher 
15180c88a02eSAlex Deucher 	cayman_cp_enable(rdev, false);
15190c88a02eSAlex Deucher 
15200c88a02eSAlex Deucher 	fw_data = (const __be32 *)rdev->pfp_fw->data;
15210c88a02eSAlex Deucher 	WREG32(CP_PFP_UCODE_ADDR, 0);
15220c88a02eSAlex Deucher 	for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
15230c88a02eSAlex Deucher 		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
15240c88a02eSAlex Deucher 	WREG32(CP_PFP_UCODE_ADDR, 0);
15250c88a02eSAlex Deucher 
15260c88a02eSAlex Deucher 	fw_data = (const __be32 *)rdev->me_fw->data;
15270c88a02eSAlex Deucher 	WREG32(CP_ME_RAM_WADDR, 0);
15280c88a02eSAlex Deucher 	for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
15290c88a02eSAlex Deucher 		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
15300c88a02eSAlex Deucher 
15310c88a02eSAlex Deucher 	WREG32(CP_PFP_UCODE_ADDR, 0);
15320c88a02eSAlex Deucher 	WREG32(CP_ME_RAM_WADDR, 0);
15330c88a02eSAlex Deucher 	WREG32(CP_ME_RAM_RADDR, 0);
15340c88a02eSAlex Deucher 	return 0;
15350c88a02eSAlex Deucher }
15360c88a02eSAlex Deucher 
cayman_cp_start(struct radeon_device * rdev)15370c88a02eSAlex Deucher static int cayman_cp_start(struct radeon_device *rdev)
15380c88a02eSAlex Deucher {
1539e32eb50dSChristian König 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
15400c88a02eSAlex Deucher 	int r, i;
15410c88a02eSAlex Deucher 
1542e32eb50dSChristian König 	r = radeon_ring_lock(rdev, ring, 7);
15430c88a02eSAlex Deucher 	if (r) {
15440c88a02eSAlex Deucher 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
15450c88a02eSAlex Deucher 		return r;
15460c88a02eSAlex Deucher 	}
1547e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
1548e32eb50dSChristian König 	radeon_ring_write(ring, 0x1);
1549e32eb50dSChristian König 	radeon_ring_write(ring, 0x0);
1550e32eb50dSChristian König 	radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
1551e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1552e32eb50dSChristian König 	radeon_ring_write(ring, 0);
1553e32eb50dSChristian König 	radeon_ring_write(ring, 0);
15541538a9e0SMichel Dänzer 	radeon_ring_unlock_commit(rdev, ring, false);
15550c88a02eSAlex Deucher 
15560c88a02eSAlex Deucher 	cayman_cp_enable(rdev, true);
15570c88a02eSAlex Deucher 
1558e32eb50dSChristian König 	r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
15590c88a02eSAlex Deucher 	if (r) {
15600c88a02eSAlex Deucher 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
15610c88a02eSAlex Deucher 		return r;
15620c88a02eSAlex Deucher 	}
15630c88a02eSAlex Deucher 
15640c88a02eSAlex Deucher 	/* setup clear context state */
1565e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1566e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
15670c88a02eSAlex Deucher 
15680c88a02eSAlex Deucher 	for (i = 0; i < cayman_default_size; i++)
1569e32eb50dSChristian König 		radeon_ring_write(ring, cayman_default_state[i]);
15700c88a02eSAlex Deucher 
1571e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
1572e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
15730c88a02eSAlex Deucher 
15740c88a02eSAlex Deucher 	/* set clear context state */
1575e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
1576e32eb50dSChristian König 	radeon_ring_write(ring, 0);
15770c88a02eSAlex Deucher 
15780c88a02eSAlex Deucher 	/* SQ_VTX_BASE_VTX_LOC */
1579e32eb50dSChristian König 	radeon_ring_write(ring, 0xc0026f00);
1580e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000000);
1581e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000000);
1582e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000000);
15830c88a02eSAlex Deucher 
15840c88a02eSAlex Deucher 	/* Clear consts */
1585e32eb50dSChristian König 	radeon_ring_write(ring, 0xc0036f00);
1586e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000bc4);
1587e32eb50dSChristian König 	radeon_ring_write(ring, 0xffffffff);
1588e32eb50dSChristian König 	radeon_ring_write(ring, 0xffffffff);
1589e32eb50dSChristian König 	radeon_ring_write(ring, 0xffffffff);
15900c88a02eSAlex Deucher 
1591e32eb50dSChristian König 	radeon_ring_write(ring, 0xc0026900);
1592e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000316);
1593e32eb50dSChristian König 	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
1594e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000010); /*  */
15959b91d18dSAlex Deucher 
15961538a9e0SMichel Dänzer 	radeon_ring_unlock_commit(rdev, ring, false);
15970c88a02eSAlex Deucher 
15980c88a02eSAlex Deucher 	/* XXX init other rings */
15990c88a02eSAlex Deucher 
16000c88a02eSAlex Deucher 	return 0;
16010c88a02eSAlex Deucher }
16020c88a02eSAlex Deucher 
cayman_cp_fini(struct radeon_device * rdev)1603755d819eSAlex Deucher static void cayman_cp_fini(struct radeon_device *rdev)
1604755d819eSAlex Deucher {
160545df6803SChristian König 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
1606755d819eSAlex Deucher 	cayman_cp_enable(rdev, false);
160745df6803SChristian König 	radeon_ring_fini(rdev, ring);
160845df6803SChristian König 	radeon_scratch_free(rdev, ring->rptr_save_reg);
1609755d819eSAlex Deucher }
1610755d819eSAlex Deucher 
cayman_cp_resume(struct radeon_device * rdev)16111109ca09SLauri Kasanen static int cayman_cp_resume(struct radeon_device *rdev)
16120c88a02eSAlex Deucher {
1613b90ca986SChristian König 	static const int ridx[] = {
1614b90ca986SChristian König 		RADEON_RING_TYPE_GFX_INDEX,
1615b90ca986SChristian König 		CAYMAN_RING_TYPE_CP1_INDEX,
1616b90ca986SChristian König 		CAYMAN_RING_TYPE_CP2_INDEX
1617b90ca986SChristian König 	};
1618b90ca986SChristian König 	static const unsigned cp_rb_cntl[] = {
1619b90ca986SChristian König 		CP_RB0_CNTL,
1620b90ca986SChristian König 		CP_RB1_CNTL,
1621b90ca986SChristian König 		CP_RB2_CNTL,
1622b90ca986SChristian König 	};
1623b90ca986SChristian König 	static const unsigned cp_rb_rptr_addr[] = {
1624b90ca986SChristian König 		CP_RB0_RPTR_ADDR,
1625b90ca986SChristian König 		CP_RB1_RPTR_ADDR,
1626b90ca986SChristian König 		CP_RB2_RPTR_ADDR
1627b90ca986SChristian König 	};
1628b90ca986SChristian König 	static const unsigned cp_rb_rptr_addr_hi[] = {
1629b90ca986SChristian König 		CP_RB0_RPTR_ADDR_HI,
1630b90ca986SChristian König 		CP_RB1_RPTR_ADDR_HI,
1631b90ca986SChristian König 		CP_RB2_RPTR_ADDR_HI
1632b90ca986SChristian König 	};
1633b90ca986SChristian König 	static const unsigned cp_rb_base[] = {
1634b90ca986SChristian König 		CP_RB0_BASE,
1635b90ca986SChristian König 		CP_RB1_BASE,
1636b90ca986SChristian König 		CP_RB2_BASE
1637b90ca986SChristian König 	};
1638ea31bf69SAlex Deucher 	static const unsigned cp_rb_rptr[] = {
1639ea31bf69SAlex Deucher 		CP_RB0_RPTR,
1640ea31bf69SAlex Deucher 		CP_RB1_RPTR,
1641ea31bf69SAlex Deucher 		CP_RB2_RPTR
1642ea31bf69SAlex Deucher 	};
1643ea31bf69SAlex Deucher 	static const unsigned cp_rb_wptr[] = {
1644ea31bf69SAlex Deucher 		CP_RB0_WPTR,
1645ea31bf69SAlex Deucher 		CP_RB1_WPTR,
1646ea31bf69SAlex Deucher 		CP_RB2_WPTR
1647ea31bf69SAlex Deucher 	};
1648e32eb50dSChristian König 	struct radeon_ring *ring;
1649b90ca986SChristian König 	int i, r;
16500c88a02eSAlex Deucher 
16510c88a02eSAlex Deucher 	/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
16520c88a02eSAlex Deucher 	WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
16530c88a02eSAlex Deucher 				 SOFT_RESET_PA |
16540c88a02eSAlex Deucher 				 SOFT_RESET_SH |
16550c88a02eSAlex Deucher 				 SOFT_RESET_VGT |
1656a49a50daSJerome Glisse 				 SOFT_RESET_SPI |
16570c88a02eSAlex Deucher 				 SOFT_RESET_SX));
16580c88a02eSAlex Deucher 	RREG32(GRBM_SOFT_RESET);
16590c88a02eSAlex Deucher 	mdelay(15);
16600c88a02eSAlex Deucher 	WREG32(GRBM_SOFT_RESET, 0);
16610c88a02eSAlex Deucher 	RREG32(GRBM_SOFT_RESET);
16620c88a02eSAlex Deucher 
166315d3332fSChristian König 	WREG32(CP_SEM_WAIT_TIMER, 0x0);
166411ef3f1fSAlex Deucher 	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
16650c88a02eSAlex Deucher 
16660c88a02eSAlex Deucher 	/* Set the write pointer delay */
16670c88a02eSAlex Deucher 	WREG32(CP_RB_WPTR_DELAY, 0);
16680c88a02eSAlex Deucher 
16690c88a02eSAlex Deucher 	WREG32(CP_DEBUG, (1 << 27));
16700c88a02eSAlex Deucher 
167148fc7f7eSAdam Buchbinder 	/* set the wb address whether it's enabled or not */
1672b90ca986SChristian König 	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
1673b90ca986SChristian König 	WREG32(SCRATCH_UMSK, 0xff);
16740c88a02eSAlex Deucher 
1675b90ca986SChristian König 	for (i = 0; i < 3; ++i) {
1676b90ca986SChristian König 		uint32_t rb_cntl;
1677b90ca986SChristian König 		uint64_t addr;
1678b90ca986SChristian König 
1679b90ca986SChristian König 		/* Set ring buffer size */
1680b90ca986SChristian König 		ring = &rdev->ring[ridx[i]];
1681b72a8925SDaniel Vetter 		rb_cntl = order_base_2(ring->ring_size / 8);
1682b72a8925SDaniel Vetter 		rb_cntl |= order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8;
1683b90ca986SChristian König #ifdef __BIG_ENDIAN
1684b90ca986SChristian König 		rb_cntl |= BUF_SWAP_32BIT;
1685b90ca986SChristian König #endif
1686b90ca986SChristian König 		WREG32(cp_rb_cntl[i], rb_cntl);
16870c88a02eSAlex Deucher 
168848fc7f7eSAdam Buchbinder 		/* set the wb address whether it's enabled or not */
1689b90ca986SChristian König 		addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
1690b90ca986SChristian König 		WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
1691b90ca986SChristian König 		WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
16920c88a02eSAlex Deucher 	}
16930c88a02eSAlex Deucher 
1694b90ca986SChristian König 	/* set the rb base addr, this causes an internal reset of ALL rings */
1695b90ca986SChristian König 	for (i = 0; i < 3; ++i) {
1696b90ca986SChristian König 		ring = &rdev->ring[ridx[i]];
1697b90ca986SChristian König 		WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
1698b90ca986SChristian König 	}
16990c88a02eSAlex Deucher 
1700b90ca986SChristian König 	for (i = 0; i < 3; ++i) {
17010c88a02eSAlex Deucher 		/* Initialize the ring buffer's read and write pointers */
1702b90ca986SChristian König 		ring = &rdev->ring[ridx[i]];
1703b90ca986SChristian König 		WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
17040c88a02eSAlex Deucher 
1705ff212f25SChristian König 		ring->wptr = 0;
1706ff212f25SChristian König 		WREG32(cp_rb_rptr[i], 0);
1707ea31bf69SAlex Deucher 		WREG32(cp_rb_wptr[i], ring->wptr);
17080c88a02eSAlex Deucher 
17090c88a02eSAlex Deucher 		mdelay(1);
1710b90ca986SChristian König 		WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
1711b90ca986SChristian König 	}
17120c88a02eSAlex Deucher 
17130c88a02eSAlex Deucher 	/* start the rings */
17140c88a02eSAlex Deucher 	cayman_cp_start(rdev);
1715e32eb50dSChristian König 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
1716e32eb50dSChristian König 	rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1717e32eb50dSChristian König 	rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
17180c88a02eSAlex Deucher 	/* this only test cp0 */
1719f712812eSAlex Deucher 	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
17200c88a02eSAlex Deucher 	if (r) {
1721e32eb50dSChristian König 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
1722e32eb50dSChristian König 		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
1723e32eb50dSChristian König 		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
17240c88a02eSAlex Deucher 		return r;
17250c88a02eSAlex Deucher 	}
17260c88a02eSAlex Deucher 
172750efa51aSAlex Deucher 	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
172850efa51aSAlex Deucher 		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
172950efa51aSAlex Deucher 
17300c88a02eSAlex Deucher 	return 0;
17310c88a02eSAlex Deucher }
17320c88a02eSAlex Deucher 
cayman_gpu_check_soft_reset(struct radeon_device * rdev)17332483b4eaSChristian König u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
1734168757eaSAlex Deucher {
1735168757eaSAlex Deucher 	u32 reset_mask = 0;
1736168757eaSAlex Deucher 	u32 tmp;
1737168757eaSAlex Deucher 
1738168757eaSAlex Deucher 	/* GRBM_STATUS */
1739168757eaSAlex Deucher 	tmp = RREG32(GRBM_STATUS);
1740168757eaSAlex Deucher 	if (tmp & (PA_BUSY | SC_BUSY |
1741168757eaSAlex Deucher 		   SH_BUSY | SX_BUSY |
1742168757eaSAlex Deucher 		   TA_BUSY | VGT_BUSY |
1743168757eaSAlex Deucher 		   DB_BUSY | CB_BUSY |
1744168757eaSAlex Deucher 		   GDS_BUSY | SPI_BUSY |
1745168757eaSAlex Deucher 		   IA_BUSY | IA_BUSY_NO_DMA))
1746168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_GFX;
1747168757eaSAlex Deucher 
1748168757eaSAlex Deucher 	if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
1749168757eaSAlex Deucher 		   CP_BUSY | CP_COHERENCY_BUSY))
1750168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_CP;
1751168757eaSAlex Deucher 
1752168757eaSAlex Deucher 	if (tmp & GRBM_EE_BUSY)
1753168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
1754168757eaSAlex Deucher 
1755168757eaSAlex Deucher 	/* DMA_STATUS_REG 0 */
1756168757eaSAlex Deucher 	tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
1757168757eaSAlex Deucher 	if (!(tmp & DMA_IDLE))
1758168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_DMA;
1759168757eaSAlex Deucher 
1760168757eaSAlex Deucher 	/* DMA_STATUS_REG 1 */
1761168757eaSAlex Deucher 	tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
1762168757eaSAlex Deucher 	if (!(tmp & DMA_IDLE))
1763168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_DMA1;
1764168757eaSAlex Deucher 
1765168757eaSAlex Deucher 	/* SRBM_STATUS2 */
1766168757eaSAlex Deucher 	tmp = RREG32(SRBM_STATUS2);
1767168757eaSAlex Deucher 	if (tmp & DMA_BUSY)
1768168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_DMA;
1769168757eaSAlex Deucher 
1770168757eaSAlex Deucher 	if (tmp & DMA1_BUSY)
1771168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_DMA1;
1772168757eaSAlex Deucher 
1773168757eaSAlex Deucher 	/* SRBM_STATUS */
1774168757eaSAlex Deucher 	tmp = RREG32(SRBM_STATUS);
1775168757eaSAlex Deucher 	if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
1776168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_RLC;
1777168757eaSAlex Deucher 
1778168757eaSAlex Deucher 	if (tmp & IH_BUSY)
1779168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_IH;
1780168757eaSAlex Deucher 
1781168757eaSAlex Deucher 	if (tmp & SEM_BUSY)
1782168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_SEM;
1783168757eaSAlex Deucher 
1784168757eaSAlex Deucher 	if (tmp & GRBM_RQ_PENDING)
1785168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_GRBM;
1786168757eaSAlex Deucher 
1787168757eaSAlex Deucher 	if (tmp & VMC_BUSY)
1788168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_VMC;
1789168757eaSAlex Deucher 
1790168757eaSAlex Deucher 	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
1791168757eaSAlex Deucher 		   MCC_BUSY | MCD_BUSY))
1792168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_MC;
1793168757eaSAlex Deucher 
1794168757eaSAlex Deucher 	if (evergreen_is_display_hung(rdev))
1795168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_DISPLAY;
1796168757eaSAlex Deucher 
1797168757eaSAlex Deucher 	/* VM_L2_STATUS */
1798168757eaSAlex Deucher 	tmp = RREG32(VM_L2_STATUS);
1799168757eaSAlex Deucher 	if (tmp & L2_BUSY)
1800168757eaSAlex Deucher 		reset_mask |= RADEON_RESET_VMC;
1801168757eaSAlex Deucher 
1802d808fc88SAlex Deucher 	/* Skip MC reset as it's mostly likely not hung, just busy */
1803d808fc88SAlex Deucher 	if (reset_mask & RADEON_RESET_MC) {
1804d808fc88SAlex Deucher 		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
1805d808fc88SAlex Deucher 		reset_mask &= ~RADEON_RESET_MC;
1806d808fc88SAlex Deucher 	}
1807d808fc88SAlex Deucher 
1808168757eaSAlex Deucher 	return reset_mask;
1809168757eaSAlex Deucher }
1810168757eaSAlex Deucher 
cayman_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)1811168757eaSAlex Deucher static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1812b9952a8aSAlex Deucher {
1813187e3593SAlex Deucher 	struct evergreen_mc_save save;
1814187e3593SAlex Deucher 	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1815187e3593SAlex Deucher 	u32 tmp;
1816187e3593SAlex Deucher 
1817187e3593SAlex Deucher 	if (reset_mask == 0)
1818168757eaSAlex Deucher 		return;
1819187e3593SAlex Deucher 
1820187e3593SAlex Deucher 	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1821187e3593SAlex Deucher 
1822187e3593SAlex Deucher 	evergreen_print_gpu_status_regs(rdev);
1823187e3593SAlex Deucher 	dev_info(rdev->dev, "  VM_CONTEXT0_PROTECTION_FAULT_ADDR   0x%08X\n",
1824187e3593SAlex Deucher 		 RREG32(0x14F8));
1825187e3593SAlex Deucher 	dev_info(rdev->dev, "  VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
1826187e3593SAlex Deucher 		 RREG32(0x14D8));
1827187e3593SAlex Deucher 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
1828187e3593SAlex Deucher 		 RREG32(0x14FC));
1829187e3593SAlex Deucher 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1830187e3593SAlex Deucher 		 RREG32(0x14DC));
1831187e3593SAlex Deucher 
1832b9952a8aSAlex Deucher 	/* Disable CP parsing/prefetching */
1833b9952a8aSAlex Deucher 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1834b9952a8aSAlex Deucher 
1835187e3593SAlex Deucher 	if (reset_mask & RADEON_RESET_DMA) {
1836187e3593SAlex Deucher 		/* dma0 */
1837187e3593SAlex Deucher 		tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1838187e3593SAlex Deucher 		tmp &= ~DMA_RB_ENABLE;
1839187e3593SAlex Deucher 		WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
1840168757eaSAlex Deucher 	}
1841187e3593SAlex Deucher 
1842168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_DMA1) {
1843187e3593SAlex Deucher 		/* dma1 */
1844187e3593SAlex Deucher 		tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1845187e3593SAlex Deucher 		tmp &= ~DMA_RB_ENABLE;
1846187e3593SAlex Deucher 		WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1847187e3593SAlex Deucher 	}
1848187e3593SAlex Deucher 
184990fb8779SAlex Deucher 	udelay(50);
185090fb8779SAlex Deucher 
185190fb8779SAlex Deucher 	evergreen_mc_stop(rdev, &save);
185290fb8779SAlex Deucher 	if (evergreen_mc_wait_for_idle(rdev)) {
185390fb8779SAlex Deucher 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
185490fb8779SAlex Deucher 	}
185590fb8779SAlex Deucher 
1856187e3593SAlex Deucher 	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1857187e3593SAlex Deucher 		grbm_soft_reset = SOFT_RESET_CB |
1858b9952a8aSAlex Deucher 			SOFT_RESET_DB |
1859b9952a8aSAlex Deucher 			SOFT_RESET_GDS |
1860b9952a8aSAlex Deucher 			SOFT_RESET_PA |
1861b9952a8aSAlex Deucher 			SOFT_RESET_SC |
1862b9952a8aSAlex Deucher 			SOFT_RESET_SPI |
1863b9952a8aSAlex Deucher 			SOFT_RESET_SH |
1864b9952a8aSAlex Deucher 			SOFT_RESET_SX |
1865b9952a8aSAlex Deucher 			SOFT_RESET_TC |
1866b9952a8aSAlex Deucher 			SOFT_RESET_TA |
1867b9952a8aSAlex Deucher 			SOFT_RESET_VGT |
1868187e3593SAlex Deucher 			SOFT_RESET_IA;
1869271d6fedSAlex Deucher 	}
1870271d6fedSAlex Deucher 
1871187e3593SAlex Deucher 	if (reset_mask & RADEON_RESET_CP) {
1872187e3593SAlex Deucher 		grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1873271d6fedSAlex Deucher 
1874187e3593SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_GRBM;
1875271d6fedSAlex Deucher 	}
1876271d6fedSAlex Deucher 
1877271d6fedSAlex Deucher 	if (reset_mask & RADEON_RESET_DMA)
1878168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_DMA;
1879168757eaSAlex Deucher 
1880168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_DMA1)
1881168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_DMA1;
1882168757eaSAlex Deucher 
1883168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_DISPLAY)
1884168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_DC;
1885168757eaSAlex Deucher 
1886168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_RLC)
1887168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_RLC;
1888168757eaSAlex Deucher 
1889168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_SEM)
1890168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_SEM;
1891168757eaSAlex Deucher 
1892168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_IH)
1893168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_IH;
1894168757eaSAlex Deucher 
1895168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_GRBM)
1896168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_GRBM;
1897168757eaSAlex Deucher 
1898168757eaSAlex Deucher 	if (reset_mask & RADEON_RESET_VMC)
1899168757eaSAlex Deucher 		srbm_soft_reset |= SOFT_RESET_VMC;
1900168757eaSAlex Deucher 
190124178ec4SAlex Deucher 	if (!(rdev->flags & RADEON_IS_IGP)) {
1902168757eaSAlex Deucher 		if (reset_mask & RADEON_RESET_MC)
1903168757eaSAlex Deucher 			srbm_soft_reset |= SOFT_RESET_MC;
190424178ec4SAlex Deucher 	}
1905187e3593SAlex Deucher 
1906187e3593SAlex Deucher 	if (grbm_soft_reset) {
1907187e3593SAlex Deucher 		tmp = RREG32(GRBM_SOFT_RESET);
1908187e3593SAlex Deucher 		tmp |= grbm_soft_reset;
1909187e3593SAlex Deucher 		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1910187e3593SAlex Deucher 		WREG32(GRBM_SOFT_RESET, tmp);
1911187e3593SAlex Deucher 		tmp = RREG32(GRBM_SOFT_RESET);
1912187e3593SAlex Deucher 
1913187e3593SAlex Deucher 		udelay(50);
1914187e3593SAlex Deucher 
1915187e3593SAlex Deucher 		tmp &= ~grbm_soft_reset;
1916187e3593SAlex Deucher 		WREG32(GRBM_SOFT_RESET, tmp);
1917187e3593SAlex Deucher 		tmp = RREG32(GRBM_SOFT_RESET);
1918187e3593SAlex Deucher 	}
1919187e3593SAlex Deucher 
1920187e3593SAlex Deucher 	if (srbm_soft_reset) {
1921187e3593SAlex Deucher 		tmp = RREG32(SRBM_SOFT_RESET);
1922187e3593SAlex Deucher 		tmp |= srbm_soft_reset;
1923187e3593SAlex Deucher 		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1924187e3593SAlex Deucher 		WREG32(SRBM_SOFT_RESET, tmp);
1925187e3593SAlex Deucher 		tmp = RREG32(SRBM_SOFT_RESET);
1926187e3593SAlex Deucher 
1927187e3593SAlex Deucher 		udelay(50);
1928187e3593SAlex Deucher 
1929187e3593SAlex Deucher 		tmp &= ~srbm_soft_reset;
1930187e3593SAlex Deucher 		WREG32(SRBM_SOFT_RESET, tmp);
1931187e3593SAlex Deucher 		tmp = RREG32(SRBM_SOFT_RESET);
1932187e3593SAlex Deucher 	}
1933271d6fedSAlex Deucher 
1934271d6fedSAlex Deucher 	/* Wait a little for things to settle down */
1935271d6fedSAlex Deucher 	udelay(50);
1936271d6fedSAlex Deucher 
1937b9952a8aSAlex Deucher 	evergreen_mc_resume(rdev, &save);
1938187e3593SAlex Deucher 	udelay(50);
1939410a3418SAlex Deucher 
1940187e3593SAlex Deucher 	evergreen_print_gpu_status_regs(rdev);
1941b9952a8aSAlex Deucher }
1942b9952a8aSAlex Deucher 
cayman_asic_reset(struct radeon_device * rdev,bool hard)194371fe2899SJérome Glisse int cayman_asic_reset(struct radeon_device *rdev, bool hard)
1944b9952a8aSAlex Deucher {
1945168757eaSAlex Deucher 	u32 reset_mask;
1946168757eaSAlex Deucher 
194771fe2899SJérome Glisse 	if (hard) {
194871fe2899SJérome Glisse 		evergreen_gpu_pci_config_reset(rdev);
194971fe2899SJérome Glisse 		return 0;
195071fe2899SJérome Glisse 	}
195171fe2899SJérome Glisse 
1952168757eaSAlex Deucher 	reset_mask = cayman_gpu_check_soft_reset(rdev);
1953168757eaSAlex Deucher 
1954168757eaSAlex Deucher 	if (reset_mask)
1955168757eaSAlex Deucher 		r600_set_bios_scratch_engine_hung(rdev, true);
1956168757eaSAlex Deucher 
1957168757eaSAlex Deucher 	cayman_gpu_soft_reset(rdev, reset_mask);
1958168757eaSAlex Deucher 
1959168757eaSAlex Deucher 	reset_mask = cayman_gpu_check_soft_reset(rdev);
1960168757eaSAlex Deucher 
1961b5470b03SAlex Deucher 	if (reset_mask)
1962b5470b03SAlex Deucher 		evergreen_gpu_pci_config_reset(rdev);
1963b5470b03SAlex Deucher 
1964168757eaSAlex Deucher 	r600_set_bios_scratch_engine_hung(rdev, false);
1965168757eaSAlex Deucher 
1966168757eaSAlex Deucher 	return 0;
1967b9952a8aSAlex Deucher }
1968b9952a8aSAlex Deucher 
1969f60cbd11SAlex Deucher /**
1970123bc183SAlex Deucher  * cayman_gfx_is_lockup - Check if the GFX engine is locked up
1971123bc183SAlex Deucher  *
1972123bc183SAlex Deucher  * @rdev: radeon_device pointer
1973123bc183SAlex Deucher  * @ring: radeon_ring structure holding ring information
1974123bc183SAlex Deucher  *
1975123bc183SAlex Deucher  * Check if the GFX engine is locked up.
1976123bc183SAlex Deucher  * Returns true if the engine appears to be locked up, false if not.
1977123bc183SAlex Deucher  */
cayman_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)1978123bc183SAlex Deucher bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1979123bc183SAlex Deucher {
1980123bc183SAlex Deucher 	u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
1981123bc183SAlex Deucher 
1982123bc183SAlex Deucher 	if (!(reset_mask & (RADEON_RESET_GFX |
1983123bc183SAlex Deucher 			    RADEON_RESET_COMPUTE |
1984123bc183SAlex Deucher 			    RADEON_RESET_CP))) {
1985ff212f25SChristian König 		radeon_ring_lockup_update(rdev, ring);
1986123bc183SAlex Deucher 		return false;
1987123bc183SAlex Deucher 	}
1988123bc183SAlex Deucher 	return radeon_ring_test_lockup(rdev, ring);
1989123bc183SAlex Deucher }
1990123bc183SAlex Deucher 
cayman_uvd_init(struct radeon_device * rdev)1991bd42210dSJérome Glisse static void cayman_uvd_init(struct radeon_device *rdev)
1992bd42210dSJérome Glisse {
1993bd42210dSJérome Glisse 	int r;
1994bd42210dSJérome Glisse 
1995bd42210dSJérome Glisse 	if (!rdev->has_uvd)
1996bd42210dSJérome Glisse 		return;
1997bd42210dSJérome Glisse 
1998bd42210dSJérome Glisse 	r = radeon_uvd_init(rdev);
1999bd42210dSJérome Glisse 	if (r) {
2000bd42210dSJérome Glisse 		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
2001bd42210dSJérome Glisse 		/*
2002bd42210dSJérome Glisse 		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
2003bd42210dSJérome Glisse 		 * to early fails uvd_v2_2_resume() and thus nothing happens
2004bd42210dSJérome Glisse 		 * there. So it is pointless to try to go through that code
2005bd42210dSJérome Glisse 		 * hence why we disable uvd here.
2006bd42210dSJérome Glisse 		 */
2007ab2c1ea4Szhengbin 		rdev->has_uvd = false;
2008bd42210dSJérome Glisse 		return;
2009bd42210dSJérome Glisse 	}
2010bd42210dSJérome Glisse 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
2011bd42210dSJérome Glisse 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
2012bd42210dSJérome Glisse }
2013bd42210dSJérome Glisse 
cayman_uvd_start(struct radeon_device * rdev)2014bd42210dSJérome Glisse static void cayman_uvd_start(struct radeon_device *rdev)
2015bd42210dSJérome Glisse {
2016bd42210dSJérome Glisse 	int r;
2017bd42210dSJérome Glisse 
2018bd42210dSJérome Glisse 	if (!rdev->has_uvd)
2019bd42210dSJérome Glisse 		return;
2020bd42210dSJérome Glisse 
2021bd42210dSJérome Glisse 	r = uvd_v2_2_resume(rdev);
2022bd42210dSJérome Glisse 	if (r) {
2023bd42210dSJérome Glisse 		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
2024bd42210dSJérome Glisse 		goto error;
2025bd42210dSJérome Glisse 	}
2026bd42210dSJérome Glisse 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
2027bd42210dSJérome Glisse 	if (r) {
2028bd42210dSJérome Glisse 		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
2029bd42210dSJérome Glisse 		goto error;
2030bd42210dSJérome Glisse 	}
2031bd42210dSJérome Glisse 	return;
2032bd42210dSJérome Glisse 
2033bd42210dSJérome Glisse error:
2034bd42210dSJérome Glisse 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
2035bd42210dSJérome Glisse }
2036bd42210dSJérome Glisse 
cayman_uvd_resume(struct radeon_device * rdev)2037bd42210dSJérome Glisse static void cayman_uvd_resume(struct radeon_device *rdev)
2038bd42210dSJérome Glisse {
2039bd42210dSJérome Glisse 	struct radeon_ring *ring;
2040bd42210dSJérome Glisse 	int r;
2041bd42210dSJérome Glisse 
2042bd42210dSJérome Glisse 	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
2043bd42210dSJérome Glisse 		return;
2044bd42210dSJérome Glisse 
2045bd42210dSJérome Glisse 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
204670a033d2SAlex Deucher 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
2047bd42210dSJérome Glisse 	if (r) {
2048bd42210dSJérome Glisse 		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
2049bd42210dSJérome Glisse 		return;
2050bd42210dSJérome Glisse 	}
2051bd42210dSJérome Glisse 	r = uvd_v1_0_init(rdev);
2052bd42210dSJérome Glisse 	if (r) {
2053bd42210dSJérome Glisse 		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
2054bd42210dSJérome Glisse 		return;
2055bd42210dSJérome Glisse 	}
2056bd42210dSJérome Glisse }
2057bd42210dSJérome Glisse 
cayman_vce_init(struct radeon_device * rdev)20586c0b1204SJérome Glisse static void cayman_vce_init(struct radeon_device *rdev)
20596c0b1204SJérome Glisse {
20606c0b1204SJérome Glisse 	int r;
20616c0b1204SJérome Glisse 
20626c0b1204SJérome Glisse 	/* Only set for CHIP_ARUBA */
20636c0b1204SJérome Glisse 	if (!rdev->has_vce)
20646c0b1204SJérome Glisse 		return;
20656c0b1204SJérome Glisse 
20666c0b1204SJérome Glisse 	r = radeon_vce_init(rdev);
20676c0b1204SJérome Glisse 	if (r) {
20686c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
20696c0b1204SJérome Glisse 		/*
20706c0b1204SJérome Glisse 		 * At this point rdev->vce.vcpu_bo is NULL which trickles down
20716c0b1204SJérome Glisse 		 * to early fails cayman_vce_start() and thus nothing happens
20726c0b1204SJérome Glisse 		 * there. So it is pointless to try to go through that code
20736c0b1204SJérome Glisse 		 * hence why we disable vce here.
20746c0b1204SJérome Glisse 		 */
2075ab2c1ea4Szhengbin 		rdev->has_vce = false;
20766c0b1204SJérome Glisse 		return;
20776c0b1204SJérome Glisse 	}
20786c0b1204SJérome Glisse 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
20796c0b1204SJérome Glisse 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
20806c0b1204SJérome Glisse 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
20816c0b1204SJérome Glisse 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
20826c0b1204SJérome Glisse }
20836c0b1204SJérome Glisse 
cayman_vce_start(struct radeon_device * rdev)20846c0b1204SJérome Glisse static void cayman_vce_start(struct radeon_device *rdev)
20856c0b1204SJérome Glisse {
20866c0b1204SJérome Glisse 	int r;
20876c0b1204SJérome Glisse 
20886c0b1204SJérome Glisse 	if (!rdev->has_vce)
20896c0b1204SJérome Glisse 		return;
20906c0b1204SJérome Glisse 
20916c0b1204SJérome Glisse 	r = radeon_vce_resume(rdev);
20926c0b1204SJérome Glisse 	if (r) {
20936c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
20946c0b1204SJérome Glisse 		goto error;
20956c0b1204SJérome Glisse 	}
20966c0b1204SJérome Glisse 	r = vce_v1_0_resume(rdev);
20976c0b1204SJérome Glisse 	if (r) {
20986c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
20996c0b1204SJérome Glisse 		goto error;
21006c0b1204SJérome Glisse 	}
21016c0b1204SJérome Glisse 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
21026c0b1204SJérome Glisse 	if (r) {
21036c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
21046c0b1204SJérome Glisse 		goto error;
21056c0b1204SJérome Glisse 	}
21066c0b1204SJérome Glisse 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
21076c0b1204SJérome Glisse 	if (r) {
21086c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
21096c0b1204SJérome Glisse 		goto error;
21106c0b1204SJérome Glisse 	}
21116c0b1204SJérome Glisse 	return;
21126c0b1204SJérome Glisse 
21136c0b1204SJérome Glisse error:
21146c0b1204SJérome Glisse 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
21156c0b1204SJérome Glisse 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
21166c0b1204SJérome Glisse }
21176c0b1204SJérome Glisse 
cayman_vce_resume(struct radeon_device * rdev)21186c0b1204SJérome Glisse static void cayman_vce_resume(struct radeon_device *rdev)
21196c0b1204SJérome Glisse {
21206c0b1204SJérome Glisse 	struct radeon_ring *ring;
21216c0b1204SJérome Glisse 	int r;
21226c0b1204SJérome Glisse 
21236c0b1204SJérome Glisse 	if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
21246c0b1204SJérome Glisse 		return;
21256c0b1204SJérome Glisse 
21266c0b1204SJérome Glisse 	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
21276c0b1204SJérome Glisse 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
21286c0b1204SJérome Glisse 	if (r) {
21296c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
21306c0b1204SJérome Glisse 		return;
21316c0b1204SJérome Glisse 	}
21326c0b1204SJérome Glisse 	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
21336c0b1204SJérome Glisse 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
21346c0b1204SJérome Glisse 	if (r) {
21356c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
21366c0b1204SJérome Glisse 		return;
21376c0b1204SJérome Glisse 	}
21386c0b1204SJérome Glisse 	r = vce_v1_0_init(rdev);
21396c0b1204SJérome Glisse 	if (r) {
21406c0b1204SJérome Glisse 		dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
21416c0b1204SJérome Glisse 		return;
21426c0b1204SJérome Glisse 	}
21436c0b1204SJérome Glisse }
21446c0b1204SJérome Glisse 
cayman_startup(struct radeon_device * rdev)2145755d819eSAlex Deucher static int cayman_startup(struct radeon_device *rdev)
2146755d819eSAlex Deucher {
2147e32eb50dSChristian König 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2148755d819eSAlex Deucher 	int r;
2149755d819eSAlex Deucher 
2150b07759bfSIlija Hadzic 	/* enable pcie gen2 link */
2151b07759bfSIlija Hadzic 	evergreen_pcie_gen2_enable(rdev);
2152f52382d7SAlex Deucher 	/* enable aspm */
2153f52382d7SAlex Deucher 	evergreen_program_aspm(rdev);
2154b07759bfSIlija Hadzic 
2155e5903d39SAlex Deucher 	/* scratch needs to be initialized before MC */
2156e5903d39SAlex Deucher 	r = r600_vram_scratch_init(rdev);
2157e5903d39SAlex Deucher 	if (r)
2158e5903d39SAlex Deucher 		return r;
2159e5903d39SAlex Deucher 
21606fab3febSAlex Deucher 	evergreen_mc_program(rdev);
21616fab3febSAlex Deucher 
21626c7bcceaSAlex Deucher 	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
2163755d819eSAlex Deucher 		r = ni_mc_load_microcode(rdev);
2164755d819eSAlex Deucher 		if (r) {
2165755d819eSAlex Deucher 			DRM_ERROR("Failed to load MC firmware!\n");
2166755d819eSAlex Deucher 			return r;
2167755d819eSAlex Deucher 		}
2168c420c745SAlex Deucher 	}
2169755d819eSAlex Deucher 
2170755d819eSAlex Deucher 	r = cayman_pcie_gart_enable(rdev);
2171755d819eSAlex Deucher 	if (r)
2172755d819eSAlex Deucher 		return r;
2173755d819eSAlex Deucher 	cayman_gpu_init(rdev);
2174755d819eSAlex Deucher 
2175c420c745SAlex Deucher 	/* allocate rlc buffers */
2176c420c745SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
21772948f5e6SAlex Deucher 		rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
21781fd11777SAlex Deucher 		rdev->rlc.reg_list_size =
21791fd11777SAlex Deucher 			(u32)ARRAY_SIZE(tn_rlc_save_restore_register_list);
21802948f5e6SAlex Deucher 		rdev->rlc.cs_data = cayman_cs_data;
21812948f5e6SAlex Deucher 		r = sumo_rlc_init(rdev);
2182c420c745SAlex Deucher 		if (r) {
2183c420c745SAlex Deucher 			DRM_ERROR("Failed to init rlc BOs!\n");
2184c420c745SAlex Deucher 			return r;
2185c420c745SAlex Deucher 		}
2186c420c745SAlex Deucher 	}
2187c420c745SAlex Deucher 
2188755d819eSAlex Deucher 	/* allocate wb buffer */
2189755d819eSAlex Deucher 	r = radeon_wb_init(rdev);
2190755d819eSAlex Deucher 	if (r)
2191755d819eSAlex Deucher 		return r;
2192755d819eSAlex Deucher 
219330eb77f4SJerome Glisse 	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
219430eb77f4SJerome Glisse 	if (r) {
219530eb77f4SJerome Glisse 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
219630eb77f4SJerome Glisse 		return r;
219730eb77f4SJerome Glisse 	}
219830eb77f4SJerome Glisse 
2199bd42210dSJérome Glisse 	cayman_uvd_start(rdev);
22006c0b1204SJérome Glisse 	cayman_vce_start(rdev);
2201a918efabSChristian König 
220230eb77f4SJerome Glisse 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
220330eb77f4SJerome Glisse 	if (r) {
220430eb77f4SJerome Glisse 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
220530eb77f4SJerome Glisse 		return r;
220630eb77f4SJerome Glisse 	}
220730eb77f4SJerome Glisse 
220830eb77f4SJerome Glisse 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
220930eb77f4SJerome Glisse 	if (r) {
221030eb77f4SJerome Glisse 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
221130eb77f4SJerome Glisse 		return r;
221230eb77f4SJerome Glisse 	}
221330eb77f4SJerome Glisse 
2214f60cbd11SAlex Deucher 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
2215f60cbd11SAlex Deucher 	if (r) {
2216f60cbd11SAlex Deucher 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2217f60cbd11SAlex Deucher 		return r;
2218f60cbd11SAlex Deucher 	}
2219f60cbd11SAlex Deucher 
2220f60cbd11SAlex Deucher 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
2221f60cbd11SAlex Deucher 	if (r) {
2222f60cbd11SAlex Deucher 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
2223f60cbd11SAlex Deucher 		return r;
2224f60cbd11SAlex Deucher 	}
2225f60cbd11SAlex Deucher 
2226755d819eSAlex Deucher 	/* Enable IRQ */
2227e49f3959SAdis Hamzić 	if (!rdev->irq.installed) {
2228e49f3959SAdis Hamzić 		r = radeon_irq_kms_init(rdev);
2229e49f3959SAdis Hamzić 		if (r)
2230e49f3959SAdis Hamzić 			return r;
2231e49f3959SAdis Hamzić 	}
2232e49f3959SAdis Hamzić 
2233755d819eSAlex Deucher 	r = r600_irq_init(rdev);
2234755d819eSAlex Deucher 	if (r) {
2235755d819eSAlex Deucher 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
2236755d819eSAlex Deucher 		radeon_irq_kms_fini(rdev);
2237755d819eSAlex Deucher 		return r;
2238755d819eSAlex Deucher 	}
2239755d819eSAlex Deucher 	evergreen_irq_set(rdev);
2240755d819eSAlex Deucher 
2241e32eb50dSChristian König 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
22422e1e6dadSChristian König 			     RADEON_CP_PACKET2);
2243755d819eSAlex Deucher 	if (r)
2244755d819eSAlex Deucher 		return r;
2245f60cbd11SAlex Deucher 
2246f60cbd11SAlex Deucher 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2247f60cbd11SAlex Deucher 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
22482e1e6dadSChristian König 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2249f60cbd11SAlex Deucher 	if (r)
2250f60cbd11SAlex Deucher 		return r;
2251f60cbd11SAlex Deucher 
2252f60cbd11SAlex Deucher 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2253f60cbd11SAlex Deucher 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
22542e1e6dadSChristian König 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
2255f60cbd11SAlex Deucher 	if (r)
2256f60cbd11SAlex Deucher 		return r;
2257f60cbd11SAlex Deucher 
2258755d819eSAlex Deucher 	r = cayman_cp_load_microcode(rdev);
2259755d819eSAlex Deucher 	if (r)
2260755d819eSAlex Deucher 		return r;
2261755d819eSAlex Deucher 	r = cayman_cp_resume(rdev);
2262755d819eSAlex Deucher 	if (r)
2263755d819eSAlex Deucher 		return r;
2264755d819eSAlex Deucher 
2265f60cbd11SAlex Deucher 	r = cayman_dma_resume(rdev);
2266f60cbd11SAlex Deucher 	if (r)
2267f60cbd11SAlex Deucher 		return r;
2268f60cbd11SAlex Deucher 
2269bd42210dSJérome Glisse 	cayman_uvd_resume(rdev);
22706c0b1204SJérome Glisse 	cayman_vce_resume(rdev);
2271a918efabSChristian König 
22722898c348SChristian König 	r = radeon_ib_pool_init(rdev);
22732898c348SChristian König 	if (r) {
22742898c348SChristian König 		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
2275b15ba512SJerome Glisse 		return r;
22762898c348SChristian König 	}
2277b15ba512SJerome Glisse 
2278c6105f24SChristian König 	r = radeon_vm_manager_init(rdev);
2279c6105f24SChristian König 	if (r) {
2280c6105f24SChristian König 		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
2281721604a1SJerome Glisse 		return r;
2282c6105f24SChristian König 	}
2283721604a1SJerome Glisse 
2284bfc1f97dSSlava Grigorev 	r = radeon_audio_init(rdev);
2285b530602fSAlex Deucher 	if (r)
2286b530602fSAlex Deucher 		return r;
22876b53a050SRafał Miłecki 
2288755d819eSAlex Deucher 	return 0;
2289755d819eSAlex Deucher }
2290755d819eSAlex Deucher 
cayman_resume(struct radeon_device * rdev)2291755d819eSAlex Deucher int cayman_resume(struct radeon_device *rdev)
2292755d819eSAlex Deucher {
2293755d819eSAlex Deucher 	int r;
2294755d819eSAlex Deucher 
2295755d819eSAlex Deucher 	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
2296755d819eSAlex Deucher 	 * posting will perform necessary task to bring back GPU into good
2297755d819eSAlex Deucher 	 * shape.
2298755d819eSAlex Deucher 	 */
2299755d819eSAlex Deucher 	/* post card */
2300755d819eSAlex Deucher 	atom_asic_init(rdev->mode_info.atom_context);
2301755d819eSAlex Deucher 
2302a2c96a21SAlex Deucher 	/* init golden registers */
2303a2c96a21SAlex Deucher 	ni_init_golden_registers(rdev);
2304a2c96a21SAlex Deucher 
2305bc6a6295SAlex Deucher 	if (rdev->pm.pm_method == PM_METHOD_DPM)
23066c7bcceaSAlex Deucher 		radeon_pm_resume(rdev);
23076c7bcceaSAlex Deucher 
2308b15ba512SJerome Glisse 	rdev->accel_working = true;
2309755d819eSAlex Deucher 	r = cayman_startup(rdev);
2310755d819eSAlex Deucher 	if (r) {
2311755d819eSAlex Deucher 		DRM_ERROR("cayman startup failed on resume\n");
23126b7746e8SJerome Glisse 		rdev->accel_working = false;
2313755d819eSAlex Deucher 		return r;
2314755d819eSAlex Deucher 	}
2315755d819eSAlex Deucher 	return r;
2316755d819eSAlex Deucher }
2317755d819eSAlex Deucher 
cayman_suspend(struct radeon_device * rdev)2318755d819eSAlex Deucher int cayman_suspend(struct radeon_device *rdev)
2319755d819eSAlex Deucher {
23206c7bcceaSAlex Deucher 	radeon_pm_suspend(rdev);
23217991d665SSlava Grigorev 	radeon_audio_fini(rdev);
2322fa3daf9aSAlex Deucher 	radeon_vm_manager_fini(rdev);
2323755d819eSAlex Deucher 	cayman_cp_enable(rdev, false);
2324f60cbd11SAlex Deucher 	cayman_dma_stop(rdev);
2325bd42210dSJérome Glisse 	if (rdev->has_uvd) {
2326f2ba57b5SChristian König 		radeon_uvd_suspend(rdev);
2327dfd6879bSQiang Ma 		uvd_v1_0_fini(rdev);
2328bd42210dSJérome Glisse 	}
2329755d819eSAlex Deucher 	evergreen_irq_suspend(rdev);
2330755d819eSAlex Deucher 	radeon_wb_disable(rdev);
2331755d819eSAlex Deucher 	cayman_pcie_gart_disable(rdev);
2332755d819eSAlex Deucher 	return 0;
2333755d819eSAlex Deucher }
2334755d819eSAlex Deucher 
2335755d819eSAlex Deucher /* Plan is to move initialization in that function and use
2336755d819eSAlex Deucher  * helper function so that radeon_device_init pretty much
2337755d819eSAlex Deucher  * do nothing more than calling asic specific function. This
2338755d819eSAlex Deucher  * should also allow to remove a bunch of callback function
2339755d819eSAlex Deucher  * like vram_info.
2340755d819eSAlex Deucher  */
cayman_init(struct radeon_device * rdev)2341755d819eSAlex Deucher int cayman_init(struct radeon_device *rdev)
2342755d819eSAlex Deucher {
2343e32eb50dSChristian König 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
2344755d819eSAlex Deucher 	int r;
2345755d819eSAlex Deucher 
2346755d819eSAlex Deucher 	/* Read BIOS */
2347755d819eSAlex Deucher 	if (!radeon_get_bios(rdev)) {
2348755d819eSAlex Deucher 		if (ASIC_IS_AVIVO(rdev))
2349755d819eSAlex Deucher 			return -EINVAL;
2350755d819eSAlex Deucher 	}
2351755d819eSAlex Deucher 	/* Must be an ATOMBIOS */
2352755d819eSAlex Deucher 	if (!rdev->is_atom_bios) {
2353755d819eSAlex Deucher 		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
2354755d819eSAlex Deucher 		return -EINVAL;
2355755d819eSAlex Deucher 	}
2356755d819eSAlex Deucher 	r = radeon_atombios_init(rdev);
2357755d819eSAlex Deucher 	if (r)
2358755d819eSAlex Deucher 		return r;
2359755d819eSAlex Deucher 
2360755d819eSAlex Deucher 	/* Post card if necessary */
2361755d819eSAlex Deucher 	if (!radeon_card_posted(rdev)) {
2362755d819eSAlex Deucher 		if (!rdev->bios) {
2363755d819eSAlex Deucher 			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2364755d819eSAlex Deucher 			return -EINVAL;
2365755d819eSAlex Deucher 		}
2366755d819eSAlex Deucher 		DRM_INFO("GPU not posted. posting now...\n");
2367755d819eSAlex Deucher 		atom_asic_init(rdev->mode_info.atom_context);
2368755d819eSAlex Deucher 	}
2369a2c96a21SAlex Deucher 	/* init golden registers */
2370a2c96a21SAlex Deucher 	ni_init_golden_registers(rdev);
2371755d819eSAlex Deucher 	/* Initialize scratch registers */
2372755d819eSAlex Deucher 	r600_scratch_init(rdev);
2373755d819eSAlex Deucher 	/* Initialize surface registers */
2374755d819eSAlex Deucher 	radeon_surface_init(rdev);
2375755d819eSAlex Deucher 	/* Initialize clocks */
2376*5e3a0f77SWu Hoi Pok 	radeon_get_clock_info(rdev_to_drm(rdev));
2377755d819eSAlex Deucher 	/* Fence driver */
2378519424d7SBernard Zhao 	radeon_fence_driver_init(rdev);
2379755d819eSAlex Deucher 	/* initialize memory controller */
2380755d819eSAlex Deucher 	r = evergreen_mc_init(rdev);
2381755d819eSAlex Deucher 	if (r)
2382755d819eSAlex Deucher 		return r;
2383755d819eSAlex Deucher 	/* Memory manager */
2384755d819eSAlex Deucher 	r = radeon_bo_init(rdev);
2385755d819eSAlex Deucher 	if (r)
2386755d819eSAlex Deucher 		return r;
2387755d819eSAlex Deucher 
238801ac8794SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
238901ac8794SAlex Deucher 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
239001ac8794SAlex Deucher 			r = ni_init_microcode(rdev);
239101ac8794SAlex Deucher 			if (r) {
239201ac8794SAlex Deucher 				DRM_ERROR("Failed to load firmware!\n");
239301ac8794SAlex Deucher 				return r;
239401ac8794SAlex Deucher 			}
239501ac8794SAlex Deucher 		}
239601ac8794SAlex Deucher 	} else {
239701ac8794SAlex Deucher 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
239801ac8794SAlex Deucher 			r = ni_init_microcode(rdev);
239901ac8794SAlex Deucher 			if (r) {
240001ac8794SAlex Deucher 				DRM_ERROR("Failed to load firmware!\n");
240101ac8794SAlex Deucher 				return r;
240201ac8794SAlex Deucher 			}
240301ac8794SAlex Deucher 		}
240401ac8794SAlex Deucher 	}
240501ac8794SAlex Deucher 
24066c7bcceaSAlex Deucher 	/* Initialize power management */
24076c7bcceaSAlex Deucher 	radeon_pm_init(rdev);
24086c7bcceaSAlex Deucher 
2409e32eb50dSChristian König 	ring->ring_obj = NULL;
2410e32eb50dSChristian König 	r600_ring_init(rdev, ring, 1024 * 1024);
2411755d819eSAlex Deucher 
2412f60cbd11SAlex Deucher 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
2413f60cbd11SAlex Deucher 	ring->ring_obj = NULL;
2414f60cbd11SAlex Deucher 	r600_ring_init(rdev, ring, 64 * 1024);
2415f60cbd11SAlex Deucher 
2416f60cbd11SAlex Deucher 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
2417f60cbd11SAlex Deucher 	ring->ring_obj = NULL;
2418f60cbd11SAlex Deucher 	r600_ring_init(rdev, ring, 64 * 1024);
2419f60cbd11SAlex Deucher 
2420bd42210dSJérome Glisse 	cayman_uvd_init(rdev);
24216c0b1204SJérome Glisse 	cayman_vce_init(rdev);
2422a918efabSChristian König 
2423755d819eSAlex Deucher 	rdev->ih.ring_obj = NULL;
2424755d819eSAlex Deucher 	r600_ih_ring_init(rdev, 64 * 1024);
2425755d819eSAlex Deucher 
2426755d819eSAlex Deucher 	r = r600_pcie_gart_init(rdev);
2427755d819eSAlex Deucher 	if (r)
2428755d819eSAlex Deucher 		return r;
2429755d819eSAlex Deucher 
2430755d819eSAlex Deucher 	rdev->accel_working = true;
2431755d819eSAlex Deucher 	r = cayman_startup(rdev);
2432755d819eSAlex Deucher 	if (r) {
2433755d819eSAlex Deucher 		dev_err(rdev->dev, "disabling GPU acceleration\n");
2434755d819eSAlex Deucher 		cayman_cp_fini(rdev);
2435f60cbd11SAlex Deucher 		cayman_dma_fini(rdev);
2436755d819eSAlex Deucher 		r600_irq_fini(rdev);
2437c420c745SAlex Deucher 		if (rdev->flags & RADEON_IS_IGP)
24382948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
2439755d819eSAlex Deucher 		radeon_wb_fini(rdev);
24402898c348SChristian König 		radeon_ib_pool_fini(rdev);
2441721604a1SJerome Glisse 		radeon_vm_manager_fini(rdev);
2442755d819eSAlex Deucher 		radeon_irq_kms_fini(rdev);
2443755d819eSAlex Deucher 		cayman_pcie_gart_fini(rdev);
2444755d819eSAlex Deucher 		rdev->accel_working = false;
2445755d819eSAlex Deucher 	}
2446755d819eSAlex Deucher 
2447755d819eSAlex Deucher 	/* Don't start up if the MC ucode is missing.
2448755d819eSAlex Deucher 	 * The default clocks and voltages before the MC ucode
2449755d819eSAlex Deucher 	 * is loaded are not suffient for advanced operations.
2450c420c745SAlex Deucher 	 *
2451c420c745SAlex Deucher 	 * We can skip this check for TN, because there is no MC
2452c420c745SAlex Deucher 	 * ucode.
2453755d819eSAlex Deucher 	 */
2454c420c745SAlex Deucher 	if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
2455755d819eSAlex Deucher 		DRM_ERROR("radeon: MC ucode required for NI+.\n");
2456755d819eSAlex Deucher 		return -EINVAL;
2457755d819eSAlex Deucher 	}
2458755d819eSAlex Deucher 
2459755d819eSAlex Deucher 	return 0;
2460755d819eSAlex Deucher }
2461755d819eSAlex Deucher 
cayman_fini(struct radeon_device * rdev)2462755d819eSAlex Deucher void cayman_fini(struct radeon_device *rdev)
2463755d819eSAlex Deucher {
24646c7bcceaSAlex Deucher 	radeon_pm_fini(rdev);
2465755d819eSAlex Deucher 	cayman_cp_fini(rdev);
2466f60cbd11SAlex Deucher 	cayman_dma_fini(rdev);
2467755d819eSAlex Deucher 	r600_irq_fini(rdev);
2468c420c745SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP)
24692948f5e6SAlex Deucher 		sumo_rlc_fini(rdev);
2470755d819eSAlex Deucher 	radeon_wb_fini(rdev);
2471721604a1SJerome Glisse 	radeon_vm_manager_fini(rdev);
24722898c348SChristian König 	radeon_ib_pool_fini(rdev);
2473755d819eSAlex Deucher 	radeon_irq_kms_fini(rdev);
2474e409b128SChristian König 	uvd_v1_0_fini(rdev);
2475f2ba57b5SChristian König 	radeon_uvd_fini(rdev);
24766c0b1204SJérome Glisse 	if (rdev->has_vce)
2477a918efabSChristian König 		radeon_vce_fini(rdev);
2478755d819eSAlex Deucher 	cayman_pcie_gart_fini(rdev);
247916cdf04dSAlex Deucher 	r600_vram_scratch_fini(rdev);
2480755d819eSAlex Deucher 	radeon_gem_fini(rdev);
2481755d819eSAlex Deucher 	radeon_fence_driver_fini(rdev);
2482755d819eSAlex Deucher 	radeon_bo_fini(rdev);
2483755d819eSAlex Deucher 	radeon_atombios_fini(rdev);
2484755d819eSAlex Deucher 	kfree(rdev->bios);
2485755d819eSAlex Deucher 	rdev->bios = NULL;
2486755d819eSAlex Deucher }
2487755d819eSAlex Deucher 
2488721604a1SJerome Glisse /*
2489721604a1SJerome Glisse  * vm
2490721604a1SJerome Glisse  */
cayman_vm_init(struct radeon_device * rdev)2491721604a1SJerome Glisse int cayman_vm_init(struct radeon_device *rdev)
2492721604a1SJerome Glisse {
2493721604a1SJerome Glisse 	/* number of VMs */
2494721604a1SJerome Glisse 	rdev->vm_manager.nvm = 8;
2495721604a1SJerome Glisse 	/* base offset of vram pages */
2496e71270fdSAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
2497e71270fdSAlex Deucher 		u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
2498e71270fdSAlex Deucher 		tmp <<= 22;
2499e71270fdSAlex Deucher 		rdev->vm_manager.vram_base_offset = tmp;
2500e71270fdSAlex Deucher 	} else
2501721604a1SJerome Glisse 		rdev->vm_manager.vram_base_offset = 0;
2502721604a1SJerome Glisse 	return 0;
2503721604a1SJerome Glisse }
2504721604a1SJerome Glisse 
cayman_vm_fini(struct radeon_device * rdev)2505721604a1SJerome Glisse void cayman_vm_fini(struct radeon_device *rdev)
2506721604a1SJerome Glisse {
2507721604a1SJerome Glisse }
2508721604a1SJerome Glisse 
250954e2e49cSAlex Deucher /**
251054e2e49cSAlex Deucher  * cayman_vm_decode_fault - print human readable fault info
251154e2e49cSAlex Deucher  *
251254e2e49cSAlex Deucher  * @rdev: radeon_device pointer
251354e2e49cSAlex Deucher  * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
251454e2e49cSAlex Deucher  * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
251554e2e49cSAlex Deucher  *
251654e2e49cSAlex Deucher  * Print human readable fault information (cayman/TN).
251754e2e49cSAlex Deucher  */
cayman_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr)251854e2e49cSAlex Deucher void cayman_vm_decode_fault(struct radeon_device *rdev,
251954e2e49cSAlex Deucher 			    u32 status, u32 addr)
252054e2e49cSAlex Deucher {
252154e2e49cSAlex Deucher 	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
252254e2e49cSAlex Deucher 	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
252354e2e49cSAlex Deucher 	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
252454e2e49cSAlex Deucher 	char *block;
252554e2e49cSAlex Deucher 
252654e2e49cSAlex Deucher 	switch (mc_id) {
252754e2e49cSAlex Deucher 	case 32:
252854e2e49cSAlex Deucher 	case 16:
252954e2e49cSAlex Deucher 	case 96:
253054e2e49cSAlex Deucher 	case 80:
253154e2e49cSAlex Deucher 	case 160:
253254e2e49cSAlex Deucher 	case 144:
253354e2e49cSAlex Deucher 	case 224:
253454e2e49cSAlex Deucher 	case 208:
253554e2e49cSAlex Deucher 		block = "CB";
253654e2e49cSAlex Deucher 		break;
253754e2e49cSAlex Deucher 	case 33:
253854e2e49cSAlex Deucher 	case 17:
253954e2e49cSAlex Deucher 	case 97:
254054e2e49cSAlex Deucher 	case 81:
254154e2e49cSAlex Deucher 	case 161:
254254e2e49cSAlex Deucher 	case 145:
254354e2e49cSAlex Deucher 	case 225:
254454e2e49cSAlex Deucher 	case 209:
254554e2e49cSAlex Deucher 		block = "CB_FMASK";
254654e2e49cSAlex Deucher 		break;
254754e2e49cSAlex Deucher 	case 34:
254854e2e49cSAlex Deucher 	case 18:
254954e2e49cSAlex Deucher 	case 98:
255054e2e49cSAlex Deucher 	case 82:
255154e2e49cSAlex Deucher 	case 162:
255254e2e49cSAlex Deucher 	case 146:
255354e2e49cSAlex Deucher 	case 226:
255454e2e49cSAlex Deucher 	case 210:
255554e2e49cSAlex Deucher 		block = "CB_CMASK";
255654e2e49cSAlex Deucher 		break;
255754e2e49cSAlex Deucher 	case 35:
255854e2e49cSAlex Deucher 	case 19:
255954e2e49cSAlex Deucher 	case 99:
256054e2e49cSAlex Deucher 	case 83:
256154e2e49cSAlex Deucher 	case 163:
256254e2e49cSAlex Deucher 	case 147:
256354e2e49cSAlex Deucher 	case 227:
256454e2e49cSAlex Deucher 	case 211:
256554e2e49cSAlex Deucher 		block = "CB_IMMED";
256654e2e49cSAlex Deucher 		break;
256754e2e49cSAlex Deucher 	case 36:
256854e2e49cSAlex Deucher 	case 20:
256954e2e49cSAlex Deucher 	case 100:
257054e2e49cSAlex Deucher 	case 84:
257154e2e49cSAlex Deucher 	case 164:
257254e2e49cSAlex Deucher 	case 148:
257354e2e49cSAlex Deucher 	case 228:
257454e2e49cSAlex Deucher 	case 212:
257554e2e49cSAlex Deucher 		block = "DB";
257654e2e49cSAlex Deucher 		break;
257754e2e49cSAlex Deucher 	case 37:
257854e2e49cSAlex Deucher 	case 21:
257954e2e49cSAlex Deucher 	case 101:
258054e2e49cSAlex Deucher 	case 85:
258154e2e49cSAlex Deucher 	case 165:
258254e2e49cSAlex Deucher 	case 149:
258354e2e49cSAlex Deucher 	case 229:
258454e2e49cSAlex Deucher 	case 213:
258554e2e49cSAlex Deucher 		block = "DB_HTILE";
258654e2e49cSAlex Deucher 		break;
258754e2e49cSAlex Deucher 	case 38:
258854e2e49cSAlex Deucher 	case 22:
258954e2e49cSAlex Deucher 	case 102:
259054e2e49cSAlex Deucher 	case 86:
259154e2e49cSAlex Deucher 	case 166:
259254e2e49cSAlex Deucher 	case 150:
259354e2e49cSAlex Deucher 	case 230:
259454e2e49cSAlex Deucher 	case 214:
259554e2e49cSAlex Deucher 		block = "SX";
259654e2e49cSAlex Deucher 		break;
259754e2e49cSAlex Deucher 	case 39:
259854e2e49cSAlex Deucher 	case 23:
259954e2e49cSAlex Deucher 	case 103:
260054e2e49cSAlex Deucher 	case 87:
260154e2e49cSAlex Deucher 	case 167:
260254e2e49cSAlex Deucher 	case 151:
260354e2e49cSAlex Deucher 	case 231:
260454e2e49cSAlex Deucher 	case 215:
260554e2e49cSAlex Deucher 		block = "DB_STEN";
260654e2e49cSAlex Deucher 		break;
260754e2e49cSAlex Deucher 	case 40:
260854e2e49cSAlex Deucher 	case 24:
260954e2e49cSAlex Deucher 	case 104:
261054e2e49cSAlex Deucher 	case 88:
261154e2e49cSAlex Deucher 	case 232:
261254e2e49cSAlex Deucher 	case 216:
261354e2e49cSAlex Deucher 	case 168:
261454e2e49cSAlex Deucher 	case 152:
261554e2e49cSAlex Deucher 		block = "TC_TFETCH";
261654e2e49cSAlex Deucher 		break;
261754e2e49cSAlex Deucher 	case 41:
261854e2e49cSAlex Deucher 	case 25:
261954e2e49cSAlex Deucher 	case 105:
262054e2e49cSAlex Deucher 	case 89:
262154e2e49cSAlex Deucher 	case 233:
262254e2e49cSAlex Deucher 	case 217:
262354e2e49cSAlex Deucher 	case 169:
262454e2e49cSAlex Deucher 	case 153:
262554e2e49cSAlex Deucher 		block = "TC_VFETCH";
262654e2e49cSAlex Deucher 		break;
262754e2e49cSAlex Deucher 	case 42:
262854e2e49cSAlex Deucher 	case 26:
262954e2e49cSAlex Deucher 	case 106:
263054e2e49cSAlex Deucher 	case 90:
263154e2e49cSAlex Deucher 	case 234:
263254e2e49cSAlex Deucher 	case 218:
263354e2e49cSAlex Deucher 	case 170:
263454e2e49cSAlex Deucher 	case 154:
263554e2e49cSAlex Deucher 		block = "VC";
263654e2e49cSAlex Deucher 		break;
263754e2e49cSAlex Deucher 	case 112:
263854e2e49cSAlex Deucher 		block = "CP";
263954e2e49cSAlex Deucher 		break;
264054e2e49cSAlex Deucher 	case 113:
264154e2e49cSAlex Deucher 	case 114:
264254e2e49cSAlex Deucher 		block = "SH";
264354e2e49cSAlex Deucher 		break;
264454e2e49cSAlex Deucher 	case 115:
264554e2e49cSAlex Deucher 		block = "VGT";
264654e2e49cSAlex Deucher 		break;
264754e2e49cSAlex Deucher 	case 178:
264854e2e49cSAlex Deucher 		block = "IH";
264954e2e49cSAlex Deucher 		break;
265054e2e49cSAlex Deucher 	case 51:
265154e2e49cSAlex Deucher 		block = "RLC";
265254e2e49cSAlex Deucher 		break;
265354e2e49cSAlex Deucher 	case 55:
265454e2e49cSAlex Deucher 		block = "DMA";
265554e2e49cSAlex Deucher 		break;
265654e2e49cSAlex Deucher 	case 56:
265754e2e49cSAlex Deucher 		block = "HDP";
265854e2e49cSAlex Deucher 		break;
265954e2e49cSAlex Deucher 	default:
266054e2e49cSAlex Deucher 		block = "unknown";
266154e2e49cSAlex Deucher 		break;
266254e2e49cSAlex Deucher 	}
266354e2e49cSAlex Deucher 
266454e2e49cSAlex Deucher 	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
266554e2e49cSAlex Deucher 	       protections, vmid, addr,
266654e2e49cSAlex Deucher 	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
266754e2e49cSAlex Deucher 	       block, mc_id);
266854e2e49cSAlex Deucher }
266954e2e49cSAlex Deucher 
267019278157SLee Jones /*
26717a083293SAlex Deucher  * cayman_vm_flush - vm flush using the CP
26727a083293SAlex Deucher  *
26737a083293SAlex Deucher  * Update the page table base and flush the VM TLB
26747a083293SAlex Deucher  * using the CP (cayman-si).
26757a083293SAlex Deucher  */
cayman_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)2676faffaf62SChristian König void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
2677faffaf62SChristian König 		     unsigned vm_id, uint64_t pd_addr)
26789b40e5d8SChristian König {
2679faffaf62SChristian König 	radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2), 0));
2680faffaf62SChristian König 	radeon_ring_write(ring, pd_addr >> 12);
2681ee60e29fSChristian König 
26829b40e5d8SChristian König 	/* flush hdp cache */
26839b40e5d8SChristian König 	radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
26849b40e5d8SChristian König 	radeon_ring_write(ring, 0x1);
26859b40e5d8SChristian König 
26869b40e5d8SChristian König 	/* bits 0-7 are the VM contexts0-7 */
26879b40e5d8SChristian König 	radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
2688faffaf62SChristian König 	radeon_ring_write(ring, 1 << vm_id);
268958f8cf56SChristian König 
2690cbfc35b9SAlex Deucher 	/* wait for the invalidate to complete */
2691cbfc35b9SAlex Deucher 	radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
2692cbfc35b9SAlex Deucher 	radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) |  /* always */
2693cbfc35b9SAlex Deucher 				 WAIT_REG_MEM_ENGINE(0))); /* me */
2694cbfc35b9SAlex Deucher 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
2695cbfc35b9SAlex Deucher 	radeon_ring_write(ring, 0);
2696cbfc35b9SAlex Deucher 	radeon_ring_write(ring, 0); /* ref */
2697cbfc35b9SAlex Deucher 	radeon_ring_write(ring, 0); /* mask */
2698cbfc35b9SAlex Deucher 	radeon_ring_write(ring, 0x20); /* poll interval */
2699cbfc35b9SAlex Deucher 
270058f8cf56SChristian König 	/* sync PFP to ME, otherwise we might get invalid PFP reads */
270158f8cf56SChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
270258f8cf56SChristian König 	radeon_ring_write(ring, 0x0);
2703721604a1SJerome Glisse }
27040fda42acSAlex Deucher 
tn_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)27050fda42acSAlex Deucher int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
27060fda42acSAlex Deucher {
27070fda42acSAlex Deucher 	struct atom_clock_dividers dividers;
27080fda42acSAlex Deucher 	int r, i;
27090fda42acSAlex Deucher 
27100fda42acSAlex Deucher 	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
27110fda42acSAlex Deucher 					   ecclk, false, &dividers);
27120fda42acSAlex Deucher 	if (r)
27130fda42acSAlex Deucher 		return r;
27140fda42acSAlex Deucher 
27150fda42acSAlex Deucher 	for (i = 0; i < 100; i++) {
27160fda42acSAlex Deucher 		if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
27170fda42acSAlex Deucher 			break;
27180fda42acSAlex Deucher 		mdelay(10);
27190fda42acSAlex Deucher 	}
27200fda42acSAlex Deucher 	if (i == 100)
27210fda42acSAlex Deucher 		return -ETIMEDOUT;
27220fda42acSAlex Deucher 
27230fda42acSAlex Deucher 	WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK));
27240fda42acSAlex Deucher 
27250fda42acSAlex Deucher 	for (i = 0; i < 100; i++) {
27260fda42acSAlex Deucher 		if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
27270fda42acSAlex Deucher 			break;
27280fda42acSAlex Deucher 		mdelay(10);
27290fda42acSAlex Deucher 	}
27300fda42acSAlex Deucher 	if (i == 100)
27310fda42acSAlex Deucher 		return -ETIMEDOUT;
27320fda42acSAlex Deucher 
27330fda42acSAlex Deucher 	return 0;
27340fda42acSAlex Deucher }
2735