162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright 2008 Advanced Micro Devices, Inc.
362306a36Sopenharmony_ci * Copyright 2008 Red Hat Inc.
462306a36Sopenharmony_ci * Copyright 2009 Jerome Glisse.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
762306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
862306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
962306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1062306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
1162306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1462306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1762306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1862306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1962306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2062306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2162306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2262306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * Authors: Dave Airlie
2562306a36Sopenharmony_ci *          Alex Deucher
2662306a36Sopenharmony_ci *          Jerome Glisse
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#include "amdgpu.h"
3062306a36Sopenharmony_ci#include <drm/amdgpu_drm.h>
3162306a36Sopenharmony_ci#include <drm/drm_drv.h>
3262306a36Sopenharmony_ci#include <drm/drm_fb_helper.h>
3362306a36Sopenharmony_ci#include "amdgpu_uvd.h"
3462306a36Sopenharmony_ci#include "amdgpu_vce.h"
3562306a36Sopenharmony_ci#include "atom.h"
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#include <linux/vga_switcheroo.h>
3862306a36Sopenharmony_ci#include <linux/slab.h>
3962306a36Sopenharmony_ci#include <linux/uaccess.h>
4062306a36Sopenharmony_ci#include <linux/pci.h>
4162306a36Sopenharmony_ci#include <linux/pm_runtime.h>
4262306a36Sopenharmony_ci#include "amdgpu_amdkfd.h"
4362306a36Sopenharmony_ci#include "amdgpu_gem.h"
4462306a36Sopenharmony_ci#include "amdgpu_display.h"
4562306a36Sopenharmony_ci#include "amdgpu_ras.h"
4662306a36Sopenharmony_ci#include "amd_pcie.h"
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_civoid amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	struct amdgpu_gpu_instance *gpu_instance;
5162306a36Sopenharmony_ci	int i;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	mutex_lock(&mgpu_info.mutex);
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	for (i = 0; i < mgpu_info.num_gpu; i++) {
5662306a36Sopenharmony_ci		gpu_instance = &(mgpu_info.gpu_ins[i]);
5762306a36Sopenharmony_ci		if (gpu_instance->adev == adev) {
5862306a36Sopenharmony_ci			mgpu_info.gpu_ins[i] =
5962306a36Sopenharmony_ci				mgpu_info.gpu_ins[mgpu_info.num_gpu - 1];
6062306a36Sopenharmony_ci			mgpu_info.num_gpu--;
6162306a36Sopenharmony_ci			if (adev->flags & AMD_IS_APU)
6262306a36Sopenharmony_ci				mgpu_info.num_apu--;
6362306a36Sopenharmony_ci			else
6462306a36Sopenharmony_ci				mgpu_info.num_dgpu--;
6562306a36Sopenharmony_ci			break;
6662306a36Sopenharmony_ci		}
6762306a36Sopenharmony_ci	}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	mutex_unlock(&mgpu_info.mutex);
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/**
7362306a36Sopenharmony_ci * amdgpu_driver_unload_kms - Main unload function for KMS.
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci * @dev: drm dev pointer
7662306a36Sopenharmony_ci *
7762306a36Sopenharmony_ci * This is the main unload function for KMS (all asics).
7862306a36Sopenharmony_ci * Returns 0 on success.
7962306a36Sopenharmony_ci */
8062306a36Sopenharmony_civoid amdgpu_driver_unload_kms(struct drm_device *dev)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	if (adev == NULL)
8562306a36Sopenharmony_ci		return;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	amdgpu_unregister_gpu_instance(adev);
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	if (adev->rmmio == NULL)
9062306a36Sopenharmony_ci		return;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_UNLOAD))
9362306a36Sopenharmony_ci		DRM_WARN("smart shift update failed\n");
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	amdgpu_acpi_fini(adev);
9662306a36Sopenharmony_ci	amdgpu_device_fini_hw(adev);
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_civoid amdgpu_register_gpu_instance(struct amdgpu_device *adev)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	struct amdgpu_gpu_instance *gpu_instance;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	mutex_lock(&mgpu_info.mutex);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	if (mgpu_info.num_gpu >= MAX_GPU_INSTANCE) {
10662306a36Sopenharmony_ci		DRM_ERROR("Cannot register more gpu instance\n");
10762306a36Sopenharmony_ci		mutex_unlock(&mgpu_info.mutex);
10862306a36Sopenharmony_ci		return;
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	gpu_instance = &(mgpu_info.gpu_ins[mgpu_info.num_gpu]);
11262306a36Sopenharmony_ci	gpu_instance->adev = adev;
11362306a36Sopenharmony_ci	gpu_instance->mgpu_fan_enabled = 0;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	mgpu_info.num_gpu++;
11662306a36Sopenharmony_ci	if (adev->flags & AMD_IS_APU)
11762306a36Sopenharmony_ci		mgpu_info.num_apu++;
11862306a36Sopenharmony_ci	else
11962306a36Sopenharmony_ci		mgpu_info.num_dgpu++;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	mutex_unlock(&mgpu_info.mutex);
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/**
12562306a36Sopenharmony_ci * amdgpu_driver_load_kms - Main load function for KMS.
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * @adev: pointer to struct amdgpu_device
12862306a36Sopenharmony_ci * @flags: device flags
12962306a36Sopenharmony_ci *
13062306a36Sopenharmony_ci * This is the main load function for KMS (all asics).
13162306a36Sopenharmony_ci * Returns 0 on success, error on failure.
13262306a36Sopenharmony_ci */
13362306a36Sopenharmony_ciint amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags)
13462306a36Sopenharmony_ci{
13562306a36Sopenharmony_ci	struct drm_device *dev;
13662306a36Sopenharmony_ci	int r, acpi_status;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	dev = adev_to_drm(adev);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	/* amdgpu_device_init should report only fatal error
14162306a36Sopenharmony_ci	 * like memory allocation failure or iomapping failure,
14262306a36Sopenharmony_ci	 * or memory manager initialization failure, it must
14362306a36Sopenharmony_ci	 * properly initialize the GPU MC controller and permit
14462306a36Sopenharmony_ci	 * VRAM allocation
14562306a36Sopenharmony_ci	 */
14662306a36Sopenharmony_ci	r = amdgpu_device_init(adev, flags);
14762306a36Sopenharmony_ci	if (r) {
14862306a36Sopenharmony_ci		dev_err(dev->dev, "Fatal error during GPU init\n");
14962306a36Sopenharmony_ci		goto out;
15062306a36Sopenharmony_ci	}
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	adev->pm.rpm_mode = AMDGPU_RUNPM_NONE;
15362306a36Sopenharmony_ci	if (amdgpu_device_supports_px(dev) &&
15462306a36Sopenharmony_ci	    (amdgpu_runtime_pm != 0)) { /* enable PX as runtime mode */
15562306a36Sopenharmony_ci		adev->pm.rpm_mode = AMDGPU_RUNPM_PX;
15662306a36Sopenharmony_ci		dev_info(adev->dev, "Using ATPX for runtime pm\n");
15762306a36Sopenharmony_ci	} else if (amdgpu_device_supports_boco(dev) &&
15862306a36Sopenharmony_ci		   (amdgpu_runtime_pm != 0)) { /* enable boco as runtime mode */
15962306a36Sopenharmony_ci		adev->pm.rpm_mode = AMDGPU_RUNPM_BOCO;
16062306a36Sopenharmony_ci		dev_info(adev->dev, "Using BOCO for runtime pm\n");
16162306a36Sopenharmony_ci	} else if (amdgpu_device_supports_baco(dev) &&
16262306a36Sopenharmony_ci		   (amdgpu_runtime_pm != 0)) {
16362306a36Sopenharmony_ci		switch (adev->asic_type) {
16462306a36Sopenharmony_ci		case CHIP_VEGA20:
16562306a36Sopenharmony_ci		case CHIP_ARCTURUS:
16662306a36Sopenharmony_ci			/* enable BACO as runpm mode if runpm=1 */
16762306a36Sopenharmony_ci			if (amdgpu_runtime_pm > 0)
16862306a36Sopenharmony_ci				adev->pm.rpm_mode = AMDGPU_RUNPM_BACO;
16962306a36Sopenharmony_ci			break;
17062306a36Sopenharmony_ci		case CHIP_VEGA10:
17162306a36Sopenharmony_ci			/* enable BACO as runpm mode if noretry=0 */
17262306a36Sopenharmony_ci			if (!adev->gmc.noretry)
17362306a36Sopenharmony_ci				adev->pm.rpm_mode = AMDGPU_RUNPM_BACO;
17462306a36Sopenharmony_ci			break;
17562306a36Sopenharmony_ci		default:
17662306a36Sopenharmony_ci			/* enable BACO as runpm mode on CI+ */
17762306a36Sopenharmony_ci			adev->pm.rpm_mode = AMDGPU_RUNPM_BACO;
17862306a36Sopenharmony_ci			break;
17962306a36Sopenharmony_ci		}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci		if (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)
18262306a36Sopenharmony_ci			dev_info(adev->dev, "Using BACO for runtime pm\n");
18362306a36Sopenharmony_ci	}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	/* Call ACPI methods: require modeset init
18662306a36Sopenharmony_ci	 * but failure is not fatal
18762306a36Sopenharmony_ci	 */
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	acpi_status = amdgpu_acpi_init(adev);
19062306a36Sopenharmony_ci	if (acpi_status)
19162306a36Sopenharmony_ci		dev_dbg(dev->dev, "Error during ACPI methods call\n");
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DRV_LOAD))
19462306a36Sopenharmony_ci		DRM_WARN("smart shift update failed\n");
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ciout:
19762306a36Sopenharmony_ci	if (r)
19862306a36Sopenharmony_ci		amdgpu_driver_unload_kms(dev);
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	return r;
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_cistatic int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info,
20462306a36Sopenharmony_ci				struct drm_amdgpu_query_fw *query_fw,
20562306a36Sopenharmony_ci				struct amdgpu_device *adev)
20662306a36Sopenharmony_ci{
20762306a36Sopenharmony_ci	switch (query_fw->fw_type) {
20862306a36Sopenharmony_ci	case AMDGPU_INFO_FW_VCE:
20962306a36Sopenharmony_ci		fw_info->ver = adev->vce.fw_version;
21062306a36Sopenharmony_ci		fw_info->feature = adev->vce.fb_version;
21162306a36Sopenharmony_ci		break;
21262306a36Sopenharmony_ci	case AMDGPU_INFO_FW_UVD:
21362306a36Sopenharmony_ci		fw_info->ver = adev->uvd.fw_version;
21462306a36Sopenharmony_ci		fw_info->feature = 0;
21562306a36Sopenharmony_ci		break;
21662306a36Sopenharmony_ci	case AMDGPU_INFO_FW_VCN:
21762306a36Sopenharmony_ci		fw_info->ver = adev->vcn.fw_version;
21862306a36Sopenharmony_ci		fw_info->feature = 0;
21962306a36Sopenharmony_ci		break;
22062306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GMC:
22162306a36Sopenharmony_ci		fw_info->ver = adev->gmc.fw_version;
22262306a36Sopenharmony_ci		fw_info->feature = 0;
22362306a36Sopenharmony_ci		break;
22462306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_ME:
22562306a36Sopenharmony_ci		fw_info->ver = adev->gfx.me_fw_version;
22662306a36Sopenharmony_ci		fw_info->feature = adev->gfx.me_feature_version;
22762306a36Sopenharmony_ci		break;
22862306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_PFP:
22962306a36Sopenharmony_ci		fw_info->ver = adev->gfx.pfp_fw_version;
23062306a36Sopenharmony_ci		fw_info->feature = adev->gfx.pfp_feature_version;
23162306a36Sopenharmony_ci		break;
23262306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_CE:
23362306a36Sopenharmony_ci		fw_info->ver = adev->gfx.ce_fw_version;
23462306a36Sopenharmony_ci		fw_info->feature = adev->gfx.ce_feature_version;
23562306a36Sopenharmony_ci		break;
23662306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_RLC:
23762306a36Sopenharmony_ci		fw_info->ver = adev->gfx.rlc_fw_version;
23862306a36Sopenharmony_ci		fw_info->feature = adev->gfx.rlc_feature_version;
23962306a36Sopenharmony_ci		break;
24062306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL:
24162306a36Sopenharmony_ci		fw_info->ver = adev->gfx.rlc_srlc_fw_version;
24262306a36Sopenharmony_ci		fw_info->feature = adev->gfx.rlc_srlc_feature_version;
24362306a36Sopenharmony_ci		break;
24462306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM:
24562306a36Sopenharmony_ci		fw_info->ver = adev->gfx.rlc_srlg_fw_version;
24662306a36Sopenharmony_ci		fw_info->feature = adev->gfx.rlc_srlg_feature_version;
24762306a36Sopenharmony_ci		break;
24862306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM:
24962306a36Sopenharmony_ci		fw_info->ver = adev->gfx.rlc_srls_fw_version;
25062306a36Sopenharmony_ci		fw_info->feature = adev->gfx.rlc_srls_feature_version;
25162306a36Sopenharmony_ci		break;
25262306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_RLCP:
25362306a36Sopenharmony_ci		fw_info->ver = adev->gfx.rlcp_ucode_version;
25462306a36Sopenharmony_ci		fw_info->feature = adev->gfx.rlcp_ucode_feature_version;
25562306a36Sopenharmony_ci		break;
25662306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_RLCV:
25762306a36Sopenharmony_ci		fw_info->ver = adev->gfx.rlcv_ucode_version;
25862306a36Sopenharmony_ci		fw_info->feature = adev->gfx.rlcv_ucode_feature_version;
25962306a36Sopenharmony_ci		break;
26062306a36Sopenharmony_ci	case AMDGPU_INFO_FW_GFX_MEC:
26162306a36Sopenharmony_ci		if (query_fw->index == 0) {
26262306a36Sopenharmony_ci			fw_info->ver = adev->gfx.mec_fw_version;
26362306a36Sopenharmony_ci			fw_info->feature = adev->gfx.mec_feature_version;
26462306a36Sopenharmony_ci		} else if (query_fw->index == 1) {
26562306a36Sopenharmony_ci			fw_info->ver = adev->gfx.mec2_fw_version;
26662306a36Sopenharmony_ci			fw_info->feature = adev->gfx.mec2_feature_version;
26762306a36Sopenharmony_ci		} else
26862306a36Sopenharmony_ci			return -EINVAL;
26962306a36Sopenharmony_ci		break;
27062306a36Sopenharmony_ci	case AMDGPU_INFO_FW_SMC:
27162306a36Sopenharmony_ci		fw_info->ver = adev->pm.fw_version;
27262306a36Sopenharmony_ci		fw_info->feature = 0;
27362306a36Sopenharmony_ci		break;
27462306a36Sopenharmony_ci	case AMDGPU_INFO_FW_TA:
27562306a36Sopenharmony_ci		switch (query_fw->index) {
27662306a36Sopenharmony_ci		case TA_FW_TYPE_PSP_XGMI:
27762306a36Sopenharmony_ci			fw_info->ver = adev->psp.xgmi_context.context.bin_desc.fw_version;
27862306a36Sopenharmony_ci			fw_info->feature = adev->psp.xgmi_context.context
27962306a36Sopenharmony_ci						   .bin_desc.feature_version;
28062306a36Sopenharmony_ci			break;
28162306a36Sopenharmony_ci		case TA_FW_TYPE_PSP_RAS:
28262306a36Sopenharmony_ci			fw_info->ver = adev->psp.ras_context.context.bin_desc.fw_version;
28362306a36Sopenharmony_ci			fw_info->feature = adev->psp.ras_context.context
28462306a36Sopenharmony_ci						   .bin_desc.feature_version;
28562306a36Sopenharmony_ci			break;
28662306a36Sopenharmony_ci		case TA_FW_TYPE_PSP_HDCP:
28762306a36Sopenharmony_ci			fw_info->ver = adev->psp.hdcp_context.context.bin_desc.fw_version;
28862306a36Sopenharmony_ci			fw_info->feature = adev->psp.hdcp_context.context
28962306a36Sopenharmony_ci						   .bin_desc.feature_version;
29062306a36Sopenharmony_ci			break;
29162306a36Sopenharmony_ci		case TA_FW_TYPE_PSP_DTM:
29262306a36Sopenharmony_ci			fw_info->ver = adev->psp.dtm_context.context.bin_desc.fw_version;
29362306a36Sopenharmony_ci			fw_info->feature = adev->psp.dtm_context.context
29462306a36Sopenharmony_ci						   .bin_desc.feature_version;
29562306a36Sopenharmony_ci			break;
29662306a36Sopenharmony_ci		case TA_FW_TYPE_PSP_RAP:
29762306a36Sopenharmony_ci			fw_info->ver = adev->psp.rap_context.context.bin_desc.fw_version;
29862306a36Sopenharmony_ci			fw_info->feature = adev->psp.rap_context.context
29962306a36Sopenharmony_ci						   .bin_desc.feature_version;
30062306a36Sopenharmony_ci			break;
30162306a36Sopenharmony_ci		case TA_FW_TYPE_PSP_SECUREDISPLAY:
30262306a36Sopenharmony_ci			fw_info->ver = adev->psp.securedisplay_context.context.bin_desc.fw_version;
30362306a36Sopenharmony_ci			fw_info->feature =
30462306a36Sopenharmony_ci				adev->psp.securedisplay_context.context.bin_desc
30562306a36Sopenharmony_ci					.feature_version;
30662306a36Sopenharmony_ci			break;
30762306a36Sopenharmony_ci		default:
30862306a36Sopenharmony_ci			return -EINVAL;
30962306a36Sopenharmony_ci		}
31062306a36Sopenharmony_ci		break;
31162306a36Sopenharmony_ci	case AMDGPU_INFO_FW_SDMA:
31262306a36Sopenharmony_ci		if (query_fw->index >= adev->sdma.num_instances)
31362306a36Sopenharmony_ci			return -EINVAL;
31462306a36Sopenharmony_ci		fw_info->ver = adev->sdma.instance[query_fw->index].fw_version;
31562306a36Sopenharmony_ci		fw_info->feature = adev->sdma.instance[query_fw->index].feature_version;
31662306a36Sopenharmony_ci		break;
31762306a36Sopenharmony_ci	case AMDGPU_INFO_FW_SOS:
31862306a36Sopenharmony_ci		fw_info->ver = adev->psp.sos.fw_version;
31962306a36Sopenharmony_ci		fw_info->feature = adev->psp.sos.feature_version;
32062306a36Sopenharmony_ci		break;
32162306a36Sopenharmony_ci	case AMDGPU_INFO_FW_ASD:
32262306a36Sopenharmony_ci		fw_info->ver = adev->psp.asd_context.bin_desc.fw_version;
32362306a36Sopenharmony_ci		fw_info->feature = adev->psp.asd_context.bin_desc.feature_version;
32462306a36Sopenharmony_ci		break;
32562306a36Sopenharmony_ci	case AMDGPU_INFO_FW_DMCU:
32662306a36Sopenharmony_ci		fw_info->ver = adev->dm.dmcu_fw_version;
32762306a36Sopenharmony_ci		fw_info->feature = 0;
32862306a36Sopenharmony_ci		break;
32962306a36Sopenharmony_ci	case AMDGPU_INFO_FW_DMCUB:
33062306a36Sopenharmony_ci		fw_info->ver = adev->dm.dmcub_fw_version;
33162306a36Sopenharmony_ci		fw_info->feature = 0;
33262306a36Sopenharmony_ci		break;
33362306a36Sopenharmony_ci	case AMDGPU_INFO_FW_TOC:
33462306a36Sopenharmony_ci		fw_info->ver = adev->psp.toc.fw_version;
33562306a36Sopenharmony_ci		fw_info->feature = adev->psp.toc.feature_version;
33662306a36Sopenharmony_ci		break;
33762306a36Sopenharmony_ci	case AMDGPU_INFO_FW_CAP:
33862306a36Sopenharmony_ci		fw_info->ver = adev->psp.cap_fw_version;
33962306a36Sopenharmony_ci		fw_info->feature = adev->psp.cap_feature_version;
34062306a36Sopenharmony_ci		break;
34162306a36Sopenharmony_ci	case AMDGPU_INFO_FW_MES_KIQ:
34262306a36Sopenharmony_ci		fw_info->ver = adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK;
34362306a36Sopenharmony_ci		fw_info->feature = (adev->mes.kiq_version & AMDGPU_MES_FEAT_VERSION_MASK)
34462306a36Sopenharmony_ci					>> AMDGPU_MES_FEAT_VERSION_SHIFT;
34562306a36Sopenharmony_ci		break;
34662306a36Sopenharmony_ci	case AMDGPU_INFO_FW_MES:
34762306a36Sopenharmony_ci		fw_info->ver = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK;
34862306a36Sopenharmony_ci		fw_info->feature = (adev->mes.sched_version & AMDGPU_MES_FEAT_VERSION_MASK)
34962306a36Sopenharmony_ci					>> AMDGPU_MES_FEAT_VERSION_SHIFT;
35062306a36Sopenharmony_ci		break;
35162306a36Sopenharmony_ci	case AMDGPU_INFO_FW_IMU:
35262306a36Sopenharmony_ci		fw_info->ver = adev->gfx.imu_fw_version;
35362306a36Sopenharmony_ci		fw_info->feature = 0;
35462306a36Sopenharmony_ci		break;
35562306a36Sopenharmony_ci	default:
35662306a36Sopenharmony_ci		return -EINVAL;
35762306a36Sopenharmony_ci	}
35862306a36Sopenharmony_ci	return 0;
35962306a36Sopenharmony_ci}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic int amdgpu_hw_ip_info(struct amdgpu_device *adev,
36262306a36Sopenharmony_ci			     struct drm_amdgpu_info *info,
36362306a36Sopenharmony_ci			     struct drm_amdgpu_info_hw_ip *result)
36462306a36Sopenharmony_ci{
36562306a36Sopenharmony_ci	uint32_t ib_start_alignment = 0;
36662306a36Sopenharmony_ci	uint32_t ib_size_alignment = 0;
36762306a36Sopenharmony_ci	enum amd_ip_block_type type;
36862306a36Sopenharmony_ci	unsigned int num_rings = 0;
36962306a36Sopenharmony_ci	unsigned int i, j;
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci	if (info->query_hw_ip.ip_instance >= AMDGPU_HW_IP_INSTANCE_MAX_COUNT)
37262306a36Sopenharmony_ci		return -EINVAL;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	switch (info->query_hw_ip.type) {
37562306a36Sopenharmony_ci	case AMDGPU_HW_IP_GFX:
37662306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_GFX;
37762306a36Sopenharmony_ci		for (i = 0; i < adev->gfx.num_gfx_rings; i++)
37862306a36Sopenharmony_ci			if (adev->gfx.gfx_ring[i].sched.ready)
37962306a36Sopenharmony_ci				++num_rings;
38062306a36Sopenharmony_ci		ib_start_alignment = 32;
38162306a36Sopenharmony_ci		ib_size_alignment = 32;
38262306a36Sopenharmony_ci		break;
38362306a36Sopenharmony_ci	case AMDGPU_HW_IP_COMPUTE:
38462306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_GFX;
38562306a36Sopenharmony_ci		for (i = 0; i < adev->gfx.num_compute_rings; i++)
38662306a36Sopenharmony_ci			if (adev->gfx.compute_ring[i].sched.ready)
38762306a36Sopenharmony_ci				++num_rings;
38862306a36Sopenharmony_ci		ib_start_alignment = 32;
38962306a36Sopenharmony_ci		ib_size_alignment = 32;
39062306a36Sopenharmony_ci		break;
39162306a36Sopenharmony_ci	case AMDGPU_HW_IP_DMA:
39262306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_SDMA;
39362306a36Sopenharmony_ci		for (i = 0; i < adev->sdma.num_instances; i++)
39462306a36Sopenharmony_ci			if (adev->sdma.instance[i].ring.sched.ready)
39562306a36Sopenharmony_ci				++num_rings;
39662306a36Sopenharmony_ci		ib_start_alignment = 256;
39762306a36Sopenharmony_ci		ib_size_alignment = 4;
39862306a36Sopenharmony_ci		break;
39962306a36Sopenharmony_ci	case AMDGPU_HW_IP_UVD:
40062306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_UVD;
40162306a36Sopenharmony_ci		for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
40262306a36Sopenharmony_ci			if (adev->uvd.harvest_config & (1 << i))
40362306a36Sopenharmony_ci				continue;
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci			if (adev->uvd.inst[i].ring.sched.ready)
40662306a36Sopenharmony_ci				++num_rings;
40762306a36Sopenharmony_ci		}
40862306a36Sopenharmony_ci		ib_start_alignment = 64;
40962306a36Sopenharmony_ci		ib_size_alignment = 64;
41062306a36Sopenharmony_ci		break;
41162306a36Sopenharmony_ci	case AMDGPU_HW_IP_VCE:
41262306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_VCE;
41362306a36Sopenharmony_ci		for (i = 0; i < adev->vce.num_rings; i++)
41462306a36Sopenharmony_ci			if (adev->vce.ring[i].sched.ready)
41562306a36Sopenharmony_ci				++num_rings;
41662306a36Sopenharmony_ci		ib_start_alignment = 4;
41762306a36Sopenharmony_ci		ib_size_alignment = 1;
41862306a36Sopenharmony_ci		break;
41962306a36Sopenharmony_ci	case AMDGPU_HW_IP_UVD_ENC:
42062306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_UVD;
42162306a36Sopenharmony_ci		for (i = 0; i < adev->uvd.num_uvd_inst; i++) {
42262306a36Sopenharmony_ci			if (adev->uvd.harvest_config & (1 << i))
42362306a36Sopenharmony_ci				continue;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci			for (j = 0; j < adev->uvd.num_enc_rings; j++)
42662306a36Sopenharmony_ci				if (adev->uvd.inst[i].ring_enc[j].sched.ready)
42762306a36Sopenharmony_ci					++num_rings;
42862306a36Sopenharmony_ci		}
42962306a36Sopenharmony_ci		ib_start_alignment = 64;
43062306a36Sopenharmony_ci		ib_size_alignment = 64;
43162306a36Sopenharmony_ci		break;
43262306a36Sopenharmony_ci	case AMDGPU_HW_IP_VCN_DEC:
43362306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_VCN;
43462306a36Sopenharmony_ci		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
43562306a36Sopenharmony_ci			if (adev->vcn.harvest_config & (1 << i))
43662306a36Sopenharmony_ci				continue;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci			if (adev->vcn.inst[i].ring_dec.sched.ready)
43962306a36Sopenharmony_ci				++num_rings;
44062306a36Sopenharmony_ci		}
44162306a36Sopenharmony_ci		ib_start_alignment = 16;
44262306a36Sopenharmony_ci		ib_size_alignment = 16;
44362306a36Sopenharmony_ci		break;
44462306a36Sopenharmony_ci	case AMDGPU_HW_IP_VCN_ENC:
44562306a36Sopenharmony_ci		type = AMD_IP_BLOCK_TYPE_VCN;
44662306a36Sopenharmony_ci		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
44762306a36Sopenharmony_ci			if (adev->vcn.harvest_config & (1 << i))
44862306a36Sopenharmony_ci				continue;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci			for (j = 0; j < adev->vcn.num_enc_rings; j++)
45162306a36Sopenharmony_ci				if (adev->vcn.inst[i].ring_enc[j].sched.ready)
45262306a36Sopenharmony_ci					++num_rings;
45362306a36Sopenharmony_ci		}
45462306a36Sopenharmony_ci		ib_start_alignment = 64;
45562306a36Sopenharmony_ci		ib_size_alignment = 1;
45662306a36Sopenharmony_ci		break;
45762306a36Sopenharmony_ci	case AMDGPU_HW_IP_VCN_JPEG:
45862306a36Sopenharmony_ci		type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ?
45962306a36Sopenharmony_ci			AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci		for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
46262306a36Sopenharmony_ci			if (adev->jpeg.harvest_config & (1 << i))
46362306a36Sopenharmony_ci				continue;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci			for (j = 0; j < adev->jpeg.num_jpeg_rings; j++)
46662306a36Sopenharmony_ci				if (adev->jpeg.inst[i].ring_dec[j].sched.ready)
46762306a36Sopenharmony_ci					++num_rings;
46862306a36Sopenharmony_ci		}
46962306a36Sopenharmony_ci		ib_start_alignment = 16;
47062306a36Sopenharmony_ci		ib_size_alignment = 16;
47162306a36Sopenharmony_ci		break;
47262306a36Sopenharmony_ci	default:
47362306a36Sopenharmony_ci		return -EINVAL;
47462306a36Sopenharmony_ci	}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	for (i = 0; i < adev->num_ip_blocks; i++)
47762306a36Sopenharmony_ci		if (adev->ip_blocks[i].version->type == type &&
47862306a36Sopenharmony_ci		    adev->ip_blocks[i].status.valid)
47962306a36Sopenharmony_ci			break;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	if (i == adev->num_ip_blocks)
48262306a36Sopenharmony_ci		return 0;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	num_rings = min(amdgpu_ctx_num_entities[info->query_hw_ip.type],
48562306a36Sopenharmony_ci			num_rings);
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	result->hw_ip_version_major = adev->ip_blocks[i].version->major;
48862306a36Sopenharmony_ci	result->hw_ip_version_minor = adev->ip_blocks[i].version->minor;
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	if (adev->asic_type >= CHIP_VEGA10) {
49162306a36Sopenharmony_ci		switch (type) {
49262306a36Sopenharmony_ci		case AMD_IP_BLOCK_TYPE_GFX:
49362306a36Sopenharmony_ci			result->ip_discovery_version = adev->ip_versions[GC_HWIP][0];
49462306a36Sopenharmony_ci			break;
49562306a36Sopenharmony_ci		case AMD_IP_BLOCK_TYPE_SDMA:
49662306a36Sopenharmony_ci			result->ip_discovery_version = adev->ip_versions[SDMA0_HWIP][0];
49762306a36Sopenharmony_ci			break;
49862306a36Sopenharmony_ci		case AMD_IP_BLOCK_TYPE_UVD:
49962306a36Sopenharmony_ci		case AMD_IP_BLOCK_TYPE_VCN:
50062306a36Sopenharmony_ci		case AMD_IP_BLOCK_TYPE_JPEG:
50162306a36Sopenharmony_ci			result->ip_discovery_version = adev->ip_versions[UVD_HWIP][0];
50262306a36Sopenharmony_ci			break;
50362306a36Sopenharmony_ci		case AMD_IP_BLOCK_TYPE_VCE:
50462306a36Sopenharmony_ci			result->ip_discovery_version = adev->ip_versions[VCE_HWIP][0];
50562306a36Sopenharmony_ci			break;
50662306a36Sopenharmony_ci		default:
50762306a36Sopenharmony_ci			result->ip_discovery_version = 0;
50862306a36Sopenharmony_ci			break;
50962306a36Sopenharmony_ci		}
51062306a36Sopenharmony_ci	} else {
51162306a36Sopenharmony_ci		result->ip_discovery_version = 0;
51262306a36Sopenharmony_ci	}
51362306a36Sopenharmony_ci	result->capabilities_flags = 0;
51462306a36Sopenharmony_ci	result->available_rings = (1 << num_rings) - 1;
51562306a36Sopenharmony_ci	result->ib_start_alignment = ib_start_alignment;
51662306a36Sopenharmony_ci	result->ib_size_alignment = ib_size_alignment;
51762306a36Sopenharmony_ci	return 0;
51862306a36Sopenharmony_ci}
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci/*
52162306a36Sopenharmony_ci * Userspace get information ioctl
52262306a36Sopenharmony_ci */
52362306a36Sopenharmony_ci/**
52462306a36Sopenharmony_ci * amdgpu_info_ioctl - answer a device specific request.
52562306a36Sopenharmony_ci *
52662306a36Sopenharmony_ci * @dev: drm device pointer
52762306a36Sopenharmony_ci * @data: request object
52862306a36Sopenharmony_ci * @filp: drm filp
52962306a36Sopenharmony_ci *
53062306a36Sopenharmony_ci * This function is used to pass device specific parameters to the userspace
53162306a36Sopenharmony_ci * drivers.  Examples include: pci device id, pipeline parms, tiling params,
53262306a36Sopenharmony_ci * etc. (all asics).
53362306a36Sopenharmony_ci * Returns 0 on success, -EINVAL on failure.
53462306a36Sopenharmony_ci */
53562306a36Sopenharmony_ciint amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
53662306a36Sopenharmony_ci{
53762306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
53862306a36Sopenharmony_ci	struct drm_amdgpu_info *info = data;
53962306a36Sopenharmony_ci	struct amdgpu_mode_info *minfo = &adev->mode_info;
54062306a36Sopenharmony_ci	void __user *out = (void __user *)(uintptr_t)info->return_pointer;
54162306a36Sopenharmony_ci	uint32_t size = info->return_size;
54262306a36Sopenharmony_ci	struct drm_crtc *crtc;
54362306a36Sopenharmony_ci	uint32_t ui32 = 0;
54462306a36Sopenharmony_ci	uint64_t ui64 = 0;
54562306a36Sopenharmony_ci	int i, found;
54662306a36Sopenharmony_ci	int ui32_size = sizeof(ui32);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	if (!info->return_size || !info->return_pointer)
54962306a36Sopenharmony_ci		return -EINVAL;
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	switch (info->query) {
55262306a36Sopenharmony_ci	case AMDGPU_INFO_ACCEL_WORKING:
55362306a36Sopenharmony_ci		ui32 = adev->accel_working;
55462306a36Sopenharmony_ci		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
55562306a36Sopenharmony_ci	case AMDGPU_INFO_CRTC_FROM_ID:
55662306a36Sopenharmony_ci		for (i = 0, found = 0; i < adev->mode_info.num_crtc; i++) {
55762306a36Sopenharmony_ci			crtc = (struct drm_crtc *)minfo->crtcs[i];
55862306a36Sopenharmony_ci			if (crtc && crtc->base.id == info->mode_crtc.id) {
55962306a36Sopenharmony_ci				struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci				ui32 = amdgpu_crtc->crtc_id;
56262306a36Sopenharmony_ci				found = 1;
56362306a36Sopenharmony_ci				break;
56462306a36Sopenharmony_ci			}
56562306a36Sopenharmony_ci		}
56662306a36Sopenharmony_ci		if (!found) {
56762306a36Sopenharmony_ci			DRM_DEBUG_KMS("unknown crtc id %d\n", info->mode_crtc.id);
56862306a36Sopenharmony_ci			return -EINVAL;
56962306a36Sopenharmony_ci		}
57062306a36Sopenharmony_ci		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
57162306a36Sopenharmony_ci	case AMDGPU_INFO_HW_IP_INFO: {
57262306a36Sopenharmony_ci		struct drm_amdgpu_info_hw_ip ip = {};
57362306a36Sopenharmony_ci		int ret;
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci		ret = amdgpu_hw_ip_info(adev, info, &ip);
57662306a36Sopenharmony_ci		if (ret)
57762306a36Sopenharmony_ci			return ret;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci		ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip)));
58062306a36Sopenharmony_ci		return ret ? -EFAULT : 0;
58162306a36Sopenharmony_ci	}
58262306a36Sopenharmony_ci	case AMDGPU_INFO_HW_IP_COUNT: {
58362306a36Sopenharmony_ci		enum amd_ip_block_type type;
58462306a36Sopenharmony_ci		uint32_t count = 0;
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci		switch (info->query_hw_ip.type) {
58762306a36Sopenharmony_ci		case AMDGPU_HW_IP_GFX:
58862306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_GFX;
58962306a36Sopenharmony_ci			break;
59062306a36Sopenharmony_ci		case AMDGPU_HW_IP_COMPUTE:
59162306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_GFX;
59262306a36Sopenharmony_ci			break;
59362306a36Sopenharmony_ci		case AMDGPU_HW_IP_DMA:
59462306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_SDMA;
59562306a36Sopenharmony_ci			break;
59662306a36Sopenharmony_ci		case AMDGPU_HW_IP_UVD:
59762306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_UVD;
59862306a36Sopenharmony_ci			break;
59962306a36Sopenharmony_ci		case AMDGPU_HW_IP_VCE:
60062306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_VCE;
60162306a36Sopenharmony_ci			break;
60262306a36Sopenharmony_ci		case AMDGPU_HW_IP_UVD_ENC:
60362306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_UVD;
60462306a36Sopenharmony_ci			break;
60562306a36Sopenharmony_ci		case AMDGPU_HW_IP_VCN_DEC:
60662306a36Sopenharmony_ci		case AMDGPU_HW_IP_VCN_ENC:
60762306a36Sopenharmony_ci			type = AMD_IP_BLOCK_TYPE_VCN;
60862306a36Sopenharmony_ci			break;
60962306a36Sopenharmony_ci		case AMDGPU_HW_IP_VCN_JPEG:
61062306a36Sopenharmony_ci			type = (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_JPEG)) ?
61162306a36Sopenharmony_ci				AMD_IP_BLOCK_TYPE_JPEG : AMD_IP_BLOCK_TYPE_VCN;
61262306a36Sopenharmony_ci			break;
61362306a36Sopenharmony_ci		default:
61462306a36Sopenharmony_ci			return -EINVAL;
61562306a36Sopenharmony_ci		}
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci		for (i = 0; i < adev->num_ip_blocks; i++)
61862306a36Sopenharmony_ci			if (adev->ip_blocks[i].version->type == type &&
61962306a36Sopenharmony_ci			    adev->ip_blocks[i].status.valid &&
62062306a36Sopenharmony_ci			    count < AMDGPU_HW_IP_INSTANCE_MAX_COUNT)
62162306a36Sopenharmony_ci				count++;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci		return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0;
62462306a36Sopenharmony_ci	}
62562306a36Sopenharmony_ci	case AMDGPU_INFO_TIMESTAMP:
62662306a36Sopenharmony_ci		ui64 = amdgpu_gfx_get_gpu_clock_counter(adev);
62762306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
62862306a36Sopenharmony_ci	case AMDGPU_INFO_FW_VERSION: {
62962306a36Sopenharmony_ci		struct drm_amdgpu_info_firmware fw_info;
63062306a36Sopenharmony_ci		int ret;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci		/* We only support one instance of each IP block right now. */
63362306a36Sopenharmony_ci		if (info->query_fw.ip_instance != 0)
63462306a36Sopenharmony_ci			return -EINVAL;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci		ret = amdgpu_firmware_info(&fw_info, &info->query_fw, adev);
63762306a36Sopenharmony_ci		if (ret)
63862306a36Sopenharmony_ci			return ret;
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci		return copy_to_user(out, &fw_info,
64162306a36Sopenharmony_ci				    min((size_t)size, sizeof(fw_info))) ? -EFAULT : 0;
64262306a36Sopenharmony_ci	}
64362306a36Sopenharmony_ci	case AMDGPU_INFO_NUM_BYTES_MOVED:
64462306a36Sopenharmony_ci		ui64 = atomic64_read(&adev->num_bytes_moved);
64562306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
64662306a36Sopenharmony_ci	case AMDGPU_INFO_NUM_EVICTIONS:
64762306a36Sopenharmony_ci		ui64 = atomic64_read(&adev->num_evictions);
64862306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
64962306a36Sopenharmony_ci	case AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS:
65062306a36Sopenharmony_ci		ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
65162306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
65262306a36Sopenharmony_ci	case AMDGPU_INFO_VRAM_USAGE:
65362306a36Sopenharmony_ci		ui64 = ttm_resource_manager_usage(&adev->mman.vram_mgr.manager);
65462306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
65562306a36Sopenharmony_ci	case AMDGPU_INFO_VIS_VRAM_USAGE:
65662306a36Sopenharmony_ci		ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr);
65762306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
65862306a36Sopenharmony_ci	case AMDGPU_INFO_GTT_USAGE:
65962306a36Sopenharmony_ci		ui64 = ttm_resource_manager_usage(&adev->mman.gtt_mgr.manager);
66062306a36Sopenharmony_ci		return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
66162306a36Sopenharmony_ci	case AMDGPU_INFO_GDS_CONFIG: {
66262306a36Sopenharmony_ci		struct drm_amdgpu_info_gds gds_info;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci		memset(&gds_info, 0, sizeof(gds_info));
66562306a36Sopenharmony_ci		gds_info.compute_partition_size = adev->gds.gds_size;
66662306a36Sopenharmony_ci		gds_info.gds_total_size = adev->gds.gds_size;
66762306a36Sopenharmony_ci		gds_info.gws_per_compute_partition = adev->gds.gws_size;
66862306a36Sopenharmony_ci		gds_info.oa_per_compute_partition = adev->gds.oa_size;
66962306a36Sopenharmony_ci		return copy_to_user(out, &gds_info,
67062306a36Sopenharmony_ci				    min((size_t)size, sizeof(gds_info))) ? -EFAULT : 0;
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci	case AMDGPU_INFO_VRAM_GTT: {
67362306a36Sopenharmony_ci		struct drm_amdgpu_info_vram_gtt vram_gtt;
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci		vram_gtt.vram_size = adev->gmc.real_vram_size -
67662306a36Sopenharmony_ci			atomic64_read(&adev->vram_pin_size) -
67762306a36Sopenharmony_ci			AMDGPU_VM_RESERVED_VRAM;
67862306a36Sopenharmony_ci		vram_gtt.vram_cpu_accessible_size =
67962306a36Sopenharmony_ci			min(adev->gmc.visible_vram_size -
68062306a36Sopenharmony_ci			    atomic64_read(&adev->visible_pin_size),
68162306a36Sopenharmony_ci			    vram_gtt.vram_size);
68262306a36Sopenharmony_ci		vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size;
68362306a36Sopenharmony_ci		vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size);
68462306a36Sopenharmony_ci		return copy_to_user(out, &vram_gtt,
68562306a36Sopenharmony_ci				    min((size_t)size, sizeof(vram_gtt))) ? -EFAULT : 0;
68662306a36Sopenharmony_ci	}
68762306a36Sopenharmony_ci	case AMDGPU_INFO_MEMORY: {
68862306a36Sopenharmony_ci		struct drm_amdgpu_memory_info mem;
68962306a36Sopenharmony_ci		struct ttm_resource_manager *gtt_man =
69062306a36Sopenharmony_ci			&adev->mman.gtt_mgr.manager;
69162306a36Sopenharmony_ci		struct ttm_resource_manager *vram_man =
69262306a36Sopenharmony_ci			&adev->mman.vram_mgr.manager;
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci		memset(&mem, 0, sizeof(mem));
69562306a36Sopenharmony_ci		mem.vram.total_heap_size = adev->gmc.real_vram_size;
69662306a36Sopenharmony_ci		mem.vram.usable_heap_size = adev->gmc.real_vram_size -
69762306a36Sopenharmony_ci			atomic64_read(&adev->vram_pin_size) -
69862306a36Sopenharmony_ci			AMDGPU_VM_RESERVED_VRAM;
69962306a36Sopenharmony_ci		mem.vram.heap_usage =
70062306a36Sopenharmony_ci			ttm_resource_manager_usage(vram_man);
70162306a36Sopenharmony_ci		mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci		mem.cpu_accessible_vram.total_heap_size =
70462306a36Sopenharmony_ci			adev->gmc.visible_vram_size;
70562306a36Sopenharmony_ci		mem.cpu_accessible_vram.usable_heap_size =
70662306a36Sopenharmony_ci			min(adev->gmc.visible_vram_size -
70762306a36Sopenharmony_ci			    atomic64_read(&adev->visible_pin_size),
70862306a36Sopenharmony_ci			    mem.vram.usable_heap_size);
70962306a36Sopenharmony_ci		mem.cpu_accessible_vram.heap_usage =
71062306a36Sopenharmony_ci			amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr);
71162306a36Sopenharmony_ci		mem.cpu_accessible_vram.max_allocation =
71262306a36Sopenharmony_ci			mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci		mem.gtt.total_heap_size = gtt_man->size;
71562306a36Sopenharmony_ci		mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
71662306a36Sopenharmony_ci			atomic64_read(&adev->gart_pin_size);
71762306a36Sopenharmony_ci		mem.gtt.heap_usage = ttm_resource_manager_usage(gtt_man);
71862306a36Sopenharmony_ci		mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4;
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci		return copy_to_user(out, &mem,
72162306a36Sopenharmony_ci				    min((size_t)size, sizeof(mem)))
72262306a36Sopenharmony_ci				    ? -EFAULT : 0;
72362306a36Sopenharmony_ci	}
72462306a36Sopenharmony_ci	case AMDGPU_INFO_READ_MMR_REG: {
72562306a36Sopenharmony_ci		unsigned int n, alloc_size;
72662306a36Sopenharmony_ci		uint32_t *regs;
72762306a36Sopenharmony_ci		unsigned int se_num = (info->read_mmr_reg.instance >>
72862306a36Sopenharmony_ci				   AMDGPU_INFO_MMR_SE_INDEX_SHIFT) &
72962306a36Sopenharmony_ci				  AMDGPU_INFO_MMR_SE_INDEX_MASK;
73062306a36Sopenharmony_ci		unsigned int sh_num = (info->read_mmr_reg.instance >>
73162306a36Sopenharmony_ci				   AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &
73262306a36Sopenharmony_ci				  AMDGPU_INFO_MMR_SH_INDEX_MASK;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci		/* set full masks if the userspace set all bits
73562306a36Sopenharmony_ci		 * in the bitfields
73662306a36Sopenharmony_ci		 */
73762306a36Sopenharmony_ci		if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
73862306a36Sopenharmony_ci			se_num = 0xffffffff;
73962306a36Sopenharmony_ci		else if (se_num >= AMDGPU_GFX_MAX_SE)
74062306a36Sopenharmony_ci			return -EINVAL;
74162306a36Sopenharmony_ci		if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
74262306a36Sopenharmony_ci			sh_num = 0xffffffff;
74362306a36Sopenharmony_ci		else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE)
74462306a36Sopenharmony_ci			return -EINVAL;
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci		if (info->read_mmr_reg.count > 128)
74762306a36Sopenharmony_ci			return -EINVAL;
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci		regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL);
75062306a36Sopenharmony_ci		if (!regs)
75162306a36Sopenharmony_ci			return -ENOMEM;
75262306a36Sopenharmony_ci		alloc_size = info->read_mmr_reg.count * sizeof(*regs);
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci		amdgpu_gfx_off_ctrl(adev, false);
75562306a36Sopenharmony_ci		for (i = 0; i < info->read_mmr_reg.count; i++) {
75662306a36Sopenharmony_ci			if (amdgpu_asic_read_register(adev, se_num, sh_num,
75762306a36Sopenharmony_ci						      info->read_mmr_reg.dword_offset + i,
75862306a36Sopenharmony_ci						      &regs[i])) {
75962306a36Sopenharmony_ci				DRM_DEBUG_KMS("unallowed offset %#x\n",
76062306a36Sopenharmony_ci					      info->read_mmr_reg.dword_offset + i);
76162306a36Sopenharmony_ci				kfree(regs);
76262306a36Sopenharmony_ci				amdgpu_gfx_off_ctrl(adev, true);
76362306a36Sopenharmony_ci				return -EFAULT;
76462306a36Sopenharmony_ci			}
76562306a36Sopenharmony_ci		}
76662306a36Sopenharmony_ci		amdgpu_gfx_off_ctrl(adev, true);
76762306a36Sopenharmony_ci		n = copy_to_user(out, regs, min(size, alloc_size));
76862306a36Sopenharmony_ci		kfree(regs);
76962306a36Sopenharmony_ci		return n ? -EFAULT : 0;
77062306a36Sopenharmony_ci	}
77162306a36Sopenharmony_ci	case AMDGPU_INFO_DEV_INFO: {
77262306a36Sopenharmony_ci		struct drm_amdgpu_info_device *dev_info;
77362306a36Sopenharmony_ci		uint64_t vm_size;
77462306a36Sopenharmony_ci		uint32_t pcie_gen_mask;
77562306a36Sopenharmony_ci		int ret;
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci		dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
77862306a36Sopenharmony_ci		if (!dev_info)
77962306a36Sopenharmony_ci			return -ENOMEM;
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci		dev_info->device_id = adev->pdev->device;
78262306a36Sopenharmony_ci		dev_info->chip_rev = adev->rev_id;
78362306a36Sopenharmony_ci		dev_info->external_rev = adev->external_rev_id;
78462306a36Sopenharmony_ci		dev_info->pci_rev = adev->pdev->revision;
78562306a36Sopenharmony_ci		dev_info->family = adev->family;
78662306a36Sopenharmony_ci		dev_info->num_shader_engines = adev->gfx.config.max_shader_engines;
78762306a36Sopenharmony_ci		dev_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se;
78862306a36Sopenharmony_ci		/* return all clocks in KHz */
78962306a36Sopenharmony_ci		dev_info->gpu_counter_freq = amdgpu_asic_get_xclk(adev) * 10;
79062306a36Sopenharmony_ci		if (adev->pm.dpm_enabled) {
79162306a36Sopenharmony_ci			dev_info->max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;
79262306a36Sopenharmony_ci			dev_info->max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;
79362306a36Sopenharmony_ci			dev_info->min_engine_clock = amdgpu_dpm_get_sclk(adev, true) * 10;
79462306a36Sopenharmony_ci			dev_info->min_memory_clock = amdgpu_dpm_get_mclk(adev, true) * 10;
79562306a36Sopenharmony_ci		} else {
79662306a36Sopenharmony_ci			dev_info->max_engine_clock =
79762306a36Sopenharmony_ci				dev_info->min_engine_clock =
79862306a36Sopenharmony_ci					adev->clock.default_sclk * 10;
79962306a36Sopenharmony_ci			dev_info->max_memory_clock =
80062306a36Sopenharmony_ci				dev_info->min_memory_clock =
80162306a36Sopenharmony_ci					adev->clock.default_mclk * 10;
80262306a36Sopenharmony_ci		}
80362306a36Sopenharmony_ci		dev_info->enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
80462306a36Sopenharmony_ci		dev_info->num_rb_pipes = adev->gfx.config.max_backends_per_se *
80562306a36Sopenharmony_ci			adev->gfx.config.max_shader_engines;
80662306a36Sopenharmony_ci		dev_info->num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts;
80762306a36Sopenharmony_ci		dev_info->ids_flags = 0;
80862306a36Sopenharmony_ci		if (adev->flags & AMD_IS_APU)
80962306a36Sopenharmony_ci			dev_info->ids_flags |= AMDGPU_IDS_FLAGS_FUSION;
81062306a36Sopenharmony_ci		if (adev->gfx.mcbp)
81162306a36Sopenharmony_ci			dev_info->ids_flags |= AMDGPU_IDS_FLAGS_PREEMPTION;
81262306a36Sopenharmony_ci		if (amdgpu_is_tmz(adev))
81362306a36Sopenharmony_ci			dev_info->ids_flags |= AMDGPU_IDS_FLAGS_TMZ;
81462306a36Sopenharmony_ci		if (adev->gfx.config.ta_cntl2_truncate_coord_mode)
81562306a36Sopenharmony_ci			dev_info->ids_flags |= AMDGPU_IDS_FLAGS_CONFORMANT_TRUNC_COORD;
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci		vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE;
81862306a36Sopenharmony_ci		vm_size -= AMDGPU_VA_RESERVED_SIZE;
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci		/* Older VCE FW versions are buggy and can handle only 40bits */
82162306a36Sopenharmony_ci		if (adev->vce.fw_version &&
82262306a36Sopenharmony_ci		    adev->vce.fw_version < AMDGPU_VCE_FW_53_45)
82362306a36Sopenharmony_ci			vm_size = min(vm_size, 1ULL << 40);
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci		dev_info->virtual_address_offset = AMDGPU_VA_RESERVED_SIZE;
82662306a36Sopenharmony_ci		dev_info->virtual_address_max =
82762306a36Sopenharmony_ci			min(vm_size, AMDGPU_GMC_HOLE_START);
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_ci		if (vm_size > AMDGPU_GMC_HOLE_START) {
83062306a36Sopenharmony_ci			dev_info->high_va_offset = AMDGPU_GMC_HOLE_END;
83162306a36Sopenharmony_ci			dev_info->high_va_max = AMDGPU_GMC_HOLE_END | vm_size;
83262306a36Sopenharmony_ci		}
83362306a36Sopenharmony_ci		dev_info->virtual_address_alignment = max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
83462306a36Sopenharmony_ci		dev_info->pte_fragment_size = (1 << adev->vm_manager.fragment_size) * AMDGPU_GPU_PAGE_SIZE;
83562306a36Sopenharmony_ci		dev_info->gart_page_size = max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE);
83662306a36Sopenharmony_ci		dev_info->cu_active_number = adev->gfx.cu_info.number;
83762306a36Sopenharmony_ci		dev_info->cu_ao_mask = adev->gfx.cu_info.ao_cu_mask;
83862306a36Sopenharmony_ci		dev_info->ce_ram_size = adev->gfx.ce_ram_size;
83962306a36Sopenharmony_ci		memcpy(&dev_info->cu_ao_bitmap[0], &adev->gfx.cu_info.ao_cu_bitmap[0],
84062306a36Sopenharmony_ci		       sizeof(adev->gfx.cu_info.ao_cu_bitmap));
84162306a36Sopenharmony_ci		memcpy(&dev_info->cu_bitmap[0], &adev->gfx.cu_info.bitmap[0],
84262306a36Sopenharmony_ci		       sizeof(dev_info->cu_bitmap));
84362306a36Sopenharmony_ci		dev_info->vram_type = adev->gmc.vram_type;
84462306a36Sopenharmony_ci		dev_info->vram_bit_width = adev->gmc.vram_width;
84562306a36Sopenharmony_ci		dev_info->vce_harvest_config = adev->vce.harvest_config;
84662306a36Sopenharmony_ci		dev_info->gc_double_offchip_lds_buf =
84762306a36Sopenharmony_ci			adev->gfx.config.double_offchip_lds_buf;
84862306a36Sopenharmony_ci		dev_info->wave_front_size = adev->gfx.cu_info.wave_front_size;
84962306a36Sopenharmony_ci		dev_info->num_shader_visible_vgprs = adev->gfx.config.max_gprs;
85062306a36Sopenharmony_ci		dev_info->num_cu_per_sh = adev->gfx.config.max_cu_per_sh;
85162306a36Sopenharmony_ci		dev_info->num_tcc_blocks = adev->gfx.config.max_texture_channel_caches;
85262306a36Sopenharmony_ci		dev_info->gs_vgt_table_depth = adev->gfx.config.gs_vgt_table_depth;
85362306a36Sopenharmony_ci		dev_info->gs_prim_buffer_depth = adev->gfx.config.gs_prim_buffer_depth;
85462306a36Sopenharmony_ci		dev_info->max_gs_waves_per_vgt = adev->gfx.config.max_gs_threads;
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci		if (adev->family >= AMDGPU_FAMILY_NV)
85762306a36Sopenharmony_ci			dev_info->pa_sc_tile_steering_override =
85862306a36Sopenharmony_ci				adev->gfx.config.pa_sc_tile_steering_override;
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci		dev_info->tcc_disabled_mask = adev->gfx.config.tcc_disabled_mask;
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci		/* Combine the chip gen mask with the platform (CPU/mobo) mask. */
86362306a36Sopenharmony_ci		pcie_gen_mask = adev->pm.pcie_gen_mask & (adev->pm.pcie_gen_mask >> 16);
86462306a36Sopenharmony_ci		dev_info->pcie_gen = fls(pcie_gen_mask);
86562306a36Sopenharmony_ci		dev_info->pcie_num_lanes =
86662306a36Sopenharmony_ci			adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X32 ? 32 :
86762306a36Sopenharmony_ci			adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X16 ? 16 :
86862306a36Sopenharmony_ci			adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X12 ? 12 :
86962306a36Sopenharmony_ci			adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X8 ? 8 :
87062306a36Sopenharmony_ci			adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X4 ? 4 :
87162306a36Sopenharmony_ci			adev->pm.pcie_mlw_mask & CAIL_PCIE_LINK_WIDTH_SUPPORT_X2 ? 2 : 1;
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci		dev_info->tcp_cache_size = adev->gfx.config.gc_tcp_l1_size;
87462306a36Sopenharmony_ci		dev_info->num_sqc_per_wgp = adev->gfx.config.gc_num_sqc_per_wgp;
87562306a36Sopenharmony_ci		dev_info->sqc_data_cache_size = adev->gfx.config.gc_l1_data_cache_size_per_sqc;
87662306a36Sopenharmony_ci		dev_info->sqc_inst_cache_size = adev->gfx.config.gc_l1_instruction_cache_size_per_sqc;
87762306a36Sopenharmony_ci		dev_info->gl1c_cache_size = adev->gfx.config.gc_gl1c_size_per_instance *
87862306a36Sopenharmony_ci					    adev->gfx.config.gc_gl1c_per_sa;
87962306a36Sopenharmony_ci		dev_info->gl2c_cache_size = adev->gfx.config.gc_gl2c_per_gpu;
88062306a36Sopenharmony_ci		dev_info->mall_size = adev->gmc.mall_size;
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci		if (adev->gfx.funcs->get_gfx_shadow_info) {
88462306a36Sopenharmony_ci			struct amdgpu_gfx_shadow_info shadow_info;
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci			ret = amdgpu_gfx_get_gfx_shadow_info(adev, &shadow_info);
88762306a36Sopenharmony_ci			if (!ret) {
88862306a36Sopenharmony_ci				dev_info->shadow_size = shadow_info.shadow_size;
88962306a36Sopenharmony_ci				dev_info->shadow_alignment = shadow_info.shadow_alignment;
89062306a36Sopenharmony_ci				dev_info->csa_size = shadow_info.csa_size;
89162306a36Sopenharmony_ci				dev_info->csa_alignment = shadow_info.csa_alignment;
89262306a36Sopenharmony_ci			}
89362306a36Sopenharmony_ci		}
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci		ret = copy_to_user(out, dev_info,
89662306a36Sopenharmony_ci				   min((size_t)size, sizeof(*dev_info))) ? -EFAULT : 0;
89762306a36Sopenharmony_ci		kfree(dev_info);
89862306a36Sopenharmony_ci		return ret;
89962306a36Sopenharmony_ci	}
90062306a36Sopenharmony_ci	case AMDGPU_INFO_VCE_CLOCK_TABLE: {
90162306a36Sopenharmony_ci		unsigned int i;
90262306a36Sopenharmony_ci		struct drm_amdgpu_info_vce_clock_table vce_clk_table = {};
90362306a36Sopenharmony_ci		struct amd_vce_state *vce_state;
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci		for (i = 0; i < AMDGPU_VCE_CLOCK_TABLE_ENTRIES; i++) {
90662306a36Sopenharmony_ci			vce_state = amdgpu_dpm_get_vce_clock_state(adev, i);
90762306a36Sopenharmony_ci			if (vce_state) {
90862306a36Sopenharmony_ci				vce_clk_table.entries[i].sclk = vce_state->sclk;
90962306a36Sopenharmony_ci				vce_clk_table.entries[i].mclk = vce_state->mclk;
91062306a36Sopenharmony_ci				vce_clk_table.entries[i].eclk = vce_state->evclk;
91162306a36Sopenharmony_ci				vce_clk_table.num_valid_entries++;
91262306a36Sopenharmony_ci			}
91362306a36Sopenharmony_ci		}
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci		return copy_to_user(out, &vce_clk_table,
91662306a36Sopenharmony_ci				    min((size_t)size, sizeof(vce_clk_table))) ? -EFAULT : 0;
91762306a36Sopenharmony_ci	}
91862306a36Sopenharmony_ci	case AMDGPU_INFO_VBIOS: {
91962306a36Sopenharmony_ci		uint32_t bios_size = adev->bios_size;
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci		switch (info->vbios_info.type) {
92262306a36Sopenharmony_ci		case AMDGPU_INFO_VBIOS_SIZE:
92362306a36Sopenharmony_ci			return copy_to_user(out, &bios_size,
92462306a36Sopenharmony_ci					min((size_t)size, sizeof(bios_size)))
92562306a36Sopenharmony_ci					? -EFAULT : 0;
92662306a36Sopenharmony_ci		case AMDGPU_INFO_VBIOS_IMAGE: {
92762306a36Sopenharmony_ci			uint8_t *bios;
92862306a36Sopenharmony_ci			uint32_t bios_offset = info->vbios_info.offset;
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci			if (bios_offset >= bios_size)
93162306a36Sopenharmony_ci				return -EINVAL;
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci			bios = adev->bios + bios_offset;
93462306a36Sopenharmony_ci			return copy_to_user(out, bios,
93562306a36Sopenharmony_ci					    min((size_t)size, (size_t)(bios_size - bios_offset)))
93662306a36Sopenharmony_ci					? -EFAULT : 0;
93762306a36Sopenharmony_ci		}
93862306a36Sopenharmony_ci		case AMDGPU_INFO_VBIOS_INFO: {
93962306a36Sopenharmony_ci			struct drm_amdgpu_info_vbios vbios_info = {};
94062306a36Sopenharmony_ci			struct atom_context *atom_context;
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci			atom_context = adev->mode_info.atom_context;
94362306a36Sopenharmony_ci			if (atom_context) {
94462306a36Sopenharmony_ci				memcpy(vbios_info.name, atom_context->name,
94562306a36Sopenharmony_ci				       sizeof(atom_context->name));
94662306a36Sopenharmony_ci				memcpy(vbios_info.vbios_pn, atom_context->vbios_pn,
94762306a36Sopenharmony_ci				       sizeof(atom_context->vbios_pn));
94862306a36Sopenharmony_ci				vbios_info.version = atom_context->version;
94962306a36Sopenharmony_ci				memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
95062306a36Sopenharmony_ci				       sizeof(atom_context->vbios_ver_str));
95162306a36Sopenharmony_ci				memcpy(vbios_info.date, atom_context->date,
95262306a36Sopenharmony_ci				       sizeof(atom_context->date));
95362306a36Sopenharmony_ci			}
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_ci			return copy_to_user(out, &vbios_info,
95662306a36Sopenharmony_ci						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
95762306a36Sopenharmony_ci		}
95862306a36Sopenharmony_ci		default:
95962306a36Sopenharmony_ci			DRM_DEBUG_KMS("Invalid request %d\n",
96062306a36Sopenharmony_ci					info->vbios_info.type);
96162306a36Sopenharmony_ci			return -EINVAL;
96262306a36Sopenharmony_ci		}
96362306a36Sopenharmony_ci	}
96462306a36Sopenharmony_ci	case AMDGPU_INFO_NUM_HANDLES: {
96562306a36Sopenharmony_ci		struct drm_amdgpu_info_num_handles handle;
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci		switch (info->query_hw_ip.type) {
96862306a36Sopenharmony_ci		case AMDGPU_HW_IP_UVD:
96962306a36Sopenharmony_ci			/* Starting Polaris, we support unlimited UVD handles */
97062306a36Sopenharmony_ci			if (adev->asic_type < CHIP_POLARIS10) {
97162306a36Sopenharmony_ci				handle.uvd_max_handles = adev->uvd.max_handles;
97262306a36Sopenharmony_ci				handle.uvd_used_handles = amdgpu_uvd_used_handles(adev);
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci				return copy_to_user(out, &handle,
97562306a36Sopenharmony_ci					min((size_t)size, sizeof(handle))) ? -EFAULT : 0;
97662306a36Sopenharmony_ci			} else {
97762306a36Sopenharmony_ci				return -ENODATA;
97862306a36Sopenharmony_ci			}
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci			break;
98162306a36Sopenharmony_ci		default:
98262306a36Sopenharmony_ci			return -EINVAL;
98362306a36Sopenharmony_ci		}
98462306a36Sopenharmony_ci	}
98562306a36Sopenharmony_ci	case AMDGPU_INFO_SENSOR: {
98662306a36Sopenharmony_ci		if (!adev->pm.dpm_enabled)
98762306a36Sopenharmony_ci			return -ENOENT;
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci		switch (info->sensor_info.type) {
99062306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_GFX_SCLK:
99162306a36Sopenharmony_ci			/* get sclk in Mhz */
99262306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
99362306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_GFX_SCLK,
99462306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
99562306a36Sopenharmony_ci				return -EINVAL;
99662306a36Sopenharmony_ci			}
99762306a36Sopenharmony_ci			ui32 /= 100;
99862306a36Sopenharmony_ci			break;
99962306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_GFX_MCLK:
100062306a36Sopenharmony_ci			/* get mclk in Mhz */
100162306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
100262306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_GFX_MCLK,
100362306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
100462306a36Sopenharmony_ci				return -EINVAL;
100562306a36Sopenharmony_ci			}
100662306a36Sopenharmony_ci			ui32 /= 100;
100762306a36Sopenharmony_ci			break;
100862306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_GPU_TEMP:
100962306a36Sopenharmony_ci			/* get temperature in millidegrees C */
101062306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
101162306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_GPU_TEMP,
101262306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
101362306a36Sopenharmony_ci				return -EINVAL;
101462306a36Sopenharmony_ci			}
101562306a36Sopenharmony_ci			break;
101662306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_GPU_LOAD:
101762306a36Sopenharmony_ci			/* get GPU load */
101862306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
101962306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_GPU_LOAD,
102062306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
102162306a36Sopenharmony_ci				return -EINVAL;
102262306a36Sopenharmony_ci			}
102362306a36Sopenharmony_ci			break;
102462306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_GPU_AVG_POWER:
102562306a36Sopenharmony_ci			/* get average GPU power */
102662306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
102762306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_GPU_AVG_POWER,
102862306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
102962306a36Sopenharmony_ci				/* fall back to input power for backwards compat */
103062306a36Sopenharmony_ci				if (amdgpu_dpm_read_sensor(adev,
103162306a36Sopenharmony_ci							   AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
103262306a36Sopenharmony_ci							   (void *)&ui32, &ui32_size)) {
103362306a36Sopenharmony_ci					return -EINVAL;
103462306a36Sopenharmony_ci				}
103562306a36Sopenharmony_ci			}
103662306a36Sopenharmony_ci			ui32 >>= 8;
103762306a36Sopenharmony_ci			break;
103862306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_VDDNB:
103962306a36Sopenharmony_ci			/* get VDDNB in millivolts */
104062306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
104162306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_VDDNB,
104262306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
104362306a36Sopenharmony_ci				return -EINVAL;
104462306a36Sopenharmony_ci			}
104562306a36Sopenharmony_ci			break;
104662306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_VDDGFX:
104762306a36Sopenharmony_ci			/* get VDDGFX in millivolts */
104862306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
104962306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_VDDGFX,
105062306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
105162306a36Sopenharmony_ci				return -EINVAL;
105262306a36Sopenharmony_ci			}
105362306a36Sopenharmony_ci			break;
105462306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK:
105562306a36Sopenharmony_ci			/* get stable pstate sclk in Mhz */
105662306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
105762306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK,
105862306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
105962306a36Sopenharmony_ci				return -EINVAL;
106062306a36Sopenharmony_ci			}
106162306a36Sopenharmony_ci			ui32 /= 100;
106262306a36Sopenharmony_ci			break;
106362306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_MCLK:
106462306a36Sopenharmony_ci			/* get stable pstate mclk in Mhz */
106562306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
106662306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK,
106762306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
106862306a36Sopenharmony_ci				return -EINVAL;
106962306a36Sopenharmony_ci			}
107062306a36Sopenharmony_ci			ui32 /= 100;
107162306a36Sopenharmony_ci			break;
107262306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_SCLK:
107362306a36Sopenharmony_ci			/* get peak pstate sclk in Mhz */
107462306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
107562306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_PEAK_PSTATE_SCLK,
107662306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
107762306a36Sopenharmony_ci				return -EINVAL;
107862306a36Sopenharmony_ci			}
107962306a36Sopenharmony_ci			ui32 /= 100;
108062306a36Sopenharmony_ci			break;
108162306a36Sopenharmony_ci		case AMDGPU_INFO_SENSOR_PEAK_PSTATE_GFX_MCLK:
108262306a36Sopenharmony_ci			/* get peak pstate mclk in Mhz */
108362306a36Sopenharmony_ci			if (amdgpu_dpm_read_sensor(adev,
108462306a36Sopenharmony_ci						   AMDGPU_PP_SENSOR_PEAK_PSTATE_MCLK,
108562306a36Sopenharmony_ci						   (void *)&ui32, &ui32_size)) {
108662306a36Sopenharmony_ci				return -EINVAL;
108762306a36Sopenharmony_ci			}
108862306a36Sopenharmony_ci			ui32 /= 100;
108962306a36Sopenharmony_ci			break;
109062306a36Sopenharmony_ci		default:
109162306a36Sopenharmony_ci			DRM_DEBUG_KMS("Invalid request %d\n",
109262306a36Sopenharmony_ci				      info->sensor_info.type);
109362306a36Sopenharmony_ci			return -EINVAL;
109462306a36Sopenharmony_ci		}
109562306a36Sopenharmony_ci		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
109662306a36Sopenharmony_ci	}
109762306a36Sopenharmony_ci	case AMDGPU_INFO_VRAM_LOST_COUNTER:
109862306a36Sopenharmony_ci		ui32 = atomic_read(&adev->vram_lost_counter);
109962306a36Sopenharmony_ci		return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
110062306a36Sopenharmony_ci	case AMDGPU_INFO_RAS_ENABLED_FEATURES: {
110162306a36Sopenharmony_ci		struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
110262306a36Sopenharmony_ci		uint64_t ras_mask;
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci		if (!ras)
110562306a36Sopenharmony_ci			return -EINVAL;
110662306a36Sopenharmony_ci		ras_mask = (uint64_t)adev->ras_enabled << 32 | ras->features;
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_ci		return copy_to_user(out, &ras_mask,
110962306a36Sopenharmony_ci				min_t(u64, size, sizeof(ras_mask))) ?
111062306a36Sopenharmony_ci			-EFAULT : 0;
111162306a36Sopenharmony_ci	}
111262306a36Sopenharmony_ci	case AMDGPU_INFO_VIDEO_CAPS: {
111362306a36Sopenharmony_ci		const struct amdgpu_video_codecs *codecs;
111462306a36Sopenharmony_ci		struct drm_amdgpu_info_video_caps *caps;
111562306a36Sopenharmony_ci		int r;
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_ci		if (!adev->asic_funcs->query_video_codecs)
111862306a36Sopenharmony_ci			return -EINVAL;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci		switch (info->video_cap.type) {
112162306a36Sopenharmony_ci		case AMDGPU_INFO_VIDEO_CAPS_DECODE:
112262306a36Sopenharmony_ci			r = amdgpu_asic_query_video_codecs(adev, false, &codecs);
112362306a36Sopenharmony_ci			if (r)
112462306a36Sopenharmony_ci				return -EINVAL;
112562306a36Sopenharmony_ci			break;
112662306a36Sopenharmony_ci		case AMDGPU_INFO_VIDEO_CAPS_ENCODE:
112762306a36Sopenharmony_ci			r = amdgpu_asic_query_video_codecs(adev, true, &codecs);
112862306a36Sopenharmony_ci			if (r)
112962306a36Sopenharmony_ci				return -EINVAL;
113062306a36Sopenharmony_ci			break;
113162306a36Sopenharmony_ci		default:
113262306a36Sopenharmony_ci			DRM_DEBUG_KMS("Invalid request %d\n",
113362306a36Sopenharmony_ci				      info->video_cap.type);
113462306a36Sopenharmony_ci			return -EINVAL;
113562306a36Sopenharmony_ci		}
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci		caps = kzalloc(sizeof(*caps), GFP_KERNEL);
113862306a36Sopenharmony_ci		if (!caps)
113962306a36Sopenharmony_ci			return -ENOMEM;
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci		for (i = 0; i < codecs->codec_count; i++) {
114262306a36Sopenharmony_ci			int idx = codecs->codec_array[i].codec_type;
114362306a36Sopenharmony_ci
114462306a36Sopenharmony_ci			switch (idx) {
114562306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2:
114662306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4:
114762306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1:
114862306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC:
114962306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC:
115062306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG:
115162306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9:
115262306a36Sopenharmony_ci			case AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1:
115362306a36Sopenharmony_ci				caps->codec_info[idx].valid = 1;
115462306a36Sopenharmony_ci				caps->codec_info[idx].max_width =
115562306a36Sopenharmony_ci					codecs->codec_array[i].max_width;
115662306a36Sopenharmony_ci				caps->codec_info[idx].max_height =
115762306a36Sopenharmony_ci					codecs->codec_array[i].max_height;
115862306a36Sopenharmony_ci				caps->codec_info[idx].max_pixels_per_frame =
115962306a36Sopenharmony_ci					codecs->codec_array[i].max_pixels_per_frame;
116062306a36Sopenharmony_ci				caps->codec_info[idx].max_level =
116162306a36Sopenharmony_ci					codecs->codec_array[i].max_level;
116262306a36Sopenharmony_ci				break;
116362306a36Sopenharmony_ci			default:
116462306a36Sopenharmony_ci				break;
116562306a36Sopenharmony_ci			}
116662306a36Sopenharmony_ci		}
116762306a36Sopenharmony_ci		r = copy_to_user(out, caps,
116862306a36Sopenharmony_ci				 min((size_t)size, sizeof(*caps))) ? -EFAULT : 0;
116962306a36Sopenharmony_ci		kfree(caps);
117062306a36Sopenharmony_ci		return r;
117162306a36Sopenharmony_ci	}
117262306a36Sopenharmony_ci	case AMDGPU_INFO_MAX_IBS: {
117362306a36Sopenharmony_ci		uint32_t max_ibs[AMDGPU_HW_IP_NUM];
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci		for (i = 0; i < AMDGPU_HW_IP_NUM; ++i)
117662306a36Sopenharmony_ci			max_ibs[i] = amdgpu_ring_max_ibs(i);
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci		return copy_to_user(out, max_ibs,
117962306a36Sopenharmony_ci				    min((size_t)size, sizeof(max_ibs))) ? -EFAULT : 0;
118062306a36Sopenharmony_ci	}
118162306a36Sopenharmony_ci	default:
118262306a36Sopenharmony_ci		DRM_DEBUG_KMS("Invalid request %d\n", info->query);
118362306a36Sopenharmony_ci		return -EINVAL;
118462306a36Sopenharmony_ci	}
118562306a36Sopenharmony_ci	return 0;
118662306a36Sopenharmony_ci}
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci/*
119062306a36Sopenharmony_ci * Outdated mess for old drm with Xorg being in charge (void function now).
119162306a36Sopenharmony_ci */
119262306a36Sopenharmony_ci/**
119362306a36Sopenharmony_ci * amdgpu_driver_lastclose_kms - drm callback for last close
119462306a36Sopenharmony_ci *
119562306a36Sopenharmony_ci * @dev: drm dev pointer
119662306a36Sopenharmony_ci *
119762306a36Sopenharmony_ci * Switch vga_switcheroo state after last close (all asics).
119862306a36Sopenharmony_ci */
119962306a36Sopenharmony_civoid amdgpu_driver_lastclose_kms(struct drm_device *dev)
120062306a36Sopenharmony_ci{
120162306a36Sopenharmony_ci	drm_fb_helper_lastclose(dev);
120262306a36Sopenharmony_ci	vga_switcheroo_process_delayed_switch();
120362306a36Sopenharmony_ci}
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci/**
120662306a36Sopenharmony_ci * amdgpu_driver_open_kms - drm callback for open
120762306a36Sopenharmony_ci *
120862306a36Sopenharmony_ci * @dev: drm dev pointer
120962306a36Sopenharmony_ci * @file_priv: drm file
121062306a36Sopenharmony_ci *
121162306a36Sopenharmony_ci * On device open, init vm on cayman+ (all asics).
121262306a36Sopenharmony_ci * Returns 0 on success, error on failure.
121362306a36Sopenharmony_ci */
121462306a36Sopenharmony_ciint amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
121562306a36Sopenharmony_ci{
121662306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
121762306a36Sopenharmony_ci	struct amdgpu_fpriv *fpriv;
121862306a36Sopenharmony_ci	int r, pasid;
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci	/* Ensure IB tests are run on ring */
122162306a36Sopenharmony_ci	flush_delayed_work(&adev->delayed_init_work);
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci	if (amdgpu_ras_intr_triggered()) {
122562306a36Sopenharmony_ci		DRM_ERROR("RAS Intr triggered, device disabled!!");
122662306a36Sopenharmony_ci		return -EHWPOISON;
122762306a36Sopenharmony_ci	}
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	file_priv->driver_priv = NULL;
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	r = pm_runtime_get_sync(dev->dev);
123262306a36Sopenharmony_ci	if (r < 0)
123362306a36Sopenharmony_ci		goto pm_put;
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_ci	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
123662306a36Sopenharmony_ci	if (unlikely(!fpriv)) {
123762306a36Sopenharmony_ci		r = -ENOMEM;
123862306a36Sopenharmony_ci		goto out_suspend;
123962306a36Sopenharmony_ci	}
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci	pasid = amdgpu_pasid_alloc(16);
124262306a36Sopenharmony_ci	if (pasid < 0) {
124362306a36Sopenharmony_ci		dev_warn(adev->dev, "No more PASIDs available!");
124462306a36Sopenharmony_ci		pasid = 0;
124562306a36Sopenharmony_ci	}
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	r = amdgpu_xcp_open_device(adev, fpriv, file_priv);
124862306a36Sopenharmony_ci	if (r)
124962306a36Sopenharmony_ci		goto error_pasid;
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	r = amdgpu_vm_init(adev, &fpriv->vm, fpriv->xcp_id);
125262306a36Sopenharmony_ci	if (r)
125362306a36Sopenharmony_ci		goto error_pasid;
125462306a36Sopenharmony_ci
125562306a36Sopenharmony_ci	r = amdgpu_vm_set_pasid(adev, &fpriv->vm, pasid);
125662306a36Sopenharmony_ci	if (r)
125762306a36Sopenharmony_ci		goto error_vm;
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL);
126062306a36Sopenharmony_ci	if (!fpriv->prt_va) {
126162306a36Sopenharmony_ci		r = -ENOMEM;
126262306a36Sopenharmony_ci		goto error_vm;
126362306a36Sopenharmony_ci	}
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	if (adev->gfx.mcbp) {
126662306a36Sopenharmony_ci		uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK;
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci		r = amdgpu_map_static_csa(adev, &fpriv->vm, adev->virt.csa_obj,
126962306a36Sopenharmony_ci						&fpriv->csa_va, csa_addr, AMDGPU_CSA_SIZE);
127062306a36Sopenharmony_ci		if (r)
127162306a36Sopenharmony_ci			goto error_vm;
127262306a36Sopenharmony_ci	}
127362306a36Sopenharmony_ci
127462306a36Sopenharmony_ci	mutex_init(&fpriv->bo_list_lock);
127562306a36Sopenharmony_ci	idr_init_base(&fpriv->bo_list_handles, 1);
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci	amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci	file_priv->driver_priv = fpriv;
128062306a36Sopenharmony_ci	goto out_suspend;
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_cierror_vm:
128362306a36Sopenharmony_ci	amdgpu_vm_fini(adev, &fpriv->vm);
128462306a36Sopenharmony_ci
128562306a36Sopenharmony_cierror_pasid:
128662306a36Sopenharmony_ci	if (pasid) {
128762306a36Sopenharmony_ci		amdgpu_pasid_free(pasid);
128862306a36Sopenharmony_ci		amdgpu_vm_set_pasid(adev, &fpriv->vm, 0);
128962306a36Sopenharmony_ci	}
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	kfree(fpriv);
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ciout_suspend:
129462306a36Sopenharmony_ci	pm_runtime_mark_last_busy(dev->dev);
129562306a36Sopenharmony_cipm_put:
129662306a36Sopenharmony_ci	pm_runtime_put_autosuspend(dev->dev);
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci	return r;
129962306a36Sopenharmony_ci}
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci/**
130262306a36Sopenharmony_ci * amdgpu_driver_postclose_kms - drm callback for post close
130362306a36Sopenharmony_ci *
130462306a36Sopenharmony_ci * @dev: drm dev pointer
130562306a36Sopenharmony_ci * @file_priv: drm file
130662306a36Sopenharmony_ci *
130762306a36Sopenharmony_ci * On device post close, tear down vm on cayman+ (all asics).
130862306a36Sopenharmony_ci */
130962306a36Sopenharmony_civoid amdgpu_driver_postclose_kms(struct drm_device *dev,
131062306a36Sopenharmony_ci				 struct drm_file *file_priv)
131162306a36Sopenharmony_ci{
131262306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
131362306a36Sopenharmony_ci	struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
131462306a36Sopenharmony_ci	struct amdgpu_bo_list *list;
131562306a36Sopenharmony_ci	struct amdgpu_bo *pd;
131662306a36Sopenharmony_ci	u32 pasid;
131762306a36Sopenharmony_ci	int handle;
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	if (!fpriv)
132062306a36Sopenharmony_ci		return;
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci	pm_runtime_get_sync(dev->dev);
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_UVD) != NULL)
132562306a36Sopenharmony_ci		amdgpu_uvd_free_handles(adev, file_priv);
132662306a36Sopenharmony_ci	if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL)
132762306a36Sopenharmony_ci		amdgpu_vce_free_handles(adev, file_priv);
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci	if (fpriv->csa_va) {
133062306a36Sopenharmony_ci		uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK;
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci		WARN_ON(amdgpu_unmap_static_csa(adev, &fpriv->vm, adev->virt.csa_obj,
133362306a36Sopenharmony_ci						fpriv->csa_va, csa_addr));
133462306a36Sopenharmony_ci		fpriv->csa_va = NULL;
133562306a36Sopenharmony_ci	}
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_ci	pasid = fpriv->vm.pasid;
133862306a36Sopenharmony_ci	pd = amdgpu_bo_ref(fpriv->vm.root.bo);
133962306a36Sopenharmony_ci	if (!WARN_ON(amdgpu_bo_reserve(pd, true))) {
134062306a36Sopenharmony_ci		amdgpu_vm_bo_del(adev, fpriv->prt_va);
134162306a36Sopenharmony_ci		amdgpu_bo_unreserve(pd);
134262306a36Sopenharmony_ci	}
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci	amdgpu_ctx_mgr_fini(&fpriv->ctx_mgr);
134562306a36Sopenharmony_ci	amdgpu_vm_fini(adev, &fpriv->vm);
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci	if (pasid)
134862306a36Sopenharmony_ci		amdgpu_pasid_free_delayed(pd->tbo.base.resv, pasid);
134962306a36Sopenharmony_ci	amdgpu_bo_unref(&pd);
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	idr_for_each_entry(&fpriv->bo_list_handles, list, handle)
135262306a36Sopenharmony_ci		amdgpu_bo_list_put(list);
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_ci	idr_destroy(&fpriv->bo_list_handles);
135562306a36Sopenharmony_ci	mutex_destroy(&fpriv->bo_list_lock);
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	kfree(fpriv);
135862306a36Sopenharmony_ci	file_priv->driver_priv = NULL;
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci	pm_runtime_mark_last_busy(dev->dev);
136162306a36Sopenharmony_ci	pm_runtime_put_autosuspend(dev->dev);
136262306a36Sopenharmony_ci}
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_civoid amdgpu_driver_release_kms(struct drm_device *dev)
136662306a36Sopenharmony_ci{
136762306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	amdgpu_device_fini_sw(adev);
137062306a36Sopenharmony_ci	pci_set_drvdata(adev->pdev, NULL);
137162306a36Sopenharmony_ci}
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci/*
137462306a36Sopenharmony_ci * VBlank related functions.
137562306a36Sopenharmony_ci */
137662306a36Sopenharmony_ci/**
137762306a36Sopenharmony_ci * amdgpu_get_vblank_counter_kms - get frame count
137862306a36Sopenharmony_ci *
137962306a36Sopenharmony_ci * @crtc: crtc to get the frame count from
138062306a36Sopenharmony_ci *
138162306a36Sopenharmony_ci * Gets the frame count on the requested crtc (all asics).
138262306a36Sopenharmony_ci * Returns frame count on success, -EINVAL on failure.
138362306a36Sopenharmony_ci */
138462306a36Sopenharmony_ciu32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc)
138562306a36Sopenharmony_ci{
138662306a36Sopenharmony_ci	struct drm_device *dev = crtc->dev;
138762306a36Sopenharmony_ci	unsigned int pipe = crtc->index;
138862306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
138962306a36Sopenharmony_ci	int vpos, hpos, stat;
139062306a36Sopenharmony_ci	u32 count;
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	if (pipe >= adev->mode_info.num_crtc) {
139362306a36Sopenharmony_ci		DRM_ERROR("Invalid crtc %u\n", pipe);
139462306a36Sopenharmony_ci		return -EINVAL;
139562306a36Sopenharmony_ci	}
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	/* The hw increments its frame counter at start of vsync, not at start
139862306a36Sopenharmony_ci	 * of vblank, as is required by DRM core vblank counter handling.
139962306a36Sopenharmony_ci	 * Cook the hw count here to make it appear to the caller as if it
140062306a36Sopenharmony_ci	 * incremented at start of vblank. We measure distance to start of
140162306a36Sopenharmony_ci	 * vblank in vpos. vpos therefore will be >= 0 between start of vblank
140262306a36Sopenharmony_ci	 * and start of vsync, so vpos >= 0 means to bump the hw frame counter
140362306a36Sopenharmony_ci	 * result by 1 to give the proper appearance to caller.
140462306a36Sopenharmony_ci	 */
140562306a36Sopenharmony_ci	if (adev->mode_info.crtcs[pipe]) {
140662306a36Sopenharmony_ci		/* Repeat readout if needed to provide stable result if
140762306a36Sopenharmony_ci		 * we cross start of vsync during the queries.
140862306a36Sopenharmony_ci		 */
140962306a36Sopenharmony_ci		do {
141062306a36Sopenharmony_ci			count = amdgpu_display_vblank_get_counter(adev, pipe);
141162306a36Sopenharmony_ci			/* Ask amdgpu_display_get_crtc_scanoutpos to return
141262306a36Sopenharmony_ci			 * vpos as distance to start of vblank, instead of
141362306a36Sopenharmony_ci			 * regular vertical scanout pos.
141462306a36Sopenharmony_ci			 */
141562306a36Sopenharmony_ci			stat = amdgpu_display_get_crtc_scanoutpos(
141662306a36Sopenharmony_ci				dev, pipe, GET_DISTANCE_TO_VBLANKSTART,
141762306a36Sopenharmony_ci				&vpos, &hpos, NULL, NULL,
141862306a36Sopenharmony_ci				&adev->mode_info.crtcs[pipe]->base.hwmode);
141962306a36Sopenharmony_ci		} while (count != amdgpu_display_vblank_get_counter(adev, pipe));
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci		if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
142262306a36Sopenharmony_ci		    (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) {
142362306a36Sopenharmony_ci			DRM_DEBUG_VBL("Query failed! stat %d\n", stat);
142462306a36Sopenharmony_ci		} else {
142562306a36Sopenharmony_ci			DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n",
142662306a36Sopenharmony_ci				      pipe, vpos);
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci			/* Bump counter if we are at >= leading edge of vblank,
142962306a36Sopenharmony_ci			 * but before vsync where vpos would turn negative and
143062306a36Sopenharmony_ci			 * the hw counter really increments.
143162306a36Sopenharmony_ci			 */
143262306a36Sopenharmony_ci			if (vpos >= 0)
143362306a36Sopenharmony_ci				count++;
143462306a36Sopenharmony_ci		}
143562306a36Sopenharmony_ci	} else {
143662306a36Sopenharmony_ci		/* Fallback to use value as is. */
143762306a36Sopenharmony_ci		count = amdgpu_display_vblank_get_counter(adev, pipe);
143862306a36Sopenharmony_ci		DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
143962306a36Sopenharmony_ci	}
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci	return count;
144262306a36Sopenharmony_ci}
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_ci/**
144562306a36Sopenharmony_ci * amdgpu_enable_vblank_kms - enable vblank interrupt
144662306a36Sopenharmony_ci *
144762306a36Sopenharmony_ci * @crtc: crtc to enable vblank interrupt for
144862306a36Sopenharmony_ci *
144962306a36Sopenharmony_ci * Enable the interrupt on the requested crtc (all asics).
145062306a36Sopenharmony_ci * Returns 0 on success, -EINVAL on failure.
145162306a36Sopenharmony_ci */
145262306a36Sopenharmony_ciint amdgpu_enable_vblank_kms(struct drm_crtc *crtc)
145362306a36Sopenharmony_ci{
145462306a36Sopenharmony_ci	struct drm_device *dev = crtc->dev;
145562306a36Sopenharmony_ci	unsigned int pipe = crtc->index;
145662306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
145762306a36Sopenharmony_ci	int idx = amdgpu_display_crtc_idx_to_irq_type(adev, pipe);
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci	return amdgpu_irq_get(adev, &adev->crtc_irq, idx);
146062306a36Sopenharmony_ci}
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci/**
146362306a36Sopenharmony_ci * amdgpu_disable_vblank_kms - disable vblank interrupt
146462306a36Sopenharmony_ci *
146562306a36Sopenharmony_ci * @crtc: crtc to disable vblank interrupt for
146662306a36Sopenharmony_ci *
146762306a36Sopenharmony_ci * Disable the interrupt on the requested crtc (all asics).
146862306a36Sopenharmony_ci */
146962306a36Sopenharmony_civoid amdgpu_disable_vblank_kms(struct drm_crtc *crtc)
147062306a36Sopenharmony_ci{
147162306a36Sopenharmony_ci	struct drm_device *dev = crtc->dev;
147262306a36Sopenharmony_ci	unsigned int pipe = crtc->index;
147362306a36Sopenharmony_ci	struct amdgpu_device *adev = drm_to_adev(dev);
147462306a36Sopenharmony_ci	int idx = amdgpu_display_crtc_idx_to_irq_type(adev, pipe);
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	amdgpu_irq_put(adev, &adev->crtc_irq, idx);
147762306a36Sopenharmony_ci}
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci/*
148062306a36Sopenharmony_ci * Debugfs info
148162306a36Sopenharmony_ci */
148262306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_FS)
148362306a36Sopenharmony_ci
148462306a36Sopenharmony_cistatic int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void *unused)
148562306a36Sopenharmony_ci{
148662306a36Sopenharmony_ci	struct amdgpu_device *adev = m->private;
148762306a36Sopenharmony_ci	struct drm_amdgpu_info_firmware fw_info;
148862306a36Sopenharmony_ci	struct drm_amdgpu_query_fw query_fw;
148962306a36Sopenharmony_ci	struct atom_context *ctx = adev->mode_info.atom_context;
149062306a36Sopenharmony_ci	uint8_t smu_program, smu_major, smu_minor, smu_debug;
149162306a36Sopenharmony_ci	int ret, i;
149262306a36Sopenharmony_ci
149362306a36Sopenharmony_ci	static const char *ta_fw_name[TA_FW_TYPE_MAX_INDEX] = {
149462306a36Sopenharmony_ci#define TA_FW_NAME(type)[TA_FW_TYPE_PSP_##type] = #type
149562306a36Sopenharmony_ci		TA_FW_NAME(XGMI),
149662306a36Sopenharmony_ci		TA_FW_NAME(RAS),
149762306a36Sopenharmony_ci		TA_FW_NAME(HDCP),
149862306a36Sopenharmony_ci		TA_FW_NAME(DTM),
149962306a36Sopenharmony_ci		TA_FW_NAME(RAP),
150062306a36Sopenharmony_ci		TA_FW_NAME(SECUREDISPLAY),
150162306a36Sopenharmony_ci#undef TA_FW_NAME
150262306a36Sopenharmony_ci	};
150362306a36Sopenharmony_ci
150462306a36Sopenharmony_ci	/* VCE */
150562306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_VCE;
150662306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
150762306a36Sopenharmony_ci	if (ret)
150862306a36Sopenharmony_ci		return ret;
150962306a36Sopenharmony_ci	seq_printf(m, "VCE feature version: %u, firmware version: 0x%08x\n",
151062306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
151162306a36Sopenharmony_ci
151262306a36Sopenharmony_ci	/* UVD */
151362306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_UVD;
151462306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
151562306a36Sopenharmony_ci	if (ret)
151662306a36Sopenharmony_ci		return ret;
151762306a36Sopenharmony_ci	seq_printf(m, "UVD feature version: %u, firmware version: 0x%08x\n",
151862306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_ci	/* GMC */
152162306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GMC;
152262306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
152362306a36Sopenharmony_ci	if (ret)
152462306a36Sopenharmony_ci		return ret;
152562306a36Sopenharmony_ci	seq_printf(m, "MC feature version: %u, firmware version: 0x%08x\n",
152662306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_ci	/* ME */
152962306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_ME;
153062306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
153162306a36Sopenharmony_ci	if (ret)
153262306a36Sopenharmony_ci		return ret;
153362306a36Sopenharmony_ci	seq_printf(m, "ME feature version: %u, firmware version: 0x%08x\n",
153462306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
153562306a36Sopenharmony_ci
153662306a36Sopenharmony_ci	/* PFP */
153762306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_PFP;
153862306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
153962306a36Sopenharmony_ci	if (ret)
154062306a36Sopenharmony_ci		return ret;
154162306a36Sopenharmony_ci	seq_printf(m, "PFP feature version: %u, firmware version: 0x%08x\n",
154262306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
154362306a36Sopenharmony_ci
154462306a36Sopenharmony_ci	/* CE */
154562306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_CE;
154662306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
154762306a36Sopenharmony_ci	if (ret)
154862306a36Sopenharmony_ci		return ret;
154962306a36Sopenharmony_ci	seq_printf(m, "CE feature version: %u, firmware version: 0x%08x\n",
155062306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci	/* RLC */
155362306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC;
155462306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
155562306a36Sopenharmony_ci	if (ret)
155662306a36Sopenharmony_ci		return ret;
155762306a36Sopenharmony_ci	seq_printf(m, "RLC feature version: %u, firmware version: 0x%08x\n",
155862306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci	/* RLC SAVE RESTORE LIST CNTL */
156162306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_CNTL;
156262306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
156362306a36Sopenharmony_ci	if (ret)
156462306a36Sopenharmony_ci		return ret;
156562306a36Sopenharmony_ci	seq_printf(m, "RLC SRLC feature version: %u, firmware version: 0x%08x\n",
156662306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
156762306a36Sopenharmony_ci
156862306a36Sopenharmony_ci	/* RLC SAVE RESTORE LIST GPM MEM */
156962306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_GPM_MEM;
157062306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
157162306a36Sopenharmony_ci	if (ret)
157262306a36Sopenharmony_ci		return ret;
157362306a36Sopenharmony_ci	seq_printf(m, "RLC SRLG feature version: %u, firmware version: 0x%08x\n",
157462306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_ci	/* RLC SAVE RESTORE LIST SRM MEM */
157762306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLC_RESTORE_LIST_SRM_MEM;
157862306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
157962306a36Sopenharmony_ci	if (ret)
158062306a36Sopenharmony_ci		return ret;
158162306a36Sopenharmony_ci	seq_printf(m, "RLC SRLS feature version: %u, firmware version: 0x%08x\n",
158262306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	/* RLCP */
158562306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCP;
158662306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
158762306a36Sopenharmony_ci	if (ret)
158862306a36Sopenharmony_ci		return ret;
158962306a36Sopenharmony_ci	seq_printf(m, "RLCP feature version: %u, firmware version: 0x%08x\n",
159062306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
159162306a36Sopenharmony_ci
159262306a36Sopenharmony_ci	/* RLCV */
159362306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_RLCV;
159462306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
159562306a36Sopenharmony_ci	if (ret)
159662306a36Sopenharmony_ci		return ret;
159762306a36Sopenharmony_ci	seq_printf(m, "RLCV feature version: %u, firmware version: 0x%08x\n",
159862306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_ci	/* MEC */
160162306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_GFX_MEC;
160262306a36Sopenharmony_ci	query_fw.index = 0;
160362306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
160462306a36Sopenharmony_ci	if (ret)
160562306a36Sopenharmony_ci		return ret;
160662306a36Sopenharmony_ci	seq_printf(m, "MEC feature version: %u, firmware version: 0x%08x\n",
160762306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci	/* MEC2 */
161062306a36Sopenharmony_ci	if (adev->gfx.mec2_fw) {
161162306a36Sopenharmony_ci		query_fw.index = 1;
161262306a36Sopenharmony_ci		ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
161362306a36Sopenharmony_ci		if (ret)
161462306a36Sopenharmony_ci			return ret;
161562306a36Sopenharmony_ci		seq_printf(m, "MEC2 feature version: %u, firmware version: 0x%08x\n",
161662306a36Sopenharmony_ci			   fw_info.feature, fw_info.ver);
161762306a36Sopenharmony_ci	}
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_ci	/* IMU */
162062306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_IMU;
162162306a36Sopenharmony_ci	query_fw.index = 0;
162262306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
162362306a36Sopenharmony_ci	if (ret)
162462306a36Sopenharmony_ci		return ret;
162562306a36Sopenharmony_ci	seq_printf(m, "IMU feature version: %u, firmware version: 0x%08x\n",
162662306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
162762306a36Sopenharmony_ci
162862306a36Sopenharmony_ci	/* PSP SOS */
162962306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_SOS;
163062306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
163162306a36Sopenharmony_ci	if (ret)
163262306a36Sopenharmony_ci		return ret;
163362306a36Sopenharmony_ci	seq_printf(m, "SOS feature version: %u, firmware version: 0x%08x\n",
163462306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_ci	/* PSP ASD */
163862306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_ASD;
163962306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
164062306a36Sopenharmony_ci	if (ret)
164162306a36Sopenharmony_ci		return ret;
164262306a36Sopenharmony_ci	seq_printf(m, "ASD feature version: %u, firmware version: 0x%08x\n",
164362306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
164462306a36Sopenharmony_ci
164562306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_TA;
164662306a36Sopenharmony_ci	for (i = TA_FW_TYPE_PSP_XGMI; i < TA_FW_TYPE_MAX_INDEX; i++) {
164762306a36Sopenharmony_ci		query_fw.index = i;
164862306a36Sopenharmony_ci		ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
164962306a36Sopenharmony_ci		if (ret)
165062306a36Sopenharmony_ci			continue;
165162306a36Sopenharmony_ci
165262306a36Sopenharmony_ci		seq_printf(m, "TA %s feature version: 0x%08x, firmware version: 0x%08x\n",
165362306a36Sopenharmony_ci			   ta_fw_name[i], fw_info.feature, fw_info.ver);
165462306a36Sopenharmony_ci	}
165562306a36Sopenharmony_ci
165662306a36Sopenharmony_ci	/* SMC */
165762306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_SMC;
165862306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
165962306a36Sopenharmony_ci	if (ret)
166062306a36Sopenharmony_ci		return ret;
166162306a36Sopenharmony_ci	smu_program = (fw_info.ver >> 24) & 0xff;
166262306a36Sopenharmony_ci	smu_major = (fw_info.ver >> 16) & 0xff;
166362306a36Sopenharmony_ci	smu_minor = (fw_info.ver >> 8) & 0xff;
166462306a36Sopenharmony_ci	smu_debug = (fw_info.ver >> 0) & 0xff;
166562306a36Sopenharmony_ci	seq_printf(m, "SMC feature version: %u, program: %d, firmware version: 0x%08x (%d.%d.%d)\n",
166662306a36Sopenharmony_ci		   fw_info.feature, smu_program, fw_info.ver, smu_major, smu_minor, smu_debug);
166762306a36Sopenharmony_ci
166862306a36Sopenharmony_ci	/* SDMA */
166962306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_SDMA;
167062306a36Sopenharmony_ci	for (i = 0; i < adev->sdma.num_instances; i++) {
167162306a36Sopenharmony_ci		query_fw.index = i;
167262306a36Sopenharmony_ci		ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
167362306a36Sopenharmony_ci		if (ret)
167462306a36Sopenharmony_ci			return ret;
167562306a36Sopenharmony_ci		seq_printf(m, "SDMA%d feature version: %u, firmware version: 0x%08x\n",
167662306a36Sopenharmony_ci			   i, fw_info.feature, fw_info.ver);
167762306a36Sopenharmony_ci	}
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci	/* VCN */
168062306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_VCN;
168162306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
168262306a36Sopenharmony_ci	if (ret)
168362306a36Sopenharmony_ci		return ret;
168462306a36Sopenharmony_ci	seq_printf(m, "VCN feature version: %u, firmware version: 0x%08x\n",
168562306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
168662306a36Sopenharmony_ci
168762306a36Sopenharmony_ci	/* DMCU */
168862306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_DMCU;
168962306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
169062306a36Sopenharmony_ci	if (ret)
169162306a36Sopenharmony_ci		return ret;
169262306a36Sopenharmony_ci	seq_printf(m, "DMCU feature version: %u, firmware version: 0x%08x\n",
169362306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
169462306a36Sopenharmony_ci
169562306a36Sopenharmony_ci	/* DMCUB */
169662306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_DMCUB;
169762306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
169862306a36Sopenharmony_ci	if (ret)
169962306a36Sopenharmony_ci		return ret;
170062306a36Sopenharmony_ci	seq_printf(m, "DMCUB feature version: %u, firmware version: 0x%08x\n",
170162306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	/* TOC */
170462306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_TOC;
170562306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
170662306a36Sopenharmony_ci	if (ret)
170762306a36Sopenharmony_ci		return ret;
170862306a36Sopenharmony_ci	seq_printf(m, "TOC feature version: %u, firmware version: 0x%08x\n",
170962306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci	/* CAP */
171262306a36Sopenharmony_ci	if (adev->psp.cap_fw) {
171362306a36Sopenharmony_ci		query_fw.fw_type = AMDGPU_INFO_FW_CAP;
171462306a36Sopenharmony_ci		ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
171562306a36Sopenharmony_ci		if (ret)
171662306a36Sopenharmony_ci			return ret;
171762306a36Sopenharmony_ci		seq_printf(m, "CAP feature version: %u, firmware version: 0x%08x\n",
171862306a36Sopenharmony_ci				fw_info.feature, fw_info.ver);
171962306a36Sopenharmony_ci	}
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci	/* MES_KIQ */
172262306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_MES_KIQ;
172362306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
172462306a36Sopenharmony_ci	if (ret)
172562306a36Sopenharmony_ci		return ret;
172662306a36Sopenharmony_ci	seq_printf(m, "MES_KIQ feature version: %u, firmware version: 0x%08x\n",
172762306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci	/* MES */
173062306a36Sopenharmony_ci	query_fw.fw_type = AMDGPU_INFO_FW_MES;
173162306a36Sopenharmony_ci	ret = amdgpu_firmware_info(&fw_info, &query_fw, adev);
173262306a36Sopenharmony_ci	if (ret)
173362306a36Sopenharmony_ci		return ret;
173462306a36Sopenharmony_ci	seq_printf(m, "MES feature version: %u, firmware version: 0x%08x\n",
173562306a36Sopenharmony_ci		   fw_info.feature, fw_info.ver);
173662306a36Sopenharmony_ci
173762306a36Sopenharmony_ci	seq_printf(m, "VBIOS version: %s\n", ctx->vbios_pn);
173862306a36Sopenharmony_ci
173962306a36Sopenharmony_ci	return 0;
174062306a36Sopenharmony_ci}
174162306a36Sopenharmony_ci
174262306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(amdgpu_debugfs_firmware_info);
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci#endif
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_civoid amdgpu_debugfs_firmware_init(struct amdgpu_device *adev)
174762306a36Sopenharmony_ci{
174862306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_FS)
174962306a36Sopenharmony_ci	struct drm_minor *minor = adev_to_drm(adev)->primary;
175062306a36Sopenharmony_ci	struct dentry *root = minor->debugfs_root;
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_ci	debugfs_create_file("amdgpu_firmware_info", 0444, root,
175362306a36Sopenharmony_ci			    adev, &amdgpu_debugfs_firmware_info_fops);
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci#endif
175662306a36Sopenharmony_ci}
1757