162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2011 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Authors: Alex Deucher 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <linux/firmware.h> 2662306a36Sopenharmony_ci#include <linux/module.h> 2762306a36Sopenharmony_ci#include <linux/pci.h> 2862306a36Sopenharmony_ci#include <linux/slab.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include <drm/drm_vblank.h> 3162306a36Sopenharmony_ci#include <drm/radeon_drm.h> 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#include "atom.h" 3462306a36Sopenharmony_ci#include "clearstate_si.h" 3562306a36Sopenharmony_ci#include "evergreen.h" 3662306a36Sopenharmony_ci#include "r600.h" 3762306a36Sopenharmony_ci#include "radeon.h" 3862306a36Sopenharmony_ci#include "radeon_asic.h" 3962306a36Sopenharmony_ci#include "radeon_audio.h" 4062306a36Sopenharmony_ci#include "radeon_ucode.h" 4162306a36Sopenharmony_ci#include "si_blit_shaders.h" 4262306a36Sopenharmony_ci#include "si.h" 4362306a36Sopenharmony_ci#include "sid.h" 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_pfp.bin"); 4762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_me.bin"); 4862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_ce.bin"); 4962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_mc.bin"); 5062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_mc2.bin"); 5162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_rlc.bin"); 5262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_smc.bin"); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_pfp.bin"); 5562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_me.bin"); 5662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_ce.bin"); 5762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_mc.bin"); 5862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_rlc.bin"); 5962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_smc.bin"); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); 6262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); 6362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_ce.bin"); 6462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_mc.bin"); 6562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin"); 6662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin"); 6762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_smc.bin"); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_pfp.bin"); 7062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_me.bin"); 7162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_ce.bin"); 7262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_mc.bin"); 7362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_rlc.bin"); 7462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_smc.bin"); 7562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_k_smc.bin"); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_pfp.bin"); 7862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_me.bin"); 7962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_ce.bin"); 8062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_mc.bin"); 8162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_mc2.bin"); 8262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_rlc.bin"); 8362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_smc.bin"); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_pfp.bin"); 8662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_me.bin"); 8762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_ce.bin"); 8862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_mc.bin"); 8962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_rlc.bin"); 9062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_smc.bin"); 9162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_k_smc.bin"); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_pfp.bin"); 9462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_me.bin"); 9562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_ce.bin"); 9662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_mc.bin"); 9762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_mc2.bin"); 9862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_rlc.bin"); 9962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_smc.bin"); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_pfp.bin"); 10262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_me.bin"); 10362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_ce.bin"); 10462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_mc.bin"); 10562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_rlc.bin"); 10662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_smc.bin"); 10762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_k_smc.bin"); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); 11062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_me.bin"); 11162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_ce.bin"); 11262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_mc.bin"); 11362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_mc2.bin"); 11462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_rlc.bin"); 11562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_smc.bin"); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_pfp.bin"); 11862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_me.bin"); 11962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_ce.bin"); 12062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_mc.bin"); 12162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_rlc.bin"); 12262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_smc.bin"); 12362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_k_smc.bin"); 12462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/banks_k_2_smc.bin"); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/si58_mc.bin"); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh); 12962306a36Sopenharmony_cistatic void si_pcie_gen3_enable(struct radeon_device *rdev); 13062306a36Sopenharmony_cistatic void si_program_aspm(struct radeon_device *rdev); 13162306a36Sopenharmony_ciextern void sumo_rlc_fini(struct radeon_device *rdev); 13262306a36Sopenharmony_ciextern int sumo_rlc_init(struct radeon_device *rdev); 13362306a36Sopenharmony_cistatic void si_enable_gui_idle_interrupt(struct radeon_device *rdev, 13462306a36Sopenharmony_ci bool enable); 13562306a36Sopenharmony_cistatic void si_init_pg(struct radeon_device *rdev); 13662306a36Sopenharmony_cistatic void si_init_cg(struct radeon_device *rdev); 13762306a36Sopenharmony_cistatic void si_fini_pg(struct radeon_device *rdev); 13862306a36Sopenharmony_cistatic void si_fini_cg(struct radeon_device *rdev); 13962306a36Sopenharmony_cistatic void si_rlc_stop(struct radeon_device *rdev); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic const u32 crtc_offsets[] = 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci EVERGREEN_CRTC0_REGISTER_OFFSET, 14462306a36Sopenharmony_ci EVERGREEN_CRTC1_REGISTER_OFFSET, 14562306a36Sopenharmony_ci EVERGREEN_CRTC2_REGISTER_OFFSET, 14662306a36Sopenharmony_ci EVERGREEN_CRTC3_REGISTER_OFFSET, 14762306a36Sopenharmony_ci EVERGREEN_CRTC4_REGISTER_OFFSET, 14862306a36Sopenharmony_ci EVERGREEN_CRTC5_REGISTER_OFFSET 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic const u32 si_disp_int_status[] = 15262306a36Sopenharmony_ci{ 15362306a36Sopenharmony_ci DISP_INTERRUPT_STATUS, 15462306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE, 15562306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE2, 15662306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE3, 15762306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE4, 15862306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE5 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci#define DC_HPDx_CONTROL(x) (DC_HPD1_CONTROL + (x * 0xc)) 16262306a36Sopenharmony_ci#define DC_HPDx_INT_CONTROL(x) (DC_HPD1_INT_CONTROL + (x * 0xc)) 16362306a36Sopenharmony_ci#define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS + (x * 0xc)) 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic const u32 verde_rlc_save_restore_register_list[] = 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci (0x8000 << 16) | (0x98f4 >> 2), 16862306a36Sopenharmony_ci 0x00000000, 16962306a36Sopenharmony_ci (0x8040 << 16) | (0x98f4 >> 2), 17062306a36Sopenharmony_ci 0x00000000, 17162306a36Sopenharmony_ci (0x8000 << 16) | (0xe80 >> 2), 17262306a36Sopenharmony_ci 0x00000000, 17362306a36Sopenharmony_ci (0x8040 << 16) | (0xe80 >> 2), 17462306a36Sopenharmony_ci 0x00000000, 17562306a36Sopenharmony_ci (0x8000 << 16) | (0x89bc >> 2), 17662306a36Sopenharmony_ci 0x00000000, 17762306a36Sopenharmony_ci (0x8040 << 16) | (0x89bc >> 2), 17862306a36Sopenharmony_ci 0x00000000, 17962306a36Sopenharmony_ci (0x8000 << 16) | (0x8c1c >> 2), 18062306a36Sopenharmony_ci 0x00000000, 18162306a36Sopenharmony_ci (0x8040 << 16) | (0x8c1c >> 2), 18262306a36Sopenharmony_ci 0x00000000, 18362306a36Sopenharmony_ci (0x9c00 << 16) | (0x98f0 >> 2), 18462306a36Sopenharmony_ci 0x00000000, 18562306a36Sopenharmony_ci (0x9c00 << 16) | (0xe7c >> 2), 18662306a36Sopenharmony_ci 0x00000000, 18762306a36Sopenharmony_ci (0x8000 << 16) | (0x9148 >> 2), 18862306a36Sopenharmony_ci 0x00000000, 18962306a36Sopenharmony_ci (0x8040 << 16) | (0x9148 >> 2), 19062306a36Sopenharmony_ci 0x00000000, 19162306a36Sopenharmony_ci (0x9c00 << 16) | (0x9150 >> 2), 19262306a36Sopenharmony_ci 0x00000000, 19362306a36Sopenharmony_ci (0x9c00 << 16) | (0x897c >> 2), 19462306a36Sopenharmony_ci 0x00000000, 19562306a36Sopenharmony_ci (0x9c00 << 16) | (0x8d8c >> 2), 19662306a36Sopenharmony_ci 0x00000000, 19762306a36Sopenharmony_ci (0x9c00 << 16) | (0xac54 >> 2), 19862306a36Sopenharmony_ci 0X00000000, 19962306a36Sopenharmony_ci 0x3, 20062306a36Sopenharmony_ci (0x9c00 << 16) | (0x98f8 >> 2), 20162306a36Sopenharmony_ci 0x00000000, 20262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9910 >> 2), 20362306a36Sopenharmony_ci 0x00000000, 20462306a36Sopenharmony_ci (0x9c00 << 16) | (0x9914 >> 2), 20562306a36Sopenharmony_ci 0x00000000, 20662306a36Sopenharmony_ci (0x9c00 << 16) | (0x9918 >> 2), 20762306a36Sopenharmony_ci 0x00000000, 20862306a36Sopenharmony_ci (0x9c00 << 16) | (0x991c >> 2), 20962306a36Sopenharmony_ci 0x00000000, 21062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9920 >> 2), 21162306a36Sopenharmony_ci 0x00000000, 21262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9924 >> 2), 21362306a36Sopenharmony_ci 0x00000000, 21462306a36Sopenharmony_ci (0x9c00 << 16) | (0x9928 >> 2), 21562306a36Sopenharmony_ci 0x00000000, 21662306a36Sopenharmony_ci (0x9c00 << 16) | (0x992c >> 2), 21762306a36Sopenharmony_ci 0x00000000, 21862306a36Sopenharmony_ci (0x9c00 << 16) | (0x9930 >> 2), 21962306a36Sopenharmony_ci 0x00000000, 22062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9934 >> 2), 22162306a36Sopenharmony_ci 0x00000000, 22262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9938 >> 2), 22362306a36Sopenharmony_ci 0x00000000, 22462306a36Sopenharmony_ci (0x9c00 << 16) | (0x993c >> 2), 22562306a36Sopenharmony_ci 0x00000000, 22662306a36Sopenharmony_ci (0x9c00 << 16) | (0x9940 >> 2), 22762306a36Sopenharmony_ci 0x00000000, 22862306a36Sopenharmony_ci (0x9c00 << 16) | (0x9944 >> 2), 22962306a36Sopenharmony_ci 0x00000000, 23062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9948 >> 2), 23162306a36Sopenharmony_ci 0x00000000, 23262306a36Sopenharmony_ci (0x9c00 << 16) | (0x994c >> 2), 23362306a36Sopenharmony_ci 0x00000000, 23462306a36Sopenharmony_ci (0x9c00 << 16) | (0x9950 >> 2), 23562306a36Sopenharmony_ci 0x00000000, 23662306a36Sopenharmony_ci (0x9c00 << 16) | (0x9954 >> 2), 23762306a36Sopenharmony_ci 0x00000000, 23862306a36Sopenharmony_ci (0x9c00 << 16) | (0x9958 >> 2), 23962306a36Sopenharmony_ci 0x00000000, 24062306a36Sopenharmony_ci (0x9c00 << 16) | (0x995c >> 2), 24162306a36Sopenharmony_ci 0x00000000, 24262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9960 >> 2), 24362306a36Sopenharmony_ci 0x00000000, 24462306a36Sopenharmony_ci (0x9c00 << 16) | (0x9964 >> 2), 24562306a36Sopenharmony_ci 0x00000000, 24662306a36Sopenharmony_ci (0x9c00 << 16) | (0x9968 >> 2), 24762306a36Sopenharmony_ci 0x00000000, 24862306a36Sopenharmony_ci (0x9c00 << 16) | (0x996c >> 2), 24962306a36Sopenharmony_ci 0x00000000, 25062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9970 >> 2), 25162306a36Sopenharmony_ci 0x00000000, 25262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9974 >> 2), 25362306a36Sopenharmony_ci 0x00000000, 25462306a36Sopenharmony_ci (0x9c00 << 16) | (0x9978 >> 2), 25562306a36Sopenharmony_ci 0x00000000, 25662306a36Sopenharmony_ci (0x9c00 << 16) | (0x997c >> 2), 25762306a36Sopenharmony_ci 0x00000000, 25862306a36Sopenharmony_ci (0x9c00 << 16) | (0x9980 >> 2), 25962306a36Sopenharmony_ci 0x00000000, 26062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9984 >> 2), 26162306a36Sopenharmony_ci 0x00000000, 26262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9988 >> 2), 26362306a36Sopenharmony_ci 0x00000000, 26462306a36Sopenharmony_ci (0x9c00 << 16) | (0x998c >> 2), 26562306a36Sopenharmony_ci 0x00000000, 26662306a36Sopenharmony_ci (0x9c00 << 16) | (0x8c00 >> 2), 26762306a36Sopenharmony_ci 0x00000000, 26862306a36Sopenharmony_ci (0x9c00 << 16) | (0x8c14 >> 2), 26962306a36Sopenharmony_ci 0x00000000, 27062306a36Sopenharmony_ci (0x9c00 << 16) | (0x8c04 >> 2), 27162306a36Sopenharmony_ci 0x00000000, 27262306a36Sopenharmony_ci (0x9c00 << 16) | (0x8c08 >> 2), 27362306a36Sopenharmony_ci 0x00000000, 27462306a36Sopenharmony_ci (0x8000 << 16) | (0x9b7c >> 2), 27562306a36Sopenharmony_ci 0x00000000, 27662306a36Sopenharmony_ci (0x8040 << 16) | (0x9b7c >> 2), 27762306a36Sopenharmony_ci 0x00000000, 27862306a36Sopenharmony_ci (0x8000 << 16) | (0xe84 >> 2), 27962306a36Sopenharmony_ci 0x00000000, 28062306a36Sopenharmony_ci (0x8040 << 16) | (0xe84 >> 2), 28162306a36Sopenharmony_ci 0x00000000, 28262306a36Sopenharmony_ci (0x8000 << 16) | (0x89c0 >> 2), 28362306a36Sopenharmony_ci 0x00000000, 28462306a36Sopenharmony_ci (0x8040 << 16) | (0x89c0 >> 2), 28562306a36Sopenharmony_ci 0x00000000, 28662306a36Sopenharmony_ci (0x8000 << 16) | (0x914c >> 2), 28762306a36Sopenharmony_ci 0x00000000, 28862306a36Sopenharmony_ci (0x8040 << 16) | (0x914c >> 2), 28962306a36Sopenharmony_ci 0x00000000, 29062306a36Sopenharmony_ci (0x8000 << 16) | (0x8c20 >> 2), 29162306a36Sopenharmony_ci 0x00000000, 29262306a36Sopenharmony_ci (0x8040 << 16) | (0x8c20 >> 2), 29362306a36Sopenharmony_ci 0x00000000, 29462306a36Sopenharmony_ci (0x8000 << 16) | (0x9354 >> 2), 29562306a36Sopenharmony_ci 0x00000000, 29662306a36Sopenharmony_ci (0x8040 << 16) | (0x9354 >> 2), 29762306a36Sopenharmony_ci 0x00000000, 29862306a36Sopenharmony_ci (0x9c00 << 16) | (0x9060 >> 2), 29962306a36Sopenharmony_ci 0x00000000, 30062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9364 >> 2), 30162306a36Sopenharmony_ci 0x00000000, 30262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9100 >> 2), 30362306a36Sopenharmony_ci 0x00000000, 30462306a36Sopenharmony_ci (0x9c00 << 16) | (0x913c >> 2), 30562306a36Sopenharmony_ci 0x00000000, 30662306a36Sopenharmony_ci (0x8000 << 16) | (0x90e0 >> 2), 30762306a36Sopenharmony_ci 0x00000000, 30862306a36Sopenharmony_ci (0x8000 << 16) | (0x90e4 >> 2), 30962306a36Sopenharmony_ci 0x00000000, 31062306a36Sopenharmony_ci (0x8000 << 16) | (0x90e8 >> 2), 31162306a36Sopenharmony_ci 0x00000000, 31262306a36Sopenharmony_ci (0x8040 << 16) | (0x90e0 >> 2), 31362306a36Sopenharmony_ci 0x00000000, 31462306a36Sopenharmony_ci (0x8040 << 16) | (0x90e4 >> 2), 31562306a36Sopenharmony_ci 0x00000000, 31662306a36Sopenharmony_ci (0x8040 << 16) | (0x90e8 >> 2), 31762306a36Sopenharmony_ci 0x00000000, 31862306a36Sopenharmony_ci (0x9c00 << 16) | (0x8bcc >> 2), 31962306a36Sopenharmony_ci 0x00000000, 32062306a36Sopenharmony_ci (0x9c00 << 16) | (0x8b24 >> 2), 32162306a36Sopenharmony_ci 0x00000000, 32262306a36Sopenharmony_ci (0x9c00 << 16) | (0x88c4 >> 2), 32362306a36Sopenharmony_ci 0x00000000, 32462306a36Sopenharmony_ci (0x9c00 << 16) | (0x8e50 >> 2), 32562306a36Sopenharmony_ci 0x00000000, 32662306a36Sopenharmony_ci (0x9c00 << 16) | (0x8c0c >> 2), 32762306a36Sopenharmony_ci 0x00000000, 32862306a36Sopenharmony_ci (0x9c00 << 16) | (0x8e58 >> 2), 32962306a36Sopenharmony_ci 0x00000000, 33062306a36Sopenharmony_ci (0x9c00 << 16) | (0x8e5c >> 2), 33162306a36Sopenharmony_ci 0x00000000, 33262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9508 >> 2), 33362306a36Sopenharmony_ci 0x00000000, 33462306a36Sopenharmony_ci (0x9c00 << 16) | (0x950c >> 2), 33562306a36Sopenharmony_ci 0x00000000, 33662306a36Sopenharmony_ci (0x9c00 << 16) | (0x9494 >> 2), 33762306a36Sopenharmony_ci 0x00000000, 33862306a36Sopenharmony_ci (0x9c00 << 16) | (0xac0c >> 2), 33962306a36Sopenharmony_ci 0x00000000, 34062306a36Sopenharmony_ci (0x9c00 << 16) | (0xac10 >> 2), 34162306a36Sopenharmony_ci 0x00000000, 34262306a36Sopenharmony_ci (0x9c00 << 16) | (0xac14 >> 2), 34362306a36Sopenharmony_ci 0x00000000, 34462306a36Sopenharmony_ci (0x9c00 << 16) | (0xae00 >> 2), 34562306a36Sopenharmony_ci 0x00000000, 34662306a36Sopenharmony_ci (0x9c00 << 16) | (0xac08 >> 2), 34762306a36Sopenharmony_ci 0x00000000, 34862306a36Sopenharmony_ci (0x9c00 << 16) | (0x88d4 >> 2), 34962306a36Sopenharmony_ci 0x00000000, 35062306a36Sopenharmony_ci (0x9c00 << 16) | (0x88c8 >> 2), 35162306a36Sopenharmony_ci 0x00000000, 35262306a36Sopenharmony_ci (0x9c00 << 16) | (0x88cc >> 2), 35362306a36Sopenharmony_ci 0x00000000, 35462306a36Sopenharmony_ci (0x9c00 << 16) | (0x89b0 >> 2), 35562306a36Sopenharmony_ci 0x00000000, 35662306a36Sopenharmony_ci (0x9c00 << 16) | (0x8b10 >> 2), 35762306a36Sopenharmony_ci 0x00000000, 35862306a36Sopenharmony_ci (0x9c00 << 16) | (0x8a14 >> 2), 35962306a36Sopenharmony_ci 0x00000000, 36062306a36Sopenharmony_ci (0x9c00 << 16) | (0x9830 >> 2), 36162306a36Sopenharmony_ci 0x00000000, 36262306a36Sopenharmony_ci (0x9c00 << 16) | (0x9834 >> 2), 36362306a36Sopenharmony_ci 0x00000000, 36462306a36Sopenharmony_ci (0x9c00 << 16) | (0x9838 >> 2), 36562306a36Sopenharmony_ci 0x00000000, 36662306a36Sopenharmony_ci (0x9c00 << 16) | (0x9a10 >> 2), 36762306a36Sopenharmony_ci 0x00000000, 36862306a36Sopenharmony_ci (0x8000 << 16) | (0x9870 >> 2), 36962306a36Sopenharmony_ci 0x00000000, 37062306a36Sopenharmony_ci (0x8000 << 16) | (0x9874 >> 2), 37162306a36Sopenharmony_ci 0x00000000, 37262306a36Sopenharmony_ci (0x8001 << 16) | (0x9870 >> 2), 37362306a36Sopenharmony_ci 0x00000000, 37462306a36Sopenharmony_ci (0x8001 << 16) | (0x9874 >> 2), 37562306a36Sopenharmony_ci 0x00000000, 37662306a36Sopenharmony_ci (0x8040 << 16) | (0x9870 >> 2), 37762306a36Sopenharmony_ci 0x00000000, 37862306a36Sopenharmony_ci (0x8040 << 16) | (0x9874 >> 2), 37962306a36Sopenharmony_ci 0x00000000, 38062306a36Sopenharmony_ci (0x8041 << 16) | (0x9870 >> 2), 38162306a36Sopenharmony_ci 0x00000000, 38262306a36Sopenharmony_ci (0x8041 << 16) | (0x9874 >> 2), 38362306a36Sopenharmony_ci 0x00000000, 38462306a36Sopenharmony_ci 0x00000000 38562306a36Sopenharmony_ci}; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_cistatic const u32 tahiti_golden_rlc_registers[] = 38862306a36Sopenharmony_ci{ 38962306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x00601005, 39062306a36Sopenharmony_ci 0xc47c, 0xffffffff, 0x10104040, 39162306a36Sopenharmony_ci 0xc488, 0xffffffff, 0x0100000a, 39262306a36Sopenharmony_ci 0xc314, 0xffffffff, 0x00000800, 39362306a36Sopenharmony_ci 0xc30c, 0xffffffff, 0x800000f4, 39462306a36Sopenharmony_ci 0xf4a8, 0xffffffff, 0x00000000 39562306a36Sopenharmony_ci}; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_cistatic const u32 tahiti_golden_registers[] = 39862306a36Sopenharmony_ci{ 39962306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00018208, 40062306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 40162306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 40262306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 40362306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000000, 40462306a36Sopenharmony_ci 0xd030, 0x000300c0, 0x00800040, 40562306a36Sopenharmony_ci 0xd830, 0x000300c0, 0x00800040, 40662306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 40762306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 40862306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 40962306a36Sopenharmony_ci 0x277c, 0x00000003, 0x000007ff, 41062306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 41162306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 41262306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 41362306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 41462306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x4e000000, 41562306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x2a00126a, 41662306a36Sopenharmony_ci 0x30, 0x000000ff, 0x0040, 41762306a36Sopenharmony_ci 0x34, 0x00000040, 0x00004040, 41862306a36Sopenharmony_ci 0x9100, 0x07ffffff, 0x03000000, 41962306a36Sopenharmony_ci 0x8e88, 0x01ff1f3f, 0x00000000, 42062306a36Sopenharmony_ci 0x8e84, 0x01ff1f3f, 0x00000000, 42162306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 42262306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 42362306a36Sopenharmony_ci 0xac14, 0x00000200, 0x000002fb, 42462306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x0000543b, 42562306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0xa9210876, 42662306a36Sopenharmony_ci 0x88d0, 0xffffffff, 0x000fff40, 42762306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 42862306a36Sopenharmony_ci 0x1410, 0x20000000, 0x20fffed8, 42962306a36Sopenharmony_ci 0x15c0, 0x000c0fc0, 0x000c0400 43062306a36Sopenharmony_ci}; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistatic const u32 tahiti_golden_registers2[] = 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci 0xc64, 0x00000001, 0x00000001 43562306a36Sopenharmony_ci}; 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_cistatic const u32 pitcairn_golden_rlc_registers[] = 43862306a36Sopenharmony_ci{ 43962306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x00601004, 44062306a36Sopenharmony_ci 0xc47c, 0xffffffff, 0x10102020, 44162306a36Sopenharmony_ci 0xc488, 0xffffffff, 0x01000020, 44262306a36Sopenharmony_ci 0xc314, 0xffffffff, 0x00000800, 44362306a36Sopenharmony_ci 0xc30c, 0xffffffff, 0x800000a4 44462306a36Sopenharmony_ci}; 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_cistatic const u32 pitcairn_golden_registers[] = 44762306a36Sopenharmony_ci{ 44862306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00018208, 44962306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 45062306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 45162306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 45262306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000000, 45362306a36Sopenharmony_ci 0xd030, 0x000300c0, 0x00800040, 45462306a36Sopenharmony_ci 0xd830, 0x000300c0, 0x00800040, 45562306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 45662306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 45762306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 45862306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 45962306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 46062306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 46162306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 46262306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 46362306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x4e000000, 46462306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x2a00126a, 46562306a36Sopenharmony_ci 0x30, 0x000000ff, 0x0040, 46662306a36Sopenharmony_ci 0x34, 0x00000040, 0x00004040, 46762306a36Sopenharmony_ci 0x9100, 0x07ffffff, 0x03000000, 46862306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 46962306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 47062306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x000000f7, 47162306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x00000000, 47262306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x32761054, 47362306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 47462306a36Sopenharmony_ci 0x15c0, 0x000c0fc0, 0x000c0400 47562306a36Sopenharmony_ci}; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_cistatic const u32 verde_golden_rlc_registers[] = 47862306a36Sopenharmony_ci{ 47962306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x033f1005, 48062306a36Sopenharmony_ci 0xc47c, 0xffffffff, 0x10808020, 48162306a36Sopenharmony_ci 0xc488, 0xffffffff, 0x00800008, 48262306a36Sopenharmony_ci 0xc314, 0xffffffff, 0x00001000, 48362306a36Sopenharmony_ci 0xc30c, 0xffffffff, 0x80010014 48462306a36Sopenharmony_ci}; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_cistatic const u32 verde_golden_registers[] = 48762306a36Sopenharmony_ci{ 48862306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00018208, 48962306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 49062306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 49162306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 49262306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000000, 49362306a36Sopenharmony_ci 0xd030, 0x000300c0, 0x00800040, 49462306a36Sopenharmony_ci 0xd030, 0x000300c0, 0x00800040, 49562306a36Sopenharmony_ci 0xd830, 0x000300c0, 0x00800040, 49662306a36Sopenharmony_ci 0xd830, 0x000300c0, 0x00800040, 49762306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 49862306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 49962306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 50062306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 50162306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 50262306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 50362306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 50462306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 50562306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 50662306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 50762306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 50862306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 50962306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 51062306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 51162306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x4e000000, 51262306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x0000124a, 51362306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x0000124a, 51462306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x0000124a, 51562306a36Sopenharmony_ci 0x30, 0x000000ff, 0x0040, 51662306a36Sopenharmony_ci 0x34, 0x00000040, 0x00004040, 51762306a36Sopenharmony_ci 0x9100, 0x07ffffff, 0x03000000, 51862306a36Sopenharmony_ci 0x9100, 0x07ffffff, 0x03000000, 51962306a36Sopenharmony_ci 0x8e88, 0x01ff1f3f, 0x00000000, 52062306a36Sopenharmony_ci 0x8e88, 0x01ff1f3f, 0x00000000, 52162306a36Sopenharmony_ci 0x8e88, 0x01ff1f3f, 0x00000000, 52262306a36Sopenharmony_ci 0x8e84, 0x01ff1f3f, 0x00000000, 52362306a36Sopenharmony_ci 0x8e84, 0x01ff1f3f, 0x00000000, 52462306a36Sopenharmony_ci 0x8e84, 0x01ff1f3f, 0x00000000, 52562306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 52662306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 52762306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x00000003, 52862306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x00000003, 52962306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x00000003, 53062306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x00000000, 53162306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x00000000, 53262306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x00000000, 53362306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x00001032, 53462306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x00001032, 53562306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x00001032, 53662306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 53762306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 53862306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 53962306a36Sopenharmony_ci 0x15c0, 0x000c0fc0, 0x000c0400 54062306a36Sopenharmony_ci}; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_cistatic const u32 oland_golden_rlc_registers[] = 54362306a36Sopenharmony_ci{ 54462306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x00601005, 54562306a36Sopenharmony_ci 0xc47c, 0xffffffff, 0x10104040, 54662306a36Sopenharmony_ci 0xc488, 0xffffffff, 0x0100000a, 54762306a36Sopenharmony_ci 0xc314, 0xffffffff, 0x00000800, 54862306a36Sopenharmony_ci 0xc30c, 0xffffffff, 0x800000f4 54962306a36Sopenharmony_ci}; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_cistatic const u32 oland_golden_registers[] = 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00018208, 55462306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 55562306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 55662306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 55762306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000000, 55862306a36Sopenharmony_ci 0xd030, 0x000300c0, 0x00800040, 55962306a36Sopenharmony_ci 0xd830, 0x000300c0, 0x00800040, 56062306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 56162306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 56262306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 56362306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 56462306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 56562306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 56662306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 56762306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 56862306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x4e000000, 56962306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x00000082, 57062306a36Sopenharmony_ci 0x30, 0x000000ff, 0x0040, 57162306a36Sopenharmony_ci 0x34, 0x00000040, 0x00004040, 57262306a36Sopenharmony_ci 0x9100, 0x07ffffff, 0x03000000, 57362306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 57462306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 57562306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x000000f3, 57662306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x00000000, 57762306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x00003210, 57862306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 57962306a36Sopenharmony_ci 0x15c0, 0x000c0fc0, 0x000c0400 58062306a36Sopenharmony_ci}; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_cistatic const u32 hainan_golden_registers[] = 58362306a36Sopenharmony_ci{ 58462306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00018208, 58562306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 58662306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 58762306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 58862306a36Sopenharmony_ci 0xd0c0, 0xff000fff, 0x00000100, 58962306a36Sopenharmony_ci 0xd030, 0x000300c0, 0x00800040, 59062306a36Sopenharmony_ci 0xd8c0, 0xff000fff, 0x00000100, 59162306a36Sopenharmony_ci 0xd830, 0x000300c0, 0x00800040, 59262306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 59362306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 59462306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 59562306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 59662306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 59762306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x4e000000, 59862306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x00000000, 59962306a36Sopenharmony_ci 0x30, 0x000000ff, 0x0040, 60062306a36Sopenharmony_ci 0x34, 0x00000040, 0x00004040, 60162306a36Sopenharmony_ci 0x9100, 0x03e00000, 0x03600000, 60262306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 60362306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 60462306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x000000f1, 60562306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x00000000, 60662306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x00003210, 60762306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 60862306a36Sopenharmony_ci 0x15c0, 0x000c0fc0, 0x000c0400 60962306a36Sopenharmony_ci}; 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistatic const u32 hainan_golden_registers2[] = 61262306a36Sopenharmony_ci{ 61362306a36Sopenharmony_ci 0x98f8, 0xffffffff, 0x02010001 61462306a36Sopenharmony_ci}; 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic const u32 tahiti_mgcg_cgcg_init[] = 61762306a36Sopenharmony_ci{ 61862306a36Sopenharmony_ci 0xc400, 0xffffffff, 0xfffffffc, 61962306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 62062306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 62162306a36Sopenharmony_ci 0x92a4, 0xffffffff, 0x00000100, 62262306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 62362306a36Sopenharmony_ci 0x9774, 0xffffffff, 0x00000100, 62462306a36Sopenharmony_ci 0x8984, 0xffffffff, 0x06000100, 62562306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 62662306a36Sopenharmony_ci 0x92a0, 0xffffffff, 0x00000100, 62762306a36Sopenharmony_ci 0xc380, 0xffffffff, 0x00000100, 62862306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 62962306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 63062306a36Sopenharmony_ci 0x8d88, 0xffffffff, 0x00000100, 63162306a36Sopenharmony_ci 0x8d8c, 0xffffffff, 0x00000100, 63262306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 63362306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 63462306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 63562306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 63662306a36Sopenharmony_ci 0xad80, 0xffffffff, 0x00000100, 63762306a36Sopenharmony_ci 0xac54, 0xffffffff, 0x00000100, 63862306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 63962306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 64062306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 64162306a36Sopenharmony_ci 0xaf04, 0xffffffff, 0x00000100, 64262306a36Sopenharmony_ci 0xae04, 0xffffffff, 0x00000100, 64362306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 64462306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 64562306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00010000, 64662306a36Sopenharmony_ci 0x9164, 0xffffffff, 0x00030002, 64762306a36Sopenharmony_ci 0x9168, 0xffffffff, 0x00040007, 64862306a36Sopenharmony_ci 0x916c, 0xffffffff, 0x00060005, 64962306a36Sopenharmony_ci 0x9170, 0xffffffff, 0x00090008, 65062306a36Sopenharmony_ci 0x9174, 0xffffffff, 0x00020001, 65162306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00040003, 65262306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00000007, 65362306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00060005, 65462306a36Sopenharmony_ci 0x9184, 0xffffffff, 0x00090008, 65562306a36Sopenharmony_ci 0x9188, 0xffffffff, 0x00030002, 65662306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00050004, 65762306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00000008, 65862306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070006, 65962306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x000a0009, 66062306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00040003, 66162306a36Sopenharmony_ci 0x91a0, 0xffffffff, 0x00060005, 66262306a36Sopenharmony_ci 0x91a4, 0xffffffff, 0x00000009, 66362306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00080007, 66462306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x000b000a, 66562306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00050004, 66662306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00070006, 66762306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x0008000b, 66862306a36Sopenharmony_ci 0x91bc, 0xffffffff, 0x000a0009, 66962306a36Sopenharmony_ci 0x91c0, 0xffffffff, 0x000d000c, 67062306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00060005, 67162306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00080007, 67262306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x0000000b, 67362306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x000a0009, 67462306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x000d000c, 67562306a36Sopenharmony_ci 0x91d8, 0xffffffff, 0x00070006, 67662306a36Sopenharmony_ci 0x91dc, 0xffffffff, 0x00090008, 67762306a36Sopenharmony_ci 0x91e0, 0xffffffff, 0x0000000c, 67862306a36Sopenharmony_ci 0x91e4, 0xffffffff, 0x000b000a, 67962306a36Sopenharmony_ci 0x91e8, 0xffffffff, 0x000e000d, 68062306a36Sopenharmony_ci 0x91ec, 0xffffffff, 0x00080007, 68162306a36Sopenharmony_ci 0x91f0, 0xffffffff, 0x000a0009, 68262306a36Sopenharmony_ci 0x91f4, 0xffffffff, 0x0000000d, 68362306a36Sopenharmony_ci 0x91f8, 0xffffffff, 0x000c000b, 68462306a36Sopenharmony_ci 0x91fc, 0xffffffff, 0x000f000e, 68562306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00090008, 68662306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x000b000a, 68762306a36Sopenharmony_ci 0x9208, 0xffffffff, 0x000c000f, 68862306a36Sopenharmony_ci 0x920c, 0xffffffff, 0x000e000d, 68962306a36Sopenharmony_ci 0x9210, 0xffffffff, 0x00110010, 69062306a36Sopenharmony_ci 0x9214, 0xffffffff, 0x000a0009, 69162306a36Sopenharmony_ci 0x9218, 0xffffffff, 0x000c000b, 69262306a36Sopenharmony_ci 0x921c, 0xffffffff, 0x0000000f, 69362306a36Sopenharmony_ci 0x9220, 0xffffffff, 0x000e000d, 69462306a36Sopenharmony_ci 0x9224, 0xffffffff, 0x00110010, 69562306a36Sopenharmony_ci 0x9228, 0xffffffff, 0x000b000a, 69662306a36Sopenharmony_ci 0x922c, 0xffffffff, 0x000d000c, 69762306a36Sopenharmony_ci 0x9230, 0xffffffff, 0x00000010, 69862306a36Sopenharmony_ci 0x9234, 0xffffffff, 0x000f000e, 69962306a36Sopenharmony_ci 0x9238, 0xffffffff, 0x00120011, 70062306a36Sopenharmony_ci 0x923c, 0xffffffff, 0x000c000b, 70162306a36Sopenharmony_ci 0x9240, 0xffffffff, 0x000e000d, 70262306a36Sopenharmony_ci 0x9244, 0xffffffff, 0x00000011, 70362306a36Sopenharmony_ci 0x9248, 0xffffffff, 0x0010000f, 70462306a36Sopenharmony_ci 0x924c, 0xffffffff, 0x00130012, 70562306a36Sopenharmony_ci 0x9250, 0xffffffff, 0x000d000c, 70662306a36Sopenharmony_ci 0x9254, 0xffffffff, 0x000f000e, 70762306a36Sopenharmony_ci 0x9258, 0xffffffff, 0x00100013, 70862306a36Sopenharmony_ci 0x925c, 0xffffffff, 0x00120011, 70962306a36Sopenharmony_ci 0x9260, 0xffffffff, 0x00150014, 71062306a36Sopenharmony_ci 0x9264, 0xffffffff, 0x000e000d, 71162306a36Sopenharmony_ci 0x9268, 0xffffffff, 0x0010000f, 71262306a36Sopenharmony_ci 0x926c, 0xffffffff, 0x00000013, 71362306a36Sopenharmony_ci 0x9270, 0xffffffff, 0x00120011, 71462306a36Sopenharmony_ci 0x9274, 0xffffffff, 0x00150014, 71562306a36Sopenharmony_ci 0x9278, 0xffffffff, 0x000f000e, 71662306a36Sopenharmony_ci 0x927c, 0xffffffff, 0x00110010, 71762306a36Sopenharmony_ci 0x9280, 0xffffffff, 0x00000014, 71862306a36Sopenharmony_ci 0x9284, 0xffffffff, 0x00130012, 71962306a36Sopenharmony_ci 0x9288, 0xffffffff, 0x00160015, 72062306a36Sopenharmony_ci 0x928c, 0xffffffff, 0x0010000f, 72162306a36Sopenharmony_ci 0x9290, 0xffffffff, 0x00120011, 72262306a36Sopenharmony_ci 0x9294, 0xffffffff, 0x00000015, 72362306a36Sopenharmony_ci 0x9298, 0xffffffff, 0x00140013, 72462306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00170016, 72562306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x96940200, 72662306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 72762306a36Sopenharmony_ci 0xc478, 0xffffffff, 0x00000080, 72862306a36Sopenharmony_ci 0xc404, 0xffffffff, 0x0020003f, 72962306a36Sopenharmony_ci 0x30, 0xffffffff, 0x0000001c, 73062306a36Sopenharmony_ci 0x34, 0x000f0000, 0x000f0000, 73162306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 73262306a36Sopenharmony_ci 0x1024, 0xffffffff, 0x00000100, 73362306a36Sopenharmony_ci 0x102c, 0x00000101, 0x00000000, 73462306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 73562306a36Sopenharmony_ci 0x264c, 0x000c0000, 0x000c0000, 73662306a36Sopenharmony_ci 0x2648, 0x000c0000, 0x000c0000, 73762306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 73862306a36Sopenharmony_ci 0x55e8, 0x00000001, 0x00000001, 73962306a36Sopenharmony_ci 0x2f50, 0x00000001, 0x00000001, 74062306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 74162306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 74262306a36Sopenharmony_ci 0xd0c0, 0xfffffff0, 0x00000100, 74362306a36Sopenharmony_ci 0xd8c0, 0xfffffff0, 0x00000100 74462306a36Sopenharmony_ci}; 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_cistatic const u32 pitcairn_mgcg_cgcg_init[] = 74762306a36Sopenharmony_ci{ 74862306a36Sopenharmony_ci 0xc400, 0xffffffff, 0xfffffffc, 74962306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 75062306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 75162306a36Sopenharmony_ci 0x92a4, 0xffffffff, 0x00000100, 75262306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 75362306a36Sopenharmony_ci 0x9774, 0xffffffff, 0x00000100, 75462306a36Sopenharmony_ci 0x8984, 0xffffffff, 0x06000100, 75562306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 75662306a36Sopenharmony_ci 0x92a0, 0xffffffff, 0x00000100, 75762306a36Sopenharmony_ci 0xc380, 0xffffffff, 0x00000100, 75862306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 75962306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 76062306a36Sopenharmony_ci 0x8d88, 0xffffffff, 0x00000100, 76162306a36Sopenharmony_ci 0x8d8c, 0xffffffff, 0x00000100, 76262306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 76362306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 76462306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 76562306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 76662306a36Sopenharmony_ci 0xad80, 0xffffffff, 0x00000100, 76762306a36Sopenharmony_ci 0xac54, 0xffffffff, 0x00000100, 76862306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 76962306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 77062306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 77162306a36Sopenharmony_ci 0xaf04, 0xffffffff, 0x00000100, 77262306a36Sopenharmony_ci 0xae04, 0xffffffff, 0x00000100, 77362306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 77462306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 77562306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00010000, 77662306a36Sopenharmony_ci 0x9164, 0xffffffff, 0x00030002, 77762306a36Sopenharmony_ci 0x9168, 0xffffffff, 0x00040007, 77862306a36Sopenharmony_ci 0x916c, 0xffffffff, 0x00060005, 77962306a36Sopenharmony_ci 0x9170, 0xffffffff, 0x00090008, 78062306a36Sopenharmony_ci 0x9174, 0xffffffff, 0x00020001, 78162306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00040003, 78262306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00000007, 78362306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00060005, 78462306a36Sopenharmony_ci 0x9184, 0xffffffff, 0x00090008, 78562306a36Sopenharmony_ci 0x9188, 0xffffffff, 0x00030002, 78662306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00050004, 78762306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00000008, 78862306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070006, 78962306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x000a0009, 79062306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00040003, 79162306a36Sopenharmony_ci 0x91a0, 0xffffffff, 0x00060005, 79262306a36Sopenharmony_ci 0x91a4, 0xffffffff, 0x00000009, 79362306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00080007, 79462306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x000b000a, 79562306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00050004, 79662306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00070006, 79762306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x0008000b, 79862306a36Sopenharmony_ci 0x91bc, 0xffffffff, 0x000a0009, 79962306a36Sopenharmony_ci 0x91c0, 0xffffffff, 0x000d000c, 80062306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00090008, 80162306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x000b000a, 80262306a36Sopenharmony_ci 0x9208, 0xffffffff, 0x000c000f, 80362306a36Sopenharmony_ci 0x920c, 0xffffffff, 0x000e000d, 80462306a36Sopenharmony_ci 0x9210, 0xffffffff, 0x00110010, 80562306a36Sopenharmony_ci 0x9214, 0xffffffff, 0x000a0009, 80662306a36Sopenharmony_ci 0x9218, 0xffffffff, 0x000c000b, 80762306a36Sopenharmony_ci 0x921c, 0xffffffff, 0x0000000f, 80862306a36Sopenharmony_ci 0x9220, 0xffffffff, 0x000e000d, 80962306a36Sopenharmony_ci 0x9224, 0xffffffff, 0x00110010, 81062306a36Sopenharmony_ci 0x9228, 0xffffffff, 0x000b000a, 81162306a36Sopenharmony_ci 0x922c, 0xffffffff, 0x000d000c, 81262306a36Sopenharmony_ci 0x9230, 0xffffffff, 0x00000010, 81362306a36Sopenharmony_ci 0x9234, 0xffffffff, 0x000f000e, 81462306a36Sopenharmony_ci 0x9238, 0xffffffff, 0x00120011, 81562306a36Sopenharmony_ci 0x923c, 0xffffffff, 0x000c000b, 81662306a36Sopenharmony_ci 0x9240, 0xffffffff, 0x000e000d, 81762306a36Sopenharmony_ci 0x9244, 0xffffffff, 0x00000011, 81862306a36Sopenharmony_ci 0x9248, 0xffffffff, 0x0010000f, 81962306a36Sopenharmony_ci 0x924c, 0xffffffff, 0x00130012, 82062306a36Sopenharmony_ci 0x9250, 0xffffffff, 0x000d000c, 82162306a36Sopenharmony_ci 0x9254, 0xffffffff, 0x000f000e, 82262306a36Sopenharmony_ci 0x9258, 0xffffffff, 0x00100013, 82362306a36Sopenharmony_ci 0x925c, 0xffffffff, 0x00120011, 82462306a36Sopenharmony_ci 0x9260, 0xffffffff, 0x00150014, 82562306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x96940200, 82662306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 82762306a36Sopenharmony_ci 0xc478, 0xffffffff, 0x00000080, 82862306a36Sopenharmony_ci 0xc404, 0xffffffff, 0x0020003f, 82962306a36Sopenharmony_ci 0x30, 0xffffffff, 0x0000001c, 83062306a36Sopenharmony_ci 0x34, 0x000f0000, 0x000f0000, 83162306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 83262306a36Sopenharmony_ci 0x1024, 0xffffffff, 0x00000100, 83362306a36Sopenharmony_ci 0x102c, 0x00000101, 0x00000000, 83462306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 83562306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 83662306a36Sopenharmony_ci 0x55e8, 0x00000001, 0x00000001, 83762306a36Sopenharmony_ci 0x2f50, 0x00000001, 0x00000001, 83862306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 83962306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 84062306a36Sopenharmony_ci 0xd0c0, 0xfffffff0, 0x00000100, 84162306a36Sopenharmony_ci 0xd8c0, 0xfffffff0, 0x00000100 84262306a36Sopenharmony_ci}; 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_cistatic const u32 verde_mgcg_cgcg_init[] = 84562306a36Sopenharmony_ci{ 84662306a36Sopenharmony_ci 0xc400, 0xffffffff, 0xfffffffc, 84762306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 84862306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 84962306a36Sopenharmony_ci 0x92a4, 0xffffffff, 0x00000100, 85062306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 85162306a36Sopenharmony_ci 0x9774, 0xffffffff, 0x00000100, 85262306a36Sopenharmony_ci 0x8984, 0xffffffff, 0x06000100, 85362306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 85462306a36Sopenharmony_ci 0x92a0, 0xffffffff, 0x00000100, 85562306a36Sopenharmony_ci 0xc380, 0xffffffff, 0x00000100, 85662306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 85762306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 85862306a36Sopenharmony_ci 0x8d88, 0xffffffff, 0x00000100, 85962306a36Sopenharmony_ci 0x8d8c, 0xffffffff, 0x00000100, 86062306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 86162306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 86262306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 86362306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 86462306a36Sopenharmony_ci 0xad80, 0xffffffff, 0x00000100, 86562306a36Sopenharmony_ci 0xac54, 0xffffffff, 0x00000100, 86662306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 86762306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 86862306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 86962306a36Sopenharmony_ci 0xaf04, 0xffffffff, 0x00000100, 87062306a36Sopenharmony_ci 0xae04, 0xffffffff, 0x00000100, 87162306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 87262306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 87362306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00010000, 87462306a36Sopenharmony_ci 0x9164, 0xffffffff, 0x00030002, 87562306a36Sopenharmony_ci 0x9168, 0xffffffff, 0x00040007, 87662306a36Sopenharmony_ci 0x916c, 0xffffffff, 0x00060005, 87762306a36Sopenharmony_ci 0x9170, 0xffffffff, 0x00090008, 87862306a36Sopenharmony_ci 0x9174, 0xffffffff, 0x00020001, 87962306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00040003, 88062306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00000007, 88162306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00060005, 88262306a36Sopenharmony_ci 0x9184, 0xffffffff, 0x00090008, 88362306a36Sopenharmony_ci 0x9188, 0xffffffff, 0x00030002, 88462306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00050004, 88562306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00000008, 88662306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070006, 88762306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x000a0009, 88862306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00040003, 88962306a36Sopenharmony_ci 0x91a0, 0xffffffff, 0x00060005, 89062306a36Sopenharmony_ci 0x91a4, 0xffffffff, 0x00000009, 89162306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00080007, 89262306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x000b000a, 89362306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00050004, 89462306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00070006, 89562306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x0008000b, 89662306a36Sopenharmony_ci 0x91bc, 0xffffffff, 0x000a0009, 89762306a36Sopenharmony_ci 0x91c0, 0xffffffff, 0x000d000c, 89862306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00090008, 89962306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x000b000a, 90062306a36Sopenharmony_ci 0x9208, 0xffffffff, 0x000c000f, 90162306a36Sopenharmony_ci 0x920c, 0xffffffff, 0x000e000d, 90262306a36Sopenharmony_ci 0x9210, 0xffffffff, 0x00110010, 90362306a36Sopenharmony_ci 0x9214, 0xffffffff, 0x000a0009, 90462306a36Sopenharmony_ci 0x9218, 0xffffffff, 0x000c000b, 90562306a36Sopenharmony_ci 0x921c, 0xffffffff, 0x0000000f, 90662306a36Sopenharmony_ci 0x9220, 0xffffffff, 0x000e000d, 90762306a36Sopenharmony_ci 0x9224, 0xffffffff, 0x00110010, 90862306a36Sopenharmony_ci 0x9228, 0xffffffff, 0x000b000a, 90962306a36Sopenharmony_ci 0x922c, 0xffffffff, 0x000d000c, 91062306a36Sopenharmony_ci 0x9230, 0xffffffff, 0x00000010, 91162306a36Sopenharmony_ci 0x9234, 0xffffffff, 0x000f000e, 91262306a36Sopenharmony_ci 0x9238, 0xffffffff, 0x00120011, 91362306a36Sopenharmony_ci 0x923c, 0xffffffff, 0x000c000b, 91462306a36Sopenharmony_ci 0x9240, 0xffffffff, 0x000e000d, 91562306a36Sopenharmony_ci 0x9244, 0xffffffff, 0x00000011, 91662306a36Sopenharmony_ci 0x9248, 0xffffffff, 0x0010000f, 91762306a36Sopenharmony_ci 0x924c, 0xffffffff, 0x00130012, 91862306a36Sopenharmony_ci 0x9250, 0xffffffff, 0x000d000c, 91962306a36Sopenharmony_ci 0x9254, 0xffffffff, 0x000f000e, 92062306a36Sopenharmony_ci 0x9258, 0xffffffff, 0x00100013, 92162306a36Sopenharmony_ci 0x925c, 0xffffffff, 0x00120011, 92262306a36Sopenharmony_ci 0x9260, 0xffffffff, 0x00150014, 92362306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x96940200, 92462306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 92562306a36Sopenharmony_ci 0xc478, 0xffffffff, 0x00000080, 92662306a36Sopenharmony_ci 0xc404, 0xffffffff, 0x0020003f, 92762306a36Sopenharmony_ci 0x30, 0xffffffff, 0x0000001c, 92862306a36Sopenharmony_ci 0x34, 0x000f0000, 0x000f0000, 92962306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 93062306a36Sopenharmony_ci 0x1024, 0xffffffff, 0x00000100, 93162306a36Sopenharmony_ci 0x102c, 0x00000101, 0x00000000, 93262306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 93362306a36Sopenharmony_ci 0x264c, 0x000c0000, 0x000c0000, 93462306a36Sopenharmony_ci 0x2648, 0x000c0000, 0x000c0000, 93562306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 93662306a36Sopenharmony_ci 0x55e8, 0x00000001, 0x00000001, 93762306a36Sopenharmony_ci 0x2f50, 0x00000001, 0x00000001, 93862306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 93962306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 94062306a36Sopenharmony_ci 0xd0c0, 0xfffffff0, 0x00000100, 94162306a36Sopenharmony_ci 0xd8c0, 0xfffffff0, 0x00000100 94262306a36Sopenharmony_ci}; 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_cistatic const u32 oland_mgcg_cgcg_init[] = 94562306a36Sopenharmony_ci{ 94662306a36Sopenharmony_ci 0xc400, 0xffffffff, 0xfffffffc, 94762306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 94862306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 94962306a36Sopenharmony_ci 0x92a4, 0xffffffff, 0x00000100, 95062306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 95162306a36Sopenharmony_ci 0x9774, 0xffffffff, 0x00000100, 95262306a36Sopenharmony_ci 0x8984, 0xffffffff, 0x06000100, 95362306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 95462306a36Sopenharmony_ci 0x92a0, 0xffffffff, 0x00000100, 95562306a36Sopenharmony_ci 0xc380, 0xffffffff, 0x00000100, 95662306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 95762306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 95862306a36Sopenharmony_ci 0x8d88, 0xffffffff, 0x00000100, 95962306a36Sopenharmony_ci 0x8d8c, 0xffffffff, 0x00000100, 96062306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 96162306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 96262306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 96362306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 96462306a36Sopenharmony_ci 0xad80, 0xffffffff, 0x00000100, 96562306a36Sopenharmony_ci 0xac54, 0xffffffff, 0x00000100, 96662306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 96762306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 96862306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 96962306a36Sopenharmony_ci 0xaf04, 0xffffffff, 0x00000100, 97062306a36Sopenharmony_ci 0xae04, 0xffffffff, 0x00000100, 97162306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 97262306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 97362306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00010000, 97462306a36Sopenharmony_ci 0x9164, 0xffffffff, 0x00030002, 97562306a36Sopenharmony_ci 0x9168, 0xffffffff, 0x00040007, 97662306a36Sopenharmony_ci 0x916c, 0xffffffff, 0x00060005, 97762306a36Sopenharmony_ci 0x9170, 0xffffffff, 0x00090008, 97862306a36Sopenharmony_ci 0x9174, 0xffffffff, 0x00020001, 97962306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00040003, 98062306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00000007, 98162306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00060005, 98262306a36Sopenharmony_ci 0x9184, 0xffffffff, 0x00090008, 98362306a36Sopenharmony_ci 0x9188, 0xffffffff, 0x00030002, 98462306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00050004, 98562306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00000008, 98662306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070006, 98762306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x000a0009, 98862306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00040003, 98962306a36Sopenharmony_ci 0x91a0, 0xffffffff, 0x00060005, 99062306a36Sopenharmony_ci 0x91a4, 0xffffffff, 0x00000009, 99162306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00080007, 99262306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x000b000a, 99362306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00050004, 99462306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00070006, 99562306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x0008000b, 99662306a36Sopenharmony_ci 0x91bc, 0xffffffff, 0x000a0009, 99762306a36Sopenharmony_ci 0x91c0, 0xffffffff, 0x000d000c, 99862306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00060005, 99962306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00080007, 100062306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x0000000b, 100162306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x000a0009, 100262306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x000d000c, 100362306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x96940200, 100462306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 100562306a36Sopenharmony_ci 0xc478, 0xffffffff, 0x00000080, 100662306a36Sopenharmony_ci 0xc404, 0xffffffff, 0x0020003f, 100762306a36Sopenharmony_ci 0x30, 0xffffffff, 0x0000001c, 100862306a36Sopenharmony_ci 0x34, 0x000f0000, 0x000f0000, 100962306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 101062306a36Sopenharmony_ci 0x1024, 0xffffffff, 0x00000100, 101162306a36Sopenharmony_ci 0x102c, 0x00000101, 0x00000000, 101262306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 101362306a36Sopenharmony_ci 0x264c, 0x000c0000, 0x000c0000, 101462306a36Sopenharmony_ci 0x2648, 0x000c0000, 0x000c0000, 101562306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 101662306a36Sopenharmony_ci 0x55e8, 0x00000001, 0x00000001, 101762306a36Sopenharmony_ci 0x2f50, 0x00000001, 0x00000001, 101862306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 101962306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 102062306a36Sopenharmony_ci 0xd0c0, 0xfffffff0, 0x00000100, 102162306a36Sopenharmony_ci 0xd8c0, 0xfffffff0, 0x00000100 102262306a36Sopenharmony_ci}; 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_cistatic const u32 hainan_mgcg_cgcg_init[] = 102562306a36Sopenharmony_ci{ 102662306a36Sopenharmony_ci 0xc400, 0xffffffff, 0xfffffffc, 102762306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 102862306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 102962306a36Sopenharmony_ci 0x92a4, 0xffffffff, 0x00000100, 103062306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 103162306a36Sopenharmony_ci 0x9774, 0xffffffff, 0x00000100, 103262306a36Sopenharmony_ci 0x8984, 0xffffffff, 0x06000100, 103362306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 103462306a36Sopenharmony_ci 0x92a0, 0xffffffff, 0x00000100, 103562306a36Sopenharmony_ci 0xc380, 0xffffffff, 0x00000100, 103662306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 103762306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 103862306a36Sopenharmony_ci 0x8d88, 0xffffffff, 0x00000100, 103962306a36Sopenharmony_ci 0x8d8c, 0xffffffff, 0x00000100, 104062306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 104162306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 104262306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 104362306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 104462306a36Sopenharmony_ci 0xad80, 0xffffffff, 0x00000100, 104562306a36Sopenharmony_ci 0xac54, 0xffffffff, 0x00000100, 104662306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 104762306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 104862306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 104962306a36Sopenharmony_ci 0xaf04, 0xffffffff, 0x00000100, 105062306a36Sopenharmony_ci 0xae04, 0xffffffff, 0x00000100, 105162306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 105262306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xe0000000, 105362306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00010000, 105462306a36Sopenharmony_ci 0x9164, 0xffffffff, 0x00030002, 105562306a36Sopenharmony_ci 0x9168, 0xffffffff, 0x00040007, 105662306a36Sopenharmony_ci 0x916c, 0xffffffff, 0x00060005, 105762306a36Sopenharmony_ci 0x9170, 0xffffffff, 0x00090008, 105862306a36Sopenharmony_ci 0x9174, 0xffffffff, 0x00020001, 105962306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00040003, 106062306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00000007, 106162306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00060005, 106262306a36Sopenharmony_ci 0x9184, 0xffffffff, 0x00090008, 106362306a36Sopenharmony_ci 0x9188, 0xffffffff, 0x00030002, 106462306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00050004, 106562306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00000008, 106662306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070006, 106762306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x000a0009, 106862306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00040003, 106962306a36Sopenharmony_ci 0x91a0, 0xffffffff, 0x00060005, 107062306a36Sopenharmony_ci 0x91a4, 0xffffffff, 0x00000009, 107162306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00080007, 107262306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x000b000a, 107362306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00050004, 107462306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00070006, 107562306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x0008000b, 107662306a36Sopenharmony_ci 0x91bc, 0xffffffff, 0x000a0009, 107762306a36Sopenharmony_ci 0x91c0, 0xffffffff, 0x000d000c, 107862306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00060005, 107962306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00080007, 108062306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x0000000b, 108162306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x000a0009, 108262306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x000d000c, 108362306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x96940200, 108462306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 108562306a36Sopenharmony_ci 0xc478, 0xffffffff, 0x00000080, 108662306a36Sopenharmony_ci 0xc404, 0xffffffff, 0x0020003f, 108762306a36Sopenharmony_ci 0x30, 0xffffffff, 0x0000001c, 108862306a36Sopenharmony_ci 0x34, 0x000f0000, 0x000f0000, 108962306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 109062306a36Sopenharmony_ci 0x1024, 0xffffffff, 0x00000100, 109162306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 109262306a36Sopenharmony_ci 0x264c, 0x000c0000, 0x000c0000, 109362306a36Sopenharmony_ci 0x2648, 0x000c0000, 0x000c0000, 109462306a36Sopenharmony_ci 0x2f50, 0x00000001, 0x00000001, 109562306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 109662306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 109762306a36Sopenharmony_ci 0xd0c0, 0xfffffff0, 0x00000100, 109862306a36Sopenharmony_ci 0xd8c0, 0xfffffff0, 0x00000100 109962306a36Sopenharmony_ci}; 110062306a36Sopenharmony_ci 110162306a36Sopenharmony_cistatic u32 verde_pg_init[] = 110262306a36Sopenharmony_ci{ 110362306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x40000, 110462306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x200010ff, 110562306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 110662306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 110762306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 110862306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 110962306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 111062306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x7007, 111162306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x300010ff, 111262306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 111362306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 111462306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 111562306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 111662306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 111762306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x400000, 111862306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x100010ff, 111962306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112062306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112162306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112262306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112362306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112462306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x120200, 112562306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x500010ff, 112662306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112762306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112862306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 112962306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113062306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113162306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x1e1e16, 113262306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x600010ff, 113362306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113462306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113562306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113662306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113762306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 113862306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x171f1e, 113962306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x700010ff, 114062306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 114162306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 114262306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 114362306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 114462306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 114562306a36Sopenharmony_ci 0x353c, 0xffffffff, 0x0, 114662306a36Sopenharmony_ci 0x3538, 0xffffffff, 0x9ff, 114762306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x0, 114862306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x10000800, 114962306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xf, 115062306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xf, 115162306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x4, 115262306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1000051e, 115362306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xffff, 115462306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xffff, 115562306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x8, 115662306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x80500, 115762306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x12, 115862306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x9050c, 115962306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x1d, 116062306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xb052c, 116162306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x2a, 116262306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1053e, 116362306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x2d, 116462306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x10546, 116562306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x30, 116662306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xa054e, 116762306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x3c, 116862306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1055f, 116962306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x3f, 117062306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x10567, 117162306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x42, 117262306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1056f, 117362306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x45, 117462306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x10572, 117562306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x48, 117662306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x20575, 117762306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x4c, 117862306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x190801, 117962306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x67, 118062306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1082a, 118162306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x6a, 118262306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1b082d, 118362306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x87, 118462306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x310851, 118562306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xba, 118662306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x891, 118762306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xbc, 118862306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x893, 118962306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xbe, 119062306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x20895, 119162306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xc2, 119262306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x20899, 119362306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xc6, 119462306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x2089d, 119562306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xca, 119662306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x8a1, 119762306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xcc, 119862306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x8a3, 119962306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xce, 120062306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x308a5, 120162306a36Sopenharmony_ci 0x3500, 0xffffffff, 0xd3, 120262306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x6d08cd, 120362306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x142, 120462306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x2000095a, 120562306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x1, 120662306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x144, 120762306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x301f095b, 120862306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x165, 120962306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xc094d, 121062306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x173, 121162306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xf096d, 121262306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x184, 121362306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x15097f, 121462306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x19b, 121562306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xc0998, 121662306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x1a9, 121762306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x409a7, 121862306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x1af, 121962306a36Sopenharmony_ci 0x3504, 0xffffffff, 0xcdc, 122062306a36Sopenharmony_ci 0x3500, 0xffffffff, 0x1b1, 122162306a36Sopenharmony_ci 0x3504, 0xffffffff, 0x800, 122262306a36Sopenharmony_ci 0x3508, 0xffffffff, 0x6c9b2000, 122362306a36Sopenharmony_ci 0x3510, 0xfc00, 0x2000, 122462306a36Sopenharmony_ci 0x3544, 0xffffffff, 0xfc0, 122562306a36Sopenharmony_ci 0x28d4, 0x00000100, 0x100 122662306a36Sopenharmony_ci}; 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_cistatic void si_init_golden_registers(struct radeon_device *rdev) 122962306a36Sopenharmony_ci{ 123062306a36Sopenharmony_ci switch (rdev->family) { 123162306a36Sopenharmony_ci case CHIP_TAHITI: 123262306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 123362306a36Sopenharmony_ci tahiti_golden_registers, 123462306a36Sopenharmony_ci (const u32)ARRAY_SIZE(tahiti_golden_registers)); 123562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 123662306a36Sopenharmony_ci tahiti_golden_rlc_registers, 123762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(tahiti_golden_rlc_registers)); 123862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 123962306a36Sopenharmony_ci tahiti_mgcg_cgcg_init, 124062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(tahiti_mgcg_cgcg_init)); 124162306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 124262306a36Sopenharmony_ci tahiti_golden_registers2, 124362306a36Sopenharmony_ci (const u32)ARRAY_SIZE(tahiti_golden_registers2)); 124462306a36Sopenharmony_ci break; 124562306a36Sopenharmony_ci case CHIP_PITCAIRN: 124662306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 124762306a36Sopenharmony_ci pitcairn_golden_registers, 124862306a36Sopenharmony_ci (const u32)ARRAY_SIZE(pitcairn_golden_registers)); 124962306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 125062306a36Sopenharmony_ci pitcairn_golden_rlc_registers, 125162306a36Sopenharmony_ci (const u32)ARRAY_SIZE(pitcairn_golden_rlc_registers)); 125262306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 125362306a36Sopenharmony_ci pitcairn_mgcg_cgcg_init, 125462306a36Sopenharmony_ci (const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init)); 125562306a36Sopenharmony_ci break; 125662306a36Sopenharmony_ci case CHIP_VERDE: 125762306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 125862306a36Sopenharmony_ci verde_golden_registers, 125962306a36Sopenharmony_ci (const u32)ARRAY_SIZE(verde_golden_registers)); 126062306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 126162306a36Sopenharmony_ci verde_golden_rlc_registers, 126262306a36Sopenharmony_ci (const u32)ARRAY_SIZE(verde_golden_rlc_registers)); 126362306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 126462306a36Sopenharmony_ci verde_mgcg_cgcg_init, 126562306a36Sopenharmony_ci (const u32)ARRAY_SIZE(verde_mgcg_cgcg_init)); 126662306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 126762306a36Sopenharmony_ci verde_pg_init, 126862306a36Sopenharmony_ci (const u32)ARRAY_SIZE(verde_pg_init)); 126962306a36Sopenharmony_ci break; 127062306a36Sopenharmony_ci case CHIP_OLAND: 127162306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 127262306a36Sopenharmony_ci oland_golden_registers, 127362306a36Sopenharmony_ci (const u32)ARRAY_SIZE(oland_golden_registers)); 127462306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 127562306a36Sopenharmony_ci oland_golden_rlc_registers, 127662306a36Sopenharmony_ci (const u32)ARRAY_SIZE(oland_golden_rlc_registers)); 127762306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 127862306a36Sopenharmony_ci oland_mgcg_cgcg_init, 127962306a36Sopenharmony_ci (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init)); 128062306a36Sopenharmony_ci break; 128162306a36Sopenharmony_ci case CHIP_HAINAN: 128262306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 128362306a36Sopenharmony_ci hainan_golden_registers, 128462306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hainan_golden_registers)); 128562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 128662306a36Sopenharmony_ci hainan_golden_registers2, 128762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hainan_golden_registers2)); 128862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 128962306a36Sopenharmony_ci hainan_mgcg_cgcg_init, 129062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init)); 129162306a36Sopenharmony_ci break; 129262306a36Sopenharmony_ci default: 129362306a36Sopenharmony_ci break; 129462306a36Sopenharmony_ci } 129562306a36Sopenharmony_ci} 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci/** 129862306a36Sopenharmony_ci * si_get_allowed_info_register - fetch the register for the info ioctl 129962306a36Sopenharmony_ci * 130062306a36Sopenharmony_ci * @rdev: radeon_device pointer 130162306a36Sopenharmony_ci * @reg: register offset in bytes 130262306a36Sopenharmony_ci * @val: register value 130362306a36Sopenharmony_ci * 130462306a36Sopenharmony_ci * Returns 0 for success or -EINVAL for an invalid register 130562306a36Sopenharmony_ci * 130662306a36Sopenharmony_ci */ 130762306a36Sopenharmony_ciint si_get_allowed_info_register(struct radeon_device *rdev, 130862306a36Sopenharmony_ci u32 reg, u32 *val) 130962306a36Sopenharmony_ci{ 131062306a36Sopenharmony_ci switch (reg) { 131162306a36Sopenharmony_ci case GRBM_STATUS: 131262306a36Sopenharmony_ci case GRBM_STATUS2: 131362306a36Sopenharmony_ci case GRBM_STATUS_SE0: 131462306a36Sopenharmony_ci case GRBM_STATUS_SE1: 131562306a36Sopenharmony_ci case SRBM_STATUS: 131662306a36Sopenharmony_ci case SRBM_STATUS2: 131762306a36Sopenharmony_ci case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET): 131862306a36Sopenharmony_ci case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET): 131962306a36Sopenharmony_ci case UVD_STATUS: 132062306a36Sopenharmony_ci *val = RREG32(reg); 132162306a36Sopenharmony_ci return 0; 132262306a36Sopenharmony_ci default: 132362306a36Sopenharmony_ci return -EINVAL; 132462306a36Sopenharmony_ci } 132562306a36Sopenharmony_ci} 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci#define PCIE_BUS_CLK 10000 132862306a36Sopenharmony_ci#define TCLK (PCIE_BUS_CLK / 10) 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_ci/** 133162306a36Sopenharmony_ci * si_get_xclk - get the xclk 133262306a36Sopenharmony_ci * 133362306a36Sopenharmony_ci * @rdev: radeon_device pointer 133462306a36Sopenharmony_ci * 133562306a36Sopenharmony_ci * Returns the reference clock used by the gfx engine 133662306a36Sopenharmony_ci * (SI). 133762306a36Sopenharmony_ci */ 133862306a36Sopenharmony_ciu32 si_get_xclk(struct radeon_device *rdev) 133962306a36Sopenharmony_ci{ 134062306a36Sopenharmony_ci u32 reference_clock = rdev->clock.spll.reference_freq; 134162306a36Sopenharmony_ci u32 tmp; 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_ci tmp = RREG32(CG_CLKPIN_CNTL_2); 134462306a36Sopenharmony_ci if (tmp & MUX_TCLK_TO_XCLK) 134562306a36Sopenharmony_ci return TCLK; 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci tmp = RREG32(CG_CLKPIN_CNTL); 134862306a36Sopenharmony_ci if (tmp & XTALIN_DIVIDE) 134962306a36Sopenharmony_ci return reference_clock / 4; 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci return reference_clock; 135262306a36Sopenharmony_ci} 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci/* get temperature in millidegrees */ 135562306a36Sopenharmony_ciint si_get_temp(struct radeon_device *rdev) 135662306a36Sopenharmony_ci{ 135762306a36Sopenharmony_ci u32 temp; 135862306a36Sopenharmony_ci int actual_temp = 0; 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >> 136162306a36Sopenharmony_ci CTF_TEMP_SHIFT; 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_ci if (temp & 0x200) 136462306a36Sopenharmony_ci actual_temp = 255; 136562306a36Sopenharmony_ci else 136662306a36Sopenharmony_ci actual_temp = temp & 0x1ff; 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci actual_temp = (actual_temp * 1000); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci return actual_temp; 137162306a36Sopenharmony_ci} 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci#define TAHITI_IO_MC_REGS_SIZE 36 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_cistatic const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { 137662306a36Sopenharmony_ci {0x0000006f, 0x03044000}, 137762306a36Sopenharmony_ci {0x00000070, 0x0480c018}, 137862306a36Sopenharmony_ci {0x00000071, 0x00000040}, 137962306a36Sopenharmony_ci {0x00000072, 0x01000000}, 138062306a36Sopenharmony_ci {0x00000074, 0x000000ff}, 138162306a36Sopenharmony_ci {0x00000075, 0x00143400}, 138262306a36Sopenharmony_ci {0x00000076, 0x08ec0800}, 138362306a36Sopenharmony_ci {0x00000077, 0x040000cc}, 138462306a36Sopenharmony_ci {0x00000079, 0x00000000}, 138562306a36Sopenharmony_ci {0x0000007a, 0x21000409}, 138662306a36Sopenharmony_ci {0x0000007c, 0x00000000}, 138762306a36Sopenharmony_ci {0x0000007d, 0xe8000000}, 138862306a36Sopenharmony_ci {0x0000007e, 0x044408a8}, 138962306a36Sopenharmony_ci {0x0000007f, 0x00000003}, 139062306a36Sopenharmony_ci {0x00000080, 0x00000000}, 139162306a36Sopenharmony_ci {0x00000081, 0x01000000}, 139262306a36Sopenharmony_ci {0x00000082, 0x02000000}, 139362306a36Sopenharmony_ci {0x00000083, 0x00000000}, 139462306a36Sopenharmony_ci {0x00000084, 0xe3f3e4f4}, 139562306a36Sopenharmony_ci {0x00000085, 0x00052024}, 139662306a36Sopenharmony_ci {0x00000087, 0x00000000}, 139762306a36Sopenharmony_ci {0x00000088, 0x66036603}, 139862306a36Sopenharmony_ci {0x00000089, 0x01000000}, 139962306a36Sopenharmony_ci {0x0000008b, 0x1c0a0000}, 140062306a36Sopenharmony_ci {0x0000008c, 0xff010000}, 140162306a36Sopenharmony_ci {0x0000008e, 0xffffefff}, 140262306a36Sopenharmony_ci {0x0000008f, 0xfff3efff}, 140362306a36Sopenharmony_ci {0x00000090, 0xfff3efbf}, 140462306a36Sopenharmony_ci {0x00000094, 0x00101101}, 140562306a36Sopenharmony_ci {0x00000095, 0x00000fff}, 140662306a36Sopenharmony_ci {0x00000096, 0x00116fff}, 140762306a36Sopenharmony_ci {0x00000097, 0x60010000}, 140862306a36Sopenharmony_ci {0x00000098, 0x10010000}, 140962306a36Sopenharmony_ci {0x00000099, 0x00006000}, 141062306a36Sopenharmony_ci {0x0000009a, 0x00001000}, 141162306a36Sopenharmony_ci {0x0000009f, 0x00a77400} 141262306a36Sopenharmony_ci}; 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_cistatic const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { 141562306a36Sopenharmony_ci {0x0000006f, 0x03044000}, 141662306a36Sopenharmony_ci {0x00000070, 0x0480c018}, 141762306a36Sopenharmony_ci {0x00000071, 0x00000040}, 141862306a36Sopenharmony_ci {0x00000072, 0x01000000}, 141962306a36Sopenharmony_ci {0x00000074, 0x000000ff}, 142062306a36Sopenharmony_ci {0x00000075, 0x00143400}, 142162306a36Sopenharmony_ci {0x00000076, 0x08ec0800}, 142262306a36Sopenharmony_ci {0x00000077, 0x040000cc}, 142362306a36Sopenharmony_ci {0x00000079, 0x00000000}, 142462306a36Sopenharmony_ci {0x0000007a, 0x21000409}, 142562306a36Sopenharmony_ci {0x0000007c, 0x00000000}, 142662306a36Sopenharmony_ci {0x0000007d, 0xe8000000}, 142762306a36Sopenharmony_ci {0x0000007e, 0x044408a8}, 142862306a36Sopenharmony_ci {0x0000007f, 0x00000003}, 142962306a36Sopenharmony_ci {0x00000080, 0x00000000}, 143062306a36Sopenharmony_ci {0x00000081, 0x01000000}, 143162306a36Sopenharmony_ci {0x00000082, 0x02000000}, 143262306a36Sopenharmony_ci {0x00000083, 0x00000000}, 143362306a36Sopenharmony_ci {0x00000084, 0xe3f3e4f4}, 143462306a36Sopenharmony_ci {0x00000085, 0x00052024}, 143562306a36Sopenharmony_ci {0x00000087, 0x00000000}, 143662306a36Sopenharmony_ci {0x00000088, 0x66036603}, 143762306a36Sopenharmony_ci {0x00000089, 0x01000000}, 143862306a36Sopenharmony_ci {0x0000008b, 0x1c0a0000}, 143962306a36Sopenharmony_ci {0x0000008c, 0xff010000}, 144062306a36Sopenharmony_ci {0x0000008e, 0xffffefff}, 144162306a36Sopenharmony_ci {0x0000008f, 0xfff3efff}, 144262306a36Sopenharmony_ci {0x00000090, 0xfff3efbf}, 144362306a36Sopenharmony_ci {0x00000094, 0x00101101}, 144462306a36Sopenharmony_ci {0x00000095, 0x00000fff}, 144562306a36Sopenharmony_ci {0x00000096, 0x00116fff}, 144662306a36Sopenharmony_ci {0x00000097, 0x60010000}, 144762306a36Sopenharmony_ci {0x00000098, 0x10010000}, 144862306a36Sopenharmony_ci {0x00000099, 0x00006000}, 144962306a36Sopenharmony_ci {0x0000009a, 0x00001000}, 145062306a36Sopenharmony_ci {0x0000009f, 0x00a47400} 145162306a36Sopenharmony_ci}; 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_cistatic const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { 145462306a36Sopenharmony_ci {0x0000006f, 0x03044000}, 145562306a36Sopenharmony_ci {0x00000070, 0x0480c018}, 145662306a36Sopenharmony_ci {0x00000071, 0x00000040}, 145762306a36Sopenharmony_ci {0x00000072, 0x01000000}, 145862306a36Sopenharmony_ci {0x00000074, 0x000000ff}, 145962306a36Sopenharmony_ci {0x00000075, 0x00143400}, 146062306a36Sopenharmony_ci {0x00000076, 0x08ec0800}, 146162306a36Sopenharmony_ci {0x00000077, 0x040000cc}, 146262306a36Sopenharmony_ci {0x00000079, 0x00000000}, 146362306a36Sopenharmony_ci {0x0000007a, 0x21000409}, 146462306a36Sopenharmony_ci {0x0000007c, 0x00000000}, 146562306a36Sopenharmony_ci {0x0000007d, 0xe8000000}, 146662306a36Sopenharmony_ci {0x0000007e, 0x044408a8}, 146762306a36Sopenharmony_ci {0x0000007f, 0x00000003}, 146862306a36Sopenharmony_ci {0x00000080, 0x00000000}, 146962306a36Sopenharmony_ci {0x00000081, 0x01000000}, 147062306a36Sopenharmony_ci {0x00000082, 0x02000000}, 147162306a36Sopenharmony_ci {0x00000083, 0x00000000}, 147262306a36Sopenharmony_ci {0x00000084, 0xe3f3e4f4}, 147362306a36Sopenharmony_ci {0x00000085, 0x00052024}, 147462306a36Sopenharmony_ci {0x00000087, 0x00000000}, 147562306a36Sopenharmony_ci {0x00000088, 0x66036603}, 147662306a36Sopenharmony_ci {0x00000089, 0x01000000}, 147762306a36Sopenharmony_ci {0x0000008b, 0x1c0a0000}, 147862306a36Sopenharmony_ci {0x0000008c, 0xff010000}, 147962306a36Sopenharmony_ci {0x0000008e, 0xffffefff}, 148062306a36Sopenharmony_ci {0x0000008f, 0xfff3efff}, 148162306a36Sopenharmony_ci {0x00000090, 0xfff3efbf}, 148262306a36Sopenharmony_ci {0x00000094, 0x00101101}, 148362306a36Sopenharmony_ci {0x00000095, 0x00000fff}, 148462306a36Sopenharmony_ci {0x00000096, 0x00116fff}, 148562306a36Sopenharmony_ci {0x00000097, 0x60010000}, 148662306a36Sopenharmony_ci {0x00000098, 0x10010000}, 148762306a36Sopenharmony_ci {0x00000099, 0x00006000}, 148862306a36Sopenharmony_ci {0x0000009a, 0x00001000}, 148962306a36Sopenharmony_ci {0x0000009f, 0x00a37400} 149062306a36Sopenharmony_ci}; 149162306a36Sopenharmony_ci 149262306a36Sopenharmony_cistatic const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { 149362306a36Sopenharmony_ci {0x0000006f, 0x03044000}, 149462306a36Sopenharmony_ci {0x00000070, 0x0480c018}, 149562306a36Sopenharmony_ci {0x00000071, 0x00000040}, 149662306a36Sopenharmony_ci {0x00000072, 0x01000000}, 149762306a36Sopenharmony_ci {0x00000074, 0x000000ff}, 149862306a36Sopenharmony_ci {0x00000075, 0x00143400}, 149962306a36Sopenharmony_ci {0x00000076, 0x08ec0800}, 150062306a36Sopenharmony_ci {0x00000077, 0x040000cc}, 150162306a36Sopenharmony_ci {0x00000079, 0x00000000}, 150262306a36Sopenharmony_ci {0x0000007a, 0x21000409}, 150362306a36Sopenharmony_ci {0x0000007c, 0x00000000}, 150462306a36Sopenharmony_ci {0x0000007d, 0xe8000000}, 150562306a36Sopenharmony_ci {0x0000007e, 0x044408a8}, 150662306a36Sopenharmony_ci {0x0000007f, 0x00000003}, 150762306a36Sopenharmony_ci {0x00000080, 0x00000000}, 150862306a36Sopenharmony_ci {0x00000081, 0x01000000}, 150962306a36Sopenharmony_ci {0x00000082, 0x02000000}, 151062306a36Sopenharmony_ci {0x00000083, 0x00000000}, 151162306a36Sopenharmony_ci {0x00000084, 0xe3f3e4f4}, 151262306a36Sopenharmony_ci {0x00000085, 0x00052024}, 151362306a36Sopenharmony_ci {0x00000087, 0x00000000}, 151462306a36Sopenharmony_ci {0x00000088, 0x66036603}, 151562306a36Sopenharmony_ci {0x00000089, 0x01000000}, 151662306a36Sopenharmony_ci {0x0000008b, 0x1c0a0000}, 151762306a36Sopenharmony_ci {0x0000008c, 0xff010000}, 151862306a36Sopenharmony_ci {0x0000008e, 0xffffefff}, 151962306a36Sopenharmony_ci {0x0000008f, 0xfff3efff}, 152062306a36Sopenharmony_ci {0x00000090, 0xfff3efbf}, 152162306a36Sopenharmony_ci {0x00000094, 0x00101101}, 152262306a36Sopenharmony_ci {0x00000095, 0x00000fff}, 152362306a36Sopenharmony_ci {0x00000096, 0x00116fff}, 152462306a36Sopenharmony_ci {0x00000097, 0x60010000}, 152562306a36Sopenharmony_ci {0x00000098, 0x10010000}, 152662306a36Sopenharmony_ci {0x00000099, 0x00006000}, 152762306a36Sopenharmony_ci {0x0000009a, 0x00001000}, 152862306a36Sopenharmony_ci {0x0000009f, 0x00a17730} 152962306a36Sopenharmony_ci}; 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_cistatic const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { 153262306a36Sopenharmony_ci {0x0000006f, 0x03044000}, 153362306a36Sopenharmony_ci {0x00000070, 0x0480c018}, 153462306a36Sopenharmony_ci {0x00000071, 0x00000040}, 153562306a36Sopenharmony_ci {0x00000072, 0x01000000}, 153662306a36Sopenharmony_ci {0x00000074, 0x000000ff}, 153762306a36Sopenharmony_ci {0x00000075, 0x00143400}, 153862306a36Sopenharmony_ci {0x00000076, 0x08ec0800}, 153962306a36Sopenharmony_ci {0x00000077, 0x040000cc}, 154062306a36Sopenharmony_ci {0x00000079, 0x00000000}, 154162306a36Sopenharmony_ci {0x0000007a, 0x21000409}, 154262306a36Sopenharmony_ci {0x0000007c, 0x00000000}, 154362306a36Sopenharmony_ci {0x0000007d, 0xe8000000}, 154462306a36Sopenharmony_ci {0x0000007e, 0x044408a8}, 154562306a36Sopenharmony_ci {0x0000007f, 0x00000003}, 154662306a36Sopenharmony_ci {0x00000080, 0x00000000}, 154762306a36Sopenharmony_ci {0x00000081, 0x01000000}, 154862306a36Sopenharmony_ci {0x00000082, 0x02000000}, 154962306a36Sopenharmony_ci {0x00000083, 0x00000000}, 155062306a36Sopenharmony_ci {0x00000084, 0xe3f3e4f4}, 155162306a36Sopenharmony_ci {0x00000085, 0x00052024}, 155262306a36Sopenharmony_ci {0x00000087, 0x00000000}, 155362306a36Sopenharmony_ci {0x00000088, 0x66036603}, 155462306a36Sopenharmony_ci {0x00000089, 0x01000000}, 155562306a36Sopenharmony_ci {0x0000008b, 0x1c0a0000}, 155662306a36Sopenharmony_ci {0x0000008c, 0xff010000}, 155762306a36Sopenharmony_ci {0x0000008e, 0xffffefff}, 155862306a36Sopenharmony_ci {0x0000008f, 0xfff3efff}, 155962306a36Sopenharmony_ci {0x00000090, 0xfff3efbf}, 156062306a36Sopenharmony_ci {0x00000094, 0x00101101}, 156162306a36Sopenharmony_ci {0x00000095, 0x00000fff}, 156262306a36Sopenharmony_ci {0x00000096, 0x00116fff}, 156362306a36Sopenharmony_ci {0x00000097, 0x60010000}, 156462306a36Sopenharmony_ci {0x00000098, 0x10010000}, 156562306a36Sopenharmony_ci {0x00000099, 0x00006000}, 156662306a36Sopenharmony_ci {0x0000009a, 0x00001000}, 156762306a36Sopenharmony_ci {0x0000009f, 0x00a07730} 156862306a36Sopenharmony_ci}; 156962306a36Sopenharmony_ci 157062306a36Sopenharmony_ci/* ucode loading */ 157162306a36Sopenharmony_ciint si_mc_load_microcode(struct radeon_device *rdev) 157262306a36Sopenharmony_ci{ 157362306a36Sopenharmony_ci const __be32 *fw_data = NULL; 157462306a36Sopenharmony_ci const __le32 *new_fw_data = NULL; 157562306a36Sopenharmony_ci u32 running; 157662306a36Sopenharmony_ci u32 *io_mc_regs = NULL; 157762306a36Sopenharmony_ci const __le32 *new_io_mc_regs = NULL; 157862306a36Sopenharmony_ci int i, regs_size, ucode_size; 157962306a36Sopenharmony_ci 158062306a36Sopenharmony_ci if (!rdev->mc_fw) 158162306a36Sopenharmony_ci return -EINVAL; 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_ci if (rdev->new_fw) { 158462306a36Sopenharmony_ci const struct mc_firmware_header_v1_0 *hdr = 158562306a36Sopenharmony_ci (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data; 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci radeon_ucode_print_mc_hdr(&hdr->header); 158862306a36Sopenharmony_ci regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2); 158962306a36Sopenharmony_ci new_io_mc_regs = (const __le32 *) 159062306a36Sopenharmony_ci (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes)); 159162306a36Sopenharmony_ci ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; 159262306a36Sopenharmony_ci new_fw_data = (const __le32 *) 159362306a36Sopenharmony_ci (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 159462306a36Sopenharmony_ci } else { 159562306a36Sopenharmony_ci ucode_size = rdev->mc_fw->size / 4; 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci switch (rdev->family) { 159862306a36Sopenharmony_ci case CHIP_TAHITI: 159962306a36Sopenharmony_ci io_mc_regs = (u32 *)&tahiti_io_mc_regs; 160062306a36Sopenharmony_ci regs_size = TAHITI_IO_MC_REGS_SIZE; 160162306a36Sopenharmony_ci break; 160262306a36Sopenharmony_ci case CHIP_PITCAIRN: 160362306a36Sopenharmony_ci io_mc_regs = (u32 *)&pitcairn_io_mc_regs; 160462306a36Sopenharmony_ci regs_size = TAHITI_IO_MC_REGS_SIZE; 160562306a36Sopenharmony_ci break; 160662306a36Sopenharmony_ci case CHIP_VERDE: 160762306a36Sopenharmony_ci default: 160862306a36Sopenharmony_ci io_mc_regs = (u32 *)&verde_io_mc_regs; 160962306a36Sopenharmony_ci regs_size = TAHITI_IO_MC_REGS_SIZE; 161062306a36Sopenharmony_ci break; 161162306a36Sopenharmony_ci case CHIP_OLAND: 161262306a36Sopenharmony_ci io_mc_regs = (u32 *)&oland_io_mc_regs; 161362306a36Sopenharmony_ci regs_size = TAHITI_IO_MC_REGS_SIZE; 161462306a36Sopenharmony_ci break; 161562306a36Sopenharmony_ci case CHIP_HAINAN: 161662306a36Sopenharmony_ci io_mc_regs = (u32 *)&hainan_io_mc_regs; 161762306a36Sopenharmony_ci regs_size = TAHITI_IO_MC_REGS_SIZE; 161862306a36Sopenharmony_ci break; 161962306a36Sopenharmony_ci } 162062306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->mc_fw->data; 162162306a36Sopenharmony_ci } 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_ci if (running == 0) { 162662306a36Sopenharmony_ci /* reset the engine and set to writable */ 162762306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 162862306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000010); 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci /* load mc io regs */ 163162306a36Sopenharmony_ci for (i = 0; i < regs_size; i++) { 163262306a36Sopenharmony_ci if (rdev->new_fw) { 163362306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++)); 163462306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++)); 163562306a36Sopenharmony_ci } else { 163662306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); 163762306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); 163862306a36Sopenharmony_ci } 163962306a36Sopenharmony_ci } 164062306a36Sopenharmony_ci /* load the MC ucode */ 164162306a36Sopenharmony_ci for (i = 0; i < ucode_size; i++) { 164262306a36Sopenharmony_ci if (rdev->new_fw) 164362306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++)); 164462306a36Sopenharmony_ci else 164562306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); 164662306a36Sopenharmony_ci } 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci /* put the engine back into the active state */ 164962306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 165062306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000004); 165162306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000001); 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_ci /* wait for training to complete */ 165462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 165562306a36Sopenharmony_ci if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0) 165662306a36Sopenharmony_ci break; 165762306a36Sopenharmony_ci udelay(1); 165862306a36Sopenharmony_ci } 165962306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 166062306a36Sopenharmony_ci if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1) 166162306a36Sopenharmony_ci break; 166262306a36Sopenharmony_ci udelay(1); 166362306a36Sopenharmony_ci } 166462306a36Sopenharmony_ci } 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_ci return 0; 166762306a36Sopenharmony_ci} 166862306a36Sopenharmony_ci 166962306a36Sopenharmony_cistatic int si_init_microcode(struct radeon_device *rdev) 167062306a36Sopenharmony_ci{ 167162306a36Sopenharmony_ci const char *chip_name; 167262306a36Sopenharmony_ci const char *new_chip_name; 167362306a36Sopenharmony_ci size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; 167462306a36Sopenharmony_ci size_t smc_req_size, mc2_req_size; 167562306a36Sopenharmony_ci char fw_name[30]; 167662306a36Sopenharmony_ci int err; 167762306a36Sopenharmony_ci int new_fw = 0; 167862306a36Sopenharmony_ci bool new_smc = false; 167962306a36Sopenharmony_ci bool si58_fw = false; 168062306a36Sopenharmony_ci bool banks2_fw = false; 168162306a36Sopenharmony_ci 168262306a36Sopenharmony_ci DRM_DEBUG("\n"); 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci switch (rdev->family) { 168562306a36Sopenharmony_ci case CHIP_TAHITI: 168662306a36Sopenharmony_ci chip_name = "TAHITI"; 168762306a36Sopenharmony_ci new_chip_name = "tahiti"; 168862306a36Sopenharmony_ci pfp_req_size = SI_PFP_UCODE_SIZE * 4; 168962306a36Sopenharmony_ci me_req_size = SI_PM4_UCODE_SIZE * 4; 169062306a36Sopenharmony_ci ce_req_size = SI_CE_UCODE_SIZE * 4; 169162306a36Sopenharmony_ci rlc_req_size = SI_RLC_UCODE_SIZE * 4; 169262306a36Sopenharmony_ci mc_req_size = SI_MC_UCODE_SIZE * 4; 169362306a36Sopenharmony_ci mc2_req_size = TAHITI_MC_UCODE_SIZE * 4; 169462306a36Sopenharmony_ci smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4); 169562306a36Sopenharmony_ci break; 169662306a36Sopenharmony_ci case CHIP_PITCAIRN: 169762306a36Sopenharmony_ci chip_name = "PITCAIRN"; 169862306a36Sopenharmony_ci if ((rdev->pdev->revision == 0x81) && 169962306a36Sopenharmony_ci ((rdev->pdev->device == 0x6810) || 170062306a36Sopenharmony_ci (rdev->pdev->device == 0x6811))) 170162306a36Sopenharmony_ci new_smc = true; 170262306a36Sopenharmony_ci new_chip_name = "pitcairn"; 170362306a36Sopenharmony_ci pfp_req_size = SI_PFP_UCODE_SIZE * 4; 170462306a36Sopenharmony_ci me_req_size = SI_PM4_UCODE_SIZE * 4; 170562306a36Sopenharmony_ci ce_req_size = SI_CE_UCODE_SIZE * 4; 170662306a36Sopenharmony_ci rlc_req_size = SI_RLC_UCODE_SIZE * 4; 170762306a36Sopenharmony_ci mc_req_size = SI_MC_UCODE_SIZE * 4; 170862306a36Sopenharmony_ci mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4; 170962306a36Sopenharmony_ci smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4); 171062306a36Sopenharmony_ci break; 171162306a36Sopenharmony_ci case CHIP_VERDE: 171262306a36Sopenharmony_ci chip_name = "VERDE"; 171362306a36Sopenharmony_ci if (((rdev->pdev->device == 0x6820) && 171462306a36Sopenharmony_ci ((rdev->pdev->revision == 0x81) || 171562306a36Sopenharmony_ci (rdev->pdev->revision == 0x83))) || 171662306a36Sopenharmony_ci ((rdev->pdev->device == 0x6821) && 171762306a36Sopenharmony_ci ((rdev->pdev->revision == 0x83) || 171862306a36Sopenharmony_ci (rdev->pdev->revision == 0x87))) || 171962306a36Sopenharmony_ci ((rdev->pdev->revision == 0x87) && 172062306a36Sopenharmony_ci ((rdev->pdev->device == 0x6823) || 172162306a36Sopenharmony_ci (rdev->pdev->device == 0x682b)))) 172262306a36Sopenharmony_ci new_smc = true; 172362306a36Sopenharmony_ci new_chip_name = "verde"; 172462306a36Sopenharmony_ci pfp_req_size = SI_PFP_UCODE_SIZE * 4; 172562306a36Sopenharmony_ci me_req_size = SI_PM4_UCODE_SIZE * 4; 172662306a36Sopenharmony_ci ce_req_size = SI_CE_UCODE_SIZE * 4; 172762306a36Sopenharmony_ci rlc_req_size = SI_RLC_UCODE_SIZE * 4; 172862306a36Sopenharmony_ci mc_req_size = SI_MC_UCODE_SIZE * 4; 172962306a36Sopenharmony_ci mc2_req_size = VERDE_MC_UCODE_SIZE * 4; 173062306a36Sopenharmony_ci smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4); 173162306a36Sopenharmony_ci break; 173262306a36Sopenharmony_ci case CHIP_OLAND: 173362306a36Sopenharmony_ci chip_name = "OLAND"; 173462306a36Sopenharmony_ci if (((rdev->pdev->revision == 0x81) && 173562306a36Sopenharmony_ci ((rdev->pdev->device == 0x6600) || 173662306a36Sopenharmony_ci (rdev->pdev->device == 0x6604) || 173762306a36Sopenharmony_ci (rdev->pdev->device == 0x6605) || 173862306a36Sopenharmony_ci (rdev->pdev->device == 0x6610))) || 173962306a36Sopenharmony_ci ((rdev->pdev->revision == 0x83) && 174062306a36Sopenharmony_ci (rdev->pdev->device == 0x6610))) 174162306a36Sopenharmony_ci new_smc = true; 174262306a36Sopenharmony_ci new_chip_name = "oland"; 174362306a36Sopenharmony_ci pfp_req_size = SI_PFP_UCODE_SIZE * 4; 174462306a36Sopenharmony_ci me_req_size = SI_PM4_UCODE_SIZE * 4; 174562306a36Sopenharmony_ci ce_req_size = SI_CE_UCODE_SIZE * 4; 174662306a36Sopenharmony_ci rlc_req_size = SI_RLC_UCODE_SIZE * 4; 174762306a36Sopenharmony_ci mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4; 174862306a36Sopenharmony_ci smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4); 174962306a36Sopenharmony_ci break; 175062306a36Sopenharmony_ci case CHIP_HAINAN: 175162306a36Sopenharmony_ci chip_name = "HAINAN"; 175262306a36Sopenharmony_ci if (((rdev->pdev->revision == 0x81) && 175362306a36Sopenharmony_ci (rdev->pdev->device == 0x6660)) || 175462306a36Sopenharmony_ci ((rdev->pdev->revision == 0x83) && 175562306a36Sopenharmony_ci ((rdev->pdev->device == 0x6660) || 175662306a36Sopenharmony_ci (rdev->pdev->device == 0x6663) || 175762306a36Sopenharmony_ci (rdev->pdev->device == 0x6665) || 175862306a36Sopenharmony_ci (rdev->pdev->device == 0x6667)))) 175962306a36Sopenharmony_ci new_smc = true; 176062306a36Sopenharmony_ci else if ((rdev->pdev->revision == 0xc3) && 176162306a36Sopenharmony_ci (rdev->pdev->device == 0x6665)) 176262306a36Sopenharmony_ci banks2_fw = true; 176362306a36Sopenharmony_ci new_chip_name = "hainan"; 176462306a36Sopenharmony_ci pfp_req_size = SI_PFP_UCODE_SIZE * 4; 176562306a36Sopenharmony_ci me_req_size = SI_PM4_UCODE_SIZE * 4; 176662306a36Sopenharmony_ci ce_req_size = SI_CE_UCODE_SIZE * 4; 176762306a36Sopenharmony_ci rlc_req_size = SI_RLC_UCODE_SIZE * 4; 176862306a36Sopenharmony_ci mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4; 176962306a36Sopenharmony_ci smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4); 177062306a36Sopenharmony_ci break; 177162306a36Sopenharmony_ci default: BUG(); 177262306a36Sopenharmony_ci } 177362306a36Sopenharmony_ci 177462306a36Sopenharmony_ci /* this memory configuration requires special firmware */ 177562306a36Sopenharmony_ci if (((RREG32(MC_SEQ_MISC0) & 0xff000000) >> 24) == 0x58) 177662306a36Sopenharmony_ci si58_fw = true; 177762306a36Sopenharmony_ci 177862306a36Sopenharmony_ci DRM_INFO("Loading %s Microcode\n", new_chip_name); 177962306a36Sopenharmony_ci 178062306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name); 178162306a36Sopenharmony_ci err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 178262306a36Sopenharmony_ci if (err) { 178362306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); 178462306a36Sopenharmony_ci err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 178562306a36Sopenharmony_ci if (err) 178662306a36Sopenharmony_ci goto out; 178762306a36Sopenharmony_ci if (rdev->pfp_fw->size != pfp_req_size) { 178862306a36Sopenharmony_ci pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n", 178962306a36Sopenharmony_ci rdev->pfp_fw->size, fw_name); 179062306a36Sopenharmony_ci err = -EINVAL; 179162306a36Sopenharmony_ci goto out; 179262306a36Sopenharmony_ci } 179362306a36Sopenharmony_ci } else { 179462306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->pfp_fw); 179562306a36Sopenharmony_ci if (err) { 179662306a36Sopenharmony_ci pr_err("si_cp: validation failed for firmware \"%s\"\n", 179762306a36Sopenharmony_ci fw_name); 179862306a36Sopenharmony_ci goto out; 179962306a36Sopenharmony_ci } else { 180062306a36Sopenharmony_ci new_fw++; 180162306a36Sopenharmony_ci } 180262306a36Sopenharmony_ci } 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name); 180562306a36Sopenharmony_ci err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 180662306a36Sopenharmony_ci if (err) { 180762306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); 180862306a36Sopenharmony_ci err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 180962306a36Sopenharmony_ci if (err) 181062306a36Sopenharmony_ci goto out; 181162306a36Sopenharmony_ci if (rdev->me_fw->size != me_req_size) { 181262306a36Sopenharmony_ci pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n", 181362306a36Sopenharmony_ci rdev->me_fw->size, fw_name); 181462306a36Sopenharmony_ci err = -EINVAL; 181562306a36Sopenharmony_ci } 181662306a36Sopenharmony_ci } else { 181762306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->me_fw); 181862306a36Sopenharmony_ci if (err) { 181962306a36Sopenharmony_ci pr_err("si_cp: validation failed for firmware \"%s\"\n", 182062306a36Sopenharmony_ci fw_name); 182162306a36Sopenharmony_ci goto out; 182262306a36Sopenharmony_ci } else { 182362306a36Sopenharmony_ci new_fw++; 182462306a36Sopenharmony_ci } 182562306a36Sopenharmony_ci } 182662306a36Sopenharmony_ci 182762306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name); 182862306a36Sopenharmony_ci err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 182962306a36Sopenharmony_ci if (err) { 183062306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); 183162306a36Sopenharmony_ci err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 183262306a36Sopenharmony_ci if (err) 183362306a36Sopenharmony_ci goto out; 183462306a36Sopenharmony_ci if (rdev->ce_fw->size != ce_req_size) { 183562306a36Sopenharmony_ci pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n", 183662306a36Sopenharmony_ci rdev->ce_fw->size, fw_name); 183762306a36Sopenharmony_ci err = -EINVAL; 183862306a36Sopenharmony_ci } 183962306a36Sopenharmony_ci } else { 184062306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->ce_fw); 184162306a36Sopenharmony_ci if (err) { 184262306a36Sopenharmony_ci pr_err("si_cp: validation failed for firmware \"%s\"\n", 184362306a36Sopenharmony_ci fw_name); 184462306a36Sopenharmony_ci goto out; 184562306a36Sopenharmony_ci } else { 184662306a36Sopenharmony_ci new_fw++; 184762306a36Sopenharmony_ci } 184862306a36Sopenharmony_ci } 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name); 185162306a36Sopenharmony_ci err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 185262306a36Sopenharmony_ci if (err) { 185362306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); 185462306a36Sopenharmony_ci err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 185562306a36Sopenharmony_ci if (err) 185662306a36Sopenharmony_ci goto out; 185762306a36Sopenharmony_ci if (rdev->rlc_fw->size != rlc_req_size) { 185862306a36Sopenharmony_ci pr_err("si_rlc: Bogus length %zu in firmware \"%s\"\n", 185962306a36Sopenharmony_ci rdev->rlc_fw->size, fw_name); 186062306a36Sopenharmony_ci err = -EINVAL; 186162306a36Sopenharmony_ci } 186262306a36Sopenharmony_ci } else { 186362306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->rlc_fw); 186462306a36Sopenharmony_ci if (err) { 186562306a36Sopenharmony_ci pr_err("si_cp: validation failed for firmware \"%s\"\n", 186662306a36Sopenharmony_ci fw_name); 186762306a36Sopenharmony_ci goto out; 186862306a36Sopenharmony_ci } else { 186962306a36Sopenharmony_ci new_fw++; 187062306a36Sopenharmony_ci } 187162306a36Sopenharmony_ci } 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci if (si58_fw) 187462306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/si58_mc.bin"); 187562306a36Sopenharmony_ci else 187662306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name); 187762306a36Sopenharmony_ci err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 187862306a36Sopenharmony_ci if (err) { 187962306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name); 188062306a36Sopenharmony_ci err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 188162306a36Sopenharmony_ci if (err) { 188262306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); 188362306a36Sopenharmony_ci err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 188462306a36Sopenharmony_ci if (err) 188562306a36Sopenharmony_ci goto out; 188662306a36Sopenharmony_ci } 188762306a36Sopenharmony_ci if ((rdev->mc_fw->size != mc_req_size) && 188862306a36Sopenharmony_ci (rdev->mc_fw->size != mc2_req_size)) { 188962306a36Sopenharmony_ci pr_err("si_mc: Bogus length %zu in firmware \"%s\"\n", 189062306a36Sopenharmony_ci rdev->mc_fw->size, fw_name); 189162306a36Sopenharmony_ci err = -EINVAL; 189262306a36Sopenharmony_ci } 189362306a36Sopenharmony_ci DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size); 189462306a36Sopenharmony_ci } else { 189562306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->mc_fw); 189662306a36Sopenharmony_ci if (err) { 189762306a36Sopenharmony_ci pr_err("si_cp: validation failed for firmware \"%s\"\n", 189862306a36Sopenharmony_ci fw_name); 189962306a36Sopenharmony_ci goto out; 190062306a36Sopenharmony_ci } else { 190162306a36Sopenharmony_ci new_fw++; 190262306a36Sopenharmony_ci } 190362306a36Sopenharmony_ci } 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci if (banks2_fw) 190662306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/banks_k_2_smc.bin"); 190762306a36Sopenharmony_ci else if (new_smc) 190862306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name); 190962306a36Sopenharmony_ci else 191062306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); 191162306a36Sopenharmony_ci err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 191262306a36Sopenharmony_ci if (err) { 191362306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); 191462306a36Sopenharmony_ci err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 191562306a36Sopenharmony_ci if (err) { 191662306a36Sopenharmony_ci pr_err("smc: error loading firmware \"%s\"\n", fw_name); 191762306a36Sopenharmony_ci release_firmware(rdev->smc_fw); 191862306a36Sopenharmony_ci rdev->smc_fw = NULL; 191962306a36Sopenharmony_ci err = 0; 192062306a36Sopenharmony_ci } else if (rdev->smc_fw->size != smc_req_size) { 192162306a36Sopenharmony_ci pr_err("si_smc: Bogus length %zu in firmware \"%s\"\n", 192262306a36Sopenharmony_ci rdev->smc_fw->size, fw_name); 192362306a36Sopenharmony_ci err = -EINVAL; 192462306a36Sopenharmony_ci } 192562306a36Sopenharmony_ci } else { 192662306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->smc_fw); 192762306a36Sopenharmony_ci if (err) { 192862306a36Sopenharmony_ci pr_err("si_cp: validation failed for firmware \"%s\"\n", 192962306a36Sopenharmony_ci fw_name); 193062306a36Sopenharmony_ci goto out; 193162306a36Sopenharmony_ci } else { 193262306a36Sopenharmony_ci new_fw++; 193362306a36Sopenharmony_ci } 193462306a36Sopenharmony_ci } 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci if (new_fw == 0) { 193762306a36Sopenharmony_ci rdev->new_fw = false; 193862306a36Sopenharmony_ci } else if (new_fw < 6) { 193962306a36Sopenharmony_ci pr_err("si_fw: mixing new and old firmware!\n"); 194062306a36Sopenharmony_ci err = -EINVAL; 194162306a36Sopenharmony_ci } else { 194262306a36Sopenharmony_ci rdev->new_fw = true; 194362306a36Sopenharmony_ci } 194462306a36Sopenharmony_ciout: 194562306a36Sopenharmony_ci if (err) { 194662306a36Sopenharmony_ci if (err != -EINVAL) 194762306a36Sopenharmony_ci pr_err("si_cp: Failed to load firmware \"%s\"\n", 194862306a36Sopenharmony_ci fw_name); 194962306a36Sopenharmony_ci release_firmware(rdev->pfp_fw); 195062306a36Sopenharmony_ci rdev->pfp_fw = NULL; 195162306a36Sopenharmony_ci release_firmware(rdev->me_fw); 195262306a36Sopenharmony_ci rdev->me_fw = NULL; 195362306a36Sopenharmony_ci release_firmware(rdev->ce_fw); 195462306a36Sopenharmony_ci rdev->ce_fw = NULL; 195562306a36Sopenharmony_ci release_firmware(rdev->rlc_fw); 195662306a36Sopenharmony_ci rdev->rlc_fw = NULL; 195762306a36Sopenharmony_ci release_firmware(rdev->mc_fw); 195862306a36Sopenharmony_ci rdev->mc_fw = NULL; 195962306a36Sopenharmony_ci release_firmware(rdev->smc_fw); 196062306a36Sopenharmony_ci rdev->smc_fw = NULL; 196162306a36Sopenharmony_ci } 196262306a36Sopenharmony_ci return err; 196362306a36Sopenharmony_ci} 196462306a36Sopenharmony_ci 196562306a36Sopenharmony_ci/* watermark setup */ 196662306a36Sopenharmony_cistatic u32 dce6_line_buffer_adjust(struct radeon_device *rdev, 196762306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc, 196862306a36Sopenharmony_ci struct drm_display_mode *mode, 196962306a36Sopenharmony_ci struct drm_display_mode *other_mode) 197062306a36Sopenharmony_ci{ 197162306a36Sopenharmony_ci u32 tmp, buffer_alloc, i; 197262306a36Sopenharmony_ci u32 pipe_offset = radeon_crtc->crtc_id * 0x20; 197362306a36Sopenharmony_ci /* 197462306a36Sopenharmony_ci * Line Buffer Setup 197562306a36Sopenharmony_ci * There are 3 line buffers, each one shared by 2 display controllers. 197662306a36Sopenharmony_ci * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between 197762306a36Sopenharmony_ci * the display controllers. The paritioning is done via one of four 197862306a36Sopenharmony_ci * preset allocations specified in bits 21:20: 197962306a36Sopenharmony_ci * 0 - half lb 198062306a36Sopenharmony_ci * 2 - whole lb, other crtc must be disabled 198162306a36Sopenharmony_ci */ 198262306a36Sopenharmony_ci /* this can get tricky if we have two large displays on a paired group 198362306a36Sopenharmony_ci * of crtcs. Ideally for multiple large displays we'd assign them to 198462306a36Sopenharmony_ci * non-linked crtcs for maximum line buffer allocation. 198562306a36Sopenharmony_ci */ 198662306a36Sopenharmony_ci if (radeon_crtc->base.enabled && mode) { 198762306a36Sopenharmony_ci if (other_mode) { 198862306a36Sopenharmony_ci tmp = 0; /* 1/2 */ 198962306a36Sopenharmony_ci buffer_alloc = 1; 199062306a36Sopenharmony_ci } else { 199162306a36Sopenharmony_ci tmp = 2; /* whole */ 199262306a36Sopenharmony_ci buffer_alloc = 2; 199362306a36Sopenharmony_ci } 199462306a36Sopenharmony_ci } else { 199562306a36Sopenharmony_ci tmp = 0; 199662306a36Sopenharmony_ci buffer_alloc = 0; 199762306a36Sopenharmony_ci } 199862306a36Sopenharmony_ci 199962306a36Sopenharmony_ci WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, 200062306a36Sopenharmony_ci DC_LB_MEMORY_CONFIG(tmp)); 200162306a36Sopenharmony_ci 200262306a36Sopenharmony_ci WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, 200362306a36Sopenharmony_ci DMIF_BUFFERS_ALLOCATED(buffer_alloc)); 200462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 200562306a36Sopenharmony_ci if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & 200662306a36Sopenharmony_ci DMIF_BUFFERS_ALLOCATED_COMPLETED) 200762306a36Sopenharmony_ci break; 200862306a36Sopenharmony_ci udelay(1); 200962306a36Sopenharmony_ci } 201062306a36Sopenharmony_ci 201162306a36Sopenharmony_ci if (radeon_crtc->base.enabled && mode) { 201262306a36Sopenharmony_ci switch (tmp) { 201362306a36Sopenharmony_ci case 0: 201462306a36Sopenharmony_ci default: 201562306a36Sopenharmony_ci return 4096 * 2; 201662306a36Sopenharmony_ci case 2: 201762306a36Sopenharmony_ci return 8192 * 2; 201862306a36Sopenharmony_ci } 201962306a36Sopenharmony_ci } 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_ci /* controller not enabled, so no lb used */ 202262306a36Sopenharmony_ci return 0; 202362306a36Sopenharmony_ci} 202462306a36Sopenharmony_ci 202562306a36Sopenharmony_cistatic u32 si_get_number_of_dram_channels(struct radeon_device *rdev) 202662306a36Sopenharmony_ci{ 202762306a36Sopenharmony_ci u32 tmp = RREG32(MC_SHARED_CHMAP); 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_ci switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { 203062306a36Sopenharmony_ci case 0: 203162306a36Sopenharmony_ci default: 203262306a36Sopenharmony_ci return 1; 203362306a36Sopenharmony_ci case 1: 203462306a36Sopenharmony_ci return 2; 203562306a36Sopenharmony_ci case 2: 203662306a36Sopenharmony_ci return 4; 203762306a36Sopenharmony_ci case 3: 203862306a36Sopenharmony_ci return 8; 203962306a36Sopenharmony_ci case 4: 204062306a36Sopenharmony_ci return 3; 204162306a36Sopenharmony_ci case 5: 204262306a36Sopenharmony_ci return 6; 204362306a36Sopenharmony_ci case 6: 204462306a36Sopenharmony_ci return 10; 204562306a36Sopenharmony_ci case 7: 204662306a36Sopenharmony_ci return 12; 204762306a36Sopenharmony_ci case 8: 204862306a36Sopenharmony_ci return 16; 204962306a36Sopenharmony_ci } 205062306a36Sopenharmony_ci} 205162306a36Sopenharmony_ci 205262306a36Sopenharmony_cistruct dce6_wm_params { 205362306a36Sopenharmony_ci u32 dram_channels; /* number of dram channels */ 205462306a36Sopenharmony_ci u32 yclk; /* bandwidth per dram data pin in kHz */ 205562306a36Sopenharmony_ci u32 sclk; /* engine clock in kHz */ 205662306a36Sopenharmony_ci u32 disp_clk; /* display clock in kHz */ 205762306a36Sopenharmony_ci u32 src_width; /* viewport width */ 205862306a36Sopenharmony_ci u32 active_time; /* active display time in ns */ 205962306a36Sopenharmony_ci u32 blank_time; /* blank time in ns */ 206062306a36Sopenharmony_ci bool interlaced; /* mode is interlaced */ 206162306a36Sopenharmony_ci fixed20_12 vsc; /* vertical scale ratio */ 206262306a36Sopenharmony_ci u32 num_heads; /* number of active crtcs */ 206362306a36Sopenharmony_ci u32 bytes_per_pixel; /* bytes per pixel display + overlay */ 206462306a36Sopenharmony_ci u32 lb_size; /* line buffer allocated to pipe */ 206562306a36Sopenharmony_ci u32 vtaps; /* vertical scaler taps */ 206662306a36Sopenharmony_ci}; 206762306a36Sopenharmony_ci 206862306a36Sopenharmony_cistatic u32 dce6_dram_bandwidth(struct dce6_wm_params *wm) 206962306a36Sopenharmony_ci{ 207062306a36Sopenharmony_ci /* Calculate raw DRAM Bandwidth */ 207162306a36Sopenharmony_ci fixed20_12 dram_efficiency; /* 0.7 */ 207262306a36Sopenharmony_ci fixed20_12 yclk, dram_channels, bandwidth; 207362306a36Sopenharmony_ci fixed20_12 a; 207462306a36Sopenharmony_ci 207562306a36Sopenharmony_ci a.full = dfixed_const(1000); 207662306a36Sopenharmony_ci yclk.full = dfixed_const(wm->yclk); 207762306a36Sopenharmony_ci yclk.full = dfixed_div(yclk, a); 207862306a36Sopenharmony_ci dram_channels.full = dfixed_const(wm->dram_channels * 4); 207962306a36Sopenharmony_ci a.full = dfixed_const(10); 208062306a36Sopenharmony_ci dram_efficiency.full = dfixed_const(7); 208162306a36Sopenharmony_ci dram_efficiency.full = dfixed_div(dram_efficiency, a); 208262306a36Sopenharmony_ci bandwidth.full = dfixed_mul(dram_channels, yclk); 208362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, dram_efficiency); 208462306a36Sopenharmony_ci 208562306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 208662306a36Sopenharmony_ci} 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_cistatic u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm) 208962306a36Sopenharmony_ci{ 209062306a36Sopenharmony_ci /* Calculate DRAM Bandwidth and the part allocated to display. */ 209162306a36Sopenharmony_ci fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */ 209262306a36Sopenharmony_ci fixed20_12 yclk, dram_channels, bandwidth; 209362306a36Sopenharmony_ci fixed20_12 a; 209462306a36Sopenharmony_ci 209562306a36Sopenharmony_ci a.full = dfixed_const(1000); 209662306a36Sopenharmony_ci yclk.full = dfixed_const(wm->yclk); 209762306a36Sopenharmony_ci yclk.full = dfixed_div(yclk, a); 209862306a36Sopenharmony_ci dram_channels.full = dfixed_const(wm->dram_channels * 4); 209962306a36Sopenharmony_ci a.full = dfixed_const(10); 210062306a36Sopenharmony_ci disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */ 210162306a36Sopenharmony_ci disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a); 210262306a36Sopenharmony_ci bandwidth.full = dfixed_mul(dram_channels, yclk); 210362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation); 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 210662306a36Sopenharmony_ci} 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_cistatic u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm) 210962306a36Sopenharmony_ci{ 211062306a36Sopenharmony_ci /* Calculate the display Data return Bandwidth */ 211162306a36Sopenharmony_ci fixed20_12 return_efficiency; /* 0.8 */ 211262306a36Sopenharmony_ci fixed20_12 sclk, bandwidth; 211362306a36Sopenharmony_ci fixed20_12 a; 211462306a36Sopenharmony_ci 211562306a36Sopenharmony_ci a.full = dfixed_const(1000); 211662306a36Sopenharmony_ci sclk.full = dfixed_const(wm->sclk); 211762306a36Sopenharmony_ci sclk.full = dfixed_div(sclk, a); 211862306a36Sopenharmony_ci a.full = dfixed_const(10); 211962306a36Sopenharmony_ci return_efficiency.full = dfixed_const(8); 212062306a36Sopenharmony_ci return_efficiency.full = dfixed_div(return_efficiency, a); 212162306a36Sopenharmony_ci a.full = dfixed_const(32); 212262306a36Sopenharmony_ci bandwidth.full = dfixed_mul(a, sclk); 212362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, return_efficiency); 212462306a36Sopenharmony_ci 212562306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 212662306a36Sopenharmony_ci} 212762306a36Sopenharmony_ci 212862306a36Sopenharmony_cistatic u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm) 212962306a36Sopenharmony_ci{ 213062306a36Sopenharmony_ci return 32; 213162306a36Sopenharmony_ci} 213262306a36Sopenharmony_ci 213362306a36Sopenharmony_cistatic u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm) 213462306a36Sopenharmony_ci{ 213562306a36Sopenharmony_ci /* Calculate the DMIF Request Bandwidth */ 213662306a36Sopenharmony_ci fixed20_12 disp_clk_request_efficiency; /* 0.8 */ 213762306a36Sopenharmony_ci fixed20_12 disp_clk, sclk, bandwidth; 213862306a36Sopenharmony_ci fixed20_12 a, b1, b2; 213962306a36Sopenharmony_ci u32 min_bandwidth; 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci a.full = dfixed_const(1000); 214262306a36Sopenharmony_ci disp_clk.full = dfixed_const(wm->disp_clk); 214362306a36Sopenharmony_ci disp_clk.full = dfixed_div(disp_clk, a); 214462306a36Sopenharmony_ci a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2); 214562306a36Sopenharmony_ci b1.full = dfixed_mul(a, disp_clk); 214662306a36Sopenharmony_ci 214762306a36Sopenharmony_ci a.full = dfixed_const(1000); 214862306a36Sopenharmony_ci sclk.full = dfixed_const(wm->sclk); 214962306a36Sopenharmony_ci sclk.full = dfixed_div(sclk, a); 215062306a36Sopenharmony_ci a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm)); 215162306a36Sopenharmony_ci b2.full = dfixed_mul(a, sclk); 215262306a36Sopenharmony_ci 215362306a36Sopenharmony_ci a.full = dfixed_const(10); 215462306a36Sopenharmony_ci disp_clk_request_efficiency.full = dfixed_const(8); 215562306a36Sopenharmony_ci disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a); 215662306a36Sopenharmony_ci 215762306a36Sopenharmony_ci min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2)); 215862306a36Sopenharmony_ci 215962306a36Sopenharmony_ci a.full = dfixed_const(min_bandwidth); 216062306a36Sopenharmony_ci bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency); 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 216362306a36Sopenharmony_ci} 216462306a36Sopenharmony_ci 216562306a36Sopenharmony_cistatic u32 dce6_available_bandwidth(struct dce6_wm_params *wm) 216662306a36Sopenharmony_ci{ 216762306a36Sopenharmony_ci /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */ 216862306a36Sopenharmony_ci u32 dram_bandwidth = dce6_dram_bandwidth(wm); 216962306a36Sopenharmony_ci u32 data_return_bandwidth = dce6_data_return_bandwidth(wm); 217062306a36Sopenharmony_ci u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm); 217162306a36Sopenharmony_ci 217262306a36Sopenharmony_ci return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth)); 217362306a36Sopenharmony_ci} 217462306a36Sopenharmony_ci 217562306a36Sopenharmony_cistatic u32 dce6_average_bandwidth(struct dce6_wm_params *wm) 217662306a36Sopenharmony_ci{ 217762306a36Sopenharmony_ci /* Calculate the display mode Average Bandwidth 217862306a36Sopenharmony_ci * DisplayMode should contain the source and destination dimensions, 217962306a36Sopenharmony_ci * timing, etc. 218062306a36Sopenharmony_ci */ 218162306a36Sopenharmony_ci fixed20_12 bpp; 218262306a36Sopenharmony_ci fixed20_12 line_time; 218362306a36Sopenharmony_ci fixed20_12 src_width; 218462306a36Sopenharmony_ci fixed20_12 bandwidth; 218562306a36Sopenharmony_ci fixed20_12 a; 218662306a36Sopenharmony_ci 218762306a36Sopenharmony_ci a.full = dfixed_const(1000); 218862306a36Sopenharmony_ci line_time.full = dfixed_const(wm->active_time + wm->blank_time); 218962306a36Sopenharmony_ci line_time.full = dfixed_div(line_time, a); 219062306a36Sopenharmony_ci bpp.full = dfixed_const(wm->bytes_per_pixel); 219162306a36Sopenharmony_ci src_width.full = dfixed_const(wm->src_width); 219262306a36Sopenharmony_ci bandwidth.full = dfixed_mul(src_width, bpp); 219362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, wm->vsc); 219462306a36Sopenharmony_ci bandwidth.full = dfixed_div(bandwidth, line_time); 219562306a36Sopenharmony_ci 219662306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 219762306a36Sopenharmony_ci} 219862306a36Sopenharmony_ci 219962306a36Sopenharmony_cistatic u32 dce6_latency_watermark(struct dce6_wm_params *wm) 220062306a36Sopenharmony_ci{ 220162306a36Sopenharmony_ci /* First calcualte the latency in ns */ 220262306a36Sopenharmony_ci u32 mc_latency = 2000; /* 2000 ns. */ 220362306a36Sopenharmony_ci u32 available_bandwidth = dce6_available_bandwidth(wm); 220462306a36Sopenharmony_ci u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; 220562306a36Sopenharmony_ci u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; 220662306a36Sopenharmony_ci u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ 220762306a36Sopenharmony_ci u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + 220862306a36Sopenharmony_ci (wm->num_heads * cursor_line_pair_return_time); 220962306a36Sopenharmony_ci u32 latency = mc_latency + other_heads_data_return_time + dc_latency; 221062306a36Sopenharmony_ci u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; 221162306a36Sopenharmony_ci u32 tmp, dmif_size = 12288; 221262306a36Sopenharmony_ci fixed20_12 a, b, c; 221362306a36Sopenharmony_ci 221462306a36Sopenharmony_ci if (wm->num_heads == 0) 221562306a36Sopenharmony_ci return 0; 221662306a36Sopenharmony_ci 221762306a36Sopenharmony_ci a.full = dfixed_const(2); 221862306a36Sopenharmony_ci b.full = dfixed_const(1); 221962306a36Sopenharmony_ci if ((wm->vsc.full > a.full) || 222062306a36Sopenharmony_ci ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) || 222162306a36Sopenharmony_ci (wm->vtaps >= 5) || 222262306a36Sopenharmony_ci ((wm->vsc.full >= a.full) && wm->interlaced)) 222362306a36Sopenharmony_ci max_src_lines_per_dst_line = 4; 222462306a36Sopenharmony_ci else 222562306a36Sopenharmony_ci max_src_lines_per_dst_line = 2; 222662306a36Sopenharmony_ci 222762306a36Sopenharmony_ci a.full = dfixed_const(available_bandwidth); 222862306a36Sopenharmony_ci b.full = dfixed_const(wm->num_heads); 222962306a36Sopenharmony_ci a.full = dfixed_div(a, b); 223062306a36Sopenharmony_ci tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512); 223162306a36Sopenharmony_ci tmp = min(dfixed_trunc(a), tmp); 223262306a36Sopenharmony_ci 223362306a36Sopenharmony_ci lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000); 223462306a36Sopenharmony_ci 223562306a36Sopenharmony_ci a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); 223662306a36Sopenharmony_ci b.full = dfixed_const(1000); 223762306a36Sopenharmony_ci c.full = dfixed_const(lb_fill_bw); 223862306a36Sopenharmony_ci b.full = dfixed_div(c, b); 223962306a36Sopenharmony_ci a.full = dfixed_div(a, b); 224062306a36Sopenharmony_ci line_fill_time = dfixed_trunc(a); 224162306a36Sopenharmony_ci 224262306a36Sopenharmony_ci if (line_fill_time < wm->active_time) 224362306a36Sopenharmony_ci return latency; 224462306a36Sopenharmony_ci else 224562306a36Sopenharmony_ci return latency + (line_fill_time - wm->active_time); 224662306a36Sopenharmony_ci 224762306a36Sopenharmony_ci} 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_cistatic bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm) 225062306a36Sopenharmony_ci{ 225162306a36Sopenharmony_ci if (dce6_average_bandwidth(wm) <= 225262306a36Sopenharmony_ci (dce6_dram_bandwidth_for_display(wm) / wm->num_heads)) 225362306a36Sopenharmony_ci return true; 225462306a36Sopenharmony_ci else 225562306a36Sopenharmony_ci return false; 225662306a36Sopenharmony_ci}; 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_cistatic bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm) 225962306a36Sopenharmony_ci{ 226062306a36Sopenharmony_ci if (dce6_average_bandwidth(wm) <= 226162306a36Sopenharmony_ci (dce6_available_bandwidth(wm) / wm->num_heads)) 226262306a36Sopenharmony_ci return true; 226362306a36Sopenharmony_ci else 226462306a36Sopenharmony_ci return false; 226562306a36Sopenharmony_ci}; 226662306a36Sopenharmony_ci 226762306a36Sopenharmony_cistatic bool dce6_check_latency_hiding(struct dce6_wm_params *wm) 226862306a36Sopenharmony_ci{ 226962306a36Sopenharmony_ci u32 lb_partitions = wm->lb_size / wm->src_width; 227062306a36Sopenharmony_ci u32 line_time = wm->active_time + wm->blank_time; 227162306a36Sopenharmony_ci u32 latency_tolerant_lines; 227262306a36Sopenharmony_ci u32 latency_hiding; 227362306a36Sopenharmony_ci fixed20_12 a; 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_ci a.full = dfixed_const(1); 227662306a36Sopenharmony_ci if (wm->vsc.full > a.full) 227762306a36Sopenharmony_ci latency_tolerant_lines = 1; 227862306a36Sopenharmony_ci else { 227962306a36Sopenharmony_ci if (lb_partitions <= (wm->vtaps + 1)) 228062306a36Sopenharmony_ci latency_tolerant_lines = 1; 228162306a36Sopenharmony_ci else 228262306a36Sopenharmony_ci latency_tolerant_lines = 2; 228362306a36Sopenharmony_ci } 228462306a36Sopenharmony_ci 228562306a36Sopenharmony_ci latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time); 228662306a36Sopenharmony_ci 228762306a36Sopenharmony_ci if (dce6_latency_watermark(wm) <= latency_hiding) 228862306a36Sopenharmony_ci return true; 228962306a36Sopenharmony_ci else 229062306a36Sopenharmony_ci return false; 229162306a36Sopenharmony_ci} 229262306a36Sopenharmony_ci 229362306a36Sopenharmony_cistatic void dce6_program_watermarks(struct radeon_device *rdev, 229462306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc, 229562306a36Sopenharmony_ci u32 lb_size, u32 num_heads) 229662306a36Sopenharmony_ci{ 229762306a36Sopenharmony_ci struct drm_display_mode *mode = &radeon_crtc->base.mode; 229862306a36Sopenharmony_ci struct dce6_wm_params wm_low, wm_high; 229962306a36Sopenharmony_ci u32 dram_channels; 230062306a36Sopenharmony_ci u32 active_time; 230162306a36Sopenharmony_ci u32 line_time = 0; 230262306a36Sopenharmony_ci u32 latency_watermark_a = 0, latency_watermark_b = 0; 230362306a36Sopenharmony_ci u32 priority_a_mark = 0, priority_b_mark = 0; 230462306a36Sopenharmony_ci u32 priority_a_cnt = PRIORITY_OFF; 230562306a36Sopenharmony_ci u32 priority_b_cnt = PRIORITY_OFF; 230662306a36Sopenharmony_ci u32 tmp, arb_control3; 230762306a36Sopenharmony_ci fixed20_12 a, b, c; 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ci if (radeon_crtc->base.enabled && num_heads && mode) { 231062306a36Sopenharmony_ci active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, 231162306a36Sopenharmony_ci (u32)mode->clock); 231262306a36Sopenharmony_ci line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, 231362306a36Sopenharmony_ci (u32)mode->clock); 231462306a36Sopenharmony_ci line_time = min(line_time, (u32)65535); 231562306a36Sopenharmony_ci priority_a_cnt = 0; 231662306a36Sopenharmony_ci priority_b_cnt = 0; 231762306a36Sopenharmony_ci 231862306a36Sopenharmony_ci if (rdev->family == CHIP_ARUBA) 231962306a36Sopenharmony_ci dram_channels = evergreen_get_number_of_dram_channels(rdev); 232062306a36Sopenharmony_ci else 232162306a36Sopenharmony_ci dram_channels = si_get_number_of_dram_channels(rdev); 232262306a36Sopenharmony_ci 232362306a36Sopenharmony_ci /* watermark for high clocks */ 232462306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { 232562306a36Sopenharmony_ci wm_high.yclk = 232662306a36Sopenharmony_ci radeon_dpm_get_mclk(rdev, false) * 10; 232762306a36Sopenharmony_ci wm_high.sclk = 232862306a36Sopenharmony_ci radeon_dpm_get_sclk(rdev, false) * 10; 232962306a36Sopenharmony_ci } else { 233062306a36Sopenharmony_ci wm_high.yclk = rdev->pm.current_mclk * 10; 233162306a36Sopenharmony_ci wm_high.sclk = rdev->pm.current_sclk * 10; 233262306a36Sopenharmony_ci } 233362306a36Sopenharmony_ci 233462306a36Sopenharmony_ci wm_high.disp_clk = mode->clock; 233562306a36Sopenharmony_ci wm_high.src_width = mode->crtc_hdisplay; 233662306a36Sopenharmony_ci wm_high.active_time = active_time; 233762306a36Sopenharmony_ci wm_high.blank_time = line_time - wm_high.active_time; 233862306a36Sopenharmony_ci wm_high.interlaced = false; 233962306a36Sopenharmony_ci if (mode->flags & DRM_MODE_FLAG_INTERLACE) 234062306a36Sopenharmony_ci wm_high.interlaced = true; 234162306a36Sopenharmony_ci wm_high.vsc = radeon_crtc->vsc; 234262306a36Sopenharmony_ci wm_high.vtaps = 1; 234362306a36Sopenharmony_ci if (radeon_crtc->rmx_type != RMX_OFF) 234462306a36Sopenharmony_ci wm_high.vtaps = 2; 234562306a36Sopenharmony_ci wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */ 234662306a36Sopenharmony_ci wm_high.lb_size = lb_size; 234762306a36Sopenharmony_ci wm_high.dram_channels = dram_channels; 234862306a36Sopenharmony_ci wm_high.num_heads = num_heads; 234962306a36Sopenharmony_ci 235062306a36Sopenharmony_ci /* watermark for low clocks */ 235162306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { 235262306a36Sopenharmony_ci wm_low.yclk = 235362306a36Sopenharmony_ci radeon_dpm_get_mclk(rdev, true) * 10; 235462306a36Sopenharmony_ci wm_low.sclk = 235562306a36Sopenharmony_ci radeon_dpm_get_sclk(rdev, true) * 10; 235662306a36Sopenharmony_ci } else { 235762306a36Sopenharmony_ci wm_low.yclk = rdev->pm.current_mclk * 10; 235862306a36Sopenharmony_ci wm_low.sclk = rdev->pm.current_sclk * 10; 235962306a36Sopenharmony_ci } 236062306a36Sopenharmony_ci 236162306a36Sopenharmony_ci wm_low.disp_clk = mode->clock; 236262306a36Sopenharmony_ci wm_low.src_width = mode->crtc_hdisplay; 236362306a36Sopenharmony_ci wm_low.active_time = active_time; 236462306a36Sopenharmony_ci wm_low.blank_time = line_time - wm_low.active_time; 236562306a36Sopenharmony_ci wm_low.interlaced = false; 236662306a36Sopenharmony_ci if (mode->flags & DRM_MODE_FLAG_INTERLACE) 236762306a36Sopenharmony_ci wm_low.interlaced = true; 236862306a36Sopenharmony_ci wm_low.vsc = radeon_crtc->vsc; 236962306a36Sopenharmony_ci wm_low.vtaps = 1; 237062306a36Sopenharmony_ci if (radeon_crtc->rmx_type != RMX_OFF) 237162306a36Sopenharmony_ci wm_low.vtaps = 2; 237262306a36Sopenharmony_ci wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */ 237362306a36Sopenharmony_ci wm_low.lb_size = lb_size; 237462306a36Sopenharmony_ci wm_low.dram_channels = dram_channels; 237562306a36Sopenharmony_ci wm_low.num_heads = num_heads; 237662306a36Sopenharmony_ci 237762306a36Sopenharmony_ci /* set for high clocks */ 237862306a36Sopenharmony_ci latency_watermark_a = min(dce6_latency_watermark(&wm_high), (u32)65535); 237962306a36Sopenharmony_ci /* set for low clocks */ 238062306a36Sopenharmony_ci latency_watermark_b = min(dce6_latency_watermark(&wm_low), (u32)65535); 238162306a36Sopenharmony_ci 238262306a36Sopenharmony_ci /* possibly force display priority to high */ 238362306a36Sopenharmony_ci /* should really do this at mode validation time... */ 238462306a36Sopenharmony_ci if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) || 238562306a36Sopenharmony_ci !dce6_average_bandwidth_vs_available_bandwidth(&wm_high) || 238662306a36Sopenharmony_ci !dce6_check_latency_hiding(&wm_high) || 238762306a36Sopenharmony_ci (rdev->disp_priority == 2)) { 238862306a36Sopenharmony_ci DRM_DEBUG_KMS("force priority to high\n"); 238962306a36Sopenharmony_ci priority_a_cnt |= PRIORITY_ALWAYS_ON; 239062306a36Sopenharmony_ci priority_b_cnt |= PRIORITY_ALWAYS_ON; 239162306a36Sopenharmony_ci } 239262306a36Sopenharmony_ci if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) || 239362306a36Sopenharmony_ci !dce6_average_bandwidth_vs_available_bandwidth(&wm_low) || 239462306a36Sopenharmony_ci !dce6_check_latency_hiding(&wm_low) || 239562306a36Sopenharmony_ci (rdev->disp_priority == 2)) { 239662306a36Sopenharmony_ci DRM_DEBUG_KMS("force priority to high\n"); 239762306a36Sopenharmony_ci priority_a_cnt |= PRIORITY_ALWAYS_ON; 239862306a36Sopenharmony_ci priority_b_cnt |= PRIORITY_ALWAYS_ON; 239962306a36Sopenharmony_ci } 240062306a36Sopenharmony_ci 240162306a36Sopenharmony_ci a.full = dfixed_const(1000); 240262306a36Sopenharmony_ci b.full = dfixed_const(mode->clock); 240362306a36Sopenharmony_ci b.full = dfixed_div(b, a); 240462306a36Sopenharmony_ci c.full = dfixed_const(latency_watermark_a); 240562306a36Sopenharmony_ci c.full = dfixed_mul(c, b); 240662306a36Sopenharmony_ci c.full = dfixed_mul(c, radeon_crtc->hsc); 240762306a36Sopenharmony_ci c.full = dfixed_div(c, a); 240862306a36Sopenharmony_ci a.full = dfixed_const(16); 240962306a36Sopenharmony_ci c.full = dfixed_div(c, a); 241062306a36Sopenharmony_ci priority_a_mark = dfixed_trunc(c); 241162306a36Sopenharmony_ci priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK; 241262306a36Sopenharmony_ci 241362306a36Sopenharmony_ci a.full = dfixed_const(1000); 241462306a36Sopenharmony_ci b.full = dfixed_const(mode->clock); 241562306a36Sopenharmony_ci b.full = dfixed_div(b, a); 241662306a36Sopenharmony_ci c.full = dfixed_const(latency_watermark_b); 241762306a36Sopenharmony_ci c.full = dfixed_mul(c, b); 241862306a36Sopenharmony_ci c.full = dfixed_mul(c, radeon_crtc->hsc); 241962306a36Sopenharmony_ci c.full = dfixed_div(c, a); 242062306a36Sopenharmony_ci a.full = dfixed_const(16); 242162306a36Sopenharmony_ci c.full = dfixed_div(c, a); 242262306a36Sopenharmony_ci priority_b_mark = dfixed_trunc(c); 242362306a36Sopenharmony_ci priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; 242462306a36Sopenharmony_ci 242562306a36Sopenharmony_ci /* Save number of lines the linebuffer leads before the scanout */ 242662306a36Sopenharmony_ci radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); 242762306a36Sopenharmony_ci } 242862306a36Sopenharmony_ci 242962306a36Sopenharmony_ci /* select wm A */ 243062306a36Sopenharmony_ci arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset); 243162306a36Sopenharmony_ci tmp = arb_control3; 243262306a36Sopenharmony_ci tmp &= ~LATENCY_WATERMARK_MASK(3); 243362306a36Sopenharmony_ci tmp |= LATENCY_WATERMARK_MASK(1); 243462306a36Sopenharmony_ci WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp); 243562306a36Sopenharmony_ci WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset, 243662306a36Sopenharmony_ci (LATENCY_LOW_WATERMARK(latency_watermark_a) | 243762306a36Sopenharmony_ci LATENCY_HIGH_WATERMARK(line_time))); 243862306a36Sopenharmony_ci /* select wm B */ 243962306a36Sopenharmony_ci tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset); 244062306a36Sopenharmony_ci tmp &= ~LATENCY_WATERMARK_MASK(3); 244162306a36Sopenharmony_ci tmp |= LATENCY_WATERMARK_MASK(2); 244262306a36Sopenharmony_ci WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp); 244362306a36Sopenharmony_ci WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset, 244462306a36Sopenharmony_ci (LATENCY_LOW_WATERMARK(latency_watermark_b) | 244562306a36Sopenharmony_ci LATENCY_HIGH_WATERMARK(line_time))); 244662306a36Sopenharmony_ci /* restore original selection */ 244762306a36Sopenharmony_ci WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3); 244862306a36Sopenharmony_ci 244962306a36Sopenharmony_ci /* write the priority marks */ 245062306a36Sopenharmony_ci WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt); 245162306a36Sopenharmony_ci WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt); 245262306a36Sopenharmony_ci 245362306a36Sopenharmony_ci /* save values for DPM */ 245462306a36Sopenharmony_ci radeon_crtc->line_time = line_time; 245562306a36Sopenharmony_ci radeon_crtc->wm_high = latency_watermark_a; 245662306a36Sopenharmony_ci radeon_crtc->wm_low = latency_watermark_b; 245762306a36Sopenharmony_ci} 245862306a36Sopenharmony_ci 245962306a36Sopenharmony_civoid dce6_bandwidth_update(struct radeon_device *rdev) 246062306a36Sopenharmony_ci{ 246162306a36Sopenharmony_ci struct drm_display_mode *mode0 = NULL; 246262306a36Sopenharmony_ci struct drm_display_mode *mode1 = NULL; 246362306a36Sopenharmony_ci u32 num_heads = 0, lb_size; 246462306a36Sopenharmony_ci int i; 246562306a36Sopenharmony_ci 246662306a36Sopenharmony_ci if (!rdev->mode_info.mode_config_initialized) 246762306a36Sopenharmony_ci return; 246862306a36Sopenharmony_ci 246962306a36Sopenharmony_ci radeon_update_display_priority(rdev); 247062306a36Sopenharmony_ci 247162306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 247262306a36Sopenharmony_ci if (rdev->mode_info.crtcs[i]->base.enabled) 247362306a36Sopenharmony_ci num_heads++; 247462306a36Sopenharmony_ci } 247562306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i += 2) { 247662306a36Sopenharmony_ci mode0 = &rdev->mode_info.crtcs[i]->base.mode; 247762306a36Sopenharmony_ci mode1 = &rdev->mode_info.crtcs[i+1]->base.mode; 247862306a36Sopenharmony_ci lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1); 247962306a36Sopenharmony_ci dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads); 248062306a36Sopenharmony_ci lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0); 248162306a36Sopenharmony_ci dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads); 248262306a36Sopenharmony_ci } 248362306a36Sopenharmony_ci} 248462306a36Sopenharmony_ci 248562306a36Sopenharmony_ci/* 248662306a36Sopenharmony_ci * Core functions 248762306a36Sopenharmony_ci */ 248862306a36Sopenharmony_cistatic void si_tiling_mode_table_init(struct radeon_device *rdev) 248962306a36Sopenharmony_ci{ 249062306a36Sopenharmony_ci u32 *tile = rdev->config.si.tile_mode_array; 249162306a36Sopenharmony_ci const u32 num_tile_mode_states = 249262306a36Sopenharmony_ci ARRAY_SIZE(rdev->config.si.tile_mode_array); 249362306a36Sopenharmony_ci u32 reg_offset, split_equal_to_row_size; 249462306a36Sopenharmony_ci 249562306a36Sopenharmony_ci switch (rdev->config.si.mem_row_size_in_kb) { 249662306a36Sopenharmony_ci case 1: 249762306a36Sopenharmony_ci split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB; 249862306a36Sopenharmony_ci break; 249962306a36Sopenharmony_ci case 2: 250062306a36Sopenharmony_ci default: 250162306a36Sopenharmony_ci split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB; 250262306a36Sopenharmony_ci break; 250362306a36Sopenharmony_ci case 4: 250462306a36Sopenharmony_ci split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB; 250562306a36Sopenharmony_ci break; 250662306a36Sopenharmony_ci } 250762306a36Sopenharmony_ci 250862306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 250962306a36Sopenharmony_ci tile[reg_offset] = 0; 251062306a36Sopenharmony_ci 251162306a36Sopenharmony_ci switch(rdev->family) { 251262306a36Sopenharmony_ci case CHIP_TAHITI: 251362306a36Sopenharmony_ci case CHIP_PITCAIRN: 251462306a36Sopenharmony_ci /* non-AA compressed depth or any compressed stencil */ 251562306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 251662306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 251762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 251862306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 251962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 252062306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 252162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 252262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 252362306a36Sopenharmony_ci /* 2xAA/4xAA compressed depth only */ 252462306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 252562306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 252662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 252762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | 252862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 252962306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 253062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 253162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 253262306a36Sopenharmony_ci /* 8xAA compressed depth only */ 253362306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 253462306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 253562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 253662306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 253762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 253862306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 253962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 254062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 254162306a36Sopenharmony_ci /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */ 254262306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 254362306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 254462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 254562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | 254662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 254762306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 254862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 254962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 255062306a36Sopenharmony_ci /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */ 255162306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 255262306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 255362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 255462306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 255562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 255662306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 255762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 255862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 255962306a36Sopenharmony_ci /* Uncompressed 16bpp depth - and stencil buffer allocated with it */ 256062306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 256162306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 256262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 256362306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 256462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 256562306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 256662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 256762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 256862306a36Sopenharmony_ci /* Uncompressed 32bpp depth - and stencil buffer allocated with it */ 256962306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 257062306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 257162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 257262306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 257362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 257462306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 257562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 257662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 257762306a36Sopenharmony_ci /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */ 257862306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 257962306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 258062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 258162306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 258262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 258362306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 258462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 258562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 258662306a36Sopenharmony_ci /* 1D and 1D Array Surfaces */ 258762306a36Sopenharmony_ci tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 258862306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 258962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 259062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 259162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 259262306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 259362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 259462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 259562306a36Sopenharmony_ci /* Displayable maps. */ 259662306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 259762306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 259862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 259962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 260062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 260162306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 260262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 260362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 260462306a36Sopenharmony_ci /* Display 8bpp. */ 260562306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 260662306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 260762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 260862306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 260962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 261062306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 261162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 261262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 261362306a36Sopenharmony_ci /* Display 16bpp. */ 261462306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 261562306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 261662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 261762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 261862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 261962306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 262062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 262162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 262262306a36Sopenharmony_ci /* Display 32bpp. */ 262362306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 262462306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 262562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 262662306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | 262762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 262862306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 262962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 263062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 263162306a36Sopenharmony_ci /* Thin. */ 263262306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 263362306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 263462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 263562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 263662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 263762306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 263862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 263962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 264062306a36Sopenharmony_ci /* Thin 8 bpp. */ 264162306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 264262306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 264362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 264462306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 264562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 264662306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 264762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 264862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 264962306a36Sopenharmony_ci /* Thin 16 bpp. */ 265062306a36Sopenharmony_ci tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 265162306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 265262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 265362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 265462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 265562306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 265662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 265762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 265862306a36Sopenharmony_ci /* Thin 32 bpp. */ 265962306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 266062306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 266162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 266262306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | 266362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 266462306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 266562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 266662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 266762306a36Sopenharmony_ci /* Thin 64 bpp. */ 266862306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 266962306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 267062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 267162306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 267262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 267362306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 267462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 267562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 267662306a36Sopenharmony_ci /* 8 bpp PRT. */ 267762306a36Sopenharmony_ci tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 267862306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 267962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 268062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 268162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 268262306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 268362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 268462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 268562306a36Sopenharmony_ci /* 16 bpp PRT */ 268662306a36Sopenharmony_ci tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 268762306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 268862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 268962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 269062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 269162306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 269262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 269362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 269462306a36Sopenharmony_ci /* 32 bpp PRT */ 269562306a36Sopenharmony_ci tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 269662306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 269762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 269862306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 269962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 270062306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 270162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 270262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 270362306a36Sopenharmony_ci /* 64 bpp PRT */ 270462306a36Sopenharmony_ci tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 270562306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 270662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 270762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | 270862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 270962306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 271062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 271162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 271262306a36Sopenharmony_ci /* 128 bpp PRT */ 271362306a36Sopenharmony_ci tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 271462306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 271562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 271662306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) | 271762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK) | 271862306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 271962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 272062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 272162306a36Sopenharmony_ci 272262306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 272362306a36Sopenharmony_ci WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]); 272462306a36Sopenharmony_ci break; 272562306a36Sopenharmony_ci 272662306a36Sopenharmony_ci case CHIP_VERDE: 272762306a36Sopenharmony_ci case CHIP_OLAND: 272862306a36Sopenharmony_ci case CHIP_HAINAN: 272962306a36Sopenharmony_ci /* non-AA compressed depth or any compressed stencil */ 273062306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 273162306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 273262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 273362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 273462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 273562306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 273662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 273762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 273862306a36Sopenharmony_ci /* 2xAA/4xAA compressed depth only */ 273962306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 274062306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 274162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 274262306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | 274362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 274462306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 274562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 274662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 274762306a36Sopenharmony_ci /* 8xAA compressed depth only */ 274862306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 274962306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 275062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 275162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 275262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 275362306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 275462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 275562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 275662306a36Sopenharmony_ci /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */ 275762306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 275862306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 275962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 276062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | 276162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 276262306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 276362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 276462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 276562306a36Sopenharmony_ci /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */ 276662306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 276762306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 276862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 276962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 277062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 277162306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 277262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 277362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 277462306a36Sopenharmony_ci /* Uncompressed 16bpp depth - and stencil buffer allocated with it */ 277562306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 277662306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 277762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 277862306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 277962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 278062306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 278162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 278262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 278362306a36Sopenharmony_ci /* Uncompressed 32bpp depth - and stencil buffer allocated with it */ 278462306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 278562306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 278662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 278762306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 278862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 278962306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 279062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 279162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 279262306a36Sopenharmony_ci /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */ 279362306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 279462306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) | 279562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 279662306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 279762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 279862306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 279962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 280062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 280162306a36Sopenharmony_ci /* 1D and 1D Array Surfaces */ 280262306a36Sopenharmony_ci tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 280362306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 280462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 280562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 280662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 280762306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 280862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 280962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 281062306a36Sopenharmony_ci /* Displayable maps. */ 281162306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 281262306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 281362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 281462306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 281562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 281662306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 281762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 281862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 281962306a36Sopenharmony_ci /* Display 8bpp. */ 282062306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 282162306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 282262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 282362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 282462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 282562306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 282662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 282762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 282862306a36Sopenharmony_ci /* Display 16bpp. */ 282962306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 283062306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 283162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 283262306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 283362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 283462306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 283562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 283662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 283762306a36Sopenharmony_ci /* Display 32bpp. */ 283862306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 283962306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) | 284062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 284162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | 284262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 284362306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 284462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 284562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 284662306a36Sopenharmony_ci /* Thin. */ 284762306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 284862306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 284962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 285062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | 285162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 285262306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 285362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 285462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 285562306a36Sopenharmony_ci /* Thin 8 bpp. */ 285662306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 285762306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 285862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 285962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 286062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 286162306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 286262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 286362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 286462306a36Sopenharmony_ci /* Thin 16 bpp. */ 286562306a36Sopenharmony_ci tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 286662306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 286762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 286862306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 286962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 287062306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 287162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 287262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 287362306a36Sopenharmony_ci /* Thin 32 bpp. */ 287462306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 287562306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 287662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 287762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | 287862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 287962306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 288062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 288162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 288262306a36Sopenharmony_ci /* Thin 64 bpp. */ 288362306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 288462306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 288562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 288662306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size) | 288762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 288862306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 288962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 289062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 289162306a36Sopenharmony_ci /* 8 bpp PRT. */ 289262306a36Sopenharmony_ci tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 289362306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 289462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 289562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 289662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 289762306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 289862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 289962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 290062306a36Sopenharmony_ci /* 16 bpp PRT */ 290162306a36Sopenharmony_ci tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 290262306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 290362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 290462306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 290562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 290662306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 290762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 290862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4)); 290962306a36Sopenharmony_ci /* 32 bpp PRT */ 291062306a36Sopenharmony_ci tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 291162306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 291262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 291362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | 291462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 291562306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 291662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 291762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 291862306a36Sopenharmony_ci /* 64 bpp PRT */ 291962306a36Sopenharmony_ci tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 292062306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 292162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 292262306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | 292362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK) | 292462306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 292562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 292662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2)); 292762306a36Sopenharmony_ci /* 128 bpp PRT */ 292862306a36Sopenharmony_ci tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 292962306a36Sopenharmony_ci MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) | 293062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 293162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) | 293262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK) | 293362306a36Sopenharmony_ci BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 293462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 293562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1)); 293662306a36Sopenharmony_ci 293762306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 293862306a36Sopenharmony_ci WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]); 293962306a36Sopenharmony_ci break; 294062306a36Sopenharmony_ci 294162306a36Sopenharmony_ci default: 294262306a36Sopenharmony_ci DRM_ERROR("unknown asic: 0x%x\n", rdev->family); 294362306a36Sopenharmony_ci } 294462306a36Sopenharmony_ci} 294562306a36Sopenharmony_ci 294662306a36Sopenharmony_cistatic void si_select_se_sh(struct radeon_device *rdev, 294762306a36Sopenharmony_ci u32 se_num, u32 sh_num) 294862306a36Sopenharmony_ci{ 294962306a36Sopenharmony_ci u32 data = INSTANCE_BROADCAST_WRITES; 295062306a36Sopenharmony_ci 295162306a36Sopenharmony_ci if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) 295262306a36Sopenharmony_ci data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES; 295362306a36Sopenharmony_ci else if (se_num == 0xffffffff) 295462306a36Sopenharmony_ci data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num); 295562306a36Sopenharmony_ci else if (sh_num == 0xffffffff) 295662306a36Sopenharmony_ci data |= SH_BROADCAST_WRITES | SE_INDEX(se_num); 295762306a36Sopenharmony_ci else 295862306a36Sopenharmony_ci data |= SH_INDEX(sh_num) | SE_INDEX(se_num); 295962306a36Sopenharmony_ci WREG32(GRBM_GFX_INDEX, data); 296062306a36Sopenharmony_ci} 296162306a36Sopenharmony_ci 296262306a36Sopenharmony_cistatic u32 si_create_bitmask(u32 bit_width) 296362306a36Sopenharmony_ci{ 296462306a36Sopenharmony_ci u32 i, mask = 0; 296562306a36Sopenharmony_ci 296662306a36Sopenharmony_ci for (i = 0; i < bit_width; i++) { 296762306a36Sopenharmony_ci mask <<= 1; 296862306a36Sopenharmony_ci mask |= 1; 296962306a36Sopenharmony_ci } 297062306a36Sopenharmony_ci return mask; 297162306a36Sopenharmony_ci} 297262306a36Sopenharmony_ci 297362306a36Sopenharmony_cistatic u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh) 297462306a36Sopenharmony_ci{ 297562306a36Sopenharmony_ci u32 data, mask; 297662306a36Sopenharmony_ci 297762306a36Sopenharmony_ci data = RREG32(CC_GC_SHADER_ARRAY_CONFIG); 297862306a36Sopenharmony_ci if (data & 1) 297962306a36Sopenharmony_ci data &= INACTIVE_CUS_MASK; 298062306a36Sopenharmony_ci else 298162306a36Sopenharmony_ci data = 0; 298262306a36Sopenharmony_ci data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG); 298362306a36Sopenharmony_ci 298462306a36Sopenharmony_ci data >>= INACTIVE_CUS_SHIFT; 298562306a36Sopenharmony_ci 298662306a36Sopenharmony_ci mask = si_create_bitmask(cu_per_sh); 298762306a36Sopenharmony_ci 298862306a36Sopenharmony_ci return ~data & mask; 298962306a36Sopenharmony_ci} 299062306a36Sopenharmony_ci 299162306a36Sopenharmony_cistatic void si_setup_spi(struct radeon_device *rdev, 299262306a36Sopenharmony_ci u32 se_num, u32 sh_per_se, 299362306a36Sopenharmony_ci u32 cu_per_sh) 299462306a36Sopenharmony_ci{ 299562306a36Sopenharmony_ci int i, j, k; 299662306a36Sopenharmony_ci u32 data, mask, active_cu; 299762306a36Sopenharmony_ci 299862306a36Sopenharmony_ci for (i = 0; i < se_num; i++) { 299962306a36Sopenharmony_ci for (j = 0; j < sh_per_se; j++) { 300062306a36Sopenharmony_ci si_select_se_sh(rdev, i, j); 300162306a36Sopenharmony_ci data = RREG32(SPI_STATIC_THREAD_MGMT_3); 300262306a36Sopenharmony_ci active_cu = si_get_cu_enabled(rdev, cu_per_sh); 300362306a36Sopenharmony_ci 300462306a36Sopenharmony_ci mask = 1; 300562306a36Sopenharmony_ci for (k = 0; k < 16; k++) { 300662306a36Sopenharmony_ci mask <<= k; 300762306a36Sopenharmony_ci if (active_cu & mask) { 300862306a36Sopenharmony_ci data &= ~mask; 300962306a36Sopenharmony_ci WREG32(SPI_STATIC_THREAD_MGMT_3, data); 301062306a36Sopenharmony_ci break; 301162306a36Sopenharmony_ci } 301262306a36Sopenharmony_ci } 301362306a36Sopenharmony_ci } 301462306a36Sopenharmony_ci } 301562306a36Sopenharmony_ci si_select_se_sh(rdev, 0xffffffff, 0xffffffff); 301662306a36Sopenharmony_ci} 301762306a36Sopenharmony_ci 301862306a36Sopenharmony_cistatic u32 si_get_rb_disabled(struct radeon_device *rdev, 301962306a36Sopenharmony_ci u32 max_rb_num_per_se, 302062306a36Sopenharmony_ci u32 sh_per_se) 302162306a36Sopenharmony_ci{ 302262306a36Sopenharmony_ci u32 data, mask; 302362306a36Sopenharmony_ci 302462306a36Sopenharmony_ci data = RREG32(CC_RB_BACKEND_DISABLE); 302562306a36Sopenharmony_ci if (data & 1) 302662306a36Sopenharmony_ci data &= BACKEND_DISABLE_MASK; 302762306a36Sopenharmony_ci else 302862306a36Sopenharmony_ci data = 0; 302962306a36Sopenharmony_ci data |= RREG32(GC_USER_RB_BACKEND_DISABLE); 303062306a36Sopenharmony_ci 303162306a36Sopenharmony_ci data >>= BACKEND_DISABLE_SHIFT; 303262306a36Sopenharmony_ci 303362306a36Sopenharmony_ci mask = si_create_bitmask(max_rb_num_per_se / sh_per_se); 303462306a36Sopenharmony_ci 303562306a36Sopenharmony_ci return data & mask; 303662306a36Sopenharmony_ci} 303762306a36Sopenharmony_ci 303862306a36Sopenharmony_cistatic void si_setup_rb(struct radeon_device *rdev, 303962306a36Sopenharmony_ci u32 se_num, u32 sh_per_se, 304062306a36Sopenharmony_ci u32 max_rb_num_per_se) 304162306a36Sopenharmony_ci{ 304262306a36Sopenharmony_ci int i, j; 304362306a36Sopenharmony_ci u32 data, mask; 304462306a36Sopenharmony_ci u32 disabled_rbs = 0; 304562306a36Sopenharmony_ci u32 enabled_rbs = 0; 304662306a36Sopenharmony_ci 304762306a36Sopenharmony_ci for (i = 0; i < se_num; i++) { 304862306a36Sopenharmony_ci for (j = 0; j < sh_per_se; j++) { 304962306a36Sopenharmony_ci si_select_se_sh(rdev, i, j); 305062306a36Sopenharmony_ci data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); 305162306a36Sopenharmony_ci disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH); 305262306a36Sopenharmony_ci } 305362306a36Sopenharmony_ci } 305462306a36Sopenharmony_ci si_select_se_sh(rdev, 0xffffffff, 0xffffffff); 305562306a36Sopenharmony_ci 305662306a36Sopenharmony_ci mask = 1; 305762306a36Sopenharmony_ci for (i = 0; i < max_rb_num_per_se * se_num; i++) { 305862306a36Sopenharmony_ci if (!(disabled_rbs & mask)) 305962306a36Sopenharmony_ci enabled_rbs |= mask; 306062306a36Sopenharmony_ci mask <<= 1; 306162306a36Sopenharmony_ci } 306262306a36Sopenharmony_ci 306362306a36Sopenharmony_ci rdev->config.si.backend_enable_mask = enabled_rbs; 306462306a36Sopenharmony_ci 306562306a36Sopenharmony_ci for (i = 0; i < se_num; i++) { 306662306a36Sopenharmony_ci si_select_se_sh(rdev, i, 0xffffffff); 306762306a36Sopenharmony_ci data = 0; 306862306a36Sopenharmony_ci for (j = 0; j < sh_per_se; j++) { 306962306a36Sopenharmony_ci switch (enabled_rbs & 3) { 307062306a36Sopenharmony_ci case 1: 307162306a36Sopenharmony_ci data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); 307262306a36Sopenharmony_ci break; 307362306a36Sopenharmony_ci case 2: 307462306a36Sopenharmony_ci data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2); 307562306a36Sopenharmony_ci break; 307662306a36Sopenharmony_ci case 3: 307762306a36Sopenharmony_ci default: 307862306a36Sopenharmony_ci data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2); 307962306a36Sopenharmony_ci break; 308062306a36Sopenharmony_ci } 308162306a36Sopenharmony_ci enabled_rbs >>= 2; 308262306a36Sopenharmony_ci } 308362306a36Sopenharmony_ci WREG32(PA_SC_RASTER_CONFIG, data); 308462306a36Sopenharmony_ci } 308562306a36Sopenharmony_ci si_select_se_sh(rdev, 0xffffffff, 0xffffffff); 308662306a36Sopenharmony_ci} 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_cistatic void si_gpu_init(struct radeon_device *rdev) 308962306a36Sopenharmony_ci{ 309062306a36Sopenharmony_ci u32 gb_addr_config = 0; 309162306a36Sopenharmony_ci u32 mc_arb_ramcfg; 309262306a36Sopenharmony_ci u32 sx_debug_1; 309362306a36Sopenharmony_ci u32 hdp_host_path_cntl; 309462306a36Sopenharmony_ci u32 tmp; 309562306a36Sopenharmony_ci int i, j; 309662306a36Sopenharmony_ci 309762306a36Sopenharmony_ci switch (rdev->family) { 309862306a36Sopenharmony_ci case CHIP_TAHITI: 309962306a36Sopenharmony_ci rdev->config.si.max_shader_engines = 2; 310062306a36Sopenharmony_ci rdev->config.si.max_tile_pipes = 12; 310162306a36Sopenharmony_ci rdev->config.si.max_cu_per_sh = 8; 310262306a36Sopenharmony_ci rdev->config.si.max_sh_per_se = 2; 310362306a36Sopenharmony_ci rdev->config.si.max_backends_per_se = 4; 310462306a36Sopenharmony_ci rdev->config.si.max_texture_channel_caches = 12; 310562306a36Sopenharmony_ci rdev->config.si.max_gprs = 256; 310662306a36Sopenharmony_ci rdev->config.si.max_gs_threads = 32; 310762306a36Sopenharmony_ci rdev->config.si.max_hw_contexts = 8; 310862306a36Sopenharmony_ci 310962306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_frontend = 0x20; 311062306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_backend = 0x100; 311162306a36Sopenharmony_ci rdev->config.si.sc_hiz_tile_fifo_size = 0x30; 311262306a36Sopenharmony_ci rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; 311362306a36Sopenharmony_ci gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN; 311462306a36Sopenharmony_ci break; 311562306a36Sopenharmony_ci case CHIP_PITCAIRN: 311662306a36Sopenharmony_ci rdev->config.si.max_shader_engines = 2; 311762306a36Sopenharmony_ci rdev->config.si.max_tile_pipes = 8; 311862306a36Sopenharmony_ci rdev->config.si.max_cu_per_sh = 5; 311962306a36Sopenharmony_ci rdev->config.si.max_sh_per_se = 2; 312062306a36Sopenharmony_ci rdev->config.si.max_backends_per_se = 4; 312162306a36Sopenharmony_ci rdev->config.si.max_texture_channel_caches = 8; 312262306a36Sopenharmony_ci rdev->config.si.max_gprs = 256; 312362306a36Sopenharmony_ci rdev->config.si.max_gs_threads = 32; 312462306a36Sopenharmony_ci rdev->config.si.max_hw_contexts = 8; 312562306a36Sopenharmony_ci 312662306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_frontend = 0x20; 312762306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_backend = 0x100; 312862306a36Sopenharmony_ci rdev->config.si.sc_hiz_tile_fifo_size = 0x30; 312962306a36Sopenharmony_ci rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; 313062306a36Sopenharmony_ci gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN; 313162306a36Sopenharmony_ci break; 313262306a36Sopenharmony_ci case CHIP_VERDE: 313362306a36Sopenharmony_ci default: 313462306a36Sopenharmony_ci rdev->config.si.max_shader_engines = 1; 313562306a36Sopenharmony_ci rdev->config.si.max_tile_pipes = 4; 313662306a36Sopenharmony_ci rdev->config.si.max_cu_per_sh = 5; 313762306a36Sopenharmony_ci rdev->config.si.max_sh_per_se = 2; 313862306a36Sopenharmony_ci rdev->config.si.max_backends_per_se = 4; 313962306a36Sopenharmony_ci rdev->config.si.max_texture_channel_caches = 4; 314062306a36Sopenharmony_ci rdev->config.si.max_gprs = 256; 314162306a36Sopenharmony_ci rdev->config.si.max_gs_threads = 32; 314262306a36Sopenharmony_ci rdev->config.si.max_hw_contexts = 8; 314362306a36Sopenharmony_ci 314462306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_frontend = 0x20; 314562306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_backend = 0x40; 314662306a36Sopenharmony_ci rdev->config.si.sc_hiz_tile_fifo_size = 0x30; 314762306a36Sopenharmony_ci rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; 314862306a36Sopenharmony_ci gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; 314962306a36Sopenharmony_ci break; 315062306a36Sopenharmony_ci case CHIP_OLAND: 315162306a36Sopenharmony_ci rdev->config.si.max_shader_engines = 1; 315262306a36Sopenharmony_ci rdev->config.si.max_tile_pipes = 4; 315362306a36Sopenharmony_ci rdev->config.si.max_cu_per_sh = 6; 315462306a36Sopenharmony_ci rdev->config.si.max_sh_per_se = 1; 315562306a36Sopenharmony_ci rdev->config.si.max_backends_per_se = 2; 315662306a36Sopenharmony_ci rdev->config.si.max_texture_channel_caches = 4; 315762306a36Sopenharmony_ci rdev->config.si.max_gprs = 256; 315862306a36Sopenharmony_ci rdev->config.si.max_gs_threads = 16; 315962306a36Sopenharmony_ci rdev->config.si.max_hw_contexts = 8; 316062306a36Sopenharmony_ci 316162306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_frontend = 0x20; 316262306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_backend = 0x40; 316362306a36Sopenharmony_ci rdev->config.si.sc_hiz_tile_fifo_size = 0x30; 316462306a36Sopenharmony_ci rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; 316562306a36Sopenharmony_ci gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN; 316662306a36Sopenharmony_ci break; 316762306a36Sopenharmony_ci case CHIP_HAINAN: 316862306a36Sopenharmony_ci rdev->config.si.max_shader_engines = 1; 316962306a36Sopenharmony_ci rdev->config.si.max_tile_pipes = 4; 317062306a36Sopenharmony_ci rdev->config.si.max_cu_per_sh = 5; 317162306a36Sopenharmony_ci rdev->config.si.max_sh_per_se = 1; 317262306a36Sopenharmony_ci rdev->config.si.max_backends_per_se = 1; 317362306a36Sopenharmony_ci rdev->config.si.max_texture_channel_caches = 2; 317462306a36Sopenharmony_ci rdev->config.si.max_gprs = 256; 317562306a36Sopenharmony_ci rdev->config.si.max_gs_threads = 16; 317662306a36Sopenharmony_ci rdev->config.si.max_hw_contexts = 8; 317762306a36Sopenharmony_ci 317862306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_frontend = 0x20; 317962306a36Sopenharmony_ci rdev->config.si.sc_prim_fifo_size_backend = 0x40; 318062306a36Sopenharmony_ci rdev->config.si.sc_hiz_tile_fifo_size = 0x30; 318162306a36Sopenharmony_ci rdev->config.si.sc_earlyz_tile_fifo_size = 0x130; 318262306a36Sopenharmony_ci gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN; 318362306a36Sopenharmony_ci break; 318462306a36Sopenharmony_ci } 318562306a36Sopenharmony_ci 318662306a36Sopenharmony_ci /* Initialize HDP */ 318762306a36Sopenharmony_ci for (i = 0, j = 0; i < 32; i++, j += 0x18) { 318862306a36Sopenharmony_ci WREG32((0x2c14 + j), 0x00000000); 318962306a36Sopenharmony_ci WREG32((0x2c18 + j), 0x00000000); 319062306a36Sopenharmony_ci WREG32((0x2c1c + j), 0x00000000); 319162306a36Sopenharmony_ci WREG32((0x2c20 + j), 0x00000000); 319262306a36Sopenharmony_ci WREG32((0x2c24 + j), 0x00000000); 319362306a36Sopenharmony_ci } 319462306a36Sopenharmony_ci 319562306a36Sopenharmony_ci WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); 319662306a36Sopenharmony_ci WREG32(SRBM_INT_CNTL, 1); 319762306a36Sopenharmony_ci WREG32(SRBM_INT_ACK, 1); 319862306a36Sopenharmony_ci 319962306a36Sopenharmony_ci evergreen_fix_pci_max_read_req_size(rdev); 320062306a36Sopenharmony_ci 320162306a36Sopenharmony_ci WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); 320262306a36Sopenharmony_ci 320362306a36Sopenharmony_ci RREG32(MC_SHARED_CHMAP); 320462306a36Sopenharmony_ci mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); 320562306a36Sopenharmony_ci 320662306a36Sopenharmony_ci rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes; 320762306a36Sopenharmony_ci rdev->config.si.mem_max_burst_length_bytes = 256; 320862306a36Sopenharmony_ci tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; 320962306a36Sopenharmony_ci rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; 321062306a36Sopenharmony_ci if (rdev->config.si.mem_row_size_in_kb > 4) 321162306a36Sopenharmony_ci rdev->config.si.mem_row_size_in_kb = 4; 321262306a36Sopenharmony_ci /* XXX use MC settings? */ 321362306a36Sopenharmony_ci rdev->config.si.shader_engine_tile_size = 32; 321462306a36Sopenharmony_ci rdev->config.si.num_gpus = 1; 321562306a36Sopenharmony_ci rdev->config.si.multi_gpu_tile_size = 64; 321662306a36Sopenharmony_ci 321762306a36Sopenharmony_ci /* fix up row size */ 321862306a36Sopenharmony_ci gb_addr_config &= ~ROW_SIZE_MASK; 321962306a36Sopenharmony_ci switch (rdev->config.si.mem_row_size_in_kb) { 322062306a36Sopenharmony_ci case 1: 322162306a36Sopenharmony_ci default: 322262306a36Sopenharmony_ci gb_addr_config |= ROW_SIZE(0); 322362306a36Sopenharmony_ci break; 322462306a36Sopenharmony_ci case 2: 322562306a36Sopenharmony_ci gb_addr_config |= ROW_SIZE(1); 322662306a36Sopenharmony_ci break; 322762306a36Sopenharmony_ci case 4: 322862306a36Sopenharmony_ci gb_addr_config |= ROW_SIZE(2); 322962306a36Sopenharmony_ci break; 323062306a36Sopenharmony_ci } 323162306a36Sopenharmony_ci 323262306a36Sopenharmony_ci /* setup tiling info dword. gb_addr_config is not adequate since it does 323362306a36Sopenharmony_ci * not have bank info, so create a custom tiling dword. 323462306a36Sopenharmony_ci * bits 3:0 num_pipes 323562306a36Sopenharmony_ci * bits 7:4 num_banks 323662306a36Sopenharmony_ci * bits 11:8 group_size 323762306a36Sopenharmony_ci * bits 15:12 row_size 323862306a36Sopenharmony_ci */ 323962306a36Sopenharmony_ci rdev->config.si.tile_config = 0; 324062306a36Sopenharmony_ci switch (rdev->config.si.num_tile_pipes) { 324162306a36Sopenharmony_ci case 1: 324262306a36Sopenharmony_ci rdev->config.si.tile_config |= (0 << 0); 324362306a36Sopenharmony_ci break; 324462306a36Sopenharmony_ci case 2: 324562306a36Sopenharmony_ci rdev->config.si.tile_config |= (1 << 0); 324662306a36Sopenharmony_ci break; 324762306a36Sopenharmony_ci case 4: 324862306a36Sopenharmony_ci rdev->config.si.tile_config |= (2 << 0); 324962306a36Sopenharmony_ci break; 325062306a36Sopenharmony_ci case 8: 325162306a36Sopenharmony_ci default: 325262306a36Sopenharmony_ci /* XXX what about 12? */ 325362306a36Sopenharmony_ci rdev->config.si.tile_config |= (3 << 0); 325462306a36Sopenharmony_ci break; 325562306a36Sopenharmony_ci } 325662306a36Sopenharmony_ci switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { 325762306a36Sopenharmony_ci case 0: /* four banks */ 325862306a36Sopenharmony_ci rdev->config.si.tile_config |= 0 << 4; 325962306a36Sopenharmony_ci break; 326062306a36Sopenharmony_ci case 1: /* eight banks */ 326162306a36Sopenharmony_ci rdev->config.si.tile_config |= 1 << 4; 326262306a36Sopenharmony_ci break; 326362306a36Sopenharmony_ci case 2: /* sixteen banks */ 326462306a36Sopenharmony_ci default: 326562306a36Sopenharmony_ci rdev->config.si.tile_config |= 2 << 4; 326662306a36Sopenharmony_ci break; 326762306a36Sopenharmony_ci } 326862306a36Sopenharmony_ci rdev->config.si.tile_config |= 326962306a36Sopenharmony_ci ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; 327062306a36Sopenharmony_ci rdev->config.si.tile_config |= 327162306a36Sopenharmony_ci ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; 327262306a36Sopenharmony_ci 327362306a36Sopenharmony_ci WREG32(GB_ADDR_CONFIG, gb_addr_config); 327462306a36Sopenharmony_ci WREG32(DMIF_ADDR_CONFIG, gb_addr_config); 327562306a36Sopenharmony_ci WREG32(DMIF_ADDR_CALC, gb_addr_config); 327662306a36Sopenharmony_ci WREG32(HDP_ADDR_CONFIG, gb_addr_config); 327762306a36Sopenharmony_ci WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); 327862306a36Sopenharmony_ci WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); 327962306a36Sopenharmony_ci if (rdev->has_uvd) { 328062306a36Sopenharmony_ci WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); 328162306a36Sopenharmony_ci WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); 328262306a36Sopenharmony_ci WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); 328362306a36Sopenharmony_ci } 328462306a36Sopenharmony_ci 328562306a36Sopenharmony_ci si_tiling_mode_table_init(rdev); 328662306a36Sopenharmony_ci 328762306a36Sopenharmony_ci si_setup_rb(rdev, rdev->config.si.max_shader_engines, 328862306a36Sopenharmony_ci rdev->config.si.max_sh_per_se, 328962306a36Sopenharmony_ci rdev->config.si.max_backends_per_se); 329062306a36Sopenharmony_ci 329162306a36Sopenharmony_ci si_setup_spi(rdev, rdev->config.si.max_shader_engines, 329262306a36Sopenharmony_ci rdev->config.si.max_sh_per_se, 329362306a36Sopenharmony_ci rdev->config.si.max_cu_per_sh); 329462306a36Sopenharmony_ci 329562306a36Sopenharmony_ci rdev->config.si.active_cus = 0; 329662306a36Sopenharmony_ci for (i = 0; i < rdev->config.si.max_shader_engines; i++) { 329762306a36Sopenharmony_ci for (j = 0; j < rdev->config.si.max_sh_per_se; j++) { 329862306a36Sopenharmony_ci rdev->config.si.active_cus += 329962306a36Sopenharmony_ci hweight32(si_get_cu_active_bitmap(rdev, i, j)); 330062306a36Sopenharmony_ci } 330162306a36Sopenharmony_ci } 330262306a36Sopenharmony_ci 330362306a36Sopenharmony_ci /* set HW defaults for 3D engine */ 330462306a36Sopenharmony_ci WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | 330562306a36Sopenharmony_ci ROQ_IB2_START(0x2b))); 330662306a36Sopenharmony_ci WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); 330762306a36Sopenharmony_ci 330862306a36Sopenharmony_ci sx_debug_1 = RREG32(SX_DEBUG_1); 330962306a36Sopenharmony_ci WREG32(SX_DEBUG_1, sx_debug_1); 331062306a36Sopenharmony_ci 331162306a36Sopenharmony_ci WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); 331262306a36Sopenharmony_ci 331362306a36Sopenharmony_ci WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) | 331462306a36Sopenharmony_ci SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) | 331562306a36Sopenharmony_ci SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) | 331662306a36Sopenharmony_ci SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size))); 331762306a36Sopenharmony_ci 331862306a36Sopenharmony_ci WREG32(VGT_NUM_INSTANCES, 1); 331962306a36Sopenharmony_ci 332062306a36Sopenharmony_ci WREG32(CP_PERFMON_CNTL, 0); 332162306a36Sopenharmony_ci 332262306a36Sopenharmony_ci WREG32(SQ_CONFIG, 0); 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_ci WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | 332562306a36Sopenharmony_ci FORCE_EOV_MAX_REZ_CNT(255))); 332662306a36Sopenharmony_ci 332762306a36Sopenharmony_ci WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) | 332862306a36Sopenharmony_ci AUTO_INVLD_EN(ES_AND_GS_AUTO)); 332962306a36Sopenharmony_ci 333062306a36Sopenharmony_ci WREG32(VGT_GS_VERTEX_REUSE, 16); 333162306a36Sopenharmony_ci WREG32(PA_SC_LINE_STIPPLE_STATE, 0); 333262306a36Sopenharmony_ci 333362306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER0_SELECT0, 0); 333462306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER0_SELECT1, 0); 333562306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER1_SELECT0, 0); 333662306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER1_SELECT1, 0); 333762306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER2_SELECT0, 0); 333862306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER2_SELECT1, 0); 333962306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER3_SELECT0, 0); 334062306a36Sopenharmony_ci WREG32(CB_PERFCOUNTER3_SELECT1, 0); 334162306a36Sopenharmony_ci 334262306a36Sopenharmony_ci tmp = RREG32(HDP_MISC_CNTL); 334362306a36Sopenharmony_ci tmp |= HDP_FLUSH_INVALIDATE_CACHE; 334462306a36Sopenharmony_ci WREG32(HDP_MISC_CNTL, tmp); 334562306a36Sopenharmony_ci 334662306a36Sopenharmony_ci hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); 334762306a36Sopenharmony_ci WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 334862306a36Sopenharmony_ci 334962306a36Sopenharmony_ci WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); 335062306a36Sopenharmony_ci 335162306a36Sopenharmony_ci udelay(50); 335262306a36Sopenharmony_ci} 335362306a36Sopenharmony_ci 335462306a36Sopenharmony_ci/* 335562306a36Sopenharmony_ci * GPU scratch registers helpers function. 335662306a36Sopenharmony_ci */ 335762306a36Sopenharmony_cistatic void si_scratch_init(struct radeon_device *rdev) 335862306a36Sopenharmony_ci{ 335962306a36Sopenharmony_ci int i; 336062306a36Sopenharmony_ci 336162306a36Sopenharmony_ci rdev->scratch.num_reg = 7; 336262306a36Sopenharmony_ci rdev->scratch.reg_base = SCRATCH_REG0; 336362306a36Sopenharmony_ci for (i = 0; i < rdev->scratch.num_reg; i++) { 336462306a36Sopenharmony_ci rdev->scratch.free[i] = true; 336562306a36Sopenharmony_ci rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); 336662306a36Sopenharmony_ci } 336762306a36Sopenharmony_ci} 336862306a36Sopenharmony_ci 336962306a36Sopenharmony_civoid si_fence_ring_emit(struct radeon_device *rdev, 337062306a36Sopenharmony_ci struct radeon_fence *fence) 337162306a36Sopenharmony_ci{ 337262306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[fence->ring]; 337362306a36Sopenharmony_ci u64 addr = rdev->fence_drv[fence->ring].gpu_addr; 337462306a36Sopenharmony_ci 337562306a36Sopenharmony_ci /* flush read cache over gart */ 337662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 337762306a36Sopenharmony_ci radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); 337862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 337962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); 338062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | 338162306a36Sopenharmony_ci PACKET3_TC_ACTION_ENA | 338262306a36Sopenharmony_ci PACKET3_SH_KCACHE_ACTION_ENA | 338362306a36Sopenharmony_ci PACKET3_SH_ICACHE_ACTION_ENA); 338462306a36Sopenharmony_ci radeon_ring_write(ring, 0xFFFFFFFF); 338562306a36Sopenharmony_ci radeon_ring_write(ring, 0); 338662306a36Sopenharmony_ci radeon_ring_write(ring, 10); /* poll interval */ 338762306a36Sopenharmony_ci /* EVENT_WRITE_EOP - flush caches, send int */ 338862306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); 338962306a36Sopenharmony_ci radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5)); 339062306a36Sopenharmony_ci radeon_ring_write(ring, lower_32_bits(addr)); 339162306a36Sopenharmony_ci radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2)); 339262306a36Sopenharmony_ci radeon_ring_write(ring, fence->seq); 339362306a36Sopenharmony_ci radeon_ring_write(ring, 0); 339462306a36Sopenharmony_ci} 339562306a36Sopenharmony_ci 339662306a36Sopenharmony_ci/* 339762306a36Sopenharmony_ci * IB stuff 339862306a36Sopenharmony_ci */ 339962306a36Sopenharmony_civoid si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 340062306a36Sopenharmony_ci{ 340162306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[ib->ring]; 340262306a36Sopenharmony_ci unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; 340362306a36Sopenharmony_ci u32 header; 340462306a36Sopenharmony_ci 340562306a36Sopenharmony_ci if (ib->is_const_ib) { 340662306a36Sopenharmony_ci /* set switch buffer packet before const IB */ 340762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); 340862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 340962306a36Sopenharmony_ci 341062306a36Sopenharmony_ci header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); 341162306a36Sopenharmony_ci } else { 341262306a36Sopenharmony_ci u32 next_rptr; 341362306a36Sopenharmony_ci if (ring->rptr_save_reg) { 341462306a36Sopenharmony_ci next_rptr = ring->wptr + 3 + 4 + 8; 341562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 341662306a36Sopenharmony_ci radeon_ring_write(ring, ((ring->rptr_save_reg - 341762306a36Sopenharmony_ci PACKET3_SET_CONFIG_REG_START) >> 2)); 341862306a36Sopenharmony_ci radeon_ring_write(ring, next_rptr); 341962306a36Sopenharmony_ci } else if (rdev->wb.enabled) { 342062306a36Sopenharmony_ci next_rptr = ring->wptr + 5 + 4 + 8; 342162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 342262306a36Sopenharmony_ci radeon_ring_write(ring, (1 << 8)); 342362306a36Sopenharmony_ci radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); 342462306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr)); 342562306a36Sopenharmony_ci radeon_ring_write(ring, next_rptr); 342662306a36Sopenharmony_ci } 342762306a36Sopenharmony_ci 342862306a36Sopenharmony_ci header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); 342962306a36Sopenharmony_ci } 343062306a36Sopenharmony_ci 343162306a36Sopenharmony_ci radeon_ring_write(ring, header); 343262306a36Sopenharmony_ci radeon_ring_write(ring, 343362306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 343462306a36Sopenharmony_ci (2 << 0) | 343562306a36Sopenharmony_ci#endif 343662306a36Sopenharmony_ci (ib->gpu_addr & 0xFFFFFFFC)); 343762306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); 343862306a36Sopenharmony_ci radeon_ring_write(ring, ib->length_dw | (vm_id << 24)); 343962306a36Sopenharmony_ci 344062306a36Sopenharmony_ci if (!ib->is_const_ib) { 344162306a36Sopenharmony_ci /* flush read cache over gart for this vmid */ 344262306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 344362306a36Sopenharmony_ci radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2); 344462306a36Sopenharmony_ci radeon_ring_write(ring, vm_id); 344562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3)); 344662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA | 344762306a36Sopenharmony_ci PACKET3_TC_ACTION_ENA | 344862306a36Sopenharmony_ci PACKET3_SH_KCACHE_ACTION_ENA | 344962306a36Sopenharmony_ci PACKET3_SH_ICACHE_ACTION_ENA); 345062306a36Sopenharmony_ci radeon_ring_write(ring, 0xFFFFFFFF); 345162306a36Sopenharmony_ci radeon_ring_write(ring, 0); 345262306a36Sopenharmony_ci radeon_ring_write(ring, 10); /* poll interval */ 345362306a36Sopenharmony_ci } 345462306a36Sopenharmony_ci} 345562306a36Sopenharmony_ci 345662306a36Sopenharmony_ci/* 345762306a36Sopenharmony_ci * CP. 345862306a36Sopenharmony_ci */ 345962306a36Sopenharmony_cistatic void si_cp_enable(struct radeon_device *rdev, bool enable) 346062306a36Sopenharmony_ci{ 346162306a36Sopenharmony_ci if (enable) 346262306a36Sopenharmony_ci WREG32(CP_ME_CNTL, 0); 346362306a36Sopenharmony_ci else { 346462306a36Sopenharmony_ci if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) 346562306a36Sopenharmony_ci radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); 346662306a36Sopenharmony_ci WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT)); 346762306a36Sopenharmony_ci WREG32(SCRATCH_UMSK, 0); 346862306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 346962306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 347062306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; 347162306a36Sopenharmony_ci } 347262306a36Sopenharmony_ci udelay(50); 347362306a36Sopenharmony_ci} 347462306a36Sopenharmony_ci 347562306a36Sopenharmony_cistatic int si_cp_load_microcode(struct radeon_device *rdev) 347662306a36Sopenharmony_ci{ 347762306a36Sopenharmony_ci int i; 347862306a36Sopenharmony_ci 347962306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw) 348062306a36Sopenharmony_ci return -EINVAL; 348162306a36Sopenharmony_ci 348262306a36Sopenharmony_ci si_cp_enable(rdev, false); 348362306a36Sopenharmony_ci 348462306a36Sopenharmony_ci if (rdev->new_fw) { 348562306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *pfp_hdr = 348662306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data; 348762306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *ce_hdr = 348862306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data; 348962306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *me_hdr = 349062306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data; 349162306a36Sopenharmony_ci const __le32 *fw_data; 349262306a36Sopenharmony_ci u32 fw_size; 349362306a36Sopenharmony_ci 349462306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&pfp_hdr->header); 349562306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&ce_hdr->header); 349662306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&me_hdr->header); 349762306a36Sopenharmony_ci 349862306a36Sopenharmony_ci /* PFP */ 349962306a36Sopenharmony_ci fw_data = (const __le32 *) 350062306a36Sopenharmony_ci (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes)); 350162306a36Sopenharmony_ci fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4; 350262306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 350362306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 350462306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++)); 350562306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 350662306a36Sopenharmony_ci 350762306a36Sopenharmony_ci /* CE */ 350862306a36Sopenharmony_ci fw_data = (const __le32 *) 350962306a36Sopenharmony_ci (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes)); 351062306a36Sopenharmony_ci fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4; 351162306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 351262306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 351362306a36Sopenharmony_ci WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++)); 351462306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 351562306a36Sopenharmony_ci 351662306a36Sopenharmony_ci /* ME */ 351762306a36Sopenharmony_ci fw_data = (const __be32 *) 351862306a36Sopenharmony_ci (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes)); 351962306a36Sopenharmony_ci fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4; 352062306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 352162306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 352262306a36Sopenharmony_ci WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++)); 352362306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 352462306a36Sopenharmony_ci } else { 352562306a36Sopenharmony_ci const __be32 *fw_data; 352662306a36Sopenharmony_ci 352762306a36Sopenharmony_ci /* PFP */ 352862306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->pfp_fw->data; 352962306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 353062306a36Sopenharmony_ci for (i = 0; i < SI_PFP_UCODE_SIZE; i++) 353162306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); 353262306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 353362306a36Sopenharmony_ci 353462306a36Sopenharmony_ci /* CE */ 353562306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->ce_fw->data; 353662306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 353762306a36Sopenharmony_ci for (i = 0; i < SI_CE_UCODE_SIZE; i++) 353862306a36Sopenharmony_ci WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++)); 353962306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 354062306a36Sopenharmony_ci 354162306a36Sopenharmony_ci /* ME */ 354262306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->me_fw->data; 354362306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 354462306a36Sopenharmony_ci for (i = 0; i < SI_PM4_UCODE_SIZE; i++) 354562306a36Sopenharmony_ci WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); 354662306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 354762306a36Sopenharmony_ci } 354862306a36Sopenharmony_ci 354962306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 355062306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 355162306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 355262306a36Sopenharmony_ci WREG32(CP_ME_RAM_RADDR, 0); 355362306a36Sopenharmony_ci return 0; 355462306a36Sopenharmony_ci} 355562306a36Sopenharmony_ci 355662306a36Sopenharmony_cistatic int si_cp_start(struct radeon_device *rdev) 355762306a36Sopenharmony_ci{ 355862306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 355962306a36Sopenharmony_ci int r, i; 356062306a36Sopenharmony_ci 356162306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, 7 + 4); 356262306a36Sopenharmony_ci if (r) { 356362306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 356462306a36Sopenharmony_ci return r; 356562306a36Sopenharmony_ci } 356662306a36Sopenharmony_ci /* init the CP */ 356762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); 356862306a36Sopenharmony_ci radeon_ring_write(ring, 0x1); 356962306a36Sopenharmony_ci radeon_ring_write(ring, 0x0); 357062306a36Sopenharmony_ci radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1); 357162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); 357262306a36Sopenharmony_ci radeon_ring_write(ring, 0); 357362306a36Sopenharmony_ci radeon_ring_write(ring, 0); 357462306a36Sopenharmony_ci 357562306a36Sopenharmony_ci /* init the CE partitions */ 357662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2)); 357762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); 357862306a36Sopenharmony_ci radeon_ring_write(ring, 0xc000); 357962306a36Sopenharmony_ci radeon_ring_write(ring, 0xe000); 358062306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 358162306a36Sopenharmony_ci 358262306a36Sopenharmony_ci si_cp_enable(rdev, true); 358362306a36Sopenharmony_ci 358462306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, si_default_size + 10); 358562306a36Sopenharmony_ci if (r) { 358662306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 358762306a36Sopenharmony_ci return r; 358862306a36Sopenharmony_ci } 358962306a36Sopenharmony_ci 359062306a36Sopenharmony_ci /* setup clear context state */ 359162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 359262306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); 359362306a36Sopenharmony_ci 359462306a36Sopenharmony_ci for (i = 0; i < si_default_size; i++) 359562306a36Sopenharmony_ci radeon_ring_write(ring, si_default_state[i]); 359662306a36Sopenharmony_ci 359762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 359862306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); 359962306a36Sopenharmony_ci 360062306a36Sopenharmony_ci /* set clear context state */ 360162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); 360262306a36Sopenharmony_ci radeon_ring_write(ring, 0); 360362306a36Sopenharmony_ci 360462306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); 360562306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000316); 360662306a36Sopenharmony_ci radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ 360762306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ 360862306a36Sopenharmony_ci 360962306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 361062306a36Sopenharmony_ci 361162306a36Sopenharmony_ci for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { 361262306a36Sopenharmony_ci ring = &rdev->ring[i]; 361362306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, 2); 361462306a36Sopenharmony_ci if (r) { 361562306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 361662306a36Sopenharmony_ci return r; 361762306a36Sopenharmony_ci } 361862306a36Sopenharmony_ci 361962306a36Sopenharmony_ci /* clear the compute context state */ 362062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); 362162306a36Sopenharmony_ci radeon_ring_write(ring, 0); 362262306a36Sopenharmony_ci 362362306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 362462306a36Sopenharmony_ci } 362562306a36Sopenharmony_ci 362662306a36Sopenharmony_ci return 0; 362762306a36Sopenharmony_ci} 362862306a36Sopenharmony_ci 362962306a36Sopenharmony_cistatic void si_cp_fini(struct radeon_device *rdev) 363062306a36Sopenharmony_ci{ 363162306a36Sopenharmony_ci struct radeon_ring *ring; 363262306a36Sopenharmony_ci si_cp_enable(rdev, false); 363362306a36Sopenharmony_ci 363462306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 363562306a36Sopenharmony_ci radeon_ring_fini(rdev, ring); 363662306a36Sopenharmony_ci radeon_scratch_free(rdev, ring->rptr_save_reg); 363762306a36Sopenharmony_ci 363862306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 363962306a36Sopenharmony_ci radeon_ring_fini(rdev, ring); 364062306a36Sopenharmony_ci radeon_scratch_free(rdev, ring->rptr_save_reg); 364162306a36Sopenharmony_ci 364262306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 364362306a36Sopenharmony_ci radeon_ring_fini(rdev, ring); 364462306a36Sopenharmony_ci radeon_scratch_free(rdev, ring->rptr_save_reg); 364562306a36Sopenharmony_ci} 364662306a36Sopenharmony_ci 364762306a36Sopenharmony_cistatic int si_cp_resume(struct radeon_device *rdev) 364862306a36Sopenharmony_ci{ 364962306a36Sopenharmony_ci struct radeon_ring *ring; 365062306a36Sopenharmony_ci u32 tmp; 365162306a36Sopenharmony_ci u32 rb_bufsz; 365262306a36Sopenharmony_ci int r; 365362306a36Sopenharmony_ci 365462306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, false); 365562306a36Sopenharmony_ci 365662306a36Sopenharmony_ci WREG32(CP_SEM_WAIT_TIMER, 0x0); 365762306a36Sopenharmony_ci WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); 365862306a36Sopenharmony_ci 365962306a36Sopenharmony_ci /* Set the write pointer delay */ 366062306a36Sopenharmony_ci WREG32(CP_RB_WPTR_DELAY, 0); 366162306a36Sopenharmony_ci 366262306a36Sopenharmony_ci WREG32(CP_DEBUG, 0); 366362306a36Sopenharmony_ci WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); 366462306a36Sopenharmony_ci 366562306a36Sopenharmony_ci /* ring 0 - compute and gfx */ 366662306a36Sopenharmony_ci /* Set ring buffer size */ 366762306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 366862306a36Sopenharmony_ci rb_bufsz = order_base_2(ring->ring_size / 8); 366962306a36Sopenharmony_ci tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; 367062306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 367162306a36Sopenharmony_ci tmp |= BUF_SWAP_32BIT; 367262306a36Sopenharmony_ci#endif 367362306a36Sopenharmony_ci WREG32(CP_RB0_CNTL, tmp); 367462306a36Sopenharmony_ci 367562306a36Sopenharmony_ci /* Initialize the ring buffer's read and write pointers */ 367662306a36Sopenharmony_ci WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); 367762306a36Sopenharmony_ci ring->wptr = 0; 367862306a36Sopenharmony_ci WREG32(CP_RB0_WPTR, ring->wptr); 367962306a36Sopenharmony_ci 368062306a36Sopenharmony_ci /* set the wb address whether it's enabled or not */ 368162306a36Sopenharmony_ci WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); 368262306a36Sopenharmony_ci WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); 368362306a36Sopenharmony_ci 368462306a36Sopenharmony_ci if (rdev->wb.enabled) 368562306a36Sopenharmony_ci WREG32(SCRATCH_UMSK, 0xff); 368662306a36Sopenharmony_ci else { 368762306a36Sopenharmony_ci tmp |= RB_NO_UPDATE; 368862306a36Sopenharmony_ci WREG32(SCRATCH_UMSK, 0); 368962306a36Sopenharmony_ci } 369062306a36Sopenharmony_ci 369162306a36Sopenharmony_ci mdelay(1); 369262306a36Sopenharmony_ci WREG32(CP_RB0_CNTL, tmp); 369362306a36Sopenharmony_ci 369462306a36Sopenharmony_ci WREG32(CP_RB0_BASE, ring->gpu_addr >> 8); 369562306a36Sopenharmony_ci 369662306a36Sopenharmony_ci /* ring1 - compute only */ 369762306a36Sopenharmony_ci /* Set ring buffer size */ 369862306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 369962306a36Sopenharmony_ci rb_bufsz = order_base_2(ring->ring_size / 8); 370062306a36Sopenharmony_ci tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; 370162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 370262306a36Sopenharmony_ci tmp |= BUF_SWAP_32BIT; 370362306a36Sopenharmony_ci#endif 370462306a36Sopenharmony_ci WREG32(CP_RB1_CNTL, tmp); 370562306a36Sopenharmony_ci 370662306a36Sopenharmony_ci /* Initialize the ring buffer's read and write pointers */ 370762306a36Sopenharmony_ci WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA); 370862306a36Sopenharmony_ci ring->wptr = 0; 370962306a36Sopenharmony_ci WREG32(CP_RB1_WPTR, ring->wptr); 371062306a36Sopenharmony_ci 371162306a36Sopenharmony_ci /* set the wb address whether it's enabled or not */ 371262306a36Sopenharmony_ci WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC); 371362306a36Sopenharmony_ci WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF); 371462306a36Sopenharmony_ci 371562306a36Sopenharmony_ci mdelay(1); 371662306a36Sopenharmony_ci WREG32(CP_RB1_CNTL, tmp); 371762306a36Sopenharmony_ci 371862306a36Sopenharmony_ci WREG32(CP_RB1_BASE, ring->gpu_addr >> 8); 371962306a36Sopenharmony_ci 372062306a36Sopenharmony_ci /* ring2 - compute only */ 372162306a36Sopenharmony_ci /* Set ring buffer size */ 372262306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 372362306a36Sopenharmony_ci rb_bufsz = order_base_2(ring->ring_size / 8); 372462306a36Sopenharmony_ci tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; 372562306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 372662306a36Sopenharmony_ci tmp |= BUF_SWAP_32BIT; 372762306a36Sopenharmony_ci#endif 372862306a36Sopenharmony_ci WREG32(CP_RB2_CNTL, tmp); 372962306a36Sopenharmony_ci 373062306a36Sopenharmony_ci /* Initialize the ring buffer's read and write pointers */ 373162306a36Sopenharmony_ci WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA); 373262306a36Sopenharmony_ci ring->wptr = 0; 373362306a36Sopenharmony_ci WREG32(CP_RB2_WPTR, ring->wptr); 373462306a36Sopenharmony_ci 373562306a36Sopenharmony_ci /* set the wb address whether it's enabled or not */ 373662306a36Sopenharmony_ci WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC); 373762306a36Sopenharmony_ci WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF); 373862306a36Sopenharmony_ci 373962306a36Sopenharmony_ci mdelay(1); 374062306a36Sopenharmony_ci WREG32(CP_RB2_CNTL, tmp); 374162306a36Sopenharmony_ci 374262306a36Sopenharmony_ci WREG32(CP_RB2_BASE, ring->gpu_addr >> 8); 374362306a36Sopenharmony_ci 374462306a36Sopenharmony_ci /* start the rings */ 374562306a36Sopenharmony_ci si_cp_start(rdev); 374662306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; 374762306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true; 374862306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true; 374962306a36Sopenharmony_ci r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 375062306a36Sopenharmony_ci if (r) { 375162306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 375262306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 375362306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; 375462306a36Sopenharmony_ci return r; 375562306a36Sopenharmony_ci } 375662306a36Sopenharmony_ci r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); 375762306a36Sopenharmony_ci if (r) { 375862306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 375962306a36Sopenharmony_ci } 376062306a36Sopenharmony_ci r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); 376162306a36Sopenharmony_ci if (r) { 376262306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; 376362306a36Sopenharmony_ci } 376462306a36Sopenharmony_ci 376562306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, true); 376662306a36Sopenharmony_ci 376762306a36Sopenharmony_ci if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) 376862306a36Sopenharmony_ci radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); 376962306a36Sopenharmony_ci 377062306a36Sopenharmony_ci return 0; 377162306a36Sopenharmony_ci} 377262306a36Sopenharmony_ci 377362306a36Sopenharmony_ciu32 si_gpu_check_soft_reset(struct radeon_device *rdev) 377462306a36Sopenharmony_ci{ 377562306a36Sopenharmony_ci u32 reset_mask = 0; 377662306a36Sopenharmony_ci u32 tmp; 377762306a36Sopenharmony_ci 377862306a36Sopenharmony_ci /* GRBM_STATUS */ 377962306a36Sopenharmony_ci tmp = RREG32(GRBM_STATUS); 378062306a36Sopenharmony_ci if (tmp & (PA_BUSY | SC_BUSY | 378162306a36Sopenharmony_ci BCI_BUSY | SX_BUSY | 378262306a36Sopenharmony_ci TA_BUSY | VGT_BUSY | 378362306a36Sopenharmony_ci DB_BUSY | CB_BUSY | 378462306a36Sopenharmony_ci GDS_BUSY | SPI_BUSY | 378562306a36Sopenharmony_ci IA_BUSY | IA_BUSY_NO_DMA)) 378662306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GFX; 378762306a36Sopenharmony_ci 378862306a36Sopenharmony_ci if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING | 378962306a36Sopenharmony_ci CP_BUSY | CP_COHERENCY_BUSY)) 379062306a36Sopenharmony_ci reset_mask |= RADEON_RESET_CP; 379162306a36Sopenharmony_ci 379262306a36Sopenharmony_ci if (tmp & GRBM_EE_BUSY) 379362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP; 379462306a36Sopenharmony_ci 379562306a36Sopenharmony_ci /* GRBM_STATUS2 */ 379662306a36Sopenharmony_ci tmp = RREG32(GRBM_STATUS2); 379762306a36Sopenharmony_ci if (tmp & (RLC_RQ_PENDING | RLC_BUSY)) 379862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_RLC; 379962306a36Sopenharmony_ci 380062306a36Sopenharmony_ci /* DMA_STATUS_REG 0 */ 380162306a36Sopenharmony_ci tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET); 380262306a36Sopenharmony_ci if (!(tmp & DMA_IDLE)) 380362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA; 380462306a36Sopenharmony_ci 380562306a36Sopenharmony_ci /* DMA_STATUS_REG 1 */ 380662306a36Sopenharmony_ci tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET); 380762306a36Sopenharmony_ci if (!(tmp & DMA_IDLE)) 380862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA1; 380962306a36Sopenharmony_ci 381062306a36Sopenharmony_ci /* SRBM_STATUS2 */ 381162306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS2); 381262306a36Sopenharmony_ci if (tmp & DMA_BUSY) 381362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA; 381462306a36Sopenharmony_ci 381562306a36Sopenharmony_ci if (tmp & DMA1_BUSY) 381662306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA1; 381762306a36Sopenharmony_ci 381862306a36Sopenharmony_ci /* SRBM_STATUS */ 381962306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS); 382062306a36Sopenharmony_ci 382162306a36Sopenharmony_ci if (tmp & IH_BUSY) 382262306a36Sopenharmony_ci reset_mask |= RADEON_RESET_IH; 382362306a36Sopenharmony_ci 382462306a36Sopenharmony_ci if (tmp & SEM_BUSY) 382562306a36Sopenharmony_ci reset_mask |= RADEON_RESET_SEM; 382662306a36Sopenharmony_ci 382762306a36Sopenharmony_ci if (tmp & GRBM_RQ_PENDING) 382862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GRBM; 382962306a36Sopenharmony_ci 383062306a36Sopenharmony_ci if (tmp & VMC_BUSY) 383162306a36Sopenharmony_ci reset_mask |= RADEON_RESET_VMC; 383262306a36Sopenharmony_ci 383362306a36Sopenharmony_ci if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY | 383462306a36Sopenharmony_ci MCC_BUSY | MCD_BUSY)) 383562306a36Sopenharmony_ci reset_mask |= RADEON_RESET_MC; 383662306a36Sopenharmony_ci 383762306a36Sopenharmony_ci if (evergreen_is_display_hung(rdev)) 383862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DISPLAY; 383962306a36Sopenharmony_ci 384062306a36Sopenharmony_ci /* VM_L2_STATUS */ 384162306a36Sopenharmony_ci tmp = RREG32(VM_L2_STATUS); 384262306a36Sopenharmony_ci if (tmp & L2_BUSY) 384362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_VMC; 384462306a36Sopenharmony_ci 384562306a36Sopenharmony_ci /* Skip MC reset as it's mostly likely not hung, just busy */ 384662306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_MC) { 384762306a36Sopenharmony_ci DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); 384862306a36Sopenharmony_ci reset_mask &= ~RADEON_RESET_MC; 384962306a36Sopenharmony_ci } 385062306a36Sopenharmony_ci 385162306a36Sopenharmony_ci return reset_mask; 385262306a36Sopenharmony_ci} 385362306a36Sopenharmony_ci 385462306a36Sopenharmony_cistatic void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 385562306a36Sopenharmony_ci{ 385662306a36Sopenharmony_ci struct evergreen_mc_save save; 385762306a36Sopenharmony_ci u32 grbm_soft_reset = 0, srbm_soft_reset = 0; 385862306a36Sopenharmony_ci u32 tmp; 385962306a36Sopenharmony_ci 386062306a36Sopenharmony_ci if (reset_mask == 0) 386162306a36Sopenharmony_ci return; 386262306a36Sopenharmony_ci 386362306a36Sopenharmony_ci dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 386462306a36Sopenharmony_ci 386562306a36Sopenharmony_ci evergreen_print_gpu_status_regs(rdev); 386662306a36Sopenharmony_ci dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", 386762306a36Sopenharmony_ci RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR)); 386862306a36Sopenharmony_ci dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 386962306a36Sopenharmony_ci RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); 387062306a36Sopenharmony_ci 387162306a36Sopenharmony_ci /* disable PG/CG */ 387262306a36Sopenharmony_ci si_fini_pg(rdev); 387362306a36Sopenharmony_ci si_fini_cg(rdev); 387462306a36Sopenharmony_ci 387562306a36Sopenharmony_ci /* stop the rlc */ 387662306a36Sopenharmony_ci si_rlc_stop(rdev); 387762306a36Sopenharmony_ci 387862306a36Sopenharmony_ci /* Disable CP parsing/prefetching */ 387962306a36Sopenharmony_ci WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); 388062306a36Sopenharmony_ci 388162306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA) { 388262306a36Sopenharmony_ci /* dma0 */ 388362306a36Sopenharmony_ci tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); 388462306a36Sopenharmony_ci tmp &= ~DMA_RB_ENABLE; 388562306a36Sopenharmony_ci WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); 388662306a36Sopenharmony_ci } 388762306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA1) { 388862306a36Sopenharmony_ci /* dma1 */ 388962306a36Sopenharmony_ci tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); 389062306a36Sopenharmony_ci tmp &= ~DMA_RB_ENABLE; 389162306a36Sopenharmony_ci WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); 389262306a36Sopenharmony_ci } 389362306a36Sopenharmony_ci 389462306a36Sopenharmony_ci udelay(50); 389562306a36Sopenharmony_ci 389662306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 389762306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 389862306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 389962306a36Sopenharmony_ci } 390062306a36Sopenharmony_ci 390162306a36Sopenharmony_ci if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) { 390262306a36Sopenharmony_ci grbm_soft_reset = SOFT_RESET_CB | 390362306a36Sopenharmony_ci SOFT_RESET_DB | 390462306a36Sopenharmony_ci SOFT_RESET_GDS | 390562306a36Sopenharmony_ci SOFT_RESET_PA | 390662306a36Sopenharmony_ci SOFT_RESET_SC | 390762306a36Sopenharmony_ci SOFT_RESET_BCI | 390862306a36Sopenharmony_ci SOFT_RESET_SPI | 390962306a36Sopenharmony_ci SOFT_RESET_SX | 391062306a36Sopenharmony_ci SOFT_RESET_TC | 391162306a36Sopenharmony_ci SOFT_RESET_TA | 391262306a36Sopenharmony_ci SOFT_RESET_VGT | 391362306a36Sopenharmony_ci SOFT_RESET_IA; 391462306a36Sopenharmony_ci } 391562306a36Sopenharmony_ci 391662306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_CP) { 391762306a36Sopenharmony_ci grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT; 391862306a36Sopenharmony_ci 391962306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_GRBM; 392062306a36Sopenharmony_ci } 392162306a36Sopenharmony_ci 392262306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA) 392362306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_DMA; 392462306a36Sopenharmony_ci 392562306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA1) 392662306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_DMA1; 392762306a36Sopenharmony_ci 392862306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DISPLAY) 392962306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_DC; 393062306a36Sopenharmony_ci 393162306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_RLC) 393262306a36Sopenharmony_ci grbm_soft_reset |= SOFT_RESET_RLC; 393362306a36Sopenharmony_ci 393462306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_SEM) 393562306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_SEM; 393662306a36Sopenharmony_ci 393762306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_IH) 393862306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_IH; 393962306a36Sopenharmony_ci 394062306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_GRBM) 394162306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_GRBM; 394262306a36Sopenharmony_ci 394362306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_VMC) 394462306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_VMC; 394562306a36Sopenharmony_ci 394662306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_MC) 394762306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_MC; 394862306a36Sopenharmony_ci 394962306a36Sopenharmony_ci if (grbm_soft_reset) { 395062306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 395162306a36Sopenharmony_ci tmp |= grbm_soft_reset; 395262306a36Sopenharmony_ci dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 395362306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 395462306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 395562306a36Sopenharmony_ci 395662306a36Sopenharmony_ci udelay(50); 395762306a36Sopenharmony_ci 395862306a36Sopenharmony_ci tmp &= ~grbm_soft_reset; 395962306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 396062306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 396162306a36Sopenharmony_ci } 396262306a36Sopenharmony_ci 396362306a36Sopenharmony_ci if (srbm_soft_reset) { 396462306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 396562306a36Sopenharmony_ci tmp |= srbm_soft_reset; 396662306a36Sopenharmony_ci dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 396762306a36Sopenharmony_ci WREG32(SRBM_SOFT_RESET, tmp); 396862306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 396962306a36Sopenharmony_ci 397062306a36Sopenharmony_ci udelay(50); 397162306a36Sopenharmony_ci 397262306a36Sopenharmony_ci tmp &= ~srbm_soft_reset; 397362306a36Sopenharmony_ci WREG32(SRBM_SOFT_RESET, tmp); 397462306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 397562306a36Sopenharmony_ci } 397662306a36Sopenharmony_ci 397762306a36Sopenharmony_ci /* Wait a little for things to settle down */ 397862306a36Sopenharmony_ci udelay(50); 397962306a36Sopenharmony_ci 398062306a36Sopenharmony_ci evergreen_mc_resume(rdev, &save); 398162306a36Sopenharmony_ci udelay(50); 398262306a36Sopenharmony_ci 398362306a36Sopenharmony_ci evergreen_print_gpu_status_regs(rdev); 398462306a36Sopenharmony_ci} 398562306a36Sopenharmony_ci 398662306a36Sopenharmony_cistatic void si_set_clk_bypass_mode(struct radeon_device *rdev) 398762306a36Sopenharmony_ci{ 398862306a36Sopenharmony_ci u32 tmp, i; 398962306a36Sopenharmony_ci 399062306a36Sopenharmony_ci tmp = RREG32(CG_SPLL_FUNC_CNTL); 399162306a36Sopenharmony_ci tmp |= SPLL_BYPASS_EN; 399262306a36Sopenharmony_ci WREG32(CG_SPLL_FUNC_CNTL, tmp); 399362306a36Sopenharmony_ci 399462306a36Sopenharmony_ci tmp = RREG32(CG_SPLL_FUNC_CNTL_2); 399562306a36Sopenharmony_ci tmp |= SPLL_CTLREQ_CHG; 399662306a36Sopenharmony_ci WREG32(CG_SPLL_FUNC_CNTL_2, tmp); 399762306a36Sopenharmony_ci 399862306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 399962306a36Sopenharmony_ci if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS) 400062306a36Sopenharmony_ci break; 400162306a36Sopenharmony_ci udelay(1); 400262306a36Sopenharmony_ci } 400362306a36Sopenharmony_ci 400462306a36Sopenharmony_ci tmp = RREG32(CG_SPLL_FUNC_CNTL_2); 400562306a36Sopenharmony_ci tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE); 400662306a36Sopenharmony_ci WREG32(CG_SPLL_FUNC_CNTL_2, tmp); 400762306a36Sopenharmony_ci 400862306a36Sopenharmony_ci tmp = RREG32(MPLL_CNTL_MODE); 400962306a36Sopenharmony_ci tmp &= ~MPLL_MCLK_SEL; 401062306a36Sopenharmony_ci WREG32(MPLL_CNTL_MODE, tmp); 401162306a36Sopenharmony_ci} 401262306a36Sopenharmony_ci 401362306a36Sopenharmony_cistatic void si_spll_powerdown(struct radeon_device *rdev) 401462306a36Sopenharmony_ci{ 401562306a36Sopenharmony_ci u32 tmp; 401662306a36Sopenharmony_ci 401762306a36Sopenharmony_ci tmp = RREG32(SPLL_CNTL_MODE); 401862306a36Sopenharmony_ci tmp |= SPLL_SW_DIR_CONTROL; 401962306a36Sopenharmony_ci WREG32(SPLL_CNTL_MODE, tmp); 402062306a36Sopenharmony_ci 402162306a36Sopenharmony_ci tmp = RREG32(CG_SPLL_FUNC_CNTL); 402262306a36Sopenharmony_ci tmp |= SPLL_RESET; 402362306a36Sopenharmony_ci WREG32(CG_SPLL_FUNC_CNTL, tmp); 402462306a36Sopenharmony_ci 402562306a36Sopenharmony_ci tmp = RREG32(CG_SPLL_FUNC_CNTL); 402662306a36Sopenharmony_ci tmp |= SPLL_SLEEP; 402762306a36Sopenharmony_ci WREG32(CG_SPLL_FUNC_CNTL, tmp); 402862306a36Sopenharmony_ci 402962306a36Sopenharmony_ci tmp = RREG32(SPLL_CNTL_MODE); 403062306a36Sopenharmony_ci tmp &= ~SPLL_SW_DIR_CONTROL; 403162306a36Sopenharmony_ci WREG32(SPLL_CNTL_MODE, tmp); 403262306a36Sopenharmony_ci} 403362306a36Sopenharmony_ci 403462306a36Sopenharmony_cistatic void si_gpu_pci_config_reset(struct radeon_device *rdev) 403562306a36Sopenharmony_ci{ 403662306a36Sopenharmony_ci struct evergreen_mc_save save; 403762306a36Sopenharmony_ci u32 tmp, i; 403862306a36Sopenharmony_ci 403962306a36Sopenharmony_ci dev_info(rdev->dev, "GPU pci config reset\n"); 404062306a36Sopenharmony_ci 404162306a36Sopenharmony_ci /* disable dpm? */ 404262306a36Sopenharmony_ci 404362306a36Sopenharmony_ci /* disable cg/pg */ 404462306a36Sopenharmony_ci si_fini_pg(rdev); 404562306a36Sopenharmony_ci si_fini_cg(rdev); 404662306a36Sopenharmony_ci 404762306a36Sopenharmony_ci /* Disable CP parsing/prefetching */ 404862306a36Sopenharmony_ci WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); 404962306a36Sopenharmony_ci /* dma0 */ 405062306a36Sopenharmony_ci tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); 405162306a36Sopenharmony_ci tmp &= ~DMA_RB_ENABLE; 405262306a36Sopenharmony_ci WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); 405362306a36Sopenharmony_ci /* dma1 */ 405462306a36Sopenharmony_ci tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); 405562306a36Sopenharmony_ci tmp &= ~DMA_RB_ENABLE; 405662306a36Sopenharmony_ci WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); 405762306a36Sopenharmony_ci /* XXX other engines? */ 405862306a36Sopenharmony_ci 405962306a36Sopenharmony_ci /* halt the rlc, disable cp internal ints */ 406062306a36Sopenharmony_ci si_rlc_stop(rdev); 406162306a36Sopenharmony_ci 406262306a36Sopenharmony_ci udelay(50); 406362306a36Sopenharmony_ci 406462306a36Sopenharmony_ci /* disable mem access */ 406562306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 406662306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 406762306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timed out !\n"); 406862306a36Sopenharmony_ci } 406962306a36Sopenharmony_ci 407062306a36Sopenharmony_ci /* set mclk/sclk to bypass */ 407162306a36Sopenharmony_ci si_set_clk_bypass_mode(rdev); 407262306a36Sopenharmony_ci /* powerdown spll */ 407362306a36Sopenharmony_ci si_spll_powerdown(rdev); 407462306a36Sopenharmony_ci /* disable BM */ 407562306a36Sopenharmony_ci pci_clear_master(rdev->pdev); 407662306a36Sopenharmony_ci /* reset */ 407762306a36Sopenharmony_ci radeon_pci_config_reset(rdev); 407862306a36Sopenharmony_ci /* wait for asic to come out of reset */ 407962306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 408062306a36Sopenharmony_ci if (RREG32(CONFIG_MEMSIZE) != 0xffffffff) 408162306a36Sopenharmony_ci break; 408262306a36Sopenharmony_ci udelay(1); 408362306a36Sopenharmony_ci } 408462306a36Sopenharmony_ci} 408562306a36Sopenharmony_ci 408662306a36Sopenharmony_ciint si_asic_reset(struct radeon_device *rdev, bool hard) 408762306a36Sopenharmony_ci{ 408862306a36Sopenharmony_ci u32 reset_mask; 408962306a36Sopenharmony_ci 409062306a36Sopenharmony_ci if (hard) { 409162306a36Sopenharmony_ci si_gpu_pci_config_reset(rdev); 409262306a36Sopenharmony_ci return 0; 409362306a36Sopenharmony_ci } 409462306a36Sopenharmony_ci 409562306a36Sopenharmony_ci reset_mask = si_gpu_check_soft_reset(rdev); 409662306a36Sopenharmony_ci 409762306a36Sopenharmony_ci if (reset_mask) 409862306a36Sopenharmony_ci r600_set_bios_scratch_engine_hung(rdev, true); 409962306a36Sopenharmony_ci 410062306a36Sopenharmony_ci /* try soft reset */ 410162306a36Sopenharmony_ci si_gpu_soft_reset(rdev, reset_mask); 410262306a36Sopenharmony_ci 410362306a36Sopenharmony_ci reset_mask = si_gpu_check_soft_reset(rdev); 410462306a36Sopenharmony_ci 410562306a36Sopenharmony_ci /* try pci config reset */ 410662306a36Sopenharmony_ci if (reset_mask && radeon_hard_reset) 410762306a36Sopenharmony_ci si_gpu_pci_config_reset(rdev); 410862306a36Sopenharmony_ci 410962306a36Sopenharmony_ci reset_mask = si_gpu_check_soft_reset(rdev); 411062306a36Sopenharmony_ci 411162306a36Sopenharmony_ci if (!reset_mask) 411262306a36Sopenharmony_ci r600_set_bios_scratch_engine_hung(rdev, false); 411362306a36Sopenharmony_ci 411462306a36Sopenharmony_ci return 0; 411562306a36Sopenharmony_ci} 411662306a36Sopenharmony_ci 411762306a36Sopenharmony_ci/** 411862306a36Sopenharmony_ci * si_gfx_is_lockup - Check if the GFX engine is locked up 411962306a36Sopenharmony_ci * 412062306a36Sopenharmony_ci * @rdev: radeon_device pointer 412162306a36Sopenharmony_ci * @ring: radeon_ring structure holding ring information 412262306a36Sopenharmony_ci * 412362306a36Sopenharmony_ci * Check if the GFX engine is locked up. 412462306a36Sopenharmony_ci * Returns true if the engine appears to be locked up, false if not. 412562306a36Sopenharmony_ci */ 412662306a36Sopenharmony_cibool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 412762306a36Sopenharmony_ci{ 412862306a36Sopenharmony_ci u32 reset_mask = si_gpu_check_soft_reset(rdev); 412962306a36Sopenharmony_ci 413062306a36Sopenharmony_ci if (!(reset_mask & (RADEON_RESET_GFX | 413162306a36Sopenharmony_ci RADEON_RESET_COMPUTE | 413262306a36Sopenharmony_ci RADEON_RESET_CP))) { 413362306a36Sopenharmony_ci radeon_ring_lockup_update(rdev, ring); 413462306a36Sopenharmony_ci return false; 413562306a36Sopenharmony_ci } 413662306a36Sopenharmony_ci return radeon_ring_test_lockup(rdev, ring); 413762306a36Sopenharmony_ci} 413862306a36Sopenharmony_ci 413962306a36Sopenharmony_ci/* MC */ 414062306a36Sopenharmony_cistatic void si_mc_program(struct radeon_device *rdev) 414162306a36Sopenharmony_ci{ 414262306a36Sopenharmony_ci struct evergreen_mc_save save; 414362306a36Sopenharmony_ci u32 tmp; 414462306a36Sopenharmony_ci int i, j; 414562306a36Sopenharmony_ci 414662306a36Sopenharmony_ci /* Initialize HDP */ 414762306a36Sopenharmony_ci for (i = 0, j = 0; i < 32; i++, j += 0x18) { 414862306a36Sopenharmony_ci WREG32((0x2c14 + j), 0x00000000); 414962306a36Sopenharmony_ci WREG32((0x2c18 + j), 0x00000000); 415062306a36Sopenharmony_ci WREG32((0x2c1c + j), 0x00000000); 415162306a36Sopenharmony_ci WREG32((0x2c20 + j), 0x00000000); 415262306a36Sopenharmony_ci WREG32((0x2c24 + j), 0x00000000); 415362306a36Sopenharmony_ci } 415462306a36Sopenharmony_ci WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); 415562306a36Sopenharmony_ci 415662306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 415762306a36Sopenharmony_ci if (radeon_mc_wait_for_idle(rdev)) { 415862306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 415962306a36Sopenharmony_ci } 416062306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) 416162306a36Sopenharmony_ci /* Lockout access through VGA aperture*/ 416262306a36Sopenharmony_ci WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); 416362306a36Sopenharmony_ci /* Update configuration */ 416462306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, 416562306a36Sopenharmony_ci rdev->mc.vram_start >> 12); 416662306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 416762306a36Sopenharmony_ci rdev->mc.vram_end >> 12); 416862306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 416962306a36Sopenharmony_ci rdev->vram_scratch.gpu_addr >> 12); 417062306a36Sopenharmony_ci tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; 417162306a36Sopenharmony_ci tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); 417262306a36Sopenharmony_ci WREG32(MC_VM_FB_LOCATION, tmp); 417362306a36Sopenharmony_ci /* XXX double check these! */ 417462306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); 417562306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); 417662306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); 417762306a36Sopenharmony_ci WREG32(MC_VM_AGP_BASE, 0); 417862306a36Sopenharmony_ci WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); 417962306a36Sopenharmony_ci WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); 418062306a36Sopenharmony_ci if (radeon_mc_wait_for_idle(rdev)) { 418162306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 418262306a36Sopenharmony_ci } 418362306a36Sopenharmony_ci evergreen_mc_resume(rdev, &save); 418462306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) { 418562306a36Sopenharmony_ci /* we need to own VRAM, so turn off the VGA renderer here 418662306a36Sopenharmony_ci * to stop it overwriting our objects */ 418762306a36Sopenharmony_ci rv515_vga_render_disable(rdev); 418862306a36Sopenharmony_ci } 418962306a36Sopenharmony_ci} 419062306a36Sopenharmony_ci 419162306a36Sopenharmony_civoid si_vram_gtt_location(struct radeon_device *rdev, 419262306a36Sopenharmony_ci struct radeon_mc *mc) 419362306a36Sopenharmony_ci{ 419462306a36Sopenharmony_ci if (mc->mc_vram_size > 0xFFC0000000ULL) { 419562306a36Sopenharmony_ci /* leave room for at least 1024M GTT */ 419662306a36Sopenharmony_ci dev_warn(rdev->dev, "limiting VRAM\n"); 419762306a36Sopenharmony_ci mc->real_vram_size = 0xFFC0000000ULL; 419862306a36Sopenharmony_ci mc->mc_vram_size = 0xFFC0000000ULL; 419962306a36Sopenharmony_ci } 420062306a36Sopenharmony_ci radeon_vram_location(rdev, &rdev->mc, 0); 420162306a36Sopenharmony_ci rdev->mc.gtt_base_align = 0; 420262306a36Sopenharmony_ci radeon_gtt_location(rdev, mc); 420362306a36Sopenharmony_ci} 420462306a36Sopenharmony_ci 420562306a36Sopenharmony_cistatic int si_mc_init(struct radeon_device *rdev) 420662306a36Sopenharmony_ci{ 420762306a36Sopenharmony_ci u32 tmp; 420862306a36Sopenharmony_ci int chansize, numchan; 420962306a36Sopenharmony_ci 421062306a36Sopenharmony_ci /* Get VRAM informations */ 421162306a36Sopenharmony_ci rdev->mc.vram_is_ddr = true; 421262306a36Sopenharmony_ci tmp = RREG32(MC_ARB_RAMCFG); 421362306a36Sopenharmony_ci if (tmp & CHANSIZE_OVERRIDE) { 421462306a36Sopenharmony_ci chansize = 16; 421562306a36Sopenharmony_ci } else if (tmp & CHANSIZE_MASK) { 421662306a36Sopenharmony_ci chansize = 64; 421762306a36Sopenharmony_ci } else { 421862306a36Sopenharmony_ci chansize = 32; 421962306a36Sopenharmony_ci } 422062306a36Sopenharmony_ci tmp = RREG32(MC_SHARED_CHMAP); 422162306a36Sopenharmony_ci switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { 422262306a36Sopenharmony_ci case 0: 422362306a36Sopenharmony_ci default: 422462306a36Sopenharmony_ci numchan = 1; 422562306a36Sopenharmony_ci break; 422662306a36Sopenharmony_ci case 1: 422762306a36Sopenharmony_ci numchan = 2; 422862306a36Sopenharmony_ci break; 422962306a36Sopenharmony_ci case 2: 423062306a36Sopenharmony_ci numchan = 4; 423162306a36Sopenharmony_ci break; 423262306a36Sopenharmony_ci case 3: 423362306a36Sopenharmony_ci numchan = 8; 423462306a36Sopenharmony_ci break; 423562306a36Sopenharmony_ci case 4: 423662306a36Sopenharmony_ci numchan = 3; 423762306a36Sopenharmony_ci break; 423862306a36Sopenharmony_ci case 5: 423962306a36Sopenharmony_ci numchan = 6; 424062306a36Sopenharmony_ci break; 424162306a36Sopenharmony_ci case 6: 424262306a36Sopenharmony_ci numchan = 10; 424362306a36Sopenharmony_ci break; 424462306a36Sopenharmony_ci case 7: 424562306a36Sopenharmony_ci numchan = 12; 424662306a36Sopenharmony_ci break; 424762306a36Sopenharmony_ci case 8: 424862306a36Sopenharmony_ci numchan = 16; 424962306a36Sopenharmony_ci break; 425062306a36Sopenharmony_ci } 425162306a36Sopenharmony_ci rdev->mc.vram_width = numchan * chansize; 425262306a36Sopenharmony_ci /* Could aper size report 0 ? */ 425362306a36Sopenharmony_ci rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); 425462306a36Sopenharmony_ci rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); 425562306a36Sopenharmony_ci /* size in MB on si */ 425662306a36Sopenharmony_ci tmp = RREG32(CONFIG_MEMSIZE); 425762306a36Sopenharmony_ci /* some boards may have garbage in the upper 16 bits */ 425862306a36Sopenharmony_ci if (tmp & 0xffff0000) { 425962306a36Sopenharmony_ci DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); 426062306a36Sopenharmony_ci if (tmp & 0xffff) 426162306a36Sopenharmony_ci tmp &= 0xffff; 426262306a36Sopenharmony_ci } 426362306a36Sopenharmony_ci rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL; 426462306a36Sopenharmony_ci rdev->mc.real_vram_size = rdev->mc.mc_vram_size; 426562306a36Sopenharmony_ci rdev->mc.visible_vram_size = rdev->mc.aper_size; 426662306a36Sopenharmony_ci si_vram_gtt_location(rdev, &rdev->mc); 426762306a36Sopenharmony_ci radeon_update_bandwidth_info(rdev); 426862306a36Sopenharmony_ci 426962306a36Sopenharmony_ci return 0; 427062306a36Sopenharmony_ci} 427162306a36Sopenharmony_ci 427262306a36Sopenharmony_ci/* 427362306a36Sopenharmony_ci * GART 427462306a36Sopenharmony_ci */ 427562306a36Sopenharmony_civoid si_pcie_gart_tlb_flush(struct radeon_device *rdev) 427662306a36Sopenharmony_ci{ 427762306a36Sopenharmony_ci /* flush hdp cache */ 427862306a36Sopenharmony_ci WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); 427962306a36Sopenharmony_ci 428062306a36Sopenharmony_ci /* bits 0-15 are the VM contexts0-15 */ 428162306a36Sopenharmony_ci WREG32(VM_INVALIDATE_REQUEST, 1); 428262306a36Sopenharmony_ci} 428362306a36Sopenharmony_ci 428462306a36Sopenharmony_cistatic int si_pcie_gart_enable(struct radeon_device *rdev) 428562306a36Sopenharmony_ci{ 428662306a36Sopenharmony_ci int r, i; 428762306a36Sopenharmony_ci 428862306a36Sopenharmony_ci if (rdev->gart.robj == NULL) { 428962306a36Sopenharmony_ci dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 429062306a36Sopenharmony_ci return -EINVAL; 429162306a36Sopenharmony_ci } 429262306a36Sopenharmony_ci r = radeon_gart_table_vram_pin(rdev); 429362306a36Sopenharmony_ci if (r) 429462306a36Sopenharmony_ci return r; 429562306a36Sopenharmony_ci /* Setup TLB control */ 429662306a36Sopenharmony_ci WREG32(MC_VM_MX_L1_TLB_CNTL, 429762306a36Sopenharmony_ci (0xA << 7) | 429862306a36Sopenharmony_ci ENABLE_L1_TLB | 429962306a36Sopenharmony_ci ENABLE_L1_FRAGMENT_PROCESSING | 430062306a36Sopenharmony_ci SYSTEM_ACCESS_MODE_NOT_IN_SYS | 430162306a36Sopenharmony_ci ENABLE_ADVANCED_DRIVER_MODEL | 430262306a36Sopenharmony_ci SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); 430362306a36Sopenharmony_ci /* Setup L2 cache */ 430462306a36Sopenharmony_ci WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | 430562306a36Sopenharmony_ci ENABLE_L2_FRAGMENT_PROCESSING | 430662306a36Sopenharmony_ci ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 430762306a36Sopenharmony_ci ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | 430862306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7) | 430962306a36Sopenharmony_ci CONTEXT1_IDENTITY_ACCESS_MODE(1)); 431062306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); 431162306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 431262306a36Sopenharmony_ci BANK_SELECT(4) | 431362306a36Sopenharmony_ci L2_CACHE_BIGK_FRAGMENT_SIZE(4)); 431462306a36Sopenharmony_ci /* setup context0 */ 431562306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); 431662306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); 431762306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); 431862306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, 431962306a36Sopenharmony_ci (u32)(rdev->dummy_page.addr >> 12)); 432062306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL2, 0); 432162306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | 432262306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_DEFAULT)); 432362306a36Sopenharmony_ci 432462306a36Sopenharmony_ci WREG32(0x15D4, 0); 432562306a36Sopenharmony_ci WREG32(0x15D8, 0); 432662306a36Sopenharmony_ci WREG32(0x15DC, 0); 432762306a36Sopenharmony_ci 432862306a36Sopenharmony_ci /* empty context1-15 */ 432962306a36Sopenharmony_ci /* set vm size, must be a multiple of 4 */ 433062306a36Sopenharmony_ci WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); 433162306a36Sopenharmony_ci WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1); 433262306a36Sopenharmony_ci /* Assign the pt base to something valid for now; the pts used for 433362306a36Sopenharmony_ci * the VMs are determined by the application and setup and assigned 433462306a36Sopenharmony_ci * on the fly in the vm part of radeon_gart.c 433562306a36Sopenharmony_ci */ 433662306a36Sopenharmony_ci for (i = 1; i < 16; i++) { 433762306a36Sopenharmony_ci if (i < 8) 433862306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), 433962306a36Sopenharmony_ci rdev->vm_manager.saved_table_addr[i]); 434062306a36Sopenharmony_ci else 434162306a36Sopenharmony_ci WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), 434262306a36Sopenharmony_ci rdev->vm_manager.saved_table_addr[i]); 434362306a36Sopenharmony_ci } 434462306a36Sopenharmony_ci 434562306a36Sopenharmony_ci /* enable context1-15 */ 434662306a36Sopenharmony_ci WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, 434762306a36Sopenharmony_ci (u32)(rdev->dummy_page.addr >> 12)); 434862306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL2, 4); 434962306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | 435062306a36Sopenharmony_ci PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) | 435162306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT | 435262306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_DEFAULT | 435362306a36Sopenharmony_ci DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | 435462306a36Sopenharmony_ci DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT | 435562306a36Sopenharmony_ci PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT | 435662306a36Sopenharmony_ci PDE0_PROTECTION_FAULT_ENABLE_DEFAULT | 435762306a36Sopenharmony_ci VALID_PROTECTION_FAULT_ENABLE_INTERRUPT | 435862306a36Sopenharmony_ci VALID_PROTECTION_FAULT_ENABLE_DEFAULT | 435962306a36Sopenharmony_ci READ_PROTECTION_FAULT_ENABLE_INTERRUPT | 436062306a36Sopenharmony_ci READ_PROTECTION_FAULT_ENABLE_DEFAULT | 436162306a36Sopenharmony_ci WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT | 436262306a36Sopenharmony_ci WRITE_PROTECTION_FAULT_ENABLE_DEFAULT); 436362306a36Sopenharmony_ci 436462306a36Sopenharmony_ci si_pcie_gart_tlb_flush(rdev); 436562306a36Sopenharmony_ci DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 436662306a36Sopenharmony_ci (unsigned)(rdev->mc.gtt_size >> 20), 436762306a36Sopenharmony_ci (unsigned long long)rdev->gart.table_addr); 436862306a36Sopenharmony_ci rdev->gart.ready = true; 436962306a36Sopenharmony_ci return 0; 437062306a36Sopenharmony_ci} 437162306a36Sopenharmony_ci 437262306a36Sopenharmony_cistatic void si_pcie_gart_disable(struct radeon_device *rdev) 437362306a36Sopenharmony_ci{ 437462306a36Sopenharmony_ci unsigned i; 437562306a36Sopenharmony_ci 437662306a36Sopenharmony_ci for (i = 1; i < 16; ++i) { 437762306a36Sopenharmony_ci uint32_t reg; 437862306a36Sopenharmony_ci if (i < 8) 437962306a36Sopenharmony_ci reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2); 438062306a36Sopenharmony_ci else 438162306a36Sopenharmony_ci reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2); 438262306a36Sopenharmony_ci rdev->vm_manager.saved_table_addr[i] = RREG32(reg); 438362306a36Sopenharmony_ci } 438462306a36Sopenharmony_ci 438562306a36Sopenharmony_ci /* Disable all tables */ 438662306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, 0); 438762306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, 0); 438862306a36Sopenharmony_ci /* Setup TLB control */ 438962306a36Sopenharmony_ci WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS | 439062306a36Sopenharmony_ci SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); 439162306a36Sopenharmony_ci /* Setup L2 cache */ 439262306a36Sopenharmony_ci WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 439362306a36Sopenharmony_ci ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | 439462306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7) | 439562306a36Sopenharmony_ci CONTEXT1_IDENTITY_ACCESS_MODE(1)); 439662306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, 0); 439762306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 439862306a36Sopenharmony_ci L2_CACHE_BIGK_FRAGMENT_SIZE(0)); 439962306a36Sopenharmony_ci radeon_gart_table_vram_unpin(rdev); 440062306a36Sopenharmony_ci} 440162306a36Sopenharmony_ci 440262306a36Sopenharmony_cistatic void si_pcie_gart_fini(struct radeon_device *rdev) 440362306a36Sopenharmony_ci{ 440462306a36Sopenharmony_ci si_pcie_gart_disable(rdev); 440562306a36Sopenharmony_ci radeon_gart_table_vram_free(rdev); 440662306a36Sopenharmony_ci radeon_gart_fini(rdev); 440762306a36Sopenharmony_ci} 440862306a36Sopenharmony_ci 440962306a36Sopenharmony_ci/* vm parser */ 441062306a36Sopenharmony_cistatic bool si_vm_reg_valid(u32 reg) 441162306a36Sopenharmony_ci{ 441262306a36Sopenharmony_ci /* context regs are fine */ 441362306a36Sopenharmony_ci if (reg >= 0x28000) 441462306a36Sopenharmony_ci return true; 441562306a36Sopenharmony_ci 441662306a36Sopenharmony_ci /* shader regs are also fine */ 441762306a36Sopenharmony_ci if (reg >= 0xB000 && reg < 0xC000) 441862306a36Sopenharmony_ci return true; 441962306a36Sopenharmony_ci 442062306a36Sopenharmony_ci /* check config regs */ 442162306a36Sopenharmony_ci switch (reg) { 442262306a36Sopenharmony_ci case GRBM_GFX_INDEX: 442362306a36Sopenharmony_ci case CP_STRMOUT_CNTL: 442462306a36Sopenharmony_ci case VGT_VTX_VECT_EJECT_REG: 442562306a36Sopenharmony_ci case VGT_CACHE_INVALIDATION: 442662306a36Sopenharmony_ci case VGT_ESGS_RING_SIZE: 442762306a36Sopenharmony_ci case VGT_GSVS_RING_SIZE: 442862306a36Sopenharmony_ci case VGT_GS_VERTEX_REUSE: 442962306a36Sopenharmony_ci case VGT_PRIMITIVE_TYPE: 443062306a36Sopenharmony_ci case VGT_INDEX_TYPE: 443162306a36Sopenharmony_ci case VGT_NUM_INDICES: 443262306a36Sopenharmony_ci case VGT_NUM_INSTANCES: 443362306a36Sopenharmony_ci case VGT_TF_RING_SIZE: 443462306a36Sopenharmony_ci case VGT_HS_OFFCHIP_PARAM: 443562306a36Sopenharmony_ci case VGT_TF_MEMORY_BASE: 443662306a36Sopenharmony_ci case PA_CL_ENHANCE: 443762306a36Sopenharmony_ci case PA_SU_LINE_STIPPLE_VALUE: 443862306a36Sopenharmony_ci case PA_SC_LINE_STIPPLE_STATE: 443962306a36Sopenharmony_ci case PA_SC_ENHANCE: 444062306a36Sopenharmony_ci case SQC_CACHES: 444162306a36Sopenharmony_ci case SPI_STATIC_THREAD_MGMT_1: 444262306a36Sopenharmony_ci case SPI_STATIC_THREAD_MGMT_2: 444362306a36Sopenharmony_ci case SPI_STATIC_THREAD_MGMT_3: 444462306a36Sopenharmony_ci case SPI_PS_MAX_WAVE_ID: 444562306a36Sopenharmony_ci case SPI_CONFIG_CNTL: 444662306a36Sopenharmony_ci case SPI_CONFIG_CNTL_1: 444762306a36Sopenharmony_ci case TA_CNTL_AUX: 444862306a36Sopenharmony_ci case TA_CS_BC_BASE_ADDR: 444962306a36Sopenharmony_ci return true; 445062306a36Sopenharmony_ci default: 445162306a36Sopenharmony_ci DRM_ERROR("Invalid register 0x%x in CS\n", reg); 445262306a36Sopenharmony_ci return false; 445362306a36Sopenharmony_ci } 445462306a36Sopenharmony_ci} 445562306a36Sopenharmony_ci 445662306a36Sopenharmony_cistatic int si_vm_packet3_ce_check(struct radeon_device *rdev, 445762306a36Sopenharmony_ci u32 *ib, struct radeon_cs_packet *pkt) 445862306a36Sopenharmony_ci{ 445962306a36Sopenharmony_ci switch (pkt->opcode) { 446062306a36Sopenharmony_ci case PACKET3_NOP: 446162306a36Sopenharmony_ci case PACKET3_SET_BASE: 446262306a36Sopenharmony_ci case PACKET3_SET_CE_DE_COUNTERS: 446362306a36Sopenharmony_ci case PACKET3_LOAD_CONST_RAM: 446462306a36Sopenharmony_ci case PACKET3_WRITE_CONST_RAM: 446562306a36Sopenharmony_ci case PACKET3_WRITE_CONST_RAM_OFFSET: 446662306a36Sopenharmony_ci case PACKET3_DUMP_CONST_RAM: 446762306a36Sopenharmony_ci case PACKET3_INCREMENT_CE_COUNTER: 446862306a36Sopenharmony_ci case PACKET3_WAIT_ON_DE_COUNTER: 446962306a36Sopenharmony_ci case PACKET3_CE_WRITE: 447062306a36Sopenharmony_ci break; 447162306a36Sopenharmony_ci default: 447262306a36Sopenharmony_ci DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode); 447362306a36Sopenharmony_ci return -EINVAL; 447462306a36Sopenharmony_ci } 447562306a36Sopenharmony_ci return 0; 447662306a36Sopenharmony_ci} 447762306a36Sopenharmony_ci 447862306a36Sopenharmony_cistatic int si_vm_packet3_cp_dma_check(u32 *ib, u32 idx) 447962306a36Sopenharmony_ci{ 448062306a36Sopenharmony_ci u32 start_reg, reg, i; 448162306a36Sopenharmony_ci u32 command = ib[idx + 4]; 448262306a36Sopenharmony_ci u32 info = ib[idx + 1]; 448362306a36Sopenharmony_ci u32 idx_value = ib[idx]; 448462306a36Sopenharmony_ci if (command & PACKET3_CP_DMA_CMD_SAS) { 448562306a36Sopenharmony_ci /* src address space is register */ 448662306a36Sopenharmony_ci if (((info & 0x60000000) >> 29) == 0) { 448762306a36Sopenharmony_ci start_reg = idx_value << 2; 448862306a36Sopenharmony_ci if (command & PACKET3_CP_DMA_CMD_SAIC) { 448962306a36Sopenharmony_ci reg = start_reg; 449062306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) { 449162306a36Sopenharmony_ci DRM_ERROR("CP DMA Bad SRC register\n"); 449262306a36Sopenharmony_ci return -EINVAL; 449362306a36Sopenharmony_ci } 449462306a36Sopenharmony_ci } else { 449562306a36Sopenharmony_ci for (i = 0; i < (command & 0x1fffff); i++) { 449662306a36Sopenharmony_ci reg = start_reg + (4 * i); 449762306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) { 449862306a36Sopenharmony_ci DRM_ERROR("CP DMA Bad SRC register\n"); 449962306a36Sopenharmony_ci return -EINVAL; 450062306a36Sopenharmony_ci } 450162306a36Sopenharmony_ci } 450262306a36Sopenharmony_ci } 450362306a36Sopenharmony_ci } 450462306a36Sopenharmony_ci } 450562306a36Sopenharmony_ci if (command & PACKET3_CP_DMA_CMD_DAS) { 450662306a36Sopenharmony_ci /* dst address space is register */ 450762306a36Sopenharmony_ci if (((info & 0x00300000) >> 20) == 0) { 450862306a36Sopenharmony_ci start_reg = ib[idx + 2]; 450962306a36Sopenharmony_ci if (command & PACKET3_CP_DMA_CMD_DAIC) { 451062306a36Sopenharmony_ci reg = start_reg; 451162306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) { 451262306a36Sopenharmony_ci DRM_ERROR("CP DMA Bad DST register\n"); 451362306a36Sopenharmony_ci return -EINVAL; 451462306a36Sopenharmony_ci } 451562306a36Sopenharmony_ci } else { 451662306a36Sopenharmony_ci for (i = 0; i < (command & 0x1fffff); i++) { 451762306a36Sopenharmony_ci reg = start_reg + (4 * i); 451862306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) { 451962306a36Sopenharmony_ci DRM_ERROR("CP DMA Bad DST register\n"); 452062306a36Sopenharmony_ci return -EINVAL; 452162306a36Sopenharmony_ci } 452262306a36Sopenharmony_ci } 452362306a36Sopenharmony_ci } 452462306a36Sopenharmony_ci } 452562306a36Sopenharmony_ci } 452662306a36Sopenharmony_ci return 0; 452762306a36Sopenharmony_ci} 452862306a36Sopenharmony_ci 452962306a36Sopenharmony_cistatic int si_vm_packet3_gfx_check(struct radeon_device *rdev, 453062306a36Sopenharmony_ci u32 *ib, struct radeon_cs_packet *pkt) 453162306a36Sopenharmony_ci{ 453262306a36Sopenharmony_ci int r; 453362306a36Sopenharmony_ci u32 idx = pkt->idx + 1; 453462306a36Sopenharmony_ci u32 idx_value = ib[idx]; 453562306a36Sopenharmony_ci u32 start_reg, end_reg, reg, i; 453662306a36Sopenharmony_ci 453762306a36Sopenharmony_ci switch (pkt->opcode) { 453862306a36Sopenharmony_ci case PACKET3_NOP: 453962306a36Sopenharmony_ci case PACKET3_SET_BASE: 454062306a36Sopenharmony_ci case PACKET3_CLEAR_STATE: 454162306a36Sopenharmony_ci case PACKET3_INDEX_BUFFER_SIZE: 454262306a36Sopenharmony_ci case PACKET3_DISPATCH_DIRECT: 454362306a36Sopenharmony_ci case PACKET3_DISPATCH_INDIRECT: 454462306a36Sopenharmony_ci case PACKET3_ALLOC_GDS: 454562306a36Sopenharmony_ci case PACKET3_WRITE_GDS_RAM: 454662306a36Sopenharmony_ci case PACKET3_ATOMIC_GDS: 454762306a36Sopenharmony_ci case PACKET3_ATOMIC: 454862306a36Sopenharmony_ci case PACKET3_OCCLUSION_QUERY: 454962306a36Sopenharmony_ci case PACKET3_SET_PREDICATION: 455062306a36Sopenharmony_ci case PACKET3_COND_EXEC: 455162306a36Sopenharmony_ci case PACKET3_PRED_EXEC: 455262306a36Sopenharmony_ci case PACKET3_DRAW_INDIRECT: 455362306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_INDIRECT: 455462306a36Sopenharmony_ci case PACKET3_INDEX_BASE: 455562306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_2: 455662306a36Sopenharmony_ci case PACKET3_CONTEXT_CONTROL: 455762306a36Sopenharmony_ci case PACKET3_INDEX_TYPE: 455862306a36Sopenharmony_ci case PACKET3_DRAW_INDIRECT_MULTI: 455962306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_AUTO: 456062306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_IMMD: 456162306a36Sopenharmony_ci case PACKET3_NUM_INSTANCES: 456262306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_MULTI_AUTO: 456362306a36Sopenharmony_ci case PACKET3_STRMOUT_BUFFER_UPDATE: 456462306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_OFFSET_2: 456562306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_MULTI_ELEMENT: 456662306a36Sopenharmony_ci case PACKET3_DRAW_INDEX_INDIRECT_MULTI: 456762306a36Sopenharmony_ci case PACKET3_MPEG_INDEX: 456862306a36Sopenharmony_ci case PACKET3_WAIT_REG_MEM: 456962306a36Sopenharmony_ci case PACKET3_MEM_WRITE: 457062306a36Sopenharmony_ci case PACKET3_PFP_SYNC_ME: 457162306a36Sopenharmony_ci case PACKET3_SURFACE_SYNC: 457262306a36Sopenharmony_ci case PACKET3_EVENT_WRITE: 457362306a36Sopenharmony_ci case PACKET3_EVENT_WRITE_EOP: 457462306a36Sopenharmony_ci case PACKET3_EVENT_WRITE_EOS: 457562306a36Sopenharmony_ci case PACKET3_SET_CONTEXT_REG: 457662306a36Sopenharmony_ci case PACKET3_SET_CONTEXT_REG_INDIRECT: 457762306a36Sopenharmony_ci case PACKET3_SET_SH_REG: 457862306a36Sopenharmony_ci case PACKET3_SET_SH_REG_OFFSET: 457962306a36Sopenharmony_ci case PACKET3_INCREMENT_DE_COUNTER: 458062306a36Sopenharmony_ci case PACKET3_WAIT_ON_CE_COUNTER: 458162306a36Sopenharmony_ci case PACKET3_WAIT_ON_AVAIL_BUFFER: 458262306a36Sopenharmony_ci case PACKET3_ME_WRITE: 458362306a36Sopenharmony_ci break; 458462306a36Sopenharmony_ci case PACKET3_COPY_DATA: 458562306a36Sopenharmony_ci if ((idx_value & 0xf00) == 0) { 458662306a36Sopenharmony_ci reg = ib[idx + 3] * 4; 458762306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 458862306a36Sopenharmony_ci return -EINVAL; 458962306a36Sopenharmony_ci } 459062306a36Sopenharmony_ci break; 459162306a36Sopenharmony_ci case PACKET3_WRITE_DATA: 459262306a36Sopenharmony_ci if ((idx_value & 0xf00) == 0) { 459362306a36Sopenharmony_ci start_reg = ib[idx + 1] * 4; 459462306a36Sopenharmony_ci if (idx_value & 0x10000) { 459562306a36Sopenharmony_ci if (!si_vm_reg_valid(start_reg)) 459662306a36Sopenharmony_ci return -EINVAL; 459762306a36Sopenharmony_ci } else { 459862306a36Sopenharmony_ci for (i = 0; i < (pkt->count - 2); i++) { 459962306a36Sopenharmony_ci reg = start_reg + (4 * i); 460062306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 460162306a36Sopenharmony_ci return -EINVAL; 460262306a36Sopenharmony_ci } 460362306a36Sopenharmony_ci } 460462306a36Sopenharmony_ci } 460562306a36Sopenharmony_ci break; 460662306a36Sopenharmony_ci case PACKET3_COND_WRITE: 460762306a36Sopenharmony_ci if (idx_value & 0x100) { 460862306a36Sopenharmony_ci reg = ib[idx + 5] * 4; 460962306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 461062306a36Sopenharmony_ci return -EINVAL; 461162306a36Sopenharmony_ci } 461262306a36Sopenharmony_ci break; 461362306a36Sopenharmony_ci case PACKET3_COPY_DW: 461462306a36Sopenharmony_ci if (idx_value & 0x2) { 461562306a36Sopenharmony_ci reg = ib[idx + 3] * 4; 461662306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 461762306a36Sopenharmony_ci return -EINVAL; 461862306a36Sopenharmony_ci } 461962306a36Sopenharmony_ci break; 462062306a36Sopenharmony_ci case PACKET3_SET_CONFIG_REG: 462162306a36Sopenharmony_ci start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START; 462262306a36Sopenharmony_ci end_reg = 4 * pkt->count + start_reg - 4; 462362306a36Sopenharmony_ci if ((start_reg < PACKET3_SET_CONFIG_REG_START) || 462462306a36Sopenharmony_ci (start_reg >= PACKET3_SET_CONFIG_REG_END) || 462562306a36Sopenharmony_ci (end_reg >= PACKET3_SET_CONFIG_REG_END)) { 462662306a36Sopenharmony_ci DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n"); 462762306a36Sopenharmony_ci return -EINVAL; 462862306a36Sopenharmony_ci } 462962306a36Sopenharmony_ci for (i = 0; i < pkt->count; i++) { 463062306a36Sopenharmony_ci reg = start_reg + (4 * i); 463162306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 463262306a36Sopenharmony_ci return -EINVAL; 463362306a36Sopenharmony_ci } 463462306a36Sopenharmony_ci break; 463562306a36Sopenharmony_ci case PACKET3_CP_DMA: 463662306a36Sopenharmony_ci r = si_vm_packet3_cp_dma_check(ib, idx); 463762306a36Sopenharmony_ci if (r) 463862306a36Sopenharmony_ci return r; 463962306a36Sopenharmony_ci break; 464062306a36Sopenharmony_ci default: 464162306a36Sopenharmony_ci DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode); 464262306a36Sopenharmony_ci return -EINVAL; 464362306a36Sopenharmony_ci } 464462306a36Sopenharmony_ci return 0; 464562306a36Sopenharmony_ci} 464662306a36Sopenharmony_ci 464762306a36Sopenharmony_cistatic int si_vm_packet3_compute_check(struct radeon_device *rdev, 464862306a36Sopenharmony_ci u32 *ib, struct radeon_cs_packet *pkt) 464962306a36Sopenharmony_ci{ 465062306a36Sopenharmony_ci int r; 465162306a36Sopenharmony_ci u32 idx = pkt->idx + 1; 465262306a36Sopenharmony_ci u32 idx_value = ib[idx]; 465362306a36Sopenharmony_ci u32 start_reg, reg, i; 465462306a36Sopenharmony_ci 465562306a36Sopenharmony_ci switch (pkt->opcode) { 465662306a36Sopenharmony_ci case PACKET3_NOP: 465762306a36Sopenharmony_ci case PACKET3_SET_BASE: 465862306a36Sopenharmony_ci case PACKET3_CLEAR_STATE: 465962306a36Sopenharmony_ci case PACKET3_DISPATCH_DIRECT: 466062306a36Sopenharmony_ci case PACKET3_DISPATCH_INDIRECT: 466162306a36Sopenharmony_ci case PACKET3_ALLOC_GDS: 466262306a36Sopenharmony_ci case PACKET3_WRITE_GDS_RAM: 466362306a36Sopenharmony_ci case PACKET3_ATOMIC_GDS: 466462306a36Sopenharmony_ci case PACKET3_ATOMIC: 466562306a36Sopenharmony_ci case PACKET3_OCCLUSION_QUERY: 466662306a36Sopenharmony_ci case PACKET3_SET_PREDICATION: 466762306a36Sopenharmony_ci case PACKET3_COND_EXEC: 466862306a36Sopenharmony_ci case PACKET3_PRED_EXEC: 466962306a36Sopenharmony_ci case PACKET3_CONTEXT_CONTROL: 467062306a36Sopenharmony_ci case PACKET3_STRMOUT_BUFFER_UPDATE: 467162306a36Sopenharmony_ci case PACKET3_WAIT_REG_MEM: 467262306a36Sopenharmony_ci case PACKET3_MEM_WRITE: 467362306a36Sopenharmony_ci case PACKET3_PFP_SYNC_ME: 467462306a36Sopenharmony_ci case PACKET3_SURFACE_SYNC: 467562306a36Sopenharmony_ci case PACKET3_EVENT_WRITE: 467662306a36Sopenharmony_ci case PACKET3_EVENT_WRITE_EOP: 467762306a36Sopenharmony_ci case PACKET3_EVENT_WRITE_EOS: 467862306a36Sopenharmony_ci case PACKET3_SET_CONTEXT_REG: 467962306a36Sopenharmony_ci case PACKET3_SET_CONTEXT_REG_INDIRECT: 468062306a36Sopenharmony_ci case PACKET3_SET_SH_REG: 468162306a36Sopenharmony_ci case PACKET3_SET_SH_REG_OFFSET: 468262306a36Sopenharmony_ci case PACKET3_INCREMENT_DE_COUNTER: 468362306a36Sopenharmony_ci case PACKET3_WAIT_ON_CE_COUNTER: 468462306a36Sopenharmony_ci case PACKET3_WAIT_ON_AVAIL_BUFFER: 468562306a36Sopenharmony_ci case PACKET3_ME_WRITE: 468662306a36Sopenharmony_ci break; 468762306a36Sopenharmony_ci case PACKET3_COPY_DATA: 468862306a36Sopenharmony_ci if ((idx_value & 0xf00) == 0) { 468962306a36Sopenharmony_ci reg = ib[idx + 3] * 4; 469062306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 469162306a36Sopenharmony_ci return -EINVAL; 469262306a36Sopenharmony_ci } 469362306a36Sopenharmony_ci break; 469462306a36Sopenharmony_ci case PACKET3_WRITE_DATA: 469562306a36Sopenharmony_ci if ((idx_value & 0xf00) == 0) { 469662306a36Sopenharmony_ci start_reg = ib[idx + 1] * 4; 469762306a36Sopenharmony_ci if (idx_value & 0x10000) { 469862306a36Sopenharmony_ci if (!si_vm_reg_valid(start_reg)) 469962306a36Sopenharmony_ci return -EINVAL; 470062306a36Sopenharmony_ci } else { 470162306a36Sopenharmony_ci for (i = 0; i < (pkt->count - 2); i++) { 470262306a36Sopenharmony_ci reg = start_reg + (4 * i); 470362306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 470462306a36Sopenharmony_ci return -EINVAL; 470562306a36Sopenharmony_ci } 470662306a36Sopenharmony_ci } 470762306a36Sopenharmony_ci } 470862306a36Sopenharmony_ci break; 470962306a36Sopenharmony_ci case PACKET3_COND_WRITE: 471062306a36Sopenharmony_ci if (idx_value & 0x100) { 471162306a36Sopenharmony_ci reg = ib[idx + 5] * 4; 471262306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 471362306a36Sopenharmony_ci return -EINVAL; 471462306a36Sopenharmony_ci } 471562306a36Sopenharmony_ci break; 471662306a36Sopenharmony_ci case PACKET3_COPY_DW: 471762306a36Sopenharmony_ci if (idx_value & 0x2) { 471862306a36Sopenharmony_ci reg = ib[idx + 3] * 4; 471962306a36Sopenharmony_ci if (!si_vm_reg_valid(reg)) 472062306a36Sopenharmony_ci return -EINVAL; 472162306a36Sopenharmony_ci } 472262306a36Sopenharmony_ci break; 472362306a36Sopenharmony_ci case PACKET3_CP_DMA: 472462306a36Sopenharmony_ci r = si_vm_packet3_cp_dma_check(ib, idx); 472562306a36Sopenharmony_ci if (r) 472662306a36Sopenharmony_ci return r; 472762306a36Sopenharmony_ci break; 472862306a36Sopenharmony_ci default: 472962306a36Sopenharmony_ci DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode); 473062306a36Sopenharmony_ci return -EINVAL; 473162306a36Sopenharmony_ci } 473262306a36Sopenharmony_ci return 0; 473362306a36Sopenharmony_ci} 473462306a36Sopenharmony_ci 473562306a36Sopenharmony_ciint si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) 473662306a36Sopenharmony_ci{ 473762306a36Sopenharmony_ci int ret = 0; 473862306a36Sopenharmony_ci u32 idx = 0, i; 473962306a36Sopenharmony_ci struct radeon_cs_packet pkt; 474062306a36Sopenharmony_ci 474162306a36Sopenharmony_ci do { 474262306a36Sopenharmony_ci pkt.idx = idx; 474362306a36Sopenharmony_ci pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]); 474462306a36Sopenharmony_ci pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]); 474562306a36Sopenharmony_ci pkt.one_reg_wr = 0; 474662306a36Sopenharmony_ci switch (pkt.type) { 474762306a36Sopenharmony_ci case RADEON_PACKET_TYPE0: 474862306a36Sopenharmony_ci dev_err(rdev->dev, "Packet0 not allowed!\n"); 474962306a36Sopenharmony_ci ret = -EINVAL; 475062306a36Sopenharmony_ci break; 475162306a36Sopenharmony_ci case RADEON_PACKET_TYPE2: 475262306a36Sopenharmony_ci idx += 1; 475362306a36Sopenharmony_ci break; 475462306a36Sopenharmony_ci case RADEON_PACKET_TYPE3: 475562306a36Sopenharmony_ci pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]); 475662306a36Sopenharmony_ci if (ib->is_const_ib) 475762306a36Sopenharmony_ci ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt); 475862306a36Sopenharmony_ci else { 475962306a36Sopenharmony_ci switch (ib->ring) { 476062306a36Sopenharmony_ci case RADEON_RING_TYPE_GFX_INDEX: 476162306a36Sopenharmony_ci ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt); 476262306a36Sopenharmony_ci break; 476362306a36Sopenharmony_ci case CAYMAN_RING_TYPE_CP1_INDEX: 476462306a36Sopenharmony_ci case CAYMAN_RING_TYPE_CP2_INDEX: 476562306a36Sopenharmony_ci ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt); 476662306a36Sopenharmony_ci break; 476762306a36Sopenharmony_ci default: 476862306a36Sopenharmony_ci dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->ring); 476962306a36Sopenharmony_ci ret = -EINVAL; 477062306a36Sopenharmony_ci break; 477162306a36Sopenharmony_ci } 477262306a36Sopenharmony_ci } 477362306a36Sopenharmony_ci idx += pkt.count + 2; 477462306a36Sopenharmony_ci break; 477562306a36Sopenharmony_ci default: 477662306a36Sopenharmony_ci dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type); 477762306a36Sopenharmony_ci ret = -EINVAL; 477862306a36Sopenharmony_ci break; 477962306a36Sopenharmony_ci } 478062306a36Sopenharmony_ci if (ret) { 478162306a36Sopenharmony_ci for (i = 0; i < ib->length_dw; i++) { 478262306a36Sopenharmony_ci if (i == idx) 478362306a36Sopenharmony_ci printk("\t0x%08x <---\n", ib->ptr[i]); 478462306a36Sopenharmony_ci else 478562306a36Sopenharmony_ci printk("\t0x%08x\n", ib->ptr[i]); 478662306a36Sopenharmony_ci } 478762306a36Sopenharmony_ci break; 478862306a36Sopenharmony_ci } 478962306a36Sopenharmony_ci } while (idx < ib->length_dw); 479062306a36Sopenharmony_ci 479162306a36Sopenharmony_ci return ret; 479262306a36Sopenharmony_ci} 479362306a36Sopenharmony_ci 479462306a36Sopenharmony_ci/* 479562306a36Sopenharmony_ci * vm 479662306a36Sopenharmony_ci */ 479762306a36Sopenharmony_ciint si_vm_init(struct radeon_device *rdev) 479862306a36Sopenharmony_ci{ 479962306a36Sopenharmony_ci /* number of VMs */ 480062306a36Sopenharmony_ci rdev->vm_manager.nvm = 16; 480162306a36Sopenharmony_ci /* base offset of vram pages */ 480262306a36Sopenharmony_ci rdev->vm_manager.vram_base_offset = 0; 480362306a36Sopenharmony_ci 480462306a36Sopenharmony_ci return 0; 480562306a36Sopenharmony_ci} 480662306a36Sopenharmony_ci 480762306a36Sopenharmony_civoid si_vm_fini(struct radeon_device *rdev) 480862306a36Sopenharmony_ci{ 480962306a36Sopenharmony_ci} 481062306a36Sopenharmony_ci 481162306a36Sopenharmony_ci/** 481262306a36Sopenharmony_ci * si_vm_decode_fault - print human readable fault info 481362306a36Sopenharmony_ci * 481462306a36Sopenharmony_ci * @rdev: radeon_device pointer 481562306a36Sopenharmony_ci * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value 481662306a36Sopenharmony_ci * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value 481762306a36Sopenharmony_ci * 481862306a36Sopenharmony_ci * Print human readable fault information (SI). 481962306a36Sopenharmony_ci */ 482062306a36Sopenharmony_cistatic void si_vm_decode_fault(struct radeon_device *rdev, 482162306a36Sopenharmony_ci u32 status, u32 addr) 482262306a36Sopenharmony_ci{ 482362306a36Sopenharmony_ci u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; 482462306a36Sopenharmony_ci u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; 482562306a36Sopenharmony_ci u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; 482662306a36Sopenharmony_ci char *block; 482762306a36Sopenharmony_ci 482862306a36Sopenharmony_ci if (rdev->family == CHIP_TAHITI) { 482962306a36Sopenharmony_ci switch (mc_id) { 483062306a36Sopenharmony_ci case 160: 483162306a36Sopenharmony_ci case 144: 483262306a36Sopenharmony_ci case 96: 483362306a36Sopenharmony_ci case 80: 483462306a36Sopenharmony_ci case 224: 483562306a36Sopenharmony_ci case 208: 483662306a36Sopenharmony_ci case 32: 483762306a36Sopenharmony_ci case 16: 483862306a36Sopenharmony_ci block = "CB"; 483962306a36Sopenharmony_ci break; 484062306a36Sopenharmony_ci case 161: 484162306a36Sopenharmony_ci case 145: 484262306a36Sopenharmony_ci case 97: 484362306a36Sopenharmony_ci case 81: 484462306a36Sopenharmony_ci case 225: 484562306a36Sopenharmony_ci case 209: 484662306a36Sopenharmony_ci case 33: 484762306a36Sopenharmony_ci case 17: 484862306a36Sopenharmony_ci block = "CB_FMASK"; 484962306a36Sopenharmony_ci break; 485062306a36Sopenharmony_ci case 162: 485162306a36Sopenharmony_ci case 146: 485262306a36Sopenharmony_ci case 98: 485362306a36Sopenharmony_ci case 82: 485462306a36Sopenharmony_ci case 226: 485562306a36Sopenharmony_ci case 210: 485662306a36Sopenharmony_ci case 34: 485762306a36Sopenharmony_ci case 18: 485862306a36Sopenharmony_ci block = "CB_CMASK"; 485962306a36Sopenharmony_ci break; 486062306a36Sopenharmony_ci case 163: 486162306a36Sopenharmony_ci case 147: 486262306a36Sopenharmony_ci case 99: 486362306a36Sopenharmony_ci case 83: 486462306a36Sopenharmony_ci case 227: 486562306a36Sopenharmony_ci case 211: 486662306a36Sopenharmony_ci case 35: 486762306a36Sopenharmony_ci case 19: 486862306a36Sopenharmony_ci block = "CB_IMMED"; 486962306a36Sopenharmony_ci break; 487062306a36Sopenharmony_ci case 164: 487162306a36Sopenharmony_ci case 148: 487262306a36Sopenharmony_ci case 100: 487362306a36Sopenharmony_ci case 84: 487462306a36Sopenharmony_ci case 228: 487562306a36Sopenharmony_ci case 212: 487662306a36Sopenharmony_ci case 36: 487762306a36Sopenharmony_ci case 20: 487862306a36Sopenharmony_ci block = "DB"; 487962306a36Sopenharmony_ci break; 488062306a36Sopenharmony_ci case 165: 488162306a36Sopenharmony_ci case 149: 488262306a36Sopenharmony_ci case 101: 488362306a36Sopenharmony_ci case 85: 488462306a36Sopenharmony_ci case 229: 488562306a36Sopenharmony_ci case 213: 488662306a36Sopenharmony_ci case 37: 488762306a36Sopenharmony_ci case 21: 488862306a36Sopenharmony_ci block = "DB_HTILE"; 488962306a36Sopenharmony_ci break; 489062306a36Sopenharmony_ci case 167: 489162306a36Sopenharmony_ci case 151: 489262306a36Sopenharmony_ci case 103: 489362306a36Sopenharmony_ci case 87: 489462306a36Sopenharmony_ci case 231: 489562306a36Sopenharmony_ci case 215: 489662306a36Sopenharmony_ci case 39: 489762306a36Sopenharmony_ci case 23: 489862306a36Sopenharmony_ci block = "DB_STEN"; 489962306a36Sopenharmony_ci break; 490062306a36Sopenharmony_ci case 72: 490162306a36Sopenharmony_ci case 68: 490262306a36Sopenharmony_ci case 64: 490362306a36Sopenharmony_ci case 8: 490462306a36Sopenharmony_ci case 4: 490562306a36Sopenharmony_ci case 0: 490662306a36Sopenharmony_ci case 136: 490762306a36Sopenharmony_ci case 132: 490862306a36Sopenharmony_ci case 128: 490962306a36Sopenharmony_ci case 200: 491062306a36Sopenharmony_ci case 196: 491162306a36Sopenharmony_ci case 192: 491262306a36Sopenharmony_ci block = "TC"; 491362306a36Sopenharmony_ci break; 491462306a36Sopenharmony_ci case 112: 491562306a36Sopenharmony_ci case 48: 491662306a36Sopenharmony_ci block = "CP"; 491762306a36Sopenharmony_ci break; 491862306a36Sopenharmony_ci case 49: 491962306a36Sopenharmony_ci case 177: 492062306a36Sopenharmony_ci case 50: 492162306a36Sopenharmony_ci case 178: 492262306a36Sopenharmony_ci block = "SH"; 492362306a36Sopenharmony_ci break; 492462306a36Sopenharmony_ci case 53: 492562306a36Sopenharmony_ci case 190: 492662306a36Sopenharmony_ci block = "VGT"; 492762306a36Sopenharmony_ci break; 492862306a36Sopenharmony_ci case 117: 492962306a36Sopenharmony_ci block = "IH"; 493062306a36Sopenharmony_ci break; 493162306a36Sopenharmony_ci case 51: 493262306a36Sopenharmony_ci case 115: 493362306a36Sopenharmony_ci block = "RLC"; 493462306a36Sopenharmony_ci break; 493562306a36Sopenharmony_ci case 119: 493662306a36Sopenharmony_ci case 183: 493762306a36Sopenharmony_ci block = "DMA0"; 493862306a36Sopenharmony_ci break; 493962306a36Sopenharmony_ci case 61: 494062306a36Sopenharmony_ci block = "DMA1"; 494162306a36Sopenharmony_ci break; 494262306a36Sopenharmony_ci case 248: 494362306a36Sopenharmony_ci case 120: 494462306a36Sopenharmony_ci block = "HDP"; 494562306a36Sopenharmony_ci break; 494662306a36Sopenharmony_ci default: 494762306a36Sopenharmony_ci block = "unknown"; 494862306a36Sopenharmony_ci break; 494962306a36Sopenharmony_ci } 495062306a36Sopenharmony_ci } else { 495162306a36Sopenharmony_ci switch (mc_id) { 495262306a36Sopenharmony_ci case 32: 495362306a36Sopenharmony_ci case 16: 495462306a36Sopenharmony_ci case 96: 495562306a36Sopenharmony_ci case 80: 495662306a36Sopenharmony_ci case 160: 495762306a36Sopenharmony_ci case 144: 495862306a36Sopenharmony_ci case 224: 495962306a36Sopenharmony_ci case 208: 496062306a36Sopenharmony_ci block = "CB"; 496162306a36Sopenharmony_ci break; 496262306a36Sopenharmony_ci case 33: 496362306a36Sopenharmony_ci case 17: 496462306a36Sopenharmony_ci case 97: 496562306a36Sopenharmony_ci case 81: 496662306a36Sopenharmony_ci case 161: 496762306a36Sopenharmony_ci case 145: 496862306a36Sopenharmony_ci case 225: 496962306a36Sopenharmony_ci case 209: 497062306a36Sopenharmony_ci block = "CB_FMASK"; 497162306a36Sopenharmony_ci break; 497262306a36Sopenharmony_ci case 34: 497362306a36Sopenharmony_ci case 18: 497462306a36Sopenharmony_ci case 98: 497562306a36Sopenharmony_ci case 82: 497662306a36Sopenharmony_ci case 162: 497762306a36Sopenharmony_ci case 146: 497862306a36Sopenharmony_ci case 226: 497962306a36Sopenharmony_ci case 210: 498062306a36Sopenharmony_ci block = "CB_CMASK"; 498162306a36Sopenharmony_ci break; 498262306a36Sopenharmony_ci case 35: 498362306a36Sopenharmony_ci case 19: 498462306a36Sopenharmony_ci case 99: 498562306a36Sopenharmony_ci case 83: 498662306a36Sopenharmony_ci case 163: 498762306a36Sopenharmony_ci case 147: 498862306a36Sopenharmony_ci case 227: 498962306a36Sopenharmony_ci case 211: 499062306a36Sopenharmony_ci block = "CB_IMMED"; 499162306a36Sopenharmony_ci break; 499262306a36Sopenharmony_ci case 36: 499362306a36Sopenharmony_ci case 20: 499462306a36Sopenharmony_ci case 100: 499562306a36Sopenharmony_ci case 84: 499662306a36Sopenharmony_ci case 164: 499762306a36Sopenharmony_ci case 148: 499862306a36Sopenharmony_ci case 228: 499962306a36Sopenharmony_ci case 212: 500062306a36Sopenharmony_ci block = "DB"; 500162306a36Sopenharmony_ci break; 500262306a36Sopenharmony_ci case 37: 500362306a36Sopenharmony_ci case 21: 500462306a36Sopenharmony_ci case 101: 500562306a36Sopenharmony_ci case 85: 500662306a36Sopenharmony_ci case 165: 500762306a36Sopenharmony_ci case 149: 500862306a36Sopenharmony_ci case 229: 500962306a36Sopenharmony_ci case 213: 501062306a36Sopenharmony_ci block = "DB_HTILE"; 501162306a36Sopenharmony_ci break; 501262306a36Sopenharmony_ci case 39: 501362306a36Sopenharmony_ci case 23: 501462306a36Sopenharmony_ci case 103: 501562306a36Sopenharmony_ci case 87: 501662306a36Sopenharmony_ci case 167: 501762306a36Sopenharmony_ci case 151: 501862306a36Sopenharmony_ci case 231: 501962306a36Sopenharmony_ci case 215: 502062306a36Sopenharmony_ci block = "DB_STEN"; 502162306a36Sopenharmony_ci break; 502262306a36Sopenharmony_ci case 72: 502362306a36Sopenharmony_ci case 68: 502462306a36Sopenharmony_ci case 8: 502562306a36Sopenharmony_ci case 4: 502662306a36Sopenharmony_ci case 136: 502762306a36Sopenharmony_ci case 132: 502862306a36Sopenharmony_ci case 200: 502962306a36Sopenharmony_ci case 196: 503062306a36Sopenharmony_ci block = "TC"; 503162306a36Sopenharmony_ci break; 503262306a36Sopenharmony_ci case 112: 503362306a36Sopenharmony_ci case 48: 503462306a36Sopenharmony_ci block = "CP"; 503562306a36Sopenharmony_ci break; 503662306a36Sopenharmony_ci case 49: 503762306a36Sopenharmony_ci case 177: 503862306a36Sopenharmony_ci case 50: 503962306a36Sopenharmony_ci case 178: 504062306a36Sopenharmony_ci block = "SH"; 504162306a36Sopenharmony_ci break; 504262306a36Sopenharmony_ci case 53: 504362306a36Sopenharmony_ci block = "VGT"; 504462306a36Sopenharmony_ci break; 504562306a36Sopenharmony_ci case 117: 504662306a36Sopenharmony_ci block = "IH"; 504762306a36Sopenharmony_ci break; 504862306a36Sopenharmony_ci case 51: 504962306a36Sopenharmony_ci case 115: 505062306a36Sopenharmony_ci block = "RLC"; 505162306a36Sopenharmony_ci break; 505262306a36Sopenharmony_ci case 119: 505362306a36Sopenharmony_ci case 183: 505462306a36Sopenharmony_ci block = "DMA0"; 505562306a36Sopenharmony_ci break; 505662306a36Sopenharmony_ci case 61: 505762306a36Sopenharmony_ci block = "DMA1"; 505862306a36Sopenharmony_ci break; 505962306a36Sopenharmony_ci case 248: 506062306a36Sopenharmony_ci case 120: 506162306a36Sopenharmony_ci block = "HDP"; 506262306a36Sopenharmony_ci break; 506362306a36Sopenharmony_ci default: 506462306a36Sopenharmony_ci block = "unknown"; 506562306a36Sopenharmony_ci break; 506662306a36Sopenharmony_ci } 506762306a36Sopenharmony_ci } 506862306a36Sopenharmony_ci 506962306a36Sopenharmony_ci printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n", 507062306a36Sopenharmony_ci protections, vmid, addr, 507162306a36Sopenharmony_ci (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", 507262306a36Sopenharmony_ci block, mc_id); 507362306a36Sopenharmony_ci} 507462306a36Sopenharmony_ci 507562306a36Sopenharmony_civoid si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, 507662306a36Sopenharmony_ci unsigned vm_id, uint64_t pd_addr) 507762306a36Sopenharmony_ci{ 507862306a36Sopenharmony_ci /* write new base address */ 507962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 508062306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | 508162306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 508262306a36Sopenharmony_ci 508362306a36Sopenharmony_ci if (vm_id < 8) { 508462306a36Sopenharmony_ci radeon_ring_write(ring, 508562306a36Sopenharmony_ci (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); 508662306a36Sopenharmony_ci } else { 508762306a36Sopenharmony_ci radeon_ring_write(ring, 508862306a36Sopenharmony_ci (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); 508962306a36Sopenharmony_ci } 509062306a36Sopenharmony_ci radeon_ring_write(ring, 0); 509162306a36Sopenharmony_ci radeon_ring_write(ring, pd_addr >> 12); 509262306a36Sopenharmony_ci 509362306a36Sopenharmony_ci /* flush hdp cache */ 509462306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 509562306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | 509662306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 509762306a36Sopenharmony_ci radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2); 509862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 509962306a36Sopenharmony_ci radeon_ring_write(ring, 0x1); 510062306a36Sopenharmony_ci 510162306a36Sopenharmony_ci /* bits 0-15 are the VM contexts0-15 */ 510262306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 510362306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) | 510462306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 510562306a36Sopenharmony_ci radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 510662306a36Sopenharmony_ci radeon_ring_write(ring, 0); 510762306a36Sopenharmony_ci radeon_ring_write(ring, 1 << vm_id); 510862306a36Sopenharmony_ci 510962306a36Sopenharmony_ci /* wait for the invalidate to complete */ 511062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); 511162306a36Sopenharmony_ci radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) | /* always */ 511262306a36Sopenharmony_ci WAIT_REG_MEM_ENGINE(0))); /* me */ 511362306a36Sopenharmony_ci radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 511462306a36Sopenharmony_ci radeon_ring_write(ring, 0); 511562306a36Sopenharmony_ci radeon_ring_write(ring, 0); /* ref */ 511662306a36Sopenharmony_ci radeon_ring_write(ring, 0); /* mask */ 511762306a36Sopenharmony_ci radeon_ring_write(ring, 0x20); /* poll interval */ 511862306a36Sopenharmony_ci 511962306a36Sopenharmony_ci /* sync PFP to ME, otherwise we might get invalid PFP reads */ 512062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); 512162306a36Sopenharmony_ci radeon_ring_write(ring, 0x0); 512262306a36Sopenharmony_ci} 512362306a36Sopenharmony_ci 512462306a36Sopenharmony_ci/* 512562306a36Sopenharmony_ci * Power and clock gating 512662306a36Sopenharmony_ci */ 512762306a36Sopenharmony_cistatic void si_wait_for_rlc_serdes(struct radeon_device *rdev) 512862306a36Sopenharmony_ci{ 512962306a36Sopenharmony_ci int i; 513062306a36Sopenharmony_ci 513162306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 513262306a36Sopenharmony_ci if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0) 513362306a36Sopenharmony_ci break; 513462306a36Sopenharmony_ci udelay(1); 513562306a36Sopenharmony_ci } 513662306a36Sopenharmony_ci 513762306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 513862306a36Sopenharmony_ci if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0) 513962306a36Sopenharmony_ci break; 514062306a36Sopenharmony_ci udelay(1); 514162306a36Sopenharmony_ci } 514262306a36Sopenharmony_ci} 514362306a36Sopenharmony_ci 514462306a36Sopenharmony_cistatic void si_enable_gui_idle_interrupt(struct radeon_device *rdev, 514562306a36Sopenharmony_ci bool enable) 514662306a36Sopenharmony_ci{ 514762306a36Sopenharmony_ci u32 tmp = RREG32(CP_INT_CNTL_RING0); 514862306a36Sopenharmony_ci u32 mask; 514962306a36Sopenharmony_ci int i; 515062306a36Sopenharmony_ci 515162306a36Sopenharmony_ci if (enable) 515262306a36Sopenharmony_ci tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 515362306a36Sopenharmony_ci else 515462306a36Sopenharmony_ci tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 515562306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING0, tmp); 515662306a36Sopenharmony_ci 515762306a36Sopenharmony_ci if (!enable) { 515862306a36Sopenharmony_ci /* read a gfx register */ 515962306a36Sopenharmony_ci tmp = RREG32(DB_DEPTH_INFO); 516062306a36Sopenharmony_ci 516162306a36Sopenharmony_ci mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS; 516262306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 516362306a36Sopenharmony_ci if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS)) 516462306a36Sopenharmony_ci break; 516562306a36Sopenharmony_ci udelay(1); 516662306a36Sopenharmony_ci } 516762306a36Sopenharmony_ci } 516862306a36Sopenharmony_ci} 516962306a36Sopenharmony_ci 517062306a36Sopenharmony_cistatic void si_set_uvd_dcm(struct radeon_device *rdev, 517162306a36Sopenharmony_ci bool sw_mode) 517262306a36Sopenharmony_ci{ 517362306a36Sopenharmony_ci u32 tmp, tmp2; 517462306a36Sopenharmony_ci 517562306a36Sopenharmony_ci tmp = RREG32(UVD_CGC_CTRL); 517662306a36Sopenharmony_ci tmp &= ~(CLK_OD_MASK | CG_DT_MASK); 517762306a36Sopenharmony_ci tmp |= DCM | CG_DT(1) | CLK_OD(4); 517862306a36Sopenharmony_ci 517962306a36Sopenharmony_ci if (sw_mode) { 518062306a36Sopenharmony_ci tmp &= ~0x7ffff800; 518162306a36Sopenharmony_ci tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7); 518262306a36Sopenharmony_ci } else { 518362306a36Sopenharmony_ci tmp |= 0x7ffff800; 518462306a36Sopenharmony_ci tmp2 = 0; 518562306a36Sopenharmony_ci } 518662306a36Sopenharmony_ci 518762306a36Sopenharmony_ci WREG32(UVD_CGC_CTRL, tmp); 518862306a36Sopenharmony_ci WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2); 518962306a36Sopenharmony_ci} 519062306a36Sopenharmony_ci 519162306a36Sopenharmony_civoid si_init_uvd_internal_cg(struct radeon_device *rdev) 519262306a36Sopenharmony_ci{ 519362306a36Sopenharmony_ci bool hw_mode = true; 519462306a36Sopenharmony_ci 519562306a36Sopenharmony_ci if (hw_mode) { 519662306a36Sopenharmony_ci si_set_uvd_dcm(rdev, false); 519762306a36Sopenharmony_ci } else { 519862306a36Sopenharmony_ci u32 tmp = RREG32(UVD_CGC_CTRL); 519962306a36Sopenharmony_ci tmp &= ~DCM; 520062306a36Sopenharmony_ci WREG32(UVD_CGC_CTRL, tmp); 520162306a36Sopenharmony_ci } 520262306a36Sopenharmony_ci} 520362306a36Sopenharmony_ci 520462306a36Sopenharmony_cistatic u32 si_halt_rlc(struct radeon_device *rdev) 520562306a36Sopenharmony_ci{ 520662306a36Sopenharmony_ci u32 data, orig; 520762306a36Sopenharmony_ci 520862306a36Sopenharmony_ci orig = data = RREG32(RLC_CNTL); 520962306a36Sopenharmony_ci 521062306a36Sopenharmony_ci if (data & RLC_ENABLE) { 521162306a36Sopenharmony_ci data &= ~RLC_ENABLE; 521262306a36Sopenharmony_ci WREG32(RLC_CNTL, data); 521362306a36Sopenharmony_ci 521462306a36Sopenharmony_ci si_wait_for_rlc_serdes(rdev); 521562306a36Sopenharmony_ci } 521662306a36Sopenharmony_ci 521762306a36Sopenharmony_ci return orig; 521862306a36Sopenharmony_ci} 521962306a36Sopenharmony_ci 522062306a36Sopenharmony_cistatic void si_update_rlc(struct radeon_device *rdev, u32 rlc) 522162306a36Sopenharmony_ci{ 522262306a36Sopenharmony_ci u32 tmp; 522362306a36Sopenharmony_ci 522462306a36Sopenharmony_ci tmp = RREG32(RLC_CNTL); 522562306a36Sopenharmony_ci if (tmp != rlc) 522662306a36Sopenharmony_ci WREG32(RLC_CNTL, rlc); 522762306a36Sopenharmony_ci} 522862306a36Sopenharmony_ci 522962306a36Sopenharmony_cistatic void si_enable_dma_pg(struct radeon_device *rdev, bool enable) 523062306a36Sopenharmony_ci{ 523162306a36Sopenharmony_ci u32 data, orig; 523262306a36Sopenharmony_ci 523362306a36Sopenharmony_ci orig = data = RREG32(DMA_PG); 523462306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA)) 523562306a36Sopenharmony_ci data |= PG_CNTL_ENABLE; 523662306a36Sopenharmony_ci else 523762306a36Sopenharmony_ci data &= ~PG_CNTL_ENABLE; 523862306a36Sopenharmony_ci if (orig != data) 523962306a36Sopenharmony_ci WREG32(DMA_PG, data); 524062306a36Sopenharmony_ci} 524162306a36Sopenharmony_ci 524262306a36Sopenharmony_cistatic void si_init_dma_pg(struct radeon_device *rdev) 524362306a36Sopenharmony_ci{ 524462306a36Sopenharmony_ci u32 tmp; 524562306a36Sopenharmony_ci 524662306a36Sopenharmony_ci WREG32(DMA_PGFSM_WRITE, 0x00002000); 524762306a36Sopenharmony_ci WREG32(DMA_PGFSM_CONFIG, 0x100010ff); 524862306a36Sopenharmony_ci 524962306a36Sopenharmony_ci for (tmp = 0; tmp < 5; tmp++) 525062306a36Sopenharmony_ci WREG32(DMA_PGFSM_WRITE, 0); 525162306a36Sopenharmony_ci} 525262306a36Sopenharmony_ci 525362306a36Sopenharmony_cistatic void si_enable_gfx_cgpg(struct radeon_device *rdev, 525462306a36Sopenharmony_ci bool enable) 525562306a36Sopenharmony_ci{ 525662306a36Sopenharmony_ci u32 tmp; 525762306a36Sopenharmony_ci 525862306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) { 525962306a36Sopenharmony_ci tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10); 526062306a36Sopenharmony_ci WREG32(RLC_TTOP_D, tmp); 526162306a36Sopenharmony_ci 526262306a36Sopenharmony_ci tmp = RREG32(RLC_PG_CNTL); 526362306a36Sopenharmony_ci tmp |= GFX_PG_ENABLE; 526462306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, tmp); 526562306a36Sopenharmony_ci 526662306a36Sopenharmony_ci tmp = RREG32(RLC_AUTO_PG_CTRL); 526762306a36Sopenharmony_ci tmp |= AUTO_PG_EN; 526862306a36Sopenharmony_ci WREG32(RLC_AUTO_PG_CTRL, tmp); 526962306a36Sopenharmony_ci } else { 527062306a36Sopenharmony_ci tmp = RREG32(RLC_AUTO_PG_CTRL); 527162306a36Sopenharmony_ci tmp &= ~AUTO_PG_EN; 527262306a36Sopenharmony_ci WREG32(RLC_AUTO_PG_CTRL, tmp); 527362306a36Sopenharmony_ci 527462306a36Sopenharmony_ci tmp = RREG32(DB_RENDER_CONTROL); 527562306a36Sopenharmony_ci } 527662306a36Sopenharmony_ci} 527762306a36Sopenharmony_ci 527862306a36Sopenharmony_cistatic void si_init_gfx_cgpg(struct radeon_device *rdev) 527962306a36Sopenharmony_ci{ 528062306a36Sopenharmony_ci u32 tmp; 528162306a36Sopenharmony_ci 528262306a36Sopenharmony_ci WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); 528362306a36Sopenharmony_ci 528462306a36Sopenharmony_ci tmp = RREG32(RLC_PG_CNTL); 528562306a36Sopenharmony_ci tmp |= GFX_PG_SRC; 528662306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, tmp); 528762306a36Sopenharmony_ci 528862306a36Sopenharmony_ci WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); 528962306a36Sopenharmony_ci 529062306a36Sopenharmony_ci tmp = RREG32(RLC_AUTO_PG_CTRL); 529162306a36Sopenharmony_ci 529262306a36Sopenharmony_ci tmp &= ~GRBM_REG_SGIT_MASK; 529362306a36Sopenharmony_ci tmp |= GRBM_REG_SGIT(0x700); 529462306a36Sopenharmony_ci tmp &= ~PG_AFTER_GRBM_REG_ST_MASK; 529562306a36Sopenharmony_ci WREG32(RLC_AUTO_PG_CTRL, tmp); 529662306a36Sopenharmony_ci} 529762306a36Sopenharmony_ci 529862306a36Sopenharmony_cistatic u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh) 529962306a36Sopenharmony_ci{ 530062306a36Sopenharmony_ci u32 mask = 0, tmp, tmp1; 530162306a36Sopenharmony_ci int i; 530262306a36Sopenharmony_ci 530362306a36Sopenharmony_ci si_select_se_sh(rdev, se, sh); 530462306a36Sopenharmony_ci tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG); 530562306a36Sopenharmony_ci tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG); 530662306a36Sopenharmony_ci si_select_se_sh(rdev, 0xffffffff, 0xffffffff); 530762306a36Sopenharmony_ci 530862306a36Sopenharmony_ci tmp &= 0xffff0000; 530962306a36Sopenharmony_ci 531062306a36Sopenharmony_ci tmp |= tmp1; 531162306a36Sopenharmony_ci tmp >>= 16; 531262306a36Sopenharmony_ci 531362306a36Sopenharmony_ci for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) { 531462306a36Sopenharmony_ci mask <<= 1; 531562306a36Sopenharmony_ci mask |= 1; 531662306a36Sopenharmony_ci } 531762306a36Sopenharmony_ci 531862306a36Sopenharmony_ci return (~tmp) & mask; 531962306a36Sopenharmony_ci} 532062306a36Sopenharmony_ci 532162306a36Sopenharmony_cistatic void si_init_ao_cu_mask(struct radeon_device *rdev) 532262306a36Sopenharmony_ci{ 532362306a36Sopenharmony_ci u32 i, j, k, active_cu_number = 0; 532462306a36Sopenharmony_ci u32 mask, counter, cu_bitmap; 532562306a36Sopenharmony_ci u32 tmp = 0; 532662306a36Sopenharmony_ci 532762306a36Sopenharmony_ci for (i = 0; i < rdev->config.si.max_shader_engines; i++) { 532862306a36Sopenharmony_ci for (j = 0; j < rdev->config.si.max_sh_per_se; j++) { 532962306a36Sopenharmony_ci mask = 1; 533062306a36Sopenharmony_ci cu_bitmap = 0; 533162306a36Sopenharmony_ci counter = 0; 533262306a36Sopenharmony_ci for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) { 533362306a36Sopenharmony_ci if (si_get_cu_active_bitmap(rdev, i, j) & mask) { 533462306a36Sopenharmony_ci if (counter < 2) 533562306a36Sopenharmony_ci cu_bitmap |= mask; 533662306a36Sopenharmony_ci counter++; 533762306a36Sopenharmony_ci } 533862306a36Sopenharmony_ci mask <<= 1; 533962306a36Sopenharmony_ci } 534062306a36Sopenharmony_ci 534162306a36Sopenharmony_ci active_cu_number += counter; 534262306a36Sopenharmony_ci tmp |= (cu_bitmap << (i * 16 + j * 8)); 534362306a36Sopenharmony_ci } 534462306a36Sopenharmony_ci } 534562306a36Sopenharmony_ci 534662306a36Sopenharmony_ci WREG32(RLC_PG_AO_CU_MASK, tmp); 534762306a36Sopenharmony_ci 534862306a36Sopenharmony_ci tmp = RREG32(RLC_MAX_PG_CU); 534962306a36Sopenharmony_ci tmp &= ~MAX_PU_CU_MASK; 535062306a36Sopenharmony_ci tmp |= MAX_PU_CU(active_cu_number); 535162306a36Sopenharmony_ci WREG32(RLC_MAX_PG_CU, tmp); 535262306a36Sopenharmony_ci} 535362306a36Sopenharmony_ci 535462306a36Sopenharmony_cistatic void si_enable_cgcg(struct radeon_device *rdev, 535562306a36Sopenharmony_ci bool enable) 535662306a36Sopenharmony_ci{ 535762306a36Sopenharmony_ci u32 data, orig, tmp; 535862306a36Sopenharmony_ci 535962306a36Sopenharmony_ci orig = data = RREG32(RLC_CGCG_CGLS_CTRL); 536062306a36Sopenharmony_ci 536162306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) { 536262306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, true); 536362306a36Sopenharmony_ci 536462306a36Sopenharmony_ci WREG32(RLC_GCPM_GENERAL_3, 0x00000080); 536562306a36Sopenharmony_ci 536662306a36Sopenharmony_ci tmp = si_halt_rlc(rdev); 536762306a36Sopenharmony_ci 536862306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff); 536962306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff); 537062306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff); 537162306a36Sopenharmony_ci 537262306a36Sopenharmony_ci si_wait_for_rlc_serdes(rdev); 537362306a36Sopenharmony_ci 537462306a36Sopenharmony_ci si_update_rlc(rdev, tmp); 537562306a36Sopenharmony_ci 537662306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, 0x007000ff); 537762306a36Sopenharmony_ci 537862306a36Sopenharmony_ci data |= CGCG_EN | CGLS_EN; 537962306a36Sopenharmony_ci } else { 538062306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, false); 538162306a36Sopenharmony_ci 538262306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 538362306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 538462306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 538562306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 538662306a36Sopenharmony_ci 538762306a36Sopenharmony_ci data &= ~(CGCG_EN | CGLS_EN); 538862306a36Sopenharmony_ci } 538962306a36Sopenharmony_ci 539062306a36Sopenharmony_ci if (orig != data) 539162306a36Sopenharmony_ci WREG32(RLC_CGCG_CGLS_CTRL, data); 539262306a36Sopenharmony_ci} 539362306a36Sopenharmony_ci 539462306a36Sopenharmony_cistatic void si_enable_mgcg(struct radeon_device *rdev, 539562306a36Sopenharmony_ci bool enable) 539662306a36Sopenharmony_ci{ 539762306a36Sopenharmony_ci u32 data, orig, tmp = 0; 539862306a36Sopenharmony_ci 539962306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) { 540062306a36Sopenharmony_ci orig = data = RREG32(CGTS_SM_CTRL_REG); 540162306a36Sopenharmony_ci data = 0x96940200; 540262306a36Sopenharmony_ci if (orig != data) 540362306a36Sopenharmony_ci WREG32(CGTS_SM_CTRL_REG, data); 540462306a36Sopenharmony_ci 540562306a36Sopenharmony_ci if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) { 540662306a36Sopenharmony_ci orig = data = RREG32(CP_MEM_SLP_CNTL); 540762306a36Sopenharmony_ci data |= CP_MEM_LS_EN; 540862306a36Sopenharmony_ci if (orig != data) 540962306a36Sopenharmony_ci WREG32(CP_MEM_SLP_CNTL, data); 541062306a36Sopenharmony_ci } 541162306a36Sopenharmony_ci 541262306a36Sopenharmony_ci orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); 541362306a36Sopenharmony_ci data &= 0xffffffc0; 541462306a36Sopenharmony_ci if (orig != data) 541562306a36Sopenharmony_ci WREG32(RLC_CGTT_MGCG_OVERRIDE, data); 541662306a36Sopenharmony_ci 541762306a36Sopenharmony_ci tmp = si_halt_rlc(rdev); 541862306a36Sopenharmony_ci 541962306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff); 542062306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff); 542162306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff); 542262306a36Sopenharmony_ci 542362306a36Sopenharmony_ci si_update_rlc(rdev, tmp); 542462306a36Sopenharmony_ci } else { 542562306a36Sopenharmony_ci orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); 542662306a36Sopenharmony_ci data |= 0x00000003; 542762306a36Sopenharmony_ci if (orig != data) 542862306a36Sopenharmony_ci WREG32(RLC_CGTT_MGCG_OVERRIDE, data); 542962306a36Sopenharmony_ci 543062306a36Sopenharmony_ci data = RREG32(CP_MEM_SLP_CNTL); 543162306a36Sopenharmony_ci if (data & CP_MEM_LS_EN) { 543262306a36Sopenharmony_ci data &= ~CP_MEM_LS_EN; 543362306a36Sopenharmony_ci WREG32(CP_MEM_SLP_CNTL, data); 543462306a36Sopenharmony_ci } 543562306a36Sopenharmony_ci orig = data = RREG32(CGTS_SM_CTRL_REG); 543662306a36Sopenharmony_ci data |= LS_OVERRIDE | OVERRIDE; 543762306a36Sopenharmony_ci if (orig != data) 543862306a36Sopenharmony_ci WREG32(CGTS_SM_CTRL_REG, data); 543962306a36Sopenharmony_ci 544062306a36Sopenharmony_ci tmp = si_halt_rlc(rdev); 544162306a36Sopenharmony_ci 544262306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff); 544362306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff); 544462306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff); 544562306a36Sopenharmony_ci 544662306a36Sopenharmony_ci si_update_rlc(rdev, tmp); 544762306a36Sopenharmony_ci } 544862306a36Sopenharmony_ci} 544962306a36Sopenharmony_ci 545062306a36Sopenharmony_cistatic void si_enable_uvd_mgcg(struct radeon_device *rdev, 545162306a36Sopenharmony_ci bool enable) 545262306a36Sopenharmony_ci{ 545362306a36Sopenharmony_ci u32 orig, data, tmp; 545462306a36Sopenharmony_ci 545562306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) { 545662306a36Sopenharmony_ci tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL); 545762306a36Sopenharmony_ci tmp |= 0x3fff; 545862306a36Sopenharmony_ci WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp); 545962306a36Sopenharmony_ci 546062306a36Sopenharmony_ci orig = data = RREG32(UVD_CGC_CTRL); 546162306a36Sopenharmony_ci data |= DCM; 546262306a36Sopenharmony_ci if (orig != data) 546362306a36Sopenharmony_ci WREG32(UVD_CGC_CTRL, data); 546462306a36Sopenharmony_ci 546562306a36Sopenharmony_ci WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0); 546662306a36Sopenharmony_ci WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0); 546762306a36Sopenharmony_ci } else { 546862306a36Sopenharmony_ci tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL); 546962306a36Sopenharmony_ci tmp &= ~0x3fff; 547062306a36Sopenharmony_ci WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp); 547162306a36Sopenharmony_ci 547262306a36Sopenharmony_ci orig = data = RREG32(UVD_CGC_CTRL); 547362306a36Sopenharmony_ci data &= ~DCM; 547462306a36Sopenharmony_ci if (orig != data) 547562306a36Sopenharmony_ci WREG32(UVD_CGC_CTRL, data); 547662306a36Sopenharmony_ci 547762306a36Sopenharmony_ci WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff); 547862306a36Sopenharmony_ci WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff); 547962306a36Sopenharmony_ci } 548062306a36Sopenharmony_ci} 548162306a36Sopenharmony_ci 548262306a36Sopenharmony_cistatic const u32 mc_cg_registers[] = 548362306a36Sopenharmony_ci{ 548462306a36Sopenharmony_ci MC_HUB_MISC_HUB_CG, 548562306a36Sopenharmony_ci MC_HUB_MISC_SIP_CG, 548662306a36Sopenharmony_ci MC_HUB_MISC_VM_CG, 548762306a36Sopenharmony_ci MC_XPB_CLK_GAT, 548862306a36Sopenharmony_ci ATC_MISC_CG, 548962306a36Sopenharmony_ci MC_CITF_MISC_WR_CG, 549062306a36Sopenharmony_ci MC_CITF_MISC_RD_CG, 549162306a36Sopenharmony_ci MC_CITF_MISC_VM_CG, 549262306a36Sopenharmony_ci VM_L2_CG, 549362306a36Sopenharmony_ci}; 549462306a36Sopenharmony_ci 549562306a36Sopenharmony_cistatic void si_enable_mc_ls(struct radeon_device *rdev, 549662306a36Sopenharmony_ci bool enable) 549762306a36Sopenharmony_ci{ 549862306a36Sopenharmony_ci int i; 549962306a36Sopenharmony_ci u32 orig, data; 550062306a36Sopenharmony_ci 550162306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) { 550262306a36Sopenharmony_ci orig = data = RREG32(mc_cg_registers[i]); 550362306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS)) 550462306a36Sopenharmony_ci data |= MC_LS_ENABLE; 550562306a36Sopenharmony_ci else 550662306a36Sopenharmony_ci data &= ~MC_LS_ENABLE; 550762306a36Sopenharmony_ci if (data != orig) 550862306a36Sopenharmony_ci WREG32(mc_cg_registers[i], data); 550962306a36Sopenharmony_ci } 551062306a36Sopenharmony_ci} 551162306a36Sopenharmony_ci 551262306a36Sopenharmony_cistatic void si_enable_mc_mgcg(struct radeon_device *rdev, 551362306a36Sopenharmony_ci bool enable) 551462306a36Sopenharmony_ci{ 551562306a36Sopenharmony_ci int i; 551662306a36Sopenharmony_ci u32 orig, data; 551762306a36Sopenharmony_ci 551862306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) { 551962306a36Sopenharmony_ci orig = data = RREG32(mc_cg_registers[i]); 552062306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG)) 552162306a36Sopenharmony_ci data |= MC_CG_ENABLE; 552262306a36Sopenharmony_ci else 552362306a36Sopenharmony_ci data &= ~MC_CG_ENABLE; 552462306a36Sopenharmony_ci if (data != orig) 552562306a36Sopenharmony_ci WREG32(mc_cg_registers[i], data); 552662306a36Sopenharmony_ci } 552762306a36Sopenharmony_ci} 552862306a36Sopenharmony_ci 552962306a36Sopenharmony_cistatic void si_enable_dma_mgcg(struct radeon_device *rdev, 553062306a36Sopenharmony_ci bool enable) 553162306a36Sopenharmony_ci{ 553262306a36Sopenharmony_ci u32 orig, data, offset; 553362306a36Sopenharmony_ci int i; 553462306a36Sopenharmony_ci 553562306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) { 553662306a36Sopenharmony_ci for (i = 0; i < 2; i++) { 553762306a36Sopenharmony_ci if (i == 0) 553862306a36Sopenharmony_ci offset = DMA0_REGISTER_OFFSET; 553962306a36Sopenharmony_ci else 554062306a36Sopenharmony_ci offset = DMA1_REGISTER_OFFSET; 554162306a36Sopenharmony_ci orig = data = RREG32(DMA_POWER_CNTL + offset); 554262306a36Sopenharmony_ci data &= ~MEM_POWER_OVERRIDE; 554362306a36Sopenharmony_ci if (data != orig) 554462306a36Sopenharmony_ci WREG32(DMA_POWER_CNTL + offset, data); 554562306a36Sopenharmony_ci WREG32(DMA_CLK_CTRL + offset, 0x00000100); 554662306a36Sopenharmony_ci } 554762306a36Sopenharmony_ci } else { 554862306a36Sopenharmony_ci for (i = 0; i < 2; i++) { 554962306a36Sopenharmony_ci if (i == 0) 555062306a36Sopenharmony_ci offset = DMA0_REGISTER_OFFSET; 555162306a36Sopenharmony_ci else 555262306a36Sopenharmony_ci offset = DMA1_REGISTER_OFFSET; 555362306a36Sopenharmony_ci orig = data = RREG32(DMA_POWER_CNTL + offset); 555462306a36Sopenharmony_ci data |= MEM_POWER_OVERRIDE; 555562306a36Sopenharmony_ci if (data != orig) 555662306a36Sopenharmony_ci WREG32(DMA_POWER_CNTL + offset, data); 555762306a36Sopenharmony_ci 555862306a36Sopenharmony_ci orig = data = RREG32(DMA_CLK_CTRL + offset); 555962306a36Sopenharmony_ci data = 0xff000000; 556062306a36Sopenharmony_ci if (data != orig) 556162306a36Sopenharmony_ci WREG32(DMA_CLK_CTRL + offset, data); 556262306a36Sopenharmony_ci } 556362306a36Sopenharmony_ci } 556462306a36Sopenharmony_ci} 556562306a36Sopenharmony_ci 556662306a36Sopenharmony_cistatic void si_enable_bif_mgls(struct radeon_device *rdev, 556762306a36Sopenharmony_ci bool enable) 556862306a36Sopenharmony_ci{ 556962306a36Sopenharmony_ci u32 orig, data; 557062306a36Sopenharmony_ci 557162306a36Sopenharmony_ci orig = data = RREG32_PCIE(PCIE_CNTL2); 557262306a36Sopenharmony_ci 557362306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS)) 557462306a36Sopenharmony_ci data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | 557562306a36Sopenharmony_ci REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN; 557662306a36Sopenharmony_ci else 557762306a36Sopenharmony_ci data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN | 557862306a36Sopenharmony_ci REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN); 557962306a36Sopenharmony_ci 558062306a36Sopenharmony_ci if (orig != data) 558162306a36Sopenharmony_ci WREG32_PCIE(PCIE_CNTL2, data); 558262306a36Sopenharmony_ci} 558362306a36Sopenharmony_ci 558462306a36Sopenharmony_cistatic void si_enable_hdp_mgcg(struct radeon_device *rdev, 558562306a36Sopenharmony_ci bool enable) 558662306a36Sopenharmony_ci{ 558762306a36Sopenharmony_ci u32 orig, data; 558862306a36Sopenharmony_ci 558962306a36Sopenharmony_ci orig = data = RREG32(HDP_HOST_PATH_CNTL); 559062306a36Sopenharmony_ci 559162306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG)) 559262306a36Sopenharmony_ci data &= ~CLOCK_GATING_DIS; 559362306a36Sopenharmony_ci else 559462306a36Sopenharmony_ci data |= CLOCK_GATING_DIS; 559562306a36Sopenharmony_ci 559662306a36Sopenharmony_ci if (orig != data) 559762306a36Sopenharmony_ci WREG32(HDP_HOST_PATH_CNTL, data); 559862306a36Sopenharmony_ci} 559962306a36Sopenharmony_ci 560062306a36Sopenharmony_cistatic void si_enable_hdp_ls(struct radeon_device *rdev, 560162306a36Sopenharmony_ci bool enable) 560262306a36Sopenharmony_ci{ 560362306a36Sopenharmony_ci u32 orig, data; 560462306a36Sopenharmony_ci 560562306a36Sopenharmony_ci orig = data = RREG32(HDP_MEM_POWER_LS); 560662306a36Sopenharmony_ci 560762306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS)) 560862306a36Sopenharmony_ci data |= HDP_LS_ENABLE; 560962306a36Sopenharmony_ci else 561062306a36Sopenharmony_ci data &= ~HDP_LS_ENABLE; 561162306a36Sopenharmony_ci 561262306a36Sopenharmony_ci if (orig != data) 561362306a36Sopenharmony_ci WREG32(HDP_MEM_POWER_LS, data); 561462306a36Sopenharmony_ci} 561562306a36Sopenharmony_ci 561662306a36Sopenharmony_cistatic void si_update_cg(struct radeon_device *rdev, 561762306a36Sopenharmony_ci u32 block, bool enable) 561862306a36Sopenharmony_ci{ 561962306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_GFX) { 562062306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, false); 562162306a36Sopenharmony_ci /* order matters! */ 562262306a36Sopenharmony_ci if (enable) { 562362306a36Sopenharmony_ci si_enable_mgcg(rdev, true); 562462306a36Sopenharmony_ci si_enable_cgcg(rdev, true); 562562306a36Sopenharmony_ci } else { 562662306a36Sopenharmony_ci si_enable_cgcg(rdev, false); 562762306a36Sopenharmony_ci si_enable_mgcg(rdev, false); 562862306a36Sopenharmony_ci } 562962306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, true); 563062306a36Sopenharmony_ci } 563162306a36Sopenharmony_ci 563262306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_MC) { 563362306a36Sopenharmony_ci si_enable_mc_mgcg(rdev, enable); 563462306a36Sopenharmony_ci si_enable_mc_ls(rdev, enable); 563562306a36Sopenharmony_ci } 563662306a36Sopenharmony_ci 563762306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_SDMA) { 563862306a36Sopenharmony_ci si_enable_dma_mgcg(rdev, enable); 563962306a36Sopenharmony_ci } 564062306a36Sopenharmony_ci 564162306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_BIF) { 564262306a36Sopenharmony_ci si_enable_bif_mgls(rdev, enable); 564362306a36Sopenharmony_ci } 564462306a36Sopenharmony_ci 564562306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_UVD) { 564662306a36Sopenharmony_ci if (rdev->has_uvd) { 564762306a36Sopenharmony_ci si_enable_uvd_mgcg(rdev, enable); 564862306a36Sopenharmony_ci } 564962306a36Sopenharmony_ci } 565062306a36Sopenharmony_ci 565162306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_HDP) { 565262306a36Sopenharmony_ci si_enable_hdp_mgcg(rdev, enable); 565362306a36Sopenharmony_ci si_enable_hdp_ls(rdev, enable); 565462306a36Sopenharmony_ci } 565562306a36Sopenharmony_ci} 565662306a36Sopenharmony_ci 565762306a36Sopenharmony_cistatic void si_init_cg(struct radeon_device *rdev) 565862306a36Sopenharmony_ci{ 565962306a36Sopenharmony_ci si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | 566062306a36Sopenharmony_ci RADEON_CG_BLOCK_MC | 566162306a36Sopenharmony_ci RADEON_CG_BLOCK_SDMA | 566262306a36Sopenharmony_ci RADEON_CG_BLOCK_BIF | 566362306a36Sopenharmony_ci RADEON_CG_BLOCK_HDP), true); 566462306a36Sopenharmony_ci if (rdev->has_uvd) { 566562306a36Sopenharmony_ci si_update_cg(rdev, RADEON_CG_BLOCK_UVD, true); 566662306a36Sopenharmony_ci si_init_uvd_internal_cg(rdev); 566762306a36Sopenharmony_ci } 566862306a36Sopenharmony_ci} 566962306a36Sopenharmony_ci 567062306a36Sopenharmony_cistatic void si_fini_cg(struct radeon_device *rdev) 567162306a36Sopenharmony_ci{ 567262306a36Sopenharmony_ci if (rdev->has_uvd) { 567362306a36Sopenharmony_ci si_update_cg(rdev, RADEON_CG_BLOCK_UVD, false); 567462306a36Sopenharmony_ci } 567562306a36Sopenharmony_ci si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | 567662306a36Sopenharmony_ci RADEON_CG_BLOCK_MC | 567762306a36Sopenharmony_ci RADEON_CG_BLOCK_SDMA | 567862306a36Sopenharmony_ci RADEON_CG_BLOCK_BIF | 567962306a36Sopenharmony_ci RADEON_CG_BLOCK_HDP), false); 568062306a36Sopenharmony_ci} 568162306a36Sopenharmony_ci 568262306a36Sopenharmony_ciu32 si_get_csb_size(struct radeon_device *rdev) 568362306a36Sopenharmony_ci{ 568462306a36Sopenharmony_ci u32 count = 0; 568562306a36Sopenharmony_ci const struct cs_section_def *sect = NULL; 568662306a36Sopenharmony_ci const struct cs_extent_def *ext = NULL; 568762306a36Sopenharmony_ci 568862306a36Sopenharmony_ci if (rdev->rlc.cs_data == NULL) 568962306a36Sopenharmony_ci return 0; 569062306a36Sopenharmony_ci 569162306a36Sopenharmony_ci /* begin clear state */ 569262306a36Sopenharmony_ci count += 2; 569362306a36Sopenharmony_ci /* context control state */ 569462306a36Sopenharmony_ci count += 3; 569562306a36Sopenharmony_ci 569662306a36Sopenharmony_ci for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { 569762306a36Sopenharmony_ci for (ext = sect->section; ext->extent != NULL; ++ext) { 569862306a36Sopenharmony_ci if (sect->id == SECT_CONTEXT) 569962306a36Sopenharmony_ci count += 2 + ext->reg_count; 570062306a36Sopenharmony_ci else 570162306a36Sopenharmony_ci return 0; 570262306a36Sopenharmony_ci } 570362306a36Sopenharmony_ci } 570462306a36Sopenharmony_ci /* pa_sc_raster_config */ 570562306a36Sopenharmony_ci count += 3; 570662306a36Sopenharmony_ci /* end clear state */ 570762306a36Sopenharmony_ci count += 2; 570862306a36Sopenharmony_ci /* clear state */ 570962306a36Sopenharmony_ci count += 2; 571062306a36Sopenharmony_ci 571162306a36Sopenharmony_ci return count; 571262306a36Sopenharmony_ci} 571362306a36Sopenharmony_ci 571462306a36Sopenharmony_civoid si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) 571562306a36Sopenharmony_ci{ 571662306a36Sopenharmony_ci u32 count = 0, i; 571762306a36Sopenharmony_ci const struct cs_section_def *sect = NULL; 571862306a36Sopenharmony_ci const struct cs_extent_def *ext = NULL; 571962306a36Sopenharmony_ci 572062306a36Sopenharmony_ci if (rdev->rlc.cs_data == NULL) 572162306a36Sopenharmony_ci return; 572262306a36Sopenharmony_ci if (buffer == NULL) 572362306a36Sopenharmony_ci return; 572462306a36Sopenharmony_ci 572562306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 572662306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); 572762306a36Sopenharmony_ci 572862306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); 572962306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x80000000); 573062306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x80000000); 573162306a36Sopenharmony_ci 573262306a36Sopenharmony_ci for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { 573362306a36Sopenharmony_ci for (ext = sect->section; ext->extent != NULL; ++ext) { 573462306a36Sopenharmony_ci if (sect->id == SECT_CONTEXT) { 573562306a36Sopenharmony_ci buffer[count++] = 573662306a36Sopenharmony_ci cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); 573762306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000); 573862306a36Sopenharmony_ci for (i = 0; i < ext->reg_count; i++) 573962306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(ext->extent[i]); 574062306a36Sopenharmony_ci } else { 574162306a36Sopenharmony_ci return; 574262306a36Sopenharmony_ci } 574362306a36Sopenharmony_ci } 574462306a36Sopenharmony_ci } 574562306a36Sopenharmony_ci 574662306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1)); 574762306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); 574862306a36Sopenharmony_ci switch (rdev->family) { 574962306a36Sopenharmony_ci case CHIP_TAHITI: 575062306a36Sopenharmony_ci case CHIP_PITCAIRN: 575162306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x2a00126a); 575262306a36Sopenharmony_ci break; 575362306a36Sopenharmony_ci case CHIP_VERDE: 575462306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x0000124a); 575562306a36Sopenharmony_ci break; 575662306a36Sopenharmony_ci case CHIP_OLAND: 575762306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000082); 575862306a36Sopenharmony_ci break; 575962306a36Sopenharmony_ci case CHIP_HAINAN: 576062306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 576162306a36Sopenharmony_ci break; 576262306a36Sopenharmony_ci default: 576362306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 576462306a36Sopenharmony_ci break; 576562306a36Sopenharmony_ci } 576662306a36Sopenharmony_ci 576762306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 576862306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); 576962306a36Sopenharmony_ci 577062306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); 577162306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0); 577262306a36Sopenharmony_ci} 577362306a36Sopenharmony_ci 577462306a36Sopenharmony_cistatic void si_init_pg(struct radeon_device *rdev) 577562306a36Sopenharmony_ci{ 577662306a36Sopenharmony_ci if (rdev->pg_flags) { 577762306a36Sopenharmony_ci if (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA) { 577862306a36Sopenharmony_ci si_init_dma_pg(rdev); 577962306a36Sopenharmony_ci } 578062306a36Sopenharmony_ci si_init_ao_cu_mask(rdev); 578162306a36Sopenharmony_ci if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) { 578262306a36Sopenharmony_ci si_init_gfx_cgpg(rdev); 578362306a36Sopenharmony_ci } else { 578462306a36Sopenharmony_ci WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); 578562306a36Sopenharmony_ci WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); 578662306a36Sopenharmony_ci } 578762306a36Sopenharmony_ci si_enable_dma_pg(rdev, true); 578862306a36Sopenharmony_ci si_enable_gfx_cgpg(rdev, true); 578962306a36Sopenharmony_ci } else { 579062306a36Sopenharmony_ci WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); 579162306a36Sopenharmony_ci WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); 579262306a36Sopenharmony_ci } 579362306a36Sopenharmony_ci} 579462306a36Sopenharmony_ci 579562306a36Sopenharmony_cistatic void si_fini_pg(struct radeon_device *rdev) 579662306a36Sopenharmony_ci{ 579762306a36Sopenharmony_ci if (rdev->pg_flags) { 579862306a36Sopenharmony_ci si_enable_dma_pg(rdev, false); 579962306a36Sopenharmony_ci si_enable_gfx_cgpg(rdev, false); 580062306a36Sopenharmony_ci } 580162306a36Sopenharmony_ci} 580262306a36Sopenharmony_ci 580362306a36Sopenharmony_ci/* 580462306a36Sopenharmony_ci * RLC 580562306a36Sopenharmony_ci */ 580662306a36Sopenharmony_civoid si_rlc_reset(struct radeon_device *rdev) 580762306a36Sopenharmony_ci{ 580862306a36Sopenharmony_ci u32 tmp = RREG32(GRBM_SOFT_RESET); 580962306a36Sopenharmony_ci 581062306a36Sopenharmony_ci tmp |= SOFT_RESET_RLC; 581162306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 581262306a36Sopenharmony_ci udelay(50); 581362306a36Sopenharmony_ci tmp &= ~SOFT_RESET_RLC; 581462306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 581562306a36Sopenharmony_ci udelay(50); 581662306a36Sopenharmony_ci} 581762306a36Sopenharmony_ci 581862306a36Sopenharmony_cistatic void si_rlc_stop(struct radeon_device *rdev) 581962306a36Sopenharmony_ci{ 582062306a36Sopenharmony_ci WREG32(RLC_CNTL, 0); 582162306a36Sopenharmony_ci 582262306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, false); 582362306a36Sopenharmony_ci 582462306a36Sopenharmony_ci si_wait_for_rlc_serdes(rdev); 582562306a36Sopenharmony_ci} 582662306a36Sopenharmony_ci 582762306a36Sopenharmony_cistatic void si_rlc_start(struct radeon_device *rdev) 582862306a36Sopenharmony_ci{ 582962306a36Sopenharmony_ci WREG32(RLC_CNTL, RLC_ENABLE); 583062306a36Sopenharmony_ci 583162306a36Sopenharmony_ci si_enable_gui_idle_interrupt(rdev, true); 583262306a36Sopenharmony_ci 583362306a36Sopenharmony_ci udelay(50); 583462306a36Sopenharmony_ci} 583562306a36Sopenharmony_ci 583662306a36Sopenharmony_cistatic bool si_lbpw_supported(struct radeon_device *rdev) 583762306a36Sopenharmony_ci{ 583862306a36Sopenharmony_ci u32 tmp; 583962306a36Sopenharmony_ci 584062306a36Sopenharmony_ci /* Enable LBPW only for DDR3 */ 584162306a36Sopenharmony_ci tmp = RREG32(MC_SEQ_MISC0); 584262306a36Sopenharmony_ci if ((tmp & 0xF0000000) == 0xB0000000) 584362306a36Sopenharmony_ci return true; 584462306a36Sopenharmony_ci return false; 584562306a36Sopenharmony_ci} 584662306a36Sopenharmony_ci 584762306a36Sopenharmony_cistatic void si_enable_lbpw(struct radeon_device *rdev, bool enable) 584862306a36Sopenharmony_ci{ 584962306a36Sopenharmony_ci u32 tmp; 585062306a36Sopenharmony_ci 585162306a36Sopenharmony_ci tmp = RREG32(RLC_LB_CNTL); 585262306a36Sopenharmony_ci if (enable) 585362306a36Sopenharmony_ci tmp |= LOAD_BALANCE_ENABLE; 585462306a36Sopenharmony_ci else 585562306a36Sopenharmony_ci tmp &= ~LOAD_BALANCE_ENABLE; 585662306a36Sopenharmony_ci WREG32(RLC_LB_CNTL, tmp); 585762306a36Sopenharmony_ci 585862306a36Sopenharmony_ci if (!enable) { 585962306a36Sopenharmony_ci si_select_se_sh(rdev, 0xffffffff, 0xffffffff); 586062306a36Sopenharmony_ci WREG32(SPI_LB_CU_MASK, 0x00ff); 586162306a36Sopenharmony_ci } 586262306a36Sopenharmony_ci} 586362306a36Sopenharmony_ci 586462306a36Sopenharmony_cistatic int si_rlc_resume(struct radeon_device *rdev) 586562306a36Sopenharmony_ci{ 586662306a36Sopenharmony_ci u32 i; 586762306a36Sopenharmony_ci 586862306a36Sopenharmony_ci if (!rdev->rlc_fw) 586962306a36Sopenharmony_ci return -EINVAL; 587062306a36Sopenharmony_ci 587162306a36Sopenharmony_ci si_rlc_stop(rdev); 587262306a36Sopenharmony_ci 587362306a36Sopenharmony_ci si_rlc_reset(rdev); 587462306a36Sopenharmony_ci 587562306a36Sopenharmony_ci si_init_pg(rdev); 587662306a36Sopenharmony_ci 587762306a36Sopenharmony_ci si_init_cg(rdev); 587862306a36Sopenharmony_ci 587962306a36Sopenharmony_ci WREG32(RLC_RL_BASE, 0); 588062306a36Sopenharmony_ci WREG32(RLC_RL_SIZE, 0); 588162306a36Sopenharmony_ci WREG32(RLC_LB_CNTL, 0); 588262306a36Sopenharmony_ci WREG32(RLC_LB_CNTR_MAX, 0xffffffff); 588362306a36Sopenharmony_ci WREG32(RLC_LB_CNTR_INIT, 0); 588462306a36Sopenharmony_ci WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); 588562306a36Sopenharmony_ci 588662306a36Sopenharmony_ci WREG32(RLC_MC_CNTL, 0); 588762306a36Sopenharmony_ci WREG32(RLC_UCODE_CNTL, 0); 588862306a36Sopenharmony_ci 588962306a36Sopenharmony_ci if (rdev->new_fw) { 589062306a36Sopenharmony_ci const struct rlc_firmware_header_v1_0 *hdr = 589162306a36Sopenharmony_ci (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data; 589262306a36Sopenharmony_ci u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; 589362306a36Sopenharmony_ci const __le32 *fw_data = (const __le32 *) 589462306a36Sopenharmony_ci (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 589562306a36Sopenharmony_ci 589662306a36Sopenharmony_ci radeon_ucode_print_rlc_hdr(&hdr->header); 589762306a36Sopenharmony_ci 589862306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) { 589962306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, i); 590062306a36Sopenharmony_ci WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++)); 590162306a36Sopenharmony_ci } 590262306a36Sopenharmony_ci } else { 590362306a36Sopenharmony_ci const __be32 *fw_data = 590462306a36Sopenharmony_ci (const __be32 *)rdev->rlc_fw->data; 590562306a36Sopenharmony_ci for (i = 0; i < SI_RLC_UCODE_SIZE; i++) { 590662306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, i); 590762306a36Sopenharmony_ci WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); 590862306a36Sopenharmony_ci } 590962306a36Sopenharmony_ci } 591062306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, 0); 591162306a36Sopenharmony_ci 591262306a36Sopenharmony_ci si_enable_lbpw(rdev, si_lbpw_supported(rdev)); 591362306a36Sopenharmony_ci 591462306a36Sopenharmony_ci si_rlc_start(rdev); 591562306a36Sopenharmony_ci 591662306a36Sopenharmony_ci return 0; 591762306a36Sopenharmony_ci} 591862306a36Sopenharmony_ci 591962306a36Sopenharmony_cistatic void si_enable_interrupts(struct radeon_device *rdev) 592062306a36Sopenharmony_ci{ 592162306a36Sopenharmony_ci u32 ih_cntl = RREG32(IH_CNTL); 592262306a36Sopenharmony_ci u32 ih_rb_cntl = RREG32(IH_RB_CNTL); 592362306a36Sopenharmony_ci 592462306a36Sopenharmony_ci ih_cntl |= ENABLE_INTR; 592562306a36Sopenharmony_ci ih_rb_cntl |= IH_RB_ENABLE; 592662306a36Sopenharmony_ci WREG32(IH_CNTL, ih_cntl); 592762306a36Sopenharmony_ci WREG32(IH_RB_CNTL, ih_rb_cntl); 592862306a36Sopenharmony_ci rdev->ih.enabled = true; 592962306a36Sopenharmony_ci} 593062306a36Sopenharmony_ci 593162306a36Sopenharmony_cistatic void si_disable_interrupts(struct radeon_device *rdev) 593262306a36Sopenharmony_ci{ 593362306a36Sopenharmony_ci u32 ih_rb_cntl = RREG32(IH_RB_CNTL); 593462306a36Sopenharmony_ci u32 ih_cntl = RREG32(IH_CNTL); 593562306a36Sopenharmony_ci 593662306a36Sopenharmony_ci ih_rb_cntl &= ~IH_RB_ENABLE; 593762306a36Sopenharmony_ci ih_cntl &= ~ENABLE_INTR; 593862306a36Sopenharmony_ci WREG32(IH_RB_CNTL, ih_rb_cntl); 593962306a36Sopenharmony_ci WREG32(IH_CNTL, ih_cntl); 594062306a36Sopenharmony_ci /* set rptr, wptr to 0 */ 594162306a36Sopenharmony_ci WREG32(IH_RB_RPTR, 0); 594262306a36Sopenharmony_ci WREG32(IH_RB_WPTR, 0); 594362306a36Sopenharmony_ci rdev->ih.enabled = false; 594462306a36Sopenharmony_ci rdev->ih.rptr = 0; 594562306a36Sopenharmony_ci} 594662306a36Sopenharmony_ci 594762306a36Sopenharmony_cistatic void si_disable_interrupt_state(struct radeon_device *rdev) 594862306a36Sopenharmony_ci{ 594962306a36Sopenharmony_ci int i; 595062306a36Sopenharmony_ci u32 tmp; 595162306a36Sopenharmony_ci 595262306a36Sopenharmony_ci tmp = RREG32(CP_INT_CNTL_RING0) & 595362306a36Sopenharmony_ci (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 595462306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING0, tmp); 595562306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING1, 0); 595662306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING2, 0); 595762306a36Sopenharmony_ci tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; 595862306a36Sopenharmony_ci WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp); 595962306a36Sopenharmony_ci tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; 596062306a36Sopenharmony_ci WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp); 596162306a36Sopenharmony_ci WREG32(GRBM_INT_CNTL, 0); 596262306a36Sopenharmony_ci WREG32(SRBM_INT_CNTL, 0); 596362306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) 596462306a36Sopenharmony_ci WREG32(INT_MASK + crtc_offsets[i], 0); 596562306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) 596662306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0); 596762306a36Sopenharmony_ci 596862306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) { 596962306a36Sopenharmony_ci WREG32(DAC_AUTODETECT_INT_CONTROL, 0); 597062306a36Sopenharmony_ci 597162306a36Sopenharmony_ci for (i = 0; i < 6; i++) 597262306a36Sopenharmony_ci WREG32_AND(DC_HPDx_INT_CONTROL(i), 597362306a36Sopenharmony_ci DC_HPDx_INT_POLARITY); 597462306a36Sopenharmony_ci } 597562306a36Sopenharmony_ci} 597662306a36Sopenharmony_ci 597762306a36Sopenharmony_cistatic int si_irq_init(struct radeon_device *rdev) 597862306a36Sopenharmony_ci{ 597962306a36Sopenharmony_ci int ret = 0; 598062306a36Sopenharmony_ci int rb_bufsz; 598162306a36Sopenharmony_ci u32 interrupt_cntl, ih_cntl, ih_rb_cntl; 598262306a36Sopenharmony_ci 598362306a36Sopenharmony_ci /* allocate ring */ 598462306a36Sopenharmony_ci ret = r600_ih_ring_alloc(rdev); 598562306a36Sopenharmony_ci if (ret) 598662306a36Sopenharmony_ci return ret; 598762306a36Sopenharmony_ci 598862306a36Sopenharmony_ci /* disable irqs */ 598962306a36Sopenharmony_ci si_disable_interrupts(rdev); 599062306a36Sopenharmony_ci 599162306a36Sopenharmony_ci /* init rlc */ 599262306a36Sopenharmony_ci ret = si_rlc_resume(rdev); 599362306a36Sopenharmony_ci if (ret) { 599462306a36Sopenharmony_ci r600_ih_ring_fini(rdev); 599562306a36Sopenharmony_ci return ret; 599662306a36Sopenharmony_ci } 599762306a36Sopenharmony_ci 599862306a36Sopenharmony_ci /* setup interrupt control */ 599962306a36Sopenharmony_ci /* set dummy read address to dummy page address */ 600062306a36Sopenharmony_ci WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8); 600162306a36Sopenharmony_ci interrupt_cntl = RREG32(INTERRUPT_CNTL); 600262306a36Sopenharmony_ci /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi 600362306a36Sopenharmony_ci * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN 600462306a36Sopenharmony_ci */ 600562306a36Sopenharmony_ci interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; 600662306a36Sopenharmony_ci /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ 600762306a36Sopenharmony_ci interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; 600862306a36Sopenharmony_ci WREG32(INTERRUPT_CNTL, interrupt_cntl); 600962306a36Sopenharmony_ci 601062306a36Sopenharmony_ci WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); 601162306a36Sopenharmony_ci rb_bufsz = order_base_2(rdev->ih.ring_size / 4); 601262306a36Sopenharmony_ci 601362306a36Sopenharmony_ci ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | 601462306a36Sopenharmony_ci IH_WPTR_OVERFLOW_CLEAR | 601562306a36Sopenharmony_ci (rb_bufsz << 1)); 601662306a36Sopenharmony_ci 601762306a36Sopenharmony_ci if (rdev->wb.enabled) 601862306a36Sopenharmony_ci ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; 601962306a36Sopenharmony_ci 602062306a36Sopenharmony_ci /* set the writeback address whether it's enabled or not */ 602162306a36Sopenharmony_ci WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); 602262306a36Sopenharmony_ci WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); 602362306a36Sopenharmony_ci 602462306a36Sopenharmony_ci WREG32(IH_RB_CNTL, ih_rb_cntl); 602562306a36Sopenharmony_ci 602662306a36Sopenharmony_ci /* set rptr, wptr to 0 */ 602762306a36Sopenharmony_ci WREG32(IH_RB_RPTR, 0); 602862306a36Sopenharmony_ci WREG32(IH_RB_WPTR, 0); 602962306a36Sopenharmony_ci 603062306a36Sopenharmony_ci /* Default settings for IH_CNTL (disabled at first) */ 603162306a36Sopenharmony_ci ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0); 603262306a36Sopenharmony_ci /* RPTR_REARM only works if msi's are enabled */ 603362306a36Sopenharmony_ci if (rdev->msi_enabled) 603462306a36Sopenharmony_ci ih_cntl |= RPTR_REARM; 603562306a36Sopenharmony_ci WREG32(IH_CNTL, ih_cntl); 603662306a36Sopenharmony_ci 603762306a36Sopenharmony_ci /* force the active interrupt state to all disabled */ 603862306a36Sopenharmony_ci si_disable_interrupt_state(rdev); 603962306a36Sopenharmony_ci 604062306a36Sopenharmony_ci pci_set_master(rdev->pdev); 604162306a36Sopenharmony_ci 604262306a36Sopenharmony_ci /* enable irqs */ 604362306a36Sopenharmony_ci si_enable_interrupts(rdev); 604462306a36Sopenharmony_ci 604562306a36Sopenharmony_ci return ret; 604662306a36Sopenharmony_ci} 604762306a36Sopenharmony_ci 604862306a36Sopenharmony_ci/* The order we write back each register here is important */ 604962306a36Sopenharmony_ciint si_irq_set(struct radeon_device *rdev) 605062306a36Sopenharmony_ci{ 605162306a36Sopenharmony_ci int i; 605262306a36Sopenharmony_ci u32 cp_int_cntl; 605362306a36Sopenharmony_ci u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; 605462306a36Sopenharmony_ci u32 grbm_int_cntl = 0; 605562306a36Sopenharmony_ci u32 dma_cntl, dma_cntl1; 605662306a36Sopenharmony_ci u32 thermal_int = 0; 605762306a36Sopenharmony_ci 605862306a36Sopenharmony_ci if (!rdev->irq.installed) { 605962306a36Sopenharmony_ci WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); 606062306a36Sopenharmony_ci return -EINVAL; 606162306a36Sopenharmony_ci } 606262306a36Sopenharmony_ci /* don't enable anything if the ih is disabled */ 606362306a36Sopenharmony_ci if (!rdev->ih.enabled) { 606462306a36Sopenharmony_ci si_disable_interrupts(rdev); 606562306a36Sopenharmony_ci /* force the active interrupt state to all disabled */ 606662306a36Sopenharmony_ci si_disable_interrupt_state(rdev); 606762306a36Sopenharmony_ci return 0; 606862306a36Sopenharmony_ci } 606962306a36Sopenharmony_ci 607062306a36Sopenharmony_ci cp_int_cntl = RREG32(CP_INT_CNTL_RING0) & 607162306a36Sopenharmony_ci (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 607262306a36Sopenharmony_ci 607362306a36Sopenharmony_ci dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; 607462306a36Sopenharmony_ci dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; 607562306a36Sopenharmony_ci 607662306a36Sopenharmony_ci thermal_int = RREG32(CG_THERMAL_INT) & 607762306a36Sopenharmony_ci ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); 607862306a36Sopenharmony_ci 607962306a36Sopenharmony_ci /* enable CP interrupts on all rings */ 608062306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { 608162306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int gfx\n"); 608262306a36Sopenharmony_ci cp_int_cntl |= TIME_STAMP_INT_ENABLE; 608362306a36Sopenharmony_ci } 608462306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) { 608562306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp1\n"); 608662306a36Sopenharmony_ci cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; 608762306a36Sopenharmony_ci } 608862306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) { 608962306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp2\n"); 609062306a36Sopenharmony_ci cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; 609162306a36Sopenharmony_ci } 609262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) { 609362306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int dma\n"); 609462306a36Sopenharmony_ci dma_cntl |= TRAP_ENABLE; 609562306a36Sopenharmony_ci } 609662306a36Sopenharmony_ci 609762306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) { 609862306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int dma1\n"); 609962306a36Sopenharmony_ci dma_cntl1 |= TRAP_ENABLE; 610062306a36Sopenharmony_ci } 610162306a36Sopenharmony_ci 610262306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING0, cp_int_cntl); 610362306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING1, cp_int_cntl1); 610462306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING2, cp_int_cntl2); 610562306a36Sopenharmony_ci 610662306a36Sopenharmony_ci WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl); 610762306a36Sopenharmony_ci WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1); 610862306a36Sopenharmony_ci 610962306a36Sopenharmony_ci WREG32(GRBM_INT_CNTL, grbm_int_cntl); 611062306a36Sopenharmony_ci 611162306a36Sopenharmony_ci if (rdev->irq.dpm_thermal) { 611262306a36Sopenharmony_ci DRM_DEBUG("dpm thermal\n"); 611362306a36Sopenharmony_ci thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; 611462306a36Sopenharmony_ci } 611562306a36Sopenharmony_ci 611662306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 611762306a36Sopenharmony_ci radeon_irq_kms_set_irq_n_enabled( 611862306a36Sopenharmony_ci rdev, INT_MASK + crtc_offsets[i], VBLANK_INT_MASK, 611962306a36Sopenharmony_ci rdev->irq.crtc_vblank_int[i] || 612062306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[i]), "vblank", i); 612162306a36Sopenharmony_ci } 612262306a36Sopenharmony_ci 612362306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) 612462306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK); 612562306a36Sopenharmony_ci 612662306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) { 612762306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 612862306a36Sopenharmony_ci radeon_irq_kms_set_irq_n_enabled( 612962306a36Sopenharmony_ci rdev, DC_HPDx_INT_CONTROL(i), 613062306a36Sopenharmony_ci DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN, 613162306a36Sopenharmony_ci rdev->irq.hpd[i], "HPD", i); 613262306a36Sopenharmony_ci } 613362306a36Sopenharmony_ci } 613462306a36Sopenharmony_ci 613562306a36Sopenharmony_ci WREG32(CG_THERMAL_INT, thermal_int); 613662306a36Sopenharmony_ci 613762306a36Sopenharmony_ci /* posting read */ 613862306a36Sopenharmony_ci RREG32(SRBM_STATUS); 613962306a36Sopenharmony_ci 614062306a36Sopenharmony_ci return 0; 614162306a36Sopenharmony_ci} 614262306a36Sopenharmony_ci 614362306a36Sopenharmony_ci/* The order we write back each register here is important */ 614462306a36Sopenharmony_cistatic inline void si_irq_ack(struct radeon_device *rdev) 614562306a36Sopenharmony_ci{ 614662306a36Sopenharmony_ci int i, j; 614762306a36Sopenharmony_ci u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int; 614862306a36Sopenharmony_ci u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int; 614962306a36Sopenharmony_ci 615062306a36Sopenharmony_ci if (ASIC_IS_NODCE(rdev)) 615162306a36Sopenharmony_ci return; 615262306a36Sopenharmony_ci 615362306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 615462306a36Sopenharmony_ci disp_int[i] = RREG32(si_disp_int_status[i]); 615562306a36Sopenharmony_ci if (i < rdev->num_crtc) 615662306a36Sopenharmony_ci grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]); 615762306a36Sopenharmony_ci } 615862306a36Sopenharmony_ci 615962306a36Sopenharmony_ci /* We write back each interrupt register in pairs of two */ 616062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i += 2) { 616162306a36Sopenharmony_ci for (j = i; j < (i + 2); j++) { 616262306a36Sopenharmony_ci if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED) 616362306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + crtc_offsets[j], 616462306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 616562306a36Sopenharmony_ci } 616662306a36Sopenharmony_ci 616762306a36Sopenharmony_ci for (j = i; j < (i + 2); j++) { 616862306a36Sopenharmony_ci if (disp_int[j] & LB_D1_VBLANK_INTERRUPT) 616962306a36Sopenharmony_ci WREG32(VBLANK_STATUS + crtc_offsets[j], 617062306a36Sopenharmony_ci VBLANK_ACK); 617162306a36Sopenharmony_ci if (disp_int[j] & LB_D1_VLINE_INTERRUPT) 617262306a36Sopenharmony_ci WREG32(VLINE_STATUS + crtc_offsets[j], 617362306a36Sopenharmony_ci VLINE_ACK); 617462306a36Sopenharmony_ci } 617562306a36Sopenharmony_ci } 617662306a36Sopenharmony_ci 617762306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 617862306a36Sopenharmony_ci if (disp_int[i] & DC_HPD1_INTERRUPT) 617962306a36Sopenharmony_ci WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK); 618062306a36Sopenharmony_ci } 618162306a36Sopenharmony_ci 618262306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 618362306a36Sopenharmony_ci if (disp_int[i] & DC_HPD1_RX_INTERRUPT) 618462306a36Sopenharmony_ci WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK); 618562306a36Sopenharmony_ci } 618662306a36Sopenharmony_ci} 618762306a36Sopenharmony_ci 618862306a36Sopenharmony_cistatic void si_irq_disable(struct radeon_device *rdev) 618962306a36Sopenharmony_ci{ 619062306a36Sopenharmony_ci si_disable_interrupts(rdev); 619162306a36Sopenharmony_ci /* Wait and acknowledge irq */ 619262306a36Sopenharmony_ci mdelay(1); 619362306a36Sopenharmony_ci si_irq_ack(rdev); 619462306a36Sopenharmony_ci si_disable_interrupt_state(rdev); 619562306a36Sopenharmony_ci} 619662306a36Sopenharmony_ci 619762306a36Sopenharmony_cistatic void si_irq_suspend(struct radeon_device *rdev) 619862306a36Sopenharmony_ci{ 619962306a36Sopenharmony_ci si_irq_disable(rdev); 620062306a36Sopenharmony_ci si_rlc_stop(rdev); 620162306a36Sopenharmony_ci} 620262306a36Sopenharmony_ci 620362306a36Sopenharmony_cistatic void si_irq_fini(struct radeon_device *rdev) 620462306a36Sopenharmony_ci{ 620562306a36Sopenharmony_ci si_irq_suspend(rdev); 620662306a36Sopenharmony_ci r600_ih_ring_fini(rdev); 620762306a36Sopenharmony_ci} 620862306a36Sopenharmony_ci 620962306a36Sopenharmony_cistatic inline u32 si_get_ih_wptr(struct radeon_device *rdev) 621062306a36Sopenharmony_ci{ 621162306a36Sopenharmony_ci u32 wptr, tmp; 621262306a36Sopenharmony_ci 621362306a36Sopenharmony_ci if (rdev->wb.enabled) 621462306a36Sopenharmony_ci wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); 621562306a36Sopenharmony_ci else 621662306a36Sopenharmony_ci wptr = RREG32(IH_RB_WPTR); 621762306a36Sopenharmony_ci 621862306a36Sopenharmony_ci if (wptr & RB_OVERFLOW) { 621962306a36Sopenharmony_ci wptr &= ~RB_OVERFLOW; 622062306a36Sopenharmony_ci /* When a ring buffer overflow happen start parsing interrupt 622162306a36Sopenharmony_ci * from the last not overwritten vector (wptr + 16). Hopefully 622262306a36Sopenharmony_ci * this should allow us to catchup. 622362306a36Sopenharmony_ci */ 622462306a36Sopenharmony_ci dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 622562306a36Sopenharmony_ci wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); 622662306a36Sopenharmony_ci rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; 622762306a36Sopenharmony_ci tmp = RREG32(IH_RB_CNTL); 622862306a36Sopenharmony_ci tmp |= IH_WPTR_OVERFLOW_CLEAR; 622962306a36Sopenharmony_ci WREG32(IH_RB_CNTL, tmp); 623062306a36Sopenharmony_ci } 623162306a36Sopenharmony_ci return (wptr & rdev->ih.ptr_mask); 623262306a36Sopenharmony_ci} 623362306a36Sopenharmony_ci 623462306a36Sopenharmony_ci/* SI IV Ring 623562306a36Sopenharmony_ci * Each IV ring entry is 128 bits: 623662306a36Sopenharmony_ci * [7:0] - interrupt source id 623762306a36Sopenharmony_ci * [31:8] - reserved 623862306a36Sopenharmony_ci * [59:32] - interrupt source data 623962306a36Sopenharmony_ci * [63:60] - reserved 624062306a36Sopenharmony_ci * [71:64] - RINGID 624162306a36Sopenharmony_ci * [79:72] - VMID 624262306a36Sopenharmony_ci * [127:80] - reserved 624362306a36Sopenharmony_ci */ 624462306a36Sopenharmony_ciint si_irq_process(struct radeon_device *rdev) 624562306a36Sopenharmony_ci{ 624662306a36Sopenharmony_ci u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int; 624762306a36Sopenharmony_ci u32 crtc_idx, hpd_idx; 624862306a36Sopenharmony_ci u32 mask; 624962306a36Sopenharmony_ci u32 wptr; 625062306a36Sopenharmony_ci u32 rptr; 625162306a36Sopenharmony_ci u32 src_id, src_data, ring_id; 625262306a36Sopenharmony_ci u32 ring_index; 625362306a36Sopenharmony_ci bool queue_hotplug = false; 625462306a36Sopenharmony_ci bool queue_dp = false; 625562306a36Sopenharmony_ci bool queue_thermal = false; 625662306a36Sopenharmony_ci u32 status, addr; 625762306a36Sopenharmony_ci const char *event_name; 625862306a36Sopenharmony_ci 625962306a36Sopenharmony_ci if (!rdev->ih.enabled || rdev->shutdown) 626062306a36Sopenharmony_ci return IRQ_NONE; 626162306a36Sopenharmony_ci 626262306a36Sopenharmony_ci wptr = si_get_ih_wptr(rdev); 626362306a36Sopenharmony_ci 626462306a36Sopenharmony_cirestart_ih: 626562306a36Sopenharmony_ci /* is somebody else already processing irqs? */ 626662306a36Sopenharmony_ci if (atomic_xchg(&rdev->ih.lock, 1)) 626762306a36Sopenharmony_ci return IRQ_NONE; 626862306a36Sopenharmony_ci 626962306a36Sopenharmony_ci rptr = rdev->ih.rptr; 627062306a36Sopenharmony_ci DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr); 627162306a36Sopenharmony_ci 627262306a36Sopenharmony_ci /* Order reading of wptr vs. reading of IH ring data */ 627362306a36Sopenharmony_ci rmb(); 627462306a36Sopenharmony_ci 627562306a36Sopenharmony_ci /* display interrupts */ 627662306a36Sopenharmony_ci si_irq_ack(rdev); 627762306a36Sopenharmony_ci 627862306a36Sopenharmony_ci while (rptr != wptr) { 627962306a36Sopenharmony_ci /* wptr/rptr are in bytes! */ 628062306a36Sopenharmony_ci ring_index = rptr / 4; 628162306a36Sopenharmony_ci src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; 628262306a36Sopenharmony_ci src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; 628362306a36Sopenharmony_ci ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff; 628462306a36Sopenharmony_ci 628562306a36Sopenharmony_ci switch (src_id) { 628662306a36Sopenharmony_ci case 1: /* D1 vblank/vline */ 628762306a36Sopenharmony_ci case 2: /* D2 vblank/vline */ 628862306a36Sopenharmony_ci case 3: /* D3 vblank/vline */ 628962306a36Sopenharmony_ci case 4: /* D4 vblank/vline */ 629062306a36Sopenharmony_ci case 5: /* D5 vblank/vline */ 629162306a36Sopenharmony_ci case 6: /* D6 vblank/vline */ 629262306a36Sopenharmony_ci crtc_idx = src_id - 1; 629362306a36Sopenharmony_ci 629462306a36Sopenharmony_ci if (src_data == 0) { /* vblank */ 629562306a36Sopenharmony_ci mask = LB_D1_VBLANK_INTERRUPT; 629662306a36Sopenharmony_ci event_name = "vblank"; 629762306a36Sopenharmony_ci 629862306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[crtc_idx]) { 629962306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, crtc_idx); 630062306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 630162306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 630262306a36Sopenharmony_ci } 630362306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[crtc_idx])) { 630462306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 630562306a36Sopenharmony_ci crtc_idx); 630662306a36Sopenharmony_ci } 630762306a36Sopenharmony_ci 630862306a36Sopenharmony_ci } else if (src_data == 1) { /* vline */ 630962306a36Sopenharmony_ci mask = LB_D1_VLINE_INTERRUPT; 631062306a36Sopenharmony_ci event_name = "vline"; 631162306a36Sopenharmony_ci } else { 631262306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", 631362306a36Sopenharmony_ci src_id, src_data); 631462306a36Sopenharmony_ci break; 631562306a36Sopenharmony_ci } 631662306a36Sopenharmony_ci 631762306a36Sopenharmony_ci if (!(disp_int[crtc_idx] & mask)) { 631862306a36Sopenharmony_ci DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n", 631962306a36Sopenharmony_ci crtc_idx + 1, event_name); 632062306a36Sopenharmony_ci } 632162306a36Sopenharmony_ci 632262306a36Sopenharmony_ci disp_int[crtc_idx] &= ~mask; 632362306a36Sopenharmony_ci DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name); 632462306a36Sopenharmony_ci 632562306a36Sopenharmony_ci break; 632662306a36Sopenharmony_ci case 8: /* D1 page flip */ 632762306a36Sopenharmony_ci case 10: /* D2 page flip */ 632862306a36Sopenharmony_ci case 12: /* D3 page flip */ 632962306a36Sopenharmony_ci case 14: /* D4 page flip */ 633062306a36Sopenharmony_ci case 16: /* D5 page flip */ 633162306a36Sopenharmony_ci case 18: /* D6 page flip */ 633262306a36Sopenharmony_ci DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); 633362306a36Sopenharmony_ci if (radeon_use_pflipirq > 0) 633462306a36Sopenharmony_ci radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); 633562306a36Sopenharmony_ci break; 633662306a36Sopenharmony_ci case 42: /* HPD hotplug */ 633762306a36Sopenharmony_ci if (src_data <= 5) { 633862306a36Sopenharmony_ci hpd_idx = src_data; 633962306a36Sopenharmony_ci mask = DC_HPD1_INTERRUPT; 634062306a36Sopenharmony_ci queue_hotplug = true; 634162306a36Sopenharmony_ci event_name = "HPD"; 634262306a36Sopenharmony_ci 634362306a36Sopenharmony_ci } else if (src_data <= 11) { 634462306a36Sopenharmony_ci hpd_idx = src_data - 6; 634562306a36Sopenharmony_ci mask = DC_HPD1_RX_INTERRUPT; 634662306a36Sopenharmony_ci queue_dp = true; 634762306a36Sopenharmony_ci event_name = "HPD_RX"; 634862306a36Sopenharmony_ci 634962306a36Sopenharmony_ci } else { 635062306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", 635162306a36Sopenharmony_ci src_id, src_data); 635262306a36Sopenharmony_ci break; 635362306a36Sopenharmony_ci } 635462306a36Sopenharmony_ci 635562306a36Sopenharmony_ci if (!(disp_int[hpd_idx] & mask)) 635662306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 635762306a36Sopenharmony_ci 635862306a36Sopenharmony_ci disp_int[hpd_idx] &= ~mask; 635962306a36Sopenharmony_ci DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1); 636062306a36Sopenharmony_ci break; 636162306a36Sopenharmony_ci case 96: 636262306a36Sopenharmony_ci DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR)); 636362306a36Sopenharmony_ci WREG32(SRBM_INT_ACK, 0x1); 636462306a36Sopenharmony_ci break; 636562306a36Sopenharmony_ci case 124: /* UVD */ 636662306a36Sopenharmony_ci DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); 636762306a36Sopenharmony_ci radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); 636862306a36Sopenharmony_ci break; 636962306a36Sopenharmony_ci case 146: 637062306a36Sopenharmony_ci case 147: 637162306a36Sopenharmony_ci addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); 637262306a36Sopenharmony_ci status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); 637362306a36Sopenharmony_ci /* reset addr and status */ 637462306a36Sopenharmony_ci WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); 637562306a36Sopenharmony_ci if (addr == 0x0 && status == 0x0) 637662306a36Sopenharmony_ci break; 637762306a36Sopenharmony_ci dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); 637862306a36Sopenharmony_ci dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", 637962306a36Sopenharmony_ci addr); 638062306a36Sopenharmony_ci dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 638162306a36Sopenharmony_ci status); 638262306a36Sopenharmony_ci si_vm_decode_fault(rdev, status, addr); 638362306a36Sopenharmony_ci break; 638462306a36Sopenharmony_ci case 176: /* RINGID0 CP_INT */ 638562306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 638662306a36Sopenharmony_ci break; 638762306a36Sopenharmony_ci case 177: /* RINGID1 CP_INT */ 638862306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 638962306a36Sopenharmony_ci break; 639062306a36Sopenharmony_ci case 178: /* RINGID2 CP_INT */ 639162306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 639262306a36Sopenharmony_ci break; 639362306a36Sopenharmony_ci case 181: /* CP EOP event */ 639462306a36Sopenharmony_ci DRM_DEBUG("IH: CP EOP\n"); 639562306a36Sopenharmony_ci switch (ring_id) { 639662306a36Sopenharmony_ci case 0: 639762306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 639862306a36Sopenharmony_ci break; 639962306a36Sopenharmony_ci case 1: 640062306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 640162306a36Sopenharmony_ci break; 640262306a36Sopenharmony_ci case 2: 640362306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 640462306a36Sopenharmony_ci break; 640562306a36Sopenharmony_ci } 640662306a36Sopenharmony_ci break; 640762306a36Sopenharmony_ci case 224: /* DMA trap event */ 640862306a36Sopenharmony_ci DRM_DEBUG("IH: DMA trap\n"); 640962306a36Sopenharmony_ci radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); 641062306a36Sopenharmony_ci break; 641162306a36Sopenharmony_ci case 230: /* thermal low to high */ 641262306a36Sopenharmony_ci DRM_DEBUG("IH: thermal low to high\n"); 641362306a36Sopenharmony_ci rdev->pm.dpm.thermal.high_to_low = false; 641462306a36Sopenharmony_ci queue_thermal = true; 641562306a36Sopenharmony_ci break; 641662306a36Sopenharmony_ci case 231: /* thermal high to low */ 641762306a36Sopenharmony_ci DRM_DEBUG("IH: thermal high to low\n"); 641862306a36Sopenharmony_ci rdev->pm.dpm.thermal.high_to_low = true; 641962306a36Sopenharmony_ci queue_thermal = true; 642062306a36Sopenharmony_ci break; 642162306a36Sopenharmony_ci case 233: /* GUI IDLE */ 642262306a36Sopenharmony_ci DRM_DEBUG("IH: GUI idle\n"); 642362306a36Sopenharmony_ci break; 642462306a36Sopenharmony_ci case 244: /* DMA trap event */ 642562306a36Sopenharmony_ci DRM_DEBUG("IH: DMA1 trap\n"); 642662306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 642762306a36Sopenharmony_ci break; 642862306a36Sopenharmony_ci default: 642962306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 643062306a36Sopenharmony_ci break; 643162306a36Sopenharmony_ci } 643262306a36Sopenharmony_ci 643362306a36Sopenharmony_ci /* wptr/rptr are in bytes! */ 643462306a36Sopenharmony_ci rptr += 16; 643562306a36Sopenharmony_ci rptr &= rdev->ih.ptr_mask; 643662306a36Sopenharmony_ci WREG32(IH_RB_RPTR, rptr); 643762306a36Sopenharmony_ci } 643862306a36Sopenharmony_ci if (queue_dp) 643962306a36Sopenharmony_ci schedule_work(&rdev->dp_work); 644062306a36Sopenharmony_ci if (queue_hotplug) 644162306a36Sopenharmony_ci schedule_delayed_work(&rdev->hotplug_work, 0); 644262306a36Sopenharmony_ci if (queue_thermal && rdev->pm.dpm_enabled) 644362306a36Sopenharmony_ci schedule_work(&rdev->pm.dpm.thermal.work); 644462306a36Sopenharmony_ci rdev->ih.rptr = rptr; 644562306a36Sopenharmony_ci atomic_set(&rdev->ih.lock, 0); 644662306a36Sopenharmony_ci 644762306a36Sopenharmony_ci /* make sure wptr hasn't changed while processing */ 644862306a36Sopenharmony_ci wptr = si_get_ih_wptr(rdev); 644962306a36Sopenharmony_ci if (wptr != rptr) 645062306a36Sopenharmony_ci goto restart_ih; 645162306a36Sopenharmony_ci 645262306a36Sopenharmony_ci return IRQ_HANDLED; 645362306a36Sopenharmony_ci} 645462306a36Sopenharmony_ci 645562306a36Sopenharmony_ci/* 645662306a36Sopenharmony_ci * startup/shutdown callbacks 645762306a36Sopenharmony_ci */ 645862306a36Sopenharmony_cistatic void si_uvd_init(struct radeon_device *rdev) 645962306a36Sopenharmony_ci{ 646062306a36Sopenharmony_ci int r; 646162306a36Sopenharmony_ci 646262306a36Sopenharmony_ci if (!rdev->has_uvd) 646362306a36Sopenharmony_ci return; 646462306a36Sopenharmony_ci 646562306a36Sopenharmony_ci r = radeon_uvd_init(rdev); 646662306a36Sopenharmony_ci if (r) { 646762306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD (%d) init.\n", r); 646862306a36Sopenharmony_ci /* 646962306a36Sopenharmony_ci * At this point rdev->uvd.vcpu_bo is NULL which trickles down 647062306a36Sopenharmony_ci * to early fails uvd_v2_2_resume() and thus nothing happens 647162306a36Sopenharmony_ci * there. So it is pointless to try to go through that code 647262306a36Sopenharmony_ci * hence why we disable uvd here. 647362306a36Sopenharmony_ci */ 647462306a36Sopenharmony_ci rdev->has_uvd = false; 647562306a36Sopenharmony_ci return; 647662306a36Sopenharmony_ci } 647762306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; 647862306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); 647962306a36Sopenharmony_ci} 648062306a36Sopenharmony_ci 648162306a36Sopenharmony_cistatic void si_uvd_start(struct radeon_device *rdev) 648262306a36Sopenharmony_ci{ 648362306a36Sopenharmony_ci int r; 648462306a36Sopenharmony_ci 648562306a36Sopenharmony_ci if (!rdev->has_uvd) 648662306a36Sopenharmony_ci return; 648762306a36Sopenharmony_ci 648862306a36Sopenharmony_ci r = uvd_v2_2_resume(rdev); 648962306a36Sopenharmony_ci if (r) { 649062306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD resume (%d).\n", r); 649162306a36Sopenharmony_ci goto error; 649262306a36Sopenharmony_ci } 649362306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); 649462306a36Sopenharmony_ci if (r) { 649562306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); 649662306a36Sopenharmony_ci goto error; 649762306a36Sopenharmony_ci } 649862306a36Sopenharmony_ci return; 649962306a36Sopenharmony_ci 650062306a36Sopenharmony_cierror: 650162306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; 650262306a36Sopenharmony_ci} 650362306a36Sopenharmony_ci 650462306a36Sopenharmony_cistatic void si_uvd_resume(struct radeon_device *rdev) 650562306a36Sopenharmony_ci{ 650662306a36Sopenharmony_ci struct radeon_ring *ring; 650762306a36Sopenharmony_ci int r; 650862306a36Sopenharmony_ci 650962306a36Sopenharmony_ci if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) 651062306a36Sopenharmony_ci return; 651162306a36Sopenharmony_ci 651262306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 651362306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0)); 651462306a36Sopenharmony_ci if (r) { 651562306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 651662306a36Sopenharmony_ci return; 651762306a36Sopenharmony_ci } 651862306a36Sopenharmony_ci r = uvd_v1_0_init(rdev); 651962306a36Sopenharmony_ci if (r) { 652062306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); 652162306a36Sopenharmony_ci return; 652262306a36Sopenharmony_ci } 652362306a36Sopenharmony_ci} 652462306a36Sopenharmony_ci 652562306a36Sopenharmony_cistatic void si_vce_init(struct radeon_device *rdev) 652662306a36Sopenharmony_ci{ 652762306a36Sopenharmony_ci int r; 652862306a36Sopenharmony_ci 652962306a36Sopenharmony_ci if (!rdev->has_vce) 653062306a36Sopenharmony_ci return; 653162306a36Sopenharmony_ci 653262306a36Sopenharmony_ci r = radeon_vce_init(rdev); 653362306a36Sopenharmony_ci if (r) { 653462306a36Sopenharmony_ci dev_err(rdev->dev, "failed VCE (%d) init.\n", r); 653562306a36Sopenharmony_ci /* 653662306a36Sopenharmony_ci * At this point rdev->vce.vcpu_bo is NULL which trickles down 653762306a36Sopenharmony_ci * to early fails si_vce_start() and thus nothing happens 653862306a36Sopenharmony_ci * there. So it is pointless to try to go through that code 653962306a36Sopenharmony_ci * hence why we disable vce here. 654062306a36Sopenharmony_ci */ 654162306a36Sopenharmony_ci rdev->has_vce = false; 654262306a36Sopenharmony_ci return; 654362306a36Sopenharmony_ci } 654462306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL; 654562306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096); 654662306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL; 654762306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096); 654862306a36Sopenharmony_ci} 654962306a36Sopenharmony_ci 655062306a36Sopenharmony_cistatic void si_vce_start(struct radeon_device *rdev) 655162306a36Sopenharmony_ci{ 655262306a36Sopenharmony_ci int r; 655362306a36Sopenharmony_ci 655462306a36Sopenharmony_ci if (!rdev->has_vce) 655562306a36Sopenharmony_ci return; 655662306a36Sopenharmony_ci 655762306a36Sopenharmony_ci r = radeon_vce_resume(rdev); 655862306a36Sopenharmony_ci if (r) { 655962306a36Sopenharmony_ci dev_err(rdev->dev, "failed VCE resume (%d).\n", r); 656062306a36Sopenharmony_ci goto error; 656162306a36Sopenharmony_ci } 656262306a36Sopenharmony_ci r = vce_v1_0_resume(rdev); 656362306a36Sopenharmony_ci if (r) { 656462306a36Sopenharmony_ci dev_err(rdev->dev, "failed VCE resume (%d).\n", r); 656562306a36Sopenharmony_ci goto error; 656662306a36Sopenharmony_ci } 656762306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX); 656862306a36Sopenharmony_ci if (r) { 656962306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r); 657062306a36Sopenharmony_ci goto error; 657162306a36Sopenharmony_ci } 657262306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX); 657362306a36Sopenharmony_ci if (r) { 657462306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r); 657562306a36Sopenharmony_ci goto error; 657662306a36Sopenharmony_ci } 657762306a36Sopenharmony_ci return; 657862306a36Sopenharmony_ci 657962306a36Sopenharmony_cierror: 658062306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; 658162306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; 658262306a36Sopenharmony_ci} 658362306a36Sopenharmony_ci 658462306a36Sopenharmony_cistatic void si_vce_resume(struct radeon_device *rdev) 658562306a36Sopenharmony_ci{ 658662306a36Sopenharmony_ci struct radeon_ring *ring; 658762306a36Sopenharmony_ci int r; 658862306a36Sopenharmony_ci 658962306a36Sopenharmony_ci if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size) 659062306a36Sopenharmony_ci return; 659162306a36Sopenharmony_ci 659262306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; 659362306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); 659462306a36Sopenharmony_ci if (r) { 659562306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); 659662306a36Sopenharmony_ci return; 659762306a36Sopenharmony_ci } 659862306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; 659962306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); 660062306a36Sopenharmony_ci if (r) { 660162306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); 660262306a36Sopenharmony_ci return; 660362306a36Sopenharmony_ci } 660462306a36Sopenharmony_ci r = vce_v1_0_init(rdev); 660562306a36Sopenharmony_ci if (r) { 660662306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE (%d).\n", r); 660762306a36Sopenharmony_ci return; 660862306a36Sopenharmony_ci } 660962306a36Sopenharmony_ci} 661062306a36Sopenharmony_ci 661162306a36Sopenharmony_cistatic int si_startup(struct radeon_device *rdev) 661262306a36Sopenharmony_ci{ 661362306a36Sopenharmony_ci struct radeon_ring *ring; 661462306a36Sopenharmony_ci int r; 661562306a36Sopenharmony_ci 661662306a36Sopenharmony_ci /* enable pcie gen2/3 link */ 661762306a36Sopenharmony_ci si_pcie_gen3_enable(rdev); 661862306a36Sopenharmony_ci /* enable aspm */ 661962306a36Sopenharmony_ci si_program_aspm(rdev); 662062306a36Sopenharmony_ci 662162306a36Sopenharmony_ci /* scratch needs to be initialized before MC */ 662262306a36Sopenharmony_ci r = r600_vram_scratch_init(rdev); 662362306a36Sopenharmony_ci if (r) 662462306a36Sopenharmony_ci return r; 662562306a36Sopenharmony_ci 662662306a36Sopenharmony_ci si_mc_program(rdev); 662762306a36Sopenharmony_ci 662862306a36Sopenharmony_ci if (!rdev->pm.dpm_enabled) { 662962306a36Sopenharmony_ci r = si_mc_load_microcode(rdev); 663062306a36Sopenharmony_ci if (r) { 663162306a36Sopenharmony_ci DRM_ERROR("Failed to load MC firmware!\n"); 663262306a36Sopenharmony_ci return r; 663362306a36Sopenharmony_ci } 663462306a36Sopenharmony_ci } 663562306a36Sopenharmony_ci 663662306a36Sopenharmony_ci r = si_pcie_gart_enable(rdev); 663762306a36Sopenharmony_ci if (r) 663862306a36Sopenharmony_ci return r; 663962306a36Sopenharmony_ci si_gpu_init(rdev); 664062306a36Sopenharmony_ci 664162306a36Sopenharmony_ci /* allocate rlc buffers */ 664262306a36Sopenharmony_ci if (rdev->family == CHIP_VERDE) { 664362306a36Sopenharmony_ci rdev->rlc.reg_list = verde_rlc_save_restore_register_list; 664462306a36Sopenharmony_ci rdev->rlc.reg_list_size = 664562306a36Sopenharmony_ci (u32)ARRAY_SIZE(verde_rlc_save_restore_register_list); 664662306a36Sopenharmony_ci } 664762306a36Sopenharmony_ci rdev->rlc.cs_data = si_cs_data; 664862306a36Sopenharmony_ci r = sumo_rlc_init(rdev); 664962306a36Sopenharmony_ci if (r) { 665062306a36Sopenharmony_ci DRM_ERROR("Failed to init rlc BOs!\n"); 665162306a36Sopenharmony_ci return r; 665262306a36Sopenharmony_ci } 665362306a36Sopenharmony_ci 665462306a36Sopenharmony_ci /* allocate wb buffer */ 665562306a36Sopenharmony_ci r = radeon_wb_init(rdev); 665662306a36Sopenharmony_ci if (r) 665762306a36Sopenharmony_ci return r; 665862306a36Sopenharmony_ci 665962306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 666062306a36Sopenharmony_ci if (r) { 666162306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 666262306a36Sopenharmony_ci return r; 666362306a36Sopenharmony_ci } 666462306a36Sopenharmony_ci 666562306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 666662306a36Sopenharmony_ci if (r) { 666762306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 666862306a36Sopenharmony_ci return r; 666962306a36Sopenharmony_ci } 667062306a36Sopenharmony_ci 667162306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 667262306a36Sopenharmony_ci if (r) { 667362306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 667462306a36Sopenharmony_ci return r; 667562306a36Sopenharmony_ci } 667662306a36Sopenharmony_ci 667762306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); 667862306a36Sopenharmony_ci if (r) { 667962306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 668062306a36Sopenharmony_ci return r; 668162306a36Sopenharmony_ci } 668262306a36Sopenharmony_ci 668362306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 668462306a36Sopenharmony_ci if (r) { 668562306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 668662306a36Sopenharmony_ci return r; 668762306a36Sopenharmony_ci } 668862306a36Sopenharmony_ci 668962306a36Sopenharmony_ci si_uvd_start(rdev); 669062306a36Sopenharmony_ci si_vce_start(rdev); 669162306a36Sopenharmony_ci 669262306a36Sopenharmony_ci /* Enable IRQ */ 669362306a36Sopenharmony_ci if (!rdev->irq.installed) { 669462306a36Sopenharmony_ci r = radeon_irq_kms_init(rdev); 669562306a36Sopenharmony_ci if (r) 669662306a36Sopenharmony_ci return r; 669762306a36Sopenharmony_ci } 669862306a36Sopenharmony_ci 669962306a36Sopenharmony_ci r = si_irq_init(rdev); 670062306a36Sopenharmony_ci if (r) { 670162306a36Sopenharmony_ci DRM_ERROR("radeon: IH init failed (%d).\n", r); 670262306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 670362306a36Sopenharmony_ci return r; 670462306a36Sopenharmony_ci } 670562306a36Sopenharmony_ci si_irq_set(rdev); 670662306a36Sopenharmony_ci 670762306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 670862306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 670962306a36Sopenharmony_ci RADEON_CP_PACKET2); 671062306a36Sopenharmony_ci if (r) 671162306a36Sopenharmony_ci return r; 671262306a36Sopenharmony_ci 671362306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 671462306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, 671562306a36Sopenharmony_ci RADEON_CP_PACKET2); 671662306a36Sopenharmony_ci if (r) 671762306a36Sopenharmony_ci return r; 671862306a36Sopenharmony_ci 671962306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 672062306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, 672162306a36Sopenharmony_ci RADEON_CP_PACKET2); 672262306a36Sopenharmony_ci if (r) 672362306a36Sopenharmony_ci return r; 672462306a36Sopenharmony_ci 672562306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 672662306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, 672762306a36Sopenharmony_ci DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0)); 672862306a36Sopenharmony_ci if (r) 672962306a36Sopenharmony_ci return r; 673062306a36Sopenharmony_ci 673162306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 673262306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, 673362306a36Sopenharmony_ci DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0)); 673462306a36Sopenharmony_ci if (r) 673562306a36Sopenharmony_ci return r; 673662306a36Sopenharmony_ci 673762306a36Sopenharmony_ci r = si_cp_load_microcode(rdev); 673862306a36Sopenharmony_ci if (r) 673962306a36Sopenharmony_ci return r; 674062306a36Sopenharmony_ci r = si_cp_resume(rdev); 674162306a36Sopenharmony_ci if (r) 674262306a36Sopenharmony_ci return r; 674362306a36Sopenharmony_ci 674462306a36Sopenharmony_ci r = cayman_dma_resume(rdev); 674562306a36Sopenharmony_ci if (r) 674662306a36Sopenharmony_ci return r; 674762306a36Sopenharmony_ci 674862306a36Sopenharmony_ci si_uvd_resume(rdev); 674962306a36Sopenharmony_ci si_vce_resume(rdev); 675062306a36Sopenharmony_ci 675162306a36Sopenharmony_ci r = radeon_ib_pool_init(rdev); 675262306a36Sopenharmony_ci if (r) { 675362306a36Sopenharmony_ci dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 675462306a36Sopenharmony_ci return r; 675562306a36Sopenharmony_ci } 675662306a36Sopenharmony_ci 675762306a36Sopenharmony_ci r = radeon_vm_manager_init(rdev); 675862306a36Sopenharmony_ci if (r) { 675962306a36Sopenharmony_ci dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); 676062306a36Sopenharmony_ci return r; 676162306a36Sopenharmony_ci } 676262306a36Sopenharmony_ci 676362306a36Sopenharmony_ci r = radeon_audio_init(rdev); 676462306a36Sopenharmony_ci if (r) 676562306a36Sopenharmony_ci return r; 676662306a36Sopenharmony_ci 676762306a36Sopenharmony_ci return 0; 676862306a36Sopenharmony_ci} 676962306a36Sopenharmony_ci 677062306a36Sopenharmony_ciint si_resume(struct radeon_device *rdev) 677162306a36Sopenharmony_ci{ 677262306a36Sopenharmony_ci int r; 677362306a36Sopenharmony_ci 677462306a36Sopenharmony_ci /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, 677562306a36Sopenharmony_ci * posting will perform necessary task to bring back GPU into good 677662306a36Sopenharmony_ci * shape. 677762306a36Sopenharmony_ci */ 677862306a36Sopenharmony_ci /* post card */ 677962306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 678062306a36Sopenharmony_ci 678162306a36Sopenharmony_ci /* init golden registers */ 678262306a36Sopenharmony_ci si_init_golden_registers(rdev); 678362306a36Sopenharmony_ci 678462306a36Sopenharmony_ci if (rdev->pm.pm_method == PM_METHOD_DPM) 678562306a36Sopenharmony_ci radeon_pm_resume(rdev); 678662306a36Sopenharmony_ci 678762306a36Sopenharmony_ci rdev->accel_working = true; 678862306a36Sopenharmony_ci r = si_startup(rdev); 678962306a36Sopenharmony_ci if (r) { 679062306a36Sopenharmony_ci DRM_ERROR("si startup failed on resume\n"); 679162306a36Sopenharmony_ci rdev->accel_working = false; 679262306a36Sopenharmony_ci return r; 679362306a36Sopenharmony_ci } 679462306a36Sopenharmony_ci 679562306a36Sopenharmony_ci return r; 679662306a36Sopenharmony_ci 679762306a36Sopenharmony_ci} 679862306a36Sopenharmony_ci 679962306a36Sopenharmony_ciint si_suspend(struct radeon_device *rdev) 680062306a36Sopenharmony_ci{ 680162306a36Sopenharmony_ci radeon_pm_suspend(rdev); 680262306a36Sopenharmony_ci radeon_audio_fini(rdev); 680362306a36Sopenharmony_ci radeon_vm_manager_fini(rdev); 680462306a36Sopenharmony_ci si_cp_enable(rdev, false); 680562306a36Sopenharmony_ci cayman_dma_stop(rdev); 680662306a36Sopenharmony_ci if (rdev->has_uvd) { 680762306a36Sopenharmony_ci radeon_uvd_suspend(rdev); 680862306a36Sopenharmony_ci uvd_v1_0_fini(rdev); 680962306a36Sopenharmony_ci } 681062306a36Sopenharmony_ci if (rdev->has_vce) 681162306a36Sopenharmony_ci radeon_vce_suspend(rdev); 681262306a36Sopenharmony_ci si_fini_pg(rdev); 681362306a36Sopenharmony_ci si_fini_cg(rdev); 681462306a36Sopenharmony_ci si_irq_suspend(rdev); 681562306a36Sopenharmony_ci radeon_wb_disable(rdev); 681662306a36Sopenharmony_ci si_pcie_gart_disable(rdev); 681762306a36Sopenharmony_ci return 0; 681862306a36Sopenharmony_ci} 681962306a36Sopenharmony_ci 682062306a36Sopenharmony_ci/* Plan is to move initialization in that function and use 682162306a36Sopenharmony_ci * helper function so that radeon_device_init pretty much 682262306a36Sopenharmony_ci * do nothing more than calling asic specific function. This 682362306a36Sopenharmony_ci * should also allow to remove a bunch of callback function 682462306a36Sopenharmony_ci * like vram_info. 682562306a36Sopenharmony_ci */ 682662306a36Sopenharmony_ciint si_init(struct radeon_device *rdev) 682762306a36Sopenharmony_ci{ 682862306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 682962306a36Sopenharmony_ci int r; 683062306a36Sopenharmony_ci 683162306a36Sopenharmony_ci /* Read BIOS */ 683262306a36Sopenharmony_ci if (!radeon_get_bios(rdev)) { 683362306a36Sopenharmony_ci if (ASIC_IS_AVIVO(rdev)) 683462306a36Sopenharmony_ci return -EINVAL; 683562306a36Sopenharmony_ci } 683662306a36Sopenharmony_ci /* Must be an ATOMBIOS */ 683762306a36Sopenharmony_ci if (!rdev->is_atom_bios) { 683862306a36Sopenharmony_ci dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); 683962306a36Sopenharmony_ci return -EINVAL; 684062306a36Sopenharmony_ci } 684162306a36Sopenharmony_ci r = radeon_atombios_init(rdev); 684262306a36Sopenharmony_ci if (r) 684362306a36Sopenharmony_ci return r; 684462306a36Sopenharmony_ci 684562306a36Sopenharmony_ci /* Post card if necessary */ 684662306a36Sopenharmony_ci if (!radeon_card_posted(rdev)) { 684762306a36Sopenharmony_ci if (!rdev->bios) { 684862306a36Sopenharmony_ci dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 684962306a36Sopenharmony_ci return -EINVAL; 685062306a36Sopenharmony_ci } 685162306a36Sopenharmony_ci DRM_INFO("GPU not posted. posting now...\n"); 685262306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 685362306a36Sopenharmony_ci } 685462306a36Sopenharmony_ci /* init golden registers */ 685562306a36Sopenharmony_ci si_init_golden_registers(rdev); 685662306a36Sopenharmony_ci /* Initialize scratch registers */ 685762306a36Sopenharmony_ci si_scratch_init(rdev); 685862306a36Sopenharmony_ci /* Initialize surface registers */ 685962306a36Sopenharmony_ci radeon_surface_init(rdev); 686062306a36Sopenharmony_ci /* Initialize clocks */ 686162306a36Sopenharmony_ci radeon_get_clock_info(rdev->ddev); 686262306a36Sopenharmony_ci 686362306a36Sopenharmony_ci /* Fence driver */ 686462306a36Sopenharmony_ci radeon_fence_driver_init(rdev); 686562306a36Sopenharmony_ci 686662306a36Sopenharmony_ci /* initialize memory controller */ 686762306a36Sopenharmony_ci r = si_mc_init(rdev); 686862306a36Sopenharmony_ci if (r) 686962306a36Sopenharmony_ci return r; 687062306a36Sopenharmony_ci /* Memory manager */ 687162306a36Sopenharmony_ci r = radeon_bo_init(rdev); 687262306a36Sopenharmony_ci if (r) 687362306a36Sopenharmony_ci return r; 687462306a36Sopenharmony_ci 687562306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || 687662306a36Sopenharmony_ci !rdev->rlc_fw || !rdev->mc_fw) { 687762306a36Sopenharmony_ci r = si_init_microcode(rdev); 687862306a36Sopenharmony_ci if (r) { 687962306a36Sopenharmony_ci DRM_ERROR("Failed to load firmware!\n"); 688062306a36Sopenharmony_ci return r; 688162306a36Sopenharmony_ci } 688262306a36Sopenharmony_ci } 688362306a36Sopenharmony_ci 688462306a36Sopenharmony_ci /* Initialize power management */ 688562306a36Sopenharmony_ci radeon_pm_init(rdev); 688662306a36Sopenharmony_ci 688762306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 688862306a36Sopenharmony_ci ring->ring_obj = NULL; 688962306a36Sopenharmony_ci r600_ring_init(rdev, ring, 1024 * 1024); 689062306a36Sopenharmony_ci 689162306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 689262306a36Sopenharmony_ci ring->ring_obj = NULL; 689362306a36Sopenharmony_ci r600_ring_init(rdev, ring, 1024 * 1024); 689462306a36Sopenharmony_ci 689562306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 689662306a36Sopenharmony_ci ring->ring_obj = NULL; 689762306a36Sopenharmony_ci r600_ring_init(rdev, ring, 1024 * 1024); 689862306a36Sopenharmony_ci 689962306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 690062306a36Sopenharmony_ci ring->ring_obj = NULL; 690162306a36Sopenharmony_ci r600_ring_init(rdev, ring, 64 * 1024); 690262306a36Sopenharmony_ci 690362306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 690462306a36Sopenharmony_ci ring->ring_obj = NULL; 690562306a36Sopenharmony_ci r600_ring_init(rdev, ring, 64 * 1024); 690662306a36Sopenharmony_ci 690762306a36Sopenharmony_ci si_uvd_init(rdev); 690862306a36Sopenharmony_ci si_vce_init(rdev); 690962306a36Sopenharmony_ci 691062306a36Sopenharmony_ci rdev->ih.ring_obj = NULL; 691162306a36Sopenharmony_ci r600_ih_ring_init(rdev, 64 * 1024); 691262306a36Sopenharmony_ci 691362306a36Sopenharmony_ci r = r600_pcie_gart_init(rdev); 691462306a36Sopenharmony_ci if (r) 691562306a36Sopenharmony_ci return r; 691662306a36Sopenharmony_ci 691762306a36Sopenharmony_ci rdev->accel_working = true; 691862306a36Sopenharmony_ci r = si_startup(rdev); 691962306a36Sopenharmony_ci if (r) { 692062306a36Sopenharmony_ci dev_err(rdev->dev, "disabling GPU acceleration\n"); 692162306a36Sopenharmony_ci si_cp_fini(rdev); 692262306a36Sopenharmony_ci cayman_dma_fini(rdev); 692362306a36Sopenharmony_ci si_irq_fini(rdev); 692462306a36Sopenharmony_ci sumo_rlc_fini(rdev); 692562306a36Sopenharmony_ci radeon_wb_fini(rdev); 692662306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 692762306a36Sopenharmony_ci radeon_vm_manager_fini(rdev); 692862306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 692962306a36Sopenharmony_ci si_pcie_gart_fini(rdev); 693062306a36Sopenharmony_ci rdev->accel_working = false; 693162306a36Sopenharmony_ci } 693262306a36Sopenharmony_ci 693362306a36Sopenharmony_ci /* Don't start up if the MC ucode is missing. 693462306a36Sopenharmony_ci * The default clocks and voltages before the MC ucode 693562306a36Sopenharmony_ci * is loaded are not suffient for advanced operations. 693662306a36Sopenharmony_ci */ 693762306a36Sopenharmony_ci if (!rdev->mc_fw) { 693862306a36Sopenharmony_ci DRM_ERROR("radeon: MC ucode required for NI+.\n"); 693962306a36Sopenharmony_ci return -EINVAL; 694062306a36Sopenharmony_ci } 694162306a36Sopenharmony_ci 694262306a36Sopenharmony_ci return 0; 694362306a36Sopenharmony_ci} 694462306a36Sopenharmony_ci 694562306a36Sopenharmony_civoid si_fini(struct radeon_device *rdev) 694662306a36Sopenharmony_ci{ 694762306a36Sopenharmony_ci radeon_pm_fini(rdev); 694862306a36Sopenharmony_ci si_cp_fini(rdev); 694962306a36Sopenharmony_ci cayman_dma_fini(rdev); 695062306a36Sopenharmony_ci si_fini_pg(rdev); 695162306a36Sopenharmony_ci si_fini_cg(rdev); 695262306a36Sopenharmony_ci si_irq_fini(rdev); 695362306a36Sopenharmony_ci sumo_rlc_fini(rdev); 695462306a36Sopenharmony_ci radeon_wb_fini(rdev); 695562306a36Sopenharmony_ci radeon_vm_manager_fini(rdev); 695662306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 695762306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 695862306a36Sopenharmony_ci if (rdev->has_uvd) { 695962306a36Sopenharmony_ci uvd_v1_0_fini(rdev); 696062306a36Sopenharmony_ci radeon_uvd_fini(rdev); 696162306a36Sopenharmony_ci } 696262306a36Sopenharmony_ci if (rdev->has_vce) 696362306a36Sopenharmony_ci radeon_vce_fini(rdev); 696462306a36Sopenharmony_ci si_pcie_gart_fini(rdev); 696562306a36Sopenharmony_ci r600_vram_scratch_fini(rdev); 696662306a36Sopenharmony_ci radeon_gem_fini(rdev); 696762306a36Sopenharmony_ci radeon_fence_driver_fini(rdev); 696862306a36Sopenharmony_ci radeon_bo_fini(rdev); 696962306a36Sopenharmony_ci radeon_atombios_fini(rdev); 697062306a36Sopenharmony_ci kfree(rdev->bios); 697162306a36Sopenharmony_ci rdev->bios = NULL; 697262306a36Sopenharmony_ci} 697362306a36Sopenharmony_ci 697462306a36Sopenharmony_ci/** 697562306a36Sopenharmony_ci * si_get_gpu_clock_counter - return GPU clock counter snapshot 697662306a36Sopenharmony_ci * 697762306a36Sopenharmony_ci * @rdev: radeon_device pointer 697862306a36Sopenharmony_ci * 697962306a36Sopenharmony_ci * Fetches a GPU clock counter snapshot (SI). 698062306a36Sopenharmony_ci * Returns the 64 bit clock counter snapshot. 698162306a36Sopenharmony_ci */ 698262306a36Sopenharmony_ciuint64_t si_get_gpu_clock_counter(struct radeon_device *rdev) 698362306a36Sopenharmony_ci{ 698462306a36Sopenharmony_ci uint64_t clock; 698562306a36Sopenharmony_ci 698662306a36Sopenharmony_ci mutex_lock(&rdev->gpu_clock_mutex); 698762306a36Sopenharmony_ci WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); 698862306a36Sopenharmony_ci clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | 698962306a36Sopenharmony_ci ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); 699062306a36Sopenharmony_ci mutex_unlock(&rdev->gpu_clock_mutex); 699162306a36Sopenharmony_ci return clock; 699262306a36Sopenharmony_ci} 699362306a36Sopenharmony_ci 699462306a36Sopenharmony_ciint si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) 699562306a36Sopenharmony_ci{ 699662306a36Sopenharmony_ci unsigned fb_div = 0, vclk_div = 0, dclk_div = 0; 699762306a36Sopenharmony_ci int r; 699862306a36Sopenharmony_ci 699962306a36Sopenharmony_ci /* bypass vclk and dclk with bclk */ 700062306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_2, 700162306a36Sopenharmony_ci VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), 700262306a36Sopenharmony_ci ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); 700362306a36Sopenharmony_ci 700462306a36Sopenharmony_ci /* put PLL in bypass mode */ 700562306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); 700662306a36Sopenharmony_ci 700762306a36Sopenharmony_ci if (!vclk || !dclk) { 700862306a36Sopenharmony_ci /* keep the Bypass mode */ 700962306a36Sopenharmony_ci return 0; 701062306a36Sopenharmony_ci } 701162306a36Sopenharmony_ci 701262306a36Sopenharmony_ci r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000, 701362306a36Sopenharmony_ci 16384, 0x03FFFFFF, 0, 128, 5, 701462306a36Sopenharmony_ci &fb_div, &vclk_div, &dclk_div); 701562306a36Sopenharmony_ci if (r) 701662306a36Sopenharmony_ci return r; 701762306a36Sopenharmony_ci 701862306a36Sopenharmony_ci /* set RESET_ANTI_MUX to 0 */ 701962306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK); 702062306a36Sopenharmony_ci 702162306a36Sopenharmony_ci /* set VCO_MODE to 1 */ 702262306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK); 702362306a36Sopenharmony_ci 702462306a36Sopenharmony_ci /* disable sleep mode */ 702562306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK); 702662306a36Sopenharmony_ci 702762306a36Sopenharmony_ci /* deassert UPLL_RESET */ 702862306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK); 702962306a36Sopenharmony_ci 703062306a36Sopenharmony_ci mdelay(1); 703162306a36Sopenharmony_ci 703262306a36Sopenharmony_ci r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL); 703362306a36Sopenharmony_ci if (r) 703462306a36Sopenharmony_ci return r; 703562306a36Sopenharmony_ci 703662306a36Sopenharmony_ci /* assert UPLL_RESET again */ 703762306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK); 703862306a36Sopenharmony_ci 703962306a36Sopenharmony_ci /* disable spread spectrum. */ 704062306a36Sopenharmony_ci WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK); 704162306a36Sopenharmony_ci 704262306a36Sopenharmony_ci /* set feedback divider */ 704362306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK); 704462306a36Sopenharmony_ci 704562306a36Sopenharmony_ci /* set ref divider to 0 */ 704662306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK); 704762306a36Sopenharmony_ci 704862306a36Sopenharmony_ci if (fb_div < 307200) 704962306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9); 705062306a36Sopenharmony_ci else 705162306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9); 705262306a36Sopenharmony_ci 705362306a36Sopenharmony_ci /* set PDIV_A and PDIV_B */ 705462306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_2, 705562306a36Sopenharmony_ci UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div), 705662306a36Sopenharmony_ci ~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK)); 705762306a36Sopenharmony_ci 705862306a36Sopenharmony_ci /* give the PLL some time to settle */ 705962306a36Sopenharmony_ci mdelay(15); 706062306a36Sopenharmony_ci 706162306a36Sopenharmony_ci /* deassert PLL_RESET */ 706262306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK); 706362306a36Sopenharmony_ci 706462306a36Sopenharmony_ci mdelay(15); 706562306a36Sopenharmony_ci 706662306a36Sopenharmony_ci /* switch from bypass mode to normal mode */ 706762306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK); 706862306a36Sopenharmony_ci 706962306a36Sopenharmony_ci r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL); 707062306a36Sopenharmony_ci if (r) 707162306a36Sopenharmony_ci return r; 707262306a36Sopenharmony_ci 707362306a36Sopenharmony_ci /* switch VCLK and DCLK selection */ 707462306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_2, 707562306a36Sopenharmony_ci VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2), 707662306a36Sopenharmony_ci ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); 707762306a36Sopenharmony_ci 707862306a36Sopenharmony_ci mdelay(100); 707962306a36Sopenharmony_ci 708062306a36Sopenharmony_ci return 0; 708162306a36Sopenharmony_ci} 708262306a36Sopenharmony_ci 708362306a36Sopenharmony_cistatic void si_pcie_gen3_enable(struct radeon_device *rdev) 708462306a36Sopenharmony_ci{ 708562306a36Sopenharmony_ci struct pci_dev *root = rdev->pdev->bus->self; 708662306a36Sopenharmony_ci enum pci_bus_speed speed_cap; 708762306a36Sopenharmony_ci u32 speed_cntl, current_data_rate; 708862306a36Sopenharmony_ci int i; 708962306a36Sopenharmony_ci u16 tmp16; 709062306a36Sopenharmony_ci 709162306a36Sopenharmony_ci if (pci_is_root_bus(rdev->pdev->bus)) 709262306a36Sopenharmony_ci return; 709362306a36Sopenharmony_ci 709462306a36Sopenharmony_ci if (radeon_pcie_gen2 == 0) 709562306a36Sopenharmony_ci return; 709662306a36Sopenharmony_ci 709762306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 709862306a36Sopenharmony_ci return; 709962306a36Sopenharmony_ci 710062306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_PCIE)) 710162306a36Sopenharmony_ci return; 710262306a36Sopenharmony_ci 710362306a36Sopenharmony_ci speed_cap = pcie_get_speed_cap(root); 710462306a36Sopenharmony_ci if (speed_cap == PCI_SPEED_UNKNOWN) 710562306a36Sopenharmony_ci return; 710662306a36Sopenharmony_ci 710762306a36Sopenharmony_ci if ((speed_cap != PCIE_SPEED_8_0GT) && 710862306a36Sopenharmony_ci (speed_cap != PCIE_SPEED_5_0GT)) 710962306a36Sopenharmony_ci return; 711062306a36Sopenharmony_ci 711162306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 711262306a36Sopenharmony_ci current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> 711362306a36Sopenharmony_ci LC_CURRENT_DATA_RATE_SHIFT; 711462306a36Sopenharmony_ci if (speed_cap == PCIE_SPEED_8_0GT) { 711562306a36Sopenharmony_ci if (current_data_rate == 2) { 711662306a36Sopenharmony_ci DRM_INFO("PCIE gen 3 link speeds already enabled\n"); 711762306a36Sopenharmony_ci return; 711862306a36Sopenharmony_ci } 711962306a36Sopenharmony_ci DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n"); 712062306a36Sopenharmony_ci } else if (speed_cap == PCIE_SPEED_5_0GT) { 712162306a36Sopenharmony_ci if (current_data_rate == 1) { 712262306a36Sopenharmony_ci DRM_INFO("PCIE gen 2 link speeds already enabled\n"); 712362306a36Sopenharmony_ci return; 712462306a36Sopenharmony_ci } 712562306a36Sopenharmony_ci DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); 712662306a36Sopenharmony_ci } 712762306a36Sopenharmony_ci 712862306a36Sopenharmony_ci if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev)) 712962306a36Sopenharmony_ci return; 713062306a36Sopenharmony_ci 713162306a36Sopenharmony_ci if (speed_cap == PCIE_SPEED_8_0GT) { 713262306a36Sopenharmony_ci /* re-try equalization if gen3 is not already enabled */ 713362306a36Sopenharmony_ci if (current_data_rate != 2) { 713462306a36Sopenharmony_ci u16 bridge_cfg, gpu_cfg; 713562306a36Sopenharmony_ci u16 bridge_cfg2, gpu_cfg2; 713662306a36Sopenharmony_ci u32 max_lw, current_lw, tmp; 713762306a36Sopenharmony_ci 713862306a36Sopenharmony_ci pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); 713962306a36Sopenharmony_ci pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); 714062306a36Sopenharmony_ci 714162306a36Sopenharmony_ci tmp = RREG32_PCIE(PCIE_LC_STATUS1); 714262306a36Sopenharmony_ci max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; 714362306a36Sopenharmony_ci current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT; 714462306a36Sopenharmony_ci 714562306a36Sopenharmony_ci if (current_lw < max_lw) { 714662306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 714762306a36Sopenharmony_ci if (tmp & LC_RENEGOTIATION_SUPPORT) { 714862306a36Sopenharmony_ci tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS); 714962306a36Sopenharmony_ci tmp |= (max_lw << LC_LINK_WIDTH_SHIFT); 715062306a36Sopenharmony_ci tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW; 715162306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp); 715262306a36Sopenharmony_ci } 715362306a36Sopenharmony_ci } 715462306a36Sopenharmony_ci 715562306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 715662306a36Sopenharmony_ci /* check status */ 715762306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 715862306a36Sopenharmony_ci PCI_EXP_DEVSTA, 715962306a36Sopenharmony_ci &tmp16); 716062306a36Sopenharmony_ci if (tmp16 & PCI_EXP_DEVSTA_TRPND) 716162306a36Sopenharmony_ci break; 716262306a36Sopenharmony_ci 716362306a36Sopenharmony_ci pcie_capability_read_word(root, PCI_EXP_LNKCTL, 716462306a36Sopenharmony_ci &bridge_cfg); 716562306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 716662306a36Sopenharmony_ci PCI_EXP_LNKCTL, 716762306a36Sopenharmony_ci &gpu_cfg); 716862306a36Sopenharmony_ci 716962306a36Sopenharmony_ci pcie_capability_read_word(root, PCI_EXP_LNKCTL2, 717062306a36Sopenharmony_ci &bridge_cfg2); 717162306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 717262306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 717362306a36Sopenharmony_ci &gpu_cfg2); 717462306a36Sopenharmony_ci 717562306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 717662306a36Sopenharmony_ci tmp |= LC_SET_QUIESCE; 717762306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 717862306a36Sopenharmony_ci 717962306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 718062306a36Sopenharmony_ci tmp |= LC_REDO_EQ; 718162306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 718262306a36Sopenharmony_ci 718362306a36Sopenharmony_ci msleep(100); 718462306a36Sopenharmony_ci 718562306a36Sopenharmony_ci /* linkctl */ 718662306a36Sopenharmony_ci pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, 718762306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD, 718862306a36Sopenharmony_ci bridge_cfg & 718962306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD); 719062306a36Sopenharmony_ci pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, 719162306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD, 719262306a36Sopenharmony_ci gpu_cfg & 719362306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD); 719462306a36Sopenharmony_ci 719562306a36Sopenharmony_ci /* linkctl2 */ 719662306a36Sopenharmony_ci pcie_capability_read_word(root, PCI_EXP_LNKCTL2, 719762306a36Sopenharmony_ci &tmp16); 719862306a36Sopenharmony_ci tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | 719962306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN); 720062306a36Sopenharmony_ci tmp16 |= (bridge_cfg2 & 720162306a36Sopenharmony_ci (PCI_EXP_LNKCTL2_ENTER_COMP | 720262306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN)); 720362306a36Sopenharmony_ci pcie_capability_write_word(root, 720462306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 720562306a36Sopenharmony_ci tmp16); 720662306a36Sopenharmony_ci 720762306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 720862306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 720962306a36Sopenharmony_ci &tmp16); 721062306a36Sopenharmony_ci tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | 721162306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN); 721262306a36Sopenharmony_ci tmp16 |= (gpu_cfg2 & 721362306a36Sopenharmony_ci (PCI_EXP_LNKCTL2_ENTER_COMP | 721462306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN)); 721562306a36Sopenharmony_ci pcie_capability_write_word(rdev->pdev, 721662306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 721762306a36Sopenharmony_ci tmp16); 721862306a36Sopenharmony_ci 721962306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 722062306a36Sopenharmony_ci tmp &= ~LC_SET_QUIESCE; 722162306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 722262306a36Sopenharmony_ci } 722362306a36Sopenharmony_ci } 722462306a36Sopenharmony_ci } 722562306a36Sopenharmony_ci 722662306a36Sopenharmony_ci /* set the link speed */ 722762306a36Sopenharmony_ci speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE; 722862306a36Sopenharmony_ci speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; 722962306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 723062306a36Sopenharmony_ci 723162306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16); 723262306a36Sopenharmony_ci tmp16 &= ~PCI_EXP_LNKCTL2_TLS; 723362306a36Sopenharmony_ci if (speed_cap == PCIE_SPEED_8_0GT) 723462306a36Sopenharmony_ci tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ 723562306a36Sopenharmony_ci else if (speed_cap == PCIE_SPEED_5_0GT) 723662306a36Sopenharmony_ci tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ 723762306a36Sopenharmony_ci else 723862306a36Sopenharmony_ci tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ 723962306a36Sopenharmony_ci pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16); 724062306a36Sopenharmony_ci 724162306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 724262306a36Sopenharmony_ci speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; 724362306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 724462306a36Sopenharmony_ci 724562306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 724662306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 724762306a36Sopenharmony_ci if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0) 724862306a36Sopenharmony_ci break; 724962306a36Sopenharmony_ci udelay(1); 725062306a36Sopenharmony_ci } 725162306a36Sopenharmony_ci} 725262306a36Sopenharmony_ci 725362306a36Sopenharmony_cistatic void si_program_aspm(struct radeon_device *rdev) 725462306a36Sopenharmony_ci{ 725562306a36Sopenharmony_ci u32 data, orig; 725662306a36Sopenharmony_ci bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false; 725762306a36Sopenharmony_ci bool disable_clkreq = false; 725862306a36Sopenharmony_ci 725962306a36Sopenharmony_ci if (radeon_aspm == 0) 726062306a36Sopenharmony_ci return; 726162306a36Sopenharmony_ci 726262306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_PCIE)) 726362306a36Sopenharmony_ci return; 726462306a36Sopenharmony_ci 726562306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL); 726662306a36Sopenharmony_ci data &= ~LC_XMIT_N_FTS_MASK; 726762306a36Sopenharmony_ci data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN; 726862306a36Sopenharmony_ci if (orig != data) 726962306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data); 727062306a36Sopenharmony_ci 727162306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3); 727262306a36Sopenharmony_ci data |= LC_GO_TO_RECOVERY; 727362306a36Sopenharmony_ci if (orig != data) 727462306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL3, data); 727562306a36Sopenharmony_ci 727662306a36Sopenharmony_ci orig = data = RREG32_PCIE(PCIE_P_CNTL); 727762306a36Sopenharmony_ci data |= P_IGNORE_EDB_ERR; 727862306a36Sopenharmony_ci if (orig != data) 727962306a36Sopenharmony_ci WREG32_PCIE(PCIE_P_CNTL, data); 728062306a36Sopenharmony_ci 728162306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL); 728262306a36Sopenharmony_ci data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK); 728362306a36Sopenharmony_ci data |= LC_PMI_TO_L1_DIS; 728462306a36Sopenharmony_ci if (!disable_l0s) 728562306a36Sopenharmony_ci data |= LC_L0S_INACTIVITY(7); 728662306a36Sopenharmony_ci 728762306a36Sopenharmony_ci if (!disable_l1) { 728862306a36Sopenharmony_ci data |= LC_L1_INACTIVITY(7); 728962306a36Sopenharmony_ci data &= ~LC_PMI_TO_L1_DIS; 729062306a36Sopenharmony_ci if (orig != data) 729162306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 729262306a36Sopenharmony_ci 729362306a36Sopenharmony_ci if (!disable_plloff_in_l1) { 729462306a36Sopenharmony_ci bool clk_req_support; 729562306a36Sopenharmony_ci 729662306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0); 729762306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 729862306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 729962306a36Sopenharmony_ci if (orig != data) 730062306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data); 730162306a36Sopenharmony_ci 730262306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1); 730362306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 730462306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 730562306a36Sopenharmony_ci if (orig != data) 730662306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data); 730762306a36Sopenharmony_ci 730862306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0); 730962306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 731062306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 731162306a36Sopenharmony_ci if (orig != data) 731262306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data); 731362306a36Sopenharmony_ci 731462306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1); 731562306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 731662306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 731762306a36Sopenharmony_ci if (orig != data) 731862306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data); 731962306a36Sopenharmony_ci 732062306a36Sopenharmony_ci if ((rdev->family != CHIP_OLAND) && (rdev->family != CHIP_HAINAN)) { 732162306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0); 732262306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_0_MASK; 732362306a36Sopenharmony_ci if (orig != data) 732462306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data); 732562306a36Sopenharmony_ci 732662306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1); 732762306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_1_MASK; 732862306a36Sopenharmony_ci if (orig != data) 732962306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data); 733062306a36Sopenharmony_ci 733162306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2); 733262306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_2_MASK; 733362306a36Sopenharmony_ci if (orig != data) 733462306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2, data); 733562306a36Sopenharmony_ci 733662306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3); 733762306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_3_MASK; 733862306a36Sopenharmony_ci if (orig != data) 733962306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3, data); 734062306a36Sopenharmony_ci 734162306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0); 734262306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_0_MASK; 734362306a36Sopenharmony_ci if (orig != data) 734462306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data); 734562306a36Sopenharmony_ci 734662306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1); 734762306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_1_MASK; 734862306a36Sopenharmony_ci if (orig != data) 734962306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data); 735062306a36Sopenharmony_ci 735162306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2); 735262306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_2_MASK; 735362306a36Sopenharmony_ci if (orig != data) 735462306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2, data); 735562306a36Sopenharmony_ci 735662306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3); 735762306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_3_MASK; 735862306a36Sopenharmony_ci if (orig != data) 735962306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3, data); 736062306a36Sopenharmony_ci } 736162306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 736262306a36Sopenharmony_ci data &= ~LC_DYN_LANES_PWR_STATE_MASK; 736362306a36Sopenharmony_ci data |= LC_DYN_LANES_PWR_STATE(3); 736462306a36Sopenharmony_ci if (orig != data) 736562306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); 736662306a36Sopenharmony_ci 736762306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY0(PB0_PIF_CNTL); 736862306a36Sopenharmony_ci data &= ~LS2_EXIT_TIME_MASK; 736962306a36Sopenharmony_ci if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN)) 737062306a36Sopenharmony_ci data |= LS2_EXIT_TIME(5); 737162306a36Sopenharmony_ci if (orig != data) 737262306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_CNTL, data); 737362306a36Sopenharmony_ci 737462306a36Sopenharmony_ci orig = data = RREG32_PIF_PHY1(PB1_PIF_CNTL); 737562306a36Sopenharmony_ci data &= ~LS2_EXIT_TIME_MASK; 737662306a36Sopenharmony_ci if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN)) 737762306a36Sopenharmony_ci data |= LS2_EXIT_TIME(5); 737862306a36Sopenharmony_ci if (orig != data) 737962306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_CNTL, data); 738062306a36Sopenharmony_ci 738162306a36Sopenharmony_ci if (!disable_clkreq && 738262306a36Sopenharmony_ci !pci_is_root_bus(rdev->pdev->bus)) { 738362306a36Sopenharmony_ci struct pci_dev *root = rdev->pdev->bus->self; 738462306a36Sopenharmony_ci u32 lnkcap; 738562306a36Sopenharmony_ci 738662306a36Sopenharmony_ci clk_req_support = false; 738762306a36Sopenharmony_ci pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap); 738862306a36Sopenharmony_ci if (lnkcap & PCI_EXP_LNKCAP_CLKPM) 738962306a36Sopenharmony_ci clk_req_support = true; 739062306a36Sopenharmony_ci } else { 739162306a36Sopenharmony_ci clk_req_support = false; 739262306a36Sopenharmony_ci } 739362306a36Sopenharmony_ci 739462306a36Sopenharmony_ci if (clk_req_support) { 739562306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2); 739662306a36Sopenharmony_ci data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23; 739762306a36Sopenharmony_ci if (orig != data) 739862306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL2, data); 739962306a36Sopenharmony_ci 740062306a36Sopenharmony_ci orig = data = RREG32(THM_CLK_CNTL); 740162306a36Sopenharmony_ci data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK); 740262306a36Sopenharmony_ci data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1); 740362306a36Sopenharmony_ci if (orig != data) 740462306a36Sopenharmony_ci WREG32(THM_CLK_CNTL, data); 740562306a36Sopenharmony_ci 740662306a36Sopenharmony_ci orig = data = RREG32(MISC_CLK_CNTL); 740762306a36Sopenharmony_ci data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK); 740862306a36Sopenharmony_ci data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1); 740962306a36Sopenharmony_ci if (orig != data) 741062306a36Sopenharmony_ci WREG32(MISC_CLK_CNTL, data); 741162306a36Sopenharmony_ci 741262306a36Sopenharmony_ci orig = data = RREG32(CG_CLKPIN_CNTL); 741362306a36Sopenharmony_ci data &= ~BCLK_AS_XCLK; 741462306a36Sopenharmony_ci if (orig != data) 741562306a36Sopenharmony_ci WREG32(CG_CLKPIN_CNTL, data); 741662306a36Sopenharmony_ci 741762306a36Sopenharmony_ci orig = data = RREG32(CG_CLKPIN_CNTL_2); 741862306a36Sopenharmony_ci data &= ~FORCE_BIF_REFCLK_EN; 741962306a36Sopenharmony_ci if (orig != data) 742062306a36Sopenharmony_ci WREG32(CG_CLKPIN_CNTL_2, data); 742162306a36Sopenharmony_ci 742262306a36Sopenharmony_ci orig = data = RREG32(MPLL_BYPASSCLK_SEL); 742362306a36Sopenharmony_ci data &= ~MPLL_CLKOUT_SEL_MASK; 742462306a36Sopenharmony_ci data |= MPLL_CLKOUT_SEL(4); 742562306a36Sopenharmony_ci if (orig != data) 742662306a36Sopenharmony_ci WREG32(MPLL_BYPASSCLK_SEL, data); 742762306a36Sopenharmony_ci 742862306a36Sopenharmony_ci orig = data = RREG32(SPLL_CNTL_MODE); 742962306a36Sopenharmony_ci data &= ~SPLL_REFCLK_SEL_MASK; 743062306a36Sopenharmony_ci if (orig != data) 743162306a36Sopenharmony_ci WREG32(SPLL_CNTL_MODE, data); 743262306a36Sopenharmony_ci } 743362306a36Sopenharmony_ci } 743462306a36Sopenharmony_ci } else { 743562306a36Sopenharmony_ci if (orig != data) 743662306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 743762306a36Sopenharmony_ci } 743862306a36Sopenharmony_ci 743962306a36Sopenharmony_ci orig = data = RREG32_PCIE(PCIE_CNTL2); 744062306a36Sopenharmony_ci data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN; 744162306a36Sopenharmony_ci if (orig != data) 744262306a36Sopenharmony_ci WREG32_PCIE(PCIE_CNTL2, data); 744362306a36Sopenharmony_ci 744462306a36Sopenharmony_ci if (!disable_l0s) { 744562306a36Sopenharmony_ci data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL); 744662306a36Sopenharmony_ci if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) { 744762306a36Sopenharmony_ci data = RREG32_PCIE(PCIE_LC_STATUS1); 744862306a36Sopenharmony_ci if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) { 744962306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL); 745062306a36Sopenharmony_ci data &= ~LC_L0S_INACTIVITY_MASK; 745162306a36Sopenharmony_ci if (orig != data) 745262306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 745362306a36Sopenharmony_ci } 745462306a36Sopenharmony_ci } 745562306a36Sopenharmony_ci } 745662306a36Sopenharmony_ci} 745762306a36Sopenharmony_ci 745862306a36Sopenharmony_cistatic int si_vce_send_vcepll_ctlreq(struct radeon_device *rdev) 745962306a36Sopenharmony_ci{ 746062306a36Sopenharmony_ci unsigned i; 746162306a36Sopenharmony_ci 746262306a36Sopenharmony_ci /* make sure VCEPLL_CTLREQ is deasserted */ 746362306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK); 746462306a36Sopenharmony_ci 746562306a36Sopenharmony_ci mdelay(10); 746662306a36Sopenharmony_ci 746762306a36Sopenharmony_ci /* assert UPLL_CTLREQ */ 746862306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK); 746962306a36Sopenharmony_ci 747062306a36Sopenharmony_ci /* wait for CTLACK and CTLACK2 to get asserted */ 747162306a36Sopenharmony_ci for (i = 0; i < 100; ++i) { 747262306a36Sopenharmony_ci uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK; 747362306a36Sopenharmony_ci if ((RREG32_SMC(CG_VCEPLL_FUNC_CNTL) & mask) == mask) 747462306a36Sopenharmony_ci break; 747562306a36Sopenharmony_ci mdelay(10); 747662306a36Sopenharmony_ci } 747762306a36Sopenharmony_ci 747862306a36Sopenharmony_ci /* deassert UPLL_CTLREQ */ 747962306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK); 748062306a36Sopenharmony_ci 748162306a36Sopenharmony_ci if (i == 100) { 748262306a36Sopenharmony_ci DRM_ERROR("Timeout setting UVD clocks!\n"); 748362306a36Sopenharmony_ci return -ETIMEDOUT; 748462306a36Sopenharmony_ci } 748562306a36Sopenharmony_ci 748662306a36Sopenharmony_ci return 0; 748762306a36Sopenharmony_ci} 748862306a36Sopenharmony_ci 748962306a36Sopenharmony_ciint si_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk) 749062306a36Sopenharmony_ci{ 749162306a36Sopenharmony_ci unsigned fb_div = 0, evclk_div = 0, ecclk_div = 0; 749262306a36Sopenharmony_ci int r; 749362306a36Sopenharmony_ci 749462306a36Sopenharmony_ci /* bypass evclk and ecclk with bclk */ 749562306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2, 749662306a36Sopenharmony_ci EVCLK_SRC_SEL(1) | ECCLK_SRC_SEL(1), 749762306a36Sopenharmony_ci ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK)); 749862306a36Sopenharmony_ci 749962306a36Sopenharmony_ci /* put PLL in bypass mode */ 750062306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_BYPASS_EN_MASK, 750162306a36Sopenharmony_ci ~VCEPLL_BYPASS_EN_MASK); 750262306a36Sopenharmony_ci 750362306a36Sopenharmony_ci if (!evclk || !ecclk) { 750462306a36Sopenharmony_ci /* keep the Bypass mode, put PLL to sleep */ 750562306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK, 750662306a36Sopenharmony_ci ~VCEPLL_SLEEP_MASK); 750762306a36Sopenharmony_ci return 0; 750862306a36Sopenharmony_ci } 750962306a36Sopenharmony_ci 751062306a36Sopenharmony_ci r = radeon_uvd_calc_upll_dividers(rdev, evclk, ecclk, 125000, 250000, 751162306a36Sopenharmony_ci 16384, 0x03FFFFFF, 0, 128, 5, 751262306a36Sopenharmony_ci &fb_div, &evclk_div, &ecclk_div); 751362306a36Sopenharmony_ci if (r) 751462306a36Sopenharmony_ci return r; 751562306a36Sopenharmony_ci 751662306a36Sopenharmony_ci /* set RESET_ANTI_MUX to 0 */ 751762306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK); 751862306a36Sopenharmony_ci 751962306a36Sopenharmony_ci /* set VCO_MODE to 1 */ 752062306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_VCO_MODE_MASK, 752162306a36Sopenharmony_ci ~VCEPLL_VCO_MODE_MASK); 752262306a36Sopenharmony_ci 752362306a36Sopenharmony_ci /* toggle VCEPLL_SLEEP to 1 then back to 0 */ 752462306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK, 752562306a36Sopenharmony_ci ~VCEPLL_SLEEP_MASK); 752662306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_SLEEP_MASK); 752762306a36Sopenharmony_ci 752862306a36Sopenharmony_ci /* deassert VCEPLL_RESET */ 752962306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK); 753062306a36Sopenharmony_ci 753162306a36Sopenharmony_ci mdelay(1); 753262306a36Sopenharmony_ci 753362306a36Sopenharmony_ci r = si_vce_send_vcepll_ctlreq(rdev); 753462306a36Sopenharmony_ci if (r) 753562306a36Sopenharmony_ci return r; 753662306a36Sopenharmony_ci 753762306a36Sopenharmony_ci /* assert VCEPLL_RESET again */ 753862306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_RESET_MASK, ~VCEPLL_RESET_MASK); 753962306a36Sopenharmony_ci 754062306a36Sopenharmony_ci /* disable spread spectrum. */ 754162306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK); 754262306a36Sopenharmony_ci 754362306a36Sopenharmony_ci /* set feedback divider */ 754462306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_3, VCEPLL_FB_DIV(fb_div), ~VCEPLL_FB_DIV_MASK); 754562306a36Sopenharmony_ci 754662306a36Sopenharmony_ci /* set ref divider to 0 */ 754762306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_REF_DIV_MASK); 754862306a36Sopenharmony_ci 754962306a36Sopenharmony_ci /* set PDIV_A and PDIV_B */ 755062306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2, 755162306a36Sopenharmony_ci VCEPLL_PDIV_A(evclk_div) | VCEPLL_PDIV_B(ecclk_div), 755262306a36Sopenharmony_ci ~(VCEPLL_PDIV_A_MASK | VCEPLL_PDIV_B_MASK)); 755362306a36Sopenharmony_ci 755462306a36Sopenharmony_ci /* give the PLL some time to settle */ 755562306a36Sopenharmony_ci mdelay(15); 755662306a36Sopenharmony_ci 755762306a36Sopenharmony_ci /* deassert PLL_RESET */ 755862306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK); 755962306a36Sopenharmony_ci 756062306a36Sopenharmony_ci mdelay(15); 756162306a36Sopenharmony_ci 756262306a36Sopenharmony_ci /* switch from bypass mode to normal mode */ 756362306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_BYPASS_EN_MASK); 756462306a36Sopenharmony_ci 756562306a36Sopenharmony_ci r = si_vce_send_vcepll_ctlreq(rdev); 756662306a36Sopenharmony_ci if (r) 756762306a36Sopenharmony_ci return r; 756862306a36Sopenharmony_ci 756962306a36Sopenharmony_ci /* switch VCLK and DCLK selection */ 757062306a36Sopenharmony_ci WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2, 757162306a36Sopenharmony_ci EVCLK_SRC_SEL(16) | ECCLK_SRC_SEL(16), 757262306a36Sopenharmony_ci ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK)); 757362306a36Sopenharmony_ci 757462306a36Sopenharmony_ci mdelay(100); 757562306a36Sopenharmony_ci 757662306a36Sopenharmony_ci return 0; 757762306a36Sopenharmony_ci} 7578