radeon_kms.c 26.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 * Copyright 2008 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 * Copyright 2009 Jerome Glisse.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Dave Airlie
 *          Alex Deucher
 *          Jerome Glisse
 */
28
#include <drm/drmP.h>
29
#include "radeon.h"
30
#include <drm/radeon_drm.h>
31
#include "radeon_asic.h"
32

33
#include <linux/vga_switcheroo.h>
34
#include <linux/slab.h>
35
#include <linux/pm_runtime.h>
36 37

#if defined(CONFIG_VGA_SWITCHEROO)
38
bool radeon_has_atpx(void);
39
#else
40
static inline bool radeon_has_atpx(void) { return false; }
41 42
#endif

A
Alex Deucher 已提交
43 44 45 46 47 48 49 50 51 52 53
/**
 * radeon_driver_unload_kms - Main unload function for KMS.
 *
 * @dev: drm dev pointer
 *
 * This is the main unload function for KMS (all asics).
 * It calls radeon_modeset_fini() to tear down the
 * displays, and radeon_device_fini() to tear down
 * the rest of the device (CP, writeback, etc.).
 * Returns 0 on success.
 */
54 55 56 57 58 59
int radeon_driver_unload_kms(struct drm_device *dev)
{
	struct radeon_device *rdev = dev->dev_private;

	if (rdev == NULL)
		return 0;
60

61 62
	if (rdev->rmmio == NULL)
		goto done_free;
63 64 65

	pm_runtime_get_sync(dev->dev);

66
	radeon_acpi_fini(rdev);
67
	
68 69
	radeon_modeset_fini(rdev);
	radeon_device_fini(rdev);
70 71

done_free:
72 73 74 75
	kfree(rdev);
	dev->dev_private = NULL;
	return 0;
}
76

A
Alex Deucher 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
90 91 92
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
{
	struct radeon_device *rdev;
93
	int r, acpi_status;
94 95 96 97 98 99 100 101

	rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL);
	if (rdev == NULL) {
		return -ENOMEM;
	}
	dev->dev_private = (void *)rdev;

	/* update BUS flag */
102
	if (drm_pci_device_is_agp(dev)) {
103
		flags |= RADEON_IS_AGP;
J
Jon Mason 已提交
104
	} else if (pci_is_pcie(dev->pdev)) {
105 106 107 108 109
		flags |= RADEON_IS_PCIE;
	} else {
		flags |= RADEON_IS_PCI;
	}

110 111 112
	if ((radeon_runtime_pm != 0) &&
	    radeon_has_atpx() &&
	    ((flags & RADEON_IS_IGP) == 0))
113 114
		flags |= RADEON_IS_PX;

115 116 117 118 119 120
	/* radeon_device_init should report only fatal error
	 * like memory allocation failure or iomapping failure,
	 * or memory manager initialization failure, it must
	 * properly initialize the GPU MC controller and permit
	 * VRAM allocation
	 */
121 122
	r = radeon_device_init(rdev, dev, dev->pdev, flags);
	if (r) {
123 124
		dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
		goto out;
125
	}
126

127 128 129 130 131
	/* Again modeset_init should fail only on fatal error
	 * otherwise it should provide enough functionalities
	 * for shadowfb to run
	 */
	r = radeon_modeset_init(rdev);
132 133
	if (r)
		dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");
134 135 136 137 138 139 140 141 142 143 144

	/* Call ACPI methods: require modeset init
	 * but failure is not fatal
	 */
	if (!r) {
		acpi_status = radeon_acpi_init(rdev);
		if (acpi_status)
		dev_dbg(&dev->pdev->dev,
				"Error during ACPI methods call\n");
	}

145
	if (radeon_is_px(dev)) {
146 147 148 149 150 151 152 153
		pm_runtime_use_autosuspend(dev->dev);
		pm_runtime_set_autosuspend_delay(dev->dev, 5000);
		pm_runtime_set_active(dev->dev);
		pm_runtime_allow(dev->dev);
		pm_runtime_mark_last_busy(dev->dev);
		pm_runtime_put_autosuspend(dev->dev);
	}

