diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 362d5fa394d4..c6ff24b5a11d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -26,12 +26,11 @@ #include "fuc/os.h" #include -#include #include -#include #include #include #include +#include #include #include @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h index 62bf56906cbe..612d5346eae9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h @@ -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[]; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c index 8df73421c78c..1e8290ab1d37 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c index ef76e2dd1d31..4fe0f969de82 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c index 94c6ca1d739a..a00731979698 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c index f4cd8e5546af..ec21f62e7248 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c index a80fda50719a..c213e9a005c6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c index 97b0e1ad040f..aad5fdb29c60 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c index 0a8d850051ee..39f42a1c2b78 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm204.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c index 719ebfb6e640..87388926efa6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c @@ -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 }, {} }; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c index 617161e4fc15..b15b86478c4f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c @@ -25,7 +25,6 @@ #include "regs.h" #include -#include #include #include #include @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c index be92015d8f9e..8f0c62d56d9d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c @@ -25,7 +25,6 @@ #include "regs.h" #include -#include #include #include @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c index 6e5b321128a6..a33ed6121d7f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c @@ -2,7 +2,6 @@ #include "regs.h" #include -#include #include #include #include @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c index 1ebf2edef4d4..4db2a17f5308 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c @@ -25,7 +25,6 @@ #include "regs.h" #include -#include #include #include #include @@ -33,10 +32,14 @@ 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; + unsigned long flags; - engctx = nvkm_engctx_get(engine, inst); - chid = fifo->chid(fifo, engctx); + 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_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); - } - 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; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c index c50cfe4875ef..daac54075705 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c @@ -24,9 +24,8 @@ #include "nv50.h" #include -#include -#include #include +#include 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