nouveau_drm.c 18.3 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
/*
 * Copyright 2012 Red Hat Inc.
 *
 * 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: Ben Skeggs
 */

25
#include <linux/console.h>
26 27 28 29 30
#include <linux/module.h>
#include <linux/pci.h>

#include <core/device.h>
#include <core/client.h>
31
#include <core/gpuobj.h>
32 33 34
#include <core/class.h>

#include <subdev/device.h>
35
#include <subdev/vm.h>
36 37

#include "nouveau_drm.h"
38
#include "nouveau_irq.h"
39
#include "nouveau_dma.h"
40 41
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
42
#include "nouveau_agp.h"
43 44 45 46 47
#include "nouveau_vga.h"
#include "nouveau_pm.h"
#include "nouveau_acpi.h"
#include "nouveau_bios.h"
#include "nouveau_ioctl.h"
48 49 50 51 52
#include "nouveau_abi16.h"
#include "nouveau_fbcon.h"
#include "nouveau_fence.h"

#include "nouveau_ttm.h"
53 54 55 56 57 58 59 60 61

MODULE_PARM_DESC(config, "option string to pass to driver core");
static char *nouveau_config;
module_param_named(config, nouveau_config, charp, 0400);

MODULE_PARM_DESC(debug, "debug string to pass to driver core");
static char *nouveau_debug;
module_param_named(debug, nouveau_debug, charp, 0400);

62 63 64 65
MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration");
static int nouveau_noaccel = 0;
module_param_named(noaccel, nouveau_noaccel, int, 0400);

66 67 68
MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
		          "0 = disabled, 1 = enabled, 2 = headless)");
int nouveau_modeset = -1;
69 70 71 72
module_param_named(modeset, nouveau_modeset, int, 0400);

static struct drm_driver driver;

73 74 75 76 77 78 79 80 81 82
static u64
nouveau_name(struct pci_dev *pdev)
{
	u64 name = (u64)pci_domain_nr(pdev->bus) << 32;
	name |= pdev->bus->number << 16;
	name |= PCI_SLOT(pdev->devfn) << 8;
	return name | PCI_FUNC(pdev->devfn);
}

static int
83 84
nouveau_cli_create(struct pci_dev *pdev, const char *name,
		   int size, void **pcli)
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
{
	struct nouveau_cli *cli;
	int ret;

	ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
				     nouveau_debug, size, pcli);
	cli = *pcli;
	if (ret)
		return ret;

	mutex_init(&cli->mutex);
	return 0;
}

static void
nouveau_cli_destroy(struct nouveau_cli *cli)
{
	struct nouveau_object *client = nv_object(cli);
103
	nouveau_vm_ref(NULL, &cli->base.vm, NULL);
104 105 106 107 108
	nouveau_client_fini(&cli->base, false);
	atomic_set(&client->refcount, 1);
	nouveau_object_ref(NULL, &client);
}

109 110 111 112 113
static void
nouveau_accel_fini(struct nouveau_drm *drm)
{
	nouveau_gpuobj_ref(NULL, &drm->notify);
	nouveau_channel_del(&drm->channel);
114
	nouveau_channel_del(&drm->cechan);
115 116 117 118 119 120 121 122 123
	if (drm->fence)
		nouveau_fence(drm)->dtor(drm);
}

static void
nouveau_accel_init(struct nouveau_drm *drm)
{
	struct nouveau_device *device = nv_device(drm->device);
	struct nouveau_object *object;
124
	u32 arg0, arg1;
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
	int ret;

	if (nouveau_noaccel)
		return;

	/* initialise synchronisation routines */
	if      (device->card_type < NV_10) ret = nv04_fence_create(drm);
	else if (device->chipset   <  0x84) ret = nv10_fence_create(drm);
	else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
	else                                ret = nvc0_fence_create(drm);
	if (ret) {
		NV_ERROR(drm, "failed to initialise sync subsystem, %d\n", ret);
		nouveau_accel_fini(drm);
		return;
	}

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	if (device->card_type >= NV_E0) {
		ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
					  NVDRM_CHAN + 1,
					  NVE0_CHANNEL_IND_ENGINE_CE0 |
					  NVE0_CHANNEL_IND_ENGINE_CE1, 0,
					  &drm->cechan);
		if (ret)
			NV_ERROR(drm, "failed to create ce channel, %d\n", ret);

		arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
		arg1 = 0;
	} else {
		arg0 = NvDmaFB;
		arg1 = NvDmaTT;
	}

