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