aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_drm.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-07-31 02:16:21 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:12:59 -0400
commit77145f1cbdf8d28b46ff8070ca749bad821e0774 (patch)
treeb496d5d69ce4f5753028b07b09d8cf12025310f2 /drivers/gpu/drm/nouveau/nouveau_drm.c
parent2094dd82eddc468b53ee99d92c38b23a65efac03 (diff)
drm/nouveau: port remainder of drm code, and rip out compat layer
v2: Ben Skeggs <bskeggs@redhat.com> - fill in nouveau_pm.dev to prevent oops - fix ppc issues (build + OF shadow) Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_drm.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c227
1 files changed, 190 insertions, 37 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 92ecf50a39d3..8b508cec65a2 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -22,6 +22,7 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <linux/console.h>
25#include <linux/module.h> 26#include <linux/module.h>
26#include <linux/pci.h> 27#include <linux/pci.h>
27 28
@@ -34,24 +35,22 @@
34#include <subdev/vm.h> 35#include <subdev/vm.h>
35 36
36#include "nouveau_drm.h" 37#include "nouveau_drm.h"
38#include "nouveau_irq.h"
37#include "nouveau_dma.h" 39#include "nouveau_dma.h"
40#include "nouveau_ttm.h"
41#include "nouveau_gem.h"
38#include "nouveau_agp.h" 42#include "nouveau_agp.h"
43#include "nouveau_vga.h"
44#include "nouveau_pm.h"
45#include "nouveau_acpi.h"
46#include "nouveau_bios.h"
47#include "nouveau_ioctl.h"
39#include "nouveau_abi16.h" 48#include "nouveau_abi16.h"
40#include "nouveau_fbcon.h" 49#include "nouveau_fbcon.h"
41#include "nouveau_fence.h" 50#include "nouveau_fence.h"
42 51
43#include "nouveau_ttm.h" 52#include "nouveau_ttm.h"
44 53
45int __devinit nouveau_pci_probe(struct pci_dev *, const struct pci_device_id *);
46void nouveau_pci_remove(struct pci_dev *);
47int nouveau_pci_suspend(struct pci_dev *, pm_message_t);
48int nouveau_pci_resume(struct pci_dev *);
49int __init nouveau_init(struct pci_driver *);
50void __exit nouveau_exit(struct pci_driver *);
51
52int nouveau_load(struct drm_device *, unsigned long);
53int nouveau_unload(struct drm_device *);
54
55MODULE_PARM_DESC(config, "option string to pass to driver core"); 54MODULE_PARM_DESC(config, "option string to pass to driver core");
56static char *nouveau_config; 55static char *nouveau_config;
57module_param_named(config, nouveau_config, charp, 0400); 56module_param_named(config, nouveau_config, charp, 0400);
@@ -64,6 +63,12 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration");
64static int nouveau_noaccel = 0; 63static int nouveau_noaccel = 0;
65module_param_named(noaccel, nouveau_noaccel, int, 0400); 64module_param_named(noaccel, nouveau_noaccel, int, 0400);
66 65
66MODULE_PARM_DESC(modeset, "enable driver");
67int nouveau_modeset = -1;
68module_param_named(modeset, nouveau_modeset, int, 0400);
69
70static struct drm_driver driver;
71
67static u64 72static u64
68nouveau_name(struct pci_dev *pdev) 73nouveau_name(struct pci_dev *pdev)
69{ 74{
@@ -206,7 +211,7 @@ nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent)
206 211
207 pci_set_master(pdev); 212 pci_set_master(pdev);
208 213
209 ret = nouveau_pci_probe(pdev, pent); 214 ret = drm_get_pci_dev(pdev, pent, &driver);
210 if (ret) { 215 if (ret) {
211 nouveau_object_ref(NULL, (struct nouveau_object **)&device); 216 nouveau_object_ref(NULL, (struct nouveau_object **)&device);
212 return ret; 217 return ret;
@@ -224,13 +229,14 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
224 int ret; 229 int ret;
225 230
226 ret = nouveau_cli_create(pdev, 0, sizeof(*drm), (void**)&drm); 231 ret = nouveau_cli_create(pdev, 0, sizeof(*drm), (void**)&drm);
227 dev->dev_private = drm;
228 if (ret) 232 if (ret)
229 return ret; 233 return ret;
230 234
235 dev->dev_private = drm;
236 drm->dev = dev;
237
231 INIT_LIST_HEAD(&drm->clients); 238 INIT_LIST_HEAD(&drm->clients);
232 spin_lock_init(&drm->tile.lock); 239 spin_lock_init(&drm->tile.lock);
233 drm->dev = dev;
234 240
235 /* make sure AGP controller is in a consistent state before we 241 /* make sure AGP controller is in a consistent state before we
236 * (possibly) execute vbios init tables (see nouveau_agp.h) 242 * (possibly) execute vbios init tables (see nouveau_agp.h)
@@ -266,9 +272,15 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
266 if (ret) 272 if (ret)
267 goto fail_device; 273 goto fail_device;
268 274
275 /* workaround an odd issue on nvc1 by disabling the device's
276 * nosnoop capability. hopefully won't cause issues until a
277 * better fix is found - assuming there is one...
278 */
269 device = nv_device(drm->device); 279 device = nv_device(drm->device);
280 if (nv_device(drm->device)->chipset == 0xc1)
281 nv_mask(device, 0x00088080, 0x00000800, 0x00000000);
270 282
271 /* initialise AGP */ 283 nouveau_vga_init(drm);
272 nouveau_agp_init(drm); 284 nouveau_agp_init(drm);
273 285
274 if (device->card_type >= NV_50) { 286 if (device->card_type >= NV_50) {
@@ -280,18 +292,43 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
280 292
281 ret = nouveau_ttm_init(drm); 293 ret = nouveau_ttm_init(drm);
282 if (ret) 294 if (ret)
283 goto fail_device; 295 goto fail_ttm;
296
297 ret = nouveau_bios_init(dev);
298 if (ret)
299 goto fail_bios;
300
301 ret = nouveau_irq_init(dev);
302 if (ret)
303 goto fail_irq;
284 304
285 ret = nouveau_load(dev, flags); 305 ret = nouveau_display_create(dev);
286 if (ret) 306 if (ret)
287 goto fail_load; 307 goto fail_dispctor;
308
309 if (dev->mode_config.num_crtc) {
310 ret = nouveau_display_init(dev);
311 if (ret)
312 goto fail_dispinit;
313 }
314
315 nouveau_pm_init(dev);
288 316
289 nouveau_accel_init(drm); 317 nouveau_accel_init(drm);
290 nouveau_fbcon_init(dev); 318 nouveau_fbcon_init(dev);
291 return 0; 319 return 0;
292 320
293fail_load: 321fail_dispinit:
322 nouveau_display_destroy(dev);
323fail_dispctor:
324 nouveau_irq_fini(dev);
325fail_irq:
326 nouveau_bios_takedown(dev);
327fail_bios:
294 nouveau_ttm_fini(drm); 328 nouveau_ttm_fini(drm);
329fail_ttm:
330 nouveau_agp_fini(drm);
331 nouveau_vga_fini(drm);
295fail_device: 332fail_device:
296 nouveau_cli_destroy(&drm->client); 333 nouveau_cli_destroy(&drm->client);
297 return ret; 334 return ret;
@@ -300,21 +337,23 @@ fail_device:
300int 337int
301nouveau_drm_unload(struct drm_device *dev) 338nouveau_drm_unload(struct drm_device *dev)
302{ 339{
303 struct nouveau_drm *drm = nouveau_newpriv(dev); 340 struct nouveau_drm *drm = nouveau_drm(dev);
304 struct pci_dev *pdev = dev->pdev;
305 int ret;
306 341
307 nouveau_fbcon_fini(dev); 342 nouveau_fbcon_fini(dev);
308 nouveau_accel_fini(drm); 343 nouveau_accel_fini(drm);
309 344
310 ret = nouveau_unload(dev); 345 nouveau_pm_fini(dev);
311 if (ret) 346
312 return ret; 347 nouveau_display_fini(dev);
348 nouveau_display_destroy(dev);
349
350 nouveau_irq_fini(dev);
351 nouveau_bios_takedown(dev);
313 352
314 nouveau_ttm_fini(drm); 353 nouveau_ttm_fini(drm);
315 nouveau_agp_fini(drm); 354 nouveau_agp_fini(drm);
355 nouveau_vga_fini(drm);
316 356
317 pci_set_drvdata(pdev, drm->client.base.device);
318 nouveau_cli_destroy(&drm->client); 357 nouveau_cli_destroy(&drm->client);
319 return 0; 358 return 0;
320} 359}
@@ -322,9 +361,13 @@ nouveau_drm_unload(struct drm_device *dev)
322static void 361static void
323nouveau_drm_remove(struct pci_dev *pdev) 362nouveau_drm_remove(struct pci_dev *pdev)
324{ 363{
364 struct drm_device *dev = pci_get_drvdata(pdev);
365 struct nouveau_drm *drm = nouveau_drm(dev);
325 struct nouveau_object *device; 366 struct nouveau_object *device;
326 nouveau_pci_remove(pdev); 367
327 device = pci_get_drvdata(pdev); 368 device = drm->client.base.device;
369 drm_put_dev(dev);
370
328 nouveau_object_ref(NULL, &device); 371 nouveau_object_ref(NULL, &device);
329 nouveau_object_debug(); 372 nouveau_object_debug();
330} 373}
@@ -333,7 +376,7 @@ int
333nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) 376nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
334{ 377{
335 struct drm_device *dev = pci_get_drvdata(pdev); 378 struct drm_device *dev = pci_get_drvdata(pdev);
336 struct nouveau_drm *drm = nouveau_newpriv(dev); 379 struct nouveau_drm *drm = nouveau_drm(dev);
337 struct nouveau_cli *cli; 380 struct nouveau_cli *cli;
338 int ret; 381 int ret;
339 382
@@ -344,8 +387,8 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
344 NV_INFO(drm, "suspending fbcon...\n"); 387 NV_INFO(drm, "suspending fbcon...\n");
345 nouveau_fbcon_set_suspend(dev, 1); 388 nouveau_fbcon_set_suspend(dev, 1);
346 389
347 NV_INFO(drm, "suspending drm...\n"); 390 NV_INFO(drm, "suspending display...\n");
348 ret = nouveau_pci_suspend(pdev, pm_state); 391 ret = nouveau_display_suspend(dev);
349 if (ret) 392 if (ret)
350 return ret; 393 return ret;
351 394
@@ -383,7 +426,8 @@ fail_client:
383 nouveau_client_init(&cli->base); 426 nouveau_client_init(&cli->base);
384 } 427 }
385 428
386 nouveau_pci_resume(pdev); 429 NV_INFO(drm, "resuming display...\n");
430 nouveau_display_resume(dev);
387 return ret; 431 return ret;
388} 432}
389 433
@@ -391,7 +435,7 @@ int
391nouveau_drm_resume(struct pci_dev *pdev) 435nouveau_drm_resume(struct pci_dev *pdev)
392{ 436{
393 struct drm_device *dev = pci_get_drvdata(pdev); 437 struct drm_device *dev = pci_get_drvdata(pdev);
394 struct nouveau_drm *drm = nouveau_newpriv(dev); 438 struct nouveau_drm *drm = nouveau_drm(dev);
395 struct nouveau_cli *cli; 439 struct nouveau_cli *cli;
396 int ret; 440 int ret;
397 441
@@ -419,7 +463,13 @@ nouveau_drm_resume(struct pci_dev *pdev)
419 if (drm->fence && nouveau_fence(drm)->resume) 463 if (drm->fence && nouveau_fence(drm)->resume)
420 nouveau_fence(drm)->resume(drm); 464 nouveau_fence(drm)->resume(drm);
421 465
422 return nouveau_pci_resume(pdev); 466 nouveau_run_vbios_init(dev);
467 nouveau_irq_postinstall(dev);
468 nouveau_pm_resume(dev);
469
470 NV_INFO(drm, "resuming display...\n");
471 nouveau_display_resume(dev);
472 return 0;
423} 473}
424 474
425int 475int
@@ -472,6 +522,90 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
472 nouveau_cli_destroy(cli); 522 nouveau_cli_destroy(cli);
473} 523}
474 524
525static struct drm_ioctl_desc
526nouveau_ioctls[] = {
527 DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_abi16_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH),
528 DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_abi16_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
529 DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_abi16_ioctl_channel_alloc, DRM_UNLOCKED|DRM_AUTH),
530 DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_abi16_ioctl_channel_free, DRM_UNLOCKED|DRM_AUTH),
531 DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_abi16_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH),
532 DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_abi16_ioctl_notifierobj_alloc, DRM_UNLOCKED|DRM_AUTH),
533 DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_abi16_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH),
534 DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH),
535 DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH),
536 DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
537 DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
538 DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH),
539};
540
541static const struct file_operations
542nouveau_driver_fops = {
543 .owner = THIS_MODULE,
544 .open = drm_open,
545 .release = drm_release,
546 .unlocked_ioctl = drm_ioctl,
547 .mmap = nouveau_ttm_mmap,
548 .poll = drm_poll,
549 .fasync = drm_fasync,
550 .read = drm_read,
551#if defined(CONFIG_COMPAT)
552 .compat_ioctl = nouveau_compat_ioctl,
553#endif
554 .llseek = noop_llseek,
555};
556
557static struct drm_driver
558driver = {
559 .driver_features =
560 DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
561 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
562 DRIVER_MODESET | DRIVER_PRIME,
563
564 .load = nouveau_drm_load,
565 .unload = nouveau_drm_unload,
566 .open = nouveau_drm_open,
567 .preclose = nouveau_drm_preclose,
568 .postclose = nouveau_drm_postclose,
569 .lastclose = nouveau_vga_lastclose,
570
571 .irq_preinstall = nouveau_irq_preinstall,
572 .irq_postinstall = nouveau_irq_postinstall,
573 .irq_uninstall = nouveau_irq_uninstall,
574 .irq_handler = nouveau_irq_handler,
575
576 .get_vblank_counter = drm_vblank_count,
577 .enable_vblank = nouveau_vblank_enable,
578 .disable_vblank = nouveau_vblank_disable,
579
580 .ioctls = nouveau_ioctls,
581 .fops = &nouveau_driver_fops,
582
583 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
584 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
585 .gem_prime_export = nouveau_gem_prime_export,
586 .gem_prime_import = nouveau_gem_prime_import,
587
588 .gem_init_object = nouveau_gem_object_new,
589 .gem_free_object = nouveau_gem_object_del,
590 .gem_open_object = nouveau_gem_object_open,
591 .gem_close_object = nouveau_gem_object_close,
592
593 .dumb_create = nouveau_display_dumb_create,
594 .dumb_map_offset = nouveau_display_dumb_map_offset,
595 .dumb_destroy = nouveau_display_dumb_destroy,
596
597 .name = DRIVER_NAME,
598 .desc = DRIVER_DESC,
599#ifdef GIT_REVISION
600 .date = GIT_REVISION,
601#else
602 .date = DRIVER_DATE,
603#endif
604 .major = DRIVER_MAJOR,
605 .minor = DRIVER_MINOR,
606 .patchlevel = DRIVER_PATCHLEVEL,
607};
608
475static struct pci_device_id 609static struct pci_device_id
476nouveau_drm_pci_table[] = { 610nouveau_drm_pci_table[] = {
477 { 611 {
@@ -500,19 +634,38 @@ nouveau_drm_pci_driver = {
500static int __init 634static int __init
501nouveau_drm_init(void) 635nouveau_drm_init(void)
502{ 636{
503 return nouveau_init(&nouveau_drm_pci_driver); 637 driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls);
638
639 if (nouveau_modeset == -1) {
640#ifdef CONFIG_VGA_CONSOLE
641 if (vgacon_text_force())
642 nouveau_modeset = 0;
643 else
644#endif
645 nouveau_modeset = 1;
646 }
647
648 if (!nouveau_modeset)
649 return 0;
650
651 nouveau_register_dsm_handler();
652 return drm_pci_init(&driver, &nouveau_drm_pci_driver);
504} 653}
505 654
506static void __exit 655static void __exit
507nouveau_drm_exit(void) 656nouveau_drm_exit(void)
508{ 657{
509 nouveau_exit(&nouveau_drm_pci_driver); 658 if (!nouveau_modeset)
659 return;
660
661 drm_pci_exit(&driver, &nouveau_drm_pci_driver);
662 nouveau_unregister_dsm_handler();
510} 663}
511 664
512module_init(nouveau_drm_init); 665module_init(nouveau_drm_init);
513module_exit(nouveau_drm_exit); 666module_exit(nouveau_drm_exit);
514 667
515MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table); 668MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table);
516MODULE_AUTHOR("Nouveau Project"); 669MODULE_AUTHOR(DRIVER_AUTHOR);
517MODULE_DESCRIPTION("nVidia Riva/TNT/GeForce/Quadro/Tesla"); 670MODULE_DESCRIPTION(DRIVER_DESC);
518MODULE_LICENSE("GPL and additional rights"); 671MODULE_LICENSE("GPL and additional rights");