nouveau_drm.c 25.8 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
#include <linux/module.h>
#include <linux/pci.h>
28 29 30 31
#include <linux/pm_runtime.h>
#include <linux/vga_switcheroo.h>
#include "drmP.h"
#include "drm_crtc_helper.h"
32 33
#include <core/device.h>
#include <core/client.h>
34
#include <core/gpuobj.h>
35 36
#include <core/class.h>

37
#include <engine/device.h>
38
#include <engine/disp.h>
39
#include <engine/fifo.h>
40

41 42
#include <subdev/vm.h>

43
#include "nouveau_drm.h"
44
#include "nouveau_dma.h"
45 46
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
47
#include "nouveau_agp.h"
48 49 50 51 52
#include "nouveau_vga.h"
#include "nouveau_pm.h"
#include "nouveau_acpi.h"
#include "nouveau_bios.h"
#include "nouveau_ioctl.h"
53 54 55
#include "nouveau_abi16.h"
#include "nouveau_fbcon.h"
#include "nouveau_fence.h"
56
#include "nouveau_debugfs.h"
57

58 59 60 61 62 63 64 65
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);

66 67 68 69
MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration");
static int nouveau_noaccel = 0;
module_param_named(noaccel, nouveau_noaccel, int, 0400);

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

75 76 77 78
MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)");
int nouveau_runtime_pm = -1;
module_param_named(runpm, nouveau_runtime_pm, int, 0400);

79 80
static struct drm_driver driver;

81 82 83 84 85 86 87 88 89
static int
nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
{
	struct nouveau_drm *drm =
		container_of(event, struct nouveau_drm, vblank[head]);
	drm_handle_vblank(drm->dev, head);
	return NVKM_EVENT_KEEP;
}

90 91 92 93 94
static int
nouveau_drm_vblank_enable(struct drm_device *dev, int head)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_disp *pdisp = nouveau_disp(drm->device);
95 96 97 98 99 100

	if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank)))
		return -EIO;
	WARN_ON_ONCE(drm->vblank[head].func);
	drm->vblank[head].func = nouveau_drm_vblank_handler;
	nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]);
101 102 103 104 105 106 107 108
	return 0;
}

static void
nouveau_drm_vblank_disable(struct drm_device *dev, int head)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_disp *pdisp = nouveau_disp(drm->device);
109 110 111 112 113
	if (drm->vblank[head].func)
		nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]);
	else
		WARN_ON_ONCE(1);
	drm->vblank[head].func = NULL;
114 115
}

116 117 118 119 120 121 122 123 124 125
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
126 127
nouveau_cli_create(struct pci_dev *pdev, const char *name,
		   int size, void **pcli)
128 129 130 131
{
	struct nouveau_cli *cli;
	int ret;

132
	*pcli = NULL;
133 134 135
	ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
				     nouveau_debug, size, pcli);
	cli = *pcli;
136 137 138 139
	if (ret) {
		if (cli)
			nouveau_client_destroy(&cli->base);
		*pcli = NULL;
140
		return ret;
141
	}
142 143 144 145 146 147 148 149 150

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

static void
nouveau_cli_destroy(struct nouveau_cli *cli)
{
	struct nouveau_object *client = nv_object(cli);
151
	nouveau_vm_ref(NULL, &cli->base.vm, NULL);
152 153 154 155 156
	nouveau_client_fini(&cli->base, false);
	atomic_set(&client->refcount, 1);
	nouveau_object_ref(NULL, &client);
}

157 158 159 160 161
static void
nouveau_accel_fini(struct nouveau_drm *drm)
{
	nouveau_gpuobj_ref(NULL, &drm->notify);
	nouveau_channel_del(&drm->channel);
162
	nouveau_channel_del(&drm->cechan);
163 164 165 166 167 168 169 170 171
	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;
172
	u32 arg0, arg1;
173 174
	int ret;

175
	if (nouveau_noaccel || !nouveau_fifo(device) /*XXX*/)
176 177 178 179
		return;

	/* initialise synchronisation routines */
	if      (device->card_type < NV_10) ret = nv04_fence_create(drm);
180 181
	else if (device->chipset   <  0x17) ret = nv10_fence_create(drm);
	else if (device->card_type < NV_50) ret = nv17_fence_create(drm);
182
	else if (device->chipset   <  0x84) ret = nv50_fence_create(drm);
183 184 185 186 187 188 189 190
	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;
	}

