Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux...
authorDave Airlie <airlied@redhat.com>
Mon, 25 Jul 2011 09:15:18 +0000 (10:15 +0100)
committerDave Airlie <airlied@redhat.com>
Mon, 25 Jul 2011 09:15:18 +0000 (10:15 +0100)
* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
  drm/nouveau/gr: disable fifo access and idle before suspend ctx unload
  drm/nouveau: pass flag to engine fini() method on suspend
  drm/nouveau: replace nv04_graph_fifo_access() use with direct reg bashing
  drm/nv40/gr: rewrite/split context takedown functions
  drm/nouveau: detect disabled device in irq handler and return IRQ_NONE
  drm/nouveau: ignore connector type when deciding digital/analog on DVI-I
  drm/nouveau: Add a quirk for Gigabyte NX86T
  drm/nouveau: do not leak in nv20_graph_create
  drm/nv50/dp: fix hack to work for macbooks booted via EFI

18 files changed:
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_connector.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_irq.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nv04_graph.c
drivers/gpu/drm/nouveau/nv10_graph.c
drivers/gpu/drm/nouveau/nv20_graph.c
drivers/gpu/drm/nouveau/nv40_graph.c
drivers/gpu/drm/nouveau/nv40_mpeg.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_mpeg.c
drivers/gpu/drm/nouveau/nv50_sor.c
drivers/gpu/drm/nouveau/nv84_crypt.c
drivers/gpu/drm/nouveau/nva3_copy.c
drivers/gpu/drm/nouveau/nvc0_copy.c
drivers/gpu/drm/nouveau/nvc0_graph.c

index 1aa73d3..b311fab 100644 (file)
@@ -5966,6 +5966,12 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx)
                if (cte->type == DCB_CONNECTOR_HDMI_1)
                        cte->type = DCB_CONNECTOR_DVI_I;
        }
+
+       /* Gigabyte GV-NX86T512H */
+       if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) {
+               if (cte->type == DCB_CONNECTOR_HDMI_1)
+                       cte->type = DCB_CONNECTOR_DVI_I;
+       }
 }
 
 static const u8 hpd_gpio[16] = {
index 1595d0b..939d4df 100644 (file)
@@ -40,7 +40,7 @@
 static void nouveau_connector_hotplug(void *, int);
 
 static struct nouveau_encoder *
-find_encoder_by_type(struct drm_connector *connector, int type)
+find_encoder(struct drm_connector *connector, int type)
 {
        struct drm_device *dev = connector->dev;
        struct nouveau_encoder *nv_encoder;
@@ -170,8 +170,8 @@ nouveau_connector_of_detect(struct drm_connector *connector)
        struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev);
 
        if (!dn ||
-           !((nv_encoder = find_encoder_by_type(connector, OUTPUT_TMDS)) ||
-             (nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG))))
+           !((nv_encoder = find_encoder(connector, OUTPUT_TMDS)) ||
+             (nv_encoder = find_encoder(connector, OUTPUT_ANALOG))))
                return NULL;
 
        for_each_child_of_node(dn, cn) {
@@ -233,6 +233,7 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
        struct drm_device *dev = connector->dev;
        struct nouveau_connector *nv_connector = nouveau_connector(connector);
        struct nouveau_encoder *nv_encoder = NULL;
+       struct nouveau_encoder *nv_partner;
        struct nouveau_i2c_chan *i2c;
        int type;
 
@@ -266,19 +267,22 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
                 * same i2c channel so the value returned from ddc_detect
                 * isn't necessarily correct.
                 */
-               if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) {
+               nv_partner = NULL;
+               if (nv_encoder->dcb->type == OUTPUT_TMDS)
+                       nv_partner = find_encoder(connector, OUTPUT_ANALOG);
+               if (nv_encoder->dcb->type == OUTPUT_ANALOG)
+                       nv_partner = find_encoder(connector, OUTPUT_TMDS);
+
+               if (nv_partner && ((nv_encoder->dcb->type == OUTPUT_ANALOG &&
+                                   nv_partner->dcb->type == OUTPUT_TMDS) ||
+                                  (nv_encoder->dcb->type == OUTPUT_TMDS &&
+                                   nv_partner->dcb->type == OUTPUT_ANALOG))) {
                        if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
                                type = OUTPUT_TMDS;
                        else
                                type = OUTPUT_ANALOG;
 
-                       nv_encoder = find_encoder_by_type(connector, type);
-                       if (!nv_encoder) {
-                               NV_ERROR(dev, "Detected %d encoder on %s, "
-                                             "but no object!\n", type,
-                                        drm_get_connector_name(connector));
-                               return connector_status_disconnected;
-                       }
+                       nv_encoder = find_encoder(connector, type);
                }
 
                nouveau_connector_set_encoder(connector, nv_encoder);
@@ -292,9 +296,9 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
        }
 
 detect_analog:
