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, ÷rs);
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