154 155 156
out:
	if (r)
		radeon_driver_unload_kms(dev);
157 158


159
	return r;
160 161
}

A
Alex Deucher 已提交
162 163 164 165 166 167 168 169 170 171
/**
 * radeon_set_filp_rights - Set filp right.
 *
 * @dev: drm dev pointer
 * @owner: drm file
 * @applier: drm file
 * @value: value
 *
 * Sets the filp rights for the device (all asics).
 */
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
static void radeon_set_filp_rights(struct drm_device *dev,
				   struct drm_file **owner,
				   struct drm_file *applier,
				   uint32_t *value)
{
	mutex_lock(&dev->struct_mutex);
	if (*value == 1) {
		/* wants rights */
		if (!*owner)
			*owner = applier;
	} else if (*value == 0) {
		/* revokes rights */
		if (*owner == applier)
			*owner = NULL;
	}
	*value = *owner == applier ? 1 : 0;
	mutex_unlock(&dev->struct_mutex);
}
190 191

/*
192
 * Userspace get information ioctl
193
 */
A
Alex Deucher 已提交
194 195 196 197 198 199 200 201 202 203 204 205
/**
 * radeon_info_ioctl - answer a device specific request.
 *
 * @rdev: radeon device pointer
 * @data: request object
 * @filp: drm filp
 *
 * This function is used to pass device specific parameters to the userspace
 * drivers.  Examples include: pci device id, pipeline parms, tiling params,
 * etc. (all asics).
 * Returns 0 on success, -EINVAL on failure.
 */
206
static int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
207 208
{
	struct radeon_device *rdev = dev->dev_private;
209
	struct drm_radeon_info *info = data;
210
	struct radeon_mode_info *minfo = &rdev->mode_info;
211 212
	uint32_t *value, value_tmp, *value_ptr, value_size;
	uint64_t value64;
213 214
	struct drm_crtc *crtc;
	int i, found;
215 216

	value_ptr = (uint32_t *)((unsigned long)info->value);
217 218
	value = &value_tmp;
	value_size = sizeof(uint32_t);
219

220 221
	switch (info->request) {
	case RADEON_INFO_DEVICE_ID:
222
		*value = dev->pdev->device;
223 224
		break;
	case RADEON_INFO_NUM_GB_PIPES:
225
		*value = rdev->num_gb_pipes;
226
		break;
227
	case RADEON_INFO_NUM_Z_PIPES:
228
		*value = rdev->num_z_pipes;
229
		break;
230
	case RADEON_INFO_ACCEL_WORKING:
231 232
		/* xf86-video-ati 6.13.0 relies on this being false for evergreen */
		if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK))
233
			*value = false;
234
		else
235
			*value = rdev->accel_working;
236
		break;
237
	case RADEON_INFO_CRTC_FROM_ID:
D
Daniel Vetter 已提交
238
		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
239 240 241
			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
			return -EFAULT;
		}
242 243
		for (i = 0, found = 0; i < rdev->num_crtc; i++) {
			crtc = (struct drm_crtc *)minfo->crtcs[i];
244
			if (crtc && crtc->base.id == *value) {
245
				struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
246
				*value = radeon_crtc->crtc_id;
247 248 249 250 251
				found = 1;
				break;
			}
		}
		if (!found) {
252
			DRM_DEBUG_KMS("unknown crtc id %d\n", *value);
253 254 255
			return -EINVAL;
		}
		break;
256
	case RADEON_INFO_ACCEL_WORKING2:
257
		if (rdev->family == CHIP_HAWAII) {
258 259 260 261 262 263
			if (rdev->accel_working) {
				if (rdev->new_fw)
					*value = 3;
				else
					*value = 2;
			} else {
264
				*value = 0;
265
			}
266 267 268
		} else {
			*value = rdev->accel_working;
		}