-       nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
+       nv_encoder = find_encoder(connector, OUTPUT_ANALOG);
        if (!nv_encoder && !nouveau_tv_disable)
-               nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
+               nv_encoder = find_encoder(connector, OUTPUT_TV);
        if (nv_encoder && force) {
                struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
                struct drm_encoder_helper_funcs *helper =
@@ -327,7 +331,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
                nv_connector->edid = NULL;
        }
 
-       nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS);
+       nv_encoder = find_encoder(connector, OUTPUT_LVDS);
        if (!nv_encoder)
                return connector_status_disconnected;
 
@@ -405,7 +409,7 @@ nouveau_connector_force(struct drm_connector *connector)
        } else
                type = OUTPUT_ANY;
 
-       nv_encoder = find_encoder_by_type(connector, type);
+       nv_encoder = find_encoder(connector, type);
        if (!nv_encoder) {
                NV_ERROR(connector->dev, "can't find encoder to force %s on!\n",
                         drm_get_connector_name(connector));
index 8256370..b30ddd8 100644 (file)
@@ -214,10 +214,13 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
        pfifo->unload_context(dev);
 
        for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
-               if (dev_priv->eng[e]) {
-                       ret = dev_priv->eng[e]->fini(dev, e);
-                       if (ret)
-                               goto out_abort;
+               if (!dev_priv->eng[e])
+                       continue;
+
+               ret = dev_priv->eng[e]->fini(dev, e, true);
+               if (ret) {
+                       NV_ERROR(dev, "... engine %d failed: %d\n", i, ret);
+                       goto out_abort;
                }
        }
 
index 72bfc14..d7d51de 100644 (file)
@@ -312,7 +312,7 @@ struct nouveau_channel {
 struct nouveau_exec_engine {
        void (*destroy)(struct drm_device *, int engine);
        int  (*init)(struct drm_device *, int engine);
-       int  (*fini)(struct drm_device *, int engine);
+       int  (*fini)(struct drm_device *, int engine, bool suspend);
        int  (*context_new)(struct nouveau_channel *, int engine);
        void (*context_del)(struct nouveau_channel *, int engine);
        int  (*object_new)(struct nouveau_channel *, int engine,
@@ -1142,7 +1142,6 @@ extern int  nvc0_fifo_unload_context(struct drm_device *);
 
 /* nv04_graph.c */
 extern int  nv04_graph_create(struct drm_device *);
-extern void nv04_graph_fifo_access(struct drm_device *, bool);
 extern int  nv04_graph_object_new(struct nouveau_channel *, int, u32, u16);
 extern int  nv04_graph_mthd_page_flip(struct nouveau_channel *chan,
                                      u32 class, u32 mthd, u32 data);
index 2ba7265..868c7fd 100644 (file)
@@ -79,7 +79,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
        int i;
 
        stat = nv_rd32(dev, NV03_PMC_INTR_0);
-       if (!stat)
+       if (stat == 0 || stat == ~0)
                return IRQ_NONE;
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
index fa1e632..10656e4 100644 (file)
@@ -694,7 +694,7 @@ out_engine:
                for (e = e - 1; e >= 0; e--) {
                        if (!dev_priv->eng[e])
                                continue;
-                       dev_priv->eng[e]->fini(dev, e);
+                       dev_priv->eng[e]->fini(dev, e, false);
                        dev_priv->eng[e]->destroy(dev,e );
                }
        }
@@ -746,7 +746,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
                engine->fifo.takedown(dev);
                for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
                        if (dev_priv->eng[e]) {
-                               dev_priv->eng[e]->fini(dev, e);
+                               dev_priv->eng[e]->fini(dev, e, false);
                                dev_priv->eng[e]->destroy(dev,e );
                        }
                }
index 3626ee7..dbdea8e 100644 (file)
@@ -450,13 +450,13 @@ nv04_graph_context_del(struct nouveau_channel *chan, int engine)
        unsigned long flags;
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-       nv04_graph_fifo_access(dev, false);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
 
        /* Unload the context if it's the currently active one */
        if (nv04_graph_channel(dev) == chan)
                nv04_graph_unload_context(dev);
 
-       nv04_graph_fifo_access(dev, true);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
        /* Free the context resources */
@@ -538,24 +538,18 @@ nv04_graph_init(struct drm_device *dev, int engine)
 }
 
 static int
-nv04_graph_fini(struct drm_device *dev, int engine)
+nv04_graph_fini(struct drm_device *dev, int engine, bool suspend)
 {
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
+       if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
+               nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+               return -EBUSY;
+       }
        nv04_graph_unload_context(dev);
        nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
        return 0;
 }
 
