162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2016 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 */ 2362306a36Sopenharmony_ci#include <linux/firmware.h> 2462306a36Sopenharmony_ci#include <linux/slab.h> 2562306a36Sopenharmony_ci#include <linux/module.h> 2662306a36Sopenharmony_ci#include <linux/pci.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include <drm/amdgpu_drm.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include "amdgpu.h" 3162306a36Sopenharmony_ci#include "amdgpu_atombios.h" 3262306a36Sopenharmony_ci#include "amdgpu_ih.h" 3362306a36Sopenharmony_ci#include "amdgpu_uvd.h" 3462306a36Sopenharmony_ci#include "amdgpu_vce.h" 3562306a36Sopenharmony_ci#include "amdgpu_ucode.h" 3662306a36Sopenharmony_ci#include "amdgpu_psp.h" 3762306a36Sopenharmony_ci#include "atom.h" 3862306a36Sopenharmony_ci#include "amd_pcie.h" 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#include "uvd/uvd_7_0_offset.h" 4162306a36Sopenharmony_ci#include "gc/gc_9_0_offset.h" 4262306a36Sopenharmony_ci#include "gc/gc_9_0_sh_mask.h" 4362306a36Sopenharmony_ci#include "sdma0/sdma0_4_0_offset.h" 4462306a36Sopenharmony_ci#include "sdma1/sdma1_4_0_offset.h" 4562306a36Sopenharmony_ci#include "nbio/nbio_7_0_default.h" 4662306a36Sopenharmony_ci#include "nbio/nbio_7_0_offset.h" 4762306a36Sopenharmony_ci#include "nbio/nbio_7_0_sh_mask.h" 4862306a36Sopenharmony_ci#include "nbio/nbio_7_0_smn.h" 4962306a36Sopenharmony_ci#include "mp/mp_9_0_offset.h" 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#include "soc15.h" 5262306a36Sopenharmony_ci#include "soc15_common.h" 5362306a36Sopenharmony_ci#include "gfx_v9_0.h" 5462306a36Sopenharmony_ci#include "gmc_v9_0.h" 5562306a36Sopenharmony_ci#include "gfxhub_v1_0.h" 5662306a36Sopenharmony_ci#include "mmhub_v1_0.h" 5762306a36Sopenharmony_ci#include "df_v1_7.h" 5862306a36Sopenharmony_ci#include "df_v3_6.h" 5962306a36Sopenharmony_ci#include "nbio_v6_1.h" 6062306a36Sopenharmony_ci#include "nbio_v7_0.h" 6162306a36Sopenharmony_ci#include "nbio_v7_4.h" 6262306a36Sopenharmony_ci#include "hdp_v4_0.h" 6362306a36Sopenharmony_ci#include "vega10_ih.h" 6462306a36Sopenharmony_ci#include "vega20_ih.h" 6562306a36Sopenharmony_ci#include "navi10_ih.h" 6662306a36Sopenharmony_ci#include "sdma_v4_0.h" 6762306a36Sopenharmony_ci#include "uvd_v7_0.h" 6862306a36Sopenharmony_ci#include "vce_v4_0.h" 6962306a36Sopenharmony_ci#include "vcn_v1_0.h" 7062306a36Sopenharmony_ci#include "vcn_v2_0.h" 7162306a36Sopenharmony_ci#include "jpeg_v2_0.h" 7262306a36Sopenharmony_ci#include "vcn_v2_5.h" 7362306a36Sopenharmony_ci#include "jpeg_v2_5.h" 7462306a36Sopenharmony_ci#include "smuio_v9_0.h" 7562306a36Sopenharmony_ci#include "smuio_v11_0.h" 7662306a36Sopenharmony_ci#include "smuio_v13_0.h" 7762306a36Sopenharmony_ci#include "amdgpu_vkms.h" 7862306a36Sopenharmony_ci#include "mxgpu_ai.h" 7962306a36Sopenharmony_ci#include "amdgpu_ras.h" 8062306a36Sopenharmony_ci#include "amdgpu_xgmi.h" 8162306a36Sopenharmony_ci#include <uapi/linux/kfd_ioctl.h> 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define mmMP0_MISC_CGTT_CTRL0 0x01b9 8462306a36Sopenharmony_ci#define mmMP0_MISC_CGTT_CTRL0_BASE_IDX 0 8562306a36Sopenharmony_ci#define mmMP0_MISC_LIGHT_SLEEP_CTRL 0x01ba 8662306a36Sopenharmony_ci#define mmMP0_MISC_LIGHT_SLEEP_CTRL_BASE_IDX 0 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic const struct amd_ip_funcs soc15_common_ip_funcs; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/* Vega, Raven, Arcturus */ 9162306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] = 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)}, 9462306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)}, 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vega_video_codecs_encode = 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci .codec_count = ARRAY_SIZE(vega_video_codecs_encode_array), 10062306a36Sopenharmony_ci .codec_array = vega_video_codecs_encode_array, 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci/* Vega */ 10462306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info vega_video_codecs_decode_array[] = 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, 10762306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, 10862306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, 10962306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, 11062306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, 11162306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vega_video_codecs_decode = 11562306a36Sopenharmony_ci{ 11662306a36Sopenharmony_ci .codec_count = ARRAY_SIZE(vega_video_codecs_decode_array), 11762306a36Sopenharmony_ci .codec_array = vega_video_codecs_decode_array, 11862306a36Sopenharmony_ci}; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* Raven */ 12162306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info rv_video_codecs_decode_array[] = 12262306a36Sopenharmony_ci{ 12362306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, 12462306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, 12562306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, 12662306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, 12762306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 186)}, 12862306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, 12962306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 4096, 4096, 0)}, 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic const struct amdgpu_video_codecs rv_video_codecs_decode = 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci .codec_count = ARRAY_SIZE(rv_video_codecs_decode_array), 13562306a36Sopenharmony_ci .codec_array = rv_video_codecs_decode_array, 13662306a36Sopenharmony_ci}; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* Renoir, Arcturus */ 13962306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info rn_video_codecs_decode_array[] = 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)}, 14262306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)}, 14362306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, 14462306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)}, 14562306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, 14662306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, 14762306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, 14862306a36Sopenharmony_ci}; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic const struct amdgpu_video_codecs rn_video_codecs_decode = 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci .codec_count = ARRAY_SIZE(rn_video_codecs_decode_array), 15362306a36Sopenharmony_ci .codec_array = rn_video_codecs_decode_array, 15462306a36Sopenharmony_ci}; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_cistatic const struct amdgpu_video_codec_info vcn_4_0_3_video_codecs_decode_array[] = { 15762306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)}, 15862306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)}, 15962306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)}, 16062306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)}, 16162306a36Sopenharmony_ci {codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)}, 16262306a36Sopenharmony_ci}; 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vcn_4_0_3_video_codecs_decode = { 16562306a36Sopenharmony_ci .codec_count = ARRAY_SIZE(vcn_4_0_3_video_codecs_decode_array), 16662306a36Sopenharmony_ci .codec_array = vcn_4_0_3_video_codecs_decode_array, 16762306a36Sopenharmony_ci}; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_cistatic const struct amdgpu_video_codecs vcn_4_0_3_video_codecs_encode = { 17062306a36Sopenharmony_ci .codec_count = 0, 17162306a36Sopenharmony_ci .codec_array = NULL, 17262306a36Sopenharmony_ci}; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic int soc15_query_video_codecs(struct amdgpu_device *adev, bool encode, 17562306a36Sopenharmony_ci const struct amdgpu_video_codecs **codecs) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci if (adev->ip_versions[VCE_HWIP][0]) { 17862306a36Sopenharmony_ci switch (adev->ip_versions[VCE_HWIP][0]) { 17962306a36Sopenharmony_ci case IP_VERSION(4, 0, 0): 18062306a36Sopenharmony_ci case IP_VERSION(4, 1, 0): 18162306a36Sopenharmony_ci if (encode) 18262306a36Sopenharmony_ci *codecs = &vega_video_codecs_encode; 18362306a36Sopenharmony_ci else 18462306a36Sopenharmony_ci *codecs = &vega_video_codecs_decode; 18562306a36Sopenharmony_ci return 0; 18662306a36Sopenharmony_ci default: 18762306a36Sopenharmony_ci return -EINVAL; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci } else { 19062306a36Sopenharmony_ci switch (adev->ip_versions[UVD_HWIP][0]) { 19162306a36Sopenharmony_ci case IP_VERSION(1, 0, 0): 19262306a36Sopenharmony_ci case IP_VERSION(1, 0, 1): 19362306a36Sopenharmony_ci if (encode) 19462306a36Sopenharmony_ci *codecs = &vega_video_codecs_encode; 19562306a36Sopenharmony_ci else 19662306a36Sopenharmony_ci *codecs = &rv_video_codecs_decode; 19762306a36Sopenharmony_ci return 0; 19862306a36Sopenharmony_ci case IP_VERSION(2, 5, 0): 19962306a36Sopenharmony_ci case IP_VERSION(2, 6, 0): 20062306a36Sopenharmony_ci case IP_VERSION(2, 2, 0): 20162306a36Sopenharmony_ci if (encode) 20262306a36Sopenharmony_ci *codecs = &vega_video_codecs_encode; 20362306a36Sopenharmony_ci else 20462306a36Sopenharmony_ci *codecs = &rn_video_codecs_decode; 20562306a36Sopenharmony_ci return 0; 20662306a36Sopenharmony_ci case IP_VERSION(4, 0, 3): 20762306a36Sopenharmony_ci if (encode) 20862306a36Sopenharmony_ci *codecs = &vcn_4_0_3_video_codecs_encode; 20962306a36Sopenharmony_ci else 21062306a36Sopenharmony_ci *codecs = &vcn_4_0_3_video_codecs_decode; 21162306a36Sopenharmony_ci return 0; 21262306a36Sopenharmony_ci default: 21362306a36Sopenharmony_ci return -EINVAL; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic u32 soc15_uvd_ctx_rreg(struct amdgpu_device *adev, u32 reg) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci unsigned long flags, address, data; 22162306a36Sopenharmony_ci u32 r; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX); 22462306a36Sopenharmony_ci data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags); 22762306a36Sopenharmony_ci WREG32(address, ((reg) & 0x1ff)); 22862306a36Sopenharmony_ci r = RREG32(data); 22962306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags); 23062306a36Sopenharmony_ci return r; 23162306a36Sopenharmony_ci} 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic void soc15_uvd_ctx_wreg(struct amdgpu_device *adev, u32 reg, u32 v) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci unsigned long flags, address, data; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci address = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_INDEX); 23862306a36Sopenharmony_ci data = SOC15_REG_OFFSET(UVD, 0, mmUVD_CTX_DATA); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci spin_lock_irqsave(&adev->uvd_ctx_idx_lock, flags); 24162306a36Sopenharmony_ci WREG32(address, ((reg) & 0x1ff)); 24262306a36Sopenharmony_ci WREG32(data, (v)); 24362306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->uvd_ctx_idx_lock, flags); 24462306a36Sopenharmony_ci} 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_cistatic u32 soc15_didt_rreg(struct amdgpu_device *adev, u32 reg) 24762306a36Sopenharmony_ci{ 24862306a36Sopenharmony_ci unsigned long flags, address, data; 24962306a36Sopenharmony_ci u32 r; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); 25262306a36Sopenharmony_ci data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci spin_lock_irqsave(&adev->didt_idx_lock, flags); 25562306a36Sopenharmony_ci WREG32(address, (reg)); 25662306a36Sopenharmony_ci r = RREG32(data); 25762306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->didt_idx_lock, flags); 25862306a36Sopenharmony_ci return r; 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic void soc15_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v) 26262306a36Sopenharmony_ci{ 26362306a36Sopenharmony_ci unsigned long flags, address, data; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX); 26662306a36Sopenharmony_ci data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA); 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci spin_lock_irqsave(&adev->didt_idx_lock, flags); 26962306a36Sopenharmony_ci WREG32(address, (reg)); 27062306a36Sopenharmony_ci WREG32(data, (v)); 27162306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->didt_idx_lock, flags); 27262306a36Sopenharmony_ci} 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cistatic u32 soc15_gc_cac_rreg(struct amdgpu_device *adev, u32 reg) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci unsigned long flags; 27762306a36Sopenharmony_ci u32 r; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); 28062306a36Sopenharmony_ci WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg)); 28162306a36Sopenharmony_ci r = RREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA); 28262306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); 28362306a36Sopenharmony_ci return r; 28462306a36Sopenharmony_ci} 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistatic void soc15_gc_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci unsigned long flags; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci spin_lock_irqsave(&adev->gc_cac_idx_lock, flags); 29162306a36Sopenharmony_ci WREG32_SOC15(GC, 0, mmGC_CAC_IND_INDEX, (reg)); 29262306a36Sopenharmony_ci WREG32_SOC15(GC, 0, mmGC_CAC_IND_DATA, (v)); 29362306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->gc_cac_idx_lock, flags); 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic u32 soc15_se_cac_rreg(struct amdgpu_device *adev, u32 reg) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci unsigned long flags; 29962306a36Sopenharmony_ci u32 r; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci spin_lock_irqsave(&adev->se_cac_idx_lock, flags); 30262306a36Sopenharmony_ci WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg)); 30362306a36Sopenharmony_ci r = RREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA); 30462306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags); 30562306a36Sopenharmony_ci return r; 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cistatic void soc15_se_cac_wreg(struct amdgpu_device *adev, u32 reg, u32 v) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci unsigned long flags; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci spin_lock_irqsave(&adev->se_cac_idx_lock, flags); 31362306a36Sopenharmony_ci WREG32_SOC15(GC, 0, mmSE_CAC_IND_INDEX, (reg)); 31462306a36Sopenharmony_ci WREG32_SOC15(GC, 0, mmSE_CAC_IND_DATA, (v)); 31562306a36Sopenharmony_ci spin_unlock_irqrestore(&adev->se_cac_idx_lock, flags); 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistatic u32 soc15_get_config_memsize(struct amdgpu_device *adev) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci return adev->nbio.funcs->get_memsize(adev); 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistatic u32 soc15_get_xclk(struct amdgpu_device *adev) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci u32 reference_clock = adev->clock.spll.reference_freq; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0) || 32862306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1) || 32962306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 6)) 33062306a36Sopenharmony_ci return 10000; 33162306a36Sopenharmony_ci if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 0) || 33262306a36Sopenharmony_ci adev->ip_versions[MP1_HWIP][0] == IP_VERSION(10, 0, 1)) 33362306a36Sopenharmony_ci return reference_clock / 4; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci return reference_clock; 33662306a36Sopenharmony_ci} 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_civoid soc15_grbm_select(struct amdgpu_device *adev, 34062306a36Sopenharmony_ci u32 me, u32 pipe, u32 queue, u32 vmid, int xcc_id) 34162306a36Sopenharmony_ci{ 34262306a36Sopenharmony_ci u32 grbm_gfx_cntl = 0; 34362306a36Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe); 34462306a36Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me); 34562306a36Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid); 34662306a36Sopenharmony_ci grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci WREG32_SOC15_RLC_SHADOW(GC, xcc_id, mmGRBM_GFX_CNTL, grbm_gfx_cntl); 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_cistatic bool soc15_read_disabled_bios(struct amdgpu_device *adev) 35262306a36Sopenharmony_ci{ 35362306a36Sopenharmony_ci /* todo */ 35462306a36Sopenharmony_ci return false; 35562306a36Sopenharmony_ci} 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_cistatic struct soc15_allowed_register_entry soc15_allowed_read_registers[] = { 35862306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)}, 35962306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)}, 36062306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE0)}, 36162306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE1)}, 36262306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE2)}, 36362306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE3)}, 36462306a36Sopenharmony_ci { SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_STATUS_REG)}, 36562306a36Sopenharmony_ci { SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_STATUS_REG)}, 36662306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STAT)}, 36762306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT1)}, 36862306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT2)}, 36962306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT3)}, 37062306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)}, 37162306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)}, 37262306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)}, 37362306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)}, 37462306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)}, 37562306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)}, 37662306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)}, 37762306a36Sopenharmony_ci { SOC15_REG_ENTRY(GC, 0, mmDB_DEBUG2)}, 37862306a36Sopenharmony_ci}; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic uint32_t soc15_read_indexed_register(struct amdgpu_device *adev, u32 se_num, 38162306a36Sopenharmony_ci u32 sh_num, u32 reg_offset) 38262306a36Sopenharmony_ci{ 38362306a36Sopenharmony_ci uint32_t val; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci mutex_lock(&adev->grbm_idx_mutex); 38662306a36Sopenharmony_ci if (se_num != 0xffffffff || sh_num != 0xffffffff) 38762306a36Sopenharmony_ci amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff, 0); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci val = RREG32(reg_offset); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci if (se_num != 0xffffffff || sh_num != 0xffffffff) 39262306a36Sopenharmony_ci amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, 0); 39362306a36Sopenharmony_ci mutex_unlock(&adev->grbm_idx_mutex); 39462306a36Sopenharmony_ci return val; 39562306a36Sopenharmony_ci} 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_cistatic uint32_t soc15_get_register_value(struct amdgpu_device *adev, 39862306a36Sopenharmony_ci bool indexed, u32 se_num, 39962306a36Sopenharmony_ci u32 sh_num, u32 reg_offset) 40062306a36Sopenharmony_ci{ 40162306a36Sopenharmony_ci if (indexed) { 40262306a36Sopenharmony_ci return soc15_read_indexed_register(adev, se_num, sh_num, reg_offset); 40362306a36Sopenharmony_ci } else { 40462306a36Sopenharmony_ci if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG)) 40562306a36Sopenharmony_ci return adev->gfx.config.gb_addr_config; 40662306a36Sopenharmony_ci else if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmDB_DEBUG2)) 40762306a36Sopenharmony_ci return adev->gfx.config.db_debug2; 40862306a36Sopenharmony_ci return RREG32(reg_offset); 40962306a36Sopenharmony_ci } 41062306a36Sopenharmony_ci} 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_cistatic int soc15_read_register(struct amdgpu_device *adev, u32 se_num, 41362306a36Sopenharmony_ci u32 sh_num, u32 reg_offset, u32 *value) 41462306a36Sopenharmony_ci{ 41562306a36Sopenharmony_ci uint32_t i; 41662306a36Sopenharmony_ci struct soc15_allowed_register_entry *en; 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci *value = 0; 41962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(soc15_allowed_read_registers); i++) { 42062306a36Sopenharmony_ci en = &soc15_allowed_read_registers[i]; 42162306a36Sopenharmony_ci if (!adev->reg_offset[en->hwip][en->inst]) 42262306a36Sopenharmony_ci continue; 42362306a36Sopenharmony_ci else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg] 42462306a36Sopenharmony_ci + en->reg_offset)) 42562306a36Sopenharmony_ci continue; 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci *value = soc15_get_register_value(adev, 42862306a36Sopenharmony_ci soc15_allowed_read_registers[i].grbm_indexed, 42962306a36Sopenharmony_ci se_num, sh_num, reg_offset); 43062306a36Sopenharmony_ci return 0; 43162306a36Sopenharmony_ci } 43262306a36Sopenharmony_ci return -EINVAL; 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci/** 43762306a36Sopenharmony_ci * soc15_program_register_sequence - program an array of registers. 43862306a36Sopenharmony_ci * 43962306a36Sopenharmony_ci * @adev: amdgpu_device pointer 44062306a36Sopenharmony_ci * @regs: pointer to the register array 44162306a36Sopenharmony_ci * @array_size: size of the register array 44262306a36Sopenharmony_ci * 44362306a36Sopenharmony_ci * Programs an array or registers with and and or masks. 44462306a36Sopenharmony_ci * This is a helper for setting golden registers. 44562306a36Sopenharmony_ci */ 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_civoid soc15_program_register_sequence(struct amdgpu_device *adev, 44862306a36Sopenharmony_ci const struct soc15_reg_golden *regs, 44962306a36Sopenharmony_ci const u32 array_size) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci const struct soc15_reg_golden *entry; 45262306a36Sopenharmony_ci u32 tmp, reg; 45362306a36Sopenharmony_ci int i; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci for (i = 0; i < array_size; ++i) { 45662306a36Sopenharmony_ci entry = ®s[i]; 45762306a36Sopenharmony_ci reg = adev->reg_offset[entry->hwip][entry->instance][entry->segment] + entry->reg; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci if (entry->and_mask == 0xffffffff) { 46062306a36Sopenharmony_ci tmp = entry->or_mask; 46162306a36Sopenharmony_ci } else { 46262306a36Sopenharmony_ci tmp = (entry->hwip == GC_HWIP) ? 46362306a36Sopenharmony_ci RREG32_SOC15_IP(GC, reg) : RREG32(reg); 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci tmp &= ~(entry->and_mask); 46662306a36Sopenharmony_ci tmp |= (entry->or_mask & entry->and_mask); 46762306a36Sopenharmony_ci } 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci if (reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_BINNER_EVENT_CNTL_3) || 47062306a36Sopenharmony_ci reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE) || 47162306a36Sopenharmony_ci reg == SOC15_REG_OFFSET(GC, 0, mmPA_SC_ENHANCE_1) || 47262306a36Sopenharmony_ci reg == SOC15_REG_OFFSET(GC, 0, mmSH_MEM_CONFIG)) 47362306a36Sopenharmony_ci WREG32_RLC(reg, tmp); 47462306a36Sopenharmony_ci else 47562306a36Sopenharmony_ci (entry->hwip == GC_HWIP) ? 47662306a36Sopenharmony_ci WREG32_SOC15_IP(GC, reg, tmp) : WREG32(reg, tmp); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci } 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci} 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_cistatic int soc15_asic_baco_reset(struct amdgpu_device *adev) 48362306a36Sopenharmony_ci{ 48462306a36Sopenharmony_ci struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 48562306a36Sopenharmony_ci int ret = 0; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci /* avoid NBIF got stuck when do RAS recovery in BACO reset */ 48862306a36Sopenharmony_ci if (ras && adev->ras_enabled) 48962306a36Sopenharmony_ci adev->nbio.funcs->enable_doorbell_interrupt(adev, false); 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci ret = amdgpu_dpm_baco_reset(adev); 49262306a36Sopenharmony_ci if (ret) 49362306a36Sopenharmony_ci return ret; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci /* re-enable doorbell interrupt after BACO exit */ 49662306a36Sopenharmony_ci if (ras && adev->ras_enabled) 49762306a36Sopenharmony_ci adev->nbio.funcs->enable_doorbell_interrupt(adev, true); 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci return 0; 50062306a36Sopenharmony_ci} 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_cistatic enum amd_reset_method 50362306a36Sopenharmony_cisoc15_asic_reset_method(struct amdgpu_device *adev) 50462306a36Sopenharmony_ci{ 50562306a36Sopenharmony_ci bool baco_reset = false; 50662306a36Sopenharmony_ci bool connected_to_cpu = false; 50762306a36Sopenharmony_ci struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci if (adev->gmc.xgmi.supported && adev->gmc.xgmi.connected_to_cpu) 51062306a36Sopenharmony_ci connected_to_cpu = true; 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 || 51362306a36Sopenharmony_ci amdgpu_reset_method == AMD_RESET_METHOD_MODE2 || 51462306a36Sopenharmony_ci amdgpu_reset_method == AMD_RESET_METHOD_BACO || 51562306a36Sopenharmony_ci amdgpu_reset_method == AMD_RESET_METHOD_PCI) { 51662306a36Sopenharmony_ci /* If connected to cpu, driver only support mode2 */ 51762306a36Sopenharmony_ci if (connected_to_cpu) 51862306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE2; 51962306a36Sopenharmony_ci return amdgpu_reset_method; 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci if (amdgpu_reset_method != -1) 52362306a36Sopenharmony_ci dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n", 52462306a36Sopenharmony_ci amdgpu_reset_method); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci switch (adev->ip_versions[MP1_HWIP][0]) { 52762306a36Sopenharmony_ci case IP_VERSION(10, 0, 0): 52862306a36Sopenharmony_ci case IP_VERSION(10, 0, 1): 52962306a36Sopenharmony_ci case IP_VERSION(12, 0, 0): 53062306a36Sopenharmony_ci case IP_VERSION(12, 0, 1): 53162306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE2; 53262306a36Sopenharmony_ci case IP_VERSION(9, 0, 0): 53362306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 53462306a36Sopenharmony_ci if (adev->asic_type == CHIP_VEGA20) { 53562306a36Sopenharmony_ci if (adev->psp.sos.fw_version >= 0x80067) 53662306a36Sopenharmony_ci baco_reset = amdgpu_dpm_is_baco_supported(adev); 53762306a36Sopenharmony_ci /* 53862306a36Sopenharmony_ci * 1. PMFW version > 0x284300: all cases use baco 53962306a36Sopenharmony_ci * 2. PMFW version <= 0x284300: only sGPU w/o RAS use baco 54062306a36Sopenharmony_ci */ 54162306a36Sopenharmony_ci if (ras && adev->ras_enabled && 54262306a36Sopenharmony_ci adev->pm.fw_version <= 0x283400) 54362306a36Sopenharmony_ci baco_reset = false; 54462306a36Sopenharmony_ci } else { 54562306a36Sopenharmony_ci baco_reset = amdgpu_dpm_is_baco_supported(adev); 54662306a36Sopenharmony_ci } 54762306a36Sopenharmony_ci break; 54862306a36Sopenharmony_ci case IP_VERSION(13, 0, 2): 54962306a36Sopenharmony_ci /* 55062306a36Sopenharmony_ci * 1.connected to cpu: driver issue mode2 reset 55162306a36Sopenharmony_ci * 2.discret gpu: driver issue mode1 reset 55262306a36Sopenharmony_ci */ 55362306a36Sopenharmony_ci if (connected_to_cpu) 55462306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE2; 55562306a36Sopenharmony_ci break; 55662306a36Sopenharmony_ci case IP_VERSION(13, 0, 6): 55762306a36Sopenharmony_ci /* Use gpu_recovery param to target a reset method. 55862306a36Sopenharmony_ci * Enable triggering of GPU reset only if specified 55962306a36Sopenharmony_ci * by module parameter. 56062306a36Sopenharmony_ci */ 56162306a36Sopenharmony_ci if (amdgpu_gpu_recovery == 4 || amdgpu_gpu_recovery == 5) 56262306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE2; 56362306a36Sopenharmony_ci else if (!(adev->flags & AMD_IS_APU)) 56462306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE1; 56562306a36Sopenharmony_ci else 56662306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE2; 56762306a36Sopenharmony_ci default: 56862306a36Sopenharmony_ci break; 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci if (baco_reset) 57262306a36Sopenharmony_ci return AMD_RESET_METHOD_BACO; 57362306a36Sopenharmony_ci else 57462306a36Sopenharmony_ci return AMD_RESET_METHOD_MODE1; 57562306a36Sopenharmony_ci} 57662306a36Sopenharmony_ci 57762306a36Sopenharmony_cistatic bool soc15_need_reset_on_resume(struct amdgpu_device *adev) 57862306a36Sopenharmony_ci{ 57962306a36Sopenharmony_ci u32 sol_reg; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci /* Will reset for the following suspend abort cases. 58462306a36Sopenharmony_ci * 1) Only reset limit on APU side, dGPU hasn't checked yet. 58562306a36Sopenharmony_ci * 2) S3 suspend abort and TOS already launched. 58662306a36Sopenharmony_ci */ 58762306a36Sopenharmony_ci if (adev->flags & AMD_IS_APU && adev->in_s3 && 58862306a36Sopenharmony_ci !adev->suspend_complete && 58962306a36Sopenharmony_ci sol_reg) 59062306a36Sopenharmony_ci return true; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci return false; 59362306a36Sopenharmony_ci} 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_cistatic int soc15_asic_reset(struct amdgpu_device *adev) 59662306a36Sopenharmony_ci{ 59762306a36Sopenharmony_ci /* original raven doesn't have full asic reset */ 59862306a36Sopenharmony_ci /* On the latest Raven, the GPU reset can be performed 59962306a36Sopenharmony_ci * successfully. So now, temporarily enable it for the 60062306a36Sopenharmony_ci * S3 suspend abort case. 60162306a36Sopenharmony_ci */ 60262306a36Sopenharmony_ci if (((adev->apu_flags & AMD_APU_IS_RAVEN) || 60362306a36Sopenharmony_ci (adev->apu_flags & AMD_APU_IS_RAVEN2)) && 60462306a36Sopenharmony_ci !soc15_need_reset_on_resume(adev)) 60562306a36Sopenharmony_ci return 0; 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci switch (soc15_asic_reset_method(adev)) { 60862306a36Sopenharmony_ci case AMD_RESET_METHOD_PCI: 60962306a36Sopenharmony_ci dev_info(adev->dev, "PCI reset\n"); 61062306a36Sopenharmony_ci return amdgpu_device_pci_reset(adev); 61162306a36Sopenharmony_ci case AMD_RESET_METHOD_BACO: 61262306a36Sopenharmony_ci dev_info(adev->dev, "BACO reset\n"); 61362306a36Sopenharmony_ci return soc15_asic_baco_reset(adev); 61462306a36Sopenharmony_ci case AMD_RESET_METHOD_MODE2: 61562306a36Sopenharmony_ci dev_info(adev->dev, "MODE2 reset\n"); 61662306a36Sopenharmony_ci return amdgpu_dpm_mode2_reset(adev); 61762306a36Sopenharmony_ci default: 61862306a36Sopenharmony_ci dev_info(adev->dev, "MODE1 reset\n"); 61962306a36Sopenharmony_ci return amdgpu_device_mode1_reset(adev); 62062306a36Sopenharmony_ci } 62162306a36Sopenharmony_ci} 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_cistatic bool soc15_supports_baco(struct amdgpu_device *adev) 62462306a36Sopenharmony_ci{ 62562306a36Sopenharmony_ci switch (adev->ip_versions[MP1_HWIP][0]) { 62662306a36Sopenharmony_ci case IP_VERSION(9, 0, 0): 62762306a36Sopenharmony_ci case IP_VERSION(11, 0, 2): 62862306a36Sopenharmony_ci if (adev->asic_type == CHIP_VEGA20) { 62962306a36Sopenharmony_ci if (adev->psp.sos.fw_version >= 0x80067) 63062306a36Sopenharmony_ci return amdgpu_dpm_is_baco_supported(adev); 63162306a36Sopenharmony_ci return false; 63262306a36Sopenharmony_ci } else { 63362306a36Sopenharmony_ci return amdgpu_dpm_is_baco_supported(adev); 63462306a36Sopenharmony_ci } 63562306a36Sopenharmony_ci break; 63662306a36Sopenharmony_ci default: 63762306a36Sopenharmony_ci return false; 63862306a36Sopenharmony_ci } 63962306a36Sopenharmony_ci} 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci/*static int soc15_set_uvd_clock(struct amdgpu_device *adev, u32 clock, 64262306a36Sopenharmony_ci u32 cntl_reg, u32 status_reg) 64362306a36Sopenharmony_ci{ 64462306a36Sopenharmony_ci return 0; 64562306a36Sopenharmony_ci}*/ 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_cistatic int soc15_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk) 64862306a36Sopenharmony_ci{ 64962306a36Sopenharmony_ci /*int r; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci r = soc15_set_uvd_clock(adev, vclk, ixCG_VCLK_CNTL, ixCG_VCLK_STATUS); 65262306a36Sopenharmony_ci if (r) 65362306a36Sopenharmony_ci return r; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci r = soc15_set_uvd_clock(adev, dclk, ixCG_DCLK_CNTL, ixCG_DCLK_STATUS); 65662306a36Sopenharmony_ci */ 65762306a36Sopenharmony_ci return 0; 65862306a36Sopenharmony_ci} 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_cistatic int soc15_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk) 66162306a36Sopenharmony_ci{ 66262306a36Sopenharmony_ci /* todo */ 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci return 0; 66562306a36Sopenharmony_ci} 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_cistatic void soc15_program_aspm(struct amdgpu_device *adev) 66862306a36Sopenharmony_ci{ 66962306a36Sopenharmony_ci if (!amdgpu_device_should_use_aspm(adev)) 67062306a36Sopenharmony_ci return; 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci if (!(adev->flags & AMD_IS_APU) && 67362306a36Sopenharmony_ci (adev->nbio.funcs->program_aspm)) 67462306a36Sopenharmony_ci adev->nbio.funcs->program_aspm(adev); 67562306a36Sopenharmony_ci} 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ciconst struct amdgpu_ip_block_version vega10_common_ip_block = 67862306a36Sopenharmony_ci{ 67962306a36Sopenharmony_ci .type = AMD_IP_BLOCK_TYPE_COMMON, 68062306a36Sopenharmony_ci .major = 2, 68162306a36Sopenharmony_ci .minor = 0, 68262306a36Sopenharmony_ci .rev = 0, 68362306a36Sopenharmony_ci .funcs = &soc15_common_ip_funcs, 68462306a36Sopenharmony_ci}; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_cistatic void soc15_reg_base_init(struct amdgpu_device *adev) 68762306a36Sopenharmony_ci{ 68862306a36Sopenharmony_ci /* Set IP register base before any HW register access */ 68962306a36Sopenharmony_ci switch (adev->asic_type) { 69062306a36Sopenharmony_ci case CHIP_VEGA10: 69162306a36Sopenharmony_ci case CHIP_VEGA12: 69262306a36Sopenharmony_ci case CHIP_RAVEN: 69362306a36Sopenharmony_ci case CHIP_RENOIR: 69462306a36Sopenharmony_ci vega10_reg_base_init(adev); 69562306a36Sopenharmony_ci break; 69662306a36Sopenharmony_ci case CHIP_VEGA20: 69762306a36Sopenharmony_ci vega20_reg_base_init(adev); 69862306a36Sopenharmony_ci break; 69962306a36Sopenharmony_ci case CHIP_ARCTURUS: 70062306a36Sopenharmony_ci arct_reg_base_init(adev); 70162306a36Sopenharmony_ci break; 70262306a36Sopenharmony_ci case CHIP_ALDEBARAN: 70362306a36Sopenharmony_ci aldebaran_reg_base_init(adev); 70462306a36Sopenharmony_ci break; 70562306a36Sopenharmony_ci default: 70662306a36Sopenharmony_ci DRM_ERROR("Unsupported asic type: %d!\n", adev->asic_type); 70762306a36Sopenharmony_ci break; 70862306a36Sopenharmony_ci } 70962306a36Sopenharmony_ci} 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_civoid soc15_set_virt_ops(struct amdgpu_device *adev) 71262306a36Sopenharmony_ci{ 71362306a36Sopenharmony_ci adev->virt.ops = &xgpu_ai_virt_ops; 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci /* init soc15 reg base early enough so we can 71662306a36Sopenharmony_ci * request request full access for sriov before 71762306a36Sopenharmony_ci * set_ip_blocks. */ 71862306a36Sopenharmony_ci soc15_reg_base_init(adev); 71962306a36Sopenharmony_ci} 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_cistatic bool soc15_need_full_reset(struct amdgpu_device *adev) 72262306a36Sopenharmony_ci{ 72362306a36Sopenharmony_ci /* change this when we implement soft reset */ 72462306a36Sopenharmony_ci return true; 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_cistatic void soc15_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, 72862306a36Sopenharmony_ci uint64_t *count1) 72962306a36Sopenharmony_ci{ 73062306a36Sopenharmony_ci uint32_t perfctr = 0; 73162306a36Sopenharmony_ci uint64_t cnt0_of, cnt1_of; 73262306a36Sopenharmony_ci int tmp; 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci /* This reports 0 on APUs, so return to avoid writing/reading registers 73562306a36Sopenharmony_ci * that may or may not be different from their GPU counterparts 73662306a36Sopenharmony_ci */ 73762306a36Sopenharmony_ci if (adev->flags & AMD_IS_APU) 73862306a36Sopenharmony_ci return; 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci /* Set the 2 events that we wish to watch, defined above */ 74162306a36Sopenharmony_ci /* Reg 40 is # received msgs */ 74262306a36Sopenharmony_ci /* Reg 104 is # of posted requests sent */ 74362306a36Sopenharmony_ci perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT0_SEL, 40); 74462306a36Sopenharmony_ci perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK, EVENT1_SEL, 104); 74562306a36Sopenharmony_ci 74662306a36Sopenharmony_ci /* Write to enable desired perf counters */ 74762306a36Sopenharmony_ci WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK, perfctr); 74862306a36Sopenharmony_ci /* Zero out and enable the perf counters 74962306a36Sopenharmony_ci * Write 0x5: 75062306a36Sopenharmony_ci * Bit 0 = Start all counters(1) 75162306a36Sopenharmony_ci * Bit 2 = Global counter reset enable(1) 75262306a36Sopenharmony_ci */ 75362306a36Sopenharmony_ci WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005); 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci msleep(1000); 75662306a36Sopenharmony_ci 75762306a36Sopenharmony_ci /* Load the shadow and disable the perf counters 75862306a36Sopenharmony_ci * Write 0x2: 75962306a36Sopenharmony_ci * Bit 0 = Stop counters(0) 76062306a36Sopenharmony_ci * Bit 1 = Load the shadow counters(1) 76162306a36Sopenharmony_ci */ 76262306a36Sopenharmony_ci WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002); 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci /* Read register values to get any >32bit overflow */ 76562306a36Sopenharmony_ci tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK); 76662306a36Sopenharmony_ci cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER0_UPPER); 76762306a36Sopenharmony_ci cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK, COUNTER1_UPPER); 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci /* Get the values and add the overflow */ 77062306a36Sopenharmony_ci *count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK) | (cnt0_of << 32); 77162306a36Sopenharmony_ci *count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK) | (cnt1_of << 32); 77262306a36Sopenharmony_ci} 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_cistatic void vega20_get_pcie_usage(struct amdgpu_device *adev, uint64_t *count0, 77562306a36Sopenharmony_ci uint64_t *count1) 77662306a36Sopenharmony_ci{ 77762306a36Sopenharmony_ci uint32_t perfctr = 0; 77862306a36Sopenharmony_ci uint64_t cnt0_of, cnt1_of; 77962306a36Sopenharmony_ci int tmp; 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci /* This reports 0 on APUs, so return to avoid writing/reading registers 78262306a36Sopenharmony_ci * that may or may not be different from their GPU counterparts 78362306a36Sopenharmony_ci */ 78462306a36Sopenharmony_ci if (adev->flags & AMD_IS_APU) 78562306a36Sopenharmony_ci return; 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci /* Set the 2 events that we wish to watch, defined above */ 78862306a36Sopenharmony_ci /* Reg 40 is # received msgs */ 78962306a36Sopenharmony_ci /* Reg 108 is # of posted requests sent on VG20 */ 79062306a36Sopenharmony_ci perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3, 79162306a36Sopenharmony_ci EVENT0_SEL, 40); 79262306a36Sopenharmony_ci perfctr = REG_SET_FIELD(perfctr, PCIE_PERF_CNTL_TXCLK3, 79362306a36Sopenharmony_ci EVENT1_SEL, 108); 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_ci /* Write to enable desired perf counters */ 79662306a36Sopenharmony_ci WREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3, perfctr); 79762306a36Sopenharmony_ci /* Zero out and enable the perf counters 79862306a36Sopenharmony_ci * Write 0x5: 79962306a36Sopenharmony_ci * Bit 0 = Start all counters(1) 80062306a36Sopenharmony_ci * Bit 2 = Global counter reset enable(1) 80162306a36Sopenharmony_ci */ 80262306a36Sopenharmony_ci WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000005); 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci msleep(1000); 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci /* Load the shadow and disable the perf counters 80762306a36Sopenharmony_ci * Write 0x2: 80862306a36Sopenharmony_ci * Bit 0 = Stop counters(0) 80962306a36Sopenharmony_ci * Bit 1 = Load the shadow counters(1) 81062306a36Sopenharmony_ci */ 81162306a36Sopenharmony_ci WREG32_PCIE(smnPCIE_PERF_COUNT_CNTL, 0x00000002); 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci /* Read register values to get any >32bit overflow */ 81462306a36Sopenharmony_ci tmp = RREG32_PCIE(smnPCIE_PERF_CNTL_TXCLK3); 81562306a36Sopenharmony_ci cnt0_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER0_UPPER); 81662306a36Sopenharmony_ci cnt1_of = REG_GET_FIELD(tmp, PCIE_PERF_CNTL_TXCLK3, COUNTER1_UPPER); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci /* Get the values and add the overflow */ 81962306a36Sopenharmony_ci *count0 = RREG32_PCIE(smnPCIE_PERF_COUNT0_TXCLK3) | (cnt0_of << 32); 82062306a36Sopenharmony_ci *count1 = RREG32_PCIE(smnPCIE_PERF_COUNT1_TXCLK3) | (cnt1_of << 32); 82162306a36Sopenharmony_ci} 82262306a36Sopenharmony_ci 82362306a36Sopenharmony_cistatic bool soc15_need_reset_on_init(struct amdgpu_device *adev) 82462306a36Sopenharmony_ci{ 82562306a36Sopenharmony_ci u32 sol_reg; 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci /* CP hangs in IGT reloading test on RN, reset to WA */ 82862306a36Sopenharmony_ci if (adev->asic_type == CHIP_RENOIR) 82962306a36Sopenharmony_ci return true; 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_ci /* Just return false for soc15 GPUs. Reset does not seem to 83262306a36Sopenharmony_ci * be necessary. 83362306a36Sopenharmony_ci */ 83462306a36Sopenharmony_ci if (!amdgpu_passthrough(adev)) 83562306a36Sopenharmony_ci return false; 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci if (adev->flags & AMD_IS_APU) 83862306a36Sopenharmony_ci return false; 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci /* Check sOS sign of life register to confirm sys driver and sOS 84162306a36Sopenharmony_ci * are already been loaded. 84262306a36Sopenharmony_ci */ 84362306a36Sopenharmony_ci sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81); 84462306a36Sopenharmony_ci if (sol_reg) 84562306a36Sopenharmony_ci return true; 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ci return false; 84862306a36Sopenharmony_ci} 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_cistatic uint64_t soc15_get_pcie_replay_count(struct amdgpu_device *adev) 85162306a36Sopenharmony_ci{ 85262306a36Sopenharmony_ci uint64_t nak_r, nak_g; 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci /* Get the number of NAKs received and generated */ 85562306a36Sopenharmony_ci nak_r = RREG32_PCIE(smnPCIE_RX_NUM_NAK); 85662306a36Sopenharmony_ci nak_g = RREG32_PCIE(smnPCIE_RX_NUM_NAK_GENERATED); 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci /* Add the total number of NAKs, i.e the number of replays */ 85962306a36Sopenharmony_ci return (nak_r + nak_g); 86062306a36Sopenharmony_ci} 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_cistatic void soc15_pre_asic_init(struct amdgpu_device *adev) 86362306a36Sopenharmony_ci{ 86462306a36Sopenharmony_ci gmc_v9_0_restore_registers(adev); 86562306a36Sopenharmony_ci} 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_cistatic const struct amdgpu_asic_funcs soc15_asic_funcs = 86862306a36Sopenharmony_ci{ 86962306a36Sopenharmony_ci .read_disabled_bios = &soc15_read_disabled_bios, 87062306a36Sopenharmony_ci .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom, 87162306a36Sopenharmony_ci .read_register = &soc15_read_register, 87262306a36Sopenharmony_ci .reset = &soc15_asic_reset, 87362306a36Sopenharmony_ci .reset_method = &soc15_asic_reset_method, 87462306a36Sopenharmony_ci .get_xclk = &soc15_get_xclk, 87562306a36Sopenharmony_ci .set_uvd_clocks = &soc15_set_uvd_clocks, 87662306a36Sopenharmony_ci .set_vce_clocks = &soc15_set_vce_clocks, 87762306a36Sopenharmony_ci .get_config_memsize = &soc15_get_config_memsize, 87862306a36Sopenharmony_ci .need_full_reset = &soc15_need_full_reset, 87962306a36Sopenharmony_ci .init_doorbell_index = &vega10_doorbell_index_init, 88062306a36Sopenharmony_ci .get_pcie_usage = &soc15_get_pcie_usage, 88162306a36Sopenharmony_ci .need_reset_on_init = &soc15_need_reset_on_init, 88262306a36Sopenharmony_ci .get_pcie_replay_count = &soc15_get_pcie_replay_count, 88362306a36Sopenharmony_ci .supports_baco = &soc15_supports_baco, 88462306a36Sopenharmony_ci .pre_asic_init = &soc15_pre_asic_init, 88562306a36Sopenharmony_ci .query_video_codecs = &soc15_query_video_codecs, 88662306a36Sopenharmony_ci}; 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_cistatic const struct amdgpu_asic_funcs vega20_asic_funcs = 88962306a36Sopenharmony_ci{ 89062306a36Sopenharmony_ci .read_disabled_bios = &soc15_read_disabled_bios, 89162306a36Sopenharmony_ci .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom, 89262306a36Sopenharmony_ci .read_register = &soc15_read_register, 89362306a36Sopenharmony_ci .reset = &soc15_asic_reset, 89462306a36Sopenharmony_ci .reset_method = &soc15_asic_reset_method, 89562306a36Sopenharmony_ci .get_xclk = &soc15_get_xclk, 89662306a36Sopenharmony_ci .set_uvd_clocks = &soc15_set_uvd_clocks, 89762306a36Sopenharmony_ci .set_vce_clocks = &soc15_set_vce_clocks, 89862306a36Sopenharmony_ci .get_config_memsize = &soc15_get_config_memsize, 89962306a36Sopenharmony_ci .need_full_reset = &soc15_need_full_reset, 90062306a36Sopenharmony_ci .init_doorbell_index = &vega20_doorbell_index_init, 90162306a36Sopenharmony_ci .get_pcie_usage = &vega20_get_pcie_usage, 90262306a36Sopenharmony_ci .need_reset_on_init = &soc15_need_reset_on_init, 90362306a36Sopenharmony_ci .get_pcie_replay_count = &soc15_get_pcie_replay_count, 90462306a36Sopenharmony_ci .supports_baco = &soc15_supports_baco, 90562306a36Sopenharmony_ci .pre_asic_init = &soc15_pre_asic_init, 90662306a36Sopenharmony_ci .query_video_codecs = &soc15_query_video_codecs, 90762306a36Sopenharmony_ci}; 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_cistatic const struct amdgpu_asic_funcs aqua_vanjaram_asic_funcs = 91062306a36Sopenharmony_ci{ 91162306a36Sopenharmony_ci .read_disabled_bios = &soc15_read_disabled_bios, 91262306a36Sopenharmony_ci .read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom, 91362306a36Sopenharmony_ci .read_register = &soc15_read_register, 91462306a36Sopenharmony_ci .reset = &soc15_asic_reset, 91562306a36Sopenharmony_ci .reset_method = &soc15_asic_reset_method, 91662306a36Sopenharmony_ci .get_xclk = &soc15_get_xclk, 91762306a36Sopenharmony_ci .set_uvd_clocks = &soc15_set_uvd_clocks, 91862306a36Sopenharmony_ci .set_vce_clocks = &soc15_set_vce_clocks, 91962306a36Sopenharmony_ci .get_config_memsize = &soc15_get_config_memsize, 92062306a36Sopenharmony_ci .need_full_reset = &soc15_need_full_reset, 92162306a36Sopenharmony_ci .init_doorbell_index = &aqua_vanjaram_doorbell_index_init, 92262306a36Sopenharmony_ci .get_pcie_usage = &amdgpu_nbio_get_pcie_usage, 92362306a36Sopenharmony_ci .need_reset_on_init = &soc15_need_reset_on_init, 92462306a36Sopenharmony_ci .get_pcie_replay_count = &amdgpu_nbio_get_pcie_replay_count, 92562306a36Sopenharmony_ci .supports_baco = &soc15_supports_baco, 92662306a36Sopenharmony_ci .pre_asic_init = &soc15_pre_asic_init, 92762306a36Sopenharmony_ci .query_video_codecs = &soc15_query_video_codecs, 92862306a36Sopenharmony_ci .encode_ext_smn_addressing = &aqua_vanjaram_encode_ext_smn_addressing, 92962306a36Sopenharmony_ci}; 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_cistatic int soc15_common_early_init(void *handle) 93262306a36Sopenharmony_ci{ 93362306a36Sopenharmony_ci#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE) 93462306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) { 93762306a36Sopenharmony_ci adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET; 93862306a36Sopenharmony_ci adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET; 93962306a36Sopenharmony_ci } 94062306a36Sopenharmony_ci adev->smc_rreg = NULL; 94162306a36Sopenharmony_ci adev->smc_wreg = NULL; 94262306a36Sopenharmony_ci adev->pcie_rreg = &amdgpu_device_indirect_rreg; 94362306a36Sopenharmony_ci adev->pcie_wreg = &amdgpu_device_indirect_wreg; 94462306a36Sopenharmony_ci adev->pcie_rreg_ext = &amdgpu_device_indirect_rreg_ext; 94562306a36Sopenharmony_ci adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext; 94662306a36Sopenharmony_ci adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64; 94762306a36Sopenharmony_ci adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64; 94862306a36Sopenharmony_ci adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg; 94962306a36Sopenharmony_ci adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg; 95062306a36Sopenharmony_ci adev->didt_rreg = &soc15_didt_rreg; 95162306a36Sopenharmony_ci adev->didt_wreg = &soc15_didt_wreg; 95262306a36Sopenharmony_ci adev->gc_cac_rreg = &soc15_gc_cac_rreg; 95362306a36Sopenharmony_ci adev->gc_cac_wreg = &soc15_gc_cac_wreg; 95462306a36Sopenharmony_ci adev->se_cac_rreg = &soc15_se_cac_rreg; 95562306a36Sopenharmony_ci adev->se_cac_wreg = &soc15_se_cac_wreg; 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_ci adev->rev_id = amdgpu_device_get_rev_id(adev); 95862306a36Sopenharmony_ci adev->external_rev_id = 0xFF; 95962306a36Sopenharmony_ci /* TODO: split the GC and PG flags based on the relevant IP version for which 96062306a36Sopenharmony_ci * they are relevant. 96162306a36Sopenharmony_ci */ 96262306a36Sopenharmony_ci switch (adev->ip_versions[GC_HWIP][0]) { 96362306a36Sopenharmony_ci case IP_VERSION(9, 0, 1): 96462306a36Sopenharmony_ci adev->asic_funcs = &soc15_asic_funcs; 96562306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 96662306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 96762306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_RLC_LS | 96862306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 96962306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 97062306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 97162306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 97262306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 97362306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_MGCG | 97462306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 97562306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 97662306a36Sopenharmony_ci AMD_CG_SUPPORT_DRM_MGCG | 97762306a36Sopenharmony_ci AMD_CG_SUPPORT_DRM_LS | 97862306a36Sopenharmony_ci AMD_CG_SUPPORT_ROM_MGCG | 97962306a36Sopenharmony_ci AMD_CG_SUPPORT_DF_MGCG | 98062306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 98162306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 98262306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 98362306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS; 98462306a36Sopenharmony_ci adev->pg_flags = 0; 98562306a36Sopenharmony_ci adev->external_rev_id = 0x1; 98662306a36Sopenharmony_ci break; 98762306a36Sopenharmony_ci case IP_VERSION(9, 2, 1): 98862306a36Sopenharmony_ci adev->asic_funcs = &soc15_asic_funcs; 98962306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 99062306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 99162306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 99262306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 99362306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 99462306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 99562306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 99662306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 99762306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 99862306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 99962306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 100062306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_MGCG | 100162306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 100262306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 100362306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 100462306a36Sopenharmony_ci AMD_CG_SUPPORT_ROM_MGCG | 100562306a36Sopenharmony_ci AMD_CG_SUPPORT_VCE_MGCG | 100662306a36Sopenharmony_ci AMD_CG_SUPPORT_UVD_MGCG; 100762306a36Sopenharmony_ci adev->pg_flags = 0; 100862306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x14; 100962306a36Sopenharmony_ci break; 101062306a36Sopenharmony_ci case IP_VERSION(9, 4, 0): 101162306a36Sopenharmony_ci adev->asic_funcs = &vega20_asic_funcs; 101262306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 101362306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 101462306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 101562306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 101662306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 101762306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 101862306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 101962306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 102062306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 102162306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 102262306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 102362306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_MGCG | 102462306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 102562306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 102662306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 102762306a36Sopenharmony_ci AMD_CG_SUPPORT_ROM_MGCG | 102862306a36Sopenharmony_ci AMD_CG_SUPPORT_VCE_MGCG | 102962306a36Sopenharmony_ci AMD_CG_SUPPORT_UVD_MGCG; 103062306a36Sopenharmony_ci adev->pg_flags = 0; 103162306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x28; 103262306a36Sopenharmony_ci break; 103362306a36Sopenharmony_ci case IP_VERSION(9, 1, 0): 103462306a36Sopenharmony_ci case IP_VERSION(9, 2, 2): 103562306a36Sopenharmony_ci adev->asic_funcs = &soc15_asic_funcs; 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci if (adev->rev_id >= 0x8) 103862306a36Sopenharmony_ci adev->apu_flags |= AMD_APU_IS_RAVEN2; 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci if (adev->apu_flags & AMD_APU_IS_RAVEN2) 104162306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x79; 104262306a36Sopenharmony_ci else if (adev->apu_flags & AMD_APU_IS_PICASSO) 104362306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x41; 104462306a36Sopenharmony_ci else if (adev->rev_id == 1) 104562306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x20; 104662306a36Sopenharmony_ci else 104762306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x01; 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_ci if (adev->apu_flags & AMD_APU_IS_RAVEN2) { 105062306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 105162306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 105262306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 105362306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 105462306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 105562306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 105662306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 105762306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 105862306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 105962306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 106062306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 106162306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 106262306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 106362306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG; 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; 106662306a36Sopenharmony_ci } else if (adev->apu_flags & AMD_APU_IS_PICASSO) { 106762306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 106862306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 106962306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 107062306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 107162306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 107262306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 107362306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 107462306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 107562306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 107662306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 107762306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 107862306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 107962306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG; 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci /* 108262306a36Sopenharmony_ci * MMHUB PG needs to be disabled for Picasso for 108362306a36Sopenharmony_ci * stability reasons. 108462306a36Sopenharmony_ci */ 108562306a36Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_SDMA | 108662306a36Sopenharmony_ci AMD_PG_SUPPORT_VCN; 108762306a36Sopenharmony_ci } else { 108862306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 108962306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 109062306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_RLC_LS | 109162306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 109262306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 109362306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 109462306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 109562306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_MGCG | 109662306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 109762306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 109862306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 109962306a36Sopenharmony_ci AMD_CG_SUPPORT_DRM_MGCG | 110062306a36Sopenharmony_ci AMD_CG_SUPPORT_DRM_LS | 110162306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 110262306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 110362306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 110462306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 110562306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG; 110662306a36Sopenharmony_ci 110762306a36Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_VCN; 110862306a36Sopenharmony_ci } 110962306a36Sopenharmony_ci break; 111062306a36Sopenharmony_ci case IP_VERSION(9, 4, 1): 111162306a36Sopenharmony_ci adev->asic_funcs = &vega20_asic_funcs; 111262306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 111362306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 111462306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 111562306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 111662306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 111762306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_MGCG | 111862306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 111962306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 112062306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 112162306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 112262306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 112362306a36Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 112462306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 112562306a36Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG; 112662306a36Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG; 112762306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x32; 112862306a36Sopenharmony_ci break; 112962306a36Sopenharmony_ci case IP_VERSION(9, 3, 0): 113062306a36Sopenharmony_ci adev->asic_funcs = &soc15_asic_funcs; 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci if (adev->apu_flags & AMD_APU_IS_RENOIR) 113362306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x91; 113462306a36Sopenharmony_ci else 113562306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0xa1; 113662306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 113762306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 113862306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGCG | 113962306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_3D_CGLS | 114062306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGCG | 114162306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | 114262306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 114362306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_MGCG | 114462306a36Sopenharmony_ci AMD_CG_SUPPORT_MC_LS | 114562306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 114662306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 114762306a36Sopenharmony_ci AMD_CG_SUPPORT_BIF_LS | 114862306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 114962306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | 115062306a36Sopenharmony_ci AMD_CG_SUPPORT_JPEG_MGCG | 115162306a36Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 115262306a36Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_LS | 115362306a36Sopenharmony_ci AMD_CG_SUPPORT_ATHUB_MGCG | 115462306a36Sopenharmony_ci AMD_CG_SUPPORT_DF_MGCG; 115562306a36Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_SDMA | 115662306a36Sopenharmony_ci AMD_PG_SUPPORT_VCN | 115762306a36Sopenharmony_ci AMD_PG_SUPPORT_JPEG | 115862306a36Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG; 115962306a36Sopenharmony_ci break; 116062306a36Sopenharmony_ci case IP_VERSION(9, 4, 2): 116162306a36Sopenharmony_ci adev->asic_funcs = &vega20_asic_funcs; 116262306a36Sopenharmony_ci adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | 116362306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGLS | 116462306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CP_LS | 116562306a36Sopenharmony_ci AMD_CG_SUPPORT_HDP_LS | 116662306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_MGCG | 116762306a36Sopenharmony_ci AMD_CG_SUPPORT_SDMA_LS | 116862306a36Sopenharmony_ci AMD_CG_SUPPORT_IH_CG | 116962306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG; 117062306a36Sopenharmony_ci adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG; 117162306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x3c; 117262306a36Sopenharmony_ci break; 117362306a36Sopenharmony_ci case IP_VERSION(9, 4, 3): 117462306a36Sopenharmony_ci adev->asic_funcs = &aqua_vanjaram_asic_funcs; 117562306a36Sopenharmony_ci adev->cg_flags = 117662306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_CGCG | 117762306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_CGLS | AMD_CG_SUPPORT_SDMA_MGCG | 117862306a36Sopenharmony_ci AMD_CG_SUPPORT_GFX_FGCG | AMD_CG_SUPPORT_REPEATER_FGCG | 117962306a36Sopenharmony_ci AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_JPEG_MGCG | 118062306a36Sopenharmony_ci AMD_CG_SUPPORT_IH_CG; 118162306a36Sopenharmony_ci adev->pg_flags = 118262306a36Sopenharmony_ci AMD_PG_SUPPORT_VCN | 118362306a36Sopenharmony_ci AMD_PG_SUPPORT_VCN_DPG | 118462306a36Sopenharmony_ci AMD_PG_SUPPORT_JPEG; 118562306a36Sopenharmony_ci adev->external_rev_id = adev->rev_id + 0x46; 118662306a36Sopenharmony_ci /* GC 9.4.3 uses MMIO register region hole at a different offset */ 118762306a36Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) { 118862306a36Sopenharmony_ci adev->rmmio_remap.reg_offset = 0x1A000; 118962306a36Sopenharmony_ci adev->rmmio_remap.bus_addr = adev->rmmio_base + 0x1A000; 119062306a36Sopenharmony_ci } 119162306a36Sopenharmony_ci break; 119262306a36Sopenharmony_ci default: 119362306a36Sopenharmony_ci /* FIXME: not supported yet */ 119462306a36Sopenharmony_ci return -EINVAL; 119562306a36Sopenharmony_ci } 119662306a36Sopenharmony_ci 119762306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) { 119862306a36Sopenharmony_ci amdgpu_virt_init_setting(adev); 119962306a36Sopenharmony_ci xgpu_ai_mailbox_set_irq_funcs(adev); 120062306a36Sopenharmony_ci } 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci return 0; 120362306a36Sopenharmony_ci} 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_cistatic int soc15_common_late_init(void *handle) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 121062306a36Sopenharmony_ci xgpu_ai_mailbox_get_irq(adev); 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci /* Enable selfring doorbell aperture late because doorbell BAR 121362306a36Sopenharmony_ci * aperture will change if resize BAR successfully in gmc sw_init. 121462306a36Sopenharmony_ci */ 121562306a36Sopenharmony_ci adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, true); 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci return 0; 121862306a36Sopenharmony_ci} 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_cistatic int soc15_common_sw_init(void *handle) 122162306a36Sopenharmony_ci{ 122262306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 122562306a36Sopenharmony_ci xgpu_ai_mailbox_add_irq_id(adev); 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci if (adev->df.funcs && 122862306a36Sopenharmony_ci adev->df.funcs->sw_init) 122962306a36Sopenharmony_ci adev->df.funcs->sw_init(adev); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci return 0; 123262306a36Sopenharmony_ci} 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_cistatic int soc15_common_sw_fini(void *handle) 123562306a36Sopenharmony_ci{ 123662306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci if (adev->df.funcs && 123962306a36Sopenharmony_ci adev->df.funcs->sw_fini) 124062306a36Sopenharmony_ci adev->df.funcs->sw_fini(adev); 124162306a36Sopenharmony_ci return 0; 124262306a36Sopenharmony_ci} 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_cistatic void soc15_sdma_doorbell_range_init(struct amdgpu_device *adev) 124562306a36Sopenharmony_ci{ 124662306a36Sopenharmony_ci int i; 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci /* sdma doorbell range is programed by hypervisor */ 124962306a36Sopenharmony_ci if (!amdgpu_sriov_vf(adev)) { 125062306a36Sopenharmony_ci for (i = 0; i < adev->sdma.num_instances; i++) { 125162306a36Sopenharmony_ci adev->nbio.funcs->sdma_doorbell_range(adev, i, 125262306a36Sopenharmony_ci true, adev->doorbell_index.sdma_engine[i] << 1, 125362306a36Sopenharmony_ci adev->doorbell_index.sdma_doorbell_range); 125462306a36Sopenharmony_ci } 125562306a36Sopenharmony_ci } 125662306a36Sopenharmony_ci} 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_cistatic int soc15_common_hw_init(void *handle) 125962306a36Sopenharmony_ci{ 126062306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci /* enable aspm */ 126362306a36Sopenharmony_ci soc15_program_aspm(adev); 126462306a36Sopenharmony_ci /* setup nbio registers */ 126562306a36Sopenharmony_ci adev->nbio.funcs->init_registers(adev); 126662306a36Sopenharmony_ci /* remap HDP registers to a hole in mmio space, 126762306a36Sopenharmony_ci * for the purpose of expose those registers 126862306a36Sopenharmony_ci * to process space 126962306a36Sopenharmony_ci */ 127062306a36Sopenharmony_ci if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) 127162306a36Sopenharmony_ci adev->nbio.funcs->remap_hdp_registers(adev); 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_ci /* enable the doorbell aperture */ 127462306a36Sopenharmony_ci adev->nbio.funcs->enable_doorbell_aperture(adev, true); 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_ci /* HW doorbell routing policy: doorbell writing not 127762306a36Sopenharmony_ci * in SDMA/IH/MM/ACV range will be routed to CP. So 127862306a36Sopenharmony_ci * we need to init SDMA doorbell range prior 127962306a36Sopenharmony_ci * to CP ip block init and ring test. IH already 128062306a36Sopenharmony_ci * happens before CP. 128162306a36Sopenharmony_ci */ 128262306a36Sopenharmony_ci soc15_sdma_doorbell_range_init(adev); 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci return 0; 128562306a36Sopenharmony_ci} 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_cistatic int soc15_common_hw_fini(void *handle) 128862306a36Sopenharmony_ci{ 128962306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_ci /* Disable the doorbell aperture and selfring doorbell aperture 129262306a36Sopenharmony_ci * separately in hw_fini because soc15_enable_doorbell_aperture 129362306a36Sopenharmony_ci * has been removed and there is no need to delay disabling 129462306a36Sopenharmony_ci * selfring doorbell. 129562306a36Sopenharmony_ci */ 129662306a36Sopenharmony_ci adev->nbio.funcs->enable_doorbell_aperture(adev, false); 129762306a36Sopenharmony_ci adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, false); 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 130062306a36Sopenharmony_ci xgpu_ai_mailbox_put_irq(adev); 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ci if (adev->nbio.ras_if && 130362306a36Sopenharmony_ci amdgpu_ras_is_supported(adev, adev->nbio.ras_if->block)) { 130462306a36Sopenharmony_ci if (adev->nbio.ras && 130562306a36Sopenharmony_ci adev->nbio.ras->init_ras_controller_interrupt) 130662306a36Sopenharmony_ci amdgpu_irq_put(adev, &adev->nbio.ras_controller_irq, 0); 130762306a36Sopenharmony_ci if (adev->nbio.ras && 130862306a36Sopenharmony_ci adev->nbio.ras->init_ras_err_event_athub_interrupt) 130962306a36Sopenharmony_ci amdgpu_irq_put(adev, &adev->nbio.ras_err_event_athub_irq, 0); 131062306a36Sopenharmony_ci } 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_ci return 0; 131362306a36Sopenharmony_ci} 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_cistatic int soc15_common_suspend(void *handle) 131662306a36Sopenharmony_ci{ 131762306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ci return soc15_common_hw_fini(adev); 132062306a36Sopenharmony_ci} 132162306a36Sopenharmony_ci 132262306a36Sopenharmony_cistatic int soc15_common_resume(void *handle) 132362306a36Sopenharmony_ci{ 132462306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_ci if (soc15_need_reset_on_resume(adev)) { 132762306a36Sopenharmony_ci dev_info(adev->dev, "S3 suspend abort case, let's reset ASIC.\n"); 132862306a36Sopenharmony_ci soc15_asic_reset(adev); 132962306a36Sopenharmony_ci } 133062306a36Sopenharmony_ci return soc15_common_hw_init(adev); 133162306a36Sopenharmony_ci} 133262306a36Sopenharmony_ci 133362306a36Sopenharmony_cistatic bool soc15_common_is_idle(void *handle) 133462306a36Sopenharmony_ci{ 133562306a36Sopenharmony_ci return true; 133662306a36Sopenharmony_ci} 133762306a36Sopenharmony_ci 133862306a36Sopenharmony_cistatic int soc15_common_wait_for_idle(void *handle) 133962306a36Sopenharmony_ci{ 134062306a36Sopenharmony_ci return 0; 134162306a36Sopenharmony_ci} 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_cistatic int soc15_common_soft_reset(void *handle) 134462306a36Sopenharmony_ci{ 134562306a36Sopenharmony_ci return 0; 134662306a36Sopenharmony_ci} 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_cistatic void soc15_update_drm_clock_gating(struct amdgpu_device *adev, bool enable) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci uint32_t def, data; 135162306a36Sopenharmony_ci 135262306a36Sopenharmony_ci def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_MGCG)) 135562306a36Sopenharmony_ci data &= ~(0x01000000 | 135662306a36Sopenharmony_ci 0x02000000 | 135762306a36Sopenharmony_ci 0x04000000 | 135862306a36Sopenharmony_ci 0x08000000 | 135962306a36Sopenharmony_ci 0x10000000 | 136062306a36Sopenharmony_ci 0x20000000 | 136162306a36Sopenharmony_ci 0x40000000 | 136262306a36Sopenharmony_ci 0x80000000); 136362306a36Sopenharmony_ci else 136462306a36Sopenharmony_ci data |= (0x01000000 | 136562306a36Sopenharmony_ci 0x02000000 | 136662306a36Sopenharmony_ci 0x04000000 | 136762306a36Sopenharmony_ci 0x08000000 | 136862306a36Sopenharmony_ci 0x10000000 | 136962306a36Sopenharmony_ci 0x20000000 | 137062306a36Sopenharmony_ci 0x40000000 | 137162306a36Sopenharmony_ci 0x80000000); 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci if (def != data) 137462306a36Sopenharmony_ci WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0), data); 137562306a36Sopenharmony_ci} 137662306a36Sopenharmony_ci 137762306a36Sopenharmony_cistatic void soc15_update_drm_light_sleep(struct amdgpu_device *adev, bool enable) 137862306a36Sopenharmony_ci{ 137962306a36Sopenharmony_ci uint32_t def, data; 138062306a36Sopenharmony_ci 138162306a36Sopenharmony_ci def = data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL)); 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DRM_LS)) 138462306a36Sopenharmony_ci data |= 1; 138562306a36Sopenharmony_ci else 138662306a36Sopenharmony_ci data &= ~1; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci if (def != data) 138962306a36Sopenharmony_ci WREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL), data); 139062306a36Sopenharmony_ci} 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_cistatic int soc15_common_set_clockgating_state(void *handle, 139362306a36Sopenharmony_ci enum amd_clockgating_state state) 139462306a36Sopenharmony_ci{ 139562306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 139862306a36Sopenharmony_ci return 0; 139962306a36Sopenharmony_ci 140062306a36Sopenharmony_ci switch (adev->ip_versions[NBIO_HWIP][0]) { 140162306a36Sopenharmony_ci case IP_VERSION(6, 1, 0): 140262306a36Sopenharmony_ci case IP_VERSION(6, 2, 0): 140362306a36Sopenharmony_ci case IP_VERSION(7, 4, 0): 140462306a36Sopenharmony_ci adev->nbio.funcs->update_medium_grain_clock_gating(adev, 140562306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 140662306a36Sopenharmony_ci adev->nbio.funcs->update_medium_grain_light_sleep(adev, 140762306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 140862306a36Sopenharmony_ci adev->hdp.funcs->update_clock_gating(adev, 140962306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 141062306a36Sopenharmony_ci soc15_update_drm_clock_gating(adev, 141162306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 141262306a36Sopenharmony_ci soc15_update_drm_light_sleep(adev, 141362306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 141462306a36Sopenharmony_ci adev->smuio.funcs->update_rom_clock_gating(adev, 141562306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 141662306a36Sopenharmony_ci adev->df.funcs->update_medium_grain_clock_gating(adev, 141762306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 141862306a36Sopenharmony_ci break; 141962306a36Sopenharmony_ci case IP_VERSION(7, 0, 0): 142062306a36Sopenharmony_ci case IP_VERSION(7, 0, 1): 142162306a36Sopenharmony_ci case IP_VERSION(2, 5, 0): 142262306a36Sopenharmony_ci adev->nbio.funcs->update_medium_grain_clock_gating(adev, 142362306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 142462306a36Sopenharmony_ci adev->nbio.funcs->update_medium_grain_light_sleep(adev, 142562306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 142662306a36Sopenharmony_ci adev->hdp.funcs->update_clock_gating(adev, 142762306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 142862306a36Sopenharmony_ci soc15_update_drm_clock_gating(adev, 142962306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 143062306a36Sopenharmony_ci soc15_update_drm_light_sleep(adev, 143162306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 143262306a36Sopenharmony_ci break; 143362306a36Sopenharmony_ci case IP_VERSION(7, 4, 1): 143462306a36Sopenharmony_ci case IP_VERSION(7, 4, 4): 143562306a36Sopenharmony_ci adev->hdp.funcs->update_clock_gating(adev, 143662306a36Sopenharmony_ci state == AMD_CG_STATE_GATE); 143762306a36Sopenharmony_ci break; 143862306a36Sopenharmony_ci default: 143962306a36Sopenharmony_ci break; 144062306a36Sopenharmony_ci } 144162306a36Sopenharmony_ci return 0; 144262306a36Sopenharmony_ci} 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_cistatic void soc15_common_get_clockgating_state(void *handle, u64 *flags) 144562306a36Sopenharmony_ci{ 144662306a36Sopenharmony_ci struct amdgpu_device *adev = (struct amdgpu_device *)handle; 144762306a36Sopenharmony_ci int data; 144862306a36Sopenharmony_ci 144962306a36Sopenharmony_ci if (amdgpu_sriov_vf(adev)) 145062306a36Sopenharmony_ci *flags = 0; 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_ci if (adev->nbio.funcs && adev->nbio.funcs->get_clockgating_state) 145362306a36Sopenharmony_ci adev->nbio.funcs->get_clockgating_state(adev, flags); 145462306a36Sopenharmony_ci 145562306a36Sopenharmony_ci if (adev->hdp.funcs && adev->hdp.funcs->get_clock_gating_state) 145662306a36Sopenharmony_ci adev->hdp.funcs->get_clock_gating_state(adev, flags); 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci if (adev->ip_versions[MP0_HWIP][0] != IP_VERSION(13, 0, 2)) { 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci /* AMD_CG_SUPPORT_DRM_MGCG */ 146162306a36Sopenharmony_ci data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); 146262306a36Sopenharmony_ci if (!(data & 0x01000000)) 146362306a36Sopenharmony_ci *flags |= AMD_CG_SUPPORT_DRM_MGCG; 146462306a36Sopenharmony_ci 146562306a36Sopenharmony_ci /* AMD_CG_SUPPORT_DRM_LS */ 146662306a36Sopenharmony_ci data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_LIGHT_SLEEP_CTRL)); 146762306a36Sopenharmony_ci if (data & 0x1) 146862306a36Sopenharmony_ci *flags |= AMD_CG_SUPPORT_DRM_LS; 146962306a36Sopenharmony_ci } 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci /* AMD_CG_SUPPORT_ROM_MGCG */ 147262306a36Sopenharmony_ci if (adev->smuio.funcs && adev->smuio.funcs->get_clock_gating_state) 147362306a36Sopenharmony_ci adev->smuio.funcs->get_clock_gating_state(adev, flags); 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci if (adev->df.funcs && adev->df.funcs->get_clockgating_state) 147662306a36Sopenharmony_ci adev->df.funcs->get_clockgating_state(adev, flags); 147762306a36Sopenharmony_ci} 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_cistatic int soc15_common_set_powergating_state(void *handle, 148062306a36Sopenharmony_ci enum amd_powergating_state state) 148162306a36Sopenharmony_ci{ 148262306a36Sopenharmony_ci /* todo */ 148362306a36Sopenharmony_ci return 0; 148462306a36Sopenharmony_ci} 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_cistatic const struct amd_ip_funcs soc15_common_ip_funcs = { 148762306a36Sopenharmony_ci .name = "soc15_common", 148862306a36Sopenharmony_ci .early_init = soc15_common_early_init, 148962306a36Sopenharmony_ci .late_init = soc15_common_late_init, 149062306a36Sopenharmony_ci .sw_init = soc15_common_sw_init, 149162306a36Sopenharmony_ci .sw_fini = soc15_common_sw_fini, 149262306a36Sopenharmony_ci .hw_init = soc15_common_hw_init, 149362306a36Sopenharmony_ci .hw_fini = soc15_common_hw_fini, 149462306a36Sopenharmony_ci .suspend = soc15_common_suspend, 149562306a36Sopenharmony_ci .resume = soc15_common_resume, 149662306a36Sopenharmony_ci .is_idle = soc15_common_is_idle, 149762306a36Sopenharmony_ci .wait_for_idle = soc15_common_wait_for_idle, 149862306a36Sopenharmony_ci .soft_reset = soc15_common_soft_reset, 149962306a36Sopenharmony_ci .set_clockgating_state = soc15_common_set_clockgating_state, 150062306a36Sopenharmony_ci .set_powergating_state = soc15_common_set_powergating_state, 150162306a36Sopenharmony_ci .get_clockgating_state= soc15_common_get_clockgating_state, 150262306a36Sopenharmony_ci}; 1503