Commit a65955e1 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/gr: remove dependence on namedb/engctx lookup

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