aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_drm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_drm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c179
1 files changed, 94 insertions, 85 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 279497b15e7b..d234a3b70bad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -37,6 +37,8 @@
37#include <core/pci.h> 37#include <core/pci.h>
38#include <core/tegra.h> 38#include <core/tegra.h>
39 39
40#include <nvif/driver.h>
41
40#include <nvif/class.h> 42#include <nvif/class.h>
41#include <nvif/cl0002.h> 43#include <nvif/cl0002.h>
42#include <nvif/cla06f.h> 44#include <nvif/cla06f.h>
@@ -109,35 +111,53 @@ nouveau_name(struct drm_device *dev)
109 return nouveau_platform_name(dev->platformdev); 111 return nouveau_platform_name(dev->platformdev);
110} 112}
111 113
114static void
115nouveau_cli_fini(struct nouveau_cli *cli)
116{
117 nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL);
118 usif_client_fini(cli);
119 nvif_device_fini(&cli->device);
120 nvif_client_fini(&cli->base);
121}
122
112static int 123static int
113nouveau_cli_create(struct drm_device *dev, const char *sname, 124nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
114 int size, void **pcli) 125 struct nouveau_cli *cli)
115{ 126{
116 struct nouveau_cli *cli = *pcli = kzalloc(size, GFP_KERNEL); 127 u64 device = nouveau_name(drm->dev);
117 int ret; 128 int ret;
118 if (cli) {
119 snprintf(cli->name, sizeof(cli->name), "%s", sname);
120 cli->dev = dev;
121 129
122 ret = nvif_client_init(NULL, cli->name, nouveau_name(dev), 130 snprintf(cli->name, sizeof(cli->name), "%s", sname);
123 nouveau_config, nouveau_debug, 131 cli->dev = drm->dev;
132 mutex_init(&cli->mutex);
133 usif_client_init(cli);
134
135 if (cli == &drm->client) {
136 ret = nvif_driver_init(NULL, nouveau_config, nouveau_debug,
137 cli->name, device, &cli->base);
138 } else {
139 ret = nvif_client_init(&drm->client.base, cli->name, device,
124 &cli->base); 140 &cli->base);
125 if (ret == 0) {
126 mutex_init(&cli->mutex);
127 usif_client_init(cli);
128 }
129 return ret;
130 } 141 }
131 return -ENOMEM; 142 if (ret) {
132} 143 NV_ERROR(drm, "Client allocation failed: %d\n", ret);
144 goto done;
145 }
133 146
134static void 147 ret = nvif_device_init(&cli->base.object, 0, NV_DEVICE,
135nouveau_cli_destroy(struct nouveau_cli *cli) 148 &(struct nv_device_v0) {
136{ 149 .device = ~0,
137 nvkm_vm_ref(NULL, &nvxx_client(&cli->base)->vm, NULL); 150 }, sizeof(struct nv_device_v0),
138 nvif_client_fini(&cli->base); 151 &cli->device);
139 usif_client_fini(cli); 152 if (ret) {
140 kfree(cli); 153 NV_ERROR(drm, "Device allocation failed: %d\n", ret);
154 goto done;
155 }
156
157done:
158 if (ret)
159 nouveau_cli_fini(cli);
160 return ret;
141} 161}
142 162
143static void 163static void
@@ -161,7 +181,7 @@ nouveau_accel_fini(struct nouveau_drm *drm)
161static void 181static void
162nouveau_accel_init(struct nouveau_drm *drm) 182nouveau_accel_init(struct nouveau_drm *drm)
163{ 183{
164 struct nvif_device *device = &drm->device; 184 struct nvif_device *device = &drm->client.device;
165 struct nvif_sclass *sclass; 185 struct nvif_sclass *sclass;
166 u32 arg0, arg1; 186 u32 arg0, arg1;
167 int ret, i, n; 187 int ret, i, n;
@@ -215,7 +235,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
215 } 235 }
216 236
217 if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { 237 if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
218 ret = nouveau_channel_new(drm, &drm->device, 238 ret = nouveau_channel_new(drm, &drm->client.device,
219 NVA06F_V0_ENGINE_CE0 | 239 NVA06F_V0_ENGINE_CE0 |
220 NVA06F_V0_ENGINE_CE1, 240 NVA06F_V0_ENGINE_CE1,
221 0, &drm->cechan); 241 0, &drm->cechan);
@@ -228,7 +248,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
228 if (device->info.chipset >= 0xa3 && 248 if (device->info.chipset >= 0xa3 &&
229 device->info.chipset != 0xaa && 249 device->info.chipset != 0xaa &&
230 device->info.chipset != 0xac) { 250 device->info.chipset != 0xac) {
231 ret = nouveau_channel_new(drm, &drm->device, 251 ret = nouveau_channel_new(drm, &drm->client.device,
232 NvDmaFB, NvDmaTT, &drm->cechan); 252 NvDmaFB, NvDmaTT, &drm->cechan);
233 if (ret) 253 if (ret)
234 NV_ERROR(drm, "failed to create ce channel, %d\n", ret); 254 NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
@@ -240,7 +260,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
240 arg1 = NvDmaTT; 260 arg1 = NvDmaTT;
241 } 261 }
242 262
243 ret = nouveau_channel_new(drm, &drm->device, arg0, arg1, &drm->channel); 263 ret = nouveau_channel_new(drm, &drm->client.device,
264 arg0, arg1, &drm->channel);
244 if (ret) { 265 if (ret) {
245 NV_ERROR(drm, "failed to create kernel channel, %d\n", ret); 266 NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
246 nouveau_accel_fini(drm); 267 nouveau_accel_fini(drm);
@@ -280,8 +301,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
280 } 301 }
281 302
282 if (device->info.family < NV_DEVICE_INFO_V0_FERMI) { 303 if (device->info.family < NV_DEVICE_INFO_V0_FERMI) {
283 ret = nvkm_gpuobj_new(nvxx_device(&drm->device), 32, 0, false, 304 ret = nvkm_gpuobj_new(nvxx_device(&drm->client.device), 32, 0,
284 NULL, &drm->notify); 305 false, NULL, &drm->notify);
285 if (ret) { 306 if (ret) {
286 NV_ERROR(drm, "failed to allocate notifier, %d\n", ret); 307 NV_ERROR(drm, "failed to allocate notifier, %d\n", ret);
287 nouveau_accel_fini(drm); 308 nouveau_accel_fini(drm);
@@ -407,12 +428,17 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
407 struct nouveau_drm *drm; 428 struct nouveau_drm *drm;
408 int ret; 429 int ret;
409 430
410 ret = nouveau_cli_create(dev, "DRM", sizeof(*drm), (void **)&drm); 431 if (!(drm = kzalloc(sizeof(*drm), GFP_KERNEL)))
432 return -ENOMEM;
433 dev->dev_private = drm;
434 drm->dev = dev;
435
436 ret = nouveau_cli_init(drm, "DRM", &drm->client);
411 if (ret) 437 if (ret)
412 return ret; 438 return ret;
413 439
414 dev->dev_private = drm; 440 dev->irq_enabled = true;
415 drm->dev = dev; 441
416 nvxx_client(&drm->client.base)->debug = 442 nvxx_client(&drm->client.base)->debug =
417 nvkm_dbgopt(nouveau_debug, "DRM"); 443 nvkm_dbgopt(nouveau_debug, "DRM");
418 444
@@ -421,33 +447,24 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
421 447
422 nouveau_get_hdmi_dev(drm); 448 nouveau_get_hdmi_dev(drm);
423 449
424 ret = nvif_device_init(&drm->client.base.object, 0, NV_DEVICE,
425 &(struct nv_device_v0) {
426 .device = ~0,
427 }, sizeof(struct nv_device_v0),
428 &drm->device);
429 if (ret)
430 goto fail_device;
431
432 dev->irq_enabled = true;
433
434 /* workaround an odd issue on nvc1 by disabling the device's 450 /* workaround an odd issue on nvc1 by disabling the device's
435 * nosnoop capability. hopefully won't cause issues until a 451 * nosnoop capability. hopefully won't cause issues until a
436 * better fix is found - assuming there is one... 452 * better fix is found - assuming there is one...
437 */ 453 */
438 if (drm->device.info.chipset == 0xc1) 454 if (drm->client.device.info.chipset == 0xc1)
439 nvif_mask(&drm->device.object, 0x00088080, 0x00000800, 0x00000000); 455 nvif_mask(&drm->client.device.object, 0x00088080, 0x00000800, 0x00000000);
440 456
441 nouveau_vga_init(drm); 457 nouveau_vga_init(drm);
442 458
443 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 459 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
444 if (!nvxx_device(&drm->device)->mmu) { 460 if (!nvxx_device(&drm->client.device)->mmu) {
445 ret = -ENOSYS; 461 ret = -ENOSYS;
446 goto fail_device; 462 goto fail_device;
447 } 463 }
448 464
449 ret = nvkm_vm_new(nvxx_device(&drm->device), 0, (1ULL << 40), 465 ret = nvkm_vm_new(nvxx_device(&drm->client.device),
450 0x1000, NULL, &drm->client.vm); 466 0, (1ULL << 40), 0x1000, NULL,
467 &drm->client.vm);
451 if (ret) 468 if (ret)
452 goto fail_device; 469 goto fail_device;
453 470
@@ -497,8 +514,8 @@ fail_bios:
497fail_ttm: 514fail_ttm:
498 nouveau_vga_fini(drm); 515 nouveau_vga_fini(drm);
499fail_device: 516fail_device:
500 nvif_device_fini(&drm->device); 517 nouveau_cli_fini(&drm->client);
501 nouveau_cli_destroy(&drm->client); 518 kfree(drm);
502 return ret; 519 return ret;
503} 520}
504 521
@@ -527,10 +544,10 @@ nouveau_drm_unload(struct drm_device *dev)
527 nouveau_ttm_fini(drm); 544 nouveau_ttm_fini(drm);
528 nouveau_vga_fini(drm); 545 nouveau_vga_fini(drm);
529 546
530 nvif_device_fini(&drm->device);
531 if (drm->hdmi_device) 547 if (drm->hdmi_device)
532 pci_dev_put(drm->hdmi_device); 548 pci_dev_put(drm->hdmi_device);
533 nouveau_cli_destroy(&drm->client); 549 nouveau_cli_fini(&drm->client);
550 kfree(drm);
534} 551}
535 552
536void 553void
@@ -560,7 +577,6 @@ static int
560nouveau_do_suspend(struct drm_device *dev, bool runtime) 577nouveau_do_suspend(struct drm_device *dev, bool runtime)
561{ 578{
562 struct nouveau_drm *drm = nouveau_drm(dev); 579 struct nouveau_drm *drm = nouveau_drm(dev);
563 struct nouveau_cli *cli;
564 int ret; 580 int ret;
565 581
566 nouveau_led_suspend(dev); 582 nouveau_led_suspend(dev);
@@ -590,7 +606,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
590 goto fail_display; 606 goto fail_display;
591 } 607 }
592 608
593 NV_INFO(drm, "suspending client object trees...\n"); 609 NV_INFO(drm, "suspending fence...\n");
594 if (drm->fence && nouveau_fence(drm)->suspend) { 610 if (drm->fence && nouveau_fence(drm)->suspend) {
595 if (!nouveau_fence(drm)->suspend(drm)) { 611 if (!nouveau_fence(drm)->suspend(drm)) {
596 ret = -ENOMEM; 612 ret = -ENOMEM;
@@ -598,13 +614,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
598 } 614 }
599 } 615 }
600 616
601 list_for_each_entry(cli, &drm->clients, head) { 617 NV_INFO(drm, "suspending object tree...\n");
602 ret = nvif_client_suspend(&cli->base);
603 if (ret)
604 goto fail_client;
605 }
606
607 NV_INFO(drm, "suspending kernel object tree...\n");
608 ret = nvif_client_suspend(&drm->client.base); 618 ret = nvif_client_suspend(&drm->client.base);
609 if (ret) 619 if (ret)
610 goto fail_client; 620 goto fail_client;
@@ -612,10 +622,6 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
612 return 0; 622 return 0;
613 623
614fail_client: 624fail_client:
615 list_for_each_entry_continue_reverse(cli, &drm->clients, head) {
616 nvif_client_resume(&cli->base);
617 }
618
619 if (drm->fence && nouveau_fence(drm)->resume) 625 if (drm->fence && nouveau_fence(drm)->resume)
620 nouveau_fence(drm)->resume(drm); 626 nouveau_fence(drm)->resume(drm);
621 627
@@ -631,19 +637,14 @@ static int
631nouveau_do_resume(struct drm_device *dev, bool runtime) 637nouveau_do_resume(struct drm_device *dev, bool runtime)
632{ 638{
633 struct nouveau_drm *drm = nouveau_drm(dev); 639 struct nouveau_drm *drm = nouveau_drm(dev);
634 struct nouveau_cli *cli;
635 640
636 NV_INFO(drm, "resuming kernel object tree...\n"); 641 NV_INFO(drm, "resuming object tree...\n");
637 nvif_client_resume(&drm->client.base); 642 nvif_client_resume(&drm->client.base);
638 643
639 NV_INFO(drm, "resuming client object trees...\n"); 644 NV_INFO(drm, "resuming fence...\n");
640 if (drm->fence && nouveau_fence(drm)->resume) 645 if (drm->fence && nouveau_fence(drm)->resume)
641 nouveau_fence(drm)->resume(drm); 646 nouveau_fence(drm)->resume(drm);
642 647
643 list_for_each_entry(cli, &drm->clients, head) {
644 nvif_client_resume(&cli->base);
645 }
646
647 nouveau_run_vbios_init(dev); 648 nouveau_run_vbios_init(dev);
648 649
649 if (dev->mode_config.num_crtc) { 650 if (dev->mode_config.num_crtc) {
@@ -758,7 +759,7 @@ nouveau_pmops_runtime_resume(struct device *dev)
758{ 759{
759 struct pci_dev *pdev = to_pci_dev(dev); 760 struct pci_dev *pdev = to_pci_dev(dev);
760 struct drm_device *drm_dev = pci_get_drvdata(pdev); 761 struct drm_device *drm_dev = pci_get_drvdata(pdev);
761 struct nvif_device *device = &nouveau_drm(drm_dev)->device; 762 struct nvif_device *device = &nouveau_drm(drm_dev)->client.device;
762 int ret; 763 int ret;
763 764
764 if (nouveau_runtime_pm == 0) 765 if (nouveau_runtime_pm == 0)
@@ -772,7 +773,10 @@ nouveau_pmops_runtime_resume(struct device *dev)
772 pci_set_master(pdev); 773 pci_set_master(pdev);
773 774
774 ret = nouveau_do_resume(drm_dev, true); 775 ret = nouveau_do_resume(drm_dev, true);
775 drm_kms_helper_poll_enable(drm_dev); 776
777 if (!drm_dev->mode_config.poll_enabled)
778 drm_kms_helper_poll_enable(drm_dev);
779
776 /* do magic */ 780 /* do magic */
777 nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25)); 781 nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25));
778 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); 782 vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON);
@@ -841,20 +845,20 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
841 get_task_comm(tmpname, current); 845 get_task_comm(tmpname, current);
842 snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid)); 846 snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid));
843 847
844 ret = nouveau_cli_create(dev, name, sizeof(*cli), (void **)&cli); 848 if (!(cli = kzalloc(sizeof(*cli), GFP_KERNEL)))
849 return ret;
845 850
851 ret = nouveau_cli_init(drm, name, cli);
846 if (ret) 852 if (ret)
847 goto out_suspend; 853 goto done;
848 854
849 cli->base.super = false; 855 cli->base.super = false;
850 856
851 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 857 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
852 ret = nvkm_vm_new(nvxx_device(&drm->device), 0, (1ULL << 40), 858 ret = nvkm_vm_new(nvxx_device(&drm->client.device), 0,
853 0x1000, NULL, &cli->vm); 859 (1ULL << 40), 0x1000, NULL, &cli->vm);
854 if (ret) { 860 if (ret)
855 nouveau_cli_destroy(cli); 861 goto done;
856 goto out_suspend;
857 }
858 862
859 nvxx_client(&cli->base)->vm = cli->vm; 863 nvxx_client(&cli->base)->vm = cli->vm;
860 } 864 }
@@ -865,10 +869,14 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
865 list_add(&cli->head, &drm->clients); 869 list_add(&cli->head, &drm->clients);
866 mutex_unlock(&drm->client.mutex); 870 mutex_unlock(&drm->client.mutex);
867 871
868out_suspend: 872done:
873 if (ret && cli) {
874 nouveau_cli_fini(cli);
875 kfree(cli);
876 }
877
869 pm_runtime_mark_last_busy(dev->dev); 878 pm_runtime_mark_last_busy(dev->dev);
870 pm_runtime_put_autosuspend(dev->dev); 879 pm_runtime_put_autosuspend(dev->dev);
871
872 return ret; 880 return ret;
873} 881}
874 882
@@ -895,7 +903,8 @@ static void
895nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv) 903nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
896{ 904{
897 struct nouveau_cli *cli = nouveau_cli(fpriv); 905 struct nouveau_cli *cli = nouveau_cli(fpriv);
898 nouveau_cli_destroy(cli); 906 nouveau_cli_fini(cli);
907 kfree(cli);
899 pm_runtime_mark_last_busy(dev->dev); 908 pm_runtime_mark_last_busy(dev->dev);
900 pm_runtime_put_autosuspend(dev->dev); 909 pm_runtime_put_autosuspend(dev->dev);
901} 910}