191 192 193 194 195 196 197 198 199 200
	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;
201
		arg1 = 1;
202 203 204 205 206 207 208 209 210 211 212 213
	} else
	if (device->chipset >= 0xa3 &&
	    device->chipset != 0xaa &&
	    device->chipset != 0xac) {
		ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
					  NVDRM_CHAN + 1, NvDmaFB, NvDmaTT,
					  &drm->cechan);
		if (ret)
			NV_ERROR(drm, "failed to create ce channel, %d\n", ret);

		arg0 = NvDmaFB;
		arg1 = NvDmaTT;
214 215 216 217 218
	} else {
		arg0 = NvDmaFB;
		arg1 = NvDmaTT;
	}

219
	ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, NVDRM_CHAN,
220
				  arg0, arg1, &drm->channel);
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
	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;
		}
	}


252
	nouveau_bo_move_init(drm);
253 254
}

255 256
static int nouveau_drm_probe(struct pci_dev *pdev,
			     const struct pci_device_id *pent)
257 258
{
	struct nouveau_device *device;
259 260
	struct apertures_struct *aper;
	bool boot = false;
261 262
	int ret;

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
	/* 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);
288
	kfree(aper);
289

290 291 292 293 294 295 296
	ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev),
				    nouveau_config, nouveau_debug, &device);
	if (ret)
		return ret;

	pci_set_master(pdev);

297
	ret = drm_get_pci_dev(pdev, pent, &driver);
298
	if (ret) {
299
		nouveau_object_ref(NULL, (struct nouveau_object **)&device);
300 301 302 303 304 305
		return ret;
	}

	return 0;
}

306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403

static void
nouveau_get_hdmi_dev(struct drm_device *dev)
{
	struct nouveau_drm *drm = dev->dev_private;
	struct pci_dev *pdev = dev->pdev;

	/* subfunction one is a hdmi audio device? */
	drm->hdmi_device = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
						PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));

	if (!drm->hdmi_device) {
		DRM_INFO("hdmi device  not found %d %d %d\n", pdev->bus->number, PCI_SLOT(pdev->devfn), 1);
		return;
	}

	if ((drm->hdmi_device->class >> 8) != PCI_CLASS_MULTIMEDIA_HD_AUDIO) {
		DRM_INFO("possible hdmi device  not audio %d\n", drm->hdmi_device->class);
		pci_dev_put(drm->hdmi_device);
		drm->hdmi_device = NULL;
		return;
	}
}

331
static int
332 333 334
nouveau_drm_load(struct drm_device *dev, unsigned long flags)
{
	struct pci_dev *pdev = dev->pdev;
335
	struct nouveau_device *device;
336 337 338
	struct nouveau_drm *drm;
	int ret;

339
	ret = nouveau_cli_create(pdev, "DRM", sizeof(*drm), (void**)&drm);
340 341 342
	if (ret)
		return ret;

343 344 345
	dev->dev_private = drm;
	drm->dev = dev;

346
	INIT_LIST_HEAD(&drm->clients);
347
	spin_lock_init(&drm->tile.lock);
348

349 350
	nouveau_get_hdmi_dev(dev);

351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
	/* 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)
369
			goto fail_device;
370 371 372 373 374

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

375 376 377 378 379 380 381 382 383 384
	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;

385 386 387 388
	/* 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...
	 */
389
	device = nv_device(drm->device);
390 391
	if (nv_device(drm->device)->chipset == 0xc1)
		nv_mask(device, 0x00088080, 0x00000800, 0x00000000);
392

393
	nouveau_vga_init(drm);
394 395
	nouveau_agp_init(drm);

396 397 398 399 400 401 402 403
	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);
