1926deccbSFrançois Tigeot /* 2926deccbSFrançois Tigeot * Copyright 2010 Advanced Micro Devices, Inc. 3926deccbSFrançois Tigeot * 4926deccbSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 5926deccbSFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 6926deccbSFrançois Tigeot * to deal in the Software without restriction, including without limitation 7926deccbSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8926deccbSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 9926deccbSFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 10926deccbSFrançois Tigeot * 11926deccbSFrançois Tigeot * The above copyright notice and this permission notice shall be included in 12926deccbSFrançois Tigeot * all copies or substantial portions of the Software. 13926deccbSFrançois Tigeot * 14926deccbSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15926deccbSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16926deccbSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17926deccbSFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18926deccbSFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19926deccbSFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20926deccbSFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE. 21926deccbSFrançois Tigeot * 22926deccbSFrançois Tigeot * Authors: Alex Deucher 23926deccbSFrançois Tigeot * $FreeBSD: head/sys/dev/drm2/radeon/ni.c 254885 2013-08-25 19:37:15Z dumbbell $ 24926deccbSFrançois Tigeot */ 2557e252bfSMichael Neumann #include <linux/firmware.h> 26*fcd4983fSzrj #include <linux/module.h> 27*fcd4983fSzrj #include <drm/drmP.h> 28926deccbSFrançois Tigeot #include "radeon.h" 29926deccbSFrançois Tigeot #include "radeon_asic.h" 30926deccbSFrançois Tigeot #include <uapi_drm/radeon_drm.h> 31926deccbSFrançois Tigeot #include "nid.h" 32926deccbSFrançois Tigeot #include "atom.h" 33926deccbSFrançois Tigeot #include "ni_reg.h" 34926deccbSFrançois Tigeot #include "cayman_blit_shaders.h" 3557e252bfSMichael Neumann #include "radeon_ucode.h" 3657e252bfSMichael Neumann #include "clearstate_cayman.h" 37926deccbSFrançois Tigeot 3857e252bfSMichael Neumann static u32 tn_rlc_save_restore_register_list[] = 3957e252bfSMichael Neumann { 4057e252bfSMichael Neumann 0x98fc, 4157e252bfSMichael Neumann 0x98f0, 4257e252bfSMichael Neumann 0x9834, 4357e252bfSMichael Neumann 0x9838, 4457e252bfSMichael Neumann 0x9870, 4557e252bfSMichael Neumann 0x9874, 4657e252bfSMichael Neumann 0x8a14, 4757e252bfSMichael Neumann 0x8b24, 4857e252bfSMichael Neumann 0x8bcc, 4957e252bfSMichael Neumann 0x8b10, 5057e252bfSMichael Neumann 0x8c30, 5157e252bfSMichael Neumann 0x8d00, 5257e252bfSMichael Neumann 0x8d04, 5357e252bfSMichael Neumann 0x8c00, 5457e252bfSMichael Neumann 0x8c04, 5557e252bfSMichael Neumann 0x8c10, 5657e252bfSMichael Neumann 0x8c14, 5757e252bfSMichael Neumann 0x8d8c, 5857e252bfSMichael Neumann 0x8cf0, 5957e252bfSMichael Neumann 0x8e38, 6057e252bfSMichael Neumann 0x9508, 6157e252bfSMichael Neumann 0x9688, 6257e252bfSMichael Neumann 0x9608, 6357e252bfSMichael Neumann 0x960c, 6457e252bfSMichael Neumann 0x9610, 6557e252bfSMichael Neumann 0x9614, 6657e252bfSMichael Neumann 0x88c4, 6757e252bfSMichael Neumann 0x8978, 6857e252bfSMichael Neumann 0x88d4, 6957e252bfSMichael Neumann 0x900c, 7057e252bfSMichael Neumann 0x9100, 7157e252bfSMichael Neumann 0x913c, 7257e252bfSMichael Neumann 0x90e8, 7357e252bfSMichael Neumann 0x9354, 7457e252bfSMichael Neumann 0xa008, 7557e252bfSMichael Neumann 0x98f8, 7657e252bfSMichael Neumann 0x9148, 7757e252bfSMichael Neumann 0x914c, 7857e252bfSMichael Neumann 0x3f94, 7957e252bfSMichael Neumann 0x98f4, 8057e252bfSMichael Neumann 0x9b7c, 8157e252bfSMichael Neumann 0x3f8c, 8257e252bfSMichael Neumann 0x8950, 8357e252bfSMichael Neumann 0x8954, 8457e252bfSMichael Neumann 0x8a18, 8557e252bfSMichael Neumann 0x8b28, 8657e252bfSMichael Neumann 0x9144, 8757e252bfSMichael Neumann 0x3f90, 8857e252bfSMichael Neumann 0x915c, 8957e252bfSMichael Neumann 0x9160, 9057e252bfSMichael Neumann 0x9178, 9157e252bfSMichael Neumann 0x917c, 9257e252bfSMichael Neumann 0x9180, 9357e252bfSMichael Neumann 0x918c, 9457e252bfSMichael Neumann 0x9190, 9557e252bfSMichael Neumann 0x9194, 9657e252bfSMichael Neumann 0x9198, 9757e252bfSMichael Neumann 0x919c, 9857e252bfSMichael Neumann 0x91a8, 9957e252bfSMichael Neumann 0x91ac, 10057e252bfSMichael Neumann 0x91b0, 10157e252bfSMichael Neumann 0x91b4, 10257e252bfSMichael Neumann 0x91b8, 10357e252bfSMichael Neumann 0x91c4, 10457e252bfSMichael Neumann 0x91c8, 10557e252bfSMichael Neumann 0x91cc, 10657e252bfSMichael Neumann 0x91d0, 10757e252bfSMichael Neumann 0x91d4, 10857e252bfSMichael Neumann 0x91e0, 10957e252bfSMichael Neumann 0x91e4, 11057e252bfSMichael Neumann 0x91ec, 11157e252bfSMichael Neumann 0x91f0, 11257e252bfSMichael Neumann 0x91f4, 11357e252bfSMichael Neumann 0x9200, 11457e252bfSMichael Neumann 0x9204, 11557e252bfSMichael Neumann 0x929c, 11657e252bfSMichael Neumann 0x8030, 11757e252bfSMichael Neumann 0x9150, 11857e252bfSMichael Neumann 0x9a60, 11957e252bfSMichael Neumann 0x920c, 12057e252bfSMichael Neumann 0x9210, 12157e252bfSMichael Neumann 0x9228, 12257e252bfSMichael Neumann 0x922c, 12357e252bfSMichael Neumann 0x9244, 12457e252bfSMichael Neumann 0x9248, 12557e252bfSMichael Neumann 0x91e8, 12657e252bfSMichael Neumann 0x9294, 12757e252bfSMichael Neumann 0x9208, 12857e252bfSMichael Neumann 0x9224, 12957e252bfSMichael Neumann 0x9240, 13057e252bfSMichael Neumann 0x9220, 13157e252bfSMichael Neumann 0x923c, 13257e252bfSMichael Neumann 0x9258, 13357e252bfSMichael Neumann 0x9744, 13457e252bfSMichael Neumann 0xa200, 13557e252bfSMichael Neumann 0xa204, 13657e252bfSMichael Neumann 0xa208, 13757e252bfSMichael Neumann 0xa20c, 13857e252bfSMichael Neumann 0x8d58, 13957e252bfSMichael Neumann 0x9030, 14057e252bfSMichael Neumann 0x9034, 14157e252bfSMichael Neumann 0x9038, 14257e252bfSMichael Neumann 0x903c, 14357e252bfSMichael Neumann 0x9040, 14457e252bfSMichael Neumann 0x9654, 14557e252bfSMichael Neumann 0x897c, 14657e252bfSMichael Neumann 0xa210, 14757e252bfSMichael Neumann 0xa214, 14857e252bfSMichael Neumann 0x9868, 14957e252bfSMichael Neumann 0xa02c, 15057e252bfSMichael Neumann 0x9664, 15157e252bfSMichael Neumann 0x9698, 15257e252bfSMichael Neumann 0x949c, 15357e252bfSMichael Neumann 0x8e10, 15457e252bfSMichael Neumann 0x8e18, 15557e252bfSMichael Neumann 0x8c50, 15657e252bfSMichael Neumann 0x8c58, 15757e252bfSMichael Neumann 0x8c60, 15857e252bfSMichael Neumann 0x8c68, 15957e252bfSMichael Neumann 0x89b4, 16057e252bfSMichael Neumann 0x9830, 16157e252bfSMichael Neumann 0x802c, 16257e252bfSMichael Neumann }; 16357e252bfSMichael Neumann static u32 tn_rlc_save_restore_register_list_size = ARRAY_SIZE(tn_rlc_save_restore_register_list); 16457e252bfSMichael Neumann 165b403bed8SMichael Neumann extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev); 166926deccbSFrançois Tigeot extern void evergreen_pcie_gen2_enable(struct radeon_device *rdev); 16757e252bfSMichael Neumann extern void evergreen_program_aspm(struct radeon_device *rdev); 168926deccbSFrançois Tigeot 16957e252bfSMichael Neumann /* Firmware Names */ 17057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_pfp.bin"); 17157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_me.bin"); 17257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_mc.bin"); 17357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BARTS_smc.bin"); 17457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/BTC_rlc.bin"); 17557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_pfp.bin"); 17657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_me.bin"); 17757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_mc.bin"); 17857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TURKS_smc.bin"); 17957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_pfp.bin"); 18057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_me.bin"); 18157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_mc.bin"); 18257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAICOS_smc.bin"); 18357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin"); 18457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_me.bin"); 18557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_mc.bin"); 18657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin"); 18757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/CAYMAN_smc.bin"); 18857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/ARUBA_pfp.bin"); 18957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/ARUBA_me.bin"); 19057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/ARUBA_rlc.bin"); 191f43cf1b1SMichael Neumann 192f43cf1b1SMichael Neumann static const u32 cayman_golden_registers2[] = 193f43cf1b1SMichael Neumann { 194f43cf1b1SMichael Neumann 0x3e5c, 0xffffffff, 0x00000000, 195f43cf1b1SMichael Neumann 0x3e48, 0xffffffff, 0x00000000, 196f43cf1b1SMichael Neumann 0x3e4c, 0xffffffff, 0x00000000, 197f43cf1b1SMichael Neumann 0x3e64, 0xffffffff, 0x00000000, 198f43cf1b1SMichael Neumann 0x3e50, 0xffffffff, 0x00000000, 199f43cf1b1SMichael Neumann 0x3e60, 0xffffffff, 0x00000000 200f43cf1b1SMichael Neumann }; 201f43cf1b1SMichael Neumann 202f43cf1b1SMichael Neumann static const u32 cayman_golden_registers[] = 203f43cf1b1SMichael Neumann { 204f43cf1b1SMichael Neumann 0x5eb4, 0xffffffff, 0x00000002, 205f43cf1b1SMichael Neumann 0x5e78, 0x8f311ff1, 0x001000f0, 206f43cf1b1SMichael Neumann 0x3f90, 0xffff0000, 0xff000000, 207f43cf1b1SMichael Neumann 0x9148, 0xffff0000, 0xff000000, 208f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000, 209f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000, 210f43cf1b1SMichael Neumann 0xc78, 0x00000080, 0x00000080, 211f43cf1b1SMichael Neumann 0xbd4, 0x70073777, 0x00011003, 212f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000, 213f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x02011003, 214f43cf1b1SMichael Neumann 0x5bc0, 0x00200000, 0x50100000, 215f43cf1b1SMichael Neumann 0x98f8, 0x33773777, 0x02011003, 216f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x76541032, 217f43cf1b1SMichael Neumann 0x7030, 0x31000311, 0x00000011, 218f43cf1b1SMichael Neumann 0x2f48, 0x33773777, 0x42010001, 219f43cf1b1SMichael Neumann 0x6b28, 0x00000010, 0x00000012, 220f43cf1b1SMichael Neumann 0x7728, 0x00000010, 0x00000012, 221f43cf1b1SMichael Neumann 0x10328, 0x00000010, 0x00000012, 222f43cf1b1SMichael Neumann 0x10f28, 0x00000010, 0x00000012, 223f43cf1b1SMichael Neumann 0x11b28, 0x00000010, 0x00000012, 224f43cf1b1SMichael Neumann 0x12728, 0x00000010, 0x00000012, 225f43cf1b1SMichael Neumann 0x240c, 0x000007ff, 0x00000000, 226f43cf1b1SMichael Neumann 0x8a14, 0xf000001f, 0x00000007, 227f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff, 228f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000, 229f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000, 230f43cf1b1SMichael Neumann 0x10c, 0x00000001, 0x00010003, 231f43cf1b1SMichael Neumann 0xa02c, 0xffffffff, 0x0000009b, 232f43cf1b1SMichael Neumann 0x913c, 0x0000010f, 0x01000100, 233f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060, 234f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000, 235f43cf1b1SMichael Neumann 0x9508, 0x3700001f, 0x00000002, 236f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210, 237f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082, 238f43cf1b1SMichael Neumann 0x88d0, 0xffffffff, 0x0f40df40, 239f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010, 240f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000 241f43cf1b1SMichael Neumann }; 242f43cf1b1SMichael Neumann 243f43cf1b1SMichael Neumann static const u32 dvst_golden_registers2[] = 244f43cf1b1SMichael Neumann { 245f43cf1b1SMichael Neumann 0x8f8, 0xffffffff, 0, 246f43cf1b1SMichael Neumann 0x8fc, 0x00380000, 0, 247f43cf1b1SMichael Neumann 0x8f8, 0xffffffff, 1, 248f43cf1b1SMichael Neumann 0x8fc, 0x0e000000, 0 249f43cf1b1SMichael Neumann }; 250f43cf1b1SMichael Neumann 251f43cf1b1SMichael Neumann static const u32 dvst_golden_registers[] = 252f43cf1b1SMichael Neumann { 253f43cf1b1SMichael Neumann 0x690, 0x3fff3fff, 0x20c00033, 254f43cf1b1SMichael Neumann 0x918c, 0x0fff0fff, 0x00010006, 255f43cf1b1SMichael Neumann 0x91a8, 0x0fff0fff, 0x00010006, 256f43cf1b1SMichael Neumann 0x9150, 0xffffdfff, 0x6e944040, 257f43cf1b1SMichael Neumann 0x917c, 0x0fff0fff, 0x00030002, 258f43cf1b1SMichael Neumann 0x9198, 0x0fff0fff, 0x00030002, 259f43cf1b1SMichael Neumann 0x915c, 0x0fff0fff, 0x00010000, 260f43cf1b1SMichael Neumann 0x3f90, 0xffff0001, 0xff000000, 261f43cf1b1SMichael Neumann 0x9178, 0x0fff0fff, 0x00070000, 262f43cf1b1SMichael Neumann 0x9194, 0x0fff0fff, 0x00070000, 263f43cf1b1SMichael Neumann 0x9148, 0xffff0001, 0xff000000, 264f43cf1b1SMichael Neumann 0x9190, 0x0fff0fff, 0x00090008, 265f43cf1b1SMichael Neumann 0x91ac, 0x0fff0fff, 0x00090008, 266f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000, 267f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000, 268f43cf1b1SMichael Neumann 0x929c, 0x00000fff, 0x00000001, 269f43cf1b1SMichael Neumann 0x55e4, 0xff607fff, 0xfc000100, 270f43cf1b1SMichael Neumann 0x8a18, 0xff000fff, 0x00000100, 271f43cf1b1SMichael Neumann 0x8b28, 0xff000fff, 0x00000100, 272f43cf1b1SMichael Neumann 0x9144, 0xfffc0fff, 0x00000100, 273f43cf1b1SMichael Neumann 0x6ed8, 0x00010101, 0x00010000, 274f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000, 275f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400, 276f43cf1b1SMichael Neumann 0x9838, 0xfffffffe, 0x00000000, 277f43cf1b1SMichael Neumann 0xd0c0, 0xff000fff, 0x00000100, 278f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000, 279f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x12010001, 280f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070, 281f43cf1b1SMichael Neumann 0x98f8, 0x73773777, 0x12010001, 282f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x00000010, 283f43cf1b1SMichael Neumann 0x9b7c, 0x00ff0000, 0x00fc0000, 284f43cf1b1SMichael Neumann 0x8030, 0x00001f0f, 0x0000100a, 285f43cf1b1SMichael Neumann 0x2f48, 0x73773777, 0x12010001, 286f43cf1b1SMichael Neumann 0x2408, 0x00030000, 0x000c007f, 287f43cf1b1SMichael Neumann 0x8a14, 0xf000003f, 0x00000007, 288f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff, 289f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000, 290f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000, 291f43cf1b1SMichael Neumann 0x4d8, 0x00000fff, 0x00000100, 292f43cf1b1SMichael Neumann 0xa008, 0xffffffff, 0x00010000, 293f43cf1b1SMichael Neumann 0x913c, 0xffff03ff, 0x01000100, 294f43cf1b1SMichael Neumann 0x8c00, 0x000000ff, 0x00000003, 295f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060, 296f43cf1b1SMichael Neumann 0x8cf0, 0x1fff1fff, 0x08e00410, 297f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000, 298f43cf1b1SMichael Neumann 0x9508, 0xf700071f, 0x00000002, 299f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210, 300f43cf1b1SMichael Neumann 0x20ef8, 0x01ff01ff, 0x00000002, 301f43cf1b1SMichael Neumann 0x20e98, 0xfffffbff, 0x00200000, 302f43cf1b1SMichael Neumann 0x2015c, 0xffffffff, 0x00000f40, 303f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082, 304f43cf1b1SMichael Neumann 0x8978, 0x3fffffff, 0x04050140, 305f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010, 306f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000 307f43cf1b1SMichael Neumann }; 308f43cf1b1SMichael Neumann 309f43cf1b1SMichael Neumann static const u32 scrapper_golden_registers[] = 310f43cf1b1SMichael Neumann { 311f43cf1b1SMichael Neumann 0x690, 0x3fff3fff, 0x20c00033, 312f43cf1b1SMichael Neumann 0x918c, 0x0fff0fff, 0x00010006, 313f43cf1b1SMichael Neumann 0x918c, 0x0fff0fff, 0x00010006, 314f43cf1b1SMichael Neumann 0x91a8, 0x0fff0fff, 0x00010006, 315f43cf1b1SMichael Neumann 0x91a8, 0x0fff0fff, 0x00010006, 316f43cf1b1SMichael Neumann 0x9150, 0xffffdfff, 0x6e944040, 317f43cf1b1SMichael Neumann 0x9150, 0xffffdfff, 0x6e944040, 318f43cf1b1SMichael Neumann 0x917c, 0x0fff0fff, 0x00030002, 319f43cf1b1SMichael Neumann 0x917c, 0x0fff0fff, 0x00030002, 320f43cf1b1SMichael Neumann 0x9198, 0x0fff0fff, 0x00030002, 321f43cf1b1SMichael Neumann 0x9198, 0x0fff0fff, 0x00030002, 322f43cf1b1SMichael Neumann 0x915c, 0x0fff0fff, 0x00010000, 323f43cf1b1SMichael Neumann 0x915c, 0x0fff0fff, 0x00010000, 324f43cf1b1SMichael Neumann 0x3f90, 0xffff0001, 0xff000000, 325f43cf1b1SMichael Neumann 0x3f90, 0xffff0001, 0xff000000, 326f43cf1b1SMichael Neumann 0x9178, 0x0fff0fff, 0x00070000, 327f43cf1b1SMichael Neumann 0x9178, 0x0fff0fff, 0x00070000, 328f43cf1b1SMichael Neumann 0x9194, 0x0fff0fff, 0x00070000, 329f43cf1b1SMichael Neumann 0x9194, 0x0fff0fff, 0x00070000, 330f43cf1b1SMichael Neumann 0x9148, 0xffff0001, 0xff000000, 331f43cf1b1SMichael Neumann 0x9148, 0xffff0001, 0xff000000, 332f43cf1b1SMichael Neumann 0x9190, 0x0fff0fff, 0x00090008, 333f43cf1b1SMichael Neumann 0x9190, 0x0fff0fff, 0x00090008, 334f43cf1b1SMichael Neumann 0x91ac, 0x0fff0fff, 0x00090008, 335f43cf1b1SMichael Neumann 0x91ac, 0x0fff0fff, 0x00090008, 336f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000, 337f43cf1b1SMichael Neumann 0x3f94, 0xffff0000, 0xff000000, 338f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000, 339f43cf1b1SMichael Neumann 0x914c, 0xffff0000, 0xff000000, 340f43cf1b1SMichael Neumann 0x929c, 0x00000fff, 0x00000001, 341f43cf1b1SMichael Neumann 0x929c, 0x00000fff, 0x00000001, 342f43cf1b1SMichael Neumann 0x55e4, 0xff607fff, 0xfc000100, 343f43cf1b1SMichael Neumann 0x8a18, 0xff000fff, 0x00000100, 344f43cf1b1SMichael Neumann 0x8a18, 0xff000fff, 0x00000100, 345f43cf1b1SMichael Neumann 0x8b28, 0xff000fff, 0x00000100, 346f43cf1b1SMichael Neumann 0x8b28, 0xff000fff, 0x00000100, 347f43cf1b1SMichael Neumann 0x9144, 0xfffc0fff, 0x00000100, 348f43cf1b1SMichael Neumann 0x9144, 0xfffc0fff, 0x00000100, 349f43cf1b1SMichael Neumann 0x6ed8, 0x00010101, 0x00010000, 350f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000, 351f43cf1b1SMichael Neumann 0x9830, 0xffffffff, 0x00000000, 352f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400, 353f43cf1b1SMichael Neumann 0x9834, 0xf00fffff, 0x00000400, 354f43cf1b1SMichael Neumann 0x9838, 0xfffffffe, 0x00000000, 355f43cf1b1SMichael Neumann 0x9838, 0xfffffffe, 0x00000000, 356f43cf1b1SMichael Neumann 0xd0c0, 0xff000fff, 0x00000100, 357f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000, 358f43cf1b1SMichael Neumann 0xd02c, 0xbfffff1f, 0x08421000, 359f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x12010001, 360f43cf1b1SMichael Neumann 0xd0b8, 0x73773777, 0x12010001, 361f43cf1b1SMichael Neumann 0x5bb0, 0x000000f0, 0x00000070, 362f43cf1b1SMichael Neumann 0x98f8, 0x73773777, 0x12010001, 363f43cf1b1SMichael Neumann 0x98f8, 0x73773777, 0x12010001, 364f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x00000010, 365f43cf1b1SMichael Neumann 0x98fc, 0xffffffff, 0x00000010, 366f43cf1b1SMichael Neumann 0x9b7c, 0x00ff0000, 0x00fc0000, 367f43cf1b1SMichael Neumann 0x9b7c, 0x00ff0000, 0x00fc0000, 368f43cf1b1SMichael Neumann 0x8030, 0x00001f0f, 0x0000100a, 369f43cf1b1SMichael Neumann 0x8030, 0x00001f0f, 0x0000100a, 370f43cf1b1SMichael Neumann 0x2f48, 0x73773777, 0x12010001, 371f43cf1b1SMichael Neumann 0x2f48, 0x73773777, 0x12010001, 372f43cf1b1SMichael Neumann 0x2408, 0x00030000, 0x000c007f, 373f43cf1b1SMichael Neumann 0x8a14, 0xf000003f, 0x00000007, 374f43cf1b1SMichael Neumann 0x8a14, 0xf000003f, 0x00000007, 375f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff, 376f43cf1b1SMichael Neumann 0x8b24, 0x3fff3fff, 0x00ff0fff, 377f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000, 378f43cf1b1SMichael Neumann 0x8b10, 0x0000ff0f, 0x00000000, 379f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000, 380f43cf1b1SMichael Neumann 0x28a4c, 0x07ffffff, 0x06000000, 381f43cf1b1SMichael Neumann 0x4d8, 0x00000fff, 0x00000100, 382f43cf1b1SMichael Neumann 0x4d8, 0x00000fff, 0x00000100, 383f43cf1b1SMichael Neumann 0xa008, 0xffffffff, 0x00010000, 384f43cf1b1SMichael Neumann 0xa008, 0xffffffff, 0x00010000, 385f43cf1b1SMichael Neumann 0x913c, 0xffff03ff, 0x01000100, 386f43cf1b1SMichael Neumann 0x913c, 0xffff03ff, 0x01000100, 387f43cf1b1SMichael Neumann 0x90e8, 0x001fffff, 0x010400c0, 388f43cf1b1SMichael Neumann 0x8c00, 0x000000ff, 0x00000003, 389f43cf1b1SMichael Neumann 0x8c00, 0x000000ff, 0x00000003, 390f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060, 391f43cf1b1SMichael Neumann 0x8c04, 0xf8ff00ff, 0x40600060, 392f43cf1b1SMichael Neumann 0x8c30, 0x0000000f, 0x00040005, 393f43cf1b1SMichael Neumann 0x8cf0, 0x1fff1fff, 0x08e00410, 394f43cf1b1SMichael Neumann 0x8cf0, 0x1fff1fff, 0x08e00410, 395f43cf1b1SMichael Neumann 0x900c, 0x00ffffff, 0x0017071f, 396f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000, 397f43cf1b1SMichael Neumann 0x28350, 0x00000f01, 0x00000000, 398f43cf1b1SMichael Neumann 0x9508, 0xf700071f, 0x00000002, 399f43cf1b1SMichael Neumann 0x9508, 0xf700071f, 0x00000002, 400f43cf1b1SMichael Neumann 0x9688, 0x00300000, 0x0017000f, 401f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210, 402f43cf1b1SMichael Neumann 0x960c, 0xffffffff, 0x54763210, 403f43cf1b1SMichael Neumann 0x20ef8, 0x01ff01ff, 0x00000002, 404f43cf1b1SMichael Neumann 0x20e98, 0xfffffbff, 0x00200000, 405f43cf1b1SMichael Neumann 0x2015c, 0xffffffff, 0x00000f40, 406f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082, 407f43cf1b1SMichael Neumann 0x88c4, 0x001f3ae3, 0x00000082, 408f43cf1b1SMichael Neumann 0x8978, 0x3fffffff, 0x04050140, 409f43cf1b1SMichael Neumann 0x8978, 0x3fffffff, 0x04050140, 410f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010, 411f43cf1b1SMichael Neumann 0x88d4, 0x0000001f, 0x00000010, 412f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000, 413f43cf1b1SMichael Neumann 0x8974, 0xffffffff, 0x00000000 414f43cf1b1SMichael Neumann }; 415f43cf1b1SMichael Neumann 416f43cf1b1SMichael Neumann static void ni_init_golden_registers(struct radeon_device *rdev) 417f43cf1b1SMichael Neumann { 418f43cf1b1SMichael Neumann switch (rdev->family) { 419f43cf1b1SMichael Neumann case CHIP_CAYMAN: 420f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev, 421f43cf1b1SMichael Neumann cayman_golden_registers, 422f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(cayman_golden_registers)); 423f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev, 424f43cf1b1SMichael Neumann cayman_golden_registers2, 425f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(cayman_golden_registers2)); 426f43cf1b1SMichael Neumann break; 427f43cf1b1SMichael Neumann case CHIP_ARUBA: 428f43cf1b1SMichael Neumann if ((rdev->ddev->pci_device == 0x9900) || 429f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9901) || 430f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9903) || 431f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9904) || 432f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9905) || 433f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9906) || 434f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9907) || 435f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9908) || 436f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9909) || 437f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x990A) || 438f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x990B) || 439f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x990C) || 440f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x990D) || 441f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x990E) || 442f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x990F) || 443f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9910) || 444f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9913) || 445f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9917) || 446f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9918)) { 447f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev, 448f43cf1b1SMichael Neumann dvst_golden_registers, 449f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(dvst_golden_registers)); 450f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev, 451f43cf1b1SMichael Neumann dvst_golden_registers2, 452f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(dvst_golden_registers2)); 453f43cf1b1SMichael Neumann } else { 454f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev, 455f43cf1b1SMichael Neumann scrapper_golden_registers, 456f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(scrapper_golden_registers)); 457f43cf1b1SMichael Neumann radeon_program_register_sequence(rdev, 458f43cf1b1SMichael Neumann dvst_golden_registers2, 459f43cf1b1SMichael Neumann (const u32)ARRAY_SIZE(dvst_golden_registers2)); 460f43cf1b1SMichael Neumann } 461f43cf1b1SMichael Neumann break; 462f43cf1b1SMichael Neumann default: 463f43cf1b1SMichael Neumann break; 464f43cf1b1SMichael Neumann } 465f43cf1b1SMichael Neumann } 466f43cf1b1SMichael Neumann 467926deccbSFrançois Tigeot #define BTC_IO_MC_REGS_SIZE 29 468926deccbSFrançois Tigeot 469926deccbSFrançois Tigeot static const u32 barts_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { 470926deccbSFrançois Tigeot {0x00000077, 0xff010100}, 471926deccbSFrançois Tigeot {0x00000078, 0x00000000}, 472926deccbSFrançois Tigeot {0x00000079, 0x00001434}, 473926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08}, 474926deccbSFrançois Tigeot {0x0000007b, 0x00040000}, 475926deccbSFrançois Tigeot {0x0000007c, 0x000080c0}, 476926deccbSFrançois Tigeot {0x0000007d, 0x09000000}, 477926deccbSFrançois Tigeot {0x0000007e, 0x00210404}, 478926deccbSFrançois Tigeot {0x00000081, 0x08a8e800}, 479926deccbSFrançois Tigeot {0x00000082, 0x00030444}, 480926deccbSFrançois Tigeot {0x00000083, 0x00000000}, 481926deccbSFrançois Tigeot {0x00000085, 0x00000001}, 482926deccbSFrançois Tigeot {0x00000086, 0x00000002}, 483926deccbSFrançois Tigeot {0x00000087, 0x48490000}, 484926deccbSFrançois Tigeot {0x00000088, 0x20244647}, 485926deccbSFrançois Tigeot {0x00000089, 0x00000005}, 486926deccbSFrançois Tigeot {0x0000008b, 0x66030000}, 487926deccbSFrançois Tigeot {0x0000008c, 0x00006603}, 488926deccbSFrançois Tigeot {0x0000008d, 0x00000100}, 489926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a}, 490926deccbSFrançois Tigeot {0x00000090, 0xff000001}, 491926deccbSFrançois Tigeot {0x00000094, 0x00101101}, 492926deccbSFrançois Tigeot {0x00000095, 0x00000fff}, 493926deccbSFrançois Tigeot {0x00000096, 0x00116fff}, 494926deccbSFrançois Tigeot {0x00000097, 0x60010000}, 495926deccbSFrançois Tigeot {0x00000098, 0x10010000}, 496926deccbSFrançois Tigeot {0x00000099, 0x00006000}, 497926deccbSFrançois Tigeot {0x0000009a, 0x00001000}, 498926deccbSFrançois Tigeot {0x0000009f, 0x00946a00} 499926deccbSFrançois Tigeot }; 500926deccbSFrançois Tigeot 501926deccbSFrançois Tigeot static const u32 turks_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { 502926deccbSFrançois Tigeot {0x00000077, 0xff010100}, 503926deccbSFrançois Tigeot {0x00000078, 0x00000000}, 504926deccbSFrançois Tigeot {0x00000079, 0x00001434}, 505926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08}, 506926deccbSFrançois Tigeot {0x0000007b, 0x00040000}, 507926deccbSFrançois Tigeot {0x0000007c, 0x000080c0}, 508926deccbSFrançois Tigeot {0x0000007d, 0x09000000}, 509926deccbSFrançois Tigeot {0x0000007e, 0x00210404}, 510926deccbSFrançois Tigeot {0x00000081, 0x08a8e800}, 511926deccbSFrançois Tigeot {0x00000082, 0x00030444}, 512926deccbSFrançois Tigeot {0x00000083, 0x00000000}, 513926deccbSFrançois Tigeot {0x00000085, 0x00000001}, 514926deccbSFrançois Tigeot {0x00000086, 0x00000002}, 515926deccbSFrançois Tigeot {0x00000087, 0x48490000}, 516926deccbSFrançois Tigeot {0x00000088, 0x20244647}, 517926deccbSFrançois Tigeot {0x00000089, 0x00000005}, 518926deccbSFrançois Tigeot {0x0000008b, 0x66030000}, 519926deccbSFrançois Tigeot {0x0000008c, 0x00006603}, 520926deccbSFrançois Tigeot {0x0000008d, 0x00000100}, 521926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a}, 522926deccbSFrançois Tigeot {0x00000090, 0xff000001}, 523926deccbSFrançois Tigeot {0x00000094, 0x00101101}, 524926deccbSFrançois Tigeot {0x00000095, 0x00000fff}, 525926deccbSFrançois Tigeot {0x00000096, 0x00116fff}, 526926deccbSFrançois Tigeot {0x00000097, 0x60010000}, 527926deccbSFrançois Tigeot {0x00000098, 0x10010000}, 528926deccbSFrançois Tigeot {0x00000099, 0x00006000}, 529926deccbSFrançois Tigeot {0x0000009a, 0x00001000}, 530926deccbSFrançois Tigeot {0x0000009f, 0x00936a00} 531926deccbSFrançois Tigeot }; 532926deccbSFrançois Tigeot 533926deccbSFrançois Tigeot static const u32 caicos_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { 534926deccbSFrançois Tigeot {0x00000077, 0xff010100}, 535926deccbSFrançois Tigeot {0x00000078, 0x00000000}, 536926deccbSFrançois Tigeot {0x00000079, 0x00001434}, 537926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08}, 538926deccbSFrançois Tigeot {0x0000007b, 0x00040000}, 539926deccbSFrançois Tigeot {0x0000007c, 0x000080c0}, 540926deccbSFrançois Tigeot {0x0000007d, 0x09000000}, 541926deccbSFrançois Tigeot {0x0000007e, 0x00210404}, 542926deccbSFrançois Tigeot {0x00000081, 0x08a8e800}, 543926deccbSFrançois Tigeot {0x00000082, 0x00030444}, 544926deccbSFrançois Tigeot {0x00000083, 0x00000000}, 545926deccbSFrançois Tigeot {0x00000085, 0x00000001}, 546926deccbSFrançois Tigeot {0x00000086, 0x00000002}, 547926deccbSFrançois Tigeot {0x00000087, 0x48490000}, 548926deccbSFrançois Tigeot {0x00000088, 0x20244647}, 549926deccbSFrançois Tigeot {0x00000089, 0x00000005}, 550926deccbSFrançois Tigeot {0x0000008b, 0x66030000}, 551926deccbSFrançois Tigeot {0x0000008c, 0x00006603}, 552926deccbSFrançois Tigeot {0x0000008d, 0x00000100}, 553926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a}, 554926deccbSFrançois Tigeot {0x00000090, 0xff000001}, 555926deccbSFrançois Tigeot {0x00000094, 0x00101101}, 556926deccbSFrançois Tigeot {0x00000095, 0x00000fff}, 557926deccbSFrançois Tigeot {0x00000096, 0x00116fff}, 558926deccbSFrançois Tigeot {0x00000097, 0x60010000}, 559926deccbSFrançois Tigeot {0x00000098, 0x10010000}, 560926deccbSFrançois Tigeot {0x00000099, 0x00006000}, 561926deccbSFrançois Tigeot {0x0000009a, 0x00001000}, 562926deccbSFrançois Tigeot {0x0000009f, 0x00916a00} 563926deccbSFrançois Tigeot }; 564926deccbSFrançois Tigeot 565926deccbSFrançois Tigeot static const u32 cayman_io_mc_regs[BTC_IO_MC_REGS_SIZE][2] = { 566926deccbSFrançois Tigeot {0x00000077, 0xff010100}, 567926deccbSFrançois Tigeot {0x00000078, 0x00000000}, 568926deccbSFrançois Tigeot {0x00000079, 0x00001434}, 569926deccbSFrançois Tigeot {0x0000007a, 0xcc08ec08}, 570926deccbSFrançois Tigeot {0x0000007b, 0x00040000}, 571926deccbSFrançois Tigeot {0x0000007c, 0x000080c0}, 572926deccbSFrançois Tigeot {0x0000007d, 0x09000000}, 573926deccbSFrançois Tigeot {0x0000007e, 0x00210404}, 574926deccbSFrançois Tigeot {0x00000081, 0x08a8e800}, 575926deccbSFrançois Tigeot {0x00000082, 0x00030444}, 576926deccbSFrançois Tigeot {0x00000083, 0x00000000}, 577926deccbSFrançois Tigeot {0x00000085, 0x00000001}, 578926deccbSFrançois Tigeot {0x00000086, 0x00000002}, 579926deccbSFrançois Tigeot {0x00000087, 0x48490000}, 580926deccbSFrançois Tigeot {0x00000088, 0x20244647}, 581926deccbSFrançois Tigeot {0x00000089, 0x00000005}, 582926deccbSFrançois Tigeot {0x0000008b, 0x66030000}, 583926deccbSFrançois Tigeot {0x0000008c, 0x00006603}, 584926deccbSFrançois Tigeot {0x0000008d, 0x00000100}, 585926deccbSFrançois Tigeot {0x0000008f, 0x00001c0a}, 586926deccbSFrançois Tigeot {0x00000090, 0xff000001}, 587926deccbSFrançois Tigeot {0x00000094, 0x00101101}, 588926deccbSFrançois Tigeot {0x00000095, 0x00000fff}, 589926deccbSFrançois Tigeot {0x00000096, 0x00116fff}, 590926deccbSFrançois Tigeot {0x00000097, 0x60010000}, 591926deccbSFrançois Tigeot {0x00000098, 0x10010000}, 592926deccbSFrançois Tigeot {0x00000099, 0x00006000}, 593926deccbSFrançois Tigeot {0x0000009a, 0x00001000}, 594926deccbSFrançois Tigeot {0x0000009f, 0x00976b00} 595926deccbSFrançois Tigeot }; 596926deccbSFrançois Tigeot 597926deccbSFrançois Tigeot int ni_mc_load_microcode(struct radeon_device *rdev) 598926deccbSFrançois Tigeot { 599926deccbSFrançois Tigeot const __be32 *fw_data; 600926deccbSFrançois Tigeot u32 mem_type, running, blackout = 0; 601926deccbSFrançois Tigeot u32 *io_mc_regs; 602926deccbSFrançois Tigeot int i, ucode_size, regs_size; 603926deccbSFrançois Tigeot 604926deccbSFrançois Tigeot if (!rdev->mc_fw) 605926deccbSFrançois Tigeot return -EINVAL; 606926deccbSFrançois Tigeot 607926deccbSFrançois Tigeot switch (rdev->family) { 608926deccbSFrançois Tigeot case CHIP_BARTS: 609926deccbSFrançois Tigeot io_mc_regs = (u32 *)&barts_io_mc_regs; 610926deccbSFrançois Tigeot ucode_size = BTC_MC_UCODE_SIZE; 611926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE; 612926deccbSFrançois Tigeot break; 613926deccbSFrançois Tigeot case CHIP_TURKS: 614926deccbSFrançois Tigeot io_mc_regs = (u32 *)&turks_io_mc_regs; 615926deccbSFrançois Tigeot ucode_size = BTC_MC_UCODE_SIZE; 616926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE; 617926deccbSFrançois Tigeot break; 618926deccbSFrançois Tigeot case CHIP_CAICOS: 619926deccbSFrançois Tigeot default: 620926deccbSFrançois Tigeot io_mc_regs = (u32 *)&caicos_io_mc_regs; 621926deccbSFrançois Tigeot ucode_size = BTC_MC_UCODE_SIZE; 622926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE; 623926deccbSFrançois Tigeot break; 624926deccbSFrançois Tigeot case CHIP_CAYMAN: 625926deccbSFrançois Tigeot io_mc_regs = (u32 *)&cayman_io_mc_regs; 626926deccbSFrançois Tigeot ucode_size = CAYMAN_MC_UCODE_SIZE; 627926deccbSFrançois Tigeot regs_size = BTC_IO_MC_REGS_SIZE; 628926deccbSFrançois Tigeot break; 629926deccbSFrançois Tigeot } 630926deccbSFrançois Tigeot 631926deccbSFrançois Tigeot mem_type = (RREG32(MC_SEQ_MISC0) & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT; 632926deccbSFrançois Tigeot running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; 633926deccbSFrançois Tigeot 634926deccbSFrançois Tigeot if ((mem_type == MC_SEQ_MISC0_GDDR5_VALUE) && (running == 0)) { 635926deccbSFrançois Tigeot if (running) { 636926deccbSFrançois Tigeot blackout = RREG32(MC_SHARED_BLACKOUT_CNTL); 637926deccbSFrançois Tigeot WREG32(MC_SHARED_BLACKOUT_CNTL, 1); 638926deccbSFrançois Tigeot } 639926deccbSFrançois Tigeot 640926deccbSFrançois Tigeot /* reset the engine and set to writable */ 641926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 642926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000010); 643926deccbSFrançois Tigeot 644926deccbSFrançois Tigeot /* load mc io regs */ 645926deccbSFrançois Tigeot for (i = 0; i < regs_size; i++) { 646926deccbSFrançois Tigeot WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); 647926deccbSFrançois Tigeot WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); 648926deccbSFrançois Tigeot } 649926deccbSFrançois Tigeot /* load the MC ucode */ 650926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->mc_fw->data; 651926deccbSFrançois Tigeot for (i = 0; i < ucode_size; i++) 652926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); 653926deccbSFrançois Tigeot 654926deccbSFrançois Tigeot /* put the engine back into the active state */ 655926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 656926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000004); 657926deccbSFrançois Tigeot WREG32(MC_SEQ_SUP_CNTL, 0x00000001); 658926deccbSFrançois Tigeot 659926deccbSFrançois Tigeot /* wait for training to complete */ 660926deccbSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) { 661926deccbSFrançois Tigeot if (RREG32(MC_IO_PAD_CNTL_D0) & MEM_FALL_OUT_CMD) 662926deccbSFrançois Tigeot break; 663926deccbSFrançois Tigeot DRM_UDELAY(1); 664926deccbSFrançois Tigeot } 665926deccbSFrançois Tigeot 666926deccbSFrançois Tigeot if (running) 667926deccbSFrançois Tigeot WREG32(MC_SHARED_BLACKOUT_CNTL, blackout); 668926deccbSFrançois Tigeot } 669926deccbSFrançois Tigeot 670926deccbSFrançois Tigeot return 0; 671926deccbSFrançois Tigeot } 672926deccbSFrançois Tigeot 673926deccbSFrançois Tigeot int ni_init_microcode(struct radeon_device *rdev) 674926deccbSFrançois Tigeot { 675926deccbSFrançois Tigeot const char *chip_name; 676926deccbSFrançois Tigeot const char *rlc_chip_name; 677926deccbSFrançois Tigeot size_t pfp_req_size, me_req_size, rlc_req_size, mc_req_size; 67857e252bfSMichael Neumann size_t smc_req_size = 0; 679926deccbSFrançois Tigeot char fw_name[30]; 680926deccbSFrançois Tigeot int err; 681926deccbSFrançois Tigeot 682926deccbSFrançois Tigeot DRM_DEBUG("\n"); 683926deccbSFrançois Tigeot 684926deccbSFrançois Tigeot switch (rdev->family) { 685926deccbSFrançois Tigeot case CHIP_BARTS: 686926deccbSFrançois Tigeot chip_name = "BARTS"; 687926deccbSFrançois Tigeot rlc_chip_name = "BTC"; 688926deccbSFrançois Tigeot pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; 689926deccbSFrançois Tigeot me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; 690926deccbSFrançois Tigeot rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; 691926deccbSFrançois Tigeot mc_req_size = BTC_MC_UCODE_SIZE * 4; 69257e252bfSMichael Neumann smc_req_size = ALIGN(BARTS_SMC_UCODE_SIZE, 4); 693926deccbSFrançois Tigeot break; 694926deccbSFrançois Tigeot case CHIP_TURKS: 695926deccbSFrançois Tigeot chip_name = "TURKS"; 696926deccbSFrançois Tigeot rlc_chip_name = "BTC"; 697926deccbSFrançois Tigeot pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; 698926deccbSFrançois Tigeot me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; 699926deccbSFrançois Tigeot rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; 700926deccbSFrançois Tigeot mc_req_size = BTC_MC_UCODE_SIZE * 4; 70157e252bfSMichael Neumann smc_req_size = ALIGN(TURKS_SMC_UCODE_SIZE, 4); 702926deccbSFrançois Tigeot break; 703926deccbSFrançois Tigeot case CHIP_CAICOS: 704926deccbSFrançois Tigeot chip_name = "CAICOS"; 705926deccbSFrançois Tigeot rlc_chip_name = "BTC"; 706926deccbSFrançois Tigeot pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4; 707926deccbSFrançois Tigeot me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4; 708926deccbSFrançois Tigeot rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4; 709926deccbSFrançois Tigeot mc_req_size = BTC_MC_UCODE_SIZE * 4; 71057e252bfSMichael Neumann smc_req_size = ALIGN(CAICOS_SMC_UCODE_SIZE, 4); 711926deccbSFrançois Tigeot break; 712926deccbSFrançois Tigeot case CHIP_CAYMAN: 713926deccbSFrançois Tigeot chip_name = "CAYMAN"; 714926deccbSFrançois Tigeot rlc_chip_name = "CAYMAN"; 715926deccbSFrançois Tigeot pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; 716926deccbSFrançois Tigeot me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; 717926deccbSFrançois Tigeot rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4; 718926deccbSFrançois Tigeot mc_req_size = CAYMAN_MC_UCODE_SIZE * 4; 71957e252bfSMichael Neumann smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4); 720926deccbSFrançois Tigeot break; 721926deccbSFrançois Tigeot case CHIP_ARUBA: 722926deccbSFrançois Tigeot chip_name = "ARUBA"; 723926deccbSFrançois Tigeot rlc_chip_name = "ARUBA"; 724926deccbSFrançois Tigeot /* pfp/me same size as CAYMAN */ 725926deccbSFrançois Tigeot pfp_req_size = CAYMAN_PFP_UCODE_SIZE * 4; 726926deccbSFrançois Tigeot me_req_size = CAYMAN_PM4_UCODE_SIZE * 4; 727926deccbSFrançois Tigeot rlc_req_size = ARUBA_RLC_UCODE_SIZE * 4; 728926deccbSFrançois Tigeot mc_req_size = 0; 729926deccbSFrançois Tigeot break; 730926deccbSFrançois Tigeot default: panic("%s: Unsupported family %d", __func__, rdev->family); 731926deccbSFrançois Tigeot } 732926deccbSFrançois Tigeot 733926deccbSFrançois Tigeot DRM_INFO("Loading %s Microcode\n", chip_name); 734926deccbSFrançois Tigeot 735926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name); 736*fcd4983fSzrj err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 737*fcd4983fSzrj if (err) 738926deccbSFrançois Tigeot goto out; 739926deccbSFrançois Tigeot if (rdev->pfp_fw->datasize != pfp_req_size) { 740926deccbSFrançois Tigeot DRM_ERROR( 74157e252bfSMichael Neumann "ni_pfp: Bogus length %zu in firmware \"%s\"\n", 742926deccbSFrançois Tigeot rdev->pfp_fw->datasize, fw_name); 743926deccbSFrançois Tigeot err = -EINVAL; 744926deccbSFrançois Tigeot goto out; 745926deccbSFrançois Tigeot } 746926deccbSFrançois Tigeot 747926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name); 748*fcd4983fSzrj err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 749*fcd4983fSzrj if (err) 750926deccbSFrançois Tigeot goto out; 751926deccbSFrançois Tigeot if (rdev->me_fw->datasize != me_req_size) { 752926deccbSFrançois Tigeot DRM_ERROR( 75357e252bfSMichael Neumann "ni_me: Bogus length %zu in firmware \"%s\"\n", 754926deccbSFrançois Tigeot rdev->me_fw->datasize, fw_name); 755926deccbSFrançois Tigeot err = -EINVAL; 756926deccbSFrançois Tigeot } 757926deccbSFrançois Tigeot 758926deccbSFrançois Tigeot ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", 759926deccbSFrançois Tigeot rlc_chip_name); 760*fcd4983fSzrj err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 761*fcd4983fSzrj if (err) 762926deccbSFrançois Tigeot goto out; 763926deccbSFrançois Tigeot if (rdev->rlc_fw->datasize != rlc_req_size) { 764926deccbSFrançois Tigeot DRM_ERROR( 765926deccbSFrançois Tigeot "ni_rlc: Bogus length %zu in firmware \"%s\"\n", 766926deccbSFrançois Tigeot rdev->rlc_fw->datasize, fw_name); 767926deccbSFrançois Tigeot err = -EINVAL; 768926deccbSFrançois Tigeot } 769926deccbSFrançois Tigeot 770926deccbSFrançois Tigeot /* no MC ucode on TN */ 771926deccbSFrançois Tigeot if (!(rdev->flags & RADEON_IS_IGP)) { 772*fcd4983fSzrj ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name); 773*fcd4983fSzrj err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 774*fcd4983fSzrj if (err) 775926deccbSFrançois Tigeot goto out; 776926deccbSFrançois Tigeot if (rdev->mc_fw->datasize != mc_req_size) { 777926deccbSFrançois Tigeot DRM_ERROR( 778926deccbSFrançois Tigeot "ni_mc: Bogus length %zu in firmware \"%s\"\n", 779926deccbSFrançois Tigeot rdev->mc_fw->datasize, fw_name); 780926deccbSFrançois Tigeot err = -EINVAL; 781926deccbSFrançois Tigeot } 782926deccbSFrançois Tigeot } 78357e252bfSMichael Neumann 78457e252bfSMichael Neumann if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) { 78557e252bfSMichael Neumann ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_smc", chip_name); 78657e252bfSMichael Neumann err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 78757e252bfSMichael Neumann if (err) { 78857e252bfSMichael Neumann printk(KERN_ERR 78957e252bfSMichael Neumann "smc: error loading firmware \"%s\"\n", 79057e252bfSMichael Neumann fw_name); 79157e252bfSMichael Neumann release_firmware(rdev->smc_fw); 79257e252bfSMichael Neumann rdev->smc_fw = NULL; 79357e252bfSMichael Neumann } else if (rdev->smc_fw->datasize != smc_req_size) { 79457e252bfSMichael Neumann printk(KERN_ERR 79557e252bfSMichael Neumann "ni_smc: Bogus length %zu in firmware \"%s\"\n", 79657e252bfSMichael Neumann rdev->smc_fw->datasize, fw_name); 79757e252bfSMichael Neumann err = -EINVAL; 79857e252bfSMichael Neumann } 79957e252bfSMichael Neumann } 80057e252bfSMichael Neumann 801926deccbSFrançois Tigeot out: 802926deccbSFrançois Tigeot if (err) { 803926deccbSFrançois Tigeot if (err != -EINVAL) 804926deccbSFrançois Tigeot DRM_ERROR( 805926deccbSFrançois Tigeot "ni_cp: Failed to load firmware \"%s\"\n", 806926deccbSFrançois Tigeot fw_name); 807*fcd4983fSzrj release_firmware(rdev->pfp_fw); 808926deccbSFrançois Tigeot rdev->pfp_fw = NULL; 809*fcd4983fSzrj release_firmware(rdev->me_fw); 810926deccbSFrançois Tigeot rdev->me_fw = NULL; 811*fcd4983fSzrj release_firmware(rdev->rlc_fw); 812926deccbSFrançois Tigeot rdev->rlc_fw = NULL; 813*fcd4983fSzrj release_firmware(rdev->mc_fw); 814926deccbSFrançois Tigeot rdev->mc_fw = NULL; 815*fcd4983fSzrj release_firmware(rdev->smc_fw); 81657e252bfSMichael Neumann rdev->smc_fw = NULL; 81757e252bfSMichael Neumann } 818926deccbSFrançois Tigeot return err; 819926deccbSFrançois Tigeot } 820926deccbSFrançois Tigeot 821926deccbSFrançois Tigeot /** 822926deccbSFrançois Tigeot * ni_fini_microcode - drop the firmwares image references 823926deccbSFrançois Tigeot * 824926deccbSFrançois Tigeot * @rdev: radeon_device pointer 825926deccbSFrançois Tigeot * 826926deccbSFrançois Tigeot * Drop the pfp, me, mc and rlc firmwares image references. 827926deccbSFrançois Tigeot * Called at driver shutdown. 828926deccbSFrançois Tigeot */ 829926deccbSFrançois Tigeot void ni_fini_microcode(struct radeon_device *rdev) 830926deccbSFrançois Tigeot { 831*fcd4983fSzrj release_firmware(rdev->pfp_fw); 832926deccbSFrançois Tigeot rdev->pfp_fw = NULL; 833*fcd4983fSzrj release_firmware(rdev->me_fw); 834926deccbSFrançois Tigeot rdev->me_fw = NULL; 835*fcd4983fSzrj release_firmware(rdev->rlc_fw); 836926deccbSFrançois Tigeot rdev->rlc_fw = NULL; 837*fcd4983fSzrj release_firmware(rdev->mc_fw); 838926deccbSFrançois Tigeot rdev->mc_fw = NULL; 839926deccbSFrançois Tigeot } 840926deccbSFrançois Tigeot 84157e252bfSMichael Neumann int tn_get_temp(struct radeon_device *rdev) 84257e252bfSMichael Neumann { 84357e252bfSMichael Neumann u32 temp = RREG32_SMC(TN_CURRENT_GNB_TEMP) & 0x7ff; 84457e252bfSMichael Neumann int actual_temp = (temp / 8) - 49; 84557e252bfSMichael Neumann 84657e252bfSMichael Neumann return actual_temp * 1000; 84757e252bfSMichael Neumann } 84857e252bfSMichael Neumann 849926deccbSFrançois Tigeot /* 850926deccbSFrançois Tigeot * Core functions 851926deccbSFrançois Tigeot */ 852926deccbSFrançois Tigeot static void cayman_gpu_init(struct radeon_device *rdev) 853926deccbSFrançois Tigeot { 854926deccbSFrançois Tigeot u32 gb_addr_config = 0; 855926deccbSFrançois Tigeot u32 mc_shared_chmap, mc_arb_ramcfg; 856926deccbSFrançois Tigeot u32 cgts_tcc_disable; 857926deccbSFrançois Tigeot u32 sx_debug_1; 858926deccbSFrançois Tigeot u32 smx_dc_ctl0; 859926deccbSFrançois Tigeot u32 cgts_sm_ctrl_reg; 860926deccbSFrançois Tigeot u32 hdp_host_path_cntl; 861926deccbSFrançois Tigeot u32 tmp; 862926deccbSFrançois Tigeot u32 disabled_rb_mask; 863926deccbSFrançois Tigeot int i, j; 864926deccbSFrançois Tigeot 865926deccbSFrançois Tigeot switch (rdev->family) { 866926deccbSFrançois Tigeot case CHIP_CAYMAN: 867926deccbSFrançois Tigeot rdev->config.cayman.max_shader_engines = 2; 868926deccbSFrançois Tigeot rdev->config.cayman.max_pipes_per_simd = 4; 869926deccbSFrançois Tigeot rdev->config.cayman.max_tile_pipes = 8; 870926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 12; 871926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 4; 872926deccbSFrançois Tigeot rdev->config.cayman.max_texture_channel_caches = 8; 873926deccbSFrançois Tigeot rdev->config.cayman.max_gprs = 256; 874926deccbSFrançois Tigeot rdev->config.cayman.max_threads = 256; 875926deccbSFrançois Tigeot rdev->config.cayman.max_gs_threads = 32; 876926deccbSFrançois Tigeot rdev->config.cayman.max_stack_entries = 512; 877926deccbSFrançois Tigeot rdev->config.cayman.sx_num_of_sets = 8; 878926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 256; 879926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 64; 880926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 192; 881926deccbSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 8; 882926deccbSFrançois Tigeot rdev->config.cayman.sq_num_cf_insts = 2; 883926deccbSFrançois Tigeot 884926deccbSFrançois Tigeot rdev->config.cayman.sc_prim_fifo_size = 0x100; 885926deccbSFrançois Tigeot rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; 886926deccbSFrançois Tigeot rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; 887926deccbSFrançois Tigeot gb_addr_config = CAYMAN_GB_ADDR_CONFIG_GOLDEN; 888926deccbSFrançois Tigeot break; 889926deccbSFrançois Tigeot case CHIP_ARUBA: 890926deccbSFrançois Tigeot default: 891926deccbSFrançois Tigeot rdev->config.cayman.max_shader_engines = 1; 892926deccbSFrançois Tigeot rdev->config.cayman.max_pipes_per_simd = 4; 893926deccbSFrançois Tigeot rdev->config.cayman.max_tile_pipes = 2; 894926deccbSFrançois Tigeot if ((rdev->ddev->pci_device == 0x9900) || 895926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9901) || 896926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9905) || 897926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9906) || 898926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9907) || 899926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9908) || 900926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9909) || 901b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x990B) || 902b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x990C) || 903b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x990F) || 904926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9910) || 905b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x9917) || 906f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9999) || 907f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x999C)) { 908926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 6; 909926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 2; 910926deccbSFrançois Tigeot } else if ((rdev->ddev->pci_device == 0x9903) || 911926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9904) || 912926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x990A) || 913b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x990D) || 914b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x990E) || 915926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9913) || 916f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x9918) || 917f43cf1b1SMichael Neumann (rdev->ddev->pci_device == 0x999D)) { 918926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 4; 919926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 2; 920926deccbSFrançois Tigeot } else if ((rdev->ddev->pci_device == 0x9919) || 921926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9990) || 922926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9991) || 923926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x9994) || 924b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x9995) || 925b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x9996) || 926b403bed8SMichael Neumann (rdev->ddev->pci_device == 0x999A) || 927926deccbSFrançois Tigeot (rdev->ddev->pci_device == 0x99A0)) { 928926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 3; 929926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 1; 930926deccbSFrançois Tigeot } else { 931926deccbSFrançois Tigeot rdev->config.cayman.max_simds_per_se = 2; 932926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se = 1; 933926deccbSFrançois Tigeot } 934926deccbSFrançois Tigeot rdev->config.cayman.max_texture_channel_caches = 2; 935926deccbSFrançois Tigeot rdev->config.cayman.max_gprs = 256; 936926deccbSFrançois Tigeot rdev->config.cayman.max_threads = 256; 937926deccbSFrançois Tigeot rdev->config.cayman.max_gs_threads = 32; 938926deccbSFrançois Tigeot rdev->config.cayman.max_stack_entries = 512; 939926deccbSFrançois Tigeot rdev->config.cayman.sx_num_of_sets = 8; 940926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_size = 256; 941926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_pos_size = 64; 942926deccbSFrançois Tigeot rdev->config.cayman.sx_max_export_smx_size = 192; 943926deccbSFrançois Tigeot rdev->config.cayman.max_hw_contexts = 8; 944926deccbSFrançois Tigeot rdev->config.cayman.sq_num_cf_insts = 2; 945926deccbSFrançois Tigeot 946926deccbSFrançois Tigeot rdev->config.cayman.sc_prim_fifo_size = 0x40; 947926deccbSFrançois Tigeot rdev->config.cayman.sc_hiz_tile_fifo_size = 0x30; 948926deccbSFrançois Tigeot rdev->config.cayman.sc_earlyz_tile_fifo_size = 0x130; 949926deccbSFrançois Tigeot gb_addr_config = ARUBA_GB_ADDR_CONFIG_GOLDEN; 950926deccbSFrançois Tigeot break; 951926deccbSFrançois Tigeot } 952926deccbSFrançois Tigeot 953926deccbSFrançois Tigeot /* Initialize HDP */ 954926deccbSFrançois Tigeot for (i = 0, j = 0; i < 32; i++, j += 0x18) { 955926deccbSFrançois Tigeot WREG32((0x2c14 + j), 0x00000000); 956926deccbSFrançois Tigeot WREG32((0x2c18 + j), 0x00000000); 957926deccbSFrançois Tigeot WREG32((0x2c1c + j), 0x00000000); 958926deccbSFrançois Tigeot WREG32((0x2c20 + j), 0x00000000); 959926deccbSFrançois Tigeot WREG32((0x2c24 + j), 0x00000000); 960926deccbSFrançois Tigeot } 961926deccbSFrançois Tigeot 962926deccbSFrançois Tigeot WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); 963926deccbSFrançois Tigeot 964926deccbSFrançois Tigeot evergreen_fix_pci_max_read_req_size(rdev); 965926deccbSFrançois Tigeot 966926deccbSFrançois Tigeot mc_shared_chmap = RREG32(MC_SHARED_CHMAP); 967926deccbSFrançois Tigeot mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); 968926deccbSFrançois Tigeot 969926deccbSFrançois Tigeot tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; 970926deccbSFrançois Tigeot rdev->config.cayman.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; 971926deccbSFrançois Tigeot if (rdev->config.cayman.mem_row_size_in_kb > 4) 972926deccbSFrançois Tigeot rdev->config.cayman.mem_row_size_in_kb = 4; 973926deccbSFrançois Tigeot /* XXX use MC settings? */ 974926deccbSFrançois Tigeot rdev->config.cayman.shader_engine_tile_size = 32; 975926deccbSFrançois Tigeot rdev->config.cayman.num_gpus = 1; 976926deccbSFrançois Tigeot rdev->config.cayman.multi_gpu_tile_size = 64; 977926deccbSFrançois Tigeot 978926deccbSFrançois Tigeot tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT; 979926deccbSFrançois Tigeot rdev->config.cayman.num_tile_pipes = (1 << tmp); 980926deccbSFrançois Tigeot tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT; 981926deccbSFrançois Tigeot rdev->config.cayman.mem_max_burst_length_bytes = (tmp + 1) * 256; 982926deccbSFrançois Tigeot tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT; 983926deccbSFrançois Tigeot rdev->config.cayman.num_shader_engines = tmp + 1; 984926deccbSFrançois Tigeot tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT; 985926deccbSFrançois Tigeot rdev->config.cayman.num_gpus = tmp + 1; 986926deccbSFrançois Tigeot tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT; 987926deccbSFrançois Tigeot rdev->config.cayman.multi_gpu_tile_size = 1 << tmp; 988926deccbSFrançois Tigeot tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT; 989926deccbSFrançois Tigeot rdev->config.cayman.mem_row_size_in_kb = 1 << tmp; 990926deccbSFrançois Tigeot 991926deccbSFrançois Tigeot 992926deccbSFrançois Tigeot /* setup tiling info dword. gb_addr_config is not adequate since it does 993926deccbSFrançois Tigeot * not have bank info, so create a custom tiling dword. 994926deccbSFrançois Tigeot * bits 3:0 num_pipes 995926deccbSFrançois Tigeot * bits 7:4 num_banks 996926deccbSFrançois Tigeot * bits 11:8 group_size 997926deccbSFrançois Tigeot * bits 15:12 row_size 998926deccbSFrançois Tigeot */ 999926deccbSFrançois Tigeot rdev->config.cayman.tile_config = 0; 1000926deccbSFrançois Tigeot switch (rdev->config.cayman.num_tile_pipes) { 1001926deccbSFrançois Tigeot case 1: 1002926deccbSFrançois Tigeot default: 1003926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (0 << 0); 1004926deccbSFrançois Tigeot break; 1005926deccbSFrançois Tigeot case 2: 1006926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (1 << 0); 1007926deccbSFrançois Tigeot break; 1008926deccbSFrançois Tigeot case 4: 1009926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (2 << 0); 1010926deccbSFrançois Tigeot break; 1011926deccbSFrançois Tigeot case 8: 1012926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= (3 << 0); 1013926deccbSFrançois Tigeot break; 1014926deccbSFrançois Tigeot } 1015926deccbSFrançois Tigeot 1016926deccbSFrançois Tigeot /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ 1017926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) 1018926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 1 << 4; 1019926deccbSFrançois Tigeot else { 1020926deccbSFrançois Tigeot switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { 1021926deccbSFrançois Tigeot case 0: /* four banks */ 1022926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 0 << 4; 1023926deccbSFrançois Tigeot break; 1024926deccbSFrançois Tigeot case 1: /* eight banks */ 1025926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 1 << 4; 1026926deccbSFrançois Tigeot break; 1027926deccbSFrançois Tigeot case 2: /* sixteen banks */ 1028926deccbSFrançois Tigeot default: 1029926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 2 << 4; 1030926deccbSFrançois Tigeot break; 1031926deccbSFrançois Tigeot } 1032926deccbSFrançois Tigeot } 1033926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 1034926deccbSFrançois Tigeot ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; 1035926deccbSFrançois Tigeot rdev->config.cayman.tile_config |= 1036926deccbSFrançois Tigeot ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; 1037926deccbSFrançois Tigeot 1038926deccbSFrançois Tigeot tmp = 0; 1039926deccbSFrançois Tigeot for (i = (rdev->config.cayman.max_shader_engines - 1); i >= 0; i--) { 1040926deccbSFrançois Tigeot u32 rb_disable_bitmap; 1041926deccbSFrançois Tigeot 1042926deccbSFrançois Tigeot WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); 1043926deccbSFrançois Tigeot WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); 1044926deccbSFrançois Tigeot rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16; 1045926deccbSFrançois Tigeot tmp <<= 4; 1046926deccbSFrançois Tigeot tmp |= rb_disable_bitmap; 1047926deccbSFrançois Tigeot } 1048926deccbSFrançois Tigeot /* enabled rb are just the one not disabled :) */ 1049926deccbSFrançois Tigeot disabled_rb_mask = tmp; 1050f43cf1b1SMichael Neumann tmp = 0; 1051f43cf1b1SMichael Neumann for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++) 1052f43cf1b1SMichael Neumann tmp |= (1 << i); 1053f43cf1b1SMichael Neumann /* if all the backends are disabled, fix it up here */ 1054f43cf1b1SMichael Neumann if ((disabled_rb_mask & tmp) == tmp) { 1055f43cf1b1SMichael Neumann for (i = 0; i < (rdev->config.cayman.max_backends_per_se * rdev->config.cayman.max_shader_engines); i++) 1056f43cf1b1SMichael Neumann disabled_rb_mask &= ~(1 << i); 1057f43cf1b1SMichael Neumann } 1058926deccbSFrançois Tigeot 1059926deccbSFrançois Tigeot WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); 1060926deccbSFrançois Tigeot WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); 1061926deccbSFrançois Tigeot 1062926deccbSFrançois Tigeot WREG32(GB_ADDR_CONFIG, gb_addr_config); 1063926deccbSFrançois Tigeot WREG32(DMIF_ADDR_CONFIG, gb_addr_config); 1064f43cf1b1SMichael Neumann if (ASIC_IS_DCE6(rdev)) 1065f43cf1b1SMichael Neumann WREG32(DMIF_ADDR_CALC, gb_addr_config); 1066926deccbSFrançois Tigeot WREG32(HDP_ADDR_CONFIG, gb_addr_config); 1067926deccbSFrançois Tigeot WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); 1068926deccbSFrançois Tigeot WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); 1069f43cf1b1SMichael Neumann WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); 1070f43cf1b1SMichael Neumann WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); 1071f43cf1b1SMichael Neumann WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); 1072926deccbSFrançois Tigeot 1073b403bed8SMichael Neumann if ((rdev->config.cayman.max_backends_per_se == 1) && 1074b403bed8SMichael Neumann (rdev->flags & RADEON_IS_IGP)) { 1075b403bed8SMichael Neumann if ((disabled_rb_mask & 3) == 1) { 1076b403bed8SMichael Neumann /* RB0 disabled, RB1 enabled */ 1077b403bed8SMichael Neumann tmp = 0x11111111; 1078b403bed8SMichael Neumann } else { 1079b403bed8SMichael Neumann /* RB1 disabled, RB0 enabled */ 1080b403bed8SMichael Neumann tmp = 0x00000000; 1081b403bed8SMichael Neumann } 1082b403bed8SMichael Neumann } else { 1083926deccbSFrançois Tigeot tmp = gb_addr_config & NUM_PIPES_MASK; 1084926deccbSFrançois Tigeot tmp = r6xx_remap_render_backend(rdev, tmp, 1085926deccbSFrançois Tigeot rdev->config.cayman.max_backends_per_se * 1086926deccbSFrançois Tigeot rdev->config.cayman.max_shader_engines, 1087926deccbSFrançois Tigeot CAYMAN_MAX_BACKENDS, disabled_rb_mask); 1088b403bed8SMichael Neumann } 1089926deccbSFrançois Tigeot WREG32(GB_BACKEND_MAP, tmp); 1090926deccbSFrançois Tigeot 1091926deccbSFrançois Tigeot cgts_tcc_disable = 0xffff0000; 1092926deccbSFrançois Tigeot for (i = 0; i < rdev->config.cayman.max_texture_channel_caches; i++) 1093926deccbSFrançois Tigeot cgts_tcc_disable &= ~(1 << (16 + i)); 1094926deccbSFrançois Tigeot WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable); 1095926deccbSFrançois Tigeot WREG32(CGTS_SYS_TCC_DISABLE, cgts_tcc_disable); 1096926deccbSFrançois Tigeot WREG32(CGTS_USER_SYS_TCC_DISABLE, cgts_tcc_disable); 1097926deccbSFrançois Tigeot WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable); 1098926deccbSFrançois Tigeot 1099926deccbSFrançois Tigeot /* reprogram the shader complex */ 1100926deccbSFrançois Tigeot cgts_sm_ctrl_reg = RREG32(CGTS_SM_CTRL_REG); 1101926deccbSFrançois Tigeot for (i = 0; i < 16; i++) 1102926deccbSFrançois Tigeot WREG32(CGTS_SM_CTRL_REG, OVERRIDE); 1103926deccbSFrançois Tigeot WREG32(CGTS_SM_CTRL_REG, cgts_sm_ctrl_reg); 1104926deccbSFrançois Tigeot 1105926deccbSFrançois Tigeot /* set HW defaults for 3D engine */ 1106926deccbSFrançois Tigeot WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); 1107926deccbSFrançois Tigeot 1108926deccbSFrançois Tigeot sx_debug_1 = RREG32(SX_DEBUG_1); 1109926deccbSFrançois Tigeot sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; 1110926deccbSFrançois Tigeot WREG32(SX_DEBUG_1, sx_debug_1); 1111926deccbSFrançois Tigeot 1112926deccbSFrançois Tigeot smx_dc_ctl0 = RREG32(SMX_DC_CTL0); 1113926deccbSFrançois Tigeot smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); 1114926deccbSFrançois Tigeot smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets); 1115926deccbSFrançois Tigeot WREG32(SMX_DC_CTL0, smx_dc_ctl0); 1116926deccbSFrançois Tigeot 1117926deccbSFrançois Tigeot WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); 1118926deccbSFrançois Tigeot 1119926deccbSFrançois Tigeot /* need to be explicitly zero-ed */ 1120926deccbSFrançois Tigeot WREG32(VGT_OFFCHIP_LDS_BASE, 0); 1121926deccbSFrançois Tigeot WREG32(SQ_LSTMP_RING_BASE, 0); 1122926deccbSFrançois Tigeot WREG32(SQ_HSTMP_RING_BASE, 0); 1123926deccbSFrançois Tigeot WREG32(SQ_ESTMP_RING_BASE, 0); 1124926deccbSFrançois Tigeot WREG32(SQ_GSTMP_RING_BASE, 0); 1125926deccbSFrançois Tigeot WREG32(SQ_VSTMP_RING_BASE, 0); 1126926deccbSFrançois Tigeot WREG32(SQ_PSTMP_RING_BASE, 0); 1127926deccbSFrançois Tigeot 1128926deccbSFrançois Tigeot WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); 1129926deccbSFrançois Tigeot 1130926deccbSFrançois Tigeot WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) | 1131926deccbSFrançois Tigeot POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) | 1132926deccbSFrançois Tigeot SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1))); 1133926deccbSFrançois Tigeot 1134926deccbSFrançois Tigeot WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) | 1135926deccbSFrançois Tigeot SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) | 1136926deccbSFrançois Tigeot SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size))); 1137926deccbSFrançois Tigeot 1138926deccbSFrançois Tigeot 1139926deccbSFrançois Tigeot WREG32(VGT_NUM_INSTANCES, 1); 1140926deccbSFrançois Tigeot 1141926deccbSFrançois Tigeot WREG32(CP_PERFMON_CNTL, 0); 1142926deccbSFrançois Tigeot 1143926deccbSFrançois Tigeot WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) | 1144926deccbSFrançois Tigeot FETCH_FIFO_HIWATER(0x4) | 1145926deccbSFrançois Tigeot DONE_FIFO_HIWATER(0xe0) | 1146926deccbSFrançois Tigeot ALU_UPDATE_FIFO_HIWATER(0x8))); 1147926deccbSFrançois Tigeot 1148926deccbSFrançois Tigeot WREG32(SQ_GPR_RESOURCE_MGMT_1, NUM_CLAUSE_TEMP_GPRS(4)); 1149926deccbSFrançois Tigeot WREG32(SQ_CONFIG, (VC_ENABLE | 1150926deccbSFrançois Tigeot EXPORT_SRC_C | 1151926deccbSFrançois Tigeot GFX_PRIO(0) | 1152926deccbSFrançois Tigeot CS1_PRIO(0) | 1153926deccbSFrançois Tigeot CS2_PRIO(1))); 1154926deccbSFrançois Tigeot WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, DYN_GPR_ENABLE); 1155926deccbSFrançois Tigeot 1156926deccbSFrançois Tigeot WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | 1157926deccbSFrançois Tigeot FORCE_EOV_MAX_REZ_CNT(255))); 1158926deccbSFrançois Tigeot 1159926deccbSFrançois Tigeot WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) | 1160926deccbSFrançois Tigeot AUTO_INVLD_EN(ES_AND_GS_AUTO)); 1161926deccbSFrançois Tigeot 1162926deccbSFrançois Tigeot WREG32(VGT_GS_VERTEX_REUSE, 16); 1163926deccbSFrançois Tigeot WREG32(PA_SC_LINE_STIPPLE_STATE, 0); 1164926deccbSFrançois Tigeot 1165926deccbSFrançois Tigeot WREG32(CB_PERF_CTR0_SEL_0, 0); 1166926deccbSFrançois Tigeot WREG32(CB_PERF_CTR0_SEL_1, 0); 1167926deccbSFrançois Tigeot WREG32(CB_PERF_CTR1_SEL_0, 0); 1168926deccbSFrançois Tigeot WREG32(CB_PERF_CTR1_SEL_1, 0); 1169926deccbSFrançois Tigeot WREG32(CB_PERF_CTR2_SEL_0, 0); 1170926deccbSFrançois Tigeot WREG32(CB_PERF_CTR2_SEL_1, 0); 1171926deccbSFrançois Tigeot WREG32(CB_PERF_CTR3_SEL_0, 0); 1172926deccbSFrançois Tigeot WREG32(CB_PERF_CTR3_SEL_1, 0); 1173926deccbSFrançois Tigeot 1174926deccbSFrançois Tigeot tmp = RREG32(HDP_MISC_CNTL); 1175926deccbSFrançois Tigeot tmp |= HDP_FLUSH_INVALIDATE_CACHE; 1176926deccbSFrançois Tigeot WREG32(HDP_MISC_CNTL, tmp); 1177926deccbSFrançois Tigeot 1178926deccbSFrançois Tigeot hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); 1179926deccbSFrançois Tigeot WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 1180926deccbSFrançois Tigeot 1181926deccbSFrançois Tigeot WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); 1182926deccbSFrançois Tigeot 1183926deccbSFrançois Tigeot DRM_UDELAY(50); 118457e252bfSMichael Neumann 118557e252bfSMichael Neumann /* set clockgating golden values on TN */ 118657e252bfSMichael Neumann if (rdev->family == CHIP_ARUBA) { 118757e252bfSMichael Neumann tmp = RREG32_CG(CG_CGTT_LOCAL_0); 118857e252bfSMichael Neumann tmp &= ~0x00380000; 118957e252bfSMichael Neumann WREG32_CG(CG_CGTT_LOCAL_0, tmp); 119057e252bfSMichael Neumann tmp = RREG32_CG(CG_CGTT_LOCAL_1); 119157e252bfSMichael Neumann tmp &= ~0x0e000000; 119257e252bfSMichael Neumann WREG32_CG(CG_CGTT_LOCAL_1, tmp); 119357e252bfSMichael Neumann } 1194926deccbSFrançois Tigeot } 1195926deccbSFrançois Tigeot 1196926deccbSFrançois Tigeot /* 1197926deccbSFrançois Tigeot * GART 1198926deccbSFrançois Tigeot */ 1199926deccbSFrançois Tigeot void cayman_pcie_gart_tlb_flush(struct radeon_device *rdev) 1200926deccbSFrançois Tigeot { 1201926deccbSFrançois Tigeot /* flush hdp cache */ 1202926deccbSFrançois Tigeot WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); 1203926deccbSFrançois Tigeot 1204926deccbSFrançois Tigeot /* bits 0-7 are the VM contexts0-7 */ 1205926deccbSFrançois Tigeot WREG32(VM_INVALIDATE_REQUEST, 1); 1206926deccbSFrançois Tigeot } 1207926deccbSFrançois Tigeot 1208926deccbSFrançois Tigeot static int cayman_pcie_gart_enable(struct radeon_device *rdev) 1209926deccbSFrançois Tigeot { 1210926deccbSFrançois Tigeot int i, r; 1211926deccbSFrançois Tigeot 1212926deccbSFrançois Tigeot if (rdev->gart.robj == NULL) { 1213926deccbSFrançois Tigeot dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 1214926deccbSFrançois Tigeot return -EINVAL; 1215926deccbSFrançois Tigeot } 1216926deccbSFrançois Tigeot r = radeon_gart_table_vram_pin(rdev); 1217926deccbSFrançois Tigeot if (r) 1218926deccbSFrançois Tigeot return r; 1219926deccbSFrançois Tigeot radeon_gart_restore(rdev); 1220926deccbSFrançois Tigeot /* Setup TLB control */ 1221926deccbSFrançois Tigeot WREG32(MC_VM_MX_L1_TLB_CNTL, 1222926deccbSFrançois Tigeot (0xA << 7) | 1223926deccbSFrançois Tigeot ENABLE_L1_TLB | 1224926deccbSFrançois Tigeot ENABLE_L1_FRAGMENT_PROCESSING | 1225926deccbSFrançois Tigeot SYSTEM_ACCESS_MODE_NOT_IN_SYS | 1226926deccbSFrançois Tigeot ENABLE_ADVANCED_DRIVER_MODEL | 1227926deccbSFrançois Tigeot SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); 1228926deccbSFrançois Tigeot /* Setup L2 cache */ 1229926deccbSFrançois Tigeot WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | 1230926deccbSFrançois Tigeot ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 1231926deccbSFrançois Tigeot ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | 1232926deccbSFrançois Tigeot EFFECTIVE_L2_QUEUE_SIZE(7) | 1233926deccbSFrançois Tigeot CONTEXT1_IDENTITY_ACCESS_MODE(1)); 1234926deccbSFrançois Tigeot WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); 1235926deccbSFrançois Tigeot WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 1236926deccbSFrançois Tigeot L2_CACHE_BIGK_FRAGMENT_SIZE(6)); 1237926deccbSFrançois Tigeot /* setup context0 */ 1238926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); 1239926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); 1240926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); 1241926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, 1242926deccbSFrançois Tigeot (u32)(rdev->dummy_page.addr >> 12)); 1243926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL2, 0); 1244926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | 1245926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); 1246926deccbSFrançois Tigeot 1247926deccbSFrançois Tigeot WREG32(0x15D4, 0); 1248926deccbSFrançois Tigeot WREG32(0x15D8, 0); 1249926deccbSFrançois Tigeot WREG32(0x15DC, 0); 1250926deccbSFrançois Tigeot 1251926deccbSFrançois Tigeot /* empty context1-7 */ 1252926deccbSFrançois Tigeot /* Assign the pt base to something valid for now; the pts used for 1253926deccbSFrançois Tigeot * the VMs are determined by the application and setup and assigned 1254926deccbSFrançois Tigeot * on the fly in the vm part of radeon_gart.c 1255926deccbSFrançois Tigeot */ 1256926deccbSFrançois Tigeot for (i = 1; i < 8; i++) { 1257926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR + (i << 2), 0); 1258926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR + (i << 2), rdev->vm_manager.max_pfn); 1259926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), 1260926deccbSFrançois Tigeot rdev->gart.table_addr >> 12); 1261926deccbSFrançois Tigeot } 1262926deccbSFrançois Tigeot 1263926deccbSFrançois Tigeot /* enable context1-7 */ 1264926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, 1265926deccbSFrançois Tigeot (u32)(rdev->dummy_page.addr >> 12)); 1266926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL2, 4); 1267926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | 1268926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT | 1269926deccbSFrançois Tigeot RANGE_PROTECTION_FAULT_ENABLE_DEFAULT | 1270926deccbSFrançois Tigeot DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | 1271926deccbSFrançois Tigeot DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT | 1272926deccbSFrançois Tigeot PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT | 1273926deccbSFrançois Tigeot PDE0_PROTECTION_FAULT_ENABLE_DEFAULT | 1274926deccbSFrançois Tigeot VALID_PROTECTION_FAULT_ENABLE_INTERRUPT | 1275926deccbSFrançois Tigeot VALID_PROTECTION_FAULT_ENABLE_DEFAULT | 1276926deccbSFrançois Tigeot READ_PROTECTION_FAULT_ENABLE_INTERRUPT | 1277926deccbSFrançois Tigeot READ_PROTECTION_FAULT_ENABLE_DEFAULT | 1278926deccbSFrançois Tigeot WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT | 1279926deccbSFrançois Tigeot WRITE_PROTECTION_FAULT_ENABLE_DEFAULT); 1280926deccbSFrançois Tigeot 1281926deccbSFrançois Tigeot cayman_pcie_gart_tlb_flush(rdev); 1282926deccbSFrançois Tigeot DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 1283926deccbSFrançois Tigeot (unsigned)(rdev->mc.gtt_size >> 20), 1284926deccbSFrançois Tigeot (unsigned long long)rdev->gart.table_addr); 1285926deccbSFrançois Tigeot rdev->gart.ready = true; 1286926deccbSFrançois Tigeot return 0; 1287926deccbSFrançois Tigeot } 1288926deccbSFrançois Tigeot 1289926deccbSFrançois Tigeot static void cayman_pcie_gart_disable(struct radeon_device *rdev) 1290926deccbSFrançois Tigeot { 1291926deccbSFrançois Tigeot /* Disable all tables */ 1292926deccbSFrançois Tigeot WREG32(VM_CONTEXT0_CNTL, 0); 1293926deccbSFrançois Tigeot WREG32(VM_CONTEXT1_CNTL, 0); 1294926deccbSFrançois Tigeot /* Setup TLB control */ 1295926deccbSFrançois Tigeot WREG32(MC_VM_MX_L1_TLB_CNTL, ENABLE_L1_FRAGMENT_PROCESSING | 1296926deccbSFrançois Tigeot SYSTEM_ACCESS_MODE_NOT_IN_SYS | 1297926deccbSFrançois Tigeot SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); 1298926deccbSFrançois Tigeot /* Setup L2 cache */ 1299926deccbSFrançois Tigeot WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 1300926deccbSFrançois Tigeot ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | 1301926deccbSFrançois Tigeot EFFECTIVE_L2_QUEUE_SIZE(7) | 1302926deccbSFrançois Tigeot CONTEXT1_IDENTITY_ACCESS_MODE(1)); 1303926deccbSFrançois Tigeot WREG32(VM_L2_CNTL2, 0); 1304926deccbSFrançois Tigeot WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 1305926deccbSFrançois Tigeot L2_CACHE_BIGK_FRAGMENT_SIZE(6)); 1306926deccbSFrançois Tigeot radeon_gart_table_vram_unpin(rdev); 1307926deccbSFrançois Tigeot } 1308926deccbSFrançois Tigeot 1309926deccbSFrançois Tigeot static void cayman_pcie_gart_fini(struct radeon_device *rdev) 1310926deccbSFrançois Tigeot { 1311926deccbSFrançois Tigeot cayman_pcie_gart_disable(rdev); 1312926deccbSFrançois Tigeot radeon_gart_table_vram_free(rdev); 1313926deccbSFrançois Tigeot radeon_gart_fini(rdev); 1314926deccbSFrançois Tigeot } 1315926deccbSFrançois Tigeot 1316926deccbSFrançois Tigeot void cayman_cp_int_cntl_setup(struct radeon_device *rdev, 1317926deccbSFrançois Tigeot int ring, u32 cp_int_cntl) 1318926deccbSFrançois Tigeot { 1319926deccbSFrançois Tigeot u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3; 1320926deccbSFrançois Tigeot 1321926deccbSFrançois Tigeot WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3)); 1322926deccbSFrançois Tigeot WREG32(CP_INT_CNTL, cp_int_cntl); 1323926deccbSFrançois Tigeot } 1324926deccbSFrançois Tigeot 1325926deccbSFrançois Tigeot /* 1326926deccbSFrançois Tigeot * CP. 1327926deccbSFrançois Tigeot */ 1328926deccbSFrançois Tigeot void cayman_fence_ring_emit(struct radeon_device *rdev, 1329926deccbSFrançois Tigeot struct radeon_fence *fence) 1330926deccbSFrançois Tigeot { 1331926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[fence->ring]; 1332926deccbSFrançois Tigeot u64 addr = rdev->fence_drv[fence->ring].gpu_addr; 1333926deccbSFrançois Tigeot 1334926deccbSFrançois Tigeot /* flush read cache over gart for this vmid */ 1335926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 1336926deccbSFrançois Tigeot radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); 1337926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1338926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); 1339926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); 1340926deccbSFrançois Tigeot radeon_ring_write(ring, 0xFFFFFFFF); 1341926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1342926deccbSFrançois Tigeot radeon_ring_write(ring, 10); /* poll interval */ 1343926deccbSFrançois Tigeot /* EVENT_WRITE_EOP - flush caches, send int */ 1344926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); 1345926deccbSFrançois Tigeot radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5)); 1346926deccbSFrançois Tigeot radeon_ring_write(ring, addr & 0xffffffff); 1347926deccbSFrançois Tigeot radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); 1348926deccbSFrançois Tigeot radeon_ring_write(ring, fence->seq); 1349926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1350926deccbSFrançois Tigeot } 1351926deccbSFrançois Tigeot 1352926deccbSFrançois Tigeot void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 1353926deccbSFrançois Tigeot { 1354926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[ib->ring]; 1355926deccbSFrançois Tigeot 1356926deccbSFrançois Tigeot /* set to DX10/11 mode */ 1357926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); 1358926deccbSFrançois Tigeot radeon_ring_write(ring, 1); 1359926deccbSFrançois Tigeot 1360926deccbSFrançois Tigeot if (ring->rptr_save_reg) { 1361926deccbSFrançois Tigeot uint32_t next_rptr = ring->wptr + 3 + 4 + 8; 1362926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 1363926deccbSFrançois Tigeot radeon_ring_write(ring, ((ring->rptr_save_reg - 1364926deccbSFrançois Tigeot PACKET3_SET_CONFIG_REG_START) >> 2)); 1365926deccbSFrançois Tigeot radeon_ring_write(ring, next_rptr); 1366926deccbSFrançois Tigeot } 1367926deccbSFrançois Tigeot 1368926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 1369926deccbSFrançois Tigeot radeon_ring_write(ring, 1370926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN 1371926deccbSFrançois Tigeot (2 << 0) | 1372926deccbSFrançois Tigeot #endif 1373926deccbSFrançois Tigeot (ib->gpu_addr & 0xFFFFFFFC)); 1374926deccbSFrançois Tigeot radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); 1375926deccbSFrançois Tigeot radeon_ring_write(ring, ib->length_dw | 1376926deccbSFrançois Tigeot (ib->vm ? (ib->vm->id << 24) : 0)); 1377926deccbSFrançois Tigeot 1378926deccbSFrançois Tigeot /* flush read cache over gart for this vmid */ 1379926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 1380926deccbSFrançois Tigeot radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); 1381926deccbSFrançois Tigeot radeon_ring_write(ring, ib->vm ? ib->vm->id : 0); 1382926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); 1383926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_TC_ACTION_ENA | PACKET3_SH_ACTION_ENA); 1384926deccbSFrançois Tigeot radeon_ring_write(ring, 0xFFFFFFFF); 1385926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1386926deccbSFrançois Tigeot radeon_ring_write(ring, 10); /* poll interval */ 1387926deccbSFrançois Tigeot } 1388926deccbSFrançois Tigeot 1389f43cf1b1SMichael Neumann void cayman_uvd_semaphore_emit(struct radeon_device *rdev, 1390f43cf1b1SMichael Neumann struct radeon_ring *ring, 1391f43cf1b1SMichael Neumann struct radeon_semaphore *semaphore, 1392f43cf1b1SMichael Neumann bool emit_wait) 1393f43cf1b1SMichael Neumann { 1394f43cf1b1SMichael Neumann uint64_t addr = semaphore->gpu_addr; 1395f43cf1b1SMichael Neumann 1396f43cf1b1SMichael Neumann radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_LOW, 0)); 1397f43cf1b1SMichael Neumann radeon_ring_write(ring, (addr >> 3) & 0x000FFFFF); 1398f43cf1b1SMichael Neumann 1399f43cf1b1SMichael Neumann radeon_ring_write(ring, PACKET0(UVD_SEMA_ADDR_HIGH, 0)); 1400f43cf1b1SMichael Neumann radeon_ring_write(ring, (addr >> 23) & 0x000FFFFF); 1401f43cf1b1SMichael Neumann 1402f43cf1b1SMichael Neumann radeon_ring_write(ring, PACKET0(UVD_SEMA_CMD, 0)); 1403f43cf1b1SMichael Neumann radeon_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); 1404f43cf1b1SMichael Neumann } 1405f43cf1b1SMichael Neumann 1406926deccbSFrançois Tigeot static void cayman_cp_enable(struct radeon_device *rdev, bool enable) 1407926deccbSFrançois Tigeot { 1408926deccbSFrançois Tigeot if (enable) 1409926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, 0); 1410926deccbSFrançois Tigeot else { 1411926deccbSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); 1412926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); 1413926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0); 1414926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 1415926deccbSFrançois Tigeot } 1416926deccbSFrançois Tigeot } 1417926deccbSFrançois Tigeot 1418926deccbSFrançois Tigeot static int cayman_cp_load_microcode(struct radeon_device *rdev) 1419926deccbSFrançois Tigeot { 1420926deccbSFrançois Tigeot const __be32 *fw_data; 1421926deccbSFrançois Tigeot int i; 1422926deccbSFrançois Tigeot 1423926deccbSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw) 1424926deccbSFrançois Tigeot return -EINVAL; 1425926deccbSFrançois Tigeot 1426926deccbSFrançois Tigeot cayman_cp_enable(rdev, false); 1427926deccbSFrançois Tigeot 1428926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->pfp_fw->data; 1429926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0); 1430926deccbSFrançois Tigeot for (i = 0; i < CAYMAN_PFP_UCODE_SIZE; i++) 1431926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); 1432926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0); 1433926deccbSFrançois Tigeot 1434926deccbSFrançois Tigeot fw_data = (const __be32 *)rdev->me_fw->data; 1435926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0); 1436926deccbSFrançois Tigeot for (i = 0; i < CAYMAN_PM4_UCODE_SIZE; i++) 1437926deccbSFrançois Tigeot WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); 1438926deccbSFrançois Tigeot 1439926deccbSFrançois Tigeot WREG32(CP_PFP_UCODE_ADDR, 0); 1440926deccbSFrançois Tigeot WREG32(CP_ME_RAM_WADDR, 0); 1441926deccbSFrançois Tigeot WREG32(CP_ME_RAM_RADDR, 0); 1442926deccbSFrançois Tigeot return 0; 1443926deccbSFrançois Tigeot } 1444926deccbSFrançois Tigeot 1445926deccbSFrançois Tigeot static int cayman_cp_start(struct radeon_device *rdev) 1446926deccbSFrançois Tigeot { 1447926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 1448926deccbSFrançois Tigeot int r, i; 1449926deccbSFrançois Tigeot 1450926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, 7); 1451926deccbSFrançois Tigeot if (r) { 1452926deccbSFrançois Tigeot DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 1453926deccbSFrançois Tigeot return r; 1454926deccbSFrançois Tigeot } 1455926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); 1456926deccbSFrançois Tigeot radeon_ring_write(ring, 0x1); 1457926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0); 1458926deccbSFrançois Tigeot radeon_ring_write(ring, rdev->config.cayman.max_hw_contexts - 1); 1459926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); 1460926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1461926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1462926deccbSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring); 1463926deccbSFrançois Tigeot 1464926deccbSFrançois Tigeot cayman_cp_enable(rdev, true); 1465926deccbSFrançois Tigeot 1466926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, cayman_default_size + 19); 1467926deccbSFrançois Tigeot if (r) { 1468926deccbSFrançois Tigeot DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 1469926deccbSFrançois Tigeot return r; 1470926deccbSFrançois Tigeot } 1471926deccbSFrançois Tigeot 1472926deccbSFrançois Tigeot /* setup clear context state */ 1473926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 1474926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); 1475926deccbSFrançois Tigeot 1476926deccbSFrançois Tigeot for (i = 0; i < cayman_default_size; i++) 1477926deccbSFrançois Tigeot radeon_ring_write(ring, cayman_default_state[i]); 1478926deccbSFrançois Tigeot 1479926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 1480926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); 1481926deccbSFrançois Tigeot 1482926deccbSFrançois Tigeot /* set clear context state */ 1483926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); 1484926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 1485926deccbSFrançois Tigeot 1486926deccbSFrançois Tigeot /* SQ_VTX_BASE_VTX_LOC */ 1487926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc0026f00); 1488926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000000); 1489926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000000); 1490926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000000); 1491926deccbSFrançois Tigeot 1492926deccbSFrançois Tigeot /* Clear consts */ 1493926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc0036f00); 1494926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000bc4); 1495926deccbSFrançois Tigeot radeon_ring_write(ring, 0xffffffff); 1496926deccbSFrançois Tigeot radeon_ring_write(ring, 0xffffffff); 1497926deccbSFrançois Tigeot radeon_ring_write(ring, 0xffffffff); 1498926deccbSFrançois Tigeot 1499926deccbSFrançois Tigeot radeon_ring_write(ring, 0xc0026900); 1500926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000316); 1501926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ 1502926deccbSFrançois Tigeot radeon_ring_write(ring, 0x00000010); /* */ 1503926deccbSFrançois Tigeot 1504926deccbSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring); 1505926deccbSFrançois Tigeot 1506926deccbSFrançois Tigeot /* XXX init other rings */ 1507926deccbSFrançois Tigeot 1508926deccbSFrançois Tigeot return 0; 1509926deccbSFrançois Tigeot } 1510926deccbSFrançois Tigeot 1511926deccbSFrançois Tigeot static void cayman_cp_fini(struct radeon_device *rdev) 1512926deccbSFrançois Tigeot { 1513926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 1514926deccbSFrançois Tigeot cayman_cp_enable(rdev, false); 1515926deccbSFrançois Tigeot radeon_ring_fini(rdev, ring); 1516926deccbSFrançois Tigeot radeon_scratch_free(rdev, ring->rptr_save_reg); 1517926deccbSFrançois Tigeot } 1518926deccbSFrançois Tigeot 1519926deccbSFrançois Tigeot static int cayman_cp_resume(struct radeon_device *rdev) 1520926deccbSFrançois Tigeot { 1521926deccbSFrançois Tigeot static const int ridx[] = { 1522926deccbSFrançois Tigeot RADEON_RING_TYPE_GFX_INDEX, 1523926deccbSFrançois Tigeot CAYMAN_RING_TYPE_CP1_INDEX, 1524926deccbSFrançois Tigeot CAYMAN_RING_TYPE_CP2_INDEX 1525926deccbSFrançois Tigeot }; 1526926deccbSFrançois Tigeot static const unsigned cp_rb_cntl[] = { 1527926deccbSFrançois Tigeot CP_RB0_CNTL, 1528926deccbSFrançois Tigeot CP_RB1_CNTL, 1529926deccbSFrançois Tigeot CP_RB2_CNTL, 1530926deccbSFrançois Tigeot }; 1531926deccbSFrançois Tigeot static const unsigned cp_rb_rptr_addr[] = { 1532926deccbSFrançois Tigeot CP_RB0_RPTR_ADDR, 1533926deccbSFrançois Tigeot CP_RB1_RPTR_ADDR, 1534926deccbSFrançois Tigeot CP_RB2_RPTR_ADDR 1535926deccbSFrançois Tigeot }; 1536926deccbSFrançois Tigeot static const unsigned cp_rb_rptr_addr_hi[] = { 1537926deccbSFrançois Tigeot CP_RB0_RPTR_ADDR_HI, 1538926deccbSFrançois Tigeot CP_RB1_RPTR_ADDR_HI, 1539926deccbSFrançois Tigeot CP_RB2_RPTR_ADDR_HI 1540926deccbSFrançois Tigeot }; 1541926deccbSFrançois Tigeot static const unsigned cp_rb_base[] = { 1542926deccbSFrançois Tigeot CP_RB0_BASE, 1543926deccbSFrançois Tigeot CP_RB1_BASE, 1544926deccbSFrançois Tigeot CP_RB2_BASE 1545926deccbSFrançois Tigeot }; 1546926deccbSFrançois Tigeot struct radeon_ring *ring; 1547926deccbSFrançois Tigeot int i, r; 1548926deccbSFrançois Tigeot 1549926deccbSFrançois Tigeot /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ 1550926deccbSFrançois Tigeot WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | 1551926deccbSFrançois Tigeot SOFT_RESET_PA | 1552926deccbSFrançois Tigeot SOFT_RESET_SH | 1553926deccbSFrançois Tigeot SOFT_RESET_VGT | 1554926deccbSFrançois Tigeot SOFT_RESET_SPI | 1555926deccbSFrançois Tigeot SOFT_RESET_SX)); 1556926deccbSFrançois Tigeot RREG32(GRBM_SOFT_RESET); 1557926deccbSFrançois Tigeot DRM_MDELAY(15); 1558926deccbSFrançois Tigeot WREG32(GRBM_SOFT_RESET, 0); 1559926deccbSFrançois Tigeot RREG32(GRBM_SOFT_RESET); 1560926deccbSFrançois Tigeot 1561926deccbSFrançois Tigeot WREG32(CP_SEM_WAIT_TIMER, 0x0); 1562926deccbSFrançois Tigeot WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); 1563926deccbSFrançois Tigeot 1564926deccbSFrançois Tigeot /* Set the write pointer delay */ 1565926deccbSFrançois Tigeot WREG32(CP_RB_WPTR_DELAY, 0); 1566926deccbSFrançois Tigeot 1567926deccbSFrançois Tigeot WREG32(CP_DEBUG, (1 << 27)); 1568926deccbSFrançois Tigeot 1569926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */ 1570926deccbSFrançois Tigeot WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); 1571926deccbSFrançois Tigeot WREG32(SCRATCH_UMSK, 0xff); 1572926deccbSFrançois Tigeot 1573926deccbSFrançois Tigeot for (i = 0; i < 3; ++i) { 1574926deccbSFrançois Tigeot uint32_t rb_cntl; 1575926deccbSFrançois Tigeot uint64_t addr; 1576926deccbSFrançois Tigeot 1577926deccbSFrançois Tigeot /* Set ring buffer size */ 1578926deccbSFrançois Tigeot ring = &rdev->ring[ridx[i]]; 1579926deccbSFrançois Tigeot rb_cntl = drm_order(ring->ring_size / 8); 1580926deccbSFrançois Tigeot rb_cntl |= drm_order(RADEON_GPU_PAGE_SIZE/8) << 8; 1581926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN 1582926deccbSFrançois Tigeot rb_cntl |= BUF_SWAP_32BIT; 1583926deccbSFrançois Tigeot #endif 1584926deccbSFrançois Tigeot WREG32(cp_rb_cntl[i], rb_cntl); 1585926deccbSFrançois Tigeot 1586926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */ 1587926deccbSFrançois Tigeot addr = rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET; 1588926deccbSFrançois Tigeot WREG32(cp_rb_rptr_addr[i], addr & 0xFFFFFFFC); 1589926deccbSFrançois Tigeot WREG32(cp_rb_rptr_addr_hi[i], upper_32_bits(addr) & 0xFF); 1590926deccbSFrançois Tigeot } 1591926deccbSFrançois Tigeot 1592926deccbSFrançois Tigeot /* set the rb base addr, this causes an internal reset of ALL rings */ 1593926deccbSFrançois Tigeot for (i = 0; i < 3; ++i) { 1594926deccbSFrançois Tigeot ring = &rdev->ring[ridx[i]]; 1595926deccbSFrançois Tigeot WREG32(cp_rb_base[i], ring->gpu_addr >> 8); 1596926deccbSFrançois Tigeot } 1597926deccbSFrançois Tigeot 1598926deccbSFrançois Tigeot for (i = 0; i < 3; ++i) { 1599926deccbSFrançois Tigeot /* Initialize the ring buffer's read and write pointers */ 1600926deccbSFrançois Tigeot ring = &rdev->ring[ridx[i]]; 1601926deccbSFrançois Tigeot WREG32_P(cp_rb_cntl[i], RB_RPTR_WR_ENA, ~RB_RPTR_WR_ENA); 1602926deccbSFrançois Tigeot 1603926deccbSFrançois Tigeot ring->rptr = ring->wptr = 0; 1604926deccbSFrançois Tigeot WREG32(ring->rptr_reg, ring->rptr); 1605926deccbSFrançois Tigeot WREG32(ring->wptr_reg, ring->wptr); 1606926deccbSFrançois Tigeot 1607926deccbSFrançois Tigeot DRM_MDELAY(1); 1608926deccbSFrançois Tigeot WREG32_P(cp_rb_cntl[i], 0, ~RB_RPTR_WR_ENA); 1609926deccbSFrançois Tigeot } 1610926deccbSFrançois Tigeot 1611926deccbSFrançois Tigeot /* start the rings */ 1612926deccbSFrançois Tigeot cayman_cp_start(rdev); 1613926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; 1614926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 1615926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; 1616926deccbSFrançois Tigeot /* this only test cp0 */ 1617926deccbSFrançois Tigeot r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 1618926deccbSFrançois Tigeot if (r) { 1619926deccbSFrançois Tigeot rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 1620926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 1621926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; 1622926deccbSFrançois Tigeot return r; 1623926deccbSFrançois Tigeot } 1624926deccbSFrançois Tigeot 1625926deccbSFrançois Tigeot return 0; 1626926deccbSFrançois Tigeot } 1627926deccbSFrançois Tigeot 1628926deccbSFrançois Tigeot /* 1629926deccbSFrançois Tigeot * DMA 1630926deccbSFrançois Tigeot * Starting with R600, the GPU has an asynchronous 1631926deccbSFrançois Tigeot * DMA engine. The programming model is very similar 1632926deccbSFrançois Tigeot * to the 3D engine (ring buffer, IBs, etc.), but the 1633926deccbSFrançois Tigeot * DMA controller has it's own packet format that is 1634926deccbSFrançois Tigeot * different form the PM4 format used by the 3D engine. 1635926deccbSFrançois Tigeot * It supports copying data, writing embedded data, 1636926deccbSFrançois Tigeot * solid fills, and a number of other things. It also 1637926deccbSFrançois Tigeot * has support for tiling/detiling of buffers. 1638926deccbSFrançois Tigeot * Cayman and newer support two asynchronous DMA engines. 1639926deccbSFrançois Tigeot */ 1640926deccbSFrançois Tigeot /** 1641926deccbSFrançois Tigeot * cayman_dma_ring_ib_execute - Schedule an IB on the DMA engine 1642926deccbSFrançois Tigeot * 1643926deccbSFrançois Tigeot * @rdev: radeon_device pointer 1644926deccbSFrançois Tigeot * @ib: IB object to schedule 1645926deccbSFrançois Tigeot * 1646926deccbSFrançois Tigeot * Schedule an IB in the DMA ring (cayman-SI). 1647926deccbSFrançois Tigeot */ 1648926deccbSFrançois Tigeot void cayman_dma_ring_ib_execute(struct radeon_device *rdev, 1649926deccbSFrançois Tigeot struct radeon_ib *ib) 1650926deccbSFrançois Tigeot { 1651926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[ib->ring]; 1652926deccbSFrançois Tigeot 1653926deccbSFrançois Tigeot if (rdev->wb.enabled) { 1654926deccbSFrançois Tigeot u32 next_rptr = ring->wptr + 4; 1655926deccbSFrançois Tigeot while ((next_rptr & 7) != 5) 1656926deccbSFrançois Tigeot next_rptr++; 1657926deccbSFrançois Tigeot next_rptr += 3; 1658926deccbSFrançois Tigeot radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); 1659926deccbSFrançois Tigeot radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); 1660926deccbSFrançois Tigeot radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr) & 0xff); 1661926deccbSFrançois Tigeot radeon_ring_write(ring, next_rptr); 1662926deccbSFrançois Tigeot } 1663926deccbSFrançois Tigeot 1664926deccbSFrançois Tigeot /* The indirect buffer packet must end on an 8 DW boundary in the DMA ring. 1665926deccbSFrançois Tigeot * Pad as necessary with NOPs. 1666926deccbSFrançois Tigeot */ 1667926deccbSFrançois Tigeot while ((ring->wptr & 7) != 5) 1668926deccbSFrançois Tigeot radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); 1669926deccbSFrançois Tigeot radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0)); 1670926deccbSFrançois Tigeot radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0)); 1671926deccbSFrançois Tigeot radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF)); 1672926deccbSFrançois Tigeot 1673926deccbSFrançois Tigeot } 1674926deccbSFrançois Tigeot 1675926deccbSFrançois Tigeot /** 1676926deccbSFrançois Tigeot * cayman_dma_stop - stop the async dma engines 1677926deccbSFrançois Tigeot * 1678926deccbSFrançois Tigeot * @rdev: radeon_device pointer 1679926deccbSFrançois Tigeot * 1680926deccbSFrançois Tigeot * Stop the async dma engines (cayman-SI). 1681926deccbSFrançois Tigeot */ 1682926deccbSFrançois Tigeot void cayman_dma_stop(struct radeon_device *rdev) 1683926deccbSFrançois Tigeot { 1684926deccbSFrançois Tigeot u32 rb_cntl; 1685926deccbSFrançois Tigeot 1686926deccbSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); 1687926deccbSFrançois Tigeot 1688926deccbSFrançois Tigeot /* dma0 */ 1689926deccbSFrançois Tigeot rb_cntl = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); 1690926deccbSFrançois Tigeot rb_cntl &= ~DMA_RB_ENABLE; 1691926deccbSFrançois Tigeot WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, rb_cntl); 1692926deccbSFrançois Tigeot 1693926deccbSFrançois Tigeot /* dma1 */ 1694926deccbSFrançois Tigeot rb_cntl = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); 1695926deccbSFrançois Tigeot rb_cntl &= ~DMA_RB_ENABLE; 1696926deccbSFrançois Tigeot WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, rb_cntl); 1697926deccbSFrançois Tigeot 1698926deccbSFrançois Tigeot rdev->ring[R600_RING_TYPE_DMA_INDEX].ready = false; 1699926deccbSFrançois Tigeot rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready = false; 1700926deccbSFrançois Tigeot } 1701926deccbSFrançois Tigeot 1702926deccbSFrançois Tigeot /** 1703926deccbSFrançois Tigeot * cayman_dma_resume - setup and start the async dma engines 1704926deccbSFrançois Tigeot * 1705926deccbSFrançois Tigeot * @rdev: radeon_device pointer 1706926deccbSFrançois Tigeot * 1707926deccbSFrançois Tigeot * Set up the DMA ring buffers and enable them. (cayman-SI). 1708926deccbSFrançois Tigeot * Returns 0 for success, error for failure. 1709926deccbSFrançois Tigeot */ 1710926deccbSFrançois Tigeot int cayman_dma_resume(struct radeon_device *rdev) 1711926deccbSFrançois Tigeot { 1712926deccbSFrançois Tigeot struct radeon_ring *ring; 1713926deccbSFrançois Tigeot u32 rb_cntl, dma_cntl, ib_cntl; 1714926deccbSFrançois Tigeot u32 rb_bufsz; 1715926deccbSFrançois Tigeot u32 reg_offset, wb_offset; 1716926deccbSFrançois Tigeot int i, r; 1717926deccbSFrançois Tigeot 1718926deccbSFrançois Tigeot /* Reset dma */ 1719926deccbSFrançois Tigeot WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); 1720926deccbSFrançois Tigeot RREG32(SRBM_SOFT_RESET); 1721926deccbSFrançois Tigeot DRM_UDELAY(50); 1722926deccbSFrançois Tigeot WREG32(SRBM_SOFT_RESET, 0); 1723926deccbSFrançois Tigeot 1724926deccbSFrançois Tigeot for (i = 0; i < 2; i++) { 1725926deccbSFrançois Tigeot if (i == 0) { 1726926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 1727926deccbSFrançois Tigeot reg_offset = DMA0_REGISTER_OFFSET; 1728926deccbSFrançois Tigeot wb_offset = R600_WB_DMA_RPTR_OFFSET; 1729926deccbSFrançois Tigeot } else { 1730926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 1731926deccbSFrançois Tigeot reg_offset = DMA1_REGISTER_OFFSET; 1732926deccbSFrançois Tigeot wb_offset = CAYMAN_WB_DMA1_RPTR_OFFSET; 1733926deccbSFrançois Tigeot } 1734926deccbSFrançois Tigeot 1735926deccbSFrançois Tigeot WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL + reg_offset, 0); 1736926deccbSFrançois Tigeot WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0); 1737926deccbSFrançois Tigeot 1738926deccbSFrançois Tigeot /* Set ring buffer size in dwords */ 1739926deccbSFrançois Tigeot rb_bufsz = drm_order(ring->ring_size / 4); 1740926deccbSFrançois Tigeot rb_cntl = rb_bufsz << 1; 1741926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN 1742926deccbSFrançois Tigeot rb_cntl |= DMA_RB_SWAP_ENABLE | DMA_RPTR_WRITEBACK_SWAP_ENABLE; 1743926deccbSFrançois Tigeot #endif 1744926deccbSFrançois Tigeot WREG32(DMA_RB_CNTL + reg_offset, rb_cntl); 1745926deccbSFrançois Tigeot 1746926deccbSFrançois Tigeot /* Initialize the ring buffer's read and write pointers */ 1747926deccbSFrançois Tigeot WREG32(DMA_RB_RPTR + reg_offset, 0); 1748926deccbSFrançois Tigeot WREG32(DMA_RB_WPTR + reg_offset, 0); 1749926deccbSFrançois Tigeot 1750926deccbSFrançois Tigeot /* set the wb address whether it's enabled or not */ 1751926deccbSFrançois Tigeot WREG32(DMA_RB_RPTR_ADDR_HI + reg_offset, 1752926deccbSFrançois Tigeot upper_32_bits(rdev->wb.gpu_addr + wb_offset) & 0xFF); 1753926deccbSFrançois Tigeot WREG32(DMA_RB_RPTR_ADDR_LO + reg_offset, 1754926deccbSFrançois Tigeot ((rdev->wb.gpu_addr + wb_offset) & 0xFFFFFFFC)); 1755926deccbSFrançois Tigeot 1756926deccbSFrançois Tigeot if (rdev->wb.enabled) 1757926deccbSFrançois Tigeot rb_cntl |= DMA_RPTR_WRITEBACK_ENABLE; 1758926deccbSFrançois Tigeot 1759926deccbSFrançois Tigeot WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8); 1760926deccbSFrançois Tigeot 1761926deccbSFrançois Tigeot /* enable DMA IBs */ 1762926deccbSFrançois Tigeot ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; 1763926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN 1764926deccbSFrançois Tigeot ib_cntl |= DMA_IB_SWAP_ENABLE; 1765926deccbSFrançois Tigeot #endif 1766926deccbSFrançois Tigeot WREG32(DMA_IB_CNTL + reg_offset, ib_cntl); 1767926deccbSFrançois Tigeot 1768926deccbSFrançois Tigeot dma_cntl = RREG32(DMA_CNTL + reg_offset); 1769926deccbSFrançois Tigeot dma_cntl &= ~CTXEMPTY_INT_ENABLE; 1770926deccbSFrançois Tigeot WREG32(DMA_CNTL + reg_offset, dma_cntl); 1771926deccbSFrançois Tigeot 1772926deccbSFrançois Tigeot ring->wptr = 0; 1773926deccbSFrançois Tigeot WREG32(DMA_RB_WPTR + reg_offset, ring->wptr << 2); 1774926deccbSFrançois Tigeot 1775926deccbSFrançois Tigeot ring->rptr = RREG32(DMA_RB_RPTR + reg_offset) >> 2; 1776926deccbSFrançois Tigeot 1777926deccbSFrançois Tigeot WREG32(DMA_RB_CNTL + reg_offset, rb_cntl | DMA_RB_ENABLE); 1778926deccbSFrançois Tigeot 1779926deccbSFrançois Tigeot ring->ready = true; 1780926deccbSFrançois Tigeot 1781926deccbSFrançois Tigeot r = radeon_ring_test(rdev, ring->idx, ring); 1782926deccbSFrançois Tigeot if (r) { 1783926deccbSFrançois Tigeot ring->ready = false; 1784926deccbSFrançois Tigeot return r; 1785926deccbSFrançois Tigeot } 1786926deccbSFrançois Tigeot } 1787926deccbSFrançois Tigeot 1788926deccbSFrançois Tigeot radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); 1789926deccbSFrançois Tigeot 1790926deccbSFrançois Tigeot return 0; 1791926deccbSFrançois Tigeot } 1792926deccbSFrançois Tigeot 1793926deccbSFrançois Tigeot /** 1794926deccbSFrançois Tigeot * cayman_dma_fini - tear down the async dma engines 1795926deccbSFrançois Tigeot * 1796926deccbSFrançois Tigeot * @rdev: radeon_device pointer 1797926deccbSFrançois Tigeot * 1798926deccbSFrançois Tigeot * Stop the async dma engines and free the rings (cayman-SI). 1799926deccbSFrançois Tigeot */ 1800926deccbSFrançois Tigeot void cayman_dma_fini(struct radeon_device *rdev) 1801926deccbSFrançois Tigeot { 1802926deccbSFrançois Tigeot cayman_dma_stop(rdev); 1803926deccbSFrançois Tigeot radeon_ring_fini(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX]); 1804926deccbSFrançois Tigeot radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); 1805926deccbSFrançois Tigeot } 1806926deccbSFrançois Tigeot 1807b403bed8SMichael Neumann static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev) 1808926deccbSFrançois Tigeot { 1809b403bed8SMichael Neumann u32 reset_mask = 0; 1810b403bed8SMichael Neumann u32 tmp; 1811926deccbSFrançois Tigeot 1812b403bed8SMichael Neumann /* GRBM_STATUS */ 1813b403bed8SMichael Neumann tmp = RREG32(GRBM_STATUS); 1814b403bed8SMichael Neumann if (tmp & (PA_BUSY | SC_BUSY | 1815b403bed8SMichael Neumann SH_BUSY | SX_BUSY | 1816b403bed8SMichael Neumann TA_BUSY | VGT_BUSY | 1817b403bed8SMichael Neumann DB_BUSY | CB_BUSY | 1818b403bed8SMichael Neumann GDS_BUSY | SPI_BUSY | 1819b403bed8SMichael Neumann IA_BUSY | IA_BUSY_NO_DMA)) 1820b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GFX; 1821b403bed8SMichael Neumann 1822b403bed8SMichael Neumann if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING | 1823b403bed8SMichael Neumann CP_BUSY | CP_COHERENCY_BUSY)) 1824b403bed8SMichael Neumann reset_mask |= RADEON_RESET_CP; 1825b403bed8SMichael Neumann 1826b403bed8SMichael Neumann if (tmp & GRBM_EE_BUSY) 1827b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP; 1828b403bed8SMichael Neumann 1829b403bed8SMichael Neumann /* DMA_STATUS_REG 0 */ 1830b403bed8SMichael Neumann tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET); 1831b403bed8SMichael Neumann if (!(tmp & DMA_IDLE)) 1832b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA; 1833b403bed8SMichael Neumann 1834b403bed8SMichael Neumann /* DMA_STATUS_REG 1 */ 1835b403bed8SMichael Neumann tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET); 1836b403bed8SMichael Neumann if (!(tmp & DMA_IDLE)) 1837b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA1; 1838b403bed8SMichael Neumann 1839b403bed8SMichael Neumann /* SRBM_STATUS2 */ 1840b403bed8SMichael Neumann tmp = RREG32(SRBM_STATUS2); 1841b403bed8SMichael Neumann if (tmp & DMA_BUSY) 1842b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA; 1843b403bed8SMichael Neumann 1844b403bed8SMichael Neumann if (tmp & DMA1_BUSY) 1845b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DMA1; 1846b403bed8SMichael Neumann 1847b403bed8SMichael Neumann /* SRBM_STATUS */ 1848b403bed8SMichael Neumann tmp = RREG32(SRBM_STATUS); 1849b403bed8SMichael Neumann if (tmp & (RLC_RQ_PENDING | RLC_BUSY)) 1850b403bed8SMichael Neumann reset_mask |= RADEON_RESET_RLC; 1851b403bed8SMichael Neumann 1852b403bed8SMichael Neumann if (tmp & IH_BUSY) 1853b403bed8SMichael Neumann reset_mask |= RADEON_RESET_IH; 1854b403bed8SMichael Neumann 1855b403bed8SMichael Neumann if (tmp & SEM_BUSY) 1856b403bed8SMichael Neumann reset_mask |= RADEON_RESET_SEM; 1857b403bed8SMichael Neumann 1858b403bed8SMichael Neumann if (tmp & GRBM_RQ_PENDING) 1859b403bed8SMichael Neumann reset_mask |= RADEON_RESET_GRBM; 1860b403bed8SMichael Neumann 1861b403bed8SMichael Neumann if (tmp & VMC_BUSY) 1862b403bed8SMichael Neumann reset_mask |= RADEON_RESET_VMC; 1863b403bed8SMichael Neumann 1864b403bed8SMichael Neumann if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY | 1865b403bed8SMichael Neumann MCC_BUSY | MCD_BUSY)) 1866b403bed8SMichael Neumann reset_mask |= RADEON_RESET_MC; 1867b403bed8SMichael Neumann 1868b403bed8SMichael Neumann if (evergreen_is_display_hung(rdev)) 1869b403bed8SMichael Neumann reset_mask |= RADEON_RESET_DISPLAY; 1870b403bed8SMichael Neumann 1871b403bed8SMichael Neumann /* VM_L2_STATUS */ 1872b403bed8SMichael Neumann tmp = RREG32(VM_L2_STATUS); 1873b403bed8SMichael Neumann if (tmp & L2_BUSY) 1874b403bed8SMichael Neumann reset_mask |= RADEON_RESET_VMC; 1875b403bed8SMichael Neumann 1876b403bed8SMichael Neumann /* Skip MC reset as it's mostly likely not hung, just busy */ 1877b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_MC) { 1878b403bed8SMichael Neumann DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); 1879b403bed8SMichael Neumann reset_mask &= ~RADEON_RESET_MC; 1880b403bed8SMichael Neumann } 1881b403bed8SMichael Neumann 1882b403bed8SMichael Neumann return reset_mask; 1883b403bed8SMichael Neumann } 1884b403bed8SMichael Neumann 1885b403bed8SMichael Neumann static void cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 1886b403bed8SMichael Neumann { 1887b403bed8SMichael Neumann struct evergreen_mc_save save; 1888b403bed8SMichael Neumann u32 grbm_soft_reset = 0, srbm_soft_reset = 0; 1889b403bed8SMichael Neumann u32 tmp; 1890b403bed8SMichael Neumann 1891b403bed8SMichael Neumann if (reset_mask == 0) 1892926deccbSFrançois Tigeot return; 1893926deccbSFrançois Tigeot 1894b403bed8SMichael Neumann dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 1895b403bed8SMichael Neumann 1896b403bed8SMichael Neumann evergreen_print_gpu_status_regs(rdev); 1897b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", 1898b403bed8SMichael Neumann RREG32(0x14F8)); 1899b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", 1900b403bed8SMichael Neumann RREG32(0x14D8)); 1901b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", 1902b403bed8SMichael Neumann RREG32(0x14FC)); 1903b403bed8SMichael Neumann dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 1904b403bed8SMichael Neumann RREG32(0x14DC)); 1905926deccbSFrançois Tigeot 1906926deccbSFrançois Tigeot /* Disable CP parsing/prefetching */ 1907926deccbSFrançois Tigeot WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); 1908926deccbSFrançois Tigeot 1909b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA) { 1910b403bed8SMichael Neumann /* dma0 */ 1911b403bed8SMichael Neumann tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); 1912b403bed8SMichael Neumann tmp &= ~DMA_RB_ENABLE; 1913b403bed8SMichael Neumann WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); 1914b403bed8SMichael Neumann } 1915b403bed8SMichael Neumann 1916b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA1) { 1917b403bed8SMichael Neumann /* dma1 */ 1918b403bed8SMichael Neumann tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); 1919b403bed8SMichael Neumann tmp &= ~DMA_RB_ENABLE; 1920b403bed8SMichael Neumann WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); 1921b403bed8SMichael Neumann } 1922b403bed8SMichael Neumann 1923b403bed8SMichael Neumann DRM_UDELAY(50); 1924b403bed8SMichael Neumann 1925b403bed8SMichael Neumann evergreen_mc_stop(rdev, &save); 1926b403bed8SMichael Neumann if (evergreen_mc_wait_for_idle(rdev)) { 1927b403bed8SMichael Neumann dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 1928b403bed8SMichael Neumann } 1929b403bed8SMichael Neumann 1930b403bed8SMichael Neumann if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) { 1931b403bed8SMichael Neumann grbm_soft_reset = SOFT_RESET_CB | 1932926deccbSFrançois Tigeot SOFT_RESET_DB | 1933926deccbSFrançois Tigeot SOFT_RESET_GDS | 1934926deccbSFrançois Tigeot SOFT_RESET_PA | 1935926deccbSFrançois Tigeot SOFT_RESET_SC | 1936926deccbSFrançois Tigeot SOFT_RESET_SPI | 1937926deccbSFrançois Tigeot SOFT_RESET_SH | 1938926deccbSFrançois Tigeot SOFT_RESET_SX | 1939926deccbSFrançois Tigeot SOFT_RESET_TC | 1940926deccbSFrançois Tigeot SOFT_RESET_TA | 1941926deccbSFrançois Tigeot SOFT_RESET_VGT | 1942b403bed8SMichael Neumann SOFT_RESET_IA; 1943926deccbSFrançois Tigeot } 1944926deccbSFrançois Tigeot 1945b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_CP) { 1946b403bed8SMichael Neumann grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT; 1947926deccbSFrançois Tigeot 1948b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_GRBM; 1949926deccbSFrançois Tigeot } 1950926deccbSFrançois Tigeot 1951926deccbSFrançois Tigeot if (reset_mask & RADEON_RESET_DMA) 1952b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DMA; 1953b403bed8SMichael Neumann 1954b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DMA1) 1955b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DMA1; 1956b403bed8SMichael Neumann 1957b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_DISPLAY) 1958b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_DC; 1959b403bed8SMichael Neumann 1960b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_RLC) 1961b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_RLC; 1962b403bed8SMichael Neumann 1963b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_SEM) 1964b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_SEM; 1965b403bed8SMichael Neumann 1966b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_IH) 1967b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_IH; 1968b403bed8SMichael Neumann 1969b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_GRBM) 1970b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_GRBM; 1971b403bed8SMichael Neumann 1972b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_VMC) 1973b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_VMC; 1974b403bed8SMichael Neumann 1975b403bed8SMichael Neumann if (!(rdev->flags & RADEON_IS_IGP)) { 1976b403bed8SMichael Neumann if (reset_mask & RADEON_RESET_MC) 1977b403bed8SMichael Neumann srbm_soft_reset |= SOFT_RESET_MC; 1978b403bed8SMichael Neumann } 1979b403bed8SMichael Neumann 1980b403bed8SMichael Neumann if (grbm_soft_reset) { 1981b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET); 1982b403bed8SMichael Neumann tmp |= grbm_soft_reset; 1983b403bed8SMichael Neumann dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 1984b403bed8SMichael Neumann WREG32(GRBM_SOFT_RESET, tmp); 1985b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET); 1986b403bed8SMichael Neumann 1987b403bed8SMichael Neumann DRM_UDELAY(50); 1988b403bed8SMichael Neumann 1989b403bed8SMichael Neumann tmp &= ~grbm_soft_reset; 1990b403bed8SMichael Neumann WREG32(GRBM_SOFT_RESET, tmp); 1991b403bed8SMichael Neumann tmp = RREG32(GRBM_SOFT_RESET); 1992b403bed8SMichael Neumann } 1993b403bed8SMichael Neumann 1994b403bed8SMichael Neumann if (srbm_soft_reset) { 1995b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET); 1996b403bed8SMichael Neumann tmp |= srbm_soft_reset; 1997b403bed8SMichael Neumann dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 1998b403bed8SMichael Neumann WREG32(SRBM_SOFT_RESET, tmp); 1999b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET); 2000b403bed8SMichael Neumann 2001b403bed8SMichael Neumann DRM_UDELAY(50); 2002b403bed8SMichael Neumann 2003b403bed8SMichael Neumann tmp &= ~srbm_soft_reset; 2004b403bed8SMichael Neumann WREG32(SRBM_SOFT_RESET, tmp); 2005b403bed8SMichael Neumann tmp = RREG32(SRBM_SOFT_RESET); 2006b403bed8SMichael Neumann } 2007926deccbSFrançois Tigeot 2008926deccbSFrançois Tigeot /* Wait a little for things to settle down */ 2009926deccbSFrançois Tigeot DRM_UDELAY(50); 2010926deccbSFrançois Tigeot 2011926deccbSFrançois Tigeot evergreen_mc_resume(rdev, &save); 2012b403bed8SMichael Neumann DRM_UDELAY(50); 2013b403bed8SMichael Neumann 2014b403bed8SMichael Neumann evergreen_print_gpu_status_regs(rdev); 2015926deccbSFrançois Tigeot } 2016926deccbSFrançois Tigeot 2017926deccbSFrançois Tigeot int cayman_asic_reset(struct radeon_device *rdev) 2018926deccbSFrançois Tigeot { 2019b403bed8SMichael Neumann u32 reset_mask; 2020b403bed8SMichael Neumann 2021b403bed8SMichael Neumann reset_mask = cayman_gpu_check_soft_reset(rdev); 2022b403bed8SMichael Neumann 2023b403bed8SMichael Neumann if (reset_mask) 2024b403bed8SMichael Neumann r600_set_bios_scratch_engine_hung(rdev, true); 2025b403bed8SMichael Neumann 2026b403bed8SMichael Neumann cayman_gpu_soft_reset(rdev, reset_mask); 2027b403bed8SMichael Neumann 2028b403bed8SMichael Neumann reset_mask = cayman_gpu_check_soft_reset(rdev); 2029b403bed8SMichael Neumann 2030b403bed8SMichael Neumann if (!reset_mask) 2031b403bed8SMichael Neumann r600_set_bios_scratch_engine_hung(rdev, false); 2032b403bed8SMichael Neumann 2033b403bed8SMichael Neumann return 0; 2034b403bed8SMichael Neumann } 2035b403bed8SMichael Neumann 2036b403bed8SMichael Neumann /** 2037b403bed8SMichael Neumann * cayman_gfx_is_lockup - Check if the GFX engine is locked up 2038b403bed8SMichael Neumann * 2039b403bed8SMichael Neumann * @rdev: radeon_device pointer 2040b403bed8SMichael Neumann * @ring: radeon_ring structure holding ring information 2041b403bed8SMichael Neumann * 2042b403bed8SMichael Neumann * Check if the GFX engine is locked up. 2043b403bed8SMichael Neumann * Returns true if the engine appears to be locked up, false if not. 2044b403bed8SMichael Neumann */ 2045b403bed8SMichael Neumann bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 2046b403bed8SMichael Neumann { 2047b403bed8SMichael Neumann u32 reset_mask = cayman_gpu_check_soft_reset(rdev); 2048b403bed8SMichael Neumann 2049b403bed8SMichael Neumann if (!(reset_mask & (RADEON_RESET_GFX | 2050926deccbSFrançois Tigeot RADEON_RESET_COMPUTE | 2051b403bed8SMichael Neumann RADEON_RESET_CP))) { 2052b403bed8SMichael Neumann radeon_ring_lockup_update(ring); 2053b403bed8SMichael Neumann return false; 2054b403bed8SMichael Neumann } 2055b403bed8SMichael Neumann /* force CP activities */ 2056b403bed8SMichael Neumann radeon_ring_force_activity(rdev, ring); 2057b403bed8SMichael Neumann return radeon_ring_test_lockup(rdev, ring); 2058926deccbSFrançois Tigeot } 2059926deccbSFrançois Tigeot 2060926deccbSFrançois Tigeot /** 2061926deccbSFrançois Tigeot * cayman_dma_is_lockup - Check if the DMA engine is locked up 2062926deccbSFrançois Tigeot * 2063926deccbSFrançois Tigeot * @rdev: radeon_device pointer 2064926deccbSFrançois Tigeot * @ring: radeon_ring structure holding ring information 2065926deccbSFrançois Tigeot * 2066b403bed8SMichael Neumann * Check if the async DMA engine is locked up. 2067926deccbSFrançois Tigeot * Returns true if the engine appears to be locked up, false if not. 2068926deccbSFrançois Tigeot */ 2069926deccbSFrançois Tigeot bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 2070926deccbSFrançois Tigeot { 2071b403bed8SMichael Neumann u32 reset_mask = cayman_gpu_check_soft_reset(rdev); 2072b403bed8SMichael Neumann u32 mask; 2073926deccbSFrançois Tigeot 2074926deccbSFrançois Tigeot if (ring->idx == R600_RING_TYPE_DMA_INDEX) 2075b403bed8SMichael Neumann mask = RADEON_RESET_DMA; 2076926deccbSFrançois Tigeot else 2077b403bed8SMichael Neumann mask = RADEON_RESET_DMA1; 2078b403bed8SMichael Neumann 2079b403bed8SMichael Neumann if (!(reset_mask & mask)) { 2080926deccbSFrançois Tigeot radeon_ring_lockup_update(ring); 2081926deccbSFrançois Tigeot return false; 2082926deccbSFrançois Tigeot } 2083926deccbSFrançois Tigeot /* force ring activities */ 2084926deccbSFrançois Tigeot radeon_ring_force_activity(rdev, ring); 2085926deccbSFrançois Tigeot return radeon_ring_test_lockup(rdev, ring); 2086926deccbSFrançois Tigeot } 2087926deccbSFrançois Tigeot 2088926deccbSFrançois Tigeot static int cayman_startup(struct radeon_device *rdev) 2089926deccbSFrançois Tigeot { 2090926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 2091926deccbSFrançois Tigeot int r; 2092926deccbSFrançois Tigeot 2093926deccbSFrançois Tigeot /* enable pcie gen2 link */ 2094926deccbSFrançois Tigeot evergreen_pcie_gen2_enable(rdev); 209557e252bfSMichael Neumann /* enable aspm */ 209657e252bfSMichael Neumann evergreen_program_aspm(rdev); 209757e252bfSMichael Neumann 209857e252bfSMichael Neumann evergreen_mc_program(rdev); 2099926deccbSFrançois Tigeot 2100926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) { 2101926deccbSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { 2102926deccbSFrançois Tigeot r = ni_init_microcode(rdev); 2103926deccbSFrançois Tigeot if (r) { 2104926deccbSFrançois Tigeot DRM_ERROR("Failed to load firmware!\n"); 2105926deccbSFrançois Tigeot return r; 2106926deccbSFrançois Tigeot } 2107926deccbSFrançois Tigeot } 2108926deccbSFrançois Tigeot } else { 2109926deccbSFrançois Tigeot if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { 2110926deccbSFrançois Tigeot r = ni_init_microcode(rdev); 2111926deccbSFrançois Tigeot if (r) { 2112926deccbSFrançois Tigeot DRM_ERROR("Failed to load firmware!\n"); 2113926deccbSFrançois Tigeot return r; 2114926deccbSFrançois Tigeot } 2115926deccbSFrançois Tigeot } 2116926deccbSFrançois Tigeot 2117926deccbSFrançois Tigeot r = ni_mc_load_microcode(rdev); 2118926deccbSFrançois Tigeot if (r) { 2119926deccbSFrançois Tigeot DRM_ERROR("Failed to load MC firmware!\n"); 2120926deccbSFrançois Tigeot return r; 2121926deccbSFrançois Tigeot } 2122926deccbSFrançois Tigeot } 2123926deccbSFrançois Tigeot 2124926deccbSFrançois Tigeot r = r600_vram_scratch_init(rdev); 2125926deccbSFrançois Tigeot if (r) 2126926deccbSFrançois Tigeot return r; 2127926deccbSFrançois Tigeot 2128926deccbSFrançois Tigeot r = cayman_pcie_gart_enable(rdev); 2129926deccbSFrançois Tigeot if (r) 2130926deccbSFrançois Tigeot return r; 2131926deccbSFrançois Tigeot cayman_gpu_init(rdev); 2132926deccbSFrançois Tigeot 2133926deccbSFrançois Tigeot r = evergreen_blit_init(rdev); 2134926deccbSFrançois Tigeot if (r) { 2135926deccbSFrançois Tigeot r600_blit_fini(rdev); 2136926deccbSFrançois Tigeot rdev->asic->copy.copy = NULL; 2137926deccbSFrançois Tigeot dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); 2138926deccbSFrançois Tigeot } 2139926deccbSFrançois Tigeot 2140926deccbSFrançois Tigeot /* allocate rlc buffers */ 2141926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) { 214257e252bfSMichael Neumann rdev->rlc.reg_list = tn_rlc_save_restore_register_list; 214357e252bfSMichael Neumann rdev->rlc.reg_list_size = tn_rlc_save_restore_register_list_size; 214457e252bfSMichael Neumann rdev->rlc.cs_data = cayman_cs_data; 214557e252bfSMichael Neumann r = sumo_rlc_init(rdev); 2146926deccbSFrançois Tigeot if (r) { 2147926deccbSFrançois Tigeot DRM_ERROR("Failed to init rlc BOs!\n"); 2148926deccbSFrançois Tigeot return r; 2149926deccbSFrançois Tigeot } 2150926deccbSFrançois Tigeot } 2151926deccbSFrançois Tigeot 2152926deccbSFrançois Tigeot /* allocate wb buffer */ 2153926deccbSFrançois Tigeot r = radeon_wb_init(rdev); 2154926deccbSFrançois Tigeot if (r) 2155926deccbSFrançois Tigeot return r; 2156926deccbSFrançois Tigeot 2157926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 2158926deccbSFrançois Tigeot if (r) { 2159926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 2160926deccbSFrançois Tigeot return r; 2161926deccbSFrançois Tigeot } 2162926deccbSFrançois Tigeot 2163f43cf1b1SMichael Neumann r = rv770_uvd_resume(rdev); 2164f43cf1b1SMichael Neumann if (!r) { 2165f43cf1b1SMichael Neumann r = radeon_fence_driver_start_ring(rdev, 2166f43cf1b1SMichael Neumann R600_RING_TYPE_UVD_INDEX); 2167f43cf1b1SMichael Neumann if (r) 2168f43cf1b1SMichael Neumann dev_err(rdev->dev, "UVD fences init error (%d).\n", r); 2169f43cf1b1SMichael Neumann } 2170f43cf1b1SMichael Neumann if (r) 2171f43cf1b1SMichael Neumann rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; 2172f43cf1b1SMichael Neumann 2173926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 2174926deccbSFrançois Tigeot if (r) { 2175926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 2176926deccbSFrançois Tigeot return r; 2177926deccbSFrançois Tigeot } 2178926deccbSFrançois Tigeot 2179926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 2180926deccbSFrançois Tigeot if (r) { 2181926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 2182926deccbSFrançois Tigeot return r; 2183926deccbSFrançois Tigeot } 2184926deccbSFrançois Tigeot 2185926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); 2186926deccbSFrançois Tigeot if (r) { 2187926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 2188926deccbSFrançois Tigeot return r; 2189926deccbSFrançois Tigeot } 2190926deccbSFrançois Tigeot 2191926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 2192926deccbSFrançois Tigeot if (r) { 2193926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 2194926deccbSFrançois Tigeot return r; 2195926deccbSFrançois Tigeot } 2196926deccbSFrançois Tigeot 2197926deccbSFrançois Tigeot /* Enable IRQ */ 2198f43cf1b1SMichael Neumann if (!rdev->irq.installed) { 2199f43cf1b1SMichael Neumann r = radeon_irq_kms_init(rdev); 2200f43cf1b1SMichael Neumann if (r) 2201f43cf1b1SMichael Neumann return r; 2202f43cf1b1SMichael Neumann } 2203f43cf1b1SMichael Neumann 2204926deccbSFrançois Tigeot r = r600_irq_init(rdev); 2205926deccbSFrançois Tigeot if (r) { 2206926deccbSFrançois Tigeot DRM_ERROR("radeon: IH init failed (%d).\n", r); 2207926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev); 2208926deccbSFrançois Tigeot return r; 2209926deccbSFrançois Tigeot } 2210926deccbSFrançois Tigeot evergreen_irq_set(rdev); 2211926deccbSFrançois Tigeot 2212926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 2213926deccbSFrançois Tigeot CP_RB0_RPTR, CP_RB0_WPTR, 2214926deccbSFrançois Tigeot 0, 0xfffff, RADEON_CP_PACKET2); 2215926deccbSFrançois Tigeot if (r) 2216926deccbSFrançois Tigeot return r; 2217926deccbSFrançois Tigeot 2218926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 2219926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, 2220926deccbSFrançois Tigeot DMA_RB_RPTR + DMA0_REGISTER_OFFSET, 2221926deccbSFrançois Tigeot DMA_RB_WPTR + DMA0_REGISTER_OFFSET, 2222926deccbSFrançois Tigeot 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); 2223926deccbSFrançois Tigeot if (r) 2224926deccbSFrançois Tigeot return r; 2225926deccbSFrançois Tigeot 2226926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 2227926deccbSFrançois Tigeot r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, 2228926deccbSFrançois Tigeot DMA_RB_RPTR + DMA1_REGISTER_OFFSET, 2229926deccbSFrançois Tigeot DMA_RB_WPTR + DMA1_REGISTER_OFFSET, 2230926deccbSFrançois Tigeot 2, 0x3fffc, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0)); 2231926deccbSFrançois Tigeot if (r) 2232926deccbSFrançois Tigeot return r; 2233926deccbSFrançois Tigeot 2234926deccbSFrançois Tigeot r = cayman_cp_load_microcode(rdev); 2235926deccbSFrançois Tigeot if (r) 2236926deccbSFrançois Tigeot return r; 2237926deccbSFrançois Tigeot r = cayman_cp_resume(rdev); 2238926deccbSFrançois Tigeot if (r) 2239926deccbSFrançois Tigeot return r; 2240926deccbSFrançois Tigeot 2241926deccbSFrançois Tigeot r = cayman_dma_resume(rdev); 2242926deccbSFrançois Tigeot if (r) 2243926deccbSFrançois Tigeot return r; 2244926deccbSFrançois Tigeot 2245f43cf1b1SMichael Neumann ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 2246f43cf1b1SMichael Neumann if (ring->ring_size) { 2247f43cf1b1SMichael Neumann r = radeon_ring_init(rdev, ring, ring->ring_size, 2248f43cf1b1SMichael Neumann R600_WB_UVD_RPTR_OFFSET, 2249f43cf1b1SMichael Neumann UVD_RBC_RB_RPTR, UVD_RBC_RB_WPTR, 2250f43cf1b1SMichael Neumann 0, 0xfffff, RADEON_CP_PACKET2); 2251f43cf1b1SMichael Neumann if (!r) 2252f43cf1b1SMichael Neumann r = r600_uvd_init(rdev); 2253f43cf1b1SMichael Neumann if (r) 2254f43cf1b1SMichael Neumann DRM_ERROR("radeon: failed initializing UVD (%d).\n", r); 2255f43cf1b1SMichael Neumann } 2256f43cf1b1SMichael Neumann 2257926deccbSFrançois Tigeot r = radeon_ib_pool_init(rdev); 2258926deccbSFrançois Tigeot if (r) { 2259926deccbSFrançois Tigeot dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 2260926deccbSFrançois Tigeot return r; 2261926deccbSFrançois Tigeot } 2262926deccbSFrançois Tigeot 2263926deccbSFrançois Tigeot r = radeon_vm_manager_init(rdev); 2264926deccbSFrançois Tigeot if (r) { 2265926deccbSFrançois Tigeot dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); 2266926deccbSFrançois Tigeot return r; 2267926deccbSFrançois Tigeot } 2268926deccbSFrançois Tigeot 2269926deccbSFrançois Tigeot r = r600_audio_init(rdev); 2270926deccbSFrançois Tigeot if (r) 2271926deccbSFrançois Tigeot return r; 2272926deccbSFrançois Tigeot 2273926deccbSFrançois Tigeot return 0; 2274926deccbSFrançois Tigeot } 2275926deccbSFrançois Tigeot 2276926deccbSFrançois Tigeot int cayman_resume(struct radeon_device *rdev) 2277926deccbSFrançois Tigeot { 2278926deccbSFrançois Tigeot int r; 2279926deccbSFrançois Tigeot 2280926deccbSFrançois Tigeot /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, 2281926deccbSFrançois Tigeot * posting will perform necessary task to bring back GPU into good 2282926deccbSFrançois Tigeot * shape. 2283926deccbSFrançois Tigeot */ 2284926deccbSFrançois Tigeot /* post card */ 2285926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context); 2286926deccbSFrançois Tigeot 2287f43cf1b1SMichael Neumann /* init golden registers */ 2288f43cf1b1SMichael Neumann ni_init_golden_registers(rdev); 2289f43cf1b1SMichael Neumann 2290926deccbSFrançois Tigeot rdev->accel_working = true; 2291926deccbSFrançois Tigeot r = cayman_startup(rdev); 2292926deccbSFrançois Tigeot if (r) { 2293926deccbSFrançois Tigeot DRM_ERROR("cayman startup failed on resume\n"); 2294926deccbSFrançois Tigeot rdev->accel_working = false; 2295926deccbSFrançois Tigeot return r; 2296926deccbSFrançois Tigeot } 2297926deccbSFrançois Tigeot return r; 2298926deccbSFrançois Tigeot } 2299926deccbSFrançois Tigeot 2300926deccbSFrançois Tigeot int cayman_suspend(struct radeon_device *rdev) 2301926deccbSFrançois Tigeot { 2302926deccbSFrançois Tigeot r600_audio_fini(rdev); 2303b403bed8SMichael Neumann radeon_vm_manager_fini(rdev); 2304926deccbSFrançois Tigeot cayman_cp_enable(rdev, false); 2305926deccbSFrançois Tigeot cayman_dma_stop(rdev); 230657e252bfSMichael Neumann r600_uvd_stop(rdev); 2307f43cf1b1SMichael Neumann radeon_uvd_suspend(rdev); 2308926deccbSFrançois Tigeot evergreen_irq_suspend(rdev); 2309926deccbSFrançois Tigeot radeon_wb_disable(rdev); 2310926deccbSFrançois Tigeot cayman_pcie_gart_disable(rdev); 2311926deccbSFrançois Tigeot return 0; 2312926deccbSFrançois Tigeot } 2313926deccbSFrançois Tigeot 2314926deccbSFrançois Tigeot /* Plan is to move initialization in that function and use 2315926deccbSFrançois Tigeot * helper function so that radeon_device_init pretty much 2316926deccbSFrançois Tigeot * do nothing more than calling asic specific function. This 2317926deccbSFrançois Tigeot * should also allow to remove a bunch of callback function 2318926deccbSFrançois Tigeot * like vram_info. 2319926deccbSFrançois Tigeot */ 2320926deccbSFrançois Tigeot int cayman_init(struct radeon_device *rdev) 2321926deccbSFrançois Tigeot { 2322926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 2323926deccbSFrançois Tigeot int r; 2324926deccbSFrançois Tigeot 2325926deccbSFrançois Tigeot /* Read BIOS */ 2326926deccbSFrançois Tigeot if (!radeon_get_bios(rdev)) { 2327926deccbSFrançois Tigeot if (ASIC_IS_AVIVO(rdev)) 2328926deccbSFrançois Tigeot return -EINVAL; 2329926deccbSFrançois Tigeot } 2330926deccbSFrançois Tigeot /* Must be an ATOMBIOS */ 2331926deccbSFrançois Tigeot if (!rdev->is_atom_bios) { 2332926deccbSFrançois Tigeot dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); 2333926deccbSFrançois Tigeot return -EINVAL; 2334926deccbSFrançois Tigeot } 2335926deccbSFrançois Tigeot r = radeon_atombios_init(rdev); 2336926deccbSFrançois Tigeot if (r) 2337926deccbSFrançois Tigeot return r; 2338926deccbSFrançois Tigeot 2339926deccbSFrançois Tigeot /* Post card if necessary */ 2340926deccbSFrançois Tigeot if (!radeon_card_posted(rdev)) { 2341926deccbSFrançois Tigeot if (!rdev->bios) { 2342926deccbSFrançois Tigeot dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 2343926deccbSFrançois Tigeot return -EINVAL; 2344926deccbSFrançois Tigeot } 2345926deccbSFrançois Tigeot DRM_INFO("GPU not posted. posting now...\n"); 2346926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context); 2347926deccbSFrançois Tigeot } 2348f43cf1b1SMichael Neumann /* init golden registers */ 2349f43cf1b1SMichael Neumann ni_init_golden_registers(rdev); 2350926deccbSFrançois Tigeot /* Initialize scratch registers */ 2351926deccbSFrançois Tigeot r600_scratch_init(rdev); 2352926deccbSFrançois Tigeot /* Initialize surface registers */ 2353926deccbSFrançois Tigeot radeon_surface_init(rdev); 2354926deccbSFrançois Tigeot /* Initialize clocks */ 2355926deccbSFrançois Tigeot radeon_get_clock_info(rdev->ddev); 2356926deccbSFrançois Tigeot /* Fence driver */ 2357926deccbSFrançois Tigeot r = radeon_fence_driver_init(rdev); 2358926deccbSFrançois Tigeot if (r) 2359926deccbSFrançois Tigeot return r; 2360926deccbSFrançois Tigeot /* initialize memory controller */ 2361926deccbSFrançois Tigeot r = evergreen_mc_init(rdev); 2362926deccbSFrançois Tigeot if (r) 2363926deccbSFrançois Tigeot return r; 2364926deccbSFrançois Tigeot /* Memory manager */ 2365926deccbSFrançois Tigeot r = radeon_bo_init(rdev); 2366926deccbSFrançois Tigeot if (r) 2367926deccbSFrançois Tigeot return r; 2368926deccbSFrançois Tigeot 2369926deccbSFrançois Tigeot ring->ring_obj = NULL; 2370926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 1024 * 1024); 2371926deccbSFrançois Tigeot 2372926deccbSFrançois Tigeot ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 2373926deccbSFrançois Tigeot ring->ring_obj = NULL; 2374926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 64 * 1024); 2375926deccbSFrançois Tigeot 2376926deccbSFrançois Tigeot ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 2377926deccbSFrançois Tigeot ring->ring_obj = NULL; 2378926deccbSFrançois Tigeot r600_ring_init(rdev, ring, 64 * 1024); 2379926deccbSFrançois Tigeot 2380f43cf1b1SMichael Neumann r = radeon_uvd_init(rdev); 2381f43cf1b1SMichael Neumann if (!r) { 2382f43cf1b1SMichael Neumann ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 2383f43cf1b1SMichael Neumann ring->ring_obj = NULL; 2384f43cf1b1SMichael Neumann r600_ring_init(rdev, ring, 4096); 2385f43cf1b1SMichael Neumann } 2386f43cf1b1SMichael Neumann 2387926deccbSFrançois Tigeot rdev->ih.ring_obj = NULL; 2388926deccbSFrançois Tigeot r600_ih_ring_init(rdev, 64 * 1024); 2389926deccbSFrançois Tigeot 2390926deccbSFrançois Tigeot r = r600_pcie_gart_init(rdev); 2391926deccbSFrançois Tigeot if (r) 2392926deccbSFrançois Tigeot return r; 2393926deccbSFrançois Tigeot 2394926deccbSFrançois Tigeot rdev->accel_working = true; 2395926deccbSFrançois Tigeot r = cayman_startup(rdev); 2396926deccbSFrançois Tigeot if (r) { 2397926deccbSFrançois Tigeot dev_err(rdev->dev, "disabling GPU acceleration\n"); 2398926deccbSFrançois Tigeot cayman_cp_fini(rdev); 2399926deccbSFrançois Tigeot cayman_dma_fini(rdev); 2400926deccbSFrançois Tigeot r600_irq_fini(rdev); 2401926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) 240257e252bfSMichael Neumann sumo_rlc_fini(rdev); 2403926deccbSFrançois Tigeot radeon_wb_fini(rdev); 2404926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev); 2405926deccbSFrançois Tigeot radeon_vm_manager_fini(rdev); 2406926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev); 2407926deccbSFrançois Tigeot cayman_pcie_gart_fini(rdev); 2408926deccbSFrançois Tigeot rdev->accel_working = false; 2409926deccbSFrançois Tigeot } 2410926deccbSFrançois Tigeot 2411926deccbSFrançois Tigeot /* Don't start up if the MC ucode is missing. 2412926deccbSFrançois Tigeot * The default clocks and voltages before the MC ucode 2413926deccbSFrançois Tigeot * is loaded are not suffient for advanced operations. 2414926deccbSFrançois Tigeot * 2415926deccbSFrançois Tigeot * We can skip this check for TN, because there is no MC 2416926deccbSFrançois Tigeot * ucode. 2417926deccbSFrançois Tigeot */ 2418926deccbSFrançois Tigeot if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { 2419926deccbSFrançois Tigeot DRM_ERROR("radeon: MC ucode required for NI+.\n"); 2420926deccbSFrançois Tigeot return -EINVAL; 2421926deccbSFrançois Tigeot } 2422926deccbSFrançois Tigeot 2423926deccbSFrançois Tigeot return 0; 2424926deccbSFrançois Tigeot } 2425926deccbSFrançois Tigeot 2426926deccbSFrançois Tigeot void cayman_fini(struct radeon_device *rdev) 2427926deccbSFrançois Tigeot { 2428926deccbSFrançois Tigeot r600_blit_fini(rdev); 2429926deccbSFrançois Tigeot cayman_cp_fini(rdev); 2430926deccbSFrançois Tigeot cayman_dma_fini(rdev); 2431926deccbSFrançois Tigeot r600_irq_fini(rdev); 2432926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) 243357e252bfSMichael Neumann sumo_rlc_fini(rdev); 2434926deccbSFrançois Tigeot radeon_wb_fini(rdev); 2435926deccbSFrançois Tigeot radeon_vm_manager_fini(rdev); 2436926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev); 2437926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev); 243857e252bfSMichael Neumann r600_uvd_stop(rdev); 2439f43cf1b1SMichael Neumann radeon_uvd_fini(rdev); 2440926deccbSFrançois Tigeot cayman_pcie_gart_fini(rdev); 2441926deccbSFrançois Tigeot r600_vram_scratch_fini(rdev); 2442926deccbSFrançois Tigeot radeon_gem_fini(rdev); 2443926deccbSFrançois Tigeot radeon_fence_driver_fini(rdev); 2444926deccbSFrançois Tigeot radeon_bo_fini(rdev); 2445926deccbSFrançois Tigeot radeon_atombios_fini(rdev); 2446926deccbSFrançois Tigeot ni_fini_microcode(rdev); 24475a3b77d5SFrançois Tigeot drm_free(rdev->bios, M_DRM); 2448926deccbSFrançois Tigeot rdev->bios = NULL; 2449926deccbSFrançois Tigeot } 2450926deccbSFrançois Tigeot 2451926deccbSFrançois Tigeot /* 2452926deccbSFrançois Tigeot * vm 2453926deccbSFrançois Tigeot */ 2454926deccbSFrançois Tigeot int cayman_vm_init(struct radeon_device *rdev) 2455926deccbSFrançois Tigeot { 2456926deccbSFrançois Tigeot /* number of VMs */ 2457926deccbSFrançois Tigeot rdev->vm_manager.nvm = 8; 2458926deccbSFrançois Tigeot /* base offset of vram pages */ 2459926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_IGP) { 2460926deccbSFrançois Tigeot u64 tmp = RREG32(FUS_MC_VM_FB_OFFSET); 2461926deccbSFrançois Tigeot tmp <<= 22; 2462926deccbSFrançois Tigeot rdev->vm_manager.vram_base_offset = tmp; 2463926deccbSFrançois Tigeot } else 2464926deccbSFrançois Tigeot rdev->vm_manager.vram_base_offset = 0; 2465926deccbSFrançois Tigeot return 0; 2466926deccbSFrançois Tigeot } 2467926deccbSFrançois Tigeot 2468926deccbSFrançois Tigeot void cayman_vm_fini(struct radeon_device *rdev) 2469926deccbSFrançois Tigeot { 2470926deccbSFrançois Tigeot } 2471926deccbSFrançois Tigeot 247257e252bfSMichael Neumann /** 247357e252bfSMichael Neumann * cayman_vm_decode_fault - print human readable fault info 247457e252bfSMichael Neumann * 247557e252bfSMichael Neumann * @rdev: radeon_device pointer 247657e252bfSMichael Neumann * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value 247757e252bfSMichael Neumann * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value 247857e252bfSMichael Neumann * 247957e252bfSMichael Neumann * Print human readable fault information (cayman/TN). 248057e252bfSMichael Neumann */ 248157e252bfSMichael Neumann void cayman_vm_decode_fault(struct radeon_device *rdev, 248257e252bfSMichael Neumann u32 status, u32 addr) 248357e252bfSMichael Neumann { 248457e252bfSMichael Neumann u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; 248557e252bfSMichael Neumann u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; 248657e252bfSMichael Neumann u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; 248757e252bfSMichael Neumann char *block; 248857e252bfSMichael Neumann 248957e252bfSMichael Neumann switch (mc_id) { 249057e252bfSMichael Neumann case 32: 249157e252bfSMichael Neumann case 16: 249257e252bfSMichael Neumann case 96: 249357e252bfSMichael Neumann case 80: 249457e252bfSMichael Neumann case 160: 249557e252bfSMichael Neumann case 144: 249657e252bfSMichael Neumann case 224: 249757e252bfSMichael Neumann case 208: 249857e252bfSMichael Neumann block = "CB"; 249957e252bfSMichael Neumann break; 250057e252bfSMichael Neumann case 33: 250157e252bfSMichael Neumann case 17: 250257e252bfSMichael Neumann case 97: 250357e252bfSMichael Neumann case 81: 250457e252bfSMichael Neumann case 161: 250557e252bfSMichael Neumann case 145: 250657e252bfSMichael Neumann case 225: 250757e252bfSMichael Neumann case 209: 250857e252bfSMichael Neumann block = "CB_FMASK"; 250957e252bfSMichael Neumann break; 251057e252bfSMichael Neumann case 34: 251157e252bfSMichael Neumann case 18: 251257e252bfSMichael Neumann case 98: 251357e252bfSMichael Neumann case 82: 251457e252bfSMichael Neumann case 162: 251557e252bfSMichael Neumann case 146: 251657e252bfSMichael Neumann case 226: 251757e252bfSMichael Neumann case 210: 251857e252bfSMichael Neumann block = "CB_CMASK"; 251957e252bfSMichael Neumann break; 252057e252bfSMichael Neumann case 35: 252157e252bfSMichael Neumann case 19: 252257e252bfSMichael Neumann case 99: 252357e252bfSMichael Neumann case 83: 252457e252bfSMichael Neumann case 163: 252557e252bfSMichael Neumann case 147: 252657e252bfSMichael Neumann case 227: 252757e252bfSMichael Neumann case 211: 252857e252bfSMichael Neumann block = "CB_IMMED"; 252957e252bfSMichael Neumann break; 253057e252bfSMichael Neumann case 36: 253157e252bfSMichael Neumann case 20: 253257e252bfSMichael Neumann case 100: 253357e252bfSMichael Neumann case 84: 253457e252bfSMichael Neumann case 164: 253557e252bfSMichael Neumann case 148: 253657e252bfSMichael Neumann case 228: 253757e252bfSMichael Neumann case 212: 253857e252bfSMichael Neumann block = "DB"; 253957e252bfSMichael Neumann break; 254057e252bfSMichael Neumann case 37: 254157e252bfSMichael Neumann case 21: 254257e252bfSMichael Neumann case 101: 254357e252bfSMichael Neumann case 85: 254457e252bfSMichael Neumann case 165: 254557e252bfSMichael Neumann case 149: 254657e252bfSMichael Neumann case 229: 254757e252bfSMichael Neumann case 213: 254857e252bfSMichael Neumann block = "DB_HTILE"; 254957e252bfSMichael Neumann break; 255057e252bfSMichael Neumann case 38: 255157e252bfSMichael Neumann case 22: 255257e252bfSMichael Neumann case 102: 255357e252bfSMichael Neumann case 86: 255457e252bfSMichael Neumann case 166: 255557e252bfSMichael Neumann case 150: 255657e252bfSMichael Neumann case 230: 255757e252bfSMichael Neumann case 214: 255857e252bfSMichael Neumann block = "SX"; 255957e252bfSMichael Neumann break; 256057e252bfSMichael Neumann case 39: 256157e252bfSMichael Neumann case 23: 256257e252bfSMichael Neumann case 103: 256357e252bfSMichael Neumann case 87: 256457e252bfSMichael Neumann case 167: 256557e252bfSMichael Neumann case 151: 256657e252bfSMichael Neumann case 231: 256757e252bfSMichael Neumann case 215: 256857e252bfSMichael Neumann block = "DB_STEN"; 256957e252bfSMichael Neumann break; 257057e252bfSMichael Neumann case 40: 257157e252bfSMichael Neumann case 24: 257257e252bfSMichael Neumann case 104: 257357e252bfSMichael Neumann case 88: 257457e252bfSMichael Neumann case 232: 257557e252bfSMichael Neumann case 216: 257657e252bfSMichael Neumann case 168: 257757e252bfSMichael Neumann case 152: 257857e252bfSMichael Neumann block = "TC_TFETCH"; 257957e252bfSMichael Neumann break; 258057e252bfSMichael Neumann case 41: 258157e252bfSMichael Neumann case 25: 258257e252bfSMichael Neumann case 105: 258357e252bfSMichael Neumann case 89: 258457e252bfSMichael Neumann case 233: 258557e252bfSMichael Neumann case 217: 258657e252bfSMichael Neumann case 169: 258757e252bfSMichael Neumann case 153: 258857e252bfSMichael Neumann block = "TC_VFETCH"; 258957e252bfSMichael Neumann break; 259057e252bfSMichael Neumann case 42: 259157e252bfSMichael Neumann case 26: 259257e252bfSMichael Neumann case 106: 259357e252bfSMichael Neumann case 90: 259457e252bfSMichael Neumann case 234: 259557e252bfSMichael Neumann case 218: 259657e252bfSMichael Neumann case 170: 259757e252bfSMichael Neumann case 154: 259857e252bfSMichael Neumann block = "VC"; 259957e252bfSMichael Neumann break; 260057e252bfSMichael Neumann case 112: 260157e252bfSMichael Neumann block = "CP"; 260257e252bfSMichael Neumann break; 260357e252bfSMichael Neumann case 113: 260457e252bfSMichael Neumann case 114: 260557e252bfSMichael Neumann block = "SH"; 260657e252bfSMichael Neumann break; 260757e252bfSMichael Neumann case 115: 260857e252bfSMichael Neumann block = "VGT"; 260957e252bfSMichael Neumann break; 261057e252bfSMichael Neumann case 178: 261157e252bfSMichael Neumann block = "IH"; 261257e252bfSMichael Neumann break; 261357e252bfSMichael Neumann case 51: 261457e252bfSMichael Neumann block = "RLC"; 261557e252bfSMichael Neumann break; 261657e252bfSMichael Neumann case 55: 261757e252bfSMichael Neumann block = "DMA"; 261857e252bfSMichael Neumann break; 261957e252bfSMichael Neumann case 56: 262057e252bfSMichael Neumann block = "HDP"; 262157e252bfSMichael Neumann break; 262257e252bfSMichael Neumann default: 262357e252bfSMichael Neumann block = "unknown"; 262457e252bfSMichael Neumann break; 262557e252bfSMichael Neumann } 262657e252bfSMichael Neumann 262757e252bfSMichael Neumann printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n", 262857e252bfSMichael Neumann protections, vmid, addr, 262957e252bfSMichael Neumann (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", 263057e252bfSMichael Neumann block, mc_id); 263157e252bfSMichael Neumann } 263257e252bfSMichael Neumann 2633926deccbSFrançois Tigeot #define R600_ENTRY_VALID (1 << 0) 2634926deccbSFrançois Tigeot #define R600_PTE_SYSTEM (1 << 1) 2635926deccbSFrançois Tigeot #define R600_PTE_SNOOPED (1 << 2) 2636926deccbSFrançois Tigeot #define R600_PTE_READABLE (1 << 5) 2637926deccbSFrançois Tigeot #define R600_PTE_WRITEABLE (1 << 6) 2638926deccbSFrançois Tigeot 2639926deccbSFrançois Tigeot uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) 2640926deccbSFrançois Tigeot { 2641926deccbSFrançois Tigeot uint32_t r600_flags = 0; 2642926deccbSFrançois Tigeot r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0; 2643926deccbSFrançois Tigeot r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; 2644926deccbSFrançois Tigeot r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; 2645926deccbSFrançois Tigeot if (flags & RADEON_VM_PAGE_SYSTEM) { 2646926deccbSFrançois Tigeot r600_flags |= R600_PTE_SYSTEM; 2647926deccbSFrançois Tigeot r600_flags |= (flags & RADEON_VM_PAGE_SNOOPED) ? R600_PTE_SNOOPED : 0; 2648926deccbSFrançois Tigeot } 2649926deccbSFrançois Tigeot return r600_flags; 2650926deccbSFrançois Tigeot } 2651926deccbSFrançois Tigeot 2652926deccbSFrançois Tigeot /** 2653926deccbSFrançois Tigeot * cayman_vm_set_page - update the page tables using the CP 2654926deccbSFrançois Tigeot * 2655926deccbSFrançois Tigeot * @rdev: radeon_device pointer 2656b403bed8SMichael Neumann * @ib: indirect buffer to fill with commands 2657926deccbSFrançois Tigeot * @pe: addr of the page entry 2658926deccbSFrançois Tigeot * @addr: dst addr to write into pe 2659926deccbSFrançois Tigeot * @count: number of page entries to update 2660926deccbSFrançois Tigeot * @incr: increase next addr by incr bytes 2661926deccbSFrançois Tigeot * @flags: access flags 2662926deccbSFrançois Tigeot * 2663b403bed8SMichael Neumann * Update the page tables using the CP (cayman/TN). 2664926deccbSFrançois Tigeot */ 2665b403bed8SMichael Neumann void cayman_vm_set_page(struct radeon_device *rdev, 2666b403bed8SMichael Neumann struct radeon_ib *ib, 2667b403bed8SMichael Neumann uint64_t pe, 2668926deccbSFrançois Tigeot uint64_t addr, unsigned count, 2669926deccbSFrançois Tigeot uint32_t incr, uint32_t flags) 2670926deccbSFrançois Tigeot { 2671926deccbSFrançois Tigeot uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); 2672926deccbSFrançois Tigeot uint64_t value; 2673926deccbSFrançois Tigeot unsigned ndw; 2674926deccbSFrançois Tigeot 2675926deccbSFrançois Tigeot if (rdev->asic->vm.pt_ring_index == RADEON_RING_TYPE_GFX_INDEX) { 2676926deccbSFrançois Tigeot while (count) { 2677926deccbSFrançois Tigeot ndw = 1 + count * 2; 2678926deccbSFrançois Tigeot if (ndw > 0x3FFF) 2679926deccbSFrançois Tigeot ndw = 0x3FFF; 2680926deccbSFrançois Tigeot 2681b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw); 2682b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = pe; 2683b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; 2684926deccbSFrançois Tigeot for (; ndw > 1; ndw -= 2, --count, pe += 8) { 2685926deccbSFrançois Tigeot if (flags & RADEON_VM_PAGE_SYSTEM) { 2686926deccbSFrançois Tigeot value = radeon_vm_map_gart(rdev, addr); 2687926deccbSFrançois Tigeot value &= 0xFFFFFFFFFFFFF000ULL; 2688926deccbSFrançois Tigeot } else if (flags & RADEON_VM_PAGE_VALID) { 2689926deccbSFrançois Tigeot value = addr; 2690926deccbSFrançois Tigeot } else { 2691926deccbSFrançois Tigeot value = 0; 2692926deccbSFrançois Tigeot } 2693926deccbSFrançois Tigeot addr += incr; 2694926deccbSFrançois Tigeot value |= r600_flags; 2695b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = value; 2696b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = upper_32_bits(value); 2697926deccbSFrançois Tigeot } 2698926deccbSFrançois Tigeot } 2699926deccbSFrançois Tigeot } else { 2700f43cf1b1SMichael Neumann if ((flags & RADEON_VM_PAGE_SYSTEM) || 2701f43cf1b1SMichael Neumann (count == 1)) { 2702926deccbSFrançois Tigeot while (count) { 2703926deccbSFrançois Tigeot ndw = count * 2; 2704926deccbSFrançois Tigeot if (ndw > 0xFFFFE) 2705926deccbSFrançois Tigeot ndw = 0xFFFFE; 2706926deccbSFrançois Tigeot 2707926deccbSFrançois Tigeot /* for non-physically contiguous pages (system) */ 2708b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw); 2709b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = pe; 2710b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; 2711926deccbSFrançois Tigeot for (; ndw > 0; ndw -= 2, --count, pe += 8) { 2712926deccbSFrançois Tigeot if (flags & RADEON_VM_PAGE_SYSTEM) { 2713926deccbSFrançois Tigeot value = radeon_vm_map_gart(rdev, addr); 2714926deccbSFrançois Tigeot value &= 0xFFFFFFFFFFFFF000ULL; 2715926deccbSFrançois Tigeot } else if (flags & RADEON_VM_PAGE_VALID) { 2716926deccbSFrançois Tigeot value = addr; 2717926deccbSFrançois Tigeot } else { 2718926deccbSFrançois Tigeot value = 0; 2719926deccbSFrançois Tigeot } 2720926deccbSFrançois Tigeot addr += incr; 2721926deccbSFrançois Tigeot value |= r600_flags; 2722b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = value; 2723b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = upper_32_bits(value); 2724926deccbSFrançois Tigeot } 2725926deccbSFrançois Tigeot } 2726b403bed8SMichael Neumann while (ib->length_dw & 0x7) 2727b403bed8SMichael Neumann ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); 2728f43cf1b1SMichael Neumann } else { 2729f43cf1b1SMichael Neumann while (count) { 2730f43cf1b1SMichael Neumann ndw = count * 2; 2731f43cf1b1SMichael Neumann if (ndw > 0xFFFFE) 2732f43cf1b1SMichael Neumann ndw = 0xFFFFE; 2733f43cf1b1SMichael Neumann 2734f43cf1b1SMichael Neumann if (flags & RADEON_VM_PAGE_VALID) 2735f43cf1b1SMichael Neumann value = addr; 2736f43cf1b1SMichael Neumann else 2737f43cf1b1SMichael Neumann value = 0; 2738f43cf1b1SMichael Neumann /* for physically contiguous pages (vram) */ 2739f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); 2740f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = pe; /* dst addr */ 2741f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; 2742f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = r600_flags; /* mask */ 2743f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = 0; 2744f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = value; /* value */ 2745f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = upper_32_bits(value); 2746f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = incr; /* increment size */ 2747f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = 0; 2748f43cf1b1SMichael Neumann pe += ndw * 4; 2749f43cf1b1SMichael Neumann addr += (ndw / 2) * incr; 2750f43cf1b1SMichael Neumann count -= ndw / 2; 2751f43cf1b1SMichael Neumann } 2752f43cf1b1SMichael Neumann } 2753f43cf1b1SMichael Neumann while (ib->length_dw & 0x7) 2754f43cf1b1SMichael Neumann ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0); 2755926deccbSFrançois Tigeot } 2756926deccbSFrançois Tigeot } 2757926deccbSFrançois Tigeot 2758926deccbSFrançois Tigeot /** 2759926deccbSFrançois Tigeot * cayman_vm_flush - vm flush using the CP 2760926deccbSFrançois Tigeot * 2761926deccbSFrançois Tigeot * @rdev: radeon_device pointer 2762926deccbSFrançois Tigeot * 2763926deccbSFrançois Tigeot * Update the page table base and flush the VM TLB 2764926deccbSFrançois Tigeot * using the CP (cayman-si). 2765926deccbSFrançois Tigeot */ 2766926deccbSFrançois Tigeot void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) 2767926deccbSFrançois Tigeot { 2768926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[ridx]; 2769926deccbSFrançois Tigeot 2770926deccbSFrançois Tigeot if (vm == NULL) 2771926deccbSFrançois Tigeot return; 2772926deccbSFrançois Tigeot 2773926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0)); 2774926deccbSFrançois Tigeot radeon_ring_write(ring, vm->pd_gpu_addr >> 12); 2775926deccbSFrançois Tigeot 2776926deccbSFrançois Tigeot /* flush hdp cache */ 2777926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(HDP_MEM_COHERENCY_FLUSH_CNTL, 0)); 2778926deccbSFrançois Tigeot radeon_ring_write(ring, 0x1); 2779926deccbSFrançois Tigeot 2780926deccbSFrançois Tigeot /* bits 0-7 are the VM contexts0-7 */ 2781926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); 2782926deccbSFrançois Tigeot radeon_ring_write(ring, 1 << vm->id); 2783926deccbSFrançois Tigeot 2784926deccbSFrançois Tigeot /* sync PFP to ME, otherwise we might get invalid PFP reads */ 2785926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); 2786926deccbSFrançois Tigeot radeon_ring_write(ring, 0x0); 2787926deccbSFrançois Tigeot } 2788926deccbSFrançois Tigeot 2789926deccbSFrançois Tigeot void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) 2790926deccbSFrançois Tigeot { 2791926deccbSFrançois Tigeot struct radeon_ring *ring = &rdev->ring[ridx]; 2792926deccbSFrançois Tigeot 2793926deccbSFrançois Tigeot if (vm == NULL) 2794926deccbSFrançois Tigeot return; 2795926deccbSFrançois Tigeot 2796926deccbSFrançois Tigeot radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); 2797926deccbSFrançois Tigeot radeon_ring_write(ring, (0xf << 16) | ((VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2)) >> 2)); 2798926deccbSFrançois Tigeot radeon_ring_write(ring, vm->pd_gpu_addr >> 12); 2799926deccbSFrançois Tigeot 2800926deccbSFrançois Tigeot /* flush hdp cache */ 2801926deccbSFrançois Tigeot radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); 2802926deccbSFrançois Tigeot radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2)); 2803926deccbSFrançois Tigeot radeon_ring_write(ring, 1); 2804926deccbSFrançois Tigeot 2805926deccbSFrançois Tigeot /* bits 0-7 are the VM contexts0-7 */ 2806926deccbSFrançois Tigeot radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); 2807926deccbSFrançois Tigeot radeon_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST >> 2)); 2808926deccbSFrançois Tigeot radeon_ring_write(ring, 1 << vm->id); 2809926deccbSFrançois Tigeot } 2810926deccbSFrançois Tigeot 2811