forked from Minki/linux
drm/nouveau/gr: remove dependence on namedb/engctx lookup
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
6ca307b0c9
commit
a65955e19e
@ -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 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
unsigned long flags;
|
||||
|
||||
engctx = nvkm_engctx_get(engine, inst);
|
||||
chid = fifo->chid(fifo, engctx);
|
||||
spin_lock_irqsave(&gr->base.engine.lock, flags);
|
||||
list_for_each_entry(temp, &gr->chan, head) {
|
||||
if (temp->inst >> 4 == inst) {
|
||||
chan = temp;
|
||||
list_del(&chan->head);
|
||||
list_add(&chan->head, &gr->chan);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stat & NV_PGRAPH_INTR_ERROR) {
|
||||
if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
|
||||
handle = nvkm_handle_get_class(engctx, class);
|
||||
if (handle && !nv_call(handle->object, mthd, data))
|
||||
show &= ~NV_PGRAPH_INTR_ERROR;
|
||||
nvkm_handle_put(handle);
|
||||
}
|
||||
|
||||
if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) {
|
||||
nvkm_mask(device, 0x402000, 0, 0);
|
||||
}
|
||||
@ -334,12 +351,12 @@ nv40_gr_intr(struct nvkm_subdev *subdev)
|
||||
nvkm_error(subdev, "intr %08x [%s] nsource %08x [%s] "
|
||||
"nstatus %08x [%s] ch %d [%08x %s] subc %d "
|
||||
"class %04x mthd %04x data %08x\n",
|
||||
show, msg, nsource, src, nstatus, sta, chid,
|
||||
inst << 4, nvkm_client_name(engctx), subc,
|
||||
class, mthd, data);
|
||||
show, msg, nsource, src, nstatus, sta,
|
||||
chan ? chan->fifo->chid : -1, inst << 4,
|
||||
nvkm_client_name(chan), subc, class, mthd, data);
|
||||
}
|
||||
|
||||
nvkm_engctx_put(engctx);
|
||||
spin_unlock_irqrestore(&gr->base.engine.lock, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -355,6 +372,8 @@ nv40_gr_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
INIT_LIST_HEAD(&gr->chan);
|
||||
|
||||
nv_subdev(gr)->unit = 0x00001000;
|
||||
nv_subdev(gr)->intr = nv40_gr_intr;
|
||||
nv_engine(gr)->cclass = &nv40_gr_cclass;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user