404
	if (ret)
405 406 407 408 409 410 411
		goto fail_ttm;

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

	ret = nouveau_display_create(dev);
412
	if (ret)
413 414 415 416 417 418 419 420 421
		goto fail_dispctor;

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

	nouveau_pm_init(dev);
422 423 424

	nouveau_accel_init(drm);
	nouveau_fbcon_init(dev);
425 426 427 428 429 430 431 432 433

	if (nouveau_runtime_pm != 0) {
		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(dev->dev);
	}
434 435
	return 0;

436 437 438 439 440
fail_dispinit:
	nouveau_display_destroy(dev);
fail_dispctor:
	nouveau_bios_takedown(dev);
fail_bios:
441
	nouveau_ttm_fini(drm);
442 443 444
fail_ttm:
	nouveau_agp_fini(drm);
	nouveau_vga_fini(drm);
445 446 447 448 449
fail_device:
	nouveau_cli_destroy(&drm->client);
	return ret;
}

450
static int
451 452
nouveau_drm_unload(struct drm_device *dev)
{
453
	struct nouveau_drm *drm = nouveau_drm(dev);
454

455
	pm_runtime_get_sync(dev->dev);
456 457 458
	nouveau_fbcon_fini(dev);
	nouveau_accel_fini(drm);

459 460
	nouveau_pm_fini(dev);

461 462
	if (dev->mode_config.num_crtc)
		nouveau_display_fini(dev);
463 464 465
	nouveau_display_destroy(dev);

	nouveau_bios_takedown(dev);
466

467
	nouveau_ttm_fini(drm);
468
	nouveau_agp_fini(drm);
469
	nouveau_vga_fini(drm);
470

471 472
	if (drm->hdmi_device)
		pci_dev_put(drm->hdmi_device);
473 474 475 476 477 478 479
	nouveau_cli_destroy(&drm->client);
	return 0;
}

static void
nouveau_drm_remove(struct pci_dev *pdev)
{
480 481
	struct drm_device *dev = pci_get_drvdata(pdev);
	struct nouveau_drm *drm = nouveau_drm(dev);
482
	struct nouveau_object *device;
483 484 485 486

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

487 488
	nouveau_object_ref(NULL, &device);
	nouveau_object_debug();
489 490
}

491
static int
D
Dave Airlie 已提交
492
nouveau_do_suspend(struct drm_device *dev)
493
{
494
	struct nouveau_drm *drm = nouveau_drm(dev);
495 496 497
	struct nouveau_cli *cli;
	int ret;

498
	if (dev->mode_config.num_crtc) {
499
		NV_SUSPEND(drm, "suspending display...\n");
500 501 502 503
		ret = nouveau_display_suspend(dev);
		if (ret)
			return ret;
	}
504

505
	NV_SUSPEND(drm, "evicting buffers...\n");
506 507
	ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);

508
	NV_SUSPEND(drm, "waiting for kernel channels to go idle...\n");
509 510 511 512 513 514 515 516 517 518 519 520
	if (drm->cechan) {
		ret = nouveau_channel_idle(drm->cechan);
		if (ret)
			return ret;
	}

	if (drm->channel) {
		ret = nouveau_channel_idle(drm->channel);
		if (ret)
			return ret;
	}

521
	NV_SUSPEND(drm, "suspending client object trees...\n");
522 523 524 525 526
	if (drm->fence && nouveau_fence(drm)->suspend) {
		if (!nouveau_fence(drm)->suspend(drm))
			return -ENOMEM;
	}

527 528 529 530 531 532
	list_for_each_entry(cli, &drm->clients, head) {
		ret = nouveau_client_fini(&cli->base, true);
		if (ret)
			goto fail_client;
	}

533
	NV_SUSPEND(drm, "suspending kernel object tree...\n");
534 535 536 537
	ret = nouveau_client_fini(&drm->client.base, true);
	if (ret)
		goto fail_client;