269
		break;
270
	case RADEON_INFO_TILING_CONFIG:
271 272 273
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.tile_config;
		else if (rdev->family >= CHIP_TAHITI)
274
			*value = rdev->config.si.tile_config;
275
		else if (rdev->family >= CHIP_CAYMAN)
276
			*value = rdev->config.cayman.tile_config;
277
		else if (rdev->family >= CHIP_CEDAR)
278
			*value = rdev->config.evergreen.tile_config;
279
		else if (rdev->family >= CHIP_RV770)
280
			*value = rdev->config.rv770.tile_config;
281
		else if (rdev->family >= CHIP_R600)
282
			*value = rdev->config.r600.tile_config;
283
		else {
284
			DRM_DEBUG_KMS("tiling config is r6xx+ only!\n");
285 286
			return -EINVAL;
		}
287
		break;
288
	case RADEON_INFO_WANT_HYPERZ:
289 290 291 292 293 294
		/* The "value" here is both an input and output parameter.
		 * If the input value is 1, filp requests hyper-z access.
		 * If the input value is 0, filp revokes its hyper-z access.
		 *
		 * When returning, the value is 1 if filp owns hyper-z access,
		 * 0 otherwise. */
D
Daniel Vetter 已提交
295
		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
296 297 298 299 300
			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
			return -EFAULT;
		}
		if (*value >= 2) {
			DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", *value);
301 302
			return -EINVAL;
		}
303
		radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, value);
304 305 306
		break;
	case RADEON_INFO_WANT_CMASK:
		/* The same logic as Hyper-Z. */
D
Daniel Vetter 已提交
307
		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
308 309 310 311 312
			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
			return -EFAULT;
		}
		if (*value >= 2) {
			DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", *value);
313
			return -EINVAL;
314
		}
315
		radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, value);
316
		break;
317 318
	case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
		/* return clock value in KHz */
319
		if (rdev->asic->get_xclk)
320
			*value = radeon_get_xclk(rdev) * 10;
321
		else
322
			*value = rdev->clock.spll.reference_freq * 10;
323
		break;
324
	case RADEON_INFO_NUM_BACKENDS:
325 326 327 328
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.max_backends_per_se *
				rdev->config.cik.max_shader_engines;
		else if (rdev->family >= CHIP_TAHITI)
329
			*value = rdev->config.si.max_backends_per_se *
330 331
				rdev->config.si.max_shader_engines;
		else if (rdev->family >= CHIP_CAYMAN)
332
			*value = rdev->config.cayman.max_backends_per_se *
333 334
				rdev->config.cayman.max_shader_engines;
		else if (rdev->family >= CHIP_CEDAR)
335
			*value = rdev->config.evergreen.max_backends;
336
		else if (rdev->family >= CHIP_RV770)
337
			*value = rdev->config.rv770.max_backends;
338
		else if (rdev->family >= CHIP_R600)
339
			*value = rdev->config.r600.max_backends;
340 341 342 343
		else {
			return -EINVAL;
		}
		break;
344
	case RADEON_INFO_NUM_TILE_PIPES:
345 346 347
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.max_tile_pipes;
		else if (rdev->family >= CHIP_TAHITI)
348
			*value = rdev->config.si.max_tile_pipes;
349
		else if (rdev->family >= CHIP_CAYMAN)
350
			*value = rdev->config.cayman.max_tile_pipes;
351
		else if (rdev->family >= CHIP_CEDAR)
352
			*value = rdev->config.evergreen.max_tile_pipes;
353
		else if (rdev->family >= CHIP_RV770)
354
			*value = rdev->config.rv770.max_tile_pipes;
355
		else if (rdev->family >= CHIP_R600)
356
			*value = rdev->config.r600.max_tile_pipes;
357 358 359 360
		else {
			return -EINVAL;
		}
		break;
361
	case RADEON_INFO_FUSION_GART_WORKING:
362
		*value = 1;
