drm/nvc0/gr: move to exec engine interfaces

Much nicer to do that nv50, the code was pretty much written to expect
such a change in the future.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2011-04-01 10:59:53 +10:00
parent 2703c21a82
commit 7a45cd19c9
5 changed files with 201 additions and 231 deletions

View File

@ -1194,15 +1194,9 @@ extern int nv50_grctx_init(struct nouveau_grctx *);
extern struct nouveau_enum nv50_data_error_names[]; extern struct nouveau_enum nv50_data_error_names[];
/* nvc0_graph.c */ /* nvc0_graph.c */
extern int nvc0_graph_init(struct drm_device *); extern int nvc0_graph_create(struct drm_device *);
extern void nvc0_graph_takedown(struct drm_device *);
extern void nvc0_graph_fifo_access(struct drm_device *, bool); extern void nvc0_graph_fifo_access(struct drm_device *, bool);
extern struct nouveau_channel *nvc0_graph_channel(struct drm_device *); extern struct nouveau_channel *nvc0_graph_channel(struct drm_device *);
extern int nvc0_graph_create_context(struct nouveau_channel *);
extern void nvc0_graph_destroy_context(struct nouveau_channel *);
extern int nvc0_graph_load_context(struct nouveau_channel *);
extern int nvc0_graph_unload_context(struct drm_device *);
extern int nvc0_graph_object_new(struct nouveau_channel *, u32, u16);
/* nv84_crypt.c */ /* nv84_crypt.c */
extern int nv84_crypt_create(struct drm_device *); extern int nv84_crypt_create(struct drm_device *);

View File

