18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2008 Advanced Micro Devices, Inc.
38c2ecf20Sopenharmony_ci * Copyright 2008 Red Hat Inc.
48c2ecf20Sopenharmony_ci * Copyright 2009 Jerome Glisse.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
78c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
88c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
98c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
108c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
118c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
148c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software.
158c2ecf20Sopenharmony_ci *
168c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
188c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
198c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
208c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
218c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
228c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * Authors: Dave Airlie
258c2ecf20Sopenharmony_ci *          Alex Deucher
268c2ecf20Sopenharmony_ci *          Jerome Glisse
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <linux/pci.h>
308c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
318c2ecf20Sopenharmony_ci#include <linux/slab.h>
328c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
338c2ecf20Sopenharmony_ci#include <linux/vga_switcheroo.h>
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#include <drm/drm_agpsupport.h>
368c2ecf20Sopenharmony_ci#include <drm/drm_fb_helper.h>
378c2ecf20Sopenharmony_ci#include <drm/drm_file.h>
388c2ecf20Sopenharmony_ci#include <drm/drm_ioctl.h>
398c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h>
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#include "radeon.h"
428c2ecf20Sopenharmony_ci#include "radeon_asic.h"
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#if defined(CONFIG_VGA_SWITCHEROO)
458c2ecf20Sopenharmony_cibool radeon_has_atpx(void);
468c2ecf20Sopenharmony_ci#else
478c2ecf20Sopenharmony_cistatic inline bool radeon_has_atpx(void) { return false; }
488c2ecf20Sopenharmony_ci#endif
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/**
518c2ecf20Sopenharmony_ci * radeon_driver_unload_kms - Main unload function for KMS.
528c2ecf20Sopenharmony_ci *
538c2ecf20Sopenharmony_ci * @dev: drm dev pointer
548c2ecf20Sopenharmony_ci *
558c2ecf20Sopenharmony_ci * This is the main unload function for KMS (all asics).
568c2ecf20Sopenharmony_ci * It calls radeon_modeset_fini() to tear down the
578c2ecf20Sopenharmony_ci * displays, and radeon_device_fini() to tear down
588c2ecf20Sopenharmony_ci * the rest of the device (CP, writeback, etc.).
598c2ecf20Sopenharmony_ci * Returns 0 on success.
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_civoid radeon_driver_unload_kms(struct drm_device *dev)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	if (rdev == NULL)
668c2ecf20Sopenharmony_ci		return;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	if (rdev->rmmio == NULL)
698c2ecf20Sopenharmony_ci		goto done_free;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	if (radeon_is_px(dev)) {
728c2ecf20Sopenharmony_ci		pm_runtime_get_sync(dev->dev);
738c2ecf20Sopenharmony_ci		pm_runtime_forbid(dev->dev);
748c2ecf20Sopenharmony_ci	}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	radeon_acpi_fini(rdev);
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	radeon_modeset_fini(rdev);
798c2ecf20Sopenharmony_ci	radeon_device_fini(rdev);
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	if (dev->agp)
828c2ecf20Sopenharmony_ci		arch_phys_wc_del(dev->agp->agp_mtrr);
838c2ecf20Sopenharmony_ci	kfree(dev->agp);
848c2ecf20Sopenharmony_ci	dev->agp = NULL;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cidone_free:
878c2ecf20Sopenharmony_ci	kfree(rdev);
888c2ecf20Sopenharmony_ci	dev->dev_private = NULL;
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/**
928c2ecf20Sopenharmony_ci * radeon_driver_load_kms - Main load function for KMS.
938c2ecf20Sopenharmony_ci *
948c2ecf20Sopenharmony_ci * @dev: drm dev pointer
958c2ecf20Sopenharmony_ci * @flags: device flags
968c2ecf20Sopenharmony_ci *
978c2ecf20Sopenharmony_ci * This is the main load function for KMS (all asics).
988c2ecf20Sopenharmony_ci * It calls radeon_device_init() to set up the non-display
998c2ecf20Sopenharmony_ci * parts of the chip (asic init, CP, writeback, etc.), and
1008c2ecf20Sopenharmony_ci * radeon_modeset_init() to set up the display parts
1018c2ecf20Sopenharmony_ci * (crtcs, encoders, hotplug detect, etc.).
1028c2ecf20Sopenharmony_ci * Returns 0 on success, error on failure.
1038c2ecf20Sopenharmony_ci */
1048c2ecf20Sopenharmony_ciint radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
1058c2ecf20Sopenharmony_ci{
1068c2ecf20Sopenharmony_ci	struct radeon_device *rdev;
1078c2ecf20Sopenharmony_ci	int r, acpi_status;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL);
1108c2ecf20Sopenharmony_ci	if (rdev == NULL) {
1118c2ecf20Sopenharmony_ci		return -ENOMEM;
1128c2ecf20Sopenharmony_ci	}
1138c2ecf20Sopenharmony_ci	dev->dev_private = (void *)rdev;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	/* update BUS flag */
1168c2ecf20Sopenharmony_ci	if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP)) {
1178c2ecf20Sopenharmony_ci		flags |= RADEON_IS_AGP;
1188c2ecf20Sopenharmony_ci	} else if (pci_is_pcie(dev->pdev)) {
1198c2ecf20Sopenharmony_ci		flags |= RADEON_IS_PCIE;
1208c2ecf20Sopenharmony_ci	} else {
1218c2ecf20Sopenharmony_ci		flags |= RADEON_IS_PCI;
1228c2ecf20Sopenharmony_ci	}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	if ((radeon_runtime_pm != 0) &&
1258c2ecf20Sopenharmony_ci	    radeon_has_atpx() &&
1268c2ecf20Sopenharmony_ci	    ((flags & RADEON_IS_IGP) == 0) &&
1278c2ecf20Sopenharmony_ci	    !pci_is_thunderbolt_attached(dev->pdev))
1288c2ecf20Sopenharmony_ci		flags |= RADEON_IS_PX;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* radeon_device_init should report only fatal error
1318c2ecf20Sopenharmony_ci	 * like memory allocation failure or iomapping failure,
1328c2ecf20Sopenharmony_ci	 * or memory manager initialization failure, it must
1338c2ecf20Sopenharmony_ci	 * properly initialize the GPU MC controller and permit
1348c2ecf20Sopenharmony_ci	 * VRAM allocation
1358c2ecf20Sopenharmony_ci	 */
1368c2ecf20Sopenharmony_ci	r = radeon_device_init(rdev, dev, dev->pdev, flags);
1378c2ecf20Sopenharmony_ci	if (r) {
1388c2ecf20Sopenharmony_ci		dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
1398c2ecf20Sopenharmony_ci		goto out;
1408c2ecf20Sopenharmony_ci	}
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	/* Again modeset_init should fail only on fatal error
1438c2ecf20Sopenharmony_ci	 * otherwise it should provide enough functionalities
1448c2ecf20Sopenharmony_ci	 * for shadowfb to run
1458c2ecf20Sopenharmony_ci	 */
1468c2ecf20Sopenharmony_ci	r = radeon_modeset_init(rdev);
1478c2ecf20Sopenharmony_ci	if (r)
1488c2ecf20Sopenharmony_ci		dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	/* Call ACPI methods: require modeset init
1518c2ecf20Sopenharmony_ci	 * but failure is not fatal
1528c2ecf20Sopenharmony_ci	 */
1538c2ecf20Sopenharmony_ci	if (!r) {
1548c2ecf20Sopenharmony_ci		acpi_status = radeon_acpi_init(rdev);
1558c2ecf20Sopenharmony_ci		if (acpi_status)
1568c2ecf20Sopenharmony_ci		dev_dbg(&dev->pdev->dev,
1578c2ecf20Sopenharmony_ci				"Error during ACPI methods call\n");
1588c2ecf20Sopenharmony_ci	}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	if (radeon_is_px(dev)) {
1618c2ecf20Sopenharmony_ci		dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);
1628c2ecf20Sopenharmony_ci		pm_runtime_use_autosuspend(dev->dev);
1638c2ecf20Sopenharmony_ci		pm_runtime_set_autosuspend_delay(dev->dev, 5000);
1648c2ecf20Sopenharmony_ci		pm_runtime_set_active(dev->dev);
1658c2ecf20Sopenharmony_ci		pm_runtime_allow(dev->dev);
1668c2ecf20Sopenharmony_ci		pm_runtime_mark_last_busy(dev->dev);
1678c2ecf20Sopenharmony_ci		pm_runtime_put_autosuspend(dev->dev);
1688c2ecf20Sopenharmony_ci	}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ciout:
1718c2ecf20Sopenharmony_ci	if (r)
1728c2ecf20Sopenharmony_ci		radeon_driver_unload_kms(dev);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	return r;
1768c2ecf20Sopenharmony_ci}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci/**
1798c2ecf20Sopenharmony_ci * radeon_set_filp_rights - Set filp right.
1808c2ecf20Sopenharmony_ci *
1818c2ecf20Sopenharmony_ci * @dev: drm dev pointer
1828c2ecf20Sopenharmony_ci * @owner: drm file
1838c2ecf20Sopenharmony_ci * @applier: drm file
1848c2ecf20Sopenharmony_ci * @value: value
1858c2ecf20Sopenharmony_ci *
1868c2ecf20Sopenharmony_ci * Sets the filp rights for the device (all asics).
1878c2ecf20Sopenharmony_ci */
1888c2ecf20Sopenharmony_cistatic void radeon_set_filp_rights(struct drm_device *dev,
1898c2ecf20Sopenharmony_ci				   struct drm_file **owner,
1908c2ecf20Sopenharmony_ci				   struct drm_file *applier,
1918c2ecf20Sopenharmony_ci				   uint32_t *value)
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	mutex_lock(&rdev->gem.mutex);
1968c2ecf20Sopenharmony_ci	if (*value == 1) {
1978c2ecf20Sopenharmony_ci		/* wants rights */
1988c2ecf20Sopenharmony_ci		if (!*owner)
1998c2ecf20Sopenharmony_ci			*owner = applier;
2008c2ecf20Sopenharmony_ci	} else if (*value == 0) {
2018c2ecf20Sopenharmony_ci		/* revokes rights */
2028c2ecf20Sopenharmony_ci		if (*owner == applier)
2038c2ecf20Sopenharmony_ci			*owner = NULL;
2048c2ecf20Sopenharmony_ci	}
2058c2ecf20Sopenharmony_ci	*value = *owner == applier ? 1 : 0;
2068c2ecf20Sopenharmony_ci	mutex_unlock(&rdev->gem.mutex);
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci/*
2108c2ecf20Sopenharmony_ci * Userspace get information ioctl
2118c2ecf20Sopenharmony_ci */
2128c2ecf20Sopenharmony_ci/**
2138c2ecf20Sopenharmony_ci * radeon_info_ioctl - answer a device specific request.
2148c2ecf20Sopenharmony_ci *
2158c2ecf20Sopenharmony_ci * @rdev: radeon device pointer
2168c2ecf20Sopenharmony_ci * @data: request object
2178c2ecf20Sopenharmony_ci * @filp: drm filp
2188c2ecf20Sopenharmony_ci *
2198c2ecf20Sopenharmony_ci * This function is used to pass device specific parameters to the userspace
2208c2ecf20Sopenharmony_ci * drivers.  Examples include: pci device id, pipeline parms, tiling params,
2218c2ecf20Sopenharmony_ci * etc. (all asics).
2228c2ecf20Sopenharmony_ci * Returns 0 on success, -EINVAL on failure.
2238c2ecf20Sopenharmony_ci */
2248c2ecf20Sopenharmony_cistatic int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
2278c2ecf20Sopenharmony_ci	struct drm_radeon_info *info = data;
2288c2ecf20Sopenharmony_ci	struct radeon_mode_info *minfo = &rdev->mode_info;
2298c2ecf20Sopenharmony_ci	uint32_t *value, value_tmp, *value_ptr, value_size;
2308c2ecf20Sopenharmony_ci	uint64_t value64;
2318c2ecf20Sopenharmony_ci	struct drm_crtc *crtc;
2328c2ecf20Sopenharmony_ci	int i, found;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	value_ptr = (uint32_t *)((unsigned long)info->value);
2358c2ecf20Sopenharmony_ci	value = &value_tmp;
2368c2ecf20Sopenharmony_ci	value_size = sizeof(uint32_t);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	switch (info->request) {
2398c2ecf20Sopenharmony_ci	case RADEON_INFO_DEVICE_ID:
2408c2ecf20Sopenharmony_ci		*value = dev->pdev->device;
2418c2ecf20Sopenharmony_ci		break;
2428c2ecf20Sopenharmony_ci	case RADEON_INFO_NUM_GB_PIPES:
2438c2ecf20Sopenharmony_ci		*value = rdev->num_gb_pipes;
2448c2ecf20Sopenharmony_ci		break;
2458c2ecf20Sopenharmony_ci	case RADEON_INFO_NUM_Z_PIPES:
2468c2ecf20Sopenharmony_ci		*value = rdev->num_z_pipes;
2478c2ecf20Sopenharmony_ci		break;
2488c2ecf20Sopenharmony_ci	case RADEON_INFO_ACCEL_WORKING:
2498c2ecf20Sopenharmony_ci		/* xf86-video-ati 6.13.0 relies on this being false for evergreen */
2508c2ecf20Sopenharmony_ci		if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK))
2518c2ecf20Sopenharmony_ci			*value = false;
2528c2ecf20Sopenharmony_ci		else
2538c2ecf20Sopenharmony_ci			*value = rdev->accel_working;
2548c2ecf20Sopenharmony_ci		break;
2558c2ecf20Sopenharmony_ci	case RADEON_INFO_CRTC_FROM_ID:
2568c2ecf20Sopenharmony_ci		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
2578c2ecf20Sopenharmony_ci			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
2588c2ecf20Sopenharmony_ci			return -EFAULT;
2598c2ecf20Sopenharmony_ci		}
2608c2ecf20Sopenharmony_ci		for (i = 0, found = 0; i < rdev->num_crtc; i++) {
2618c2ecf20Sopenharmony_ci			crtc = (struct drm_crtc *)minfo->crtcs[i];
2628c2ecf20Sopenharmony_ci			if (crtc && crtc->base.id == *value) {
2638c2ecf20Sopenharmony_ci				struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
2648c2ecf20Sopenharmony_ci				*value = radeon_crtc->crtc_id;
2658c2ecf20Sopenharmony_ci				found = 1;
2668c2ecf20Sopenharmony_ci				break;
2678c2ecf20Sopenharmony_ci			}
2688c2ecf20Sopenharmony_ci		}
2698c2ecf20Sopenharmony_ci		if (!found) {
2708c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("unknown crtc id %d\n", *value);
2718c2ecf20Sopenharmony_ci			return -EINVAL;
2728c2ecf20Sopenharmony_ci		}
2738c2ecf20Sopenharmony_ci		break;
2748c2ecf20Sopenharmony_ci	case RADEON_INFO_ACCEL_WORKING2:
2758c2ecf20Sopenharmony_ci		if (rdev->family == CHIP_HAWAII) {
2768c2ecf20Sopenharmony_ci			if (rdev->accel_working) {
2778c2ecf20Sopenharmony_ci				if (rdev->new_fw)
2788c2ecf20Sopenharmony_ci					*value = 3;
2798c2ecf20Sopenharmony_ci				else
2808c2ecf20Sopenharmony_ci					*value = 2;
2818c2ecf20Sopenharmony_ci			} else {
2828c2ecf20Sopenharmony_ci				*value = 0;
2838c2ecf20Sopenharmony_ci			}
2848c2ecf20Sopenharmony_ci		} else {
2858c2ecf20Sopenharmony_ci			*value = rdev->accel_working;
2868c2ecf20Sopenharmony_ci		}
2878c2ecf20Sopenharmony_ci		break;
2888c2ecf20Sopenharmony_ci	case RADEON_INFO_TILING_CONFIG:
2898c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
2908c2ecf20Sopenharmony_ci			*value = rdev->config.cik.tile_config;
2918c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
2928c2ecf20Sopenharmony_ci			*value = rdev->config.si.tile_config;
2938c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
2948c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.tile_config;
2958c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
2968c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.tile_config;
2978c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV770)
2988c2ecf20Sopenharmony_ci			*value = rdev->config.rv770.tile_config;
2998c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_R600)
3008c2ecf20Sopenharmony_ci			*value = rdev->config.r600.tile_config;
3018c2ecf20Sopenharmony_ci		else {
3028c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
3038c2ecf20Sopenharmony_ci			return -EINVAL;
3048c2ecf20Sopenharmony_ci		}
3058c2ecf20Sopenharmony_ci		break;
3068c2ecf20Sopenharmony_ci	case RADEON_INFO_WANT_HYPERZ:
3078c2ecf20Sopenharmony_ci		/* The "value" here is both an input and output parameter.
3088c2ecf20Sopenharmony_ci		 * If the input value is 1, filp requests hyper-z access.
3098c2ecf20Sopenharmony_ci		 * If the input value is 0, filp revokes its hyper-z access.
3108c2ecf20Sopenharmony_ci		 *
3118c2ecf20Sopenharmony_ci		 * When returning, the value is 1 if filp owns hyper-z access,
3128c2ecf20Sopenharmony_ci		 * 0 otherwise. */
3138c2ecf20Sopenharmony_ci		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
3148c2ecf20Sopenharmony_ci			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
3158c2ecf20Sopenharmony_ci			return -EFAULT;
3168c2ecf20Sopenharmony_ci		}
3178c2ecf20Sopenharmony_ci		if (*value >= 2) {
3188c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", *value);
3198c2ecf20Sopenharmony_ci			return -EINVAL;
3208c2ecf20Sopenharmony_ci		}
3218c2ecf20Sopenharmony_ci		radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, value);
3228c2ecf20Sopenharmony_ci		break;
3238c2ecf20Sopenharmony_ci	case RADEON_INFO_WANT_CMASK:
3248c2ecf20Sopenharmony_ci		/* The same logic as Hyper-Z. */
3258c2ecf20Sopenharmony_ci		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
3268c2ecf20Sopenharmony_ci			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
3278c2ecf20Sopenharmony_ci			return -EFAULT;
3288c2ecf20Sopenharmony_ci		}
3298c2ecf20Sopenharmony_ci		if (*value >= 2) {
3308c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", *value);
3318c2ecf20Sopenharmony_ci			return -EINVAL;
3328c2ecf20Sopenharmony_ci		}
3338c2ecf20Sopenharmony_ci		radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, value);
3348c2ecf20Sopenharmony_ci		break;
3358c2ecf20Sopenharmony_ci	case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
3368c2ecf20Sopenharmony_ci		/* return clock value in KHz */
3378c2ecf20Sopenharmony_ci		if (rdev->asic->get_xclk)
3388c2ecf20Sopenharmony_ci			*value = radeon_get_xclk(rdev) * 10;
3398c2ecf20Sopenharmony_ci		else
3408c2ecf20Sopenharmony_ci			*value = rdev->clock.spll.reference_freq * 10;
3418c2ecf20Sopenharmony_ci		break;
3428c2ecf20Sopenharmony_ci	case RADEON_INFO_NUM_BACKENDS:
3438c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
3448c2ecf20Sopenharmony_ci			*value = rdev->config.cik.max_backends_per_se *
3458c2ecf20Sopenharmony_ci				rdev->config.cik.max_shader_engines;
3468c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
3478c2ecf20Sopenharmony_ci			*value = rdev->config.si.max_backends_per_se *
3488c2ecf20Sopenharmony_ci				rdev->config.si.max_shader_engines;
3498c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
3508c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.max_backends_per_se *
3518c2ecf20Sopenharmony_ci				rdev->config.cayman.max_shader_engines;
3528c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
3538c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.max_backends;
3548c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV770)
3558c2ecf20Sopenharmony_ci			*value = rdev->config.rv770.max_backends;
3568c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_R600)
3578c2ecf20Sopenharmony_ci			*value = rdev->config.r600.max_backends;
3588c2ecf20Sopenharmony_ci		else {
3598c2ecf20Sopenharmony_ci			return -EINVAL;
3608c2ecf20Sopenharmony_ci		}
3618c2ecf20Sopenharmony_ci		break;
3628c2ecf20Sopenharmony_ci	case RADEON_INFO_NUM_TILE_PIPES:
3638c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
3648c2ecf20Sopenharmony_ci			*value = rdev->config.cik.max_tile_pipes;
3658c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
3668c2ecf20Sopenharmony_ci			*value = rdev->config.si.max_tile_pipes;
3678c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
3688c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.max_tile_pipes;
3698c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
3708c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.max_tile_pipes;
3718c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV770)
3728c2ecf20Sopenharmony_ci			*value = rdev->config.rv770.max_tile_pipes;
3738c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_R600)
3748c2ecf20Sopenharmony_ci			*value = rdev->config.r600.max_tile_pipes;
3758c2ecf20Sopenharmony_ci		else {
3768c2ecf20Sopenharmony_ci			return -EINVAL;
3778c2ecf20Sopenharmony_ci		}
3788c2ecf20Sopenharmony_ci		break;
3798c2ecf20Sopenharmony_ci	case RADEON_INFO_FUSION_GART_WORKING:
3808c2ecf20Sopenharmony_ci		*value = 1;
3818c2ecf20Sopenharmony_ci		break;
3828c2ecf20Sopenharmony_ci	case RADEON_INFO_BACKEND_MAP:
3838c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
3848c2ecf20Sopenharmony_ci			*value = rdev->config.cik.backend_map;
3858c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
3868c2ecf20Sopenharmony_ci			*value = rdev->config.si.backend_map;
3878c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
3888c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.backend_map;
3898c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
3908c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.backend_map;
3918c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV770)
3928c2ecf20Sopenharmony_ci			*value = rdev->config.rv770.backend_map;
3938c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_R600)
3948c2ecf20Sopenharmony_ci			*value = rdev->config.r600.backend_map;
3958c2ecf20Sopenharmony_ci		else {
3968c2ecf20Sopenharmony_ci			return -EINVAL;
3978c2ecf20Sopenharmony_ci		}
3988c2ecf20Sopenharmony_ci		break;
3998c2ecf20Sopenharmony_ci	case RADEON_INFO_VA_START:
4008c2ecf20Sopenharmony_ci		/* this is where we report if vm is supported or not */
4018c2ecf20Sopenharmony_ci		if (rdev->family < CHIP_CAYMAN)
4028c2ecf20Sopenharmony_ci			return -EINVAL;
4038c2ecf20Sopenharmony_ci		*value = RADEON_VA_RESERVED_SIZE;
4048c2ecf20Sopenharmony_ci		break;
4058c2ecf20Sopenharmony_ci	case RADEON_INFO_IB_VM_MAX_SIZE:
4068c2ecf20Sopenharmony_ci		/* this is where we report if vm is supported or not */
4078c2ecf20Sopenharmony_ci		if (rdev->family < CHIP_CAYMAN)
4088c2ecf20Sopenharmony_ci			return -EINVAL;
4098c2ecf20Sopenharmony_ci		*value = RADEON_IB_VM_MAX_SIZE;
4108c2ecf20Sopenharmony_ci		break;
4118c2ecf20Sopenharmony_ci	case RADEON_INFO_MAX_PIPES:
4128c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
4138c2ecf20Sopenharmony_ci			*value = rdev->config.cik.max_cu_per_sh;
4148c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
4158c2ecf20Sopenharmony_ci			*value = rdev->config.si.max_cu_per_sh;
4168c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
4178c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.max_pipes_per_simd;
4188c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
4198c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.max_pipes;
4208c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV770)
4218c2ecf20Sopenharmony_ci			*value = rdev->config.rv770.max_pipes;
4228c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_R600)
4238c2ecf20Sopenharmony_ci			*value = rdev->config.r600.max_pipes;
4248c2ecf20Sopenharmony_ci		else {
4258c2ecf20Sopenharmony_ci			return -EINVAL;
4268c2ecf20Sopenharmony_ci		}
4278c2ecf20Sopenharmony_ci		break;
4288c2ecf20Sopenharmony_ci	case RADEON_INFO_TIMESTAMP:
4298c2ecf20Sopenharmony_ci		if (rdev->family < CHIP_R600) {
4308c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
4318c2ecf20Sopenharmony_ci			return -EINVAL;
4328c2ecf20Sopenharmony_ci		}
4338c2ecf20Sopenharmony_ci		value = (uint32_t*)&value64;
4348c2ecf20Sopenharmony_ci		value_size = sizeof(uint64_t);
4358c2ecf20Sopenharmony_ci		value64 = radeon_get_gpu_clock_counter(rdev);
4368c2ecf20Sopenharmony_ci		break;
4378c2ecf20Sopenharmony_ci	case RADEON_INFO_MAX_SE:
4388c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
4398c2ecf20Sopenharmony_ci			*value = rdev->config.cik.max_shader_engines;
4408c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
4418c2ecf20Sopenharmony_ci			*value = rdev->config.si.max_shader_engines;
4428c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
4438c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.max_shader_engines;
4448c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
4458c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.num_ses;
4468c2ecf20Sopenharmony_ci		else
4478c2ecf20Sopenharmony_ci			*value = 1;
4488c2ecf20Sopenharmony_ci		break;
4498c2ecf20Sopenharmony_ci	case RADEON_INFO_MAX_SH_PER_SE:
4508c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
4518c2ecf20Sopenharmony_ci			*value = rdev->config.cik.max_sh_per_se;
4528c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
4538c2ecf20Sopenharmony_ci			*value = rdev->config.si.max_sh_per_se;
4548c2ecf20Sopenharmony_ci		else
4558c2ecf20Sopenharmony_ci			return -EINVAL;
4568c2ecf20Sopenharmony_ci		break;
4578c2ecf20Sopenharmony_ci	case RADEON_INFO_FASTFB_WORKING:
4588c2ecf20Sopenharmony_ci		*value = rdev->fastfb_working;
4598c2ecf20Sopenharmony_ci		break;
4608c2ecf20Sopenharmony_ci	case RADEON_INFO_RING_WORKING:
4618c2ecf20Sopenharmony_ci		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
4628c2ecf20Sopenharmony_ci			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
4638c2ecf20Sopenharmony_ci			return -EFAULT;
4648c2ecf20Sopenharmony_ci		}
4658c2ecf20Sopenharmony_ci		switch (*value) {
4668c2ecf20Sopenharmony_ci		case RADEON_CS_RING_GFX:
4678c2ecf20Sopenharmony_ci		case RADEON_CS_RING_COMPUTE:
4688c2ecf20Sopenharmony_ci			*value = rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready;
4698c2ecf20Sopenharmony_ci			break;
4708c2ecf20Sopenharmony_ci		case RADEON_CS_RING_DMA:
4718c2ecf20Sopenharmony_ci			*value = rdev->ring[R600_RING_TYPE_DMA_INDEX].ready;
4728c2ecf20Sopenharmony_ci			*value |= rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready;
4738c2ecf20Sopenharmony_ci			break;
4748c2ecf20Sopenharmony_ci		case RADEON_CS_RING_UVD:
4758c2ecf20Sopenharmony_ci			*value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready;
4768c2ecf20Sopenharmony_ci			break;
4778c2ecf20Sopenharmony_ci		case RADEON_CS_RING_VCE:
4788c2ecf20Sopenharmony_ci			*value = rdev->ring[TN_RING_TYPE_VCE1_INDEX].ready;
4798c2ecf20Sopenharmony_ci			break;
4808c2ecf20Sopenharmony_ci		default:
4818c2ecf20Sopenharmony_ci			return -EINVAL;
4828c2ecf20Sopenharmony_ci		}
4838c2ecf20Sopenharmony_ci		break;
4848c2ecf20Sopenharmony_ci	case RADEON_INFO_SI_TILE_MODE_ARRAY:
4858c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE) {
4868c2ecf20Sopenharmony_ci			value = rdev->config.cik.tile_mode_array;
4878c2ecf20Sopenharmony_ci			value_size = sizeof(uint32_t)*32;
4888c2ecf20Sopenharmony_ci		} else if (rdev->family >= CHIP_TAHITI) {
4898c2ecf20Sopenharmony_ci			value = rdev->config.si.tile_mode_array;
4908c2ecf20Sopenharmony_ci			value_size = sizeof(uint32_t)*32;
4918c2ecf20Sopenharmony_ci		} else {
4928c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("tile mode array is si+ only!\n");
4938c2ecf20Sopenharmony_ci			return -EINVAL;
4948c2ecf20Sopenharmony_ci		}
4958c2ecf20Sopenharmony_ci		break;
4968c2ecf20Sopenharmony_ci	case RADEON_INFO_CIK_MACROTILE_MODE_ARRAY:
4978c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE) {
4988c2ecf20Sopenharmony_ci			value = rdev->config.cik.macrotile_mode_array;
4998c2ecf20Sopenharmony_ci			value_size = sizeof(uint32_t)*16;
5008c2ecf20Sopenharmony_ci		} else {
5018c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("macrotile mode array is cik+ only!\n");
5028c2ecf20Sopenharmony_ci			return -EINVAL;
5038c2ecf20Sopenharmony_ci		}
5048c2ecf20Sopenharmony_ci		break;
5058c2ecf20Sopenharmony_ci	case RADEON_INFO_SI_CP_DMA_COMPUTE:
5068c2ecf20Sopenharmony_ci		*value = 1;
5078c2ecf20Sopenharmony_ci		break;
5088c2ecf20Sopenharmony_ci	case RADEON_INFO_SI_BACKEND_ENABLED_MASK:
5098c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE) {
5108c2ecf20Sopenharmony_ci			*value = rdev->config.cik.backend_enable_mask;
5118c2ecf20Sopenharmony_ci		} else if (rdev->family >= CHIP_TAHITI) {
5128c2ecf20Sopenharmony_ci			*value = rdev->config.si.backend_enable_mask;
5138c2ecf20Sopenharmony_ci		} else {
5148c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n");
5158c2ecf20Sopenharmony_ci			return -EINVAL;
5168c2ecf20Sopenharmony_ci		}
5178c2ecf20Sopenharmony_ci		break;
5188c2ecf20Sopenharmony_ci	case RADEON_INFO_MAX_SCLK:
5198c2ecf20Sopenharmony_ci		if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
5208c2ecf20Sopenharmony_ci		    rdev->pm.dpm_enabled)
5218c2ecf20Sopenharmony_ci			*value = rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk * 10;
5228c2ecf20Sopenharmony_ci		else
5238c2ecf20Sopenharmony_ci			*value = rdev->pm.default_sclk * 10;
5248c2ecf20Sopenharmony_ci		break;
5258c2ecf20Sopenharmony_ci	case RADEON_INFO_VCE_FW_VERSION:
5268c2ecf20Sopenharmony_ci		*value = rdev->vce.fw_version;
5278c2ecf20Sopenharmony_ci		break;
5288c2ecf20Sopenharmony_ci	case RADEON_INFO_VCE_FB_VERSION:
5298c2ecf20Sopenharmony_ci		*value = rdev->vce.fb_version;
5308c2ecf20Sopenharmony_ci		break;
5318c2ecf20Sopenharmony_ci	case RADEON_INFO_NUM_BYTES_MOVED:
5328c2ecf20Sopenharmony_ci		value = (uint32_t*)&value64;
5338c2ecf20Sopenharmony_ci		value_size = sizeof(uint64_t);
5348c2ecf20Sopenharmony_ci		value64 = atomic64_read(&rdev->num_bytes_moved);
5358c2ecf20Sopenharmony_ci		break;
5368c2ecf20Sopenharmony_ci	case RADEON_INFO_VRAM_USAGE:
5378c2ecf20Sopenharmony_ci		value = (uint32_t*)&value64;
5388c2ecf20Sopenharmony_ci		value_size = sizeof(uint64_t);
5398c2ecf20Sopenharmony_ci		value64 = atomic64_read(&rdev->vram_usage);
5408c2ecf20Sopenharmony_ci		break;
5418c2ecf20Sopenharmony_ci	case RADEON_INFO_GTT_USAGE:
5428c2ecf20Sopenharmony_ci		value = (uint32_t*)&value64;
5438c2ecf20Sopenharmony_ci		value_size = sizeof(uint64_t);
5448c2ecf20Sopenharmony_ci		value64 = atomic64_read(&rdev->gtt_usage);
5458c2ecf20Sopenharmony_ci		break;
5468c2ecf20Sopenharmony_ci	case RADEON_INFO_ACTIVE_CU_COUNT:
5478c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE)
5488c2ecf20Sopenharmony_ci			*value = rdev->config.cik.active_cus;
5498c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_TAHITI)
5508c2ecf20Sopenharmony_ci			*value = rdev->config.si.active_cus;
5518c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CAYMAN)
5528c2ecf20Sopenharmony_ci			*value = rdev->config.cayman.active_simds;
5538c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_CEDAR)
5548c2ecf20Sopenharmony_ci			*value = rdev->config.evergreen.active_simds;
5558c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_RV770)
5568c2ecf20Sopenharmony_ci			*value = rdev->config.rv770.active_simds;
5578c2ecf20Sopenharmony_ci		else if (rdev->family >= CHIP_R600)
5588c2ecf20Sopenharmony_ci			*value = rdev->config.r600.active_simds;
5598c2ecf20Sopenharmony_ci		else
5608c2ecf20Sopenharmony_ci			*value = 1;
5618c2ecf20Sopenharmony_ci		break;
5628c2ecf20Sopenharmony_ci	case RADEON_INFO_CURRENT_GPU_TEMP:
5638c2ecf20Sopenharmony_ci		/* get temperature in millidegrees C */
5648c2ecf20Sopenharmony_ci		if (rdev->asic->pm.get_temperature)
5658c2ecf20Sopenharmony_ci			*value = radeon_get_temperature(rdev);
5668c2ecf20Sopenharmony_ci		else
5678c2ecf20Sopenharmony_ci			*value = 0;
5688c2ecf20Sopenharmony_ci		break;
5698c2ecf20Sopenharmony_ci	case RADEON_INFO_CURRENT_GPU_SCLK:
5708c2ecf20Sopenharmony_ci		/* get sclk in Mhz */
5718c2ecf20Sopenharmony_ci		if (rdev->pm.dpm_enabled)
5728c2ecf20Sopenharmony_ci			*value = radeon_dpm_get_current_sclk(rdev) / 100;
5738c2ecf20Sopenharmony_ci		else
5748c2ecf20Sopenharmony_ci			*value = rdev->pm.current_sclk / 100;
5758c2ecf20Sopenharmony_ci		break;
5768c2ecf20Sopenharmony_ci	case RADEON_INFO_CURRENT_GPU_MCLK:
5778c2ecf20Sopenharmony_ci		/* get mclk in Mhz */
5788c2ecf20Sopenharmony_ci		if (rdev->pm.dpm_enabled)
5798c2ecf20Sopenharmony_ci			*value = radeon_dpm_get_current_mclk(rdev) / 100;
5808c2ecf20Sopenharmony_ci		else
5818c2ecf20Sopenharmony_ci			*value = rdev->pm.current_mclk / 100;
5828c2ecf20Sopenharmony_ci		break;
5838c2ecf20Sopenharmony_ci	case RADEON_INFO_READ_REG:
5848c2ecf20Sopenharmony_ci		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
5858c2ecf20Sopenharmony_ci			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
5868c2ecf20Sopenharmony_ci			return -EFAULT;
5878c2ecf20Sopenharmony_ci		}
5888c2ecf20Sopenharmony_ci		if (radeon_get_allowed_info_register(rdev, *value, value))
5898c2ecf20Sopenharmony_ci			return -EINVAL;
5908c2ecf20Sopenharmony_ci		break;
5918c2ecf20Sopenharmony_ci	case RADEON_INFO_VA_UNMAP_WORKING:
5928c2ecf20Sopenharmony_ci		*value = true;
5938c2ecf20Sopenharmony_ci		break;
5948c2ecf20Sopenharmony_ci	case RADEON_INFO_GPU_RESET_COUNTER:
5958c2ecf20Sopenharmony_ci		*value = atomic_read(&rdev->gpu_reset_counter);
5968c2ecf20Sopenharmony_ci		break;
5978c2ecf20Sopenharmony_ci	default:
5988c2ecf20Sopenharmony_ci		DRM_DEBUG_KMS("Invalid request %d\n", info->request);
5998c2ecf20Sopenharmony_ci		return -EINVAL;
6008c2ecf20Sopenharmony_ci	}
6018c2ecf20Sopenharmony_ci	if (copy_to_user(value_ptr, (char*)value, value_size)) {
6028c2ecf20Sopenharmony_ci		DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
6038c2ecf20Sopenharmony_ci		return -EFAULT;
6048c2ecf20Sopenharmony_ci	}
6058c2ecf20Sopenharmony_ci	return 0;
6068c2ecf20Sopenharmony_ci}
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci
6098c2ecf20Sopenharmony_ci/*
6108c2ecf20Sopenharmony_ci * Outdated mess for old drm with Xorg being in charge (void function now).
6118c2ecf20Sopenharmony_ci */
6128c2ecf20Sopenharmony_ci/**
6138c2ecf20Sopenharmony_ci * radeon_driver_lastclose_kms - drm callback for last close
6148c2ecf20Sopenharmony_ci *
6158c2ecf20Sopenharmony_ci * @dev: drm dev pointer
6168c2ecf20Sopenharmony_ci *
6178c2ecf20Sopenharmony_ci * Switch vga_switcheroo state after last close (all asics).
6188c2ecf20Sopenharmony_ci */
6198c2ecf20Sopenharmony_civoid radeon_driver_lastclose_kms(struct drm_device *dev)
6208c2ecf20Sopenharmony_ci{
6218c2ecf20Sopenharmony_ci	drm_fb_helper_lastclose(dev);
6228c2ecf20Sopenharmony_ci	vga_switcheroo_process_delayed_switch();
6238c2ecf20Sopenharmony_ci}
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_ci/**
6268c2ecf20Sopenharmony_ci * radeon_driver_open_kms - drm callback for open
6278c2ecf20Sopenharmony_ci *
6288c2ecf20Sopenharmony_ci * @dev: drm dev pointer
6298c2ecf20Sopenharmony_ci * @file_priv: drm file
6308c2ecf20Sopenharmony_ci *
6318c2ecf20Sopenharmony_ci * On device open, init vm on cayman+ (all asics).
6328c2ecf20Sopenharmony_ci * Returns 0 on success, error on failure.
6338c2ecf20Sopenharmony_ci */
6348c2ecf20Sopenharmony_ciint radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
6358c2ecf20Sopenharmony_ci{
6368c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
6378c2ecf20Sopenharmony_ci	struct radeon_fpriv *fpriv;
6388c2ecf20Sopenharmony_ci	struct radeon_vm *vm;
6398c2ecf20Sopenharmony_ci	int r;
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	file_priv->driver_priv = NULL;
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	r = pm_runtime_get_sync(dev->dev);
6448c2ecf20Sopenharmony_ci	if (r < 0) {
6458c2ecf20Sopenharmony_ci		pm_runtime_put_autosuspend(dev->dev);
6468c2ecf20Sopenharmony_ci		return r;
6478c2ecf20Sopenharmony_ci	}
6488c2ecf20Sopenharmony_ci
6498c2ecf20Sopenharmony_ci	/* new gpu have virtual address space support */
6508c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN) {
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci		fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
6538c2ecf20Sopenharmony_ci		if (unlikely(!fpriv)) {
6548c2ecf20Sopenharmony_ci			r = -ENOMEM;
6558c2ecf20Sopenharmony_ci			goto err_suspend;
6568c2ecf20Sopenharmony_ci		}
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci		if (rdev->accel_working) {
6598c2ecf20Sopenharmony_ci			vm = &fpriv->vm;
6608c2ecf20Sopenharmony_ci			r = radeon_vm_init(rdev, vm);
6618c2ecf20Sopenharmony_ci			if (r)
6628c2ecf20Sopenharmony_ci				goto err_fpriv;
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci			r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
6658c2ecf20Sopenharmony_ci			if (r)
6668c2ecf20Sopenharmony_ci				goto err_vm_fini;
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci			/* map the ib pool buffer read only into
6698c2ecf20Sopenharmony_ci			 * virtual address space */
6708c2ecf20Sopenharmony_ci			vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
6718c2ecf20Sopenharmony_ci							rdev->ring_tmp_bo.bo);
6728c2ecf20Sopenharmony_ci			if (!vm->ib_bo_va) {
6738c2ecf20Sopenharmony_ci				r = -ENOMEM;
6748c2ecf20Sopenharmony_ci				goto err_vm_fini;
6758c2ecf20Sopenharmony_ci			}
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci			r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va,
6788c2ecf20Sopenharmony_ci						  RADEON_VA_IB_OFFSET,
6798c2ecf20Sopenharmony_ci						  RADEON_VM_PAGE_READABLE |
6808c2ecf20Sopenharmony_ci						  RADEON_VM_PAGE_SNOOPED);
6818c2ecf20Sopenharmony_ci			if (r)
6828c2ecf20Sopenharmony_ci				goto err_vm_fini;
6838c2ecf20Sopenharmony_ci		}
6848c2ecf20Sopenharmony_ci		file_priv->driver_priv = fpriv;
6858c2ecf20Sopenharmony_ci	}
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci	pm_runtime_mark_last_busy(dev->dev);
6888c2ecf20Sopenharmony_ci	pm_runtime_put_autosuspend(dev->dev);
6898c2ecf20Sopenharmony_ci	return 0;
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_cierr_vm_fini:
6928c2ecf20Sopenharmony_ci	radeon_vm_fini(rdev, vm);
6938c2ecf20Sopenharmony_cierr_fpriv:
6948c2ecf20Sopenharmony_ci	kfree(fpriv);
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_cierr_suspend:
6978c2ecf20Sopenharmony_ci	pm_runtime_mark_last_busy(dev->dev);
6988c2ecf20Sopenharmony_ci	pm_runtime_put_autosuspend(dev->dev);
6998c2ecf20Sopenharmony_ci	return r;
7008c2ecf20Sopenharmony_ci}
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci/**
7038c2ecf20Sopenharmony_ci * radeon_driver_postclose_kms - drm callback for post close
7048c2ecf20Sopenharmony_ci *
7058c2ecf20Sopenharmony_ci * @dev: drm dev pointer
7068c2ecf20Sopenharmony_ci * @file_priv: drm file
7078c2ecf20Sopenharmony_ci *
7088c2ecf20Sopenharmony_ci * On device close, tear down hyperz and cmask filps on r1xx-r5xx
7098c2ecf20Sopenharmony_ci * (all asics).  And tear down vm on cayman+ (all asics).
7108c2ecf20Sopenharmony_ci */
7118c2ecf20Sopenharmony_civoid radeon_driver_postclose_kms(struct drm_device *dev,
7128c2ecf20Sopenharmony_ci				 struct drm_file *file_priv)
7138c2ecf20Sopenharmony_ci{
7148c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
7158c2ecf20Sopenharmony_ci
7168c2ecf20Sopenharmony_ci	pm_runtime_get_sync(dev->dev);
7178c2ecf20Sopenharmony_ci
7188c2ecf20Sopenharmony_ci	mutex_lock(&rdev->gem.mutex);
7198c2ecf20Sopenharmony_ci	if (rdev->hyperz_filp == file_priv)
7208c2ecf20Sopenharmony_ci		rdev->hyperz_filp = NULL;
7218c2ecf20Sopenharmony_ci	if (rdev->cmask_filp == file_priv)
7228c2ecf20Sopenharmony_ci		rdev->cmask_filp = NULL;
7238c2ecf20Sopenharmony_ci	mutex_unlock(&rdev->gem.mutex);
7248c2ecf20Sopenharmony_ci
7258c2ecf20Sopenharmony_ci	radeon_uvd_free_handles(rdev, file_priv);
7268c2ecf20Sopenharmony_ci	radeon_vce_free_handles(rdev, file_priv);
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ci	/* new gpu have virtual address space support */
7298c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) {
7308c2ecf20Sopenharmony_ci		struct radeon_fpriv *fpriv = file_priv->driver_priv;
7318c2ecf20Sopenharmony_ci		struct radeon_vm *vm = &fpriv->vm;
7328c2ecf20Sopenharmony_ci		int r;
7338c2ecf20Sopenharmony_ci
7348c2ecf20Sopenharmony_ci		if (rdev->accel_working) {
7358c2ecf20Sopenharmony_ci			r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
7368c2ecf20Sopenharmony_ci			if (!r) {
7378c2ecf20Sopenharmony_ci				if (vm->ib_bo_va)
7388c2ecf20Sopenharmony_ci					radeon_vm_bo_rmv(rdev, vm->ib_bo_va);
7398c2ecf20Sopenharmony_ci				radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
7408c2ecf20Sopenharmony_ci			}
7418c2ecf20Sopenharmony_ci			radeon_vm_fini(rdev, vm);
7428c2ecf20Sopenharmony_ci		}
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_ci		kfree(fpriv);
7458c2ecf20Sopenharmony_ci		file_priv->driver_priv = NULL;
7468c2ecf20Sopenharmony_ci	}
7478c2ecf20Sopenharmony_ci	pm_runtime_mark_last_busy(dev->dev);
7488c2ecf20Sopenharmony_ci	pm_runtime_put_autosuspend(dev->dev);
7498c2ecf20Sopenharmony_ci}
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_ci/*
7528c2ecf20Sopenharmony_ci * VBlank related functions.
7538c2ecf20Sopenharmony_ci */
7548c2ecf20Sopenharmony_ci/**
7558c2ecf20Sopenharmony_ci * radeon_get_vblank_counter_kms - get frame count
7568c2ecf20Sopenharmony_ci *
7578c2ecf20Sopenharmony_ci * @crtc: crtc to get the frame count from
7588c2ecf20Sopenharmony_ci *
7598c2ecf20Sopenharmony_ci * Gets the frame count on the requested crtc (all asics).
7608c2ecf20Sopenharmony_ci * Returns frame count on success, -EINVAL on failure.
7618c2ecf20Sopenharmony_ci */
7628c2ecf20Sopenharmony_ciu32 radeon_get_vblank_counter_kms(struct drm_crtc *crtc)
7638c2ecf20Sopenharmony_ci{
7648c2ecf20Sopenharmony_ci	struct drm_device *dev = crtc->dev;
7658c2ecf20Sopenharmony_ci	unsigned int pipe = crtc->index;
7668c2ecf20Sopenharmony_ci	int vpos, hpos, stat;
7678c2ecf20Sopenharmony_ci	u32 count;
7688c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
7698c2ecf20Sopenharmony_ci
7708c2ecf20Sopenharmony_ci	if (pipe >= rdev->num_crtc) {
7718c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid crtc %u\n", pipe);
7728c2ecf20Sopenharmony_ci		return -EINVAL;
7738c2ecf20Sopenharmony_ci	}
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_ci	/* The hw increments its frame counter at start of vsync, not at start
7768c2ecf20Sopenharmony_ci	 * of vblank, as is required by DRM core vblank counter handling.
7778c2ecf20Sopenharmony_ci	 * Cook the hw count here to make it appear to the caller as if it
7788c2ecf20Sopenharmony_ci	 * incremented at start of vblank. We measure distance to start of
7798c2ecf20Sopenharmony_ci	 * vblank in vpos. vpos therefore will be >= 0 between start of vblank
7808c2ecf20Sopenharmony_ci	 * and start of vsync, so vpos >= 0 means to bump the hw frame counter
7818c2ecf20Sopenharmony_ci	 * result by 1 to give the proper appearance to caller.
7828c2ecf20Sopenharmony_ci	 */
7838c2ecf20Sopenharmony_ci	if (rdev->mode_info.crtcs[pipe]) {
7848c2ecf20Sopenharmony_ci		/* Repeat readout if needed to provide stable result if
7858c2ecf20Sopenharmony_ci		 * we cross start of vsync during the queries.
7868c2ecf20Sopenharmony_ci		 */
7878c2ecf20Sopenharmony_ci		do {
7888c2ecf20Sopenharmony_ci			count = radeon_get_vblank_counter(rdev, pipe);
7898c2ecf20Sopenharmony_ci			/* Ask radeon_get_crtc_scanoutpos to return vpos as
7908c2ecf20Sopenharmony_ci			 * distance to start of vblank, instead of regular
7918c2ecf20Sopenharmony_ci			 * vertical scanout pos.
7928c2ecf20Sopenharmony_ci			 */
7938c2ecf20Sopenharmony_ci			stat = radeon_get_crtc_scanoutpos(
7948c2ecf20Sopenharmony_ci				dev, pipe, GET_DISTANCE_TO_VBLANKSTART,
7958c2ecf20Sopenharmony_ci				&vpos, &hpos, NULL, NULL,
7968c2ecf20Sopenharmony_ci				&rdev->mode_info.crtcs[pipe]->base.hwmode);
7978c2ecf20Sopenharmony_ci		} while (count != radeon_get_vblank_counter(rdev, pipe));
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ci		if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
8008c2ecf20Sopenharmony_ci		    (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) {
8018c2ecf20Sopenharmony_ci			DRM_DEBUG_VBL("Query failed! stat %d\n", stat);
8028c2ecf20Sopenharmony_ci		}
8038c2ecf20Sopenharmony_ci		else {
8048c2ecf20Sopenharmony_ci			DRM_DEBUG_VBL("crtc %u: dist from vblank start %d\n",
8058c2ecf20Sopenharmony_ci				      pipe, vpos);
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci			/* Bump counter if we are at >= leading edge of vblank,
8088c2ecf20Sopenharmony_ci			 * but before vsync where vpos would turn negative and
8098c2ecf20Sopenharmony_ci			 * the hw counter really increments.
8108c2ecf20Sopenharmony_ci			 */
8118c2ecf20Sopenharmony_ci			if (vpos >= 0)
8128c2ecf20Sopenharmony_ci				count++;
8138c2ecf20Sopenharmony_ci		}
8148c2ecf20Sopenharmony_ci	}
8158c2ecf20Sopenharmony_ci	else {
8168c2ecf20Sopenharmony_ci	    /* Fallback to use value as is. */
8178c2ecf20Sopenharmony_ci	    count = radeon_get_vblank_counter(rdev, pipe);
8188c2ecf20Sopenharmony_ci	    DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
8198c2ecf20Sopenharmony_ci	}
8208c2ecf20Sopenharmony_ci
8218c2ecf20Sopenharmony_ci	return count;
8228c2ecf20Sopenharmony_ci}
8238c2ecf20Sopenharmony_ci
8248c2ecf20Sopenharmony_ci/**
8258c2ecf20Sopenharmony_ci * radeon_enable_vblank_kms - enable vblank interrupt
8268c2ecf20Sopenharmony_ci *
8278c2ecf20Sopenharmony_ci * @crtc: crtc to enable vblank interrupt for
8288c2ecf20Sopenharmony_ci *
8298c2ecf20Sopenharmony_ci * Enable the interrupt on the requested crtc (all asics).
8308c2ecf20Sopenharmony_ci * Returns 0 on success, -EINVAL on failure.
8318c2ecf20Sopenharmony_ci */
8328c2ecf20Sopenharmony_ciint radeon_enable_vblank_kms(struct drm_crtc *crtc)
8338c2ecf20Sopenharmony_ci{
8348c2ecf20Sopenharmony_ci	struct drm_device *dev = crtc->dev;
8358c2ecf20Sopenharmony_ci	unsigned int pipe = crtc->index;
8368c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
8378c2ecf20Sopenharmony_ci	unsigned long irqflags;
8388c2ecf20Sopenharmony_ci	int r;
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci	if (pipe >= rdev->num_crtc) {
8418c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid crtc %d\n", pipe);
8428c2ecf20Sopenharmony_ci		return -EINVAL;
8438c2ecf20Sopenharmony_ci	}
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->irq.lock, irqflags);
8468c2ecf20Sopenharmony_ci	rdev->irq.crtc_vblank_int[pipe] = true;
8478c2ecf20Sopenharmony_ci	r = radeon_irq_set(rdev);
8488c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
8498c2ecf20Sopenharmony_ci	return r;
8508c2ecf20Sopenharmony_ci}
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci/**
8538c2ecf20Sopenharmony_ci * radeon_disable_vblank_kms - disable vblank interrupt
8548c2ecf20Sopenharmony_ci *
8558c2ecf20Sopenharmony_ci * @crtc: crtc to disable vblank interrupt for
8568c2ecf20Sopenharmony_ci *
8578c2ecf20Sopenharmony_ci * Disable the interrupt on the requested crtc (all asics).
8588c2ecf20Sopenharmony_ci */
8598c2ecf20Sopenharmony_civoid radeon_disable_vblank_kms(struct drm_crtc *crtc)
8608c2ecf20Sopenharmony_ci{
8618c2ecf20Sopenharmony_ci	struct drm_device *dev = crtc->dev;
8628c2ecf20Sopenharmony_ci	unsigned int pipe = crtc->index;
8638c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
8648c2ecf20Sopenharmony_ci	unsigned long irqflags;
8658c2ecf20Sopenharmony_ci
8668c2ecf20Sopenharmony_ci	if (pipe >= rdev->num_crtc) {
8678c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid crtc %d\n", pipe);
8688c2ecf20Sopenharmony_ci		return;
8698c2ecf20Sopenharmony_ci	}
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->irq.lock, irqflags);
8728c2ecf20Sopenharmony_ci	rdev->irq.crtc_vblank_int[pipe] = false;
8738c2ecf20Sopenharmony_ci	radeon_irq_set(rdev);
8748c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
8758c2ecf20Sopenharmony_ci}
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ciconst struct drm_ioctl_desc radeon_ioctls_kms[] = {
8788c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
8798c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CP_START, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
8808c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
8818c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
8828c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, drm_invalid_op, DRM_AUTH),
8838c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, drm_invalid_op, DRM_AUTH),
8848c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_RESET, drm_invalid_op, DRM_AUTH),
8858c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, drm_invalid_op, DRM_AUTH),
8868c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_SWAP, drm_invalid_op, DRM_AUTH),
8878c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CLEAR, drm_invalid_op, DRM_AUTH),
8888c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_VERTEX, drm_invalid_op, DRM_AUTH),
8898c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_INDICES, drm_invalid_op, DRM_AUTH),
8908c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, drm_invalid_op, DRM_AUTH),
8918c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, drm_invalid_op, DRM_AUTH),
8928c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
8938c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, drm_invalid_op, DRM_AUTH),
8948c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, drm_invalid_op, DRM_AUTH),
8958c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, drm_invalid_op, DRM_AUTH),
8968c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_FLIP, drm_invalid_op, DRM_AUTH),
8978c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_ALLOC, drm_invalid_op, DRM_AUTH),
8988c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_FREE, drm_invalid_op, DRM_AUTH),
8998c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
9008c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, drm_invalid_op, DRM_AUTH),
9018c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, drm_invalid_op, DRM_AUTH),
9028c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, drm_invalid_op, DRM_AUTH),
9038c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, drm_invalid_op, DRM_AUTH),
9048c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, drm_invalid_op, DRM_AUTH),
9058c2ecf20Sopenharmony_ci	/* KMS */
9068c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9078c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9088c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9098c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9108c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH),
9118c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH),
9128c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9138c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9148c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9158c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9168c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9178c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9188c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9198c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9208c2ecf20Sopenharmony_ci	DRM_IOCTL_DEF_DRV(RADEON_GEM_USERPTR, radeon_gem_userptr_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
9218c2ecf20Sopenharmony_ci};
9228c2ecf20Sopenharmony_ciint radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms);
923