1fb4d8502Sjsg /* 2fb4d8502Sjsg * Copyright 2008 Advanced Micro Devices, Inc. 3fb4d8502Sjsg * Copyright 2008 Red Hat Inc. 4fb4d8502Sjsg * Copyright 2009 Jerome Glisse. 5fb4d8502Sjsg * 6fb4d8502Sjsg * Permission is hereby granted, free of charge, to any person obtaining a 7fb4d8502Sjsg * copy of this software and associated documentation files (the "Software"), 8fb4d8502Sjsg * to deal in the Software without restriction, including without limitation 9fb4d8502Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10fb4d8502Sjsg * and/or sell copies of the Software, and to permit persons to whom the 11fb4d8502Sjsg * Software is furnished to do so, subject to the following conditions: 12fb4d8502Sjsg * 13fb4d8502Sjsg * The above copyright notice and this permission notice shall be included in 14fb4d8502Sjsg * all copies or substantial portions of the Software. 15fb4d8502Sjsg * 16fb4d8502Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17fb4d8502Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18fb4d8502Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19fb4d8502Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20fb4d8502Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21fb4d8502Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22fb4d8502Sjsg * OTHER DEALINGS IN THE SOFTWARE. 23fb4d8502Sjsg * 24fb4d8502Sjsg * Authors: Dave Airlie 25fb4d8502Sjsg * Alex Deucher 26fb4d8502Sjsg * Jerome Glisse 27fb4d8502Sjsg */ 28c349dbc7Sjsg 29fb4d8502Sjsg #include "amdgpu.h" 30fb4d8502Sjsg #include <drm/amdgpu_drm.h> 315ca02815Sjsg #include <drm/drm_drv.h> 32f005ef32Sjsg #include <drm/drm_fb_helper.h> 33fb4d8502Sjsg #include "amdgpu_uvd.h" 34fb4d8502Sjsg #include "amdgpu_vce.h" 35fb4d8502Sjsg #include "atom.h" 36fb4d8502Sjsg 37fb4d8502Sjsg #include <linux/vga_switcheroo.h> 38fb4d8502Sjsg #include <linux/slab.h> 39c349dbc7Sjsg #include <linux/uaccess.h> 40c349dbc7Sjsg #include <linux/pci.h> 41fb4d8502Sjsg #include <linux/pm_runtime.h> 42fb4d8502Sjsg #include "amdgpu_amdkfd.h" 43c349dbc7Sjsg #include "amdgpu_gem.h" 44c349dbc7Sjsg #include "amdgpu_display.h" 45c349dbc7Sjsg #include "amdgpu_ras.h" 46*3cbf4bddSjsg #include "amdgpu_reset.h" 47f005ef32Sjsg #include "amd_pcie.h" 48c349dbc7Sjsg 49c349dbc7Sjsg void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev) 50c349dbc7Sjsg { 51c349dbc7Sjsg struct amdgpu_gpu_instance *gpu_instance; 52c349dbc7Sjsg int i; 53c349dbc7Sjsg 54c349dbc7Sjsg mutex_lock(&mgpu_info.mutex); 55c349dbc7Sjsg 56c349dbc7Sjsg for (i = 0; i < mgpu_info.num_gpu; i++) { 57c349dbc7Sjsg gpu_instance = &(mgpu_info.gpu_ins[i]); 58c349dbc7Sjsg if (gpu_instance->adev == adev) { 59c349dbc7Sjsg mgpu_info.gpu_ins[i] = 60c349dbc7Sjsg mgpu_info.gpu_ins[mgpu_info.num_gpu - 1]; 61c349dbc7Sjsg mgpu_info.num_gpu--; 62c349dbc7Sjsg if (adev->flags & AMD_IS_APU) 63c349dbc7Sjsg mgpu_info.num_apu--; 64c349dbc7Sjsg else 65c349dbc7Sjsg mgpu_info.num_dgpu--; 66c349dbc7Sjsg break; 67c349dbc7Sjsg } 68c349dbc7Sjsg } 69c349dbc7Sjsg 70c349dbc7Sjsg mutex_unlock(&mgpu_info.mutex); 71c349dbc7Sjsg } 72c349dbc7Sjsg 73fb4d8502Sjsg /** 74fb4d8502Sjsg * amdgpu_driver_unload_kms - Main unload function for KMS. 75fb4d8502Sjsg * 76fb4d8502Sjsg * @dev: drm dev pointer 77fb4d8502Sjsg * 78fb4d8502Sjsg * This is the main unload function for KMS (all asics). 79fb4d8502Sjsg * Returns 0 on success. 80fb4d8502Sjsg */ 81fb4d8502Sjsg void amdgpu_driver_unload_kms(struct drm_device *dev) 82fb4d8502Sjsg { 83ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 84fb4d8502Sjsg 85fb4d8502Sjsg if (adev == NULL) 86fb4d8502Sjsg return; 87fb4d8502Sjsg 88c349dbc7Sjsg amdgpu_unregister_gpu_instance(adev); 89c349dbc7Sjsg 90fb4d8502Sjsg if (adev->rmmio == NULL) 91ad8b1aafSjsg return; 92fb4d8502Sjsg 935ca02815Sjsg if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_UNLOAD)) 945ca02815Sjsg DRM_WARN("smart shift update failed\n"); 955ca02815Sjsg 96fb4d8502Sjsg amdgpu_acpi_fini(adev); 975ca02815Sjsg amdgpu_device_fini_hw(adev); 98fb4d8502Sjsg } 99fb4d8502Sjsg 100c349dbc7Sjsg void amdgpu_register_gpu_instance(struct amdgpu_device *adev) 101c349dbc7Sjsg { 102c349dbc7Sjsg struct amdgpu_gpu_instance *gpu_instance; 103c349dbc7Sjsg 104c349dbc7Sjsg mutex_lock(&mgpu_info.mutex); 105c349dbc7Sjsg 106c349dbc7Sjsg if (mgpu_info.num_gpu >= MAX_GPU_INSTANCE) { 107c349dbc7Sjsg DRM_ERROR("Cannot register more gpu instance\n"); 108c349dbc7Sjsg mutex_unlock(&mgpu_info.mutex); 109c349dbc7Sjsg return; 110c349dbc7Sjsg } 111c349dbc7Sjsg 112c349dbc7Sjsg gpu_instance = &(mgpu_info.gpu_ins[mgpu_info.num_gpu]); 113c349dbc7Sjsg gpu_instance->adev = adev; 114c349dbc7Sjsg gpu_instance->mgpu_fan_enabled = 0; 115c349dbc7Sjsg 116c349dbc7Sjsg mgpu_info.num_gpu++; 117c349dbc7Sjsg if (adev->flags & AMD_IS_APU) 118c349dbc7Sjsg mgpu_info.num_apu++; 119c349dbc7Sjsg else 120c349dbc7Sjsg mgpu_info.num_dgpu++; 121c349dbc7Sjsg 122c349dbc7Sjsg mutex_unlock(&mgpu_info.mutex); 123c349dbc7Sjsg } 124c349dbc7Sjsg 125fb4d8502Sjsg /** 126fb4d8502Sjsg * amdgpu_driver_load_kms - Main load function for KMS. 127fb4d8502Sjsg * 128ad8b1aafSjsg * @adev: pointer to struct amdgpu_device 129fb4d8502Sjsg * @flags: device flags 130fb4d8502Sjsg * 131fb4d8502Sjsg * This is the main load function for KMS (all asics). 132fb4d8502Sjsg * Returns 0 on success, error on failure. 133fb4d8502Sjsg */ 134ad8b1aafSjsg int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags) 135fb4d8502Sjsg { 136ad8b1aafSjsg struct drm_device *dev; 137fb4d8502Sjsg int r, acpi_status; 138fb4d8502Sjsg 139ad8b1aafSjsg dev = adev_to_drm(adev); 140fb4d8502Sjsg 141fb4d8502Sjsg /* amdgpu_device_init should report only fatal error 142fb4d8502Sjsg * like memory allocation failure or iomapping failure, 143fb4d8502Sjsg * or memory manager initialization failure, it must 144fb4d8502Sjsg * properly initialize the GPU MC controller and permit 145fb4d8502Sjsg * VRAM allocation 146fb4d8502Sjsg */ 147ad8b1aafSjsg r = amdgpu_device_init(adev, flags); 148fb4d8502Sjsg if (r) { 1495ca02815Sjsg dev_err(dev->dev, "Fatal error during GPU init\n"); 150fb4d8502Sjsg goto out; 151fb4d8502Sjsg } 152fb4d8502Sjsg 1531bb76ff1Sjsg adev->pm.rpm_mode = AMDGPU_RUNPM_NONE; 1545ca02815Sjsg if (amdgpu_device_supports_px(dev) && 1551bb76ff1Sjsg (amdgpu_runtime_pm != 0)) { /* enable PX as runtime mode */ 1561bb76ff1Sjsg adev->pm.rpm_mode = AMDGPU_RUNPM_PX; 1575ca02815Sjsg dev_info(adev->dev, "Using ATPX for runtime pm\n"); 1585ca02815Sjsg } else if (amdgpu_device_supports_boco(dev) && 1591bb76ff1Sjsg (amdgpu_runtime_pm != 0)) { /* enable boco as runtime mode */ 1601bb76ff1Sjsg adev->pm.rpm_mode = AMDGPU_RUNPM_BOCO; 1615ca02815Sjsg dev_info(adev->dev, "Using BOCO for runtime pm\n"); 162ad8b1aafSjsg } else if (amdgpu_device_supports_baco(dev) && 163ad8b1aafSjsg (amdgpu_runtime_pm != 0)) { 164ad8b1aafSjsg switch (adev->asic_type) { 165ad8b1aafSjsg case CHIP_VEGA20: 166ad8b1aafSjsg case CHIP_ARCTURUS: 1671bb76ff1Sjsg /* enable BACO as runpm mode if runpm=1 */ 168ad8b1aafSjsg if (amdgpu_runtime_pm > 0) 1691bb76ff1Sjsg adev->pm.rpm_mode = AMDGPU_RUNPM_BACO; 170ad8b1aafSjsg break; 171ad8b1aafSjsg case CHIP_VEGA10: 1721bb76ff1Sjsg /* enable BACO as runpm mode if noretry=0 */ 173ad8b1aafSjsg if (!adev->gmc.noretry) 1741bb76ff1Sjsg adev->pm.rpm_mode = AMDGPU_RUNPM_BACO; 175ad8b1aafSjsg break; 176ad8b1aafSjsg default: 1771bb76ff1Sjsg /* enable BACO as runpm mode on CI+ */ 1781bb76ff1Sjsg adev->pm.rpm_mode = AMDGPU_RUNPM_BACO; 179ad8b1aafSjsg break; 180ad8b1aafSjsg } 1811bb76ff1Sjsg 1821bb76ff1Sjsg if (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO) 1835ca02815Sjsg dev_info(adev->dev, "Using BACO for runtime pm\n"); 184ad8b1aafSjsg } 185c349dbc7Sjsg 186fb4d8502Sjsg /* Call ACPI methods: require modeset init 187fb4d8502Sjsg * but failure is not fatal 188fb4d8502Sjsg */ 189ad8b1aafSjsg 190fb4d8502Sjsg acpi_status = amdgpu_acpi_init(adev); 191fb4d8502Sjsg if (acpi_status) 1925ca02815Sjsg dev_dbg(dev->dev, "Error during ACPI methods call\n"); 193fb4d8502Sjsg 1945ca02815Sjsg if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD)) 1955ca02815Sjsg DRM_WARN("smart shift update failed\n"); 1965ca02815Sjsg 197fb4d8502Sjsg out: 1981bb76ff1Sjsg if (r) 199fb4d8502Sjsg amdgpu_driver_unload_kms(dev); 200fb4d8502Sjsg 201fb4d8502Sjsg return r; 202fb4d8502Sjsg } 203fb4d8502Sjsg 204fb4d8502Sjsg static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, 205fb4d8502Sjsg struct drm_amdgpu_query_fw *query_fw, 206fb4d8502Sjsg struct amdgpu_device *adev) 207fb4d8502Sjsg { 208fb4d8502Sjsg switch (query_fw->fw_type) { 209fb4d8502Sjsg case AMDGPU_INFO_FW_VCE: 210fb4d8502Sjsg fw_info->ver = adev->vce.fw_version; 211fb4d8502Sjsg fw_info->feature = adev->vce.fb_version; 212fb4d8502Sjsg break; 213fb4d8502Sjsg case AMDGPU_INFO_FW_UVD: 214fb4d8502Sjsg fw_info->ver = adev->uvd.fw_version; 215fb4d8502Sjsg fw_info->feature = 0; 216fb4d8502Sjsg break; 217fb4d8502Sjsg case AMDGPU_INFO_FW_VCN: 218fb4d8502Sjsg fw_info->ver = adev->vcn.fw_version; 219fb4d8502Sjsg fw_info->feature = 0; 220fb4d8502Sjsg break; 221fb4d8502Sjsg case AMDGPU_INFO_FW_GMC: 222fb4d8502Sjsg fw_info->ver = adev->gmc.fw_version; 223fb4d8502Sjsg fw_info->feature = 0; 224fb4d8502Sjsg break; 225fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_ME: 226fb4d8502Sjsg fw_info->ver = adev->gfx.me_fw_version; 227fb4d8502Sjsg fw_info->feature = adev->gfx.me_feature_version; 228fb4d8502Sjsg break; 229fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_PFP: 230fb4d8502Sjsg fw_info->ver = adev->gfx.pfp_fw_version; 231fb4d8502Sjsg fw_info->feature = adev->gfx.pfp_feature_version; 232fb4d8502Sjsg break; 233fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_CE: 234fb4d8502Sjsg fw_info->ver = adev->gfx.ce_fw_version; 235fb4d8502Sjsg fw_info->feature = adev->gfx.ce_feature_version; 236fb4d8502Sjsg break; 237fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_RLC: 238fb4d8502Sjsg fw_info->ver = adev->gfx.rlc_fw_version; 239fb4d8502Sjsg fw_info->feature = adev->gfx.rlc_feature_version; 240fb4d8502Sjsg break; 241fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL: 242fb4d8502Sjsg fw_info->ver = adev->gfx.rlc_srlc_fw_version; 243fb4d8502Sjsg fw_info->feature = adev->gfx.rlc_srlc_feature_version; 244fb4d8502Sjsg break; 245fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM: 246fb4d8502Sjsg fw_info->ver = adev->gfx.rlc_srlg_fw_version; 247fb4d8502Sjsg fw_info->feature = adev->gfx.rlc_srlg_feature_version; 248fb4d8502Sjsg break; 249fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM: 250fb4d8502Sjsg fw_info->ver = adev->gfx.rlc_srls_fw_version; 251fb4d8502Sjsg fw_info->feature = adev->gfx.rlc_srls_feature_version; 252fb4d8502Sjsg break; 2531bb76ff1Sjsg case AMDGPU_INFO_FW_GFX_RLCP: 2541bb76ff1Sjsg fw_info->ver = adev->gfx.rlcp_ucode_version; 2551bb76ff1Sjsg fw_info->feature = adev->gfx.rlcp_ucode_feature_version; 2561bb76ff1Sjsg break; 2571bb76ff1Sjsg case AMDGPU_INFO_FW_GFX_RLCV: 2581bb76ff1Sjsg fw_info->ver = adev->gfx.rlcv_ucode_version; 2591bb76ff1Sjsg fw_info->feature = adev->gfx.rlcv_ucode_feature_version; 2601bb76ff1Sjsg break; 261fb4d8502Sjsg case AMDGPU_INFO_FW_GFX_MEC: 262fb4d8502Sjsg if (query_fw->index == 0) { 263fb4d8502Sjsg fw_info->ver = adev->gfx.mec_fw_version; 264fb4d8502Sjsg fw_info->feature = adev->gfx.mec_feature_version; 265fb4d8502Sjsg } else if (query_fw->index == 1) { 266fb4d8502Sjsg fw_info->ver = adev->gfx.mec2_fw_version; 267fb4d8502Sjsg fw_info->feature = adev->gfx.mec2_feature_version; 268fb4d8502Sjsg } else 269fb4d8502Sjsg return -EINVAL; 270fb4d8502Sjsg break; 271fb4d8502Sjsg case AMDGPU_INFO_FW_SMC: 272fb4d8502Sjsg fw_info->ver = adev->pm.fw_version; 273fb4d8502Sjsg fw_info->feature = 0; 274fb4d8502Sjsg break; 275c349dbc7Sjsg case AMDGPU_INFO_FW_TA: 276ad8b1aafSjsg switch (query_fw->index) { 2775ca02815Sjsg case TA_FW_TYPE_PSP_XGMI: 2781bb76ff1Sjsg fw_info->ver = adev->psp.xgmi_context.context.bin_desc.fw_version; 2791bb76ff1Sjsg fw_info->feature = adev->psp.xgmi_context.context 2801bb76ff1Sjsg .bin_desc.feature_version; 281ad8b1aafSjsg break; 2825ca02815Sjsg case TA_FW_TYPE_PSP_RAS: 2831bb76ff1Sjsg fw_info->ver = adev->psp.ras_context.context.bin_desc.fw_version; 2841bb76ff1Sjsg fw_info->feature = adev->psp.ras_context.context 2851bb76ff1Sjsg .bin_desc.feature_version; 286ad8b1aafSjsg break; 2875ca02815Sjsg case TA_FW_TYPE_PSP_HDCP: 2881bb76ff1Sjsg fw_info->ver = adev->psp.hdcp_context.context.bin_desc.fw_version; 2891bb76ff1Sjsg fw_info->feature = adev->psp.hdcp_context.context 2901bb76ff1Sjsg .bin_desc.feature_version; 291ad8b1aafSjsg break; 2925ca02815Sjsg case TA_FW_TYPE_PSP_DTM: 2931bb76ff1Sjsg fw_info->ver = adev->psp.dtm_context.context.bin_desc.fw_version; 2941bb76ff1Sjsg fw_info->feature = adev->psp.dtm_context.context 2951bb76ff1Sjsg .bin_desc.feature_version; 2965ca02815Sjsg break; 2975ca02815Sjsg case TA_FW_TYPE_PSP_RAP: 2981bb76ff1Sjsg fw_info->ver = adev->psp.rap_context.context.bin_desc.fw_version; 2991bb76ff1Sjsg fw_info->feature = adev->psp.rap_context.context 3001bb76ff1Sjsg .bin_desc.feature_version; 3015ca02815Sjsg break; 3025ca02815Sjsg case TA_FW_TYPE_PSP_SECUREDISPLAY: 3031bb76ff1Sjsg fw_info->ver = adev->psp.securedisplay_context.context.bin_desc.fw_version; 3041bb76ff1Sjsg fw_info->feature = 3051bb76ff1Sjsg adev->psp.securedisplay_context.context.bin_desc 3061bb76ff1Sjsg .feature_version; 307ad8b1aafSjsg break; 308ad8b1aafSjsg default: 309ad8b1aafSjsg return -EINVAL; 310c349dbc7Sjsg } 311c349dbc7Sjsg break; 312fb4d8502Sjsg case AMDGPU_INFO_FW_SDMA: 313fb4d8502Sjsg if (query_fw->index >= adev->sdma.num_instances) 314fb4d8502Sjsg return -EINVAL; 315fb4d8502Sjsg fw_info->ver = adev->sdma.instance[query_fw->index].fw_version; 316fb4d8502Sjsg fw_info->feature = adev->sdma.instance[query_fw->index].feature_version; 317fb4d8502Sjsg break; 318fb4d8502Sjsg case AMDGPU_INFO_FW_SOS: 3195ca02815Sjsg fw_info->ver = adev->psp.sos.fw_version; 3205ca02815Sjsg fw_info->feature = adev->psp.sos.feature_version; 321fb4d8502Sjsg break; 322fb4d8502Sjsg case AMDGPU_INFO_FW_ASD: 3231bb76ff1Sjsg fw_info->ver = adev->psp.asd_context.bin_desc.fw_version; 3241bb76ff1Sjsg fw_info->feature = adev->psp.asd_context.bin_desc.feature_version; 325fb4d8502Sjsg break; 326c349dbc7Sjsg case AMDGPU_INFO_FW_DMCU: 327c349dbc7Sjsg fw_info->ver = adev->dm.dmcu_fw_version; 328c349dbc7Sjsg fw_info->feature = 0; 329c349dbc7Sjsg break; 330c349dbc7Sjsg case AMDGPU_INFO_FW_DMCUB: 331c349dbc7Sjsg fw_info->ver = adev->dm.dmcub_fw_version; 332c349dbc7Sjsg fw_info->feature = 0; 333c349dbc7Sjsg break; 3345ca02815Sjsg case AMDGPU_INFO_FW_TOC: 3355ca02815Sjsg fw_info->ver = adev->psp.toc.fw_version; 3365ca02815Sjsg fw_info->feature = adev->psp.toc.feature_version; 3375ca02815Sjsg break; 3381bb76ff1Sjsg case AMDGPU_INFO_FW_CAP: 3391bb76ff1Sjsg fw_info->ver = adev->psp.cap_fw_version; 3401bb76ff1Sjsg fw_info->feature = adev->psp.cap_feature_version; 3411bb76ff1Sjsg break; 3421bb76ff1Sjsg case AMDGPU_INFO_FW_MES_KIQ: 3431bb76ff1Sjsg fw_info->ver = adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK; 3441bb76ff1Sjsg fw_info->feature = (adev->mes.kiq_version & AMDGPU_MES_FEAT_VERSION_MASK) 3451bb76ff1Sjsg >> AMDGPU_MES_FEAT_VERSION_SHIFT; 3461bb76ff1Sjsg break; 3471bb76ff1Sjsg case AMDGPU_INFO_FW_MES: 3481bb76ff1Sjsg fw_info->ver = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK; 3491bb76ff1Sjsg fw_info->feature = (adev->mes.sched_version & AMDGPU_MES_FEAT_VERSION_MASK) 3501bb76ff1Sjsg >> AMDGPU_MES_FEAT_VERSION_SHIFT; 3511bb76ff1Sjsg break; 3521bb76ff1Sjsg case AMDGPU_INFO_FW_IMU: 3531bb76ff1Sjsg fw_info->ver = adev->gfx.imu_fw_version; 3541bb76ff1Sjsg fw_info->feature = 0; 3551bb76ff1Sjsg break; 356fb4d8502Sjsg default: 357fb4d8502Sjsg return -EINVAL; 358fb4d8502Sjsg } 359fb4d8502Sjsg return 0; 360fb4d8502Sjsg } 361fb4d8502Sjsg 362c349dbc7Sjsg static int amdgpu_hw_ip_info(struct amdgpu_device *adev, 363c349dbc7Sjsg struct drm_amdgpu_info *info, 364c349dbc7Sjsg struct drm_amdgpu_info_hw_ip *result) 365c349dbc7Sjsg { 366c349dbc7Sjsg uint32_t ib_start_alignment = 0; 367c349dbc7Sjsg uint32_t ib_size_alignment = 0; 368c349dbc7Sjsg enum amd_ip_block_type type; 369c349dbc7Sjsg unsigned int num_rings = 0; 370c349dbc7Sjsg unsigned int i, j; 371c349dbc7Sjsg 372c349dbc7Sjsg if (info->query_hw_ip.ip_instance >= AMDGPU_HW_IP_INSTANCE_MAX_COUNT) 373c349dbc7Sjsg return -EINVAL; 374c349dbc7Sjsg 375c349dbc7Sjsg switch (info->query_hw_ip.type) { 376c349dbc7Sjsg case AMDGPU_HW_IP_GFX: 377c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_GFX; 378c349dbc7Sjsg for (i = 0; i < adev->gfx.num_gfx_rings; i++) 379c349dbc7Sjsg if (adev->gfx.gfx_ring[i].sched.ready) 380c349dbc7Sjsg ++num_rings; 381c349dbc7Sjsg ib_start_alignment = 32; 382c349dbc7Sjsg ib_size_alignment = 32; 383c349dbc7Sjsg break; 384c349dbc7Sjsg case AMDGPU_HW_IP_COMPUTE: 385c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_GFX; 386c349dbc7Sjsg for (i = 0; i < adev->gfx.num_compute_rings; i++) 387c349dbc7Sjsg if (adev->gfx.compute_ring[i].sched.ready) 388c349dbc7Sjsg ++num_rings; 389c349dbc7Sjsg ib_start_alignment = 32; 390c349dbc7Sjsg ib_size_alignment = 32; 391c349dbc7Sjsg break; 392c349dbc7Sjsg case AMDGPU_HW_IP_DMA: 393c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_SDMA; 394c349dbc7Sjsg for (i = 0; i < adev->sdma.num_instances; i++) 395c349dbc7Sjsg if (adev->sdma.instance[i].ring.sched.ready) 396c349dbc7Sjsg ++num_rings; 397c349dbc7Sjsg ib_start_alignment = 256; 398c349dbc7Sjsg ib_size_alignment = 4; 399c349dbc7Sjsg break; 400c349dbc7Sjsg case AMDGPU_HW_IP_UVD: 401c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_UVD; 402c349dbc7Sjsg for (i = 0; i < adev->uvd.num_uvd_inst; i++) { 403c349dbc7Sjsg if (adev->uvd.harvest_config & (1 << i)) 404c349dbc7Sjsg continue; 405c349dbc7Sjsg 406c349dbc7Sjsg if (adev->uvd.inst[i].ring.sched.ready) 407c349dbc7Sjsg ++num_rings; 408c349dbc7Sjsg } 409c349dbc7Sjsg ib_start_alignment = 64; 410c349dbc7Sjsg ib_size_alignment = 64; 411c349dbc7Sjsg break; 412c349dbc7Sjsg case AMDGPU_HW_IP_VCE: 413c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_VCE; 414c349dbc7Sjsg for (i = 0; i < adev->vce.num_rings; i++) 415c349dbc7Sjsg if (adev->vce.ring[i].sched.ready) 416c349dbc7Sjsg ++num_rings; 417c349dbc7Sjsg ib_start_alignment = 4; 418c349dbc7Sjsg ib_size_alignment = 1; 419c349dbc7Sjsg break; 420c349dbc7Sjsg case AMDGPU_HW_IP_UVD_ENC: 421c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_UVD; 422c349dbc7Sjsg for (i = 0; i < adev->uvd.num_uvd_inst; i++) { 423c349dbc7Sjsg if (adev->uvd.harvest_config & (1 << i)) 424c349dbc7Sjsg continue; 425c349dbc7Sjsg 426c349dbc7Sjsg for (j = 0; j < adev->uvd.num_enc_rings; j++) 427c349dbc7Sjsg if (adev->uvd.inst[i].ring_enc[j].sched.ready) 428c349dbc7Sjsg ++num_rings; 429c349dbc7Sjsg } 430c349dbc7Sjsg ib_start_alignment = 64; 431c349dbc7Sjsg ib_size_alignment = 64; 432c349dbc7Sjsg break; 433c349dbc7Sjsg case AMDGPU_HW_IP_VCN_DEC: 434c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_VCN; 435c349dbc7Sjsg for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 436f005ef32Sjsg if (adev->vcn.harvest_config & (1 << i)) 437c349dbc7Sjsg continue; 438c349dbc7Sjsg 439c349dbc7Sjsg if (adev->vcn.inst[i].ring_dec.sched.ready) 440c349dbc7Sjsg ++num_rings; 441c349dbc7Sjsg } 442c349dbc7Sjsg ib_start_alignment = 16; 443c349dbc7Sjsg ib_size_alignment = 16; 444c349dbc7Sjsg break; 445c349dbc7Sjsg case AMDGPU_HW_IP_VCN_ENC: 446c349dbc7Sjsg type = AMD_IP_BLOCK_TYPE_VCN; 447c349dbc7Sjsg for (i = 0; i < adev->vcn.num_vcn_inst; i++) { 448f005ef32Sjsg if (adev->vcn.harvest_config & (1 << i)) 449c349dbc7Sjsg continue; 450c349dbc7Sjsg 451c349dbc7Sjsg for (j = 0; j < adev->vcn.num_enc_rings; j++) 452c349dbc7Sjsg if (adev->vcn.inst[i].ring_enc[j].sched.ready) 453c349dbc7Sjsg ++num_rings; 454c349dbc7Sjsg } 455c349dbc7Sjsg ib_start_alignment = 64; 456c349dbc7Sjsg ib_size_alignment = 1; 457c349dbc7Sjsg break; 458c349dbc7Sjsg case AMDGPU_HW_IP_VCN_JPEG: 459c349dbc7Sjsg type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ? 460c349dbc7Sjsg AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN; 461c349dbc7Sjsg 462c349dbc7Sjsg for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) { 463c349dbc7Sjsg if (adev->jpeg.harvest_config & (1 << i)) 464c349dbc7Sjsg continue; 465c349dbc7Sjsg 466f005ef32Sjsg for (j = 0; j < adev->jpeg.num_jpeg_rings; j++) 467f005ef32Sjsg if (adev->jpeg.inst[i].ring_dec[j].sched.ready) 468c349dbc7Sjsg ++num_rings; 469c349dbc7Sjsg } 470c349dbc7Sjsg ib_start_alignment = 16; 471c349dbc7Sjsg ib_size_alignment = 16; 472c349dbc7Sjsg break; 473c349dbc7Sjsg default: 474c349dbc7Sjsg return -EINVAL; 475c349dbc7Sjsg } 476c349dbc7Sjsg 477c349dbc7Sjsg for (i = 0; i < adev->num_ip_blocks; i++) 478c349dbc7Sjsg if (adev->ip_blocks[i].version->type == type && 479c349dbc7Sjsg adev->ip_blocks[i].status.valid) 480c349dbc7Sjsg break; 481c349dbc7Sjsg 482c349dbc7Sjsg if (i == adev->num_ip_blocks) 483c349dbc7Sjsg return 0; 484c349dbc7Sjsg 485c349dbc7Sjsg num_rings = min(amdgpu_ctx_num_entities[info->query_hw_ip.type], 486c349dbc7Sjsg num_rings); 487c349dbc7Sjsg 488c349dbc7Sjsg result->hw_ip_version_major = adev->ip_blocks[i].version->major; 489c349dbc7Sjsg result->hw_ip_version_minor = adev->ip_blocks[i].version->minor; 4901bb76ff1Sjsg 4911bb76ff1Sjsg if (adev->asic_type >= CHIP_VEGA10) { 4921bb76ff1Sjsg switch (type) { 4931bb76ff1Sjsg case AMD_IP_BLOCK_TYPE_GFX: 4941bb76ff1Sjsg result->ip_discovery_version = adev->ip_versions[GC_HWIP][0]; 4951bb76ff1Sjsg break; 4961bb76ff1Sjsg case AMD_IP_BLOCK_TYPE_SDMA: 4971bb76ff1Sjsg result->ip_discovery_version = adev->ip_versions[SDMA0_HWIP][0]; 4981bb76ff1Sjsg break; 4991bb76ff1Sjsg case AMD_IP_BLOCK_TYPE_UVD: 5001bb76ff1Sjsg case AMD_IP_BLOCK_TYPE_VCN: 5011bb76ff1Sjsg case AMD_IP_BLOCK_TYPE_JPEG: 5021bb76ff1Sjsg result->ip_discovery_version = adev->ip_versions[UVD_HWIP][0]; 5031bb76ff1Sjsg break; 5041bb76ff1Sjsg case AMD_IP_BLOCK_TYPE_VCE: 5051bb76ff1Sjsg result->ip_discovery_version = adev->ip_versions[VCE_HWIP][0]; 5061bb76ff1Sjsg break; 5071bb76ff1Sjsg default: 5081bb76ff1Sjsg result->ip_discovery_version = 0; 5091bb76ff1Sjsg break; 5101bb76ff1Sjsg } 5111bb76ff1Sjsg } else { 5121bb76ff1Sjsg result->ip_discovery_version = 0; 5131bb76ff1Sjsg } 514c349dbc7Sjsg result->capabilities_flags = 0; 515c349dbc7Sjsg result->available_rings = (1 << num_rings) - 1; 516c349dbc7Sjsg result->ib_start_alignment = ib_start_alignment; 517c349dbc7Sjsg result->ib_size_alignment = ib_size_alignment; 518c349dbc7Sjsg return 0; 519c349dbc7Sjsg } 520c349dbc7Sjsg 521fb4d8502Sjsg /* 522fb4d8502Sjsg * Userspace get information ioctl 523fb4d8502Sjsg */ 524fb4d8502Sjsg /** 525fb4d8502Sjsg * amdgpu_info_ioctl - answer a device specific request. 526fb4d8502Sjsg * 5275ca02815Sjsg * @dev: drm device pointer 528fb4d8502Sjsg * @data: request object 529fb4d8502Sjsg * @filp: drm filp 530fb4d8502Sjsg * 531fb4d8502Sjsg * This function is used to pass device specific parameters to the userspace 532fb4d8502Sjsg * drivers. Examples include: pci device id, pipeline parms, tiling params, 533fb4d8502Sjsg * etc. (all asics). 534fb4d8502Sjsg * Returns 0 on success, -EINVAL on failure. 535fb4d8502Sjsg */ 5365ca02815Sjsg int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 537fb4d8502Sjsg { 538ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 539fb4d8502Sjsg struct drm_amdgpu_info *info = data; 540fb4d8502Sjsg struct amdgpu_mode_info *minfo = &adev->mode_info; 541fb4d8502Sjsg void __user *out = (void __user *)(uintptr_t)info->return_pointer; 542fb4d8502Sjsg uint32_t size = info->return_size; 543fb4d8502Sjsg struct drm_crtc *crtc; 544fb4d8502Sjsg uint32_t ui32 = 0; 545fb4d8502Sjsg uint64_t ui64 = 0; 546c349dbc7Sjsg int i, found; 547fb4d8502Sjsg int ui32_size = sizeof(ui32); 548fb4d8502Sjsg 549fb4d8502Sjsg if (!info->return_size || !info->return_pointer) 550fb4d8502Sjsg return -EINVAL; 551fb4d8502Sjsg 552fb4d8502Sjsg switch (info->query) { 553fb4d8502Sjsg case AMDGPU_INFO_ACCEL_WORKING: 554fb4d8502Sjsg ui32 = adev->accel_working; 555fb4d8502Sjsg return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; 556fb4d8502Sjsg case AMDGPU_INFO_CRTC_FROM_ID: 557fb4d8502Sjsg for (i = 0, found = 0; i < adev->mode_info.num_crtc; i++) { 558fb4d8502Sjsg crtc = (struct drm_crtc *)minfo->crtcs[i]; 559fb4d8502Sjsg if (crtc && crtc->base.id == info->mode_crtc.id) { 560fb4d8502Sjsg struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 561ba393808Sjsg 562fb4d8502Sjsg ui32 = amdgpu_crtc->crtc_id; 563fb4d8502Sjsg found = 1; 564fb4d8502Sjsg break; 565fb4d8502Sjsg } 566fb4d8502Sjsg } 567fb4d8502Sjsg if (!found) { 568fb4d8502Sjsg DRM_DEBUG_KMS("unknown crtc id %d\n", info->mode_crtc.id); 569fb4d8502Sjsg return -EINVAL; 570fb4d8502Sjsg } 571fb4d8502Sjsg return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; 572fb4d8502Sjsg case AMDGPU_INFO_HW_IP_INFO: { 573fb4d8502Sjsg struct drm_amdgpu_info_hw_ip ip = {}; 574c349dbc7Sjsg int ret; 575fb4d8502Sjsg 576c349dbc7Sjsg ret = amdgpu_hw_ip_info(adev, info, &ip); 577c349dbc7Sjsg if (ret) 578c349dbc7Sjsg return ret; 579fb4d8502Sjsg 580ba393808Sjsg ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip))); 581c349dbc7Sjsg return ret ? -EFAULT : 0; 582fb4d8502Sjsg } 583fb4d8502Sjsg case AMDGPU_INFO_HW_IP_COUNT: { 584fb4d8502Sjsg enum amd_ip_block_type type; 585fb4d8502Sjsg uint32_t count = 0; 586fb4d8502Sjsg 587fb4d8502Sjsg switch (info->query_hw_ip.type) { 588fb4d8502Sjsg case AMDGPU_HW_IP_GFX: 589fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_GFX; 590fb4d8502Sjsg break; 591fb4d8502Sjsg case AMDGPU_HW_IP_COMPUTE: 592fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_GFX; 593fb4d8502Sjsg break; 594fb4d8502Sjsg case AMDGPU_HW_IP_DMA: 595fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_SDMA; 596fb4d8502Sjsg break; 597fb4d8502Sjsg case AMDGPU_HW_IP_UVD: 598fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_UVD; 599fb4d8502Sjsg break; 600fb4d8502Sjsg case AMDGPU_HW_IP_VCE: 601fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_VCE; 602fb4d8502Sjsg break; 603fb4d8502Sjsg case AMDGPU_HW_IP_UVD_ENC: 604fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_UVD; 605fb4d8502Sjsg break; 606fb4d8502Sjsg case AMDGPU_HW_IP_VCN_DEC: 607fb4d8502Sjsg case AMDGPU_HW_IP_VCN_ENC: 608fb4d8502Sjsg type = AMD_IP_BLOCK_TYPE_VCN; 609fb4d8502Sjsg break; 610c349dbc7Sjsg case AMDGPU_HW_IP_VCN_JPEG: 611c349dbc7Sjsg type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ? 612c349dbc7Sjsg AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN; 613c349dbc7Sjsg break; 614fb4d8502Sjsg default: 615fb4d8502Sjsg return -EINVAL; 616fb4d8502Sjsg } 617fb4d8502Sjsg 618fb4d8502Sjsg for (i = 0; i < adev->num_ip_blocks; i++) 619fb4d8502Sjsg if (adev->ip_blocks[i].version->type == type && 620fb4d8502Sjsg adev->ip_blocks[i].status.valid && 621fb4d8502Sjsg count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT) 622fb4d8502Sjsg count++; 623fb4d8502Sjsg 624fb4d8502Sjsg return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0; 625fb4d8502Sjsg } 626fb4d8502Sjsg case AMDGPU_INFO_TIMESTAMP: 627fb4d8502Sjsg ui64 = amdgpu_gfx_get_gpu_clock_counter(adev); 628fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 629fb4d8502Sjsg case AMDGPU_INFO_FW_VERSION: { 630fb4d8502Sjsg struct drm_amdgpu_info_firmware fw_info; 631fb4d8502Sjsg int ret; 632fb4d8502Sjsg 633fb4d8502Sjsg /* We only support one instance of each IP block right now. */ 634fb4d8502Sjsg if (info->query_fw.ip_instance != 0) 635fb4d8502Sjsg return -EINVAL; 636fb4d8502Sjsg 637fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &info->query_fw, adev); 638fb4d8502Sjsg if (ret) 639fb4d8502Sjsg return ret; 640fb4d8502Sjsg 641fb4d8502Sjsg return copy_to_user(out, &fw_info, 642fb4d8502Sjsg min((size_t)size, sizeof(fw_info))) ? -EFAULT : 0; 643fb4d8502Sjsg } 644fb4d8502Sjsg case AMDGPU_INFO_NUM_BYTES_MOVED: 645fb4d8502Sjsg ui64 = atomic64_read(&adev->num_bytes_moved); 646fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 647fb4d8502Sjsg case AMDGPU_INFO_NUM_EVICTIONS: 648fb4d8502Sjsg ui64 = atomic64_read(&adev->num_evictions); 649fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 650fb4d8502Sjsg case AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS: 651fb4d8502Sjsg ui64 = atomic64_read(&adev->num_vram_cpu_page_faults); 652fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 653fb4d8502Sjsg case AMDGPU_INFO_VRAM_USAGE: 6541bb76ff1Sjsg ui64 = ttm_resource_manager_usage(&adev->mman.vram_mgr.manager); 655fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 656fb4d8502Sjsg case AMDGPU_INFO_VIS_VRAM_USAGE: 6571bb76ff1Sjsg ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr); 658fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 659fb4d8502Sjsg case AMDGPU_INFO_GTT_USAGE: 6601bb76ff1Sjsg ui64 = ttm_resource_manager_usage(&adev->mman.gtt_mgr.manager); 661fb4d8502Sjsg return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; 662fb4d8502Sjsg case AMDGPU_INFO_GDS_CONFIG: { 663fb4d8502Sjsg struct drm_amdgpu_info_gds gds_info; 664fb4d8502Sjsg 665fb4d8502Sjsg memset(&gds_info, 0, sizeof(gds_info)); 666c349dbc7Sjsg gds_info.compute_partition_size = adev->gds.gds_size; 667c349dbc7Sjsg gds_info.gds_total_size = adev->gds.gds_size; 668c349dbc7Sjsg gds_info.gws_per_compute_partition = adev->gds.gws_size; 669c349dbc7Sjsg gds_info.oa_per_compute_partition = adev->gds.oa_size; 670fb4d8502Sjsg return copy_to_user(out, &gds_info, 671fb4d8502Sjsg min((size_t)size, sizeof(gds_info))) ? -EFAULT : 0; 672fb4d8502Sjsg } 673fb4d8502Sjsg case AMDGPU_INFO_VRAM_GTT: { 674fb4d8502Sjsg struct drm_amdgpu_info_vram_gtt vram_gtt; 675fb4d8502Sjsg 676fb4d8502Sjsg vram_gtt.vram_size = adev->gmc.real_vram_size - 677c349dbc7Sjsg atomic64_read(&adev->vram_pin_size) - 678c349dbc7Sjsg AMDGPU_VM_RESERVED_VRAM; 679c349dbc7Sjsg vram_gtt.vram_cpu_accessible_size = 680c349dbc7Sjsg min(adev->gmc.visible_vram_size - 681c349dbc7Sjsg atomic64_read(&adev->visible_pin_size), 682c349dbc7Sjsg vram_gtt.vram_size); 683ad8b1aafSjsg vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size; 684fb4d8502Sjsg vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size); 685fb4d8502Sjsg return copy_to_user(out, &vram_gtt, 686fb4d8502Sjsg min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0; 687fb4d8502Sjsg } 688fb4d8502Sjsg case AMDGPU_INFO_MEMORY: { 689fb4d8502Sjsg struct drm_amdgpu_memory_info mem; 690ad8b1aafSjsg struct ttm_resource_manager *gtt_man = 6911bb76ff1Sjsg &adev->mman.gtt_mgr.manager; 6921bb76ff1Sjsg struct ttm_resource_manager *vram_man = 6931bb76ff1Sjsg &adev->mman.vram_mgr.manager; 6941bb76ff1Sjsg 695fb4d8502Sjsg memset(&mem, 0, sizeof(mem)); 696fb4d8502Sjsg mem.vram.total_heap_size = adev->gmc.real_vram_size; 697fb4d8502Sjsg mem.vram.usable_heap_size = adev->gmc.real_vram_size - 698c349dbc7Sjsg atomic64_read(&adev->vram_pin_size) - 699c349dbc7Sjsg AMDGPU_VM_RESERVED_VRAM; 700fb4d8502Sjsg mem.vram.heap_usage = 7011bb76ff1Sjsg ttm_resource_manager_usage(vram_man); 702fb4d8502Sjsg mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4; 703fb4d8502Sjsg 704fb4d8502Sjsg mem.cpu_accessible_vram.total_heap_size = 705fb4d8502Sjsg adev->gmc.visible_vram_size; 706c349dbc7Sjsg mem.cpu_accessible_vram.usable_heap_size = 707c349dbc7Sjsg min(adev->gmc.visible_vram_size - 708c349dbc7Sjsg atomic64_read(&adev->visible_pin_size), 709c349dbc7Sjsg mem.vram.usable_heap_size); 710fb4d8502Sjsg mem.cpu_accessible_vram.heap_usage = 7111bb76ff1Sjsg amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr); 712fb4d8502Sjsg mem.cpu_accessible_vram.max_allocation = 713fb4d8502Sjsg mem.cpu_accessible_vram.usable_heap_size * 3 / 4; 714fb4d8502Sjsg 715ad8b1aafSjsg mem.gtt.total_heap_size = gtt_man->size; 716fb4d8502Sjsg mem.gtt.usable_heap_size = mem.gtt.total_heap_size - 717fb4d8502Sjsg atomic64_read(&adev->gart_pin_size); 7181bb76ff1Sjsg mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man); 719fb4d8502Sjsg mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4; 720fb4d8502Sjsg 721fb4d8502Sjsg return copy_to_user(out, &mem, 722fb4d8502Sjsg min((size_t)size, sizeof(mem))) 723fb4d8502Sjsg ? -EFAULT : 0; 724fb4d8502Sjsg } 725fb4d8502Sjsg case AMDGPU_INFO_READ_MMR_REG: { 726*3cbf4bddSjsg int ret = 0; 727ba393808Sjsg unsigned int n, alloc_size; 728fb4d8502Sjsg uint32_t *regs; 729ba393808Sjsg unsigned int se_num = (info->read_mmr_reg.instance >> 730fb4d8502Sjsg AMDGPU_INFO_MMR_SE_INDEX_SHIFT) & 731fb4d8502Sjsg AMDGPU_INFO_MMR_SE_INDEX_MASK; 732ba393808Sjsg unsigned int sh_num = (info->read_mmr_reg.instance >> 733fb4d8502Sjsg AMDGPU_INFO_MMR_SH_INDEX_SHIFT) & 734fb4d8502Sjsg AMDGPU_INFO_MMR_SH_INDEX_MASK; 735fb4d8502Sjsg 736*3cbf4bddSjsg if (!down_read_trylock(&adev->reset_domain->sem)) 737*3cbf4bddSjsg return -ENOENT; 738*3cbf4bddSjsg 739fb4d8502Sjsg /* set full masks if the userspace set all bits 740ba393808Sjsg * in the bitfields 741ba393808Sjsg */ 742*3cbf4bddSjsg if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) { 743fb4d8502Sjsg se_num = 0xffffffff; 744*3cbf4bddSjsg } else if (se_num >= AMDGPU_GFX_MAX_SE) { 745*3cbf4bddSjsg ret = -EINVAL; 746*3cbf4bddSjsg goto out; 747*3cbf4bddSjsg } 748fb4d8502Sjsg 749*3cbf4bddSjsg if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) { 750*3cbf4bddSjsg sh_num = 0xffffffff; 751*3cbf4bddSjsg } else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) { 752*3cbf4bddSjsg ret = -EINVAL; 753*3cbf4bddSjsg goto out; 754*3cbf4bddSjsg } 755*3cbf4bddSjsg 756*3cbf4bddSjsg if (info->read_mmr_reg.count > 128) { 757*3cbf4bddSjsg ret = -EINVAL; 758*3cbf4bddSjsg goto out; 759*3cbf4bddSjsg } 760a08658d0Sjsg 761fb4d8502Sjsg regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL); 762*3cbf4bddSjsg if (!regs) { 763*3cbf4bddSjsg ret = -ENOMEM; 764*3cbf4bddSjsg goto out; 765*3cbf4bddSjsg } 766*3cbf4bddSjsg 767fb4d8502Sjsg alloc_size = info->read_mmr_reg.count * sizeof(*regs); 768fb4d8502Sjsg 769c349dbc7Sjsg amdgpu_gfx_off_ctrl(adev, false); 770c349dbc7Sjsg for (i = 0; i < info->read_mmr_reg.count; i++) { 771fb4d8502Sjsg if (amdgpu_asic_read_register(adev, se_num, sh_num, 772fb4d8502Sjsg info->read_mmr_reg.dword_offset + i, 773fb4d8502Sjsg ®s[i])) { 774fb4d8502Sjsg DRM_DEBUG_KMS("unallowed offset %#x\n", 775fb4d8502Sjsg info->read_mmr_reg.dword_offset + i); 776fb4d8502Sjsg kfree(regs); 777c349dbc7Sjsg amdgpu_gfx_off_ctrl(adev, true); 778*3cbf4bddSjsg ret = -EFAULT; 779*3cbf4bddSjsg goto out; 780fb4d8502Sjsg } 781c349dbc7Sjsg } 782c349dbc7Sjsg amdgpu_gfx_off_ctrl(adev, true); 783fb4d8502Sjsg n = copy_to_user(out, regs, min(size, alloc_size)); 784fb4d8502Sjsg kfree(regs); 785*3cbf4bddSjsg ret = (n ? -EFAULT : 0); 786*3cbf4bddSjsg out: 787*3cbf4bddSjsg up_read(&adev->reset_domain->sem); 788*3cbf4bddSjsg return ret; 789fb4d8502Sjsg } 790fb4d8502Sjsg case AMDGPU_INFO_DEV_INFO: { 7915ca02815Sjsg struct drm_amdgpu_info_device *dev_info; 792fb4d8502Sjsg uint64_t vm_size; 793f005ef32Sjsg uint32_t pcie_gen_mask; 7945ca02815Sjsg int ret; 795fb4d8502Sjsg 7965ca02815Sjsg dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); 7975ca02815Sjsg if (!dev_info) 7985ca02815Sjsg return -ENOMEM; 7995ca02815Sjsg 8005ca02815Sjsg dev_info->device_id = adev->pdev->device; 8015ca02815Sjsg dev_info->chip_rev = adev->rev_id; 8025ca02815Sjsg dev_info->external_rev = adev->external_rev_id; 8035ca02815Sjsg dev_info->pci_rev = adev->pdev->revision; 8045ca02815Sjsg dev_info->family = adev->family; 8055ca02815Sjsg dev_info->num_shader_engines = adev->gfx.config.max_shader_engines; 8065ca02815Sjsg dev_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se; 807fb4d8502Sjsg /* return all clocks in KHz */ 8085ca02815Sjsg dev_info->gpu_counter_freq = amdgpu_asic_get_xclk(adev) * 10; 809fb4d8502Sjsg if (adev->pm.dpm_enabled) { 8105ca02815Sjsg dev_info->max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10; 8115ca02815Sjsg dev_info->max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10; 812f005ef32Sjsg dev_info->min_engine_clock = amdgpu_dpm_get_sclk(adev, true) * 10; 813f005ef32Sjsg dev_info->min_memory_clock = amdgpu_dpm_get_mclk(adev, true) * 10; 814fb4d8502Sjsg } else { 815f005ef32Sjsg dev_info->max_engine_clock = 816f005ef32Sjsg dev_info->min_engine_clock = 817f005ef32Sjsg adev->clock.default_sclk * 10; 818f005ef32Sjsg dev_info->max_memory_clock = 819f005ef32Sjsg dev_info->min_memory_clock = 820f005ef32Sjsg adev->clock.default_mclk * 10; 821fb4d8502Sjsg } 8225ca02815Sjsg dev_info->enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask; 8235ca02815Sjsg dev_info->num_rb_pipes = adev->gfx.config.max_backends_per_se * 824fb4d8502Sjsg adev->gfx.config.max_shader_engines; 8255ca02815Sjsg dev_info->num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts; 8265ca02815Sjsg dev_info->ids_flags = 0; 827fb4d8502Sjsg if (adev->flags & AMD_IS_APU) 8285ca02815Sjsg dev_info->ids_flags |= AMDGPU_IDS_FLAGS_FUSION; 829f005ef32Sjsg if (adev->gfx.mcbp) 8305ca02815Sjsg dev_info->ids_flags |= AMDGPU_IDS_FLAGS_PREEMPTION; 831ad8b1aafSjsg if (amdgpu_is_tmz(adev)) 8325ca02815Sjsg dev_info->ids_flags |= AMDGPU_IDS_FLAGS_TMZ; 833f005ef32Sjsg if (adev->gfx.config.ta_cntl2_truncate_coord_mode) 834f005ef32Sjsg dev_info->ids_flags |= AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD; 835fb4d8502Sjsg 836fb4d8502Sjsg vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; 837fb4d8502Sjsg vm_size -= AMDGPU_VA_RESERVED_SIZE; 838fb4d8502Sjsg 839fb4d8502Sjsg /* Older VCE FW versions are buggy and can handle only 40bits */ 840c349dbc7Sjsg if (adev->vce.fw_version && 841c349dbc7Sjsg adev->vce.fw_version < AMDGPU_VCE_FW_53_45) 842fb4d8502Sjsg vm_size = min(vm_size, 1ULL << 40); 843fb4d8502Sjsg 8445ca02815Sjsg dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_SIZE; 8455ca02815Sjsg dev_info->virtual_address_max = 846c349dbc7Sjsg min(vm_size, AMDGPU_GMC_HOLE_START); 847fb4d8502Sjsg 848c349dbc7Sjsg if (vm_size > AMDGPU_GMC_HOLE_START) { 8495ca02815Sjsg dev_info->high_va_offset = AMDGPU_GMC_HOLE_END; 8505ca02815Sjsg dev_info->high_va_max = AMDGPU_GMC_HOLE_END | vm_size; 851fb4d8502Sjsg } 8525ca02815Sjsg dev_info->virtual_address_alignment = max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); 8535ca02815Sjsg dev_info->pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE; 8545ca02815Sjsg dev_info->gart_page_size = max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE); 8555ca02815Sjsg dev_info->cu_active_number = adev->gfx.cu_info.number; 8565ca02815Sjsg dev_info->cu_ao_mask = adev->gfx.cu_info.ao_cu_mask; 8575ca02815Sjsg dev_info->ce_ram_size = adev->gfx.ce_ram_size; 8585ca02815Sjsg memcpy(&dev_info->cu_ao_bitmap[0], &adev->gfx.cu_info.ao_cu_bitmap[0], 859fb4d8502Sjsg sizeof(adev->gfx.cu_info.ao_cu_bitmap)); 8605ca02815Sjsg memcpy(&dev_info->cu_bitmap[0], &adev->gfx.cu_info.bitmap[0], 861f005ef32Sjsg sizeof(dev_info->cu_bitmap)); 8625ca02815Sjsg dev_info->vram_type = adev->gmc.vram_type; 8635ca02815Sjsg dev_info->vram_bit_width = adev->gmc.vram_width; 8645ca02815Sjsg dev_info->vce_harvest_config = adev->vce.harvest_config; 8655ca02815Sjsg dev_info->gc_double_offchip_lds_buf = 866fb4d8502Sjsg adev->gfx.config.double_offchip_lds_buf; 8675ca02815Sjsg dev_info->wave_front_size = adev->gfx.cu_info.wave_front_size; 8685ca02815Sjsg dev_info->num_shader_visible_vgprs = adev->gfx.config.max_gprs; 8695ca02815Sjsg dev_info->num_cu_per_sh = adev->gfx.config.max_cu_per_sh; 8705ca02815Sjsg dev_info->num_tcc_blocks = adev->gfx.config.max_texture_channel_caches; 8715ca02815Sjsg dev_info->gs_vgt_table_depth = adev->gfx.config.gs_vgt_table_depth; 8725ca02815Sjsg dev_info->gs_prim_buffer_depth = adev->gfx.config.gs_prim_buffer_depth; 8735ca02815Sjsg dev_info->max_gs_waves_per_vgt = adev->gfx.config.max_gs_threads; 874fb4d8502Sjsg 875c349dbc7Sjsg if (adev->family >= AMDGPU_FAMILY_NV) 8765ca02815Sjsg dev_info->pa_sc_tile_steering_override = 877c349dbc7Sjsg adev->gfx.config.pa_sc_tile_steering_override; 878c349dbc7Sjsg 8795ca02815Sjsg dev_info->tcc_disabled_mask = adev->gfx.config.tcc_disabled_mask; 880c349dbc7Sjsg 881f005ef32Sjsg /* Combine the chip gen mask with the platform (CPU/mobo) mask. */ 882f005ef32Sjsg pcie_gen_mask = adev->pm.pcie_gen_mask & (adev->pm.pcie_gen_mask >> 16); 883f005ef32Sjsg dev_info->pcie_gen = fls(pcie_gen_mask); 884f005ef32Sjsg dev_info->pcie_num_lanes = 885f005ef32Sjsg adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 ? 32 : 886f005ef32Sjsg adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 ? 16 : 887f005ef32Sjsg adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 ? 12 : 888f005ef32Sjsg adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 ? 8 : 889f005ef32Sjsg adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 ? 4 : 890f005ef32Sjsg adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 ? 2 : 1; 891f005ef32Sjsg 892f005ef32Sjsg dev_info->tcp_cache_size = adev->gfx.config.gc_tcp_l1_size; 893f005ef32Sjsg dev_info->num_sqc_per_wgp = adev->gfx.config.gc_num_sqc_per_wgp; 894f005ef32Sjsg dev_info->sqc_data_cache_size = adev->gfx.config.gc_l1_data_cache_size_per_sqc; 895f005ef32Sjsg dev_info->sqc_inst_cache_size = adev->gfx.config.gc_l1_instruction_cache_size_per_sqc; 896f005ef32Sjsg dev_info->gl1c_cache_size = adev->gfx.config.gc_gl1c_size_per_instance * 897f005ef32Sjsg adev->gfx.config.gc_gl1c_per_sa; 898f005ef32Sjsg dev_info->gl2c_cache_size = adev->gfx.config.gc_gl2c_per_gpu; 899f005ef32Sjsg dev_info->mall_size = adev->gmc.mall_size; 900f005ef32Sjsg 901f005ef32Sjsg 902f005ef32Sjsg if (adev->gfx.funcs->get_gfx_shadow_info) { 903f005ef32Sjsg struct amdgpu_gfx_shadow_info shadow_info; 904f005ef32Sjsg 905f005ef32Sjsg ret = amdgpu_gfx_get_gfx_shadow_info(adev, &shadow_info); 906f005ef32Sjsg if (!ret) { 907f005ef32Sjsg dev_info->shadow_size = shadow_info.shadow_size; 908f005ef32Sjsg dev_info->shadow_alignment = shadow_info.shadow_alignment; 909f005ef32Sjsg dev_info->csa_size = shadow_info.csa_size; 910f005ef32Sjsg dev_info->csa_alignment = shadow_info.csa_alignment; 911f005ef32Sjsg } 912f005ef32Sjsg } 913f005ef32Sjsg 9145ca02815Sjsg ret = copy_to_user(out, dev_info, 9155ca02815Sjsg min((size_t)size, sizeof(*dev_info))) ? -EFAULT : 0; 9165ca02815Sjsg kfree(dev_info); 9175ca02815Sjsg return ret; 918fb4d8502Sjsg } 919fb4d8502Sjsg case AMDGPU_INFO_VCE_CLOCK_TABLE: { 920ba393808Sjsg unsigned int i; 921fb4d8502Sjsg struct drm_amdgpu_info_vce_clock_table vce_clk_table = {}; 922fb4d8502Sjsg struct amd_vce_state *vce_state; 923fb4d8502Sjsg 924fb4d8502Sjsg for (i = 0; i < AMDGPU_VCE_CLOCK_TABLE_ENTRIES; i++) { 925fb4d8502Sjsg vce_state = amdgpu_dpm_get_vce_clock_state(adev, i); 926fb4d8502Sjsg if (vce_state) { 927fb4d8502Sjsg vce_clk_table.entries[i].sclk = vce_state->sclk; 928fb4d8502Sjsg vce_clk_table.entries[i].mclk = vce_state->mclk; 929fb4d8502Sjsg vce_clk_table.entries[i].eclk = vce_state->evclk; 930fb4d8502Sjsg vce_clk_table.num_valid_entries++; 931fb4d8502Sjsg } 932fb4d8502Sjsg } 933fb4d8502Sjsg 934fb4d8502Sjsg return copy_to_user(out, &vce_clk_table, 935fb4d8502Sjsg min((size_t)size, sizeof(vce_clk_table))) ? -EFAULT : 0; 936fb4d8502Sjsg } 937fb4d8502Sjsg case AMDGPU_INFO_VBIOS: { 938fb4d8502Sjsg uint32_t bios_size = adev->bios_size; 939fb4d8502Sjsg 940fb4d8502Sjsg switch (info->vbios_info.type) { 941fb4d8502Sjsg case AMDGPU_INFO_VBIOS_SIZE: 942fb4d8502Sjsg return copy_to_user(out, &bios_size, 943fb4d8502Sjsg min((size_t)size, sizeof(bios_size))) 944fb4d8502Sjsg ? -EFAULT : 0; 945fb4d8502Sjsg case AMDGPU_INFO_VBIOS_IMAGE: { 946fb4d8502Sjsg uint8_t *bios; 947fb4d8502Sjsg uint32_t bios_offset = info->vbios_info.offset; 948fb4d8502Sjsg 949fb4d8502Sjsg if (bios_offset >= bios_size) 950fb4d8502Sjsg return -EINVAL; 951fb4d8502Sjsg 952fb4d8502Sjsg bios = adev->bios + bios_offset; 953fb4d8502Sjsg return copy_to_user(out, bios, 954fb4d8502Sjsg min((size_t)size, (size_t)(bios_size - bios_offset))) 955fb4d8502Sjsg ? -EFAULT : 0; 956fb4d8502Sjsg } 9575ca02815Sjsg case AMDGPU_INFO_VBIOS_INFO: { 9585ca02815Sjsg struct drm_amdgpu_info_vbios vbios_info = {}; 9595ca02815Sjsg struct atom_context *atom_context; 9605ca02815Sjsg 9615ca02815Sjsg atom_context = adev->mode_info.atom_context; 96200fba9d1Sjsg if (atom_context) { 96300fba9d1Sjsg memcpy(vbios_info.name, atom_context->name, 96400fba9d1Sjsg sizeof(atom_context->name)); 96500fba9d1Sjsg memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, 96600fba9d1Sjsg sizeof(atom_context->vbios_pn)); 9675ca02815Sjsg vbios_info.version = atom_context->version; 9685ca02815Sjsg memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, 9695ca02815Sjsg sizeof(atom_context->vbios_ver_str)); 97000fba9d1Sjsg memcpy(vbios_info.date, atom_context->date, 97100fba9d1Sjsg sizeof(atom_context->date)); 97200fba9d1Sjsg } 9735ca02815Sjsg 9745ca02815Sjsg return copy_to_user(out, &vbios_info, 9755ca02815Sjsg min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0; 9765ca02815Sjsg } 977fb4d8502Sjsg default: 978fb4d8502Sjsg DRM_DEBUG_KMS("Invalid request %d\n", 979fb4d8502Sjsg info->vbios_info.type); 980fb4d8502Sjsg return -EINVAL; 981fb4d8502Sjsg } 982fb4d8502Sjsg } 983fb4d8502Sjsg case AMDGPU_INFO_NUM_HANDLES: { 984fb4d8502Sjsg struct drm_amdgpu_info_num_handles handle; 985fb4d8502Sjsg 986fb4d8502Sjsg switch (info->query_hw_ip.type) { 987fb4d8502Sjsg case AMDGPU_HW_IP_UVD: 988fb4d8502Sjsg /* Starting Polaris, we support unlimited UVD handles */ 989fb4d8502Sjsg if (adev->asic_type < CHIP_POLARIS10) { 990fb4d8502Sjsg handle.uvd_max_handles = adev->uvd.max_handles; 991fb4d8502Sjsg handle.uvd_used_handles = amdgpu_uvd_used_handles(adev); 992fb4d8502Sjsg 993fb4d8502Sjsg return copy_to_user(out, &handle, 994fb4d8502Sjsg min((size_t)size, sizeof(handle))) ? -EFAULT : 0; 995fb4d8502Sjsg } else { 996fb4d8502Sjsg return -ENODATA; 997fb4d8502Sjsg } 998fb4d8502Sjsg 999fb4d8502Sjsg break; 1000fb4d8502Sjsg default: 1001fb4d8502Sjsg return -EINVAL; 1002fb4d8502Sjsg } 1003fb4d8502Sjsg } 1004fb4d8502Sjsg case AMDGPU_INFO_SENSOR: { 1005fb4d8502Sjsg if (!adev->pm.dpm_enabled) 1006fb4d8502Sjsg return -ENOENT; 1007fb4d8502Sjsg 1008fb4d8502Sjsg switch (info->sensor_info.type) { 1009fb4d8502Sjsg case AMDGPU_INFO_SENSOR_GFX_SCLK: 1010fb4d8502Sjsg /* get sclk in Mhz */ 1011fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1012fb4d8502Sjsg AMDGPU_PP_SENSOR_GFX_SCLK, 1013fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1014fb4d8502Sjsg return -EINVAL; 1015fb4d8502Sjsg } 1016fb4d8502Sjsg ui32 /= 100; 1017fb4d8502Sjsg break; 1018fb4d8502Sjsg case AMDGPU_INFO_SENSOR_GFX_MCLK: 1019fb4d8502Sjsg /* get mclk in Mhz */ 1020fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1021fb4d8502Sjsg AMDGPU_PP_SENSOR_GFX_MCLK, 1022fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1023fb4d8502Sjsg return -EINVAL; 1024fb4d8502Sjsg } 1025fb4d8502Sjsg ui32 /= 100; 1026fb4d8502Sjsg break; 1027fb4d8502Sjsg case AMDGPU_INFO_SENSOR_GPU_TEMP: 1028fb4d8502Sjsg /* get temperature in millidegrees C */ 1029fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1030fb4d8502Sjsg AMDGPU_PP_SENSOR_GPU_TEMP, 1031fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1032fb4d8502Sjsg return -EINVAL; 1033fb4d8502Sjsg } 1034fb4d8502Sjsg break; 1035fb4d8502Sjsg case AMDGPU_INFO_SENSOR_GPU_LOAD: 1036fb4d8502Sjsg /* get GPU load */ 1037fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1038fb4d8502Sjsg AMDGPU_PP_SENSOR_GPU_LOAD, 1039fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1040fb4d8502Sjsg return -EINVAL; 1041fb4d8502Sjsg } 1042fb4d8502Sjsg break; 1043fb4d8502Sjsg case AMDGPU_INFO_SENSOR_GPU_AVG_POWER: 1044fb4d8502Sjsg /* get average GPU power */ 1045fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1046f005ef32Sjsg AMDGPU_PP_SENSOR_GPU_AVG_POWER, 1047fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1048da5a99b8Sjsg /* fall back to input power for backwards compat */ 1049da5a99b8Sjsg if (amdgpu_dpm_read_sensor(adev, 1050da5a99b8Sjsg AMDGPU_PP_SENSOR_GPU_INPUT_POWER, 1051da5a99b8Sjsg (void *)&ui32, &ui32_size)) { 1052fb4d8502Sjsg return -EINVAL; 1053fb4d8502Sjsg } 1054da5a99b8Sjsg } 1055fb4d8502Sjsg ui32 >>= 8; 1056fb4d8502Sjsg break; 1057fb4d8502Sjsg case AMDGPU_INFO_SENSOR_VDDNB: 1058fb4d8502Sjsg /* get VDDNB in millivolts */ 1059fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1060fb4d8502Sjsg AMDGPU_PP_SENSOR_VDDNB, 1061fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1062fb4d8502Sjsg return -EINVAL; 1063fb4d8502Sjsg } 1064fb4d8502Sjsg break; 1065fb4d8502Sjsg case AMDGPU_INFO_SENSOR_VDDGFX: 1066fb4d8502Sjsg /* get VDDGFX in millivolts */ 1067fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1068fb4d8502Sjsg AMDGPU_PP_SENSOR_VDDGFX, 1069fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1070fb4d8502Sjsg return -EINVAL; 1071fb4d8502Sjsg } 1072fb4d8502Sjsg break; 1073fb4d8502Sjsg case AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK: 1074fb4d8502Sjsg /* get stable pstate sclk in Mhz */ 1075fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1076fb4d8502Sjsg AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK, 1077fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1078fb4d8502Sjsg return -EINVAL; 1079fb4d8502Sjsg } 1080fb4d8502Sjsg ui32 /= 100; 1081fb4d8502Sjsg break; 1082fb4d8502Sjsg case AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK: 1083fb4d8502Sjsg /* get stable pstate mclk in Mhz */ 1084fb4d8502Sjsg if (amdgpu_dpm_read_sensor(adev, 1085fb4d8502Sjsg AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK, 1086fb4d8502Sjsg (void *)&ui32, &ui32_size)) { 1087fb4d8502Sjsg return -EINVAL; 1088fb4d8502Sjsg } 1089fb4d8502Sjsg ui32 /= 100; 1090fb4d8502Sjsg break; 1091f005ef32Sjsg case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK: 1092f005ef32Sjsg /* get peak pstate sclk in Mhz */ 1093f005ef32Sjsg if (amdgpu_dpm_read_sensor(adev, 1094f005ef32Sjsg AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK, 1095f005ef32Sjsg (void *)&ui32, &ui32_size)) { 1096f005ef32Sjsg return -EINVAL; 1097f005ef32Sjsg } 1098f005ef32Sjsg ui32 /= 100; 1099f005ef32Sjsg break; 1100f005ef32Sjsg case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK: 1101f005ef32Sjsg /* get peak pstate mclk in Mhz */ 1102f005ef32Sjsg if (amdgpu_dpm_read_sensor(adev, 1103f005ef32Sjsg AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK, 1104f005ef32Sjsg (void *)&ui32, &ui32_size)) { 1105f005ef32Sjsg return -EINVAL; 1106f005ef32Sjsg } 1107f005ef32Sjsg ui32 /= 100; 1108f005ef32Sjsg break; 1109fb4d8502Sjsg default: 1110fb4d8502Sjsg DRM_DEBUG_KMS("Invalid request %d\n", 1111fb4d8502Sjsg info->sensor_info.type); 1112fb4d8502Sjsg return -EINVAL; 1113fb4d8502Sjsg } 1114fb4d8502Sjsg return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; 1115fb4d8502Sjsg } 1116fb4d8502Sjsg case AMDGPU_INFO_VRAM_LOST_COUNTER: 1117fb4d8502Sjsg ui32 = atomic_read(&adev->vram_lost_counter); 1118fb4d8502Sjsg return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0; 1119c349dbc7Sjsg case AMDGPU_INFO_RAS_ENABLED_FEATURES: { 1120c349dbc7Sjsg struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); 1121c349dbc7Sjsg uint64_t ras_mask; 1122c349dbc7Sjsg 1123c349dbc7Sjsg if (!ras) 1124c349dbc7Sjsg return -EINVAL; 11255ca02815Sjsg ras_mask = (uint64_t)adev->ras_enabled << 32 | ras->features; 1126c349dbc7Sjsg 1127c349dbc7Sjsg return copy_to_user(out, &ras_mask, 1128c349dbc7Sjsg min_t(u64, size, sizeof(ras_mask))) ? 1129c349dbc7Sjsg -EFAULT : 0; 1130c349dbc7Sjsg } 11315ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS: { 11325ca02815Sjsg const struct amdgpu_video_codecs *codecs; 11335ca02815Sjsg struct drm_amdgpu_info_video_caps *caps; 11345ca02815Sjsg int r; 11355ca02815Sjsg 1136f005ef32Sjsg if (!adev->asic_funcs->query_video_codecs) 1137f005ef32Sjsg return -EINVAL; 1138f005ef32Sjsg 11395ca02815Sjsg switch (info->video_cap.type) { 11405ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_DECODE: 11415ca02815Sjsg r = amdgpu_asic_query_video_codecs(adev, false, &codecs); 11425ca02815Sjsg if (r) 11435ca02815Sjsg return -EINVAL; 11445ca02815Sjsg break; 11455ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_ENCODE: 11465ca02815Sjsg r = amdgpu_asic_query_video_codecs(adev, true, &codecs); 11475ca02815Sjsg if (r) 11485ca02815Sjsg return -EINVAL; 11495ca02815Sjsg break; 11505ca02815Sjsg default: 11515ca02815Sjsg DRM_DEBUG_KMS("Invalid request %d\n", 11525ca02815Sjsg info->video_cap.type); 11535ca02815Sjsg return -EINVAL; 11545ca02815Sjsg } 11555ca02815Sjsg 11565ca02815Sjsg caps = kzalloc(sizeof(*caps), GFP_KERNEL); 11575ca02815Sjsg if (!caps) 11585ca02815Sjsg return -ENOMEM; 11595ca02815Sjsg 11605ca02815Sjsg for (i = 0; i < codecs->codec_count; i++) { 11615ca02815Sjsg int idx = codecs->codec_array[i].codec_type; 11625ca02815Sjsg 11635ca02815Sjsg switch (idx) { 11645ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2: 11655ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4: 11665ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1: 11675ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC: 11685ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC: 11695ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG: 11705ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9: 11715ca02815Sjsg case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1: 11725ca02815Sjsg caps->codec_info[idx].valid = 1; 11735ca02815Sjsg caps->codec_info[idx].max_width = 11745ca02815Sjsg codecs->codec_array[i].max_width; 11755ca02815Sjsg caps->codec_info[idx].max_height = 11765ca02815Sjsg codecs->codec_array[i].max_height; 11775ca02815Sjsg caps->codec_info[idx].max_pixels_per_frame = 11785ca02815Sjsg codecs->codec_array[i].max_pixels_per_frame; 11795ca02815Sjsg caps->codec_info[idx].max_level = 11805ca02815Sjsg codecs->codec_array[i].max_level; 11815ca02815Sjsg break; 11825ca02815Sjsg default: 11835ca02815Sjsg break; 11845ca02815Sjsg } 11855ca02815Sjsg } 11865ca02815Sjsg r = copy_to_user(out, caps, 11875ca02815Sjsg min((size_t)size, sizeof(*caps))) ? -EFAULT : 0; 11885ca02815Sjsg kfree(caps); 11895ca02815Sjsg return r; 11905ca02815Sjsg } 1191f005ef32Sjsg case AMDGPU_INFO_MAX_IBS: { 1192f005ef32Sjsg uint32_t max_ibs[AMDGPU_HW_IP_NUM]; 1193f005ef32Sjsg 1194f005ef32Sjsg for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) 1195f005ef32Sjsg max_ibs[i] = amdgpu_ring_max_ibs(i); 1196f005ef32Sjsg 1197f005ef32Sjsg return copy_to_user(out, max_ibs, 1198f005ef32Sjsg min((size_t)size, sizeof(max_ibs))) ? -EFAULT : 0; 1199f005ef32Sjsg } 1200fb4d8502Sjsg default: 1201fb4d8502Sjsg DRM_DEBUG_KMS("Invalid request %d\n", info->query); 1202fb4d8502Sjsg return -EINVAL; 1203fb4d8502Sjsg } 1204fb4d8502Sjsg return 0; 1205fb4d8502Sjsg } 1206fb4d8502Sjsg 1207fb4d8502Sjsg 1208fb4d8502Sjsg /* 1209fb4d8502Sjsg * Outdated mess for old drm with Xorg being in charge (void function now). 1210fb4d8502Sjsg */ 1211fb4d8502Sjsg /** 1212fb4d8502Sjsg * amdgpu_driver_lastclose_kms - drm callback for last close 1213fb4d8502Sjsg * 1214fb4d8502Sjsg * @dev: drm dev pointer 1215fb4d8502Sjsg * 1216fb4d8502Sjsg * Switch vga_switcheroo state after last close (all asics). 1217fb4d8502Sjsg */ 1218fb4d8502Sjsg void amdgpu_driver_lastclose_kms(struct drm_device *dev) 1219fb4d8502Sjsg { 1220fb4d8502Sjsg drm_fb_helper_lastclose(dev); 1221fb4d8502Sjsg vga_switcheroo_process_delayed_switch(); 1222fb4d8502Sjsg } 1223fb4d8502Sjsg 1224fb4d8502Sjsg /** 1225fb4d8502Sjsg * amdgpu_driver_open_kms - drm callback for open 1226fb4d8502Sjsg * 1227fb4d8502Sjsg * @dev: drm dev pointer 1228fb4d8502Sjsg * @file_priv: drm file 1229fb4d8502Sjsg * 1230fb4d8502Sjsg * On device open, init vm on cayman+ (all asics). 1231fb4d8502Sjsg * Returns 0 on success, error on failure. 1232fb4d8502Sjsg */ 1233fb4d8502Sjsg int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) 1234fb4d8502Sjsg { 1235ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 1236fb4d8502Sjsg struct amdgpu_fpriv *fpriv; 1237fb4d8502Sjsg int r, pasid; 1238fb4d8502Sjsg 1239fb4d8502Sjsg /* Ensure IB tests are run on ring */ 1240c349dbc7Sjsg flush_delayed_work(&adev->delayed_init_work); 1241c349dbc7Sjsg 1242c349dbc7Sjsg 1243c349dbc7Sjsg if (amdgpu_ras_intr_triggered()) { 1244c349dbc7Sjsg DRM_ERROR("RAS Intr triggered, device disabled!!"); 1245c349dbc7Sjsg return -EHWPOISON; 1246c349dbc7Sjsg } 1247fb4d8502Sjsg 1248fb4d8502Sjsg file_priv->driver_priv = NULL; 1249fb4d8502Sjsg 1250fb4d8502Sjsg r = pm_runtime_get_sync(dev->dev); 1251fb4d8502Sjsg if (r < 0) 1252ad8b1aafSjsg goto pm_put; 1253fb4d8502Sjsg 1254fb4d8502Sjsg fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); 1255fb4d8502Sjsg if (unlikely(!fpriv)) { 1256fb4d8502Sjsg r = -ENOMEM; 1257fb4d8502Sjsg goto out_suspend; 1258fb4d8502Sjsg } 1259fb4d8502Sjsg 1260fb4d8502Sjsg pasid = amdgpu_pasid_alloc(16); 1261fb4d8502Sjsg if (pasid < 0) { 1262fb4d8502Sjsg dev_warn(adev->dev, "No more PASIDs available!"); 1263fb4d8502Sjsg pasid = 0; 1264fb4d8502Sjsg } 12655ca02815Sjsg 1266f005ef32Sjsg r = amdgpu_xcp_open_device(adev, fpriv, file_priv); 1267f005ef32Sjsg if (r) 1268f005ef32Sjsg goto error_pasid; 1269f005ef32Sjsg 1270f005ef32Sjsg r = amdgpu_vm_init(adev, &fpriv->vm, fpriv->xcp_id); 1271fb4d8502Sjsg if (r) 1272fb4d8502Sjsg goto error_pasid; 1273fb4d8502Sjsg 12745ca02815Sjsg r = amdgpu_vm_set_pasid(adev, &fpriv->vm, pasid); 12755ca02815Sjsg if (r) 12765ca02815Sjsg goto error_vm; 12775ca02815Sjsg 1278fb4d8502Sjsg fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL); 1279fb4d8502Sjsg if (!fpriv->prt_va) { 1280fb4d8502Sjsg r = -ENOMEM; 1281fb4d8502Sjsg goto error_vm; 1282fb4d8502Sjsg } 1283fb4d8502Sjsg 1284f005ef32Sjsg if (adev->gfx.mcbp) { 1285c349dbc7Sjsg uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK; 1286c349dbc7Sjsg 1287c349dbc7Sjsg r = amdgpu_map_static_csa(adev, &fpriv->vm, adev->virt.csa_obj, 1288c349dbc7Sjsg &fpriv->csa_va, csa_addr, AMDGPU_CSA_SIZE); 1289fb4d8502Sjsg if (r) 1290fb4d8502Sjsg goto error_vm; 1291fb4d8502Sjsg } 1292fb4d8502Sjsg 1293fb4d8502Sjsg rw_init(&fpriv->bo_list_lock, "agbo"); 12941bb76ff1Sjsg idr_init_base(&fpriv->bo_list_handles, 1); 1295fb4d8502Sjsg 12961bb76ff1Sjsg amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev); 1297fb4d8502Sjsg 1298fb4d8502Sjsg file_priv->driver_priv = fpriv; 1299fb4d8502Sjsg goto out_suspend; 1300fb4d8502Sjsg 1301fb4d8502Sjsg error_vm: 1302fb4d8502Sjsg amdgpu_vm_fini(adev, &fpriv->vm); 1303fb4d8502Sjsg 1304fb4d8502Sjsg error_pasid: 13055ca02815Sjsg if (pasid) { 1306fb4d8502Sjsg amdgpu_pasid_free(pasid); 13075ca02815Sjsg amdgpu_vm_set_pasid(adev, &fpriv->vm, 0); 13085ca02815Sjsg } 1309fb4d8502Sjsg 1310fb4d8502Sjsg kfree(fpriv); 1311fb4d8502Sjsg 1312fb4d8502Sjsg out_suspend: 1313fb4d8502Sjsg pm_runtime_mark_last_busy(dev->dev); 1314ad8b1aafSjsg pm_put: 1315fb4d8502Sjsg pm_runtime_put_autosuspend(dev->dev); 1316fb4d8502Sjsg 1317fb4d8502Sjsg return r; 1318fb4d8502Sjsg } 1319fb4d8502Sjsg 1320fb4d8502Sjsg /** 1321fb4d8502Sjsg * amdgpu_driver_postclose_kms - drm callback for post close 1322fb4d8502Sjsg * 1323fb4d8502Sjsg * @dev: drm dev pointer 1324fb4d8502Sjsg * @file_priv: drm file 1325fb4d8502Sjsg * 1326fb4d8502Sjsg * On device post close, tear down vm on cayman+ (all asics). 1327fb4d8502Sjsg */ 1328fb4d8502Sjsg void amdgpu_driver_postclose_kms(struct drm_device *dev, 1329fb4d8502Sjsg struct drm_file *file_priv) 1330fb4d8502Sjsg { 1331ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 1332fb4d8502Sjsg struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 1333fb4d8502Sjsg struct amdgpu_bo_list *list; 1334fb4d8502Sjsg struct amdgpu_bo *pd; 1335ad8b1aafSjsg u32 pasid; 1336fb4d8502Sjsg int handle; 1337fb4d8502Sjsg 1338fb4d8502Sjsg if (!fpriv) 1339fb4d8502Sjsg return; 1340fb4d8502Sjsg 1341fb4d8502Sjsg pm_runtime_get_sync(dev->dev); 1342fb4d8502Sjsg 1343607884a3Sjsg if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_UVD) != NULL) 1344fb4d8502Sjsg amdgpu_uvd_free_handles(adev, file_priv); 1345607884a3Sjsg if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL) 1346fb4d8502Sjsg amdgpu_vce_free_handles(adev, file_priv); 1347fb4d8502Sjsg 1348f005ef32Sjsg if (fpriv->csa_va) { 1349f005ef32Sjsg uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK; 1350f005ef32Sjsg 1351f005ef32Sjsg WARN_ON(amdgpu_unmap_static_csa(adev, &fpriv->vm, adev->virt.csa_obj, 1352f005ef32Sjsg fpriv->csa_va, csa_addr)); 1353fb4d8502Sjsg fpriv->csa_va = NULL; 1354fb4d8502Sjsg } 1355fb4d8502Sjsg 1356fb4d8502Sjsg pasid = fpriv->vm.pasid; 13575ca02815Sjsg pd = amdgpu_bo_ref(fpriv->vm.root.bo); 13581bb76ff1Sjsg if (!WARN_ON(amdgpu_bo_reserve(pd, true))) { 13591bb76ff1Sjsg amdgpu_vm_bo_del(adev, fpriv->prt_va); 13601bb76ff1Sjsg amdgpu_bo_unreserve(pd); 13611bb76ff1Sjsg } 1362fb4d8502Sjsg 1363fb4d8502Sjsg amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr); 1364c349dbc7Sjsg amdgpu_vm_fini(adev, &fpriv->vm); 1365fb4d8502Sjsg 1366fb4d8502Sjsg if (pasid) 1367c349dbc7Sjsg amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid); 1368fb4d8502Sjsg amdgpu_bo_unref(&pd); 1369fb4d8502Sjsg 1370fb4d8502Sjsg idr_for_each_entry(&fpriv->bo_list_handles, list, handle) 1371fb4d8502Sjsg amdgpu_bo_list_put(list); 1372fb4d8502Sjsg 1373fb4d8502Sjsg idr_destroy(&fpriv->bo_list_handles); 1374fb4d8502Sjsg mutex_destroy(&fpriv->bo_list_lock); 1375fb4d8502Sjsg 1376fb4d8502Sjsg kfree(fpriv); 1377fb4d8502Sjsg file_priv->driver_priv = NULL; 1378fb4d8502Sjsg 1379fb4d8502Sjsg pm_runtime_mark_last_busy(dev->dev); 1380fb4d8502Sjsg pm_runtime_put_autosuspend(dev->dev); 1381fb4d8502Sjsg } 1382fb4d8502Sjsg 13835ca02815Sjsg 13845ca02815Sjsg void amdgpu_driver_release_kms(struct drm_device *dev) 13855ca02815Sjsg { 13865ca02815Sjsg struct amdgpu_device *adev = drm_to_adev(dev); 13875ca02815Sjsg 13885ca02815Sjsg amdgpu_device_fini_sw(adev); 13895ca02815Sjsg pci_set_drvdata(adev->pdev, NULL); 13905ca02815Sjsg } 13915ca02815Sjsg 1392fb4d8502Sjsg /* 1393fb4d8502Sjsg * VBlank related functions. 1394fb4d8502Sjsg */ 1395fb4d8502Sjsg /** 1396fb4d8502Sjsg * amdgpu_get_vblank_counter_kms - get frame count 1397fb4d8502Sjsg * 1398c349dbc7Sjsg * @crtc: crtc to get the frame count from 1399fb4d8502Sjsg * 1400fb4d8502Sjsg * Gets the frame count on the requested crtc (all asics). 1401fb4d8502Sjsg * Returns frame count on success, -EINVAL on failure. 1402fb4d8502Sjsg */ 1403c349dbc7Sjsg u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc) 1404fb4d8502Sjsg { 1405c349dbc7Sjsg struct drm_device *dev = crtc->dev; 1406c349dbc7Sjsg unsigned int pipe = crtc->index; 1407ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 1408fb4d8502Sjsg int vpos, hpos, stat; 1409fb4d8502Sjsg u32 count; 1410fb4d8502Sjsg 1411fb4d8502Sjsg if (pipe >= adev->mode_info.num_crtc) { 1412fb4d8502Sjsg DRM_ERROR("Invalid crtc %u\n", pipe); 1413fb4d8502Sjsg return -EINVAL; 1414fb4d8502Sjsg } 1415fb4d8502Sjsg 1416fb4d8502Sjsg /* The hw increments its frame counter at start of vsync, not at start 1417fb4d8502Sjsg * of vblank, as is required by DRM core vblank counter handling. 1418fb4d8502Sjsg * Cook the hw count here to make it appear to the caller as if it 1419fb4d8502Sjsg * incremented at start of vblank. We measure distance to start of 1420fb4d8502Sjsg * vblank in vpos. vpos therefore will be >= 0 between start of vblank 1421fb4d8502Sjsg * and start of vsync, so vpos >= 0 means to bump the hw frame counter 1422fb4d8502Sjsg * result by 1 to give the proper appearance to caller. 1423fb4d8502Sjsg */ 1424fb4d8502Sjsg if (adev->mode_info.crtcs[pipe]) { 1425fb4d8502Sjsg /* Repeat readout if needed to provide stable result if 1426fb4d8502Sjsg * we cross start of vsync during the queries. 1427fb4d8502Sjsg */ 1428fb4d8502Sjsg do { 1429fb4d8502Sjsg count = amdgpu_display_vblank_get_counter(adev, pipe); 1430fb4d8502Sjsg /* Ask amdgpu_display_get_crtc_scanoutpos to return 1431fb4d8502Sjsg * vpos as distance to start of vblank, instead of 1432fb4d8502Sjsg * regular vertical scanout pos. 1433fb4d8502Sjsg */ 1434fb4d8502Sjsg stat = amdgpu_display_get_crtc_scanoutpos( 1435fb4d8502Sjsg dev, pipe, GET_DISTANCE_TO_VBLANKSTART, 1436fb4d8502Sjsg &vpos, &hpos, NULL, NULL, 1437fb4d8502Sjsg &adev->mode_info.crtcs[pipe]->base.hwmode); 1438fb4d8502Sjsg } while (count != amdgpu_display_vblank_get_counter(adev, pipe)); 1439fb4d8502Sjsg 1440fb4d8502Sjsg if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) != 1441fb4d8502Sjsg (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) { 1442fb4d8502Sjsg DRM_DEBUG_VBL("Query failed! stat %d\n", stat); 1443fb4d8502Sjsg } else { 1444fb4d8502Sjsg DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n", 1445fb4d8502Sjsg pipe, vpos); 1446fb4d8502Sjsg 1447fb4d8502Sjsg /* Bump counter if we are at >= leading edge of vblank, 1448fb4d8502Sjsg * but before vsync where vpos would turn negative and 1449fb4d8502Sjsg * the hw counter really increments. 1450fb4d8502Sjsg */ 1451fb4d8502Sjsg if (vpos >= 0) 1452fb4d8502Sjsg count++; 1453fb4d8502Sjsg } 1454fb4d8502Sjsg } else { 1455fb4d8502Sjsg /* Fallback to use value as is. */ 1456fb4d8502Sjsg count = amdgpu_display_vblank_get_counter(adev, pipe); 1457fb4d8502Sjsg DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n"); 1458fb4d8502Sjsg } 1459fb4d8502Sjsg 1460fb4d8502Sjsg return count; 1461fb4d8502Sjsg } 1462fb4d8502Sjsg 1463fb4d8502Sjsg /** 1464fb4d8502Sjsg * amdgpu_enable_vblank_kms - enable vblank interrupt 1465fb4d8502Sjsg * 1466c349dbc7Sjsg * @crtc: crtc to enable vblank interrupt for 1467fb4d8502Sjsg * 1468fb4d8502Sjsg * Enable the interrupt on the requested crtc (all asics). 1469fb4d8502Sjsg * Returns 0 on success, -EINVAL on failure. 1470fb4d8502Sjsg */ 1471c349dbc7Sjsg int amdgpu_enable_vblank_kms(struct drm_crtc *crtc) 1472fb4d8502Sjsg { 1473c349dbc7Sjsg struct drm_device *dev = crtc->dev; 1474c349dbc7Sjsg unsigned int pipe = crtc->index; 1475ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 1476fb4d8502Sjsg int idx = amdgpu_display_crtc_idx_to_irq_type(adev, pipe); 1477fb4d8502Sjsg 1478fb4d8502Sjsg return amdgpu_irq_get(adev, &adev->crtc_irq, idx); 1479fb4d8502Sjsg } 1480fb4d8502Sjsg 1481fb4d8502Sjsg /** 1482fb4d8502Sjsg * amdgpu_disable_vblank_kms - disable vblank interrupt 1483fb4d8502Sjsg * 1484c349dbc7Sjsg * @crtc: crtc to disable vblank interrupt for 1485fb4d8502Sjsg * 1486fb4d8502Sjsg * Disable the interrupt on the requested crtc (all asics). 1487fb4d8502Sjsg */ 1488c349dbc7Sjsg void amdgpu_disable_vblank_kms(struct drm_crtc *crtc) 1489fb4d8502Sjsg { 1490c349dbc7Sjsg struct drm_device *dev = crtc->dev; 1491c349dbc7Sjsg unsigned int pipe = crtc->index; 1492ad8b1aafSjsg struct amdgpu_device *adev = drm_to_adev(dev); 1493fb4d8502Sjsg int idx = amdgpu_display_crtc_idx_to_irq_type(adev, pipe); 1494fb4d8502Sjsg 1495fb4d8502Sjsg amdgpu_irq_put(adev, &adev->crtc_irq, idx); 1496fb4d8502Sjsg } 1497fb4d8502Sjsg 1498fb4d8502Sjsg /* 1499fb4d8502Sjsg * Debugfs info 1500fb4d8502Sjsg */ 1501fb4d8502Sjsg #if defined(CONFIG_DEBUG_FS) 1502fb4d8502Sjsg 15035ca02815Sjsg static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused) 1504fb4d8502Sjsg { 1505f005ef32Sjsg struct amdgpu_device *adev = m->private; 1506fb4d8502Sjsg struct drm_amdgpu_info_firmware fw_info; 1507fb4d8502Sjsg struct drm_amdgpu_query_fw query_fw; 1508fb4d8502Sjsg struct atom_context *ctx = adev->mode_info.atom_context; 15091bb76ff1Sjsg uint8_t smu_program, smu_major, smu_minor, smu_debug; 1510fb4d8502Sjsg int ret, i; 1511fb4d8502Sjsg 15125ca02815Sjsg static const char *ta_fw_name[TA_FW_TYPE_MAX_INDEX] = { 15135ca02815Sjsg #define TA_FW_NAME(type)[TA_FW_TYPE_PSP_##type] = #type 15145ca02815Sjsg TA_FW_NAME(XGMI), 15155ca02815Sjsg TA_FW_NAME(RAS), 15165ca02815Sjsg TA_FW_NAME(HDCP), 15175ca02815Sjsg TA_FW_NAME(DTM), 15185ca02815Sjsg TA_FW_NAME(RAP), 15195ca02815Sjsg TA_FW_NAME(SECUREDISPLAY), 15205ca02815Sjsg #undef TA_FW_NAME 15215ca02815Sjsg }; 15225ca02815Sjsg 1523fb4d8502Sjsg /* VCE */ 1524fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_VCE; 1525fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1526fb4d8502Sjsg if (ret) 1527fb4d8502Sjsg return ret; 1528fb4d8502Sjsg seq_printf(m, "VCE feature version: %u, firmware version: 0x%08x\n", 1529fb4d8502Sjsg fw_info.feature, fw_info.ver); 1530fb4d8502Sjsg 1531fb4d8502Sjsg /* UVD */ 1532fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_UVD; 1533fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1534fb4d8502Sjsg if (ret) 1535fb4d8502Sjsg return ret; 1536fb4d8502Sjsg seq_printf(m, "UVD feature version: %u, firmware version: 0x%08x\n", 1537fb4d8502Sjsg fw_info.feature, fw_info.ver); 1538fb4d8502Sjsg 1539fb4d8502Sjsg /* GMC */ 1540fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GMC; 1541fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1542fb4d8502Sjsg if (ret) 1543fb4d8502Sjsg return ret; 1544fb4d8502Sjsg seq_printf(m, "MC feature version: %u, firmware version: 0x%08x\n", 1545fb4d8502Sjsg fw_info.feature, fw_info.ver); 1546fb4d8502Sjsg 1547fb4d8502Sjsg /* ME */ 1548fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_ME; 1549fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1550fb4d8502Sjsg if (ret) 1551fb4d8502Sjsg return ret; 1552fb4d8502Sjsg seq_printf(m, "ME feature version: %u, firmware version: 0x%08x\n", 1553fb4d8502Sjsg fw_info.feature, fw_info.ver); 1554fb4d8502Sjsg 1555fb4d8502Sjsg /* PFP */ 1556fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_PFP; 1557fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1558fb4d8502Sjsg if (ret) 1559fb4d8502Sjsg return ret; 1560fb4d8502Sjsg seq_printf(m, "PFP feature version: %u, firmware version: 0x%08x\n", 1561fb4d8502Sjsg fw_info.feature, fw_info.ver); 1562fb4d8502Sjsg 1563fb4d8502Sjsg /* CE */ 1564fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_CE; 1565fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1566fb4d8502Sjsg if (ret) 1567fb4d8502Sjsg return ret; 1568fb4d8502Sjsg seq_printf(m, "CE feature version: %u, firmware version: 0x%08x\n", 1569fb4d8502Sjsg fw_info.feature, fw_info.ver); 1570fb4d8502Sjsg 1571fb4d8502Sjsg /* RLC */ 1572fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC; 1573fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1574fb4d8502Sjsg if (ret) 1575fb4d8502Sjsg return ret; 1576fb4d8502Sjsg seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n", 1577fb4d8502Sjsg fw_info.feature, fw_info.ver); 1578fb4d8502Sjsg 1579fb4d8502Sjsg /* RLC SAVE RESTORE LIST CNTL */ 1580fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL; 1581fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1582fb4d8502Sjsg if (ret) 1583fb4d8502Sjsg return ret; 1584fb4d8502Sjsg seq_printf(m, "RLC SRLC feature version: %u, firmware version: 0x%08x\n", 1585fb4d8502Sjsg fw_info.feature, fw_info.ver); 1586fb4d8502Sjsg 1587fb4d8502Sjsg /* RLC SAVE RESTORE LIST GPM MEM */ 1588fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM; 1589fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1590fb4d8502Sjsg if (ret) 1591fb4d8502Sjsg return ret; 1592fb4d8502Sjsg seq_printf(m, "RLC SRLG feature version: %u, firmware version: 0x%08x\n", 1593fb4d8502Sjsg fw_info.feature, fw_info.ver); 1594fb4d8502Sjsg 1595fb4d8502Sjsg /* RLC SAVE RESTORE LIST SRM MEM */ 1596fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM; 1597fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1598fb4d8502Sjsg if (ret) 1599fb4d8502Sjsg return ret; 1600fb4d8502Sjsg seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n", 1601fb4d8502Sjsg fw_info.feature, fw_info.ver); 1602fb4d8502Sjsg 16031bb76ff1Sjsg /* RLCP */ 16041bb76ff1Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCP; 16051bb76ff1Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 16061bb76ff1Sjsg if (ret) 16071bb76ff1Sjsg return ret; 16081bb76ff1Sjsg seq_printf(m, "RLCP feature version: %u, firmware version: 0x%08x\n", 16091bb76ff1Sjsg fw_info.feature, fw_info.ver); 16101bb76ff1Sjsg 16111bb76ff1Sjsg /* RLCV */ 16121bb76ff1Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCV; 16131bb76ff1Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 16141bb76ff1Sjsg if (ret) 16151bb76ff1Sjsg return ret; 16161bb76ff1Sjsg seq_printf(m, "RLCV feature version: %u, firmware version: 0x%08x\n", 16171bb76ff1Sjsg fw_info.feature, fw_info.ver); 16181bb76ff1Sjsg 1619fb4d8502Sjsg /* MEC */ 1620fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC; 1621fb4d8502Sjsg query_fw.index = 0; 1622fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1623fb4d8502Sjsg if (ret) 1624fb4d8502Sjsg return ret; 1625fb4d8502Sjsg seq_printf(m, "MEC feature version: %u, firmware version: 0x%08x\n", 1626fb4d8502Sjsg fw_info.feature, fw_info.ver); 1627fb4d8502Sjsg 1628fb4d8502Sjsg /* MEC2 */ 1629ad8b1aafSjsg if (adev->gfx.mec2_fw) { 1630fb4d8502Sjsg query_fw.index = 1; 1631fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1632fb4d8502Sjsg if (ret) 1633fb4d8502Sjsg return ret; 1634fb4d8502Sjsg seq_printf(m, "MEC2 feature version: %u, firmware version: 0x%08x\n", 1635fb4d8502Sjsg fw_info.feature, fw_info.ver); 1636fb4d8502Sjsg } 1637fb4d8502Sjsg 16381bb76ff1Sjsg /* IMU */ 16391bb76ff1Sjsg query_fw.fw_type = AMDGPU_INFO_FW_IMU; 16401bb76ff1Sjsg query_fw.index = 0; 16411bb76ff1Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 16421bb76ff1Sjsg if (ret) 16431bb76ff1Sjsg return ret; 16441bb76ff1Sjsg seq_printf(m, "IMU feature version: %u, firmware version: 0x%08x\n", 16451bb76ff1Sjsg fw_info.feature, fw_info.ver); 16461bb76ff1Sjsg 1647fb4d8502Sjsg /* PSP SOS */ 1648fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_SOS; 1649fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1650fb4d8502Sjsg if (ret) 1651fb4d8502Sjsg return ret; 1652fb4d8502Sjsg seq_printf(m, "SOS feature version: %u, firmware version: 0x%08x\n", 1653fb4d8502Sjsg fw_info.feature, fw_info.ver); 1654fb4d8502Sjsg 1655fb4d8502Sjsg 1656fb4d8502Sjsg /* PSP ASD */ 1657fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_ASD; 1658fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1659fb4d8502Sjsg if (ret) 1660fb4d8502Sjsg return ret; 1661fb4d8502Sjsg seq_printf(m, "ASD feature version: %u, firmware version: 0x%08x\n", 1662fb4d8502Sjsg fw_info.feature, fw_info.ver); 1663fb4d8502Sjsg 1664c349dbc7Sjsg query_fw.fw_type = AMDGPU_INFO_FW_TA; 16655ca02815Sjsg for (i = TA_FW_TYPE_PSP_XGMI; i < TA_FW_TYPE_MAX_INDEX; i++) { 1666c349dbc7Sjsg query_fw.index = i; 1667c349dbc7Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1668c349dbc7Sjsg if (ret) 1669c349dbc7Sjsg continue; 16705ca02815Sjsg 1671ad8b1aafSjsg seq_printf(m, "TA %s feature version: 0x%08x, firmware version: 0x%08x\n", 16725ca02815Sjsg ta_fw_name[i], fw_info.feature, fw_info.ver); 1673c349dbc7Sjsg } 1674c349dbc7Sjsg 1675fb4d8502Sjsg /* SMC */ 1676fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_SMC; 1677fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1678fb4d8502Sjsg if (ret) 1679fb4d8502Sjsg return ret; 16801bb76ff1Sjsg smu_program = (fw_info.ver >> 24) & 0xff; 16811bb76ff1Sjsg smu_major = (fw_info.ver >> 16) & 0xff; 16821bb76ff1Sjsg smu_minor = (fw_info.ver >> 8) & 0xff; 16831bb76ff1Sjsg smu_debug = (fw_info.ver >> 0) & 0xff; 16841bb76ff1Sjsg seq_printf(m, "SMC feature version: %u, program: %d, firmware version: 0x%08x (%d.%d.%d)\n", 16851bb76ff1Sjsg fw_info.feature, smu_program, fw_info.ver, smu_major, smu_minor, smu_debug); 1686fb4d8502Sjsg 1687fb4d8502Sjsg /* SDMA */ 1688fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_SDMA; 1689fb4d8502Sjsg for (i = 0; i < adev->sdma.num_instances; i++) { 1690fb4d8502Sjsg query_fw.index = i; 1691fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1692fb4d8502Sjsg if (ret) 1693fb4d8502Sjsg return ret; 1694fb4d8502Sjsg seq_printf(m, "SDMA%d feature version: %u, firmware version: 0x%08x\n", 1695fb4d8502Sjsg i, fw_info.feature, fw_info.ver); 1696fb4d8502Sjsg } 1697fb4d8502Sjsg 1698fb4d8502Sjsg /* VCN */ 1699fb4d8502Sjsg query_fw.fw_type = AMDGPU_INFO_FW_VCN; 1700fb4d8502Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1701fb4d8502Sjsg if (ret) 1702fb4d8502Sjsg return ret; 1703fb4d8502Sjsg seq_printf(m, "VCN feature version: %u, firmware version: 0x%08x\n", 1704fb4d8502Sjsg fw_info.feature, fw_info.ver); 1705fb4d8502Sjsg 1706c349dbc7Sjsg /* DMCU */ 1707c349dbc7Sjsg query_fw.fw_type = AMDGPU_INFO_FW_DMCU; 1708c349dbc7Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1709c349dbc7Sjsg if (ret) 1710c349dbc7Sjsg return ret; 1711c349dbc7Sjsg seq_printf(m, "DMCU feature version: %u, firmware version: 0x%08x\n", 1712c349dbc7Sjsg fw_info.feature, fw_info.ver); 1713c349dbc7Sjsg 1714c349dbc7Sjsg /* DMCUB */ 1715c349dbc7Sjsg query_fw.fw_type = AMDGPU_INFO_FW_DMCUB; 1716c349dbc7Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 1717c349dbc7Sjsg if (ret) 1718c349dbc7Sjsg return ret; 1719c349dbc7Sjsg seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n", 1720c349dbc7Sjsg fw_info.feature, fw_info.ver); 1721c349dbc7Sjsg 17225ca02815Sjsg /* TOC */ 17235ca02815Sjsg query_fw.fw_type = AMDGPU_INFO_FW_TOC; 17245ca02815Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 17255ca02815Sjsg if (ret) 17265ca02815Sjsg return ret; 17275ca02815Sjsg seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n", 17285ca02815Sjsg fw_info.feature, fw_info.ver); 1729fb4d8502Sjsg 17301bb76ff1Sjsg /* CAP */ 17311bb76ff1Sjsg if (adev->psp.cap_fw) { 17321bb76ff1Sjsg query_fw.fw_type = AMDGPU_INFO_FW_CAP; 17331bb76ff1Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 17341bb76ff1Sjsg if (ret) 17351bb76ff1Sjsg return ret; 17361bb76ff1Sjsg seq_printf(m, "CAP feature version: %u, firmware version: 0x%08x\n", 17371bb76ff1Sjsg fw_info.feature, fw_info.ver); 17381bb76ff1Sjsg } 17391bb76ff1Sjsg 17401bb76ff1Sjsg /* MES_KIQ */ 17411bb76ff1Sjsg query_fw.fw_type = AMDGPU_INFO_FW_MES_KIQ; 17421bb76ff1Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 17431bb76ff1Sjsg if (ret) 17441bb76ff1Sjsg return ret; 17451bb76ff1Sjsg seq_printf(m, "MES_KIQ feature version: %u, firmware version: 0x%08x\n", 17461bb76ff1Sjsg fw_info.feature, fw_info.ver); 17471bb76ff1Sjsg 17481bb76ff1Sjsg /* MES */ 17491bb76ff1Sjsg query_fw.fw_type = AMDGPU_INFO_FW_MES; 17501bb76ff1Sjsg ret = amdgpu_firmware_info(&fw_info, &query_fw, adev); 17511bb76ff1Sjsg if (ret) 17521bb76ff1Sjsg return ret; 17531bb76ff1Sjsg seq_printf(m, "MES feature version: %u, firmware version: 0x%08x\n", 17541bb76ff1Sjsg fw_info.feature, fw_info.ver); 17551bb76ff1Sjsg 1756f005ef32Sjsg seq_printf(m, "VBIOS version: %s\n", ctx->vbios_pn); 1757fb4d8502Sjsg 1758fb4d8502Sjsg return 0; 1759fb4d8502Sjsg } 1760fb4d8502Sjsg 17615ca02815Sjsg DEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_firmware_info); 17625ca02815Sjsg 1763fb4d8502Sjsg #endif 1764fb4d8502Sjsg 17655ca02815Sjsg void amdgpu_debugfs_firmware_init(struct amdgpu_device *adev) 1766fb4d8502Sjsg { 1767fb4d8502Sjsg #if defined(CONFIG_DEBUG_FS) 17685ca02815Sjsg struct drm_minor *minor = adev_to_drm(adev)->primary; 17695ca02815Sjsg struct dentry *root = minor->debugfs_root; 17705ca02815Sjsg 17715ca02815Sjsg debugfs_create_file("amdgpu_firmware_info", 0444, root, 17725ca02815Sjsg adev, &amdgpu_debugfs_firmware_info_fops); 17735ca02815Sjsg 1774fb4d8502Sjsg #endif 1775fb4d8502Sjsg } 1776