@ -440,15 +440,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.takedown = nv04_timer_takedown; engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nvc0_fb_init; engine->fb.init = nvc0_fb_init;
engine->fb.takedown = nvc0_fb_takedown; engine->fb.takedown = nvc0_fb_takedown;
engine->graph.init = nvc0_graph_init;
engine->graph.takedown = nvc0_graph_takedown;
engine->graph.fifo_access = nvc0_graph_fifo_access; engine->graph.fifo_access = nvc0_graph_fifo_access;
engine->graph.channel = nvc0_graph_channel; engine->graph.channel = nvc0_graph_channel;
engine->graph.create_context = nvc0_graph_create_context;
engine->graph.destroy_context = nvc0_graph_destroy_context;
engine->graph.load_context = nvc0_graph_load_context;
engine->graph.unload_context = nvc0_graph_unload_context;
engine->graph.object_new = nvc0_graph_object_new;
engine->fifo.channels = 128; engine->fifo.channels = 128;
engine->fifo.init = nvc0_fifo_init; engine->fifo.init = nvc0_fifo_init;
engine->fifo.takedown = nvc0_fifo_takedown; engine->fifo.takedown = nvc0_fifo_takedown;
@ -627,6 +620,9 @@ nouveau_card_init(struct drm_device *dev)
if (dev_priv->card_type == NV_50) if (dev_priv->card_type == NV_50)
nv50_graph_create(dev); nv50_graph_create(dev);
else
if (dev_priv->card_type == NV_C0)
nvc0_graph_create(dev);
switch (dev_priv->chipset) { switch (dev_priv->chipset) {
case 0x84: case 0x84:

View File

@ -30,10 +30,6 @@
#include "nouveau_mm.h" #include "nouveau_mm.h"
#include "nvc0_graph.h" #include "nvc0_graph.h"
static void nvc0_graph_isr(struct drm_device *);
static void nvc0_runk140_isr(struct drm_device *);
static int nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan);
void void
nvc0_graph_fifo_access(struct drm_device *dev, bool enabled) nvc0_graph_fifo_access(struct drm_device *dev, bool enabled)
{ {
@ -45,12 +41,40 @@ nvc0_graph_channel(struct drm_device *dev)
return NULL; return NULL;
} }
static int
nvc0_graph_load_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
nv_wr32(dev, 0x409840, 0x00000030);
nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
nv_wr32(dev, 0x409504, 0x00000003);
if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
return 0;
}
static int
nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan)
{
nv_wr32(dev, 0x409840, 0x00000003);
nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12);
nv_wr32(dev, 0x409504, 0x00000009);
if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) {
NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
return -EBUSY;
}
return 0;
}
static int static int
nvc0_graph_construct_context(struct nouveau_channel *chan) nvc0_graph_construct_context(struct nouveau_channel *chan)
{ {
struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_chan *grch = chan->pgraph_ctx; struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
int ret, i; int ret, i;
u32 *ctx; u32 *ctx;
@ -89,9 +113,8 @@ nvc0_graph_construct_context(struct nouveau_channel *chan)
static int static int
nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
{ {
struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
struct nvc0_graph_chan *grch = chan->pgraph_ctx;
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
int i = 0, gpc, tp, ret; int i = 0, gpc, tp, ret;
u32 magic; u32 magic;
@ -158,29 +181,27 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
return 0; return 0;
} }
int static int
nvc0_graph_create_context(struct nouveau_channel *chan) nvc0_graph_context_new(struct nouveau_channel *chan, int engine)
{ {
struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nvc0_graph_priv *priv = pgraph->priv;
struct nvc0_graph_chan *grch;
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
struct nvc0_graph_priv *priv = nv_engine(dev, engine);
struct nvc0_graph_chan *grch;
struct nouveau_gpuobj *grctx; struct nouveau_gpuobj *grctx;
int ret, i; int ret, i;
chan->pgraph_ctx = kzalloc(sizeof(*grch), GFP_KERNEL); grch = kzalloc(sizeof(*grch), GFP_KERNEL);
if (!chan->pgraph_ctx) if (!grch)
return -ENOMEM; return -ENOMEM;
grch = chan->pgraph_ctx; chan->engctx[NVOBJ_ENGINE_GR] = grch;
ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256, ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256,
NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC, NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC,
&grch->grctx); &grch->grctx);
if (ret) if (ret)
goto error; goto error;
chan->ramin_grctx = grch->grctx;
grctx = grch->grctx; grctx = grch->grctx;
ret = nvc0_graph_create_context_mmio_list(chan); ret = nvc0_graph_create_context_mmio_list(chan);
@ -213,97 +234,42 @@ nvc0_graph_create_context(struct nouveau_channel *chan)
return 0; return 0;
error: error:
pgraph->destroy_context(chan); priv->base.context_del(chan, engine);
return ret; return ret;
} }
void static void
nvc0_graph_destroy_context(struct nouveau_channel *chan) nvc0_graph_context_del(struct nouveau_channel *chan, int engine)
{ {
struct nvc0_graph_chan *grch; struct nvc0_graph_chan *grch = chan->engctx[engine];
grch = chan->pgraph_ctx;
chan->pgraph_ctx = NULL;
if (!grch)
return;
nouveau_gpuobj_ref(NULL, &grch->mmio); nouveau_gpuobj_ref(NULL, &grch->mmio);
nouveau_gpuobj_ref(NULL, &grch->unk418810); nouveau_gpuobj_ref(NULL, &grch->unk418810);
nouveau_gpuobj_ref(NULL, &grch->unk40800c); nouveau_gpuobj_ref(NULL, &grch->unk40800c);
nouveau_gpuobj_ref(NULL, &grch->unk408004); nouveau_gpuobj_ref(NULL, &grch->unk408004);
nouveau_gpuobj_ref(NULL, &grch->grctx); nouveau_gpuobj_ref(NULL, &grch->grctx);
chan->ramin_grctx = NULL; chan->engctx[engine] = NULL;
} }
int static int
nvc0_graph_load_context(struct nouveau_channel *chan) nvc0_graph_object_new(struct nouveau_channel *chan, int engine,
u32 handle, u16 class)
{ {
struct drm_device *dev = chan->dev;
nv_wr32(dev, 0x409840, 0x00000030);
nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
nv_wr32(dev, 0x409504, 0x00000003);
if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
return 0; return 0;
} }
static int static int
nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan) nvc0_graph_fini(struct drm_device *dev, int engine)
{ {
nv_wr32(dev, 0x409840, 0x00000003); u32 inst = nv_rd32(dev, 0x409b00);
nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12); if (inst & 0x80000000) {
nv_wr32(dev, 0x409504, 0x00000009); inst &= 0x0fffffff;
if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) { nvc0_graph_unload_context_to(dev, (u64)inst << 12);
NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
return -EBUSY;
} }
return 0; return 0;
} }
int
nvc0_graph_unload_context(struct drm_device *dev)
{
u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12;
return nvc0_graph_unload_context_to(dev, inst);
}
int
nvc0_graph_object_new(struct nouveau_channel *chan, u32 handle, u16 class)
{
return 0;
}
static void
nvc0_graph_destroy(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nvc0_graph_priv *priv;
priv = pgraph->priv;
if (!priv)
return;
nouveau_irq_unregister(dev, 12);
nouveau_irq_unregister(dev, 25);
nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
if (priv->grctx_vals)
kfree(priv->grctx_vals);
kfree(priv);
}
void
nvc0_graph_takedown(struct drm_device *dev)
{
nvc0_graph_destroy(dev);
}
static int static int
nvc0_graph_mthd_page_flip(struct nouveau_channel *chan, nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
u32 class, u32 mthd, u32 data) u32 class, u32 mthd, u32 data)
@ -312,119 +278,10 @@ nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
return 0; return 0;
} }
static int
nvc0_graph_create(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nvc0_graph_priv *priv;
int ret, gpc, i;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
pgraph->priv = priv;
ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
if (ret)
goto error;
ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
if (ret)
goto error;
for (i = 0; i < 0x1000; i += 4) {
nv_wo32(priv->unk4188b4, i, 0x00000010);
nv_wo32(priv->unk4188b8, i, 0x00000010);
}
priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f;
priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
priv->tp_total += priv->tp_nr[gpc];
}
/*XXX: these need figuring out... */
switch (dev_priv->chipset) {
case 0xc0:
if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
priv->magic_not_rop_nr = 0x07;
/* filled values up to tp_total, the rest 0 */
priv->magicgpc980[0] = 0x22111000;
priv->magicgpc980[1] = 0x00000233;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x000ba2e9;
} else
if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
priv->magic_not_rop_nr = 0x05;
priv->magicgpc980[0] = 0x11110000;
priv->magicgpc980[1] = 0x00233222;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00092493;
} else
if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
priv->magic_not_rop_nr = 0x06;
priv->magicgpc980[0] = 0x11110000;
priv->magicgpc980[1] = 0x03332222;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00088889;
}
break;
case 0xc3: /* 450, 4/0/0/0, 2 */
priv->magic_not_rop_nr = 0x03;
priv->magicgpc980[0] = 0x00003210;
priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00200000;
break;
case 0xc4: /* 460, 3/4/0/0, 4 */
priv->magic_not_rop_nr = 0x01;
priv->magicgpc980[0] = 0x02321100;
priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00124925;
break;
}
if (!priv->magic_not_rop_nr) {
NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
priv->tp_nr[3], priv->rop_nr);
/* use 0xc3's values... */
priv->magic_not_rop_nr = 0x03;
priv->magicgpc980[0] = 0x00003210;
priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00200000;
}
nouveau_irq_register(dev, 12, nvc0_graph_isr);
nouveau_irq_register(dev, 25, nvc0_runk140_isr);
NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
return 0;
error:
nvc0_graph_destroy(dev);
return ret;
}
static void static void
nvc0_graph_init_obj418880(struct drm_device *dev) nvc0_graph_init_obj418880(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
struct nvc0_graph_priv *priv = pgraph->priv;
int i; int i;
nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000); nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000);
@ -455,8 +312,7 @@ nvc0_graph_init_regs(struct drm_device *dev)
static void static void
nvc0_graph_init_gpc_0(struct drm_device *dev) nvc0_graph_init_gpc_0(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
int gpc; int gpc;
/* /*
@ -517,8 +373,7 @@ nvc0_graph_init_units(struct drm_device *dev)
static void static void
nvc0_graph_init_gpc_1(struct drm_device *dev) nvc0_graph_init_gpc_1(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
int gpc, tp; int gpc, tp;
for (gpc = 0; gpc < priv->gpc_nr; gpc++) { for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
@ -543,8 +398,7 @@ nvc0_graph_init_gpc_1(struct drm_device *dev)
static void static void
nvc0_graph_init_rop(struct drm_device *dev) nvc0_graph_init_rop(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
int rop; int rop;
for (rop = 0; rop < priv->rop_nr; rop++) { for (rop = 0; rop < priv->rop_nr; rop++) {
@ -596,8 +450,7 @@ nvc0_fuc_load_fw(struct drm_device *dev, u32 fuc_base,
static int static int
nvc0_graph_init_ctxctl(struct drm_device *dev) nvc0_graph_init_ctxctl(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
u32 r000260; u32 r000260;
int ret; int ret;
@ -652,11 +505,10 @@ nvc0_graph_init_ctxctl(struct drm_device *dev)
return 0; return 0;
} }
int static int
nvc0_graph_init(struct drm_device *dev) nvc0_graph_init(struct drm_device *dev, int engine)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
int ret; int ret;
dev_priv->engine.graph.accel_blocked = true; dev_priv->engine.graph.accel_blocked = true;
@ -676,12 +528,6 @@ nvc0_graph_init(struct drm_device *dev)
nv_mask(dev, 0x000200, 0x18001000, 0x00000000); nv_mask(dev, 0x000200, 0x18001000, 0x00000000);
nv_mask(dev, 0x000200, 0x18001000, 0x18001000); nv_mask(dev, 0x000200, 0x18001000, 0x18001000);
if (!pgraph->priv) {
ret = nvc0_graph_create(dev);
if (ret)
return ret;
}
nvc0_graph_init_obj418880(dev); nvc0_graph_init_obj418880(dev);
nvc0_graph_init_regs(dev); nvc0_graph_init_regs(dev);
/*nvc0_graph_init_unitplemented_magics(dev);*/ /*nvc0_graph_init_unitplemented_magics(dev);*/
@ -814,3 +660,135 @@ nvc0_runk140_isr(struct drm_device *dev)
units &= ~(1 << unit); units &= ~(1 << unit);
} }
} }
static void
nvc0_graph_destroy(struct drm_device *dev, int engine)
{
struct nvc0_graph_priv *priv = nv_engine(dev, engine);
nouveau_irq_unregister(dev, 12);
nouveau_irq_unregister(dev, 25);
nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
if (priv->grctx_vals)
kfree(priv->grctx_vals);
NVOBJ_ENGINE_DEL(dev, GR);
kfree(priv);
}
int
nvc0_graph_create(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvc0_graph_priv *priv;
int ret, gpc, i;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->base.destroy = nvc0_graph_destroy;
priv->base.init = nvc0_graph_init;
priv->base.fini = nvc0_graph_fini;
priv->base.context_new = nvc0_graph_context_new;
priv->base.context_del = nvc0_graph_context_del;
priv->base.object_new = nvc0_graph_object_new;
NVOBJ_ENGINE_ADD(dev, GR, &priv->base);
nouveau_irq_register(dev, 12, nvc0_graph_isr);
nouveau_irq_register(dev, 25, nvc0_runk140_isr);
ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
if (ret)
goto error;
ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
if (ret)
goto error;
for (i = 0; i < 0x1000; i += 4) {
nv_wo32(priv->unk4188b4, i, 0x00000010);
nv_wo32(priv->unk4188b8, i, 0x00000010);
}
priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f;
priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
priv->tp_total += priv->tp_nr[gpc];
}
/*XXX: these need figuring out... */
switch (dev_priv->chipset) {
case 0xc0:
if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
priv->magic_not_rop_nr = 0x07;
/* filled values up to tp_total, the rest 0 */
priv->magicgpc980[0] = 0x22111000;
priv->magicgpc980[1] = 0x00000233;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x000ba2e9;
} else
if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
priv->magic_not_rop_nr = 0x05;
priv->magicgpc980[0] = 0x11110000;
priv->magicgpc980[1] = 0x00233222;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00092493;
} else
if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
priv->magic_not_rop_nr = 0x06;
priv->magicgpc980[0] = 0x11110000;
priv->magicgpc980[1] = 0x03332222;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00088889;
}
break;
case 0xc3: /* 450, 4/0/0/0, 2 */
priv->magic_not_rop_nr = 0x03;
priv->magicgpc980[0] = 0x00003210;
priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00200000;
break;
case 0xc4: /* 460, 3/4/0/0, 4 */
priv->magic_not_rop_nr = 0x01;
priv->magicgpc980[0] = 0x02321100;
priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00124925;
break;
}
if (!priv->magic_not_rop_nr) {
NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
priv->tp_nr[3], priv->rop_nr);
/* use 0xc3's values... */
priv->magic_not_rop_nr = 0x03;
priv->magicgpc980[0] = 0x00003210;
priv->magicgpc980[1] = 0x00000000;
priv->magicgpc980[2] = 0x00000000;
priv->magicgpc980[3] = 0x00000000;
priv->magicgpc918 = 0x00200000;
}
NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
return 0;
error:
nvc0_graph_destroy(dev, NVOBJ_ENGINE_GR);
return ret;
}

View File

@ -35,6 +35,8 @@
#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) #define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
struct nvc0_graph_priv { struct nvc0_graph_priv {
struct nouveau_exec_engine base;
u8 gpc_nr; u8 gpc_nr;
u8 rop_nr; u8 rop_nr;
u8 tp_nr[GPC_MAX]; u8 tp_nr[GPC_MAX];

View File

@ -1797,8 +1797,8 @@ int
nvc0_grctx_generate(struct nouveau_channel *chan) nvc0_grctx_generate(struct nouveau_channel *chan)
{ {
struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
struct nvc0_graph_chan *grch = chan->pgraph_ctx; struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
int i, gpc, tp, id; int i, gpc, tp, id;
u32 r000260, tmp; u32 r000260, tmp;