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/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