drm/nouveau: fixup init/fini sequence to deal with no CRTCs
authorBen Skeggs <bskeggs@redhat.com>
Mon, 4 Jul 2011 01:55:39 +0000 (11:55 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 20 Sep 2011 06:05:09 +0000 (16:05 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_object.c
drivers/gpu/drm/nouveau/nouveau_state.c

index 363379c..4406c17 100644 (file)
@@ -793,7 +793,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
                        return ret;
 
                /* dma objects for display sync channel semaphore blocks */
-               for (i = 0; i < 2; i++) {
+               for (i = 0; i < dev->mode_config.num_crtc; i++) {
                        struct nouveau_gpuobj *sem = NULL;
                        struct nv50_display_crtc *dispc =
                                &nv50_display(dev)->crtc[i];
@@ -878,7 +878,7 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
        if (dev_priv->card_type >= NV_50) {
                struct nv50_display *disp = nv50_display(dev);
 
-               for (i = 0; i < 2; i++) {
+               for (i = 0; i < dev->mode_config.num_crtc; i++) {
                        struct nv50_display_crtc *dispc = &disp->crtc[i];
                        nouveau_bo_vma_del(dispc->sem.bo, &chan->dispc_vma[i]);
                }
index 2d7a4ed..d457022 100644 (file)
@@ -452,21 +452,6 @@ nouveau_vga_set_decode(void *priv, bool state)
                return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
 }
 
-static int
-nouveau_card_init_channel(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       int ret;
-
-       ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
-                                   NvDmaFB, NvDmaTT);
-       if (ret)
-               return ret;
-
-       mutex_unlock(&dev_priv->channel->mutex);
-       return 0;
-}
-
 static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
                                         enum vga_switcheroo_state state)
 {
@@ -657,6 +642,10 @@ nouveau_card_init(struct drm_device *dev)
                        goto out_engine;
        }
 
+       ret = nouveau_irq_init(dev);
+       if (ret)
+               goto out_fifo;
+
        /* initialise general modesetting */
        drm_mode_config_init(dev);
        drm_mode_create_scaling_mode_property(dev);
@@ -679,39 +668,40 @@ nouveau_card_init(struct drm_device *dev)
 
        ret = engine->display.create(dev);
        if (ret)
-               goto out_fifo;
-
-       ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1);
-       if (ret)
-               goto out_vblank;
-
-       ret = nouveau_irq_init(dev);
-       if (ret)
-               goto out_vblank;
-
-       /* what about PVIDEO/PCRTC/PRAMDAC etc? */
+               goto out_irq;
 
        if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
                ret = nouveau_fence_init(dev);
                if (ret)
-                       goto out_irq;
+                       goto out_disp;
 
-               ret = nouveau_card_init_channel(dev);
+               ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL,
+                                           NvDmaFB, NvDmaTT);
                if (ret)
                        goto out_fence;
+
+               mutex_unlock(&dev_priv->channel->mutex);
+       }
+
+       if (dev->mode_config.num_crtc) {
+               ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+               if (ret)
+                       goto out_chan;
+
+               nouveau_fbcon_init(dev);
+               drm_kms_helper_poll_init(dev);
        }
 
-       nouveau_fbcon_init(dev);
-       drm_kms_helper_poll_init(dev);
        return 0;
 
+out_chan:
+       nouveau_channel_put_unlocked(&dev_priv->channel);
 out_fence:
        nouveau_fence_fini(dev);
+out_disp:
+       engine->display.destroy(dev);
 out_irq:
        nouveau_irq_fini(dev);
-out_vblank:
-       drm_vblank_cleanup(dev);
-       engine->display.destroy(dev);
 out_fifo:
        if (!dev_priv->noaccel)
                engine->fifo.takedown(dev);
@@ -758,8 +748,11 @@ static void nouveau_card_takedown(struct drm_device *dev)
        struct nouveau_engine *engine = &dev_priv->engine;
        int e;
 
-       drm_kms_helper_poll_fini(dev);
-       nouveau_fbcon_fini(dev);
+       if (dev->mode_config.num_crtc) {
+               drm_kms_helper_poll_fini(dev);
+               nouveau_fbcon_fini(dev);
+               drm_vblank_cleanup(dev);
+       }
 
        if (dev_priv->channel) {
                nouveau_channel_put_unlocked(&dev_priv->channel);
@@ -801,7 +794,6 @@ static void nouveau_card_takedown(struct drm_device *dev)
        engine->vram.takedown(dev);
 
        nouveau_irq_fini(dev);
-       drm_vblank_cleanup(dev);
 
        nouveau_pm_fini(dev);
        nouveau_bios_takedown(dev);