157
	ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, NVDRM_CHAN,
158
				  arg0, arg1, &drm->channel);
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
	if (ret) {
		NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
		nouveau_accel_fini(drm);
		return;
	}

	if (device->card_type < NV_C0) {
		ret = nouveau_gpuobj_new(drm->device, NULL, 32, 0, 0,
					&drm->notify);
		if (ret) {
			NV_ERROR(drm, "failed to allocate notifier, %d\n", ret);
			nouveau_accel_fini(drm);
			return;
		}

		ret = nouveau_object_new(nv_object(drm),
					 drm->channel->handle, NvNotify0,
					 0x003d, &(struct nv_dma_class) {
						.flags = NV_DMA_TARGET_VRAM |
							 NV_DMA_ACCESS_RDWR,
						.start = drm->notify->addr,
						.limit = drm->notify->addr + 31
						}, sizeof(struct nv_dma_class),
					 &object);
		if (ret) {
			nouveau_accel_fini(drm);
			return;
		}
	}


190
	nouveau_bo_move_init(drm);
191 192
}

193 194 195 196
static int __devinit
nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent)
{
	struct nouveau_device *device;
197 198
	struct apertures_struct *aper;
	bool boot = false;
199 200
	int ret;

201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
	/* remove conflicting drivers (vesafb, efifb etc) */
	aper = alloc_apertures(3);
	if (!aper)
		return -ENOMEM;

	aper->ranges[0].base = pci_resource_start(pdev, 1);
	aper->ranges[0].size = pci_resource_len(pdev, 1);
	aper->count = 1;

	if (pci_resource_len(pdev, 2)) {
		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
		aper->count++;
	}

	if (pci_resource_len(pdev, 3)) {
		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
		aper->count++;
	}

#ifdef CONFIG_X86
	boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
#endif
	remove_conflicting_framebuffers(aper, "nouveaufb", boot);
226
	kfree(aper);
227

228 229 230 231 232 233 234
	ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev),
				    nouveau_config, nouveau_debug, &device);
	if (ret)
		return ret;

	pci_set_master(pdev);

235
	ret = drm_get_pci_dev(pdev, pent, &driver);
236
	if (ret) {
237
		nouveau_object_ref(NULL, (struct nouveau_object **)&device);
238 239 240 241 242 243
		return ret;
	}

	return 0;
}

244
static int
245 246 247
nouveau_drm_load(struct drm_device *dev, unsigned long flags)
{
	struct pci_dev *pdev = dev->pdev;
248
	struct nouveau_device *device;
249 250 251
	struct nouveau_drm *drm;
	int ret;

252
	ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);
253 254 255
	if (ret)
		return ret;

256 257 258
	dev->dev_private = drm;
	drm->dev = dev;

259
	INIT_LIST_HEAD(&drm->clients);
260
	spin_lock_init(&drm->tile.lock);
261

262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
	/* make sure AGP controller is in a consistent state before we
	 * (possibly) execute vbios init tables (see nouveau_agp.h)
	 */
	if (drm_pci_device_is_agp(dev) && dev->agp) {
		/* dummy device object, doesn't init anything, but allows
		 * agp code access to registers
		 */
		ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT,
					 NVDRM_DEVICE, 0x0080,
					 &(struct nv_device_class) {
						.device = ~0,
						.disable =
						 ~(NV_DEVICE_DISABLE_MMIO |
						   NV_DEVICE_DISABLE_IDENTIFY),
						.debug0 = ~0,
					 }, sizeof(struct nv_device_class),
					 &drm->device);
		if (ret)
280
			goto fail_device;
281 282 283 284 285

		nouveau_agp_reset(drm);
		nouveau_object_del(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE);
	}

286 287 288 289 290 291 292 293 294 295
	ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE,
				 0x0080, &(struct nv_device_class) {
					.device = ~0,
					.disable = 0,
					.debug0 = 0,
				 }, sizeof(struct nv_device_class),
				 &drm->device);
	if (ret)
		goto fail_device;

296 297 298 299
	/* workaround an odd issue on nvc1 by disabling the device's
	 * nosnoop capability.  hopefully won't cause issues until a
	 * better fix is found - assuming there is one...
	 */
