drm/nvc0: support for sw methods + enable page flipping
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 Feb 2011 05:16:23 +0000 (15:16 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 24 Feb 2011 20:45:20 +0000 (06:45 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/nouveau/nvc0_graph.c

index d6da139155d62701ff68c98c2d76267466544281..c42d84e26763960a0d7de0b81043aeb730db2da0 100644 (file)
@@ -224,6 +224,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
                       struct nouveau_page_flip_state *s,
                       struct nouveau_fence **pfence)
 {
+       struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
        struct drm_device *dev = chan->dev;
        unsigned long flags;
        int ret;
@@ -243,9 +244,12 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
        if (ret)
                goto fail;
 
-       BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
-       OUT_RING(chan, 0);
-       FIRE_RING(chan);
+       if (dev_priv->card_type < NV_C0)
+               BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
+       else
+               BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1);
+       OUT_RING  (chan, 0);
+       FIRE_RING (chan);
 
        ret = nouveau_fence_new(chan, pfence, true);
        if (ret)
index e03cd34454660560b93e1a49ae22eefe1ab09ffb..43acfc2aded5237db7ed75022c5e532632754908 100644 (file)
@@ -1118,7 +1118,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
                getparam->value = 1;
                break;
        case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
-               getparam->value = (dev_priv->card_type < NV_C0) ? 1 : 0;
+               getparam->value = 1;
                break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register
index afa7afe4ef9234dfd2cc212f5a1127392c10b8c6..3de9b721d8dbe61260af7487ce086fc23acaa758 100644 (file)
@@ -298,6 +298,14 @@ nvc0_graph_takedown(struct drm_device *dev)
        nvc0_graph_destroy(dev);
 }
 
+static int
+nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
+                         u32 class, u32 mthd, u32 data)
+{
+       nouveau_finish_page_flip(chan, NULL);
+       return 0;
+}
+
 static int
 nvc0_graph_create(struct drm_device *dev)
 {
@@ -395,6 +403,7 @@ nvc0_graph_create(struct drm_device *dev)
        nouveau_irq_register(dev, 25, nvc0_runk140_isr);
        NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
        NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
+       NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
        NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
        NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
        return 0;
@@ -728,9 +737,12 @@ nvc0_graph_isr(struct drm_device *dev)
        u32 class = nv_rd32(dev, 0x404200 + (subc * 4));
 
        if (stat & 0x00000010) {
-               NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] subc %d "
-                            "class 0x%04x mthd 0x%04x data 0x%08x\n",
-                       chid, inst, subc, class, mthd, data);
+               if (nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) {
+                       NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] "
+                                    "subc %d class 0x%04x mthd 0x%04x "
+                                    "data 0x%08x\n",
+                               chid, inst, subc, class, mthd, data);
+               }
                nv_wr32(dev, 0x400100, 0x00000010);
                stat &= ~0x00000010;
        }