aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-07-03 21:55:39 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:05:09 -0400
commit1575b3646c1c2141cfb68f7581c50d8bd19f17ac (patch)
treef882f6ba3e4d8be6816fdb4efaab8f58ff33c369 /drivers/gpu
parent048a88595a66526f68636b51b1cdb5842bc0f28c (diff)
drm/nouveau: fixup init/fini sequence to deal with no CRTCs
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c64
2 files changed, 30 insertions, 38 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index 363379c226ed..4406c1751069 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -793,7 +793,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
793 return ret; 793 return ret;
794 794
795 /* dma objects for display sync channel semaphore blocks */ 795 /* dma objects for display sync channel semaphore blocks */
796 for (i = 0; i < 2; i++) { 796 for (i = 0; i < dev->mode_config.num_crtc; i++) {
797 struct nouveau_gpuobj *sem = NULL; 797 struct nouveau_gpuobj *sem = NULL;
798 struct nv50_display_crtc *dispc = 798 struct nv50_display_crtc *dispc =
799 &nv50_display(dev)->crtc[i]; 799 &nv50_display(dev)->crtc[i];
@@ -878,7 +878,7 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
878 if (dev_priv->card_type >= NV_50) { 878 if (dev_priv->card_type >= NV_50) {
879 struct nv50_display *disp = nv50_display(dev); 879 struct nv50_display *disp = nv50_display(dev);
880 880
881 for (i = 0; i < 2; i++) { 881 for (i = 0; i < dev->mode_config.num_crtc; i++) {
882 struct nv50_display_crtc *dispc = &disp->crtc[i]; 882 struct nv50_display_crtc *dispc = &disp->crtc[i];
883 nouveau_bo_vma_del(dispc->sem.bo, &chan->dispc_vma[i]); 883 nouveau_bo_vma_del(dispc->sem.bo, &chan->dispc_vma[i]);
884 } 884 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 2d7a4ed60142..d4570220417f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -452,21 +452,6 @@ nouveau_vga_set_decode(void *priv, bool state)
452 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 452 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
453} 453}
454 454
455static int
456nouveau_card_init_channel(struct drm_device *dev)
457{
458 struct drm_nouveau_private *dev_priv = dev->dev_private;
459 int ret;
460
461 ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
462 NvDmaFB, NvDmaTT);
463 if (ret)
464 return ret;
465
466 mutex_unlock(&dev_priv->channel->mutex);
467 return 0;
468}
469
470static void nouveau_switcheroo_set_state(struct pci_dev *pdev, 455static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
471 enum vga_switcheroo_state state) 456 enum vga_switcheroo_state state)
472{ 457{
@@ -657,6 +642,10 @@ nouveau_card_init(struct drm_device *dev)
657 goto out_engine; 642 goto out_engine;
658 } 643 }
659 644
645 ret = nouveau_irq_init(dev);
646 if (ret)
647 goto out_fifo;
648
660 /* initialise general modesetting */ 649 /* initialise general modesetting */
661 drm_mode_config_init(dev); 650 drm_mode_config_init(dev);
662 drm_mode_create_scaling_mode_property(dev); 651 drm_mode_create_scaling_mode_property(dev);
@@ -679,39 +668,40 @@ nouveau_card_init(struct drm_device *dev)
679 668
680 ret = engine->display.create(dev); 669 ret = engine->display.create(dev);
681 if (ret) 670 if (ret)
682 goto out_fifo; 671 goto out_irq;
683
684 ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1);
685 if (ret)
686 goto out_vblank;
687
688 ret = nouveau_irq_init(dev);
689 if (ret)
690 goto out_vblank;
691
692 /* what about PVIDEO/PCRTC/PRAMDAC etc? */
693 672
694 if (dev_priv->eng[NVOBJ_ENGINE_GR]) { 673 if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
695 ret = nouveau_fence_init(dev); 674 ret = nouveau_fence_init(dev);
696 if (ret) 675 if (ret)
697 goto out_irq; 676 goto out_disp;
698 677
699 ret = nouveau_card_init_channel(dev); 678 ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
679 NvDmaFB, NvDmaTT);
700 if (ret) 680 if (ret)
701 goto out_fence; 681 goto out_fence;
682
683 mutex_unlock(&dev_priv->channel->mutex);
684 }
685
686 if (dev->mode_config.num_crtc) {
687 ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
688 if (ret)
689 goto out_chan;
690
691 nouveau_fbcon_init(dev);
692 drm_kms_helper_poll_init(dev);
702 } 693 }
703 694
704 nouveau_fbcon_init(dev);
705 drm_kms_helper_poll_init(dev);
706 return 0; 695 return 0;
707 696
697out_chan:
698 nouveau_channel_put_unlocked(&dev_priv->channel);
708out_fence: 699out_fence:
709 nouveau_fence_fini(dev); 700 nouveau_fence_fini(dev);
701out_disp:
702 engine->display.destroy(dev);
710out_irq: 703out_irq:
711 nouveau_irq_fini(dev); 704 nouveau_irq_fini(dev);
712out_vblank:
713 drm_vblank_cleanup(dev);
714 engine->display.destroy(dev);
715out_fifo: 705out_fifo:
716 if (!dev_priv->noaccel) 706 if (!dev_priv->noaccel)
717 engine->fifo.takedown(dev); 707 engine->fifo.takedown(dev);
@@ -758,8 +748,11 @@ static void nouveau_card_takedown(struct drm_device *dev)
758 struct nouveau_engine *engine = &dev_priv->engine; 748 struct nouveau_engine *engine = &dev_priv->engine;
759 int e; 749 int e;
760 750
761 drm_kms_helper_poll_fini(dev); 751 if (dev->mode_config.num_crtc) {
762 nouveau_fbcon_fini(dev); 752 drm_kms_helper_poll_fini(dev);
753 nouveau_fbcon_fini(dev);
754 drm_vblank_cleanup(dev);
755 }
763 756
764 if (dev_priv->channel) { 757 if (dev_priv->channel) {
765 nouveau_channel_put_unlocked(&dev_priv->channel); 758 nouveau_channel_put_unlocked(&dev_priv->channel);
@@ -801,7 +794,6 @@ static void nouveau_card_takedown(struct drm_device *dev)
801 engine->vram.takedown(dev); 794 engine->vram.takedown(dev);
802 795
803 nouveau_irq_fini(dev); 796 nouveau_irq_fini(dev);
804 drm_vblank_cleanup(dev);
805 797
806 nouveau_pm_fini(dev); 798 nouveau_pm_fini(dev);
807 nouveau_bios_takedown(dev); 799 nouveau_bios_takedown(dev);