300
	device = nv_device(drm->device);
301 302
	if (nv_device(drm->device)->chipset == 0xc1)
		nv_mask(device, 0x00088080, 0x00000800, 0x00000000);
303

304
	nouveau_vga_init(drm);
305 306
	nouveau_agp_init(drm);

307 308 309 310 311 312 313 314
	if (device->card_type >= NV_50) {
		ret = nouveau_vm_new(nv_device(drm->device), 0, (1ULL << 40),
				     0x1000, &drm->client.base.vm);
		if (ret)
			goto fail_device;
	}

	ret = nouveau_ttm_init(drm);
315
	if (ret)
316 317 318 319 320 321 322 323 324
		goto fail_ttm;

	ret = nouveau_bios_init(dev);
	if (ret)
		goto fail_bios;

	ret = nouveau_irq_init(dev);
	if (ret)
		goto fail_irq;
325

326
	ret = nouveau_display_create(dev);
327
	if (ret)
328 329 330 331 332 333 334 335 336
		goto fail_dispctor;

	if (dev->mode_config.num_crtc) {
		ret = nouveau_display_init(dev);
		if (ret)
			goto fail_dispinit;
	}

	nouveau_pm_init(dev);
337 338 339

	nouveau_accel_init(drm);
	nouveau_fbcon_init(dev);
340 341
	return 0;

342 343 344 345 346 347 348
fail_dispinit:
	nouveau_display_destroy(dev);
fail_dispctor:
	nouveau_irq_fini(dev);
fail_irq:
	nouveau_bios_takedown(dev);
fail_bios:
349
	nouveau_ttm_fini(drm);
350 351 352
fail_ttm:
	nouveau_agp_fini(drm);
	nouveau_vga_fini(drm);
353 354 355 356 357
fail_device:
	nouveau_cli_destroy(&drm->client);
	return ret;
}

358
static int
359 360
nouveau_drm_unload(struct drm_device *dev)
{
361
	struct nouveau_drm *drm = nouveau_drm(dev);
362

363 364 365
	nouveau_fbcon_fini(dev);
	nouveau_accel_fini(drm);

366 367
	nouveau_pm_fini(dev);

368 369
	if (dev->mode_config.num_crtc)
		nouveau_display_fini(dev);
370 371 372 373
	nouveau_display_destroy(dev);

	nouveau_irq_fini(dev);
	nouveau_bios_takedown(dev);
374

375
	nouveau_ttm_fini(drm);
376
	nouveau_agp_fini(drm);
377
	nouveau_vga_fini(drm);
378

379 380 381 382 383 384 385
	nouveau_cli_destroy(&drm->client);
	return 0;
}

static void
nouveau_drm_remove(struct pci_dev *pdev)
{
386 387
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct nouveau_drm *drm = nouveau_drm(dev);
388
	struct nouveau_object *device;
389 390 391 392

	device = drm->client.base.device;
	drm_put_dev(dev);

393 394
	nouveau_object_ref(NULL, &device);
	nouveau_object_debug();
395 396 397
}

int
D
Dave Airlie 已提交
398
nouveau_do_suspend(struct drm_device *dev)
399
{
400
	struct nouveau_drm *drm = nouveau_drm(dev);
401 402 403
	struct nouveau_cli *cli;
	int ret;

404 405 406
	if (dev->mode_config.num_crtc) {
		NV_INFO(drm, "suspending fbcon...\n");
		nouveau_fbcon_set_suspend(dev, 1);
407

408 409 410 411 412
		NV_INFO(drm, "suspending display...\n");
		ret = nouveau_display_suspend(dev);
		if (ret)
			return ret;
	}
413

414 415 416 417 418 419 420 421 422
	NV_INFO(drm, "evicting buffers...\n");
	ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);

	if (drm->fence && nouveau_fence(drm)->suspend) {
		if (!nouveau_fence(drm)->suspend(drm))
			return -ENOMEM;
	}

	NV_INFO(drm, "suspending client object trees...\n");
423 424 425 426 427 428 429 430 431 432
	list_for_each_entry(cli, &drm->clients, head) {
		ret = nouveau_client_fini(&cli->base, true);
		if (ret)
			goto fail_client;
	}

	ret = nouveau_client_fini(&drm->client.base, true);
	if (ret)
		goto fail_client;