-void
-nv04_graph_fifo_access(struct drm_device *dev, bool enabled)
-{
-       if (enabled)
-               nv_wr32(dev, NV04_PGRAPH_FIFO,
-                                       nv_rd32(dev, NV04_PGRAPH_FIFO) | 1);
-       else
-               nv_wr32(dev, NV04_PGRAPH_FIFO,
-                                       nv_rd32(dev, NV04_PGRAPH_FIFO) & ~1);
-}
-
 static int
 nv04_graph_mthd_set_ref(struct nouveau_channel *chan,
                        u32 class, u32 mthd, u32 data)
index 0930c6c..7255e4a 100644 (file)
@@ -708,8 +708,8 @@ static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan,
                0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
        nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
        nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
-       nv04_graph_fifo_access(dev, true);
-       nv04_graph_fifo_access(dev, false);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
 
        /* Restore the FIFO state */
        for (i = 0; i < ARRAY_SIZE(fifo); i++)
@@ -879,13 +879,13 @@ nv10_graph_context_del(struct nouveau_channel *chan, int engine)
        unsigned long flags;
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-       nv04_graph_fifo_access(dev, false);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
 
        /* Unload the context if it's the currently active one */
        if (nv10_graph_channel(dev) == chan)
                nv10_graph_unload_context(dev);
 
-       nv04_graph_fifo_access(dev, true);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
        /* Free the context resources */
@@ -957,8 +957,13 @@ nv10_graph_init(struct drm_device *dev, int engine)
 }
 
 static int
-nv10_graph_fini(struct drm_device *dev, int engine)
+nv10_graph_fini(struct drm_device *dev, int engine, bool suspend)
 {
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
+       if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
+               nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+               return -EBUSY;
+       }
        nv10_graph_unload_context(dev);
        nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
        return 0;
index affc7d7..183e375 100644 (file)
@@ -454,13 +454,13 @@ nv20_graph_context_del(struct nouveau_channel *chan, int engine)
        unsigned long flags;
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-       nv04_graph_fifo_access(dev, false);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
 
        /* Unload the context if it's the currently active one */
        if (nv10_graph_channel(dev) == chan)
                nv20_graph_unload_context(dev);
 
-       nv04_graph_fifo_access(dev, true);
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
        /* Free the context resources */
@@ -654,8 +654,13 @@ nv30_graph_init(struct drm_device *dev, int engine)
 }
 
 int
-nv20_graph_fini(struct drm_device *dev, int engine)
+nv20_graph_fini(struct drm_device *dev, int engine, bool suspend)
 {
+       nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000000);
+       if (!nv_wait(dev, NV04_PGRAPH_STATUS, ~0, 0) && suspend) {
+               nv_mask(dev, NV04_PGRAPH_FIFO, 0x00000001, 0x00000001);
+               return -EBUSY;
+       }
        nv20_graph_unload_context(dev);
        nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
        return 0;
@@ -753,6 +758,7 @@ nv20_graph_create(struct drm_device *dev)
                        break;
                default:
                        NV_ERROR(dev, "PGRAPH: unknown chipset\n");
+                       kfree(pgraph);
                        return 0;
                }
        } else {
@@ -774,6 +780,7 @@ nv20_graph_create(struct drm_device *dev)
                        break;
                default:
                        NV_ERROR(dev, "PGRAPH: unknown chipset\n");
+                       kfree(pgraph);
                        return 0;
                }
        }