363
		break;
364
	case RADEON_INFO_BACKEND_MAP:
365
		if (rdev->family >= CHIP_BONAIRE)
366
			*value = rdev->config.cik.backend_map;
367
		else if (rdev->family >= CHIP_TAHITI)
368
			*value = rdev->config.si.backend_map;
369
		else if (rdev->family >= CHIP_CAYMAN)
370
			*value = rdev->config.cayman.backend_map;
371
		else if (rdev->family >= CHIP_CEDAR)
372
			*value = rdev->config.evergreen.backend_map;
373
		else if (rdev->family >= CHIP_RV770)
374
			*value = rdev->config.rv770.backend_map;
375
		else if (rdev->family >= CHIP_R600)
376
			*value = rdev->config.r600.backend_map;
377 378 379 380
		else {
			return -EINVAL;
		}
		break;
381 382 383 384
	case RADEON_INFO_VA_START:
		/* this is where we report if vm is supported or not */
		if (rdev->family < CHIP_CAYMAN)
			return -EINVAL;
385
		*value = RADEON_VA_RESERVED_SIZE;
386 387 388 389 390
		break;
	case RADEON_INFO_IB_VM_MAX_SIZE:
		/* this is where we report if vm is supported or not */
		if (rdev->family < CHIP_CAYMAN)
			return -EINVAL;
391
		*value = RADEON_IB_VM_MAX_SIZE;
392
		break;
393
	case RADEON_INFO_MAX_PIPES:
394 395 396
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.max_cu_per_sh;
		else if (rdev->family >= CHIP_TAHITI)
397
			*value = rdev->config.si.max_cu_per_sh;
398
		else if (rdev->family >= CHIP_CAYMAN)
399
			*value = rdev->config.cayman.max_pipes_per_simd;
400
		else if (rdev->family >= CHIP_CEDAR)
401
			*value = rdev->config.evergreen.max_pipes;
402
		else if (rdev->family >= CHIP_RV770)
403
			*value = rdev->config.rv770.max_pipes;
404
		else if (rdev->family >= CHIP_R600)
405
			*value = rdev->config.r600.max_pipes;
406 407 408 409
		else {
			return -EINVAL;
		}
		break;
410 411 412 413 414 415 416 417 418
	case RADEON_INFO_TIMESTAMP:
		if (rdev->family < CHIP_R600) {
			DRM_DEBUG_KMS("timestamp is r6xx+ only!\n");
			return -EINVAL;
		}
		value = (uint32_t*)&value64;
		value_size = sizeof(uint64_t);
		value64 = radeon_get_gpu_clock_counter(rdev);
		break;
419
	case RADEON_INFO_MAX_SE:
420 421 422
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.max_shader_engines;
		else if (rdev->family >= CHIP_TAHITI)
423
			*value = rdev->config.si.max_shader_engines;
424
		else if (rdev->family >= CHIP_CAYMAN)
425
			*value = rdev->config.cayman.max_shader_engines;
426
		else if (rdev->family >= CHIP_CEDAR)
427
			*value = rdev->config.evergreen.num_ses;
428
		else
429
			*value = 1;
430 431
		break;
	case RADEON_INFO_MAX_SH_PER_SE:
432 433 434
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.max_sh_per_se;
		else if (rdev->family >= CHIP_TAHITI)
435
			*value = rdev->config.si.max_sh_per_se;
436 437 438
		else
			return -EINVAL;
		break;
439
	case RADEON_INFO_FASTFB_WORKING:
440
		*value = rdev->fastfb_working;
441
		break;
442
	case RADEON_INFO_RING_WORKING:
D
Daniel Vetter 已提交
443
		if (copy_from_user(value, value_ptr, sizeof(uint32_t))) {
444 445 446 447
			DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__);
			return -EFAULT;
		}
		switch (*value) {
448 449
		case RADEON_CS_RING_GFX:
		case RADEON_CS_RING_COMPUTE:
450
			*value = rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready;
451 452
			break;
		case RADEON_CS_RING_DMA:
453 454
			*value = rdev->ring[R600_RING_TYPE_DMA_INDEX].ready;
			*value |= rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX].ready;