538
	nouveau_agp_fini(drm);
539 540 541 542 543 544 545
	return 0;

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

546
	if (dev->mode_config.num_crtc) {
547
		NV_SUSPEND(drm, "resuming display...\n");
548 549
		nouveau_display_resume(dev);
	}
550 551 552
	return ret;
}

D
Dave Airlie 已提交
553
int nouveau_pmops_suspend(struct device *dev)
554
{
D
Dave Airlie 已提交
555 556
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
557 558
	int ret;

559 560
	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
	    drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
561 562
		return 0;

563 564 565 566
	if (drm_dev->mode_config.num_crtc)
		nouveau_fbcon_set_suspend(drm_dev, 1);

	nv_suspend_set_printk_level(NV_DBG_INFO);
D
Dave Airlie 已提交
567
	ret = nouveau_do_suspend(drm_dev);
568 569
	if (ret)
		return ret;
D
Dave Airlie 已提交
570 571 572 573

	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, PCI_D3hot);
574
	nv_suspend_set_printk_level(NV_DBG_DEBUG);
D
Dave Airlie 已提交
575 576 577 578

	return 0;
}

579
static int
D
Dave Airlie 已提交
580 581 582 583 584
nouveau_do_resume(struct drm_device *dev)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_cli *cli;

585
	NV_SUSPEND(drm, "re-enabling device...\n");
586

587 588
	nouveau_agp_reset(drm);

589
	NV_SUSPEND(drm, "resuming kernel object tree...\n");
590
	nouveau_client_init(&drm->client.base);
591
	nouveau_agp_init(drm);
592

593
	NV_SUSPEND(drm, "resuming client object trees...\n");
594 595 596
	if (drm->fence && nouveau_fence(drm)->resume)
		nouveau_fence(drm)->resume(drm);

597 598 599
	list_for_each_entry(cli, &drm->clients, head) {
		nouveau_client_init(&cli->base);
	}
600

601 602 603
	nouveau_run_vbios_init(dev);
	nouveau_pm_resume(dev);

604
	if (dev->mode_config.num_crtc) {
605 606
		NV_SUSPEND(drm, "resuming display...\n");
		nouveau_display_repin(dev);
607
	}
608

609
	return 0;
610 611
}

D
Dave Airlie 已提交
612 613 614 615 616 617
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;

618 619
	if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF ||
	    drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF)
D
Dave Airlie 已提交
620 621 622 623 624 625 626 627 628
		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);

629 630 631 632 633 634 635 636 637 638 639 640 641
	nv_suspend_set_printk_level(NV_DBG_INFO);
	ret = nouveau_do_resume(drm_dev);
	if (ret) {
		nv_suspend_set_printk_level(NV_DBG_DEBUG);
		return ret;
	}
	if (drm_dev->mode_config.num_crtc)
		nouveau_fbcon_set_suspend(drm_dev, 0);

	nouveau_fbcon_zfill_all(drm_dev);
	nouveau_display_resume(drm_dev);
	nv_suspend_set_printk_level(NV_DBG_DEBUG);
	return 0;
D
Dave Airlie 已提交
642 643 644 645 646 647
}

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);
648 649 650 651 652
	int ret;

	nv_suspend_set_printk_level(NV_DBG_INFO);
	if (drm_dev->mode_config.num_crtc)
		nouveau_fbcon_set_suspend(drm_dev, 1);
D
Dave Airlie 已提交
653

654 655 656
	ret = nouveau_do_suspend(drm_dev);
	nv_suspend_set_printk_level(NV_DBG_DEBUG);
	return ret;
D
Dave Airlie 已提交
657 658 659 660 661 662
}

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);
663
	int ret;
D
Dave Airlie 已提交
664