index 5beb01b..ba14a93 100644 (file)
@@ -35,89 +35,6 @@ struct nv40_graph_engine {
        u32 grctx_size;
 };
 
-static struct nouveau_channel *
-nv40_graph_channel(struct drm_device *dev)
-{
-       struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_gpuobj *grctx;
-       uint32_t inst;
-       int i;
-
-       inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
-       if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
-               return NULL;
-       inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4;
-
-       for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
-               if (!dev_priv->channels.ptr[i])
-                       continue;
-
-               grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR];
-               if (grctx && grctx->pinst == inst)
-                       return dev_priv->channels.ptr[i];
-       }
-
-       return NULL;
-}
-
-static int
-nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
-{
-       uint32_t old_cp, tv = 1000, tmp;
-       int i;
-
-       old_cp = nv_rd32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER);
-       nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
-
-       tmp  = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0310);
-       tmp |= save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE :
-                     NV40_PGRAPH_CTXCTL_0310_XFER_LOAD;
-       nv_wr32(dev, NV40_PGRAPH_CTXCTL_0310, tmp);
-
-       tmp  = nv_rd32(dev, NV40_PGRAPH_CTXCTL_0304);
-       tmp |= NV40_PGRAPH_CTXCTL_0304_XFER_CTX;
-       nv_wr32(dev, NV40_PGRAPH_CTXCTL_0304, tmp);
-
-       nouveau_wait_for_idle(dev);
-
-       for (i = 0; i < tv; i++) {
-               if (nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C) == 0)
-                       break;
-       }
-
-       nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, old_cp);
-
-       if (i == tv) {
-               uint32_t ucstat = nv_rd32(dev, NV40_PGRAPH_CTXCTL_UCODE_STAT);
-               NV_ERROR(dev, "Failed: Instance=0x%08x Save=%d\n", inst, save);
-               NV_ERROR(dev, "IP: 0x%02x, Opcode: 0x%08x\n",
-                        ucstat >> NV40_PGRAPH_CTXCTL_UCODE_STAT_IP_SHIFT,
-                        ucstat  & NV40_PGRAPH_CTXCTL_UCODE_STAT_OP_MASK);
-               NV_ERROR(dev, "0x40030C = 0x%08x\n",
-                        nv_rd32(dev, NV40_PGRAPH_CTXCTL_030C));
-               return -EBUSY;
-       }
-
-       return 0;
-}
-
-static int
-nv40_graph_unload_context(struct drm_device *dev)
-{
-       uint32_t inst;
-       int ret;
-
-       inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
-       if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
-               return 0;
-       inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE;
-
-       ret = nv40_graph_transfer_context(dev, inst, 1);
-
-       nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst);
-       return ret;
-}
-
 static int
 nv40_graph_context_new(struct nouveau_channel *chan, int engine)
 {
@@ -163,16 +80,16 @@ nv40_graph_context_del(struct nouveau_channel *chan, int engine)
        struct nouveau_gpuobj *grctx = chan->engctx[engine];
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
+       u32 inst = 0x01000000 | (grctx->pinst >> 4);
        unsigned long flags;
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-       nv04_graph_fifo_access(dev, false);
-
-       /* Unload the context if it's the currently active one */
-       if (nv40_graph_channel(dev) == chan)
-               nv40_graph_unload_context(dev);
-
-       nv04_graph_fifo_access(dev, true);
+       nv_mask(dev, 0x400720, 0x00000000, 0x00000001);
+       if (nv_rd32(dev, 0x40032c) == inst)
+               nv_mask(dev, 0x40032c, 0x01000000, 0x00000000);
+       if (nv_rd32(dev, 0x400330) == inst)
+               nv_mask(dev, 0x400330, 0x01000000, 0x00000000);
+       nv_mask(dev, 0x400720, 0x00000001, 0x00000001);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
        /* Free the context resources */
@@ -429,9 +346,20 @@ nv40_graph_init(struct drm_device *dev, int engine)
 }
 
 static int