455 456
			break;
		case RADEON_CS_RING_UVD:
457
			*value = rdev->ring[R600_RING_TYPE_UVD_INDEX].ready;
458
			break;
459 460 461
		case RADEON_CS_RING_VCE:
			*value = rdev->ring[TN_RING_TYPE_VCE1_INDEX].ready;
			break;
462 463 464 465
		default:
			return -EINVAL;
		}
		break;
466
	case RADEON_INFO_SI_TILE_MODE_ARRAY:
467
		if (rdev->family >= CHIP_BONAIRE) {
468 469 470 471 472 473 474
			value = rdev->config.cik.tile_mode_array;
			value_size = sizeof(uint32_t)*32;
		} else if (rdev->family >= CHIP_TAHITI) {
			value = rdev->config.si.tile_mode_array;
			value_size = sizeof(uint32_t)*32;
		} else {
			DRM_DEBUG_KMS("tile mode array is si+ only!\n");
475 476
			return -EINVAL;
		}
477
		break;
478 479 480 481 482 483 484 485 486
	case RADEON_INFO_CIK_MACROTILE_MODE_ARRAY:
		if (rdev->family >= CHIP_BONAIRE) {
			value = rdev->config.cik.macrotile_mode_array;
			value_size = sizeof(uint32_t)*16;
		} else {
			DRM_DEBUG_KMS("macrotile mode array is cik+ only!\n");
			return -EINVAL;
		}
		break;
487 488 489
	case RADEON_INFO_SI_CP_DMA_COMPUTE:
		*value = 1;
		break;
490 491 492 493 494 495 496 497 498
	case RADEON_INFO_SI_BACKEND_ENABLED_MASK:
		if (rdev->family >= CHIP_BONAIRE) {
			*value = rdev->config.cik.backend_enable_mask;
		} else if (rdev->family >= CHIP_TAHITI) {
			*value = rdev->config.si.backend_enable_mask;
		} else {
			DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n");
		}
		break;
499 500 501 502 503 504 505
	case RADEON_INFO_MAX_SCLK:
		if ((rdev->pm.pm_method == PM_METHOD_DPM) &&
		    rdev->pm.dpm_enabled)
			*value = rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk * 10;
		else
			*value = rdev->pm.default_sclk * 10;
		break;
506 507 508 509 510 511
	case RADEON_INFO_VCE_FW_VERSION:
		*value = rdev->vce.fw_version;
		break;
	case RADEON_INFO_VCE_FB_VERSION:
		*value = rdev->vce.fb_version;
		break;
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
	case RADEON_INFO_NUM_BYTES_MOVED:
		value = (uint32_t*)&value64;
		value_size = sizeof(uint64_t);
		value64 = atomic64_read(&rdev->num_bytes_moved);
		break;
	case RADEON_INFO_VRAM_USAGE:
		value = (uint32_t*)&value64;
		value_size = sizeof(uint64_t);
		value64 = atomic64_read(&rdev->vram_usage);
		break;
	case RADEON_INFO_GTT_USAGE:
		value = (uint32_t*)&value64;
		value_size = sizeof(uint64_t);
		value64 = atomic64_read(&rdev->gtt_usage);
		break;
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
	case RADEON_INFO_ACTIVE_CU_COUNT:
		if (rdev->family >= CHIP_BONAIRE)
			*value = rdev->config.cik.active_cus;
		else if (rdev->family >= CHIP_TAHITI)
			*value = rdev->config.si.active_cus;
		else if (rdev->family >= CHIP_CAYMAN)
			*value = rdev->config.cayman.active_simds;
		else if (rdev->family >= CHIP_CEDAR)
			*value = rdev->config.evergreen.active_simds;
		else if (rdev->family >= CHIP_RV770)
			*value = rdev->config.rv770.active_simds;
		else if (rdev->family >= CHIP_R600)
			*value = rdev->config.r600.active_simds;
		else
			*value = 1;
		break;