665 666 667 668 669 670 671 672 673 674 675 676
	nv_suspend_set_printk_level(NV_DBG_INFO);
	ret = nouveau_do_resume(drm_dev);
	if (ret) {
		nv_suspend_set_printk_level(NV_DBG_DEBUG);
		return ret;
	}
	if (drm_dev->mode_config.num_crtc)
		nouveau_fbcon_set_suspend(drm_dev, 0);
	nouveau_fbcon_zfill_all(drm_dev);
	nouveau_display_resume(drm_dev);
	nv_suspend_set_printk_level(NV_DBG_DEBUG);
	return 0;
D
Dave Airlie 已提交
677 678 679
}


680
static int
681 682 683 684 685
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;
686
	char name[32], tmpname[TASK_COMM_LEN];
687 688
	int ret;

689 690 691 692 693
	/* need to bring up power immediately if opening device */
	ret = pm_runtime_get_sync(dev->dev);
	if (ret < 0)
		return ret;

694 695
	get_task_comm(tmpname, current);
	snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid));
696 697

	ret = nouveau_cli_create(pdev, name, sizeof(*cli), (void **)&cli);
698
	if (ret)
699
		goto out_suspend;
700 701 702 703 704 705

	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);
706
			goto out_suspend;
707 708 709 710 711 712 713 714
		}
	}

	fpriv->driver_priv = cli;

	mutex_lock(&drm->client.mutex);
	list_add(&cli->head, &drm->clients);
	mutex_unlock(&drm->client.mutex);
715 716 717 718 719 720

out_suspend:
	pm_runtime_mark_last_busy(dev->dev);
	pm_runtime_put_autosuspend(dev->dev);

	return ret;
721 722
}

723
static void
724 725 726 727 728
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);

729 730
	pm_runtime_get_sync(dev->dev);

731 732 733 734 735 736
	if (cli->abi16)
		nouveau_abi16_fini(cli->abi16);

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

738 739
}

740
static void
741 742 743 744
nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
{
	struct nouveau_cli *cli = nouveau_cli(fpriv);
	nouveau_cli_destroy(cli);
745 746
	pm_runtime_mark_last_busy(dev->dev);
	pm_runtime_put_autosuspend(dev->dev);
747 748
}

R
Rob Clark 已提交
749
static const struct drm_ioctl_desc
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
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),
};

765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
long nouveau_drm_ioctl(struct file *filp,
		       unsigned int cmd, unsigned long arg)
{
	struct drm_file *file_priv = filp->private_data;
	struct drm_device *dev;
	long ret;
	dev = file_priv->minor->dev;

	ret = pm_runtime_get_sync(dev->dev);
	if (ret < 0)
		return ret;

	ret = drm_ioctl(filp, cmd, arg);

	pm_runtime_mark_last_busy(dev->dev);
	pm_runtime_put_autosuspend(dev->dev);
	return ret;
}
783 784 785 786 787
static const struct file_operations
nouveau_driver_fops = {
	.owner = THIS_MODULE,
	.open = drm_open,
	.release = drm_release,
788
	.unlocked_ioctl = nouveau_drm_ioctl,
789 790 791 792 793 794 795 796 797 798 799 800
	.mmap = nouveau_ttm_mmap,
	.poll = drm_poll,
	.read = drm_read,
#if defined(CONFIG_COMPAT)
	.compat_ioctl = nouveau_compat_ioctl,
#endif
	.llseek = noop_llseek,
};