433
	nouveau_agp_fini(drm);
434 435 436 437 438 439 440
	return 0;

fail_client:
	list_for_each_entry_continue_reverse(cli, &drm->clients, head) {
		nouveau_client_init(&cli->base);
	}

441 442 443 444
	if (dev->mode_config.num_crtc) {
		NV_INFO(drm, "resuming display...\n");
		nouveau_display_resume(dev);
	}
445 446 447
	return ret;
}

D
Dave Airlie 已提交
448
int nouveau_pmops_suspend(struct device *dev)
449
{
D
Dave Airlie 已提交
450 451
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
452 453
	int ret;

D
Dave Airlie 已提交
454
	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
455 456
		return 0;

D
Dave Airlie 已提交
457
	ret = nouveau_do_suspend(drm_dev);
458 459
	if (ret)
		return ret;
D
Dave Airlie 已提交
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474

	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, PCI_D3hot);

	return 0;
}

int
nouveau_do_resume(struct drm_device *dev)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_cli *cli;

	NV_INFO(drm, "re-enabling device...\n");
475

476 477
	nouveau_agp_reset(drm);

478
	NV_INFO(drm, "resuming client object trees...\n");
479
	nouveau_client_init(&drm->client.base);
480
	nouveau_agp_init(drm);
481 482 483 484

	list_for_each_entry(cli, &drm->clients, head) {
		nouveau_client_init(&cli->base);
	}
485

486 487
	if (drm->fence && nouveau_fence(drm)->resume)
		nouveau_fence(drm)->resume(drm);
488

489 490 491 492
	nouveau_run_vbios_init(dev);
	nouveau_irq_postinstall(dev);
	nouveau_pm_resume(dev);

493 494 495 496
	if (dev->mode_config.num_crtc) {
		NV_INFO(drm, "resuming display...\n");
		nouveau_display_resume(dev);
	}
497
	return 0;
498 499
}

D
Dave Airlie 已提交
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
int nouveau_pmops_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
	int ret;

	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
		return 0;

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);
	ret = pci_enable_device(pdev);
	if (ret)
		return ret;
	pci_set_master(pdev);

	return nouveau_do_resume(drm_dev);
}

static int nouveau_pmops_freeze(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);

	return nouveau_do_suspend(drm_dev);
}

static int nouveau_pmops_thaw(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);

	return nouveau_do_resume(drm_dev);
}


536
static int
537 538 539 540 541
nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
{
	struct pci_dev *pdev = dev->pdev;
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_cli *cli;
542
	char name[16];
543 544
	int ret;

545
	snprintf(name, sizeof(name), "%d", pid_nr(fpriv->pid));
546 547

	ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli);
548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
	if (ret)
		return ret;

	if (nv_device(drm->device)->card_type >= NV_50) {
		ret = nouveau_vm_new(nv_device(drm->device), 0, (1ULL << 40),
				     0x1000, &cli->base.vm);
		if (ret) {
			nouveau_cli_destroy(cli);
			return ret;
		}
	}

	fpriv->driver_priv = cli;

	mutex_lock(&drm->client.mutex);
	list_add(&cli->head, &drm->clients);
	mutex_unlock(&drm->client.mutex);
	return 0;
}

568
static void
569 570 571 572 573 574 575 576 577 578 579 580 581
nouveau_drm_preclose(struct drm_device *dev, struct drm_file *fpriv)
{
	struct nouveau_cli *cli = nouveau_cli(fpriv);
	struct nouveau_drm *drm = nouveau_drm(dev);

	if (cli->abi16)
		nouveau_abi16_fini(cli->abi16);

	mutex_lock(&drm->client.mutex);
	list_del(&cli->head);
	mutex_unlock(&drm->client.mutex);
}

582
static void
583 584 585 586 587 588
nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
{
	struct nouveau_cli *cli = nouveau_cli(fpriv);
	nouveau_cli_destroy(cli);
}

589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
static struct drm_ioctl_desc
nouveau_ioctls[] = {
	DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_abi16_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_abi16_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
	DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_abi16_ioctl_channel_alloc, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_abi16_ioctl_channel_free, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_abi16_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
	DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH),
};