543
	default:
544
		DRM_DEBUG_KMS("Invalid request %d\n", info->request);
545 546
		return -EINVAL;
	}
D
Daniel Vetter 已提交
547
	if (copy_to_user(value_ptr, (char*)value, value_size)) {
548
		DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__);
549 550 551 552 553 554 555 556 557
		return -EFAULT;
	}
	return 0;
}


/*
 * Outdated mess for old drm with Xorg being in charge (void function now).
 */
A
Alex Deucher 已提交
558 559 560 561 562 563 564
/**
 * radeon_driver_firstopen_kms - drm callback for last close
 *
 * @dev: drm dev pointer
 *
 * Switch vga switcheroo state after last close (all asics).
 */
565 566
void radeon_driver_lastclose_kms(struct drm_device *dev)
{
567
	vga_switcheroo_process_delayed_switch();
568 569
}

A
Alex Deucher 已提交
570 571 572 573 574 575 576 577 578
/**
 * radeon_driver_open_kms - drm callback for open
 *
 * @dev: drm dev pointer
 * @file_priv: drm file
 *
 * On device open, init vm on cayman+ (all asics).
 * Returns 0 on success, error on failure.
 */
579 580
int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
{
581
	struct radeon_device *rdev = dev->dev_private;
582
	int r;
583 584 585

	file_priv->driver_priv = NULL;

586 587 588 589
	r = pm_runtime_get_sync(dev->dev);
	if (r < 0)
		return r;

590 591 592
	/* new gpu have virtual address space support */
	if (rdev->family >= CHIP_CAYMAN) {
		struct radeon_fpriv *fpriv;
593
		struct radeon_vm *vm;
594 595 596 597 598 599 600
		int r;

		fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
		if (unlikely(!fpriv)) {
			return -ENOMEM;
		}

601 602
		vm = &fpriv->vm;
		r = radeon_vm_init(rdev, vm);
603 604
		if (r) {
			kfree(fpriv);
605
			return r;
606
		}
607

608 609 610
		if (rdev->accel_working) {
			r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
			if (r) {
611
				radeon_vm_fini(rdev, vm);
612 613 614
				kfree(fpriv);
				return r;
			}
615

616 617
			/* map the ib pool buffer read only into
			 * virtual address space */
618 619 620 621
			vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
							rdev->ring_tmp_bo.bo);
			r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va,
						  RADEON_VA_IB_OFFSET,
622 623
						  RADEON_VM_PAGE_READABLE |
						  RADEON_VM_PAGE_SNOOPED);
624

625 626
			radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
			if (r) {
627
				radeon_vm_fini(rdev, vm);
628 629 630
				kfree(fpriv);
				return r;
			}
631 632 633
		}
		file_priv->driver_priv = fpriv;
	}
634 635 636

	pm_runtime_mark_last_busy(dev->dev);
	pm_runtime_put_autosuspend(dev->dev);
637 638 639
	return 0;
}

A
Alex Deucher 已提交
640 641 642 643 644 645 646 647
/**
 * radeon_driver_postclose_kms - drm callback for post close
 *
 * @dev: drm dev pointer
 * @file_priv: drm file
 *
 * On device post close, tear down vm on cayman+ (all asics).
 */
648 649 650
void radeon_driver_postclose_kms(struct drm_device *dev,
				 struct drm_file *file_priv)
{
651 652 653 654 655
	struct radeon_device *rdev = dev->dev_private;

	/* new gpu have virtual address space support */
	if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) {
		struct radeon_fpriv *fpriv = file_priv->driver_priv;
656
		struct radeon_vm *vm = &fpriv->vm;
657 658
		int r;

659 660 661
		if (rdev->accel_working) {
			r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
			if (!r) {
662 663
				if (vm->ib_bo_va)
					radeon_vm_bo_rmv(rdev, vm->ib_bo_va);
664 665
				radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
			}
666
		}
667

668
		radeon_vm_fini(rdev, vm);
669 670 671
		kfree(fpriv);
		file_priv->driver_priv = NULL;
	}
