drm/nouveau/gr: remove dependence on namedb/engctx lookup
authorBen Skeggs <bskeggs@redhat.com>
Thu, 20 Aug 2015 04:54:18 +0000 (14:54 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 28 Aug 2015 02:40:38 +0000 (12:40 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
15 files changed:
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c

index 362d5fa..c6ff24b 100644 (file)
 #include "fuc/os.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <core/option.h>
-#include <engine/fifo.h>
 #include <subdev/fb.h>
 #include <subdev/mc.h>
 #include <subdev/timer.h>
+#include <engine/fifo.h>
 
 #include <nvif/class.h>
 #include <nvif/unpack.h>
@@ -233,39 +232,39 @@ gf100_fermi_ofuncs = {
        .mthd = gf100_fermi_mthd,
 };
 
-static int
-gf100_gr_set_shader_exceptions(struct nvkm_object *object, u32 mthd,
-                              void *pdata, u32 size)
+static void
+gf100_gr_mthd_set_shader_exceptions(struct nvkm_device *device, u32 data)
 {
-       struct gf100_gr *gr = (void *)object->engine;
-       struct nvkm_device *device = gr->base.engine.subdev.device;
-       if (size >= sizeof(u32)) {
-               u32 data = *(u32 *)pdata ? 0xffffffff : 0x00000000;
-               nvkm_wr32(device, 0x419e44, data);
-               nvkm_wr32(device, 0x419e4c, data);
-               return 0;
-       }
-       return -EINVAL;
+       nvkm_wr32(device, 0x419e44, data ? 0xffffffff : 0x00000000);
+       nvkm_wr32(device, 0x419e4c, data ? 0xffffffff : 0x00000000);
 }
 
-struct nvkm_omthds
-gf100_gr_9097_omthds[] = {
-       { 0x1528, 0x1528, gf100_gr_set_shader_exceptions },
-       {}
-};
-
-struct nvkm_omthds
-gf100_gr_90c0_omthds[] = {
-       { 0x1528, 0x1528, gf100_gr_set_shader_exceptions },
-       {}
-};
+static bool
+gf100_gr_mthd_sw(struct nvkm_device *device, u16 class, u32 mthd, u32 data)
+{
+       switch (class & 0x00ff) {
+       case 0x97:
+       case 0xc0:
+               switch (mthd) {
+               case 0x1528:
+                       gf100_gr_mthd_set_shader_exceptions(device, data);
+                       return true;
+               default:
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+       return false;
+}
 
 struct nvkm_oclass
 gf100_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { FERMI_MEMORY_TO_MEMORY_FORMAT_A, &nvkm_object_ofuncs },
-       { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { FERMI_A, &gf100_fermi_ofuncs },
+       { FERMI_COMPUTE_A, &nvkm_object_ofuncs },
        {}
 };
 
@@ -365,7 +364,6 @@ gf100_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
                nvkm_wo32(image, 0x2c, 0);
        }
        nvkm_done(image);
-
        return 0;
 }
 
@@ -1160,10 +1158,8 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
 {
        struct gf100_gr *gr = (void *)subdev;
        struct nvkm_device *device = gr->base.engine.subdev.device;
-       struct nvkm_fifo *fifo = device->fifo;
-       struct nvkm_engine *engine = nv_engine(subdev);
-       struct nvkm_object *engctx;
-       struct nvkm_handle *handle;
+       struct nvkm_fifo_chan *chan;
+       unsigned long flags;
        u64 inst = nvkm_rd32(device, 0x409b00) & 0x0fffffff;
        u32 stat = nvkm_rd32(device, 0x400100);
        u32 addr = nvkm_rd32(device, 0x400704);
@@ -1174,14 +1170,14 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
        u32 class;
        int chid;
 
+       chan = nvkm_fifo_chan_inst(device->fifo, (u64)inst << 12, &flags);
+       chid = chan ? chan->chid : -1;
+
        if (nv_device(gr)->card_type < NV_E0 || subc < 4)
                class = nvkm_rd32(device, 0x404200 + (subc * 4));
        else
                class = 0x0000;
 
-       engctx = nvkm_engctx_get(engine, inst);
-       chid   = fifo->chid(fifo, engctx);
-
        if (stat & 0x00000001) {
                /*
                 * notifier interrupt, only needed for cyclestats
@@ -1192,14 +1188,12 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
        }
 
        if (stat & 0x00000010) {
-               handle = nvkm_handle_get_class(engctx, class);
-               if (!handle || nv_call(handle->object, mthd, data)) {
+               if (!gf100_gr_mthd_sw(device, class, mthd, data)) {
                        nvkm_error(subdev, "ILLEGAL_MTHD ch %d [%010llx %s] "
                                   "subc %d class %04x mthd %04x data %08x\n",
-                                  chid, inst << 12, nvkm_client_name(engctx),
+                                  chid, inst << 12, nvkm_client_name(chan),
                                   subc, class, mthd, data);
                }
-               nvkm_handle_put(handle);
                nvkm_wr32(device, 0x400100, 0x00000010);
                stat &= ~0x00000010;
        }
@@ -1207,7 +1201,7 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
        if (stat & 0x00000020) {
                nvkm_error(subdev, "ILLEGAL_CLASS ch %d [%010llx %s] "
                           "subc %d class %04x mthd %04x data %08x\n",
-                          chid, inst << 12, nvkm_client_name(engctx), subc,
+                          chid, inst << 12, nvkm_client_name(chan), subc,
                           class, mthd, data);
                nvkm_wr32(device, 0x400100, 0x00000020);
                stat &= ~0x00000020;
@@ -1219,15 +1213,14 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
                nvkm_error(subdev, "DATA_ERROR %08x [%s] ch %d [%010llx %s] "
                                   "subc %d class %04x mthd %04x data %08x\n",
                           code, en ? en->name : "", chid, inst << 12,
-                          nvkm_client_name(engctx), subc, class, mthd, data);
+                          nvkm_client_name(chan), subc, class, mthd, data);
                nvkm_wr32(device, 0x400100, 0x00100000);
                stat &= ~0x00100000;
        }
 
        if (stat & 0x00200000) {
                nvkm_error(subdev, "TRAP ch %d [%010llx %s]\n",
-                          chid, inst << 12,
-                          nvkm_client_name(engctx));
+                          chid, inst << 12, nvkm_client_name(chan));
                gf100_gr_trap_intr(gr);
                nvkm_wr32(device, 0x400100, 0x00200000);
                stat &= ~0x00200000;
@@ -1245,7 +1238,7 @@ gf100_gr_intr(struct nvkm_subdev *subdev)
        }
 
        nvkm_wr32(device, 0x400500, 0x00010001);
-       nvkm_engctx_put(engctx);
+       nvkm_fifo_chan_put(device->fifo, flags, &chan);
 }
 
 void
index 62bf569..612d534 100644 (file)
@@ -152,8 +152,6 @@ int  gm204_gr_init(struct nvkm_object *);
 extern struct nvkm_ofuncs gf100_fermi_ofuncs;
 
 extern struct nvkm_oclass gf100_gr_sclass[];
-extern struct nvkm_omthds gf100_gr_9097_omthds[];
-extern struct nvkm_omthds gf100_gr_90c0_omthds[];
 extern struct nvkm_oclass gf110_gr_sclass[];
 extern struct nvkm_oclass gk110_gr_sclass[];
 extern struct nvkm_oclass gm204_gr_sclass[];
index 8df7342..1e8290a 100644 (file)
@@ -34,9 +34,9 @@ static struct nvkm_oclass
 gf108_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { FERMI_MEMORY_TO_MEMORY_FORMAT_A, &nvkm_object_ofuncs },
-       { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { FERMI_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { FERMI_A, &gf100_fermi_ofuncs },
+       { FERMI_B, &gf100_fermi_ofuncs },
+       { FERMI_COMPUTE_A, &nvkm_object_ofuncs },
        {}
 };
 
index ef76e2d..4fe0f96 100644 (file)
@@ -34,10 +34,10 @@ struct nvkm_oclass
 gf110_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { FERMI_MEMORY_TO_MEMORY_FORMAT_A, &nvkm_object_ofuncs },
-       { FERMI_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { FERMI_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { FERMI_C, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { FERMI_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { FERMI_A, &gf100_fermi_ofuncs },
+       { FERMI_B, &gf100_fermi_ofuncs },
+       { FERMI_C, &gf100_fermi_ofuncs },
+       { FERMI_COMPUTE_A, &nvkm_object_ofuncs },
        {}
 };
 
index 94c6ca1..a007319 100644 (file)
@@ -36,8 +36,8 @@ static struct nvkm_oclass
 gk104_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { KEPLER_INLINE_TO_MEMORY_A, &nvkm_object_ofuncs },
-       { KEPLER_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { KEPLER_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { KEPLER_A, &gf100_fermi_ofuncs },
+       { KEPLER_COMPUTE_A, &nvkm_object_ofuncs },
        {}
 };
 
index f4cd8e5..ec21f62 100644 (file)
@@ -36,8 +36,8 @@ struct nvkm_oclass
 gk110_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { KEPLER_INLINE_TO_MEMORY_B, &nvkm_object_ofuncs },
-       { KEPLER_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { KEPLER_COMPUTE_B, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { KEPLER_B, &gf100_fermi_ofuncs },
+       { KEPLER_COMPUTE_B, &nvkm_object_ofuncs },
        {}
 };
 
index a80fda5..c213e9a 100644 (file)
@@ -29,8 +29,8 @@ static struct nvkm_oclass
 gk20a_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { KEPLER_INLINE_TO_MEMORY_A, &nvkm_object_ofuncs },
-       { KEPLER_C, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { KEPLER_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { KEPLER_C, &gf100_fermi_ofuncs },
+       { KEPLER_COMPUTE_A, &nvkm_object_ofuncs },
        {}
 };
 
index 97b0e1a..aad5fdb 100644 (file)
@@ -37,8 +37,8 @@ static struct nvkm_oclass
 gm107_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { KEPLER_INLINE_TO_MEMORY_B, &nvkm_object_ofuncs },
-       { MAXWELL_A, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { MAXWELL_COMPUTE_A, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { MAXWELL_A, &gf100_fermi_ofuncs },
+       { MAXWELL_COMPUTE_A, &nvkm_object_ofuncs },
        {}
 };
 
index 0a8d850..39f42a1 100644 (file)
@@ -34,8 +34,8 @@ struct nvkm_oclass
 gm204_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { KEPLER_INLINE_TO_MEMORY_B, &nvkm_object_ofuncs },
-       { MAXWELL_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { MAXWELL_COMPUTE_B, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { MAXWELL_B, &gf100_fermi_ofuncs },
+       { MAXWELL_COMPUTE_B, &nvkm_object_ofuncs },
        {}
 };
 
index 719ebfb..8738892 100644 (file)
@@ -29,8 +29,8 @@ static struct nvkm_oclass
 gm20b_gr_sclass[] = {
        { FERMI_TWOD_A, &nvkm_object_ofuncs },
        { KEPLER_INLINE_TO_MEMORY_B, &nvkm_object_ofuncs },
-       { MAXWELL_B, &gf100_fermi_ofuncs, gf100_gr_9097_omthds },
-       { MAXWELL_COMPUTE_B, &nvkm_object_ofuncs, gf100_gr_90c0_omthds },
+       { MAXWELL_B, &gf100_fermi_ofuncs },
+       { MAXWELL_COMPUTE_B, &nvkm_object_ofuncs },
        {}
 };
 
index 617161e..b15b864 100644 (file)
@@ -25,7 +25,6 @@
 #include "regs.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <engine/fifo.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
@@ -443,42 +442,34 @@ nv04_gr(struct nv04_gr_chan *chan)
  */
 
 static void
-nv04_gr_set_ctx1(struct nvkm_object *obj, u32 mask, u32 value)
+nv04_gr_set_ctx1(struct nvkm_device *device, u32 inst, u32 mask, u32 value)
 {
-       struct nvkm_gpuobj *object = container_of(obj, typeof(*object), object);
-       struct nv04_gr *gr = (void *)object->object.engine;
-       struct nvkm_device *device = gr->base.engine.subdev.device;
        int subc = (nvkm_rd32(device, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7;
        u32 tmp;
 
-       nvkm_kmap(object);
-       tmp  = nvkm_ro32(object, 0x00);
+       tmp  = nvkm_rd32(device, 0x700000 + inst);
        tmp &= ~mask;
        tmp |= value;
-       nvkm_wo32(object, 0x00, tmp);
-       nvkm_done(object);
+       nvkm_wr32(device, 0x700000 + inst, tmp);
 
        nvkm_wr32(device, NV04_PGRAPH_CTX_SWITCH1, tmp);
-       nvkm_wr32(device, NV04_PGRAPH_CTX_CACHE1 + (subc<<2), tmp);
+       nvkm_wr32(device, NV04_PGRAPH_CTX_CACHE1 + (subc << 2), tmp);
 }
 
 static void
-nv04_gr_set_ctx_val(struct nvkm_object *obj, u32 mask, u32 value)
+nv04_gr_set_ctx_val(struct nvkm_device *device, u32 inst, u32 mask, u32 value)
 {
-       struct nvkm_gpuobj *object = container_of(obj, typeof(*object), object);
        int class, op, valid = 1;
        u32 tmp, ctx1;
 
-       nvkm_kmap(object);
-       ctx1 = nvkm_ro32(object, 0x00);
+       ctx1 = nvkm_rd32(device, 0x700000 + inst);
        class = ctx1 & 0xff;
        op = (ctx1 >> 15) & 7;
 
-       tmp = nvkm_ro32(object, 0x0c);
+       tmp = nvkm_rd32(device, 0x70000c + inst);
        tmp &= ~mask;
        tmp |= value;
-       nvkm_wo32(object, 0x0c, tmp);
-       nvkm_done(object);
+       nvkm_wr32(device, 0x70000c + inst, tmp);
 
        /* check for valid surf2d/surf_dst/surf_color */
        if (!(tmp & 0x02000000))
@@ -510,39 +501,32 @@ nv04_gr_set_ctx_val(struct nvkm_object *obj, u32 mask, u32 value)
                break;
        }
 
-       nv04_gr_set_ctx1(obj, 0x01000000, valid << 24);
+       nv04_gr_set_ctx1(device, inst, 0x01000000, valid << 24);
 }
 
-static int
-nv04_gr_mthd_set_operation(struct nvkm_object *obj, u32 mthd,
-                          void *args, u32 size)
+static bool
+nv04_gr_mthd_set_operation(struct nvkm_device *device, u32 inst, u32 data)
 {
-       struct nvkm_gpuobj *object = container_of(obj, typeof(*object), object);
-       u32 class = nvkm_ro32(object, 0) & 0xff;
-       u32 data = *(u32 *)args;
+       u8 class = nvkm_rd32(device, 0x700000) & 0x000000ff;
        if (data > 5)
-               return 1;
+               return false;
        /* Old versions of the objects only accept first three operations. */
        if (data > 2 && class < 0x40)
-               return 1;
-       nv04_gr_set_ctx1(obj, 0x00038000, data << 15);
+               return false;
+       nv04_gr_set_ctx1(device, inst, 0x00038000, data << 15);
        /* changing operation changes set of objects needed for validation */
-       nv04_gr_set_ctx_val(obj, 0, 0);
-       return 0;
+       nv04_gr_set_ctx_val(device, inst, 0, 0);
+       return true;
 }
 
-static int
-nv04_gr_mthd_surf3d_clip_h(struct nvkm_object *object, u32 mthd,
-                          void *args, u32 size)
+static bool
+nv04_gr_mthd_surf3d_clip_h(struct nvkm_device *device, u32 inst, u32 data)
 {
-       struct nv04_gr *gr = (void *)object->engine;
-       struct nvkm_device *device = gr->base.engine.subdev.device;
-       u32 data = *(u32 *)args;
        u32 min = data & 0xffff, max;
        u32 w = data >> 16;
        if (min & 0x8000)
                /* too large */
-               return 1;
+               return false;
        if (w & 0x8000)
                /* yes, it accepts negative for some reason. */
                w |= 0xffff0000;
@@ -550,21 +534,17 @@ nv04_gr_mthd_surf3d_clip_h(struct nvkm_object *object, u32 mthd,
        max &= 0x3ffff;
        nvkm_wr32(device, 0x40053c, min);
        nvkm_wr32(device, 0x400544, max);
-       return 0;
+       return true;
 }
 
-static int
-nv04_gr_mthd_surf3d_clip_v(struct nvkm_object *object, u32 mthd,
-                          void *args, u32 size)
+static bool
+nv04_gr_mthd_surf3d_clip_v(struct nvkm_device *device, u32 inst, u32 data)
 {
-       struct nv04_gr *gr = (void *)object->engine;
-       struct nvkm_device *device = gr->base.engine.subdev.device;
-       u32 data = *(u32 *)args;
        u32 min = data & 0xffff, max;
        u32 w = data >> 16;
        if (min & 0x8000)
                /* too large */
-               return 1;
+               return false;
        if (w & 0x8000)
                /* yes, it accepts negative for some reason. */
                w |= 0xffff0000;
@@ -572,389 +552,492 @@ nv04_gr_mthd_surf3d_clip_v(struct nvkm_object *object, u32 mthd,
        max &= 0x3ffff;
        nvkm_wr32(device, 0x400540, min);
        nvkm_wr32(device, 0x400548, max);
-       return 0;
+       return true;
 }
 
-static u16
-nv04_gr_mthd_bind_class(struct nvkm_object *object, u32 *args, u32 size)
+static u8
+nv04_gr_mthd_bind_class(struct nvkm_device *device, u32 inst)
 {
-       struct nvkm_instmem *imem = nvkm_instmem(object);
-       u32 inst = *(u32 *)args << 4;
-       return imem->func->rd32(imem, inst);
+       return nvkm_rd32(device, 0x700000 + (inst << 4));
 }
 
-static int
-nv04_gr_mthd_bind_surf2d(struct nvkm_object *object, u32 mthd,
-                           void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_surf2d(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx1(object, 0x00004000, 0);
-               nv04_gr_set_ctx_val(object, 0x02000000, 0);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x00004000, 0);
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0);
+               return true;
        case 0x42:
-               nv04_gr_set_ctx1(object, 0x00004000, 0);
-               nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x00004000, 0);
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_surf2d_swzsurf(struct nvkm_object *object, u32 mthd,
-                                void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_surf2d_swzsurf(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx1(object, 0x00004000, 0);
-               nv04_gr_set_ctx_val(object, 0x02000000, 0);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x00004000, 0);
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0);
+               return true;
        case 0x42:
-               nv04_gr_set_ctx1(object, 0x00004000, 0);
-               nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x00004000, 0);
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000);
+               return true;
        case 0x52:
-               nv04_gr_set_ctx1(object, 0x00004000, 0x00004000);
-               nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x00004000, 0x00004000);
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv01_gr_mthd_bind_patt(struct nvkm_object *object, u32 mthd,
-                      void *args, u32 size)
+static bool
+nv01_gr_mthd_bind_patt(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x08000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x08000000, 0);
+               return true;
        case 0x18:
-               nv04_gr_set_ctx_val(object, 0x08000000, 0x08000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x08000000, 0x08000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_patt(struct nvkm_object *object, u32 mthd,
-                      void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_patt(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x08000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x08000000, 0);
+               return true;
        case 0x44:
-               nv04_gr_set_ctx_val(object, 0x08000000, 0x08000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x08000000, 0x08000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_rop(struct nvkm_object *object, u32 mthd,
-                     void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_rop(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x10000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x10000000, 0);
+               return true;
        case 0x43:
-               nv04_gr_set_ctx_val(object, 0x10000000, 0x10000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x10000000, 0x10000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_beta1(struct nvkm_object *object, u32 mthd,
-                       void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_beta1(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x20000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x20000000, 0);
+               return true;
        case 0x12:
-               nv04_gr_set_ctx_val(object, 0x20000000, 0x20000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x20000000, 0x20000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_beta4(struct nvkm_object *object, u32 mthd,
-                       void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_beta4(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x40000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x40000000, 0);
+               return true;
        case 0x72:
-               nv04_gr_set_ctx_val(object, 0x40000000, 0x40000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x40000000, 0x40000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_surf_dst(struct nvkm_object *object, u32 mthd,
-                          void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_surf_dst(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x02000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0);
+               return true;
        case 0x58:
-               nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_surf_src(struct nvkm_object *object, u32 mthd,
-                          void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_surf_src(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x04000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x04000000, 0);
+               return true;
        case 0x59:
-               nv04_gr_set_ctx_val(object, 0x04000000, 0x04000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x04000000, 0x04000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_surf_color(struct nvkm_object *object, u32 mthd,
-                            void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_surf_color(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x02000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0);
+               return true;
        case 0x5a:
-               nv04_gr_set_ctx_val(object, 0x02000000, 0x02000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x02000000, 0x02000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv04_gr_mthd_bind_surf_zeta(struct nvkm_object *object, u32 mthd,
-                           void *args, u32 size)
+static bool
+nv04_gr_mthd_bind_surf_zeta(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx_val(object, 0x04000000, 0);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x04000000, 0);
+               return true;
        case 0x5b:
-               nv04_gr_set_ctx_val(object, 0x04000000, 0x04000000);
-               return 0;
+               nv04_gr_set_ctx_val(device, inst, 0x04000000, 0x04000000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv01_gr_mthd_bind_clip(struct nvkm_object *object, u32 mthd,
-                      void *args, u32 size)
+static bool
+nv01_gr_mthd_bind_clip(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx1(object, 0x2000, 0);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x2000, 0);
+               return true;
        case 0x19:
-               nv04_gr_set_ctx1(object, 0x2000, 0x2000);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x2000, 0x2000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static int
-nv01_gr_mthd_bind_chroma(struct nvkm_object *object, u32 mthd,
-                        void *args, u32 size)
+static bool
+nv01_gr_mthd_bind_chroma(struct nvkm_device *device, u32 inst, u32 data)
 {
-       switch (nv04_gr_mthd_bind_class(object, args, size)) {
+       switch (nv04_gr_mthd_bind_class(device, data)) {
        case 0x30:
-               nv04_gr_set_ctx1(object, 0x1000, 0);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x1000, 0);
+               return true;
        /* Yes, for some reason even the old versions of objects
         * accept 0x57 and not 0x17. Consistency be damned.
         */
        case 0x57:
-               nv04_gr_set_ctx1(object, 0x1000, 0x1000);
-               return 0;
+               nv04_gr_set_ctx1(device, inst, 0x1000, 0x1000);
+               return true;
        }
-       return 1;
+       return false;
 }
 
-static struct nvkm_omthds
-nv03_gr_gdi_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_patt },
-       { 0x0188, 0x0188, nv04_gr_mthd_bind_rop },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_beta1 },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_surf_dst },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv03_gr_mthd_gdi(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_patt; break;
+       case 0x0188: func = nv04_gr_mthd_bind_rop; break;
+       case 0x018c: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0190: func = nv04_gr_mthd_bind_surf_dst; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_gdi_omthds[] = {
-       { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_gdi(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0188: func = nv04_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x0198: func = nv04_gr_mthd_bind_surf2d; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv01_gr_blit_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
-       { 0x018c, 0x018c, nv01_gr_mthd_bind_patt },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_surf_dst },
-       { 0x019c, 0x019c, nv04_gr_mthd_bind_surf_src },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv01_gr_mthd_blit(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x0188: func = nv01_gr_mthd_bind_clip; break;
+       case 0x018c: func = nv01_gr_mthd_bind_patt; break;
+       case 0x0190: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0198: func = nv04_gr_mthd_bind_surf_dst; break;
+       case 0x019c: func = nv04_gr_mthd_bind_surf_src; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_blit_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_patt },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_beta4 },
-       { 0x019c, 0x019c, nv04_gr_mthd_bind_surf2d },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_blit(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x0188: func = nv01_gr_mthd_bind_clip; break;
+       case 0x018c: func = nv04_gr_mthd_bind_patt; break;
+       case 0x0190: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0198: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x019c: func = nv04_gr_mthd_bind_surf2d; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_iifc_omthds[] = {
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_chroma },
-       { 0x018c, 0x018c, nv01_gr_mthd_bind_clip },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_patt },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_rop },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_beta1 },
-       { 0x019c, 0x019c, nv04_gr_mthd_bind_beta4 },
-       { 0x01a0, 0x01a0, nv04_gr_mthd_bind_surf2d_swzsurf },
-       { 0x03e4, 0x03e4, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_iifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0188: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x018c: func = nv01_gr_mthd_bind_clip; break;
+       case 0x0190: func = nv04_gr_mthd_bind_patt; break;
+       case 0x0194: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0198: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x019c: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x01a0: func = nv04_gr_mthd_bind_surf2d_swzsurf; break;
+       case 0x03e4: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv01_gr_ifc_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
-       { 0x018c, 0x018c, nv01_gr_mthd_bind_patt },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_surf_dst },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv01_gr_mthd_ifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x0188: func = nv01_gr_mthd_bind_clip; break;
+       case 0x018c: func = nv01_gr_mthd_bind_patt; break;
+       case 0x0190: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0198: func = nv04_gr_mthd_bind_surf_dst; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_ifc_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_patt },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_rop },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta1 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_beta4 },
-       { 0x019c, 0x019c, nv04_gr_mthd_bind_surf2d },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_ifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x0188: func = nv01_gr_mthd_bind_clip; break;
+       case 0x018c: func = nv04_gr_mthd_bind_patt; break;
+       case 0x0190: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0198: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x019c: func = nv04_gr_mthd_bind_surf2d; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv03_gr_sifc_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv03_gr_mthd_sifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x0188: func = nv01_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_surf_dst; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_sifc_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_chroma },
-       { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_sifc(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_chroma; break;
+       case 0x0188: func = nv04_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x0198: func = nv04_gr_mthd_bind_surf2d; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv03_gr_sifm_omthds[] = {
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
-       { 0x0304, 0x0304, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv03_gr_mthd_sifm(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0188: func = nv01_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_surf_dst; break;
+       case 0x0304: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_sifm_omthds[] = {
-       { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
-       { 0x0304, 0x0304, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_sifm(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0188: func = nv04_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x0198: func = nv04_gr_mthd_bind_surf2d; break;
+       case 0x0304: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_surf3d_omthds[] = {
-       { 0x02f8, 0x02f8, nv04_gr_mthd_surf3d_clip_h },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_surf3d_clip_v },
-       {}
-};
+static bool
+nv04_gr_mthd_surf3d(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x02f8: func = nv04_gr_mthd_surf3d_clip_h; break;
+       case 0x02fc: func = nv04_gr_mthd_surf3d_clip_v; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv03_gr_ttri_omthds[] = {
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_clip },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_surf_color },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_surf_zeta },
-       {}
-};
+static bool
+nv03_gr_mthd_ttri(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0188: func = nv01_gr_mthd_bind_clip; break;
+       case 0x018c: func = nv04_gr_mthd_bind_surf_color; break;
+       case 0x0190: func = nv04_gr_mthd_bind_surf_zeta; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv01_gr_prim_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_clip },
-       { 0x0188, 0x0188, nv01_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_surf_dst },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv01_gr_mthd_prim(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_clip; break;
+       case 0x0188: func = nv01_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_surf_dst; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
 
-static struct nvkm_omthds
-nv04_gr_prim_omthds[] = {
-       { 0x0184, 0x0184, nv01_gr_mthd_bind_clip },
-       { 0x0188, 0x0188, nv04_gr_mthd_bind_patt },
-       { 0x018c, 0x018c, nv04_gr_mthd_bind_rop },
-       { 0x0190, 0x0190, nv04_gr_mthd_bind_beta1 },
-       { 0x0194, 0x0194, nv04_gr_mthd_bind_beta4 },
-       { 0x0198, 0x0198, nv04_gr_mthd_bind_surf2d },
-       { 0x02fc, 0x02fc, nv04_gr_mthd_set_operation },
-       {}
-};
+static bool
+nv04_gr_mthd_prim(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32);
+       switch (mthd) {
+       case 0x0184: func = nv01_gr_mthd_bind_clip; break;
+       case 0x0188: func = nv04_gr_mthd_bind_patt; break;
+       case 0x018c: func = nv04_gr_mthd_bind_rop; break;
+       case 0x0190: func = nv04_gr_mthd_bind_beta1; break;
+       case 0x0194: func = nv04_gr_mthd_bind_beta4; break;
+       case 0x0198: func = nv04_gr_mthd_bind_surf2d; break;
+       case 0x02fc: func = nv04_gr_mthd_set_operation; break;
+       default:
+               return false;
+       }
+       return func(device, inst, data);
+}
+
+static bool
+nv04_gr_mthd(struct nvkm_device *device, u32 inst, u32 mthd, u32 data)
+{
+       bool (*func)(struct nvkm_device *, u32, u32, u32);
+       switch (nvkm_rd32(device, 0x700000 + inst) & 0x000000ff) {
+       case 0x1c ... 0x1e:
+                  func = nv01_gr_mthd_prim; break;
+       case 0x1f: func = nv01_gr_mthd_blit; break;
+       case 0x21: func = nv01_gr_mthd_ifc; break;
+       case 0x36: func = nv03_gr_mthd_sifc; break;
+       case 0x37: func = nv03_gr_mthd_sifm; break;
+       case 0x48: func = nv03_gr_mthd_ttri; break;
+       case 0x4a: func = nv04_gr_mthd_gdi; break;
+       case 0x4b: func = nv03_gr_mthd_gdi; break;
+       case 0x53: func = nv04_gr_mthd_surf3d; break;
+       case 0x5c ... 0x5e:
+                  func = nv04_gr_mthd_prim; break;
+       case 0x5f: func = nv04_gr_mthd_blit; break;
+       case 0x60: func = nv04_gr_mthd_iifc; break;
+       case 0x61: func = nv04_gr_mthd_ifc; break;
+       case 0x76: func = nv04_gr_mthd_sifc; break;
+       case 0x77: func = nv04_gr_mthd_sifm; break;
+       default:
+               return false;
+       }
+       return func(device, inst, mthd, data);
+}
 
 static int
 nv04_gr_object_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
@@ -998,24 +1081,24 @@ nv04_gr_sclass[] = {
        { 0x0017, &nv04_gr_ofuncs }, /* chroma */
        { 0x0018, &nv04_gr_ofuncs }, /* pattern (nv01) */
        { 0x0019, &nv04_gr_ofuncs }, /* clip */
-       { 0x001c, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* line */
-       { 0x001d, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* tri */
-       { 0x001e, &nv04_gr_ofuncs, nv01_gr_prim_omthds }, /* rect */
-       { 0x001f, &nv04_gr_ofuncs, nv01_gr_blit_omthds },
-       { 0x0021, &nv04_gr_ofuncs, nv01_gr_ifc_omthds },
+       { 0x001c, &nv04_gr_ofuncs }, /* line */
+       { 0x001d, &nv04_gr_ofuncs }, /* tri */
+       { 0x001e, &nv04_gr_ofuncs }, /* rect */
+       { 0x001f, &nv04_gr_ofuncs },
+       { 0x0021, &nv04_gr_ofuncs },
        { 0x0030, &nv04_gr_ofuncs }, /* null */
-       { 0x0036, &nv04_gr_ofuncs, nv03_gr_sifc_omthds },
-       { 0x0037, &nv04_gr_ofuncs, nv03_gr_sifm_omthds },
+       { 0x0036, &nv04_gr_ofuncs },
+       { 0x0037, &nv04_gr_ofuncs },
        { 0x0038, &nv04_gr_ofuncs }, /* dvd subpicture */
        { 0x0039, &nv04_gr_ofuncs }, /* m2mf */
        { 0x0042, &nv04_gr_ofuncs }, /* surf2d */
        { 0x0043, &nv04_gr_ofuncs }, /* rop */
        { 0x0044, &nv04_gr_ofuncs }, /* pattern */
-       { 0x0048, &nv04_gr_ofuncs, nv03_gr_ttri_omthds },
-       { 0x004a, &nv04_gr_ofuncs, nv04_gr_gdi_omthds },
-       { 0x004b, &nv04_gr_ofuncs, nv03_gr_gdi_omthds },
+       { 0x0048, &nv04_gr_ofuncs },
+       { 0x004a, &nv04_gr_ofuncs },
+       { 0x004b, &nv04_gr_ofuncs },
        { 0x0052, &nv04_gr_ofuncs }, /* swzsurf */
-       { 0x0053, &nv04_gr_ofuncs, nv04_gr_surf3d_omthds },
+       { 0x0053, &nv04_gr_ofuncs },
        { 0x0054, &nv04_gr_ofuncs }, /* ttri */
        { 0x0055, &nv04_gr_ofuncs }, /* mtri */
        { 0x0057, &nv04_gr_ofuncs }, /* chroma */
@@ -1023,18 +1106,18 @@ nv04_gr_sclass[] = {
        { 0x0059, &nv04_gr_ofuncs }, /* surf_src */
        { 0x005a, &nv04_gr_ofuncs }, /* surf_color */
        { 0x005b, &nv04_gr_ofuncs }, /* surf_zeta */
-       { 0x005c, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* line */
-       { 0x005d, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* tri */
-       { 0x005e, &nv04_gr_ofuncs, nv04_gr_prim_omthds }, /* rect */
-       { 0x005f, &nv04_gr_ofuncs, nv04_gr_blit_omthds },
-       { 0x0060, &nv04_gr_ofuncs, nv04_gr_iifc_omthds },
-       { 0x0061, &nv04_gr_ofuncs, nv04_gr_ifc_omthds },
+       { 0x005c, &nv04_gr_ofuncs }, /* line */
+       { 0x005d, &nv04_gr_ofuncs }, /* tri */
+       { 0x005e, &nv04_gr_ofuncs }, /* rect */
+       { 0x005f, &nv04_gr_ofuncs },
+       { 0x0060, &nv04_gr_ofuncs },
+       { 0x0061, &nv04_gr_ofuncs },
        { 0x0064, &nv04_gr_ofuncs }, /* iifc (nv05) */
        { 0x0065, &nv04_gr_ofuncs }, /* ifc (nv05) */
        { 0x0066, &nv04_gr_ofuncs }, /* sifc (nv05) */
        { 0x0072, &nv04_gr_ofuncs }, /* beta4 */
-       { 0x0076, &nv04_gr_ofuncs, nv04_gr_sifc_omthds },
-       { 0x0077, &nv04_gr_ofuncs, nv04_gr_sifm_omthds },
+       { 0x0076, &nv04_gr_ofuncs },
+       { 0x0077, &nv04_gr_ofuncs },
        {},
 };
 
@@ -1092,10 +1175,8 @@ nv04_gr_context_switch(struct nv04_gr *gr)
        struct nvkm_device *device = gr->base.engine.subdev.device;
        struct nv04_gr_chan *prev = NULL;
        struct nv04_gr_chan *next = NULL;
-       unsigned long flags;
        int chid;
 
-       spin_lock_irqsave(&gr->lock, flags);
        nv04_gr_idle(gr);
 
        /* If previous context is valid, we need to save it */
@@ -1108,8 +1189,6 @@ nv04_gr_context_switch(struct nv04_gr *gr)
        next = gr->chan[chid];
        if (next)
                nv04_gr_load_context(next, chid);
-
-       spin_unlock_irqrestore(&gr->lock, flags);
 }
 
 static u32 *ctx_reg(struct nv04_gr_chan *chan, u32 reg)
@@ -1272,8 +1351,6 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
 {
        struct nv04_gr *gr = (void *)subdev;
        struct nv04_gr_chan *chan = NULL;
-       struct nvkm_namedb *namedb = NULL;
-       struct nvkm_handle *handle = NULL;
        struct nvkm_device *device = gr->base.engine.subdev.device;
        u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
        u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
@@ -1291,14 +1368,10 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
 
        spin_lock_irqsave(&gr->lock, flags);
        chan = gr->chan[chid];
-       if (chan)
-               namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS);
-       spin_unlock_irqrestore(&gr->lock, flags);
 
        if (stat & NV_PGRAPH_INTR_NOTIFY) {
                if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
-                       handle = nvkm_namedb_get_vinst(namedb, inst);
-                       if (handle && !nv_call(handle->object, mthd, data))
+                       if (!nv04_gr_mthd(device, inst, mthd, data))
                                show &= ~NV_PGRAPH_INTR_NOTIFY;
                }
        }
@@ -1324,7 +1397,7 @@ nv04_gr_intr(struct nvkm_subdev *subdev)
                           nvkm_client_name(chan), subc, class, mthd, data);
        }
 
-       nvkm_namedb_put(handle);
+       spin_unlock_irqrestore(&gr->lock, flags);
 }
 
 static int
index be92015..8f0c62d 100644 (file)
@@ -25,7 +25,6 @@
 #include "regs.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <engine/fifo.h>
 #include <subdev/fb.h>
 
@@ -473,40 +472,37 @@ nv15_gr_sclass[] = {
        {},
 };
 
-static int
-nv17_gr_mthd_lma_window(struct nvkm_object *object, u32 mthd,
-                       void *args, u32 size)
+static void
+nv17_gr_mthd_lma_window(struct nv10_gr_chan *chan, u32 mthd, u32 data)
 {
-       struct nv10_gr_chan *chan = (void *)object->parent;
-       struct nv10_gr *gr = nv10_gr(chan);
+       struct nvkm_device *device = chan->base.engine->subdev.device;
+       struct nvkm_gr *gr = nvkm_gr(chan);
        struct pipe_state *pipe = &chan->pipe_state;
-       struct nvkm_device *device = gr->base.engine.subdev.device;
        u32 pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
        u32 xfmode0, xfmode1;
-       u32 data = *(u32 *)args;
        int i;
 
        chan->lma_window[(mthd - 0x1638) / 4] = data;
 
        if (mthd != 0x1644)
-               return 0;
+               return;
 
        nv04_gr_idle(gr);
 
-       PIPE_SAVE(gr, pipe_0x0040, 0x0040);
-       PIPE_SAVE(gr, pipe->pipe_0x0200, 0x0200);
+       PIPE_SAVE(device, pipe_0x0040, 0x0040);
+       PIPE_SAVE(device, pipe->pipe_0x0200, 0x0200);
 
-       PIPE_RESTORE(gr, chan->lma_window, 0x6790);
+       PIPE_RESTORE(device, chan->lma_window, 0x6790);
 
        nv04_gr_idle(gr);
 
        xfmode0 = nvkm_rd32(device, NV10_PGRAPH_XFMODE0);
        xfmode1 = nvkm_rd32(device, NV10_PGRAPH_XFMODE1);
 
-       PIPE_SAVE(gr, pipe->pipe_0x4400, 0x4400);
-       PIPE_SAVE(gr, pipe_0x64c0, 0x64c0);
-       PIPE_SAVE(gr, pipe_0x6ab0, 0x6ab0);
-       PIPE_SAVE(gr, pipe_0x6a80, 0x6a80);
+       PIPE_SAVE(device, pipe->pipe_0x4400, 0x4400);
+       PIPE_SAVE(device, pipe_0x64c0, 0x64c0);
+       PIPE_SAVE(device, pipe_0x6ab0, 0x6ab0);
+       PIPE_SAVE(device, pipe_0x6a80, 0x6a80);
 
        nv04_gr_idle(gr);
 
@@ -529,52 +525,64 @@ nv17_gr_mthd_lma_window(struct nvkm_object *object, u32 mthd,
        nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040);
        nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000008);
 
-       PIPE_RESTORE(gr, pipe->pipe_0x0200, 0x0200);
+       PIPE_RESTORE(device, pipe->pipe_0x0200, 0x0200);
 
        nv04_gr_idle(gr);
 
-       PIPE_RESTORE(gr, pipe_0x0040, 0x0040);
+       PIPE_RESTORE(device, pipe_0x0040, 0x0040);
 
        nvkm_wr32(device, NV10_PGRAPH_XFMODE0, xfmode0);
        nvkm_wr32(device, NV10_PGRAPH_XFMODE1, xfmode1);
 
-       PIPE_RESTORE(gr, pipe_0x64c0, 0x64c0);
-       PIPE_RESTORE(gr, pipe_0x6ab0, 0x6ab0);
-       PIPE_RESTORE(gr, pipe_0x6a80, 0x6a80);
-       PIPE_RESTORE(gr, pipe->pipe_0x4400, 0x4400);
+       PIPE_RESTORE(device, pipe_0x64c0, 0x64c0);
+       PIPE_RESTORE(device, pipe_0x6ab0, 0x6ab0);
+       PIPE_RESTORE(device, pipe_0x6a80, 0x6a80);
+       PIPE_RESTORE(device, pipe->pipe_0x4400, 0x4400);
 
        nvkm_wr32(device, NV10_PGRAPH_PIPE_ADDRESS, 0x000000c0);
        nvkm_wr32(device, NV10_PGRAPH_PIPE_DATA, 0x00000000);
 
        nv04_gr_idle(gr);
-
-       return 0;
 }
 
-static int
-nv17_gr_mthd_lma_enable(struct nvkm_object *object, u32 mthd,
-                       void *args, u32 size)
+static void
+nv17_gr_mthd_lma_enable(struct nv10_gr_chan *chan, u32 mthd, u32 data)
 {
-       struct nv10_gr_chan *chan = (void *)object->parent;
-       struct nv10_gr *gr = nv10_gr(chan);
-       struct nvkm_device *device = gr->base.engine.subdev.device;
+       struct nvkm_device *device = chan->base.engine->subdev.device;
+       struct nvkm_gr *gr = nvkm_gr(chan);
 
        nv04_gr_idle(gr);
 
        nvkm_mask(device, NV10_PGRAPH_DEBUG_4, 0x00000100, 0x00000100);
        nvkm_mask(device, 0x4006b0, 0x08000000, 0x08000000);
-       return 0;
 }
 
-static struct nvkm_omthds
-nv17_celcius_omthds[] = {
-       { 0x1638, 0x1638, nv17_gr_mthd_lma_window },
-       { 0x163c, 0x163c, nv17_gr_mthd_lma_window },
-       { 0x1640, 0x1640, nv17_gr_mthd_lma_window },
-       { 0x1644, 0x1644, nv17_gr_mthd_lma_window },
-       { 0x1658, 0x1658, nv17_gr_mthd_lma_enable },
-       {}
-};
+static bool
+nv17_gr_mthd_celcius(struct nv10_gr_chan *chan, u32 mthd, u32 data)
+{
+       void (*func)(struct nv10_gr_chan *, u32, u32);
+       switch (mthd) {
+       case 0x1638 ... 0x1644:
+                    func = nv17_gr_mthd_lma_window; break;
+       case 0x1658: func = nv17_gr_mthd_lma_enable; break;
+       default:
+               return false;
+       }
+       func(chan, mthd, data);
+       return true;
+}
+
+static bool
+nv10_gr_mthd(struct nv10_gr_chan *chan, u8 class, u32 mthd, u32 data)
+{
+       bool (*func)(struct nv10_gr_chan *, u32, u32);
+       switch (class) {
+       case 0x99: func = nv17_gr_mthd_celcius; break;
+       default:
+               return false;
+       }
+       return func(chan, mthd, data);
+}
 
 static struct nvkm_oclass
 nv17_gr_sclass[] = {
@@ -595,7 +603,7 @@ nv17_gr_sclass[] = {
        { 0x0093, &nv04_gr_ofuncs }, /* surf3d */
        { 0x0094, &nv04_gr_ofuncs }, /* ttri */
        { 0x0095, &nv04_gr_ofuncs }, /* mtri */
-       { 0x0099, &nv04_gr_ofuncs, nv17_celcius_omthds },
+       { 0x0099, &nv04_gr_ofuncs },
        {},
 };
 
@@ -996,10 +1004,8 @@ nv10_gr_context_switch(struct nv10_gr *gr)
        struct nvkm_device *device = gr->base.engine.subdev.device;
        struct nv10_gr_chan *prev = NULL;
        struct nv10_gr_chan *next = NULL;
-       unsigned long flags;
        int chid;
 
-       spin_lock_irqsave(&gr->lock, flags);
        nv04_gr_idle(gr);
 
        /* If previous context is valid, we need to save it */
@@ -1012,8 +1018,6 @@ nv10_gr_context_switch(struct nv10_gr *gr)
        next = gr->chan[chid];
        if (next)
                nv10_gr_load_context(next, chid);
-
-       spin_unlock_irqrestore(&gr->lock, flags);
 }
 
 #define NV_WRITE_CTX(reg, val) do { \
@@ -1167,8 +1171,6 @@ nv10_gr_intr(struct nvkm_subdev *subdev)
 {
        struct nv10_gr *gr = (void *)subdev;
        struct nv10_gr_chan *chan = NULL;
-       struct nvkm_namedb *namedb = NULL;
-       struct nvkm_handle *handle = NULL;
        struct nvkm_device *device = gr->base.engine.subdev.device;
        u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
        u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
@@ -1185,14 +1187,10 @@ nv10_gr_intr(struct nvkm_subdev *subdev)
 
        spin_lock_irqsave(&gr->lock, flags);
        chan = gr->chan[chid];
-       if (chan)
-               namedb = (void *)nv_pclass(nv_object(chan), NV_NAMEDB_CLASS);
-       spin_unlock_irqrestore(&gr->lock, flags);
 
        if (stat & NV_PGRAPH_INTR_ERROR) {
                if (chan && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD)) {
-                       handle = nvkm_namedb_get_class(namedb, class);
-                       if (handle && !nv_call(handle->object, mthd, data))
+                       if (!nv10_gr_mthd(chan, class, mthd, data))
                                show &= ~NV_PGRAPH_INTR_ERROR;
                }
        }
@@ -1218,7 +1216,7 @@ nv10_gr_intr(struct nvkm_subdev *subdev)
                           nvkm_client_name(chan), subc, class, mthd, data);
        }
 
-       nvkm_namedb_put(handle);
+       spin_unlock_irqrestore(&gr->lock, flags);
 }
 
 static int
index 6e5b321..a33ed61 100644 (file)
@@ -2,7 +2,6 @@
 #include "regs.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <engine/fifo.h>
 #include <subdev/fb.h>
 #include <subdev/timer.h>
@@ -145,6 +144,7 @@ nv20_gr_context_fini(struct nvkm_object *object, bool suspend)
        nvkm_kmap(gr->ctxtab);
        nvkm_wo32(gr->ctxtab, chan->chid * 4, 0x00000000);
        nvkm_done(gr->ctxtab);
+
        return nvkm_gr_context_fini(&chan->base, suspend);
 }
 
@@ -200,11 +200,9 @@ nv20_gr_tile_prog(struct nvkm_engine *engine, int i)
 void
 nv20_gr_intr(struct nvkm_subdev *subdev)
 {
-       struct nvkm_engine *engine = nv_engine(subdev);
-       struct nvkm_object *engctx;
-       struct nvkm_handle *handle;
        struct nv20_gr *gr = (void *)subdev;
        struct nvkm_device *device = gr->base.engine.subdev.device;
+       struct nvkm_fifo_chan *chan;
        u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
        u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
        u32 nstatus = nvkm_rd32(device, NV03_PGRAPH_NSTATUS);
@@ -216,16 +214,9 @@ nv20_gr_intr(struct nvkm_subdev *subdev)
        u32 class = nvkm_rd32(device, 0x400160 + subc * 4) & 0xfff;
        u32 show = stat;
        char msg[128], src[128], sta[128];
+       unsigned long flags;
 
-       engctx = nvkm_engctx_get(engine, chid);
-       if (stat & NV_PGRAPH_INTR_ERROR) {
-               if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
-                       handle = nvkm_handle_get_class(engctx, class);
-                       if (handle && !nv_call(handle->object, mthd, data))
-                               show &= ~NV_PGRAPH_INTR_ERROR;
-                       nvkm_handle_put(handle);
-               }
-       }
+       chan = nvkm_fifo_chan_chid(device->fifo, chid, &flags);
 
        nvkm_wr32(device, NV03_PGRAPH_INTR, stat);
        nvkm_wr32(device, NV04_PGRAPH_FIFO, 0x00000001);
@@ -238,10 +229,10 @@ nv20_gr_intr(struct nvkm_subdev *subdev)
                                   "nstatus %08x [%s] ch %d [%s] subc %d "
                                   "class %04x mthd %04x data %08x\n",
                           show, msg, nsource, src, nstatus, sta, chid,
-                          nvkm_client_name(engctx), subc, class, mthd, data);
+                          nvkm_client_name(chan), subc, class, mthd, data);
        }
 
-       nvkm_engctx_put(engctx);
+       nvkm_fifo_chan_put(device->fifo, flags, &chan);
 }
 
 static int
index 1ebf2ed..4db2a17 100644 (file)
@@ -25,7 +25,6 @@
 #include "regs.h"
 
 #include <core/client.h>
-#include <core/handle.h>
 #include <subdev/fb.h>
 #include <subdev/timer.h>
 #include <engine/fifo.h>
 struct nv40_gr {
        struct nvkm_gr base;
        u32 size;
+       struct list_head chan;
 };
 
 struct nv40_gr_chan {
        struct nvkm_gr_chan base;
+       struct nvkm_fifo_chan *fifo;
+       u32 inst;
+       struct list_head head;
 };
 
 static u64
@@ -132,6 +135,16 @@ nv44_gr_sclass[] = {
  * PGRAPH context
  ******************************************************************************/
 
+static void
+nv40_gr_context_dtor(struct nvkm_object *object)
+{
+       struct nv40_gr_chan *chan = (void *)object;
+       unsigned long flags;
+       spin_lock_irqsave(&object->engine->lock, flags);
+       list_del(&chan->head);
+       spin_unlock_irqrestore(&object->engine->lock, flags);
+}
+
 static int
 nv40_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
                     struct nvkm_oclass *oclass, void *data, u32 size,
@@ -139,6 +152,7 @@ nv40_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 {
        struct nv40_gr *gr = (void *)engine;
        struct nv40_gr_chan *chan;
+       unsigned long flags;
        int ret;
 
        ret = nvkm_gr_context_create(parent, engine, oclass, NULL, gr->size,
@@ -149,6 +163,12 @@ nv40_gr_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 
        nv40_grctx_fill(nv_device(gr), nv_gpuobj(chan));
        nvkm_wo32(&chan->base.base.gpuobj, 0x00000, nv_gpuobj(chan)->addr >> 4);
+
+       spin_lock_irqsave(&gr->base.engine.lock, flags);
+       chan->fifo = (void *)parent;
+       chan->inst = chan->base.base.gpuobj.addr;
+       list_add(&chan->head, &gr->chan);
+       spin_unlock_irqrestore(&gr->base.engine.lock, flags);
        return 0;
 }
 
@@ -195,7 +215,7 @@ nv40_gr_cclass = {
        .handle = NV_ENGCTX(GR, 0x40),
        .ofuncs = &(struct nvkm_ofuncs) {
                .ctor = nv40_gr_context_ctor,
-               .dtor = _nvkm_gr_context_dtor,
+               .dtor = nv40_gr_context_dtor,
                .init = _nvkm_gr_context_init,
                .fini = nv40_gr_context_fini,
                .rd32 = _nvkm_gr_context_rd32,
@@ -289,11 +309,8 @@ nv40_gr_tile_prog(struct nvkm_engine *engine, int i)
 static void
 nv40_gr_intr(struct nvkm_subdev *subdev)
 {
-       struct nvkm_fifo *fifo = nvkm_fifo(subdev);
-       struct nvkm_engine *engine = nv_engine(subdev);
-       struct nvkm_object *engctx;
-       struct nvkm_handle *handle = NULL;
        struct nv40_gr *gr = (void *)subdev;
+       struct nv40_gr_chan *temp, *chan = NULL;
        struct nvkm_device *device = gr->base.engine.subdev.device;
        u32 stat = nvkm_rd32(device, NV03_PGRAPH_INTR);
        u32 nsource = nvkm_rd32(device, NV03_PGRAPH_NSOURCE);
@@ -306,19 +323,19 @@ nv40_gr_intr(struct nvkm_subdev *subdev)
        u32 class = nvkm_rd32(device, 0x400160 + subc * 4) & 0xffff;
        u32 show = stat;
        char msg[128], src[128], sta[128];
-       int chid;
-
-       engctx = nvkm_engctx_get(engine, inst);
-       chid   = fifo->chid(fifo, engctx);
+       unsigned long flags;
 
-       if (stat & NV_PGRAPH_INTR_ERROR) {
-               if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
-                       handle = nvkm_handle_get_class(engctx, class);
-                       if (handle && !nv_call(handle->object, mthd, data))
-                               show &= ~NV_PGRAPH_INTR_ERROR;
-                       nvkm_handle_put(handle);
+       spin_lock_irqsave(&gr->base.engine.lock, flags);
+       list_for_each_entry(temp, &gr->chan, head) {
+               if (temp->inst >> 4 == inst) {
+                       chan = temp;
+                       list_del(&chan->head);
+                       list_add(&chan->head, &gr->chan);
+                       break;
                }
+       }
 
+       if (stat & NV_PGRAPH_INTR_ERROR) {
                if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) {
                        nvkm_mask(device, 0x402000, 0, 0);
                }
@@ -334,12 +351,12 @@ nv40_gr_intr(struct nvkm_subdev *subdev)
                nvkm_error(subdev, "intr %08x [%s] nsource %08x [%s] "
                                   "nstatus %08x [%s] ch %d [%08x %s] subc %d "
                                   "class %04x mthd %04x data %08x\n",
-                          show, msg, nsource, src, nstatus, sta, chid,
-                          inst << 4, nvkm_client_name(engctx), subc,
-                          class, mthd, data);
+                          show, msg, nsource, src, nstatus, sta,
+                          chan ? chan->fifo->chid : -1, inst << 4,
+                          nvkm_client_name(chan), subc, class, mthd, data);
        }
 
-       nvkm_engctx_put(engctx);
+       spin_unlock_irqrestore(&gr->base.engine.lock, flags);
 }
 
 static int
@@ -355,6 +372,8 @@ nv40_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
        if (ret)
                return ret;
 
+       INIT_LIST_HEAD(&gr->chan);
+
        nv_subdev(gr)->unit = 0x00001000;
        nv_subdev(gr)->intr = nv40_gr_intr;
        nv_engine(gr)->cclass = &nv40_gr_cclass;
index c50cfe4..daac540 100644 (file)
@@ -24,9 +24,8 @@
 #include "nv50.h"
 
 #include <core/client.h>
-#include <core/handle.h>
-#include <engine/fifo.h>
 #include <subdev/timer.h>
+#include <engine/fifo.h>
 
 struct nv50_gr {
        struct nvkm_gr base;
@@ -609,7 +608,7 @@ nv50_gr_tp_trap(struct nv50_gr *gr, int type, u32 ustatus_old,
 
 static int
 nv50_gr_trap_handler(struct nv50_gr *gr, u32 display,
-                    int chid, u64 inst, struct nvkm_object *engctx)
+                    int chid, u64 inst, struct nvkm_fifo_chan *chan)
 {
        struct nvkm_subdev *subdev = &gr->base.engine.subdev;
        struct nvkm_device *device = subdev->device;
@@ -649,8 +648,7 @@ nv50_gr_trap_handler(struct nv50_gr *gr, u32 display,
                                           "ch %d [%010llx %s] subc %d "
                                           "class %04x mthd %04x data %08x%08x "
                                           "400808 %08x 400848 %08x\n",
-                                          chid, inst,
-                                          nvkm_client_name(engctx),
+                                          chid, inst, nvkm_client_name(chan),
                                           subc, class, mthd,
                                           datah, datal, addr, r848);
                        } else
@@ -677,7 +675,7 @@ nv50_gr_trap_handler(struct nv50_gr *gr, u32 display,
                                           "ch %d [%010llx %s] subc %d "
                                           "class %04x mthd %04x data %08x "
                                           "40084c %08x\n", chid, inst,
-                                          nvkm_client_name(engctx), subc,
+                                          nvkm_client_name(chan), subc,
                                           class, mthd, data, addr);
                        } else
                        if (display) {
@@ -840,10 +838,7 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
 {
        struct nv50_gr *gr = (void *)subdev;
        struct nvkm_device *device = gr->base.engine.subdev.device;
-       struct nvkm_fifo *fifo = device->fifo;
-       struct nvkm_engine *engine = nv_engine(subdev);
-       struct nvkm_object *engctx;
-       struct nvkm_handle *handle = NULL;
+       struct nvkm_fifo_chan *chan;
        u32 stat = nvkm_rd32(device, 0x400100);
        u32 inst = nvkm_rd32(device, 0x40032c) & 0x0fffffff;
        u32 addr = nvkm_rd32(device, 0x400704);
@@ -853,18 +848,12 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
        u32 class = nvkm_rd32(device, 0x400814);
        u32 show = stat, show_bitfield = stat;
        const struct nvkm_enum *en;
+       unsigned long flags;
        char msg[128];
        int chid;
 
-       engctx = nvkm_engctx_get(engine, inst);
-       chid   = fifo->chid(fifo, engctx);
-
-       if (stat & 0x00000010) {
-               handle = nvkm_handle_get_class(engctx, class);
-               if (handle && !nv_call(handle->object, mthd, data))
-                       show &= ~0x00000010;
-               nvkm_handle_put(handle);
-       }
+       chan = nvkm_fifo_chan_inst(device->fifo, (u64)inst << 12, &flags);
+       chid = chan ? chan->chid : -1;
 
        if (show & 0x00100000) {
                u32 ecode = nvkm_rd32(device, 0x400110);
@@ -875,8 +864,7 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
        }
 
        if (stat & 0x00200000) {
-               if (!nv50_gr_trap_handler(gr, show, chid, (u64)inst << 12,
-                                         engctx))
+               if (!nv50_gr_trap_handler(gr, show, chid, (u64)inst << 12, chan))
                        show &= ~0x00200000;
                show_bitfield &= ~0x00200000;
        }
@@ -890,13 +878,13 @@ nv50_gr_intr(struct nvkm_subdev *subdev)
                nvkm_error(subdev, "%08x [%s] ch %d [%010llx %s] subc %d "
                                   "class %04x mthd %04x data %08x\n",
                           stat, msg, chid, (u64)inst << 12,
-                          nvkm_client_name(engctx), subc, class, mthd, data);
+                          nvkm_client_name(chan), subc, class, mthd, data);
        }
 
        if (nvkm_rd32(device, 0x400824) & (1 << 31))
                nvkm_wr32(device, 0x400824, nvkm_rd32(device, 0x400824) & ~(1 << 31));
 
-       nvkm_engctx_put(engctx);
+       nvkm_fifo_chan_put(device->fifo, flags, &chan);
 }
 
 static int