static const struct file_operations
nouveau_driver_fops = {
	.owner = THIS_MODULE,
	.open = drm_open,
	.release = drm_release,
	.unlocked_ioctl = drm_ioctl,
	.mmap = nouveau_ttm_mmap,
	.poll = drm_poll,
	.fasync = drm_fasync,
	.read = drm_read,
#if defined(CONFIG_COMPAT)
	.compat_ioctl = nouveau_compat_ioctl,
#endif
	.llseek = noop_llseek,
};

static struct drm_driver
driver = {
	.driver_features =
		DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
		DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
		DRIVER_MODESET | DRIVER_PRIME,

	.load = nouveau_drm_load,
	.unload = nouveau_drm_unload,
	.open = nouveau_drm_open,
	.preclose = nouveau_drm_preclose,
	.postclose = nouveau_drm_postclose,
	.lastclose = nouveau_vga_lastclose,

	.irq_preinstall = nouveau_irq_preinstall,
	.irq_postinstall = nouveau_irq_postinstall,
	.irq_uninstall = nouveau_irq_uninstall,
	.irq_handler = nouveau_irq_handler,

	.get_vblank_counter = drm_vblank_count,
	.enable_vblank = nouveau_vblank_enable,
	.disable_vblank = nouveau_vblank_disable,

	.ioctls = nouveau_ioctls,
	.fops = &nouveau_driver_fops,

	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
	.gem_prime_export = nouveau_gem_prime_export,
	.gem_prime_import = nouveau_gem_prime_import,

	.gem_init_object = nouveau_gem_object_new,
	.gem_free_object = nouveau_gem_object_del,
	.gem_open_object = nouveau_gem_object_open,
	.gem_close_object = nouveau_gem_object_close,

	.dumb_create = nouveau_display_dumb_create,
	.dumb_map_offset = nouveau_display_dumb_map_offset,
	.dumb_destroy = nouveau_display_dumb_destroy,

	.name = DRIVER_NAME,
	.desc = DRIVER_DESC,
#ifdef GIT_REVISION
	.date = GIT_REVISION,
#else
	.date = DRIVER_DATE,
#endif
	.major = DRIVER_MAJOR,
	.minor = DRIVER_MINOR,
	.patchlevel = DRIVER_PATCHLEVEL,
};

673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
static struct pci_device_id
nouveau_drm_pci_table[] = {
	{
		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
		.class = PCI_BASE_CLASS_DISPLAY << 16,
		.class_mask  = 0xff << 16,
	},
	{
		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID),
		.class = PCI_BASE_CLASS_DISPLAY << 16,
		.class_mask  = 0xff << 16,
	},
	{}
};

D
Dave Airlie 已提交
688 689 690 691 692 693 694 695 696
static const struct dev_pm_ops nouveau_pm_ops = {
	.suspend = nouveau_pmops_suspend,
	.resume = nouveau_pmops_resume,
	.freeze = nouveau_pmops_freeze,
	.thaw = nouveau_pmops_thaw,
	.poweroff = nouveau_pmops_freeze,
	.restore = nouveau_pmops_resume,
};

697 698 699 700 701 702
static struct pci_driver
nouveau_drm_pci_driver = {
	.name = "nouveau",
	.id_table = nouveau_drm_pci_table,
	.probe = nouveau_drm_probe,
	.remove = nouveau_drm_remove,
D
Dave Airlie 已提交
703
	.driver.pm = &nouveau_pm_ops,
704 705 706 707 708
};

static int __init
nouveau_drm_init(void)
{
709 710 711 712 713 714 715 716 717 718 719 720 721 722
	driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls);

	if (nouveau_modeset == -1) {
#ifdef CONFIG_VGA_CONSOLE
		if (vgacon_text_force())
			nouveau_modeset = 0;
#endif
	}

	if (!nouveau_modeset)
		return 0;

	nouveau_register_dsm_handler();
	return drm_pci_init(&driver, &nouveau_drm_pci_driver);
723 724 725 726 727
}

static void __exit
nouveau_drm_exit(void)
{
728 729 730 731 732
	if (!nouveau_modeset)
		return;

	drm_pci_exit(&driver, &nouveau_drm_pci_driver);
	nouveau_unregister_dsm_handler();
733 734 735 736 737 738
}

module_init(nouveau_drm_init);
module_exit(nouveau_drm_exit);

MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table);
739 740
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
741
MODULE_LICENSE("GPL and additional rights");