drm/nve0: allow specification of channel engine type in abi16 call
authorBen Skeggs <bskeggs@redhat.com>
Thu, 22 Nov 2012 03:43:55 +0000 (13:43 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:58:05 +0000 (09:58 +1000)
Previously, if either vram/gart handles were specified as ~0, the ioctl
call would fail.  In order to hack engine selection into the ioctl for
kepler, we now define (fb_ctxdma_handle == ~0) to mean "engine mask is
in tt_ctxdma_handle".

This approach also allows new userspace to detect lack of support for
non-PGRAPH channels on older kernels.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_drm.c

index 2720ce009664eeae41d1ec7817357e24532dc9ba..d48c02a365271fff00524dc8f890da1116f0651b 100644 (file)
@@ -242,14 +242,26 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
        if (unlikely(!abi16))
                return -ENOMEM;
        client = nv_client(abi16->client);
-
-       if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
-               return nouveau_abi16_put(abi16, -EINVAL);
-
        device = nv_device(abi16->device);
        imem   = nouveau_instmem(device);
        pfb    = nouveau_fb(device);
 
+       /* hack to allow channel engine type specification on kepler */
+       if (device->card_type >= NV_E0) {
+               if (init->fb_ctxdma_handle != ~0)
+                       init->fb_ctxdma_handle = NVE0_CHANNEL_IND_ENGINE_GR;
+               else
+                       init->fb_ctxdma_handle = init->tt_ctxdma_handle;
+
+               /* allow flips to be executed if this is a graphics channel */
+               init->tt_ctxdma_handle = 0;
+               if (init->fb_ctxdma_handle == NVE0_CHANNEL_IND_ENGINE_GR)
+                       init->tt_ctxdma_handle = 1;
+       }
+
+       if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
+               return nouveau_abi16_put(abi16, -EINVAL);
+
        /* allocate "abi16 channel" data and make up a handle for it */
        init->channel = ffsll(~abi16->handles);
        if (!init->channel--)
@@ -264,11 +276,6 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
        abi16->handles |= (1 << init->channel);
 
        /* create channel object and initialise dma and fence management */
-       if (device->card_type >= NV_E0) {
-               init->fb_ctxdma_handle = NVE0_CHANNEL_IND_ENGINE_GR;
-               init->tt_ctxdma_handle = 0;
-       }
-
        ret = nouveau_channel_new(drm, cli, NVDRM_DEVICE, NVDRM_CHAN |
                                  init->channel, init->fb_ctxdma_handle,
                                  init->tt_ctxdma_handle, &chan->chan);
index 049c6b23e1d7c7d569c77299ace00f1f9b26b590..1363578bf94570f6f46226c456d8ed6e20138677 100644 (file)
@@ -346,7 +346,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
        /* allocate software object class (used for fences on <= nv05, and
         * to signal flip completion), bind it to a subchannel.
         */
-       if (chan != chan->drm->cechan) {
+       if ((device->card_type < NV_E0) || gart /* nve0: want_nvsw */) {
                ret = nouveau_object_new(nv_object(client), chan->handle,
                                         NvSw, nouveau_abi16_swclass(chan->drm),
                                         NULL, 0, &object);
index f62dbd2733bf77ec948a58db78e8afe724394fd8..919186c4651bbff9de2f04f25654a1988ae3426d 100644 (file)
@@ -148,7 +148,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
                        NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
 
                arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
-               arg1 = 0;
+               arg1 = 1;
        } else {
                arg0 = NvDmaFB;
                arg1 = NvDmaTT;