672 673
}

A
Alex Deucher 已提交
674 675 676 677 678 679 680 681 682
/**
 * radeon_driver_preclose_kms - drm callback for pre close
 *
 * @dev: drm dev pointer
 * @file_priv: drm file
 *
 * On device pre close, tear down hyperz and cmask filps on r1xx-r5xx
 * (all asics).
 */
683 684 685
void radeon_driver_preclose_kms(struct drm_device *dev,
				struct drm_file *file_priv)
{
686 687 688
	struct radeon_device *rdev = dev->dev_private;
	if (rdev->hyperz_filp == file_priv)
		rdev->hyperz_filp = NULL;
689 690
	if (rdev->cmask_filp == file_priv)
		rdev->cmask_filp = NULL;
C
Christian König 已提交
691
	radeon_uvd_free_handles(rdev, file_priv);
692
	radeon_vce_free_handles(rdev, file_priv);
693 694 695 696 697
}

/*
 * VBlank related functions.
 */
A
Alex Deucher 已提交
698 699 700 701 702 703 704 705 706
/**
 * radeon_get_vblank_counter_kms - get frame count
 *
 * @dev: drm dev pointer
 * @crtc: crtc to get the frame count from
 *
 * Gets the frame count on the requested crtc (all asics).
 * Returns frame count on success, -EINVAL on failure.
 */
707 708
u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc)
{
709 710
	struct radeon_device *rdev = dev->dev_private;

711
	if (crtc < 0 || crtc >= rdev->num_crtc) {
712 713 714 715 716
		DRM_ERROR("Invalid crtc %d\n", crtc);
		return -EINVAL;
	}

	return radeon_get_vblank_counter(rdev, crtc);
717 718
}

A
Alex Deucher 已提交
719 720 721 722 723 724 725 726 727
/**
 * radeon_enable_vblank_kms - enable vblank interrupt
 *
 * @dev: drm dev pointer
 * @crtc: crtc to enable vblank interrupt for
 *
 * Enable the interrupt on the requested crtc (all asics).
 * Returns 0 on success, -EINVAL on failure.
 */
728 729
int radeon_enable_vblank_kms(struct drm_device *dev, int crtc)
{
730
	struct radeon_device *rdev = dev->dev_private;
731 732
	unsigned long irqflags;
	int r;
733

734
	if (crtc < 0 || crtc >= rdev->num_crtc) {
735 736 737 738
		DRM_ERROR("Invalid crtc %d\n", crtc);
		return -EINVAL;
	}

739
	spin_lock_irqsave(&rdev->irq.lock, irqflags);
740
	rdev->irq.crtc_vblank_int[crtc] = true;
741 742 743
	r = radeon_irq_set(rdev);
	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
	return r;
744 745
}

A
Alex Deucher 已提交
746 747 748 749 750 751 752 753
/**
 * radeon_disable_vblank_kms - disable vblank interrupt
 *
 * @dev: drm dev pointer
 * @crtc: crtc to disable vblank interrupt for
 *
 * Disable the interrupt on the requested crtc (all asics).
 */
754 755
void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
{
756
	struct radeon_device *rdev = dev->dev_private;
757
	unsigned long irqflags;
758

759
	if (crtc < 0 || crtc >= rdev->num_crtc) {
760 761 762 763
		DRM_ERROR("Invalid crtc %d\n", crtc);
		return;
	}

764
	spin_lock_irqsave(&rdev->irq.lock, irqflags);
765 766
	rdev->irq.crtc_vblank_int[crtc] = false;
	radeon_irq_set(rdev);
767
	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
768 769
}