-nv40_graph_fini(struct drm_device *dev, int engine)
+nv40_graph_fini(struct drm_device *dev, int engine, bool suspend)
 {
-       nv40_graph_unload_context(dev);
+       u32 inst = nv_rd32(dev, 0x40032c);
+       if (inst & 0x01000000) {
+               nv_wr32(dev, 0x400720, 0x00000000);
+               nv_wr32(dev, 0x400784, inst);
+               nv_mask(dev, 0x400310, 0x00000020, 0x00000020);
+               nv_mask(dev, 0x400304, 0x00000001, 0x00000001);
+               if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000)) {
+                       u32 insn = nv_rd32(dev, 0x400308);
+                       NV_ERROR(dev, "PGRAPH: ctxprog timeout 0x%08x\n", insn);
+               }
+               nv_mask(dev, 0x40032c, 0x01000000, 0x00000000);
+       }
        return 0;
 }
 
index 6d2af29..ad03a0e 100644 (file)
@@ -137,7 +137,7 @@ nv40_mpeg_init(struct drm_device *dev, int engine)
 }
 
 static int
-nv40_mpeg_fini(struct drm_device *dev, int engine)
+nv40_mpeg_fini(struct drm_device *dev, int engine, bool suspend)
 {
        /*XXX: context save? */
        nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
index e25cbb4..d27dcf0 100644 (file)
@@ -125,7 +125,6 @@ static void
 nv50_graph_init_reset(struct drm_device *dev)
 {
        uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21);
-
        NV_DEBUG(dev, "\n");
 
        nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e);
@@ -255,9 +254,13 @@ nv50_graph_init(struct drm_device *dev, int engine)
 }
 
 static int
-nv50_graph_fini(struct drm_device *dev, int engine)
+nv50_graph_fini(struct drm_device *dev, int engine, bool suspend)
 {
-       NV_DEBUG(dev, "\n");
+       nv_mask(dev, 0x400500, 0x00010001, 0x00000000);
+       if (!nv_wait(dev, 0x400700, ~0, 0) && suspend) {
+               nv_mask(dev, 0x400500, 0x00010001, 0x00010001);
+               return -EBUSY;
+       }
        nv50_graph_unload_context(dev);
        nv_wr32(dev, 0x40013c, 0x00000000);
        return 0;
index 1dc5913..b57a2d1 100644 (file)
@@ -160,7 +160,7 @@ nv50_mpeg_init(struct drm_device *dev, int engine)
 }
 
 static int
-nv50_mpeg_fini(struct drm_device *dev, int engine)
+nv50_mpeg_fini(struct drm_device *dev, int engine, bool suspend)
 {
        /*XXX: context save for s/r */
        nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
index c25c593..ffe8b48 100644 (file)
@@ -318,6 +318,8 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
                uint32_t tmp;
 
                tmp = nv_rd32(dev, 0x61c700 + (or * 0x800));
+               if (!tmp)
+                       tmp = nv_rd32(dev, 0x610798 + (or * 8));
 
                switch ((tmp & 0x00000f00) >> 8) {
                case 8:
index 75b809a..edece9c 100644 (file)
@@ -138,7 +138,7 @@ nv84_crypt_isr(struct drm_device *dev)
 }
 
 static int
-nv84_crypt_fini(struct drm_device *dev, int engine)
+nv84_crypt_fini(struct drm_device *dev, int engine, bool suspend)
 {
        nv_wr32(dev, 0x102140, 0x00000000);
        return 0;
index b86820a..8f356d5 100644 (file)
@@ -140,7 +140,7 @@ nva3_copy_init(struct drm_device *dev, int engine)
 }
 
 static int
-nva3_copy_fini(struct drm_device *dev, int engine)
+nva3_copy_fini(struct drm_device *dev, int engine, bool suspend)
 {
        nv_mask(dev, 0x104048, 0x00000003, 0x00000000);
 
index 5ebcd74..dddf006 100644 (file)
@@ -127,7 +127,7 @@ nvc0_copy_init(struct drm_device *dev, int engine)
 }
 
 static int
-nvc0_copy_fini(struct drm_device *dev, int engine)
+nvc0_copy_fini(struct drm_device *dev, int engine, bool suspend)
 {
        struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
 
index 3a97431..5b2f6f4 100644 (file)
@@ -304,7 +304,7 @@ nvc0_graph_object_new(struct nouveau_channel *chan, int engine,
 }
 
 static int
-nvc0_graph_fini(struct drm_device *dev, int engine)
+nvc0_graph_fini(struct drm_device *dev, int engine, bool suspend)
 {
        return 0;
 }