xref: /openbsd/sys/dev/pci/drm/radeon/ni.c (revision d9c286e0)
11099013bSjsg /*
21099013bSjsg  * Copyright 2010 Advanced Micro Devices, Inc.
31099013bSjsg  *
41099013bSjsg  * Permission is hereby granted, free of charge, to any person obtaining a
51099013bSjsg  * copy of this software and associated documentation files (the "Software"),
61099013bSjsg  * to deal in the Software without restriction, including without limitation
71099013bSjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81099013bSjsg  * and/or sell copies of the Software, and to permit persons to whom the
91099013bSjsg  * Software is furnished to do so, subject to the following conditions:
101099013bSjsg  *
111099013bSjsg  * The above copyright notice and this permission notice shall be included in
121099013bSjsg  * all copies or substantial portions of the Software.
131099013bSjsg  *
141099013bSjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151099013bSjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161099013bSjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
171099013bSjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
181099013bSjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
191099013bSjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
201099013bSjsg  * OTHER DEALINGS IN THE SOFTWARE.
211099013bSjsg  *
221099013bSjsg  * Authors: Alex Deucher
231099013bSjsg  */
24c349dbc7Sjsg 
257f4dd379Sjsg #include <linux/firmware.h>
267f4dd379Sjsg #include <linux/module.h>
27c349dbc7Sjsg #include <linux/pci.h>
28c349dbc7Sjsg #include <linux/slab.h>
29c349dbc7Sjsg 
30c349dbc7Sjsg #include <drm/radeon_drm.h>
31c349dbc7Sjsg 
32c349dbc7Sjsg #include "atom.h"
33c349dbc7Sjsg #include "cayman_blit_shaders.h"
34c349dbc7Sjsg #include "clearstate_cayman.h"
355ca02815Sjsg #include "evergreen.h"
365ca02815Sjsg #include "ni.h"
37c349dbc7Sjsg #include "ni_reg.h"
38c349dbc7Sjsg #include "nid.h"
391099013bSjsg #include "radeon.h"
401099013bSjsg #include "radeon_asic.h"
417ccd5a2cSjsg #include "radeon_audio.h"
427ccd5a2cSjsg #include "radeon_ucode.h"
431099013bSjsg 
447ccd5a2cSjsg /*
457ccd5a2cSjsg  * Indirect registers accessor
467ccd5a2cSjsg  */
tn_smc_rreg(struct radeon_device * rdev,u32 reg)477ccd5a2cSjsg u32 tn_smc_rreg(struct radeon_device *rdev, u32 reg)
487ccd5a2cSjsg {
497ccd5a2cSjsg 	unsigned long flags;
507ccd5a2cSjsg 	u32 r;
517ccd5a2cSjsg 
527ccd5a2cSjsg 	spin_lock_irqsave(&rdev->smc_idx_lock, flags);
537ccd5a2cSjsg 	WREG32(TN_SMC_IND_INDEX_0, (reg));
547ccd5a2cSjsg 	r = RREG32(TN_SMC_IND_DATA_0);
557ccd5a2cSjsg 	spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
567ccd5a2cSjsg 	return r;
577ccd5a2cSjsg }
587ccd5a2cSjsg 
tn_smc_wreg(struct radeon_device * rdev,u32 reg,u32 v)597ccd5a2cSjsg void tn_smc_wreg(struct radeon_device *rdev, u32 reg, u32 v)
607ccd5a2cSjsg {
617ccd5a2cSjsg 	unsigned long flags;
627ccd5a2cSjsg 
637ccd5a2cSjsg 	spin_lock_irqsave(&rdev->smc_idx_lock, flags);
647ccd5a2cSjsg 	WREG32(TN_SMC_IND_INDEX_0, (reg));
657ccd5a2cSjsg 	WREG32(TN_SMC_IND_DATA_0, (v));
667ccd5a2cSjsg 	spin_unlock_irqrestore(&rdev->smc_idx_lock, flags);
677ccd5a2cSjsg }
687ccd5a2cSjsg 
697ccd5a2cSjsg static const u32 tn_rlc_save_restore_register_list[] =
707ccd5a2cSjsg {
717ccd5a2cSjsg 	0x98fc,
727ccd5a2cSjsg 	0x98f0,
737ccd5a2cSjsg 	0x9834,
747ccd5a2cSjsg 	0x9838,
757ccd5a2cSjsg 	0x9870,
767ccd5a2cSjsg 	0x9874,
777ccd5a2cSjsg 	0x8a14,
787ccd5a2cSjsg 	0x8b24,
797ccd5a2cSjsg 	0x8bcc,
807ccd5a2cSjsg 	0x8b10,
817ccd5a2cSjsg 	0x8c30,
827ccd5a2cSjsg 	0x8d00,
837ccd5a2cSjsg 	0x8d04,
847ccd5a2cSjsg 	0x8c00,
857ccd5a2cSjsg 	0x8c04,
867ccd5a2cSjsg 	0x8c10,
877ccd5a2cSjsg 	0x8c14,
887ccd5a2cSjsg 	0x8d8c,
897ccd5a2cSjsg 	0x8cf0,
907ccd5a2cSjsg 	0x8e38,
917ccd5a2cSjsg 	0x9508,
927ccd5a2cSjsg 	0x9688,
937ccd5a2cSjsg 	0x9608,
947ccd5a2cSjsg 	0x960c,
957ccd5a2cSjsg 	0x9610,
967ccd5a2cSjsg 	0x9614,
977ccd5a2cSjsg 	0x88c4,
987ccd5a2cSjsg 	0x8978,
997ccd5a2cSjsg 	0x88d4,
1007ccd5a2cSjsg 	0x900c,
1017ccd5a2cSjsg 	0x9100,
1027ccd5a2cSjsg 	0x913c,
1037ccd5a2cSjsg 	0x90e8,
1047ccd5a2cSjsg 	0x9354,
1057ccd5a2cSjsg 	0xa008,
1067ccd5a2cSjsg 	0x98f8,
1077ccd5a2cSjsg 	0x9148,
1087ccd5a2cSjsg 	0x914c,
1097ccd5a2cSjsg 	0x3f94,
1107ccd5a2cSjsg 	0x98f4,
1117ccd5a2cSjsg 	0x9b7c,
1127ccd5a2cSjsg 	0x3f8c,
1137ccd5a2cSjsg 	0x8950,
1147ccd5a2cSjsg 	0x8954,
1157ccd5a2cSjsg 	0x8a18,
1167ccd5a2cSjsg 	0x8b28,
1177ccd5a2cSjsg 	0x9144,
1187ccd5a2cSjsg 	0x3f90,
1197ccd5a2cSjsg 	0x915c,
1207ccd5a2cSjsg 	0x9160,
1217ccd5a2cSjsg 	0x9178,
1227ccd5a2cSjsg 	0x917c,
1237ccd5a2cSjsg 	0x9180,
1247ccd5a2cSjsg 	0x918c,
1257ccd5a2cSjsg 	0x9190,
1267ccd5a2cSjsg 	0x9194,
1277ccd5a2cSjsg 	0x9198,
1287ccd5a2cSjsg 	0x919c,
1297ccd5a2cSjsg 	0x91a8,
1307ccd5a2cSjsg 	0x91ac,
1317ccd5a2cSjsg 	0x91b0,
1327ccd5a2cSjsg 	0x91b4,
1337ccd5a2cSjsg 	0x91b8,
1347ccd5a2cSjsg 	0x91c4,
1357ccd5a2cSjsg 	0x91c8,
1367ccd5a2cSjsg 	0x91cc,
1377ccd5a2cSjsg 	0x91d0,
1387ccd5a2cSjsg 	0x91d4,
1397ccd5a2cSjsg 	0x91e0,
1407ccd5a2cSjsg 	0x91e4,
1417ccd5a2cSjsg 	0x91ec,
1427ccd5a2cSjsg 	0x91f0,
1437ccd5a2cSjsg 	0x91f4,
1447ccd5a2cSjsg 	0x9200,
1457ccd5a2cSjsg 	0x9204,
1467ccd5a2cSjsg 	0x929c,
1477ccd5a2cSjsg 	0x8030,
1487ccd5a2cSjsg 	0x9150,
1497ccd5a2cSjsg 	0x9a60,
1507ccd5a2cSjsg 	0x920c,
1517ccd5a2cSjsg 	0x9210,
1527ccd5a2cSjsg 	0x9228,
1537ccd5a2cSjsg 	0x922c,
1547ccd5a2cSjsg 	0x9244,
1557ccd5a2cSjsg 	0x9248,
1567ccd5a2cSjsg 	0x91e8,
1577ccd5a2cSjsg 	0x9294,
1587ccd5a2cSjsg 	0x9208,
1597ccd5a2cSjsg 	0x9224,
1607ccd5a2cSjsg 	0x9240,
1617ccd5a2cSjsg 	0x9220,
1627ccd5a2cSjsg 	0x923c,
1637ccd5a2cSjsg 	0x9258,
1647ccd5a2cSjsg 	0x9744,
1657ccd5a2cSjsg 	0xa200,
1667ccd5a2cSjsg 	0xa204,
1677ccd5a2cSjsg 	0xa208,
1687ccd5a2cSjsg 	0xa20c,
1697ccd5a2cSjsg 	0x8d58,
1707ccd5a2cSjsg 	0x9030,
1717ccd5a2cSjsg 	0x9034,
1727ccd5a2cSjsg 	0x9038,
1737ccd5a2cSjsg 	0x903c,
1747ccd5a2cSjsg 	0x9040,
1757ccd5a2cSjsg 	0x9654,
1767ccd5a2cSjsg 	0x897c,
1777ccd5a2cSjsg 	0xa210,
1787ccd5a2cSjsg 	0xa214,
1797ccd5a2cSjsg 	0x9868,
1807ccd5a2cSjsg 	0xa02c,
1817ccd5a2cSjsg 	0x9664,
1827ccd5a2cSjsg 	0x9698,
1837ccd5a2cSjsg 	0x949c,
1847ccd5a2cSjsg 	0x8e10,
1857ccd5a2cSjsg 	0x8e18,
1867ccd5a2cSjsg 	0x8c50,
1877ccd5a2cSjsg 	0x8c58,
1887ccd5a2cSjsg 	0x8c60,
1897ccd5a2cSjsg 	0x8c68,
1907ccd5a2cSjsg 	0x89b4,
1917ccd5a2cSjsg 	0x9830,
1927ccd5a2cSjsg 	0x802c,
1937ccd5a2cSjsg };
1947ccd5a2cSjsg 
1951099013bSjsg /* Firmware Names */
1961099013bSjsg MODULE_FIRMWARE("radeon/BARTS_pfp.bin");
1971099013bSjsg MODULE_FIRMWARE("radeon/BARTS_me.bin");
1981099013bSjsg MODULE_FIRMWARE("radeon/BARTS_mc.bin");
1997ccd5a2cSjsg MODULE_FIRMWARE("radeon/BARTS_smc.bin");
2001099013bSjsg MODULE_FIRMWARE("radeon/BTC_rlc.bin");
2011099013bSjsg MODULE_FIRMWARE("radeon/TURKS_pfp.bin");
2021099013bSjsg MODULE_FIRMWARE("radeon/TURKS_me.bin");
2031099013bSjsg MODULE_FIRMWARE("radeon/TURKS_mc.bin");
2047ccd5a2cSjsg MODULE_FIRMWARE("radeon/TURKS_smc.bin");
2051099013bSjsg MODULE_FIRMWARE("radeon/CAICOS_pfp.bin");
2061099013bSjsg MODULE_FIRMWARE("radeon/CAICOS_me.bin");
2071099013bSjsg MODULE_FIRMWARE("radeon/CAICOS_mc.bin");
2087ccd5a2cSjsg MODULE_FIRMWARE("radeon/CAICOS_smc.bin");
2091099013bSjsg MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
2101099013bSjsg MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
2111099013bSjsg MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
2121099013bSjsg MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
2137ccd5a2cSjsg MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
2141099013bSjsg MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
2151099013bSjsg MODULE_FIRMWARE("radeon/ARUBA_me.bin");
2161099013bSjsg MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
2171099013bSjsg 
2187ccd5a2cSjsg 
2197ccd5a2cSjsg static const u32 cayman_golden_registers2[] =
2207ccd5a2cSjsg {
2217ccd5a2cSjsg 	0x3e5c, 0xffffffff, 0x00000000,
2227ccd5a2cSjsg 	0x3e48, 0xffffffff, 0x00000000,
2237ccd5a2cSjsg 	0x3e4c, 0xffffffff, 0x00000000,
2247ccd5a2cSjsg 	0x3e64, 0xffffffff, 0x00000000,
2257ccd5a2cSjsg 	0x3e50, 0xffffffff, 0x00000000,
2267ccd5a2cSjsg 	0x3e60, 0xffffffff, 0x00000000
2277ccd5a2cSjsg };
2287ccd5a2cSjsg 
2297ccd5a2cSjsg static const u32 cayman_golden_registers[] =
2307ccd5a2cSjsg {
2317ccd5a2cSjsg 	0x5eb4, 0xffffffff, 0x00000002,
2327ccd5a2cSjsg 	0x5e78, 0x8f311ff1, 0x001000f0,
2337ccd5a2cSjsg 	0x3f90, 0xffff0000, 0xff000000,
2347ccd5a2cSjsg 	0x9148, 0xffff0000, 0xff000000,
2357ccd5a2cSjsg 	0x3f94, 0xffff0000, 0xff000000,
2367ccd5a2cSjsg 	0x914c, 0xffff0000, 0xff000000,
2377ccd5a2cSjsg 	0xc78, 0x00000080, 0x00000080,
2387ccd5a2cSjsg 	0xbd4, 0x70073777, 0x00011003,
2397ccd5a2cSjsg 	0xd02c, 0xbfffff1f, 0x08421000,
2407ccd5a2cSjsg 	0xd0b8, 0x73773777, 0x02011003,
2417ccd5a2cSjsg 	0x5bc0, 0x00200000, 0x50100000,
2427ccd5a2cSjsg 	0x98f8, 0x33773777, 0x02011003,
2437ccd5a2cSjsg 	0x98fc, 0xffffffff, 0x76541032,
2447ccd5a2cSjsg 	0x7030, 0x31000311, 0x00000011,
2457ccd5a2cSjsg 	0x2f48, 0x33773777, 0x42010001,
2467ccd5a2cSjsg 	0x6b28, 0x00000010, 0x00000012,
2477ccd5a2cSjsg 	0x7728, 0x00000010, 0x00000012,
2487ccd5a2cSjsg 	0x10328, 0x00000010, 0x00000012,
2497ccd5a2cSjsg 	0x10f28, 0x00000010, 0x00000012,
2507ccd5a2cSjsg 	0x11b28, 0x00000010, 0x00000012,
2517ccd5a2cSjsg 	0x12728, 0x00000010, 0x00000012,
2527ccd5a2cSjsg 	0x240c, 0x000007ff, 0x00000000,
2537ccd5a2cSjsg 	0x8a14, 0xf000001f, 0x00000007,
2547ccd5a2cSjsg 	0x8b24, 0x3fff3fff, 0x00ff0fff,
2557ccd5a2cSjsg 	0x8b10, 0x0000ff0f, 0x00000000,
2567ccd5a2cSjsg 	0x28a4c, 0x07ffffff, 0x06000000,
2577ccd5a2cSjsg 	0x10c, 0x00000001, 0x00010003,
2587ccd5a2cSjsg 	0xa02c, 0xffffffff, 0x0000009b,
2597ccd5a2cSjsg 	0x913c, 0x0000010f, 0x01000100,
2607ccd5a2cSjsg 	0x8c04, 0xf8ff00ff, 0x40600060,
2617ccd5a2cSjsg 	0x28350, 0x00000f01, 0x00000000,
2627ccd5a2cSjsg 	0x9508, 0x3700001f, 0x00000002,
2637ccd5a2cSjsg 	0x960c, 0xffffffff, 0x54763210,
2647ccd5a2cSjsg 	0x88c4, 0x001f3ae3, 0x00000082,
2657ccd5a2cSjsg 	0x88d0, 0xffffffff, 0x0f40df40,
2667ccd5a2cSjsg 	0x88d4, 0x0000001f, 0x00000010,
2677ccd5a2cSjsg 	0x8974, 0xffffffff, 0x00000000
2687ccd5a2cSjsg };
2697ccd5a2cSjsg 
2707ccd5a2cSjsg static const u32 dvst_golden_registers2[] =
2717ccd5a2cSjsg {
2727ccd5a2cSjsg 	0x8f8, 0xffffffff, 0,
2737ccd5a2cSjsg 	0x8fc, 0x00380000, 0,
2747ccd5a2cSjsg 	0x8f8, 0xffffffff, 1,
2757ccd5a2cSjsg 	0x8fc, 0x0e000000, 0
2767ccd5a2cSjsg };
2777ccd5a2cSjsg 
2787ccd5a2cSjsg static const u32 dvst_golden_registers[] =
2797ccd5a2cSjsg {
2807ccd5a2cSjsg 	0x690, 0x3fff3fff, 0x20c00033,
2817ccd5a2cSjsg 	0x918c, 0x0fff0fff, 0x00010006,
2827ccd5a2cSjsg 	0x91a8, 0x0fff0fff, 0x00010006,
2837ccd5a2cSjsg 	0x9150, 0xffffdfff, 0x6e944040,
2847ccd5a2cSjsg 	0x917c, 0x0fff0fff, 0x00030002,
2857ccd5a2cSjsg 	0x9198, 0x0fff0fff, 0x00030002,
2867ccd5a2cSjsg 	0x915c, 0x0fff0fff, 0x00010000,
2877ccd5a2cSjsg 	0x3f90, 0xffff0001, 0xff000000,
2887ccd5a2cSjsg 	0x9178, 0x0fff0fff, 0x00070000,
2897ccd5a2cSjsg 	0x9194, 0x0fff0fff, 0x00070000,
2907ccd5a2cSjsg 	0x9148, 0xffff0001, 0xff000000,
2917ccd5a2cSjsg 	0x9190, 0x0fff0fff, 0x00090008,
2927ccd5a2cSjsg 	0x91ac, 0x0fff0fff, 0x00090008,
2937ccd5a2cSjsg 	0x3f94, 0xffff0000, 0xff000000,
2947ccd5a2cSjsg 	0x914c, 0xffff0000, 0xff000000,
2957ccd5a2cSjsg 	0x929c, 0x00000fff, 0x00000001,
2967ccd5a2cSjsg 	0x55e4, 0xff607fff, 0xfc000100,
2977ccd5a2cSjsg 	0x8a18, 0xff000fff, 0x00000100,
2987ccd5a2cSjsg 	0x8b28, 0xff000fff, 0x00000100,
2997ccd5a2cSjsg 	0x9144, 0xfffc0fff, 0x00000100,
3007ccd5a2cSjsg 	0x6ed8, 0x00010101, 0x00010000,
3017ccd5a2cSjsg 	0x9830, 0xffffffff, 0x00000000,
3027ccd5a2cSjsg 	0x9834, 0xf00fffff, 0x00000400,
3037ccd5a2cSjsg 	0x9838, 0xfffffffe, 0x00000000,
3047ccd5a2cSjsg 	0xd0c0, 0xff000fff, 0x00000100,
3057ccd5a2cSjsg 	0xd02c, 0xbfffff1f, 0x08421000,
3067ccd5a2cSjsg 	0xd0b8, 0x73773777, 0x12010001,
3077ccd5a2cSjsg 	0x5bb0, 0x000000f0, 0x00000070,
3087ccd5a2cSjsg 	0x98f8, 0x73773777, 0x12010001,
3097ccd5a2cSjsg 	0x98fc, 0xffffffff, 0x00000010,
3107ccd5a2cSjsg 	0x9b7c, 0x00ff0000, 0x00fc0000,
3117ccd5a2cSjsg 	0x8030, 0x00001f0f, 0x0000100a,
3127ccd5a2cSjsg 	0x2f48, 0x73773777, 0x12010001,
3137ccd5a2cSjsg 	0x2408, 0x00030000, 0x000c007f,
3147ccd5a2cSjsg 	0x8a14, 0xf000003f, 0x00000007,
3157ccd5a2cSjsg 	0x8b24, 0x3fff3fff, 0x00ff0fff,
3167ccd5a2cSjsg 	0x8b10, 0x0000ff0f, 0x00000000,
3177ccd5a2cSjsg 	0x28a4c, 0x07ffffff, 0x06000000,
3187ccd5a2cSjsg 	0x4d8, 0x00000fff, 0x00000100,
3197ccd5a2cSjsg 	0xa008, 0xffffffff, 0x00010000,
3207ccd5a2cSjsg 	0x913c, 0xffff03ff, 0x01000100,
3217ccd5a2cSjsg 	0x8c00, 0x000000ff, 0x00000003,
3227ccd5a2cSjsg 	0x8c04, 0xf8ff00ff, 0x40600060,
3237ccd5a2cSjsg 	0x8cf0, 0x1fff1fff, 0x08e00410,
3247ccd5a2cSjsg 	0x28350, 0x00000f01, 0x00000000,
3257ccd5a2cSjsg 	0x9508, 0xf700071f, 0x00000002,
3267ccd5a2cSjsg 	0x960c, 0xffffffff, 0x54763210,
3277ccd5a2cSjsg 	0x20ef8, 0x01ff01ff, 0x00000002,
3287ccd5a2cSjsg 	0x20e98, 0xfffffbff, 0x00200000,
3297ccd5a2cSjsg 	0x2015c, 0xffffffff, 0x00000f40,
3307ccd5a2cSjsg 	0x88c4, 0x001f3ae3, 0x00000082,
3317ccd5a2cSjsg 	0x8978, 0x3fffffff, 0x04050140,
3327ccd5a2cSjsg 	0x88d4, 0x0000001f, 0x00000010,
3337ccd5a2cSjsg 	0x8974, 0xffffffff, 0x00000000
3347ccd5a2cSjsg };
3357ccd5a2cSjsg 
3367ccd5a2cSjsg static const u32 scrapper_golden_registers[] =
3377ccd5a2cSjsg {
3387ccd5a2cSjsg 	0x690, 0x3fff3fff, 0x20c00033,
3397ccd5a2cSjsg 	0x918c, 0x0fff0fff, 0x00010006,
3407ccd5a2cSjsg 	0x918c, 0x0fff0fff, 0x00010006,
3417ccd5a2cSjsg 	0x91a8, 0x0fff0fff, 0x00010006,
3427ccd5a2cSjsg 	0x91a8, 0x0fff0fff, 0x00010006,
3437ccd5a2cSjsg 	0x9150, 0xffffdfff, 0x6e944040,
3447ccd5a2cSjsg 	0x9150, 0xffffdfff, 0x6e944040,
3457ccd5a2cSjsg 	0x917c, 0x0fff0fff, 0x00030002,
3467ccd5a2cSjsg 	0x917c, 0x0fff0fff, 0x00030002,
3477ccd5a2cSjsg 	0x9198, 0x0fff0fff, 0x00030002,
3487ccd5a2cSjsg 	0x9198, 0x0fff0fff, 0x00030002,
3497ccd5a2cSjsg 	0x915c, 0x0fff0fff, 0x00010000,
3507ccd5a2cSjsg 	0x915c, 0x0fff0fff, 0x00010000,
3517ccd5a2cSjsg 	0x3f90, 0xffff0001, 0xff000000,
3527ccd5a2cSjsg 	0x3f90, 0xffff0001, 0xff000000,
3537ccd5a2cSjsg 	0x9178, 0x0fff0fff, 0x00070000,
3547ccd5a2cSjsg 	0x9178, 0x0fff0fff, 0x00070000,
3557ccd5a2cSjsg 	0x9194, 0x0fff0fff, 0x00070000,
3567ccd5a2cSjsg 	0x9194, 0x0fff0fff, 0x00070000,
3577ccd5a2cSjsg 	0x9148, 0xffff0001, 0xff000000,
3587ccd5a2cSjsg 	0x9148, 0xffff0001, 0xff000000,
3597ccd5a2cSjsg 	0x9190, 0x0fff0fff, 0x00090008,
3607ccd5a2cSjsg 	0x9190, 0x0fff0fff, 0x00090008,
3617ccd5a2cSjsg 	0x91ac, 0x0fff0fff, 0x00090008,
3627ccd5a2cSjsg 	0x91ac, 0x0fff0fff, 0x00090008,
3637ccd5a2cSjsg 	0x3f94, 0xffff0000, 0xff000000,
3647ccd5a2cSjsg 	0x3f94, 0xffff0000, 0xff000000,
3657ccd5a2cSjsg 	0x914c, 0xffff0000, 0xff000000,
3667ccd5a2cSjsg 	0x914c, 0xffff0000, 0xff000000,
3677ccd5a2cSjsg 	0x929c, 0x00000fff, 0x00000001,
3687ccd5a2cSjsg 	0x929c, 0x00000fff, 0x00000001,
3697ccd5a2cSjsg 	0x55e4, 0xff607fff, 0xfc000100,
3707ccd5a2cSjsg 	0x8a18, 0xff000fff, 0x00000100,
3717ccd5a2cSjsg 	0x8a18, 0xff000fff, 0x00000100,
3727ccd5a2cSjsg 	0x8b28, 0xff000fff, 0x00000100,
3737ccd5a2cSjsg 	0x8b28, 0xff000fff, 0x00000100,
3747ccd5a2cSjsg 	0x9144, 0xfffc0fff, 0x00000100,
3757ccd5a2cSjsg 	0x9144, 0xfffc0fff, 0x00000100,
3767ccd5a2cSjsg 	0x6ed8, 0x00010101, 0x00010000,
3777ccd5a2cSjsg 	0x9830, 0xffffffff, 0x00000000,
3787ccd5a2cSjsg 	0x9830, 0xffffffff, 0x00000000,
3797ccd5a2cSjsg 	0x9834, 0xf00fffff, 0x00000400,
3807ccd5a2cSjsg 	0x9834, 0xf00fffff, 0x00000400,
3817ccd5a2cSjsg 	0x9838, 0xfffffffe, 0x00000000,
3827ccd5a2cSjsg 	0x9838, 0xfffffffe, 0x00000000,
3837ccd5a2cSjsg 	0xd0c0, 0xff000fff, 0x00000100,
3847ccd5a2cSjsg 	0xd02c, 0xbfffff1f, 0x08421000,
3857ccd5a2cSjsg 	0xd02c, 0xbfffff1f, 0x08421000,
3867ccd5a2cSjsg 	0xd0b8, 0x73773777, 0x12010001,
3877ccd5a2cSjsg 	0xd0b8, 0x73773777, 0x12010001,
3887ccd5a2cSjsg 	0x5bb0, 0x000000f0, 0x00000070,
3897ccd5a2cSjsg 	0x98f8, 0x73773777, 0x12010001,
3907ccd5a2cSjsg 	0x98f8, 0x73773777, 0x12010001,
3917ccd5a2cSjsg 	0x98fc, 0xffffffff, 0x00000010,
3927ccd5a2cSjsg 	0x98fc, 0xffffffff, 0x00000010,
3937ccd5a2cSjsg 	0x9b7c, 0x00ff0000, 0x00fc0000,
3947ccd5a2cSjsg 	0x9b7c, 0x00ff0000, 0x00fc0000,
3957ccd5a2cSjsg 	0x8030, 0x00001f0f, 0x0000100a,
3967ccd5a2cSjsg 	0x8030, 0x00001f0f, 0x0000100a,
3977ccd5a2cSjsg 	0x2f48, 0x73773777, 0x12010001,
3987ccd5a2cSjsg 	0x2f48, 0x73773777, 0x12010001,
3997ccd5a2cSjsg 	0x2408, 0x00030000, 0x000c007f,
4007ccd5a2cSjsg 	0x8a14, 0xf000003f, 0x00000007,
4017ccd5a2cSjsg 	0x8a14, 0xf000003f, 0x00000007,
4027ccd5a2cSjsg 	0x8b24, 0x3fff3fff, 0x00ff0fff,
4037ccd5a2cSjsg 	0x8b24, 0x3fff3fff, 0x00ff0fff,
4047ccd5a2cSjsg 	0x8b10, 0x0000ff0f, 0x00000000,
4057ccd5a2cSjsg 	0x8b10, 0x0000ff0f, 0x00000000,
4067ccd5a2cSjsg 	0x28a4c, 0x07ffffff, 0x06000000,
4077ccd5a2cSjsg 	0x28a4c, 0x07ffffff, 0x06000000,
4087ccd5a2cSjsg 	0x4d8, 0x00000fff, 0x00000100,
4097ccd5a2cSjsg 	0x4d8, 0x00000fff, 0x00000100,
4107ccd5a2cSjsg 	0xa008, 0xffffffff, 0x00010000,
4117ccd5a2cSjsg 	0xa008, 0xffffffff, 0x00010000,
4127ccd5a2cSjsg 	0x913c, 0xffff03ff, 0x01000100,
4137ccd5a2cSjsg 	0x913c, 0xffff03ff, 0x01000100,
4147ccd5a2cSjsg 	0x90e8, 0x001fffff, 0x010400c0,
4157ccd5a2cSjsg 	0x8c00, 0x000000ff, 0x00000003,
4167ccd5a2cSjsg 	0x8c00, 0x000000ff, 0x00000003,
4177ccd5a2cSjsg 	0x8c04, 0xf8ff00ff, 0x40600060,
4187ccd5a2cSjsg 	0x8c04, 0xf8ff00ff, 0x40600060,
4197ccd5a2cSjsg 	0x8c30, 0x0000000f, 0x00040005,
4207ccd5a2cSjsg 	0x8cf0, 0x1fff1fff, 0x08e00410,
4217ccd5a2cSjsg 	0x8cf0, 0x1fff1fff, 0x08e00410,
4227ccd5a2cSjsg 	0x900c, 0x00ffffff, 0x0017071f,
4237ccd5a2cSjsg 	0x28350, 0x00000f01, 0x00000000,
4247ccd5a2cSjsg 	0x28350, 0x00000f01, 0x00000000,
4257ccd5a2cSjsg 	0x9508, 0xf700071f, 0x00000002,
4267ccd5a2cSjsg 	0x9508, 0xf700071f, 0x00000002,
4277ccd5a2cSjsg 	0x9688, 0x00300000, 0x0017000f,
4287ccd5a2cSjsg 	0x960c, 0xffffffff, 0x54763210,
4297ccd5a2cSjsg 	0x960c, 0xffffffff, 0x54763210,
4307ccd5a2cSjsg 	0x20ef8, 0x01ff01ff, 0x00000002,
4317ccd5a2cSjsg 	0x20e98, 0xfffffbff, 0x00200000,
4327ccd5a2cSjsg 	0x2015c, 0xffffffff, 0x00000f40,
4337ccd5a2cSjsg 	0x88c4, 0x001f3ae3, 0x00000082,
4347ccd5a2cSjsg 	0x88c4, 0x001f3ae3, 0x00000082,
4357ccd5a2cSjsg 	0x8978, 0x3fffffff, 0x04050140,
4367ccd5a2cSjsg 	0x8978, 0x3fffffff, 0x04050140,
4377ccd5a2cSjsg 	0x88d4, 0x0000001f, 0x00000010,
4387ccd5a2cSjsg 	0x88d4, 0x0000001f, 0x00000010,
4397ccd5a2cSjsg 	0x8974, 0xffffffff, 0x00000000,
4407ccd5a2cSjsg 	0x8974, 0xffffffff, 0x00000000
4417ccd5a2cSjsg };
4427ccd5a2cSjsg 
ni_init_golden_registers(struct radeon_device * rdev)4437ccd5a2cSjsg static void ni_init_golden_registers(struct radeon_device *rdev)
4447ccd5a2cSjsg {
4457ccd5a2cSjsg 	switch (rdev->family) {
4467ccd5a2cSjsg 	case CHIP_CAYMAN:
4477ccd5a2cSjsg 		radeon_program_register_sequence(rdev,
4487ccd5a2cSjsg 						 cayman_golden_registers,
4497ccd5a2cSjsg 						 (const u32)ARRAY_SIZE(cayman_golden_registers));
4507ccd5a2cSjsg 		radeon_program_register_sequence(rdev,
4517ccd5a2cSjsg 						 cayman_golden_registers2,
4527ccd5a2cSjsg 						 (const u32)ARRAY_SIZE(cayman_golden_registers2));
4537ccd5a2cSjsg 		break;
4547ccd5a2cSjsg 	case CHIP_ARUBA:
4557ccd5a2cSjsg 		if ((rdev->pdev->device == 0x9900) ||
4567ccd5a2cSjsg 		    (rdev->pdev->device == 0x9901) ||
4577ccd5a2cSjsg 		    (rdev->pdev->device == 0x9903) ||
4587ccd5a2cSjsg 		    (rdev->pdev->device == 0x9904) ||
4597ccd5a2cSjsg 		    (rdev->pdev->device == 0x9905) ||
4607ccd5a2cSjsg 		    (rdev->pdev->device == 0x9906) ||
4617ccd5a2cSjsg 		    (rdev->pdev->device == 0x9907) ||
4627ccd5a2cSjsg 		    (rdev->pdev->device == 0x9908) ||
4637ccd5a2cSjsg 		    (rdev->pdev->device == 0x9909) ||
4647ccd5a2cSjsg 		    (rdev->pdev->device == 0x990A) ||
4657ccd5a2cSjsg 		    (rdev->pdev->device == 0x990B) ||
4667ccd5a2cSjsg 		    (rdev->pdev->device == 0x990C) ||
4677ccd5a2cSjsg 		    (rdev->pdev->device == 0x990D) ||
4687ccd5a2cSjsg 		    (rdev->pdev->device == 0x990E) ||
4697ccd5a2cSjsg 		    (rdev->pdev->device == 0x990F) ||
4707ccd5a2cSjsg 		    (rdev->pdev->device == 0x9910) ||
4717ccd5a2cSjsg 		    (rdev->pdev->device == 0x9913) ||
4727ccd5a2cSjsg 		    (rdev->pdev->device == 0x9917) ||
4737ccd5a2cSjsg 		    (rdev->pdev->device == 0x9918)) {
4747ccd5a2cSjsg 			radeon_program_register_sequence(rdev,
4757ccd5a2cSjsg 							 dvst_golden_registers,
4767ccd5a2cSjsg 							 (const u32)ARRAY_SIZE(dvst_golden_registers));
4777ccd5a2cSjsg 			radeon_program_register_sequence(rdev,
4787ccd5a2cSjsg 							 dvst_golden_registers2,
4797ccd5a2cSjsg 							 (const u32)ARRAY_SIZE(dvst_golden_registers2));
4807ccd5a2cSjsg 		} else {
4817ccd5a2cSjsg 			radeon_program_register_sequence(rdev,
4827ccd5a2cSjsg 							 scrapper_golden_registers,
4837ccd5a2cSjsg 							 (const u32)ARRAY_SIZE(scrapper_golden_registers));
4847ccd5a2cSjsg 			radeon_program_register_sequence(rdev,
4857ccd5a2cSjsg 							 dvst_golden_registers2,
4867ccd5a2cSjsg 							 (const u32)ARRAY_SIZE(dvst_golden_registers2));
4877ccd5a2cSjsg 		}
4887ccd5a2cSjsg 		break;
4897ccd5a2cSjsg 	default:
4907ccd5a2cSjsg 		break;
4917ccd5a2cSjsg 	}
4927ccd5a2cSjsg }
4937ccd5a2cSjsg 
4941099013bSjsg #define BTC_IO_MC_REGS_SIZE 29
4951099013bSjsg 
4961099013bSjsg static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
4971099013bSjsg 	{0x00000077, 0xff010100},
4981099013bSjsg 	{0x00000078, 0x00000000},
4991099013bSjsg 	{0x00000079, 0x00001434},
5001099013bSjsg 	{0x0000007a, 0xcc08ec08},
5011099013bSjsg 	{0x0000007b, 0x00040000},
5021099013bSjsg 	{0x0000007c, 0x000080c0},
5031099013bSjsg 	{0x0000007d, 0x09000000},
5041099013bSjsg 	{0x0000007e, 0x00210404},
5051099013bSjsg 	{0x00000081, 0x08a8e800},
5061099013bSjsg 	{0x00000082, 0x00030444},
5071099013bSjsg 	{0x00000083, 0x00000000},
5081099013bSjsg 	{0x00000085, 0x00000001},
5091099013bSjsg 	{0x00000086, 0x00000002},
5101099013bSjsg 	{0x00000087, 0x48490000},
5111099013bSjsg 	{0x00000088, 0x20244647},
5121099013bSjsg 	{0x00000089, 0x00000005},
5131099013bSjsg 	{0x0000008b, 0x66030000},
5141099013bSjsg 	{0x0000008c, 0x00006603},
5151099013bSjsg 	{0x0000008d, 0x00000100},
5161099013bSjsg 	{0x0000008f, 0x00001c0a},
5171099013bSjsg 	{0x00000090, 0xff000001},
5181099013bSjsg 	{0x00000094, 0x00101101},
5191099013bSjsg 	{0x00000095, 0x00000fff},
5201099013bSjsg 	{0x00000096, 0x00116fff},
5211099013bSjsg 	{0x00000097, 0x60010000},
5221099013bSjsg 	{0x00000098, 0x10010000},
5231099013bSjsg 	{0x00000099, 0x00006000},
5241099013bSjsg 	{0x0000009a, 0x00001000},
5251099013bSjsg 	{0x0000009f, 0x00946a00}
5261099013bSjsg };
5271099013bSjsg 
5281099013bSjsg static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
5291099013bSjsg 	{0x00000077, 0xff010100},
5301099013bSjsg 	{0x00000078, 0x00000000},
5311099013bSjsg 	{0x00000079, 0x00001434},
5321099013bSjsg 	{0x0000007a, 0xcc08ec08},
5331099013bSjsg 	{0x0000007b, 0x00040000},
5341099013bSjsg 	{0x0000007c, 0x000080c0},
5351099013bSjsg 	{0x0000007d, 0x09000000},
5361099013bSjsg 	{0x0000007e, 0x00210404},
5371099013bSjsg 	{0x00000081, 0x08a8e800},
5381099013bSjsg 	{0x00000082, 0x00030444},
5391099013bSjsg 	{0x00000083, 0x00000000},
5401099013bSjsg 	{0x00000085, 0x00000001},
5411099013bSjsg 	{0x00000086, 0x00000002},
5421099013bSjsg 	{0x00000087, 0x48490000},
5431099013bSjsg 	{0x00000088, 0x20244647},
5441099013bSjsg 	{0x00000089, 0x00000005},
5451099013bSjsg 	{0x0000008b, 0x66030000},
5461099013bSjsg 	{0x0000008c, 0x00006603},
5471099013bSjsg 	{0x0000008d, 0x00000100},
5481099013bSjsg 	{0x0000008f, 0x00001c0a},
5491099013bSjsg 	{0x00000090, 0xff000001},
5501099013bSjsg 	{0x00000094, 0x00101101},
5511099013bSjsg 	{0x00000095, 0x00000fff},
5521099013bSjsg 	{0x00000096, 0x00116fff},
5531099013bSjsg 	{0x00000097, 0x60010000},
5541099013bSjsg 	{0x00000098, 0x10010000},
5551099013bSjsg 	{0x00000099, 0x00006000},
5561099013bSjsg 	{0x0000009a, 0x00001000},
5571099013bSjsg 	{0x0000009f, 0x00936a00}
5581099013bSjsg };
5591099013bSjsg 
5601099013bSjsg static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
5611099013bSjsg 	{0x00000077, 0xff010100},
5621099013bSjsg 	{0x00000078, 0x00000000},
5631099013bSjsg 	{0x00000079, 0x00001434},
5641099013bSjsg 	{0x0000007a, 0xcc08ec08},
5651099013bSjsg 	{0x0000007b, 0x00040000},
5661099013bSjsg 	{0x0000007c, 0x000080c0},
5671099013bSjsg 	{0x0000007d, 0x09000000},
5681099013bSjsg 	{0x0000007e, 0x00210404},
5691099013bSjsg 	{0x00000081, 0x08a8e800},
5701099013bSjsg 	{0x00000082, 0x00030444},
5711099013bSjsg 	{0x00000083, 0x00000000},
5721099013bSjsg 	{0x00000085, 0x00000001},
5731099013bSjsg 	{0x00000086, 0x00000002},
5741099013bSjsg 	{0x00000087, 0x48490000},
5751099013bSjsg 	{0x00000088, 0x20244647},
5761099013bSjsg 	{0x00000089, 0x00000005},
5771099013bSjsg 	{0x0000008b, 0x66030000},
5781099013bSjsg 	{0x0000008c, 0x00006603},
5791099013bSjsg 	{0x0000008d, 0x00000100},
5801099013bSjsg 	{0x0000008f, 0x00001c0a},
5811099013bSjsg 	{0x00000090, 0xff000001},
5821099013bSjsg 	{0x00000094, 0x00101101},
5831099013bSjsg 	{0x00000095, 0x00000fff},
5841099013bSjsg 	{0x00000096, 0x00116fff},
5851099013bSjsg 	{0x00000097, 0x60010000},
5861099013bSjsg 	{0x00000098, 0x10010000},
5871099013bSjsg 	{0x00000099, 0x00006000},
5881099013bSjsg 	{0x0000009a, 0x00001000},
5891099013bSjsg 	{0x0000009f, 0x00916a00}
5901099013bSjsg };
5911099013bSjsg 
5921099013bSjsg static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = {
5931099013bSjsg 	{0x00000077, 0xff010100},
5941099013bSjsg 	{0x00000078, 0x00000000},
5951099013bSjsg 	{0x00000079, 0x00001434},
5961099013bSjsg 	{0x0000007a, 0xcc08ec08},
5971099013bSjsg 	{0x0000007b, 0x00040000},
5981099013bSjsg 	{0x0000007c, 0x000080c0},
5991099013bSjsg 	{0x0000007d, 0x09000000},
6001099013bSjsg 	{0x0000007e, 0x00210404},
6011099013bSjsg 	{0x00000081, 0x08a8e800},
6021099013bSjsg 	{0x00000082, 0x00030444},
6031099013bSjsg 	{0x00000083, 0x00000000},
6041099013bSjsg 	{0x00000085, 0x00000001},
6051099013bSjsg 	{0x00000086, 0x00000002},
6061099013bSjsg 	{0x00000087, 0x48490000},
6071099013bSjsg 	{0x00000088, 0x20244647},
6081099013bSjsg 	{0x00000089, 0x00000005},
6091099013bSjsg 	{0x0000008b, 0x66030000},
6101099013bSjsg 	{0x0000008c, 0x00006603},
6111099013bSjsg 	{0x0000008d, 0x00000100},
6121099013bSjsg 	{0x0000008f, 0x00001c0a},
6131099013bSjsg 	{0x00000090, 0xff000001},
6141099013bSjsg 	{0x00000094, 0x00101101},
6151099013bSjsg 	{0x00000095, 0x00000fff},
6161099013bSjsg 	{0x00000096, 0x00116fff},
6171099013bSjsg 	{0x00000097, 0x60010000},
6181099013bSjsg 	{0x00000098, 0x10010000},
6191099013bSjsg 	{0x00000099, 0x00006000},
6201099013bSjsg 	{0x0000009a, 0x00001000},
6211099013bSjsg 	{0x0000009f, 0x00976b00}
6221099013bSjsg };
6231099013bSjsg 
ni_mc_load_microcode(struct radeon_device * rdev)6241099013bSjsg int ni_mc_load_microcode(struct radeon_device *rdev)
6251099013bSjsg {
6261099013bSjsg 	const __be32 *fw_data;
6271099013bSjsg 	u32 mem_type, running, blackout = 0;
6281099013bSjsg 	u32 *io_mc_regs;
6291099013bSjsg 	int i, ucode_size, regs_size;
6301099013bSjsg 
6311099013bSjsg 	if (!rdev->mc_fw)
6321099013bSjsg 		return -EINVAL;
6331099013bSjsg 
6341099013bSjsg 	switch (rdev->family) {
6351099013bSjsg 	case CHIP_BARTS:
6361099013bSjsg 		io_mc_regs = (u32 *)&barts_io_mc_regs;
6371099013bSjsg 		ucode_size = BTC_MC_UCODE_SIZE;
6381099013bSjsg 		regs_size = BTC_IO_MC_REGS_SIZE;
6391099013bSjsg 		break;
6401099013bSjsg 	case CHIP_TURKS:
6411099013bSjsg 		io_mc_regs = (u32 *)&turks_io_mc_regs;
6421099013bSjsg 		ucode_size = BTC_MC_UCODE_SIZE;
6431099013bSjsg 		regs_size = BTC_IO_MC_REGS_SIZE;
6441099013bSjsg 		break;
6451099013bSjsg 	case CHIP_CAICOS:
6461099013bSjsg 	default:
6471099013bSjsg 		io_mc_regs = (u32 *)&caicos_io_mc_regs;
6481099013bSjsg 		ucode_size = BTC_MC_UCODE_SIZE;
6491099013bSjsg 		regs_size = BTC_IO_MC_REGS_SIZE;
6501099013bSjsg 		break;
6511099013bSjsg 	case CHIP_CAYMAN:
6521099013bSjsg 		io_mc_regs = (u32 *)&cayman_io_mc_regs;
6531099013bSjsg 		ucode_size = CAYMAN_MC_UCODE_SIZE;
6541099013bSjsg 		regs_size = BTC_IO_MC_REGS_SIZE;
6551099013bSjsg 		break;
6561099013bSjsg 	}
6571099013bSjsg 
6581099013bSjsg 	mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT;
6591099013bSjsg 	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
6601099013bSjsg 
6611099013bSjsg 	if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) {
6621099013bSjsg 		if (running) {
6631099013bSjsg 			blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
6641099013bSjsg 			WREG32(MC_SHARED_BLACKOUT_CNTL, 1);
6651099013bSjsg 		}
6661099013bSjsg 
6671099013bSjsg 		/* reset the engine and set to writable */
6681099013bSjsg 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
6691099013bSjsg 		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
6701099013bSjsg 
6711099013bSjsg 		/* load mc io regs */
6721099013bSjsg 		for (i = 0; i < regs_size; i++) {
6731099013bSjsg 			WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
6741099013bSjsg 			WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
6751099013bSjsg 		}
6761099013bSjsg 		/* load the MC ucode */
6777ccd5a2cSjsg 		fw_data = (const __be32 *)rdev->mc_fw->data;
6781099013bSjsg 		for (i = 0; i < ucode_size; i++)
6791099013bSjsg 			WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
6801099013bSjsg 
6811099013bSjsg 		/* put the engine back into the active state */
6821099013bSjsg 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
6831099013bSjsg 		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
6841099013bSjsg 		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
6851099013bSjsg 
6861099013bSjsg 		/* wait for training to complete */
6871099013bSjsg 		for (i = 0; i < rdev->usec_timeout; i++) {
6881099013bSjsg 			if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD)
6891099013bSjsg 				break;
6901099013bSjsg 			udelay(1);
6911099013bSjsg 		}
6921099013bSjsg 
6931099013bSjsg 		if (running)
6941099013bSjsg 			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
6951099013bSjsg 	}
6961099013bSjsg 
6971099013bSjsg 	return 0;
6981099013bSjsg }
6991099013bSjsg 
ni_init_microcode(struct radeon_device * rdev)7001099013bSjsg int ni_init_microcode(struct radeon_device *rdev)
7011099013bSjsg {
7021099013bSjsg 	const char *chip_name;
7031099013bSjsg 	const char *rlc_chip_name;
7041099013bSjsg 	size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size;
7057ccd5a2cSjsg 	size_t smc_req_size = 0;
7061099013bSjsg 	char fw_name[30];
7071099013bSjsg 	int err;
7081099013bSjsg 
7091099013bSjsg 	DRM_DEBUG("\n");
7101099013bSjsg 
7111099013bSjsg 	switch (rdev->family) {
7121099013bSjsg 	case CHIP_BARTS:
7137ccd5a2cSjsg 		chip_name = "BARTS";
7147ccd5a2cSjsg 		rlc_chip_name = "BTC";
7151099013bSjsg 		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
7161099013bSjsg 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
7171099013bSjsg 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
7181099013bSjsg 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
719f005ef32Sjsg 		smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4);
7201099013bSjsg 		break;
7211099013bSjsg 	case CHIP_TURKS:
7227ccd5a2cSjsg 		chip_name = "TURKS";
7237ccd5a2cSjsg 		rlc_chip_name = "BTC";
7241099013bSjsg 		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
7251099013bSjsg 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
7261099013bSjsg 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
7271099013bSjsg 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
728f005ef32Sjsg 		smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4);
7291099013bSjsg 		break;
7301099013bSjsg 	case CHIP_CAICOS:
7317ccd5a2cSjsg 		chip_name = "CAICOS";
7327ccd5a2cSjsg 		rlc_chip_name = "BTC";
7331099013bSjsg 		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
7341099013bSjsg 		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
7351099013bSjsg 		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
7361099013bSjsg 		mc_req_size = BTC_MC_UCODE_SIZE * 4;
737f005ef32Sjsg 		smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4);
7381099013bSjsg 		break;
7391099013bSjsg 	case CHIP_CAYMAN:
7407ccd5a2cSjsg 		chip_name = "CAYMAN";
7417ccd5a2cSjsg 		rlc_chip_name = "CAYMAN";
7421099013bSjsg 		pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
7431099013bSjsg 		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
7441099013bSjsg 		rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
7451099013bSjsg 		mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
746f005ef32Sjsg 		smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
7471099013bSjsg 		break;
7481099013bSjsg 	case CHIP_ARUBA:
7497ccd5a2cSjsg 		chip_name = "ARUBA";
7507ccd5a2cSjsg 		rlc_chip_name = "ARUBA";
7511099013bSjsg 		/* pfp/me same size as CAYMAN */
7521099013bSjsg 		pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4;
7531099013bSjsg 		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
7541099013bSjsg 		rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4;
7551099013bSjsg 		mc_req_size = 0;
7561099013bSjsg 		break;
7571099013bSjsg 	default: BUG();
7581099013bSjsg 	}
7591099013bSjsg 
7601099013bSjsg 	DRM_INFO("Loading %s Microcode\n", chip_name);
7611099013bSjsg 
7627ccd5a2cSjsg 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
7637ccd5a2cSjsg 	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
7641099013bSjsg 	if (err)
7651099013bSjsg 		goto out;
7667ccd5a2cSjsg 	if (rdev->pfp_fw->size != pfp_req_size) {
7677f4dd379Sjsg 		pr_err("ni_cp: Bogus length %zu in firmware \"%s\"\n",
7687ccd5a2cSjsg 		       rdev->pfp_fw->size, fw_name);
7691099013bSjsg 		err = -EINVAL;
7701099013bSjsg 		goto out;
7711099013bSjsg 	}
7721099013bSjsg 
7737ccd5a2cSjsg 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
7747ccd5a2cSjsg 	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
7751099013bSjsg 	if (err)
7761099013bSjsg 		goto out;
7777ccd5a2cSjsg 	if (rdev->me_fw->size != me_req_size) {
7787f4dd379Sjsg 		pr_err("ni_cp: Bogus length %zu in firmware \"%s\"\n",
7797ccd5a2cSjsg 		       rdev->me_fw->size, fw_name);
7801099013bSjsg 		err = -EINVAL;
7811099013bSjsg 	}
7821099013bSjsg 
7837ccd5a2cSjsg 	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
7847ccd5a2cSjsg 	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
7851099013bSjsg 	if (err)
7861099013bSjsg 		goto out;
7877ccd5a2cSjsg 	if (rdev->rlc_fw->size != rlc_req_size) {
7887f4dd379Sjsg 		pr_err("ni_rlc: Bogus length %zu in firmware \"%s\"\n",
7897ccd5a2cSjsg 		       rdev->rlc_fw->size, fw_name);
7901099013bSjsg 		err = -EINVAL;
7911099013bSjsg 	}
7921099013bSjsg 
7931099013bSjsg 	/* no MC ucode on TN */
7941099013bSjsg 	if (!(rdev->flags & RADEON_IS_IGP)) {
7957ccd5a2cSjsg 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
7967ccd5a2cSjsg 		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
7971099013bSjsg 		if (err)
7981099013bSjsg 			goto out;
7997ccd5a2cSjsg 		if (rdev->mc_fw->size != mc_req_size) {
8007f4dd379Sjsg 			pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n",
8017ccd5a2cSjsg 			       rdev->mc_fw->size, fw_name);
8021099013bSjsg 			err = -EINVAL;
8031099013bSjsg 		}
8041099013bSjsg 	}
8057ccd5a2cSjsg 
8067ccd5a2cSjsg 	if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
8077ccd5a2cSjsg 		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
8087ccd5a2cSjsg 		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
8097ccd5a2cSjsg 		if (err) {
8107f4dd379Sjsg 			pr_err("smc: error loading firmware \"%s\"\n", fw_name);
8117ccd5a2cSjsg 			release_firmware(rdev->smc_fw);
8127ccd5a2cSjsg 			rdev->smc_fw = NULL;
8137ccd5a2cSjsg 			err = 0;
8147ccd5a2cSjsg 		} else if (rdev->smc_fw->size != smc_req_size) {
8157f4dd379Sjsg 			pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n",
816*d9c286e0Sjsg 			       rdev->smc_fw->size, fw_name);
8177ccd5a2cSjsg 			err = -EINVAL;
8187ccd5a2cSjsg 		}
8197ccd5a2cSjsg 	}
8207ccd5a2cSjsg 
8211099013bSjsg out:
8221099013bSjsg 	if (err) {
8231099013bSjsg 		if (err != -EINVAL)
8247f4dd379Sjsg 			pr_err("ni_cp: Failed to load firmware \"%s\"\n",
8251099013bSjsg 			       fw_name);
8267ccd5a2cSjsg 		release_firmware(rdev->pfp_fw);
8271099013bSjsg 		rdev->pfp_fw = NULL;
8287ccd5a2cSjsg 		release_firmware(rdev->me_fw);
8291099013bSjsg 		rdev->me_fw = NULL;
8307ccd5a2cSjsg 		release_firmware(rdev->rlc_fw);
8311099013bSjsg 		rdev->rlc_fw = NULL;
8327ccd5a2cSjsg 		release_firmware(rdev->mc_fw);
8331099013bSjsg 		rdev->mc_fw = NULL;
8341099013bSjsg 	}
8351099013bSjsg 	return err;
8361099013bSjsg }
8371099013bSjsg 
8387ccd5a2cSjsg /**
8397ccd5a2cSjsg  * cayman_get_allowed_info_register - fetch the register for the info ioctl
8407ccd5a2cSjsg  *
8417ccd5a2cSjsg  * @rdev: radeon_device pointer
8427ccd5a2cSjsg  * @reg: register offset in bytes
8437ccd5a2cSjsg  * @val: register value
8447ccd5a2cSjsg  *
8457ccd5a2cSjsg  * Returns 0 for success or -EINVAL for an invalid register
8467ccd5a2cSjsg  *
8477ccd5a2cSjsg  */
cayman_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)8487ccd5a2cSjsg int cayman_get_allowed_info_register(struct radeon_device *rdev,
8497ccd5a2cSjsg 				     u32 reg, u32 *val)
8507ccd5a2cSjsg {
8517ccd5a2cSjsg 	switch (reg) {
8527ccd5a2cSjsg 	case GRBM_STATUS:
8537ccd5a2cSjsg 	case GRBM_STATUS_SE0:
8547ccd5a2cSjsg 	case GRBM_STATUS_SE1:
8557ccd5a2cSjsg 	case SRBM_STATUS:
8567ccd5a2cSjsg 	case SRBM_STATUS2:
8577ccd5a2cSjsg 	case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
8587ccd5a2cSjsg 	case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
8597ccd5a2cSjsg 	case UVD_STATUS:
8607ccd5a2cSjsg 		*val = RREG32(reg);
8617ccd5a2cSjsg 		return 0;
8627ccd5a2cSjsg 	default:
8637ccd5a2cSjsg 		return -EINVAL;
8647ccd5a2cSjsg 	}
8657ccd5a2cSjsg }
8667ccd5a2cSjsg 
tn_get_temp(struct radeon_device * rdev)8677ccd5a2cSjsg int tn_get_temp(struct radeon_device *rdev)
8687ccd5a2cSjsg {
8697ccd5a2cSjsg 	u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff;
8707ccd5a2cSjsg 	int actual_temp = (temp / 8) - 49;
8717ccd5a2cSjsg 
8727ccd5a2cSjsg 	return actual_temp * 1000;
8737ccd5a2cSjsg }
8747ccd5a2cSjsg 
8751099013bSjsg /*
8761099013bSjsg  * Core functions
8771099013bSjsg  */
cayman_gpu_init(struct radeon_device * rdev)8781099013bSjsg static void cayman_gpu_init(struct radeon_device *rdev)
8791099013bSjsg {
8801099013bSjsg 	u32 gb_addr_config = 0;
8815ca02815Sjsg 	u32 mc_arb_ramcfg;
8821099013bSjsg 	u32 cgts_tcc_disable;
8831099013bSjsg 	u32 sx_debug_1;
8841099013bSjsg 	u32 smx_dc_ctl0;
8851099013bSjsg 	u32 cgts_sm_ctrl_reg;
8861099013bSjsg 	u32 hdp_host_path_cntl;
8871099013bSjsg 	u32 tmp;
8881099013bSjsg 	u32 disabled_rb_mask;
8891099013bSjsg 	int i, j;
8901099013bSjsg 
8911099013bSjsg 	switch (rdev->family) {
8921099013bSjsg 	case CHIP_CAYMAN:
8931099013bSjsg 		rdev->config.cayman.max_shader_engines = 2;
8941099013bSjsg 		rdev->config.cayman.max_pipes_per_simd = 4;
8951099013bSjsg 		rdev->config.cayman.max_tile_pipes = 8;
8961099013bSjsg 		rdev->config.cayman.max_simds_per_se = 12;
8971099013bSjsg 		rdev->config.cayman.max_backends_per_se = 4;
8981099013bSjsg 		rdev->config.cayman.max_texture_channel_caches = 8;
8991099013bSjsg 		rdev->config.cayman.max_gprs = 256;
9001099013bSjsg 		rdev->config.cayman.max_threads = 256;
9011099013bSjsg 		rdev->config.cayman.max_gs_threads = 32;
9021099013bSjsg 		rdev->config.cayman.max_stack_entries = 512;
9031099013bSjsg 		rdev->config.cayman.sx_num_of_sets = 8;
9041099013bSjsg 		rdev->config.cayman.sx_max_export_size = 256;
9051099013bSjsg 		rdev->config.cayman.sx_max_export_pos_size = 64;
9061099013bSjsg 		rdev->config.cayman.sx_max_export_smx_size = 192;
9071099013bSjsg 		rdev->config.cayman.max_hw_contexts = 8;
9081099013bSjsg 		rdev->config.cayman.sq_num_cf_insts = 2;
9091099013bSjsg 
9101099013bSjsg 		rdev->config.cayman.sc_prim_fifo_size = 0x100;
9111099013bSjsg 		rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
9121099013bSjsg 		rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
9131099013bSjsg 		gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN;
9141099013bSjsg 		break;
9151099013bSjsg 	case CHIP_ARUBA:
9161099013bSjsg 	default:
9171099013bSjsg 		rdev->config.cayman.max_shader_engines = 1;
9181099013bSjsg 		rdev->config.cayman.max_pipes_per_simd = 4;
9191099013bSjsg 		rdev->config.cayman.max_tile_pipes = 2;
920b830ca6dSjsg 		if ((rdev->pdev->device == 0x9900) ||
921b830ca6dSjsg 		    (rdev->pdev->device == 0x9901) ||
922b830ca6dSjsg 		    (rdev->pdev->device == 0x9905) ||
923b830ca6dSjsg 		    (rdev->pdev->device == 0x9906) ||
924b830ca6dSjsg 		    (rdev->pdev->device == 0x9907) ||
925b830ca6dSjsg 		    (rdev->pdev->device == 0x9908) ||
926b830ca6dSjsg 		    (rdev->pdev->device == 0x9909) ||
927b830ca6dSjsg 		    (rdev->pdev->device == 0x990B) ||
928b830ca6dSjsg 		    (rdev->pdev->device == 0x990C) ||
929b830ca6dSjsg 		    (rdev->pdev->device == 0x990F) ||
930b830ca6dSjsg 		    (rdev->pdev->device == 0x9910) ||
931b830ca6dSjsg 		    (rdev->pdev->device == 0x9917) ||
932b830ca6dSjsg 		    (rdev->pdev->device == 0x9999) ||
933b830ca6dSjsg 		    (rdev->pdev->device == 0x999C)) {
9341099013bSjsg 			rdev->config.cayman.max_simds_per_se = 6;
9351099013bSjsg 			rdev->config.cayman.max_backends_per_se = 2;
93625e4e82bSjsg 			rdev->config.cayman.max_hw_contexts = 8;
93725e4e82bSjsg 			rdev->config.cayman.sx_max_export_size = 256;
93825e4e82bSjsg 			rdev->config.cayman.sx_max_export_pos_size = 64;
93925e4e82bSjsg 			rdev->config.cayman.sx_max_export_smx_size = 192;
940b830ca6dSjsg 		} else if ((rdev->pdev->device == 0x9903) ||
941b830ca6dSjsg 			   (rdev->pdev->device == 0x9904) ||
942b830ca6dSjsg 			   (rdev->pdev->device == 0x990A) ||
943b830ca6dSjsg 			   (rdev->pdev->device == 0x990D) ||
944b830ca6dSjsg 			   (rdev->pdev->device == 0x990E) ||
945b830ca6dSjsg 			   (rdev->pdev->device == 0x9913) ||
946b830ca6dSjsg 			   (rdev->pdev->device == 0x9918) ||
947b830ca6dSjsg 			   (rdev->pdev->device == 0x999D)) {
9481099013bSjsg 			rdev->config.cayman.max_simds_per_se = 4;
9491099013bSjsg 			rdev->config.cayman.max_backends_per_se = 2;
95025e4e82bSjsg 			rdev->config.cayman.max_hw_contexts = 8;
95125e4e82bSjsg 			rdev->config.cayman.sx_max_export_size = 256;
95225e4e82bSjsg 			rdev->config.cayman.sx_max_export_pos_size = 64;
95325e4e82bSjsg 			rdev->config.cayman.sx_max_export_smx_size = 192;
954b830ca6dSjsg 		} else if ((rdev->pdev->device == 0x9919) ||
955b830ca6dSjsg 			   (rdev->pdev->device == 0x9990) ||
956b830ca6dSjsg 			   (rdev->pdev->device == 0x9991) ||
957b830ca6dSjsg 			   (rdev->pdev->device == 0x9994) ||
958b830ca6dSjsg 			   (rdev->pdev->device == 0x9995) ||
959b830ca6dSjsg 			   (rdev->pdev->device == 0x9996) ||
960b830ca6dSjsg 			   (rdev->pdev->device == 0x999A) ||
961b830ca6dSjsg 			   (rdev->pdev->device == 0x99A0)) {
9621099013bSjsg 			rdev->config.cayman.max_simds_per_se = 3;
9631099013bSjsg 			rdev->config.cayman.max_backends_per_se = 1;
96425e4e82bSjsg 			rdev->config.cayman.max_hw_contexts = 4;
96525e4e82bSjsg 			rdev->config.cayman.sx_max_export_size = 128;
96625e4e82bSjsg 			rdev->config.cayman.sx_max_export_pos_size = 32;
96725e4e82bSjsg 			rdev->config.cayman.sx_max_export_smx_size = 96;
9681099013bSjsg 		} else {
9691099013bSjsg 			rdev->config.cayman.max_simds_per_se = 2;
9701099013bSjsg 			rdev->config.cayman.max_backends_per_se = 1;
97125e4e82bSjsg 			rdev->config.cayman.max_hw_contexts = 4;
97225e4e82bSjsg 			rdev->config.cayman.sx_max_export_size = 128;
97325e4e82bSjsg 			rdev->config.cayman.sx_max_export_pos_size = 32;
97425e4e82bSjsg 			rdev->config.cayman.sx_max_export_smx_size = 96;
9751099013bSjsg 		}
9761099013bSjsg 		rdev->config.cayman.max_texture_channel_caches = 2;
9771099013bSjsg 		rdev->config.cayman.max_gprs = 256;
9781099013bSjsg 		rdev->config.cayman.max_threads = 256;
9791099013bSjsg 		rdev->config.cayman.max_gs_threads = 32;
9801099013bSjsg 		rdev->config.cayman.max_stack_entries = 512;
9811099013bSjsg 		rdev->config.cayman.sx_num_of_sets = 8;
9821099013bSjsg 		rdev->config.cayman.sq_num_cf_insts = 2;
9831099013bSjsg 
9841099013bSjsg 		rdev->config.cayman.sc_prim_fifo_size = 0x40;
9851099013bSjsg 		rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30;
9861099013bSjsg 		rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130;
9871099013bSjsg 		gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN;
9881099013bSjsg 		break;
9891099013bSjsg 	}
9901099013bSjsg 
9911099013bSjsg 	/* Initialize HDP */
9921099013bSjsg 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
9931099013bSjsg 		WREG32((0x2c14 + j), 0x00000000);
9941099013bSjsg 		WREG32((0x2c18 + j), 0x00000000);
9951099013bSjsg 		WREG32((0x2c1c + j), 0x00000000);
9961099013bSjsg 		WREG32((0x2c20 + j), 0x00000000);
9971099013bSjsg 		WREG32((0x2c24 + j), 0x00000000);
9981099013bSjsg 	}
9991099013bSjsg 
10001099013bSjsg 	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
10017ccd5a2cSjsg 	WREG32(SRBM_INT_CNTL, 0x1);
10027ccd5a2cSjsg 	WREG32(SRBM_INT_ACK, 0x1);
10031099013bSjsg 
10041099013bSjsg 	evergreen_fix_pci_max_read_req_size(rdev);
10051099013bSjsg 
10065ca02815Sjsg 	RREG32(MC_SHARED_CHMAP);
10071099013bSjsg 	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
10081099013bSjsg 
10091099013bSjsg 	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
10101099013bSjsg 	rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
10111099013bSjsg 	if (rdev->config.cayman.mem_row_size_in_kb > 4)
10121099013bSjsg 		rdev->config.cayman.mem_row_size_in_kb = 4;
10131099013bSjsg 	/* XXX use MC settings? */
10141099013bSjsg 	rdev->config.cayman.shader_engine_tile_size = 32;
10151099013bSjsg 	rdev->config.cayman.num_gpus = 1;
10161099013bSjsg 	rdev->config.cayman.multi_gpu_tile_size = 64;
10171099013bSjsg 
10181099013bSjsg 	tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
10191099013bSjsg 	rdev->config.cayman.num_tile_pipes = (1 << tmp);
10201099013bSjsg 	tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
10211099013bSjsg 	rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256;
10221099013bSjsg 	tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
10231099013bSjsg 	rdev->config.cayman.num_shader_engines = tmp + 1;
10241099013bSjsg 	tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
10251099013bSjsg 	rdev->config.cayman.num_gpus = tmp + 1;
10261099013bSjsg 	tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
10271099013bSjsg 	rdev->config.cayman.multi_gpu_tile_size = 1 << tmp;
10281099013bSjsg 	tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
10291099013bSjsg 	rdev->config.cayman.mem_row_size_in_kb = 1 << tmp;
10301099013bSjsg 
10311099013bSjsg 
10321099013bSjsg 	/* setup tiling info dword.  gb_addr_config is not adequate since it does
10331099013bSjsg 	 * not have bank info, so create a custom tiling dword.
10341099013bSjsg 	 * bits 3:0   num_pipes
10351099013bSjsg 	 * bits 7:4   num_banks
10361099013bSjsg 	 * bits 11:8  group_size
10371099013bSjsg 	 * bits 15:12 row_size
10381099013bSjsg 	 */
10391099013bSjsg 	rdev->config.cayman.tile_config = 0;
10401099013bSjsg 	switch (rdev->config.cayman.num_tile_pipes) {
10411099013bSjsg 	case 1:
10421099013bSjsg 	default:
10431099013bSjsg 		rdev->config.cayman.tile_config |= (0 << 0);
10441099013bSjsg 		break;
10451099013bSjsg 	case 2:
10461099013bSjsg 		rdev->config.cayman.tile_config |= (1 << 0);
10471099013bSjsg 		break;
10481099013bSjsg 	case 4:
10491099013bSjsg 		rdev->config.cayman.tile_config |= (2 << 0);
10501099013bSjsg 		break;
10511099013bSjsg 	case 8:
10521099013bSjsg 		rdev->config.cayman.tile_config |= (3 << 0);
10531099013bSjsg 		break;
10541099013bSjsg 	}
10551099013bSjsg 
10561099013bSjsg 	/* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
10571099013bSjsg 	if (rdev->flags & RADEON_IS_IGP)
10581099013bSjsg 		rdev->config.cayman.tile_config |= 1 << 4;
10591099013bSjsg 	else {
10601099013bSjsg 		switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
10611099013bSjsg 		case 0: /* four banks */
10621099013bSjsg 			rdev->config.cayman.tile_config |= 0 << 4;
10631099013bSjsg 			break;
10641099013bSjsg 		case 1: /* eight banks */
10651099013bSjsg 			rdev->config.cayman.tile_config |= 1 << 4;
10661099013bSjsg 			break;
10671099013bSjsg 		case 2: /* sixteen banks */
10681099013bSjsg 		default:
10691099013bSjsg 			rdev->config.cayman.tile_config |= 2 << 4;
10701099013bSjsg 			break;
10711099013bSjsg 		}
10721099013bSjsg 	}
10731099013bSjsg 	rdev->config.cayman.tile_config |=
10741099013bSjsg 		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
10751099013bSjsg 	rdev->config.cayman.tile_config |=
10761099013bSjsg 		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
10771099013bSjsg 
10781099013bSjsg 	tmp = 0;
10791099013bSjsg 	for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) {
10801099013bSjsg 		u32 rb_disable_bitmap;
10811099013bSjsg 
10821099013bSjsg 		WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
10831099013bSjsg 		WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
10841099013bSjsg 		rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
10851099013bSjsg 		tmp <<= 4;
10861099013bSjsg 		tmp |= rb_disable_bitmap;
10871099013bSjsg 	}
10881099013bSjsg 	/* enabled rb are just the one not disabled :) */
10891099013bSjsg 	disabled_rb_mask = tmp;
10907ccd5a2cSjsg 	tmp = 0;
10917ccd5a2cSjsg 	for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
10927ccd5a2cSjsg 		tmp |= (1 << i);
10937ccd5a2cSjsg 	/* if all the backends are disabled, fix it up here */
10947ccd5a2cSjsg 	if ((disabled_rb_mask & tmp) == tmp) {
10957ccd5a2cSjsg 		for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++)
10967ccd5a2cSjsg 			disabled_rb_mask &= ~(1 << i);
10977ccd5a2cSjsg 	}
10987ccd5a2cSjsg 
10997ccd5a2cSjsg 	for (i = 0; i < rdev->config.cayman.max_shader_engines; i++) {
11007ccd5a2cSjsg 		u32 simd_disable_bitmap;
11017ccd5a2cSjsg 
11027ccd5a2cSjsg 		WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
11037ccd5a2cSjsg 		WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
11047ccd5a2cSjsg 		simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
11057ccd5a2cSjsg 		simd_disable_bitmap |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
11067ccd5a2cSjsg 		tmp <<= 16;
11077ccd5a2cSjsg 		tmp |= simd_disable_bitmap;
11087ccd5a2cSjsg 	}
11097ccd5a2cSjsg 	rdev->config.cayman.active_simds = hweight32(~tmp);
11101099013bSjsg 
11111099013bSjsg 	WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
11121099013bSjsg 	WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
11131099013bSjsg 
11141099013bSjsg 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
11151099013bSjsg 	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
11161099013bSjsg 	if (ASIC_IS_DCE6(rdev))
11171099013bSjsg 		WREG32(DMIF_ADDR_CALC, gb_addr_config);
11181099013bSjsg 	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
11191099013bSjsg 	WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
11201099013bSjsg 	WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
11217ccd5a2cSjsg 	WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
11227ccd5a2cSjsg 	WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
11237ccd5a2cSjsg 	WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
11241099013bSjsg 
11251099013bSjsg 	if ((rdev->config.cayman.max_backends_per_se == 1) &&
11261099013bSjsg 	    (rdev->flags & RADEON_IS_IGP)) {
11277ccd5a2cSjsg 		if ((disabled_rb_mask & 3) == 2) {
1128f3eef2b6Sderaadt 			/* RB1 disabled, RB0 enabled */
1129f3eef2b6Sderaadt 			tmp = 0x00000000;
11307ccd5a2cSjsg 		} else {
11317ccd5a2cSjsg 			/* RB0 disabled, RB1 enabled */
11327ccd5a2cSjsg 			tmp = 0x11111111;
11331099013bSjsg 		}
11341099013bSjsg 	} else {
11351099013bSjsg 		tmp = gb_addr_config & NUM_PIPES_MASK;
11361099013bSjsg 		tmp = r6xx_remap_render_backend(rdev, tmp,
11371099013bSjsg 						rdev->config.cayman.max_backends_per_se *
11381099013bSjsg 						rdev->config.cayman.max_shader_engines,
11391099013bSjsg 						CAYMAN_MAX_BACKENDS, disabled_rb_mask);
11401099013bSjsg 	}
11417f4dd379Sjsg 	rdev->config.cayman.backend_map = tmp;
11421099013bSjsg 	WREG32(GB_BACKEND_MAP, tmp);
11431099013bSjsg 
11441099013bSjsg 	cgts_tcc_disable = 0xffff0000;
11451099013bSjsg 	for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++)
11461099013bSjsg 		cgts_tcc_disable &= ~(1 << (16 + i));
11471099013bSjsg 	WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
11481099013bSjsg 	WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable);
11491099013bSjsg 	WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable);
11501099013bSjsg 	WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
11511099013bSjsg 
11521099013bSjsg 	/* reprogram the shader complex */
11531099013bSjsg 	cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG);
11541099013bSjsg 	for (i = 0; i < 16; i++)
11551099013bSjsg 		WREG32(CGTS_SM_CTRL_REG, OVERRIDE);
11561099013bSjsg 	WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg);
11571099013bSjsg 
11581099013bSjsg 	/* set HW defaults for 3D engine */
11591099013bSjsg 	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
11601099013bSjsg 
11611099013bSjsg 	sx_debug_1 = RREG32(SX_DEBUG_1);
11621099013bSjsg 	sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
11631099013bSjsg 	WREG32(SX_DEBUG_1, sx_debug_1);
11641099013bSjsg 
11651099013bSjsg 	smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
11661099013bSjsg 	smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
11671099013bSjsg 	smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets);
11681099013bSjsg 	WREG32(SMX_DC_CTL0, smx_dc_ctl0);
11691099013bSjsg 
11701099013bSjsg 	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE);
11711099013bSjsg 
11721099013bSjsg 	/* need to be explicitly zero-ed */
11731099013bSjsg 	WREG32(VGT_OFFCHIP_LDS_BASE, 0);
11741099013bSjsg 	WREG32(SQ_LSTMP_RING_BASE, 0);
11751099013bSjsg 	WREG32(SQ_HSTMP_RING_BASE, 0);
11761099013bSjsg 	WREG32(SQ_ESTMP_RING_BASE, 0);
11771099013bSjsg 	WREG32(SQ_GSTMP_RING_BASE, 0);
11781099013bSjsg 	WREG32(SQ_VSTMP_RING_BASE, 0);
11791099013bSjsg 	WREG32(SQ_PSTMP_RING_BASE, 0);
11801099013bSjsg 
11811099013bSjsg 	WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO);
11821099013bSjsg 
11831099013bSjsg 	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) |
11841099013bSjsg 					POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) |
11851099013bSjsg 					SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1)));
11861099013bSjsg 
11871099013bSjsg 	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) |
11881099013bSjsg 				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) |
11891099013bSjsg 				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size)));
11901099013bSjsg 
11911099013bSjsg 
11921099013bSjsg 	WREG32(VGT_NUM_INSTANCES, 1);
11931099013bSjsg 
11941099013bSjsg 	WREG32(CP_PERFMON_CNTL, 0);
11951099013bSjsg 
11961099013bSjsg 	WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) |
11971099013bSjsg 				  FETCH_FIFO_HIWATER(0x4) |
11981099013bSjsg 				  DONE_FIFO_HIWATER(0xe0) |
11991099013bSjsg 				  ALU_UPDATE_FIFO_HIWATER(0x8)));
12001099013bSjsg 
12011099013bSjsg 	WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4));
12021099013bSjsg 	WREG32(SQ_CONFIG, (VC_ENABLE |
12031099013bSjsg 			   EXPORT_SRC_C |
12041099013bSjsg 			   GFX_PRIO(0) |
12051099013bSjsg 			   CS1_PRIO(0) |
12061099013bSjsg 			   CS2_PRIO(1)));
12071099013bSjsg 	WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE);
12081099013bSjsg 
12091099013bSjsg 	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
12101099013bSjsg 					  FORCE_EOV_MAX_REZ_CNT(255)));
12111099013bSjsg 
12121099013bSjsg 	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
12131099013bSjsg 	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
12141099013bSjsg 
12151099013bSjsg 	WREG32(VGT_GS_VERTEX_REUSE, 16);
12161099013bSjsg 	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
12171099013bSjsg 
12181099013bSjsg 	WREG32(CB_PERF_CTR0_SEL_0, 0);
12191099013bSjsg 	WREG32(CB_PERF_CTR0_SEL_1, 0);
12201099013bSjsg 	WREG32(CB_PERF_CTR1_SEL_0, 0);
12211099013bSjsg 	WREG32(CB_PERF_CTR1_SEL_1, 0);
12221099013bSjsg 	WREG32(CB_PERF_CTR2_SEL_0, 0);
12231099013bSjsg 	WREG32(CB_PERF_CTR2_SEL_1, 0);
12241099013bSjsg 	WREG32(CB_PERF_CTR3_SEL_0, 0);
12251099013bSjsg 	WREG32(CB_PERF_CTR3_SEL_1, 0);
12261099013bSjsg 
12271099013bSjsg 	tmp = RREG32(HDP_MISC_CNTL);
12281099013bSjsg 	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
12291099013bSjsg 	WREG32(HDP_MISC_CNTL, tmp);
12301099013bSjsg 
12311099013bSjsg 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
12321099013bSjsg 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
12331099013bSjsg 
12341099013bSjsg 	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
12351099013bSjsg 
12361099013bSjsg 	udelay(50);
12377ccd5a2cSjsg 
12387ccd5a2cSjsg 	/* set clockgating golden values on TN */
12397ccd5a2cSjsg 	if (rdev->family == CHIP_ARUBA) {
12407ccd5a2cSjsg 		tmp = RREG32_CG(CG_CGTT_LOCAL_0);
12417ccd5a2cSjsg 		tmp &= ~0x00380000;
12427ccd5a2cSjsg 		WREG32_CG(CG_CGTT_LOCAL_0, tmp);
12437ccd5a2cSjsg 		tmp = RREG32_CG(CG_CGTT_LOCAL_1);
12447ccd5a2cSjsg 		tmp &= ~0x0e000000;
12457ccd5a2cSjsg 		WREG32_CG(CG_CGTT_LOCAL_1, tmp);
12467ccd5a2cSjsg 	}
12471099013bSjsg }
12481099013bSjsg 
12491099013bSjsg /*
12501099013bSjsg  * GART
12511099013bSjsg  */
cayman_pcie_gart_tlb_flush(struct radeon_device * rdev)12521099013bSjsg void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev)
12531099013bSjsg {
12541099013bSjsg 	/* flush hdp cache */
12551099013bSjsg 	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
12561099013bSjsg 
12571099013bSjsg 	/* bits 0-7 are the VM contexts0-7 */
12581099013bSjsg 	WREG32(VM_INVALIDATE_REQUEST, 1);
12591099013bSjsg }
12601099013bSjsg 
cayman_pcie_gart_enable(struct radeon_device * rdev)12611099013bSjsg static int cayman_pcie_gart_enable(struct radeon_device *rdev)
12621099013bSjsg {
12631099013bSjsg 	int i, r;
12641099013bSjsg 
12651099013bSjsg 	if (rdev->gart.robj == NULL) {
12661099013bSjsg 		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
12671099013bSjsg 		return -EINVAL;
12681099013bSjsg 	}
12691099013bSjsg 	r = radeon_gart_table_vram_pin(rdev);
12701099013bSjsg 	if (r)
12711099013bSjsg 		return r;
12721099013bSjsg 	/* Setup TLB control */
12731099013bSjsg 	WREG32(MC_VM_MX_L1_TLB_CNTL,
12741099013bSjsg 	       (0xA << 7) |
12751099013bSjsg 	       ENABLE_L1_TLB |
12761099013bSjsg 	       ENABLE_L1_FRAGMENT_PROCESSING |
12771099013bSjsg 	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
12781099013bSjsg 	       ENABLE_ADVANCED_DRIVER_MODEL |
12791099013bSjsg 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
12801099013bSjsg 	/* Setup L2 cache */
12811099013bSjsg 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
12827ccd5a2cSjsg 	       ENABLE_L2_FRAGMENT_PROCESSING |
12831099013bSjsg 	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
12841099013bSjsg 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
12851099013bSjsg 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
12861099013bSjsg 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
12871099013bSjsg 	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
12881099013bSjsg 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
12897ccd5a2cSjsg 	       BANK_SELECT(6) |
12901099013bSjsg 	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
12911099013bSjsg 	/* setup context0 */
12921099013bSjsg 	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
12931099013bSjsg 	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
12941099013bSjsg 	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
12951099013bSjsg 	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
12961099013bSjsg 			(u32)(rdev->dummy_page.addr >> 12));
12971099013bSjsg 	WREG32(VM_CONTEXT0_CNTL2, 0);
12981099013bSjsg 	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
12991099013bSjsg 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
13001099013bSjsg 
13011099013bSjsg 	WREG32(0x15D4, 0);
13021099013bSjsg 	WREG32(0x15D8, 0);
13031099013bSjsg 	WREG32(0x15DC, 0);
13041099013bSjsg 
13051099013bSjsg 	/* empty context1-7 */
13061099013bSjsg 	/* Assign the pt base to something valid for now; the pts used for
13071099013bSjsg 	 * the VMs are determined by the application and setup and assigned
13081099013bSjsg 	 * on the fly in the vm part of radeon_gart.c
13091099013bSjsg 	 */
13101099013bSjsg 	for (i = 1; i < 8; i++) {
13111099013bSjsg 		WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0);
13127ccd5a2cSjsg 		WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2),
13137ccd5a2cSjsg 			rdev->vm_manager.max_pfn - 1);
13141099013bSjsg 		WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
13157ccd5a2cSjsg 		       rdev->vm_manager.saved_table_addr[i]);
13161099013bSjsg 	}
13171099013bSjsg 
13181099013bSjsg 	/* enable context1-7 */
13191099013bSjsg 	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
13201099013bSjsg 	       (u32)(rdev->dummy_page.addr >> 12));
13211099013bSjsg 	WREG32(VM_CONTEXT1_CNTL2, 4);
13221099013bSjsg 	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
13237ccd5a2cSjsg 				PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
13241099013bSjsg 				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
13251099013bSjsg 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
13261099013bSjsg 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
13271099013bSjsg 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
13281099013bSjsg 				PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
13291099013bSjsg 				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
13301099013bSjsg 				VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
13311099013bSjsg 				VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
13321099013bSjsg 				READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
13331099013bSjsg 				READ_PROTECTION_FAULT_ENABLE_DEFAULT |
13341099013bSjsg 				WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
13351099013bSjsg 				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
13361099013bSjsg 
13371099013bSjsg 	cayman_pcie_gart_tlb_flush(rdev);
13381099013bSjsg 	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
13391099013bSjsg 		 (unsigned)(rdev->mc.gtt_size >> 20),
13401099013bSjsg 		 (unsigned long long)rdev->gart.table_addr);
13411099013bSjsg 	rdev->gart.ready = true;
13421099013bSjsg 	return 0;
13431099013bSjsg }
13441099013bSjsg 
cayman_pcie_gart_disable(struct radeon_device * rdev)13451099013bSjsg static void cayman_pcie_gart_disable(struct radeon_device *rdev)
13461099013bSjsg {
13477ccd5a2cSjsg 	unsigned i;
13487ccd5a2cSjsg 
13497ccd5a2cSjsg 	for (i = 1; i < 8; ++i) {
13507ccd5a2cSjsg 		rdev->vm_manager.saved_table_addr[i] = RREG32(
13517ccd5a2cSjsg 			VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2));
13527ccd5a2cSjsg 	}
13537ccd5a2cSjsg 
13541099013bSjsg 	/* Disable all tables */
13551099013bSjsg 	WREG32(VM_CONTEXT0_CNTL, 0);
13561099013bSjsg 	WREG32(VM_CONTEXT1_CNTL, 0);
13571099013bSjsg 	/* Setup TLB control */
13581099013bSjsg 	WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING |
13591099013bSjsg 	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
13601099013bSjsg 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
13611099013bSjsg 	/* Setup L2 cache */
13621099013bSjsg 	WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
13631099013bSjsg 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
13641099013bSjsg 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
13651099013bSjsg 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
13661099013bSjsg 	WREG32(VM_L2_CNTL2, 0);
13671099013bSjsg 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
13681099013bSjsg 	       L2_CACHE_BIGK_FRAGMENT_SIZE(6));
13691099013bSjsg 	radeon_gart_table_vram_unpin(rdev);
13701099013bSjsg }
13711099013bSjsg 
cayman_pcie_gart_fini(struct radeon_device * rdev)13721099013bSjsg static void cayman_pcie_gart_fini(struct radeon_device *rdev)
13731099013bSjsg {
13741099013bSjsg 	cayman_pcie_gart_disable(rdev);
13751099013bSjsg 	radeon_gart_table_vram_free(rdev);
13761099013bSjsg 	radeon_gart_fini(rdev);
13771099013bSjsg }
13781099013bSjsg 
cayman_cp_int_cntl_setup(struct radeon_device * rdev,int ring,u32 cp_int_cntl)13791099013bSjsg void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
13801099013bSjsg 			      int ring, u32 cp_int_cntl)
13811099013bSjsg {
13827ccd5a2cSjsg 	WREG32(SRBM_GFX_CNTL, RINGID(ring));
13831099013bSjsg 	WREG32(CP_INT_CNTL, cp_int_cntl);
13841099013bSjsg }
13851099013bSjsg 
13861099013bSjsg /*
13871099013bSjsg  * CP.
13881099013bSjsg  */
cayman_fence_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)13891099013bSjsg void cayman_fence_ring_emit(struct radeon_device *rdev,
13901099013bSjsg 			    struct radeon_fence *fence)
13911099013bSjsg {
13921099013bSjsg 	struct radeon_ring *ring = &rdev->ring[fence->ring];
13931099013bSjsg 	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
1394bc26ceb1Sjsg 	u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
1395bc26ceb1Sjsg 		PACKET3_SH_ACTION_ENA;
13961099013bSjsg 
13971099013bSjsg 	/* flush read cache over gart for this vmid */
13981099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1399bc26ceb1Sjsg 	radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
14001099013bSjsg 	radeon_ring_write(ring, 0xFFFFFFFF);
14011099013bSjsg 	radeon_ring_write(ring, 0);
14021099013bSjsg 	radeon_ring_write(ring, 10); /* poll interval */
14031099013bSjsg 	/* EVENT_WRITE_EOP - flush caches, send int */
14041099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
14051099013bSjsg 	radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
14067ccd5a2cSjsg 	radeon_ring_write(ring, lower_32_bits(addr));
14071099013bSjsg 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
14081099013bSjsg 	radeon_ring_write(ring, fence->seq);
14091099013bSjsg 	radeon_ring_write(ring, 0);
14101099013bSjsg }
14111099013bSjsg 
cayman_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)14121099013bSjsg void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
14131099013bSjsg {
14141099013bSjsg 	struct radeon_ring *ring = &rdev->ring[ib->ring];
14157ccd5a2cSjsg 	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
1416bc26ceb1Sjsg 	u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
1417bc26ceb1Sjsg 		PACKET3_SH_ACTION_ENA;
14181099013bSjsg 
14191099013bSjsg 	/* set to DX10/11 mode */
14201099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
14211099013bSjsg 	radeon_ring_write(ring, 1);
14221099013bSjsg 
14231099013bSjsg 	if (ring->rptr_save_reg) {
14241099013bSjsg 		uint32_t next_rptr = ring->wptr + 3 + 4 + 8;
14251099013bSjsg 		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
14261099013bSjsg 		radeon_ring_write(ring, ((ring->rptr_save_reg -
14271099013bSjsg 					  PACKET3_SET_CONFIG_REG_START) >> 2));
14281099013bSjsg 		radeon_ring_write(ring, next_rptr);
14291099013bSjsg 	}
14301099013bSjsg 
14311099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
14321099013bSjsg 	radeon_ring_write(ring,
14331099013bSjsg #ifdef __BIG_ENDIAN
14341099013bSjsg 			  (2 << 0) |
14351099013bSjsg #endif
14361099013bSjsg 			  (ib->gpu_addr & 0xFFFFFFFC));
14371099013bSjsg 	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
14387ccd5a2cSjsg 	radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
14391099013bSjsg 
14401099013bSjsg 	/* flush read cache over gart for this vmid */
14411099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
1442bc26ceb1Sjsg 	radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
14431099013bSjsg 	radeon_ring_write(ring, 0xFFFFFFFF);
14441099013bSjsg 	radeon_ring_write(ring, 0);
14457ccd5a2cSjsg 	radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */
14461099013bSjsg }
14471099013bSjsg 
cayman_cp_enable(struct radeon_device * rdev,bool enable)14481099013bSjsg static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
14491099013bSjsg {
14501099013bSjsg 	if (enable)
14511099013bSjsg 		WREG32(CP_ME_CNTL, 0);
14521099013bSjsg 	else {
14537ccd5a2cSjsg 		if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
14541099013bSjsg 			radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
14551099013bSjsg 		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT));
14561099013bSjsg 		WREG32(SCRATCH_UMSK, 0);
14571099013bSjsg 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
14581099013bSjsg 	}
14591099013bSjsg }
14601099013bSjsg 
cayman_gfx_get_rptr(struct radeon_device * rdev,struct radeon_ring * ring)14617ccd5a2cSjsg u32 cayman_gfx_get_rptr(struct radeon_device *rdev,
14627ccd5a2cSjsg 			struct radeon_ring *ring)
14637ccd5a2cSjsg {
14647ccd5a2cSjsg 	u32 rptr;
14657ccd5a2cSjsg 
14667ccd5a2cSjsg 	if (rdev->wb.enabled)
14677ccd5a2cSjsg 		rptr = rdev->wb.wb[ring->rptr_offs/4];
14687ccd5a2cSjsg 	else {
14697ccd5a2cSjsg 		if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
14707ccd5a2cSjsg 			rptr = RREG32(CP_RB0_RPTR);
14717ccd5a2cSjsg 		else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
14727ccd5a2cSjsg 			rptr = RREG32(CP_RB1_RPTR);
14737ccd5a2cSjsg 		else
14747ccd5a2cSjsg 			rptr = RREG32(CP_RB2_RPTR);
14757ccd5a2cSjsg 	}
14767ccd5a2cSjsg 
14777ccd5a2cSjsg 	return rptr;
14787ccd5a2cSjsg }
14797ccd5a2cSjsg 
cayman_gfx_get_wptr(struct radeon_device * rdev,struct radeon_ring * ring)14807ccd5a2cSjsg u32 cayman_gfx_get_wptr(struct radeon_device *rdev,
14817ccd5a2cSjsg 			struct radeon_ring *ring)
14827ccd5a2cSjsg {
14837ccd5a2cSjsg 	u32 wptr;
14847ccd5a2cSjsg 
14857ccd5a2cSjsg 	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX)
14867ccd5a2cSjsg 		wptr = RREG32(CP_RB0_WPTR);
14877ccd5a2cSjsg 	else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX)
14887ccd5a2cSjsg 		wptr = RREG32(CP_RB1_WPTR);
14897ccd5a2cSjsg 	else
14907ccd5a2cSjsg 		wptr = RREG32(CP_RB2_WPTR);
14917ccd5a2cSjsg 
14927ccd5a2cSjsg 	return wptr;
14937ccd5a2cSjsg }
14947ccd5a2cSjsg 
cayman_gfx_set_wptr(struct radeon_device * rdev,struct radeon_ring * ring)14957ccd5a2cSjsg void cayman_gfx_set_wptr(struct radeon_device *rdev,
14967ccd5a2cSjsg 			 struct radeon_ring *ring)
14977ccd5a2cSjsg {
14987ccd5a2cSjsg 	if (ring->idx == RADEON_RING_TYPE_GFX_INDEX) {
14997ccd5a2cSjsg 		WREG32(CP_RB0_WPTR, ring->wptr);
15007ccd5a2cSjsg 		(void)RREG32(CP_RB0_WPTR);
15017ccd5a2cSjsg 	} else if (ring->idx == CAYMAN_RING_TYPE_CP1_INDEX) {
15027ccd5a2cSjsg 		WREG32(CP_RB1_WPTR, ring->wptr);
15037ccd5a2cSjsg 		(void)RREG32(CP_RB1_WPTR);
15047ccd5a2cSjsg 	} else {
15057ccd5a2cSjsg 		WREG32(CP_RB2_WPTR, ring->wptr);
15067ccd5a2cSjsg 		(void)RREG32(CP_RB2_WPTR);
15077ccd5a2cSjsg 	}
15087ccd5a2cSjsg }
15097ccd5a2cSjsg 
cayman_cp_load_microcode(struct radeon_device * rdev)15101099013bSjsg static int cayman_cp_load_microcode(struct radeon_device *rdev)
15111099013bSjsg {
15121099013bSjsg 	const __be32 *fw_data;
15131099013bSjsg 	int i;
15141099013bSjsg 
15151099013bSjsg 	if (!rdev->me_fw || !rdev->pfp_fw)
15161099013bSjsg 		return -EINVAL;
15171099013bSjsg 
15181099013bSjsg 	cayman_cp_enable(rdev, false);
15191099013bSjsg 
15207ccd5a2cSjsg 	fw_data = (const __be32 *)rdev->pfp_fw->data;
15211099013bSjsg 	WREG32(CP_PFP_UCODE_ADDR, 0);
15221099013bSjsg 	for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++)
15231099013bSjsg 		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
15241099013bSjsg 	WREG32(CP_PFP_UCODE_ADDR, 0);
15251099013bSjsg 
15267ccd5a2cSjsg 	fw_data = (const __be32 *)rdev->me_fw->data;
15271099013bSjsg 	WREG32(CP_ME_RAM_WADDR, 0);
15281099013bSjsg 	for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++)
15291099013bSjsg 		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
15301099013bSjsg 
15311099013bSjsg 	WREG32(CP_PFP_UCODE_ADDR, 0);
15321099013bSjsg 	WREG32(CP_ME_RAM_WADDR, 0);
15331099013bSjsg 	WREG32(CP_ME_RAM_RADDR, 0);
15341099013bSjsg 	return 0;
15351099013bSjsg }
15361099013bSjsg 
cayman_cp_start(struct radeon_device * rdev)15371099013bSjsg static int cayman_cp_start(struct radeon_device *rdev)
15381099013bSjsg {
15391099013bSjsg 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
15401099013bSjsg 	int r, i;
15411099013bSjsg 
15421099013bSjsg 	r = radeon_ring_lock(rdev, ring, 7);
15431099013bSjsg 	if (r) {
15441099013bSjsg 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
15451099013bSjsg 		return r;
15461099013bSjsg 	}
15471099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
15481099013bSjsg 	radeon_ring_write(ring, 0x1);
15491099013bSjsg 	radeon_ring_write(ring, 0x0);
15501099013bSjsg 	radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1);
15511099013bSjsg 	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
15521099013bSjsg 	radeon_ring_write(ring, 0);
15531099013bSjsg 	radeon_ring_write(ring, 0);
15547ccd5a2cSjsg 	radeon_ring_unlock_commit(rdev, ring, false);
15551099013bSjsg 
15561099013bSjsg 	cayman_cp_enable(rdev, true);
15571099013bSjsg 
15581099013bSjsg 	r = radeon_ring_lock(rdev, ring, cayman_default_size + 19);
15591099013bSjsg 	if (r) {
15601099013bSjsg 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
15611099013bSjsg 		return r;
15621099013bSjsg 	}
15631099013bSjsg 
15641099013bSjsg 	/* setup clear context state */
15651099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
15661099013bSjsg 	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
15671099013bSjsg 
15681099013bSjsg 	for (i = 0; i < cayman_default_size; i++)
15691099013bSjsg 		radeon_ring_write(ring, cayman_default_state[i]);
15701099013bSjsg 
15711099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
15721099013bSjsg 	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
15731099013bSjsg 
15741099013bSjsg 	/* set clear context state */
15751099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
15761099013bSjsg 	radeon_ring_write(ring, 0);
15771099013bSjsg 
15781099013bSjsg 	/* SQ_VTX_BASE_VTX_LOC */
15791099013bSjsg 	radeon_ring_write(ring, 0xc0026f00);
15801099013bSjsg 	radeon_ring_write(ring, 0x00000000);
15811099013bSjsg 	radeon_ring_write(ring, 0x00000000);
15821099013bSjsg 	radeon_ring_write(ring, 0x00000000);
15831099013bSjsg 
15841099013bSjsg 	/* Clear consts */
15851099013bSjsg 	radeon_ring_write(ring, 0xc0036f00);
15861099013bSjsg 	radeon_ring_write(ring, 0x00000bc4);
15871099013bSjsg 	radeon_ring_write(ring, 0xffffffff);
15881099013bSjsg 	radeon_ring_write(ring, 0xffffffff);
15891099013bSjsg 	radeon_ring_write(ring, 0xffffffff);
15901099013bSjsg 
15911099013bSjsg 	radeon_ring_write(ring, 0xc0026900);
15921099013bSjsg 	radeon_ring_write(ring, 0x00000316);
15931099013bSjsg 	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
15941099013bSjsg 	radeon_ring_write(ring, 0x00000010); /*  */
15951099013bSjsg 
15967ccd5a2cSjsg 	radeon_ring_unlock_commit(rdev, ring, false);
15971099013bSjsg 
15981099013bSjsg 	/* XXX init other rings */
15991099013bSjsg 
16001099013bSjsg 	return 0;
16011099013bSjsg }
16021099013bSjsg 
cayman_cp_fini(struct radeon_device * rdev)16031099013bSjsg static void cayman_cp_fini(struct radeon_device *rdev)
16041099013bSjsg {
16051099013bSjsg 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
16061099013bSjsg 	cayman_cp_enable(rdev, false);
16071099013bSjsg 	radeon_ring_fini(rdev, ring);
16081099013bSjsg 	radeon_scratch_free(rdev, ring->rptr_save_reg);
16091099013bSjsg }
16101099013bSjsg 
cayman_cp_resume(struct radeon_device * rdev)16111099013bSjsg static int cayman_cp_resume(struct radeon_device *rdev)
16121099013bSjsg {
16131099013bSjsg 	static const int ridx[] = {
16141099013bSjsg 		RADEON_RING_TYPE_GFX_INDEX,
16151099013bSjsg 		CAYMAN_RING_TYPE_CP1_INDEX,
16161099013bSjsg 		CAYMAN_RING_TYPE_CP2_INDEX
16171099013bSjsg 	};
16181099013bSjsg 	static const unsigned cp_rb_cntl[] = {
16191099013bSjsg 		CP_RB0_CNTL,
16201099013bSjsg 		CP_RB1_CNTL,
16211099013bSjsg 		CP_RB2_CNTL,
16221099013bSjsg 	};
16231099013bSjsg 	static const unsigned cp_rb_rptr_addr[] = {
16241099013bSjsg 		CP_RB0_RPTR_ADDR,
16251099013bSjsg 		CP_RB1_RPTR_ADDR,
16261099013bSjsg 		CP_RB2_RPTR_ADDR
16271099013bSjsg 	};
16281099013bSjsg 	static const unsigned cp_rb_rptr_addr_hi[] = {
16291099013bSjsg 		CP_RB0_RPTR_ADDR_HI,
16301099013bSjsg 		CP_RB1_RPTR_ADDR_HI,
16311099013bSjsg 		CP_RB2_RPTR_ADDR_HI
16321099013bSjsg 	};
16331099013bSjsg 	static const unsigned cp_rb_base[] = {
16341099013bSjsg 		CP_RB0_BASE,
16351099013bSjsg 		CP_RB1_BASE,
16361099013bSjsg 		CP_RB2_BASE
16371099013bSjsg 	};
16387ccd5a2cSjsg 	static const unsigned cp_rb_rptr[] = {
16397ccd5a2cSjsg 		CP_RB0_RPTR,
16407ccd5a2cSjsg 		CP_RB1_RPTR,
16417ccd5a2cSjsg 		CP_RB2_RPTR
16427ccd5a2cSjsg 	};
16437ccd5a2cSjsg 	static const unsigned cp_rb_wptr[] = {
16447ccd5a2cSjsg 		CP_RB0_WPTR,
16457ccd5a2cSjsg 		CP_RB1_WPTR,
16467ccd5a2cSjsg 		CP_RB2_WPTR
16477ccd5a2cSjsg 	};
16481099013bSjsg 	struct radeon_ring *ring;
16491099013bSjsg 	int i, r;
16501099013bSjsg 
16511099013bSjsg 	/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
16521099013bSjsg 	WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
16531099013bSjsg 				 SOFT_RESET_PA |
16541099013bSjsg 				 SOFT_RESET_SH |
16551099013bSjsg 				 SOFT_RESET_VGT |
16561099013bSjsg 				 SOFT_RESET_SPI |
16571099013bSjsg 				 SOFT_RESET_SX));
16581099013bSjsg 	RREG32(GRBM_SOFT_RESET);
16591099013bSjsg 	mdelay(15);
16601099013bSjsg 	WREG32(GRBM_SOFT_RESET, 0);
16611099013bSjsg 	RREG32(GRBM_SOFT_RESET);
16621099013bSjsg 
16631099013bSjsg 	WREG32(CP_SEM_WAIT_TIMER, 0x0);
16641099013bSjsg 	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
16651099013bSjsg 
16661099013bSjsg 	/* Set the write pointer delay */
16671099013bSjsg 	WREG32(CP_RB_WPTR_DELAY, 0);
16681099013bSjsg 
16691099013bSjsg 	WREG32(CP_DEBUG, (1 << 27));
16701099013bSjsg 
16711099013bSjsg 	/* set the wb address whether it's enabled or not */
16721099013bSjsg 	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
16731099013bSjsg 	WREG32(SCRATCH_UMSK, 0xff);
16741099013bSjsg 
16751099013bSjsg 	for (i = 0; i < 3; ++i) {
16761099013bSjsg 		uint32_t rb_cntl;
16771099013bSjsg 		uint64_t addr;
16781099013bSjsg 
16791099013bSjsg 		/* Set ring buffer size */
16801099013bSjsg 		ring = &rdev->ring[ridx[i]];
16817ccd5a2cSjsg 		rb_cntl = order_base_2(ring->ring_size / 8);
16827ccd5a2cSjsg 		rb_cntl |= order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8;
16831099013bSjsg #ifdef __BIG_ENDIAN
16841099013bSjsg 		rb_cntl |= BUF_SWAP_32BIT;
16851099013bSjsg #endif
16861099013bSjsg 		WREG32(cp_rb_cntl[i], rb_cntl);
16871099013bSjsg 
16881099013bSjsg 		/* set the wb address whether it's enabled or not */
16891099013bSjsg 		addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET;
16901099013bSjsg 		WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC);
16911099013bSjsg 		WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF);
16921099013bSjsg 	}
16931099013bSjsg 
16941099013bSjsg 	/* set the rb base addr, this causes an internal reset of ALL rings */
16951099013bSjsg 	for (i = 0; i < 3; ++i) {
16961099013bSjsg 		ring = &rdev->ring[ridx[i]];
16971099013bSjsg 		WREG32(cp_rb_base[i], ring->gpu_addr >> 8);
16981099013bSjsg 	}
16991099013bSjsg 
17001099013bSjsg 	for (i = 0; i < 3; ++i) {
17011099013bSjsg 		/* Initialize the ring buffer's read and write pointers */
17021099013bSjsg 		ring = &rdev->ring[ridx[i]];
17031099013bSjsg 		WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA);
17041099013bSjsg 
17057ccd5a2cSjsg 		ring->wptr = 0;
17067ccd5a2cSjsg 		WREG32(cp_rb_rptr[i], 0);
17077ccd5a2cSjsg 		WREG32(cp_rb_wptr[i], ring->wptr);
17081099013bSjsg 
17091099013bSjsg 		mdelay(1);
17101099013bSjsg 		WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA);
17111099013bSjsg 	}
17121099013bSjsg 
17131099013bSjsg 	/* start the rings */
17141099013bSjsg 	cayman_cp_start(rdev);
17151099013bSjsg 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
17161099013bSjsg 	rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
17171099013bSjsg 	rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
17181099013bSjsg 	/* this only test cp0 */
17191099013bSjsg 	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
17201099013bSjsg 	if (r) {
17211099013bSjsg 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
17221099013bSjsg 		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
17231099013bSjsg 		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
17241099013bSjsg 		return r;
17251099013bSjsg 	}
17261099013bSjsg 
17277ccd5a2cSjsg 	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
17281099013bSjsg 		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
17291099013bSjsg 
17301099013bSjsg 	return 0;
17311099013bSjsg }
17321099013bSjsg 
cayman_gpu_check_soft_reset(struct radeon_device * rdev)17337ccd5a2cSjsg u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev)
17341099013bSjsg {
17357ccd5a2cSjsg 	u32 reset_mask = 0;
17367ccd5a2cSjsg 	u32 tmp;
17377ccd5a2cSjsg 
17387ccd5a2cSjsg 	/* GRBM_STATUS */
17397ccd5a2cSjsg 	tmp = RREG32(GRBM_STATUS);
17407ccd5a2cSjsg 	if (tmp & (PA_BUSY | SC_BUSY |
17417ccd5a2cSjsg 		   SH_BUSY | SX_BUSY |
17427ccd5a2cSjsg 		   TA_BUSY | VGT_BUSY |
17437ccd5a2cSjsg 		   DB_BUSY | CB_BUSY |
17447ccd5a2cSjsg 		   GDS_BUSY | SPI_BUSY |
17457ccd5a2cSjsg 		   IA_BUSY | IA_BUSY_NO_DMA))
17467ccd5a2cSjsg 		reset_mask |= RADEON_RESET_GFX;
17477ccd5a2cSjsg 
17487ccd5a2cSjsg 	if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
17497ccd5a2cSjsg 		   CP_BUSY | CP_COHERENCY_BUSY))
17507ccd5a2cSjsg 		reset_mask |= RADEON_RESET_CP;
17517ccd5a2cSjsg 
17527ccd5a2cSjsg 	if (tmp & GRBM_EE_BUSY)
17537ccd5a2cSjsg 		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
17547ccd5a2cSjsg 
17557ccd5a2cSjsg 	/* DMA_STATUS_REG 0 */
17567ccd5a2cSjsg 	tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
17577ccd5a2cSjsg 	if (!(tmp & DMA_IDLE))
17587ccd5a2cSjsg 		reset_mask |= RADEON_RESET_DMA;
17597ccd5a2cSjsg 
17607ccd5a2cSjsg 	/* DMA_STATUS_REG 1 */
17617ccd5a2cSjsg 	tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
17627ccd5a2cSjsg 	if (!(tmp & DMA_IDLE))
17637ccd5a2cSjsg 		reset_mask |= RADEON_RESET_DMA1;
17647ccd5a2cSjsg 
17657ccd5a2cSjsg 	/* SRBM_STATUS2 */
17667ccd5a2cSjsg 	tmp = RREG32(SRBM_STATUS2);
17677ccd5a2cSjsg 	if (tmp & DMA_BUSY)
17687ccd5a2cSjsg 		reset_mask |= RADEON_RESET_DMA;
17697ccd5a2cSjsg 
17707ccd5a2cSjsg 	if (tmp & DMA1_BUSY)
17717ccd5a2cSjsg 		reset_mask |= RADEON_RESET_DMA1;
17727ccd5a2cSjsg 
17737ccd5a2cSjsg 	/* SRBM_STATUS */
17747ccd5a2cSjsg 	tmp = RREG32(SRBM_STATUS);
17757ccd5a2cSjsg 	if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
17767ccd5a2cSjsg 		reset_mask |= RADEON_RESET_RLC;
17777ccd5a2cSjsg 
17787ccd5a2cSjsg 	if (tmp & IH_BUSY)
17797ccd5a2cSjsg 		reset_mask |= RADEON_RESET_IH;
17807ccd5a2cSjsg 
17817ccd5a2cSjsg 	if (tmp & SEM_BUSY)
17827ccd5a2cSjsg 		reset_mask |= RADEON_RESET_SEM;
17837ccd5a2cSjsg 
17847ccd5a2cSjsg 	if (tmp & GRBM_RQ_PENDING)
17857ccd5a2cSjsg 		reset_mask |= RADEON_RESET_GRBM;
17867ccd5a2cSjsg 
17877ccd5a2cSjsg 	if (tmp & VMC_BUSY)
17887ccd5a2cSjsg 		reset_mask |= RADEON_RESET_VMC;
17897ccd5a2cSjsg 
17907ccd5a2cSjsg 	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
17917ccd5a2cSjsg 		   MCC_BUSY | MCD_BUSY))
17927ccd5a2cSjsg 		reset_mask |= RADEON_RESET_MC;
17937ccd5a2cSjsg 
17947ccd5a2cSjsg 	if (evergreen_is_display_hung(rdev))
17957ccd5a2cSjsg 		reset_mask |= RADEON_RESET_DISPLAY;
17967ccd5a2cSjsg 
17977ccd5a2cSjsg 	/* VM_L2_STATUS */
17987ccd5a2cSjsg 	tmp = RREG32(VM_L2_STATUS);
17997ccd5a2cSjsg 	if (tmp & L2_BUSY)
18007ccd5a2cSjsg 		reset_mask |= RADEON_RESET_VMC;
18017ccd5a2cSjsg 
18027ccd5a2cSjsg 	/* Skip MC reset as it's mostly likely not hung, just busy */
18037ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_MC) {
18047ccd5a2cSjsg 		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
18057ccd5a2cSjsg 		reset_mask &= ~RADEON_RESET_MC;
18061099013bSjsg 	}
18071099013bSjsg 
18087ccd5a2cSjsg 	return reset_mask;
18097ccd5a2cSjsg }
181039214a00Sderaadt 
cayman_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)18117ccd5a2cSjsg static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
18127ccd5a2cSjsg {
18137ccd5a2cSjsg 	struct evergreen_mc_save save;
18147ccd5a2cSjsg 	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
18157ccd5a2cSjsg 	u32 tmp;
18167ccd5a2cSjsg 
18177ccd5a2cSjsg 	if (reset_mask == 0)
18181099013bSjsg 		return;
18191099013bSjsg 
18207ccd5a2cSjsg 	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
18217ccd5a2cSjsg 
18227ccd5a2cSjsg 	evergreen_print_gpu_status_regs(rdev);
18237ccd5a2cSjsg 	dev_info(rdev->dev, "  VM_CONTEXT0_PROTECTION_FAULT_ADDR   0x%08X\n",
18247ccd5a2cSjsg 		 RREG32(0x14F8));
18257ccd5a2cSjsg 	dev_info(rdev->dev, "  VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
18267ccd5a2cSjsg 		 RREG32(0x14D8));
18277ccd5a2cSjsg 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
18287ccd5a2cSjsg 		 RREG32(0x14FC));
18297ccd5a2cSjsg 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
18307ccd5a2cSjsg 		 RREG32(0x14DC));
18311099013bSjsg 
18321099013bSjsg 	/* Disable CP parsing/prefetching */
18331099013bSjsg 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
18341099013bSjsg 
18357ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_DMA) {
18367ccd5a2cSjsg 		/* dma0 */
18377ccd5a2cSjsg 		tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
18387ccd5a2cSjsg 		tmp &= ~DMA_RB_ENABLE;
18397ccd5a2cSjsg 		WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
18407ccd5a2cSjsg 	}
18417ccd5a2cSjsg 
18427ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_DMA1) {
18437ccd5a2cSjsg 		/* dma1 */
18447ccd5a2cSjsg 		tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
18457ccd5a2cSjsg 		tmp &= ~DMA_RB_ENABLE;
18467ccd5a2cSjsg 		WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
18477ccd5a2cSjsg 	}
18487ccd5a2cSjsg 
18497ccd5a2cSjsg 	udelay(50);
18507ccd5a2cSjsg 
18517ccd5a2cSjsg 	evergreen_mc_stop(rdev, &save);
18527ccd5a2cSjsg 	if (evergreen_mc_wait_for_idle(rdev)) {
18537ccd5a2cSjsg 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
18547ccd5a2cSjsg 	}
18557ccd5a2cSjsg 
18567ccd5a2cSjsg 	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
18577ccd5a2cSjsg 		grbm_soft_reset = SOFT_RESET_CB |
18581099013bSjsg 			SOFT_RESET_DB |
18591099013bSjsg 			SOFT_RESET_GDS |
18601099013bSjsg 			SOFT_RESET_PA |
18611099013bSjsg 			SOFT_RESET_SC |
18621099013bSjsg 			SOFT_RESET_SPI |
18631099013bSjsg 			SOFT_RESET_SH |
18641099013bSjsg 			SOFT_RESET_SX |
18651099013bSjsg 			SOFT_RESET_TC |
18661099013bSjsg 			SOFT_RESET_TA |
18671099013bSjsg 			SOFT_RESET_VGT |
18687ccd5a2cSjsg 			SOFT_RESET_IA;
18691099013bSjsg 	}
18701099013bSjsg 
18717ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_CP) {
18727ccd5a2cSjsg 		grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
18731099013bSjsg 
18747ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_GRBM;
18751099013bSjsg 	}
18761099013bSjsg 
18771099013bSjsg 	if (reset_mask & RADEON_RESET_DMA)
18787ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_DMA;
18797ccd5a2cSjsg 
18807ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_DMA1)
18817ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_DMA1;
18827ccd5a2cSjsg 
18837ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_DISPLAY)
18847ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_DC;
18857ccd5a2cSjsg 
18867ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_RLC)
18877ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_RLC;
18887ccd5a2cSjsg 
18897ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_SEM)
18907ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_SEM;
18917ccd5a2cSjsg 
18927ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_IH)
18937ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_IH;
18947ccd5a2cSjsg 
18957ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_GRBM)
18967ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_GRBM;
18977ccd5a2cSjsg 
18987ccd5a2cSjsg 	if (reset_mask & RADEON_RESET_VMC)
18997ccd5a2cSjsg 		srbm_soft_reset |= SOFT_RESET_VMC;
19007ccd5a2cSjsg 
19017ccd5a2cSjsg 	if (!(rdev->flags & RADEON_IS_IGP)) {
19027ccd5a2cSjsg 		if (reset_mask & RADEON_RESET_MC)
19037ccd5a2cSjsg 			srbm_soft_reset |= SOFT_RESET_MC;
19047ccd5a2cSjsg 	}
19057ccd5a2cSjsg 
19067ccd5a2cSjsg 	if (grbm_soft_reset) {
19077ccd5a2cSjsg 		tmp = RREG32(GRBM_SOFT_RESET);
19087ccd5a2cSjsg 		tmp |= grbm_soft_reset;
19097ccd5a2cSjsg 		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
19107ccd5a2cSjsg 		WREG32(GRBM_SOFT_RESET, tmp);
19117ccd5a2cSjsg 		tmp = RREG32(GRBM_SOFT_RESET);
19127ccd5a2cSjsg 
19137ccd5a2cSjsg 		udelay(50);
19147ccd5a2cSjsg 
19157ccd5a2cSjsg 		tmp &= ~grbm_soft_reset;
19167ccd5a2cSjsg 		WREG32(GRBM_SOFT_RESET, tmp);
19177ccd5a2cSjsg 		tmp = RREG32(GRBM_SOFT_RESET);
19187ccd5a2cSjsg 	}
19197ccd5a2cSjsg 
19207ccd5a2cSjsg 	if (srbm_soft_reset) {
19217ccd5a2cSjsg 		tmp = RREG32(SRBM_SOFT_RESET);
19227ccd5a2cSjsg 		tmp |= srbm_soft_reset;
19237ccd5a2cSjsg 		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
19247ccd5a2cSjsg 		WREG32(SRBM_SOFT_RESET, tmp);
19257ccd5a2cSjsg 		tmp = RREG32(SRBM_SOFT_RESET);
19267ccd5a2cSjsg 
19277ccd5a2cSjsg 		udelay(50);
19287ccd5a2cSjsg 
19297ccd5a2cSjsg 		tmp &= ~srbm_soft_reset;
19307ccd5a2cSjsg 		WREG32(SRBM_SOFT_RESET, tmp);
19317ccd5a2cSjsg 		tmp = RREG32(SRBM_SOFT_RESET);
19327ccd5a2cSjsg 	}
19331099013bSjsg 
19341099013bSjsg 	/* Wait a little for things to settle down */
19351099013bSjsg 	udelay(50);
19361099013bSjsg 
19371099013bSjsg 	evergreen_mc_resume(rdev, &save);
19387ccd5a2cSjsg 	udelay(50);
19397ccd5a2cSjsg 
19407ccd5a2cSjsg 	evergreen_print_gpu_status_regs(rdev);
19411099013bSjsg }
19421099013bSjsg 
cayman_asic_reset(struct radeon_device * rdev,bool hard)19437f4dd379Sjsg int cayman_asic_reset(struct radeon_device *rdev, bool hard)
19441099013bSjsg {
19457ccd5a2cSjsg 	u32 reset_mask;
19467ccd5a2cSjsg 
19477f4dd379Sjsg 	if (hard) {
19487f4dd379Sjsg 		evergreen_gpu_pci_config_reset(rdev);
19497f4dd379Sjsg 		return 0;
19507f4dd379Sjsg 	}
19517f4dd379Sjsg 
19527ccd5a2cSjsg 	reset_mask = cayman_gpu_check_soft_reset(rdev);
19537ccd5a2cSjsg 
19547ccd5a2cSjsg 	if (reset_mask)
19557ccd5a2cSjsg 		r600_set_bios_scratch_engine_hung(rdev, true);
19567ccd5a2cSjsg 
19577ccd5a2cSjsg 	cayman_gpu_soft_reset(rdev, reset_mask);
19587ccd5a2cSjsg 
19597ccd5a2cSjsg 	reset_mask = cayman_gpu_check_soft_reset(rdev);
19607ccd5a2cSjsg 
19617ccd5a2cSjsg 	if (reset_mask)
19627ccd5a2cSjsg 		evergreen_gpu_pci_config_reset(rdev);
19637ccd5a2cSjsg 
19647ccd5a2cSjsg 	r600_set_bios_scratch_engine_hung(rdev, false);
19657ccd5a2cSjsg 
19667ccd5a2cSjsg 	return 0;
19671099013bSjsg }
19681099013bSjsg 
19691099013bSjsg /**
19707ccd5a2cSjsg  * cayman_gfx_is_lockup - Check if the GFX engine is locked up
19711099013bSjsg  *
19721099013bSjsg  * @rdev: radeon_device pointer
19731099013bSjsg  * @ring: radeon_ring structure holding ring information
19741099013bSjsg  *
19757ccd5a2cSjsg  * Check if the GFX engine is locked up.
19761099013bSjsg  * Returns true if the engine appears to be locked up, false if not.
19771099013bSjsg  */
cayman_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)19787ccd5a2cSjsg bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
19791099013bSjsg {
19807ccd5a2cSjsg 	u32 reset_mask = cayman_gpu_check_soft_reset(rdev);
19811099013bSjsg 
19827ccd5a2cSjsg 	if (!(reset_mask & (RADEON_RESET_GFX |
19837ccd5a2cSjsg 			    RADEON_RESET_COMPUTE |
19847ccd5a2cSjsg 			    RADEON_RESET_CP))) {
19857ccd5a2cSjsg 		radeon_ring_lockup_update(rdev, ring);
19861099013bSjsg 		return false;
19871099013bSjsg 	}
19881099013bSjsg 	return radeon_ring_test_lockup(rdev, ring);
19891099013bSjsg }
19901099013bSjsg 
cayman_uvd_init(struct radeon_device * rdev)19917f4dd379Sjsg static void cayman_uvd_init(struct radeon_device *rdev)
19927f4dd379Sjsg {
19937f4dd379Sjsg 	int r;
19947f4dd379Sjsg 
19957f4dd379Sjsg 	if (!rdev->has_uvd)
19967f4dd379Sjsg 		return;
19977f4dd379Sjsg 
19987f4dd379Sjsg 	r = radeon_uvd_init(rdev);
19997f4dd379Sjsg 	if (r) {
20007f4dd379Sjsg 		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
20017f4dd379Sjsg 		/*
20027f4dd379Sjsg 		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
20037f4dd379Sjsg 		 * to early fails uvd_v2_2_resume() and thus nothing happens
20047f4dd379Sjsg 		 * there. So it is pointless to try to go through that code
20057f4dd379Sjsg 		 * hence why we disable uvd here.
20067f4dd379Sjsg 		 */
2007c349dbc7Sjsg 		rdev->has_uvd = false;
20087f4dd379Sjsg 		return;
20097f4dd379Sjsg 	}
20107f4dd379Sjsg 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
20117f4dd379Sjsg 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
20127f4dd379Sjsg }
20137f4dd379Sjsg 
cayman_uvd_start(struct radeon_device * rdev)20147f4dd379Sjsg static void cayman_uvd_start(struct radeon_device *rdev)
20157f4dd379Sjsg {
20167f4dd379Sjsg 	int r;
20177f4dd379Sjsg 
20187f4dd379Sjsg 	if (!rdev->has_uvd)
20197f4dd379Sjsg 		return;
20207f4dd379Sjsg 
20217f4dd379Sjsg 	r = uvd_v2_2_resume(rdev);
20227f4dd379Sjsg 	if (r) {
20237f4dd379Sjsg 		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
20247f4dd379Sjsg 		goto error;
20257f4dd379Sjsg 	}
20267f4dd379Sjsg 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
20277f4dd379Sjsg 	if (r) {
20287f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
20297f4dd379Sjsg 		goto error;
20307f4dd379Sjsg 	}
20317f4dd379Sjsg 	return;
20327f4dd379Sjsg 
20337f4dd379Sjsg error:
20347f4dd379Sjsg 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
20357f4dd379Sjsg }
20367f4dd379Sjsg 
cayman_uvd_resume(struct radeon_device * rdev)20377f4dd379Sjsg static void cayman_uvd_resume(struct radeon_device *rdev)
20387f4dd379Sjsg {
20397f4dd379Sjsg 	struct radeon_ring *ring;
20407f4dd379Sjsg 	int r;
20417f4dd379Sjsg 
20427f4dd379Sjsg 	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
20437f4dd379Sjsg 		return;
20447f4dd379Sjsg 
20457f4dd379Sjsg 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
20467f4dd379Sjsg 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
20477f4dd379Sjsg 	if (r) {
20487f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
20497f4dd379Sjsg 		return;
20507f4dd379Sjsg 	}
20517f4dd379Sjsg 	r = uvd_v1_0_init(rdev);
20527f4dd379Sjsg 	if (r) {
20537f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
20547f4dd379Sjsg 		return;
20557f4dd379Sjsg 	}
20567f4dd379Sjsg }
20577f4dd379Sjsg 
cayman_vce_init(struct radeon_device * rdev)20587f4dd379Sjsg static void cayman_vce_init(struct radeon_device *rdev)
20597f4dd379Sjsg {
20607f4dd379Sjsg 	int r;
20617f4dd379Sjsg 
20627f4dd379Sjsg 	/* Only set for CHIP_ARUBA */
20637f4dd379Sjsg 	if (!rdev->has_vce)
20647f4dd379Sjsg 		return;
20657f4dd379Sjsg 
20667f4dd379Sjsg 	r = radeon_vce_init(rdev);
20677f4dd379Sjsg 	if (r) {
20687f4dd379Sjsg 		dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
20697f4dd379Sjsg 		/*
20707f4dd379Sjsg 		 * At this point rdev->vce.vcpu_bo is NULL which trickles down
20717f4dd379Sjsg 		 * to early fails cayman_vce_start() and thus nothing happens
20727f4dd379Sjsg 		 * there. So it is pointless to try to go through that code
20737f4dd379Sjsg 		 * hence why we disable vce here.
20747f4dd379Sjsg 		 */
2075c349dbc7Sjsg 		rdev->has_vce = false;
20767f4dd379Sjsg 		return;
20777f4dd379Sjsg 	}
20787f4dd379Sjsg 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
20797f4dd379Sjsg 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
20807f4dd379Sjsg 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
20817f4dd379Sjsg 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
20827f4dd379Sjsg }
20837f4dd379Sjsg 
cayman_vce_start(struct radeon_device * rdev)20847f4dd379Sjsg static void cayman_vce_start(struct radeon_device *rdev)
20857f4dd379Sjsg {
20867f4dd379Sjsg 	int r;
20877f4dd379Sjsg 
20887f4dd379Sjsg 	if (!rdev->has_vce)
20897f4dd379Sjsg 		return;
20907f4dd379Sjsg 
20917f4dd379Sjsg 	r = radeon_vce_resume(rdev);
20927f4dd379Sjsg 	if (r) {
20937f4dd379Sjsg 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
20947f4dd379Sjsg 		goto error;
20957f4dd379Sjsg 	}
20967f4dd379Sjsg 	r = vce_v1_0_resume(rdev);
20977f4dd379Sjsg 	if (r) {
20987f4dd379Sjsg 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
20997f4dd379Sjsg 		goto error;
21007f4dd379Sjsg 	}
21017f4dd379Sjsg 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
21027f4dd379Sjsg 	if (r) {
21037f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
21047f4dd379Sjsg 		goto error;
21057f4dd379Sjsg 	}
21067f4dd379Sjsg 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
21077f4dd379Sjsg 	if (r) {
21087f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
21097f4dd379Sjsg 		goto error;
21107f4dd379Sjsg 	}
21117f4dd379Sjsg 	return;
21127f4dd379Sjsg 
21137f4dd379Sjsg error:
21147f4dd379Sjsg 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
21157f4dd379Sjsg 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
21167f4dd379Sjsg }
21177f4dd379Sjsg 
cayman_vce_resume(struct radeon_device * rdev)21187f4dd379Sjsg static void cayman_vce_resume(struct radeon_device *rdev)
21197f4dd379Sjsg {
21207f4dd379Sjsg 	struct radeon_ring *ring;
21217f4dd379Sjsg 	int r;
21227f4dd379Sjsg 
21237f4dd379Sjsg 	if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
21247f4dd379Sjsg 		return;
21257f4dd379Sjsg 
21267f4dd379Sjsg 	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
21277f4dd379Sjsg 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
21287f4dd379Sjsg 	if (r) {
21297f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
21307f4dd379Sjsg 		return;
21317f4dd379Sjsg 	}
21327f4dd379Sjsg 	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
21337f4dd379Sjsg 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, 0x0);
21347f4dd379Sjsg 	if (r) {
21357f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
21367f4dd379Sjsg 		return;
21377f4dd379Sjsg 	}
21387f4dd379Sjsg 	r = vce_v1_0_init(rdev);
21397f4dd379Sjsg 	if (r) {
21407f4dd379Sjsg 		dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
21417f4dd379Sjsg 		return;
21427f4dd379Sjsg 	}
21437f4dd379Sjsg }
21447f4dd379Sjsg 
cayman_startup(struct radeon_device * rdev)21451099013bSjsg static int cayman_startup(struct radeon_device *rdev)
21461099013bSjsg {
21471099013bSjsg 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
21481099013bSjsg 	int r;
21491099013bSjsg 
21501099013bSjsg 	/* enable pcie gen2 link */
21511099013bSjsg 	evergreen_pcie_gen2_enable(rdev);
21527ccd5a2cSjsg 	/* enable aspm */
21537ccd5a2cSjsg 	evergreen_program_aspm(rdev);
21547ccd5a2cSjsg 
21557ccd5a2cSjsg 	/* scratch needs to be initialized before MC */
21567ccd5a2cSjsg 	r = r600_vram_scratch_init(rdev);
21577ccd5a2cSjsg 	if (r)
21587ccd5a2cSjsg 		return r;
21591099013bSjsg 
21604745e775Sjsg 	evergreen_mc_program(rdev);
21614745e775Sjsg 
21627ccd5a2cSjsg 	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
21631099013bSjsg 		r = ni_mc_load_microcode(rdev);
21641099013bSjsg 		if (r) {
21651099013bSjsg 			DRM_ERROR("Failed to load MC firmware!\n");
21661099013bSjsg 			return r;
21671099013bSjsg 		}
21681099013bSjsg 	}
21691099013bSjsg 
21701099013bSjsg 	r = cayman_pcie_gart_enable(rdev);
21711099013bSjsg 	if (r)
21721099013bSjsg 		return r;
21731099013bSjsg 	cayman_gpu_init(rdev);
21741099013bSjsg 
21751099013bSjsg 	/* allocate rlc buffers */
21761099013bSjsg 	if (rdev->flags & RADEON_IS_IGP) {
21777ccd5a2cSjsg 		rdev->rlc.reg_list = tn_rlc_save_restore_register_list;
21787ccd5a2cSjsg 		rdev->rlc.reg_list_size =
21797ccd5a2cSjsg 			(u32)ARRAY_SIZE(tn_rlc_save_restore_register_list);
21807ccd5a2cSjsg 		rdev->rlc.cs_data = cayman_cs_data;
21817ccd5a2cSjsg 		r = sumo_rlc_init(rdev);
21821099013bSjsg 		if (r) {
21831099013bSjsg 			DRM_ERROR("Failed to init rlc BOs!\n");
21841099013bSjsg 			return r;
21851099013bSjsg 		}
21861099013bSjsg 	}
21871099013bSjsg 
21881099013bSjsg 	/* allocate wb buffer */
21891099013bSjsg 	r = radeon_wb_init(rdev);
21901099013bSjsg 	if (r)
21911099013bSjsg 		return r;
21921099013bSjsg 
21931099013bSjsg 	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
21941099013bSjsg 	if (r) {
21951099013bSjsg 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
21961099013bSjsg 		return r;
21971099013bSjsg 	}
21981099013bSjsg 
21997f4dd379Sjsg 	cayman_uvd_start(rdev);
22007f4dd379Sjsg 	cayman_vce_start(rdev);
22017ccd5a2cSjsg 
22021099013bSjsg 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
22031099013bSjsg 	if (r) {
22041099013bSjsg 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
22051099013bSjsg 		return r;
22061099013bSjsg 	}
22071099013bSjsg 
22081099013bSjsg 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
22091099013bSjsg 	if (r) {
22101099013bSjsg 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
22111099013bSjsg 		return r;
22121099013bSjsg 	}
22131099013bSjsg 
22141099013bSjsg 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
22151099013bSjsg 	if (r) {
22161099013bSjsg 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
22171099013bSjsg 		return r;
22181099013bSjsg 	}
22191099013bSjsg 
22201099013bSjsg 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
22211099013bSjsg 	if (r) {
22221099013bSjsg 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
22231099013bSjsg 		return r;
22241099013bSjsg 	}
22251099013bSjsg 
22261099013bSjsg 	/* Enable IRQ */
222755fe5614Sjsg 	if (!rdev->irq.installed) {
222855fe5614Sjsg 		r = radeon_irq_kms_init(rdev);
222955fe5614Sjsg 		if (r)
223055fe5614Sjsg 			return r;
223155fe5614Sjsg 	}
223255fe5614Sjsg 
22331099013bSjsg 	r = r600_irq_init(rdev);
22341099013bSjsg 	if (r) {
22351099013bSjsg 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
22361099013bSjsg 		radeon_irq_kms_fini(rdev);
22371099013bSjsg 		return r;
22381099013bSjsg 	}
22391099013bSjsg 	evergreen_irq_set(rdev);
22401099013bSjsg 
22411099013bSjsg 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
22427ccd5a2cSjsg 			     RADEON_CP_PACKET2);
22431099013bSjsg 	if (r)
22441099013bSjsg 		return r;
22451099013bSjsg 
22461099013bSjsg 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
22471099013bSjsg 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
22487ccd5a2cSjsg 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
22491099013bSjsg 	if (r)
22501099013bSjsg 		return r;
22511099013bSjsg 
22521099013bSjsg 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
22531099013bSjsg 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
22547ccd5a2cSjsg 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
22551099013bSjsg 	if (r)
22561099013bSjsg 		return r;
22571099013bSjsg 
22581099013bSjsg 	r = cayman_cp_load_microcode(rdev);
22591099013bSjsg 	if (r)
22601099013bSjsg 		return r;
22611099013bSjsg 	r = cayman_cp_resume(rdev);
22621099013bSjsg 	if (r)
22631099013bSjsg 		return r;
22641099013bSjsg 
22651099013bSjsg 	r = cayman_dma_resume(rdev);
22661099013bSjsg 	if (r)
22671099013bSjsg 		return r;
22681099013bSjsg 
22697f4dd379Sjsg 	cayman_uvd_resume(rdev);
22707f4dd379Sjsg 	cayman_vce_resume(rdev);
22717ccd5a2cSjsg 
22721099013bSjsg 	r = radeon_ib_pool_init(rdev);
22731099013bSjsg 	if (r) {
22741099013bSjsg 		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
22751099013bSjsg 		return r;
22761099013bSjsg 	}
22771099013bSjsg 
22781099013bSjsg 	r = radeon_vm_manager_init(rdev);
22791099013bSjsg 	if (r) {
22801099013bSjsg 		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
22811099013bSjsg 		return r;
22821099013bSjsg 	}
22831099013bSjsg 
22847ccd5a2cSjsg 	r = radeon_audio_init(rdev);
22851099013bSjsg 	if (r)
22861099013bSjsg 		return r;
22871099013bSjsg 
22881099013bSjsg 	return 0;
22891099013bSjsg }
22901099013bSjsg 
cayman_resume(struct radeon_device * rdev)22911099013bSjsg int cayman_resume(struct radeon_device *rdev)
22921099013bSjsg {
22931099013bSjsg 	int r;
22941099013bSjsg 
22951099013bSjsg 	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
22961099013bSjsg 	 * posting will perform necessary task to bring back GPU into good
22971099013bSjsg 	 * shape.
22981099013bSjsg 	 */
22991099013bSjsg 	/* post card */
23001099013bSjsg 	atom_asic_init(rdev->mode_info.atom_context);
23011099013bSjsg 
23027ccd5a2cSjsg 	/* init golden registers */
23037ccd5a2cSjsg 	ni_init_golden_registers(rdev);
23047ccd5a2cSjsg 
23057ccd5a2cSjsg 	if (rdev->pm.pm_method == PM_METHOD_DPM)
23067ccd5a2cSjsg 		radeon_pm_resume(rdev);
23077ccd5a2cSjsg 
23081099013bSjsg 	rdev->accel_working = true;
23091099013bSjsg 	r = cayman_startup(rdev);
23101099013bSjsg 	if (r) {
23111099013bSjsg 		DRM_ERROR("cayman startup failed on resume\n");
23121099013bSjsg 		rdev->accel_working = false;
23131099013bSjsg 		return r;
23141099013bSjsg 	}
23151099013bSjsg 	return r;
23161099013bSjsg }
23171099013bSjsg 
cayman_suspend(struct radeon_device * rdev)23181099013bSjsg int cayman_suspend(struct radeon_device *rdev)
23191099013bSjsg {
23207ccd5a2cSjsg 	radeon_pm_suspend(rdev);
23217ccd5a2cSjsg 	radeon_audio_fini(rdev);
23221099013bSjsg 	radeon_vm_manager_fini(rdev);
23231099013bSjsg 	cayman_cp_enable(rdev, false);
23241099013bSjsg 	cayman_dma_stop(rdev);
23257f4dd379Sjsg 	if (rdev->has_uvd) {
23267ccd5a2cSjsg 		radeon_uvd_suspend(rdev);
23271bb76ff1Sjsg 		uvd_v1_0_fini(rdev);
23287f4dd379Sjsg 	}
23291099013bSjsg 	evergreen_irq_suspend(rdev);
23301099013bSjsg 	radeon_wb_disable(rdev);
23311099013bSjsg 	cayman_pcie_gart_disable(rdev);
23321099013bSjsg 	return 0;
23331099013bSjsg }
23341099013bSjsg 
23351099013bSjsg /* Plan is to move initialization in that function and use
23361099013bSjsg  * helper function so that radeon_device_init pretty much
23371099013bSjsg  * do nothing more than calling asic specific function. This
23381099013bSjsg  * should also allow to remove a bunch of callback function
23391099013bSjsg  * like vram_info.
23401099013bSjsg  */
cayman_init(struct radeon_device * rdev)23411099013bSjsg int cayman_init(struct radeon_device *rdev)
23421099013bSjsg {
23431099013bSjsg 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
23441099013bSjsg 	int r;
23451099013bSjsg 
23461099013bSjsg 	/* Read BIOS */
23471099013bSjsg 	if (!radeon_get_bios(rdev)) {
23481099013bSjsg 		if (ASIC_IS_AVIVO(rdev))
23491099013bSjsg 			return -EINVAL;
23501099013bSjsg 	}
23511099013bSjsg 	/* Must be an ATOMBIOS */
23521099013bSjsg 	if (!rdev->is_atom_bios) {
23531099013bSjsg 		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
23541099013bSjsg 		return -EINVAL;
23551099013bSjsg 	}
23561099013bSjsg 	r = radeon_atombios_init(rdev);
23571099013bSjsg 	if (r)
23581099013bSjsg 		return r;
23591099013bSjsg 
23601099013bSjsg 	/* Post card if necessary */
23611099013bSjsg 	if (!radeon_card_posted(rdev)) {
23621099013bSjsg 		if (!rdev->bios) {
23631099013bSjsg 			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
23641099013bSjsg 			return -EINVAL;
23651099013bSjsg 		}
23661099013bSjsg 		DRM_INFO("GPU not posted. posting now...\n");
23671099013bSjsg 		atom_asic_init(rdev->mode_info.atom_context);
23681099013bSjsg 	}
23697ccd5a2cSjsg 	/* init golden registers */
23707ccd5a2cSjsg 	ni_init_golden_registers(rdev);
23711099013bSjsg 	/* Initialize scratch registers */
23721099013bSjsg 	r600_scratch_init(rdev);
23731099013bSjsg 	/* Initialize surface registers */
23741099013bSjsg 	radeon_surface_init(rdev);
23751099013bSjsg 	/* Initialize clocks */
23761099013bSjsg 	radeon_get_clock_info(rdev->ddev);
23771099013bSjsg 	/* Fence driver */
23785ca02815Sjsg 	radeon_fence_driver_init(rdev);
23791099013bSjsg 	/* initialize memory controller */
23801099013bSjsg 	r = evergreen_mc_init(rdev);
23811099013bSjsg 	if (r)
23821099013bSjsg 		return r;
23831099013bSjsg 	/* Memory manager */
23841099013bSjsg 	r = radeon_bo_init(rdev);
23851099013bSjsg 	if (r)
23861099013bSjsg 		return r;
23871099013bSjsg 
23887ccd5a2cSjsg 	if (rdev->flags & RADEON_IS_IGP) {
23897ccd5a2cSjsg 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
23907ccd5a2cSjsg 			r = ni_init_microcode(rdev);
23917ccd5a2cSjsg 			if (r) {
23927ccd5a2cSjsg 				DRM_ERROR("Failed to load firmware!\n");
23937ccd5a2cSjsg 				return r;
23947ccd5a2cSjsg 			}
23957ccd5a2cSjsg 		}
23967ccd5a2cSjsg 	} else {
23977ccd5a2cSjsg 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
23987ccd5a2cSjsg 			r = ni_init_microcode(rdev);
23997ccd5a2cSjsg 			if (r) {
24007ccd5a2cSjsg 				DRM_ERROR("Failed to load firmware!\n");
24017ccd5a2cSjsg 				return r;
24027ccd5a2cSjsg 			}
24037ccd5a2cSjsg 		}
24047ccd5a2cSjsg 	}
24057ccd5a2cSjsg 
24067ccd5a2cSjsg 	/* Initialize power management */
24077ccd5a2cSjsg 	radeon_pm_init(rdev);
24087ccd5a2cSjsg 
24091099013bSjsg 	ring->ring_obj = NULL;
24101099013bSjsg 	r600_ring_init(rdev, ring, 1024 * 1024);
24111099013bSjsg 
24121099013bSjsg 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
24131099013bSjsg 	ring->ring_obj = NULL;
24141099013bSjsg 	r600_ring_init(rdev, ring, 64 * 1024);
24151099013bSjsg 
24161099013bSjsg 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
24171099013bSjsg 	ring->ring_obj = NULL;
24181099013bSjsg 	r600_ring_init(rdev, ring, 64 * 1024);
24191099013bSjsg 
24207f4dd379Sjsg 	cayman_uvd_init(rdev);
24217f4dd379Sjsg 	cayman_vce_init(rdev);
24227ccd5a2cSjsg 
24231099013bSjsg 	rdev->ih.ring_obj = NULL;
24241099013bSjsg 	r600_ih_ring_init(rdev, 64 * 1024);
24251099013bSjsg 
24261099013bSjsg 	r = r600_pcie_gart_init(rdev);
24271099013bSjsg 	if (r)
24281099013bSjsg 		return r;
24291099013bSjsg 
24301099013bSjsg 	rdev->accel_working = true;
24311099013bSjsg 	r = cayman_startup(rdev);
24321099013bSjsg 	if (r) {
24331099013bSjsg 		dev_err(rdev->dev, "disabling GPU acceleration\n");
24341099013bSjsg 		cayman_cp_fini(rdev);
24351099013bSjsg 		cayman_dma_fini(rdev);
24361099013bSjsg 		r600_irq_fini(rdev);
24371099013bSjsg 		if (rdev->flags & RADEON_IS_IGP)
24387ccd5a2cSjsg 			sumo_rlc_fini(rdev);
24391099013bSjsg 		radeon_wb_fini(rdev);
24401099013bSjsg 		radeon_ib_pool_fini(rdev);
24411099013bSjsg 		radeon_vm_manager_fini(rdev);
24421099013bSjsg 		radeon_irq_kms_fini(rdev);
24431099013bSjsg 		cayman_pcie_gart_fini(rdev);
24441099013bSjsg 		rdev->accel_working = false;
24451099013bSjsg 	}
24461099013bSjsg 
24471099013bSjsg 	/* Don't start up if the MC ucode is missing.
24481099013bSjsg 	 * The default clocks and voltages before the MC ucode
24491099013bSjsg 	 * is loaded are not suffient for advanced operations.
24501099013bSjsg 	 *
24511099013bSjsg 	 * We can skip this check for TN, because there is no MC
24521099013bSjsg 	 * ucode.
24531099013bSjsg 	 */
24541099013bSjsg 	if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
24551099013bSjsg 		DRM_ERROR("radeon: MC ucode required for NI+.\n");
24561099013bSjsg 		return -EINVAL;
24571099013bSjsg 	}
24581099013bSjsg 
24591099013bSjsg 	return 0;
24601099013bSjsg }
24611099013bSjsg 
cayman_fini(struct radeon_device * rdev)24621099013bSjsg void cayman_fini(struct radeon_device *rdev)
24631099013bSjsg {
24647ccd5a2cSjsg 	radeon_pm_fini(rdev);
24651099013bSjsg 	cayman_cp_fini(rdev);
24661099013bSjsg 	cayman_dma_fini(rdev);
24671099013bSjsg 	r600_irq_fini(rdev);
24681099013bSjsg 	if (rdev->flags & RADEON_IS_IGP)
24697ccd5a2cSjsg 		sumo_rlc_fini(rdev);
24701099013bSjsg 	radeon_wb_fini(rdev);
24711099013bSjsg 	radeon_vm_manager_fini(rdev);
24721099013bSjsg 	radeon_ib_pool_fini(rdev);
24731099013bSjsg 	radeon_irq_kms_fini(rdev);
24747ccd5a2cSjsg 	uvd_v1_0_fini(rdev);
24757ccd5a2cSjsg 	radeon_uvd_fini(rdev);
24767f4dd379Sjsg 	if (rdev->has_vce)
24777ccd5a2cSjsg 		radeon_vce_fini(rdev);
24781099013bSjsg 	cayman_pcie_gart_fini(rdev);
24791099013bSjsg 	r600_vram_scratch_fini(rdev);
24801099013bSjsg 	radeon_gem_fini(rdev);
24811099013bSjsg 	radeon_fence_driver_fini(rdev);
24821099013bSjsg 	radeon_bo_fini(rdev);
24831099013bSjsg 	radeon_atombios_fini(rdev);
2484de5631a0Sjsg 	kfree(rdev->bios);
24851099013bSjsg 	rdev->bios = NULL;
24861099013bSjsg }
24871099013bSjsg 
24881099013bSjsg /*
24891099013bSjsg  * vm
24901099013bSjsg  */
cayman_vm_init(struct radeon_device * rdev)24911099013bSjsg int cayman_vm_init(struct radeon_device *rdev)
24921099013bSjsg {
24931099013bSjsg 	/* number of VMs */
24941099013bSjsg 	rdev->vm_manager.nvm = 8;
24951099013bSjsg 	/* base offset of vram pages */
24961099013bSjsg 	if (rdev->flags & RADEON_IS_IGP) {
24971099013bSjsg 		u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET);
24981099013bSjsg 		tmp <<= 22;
24991099013bSjsg 		rdev->vm_manager.vram_base_offset = tmp;
25001099013bSjsg 	} else
25011099013bSjsg 		rdev->vm_manager.vram_base_offset = 0;
25021099013bSjsg 	return 0;
25031099013bSjsg }
25041099013bSjsg 
cayman_vm_fini(struct radeon_device * rdev)25051099013bSjsg void cayman_vm_fini(struct radeon_device *rdev)
25061099013bSjsg {
25071099013bSjsg }
25081099013bSjsg 
2509f3eef2b6Sderaadt /**
25107ccd5a2cSjsg  * cayman_vm_decode_fault - print human readable fault info
2511f3eef2b6Sderaadt  *
2512f3eef2b6Sderaadt  * @rdev: radeon_device pointer
25137ccd5a2cSjsg  * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
25147ccd5a2cSjsg  * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
2515f3eef2b6Sderaadt  *
25167ccd5a2cSjsg  * Print human readable fault information (cayman/TN).
2517f3eef2b6Sderaadt  */
cayman_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr)25187ccd5a2cSjsg void cayman_vm_decode_fault(struct radeon_device *rdev,
25197ccd5a2cSjsg 			    u32 status, u32 addr)
2520f3eef2b6Sderaadt {
25217ccd5a2cSjsg 	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
25227ccd5a2cSjsg 	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
25237ccd5a2cSjsg 	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
25247ccd5a2cSjsg 	char *block;
2525f3eef2b6Sderaadt 
25267ccd5a2cSjsg 	switch (mc_id) {
25277ccd5a2cSjsg 	case 32:
25287ccd5a2cSjsg 	case 16:
25297ccd5a2cSjsg 	case 96:
25307ccd5a2cSjsg 	case 80:
25317ccd5a2cSjsg 	case 160:
25327ccd5a2cSjsg 	case 144:
25337ccd5a2cSjsg 	case 224:
25347ccd5a2cSjsg 	case 208:
25357ccd5a2cSjsg 		block = "CB";
25367ccd5a2cSjsg 		break;
25377ccd5a2cSjsg 	case 33:
25387ccd5a2cSjsg 	case 17:
25397ccd5a2cSjsg 	case 97:
25407ccd5a2cSjsg 	case 81:
25417ccd5a2cSjsg 	case 161:
25427ccd5a2cSjsg 	case 145:
25437ccd5a2cSjsg 	case 225:
25447ccd5a2cSjsg 	case 209:
25457ccd5a2cSjsg 		block = "CB_FMASK";
25467ccd5a2cSjsg 		break;
25477ccd5a2cSjsg 	case 34:
25487ccd5a2cSjsg 	case 18:
25497ccd5a2cSjsg 	case 98:
25507ccd5a2cSjsg 	case 82:
25517ccd5a2cSjsg 	case 162:
25527ccd5a2cSjsg 	case 146:
25537ccd5a2cSjsg 	case 226:
25547ccd5a2cSjsg 	case 210:
25557ccd5a2cSjsg 		block = "CB_CMASK";
25567ccd5a2cSjsg 		break;
25577ccd5a2cSjsg 	case 35:
25587ccd5a2cSjsg 	case 19:
25597ccd5a2cSjsg 	case 99:
25607ccd5a2cSjsg 	case 83:
25617ccd5a2cSjsg 	case 163:
25627ccd5a2cSjsg 	case 147:
25637ccd5a2cSjsg 	case 227:
25647ccd5a2cSjsg 	case 211:
25657ccd5a2cSjsg 		block = "CB_IMMED";
25667ccd5a2cSjsg 		break;
25677ccd5a2cSjsg 	case 36:
25687ccd5a2cSjsg 	case 20:
25697ccd5a2cSjsg 	case 100:
25707ccd5a2cSjsg 	case 84:
25717ccd5a2cSjsg 	case 164:
25727ccd5a2cSjsg 	case 148:
25737ccd5a2cSjsg 	case 228:
25747ccd5a2cSjsg 	case 212:
25757ccd5a2cSjsg 		block = "DB";
25767ccd5a2cSjsg 		break;
25777ccd5a2cSjsg 	case 37:
25787ccd5a2cSjsg 	case 21:
25797ccd5a2cSjsg 	case 101:
25807ccd5a2cSjsg 	case 85:
25817ccd5a2cSjsg 	case 165:
25827ccd5a2cSjsg 	case 149:
25837ccd5a2cSjsg 	case 229:
25847ccd5a2cSjsg 	case 213:
25857ccd5a2cSjsg 		block = "DB_HTILE";
25867ccd5a2cSjsg 		break;
25877ccd5a2cSjsg 	case 38:
25887ccd5a2cSjsg 	case 22:
25897ccd5a2cSjsg 	case 102:
25907ccd5a2cSjsg 	case 86:
25917ccd5a2cSjsg 	case 166:
25927ccd5a2cSjsg 	case 150:
25937ccd5a2cSjsg 	case 230:
25947ccd5a2cSjsg 	case 214:
25957ccd5a2cSjsg 		block = "SX";
25967ccd5a2cSjsg 		break;
25977ccd5a2cSjsg 	case 39:
25987ccd5a2cSjsg 	case 23:
25997ccd5a2cSjsg 	case 103:
26007ccd5a2cSjsg 	case 87:
26017ccd5a2cSjsg 	case 167:
26027ccd5a2cSjsg 	case 151:
26037ccd5a2cSjsg 	case 231:
26047ccd5a2cSjsg 	case 215:
26057ccd5a2cSjsg 		block = "DB_STEN";
26067ccd5a2cSjsg 		break;
26077ccd5a2cSjsg 	case 40:
26087ccd5a2cSjsg 	case 24:
26097ccd5a2cSjsg 	case 104:
26107ccd5a2cSjsg 	case 88:
26117ccd5a2cSjsg 	case 232:
26127ccd5a2cSjsg 	case 216:
26137ccd5a2cSjsg 	case 168:
26147ccd5a2cSjsg 	case 152:
26157ccd5a2cSjsg 		block = "TC_TFETCH";
26167ccd5a2cSjsg 		break;
26177ccd5a2cSjsg 	case 41:
26187ccd5a2cSjsg 	case 25:
26197ccd5a2cSjsg 	case 105:
26207ccd5a2cSjsg 	case 89:
26217ccd5a2cSjsg 	case 233:
26227ccd5a2cSjsg 	case 217:
26237ccd5a2cSjsg 	case 169:
26247ccd5a2cSjsg 	case 153:
26257ccd5a2cSjsg 		block = "TC_VFETCH";
26267ccd5a2cSjsg 		break;
26277ccd5a2cSjsg 	case 42:
26287ccd5a2cSjsg 	case 26:
26297ccd5a2cSjsg 	case 106:
26307ccd5a2cSjsg 	case 90:
26317ccd5a2cSjsg 	case 234:
26327ccd5a2cSjsg 	case 218:
26337ccd5a2cSjsg 	case 170:
26347ccd5a2cSjsg 	case 154:
26357ccd5a2cSjsg 		block = "VC";
26367ccd5a2cSjsg 		break;
26377ccd5a2cSjsg 	case 112:
26387ccd5a2cSjsg 		block = "CP";
26397ccd5a2cSjsg 		break;
26407ccd5a2cSjsg 	case 113:
26417ccd5a2cSjsg 	case 114:
26427ccd5a2cSjsg 		block = "SH";
26437ccd5a2cSjsg 		break;
26447ccd5a2cSjsg 	case 115:
26457ccd5a2cSjsg 		block = "VGT";
26467ccd5a2cSjsg 		break;
26477ccd5a2cSjsg 	case 178:
26487ccd5a2cSjsg 		block = "IH";
26497ccd5a2cSjsg 		break;
26507ccd5a2cSjsg 	case 51:
26517ccd5a2cSjsg 		block = "RLC";
26527ccd5a2cSjsg 		break;
26537ccd5a2cSjsg 	case 55:
26547ccd5a2cSjsg 		block = "DMA";
26557ccd5a2cSjsg 		break;
26567ccd5a2cSjsg 	case 56:
26577ccd5a2cSjsg 		block = "HDP";
26587ccd5a2cSjsg 		break;
26597ccd5a2cSjsg 	default:
26607ccd5a2cSjsg 		block = "unknown";
26617ccd5a2cSjsg 		break;
26627ccd5a2cSjsg 	}
2663f3eef2b6Sderaadt 
26647ccd5a2cSjsg 	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
26657ccd5a2cSjsg 	       protections, vmid, addr,
26667ccd5a2cSjsg 	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
26677ccd5a2cSjsg 	       block, mc_id);
26681099013bSjsg }
26691099013bSjsg 
26705ca02815Sjsg /*
26711099013bSjsg  * cayman_vm_flush - vm flush using the CP
26721099013bSjsg  *
26731099013bSjsg  * Update the page table base and flush the VM TLB
26741099013bSjsg  * using the CP (cayman-si).
26751099013bSjsg  */
cayman_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)26767ccd5a2cSjsg void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
26777ccd5a2cSjsg 		     unsigned vm_id, uint64_t pd_addr)
26781099013bSjsg {
26797ccd5a2cSjsg 	radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2), 0));
26807ccd5a2cSjsg 	radeon_ring_write(ring, pd_addr >> 12);
26811099013bSjsg 
26821099013bSjsg 	/* flush hdp cache */
26831099013bSjsg 	radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
26841099013bSjsg 	radeon_ring_write(ring, 0x1);
26851099013bSjsg 
26861099013bSjsg 	/* bits 0-7 are the VM contexts0-7 */
26871099013bSjsg 	radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0));
26887ccd5a2cSjsg 	radeon_ring_write(ring, 1 << vm_id);
26897ccd5a2cSjsg 
26907ccd5a2cSjsg 	/* wait for the invalidate to complete */
26917ccd5a2cSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
26927ccd5a2cSjsg 	radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) |  /* always */
26937ccd5a2cSjsg 				 WAIT_REG_MEM_ENGINE(0))); /* me */
26947ccd5a2cSjsg 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
26957ccd5a2cSjsg 	radeon_ring_write(ring, 0);
26967ccd5a2cSjsg 	radeon_ring_write(ring, 0); /* ref */
26977ccd5a2cSjsg 	radeon_ring_write(ring, 0); /* mask */
26987ccd5a2cSjsg 	radeon_ring_write(ring, 0x20); /* poll interval */
26991099013bSjsg 
27001099013bSjsg 	/* sync PFP to ME, otherwise we might get invalid PFP reads */
27011099013bSjsg 	radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
27021099013bSjsg 	radeon_ring_write(ring, 0x0);
27031099013bSjsg }
27041099013bSjsg 
tn_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)27057ccd5a2cSjsg int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
27061099013bSjsg {
27077ccd5a2cSjsg 	struct atom_clock_dividers dividers;
27087ccd5a2cSjsg 	int r, i;
27091099013bSjsg 
27107ccd5a2cSjsg 	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
27117ccd5a2cSjsg 					   ecclk, false, &dividers);
27127ccd5a2cSjsg 	if (r)
27137ccd5a2cSjsg 		return r;
27141099013bSjsg 
27157ccd5a2cSjsg 	for (i = 0; i < 100; i++) {
27167ccd5a2cSjsg 		if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
27177ccd5a2cSjsg 			break;
27187ccd5a2cSjsg 		mdelay(10);
27191099013bSjsg 	}
27207ccd5a2cSjsg 	if (i == 100)
27217ccd5a2cSjsg 		return -ETIMEDOUT;
27221099013bSjsg 
27237ccd5a2cSjsg 	WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK));
27247ccd5a2cSjsg 
27257ccd5a2cSjsg 	for (i = 0; i < 100; i++) {
27267ccd5a2cSjsg 		if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
27277ccd5a2cSjsg 			break;
27287ccd5a2cSjsg 		mdelay(10);
27297ccd5a2cSjsg 	}
27307ccd5a2cSjsg 	if (i == 100)
27317ccd5a2cSjsg 		return -ETIMEDOUT;
27327ccd5a2cSjsg 
27337ccd5a2cSjsg 	return 0;
27347ccd5a2cSjsg }
2735