18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright 2019 Advanced Micro Devices, Inc. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 128c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 158c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 168c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 178c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 188c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 198c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 208c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci#include <linux/firmware.h> 248c2ecf20Sopenharmony_ci#include <linux/slab.h> 258c2ecf20Sopenharmony_ci#include <linux/module.h> 268c2ecf20Sopenharmony_ci#include <linux/pci.h> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include "amdgpu.h" 298c2ecf20Sopenharmony_ci#include "amdgpu_atombios.h" 308c2ecf20Sopenharmony_ci#include "amdgpu_ih.h" 318c2ecf20Sopenharmony_ci#include "amdgpu_uvd.h" 328c2ecf20Sopenharmony_ci#include "amdgpu_vce.h" 338c2ecf20Sopenharmony_ci#include "amdgpu_ucode.h" 348c2ecf20Sopenharmony_ci#include "amdgpu_psp.h" 358c2ecf20Sopenharmony_ci#include "amdgpu_smu.h" 368c2ecf20Sopenharmony_ci#include "atom.h" 378c2ecf20Sopenharmony_ci#include "amd_pcie.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#include "gc/gc_10_1_0_offset.h" 408c2ecf20Sopenharmony_ci#include "gc/gc_10_1_0_sh_mask.h" 418c2ecf20Sopenharmony_ci#include "hdp/hdp_5_0_0_offset.h" 428c2ecf20Sopenharmony_ci#include "hdp/hdp_5_0_0_sh_mask.h" 438c2ecf20Sopenharmony_ci#include "smuio/smuio_11_0_0_offset.h" 448c2ecf20Sopenharmony_ci#include "mp/mp_11_0_offset.h" 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#include "soc15.h" 478c2ecf20Sopenharmony_ci#include "soc15_common.h" 488c2ecf20Sopenharmony_ci#include "gmc_v10_0.h" 498c2ecf20Sopenharmony_ci#include "gfxhub_v2_0.h" 508c2ecf20Sopenharmony_ci#include "mmhub_v2_0.h" 518c2ecf20Sopenharmony_ci#include "nbio_v2_3.h" 528c2ecf20Sopenharmony_ci#include "nv.h" 538c2ecf20Sopenharmony_ci#include "navi10_ih.h" 548c2ecf20Sopenharmony_ci#include "gfx_v10_0.h" 558c2ecf20Sopenharmony_ci#include "sdma_v5_0.h" 568c2ecf20Sopenharmony_ci#include "sdma_v5_2.h" 578c2ecf20Sopenharmony_ci#include "vcn_v2_0.h" 588c2ecf20Sopenharmony_ci#include "jpeg_v2_0.h" 598c2ecf20Sopenharmony_ci#include "vcn_v3_0.h" 608c2ecf20Sopenharmony_ci#include "jpeg_v3_0.h" 618c2ecf20Sopenharmony_ci#include "dce_virtual.h" 628c2ecf20Sopenharmony_ci#include "mes_v10_1.h" 638c2ecf20Sopenharmony_ci#include "mxgpu_nv.h" 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistatic const struct amd_ip_funcs nv_common_ip_funcs; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* 688c2ecf20Sopenharmony_ci * Indirect registers accessor 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistatic u32 nv_pcie_rreg(struct amdgpu_device *adev, u32 reg) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci unsigned long address, data; 738c2ecf20Sopenharmony_ci address = adev->nbio.funcs->get_pcie_index_offset(adev); 748c2ecf20Sopenharmony_ci data = adev->nbio.funcs->get_pcie_data_offset(adev); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci return amdgpu_device_indirect_rreg(adev, address, data, reg); 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic void nv_pcie_wreg(struct amdgpu_device *adev, u32 reg, u32 v) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci unsigned long address, data; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci address = adev->nbio.funcs->get_pcie_index_offset(adev); 848c2ecf20Sopenharmony_ci data = adev->nbio.funcs->get_pcie_data_offset(adev); 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci amdgpu_device_indirect_wreg(adev, address, data, reg, v); 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_cistatic u64 nv_pcie_rreg64(struct amdgpu_device *adev, u32 reg) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci unsigned long address, data; 928c2ecf20Sopenharmony_ci address = adev->nbio.funcs->get_pcie_index_offset(adev); 938c2ecf20Sopenharmony_ci data = adev->nbio.funcs->get_pcie_data_offset(adev); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci return amdgpu_device_indirect_rreg64(adev, address, data, reg); 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic void nv_pcie_wreg64(struct amdgpu_device *adev, u32 reg, u64 v) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci unsigned long address, data; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci address = adev->nbio.funcs->get_pcie_index_offset(adev); 1038c2ecf20Sopenharmony_ci data = adev->nbio.funcs->get_pcie_data_offset(adev); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci amdgpu_device_indirect_wreg64(adev, address, data, reg, v); 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci unsigned long flags, address, data; 1118c2ecf20Sopenharmony_ci u32 r; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); 1148c2ecf20Sopenharmony_ci data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci spin_lock_irqsave(&adev->didt_idx_lock, flags); 1178c2ecf20Sopenharmony_ci WREG32(address, (reg)); 1188c2ecf20Sopenharmony_ci r = RREG32(data); 1198c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&adev->didt_idx_lock, flags); 1208c2ecf20Sopenharmony_ci return r; 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic void nv_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci unsigned long flags, address, data; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); 1288c2ecf20Sopenharmony_ci data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci spin_lock_irqsave(&adev->didt_idx_lock, flags); 1318c2ecf20Sopenharmony_ci WREG32(address, (reg)); 1328c2ecf20Sopenharmony_ci WREG32(data, (v)); 1338c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&adev->didt_idx_lock, flags); 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic u32 nv_get_config_memsize(struct amdgpu_device *adev) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci return adev->nbio.funcs->get_memsize(adev); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic u32 nv_get_xclk(struct amdgpu_device *adev) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci return adev->clock.spll.reference_freq; 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_civoid nv_grbm_select(struct amdgpu_device *adev, 1488c2ecf20Sopenharmony_ci u32 me, u32 pipe, u32 queue, u32 vmid) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci u32 grbm_gfx_cntl = 0; 1518c2ecf20Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe); 1528c2ecf20Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me); 1538c2ecf20Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid); 1548c2ecf20Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci WREG32(SOC15_REG_OFFSET(GC, 0, mmGRBM_GFX_CNTL), grbm_gfx_cntl); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic void nv_vga_set_state(struct amdgpu_device *adev, bool state) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci /* todo */ 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic bool nv_read_disabled_bios(struct amdgpu_device *adev) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci /* todo */ 1678c2ecf20Sopenharmony_ci return false; 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_cistatic bool nv_read_bios_from_rom(struct amdgpu_device *adev, 1718c2ecf20Sopenharmony_ci u8 *bios, u32 length_bytes) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci u32 *dw_ptr; 1748c2ecf20Sopenharmony_ci u32 i, length_dw; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci if (bios == NULL) 1778c2ecf20Sopenharmony_ci return false; 1788c2ecf20Sopenharmony_ci if (length_bytes == 0) 1798c2ecf20Sopenharmony_ci return false; 1808c2ecf20Sopenharmony_ci /* APU vbios image is part of sbios image */ 1818c2ecf20Sopenharmony_ci if (adev->flags & AMD_IS_APU) 1828c2ecf20Sopenharmony_ci return false; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci dw_ptr = (u32 *)bios; 1858c2ecf20Sopenharmony_ci length_dw = ALIGN(length_bytes, 4) / 4; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci /* set rom index to 0 */ 1888c2ecf20Sopenharmony_ci WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX), 0); 1898c2ecf20Sopenharmony_ci /* read out the rom data */ 1908c2ecf20Sopenharmony_ci for (i = 0; i < length_dw; i++) 1918c2ecf20Sopenharmony_ci dw_ptr[i] = RREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA)); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci return true; 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic struct soc15_allowed_register_entry nv_allowed_read_registers[] = { 1978c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)}, 1988c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)}, 1998c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE0)}, 2008c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE1)}, 2018c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE2)}, 2028c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE3)}, 2038c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_STATUS_REG)}, 2048c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_STATUS_REG)}, 2058c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STAT)}, 2068c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT1)}, 2078c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT2)}, 2088c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT3)}, 2098c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)}, 2108c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)}, 2118c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)}, 2128c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)}, 2138c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)}, 2148c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)}, 2158c2ecf20Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)}, 2168c2ecf20Sopenharmony_ci}; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_cistatic uint32_t nv_read_indexed_register(struct amdgpu_device *adev, u32 se_num, 2198c2ecf20Sopenharmony_ci u32 sh_num, u32 reg_offset) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci uint32_t val; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci mutex_lock(&adev->grbm_idx_mutex); 2248c2ecf20Sopenharmony_ci if (se_num != 0xffffffff || sh_num != 0xffffffff) 2258c2ecf20Sopenharmony_ci amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff); 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci val = RREG32(reg_offset); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci if (se_num != 0xffffffff || sh_num != 0xffffffff) 2308c2ecf20Sopenharmony_ci amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff); 2318c2ecf20Sopenharmony_ci mutex_unlock(&adev->grbm_idx_mutex); 2328c2ecf20Sopenharmony_ci return val; 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic uint32_t nv_get_register_value(struct amdgpu_device *adev, 2368c2ecf20Sopenharmony_ci bool indexed, u32 se_num, 2378c2ecf20Sopenharmony_ci u32 sh_num, u32 reg_offset) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci if (indexed) { 2408c2ecf20Sopenharmony_ci return nv_read_indexed_register(adev, se_num, sh_num, reg_offset); 2418c2ecf20Sopenharmony_ci } else { 2428c2ecf20Sopenharmony_ci if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) 2438c2ecf20Sopenharmony_ci return adev->gfx.config.gb_addr_config; 2448c2ecf20Sopenharmony_ci return RREG32(reg_offset); 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci} 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cistatic int nv_read_register(struct amdgpu_device *adev, u32 se_num, 2498c2ecf20Sopenharmony_ci u32 sh_num, u32 reg_offset, u32 *value) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci uint32_t i; 2528c2ecf20Sopenharmony_ci struct soc15_allowed_register_entry *en; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci *value = 0; 2558c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) { 2568c2ecf20Sopenharmony_ci en = &nv_allowed_read_registers[i]; 2578c2ecf20Sopenharmony_ci if (reg_offset != 2588c2ecf20Sopenharmony_ci (adev->reg_offset[en->hwip][en->inst][en->seg] + en->reg_offset)) 2598c2ecf20Sopenharmony_ci continue; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci *value = nv_get_register_value(adev, 2628c2ecf20Sopenharmony_ci nv_allowed_read_registers[i].grbm_indexed, 2638c2ecf20Sopenharmony_ci se_num, sh_num, reg_offset); 2648c2ecf20Sopenharmony_ci return 0; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci return -EINVAL; 2678c2ecf20Sopenharmony_ci} 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_cistatic int nv_asic_mode1_reset(struct amdgpu_device *adev) 2708c2ecf20Sopenharmony_ci{ 2718c2ecf20Sopenharmony_ci u32 i; 2728c2ecf20Sopenharmony_ci int ret = 0; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci amdgpu_atombios_scratch_regs_engine_hung(adev, true); 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci /* disable BM */ 2778c2ecf20Sopenharmony_ci pci_clear_master(adev->pdev); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci amdgpu_device_cache_pci_state(adev->pdev); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci if (amdgpu_dpm_is_mode1_reset_supported(adev)) { 2828c2ecf20Sopenharmony_ci dev_info(adev->dev, "GPU smu mode1 reset\n"); 2838c2ecf20Sopenharmony_ci ret = amdgpu_dpm_mode1_reset(adev); 2848c2ecf20Sopenharmony_ci } else { 2858c2ecf20Sopenharmony_ci dev_info(adev->dev, "GPU psp mode1 reset\n"); 2868c2ecf20Sopenharmony_ci ret = psp_gpu_reset(adev); 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci if (ret) 2908c2ecf20Sopenharmony_ci dev_err(adev->dev, "GPU mode1 reset failed\n"); 2918c2ecf20Sopenharmony_ci amdgpu_device_load_pci_state(adev->pdev); 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci /* wait for asic to come out of reset */ 2948c2ecf20Sopenharmony_ci for (i = 0; i < adev->usec_timeout; i++) { 2958c2ecf20Sopenharmony_ci u32 memsize = adev->nbio.funcs->get_memsize(adev); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci if (memsize != 0xffffffff) 2988c2ecf20Sopenharmony_ci break; 2998c2ecf20Sopenharmony_ci udelay(1); 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci amdgpu_atombios_scratch_regs_engine_hung(adev, false); 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci return ret; 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_cistatic bool nv_asic_supports_baco(struct amdgpu_device *adev) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci struct smu_context *smu = &adev->smu; 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci if (smu_baco_is_support(smu)) 3128c2ecf20Sopenharmony_ci return true; 3138c2ecf20Sopenharmony_ci else 3148c2ecf20Sopenharmony_ci return false; 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic enum amd_reset_method 3188c2ecf20Sopenharmony_cinv_asic_reset_method(struct amdgpu_device *adev) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci struct smu_context *smu = &adev->smu; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || 3238c2ecf20Sopenharmony_ci amdgpu_reset_method == AMD_RESET_METHOD_BACO) 3248c2ecf20Sopenharmony_ci return amdgpu_reset_method; 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci if (amdgpu_reset_method != -1) 3278c2ecf20Sopenharmony_ci dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", 3288c2ecf20Sopenharmony_ci amdgpu_reset_method); 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci switch (adev->asic_type) { 3318c2ecf20Sopenharmony_ci case CHIP_SIENNA_CICHLID: 3328c2ecf20Sopenharmony_ci case CHIP_NAVY_FLOUNDER: 3338c2ecf20Sopenharmony_ci return AMD_RESET_METHOD_MODE1; 3348c2ecf20Sopenharmony_ci default: 3358c2ecf20Sopenharmony_ci if (smu_baco_is_support(smu)) 3368c2ecf20Sopenharmony_ci return AMD_RESET_METHOD_BACO; 3378c2ecf20Sopenharmony_ci else 3388c2ecf20Sopenharmony_ci return AMD_RESET_METHOD_MODE1; 3398c2ecf20Sopenharmony_ci } 3408c2ecf20Sopenharmony_ci} 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_cistatic int nv_asic_reset(struct amdgpu_device *adev) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci int ret = 0; 3458c2ecf20Sopenharmony_ci struct smu_context *smu = &adev->smu; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci if (nv_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) { 3488c2ecf20Sopenharmony_ci dev_info(adev->dev, "BACO reset\n"); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci ret = smu_baco_enter(smu); 3518c2ecf20Sopenharmony_ci if (ret) 3528c2ecf20Sopenharmony_ci return ret; 3538c2ecf20Sopenharmony_ci ret = smu_baco_exit(smu); 3548c2ecf20Sopenharmony_ci if (ret) 3558c2ecf20Sopenharmony_ci return ret; 3568c2ecf20Sopenharmony_ci } else { 3578c2ecf20Sopenharmony_ci dev_info(adev->dev, "MODE1 reset\n"); 3588c2ecf20Sopenharmony_ci ret = nv_asic_mode1_reset(adev); 3598c2ecf20Sopenharmony_ci } 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci return ret; 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_cistatic int nv_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk) 3658c2ecf20Sopenharmony_ci{ 3668c2ecf20Sopenharmony_ci /* todo */ 3678c2ecf20Sopenharmony_ci return 0; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic int nv_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci /* todo */ 3738c2ecf20Sopenharmony_ci return 0; 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_cistatic void nv_pcie_gen3_enable(struct amdgpu_device *adev) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci if (pci_is_root_bus(adev->pdev->bus)) 3798c2ecf20Sopenharmony_ci return; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci if (amdgpu_pcie_gen2 == 0) 3828c2ecf20Sopenharmony_ci return; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 | 3858c2ecf20Sopenharmony_ci CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3))) 3868c2ecf20Sopenharmony_ci return; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci /* todo */ 3898c2ecf20Sopenharmony_ci} 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_cistatic void nv_program_aspm(struct amdgpu_device *adev) 3928c2ecf20Sopenharmony_ci{ 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci if (amdgpu_aspm == 0) 3958c2ecf20Sopenharmony_ci return; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci /* todo */ 3988c2ecf20Sopenharmony_ci} 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_cistatic void nv_enable_doorbell_aperture(struct amdgpu_device *adev, 4018c2ecf20Sopenharmony_ci bool enable) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci adev->nbio.funcs->enable_doorbell_aperture(adev, enable); 4048c2ecf20Sopenharmony_ci adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable); 4058c2ecf20Sopenharmony_ci} 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_cistatic const struct amdgpu_ip_block_version nv_common_ip_block = 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci .type = AMD_IP_BLOCK_TYPE_COMMON, 4108c2ecf20Sopenharmony_ci .major = 1, 4118c2ecf20Sopenharmony_ci .minor = 0, 4128c2ecf20Sopenharmony_ci .rev = 0, 4138c2ecf20Sopenharmony_ci .funcs = &nv_common_ip_funcs, 4148c2ecf20Sopenharmony_ci}; 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_cistatic int nv_reg_base_init(struct amdgpu_device *adev) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci int r; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if (amdgpu_discovery) { 4218c2ecf20Sopenharmony_ci r = amdgpu_discovery_reg_base_init(adev); 4228c2ecf20Sopenharmony_ci if (r) { 4238c2ecf20Sopenharmony_ci DRM_WARN("failed to init reg base from ip discovery table, " 4248c2ecf20Sopenharmony_ci "fallback to legacy init method\n"); 4258c2ecf20Sopenharmony_ci goto legacy_init; 4268c2ecf20Sopenharmony_ci } 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci return 0; 4298c2ecf20Sopenharmony_ci } 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_cilegacy_init: 4328c2ecf20Sopenharmony_ci switch (adev->asic_type) { 4338c2ecf20Sopenharmony_ci case CHIP_NAVI10: 4348c2ecf20Sopenharmony_ci navi10_reg_base_init(adev); 4358c2ecf20Sopenharmony_ci break; 4368c2ecf20Sopenharmony_ci case CHIP_NAVI14: 4378c2ecf20Sopenharmony_ci navi14_reg_base_init(adev); 4388c2ecf20Sopenharmony_ci break; 4398c2ecf20Sopenharmony_ci case CHIP_NAVI12: 4408c2ecf20Sopenharmony_ci navi12_reg_base_init(adev); 4418c2ecf20Sopenharmony_ci break; 4428c2ecf20Sopenharmony_ci case CHIP_SIENNA_CICHLID: 4438c2ecf20Sopenharmony_ci case CHIP_NAVY_FLOUNDER: 4448c2ecf20Sopenharmony_ci sienna_cichlid_reg_base_init(adev); 4458c2ecf20Sopenharmony_ci break; 4468c2ecf20Sopenharmony_ci default: 4478c2ecf20Sopenharmony_ci return -EINVAL; 4488c2ecf20Sopenharmony_ci } 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci return 0; 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_civoid nv_set_virt_ops(struct amdgpu_device *adev) 4548c2ecf20Sopenharmony_ci{ 4558c2ecf20Sopenharmony_ci adev->virt.ops = &xgpu_nv_virt_ops; 4568c2ecf20Sopenharmony_ci} 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_cistatic bool nv_is_headless_sku(struct pci_dev *pdev) 4598c2ecf20Sopenharmony_ci{ 4608c2ecf20Sopenharmony_ci if ((pdev->device == 0x731E && 4618c2ecf20Sopenharmony_ci (pdev->revision == 0xC6 || pdev->revision == 0xC7)) || 4628c2ecf20Sopenharmony_ci (pdev->device == 0x7340 && pdev->revision == 0xC9) || 4638c2ecf20Sopenharmony_ci (pdev->device == 0x7360 && pdev->revision == 0xC7)) 4648c2ecf20Sopenharmony_ci return true; 4658c2ecf20Sopenharmony_ci return false; 4668c2ecf20Sopenharmony_ci} 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ciint nv_set_ip_blocks(struct amdgpu_device *adev) 4698c2ecf20Sopenharmony_ci{ 4708c2ecf20Sopenharmony_ci int r; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci adev->nbio.funcs = &nbio_v2_3_funcs; 4738c2ecf20Sopenharmony_ci adev->nbio.hdp_flush_reg = &nbio_v2_3_hdp_flush_reg; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci if (adev->asic_type == CHIP_SIENNA_CICHLID) 4768c2ecf20Sopenharmony_ci adev->gmc.xgmi.supported = true; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* Set IP register base before any HW register access */ 4798c2ecf20Sopenharmony_ci r = nv_reg_base_init(adev); 4808c2ecf20Sopenharmony_ci if (r) 4818c2ecf20Sopenharmony_ci return r; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci switch (adev->asic_type) { 4848c2ecf20Sopenharmony_ci case CHIP_NAVI10: 4858c2ecf20Sopenharmony_ci case CHIP_NAVI14: 4868c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &nv_common_ip_block); 4878c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); 4888c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); 4898c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); 4908c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && 4918c2ecf20Sopenharmony_ci !amdgpu_sriov_vf(adev)) 4928c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 4938c2ecf20Sopenharmony_ci if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) 4948c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 4958c2ecf20Sopenharmony_ci#if defined(CONFIG_DRM_AMD_DC) 4968c2ecf20Sopenharmony_ci else if (amdgpu_device_has_dc_support(adev)) 4978c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dm_ip_block); 4988c2ecf20Sopenharmony_ci#endif 4998c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); 5008c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); 5018c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && 5028c2ecf20Sopenharmony_ci !amdgpu_sriov_vf(adev)) 5038c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 5048c2ecf20Sopenharmony_ci if (!nv_is_headless_sku(adev->pdev)) 5058c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); 5068c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); 5078c2ecf20Sopenharmony_ci if (adev->enable_mes) 5088c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block); 5098c2ecf20Sopenharmony_ci break; 5108c2ecf20Sopenharmony_ci case CHIP_NAVI12: 5118c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &nv_common_ip_block); 5128c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); 5138c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); 5148c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); 5158c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) 5168c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 5178c2ecf20Sopenharmony_ci if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) 5188c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 5198c2ecf20Sopenharmony_ci#if defined(CONFIG_DRM_AMD_DC) 5208c2ecf20Sopenharmony_ci else if (amdgpu_device_has_dc_support(adev)) 5218c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dm_ip_block); 5228c2ecf20Sopenharmony_ci#endif 5238c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); 5248c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v5_0_ip_block); 5258c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && 5268c2ecf20Sopenharmony_ci !amdgpu_sriov_vf(adev)) 5278c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 5288c2ecf20Sopenharmony_ci if (!nv_is_headless_sku(adev->pdev)) 5298c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v2_0_ip_block); 5308c2ecf20Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) 5318c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v2_0_ip_block); 5328c2ecf20Sopenharmony_ci break; 5338c2ecf20Sopenharmony_ci case CHIP_SIENNA_CICHLID: 5348c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &nv_common_ip_block); 5358c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); 5368c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); 5378c2ecf20Sopenharmony_ci if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) 5388c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); 5398c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && 5408c2ecf20Sopenharmony_ci is_support_sw_smu(adev) && !amdgpu_sriov_vf(adev)) 5418c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 5428c2ecf20Sopenharmony_ci if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) 5438c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 5448c2ecf20Sopenharmony_ci#if defined(CONFIG_DRM_AMD_DC) 5458c2ecf20Sopenharmony_ci else if (amdgpu_device_has_dc_support(adev)) 5468c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dm_ip_block); 5478c2ecf20Sopenharmony_ci#endif 5488c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); 5498c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); 5508c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); 5518c2ecf20Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) 5528c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci if (adev->enable_mes) 5558c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &mes_v10_1_ip_block); 5568c2ecf20Sopenharmony_ci break; 5578c2ecf20Sopenharmony_ci case CHIP_NAVY_FLOUNDER: 5588c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &nv_common_ip_block); 5598c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gmc_v10_0_ip_block); 5608c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &navi10_ih_ip_block); 5618c2ecf20Sopenharmony_ci if (likely(adev->firmware.load_type == AMDGPU_FW_LOAD_PSP)) 5628c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block); 5638c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP && 5648c2ecf20Sopenharmony_ci is_support_sw_smu(adev)) 5658c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 5668c2ecf20Sopenharmony_ci if (adev->enable_virtual_display || amdgpu_sriov_vf(adev)) 5678c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dce_virtual_ip_block); 5688c2ecf20Sopenharmony_ci#if defined(CONFIG_DRM_AMD_DC) 5698c2ecf20Sopenharmony_ci else if (amdgpu_device_has_dc_support(adev)) 5708c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &dm_ip_block); 5718c2ecf20Sopenharmony_ci#endif 5728c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &gfx_v10_0_ip_block); 5738c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &sdma_v5_2_ip_block); 5748c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &vcn_v3_0_ip_block); 5758c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &jpeg_v3_0_ip_block); 5768c2ecf20Sopenharmony_ci if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT && 5778c2ecf20Sopenharmony_ci is_support_sw_smu(adev)) 5788c2ecf20Sopenharmony_ci amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block); 5798c2ecf20Sopenharmony_ci break; 5808c2ecf20Sopenharmony_ci default: 5818c2ecf20Sopenharmony_ci return -EINVAL; 5828c2ecf20Sopenharmony_ci } 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci return 0; 5858c2ecf20Sopenharmony_ci} 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_cistatic uint32_t nv_get_rev_id(struct amdgpu_device *adev) 5888c2ecf20Sopenharmony_ci{ 5898c2ecf20Sopenharmony_ci return adev->nbio.funcs->get_rev_id(adev); 5908c2ecf20Sopenharmony_ci} 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistatic void nv_flush_hdp(struct amdgpu_device *adev, struct amdgpu_ring *ring) 5938c2ecf20Sopenharmony_ci{ 5948c2ecf20Sopenharmony_ci adev->nbio.funcs->hdp_flush(adev, ring); 5958c2ecf20Sopenharmony_ci} 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_cistatic void nv_invalidate_hdp(struct amdgpu_device *adev, 5988c2ecf20Sopenharmony_ci struct amdgpu_ring *ring) 5998c2ecf20Sopenharmony_ci{ 6008c2ecf20Sopenharmony_ci if (!ring || !ring->funcs->emit_wreg) { 6018c2ecf20Sopenharmony_ci WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1); 6028c2ecf20Sopenharmony_ci } else { 6038c2ecf20Sopenharmony_ci amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET( 6048c2ecf20Sopenharmony_ci HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1); 6058c2ecf20Sopenharmony_ci } 6068c2ecf20Sopenharmony_ci} 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_cistatic bool nv_need_full_reset(struct amdgpu_device *adev) 6098c2ecf20Sopenharmony_ci{ 6108c2ecf20Sopenharmony_ci return true; 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic bool nv_need_reset_on_init(struct amdgpu_device *adev) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci u32 sol_reg; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci if (adev->flags & AMD_IS_APU) 6188c2ecf20Sopenharmony_ci return false; 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci /* Check sOS sign of life register to confirm sys driver and sOS 6218c2ecf20Sopenharmony_ci * are already been loaded. 6228c2ecf20Sopenharmony_ci */ 6238c2ecf20Sopenharmony_ci sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 6248c2ecf20Sopenharmony_ci if (sol_reg) 6258c2ecf20Sopenharmony_ci return true; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci return false; 6288c2ecf20Sopenharmony_ci} 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_cistatic uint64_t nv_get_pcie_replay_count(struct amdgpu_device *adev) 6318c2ecf20Sopenharmony_ci{ 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci /* TODO 6348c2ecf20Sopenharmony_ci * dummy implement for pcie_replay_count sysfs interface 6358c2ecf20Sopenharmony_ci * */ 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci return 0; 6388c2ecf20Sopenharmony_ci} 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_cistatic void nv_init_doorbell_index(struct amdgpu_device *adev) 6418c2ecf20Sopenharmony_ci{ 6428c2ecf20Sopenharmony_ci adev->doorbell_index.kiq = AMDGPU_NAVI10_DOORBELL_KIQ; 6438c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring0 = AMDGPU_NAVI10_DOORBELL_MEC_RING0; 6448c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring1 = AMDGPU_NAVI10_DOORBELL_MEC_RING1; 6458c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring2 = AMDGPU_NAVI10_DOORBELL_MEC_RING2; 6468c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring3 = AMDGPU_NAVI10_DOORBELL_MEC_RING3; 6478c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring4 = AMDGPU_NAVI10_DOORBELL_MEC_RING4; 6488c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring5 = AMDGPU_NAVI10_DOORBELL_MEC_RING5; 6498c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring6 = AMDGPU_NAVI10_DOORBELL_MEC_RING6; 6508c2ecf20Sopenharmony_ci adev->doorbell_index.mec_ring7 = AMDGPU_NAVI10_DOORBELL_MEC_RING7; 6518c2ecf20Sopenharmony_ci adev->doorbell_index.userqueue_start = AMDGPU_NAVI10_DOORBELL_USERQUEUE_START; 6528c2ecf20Sopenharmony_ci adev->doorbell_index.userqueue_end = AMDGPU_NAVI10_DOORBELL_USERQUEUE_END; 6538c2ecf20Sopenharmony_ci adev->doorbell_index.gfx_ring0 = AMDGPU_NAVI10_DOORBELL_GFX_RING0; 6548c2ecf20Sopenharmony_ci adev->doorbell_index.gfx_ring1 = AMDGPU_NAVI10_DOORBELL_GFX_RING1; 6558c2ecf20Sopenharmony_ci adev->doorbell_index.mes_ring = AMDGPU_NAVI10_DOORBELL_MES_RING; 6568c2ecf20Sopenharmony_ci adev->doorbell_index.sdma_engine[0] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0; 6578c2ecf20Sopenharmony_ci adev->doorbell_index.sdma_engine[1] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1; 6588c2ecf20Sopenharmony_ci adev->doorbell_index.sdma_engine[2] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE2; 6598c2ecf20Sopenharmony_ci adev->doorbell_index.sdma_engine[3] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE3; 6608c2ecf20Sopenharmony_ci adev->doorbell_index.ih = AMDGPU_NAVI10_DOORBELL_IH; 6618c2ecf20Sopenharmony_ci adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_NAVI10_DOORBELL64_VCN0_1; 6628c2ecf20Sopenharmony_ci adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_NAVI10_DOORBELL64_VCN2_3; 6638c2ecf20Sopenharmony_ci adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_NAVI10_DOORBELL64_VCN4_5; 6648c2ecf20Sopenharmony_ci adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_NAVI10_DOORBELL64_VCN6_7; 6658c2ecf20Sopenharmony_ci adev->doorbell_index.first_non_cp = AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP; 6668c2ecf20Sopenharmony_ci adev->doorbell_index.last_non_cp = AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP; 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci adev->doorbell_index.max_assignment = AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT << 1; 6698c2ecf20Sopenharmony_ci adev->doorbell_index.sdma_doorbell_range = 20; 6708c2ecf20Sopenharmony_ci} 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_cistatic void nv_pre_asic_init(struct amdgpu_device *adev) 6738c2ecf20Sopenharmony_ci{ 6748c2ecf20Sopenharmony_ci} 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_cistatic const struct amdgpu_asic_funcs nv_asic_funcs = 6778c2ecf20Sopenharmony_ci{ 6788c2ecf20Sopenharmony_ci .read_disabled_bios = &nv_read_disabled_bios, 6798c2ecf20Sopenharmony_ci .read_bios_from_rom = &nv_read_bios_from_rom, 6808c2ecf20Sopenharmony_ci .read_register = &nv_read_register, 6818c2ecf20Sopenharmony_ci .reset = &nv_asic_reset, 6828c2ecf20Sopenharmony_ci .reset_method = &nv_asic_reset_method, 6838c2ecf20Sopenharmony_ci .set_vga_state = &nv_vga_set_state, 6848c2ecf20Sopenharmony_ci .get_xclk = &nv_get_xclk, 6858c2ecf20Sopenharmony_ci .set_uvd_clocks = &nv_set_uvd_clocks, 6868c2ecf20Sopenharmony_ci .set_vce_clocks = &nv_set_vce_clocks, 6878c2ecf20Sopenharmony_ci .get_config_memsize = &nv_get_config_memsize, 6888c2ecf20Sopenharmony_ci .flush_hdp = &nv_flush_hdp, 6898c2ecf20Sopenharmony_ci .invalidate_hdp = &nv_invalidate_hdp, 6908c2ecf20Sopenharmony_ci .init_doorbell_index = &nv_init_doorbell_index, 6918c2ecf20Sopenharmony_ci .need_full_reset = &nv_need_full_reset, 6928c2ecf20Sopenharmony_ci .need_reset_on_init = &nv_need_reset_on_init, 6938c2ecf20Sopenharmony_ci .get_pcie_replay_count = &nv_get_pcie_replay_count, 6948c2ecf20Sopenharmony_ci .supports_baco = &nv_asic_supports_baco, 6958c2ecf20Sopenharmony_ci .pre_asic_init = &nv_pre_asic_init, 6968c2ecf20Sopenharmony_ci}; 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_cistatic int nv_common_early_init(void *handle) 6998c2ecf20Sopenharmony_ci{ 7008c2ecf20Sopenharmony_ci#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) 7018c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_ci adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; 7048c2ecf20Sopenharmony_ci adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; 7058c2ecf20Sopenharmony_ci adev->smc_rreg = NULL; 7068c2ecf20Sopenharmony_ci adev->smc_wreg = NULL; 7078c2ecf20Sopenharmony_ci adev->pcie_rreg = &nv_pcie_rreg; 7088c2ecf20Sopenharmony_ci adev->pcie_wreg = &nv_pcie_wreg; 7098c2ecf20Sopenharmony_ci adev->pcie_rreg64 = &nv_pcie_rreg64; 7108c2ecf20Sopenharmony_ci adev->pcie_wreg64 = &nv_pcie_wreg64; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci /* TODO: will add them during VCN v2 implementation */ 7138c2ecf20Sopenharmony_ci adev->uvd_ctx_rreg = NULL; 7148c2ecf20Sopenharmony_ci adev->uvd_ctx_wreg = NULL; 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci adev->didt_rreg = &nv_didt_rreg; 7178c2ecf20Sopenharmony_ci adev->didt_wreg = &nv_didt_wreg; 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_ci adev->asic_funcs = &nv_asic_funcs; 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci adev->rev_id = nv_get_rev_id(adev); 7228c2ecf20Sopenharmony_ci adev->external_rev_id = 0xff; 7238c2ecf20Sopenharmony_ci switch (adev->asic_type) { 7248c2ecf20Sopenharmony_ci case CHIP_NAVI10: 7258c2ecf20Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 7268c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 7278c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 7288c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 7298c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 7308c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 7318c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 7328c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 7338c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 7348c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_MGCG | 7358c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_LS | 7368c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 7378c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG | 7388c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_BIF_MGCG | 7398c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS; 7408c2ecf20Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN | 7418c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG | 7428c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_JPEG | 7438c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_ATHUB; 7448c2ecf20Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x1; 7458c2ecf20Sopenharmony_ci break; 7468c2ecf20Sopenharmony_ci case CHIP_NAVI14: 7478c2ecf20Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 7488c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 7498c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 7508c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 7518c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 7528c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 7538c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 7548c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 7558c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 7568c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_MGCG | 7578c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_LS | 7588c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 7598c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG | 7608c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_BIF_MGCG | 7618c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS; 7628c2ecf20Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN | 7638c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_JPEG | 7648c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG; 7658c2ecf20Sopenharmony_ci adev->external_rev_id = adev->rev_id + 20; 7668c2ecf20Sopenharmony_ci break; 7678c2ecf20Sopenharmony_ci case CHIP_NAVI12: 7688c2ecf20Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 7698c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 7708c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 7718c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 7728c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_RLC_LS | 7738c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 7748c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 7758c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 7768c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 7778c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 7788c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 7798c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 7808c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_MGCG | 7818c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_LS | 7828c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 7838c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG; 7848c2ecf20Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN | 7858c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG | 7868c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_JPEG | 7878c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_ATHUB; 7888c2ecf20Sopenharmony_ci /* guest vm gets 0xffffffff when reading RCC_DEV0_EPF0_STRAP0, 7898c2ecf20Sopenharmony_ci * as a consequence, the rev_id and external_rev_id are wrong. 7908c2ecf20Sopenharmony_ci * workaround it by hardcoding rev_id to 0 (default value). 7918c2ecf20Sopenharmony_ci */ 7928c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 7938c2ecf20Sopenharmony_ci adev->rev_id = 0; 7948c2ecf20Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0xa; 7958c2ecf20Sopenharmony_ci break; 7968c2ecf20Sopenharmony_ci case CHIP_SIENNA_CICHLID: 7978c2ecf20Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 7988c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 7998c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 8008c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 8018c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 8028c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG | 8038c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 8048c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 8058c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 8068c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_LS; 8078c2ecf20Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN | 8088c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG | 8098c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_JPEG | 8108c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_ATHUB | 8118c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_MMHUB; 8128c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) { 8138c2ecf20Sopenharmony_ci /* hypervisor control CG and PG enablement */ 8148c2ecf20Sopenharmony_ci adev->cg_flags = 0; 8158c2ecf20Sopenharmony_ci adev->pg_flags = 0; 8168c2ecf20Sopenharmony_ci } 8178c2ecf20Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x28; 8188c2ecf20Sopenharmony_ci break; 8198c2ecf20Sopenharmony_ci case CHIP_NAVY_FLOUNDER: 8208c2ecf20Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 8218c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 8228c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 8238c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 8248c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG | 8258c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 8268c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 8278c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 8288c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 8298c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_IH_CG; 8308c2ecf20Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN | 8318c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG | 8328c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_JPEG | 8338c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_ATHUB | 8348c2ecf20Sopenharmony_ci AMD_PG_SUPPORT_MMHUB; 8358c2ecf20Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x32; 8368c2ecf20Sopenharmony_ci break; 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci default: 8398c2ecf20Sopenharmony_ci /* FIXME: not supported yet */ 8408c2ecf20Sopenharmony_ci return -EINVAL; 8418c2ecf20Sopenharmony_ci } 8428c2ecf20Sopenharmony_ci 8438c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) { 8448c2ecf20Sopenharmony_ci amdgpu_virt_init_setting(adev); 8458c2ecf20Sopenharmony_ci xgpu_nv_mailbox_set_irq_funcs(adev); 8468c2ecf20Sopenharmony_ci } 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci return 0; 8498c2ecf20Sopenharmony_ci} 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_cistatic int nv_common_late_init(void *handle) 8528c2ecf20Sopenharmony_ci{ 8538c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 8568c2ecf20Sopenharmony_ci xgpu_nv_mailbox_get_irq(adev); 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci return 0; 8598c2ecf20Sopenharmony_ci} 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_cistatic int nv_common_sw_init(void *handle) 8628c2ecf20Sopenharmony_ci{ 8638c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 8668c2ecf20Sopenharmony_ci xgpu_nv_mailbox_add_irq_id(adev); 8678c2ecf20Sopenharmony_ci 8688c2ecf20Sopenharmony_ci return 0; 8698c2ecf20Sopenharmony_ci} 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_cistatic int nv_common_sw_fini(void *handle) 8728c2ecf20Sopenharmony_ci{ 8738c2ecf20Sopenharmony_ci return 0; 8748c2ecf20Sopenharmony_ci} 8758c2ecf20Sopenharmony_ci 8768c2ecf20Sopenharmony_cistatic int nv_common_hw_init(void *handle) 8778c2ecf20Sopenharmony_ci{ 8788c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 8798c2ecf20Sopenharmony_ci 8808c2ecf20Sopenharmony_ci /* enable pcie gen2/3 link */ 8818c2ecf20Sopenharmony_ci nv_pcie_gen3_enable(adev); 8828c2ecf20Sopenharmony_ci /* enable aspm */ 8838c2ecf20Sopenharmony_ci nv_program_aspm(adev); 8848c2ecf20Sopenharmony_ci /* setup nbio registers */ 8858c2ecf20Sopenharmony_ci adev->nbio.funcs->init_registers(adev); 8868c2ecf20Sopenharmony_ci /* remap HDP registers to a hole in mmio space, 8878c2ecf20Sopenharmony_ci * for the purpose of expose those registers 8888c2ecf20Sopenharmony_ci * to process space 8898c2ecf20Sopenharmony_ci */ 8908c2ecf20Sopenharmony_ci if (adev->nbio.funcs->remap_hdp_registers) 8918c2ecf20Sopenharmony_ci adev->nbio.funcs->remap_hdp_registers(adev); 8928c2ecf20Sopenharmony_ci /* enable the doorbell aperture */ 8938c2ecf20Sopenharmony_ci nv_enable_doorbell_aperture(adev, true); 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_ci return 0; 8968c2ecf20Sopenharmony_ci} 8978c2ecf20Sopenharmony_ci 8988c2ecf20Sopenharmony_cistatic int nv_common_hw_fini(void *handle) 8998c2ecf20Sopenharmony_ci{ 9008c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 9018c2ecf20Sopenharmony_ci 9028c2ecf20Sopenharmony_ci /* disable the doorbell aperture */ 9038c2ecf20Sopenharmony_ci nv_enable_doorbell_aperture(adev, false); 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci return 0; 9068c2ecf20Sopenharmony_ci} 9078c2ecf20Sopenharmony_ci 9088c2ecf20Sopenharmony_cistatic int nv_common_suspend(void *handle) 9098c2ecf20Sopenharmony_ci{ 9108c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci return nv_common_hw_fini(adev); 9138c2ecf20Sopenharmony_ci} 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_cistatic int nv_common_resume(void *handle) 9168c2ecf20Sopenharmony_ci{ 9178c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci return nv_common_hw_init(adev); 9208c2ecf20Sopenharmony_ci} 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_cistatic bool nv_common_is_idle(void *handle) 9238c2ecf20Sopenharmony_ci{ 9248c2ecf20Sopenharmony_ci return true; 9258c2ecf20Sopenharmony_ci} 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_cistatic int nv_common_wait_for_idle(void *handle) 9288c2ecf20Sopenharmony_ci{ 9298c2ecf20Sopenharmony_ci return 0; 9308c2ecf20Sopenharmony_ci} 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_cistatic int nv_common_soft_reset(void *handle) 9338c2ecf20Sopenharmony_ci{ 9348c2ecf20Sopenharmony_ci return 0; 9358c2ecf20Sopenharmony_ci} 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_cistatic void nv_update_hdp_mem_power_gating(struct amdgpu_device *adev, 9388c2ecf20Sopenharmony_ci bool enable) 9398c2ecf20Sopenharmony_ci{ 9408c2ecf20Sopenharmony_ci uint32_t hdp_clk_cntl, hdp_clk_cntl1; 9418c2ecf20Sopenharmony_ci uint32_t hdp_mem_pwr_cntl; 9428c2ecf20Sopenharmony_ci 9438c2ecf20Sopenharmony_ci if (!(adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | 9448c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_DS | 9458c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_SD))) 9468c2ecf20Sopenharmony_ci return; 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ci hdp_clk_cntl = hdp_clk_cntl1 = RREG32_SOC15(HDP, 0, mmHDP_CLK_CNTL); 9498c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = RREG32_SOC15(HDP, 0, mmHDP_MEM_POWER_CTRL); 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci /* Before doing clock/power mode switch, 9528c2ecf20Sopenharmony_ci * forced on IPH & RC clock */ 9538c2ecf20Sopenharmony_ci hdp_clk_cntl = REG_SET_FIELD(hdp_clk_cntl, HDP_CLK_CNTL, 9548c2ecf20Sopenharmony_ci IPH_MEM_CLK_SOFT_OVERRIDE, 1); 9558c2ecf20Sopenharmony_ci hdp_clk_cntl = REG_SET_FIELD(hdp_clk_cntl, HDP_CLK_CNTL, 9568c2ecf20Sopenharmony_ci RC_MEM_CLK_SOFT_OVERRIDE, 1); 9578c2ecf20Sopenharmony_ci WREG32_SOC15(HDP, 0, mmHDP_CLK_CNTL, hdp_clk_cntl); 9588c2ecf20Sopenharmony_ci 9598c2ecf20Sopenharmony_ci /* HDP 5.0 doesn't support dynamic power mode switch, 9608c2ecf20Sopenharmony_ci * disable clock and power gating before any changing */ 9618c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9628c2ecf20Sopenharmony_ci IPH_MEM_POWER_CTRL_EN, 0); 9638c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9648c2ecf20Sopenharmony_ci IPH_MEM_POWER_LS_EN, 0); 9658c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9668c2ecf20Sopenharmony_ci IPH_MEM_POWER_DS_EN, 0); 9678c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9688c2ecf20Sopenharmony_ci IPH_MEM_POWER_SD_EN, 0); 9698c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9708c2ecf20Sopenharmony_ci RC_MEM_POWER_CTRL_EN, 0); 9718c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9728c2ecf20Sopenharmony_ci RC_MEM_POWER_LS_EN, 0); 9738c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9748c2ecf20Sopenharmony_ci RC_MEM_POWER_DS_EN, 0); 9758c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 9768c2ecf20Sopenharmony_ci RC_MEM_POWER_SD_EN, 0); 9778c2ecf20Sopenharmony_ci WREG32_SOC15(HDP, 0, mmHDP_MEM_POWER_CTRL, hdp_mem_pwr_cntl); 9788c2ecf20Sopenharmony_ci 9798c2ecf20Sopenharmony_ci /* only one clock gating mode (LS/DS/SD) can be enabled */ 9808c2ecf20Sopenharmony_ci if (adev->cg_flags & AMD_CG_SUPPORT_HDP_LS) { 9818c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, 9828c2ecf20Sopenharmony_ci HDP_MEM_POWER_CTRL, 9838c2ecf20Sopenharmony_ci IPH_MEM_POWER_LS_EN, enable); 9848c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, 9858c2ecf20Sopenharmony_ci HDP_MEM_POWER_CTRL, 9868c2ecf20Sopenharmony_ci RC_MEM_POWER_LS_EN, enable); 9878c2ecf20Sopenharmony_ci } else if (adev->cg_flags & AMD_CG_SUPPORT_HDP_DS) { 9888c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, 9898c2ecf20Sopenharmony_ci HDP_MEM_POWER_CTRL, 9908c2ecf20Sopenharmony_ci IPH_MEM_POWER_DS_EN, enable); 9918c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, 9928c2ecf20Sopenharmony_ci HDP_MEM_POWER_CTRL, 9938c2ecf20Sopenharmony_ci RC_MEM_POWER_DS_EN, enable); 9948c2ecf20Sopenharmony_ci } else if (adev->cg_flags & AMD_CG_SUPPORT_HDP_SD) { 9958c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, 9968c2ecf20Sopenharmony_ci HDP_MEM_POWER_CTRL, 9978c2ecf20Sopenharmony_ci IPH_MEM_POWER_SD_EN, enable); 9988c2ecf20Sopenharmony_ci /* RC should not use shut down mode, fallback to ds */ 9998c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, 10008c2ecf20Sopenharmony_ci HDP_MEM_POWER_CTRL, 10018c2ecf20Sopenharmony_ci RC_MEM_POWER_DS_EN, enable); 10028c2ecf20Sopenharmony_ci } 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci /* confirmed that IPH_MEM_POWER_CTRL_EN and RC_MEM_POWER_CTRL_EN have to 10058c2ecf20Sopenharmony_ci * be set for SRAM LS/DS/SD */ 10068c2ecf20Sopenharmony_ci if (adev->cg_flags & (AMD_CG_SUPPORT_HDP_LS | AMD_CG_SUPPORT_HDP_DS | 10078c2ecf20Sopenharmony_ci AMD_CG_SUPPORT_HDP_SD)) { 10088c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 10098c2ecf20Sopenharmony_ci IPH_MEM_POWER_CTRL_EN, 1); 10108c2ecf20Sopenharmony_ci hdp_mem_pwr_cntl = REG_SET_FIELD(hdp_mem_pwr_cntl, HDP_MEM_POWER_CTRL, 10118c2ecf20Sopenharmony_ci RC_MEM_POWER_CTRL_EN, 1); 10128c2ecf20Sopenharmony_ci } 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_ci WREG32_SOC15(HDP, 0, mmHDP_MEM_POWER_CTRL, hdp_mem_pwr_cntl); 10158c2ecf20Sopenharmony_ci 10168c2ecf20Sopenharmony_ci /* restore IPH & RC clock override after clock/power mode changing */ 10178c2ecf20Sopenharmony_ci WREG32_SOC15(HDP, 0, mmHDP_CLK_CNTL, hdp_clk_cntl1); 10188c2ecf20Sopenharmony_ci} 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_cistatic void nv_update_hdp_clock_gating(struct amdgpu_device *adev, 10218c2ecf20Sopenharmony_ci bool enable) 10228c2ecf20Sopenharmony_ci{ 10238c2ecf20Sopenharmony_ci uint32_t hdp_clk_cntl; 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_ci if (!(adev->cg_flags & AMD_CG_SUPPORT_HDP_MGCG)) 10268c2ecf20Sopenharmony_ci return; 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci hdp_clk_cntl = RREG32_SOC15(HDP, 0, mmHDP_CLK_CNTL); 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci if (enable) { 10318c2ecf20Sopenharmony_ci hdp_clk_cntl &= 10328c2ecf20Sopenharmony_ci ~(uint32_t) 10338c2ecf20Sopenharmony_ci (HDP_CLK_CNTL__IPH_MEM_CLK_SOFT_OVERRIDE_MASK | 10348c2ecf20Sopenharmony_ci HDP_CLK_CNTL__RC_MEM_CLK_SOFT_OVERRIDE_MASK | 10358c2ecf20Sopenharmony_ci HDP_CLK_CNTL__DBUS_CLK_SOFT_OVERRIDE_MASK | 10368c2ecf20Sopenharmony_ci HDP_CLK_CNTL__DYN_CLK_SOFT_OVERRIDE_MASK | 10378c2ecf20Sopenharmony_ci HDP_CLK_CNTL__XDP_REG_CLK_SOFT_OVERRIDE_MASK | 10388c2ecf20Sopenharmony_ci HDP_CLK_CNTL__HDP_REG_CLK_SOFT_OVERRIDE_MASK); 10398c2ecf20Sopenharmony_ci } else { 10408c2ecf20Sopenharmony_ci hdp_clk_cntl |= HDP_CLK_CNTL__IPH_MEM_CLK_SOFT_OVERRIDE_MASK | 10418c2ecf20Sopenharmony_ci HDP_CLK_CNTL__RC_MEM_CLK_SOFT_OVERRIDE_MASK | 10428c2ecf20Sopenharmony_ci HDP_CLK_CNTL__DBUS_CLK_SOFT_OVERRIDE_MASK | 10438c2ecf20Sopenharmony_ci HDP_CLK_CNTL__DYN_CLK_SOFT_OVERRIDE_MASK | 10448c2ecf20Sopenharmony_ci HDP_CLK_CNTL__XDP_REG_CLK_SOFT_OVERRIDE_MASK | 10458c2ecf20Sopenharmony_ci HDP_CLK_CNTL__HDP_REG_CLK_SOFT_OVERRIDE_MASK; 10468c2ecf20Sopenharmony_ci } 10478c2ecf20Sopenharmony_ci 10488c2ecf20Sopenharmony_ci WREG32_SOC15(HDP, 0, mmHDP_CLK_CNTL, hdp_clk_cntl); 10498c2ecf20Sopenharmony_ci} 10508c2ecf20Sopenharmony_ci 10518c2ecf20Sopenharmony_cistatic int nv_common_set_clockgating_state(void *handle, 10528c2ecf20Sopenharmony_ci enum amd_clockgating_state state) 10538c2ecf20Sopenharmony_ci{ 10548c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 10558c2ecf20Sopenharmony_ci 10568c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 10578c2ecf20Sopenharmony_ci return 0; 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci switch (adev->asic_type) { 10608c2ecf20Sopenharmony_ci case CHIP_NAVI10: 10618c2ecf20Sopenharmony_ci case CHIP_NAVI14: 10628c2ecf20Sopenharmony_ci case CHIP_NAVI12: 10638c2ecf20Sopenharmony_ci case CHIP_SIENNA_CICHLID: 10648c2ecf20Sopenharmony_ci case CHIP_NAVY_FLOUNDER: 10658c2ecf20Sopenharmony_ci adev->nbio.funcs->update_medium_grain_clock_gating(adev, 10668c2ecf20Sopenharmony_ci state == AMD_CG_STATE_GATE); 10678c2ecf20Sopenharmony_ci adev->nbio.funcs->update_medium_grain_light_sleep(adev, 10688c2ecf20Sopenharmony_ci state == AMD_CG_STATE_GATE); 10698c2ecf20Sopenharmony_ci nv_update_hdp_mem_power_gating(adev, 10708c2ecf20Sopenharmony_ci state == AMD_CG_STATE_GATE); 10718c2ecf20Sopenharmony_ci nv_update_hdp_clock_gating(adev, 10728c2ecf20Sopenharmony_ci state == AMD_CG_STATE_GATE); 10738c2ecf20Sopenharmony_ci break; 10748c2ecf20Sopenharmony_ci default: 10758c2ecf20Sopenharmony_ci break; 10768c2ecf20Sopenharmony_ci } 10778c2ecf20Sopenharmony_ci return 0; 10788c2ecf20Sopenharmony_ci} 10798c2ecf20Sopenharmony_ci 10808c2ecf20Sopenharmony_cistatic int nv_common_set_powergating_state(void *handle, 10818c2ecf20Sopenharmony_ci enum amd_powergating_state state) 10828c2ecf20Sopenharmony_ci{ 10838c2ecf20Sopenharmony_ci /* TODO */ 10848c2ecf20Sopenharmony_ci return 0; 10858c2ecf20Sopenharmony_ci} 10868c2ecf20Sopenharmony_ci 10878c2ecf20Sopenharmony_cistatic void nv_common_get_clockgating_state(void *handle, u32 *flags) 10888c2ecf20Sopenharmony_ci{ 10898c2ecf20Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 10908c2ecf20Sopenharmony_ci uint32_t tmp; 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 10938c2ecf20Sopenharmony_ci *flags = 0; 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_ci adev->nbio.funcs->get_clockgating_state(adev, flags); 10968c2ecf20Sopenharmony_ci 10978c2ecf20Sopenharmony_ci /* AMD_CG_SUPPORT_HDP_MGCG */ 10988c2ecf20Sopenharmony_ci tmp = RREG32_SOC15(HDP, 0, mmHDP_CLK_CNTL); 10998c2ecf20Sopenharmony_ci if (!(tmp & (HDP_CLK_CNTL__IPH_MEM_CLK_SOFT_OVERRIDE_MASK | 11008c2ecf20Sopenharmony_ci HDP_CLK_CNTL__RC_MEM_CLK_SOFT_OVERRIDE_MASK | 11018c2ecf20Sopenharmony_ci HDP_CLK_CNTL__DBUS_CLK_SOFT_OVERRIDE_MASK | 11028c2ecf20Sopenharmony_ci HDP_CLK_CNTL__DYN_CLK_SOFT_OVERRIDE_MASK | 11038c2ecf20Sopenharmony_ci HDP_CLK_CNTL__XDP_REG_CLK_SOFT_OVERRIDE_MASK | 11048c2ecf20Sopenharmony_ci HDP_CLK_CNTL__HDP_REG_CLK_SOFT_OVERRIDE_MASK))) 11058c2ecf20Sopenharmony_ci *flags |= AMD_CG_SUPPORT_HDP_MGCG; 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_ci /* AMD_CG_SUPPORT_HDP_LS/DS/SD */ 11088c2ecf20Sopenharmony_ci tmp = RREG32_SOC15(HDP, 0, mmHDP_MEM_POWER_CTRL); 11098c2ecf20Sopenharmony_ci if (tmp & HDP_MEM_POWER_CTRL__IPH_MEM_POWER_LS_EN_MASK) 11108c2ecf20Sopenharmony_ci *flags |= AMD_CG_SUPPORT_HDP_LS; 11118c2ecf20Sopenharmony_ci else if (tmp & HDP_MEM_POWER_CTRL__IPH_MEM_POWER_DS_EN_MASK) 11128c2ecf20Sopenharmony_ci *flags |= AMD_CG_SUPPORT_HDP_DS; 11138c2ecf20Sopenharmony_ci else if (tmp & HDP_MEM_POWER_CTRL__IPH_MEM_POWER_SD_EN_MASK) 11148c2ecf20Sopenharmony_ci *flags |= AMD_CG_SUPPORT_HDP_SD; 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_ci return; 11178c2ecf20Sopenharmony_ci} 11188c2ecf20Sopenharmony_ci 11198c2ecf20Sopenharmony_cistatic const struct amd_ip_funcs nv_common_ip_funcs = { 11208c2ecf20Sopenharmony_ci .name = "nv_common", 11218c2ecf20Sopenharmony_ci .early_init = nv_common_early_init, 11228c2ecf20Sopenharmony_ci .late_init = nv_common_late_init, 11238c2ecf20Sopenharmony_ci .sw_init = nv_common_sw_init, 11248c2ecf20Sopenharmony_ci .sw_fini = nv_common_sw_fini, 11258c2ecf20Sopenharmony_ci .hw_init = nv_common_hw_init, 11268c2ecf20Sopenharmony_ci .hw_fini = nv_common_hw_fini, 11278c2ecf20Sopenharmony_ci .suspend = nv_common_suspend, 11288c2ecf20Sopenharmony_ci .resume = nv_common_resume, 11298c2ecf20Sopenharmony_ci .is_idle = nv_common_is_idle, 11308c2ecf20Sopenharmony_ci .wait_for_idle = nv_common_wait_for_idle, 11318c2ecf20Sopenharmony_ci .soft_reset = nv_common_soft_reset, 11328c2ecf20Sopenharmony_ci .set_clockgating_state = nv_common_set_clockgating_state, 11338c2ecf20Sopenharmony_ci .set_powergating_state = nv_common_set_powergating_state, 11348c2ecf20Sopenharmony_ci .get_clockgating_state = nv_common_get_clockgating_state, 11358c2ecf20Sopenharmony_ci}; 1136