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