static struct drm_driver
driver = {
	.driver_features =
801
		DRIVER_USE_AGP |
802
		DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME,
803 804 805 806 807 808 809 810

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

811 812 813 814 815
#if defined(CONFIG_DEBUG_FS)
	.debugfs_init = nouveau_debugfs_init,
	.debugfs_cleanup = nouveau_debugfs_takedown,
#endif

816
	.get_vblank_counter = drm_vblank_count,
817 818
	.enable_vblank = nouveau_drm_vblank_enable,
	.disable_vblank = nouveau_drm_vblank_disable,
819 820

	.ioctls = nouveau_ioctls,
R
Rob Clark 已提交
821
	.num_ioctls = ARRAY_SIZE(nouveau_ioctls),
822 823 824 825
	.fops = &nouveau_driver_fops,

	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
A
Aaron Plattner 已提交
826 827 828
	.gem_prime_export = drm_gem_prime_export,
	.gem_prime_import = drm_gem_prime_import,
	.gem_prime_pin = nouveau_gem_prime_pin,
829
	.gem_prime_unpin = nouveau_gem_prime_unpin,
A
Aaron Plattner 已提交
830 831 832 833
	.gem_prime_get_sg_table = nouveau_gem_prime_get_sg_table,
	.gem_prime_import_sg_table = nouveau_gem_prime_import_sg_table,
	.gem_prime_vmap = nouveau_gem_prime_vmap,
	.gem_prime_vunmap = nouveau_gem_prime_vunmap,
834 835 836 837 838 839 840 841

	.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,
842
	.dumb_destroy = drm_gem_dumb_destroy,
843 844 845 846 847 848 849 850 851 852 853 854 855

	.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,
};

856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
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,
	},
	{}
};

871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954
static int nouveau_pmops_runtime_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
	int ret;

	if (nouveau_runtime_pm == 0)
		return -EINVAL;

	drm_kms_helper_poll_disable(drm_dev);
	vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF);
	nouveau_switcheroo_optimus_dsm();
	ret = nouveau_do_suspend(drm_dev);
	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, PCI_D3cold);
	drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF;
	return ret;
}

static int nouveau_pmops_runtime_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
	struct nouveau_device *device = nouveau_dev(drm_dev);
	int ret;

	if (nouveau_runtime_pm == 0)
		return -EINVAL;

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

	ret = nouveau_do_resume(drm_dev);
	nouveau_display_resume(drm_dev);
	drm_kms_helper_poll_enable(drm_dev);
	/* do magic */
	nv_mask(device, 0x88488, (1 << 25), (1 << 25));
	vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
	drm_dev->switch_power_state = DRM_SWITCH_POWER_ON;
	return ret;
}

static int nouveau_pmops_runtime_idle(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
	struct nouveau_drm *drm = nouveau_drm(drm_dev);
	struct drm_crtc *crtc;

	if (nouveau_runtime_pm == 0)
		return -EBUSY;

	/* are we optimus enabled? */
	if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
		DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
		return -EBUSY;
	}

	/* if we have a hdmi audio device - make sure it has a driver loaded */
	if (drm->hdmi_device) {
		if (!drm->hdmi_device->driver) {
			DRM_DEBUG_DRIVER("failing to power off - no HDMI audio driver loaded\n");
			pm_runtime_mark_last_busy(dev);
			return -EBUSY;
		}
	}

	list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) {
		if (crtc->enabled) {
			DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
			return -EBUSY;
		}
	}
	pm_runtime_mark_last_busy(dev);
	pm_runtime_autosuspend(dev);
	/* we don't want the main rpm_idle to call suspend - we want to autosuspend */
	return 1;
}

D
Dave Airlie 已提交
955 956 957 958 959 960 961
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,
962 963 964
	.runtime_suspend = nouveau_pmops_runtime_suspend,
	.runtime_resume = nouveau_pmops_runtime_resume,
	.runtime_idle = nouveau_pmops_runtime_idle,
D
Dave Airlie 已提交
965 966
};

967 968 969 970 971 972
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 已提交
973
	.driver.pm = &nouveau_pm_ops,
974 975 976 977 978
};

static int __init
nouveau_drm_init(void)
{
979 980 981 982 983 984 985 986 987 988 989 990
	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);
991 992 993 994 995
}

static void __exit
nouveau_drm_exit(void)
{
996 997 998 999 1000
	if (!nouveau_modeset)
		return;

	drm_pci_exit(&driver, &nouveau_drm_pci_driver);
	nouveau_unregister_dsm_handler();
1001 1002 1003 1004 1005 1006
}

module_init(nouveau_drm_init);
module_exit(nouveau_drm_exit);

MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table);
1007 1008
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
1009
MODULE_LICENSE("GPL and additional rights");