A
Alex Deucher 已提交
770 771 772 773 774 775 776 777 778 779 780 781 782
/**
 * radeon_get_vblank_timestamp_kms - get vblank timestamp
 *
 * @dev: drm dev pointer
 * @crtc: crtc to get the timestamp for
 * @max_error: max error
 * @vblank_time: time value
 * @flags: flags passed to the driver
 *
 * Gets the timestamp on the requested crtc based on the
 * scanout position.  (all asics).
 * Returns postive status flags on success, negative error on failure.
 */
783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc,
				    int *max_error,
				    struct timeval *vblank_time,
				    unsigned flags)
{
	struct drm_crtc *drmcrtc;
	struct radeon_device *rdev = dev->dev_private;

	if (crtc < 0 || crtc >= dev->num_crtcs) {
		DRM_ERROR("Invalid crtc %d\n", crtc);
		return -EINVAL;
	}

	/* Get associated drm_crtc: */
	drmcrtc = &rdev->mode_info.crtcs[crtc]->base;

	/* Helper routine in DRM core does all the work: */
	return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
						     vblank_time, flags,
802
						     drmcrtc, &drmcrtc->hwmode);
803
}
804 805

#define KMS_INVALID_IOCTL(name)						\
806 807
static int name(struct drm_device *dev, void *data, struct drm_file	\
		*file_priv)						\
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
{									\
	DRM_ERROR("invalid ioctl with kms %s\n", __func__);		\
	return -EINVAL;							\
}

/*
 * All these ioctls are invalid in kms world.
 */
KMS_INVALID_IOCTL(radeon_cp_init_kms)
KMS_INVALID_IOCTL(radeon_cp_start_kms)
KMS_INVALID_IOCTL(radeon_cp_stop_kms)
KMS_INVALID_IOCTL(radeon_cp_reset_kms)
KMS_INVALID_IOCTL(radeon_cp_idle_kms)
KMS_INVALID_IOCTL(radeon_cp_resume_kms)
KMS_INVALID_IOCTL(radeon_engine_reset_kms)
KMS_INVALID_IOCTL(radeon_fullscreen_kms)
KMS_INVALID_IOCTL(radeon_cp_swap_kms)
KMS_INVALID_IOCTL(radeon_cp_clear_kms)
KMS_INVALID_IOCTL(radeon_cp_vertex_kms)
KMS_INVALID_IOCTL(radeon_cp_indices_kms)
KMS_INVALID_IOCTL(radeon_cp_texture_kms)
KMS_INVALID_IOCTL(radeon_cp_stipple_kms)
KMS_INVALID_IOCTL(radeon_cp_indirect_kms)
KMS_INVALID_IOCTL(radeon_cp_vertex2_kms)
KMS_INVALID_IOCTL(radeon_cp_cmdbuf_kms)
KMS_INVALID_IOCTL(radeon_cp_getparam_kms)
KMS_INVALID_IOCTL(radeon_cp_flip_kms)
KMS_INVALID_IOCTL(radeon_mem_alloc_kms)
KMS_INVALID_IOCTL(radeon_mem_free_kms)
KMS_INVALID_IOCTL(radeon_mem_init_heap_kms)
KMS_INVALID_IOCTL(radeon_irq_emit_kms)
KMS_INVALID_IOCTL(radeon_irq_wait_kms)
KMS_INVALID_IOCTL(radeon_cp_setparam_kms)
KMS_INVALID_IOCTL(radeon_surface_alloc_kms)
KMS_INVALID_IOCTL(radeon_surface_free_kms)


R
Rob Clark 已提交
845
const struct drm_ioctl_desc radeon_ioctls_kms[] = {
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
	DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH),
	DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH),
873
	/* KMS */
874 875 876 877
	DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
878 879
	DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED),
880 881 882 883 884 885 886
	DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
	DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
887
	DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
888
	DRM_IOCTL_DEF_DRV(RADEON_GEM_USERPTR, radeon_gem_userptr_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
889
};
890
int radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms);