nouveau: Try to get nv35 pgraph switching working. Doesn't quite yet.
Hook into nv20 pgraph switching functions (they're identical for nv3x). Actually call nv30_pgraph_context_init so the ctx_table is allocated. Thanks to Carlos Martin for the help.main
parent
fdbc34fab0
commit
78a4f5c1bc
|
@ -373,7 +373,7 @@ static void nouveau_nv30_context_init(drm_device_t *dev,
|
|||
/*
|
||||
* TODO: We need to put this somewhere...
|
||||
*/
|
||||
/* INSTANCE_WR(dev_priv->ctx_table, init->channel, grctx_inst); */
|
||||
/*INSTANCE_WR(dev_priv->ctx_table, init->channel, grctx_inst);*/
|
||||
RAMFC_WR(DMA_SUBROUTINE, init->put_base);
|
||||
}
|
||||
|
||||
|
|
|
@ -330,6 +330,7 @@ static void nouveau_pgraph_irq_handler(drm_device_t *dev)
|
|||
nouveau_nv10_context_switch(dev);
|
||||
break;
|
||||
case NV_20:
|
||||
case NV_30:
|
||||
nouveau_nv20_context_switch(dev);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -96,8 +96,8 @@ int nouveau_firstopen(struct drm_device *dev)
|
|||
/* FIXME: doesn't belong here, and have no idea what it's for.. */
|
||||
if (dev_priv->card_type >= NV_40)
|
||||
nv40_graph_init(dev);
|
||||
else if (dev_priv->card_type >= NV_30) {
|
||||
}
|
||||
else if (dev_priv->card_type >= NV_30)
|
||||
nv30_graph_init(dev);
|
||||
else if (dev_priv->card_type >= NV_20)
|
||||
nv20_graph_init(dev);
|
||||
else if (dev_priv->card_type >= NV_10)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* TODO: In the dump start seems to be 7654b0 while end is 76ac28.
|
||||
* This is obviously not the correct size.
|
||||
*/
|
||||
#define NV30_GRCTX_SIZE (22392)
|
||||
#define NV30_GRCTX_SIZE (23840)
|
||||
|
||||
/*TODO: deciper what each offset in the context represents. The below
|
||||
* contexts are taken from dumps just after the 3D object is
|
||||
|
@ -21,7 +21,7 @@ static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
{
|
||||
drm_nouveau_private_t *dev_priv = dev->dev_private;
|
||||
int i;
|
||||
|
||||
|
||||
INSTANCE_WR(ctx, 0x28/4, 0x10000000);
|
||||
INSTANCE_WR(ctx, 0x40c/4, 0x00000101);
|
||||
INSTANCE_WR(ctx, 0x420/4, 0x00000111);
|
||||
|
@ -101,8 +101,7 @@ static void nv30_graph_context_init(drm_device_t *dev, struct mem_block *ctx)
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
nv30_graph_context_create(drm_device_t *dev, int channel)
|
||||
int nv30_graph_context_create(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
|
@ -128,97 +127,14 @@ nv30_graph_context_create(drm_device_t *dev, int channel)
|
|||
|
||||
/* Initialise default context values */
|
||||
ctx_init(dev, chan->ramin_grctx);
|
||||
|
||||
INSTANCE_WR(chan->ramin_grctx, 10, channel << 24); /* CTX_USER */
|
||||
INSTANCE_WR(dev_priv->ctx_table, channel, nouveau_chip_instance_get(dev, chan->ramin_grctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
/* Save current context (from PGRAPH) into the channel's context
|
||||
*XXX: fails sometimes, not sure why..
|
||||
*/
|
||||
void
|
||||
nv40_graph_context_save_current(drm_device_t *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
uint32_t instance;
|
||||
int i;
|
||||
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 0);
|
||||
|
||||
instance = NV_READ(0x40032C) & 0xFFFFF;
|
||||
if (!instance) {
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
NV_WRITE(0x400784, instance);
|
||||
NV_WRITE(0x400310, NV_READ(0x400310) | 0x20);
|
||||
NV_WRITE(0x400304, 1);
|
||||
/* just in case, we don't want to spin in-kernel forever */
|
||||
for (i=0; i<1000; i++) {
|
||||
if (NV_READ(0x40030C) == 0)
|
||||
break;
|
||||
}
|
||||
if (i==1000) {
|
||||
DRM_ERROR("failed to save current grctx to ramin\n");
|
||||
DRM_ERROR("instance = 0x%08x\n", NV_READ(0x40032C));
|
||||
DRM_ERROR("0x40030C = 0x%08x\n", NV_READ(0x40030C));
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 1);
|
||||
}
|
||||
|
||||
/* Restore the context for a specific channel into PGRAPH
|
||||
* XXX: fails sometimes.. not sure why
|
||||
*/
|
||||
void
|
||||
nv40_graph_context_restore(drm_device_t *dev, int channel)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
struct nouveau_fifo *chan = &dev_priv->fifos[channel];
|
||||
uint32_t instance;
|
||||
int i;
|
||||
|
||||
instance = nouveau_chip_instance_get(dev, chan->ramin_grctx);
|
||||
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 0);
|
||||
NV_WRITE(0x400784, instance);
|
||||
NV_WRITE(0x400310, NV_READ(0x400310) | 0x40);
|
||||
NV_WRITE(0x400304, 1);
|
||||
/* just in case, we don't want to spin in-kernel forever */
|
||||
for (i=0; i<1000; i++) {
|
||||
if (NV_READ(0x40030C) == 0)
|
||||
break;
|
||||
}
|
||||
if (i==1000) {
|
||||
DRM_ERROR("failed to restore grctx for ch%d to PGRAPH\n",
|
||||
channel);
|
||||
DRM_ERROR("instance = 0x%08x\n", instance);
|
||||
DRM_ERROR("0x40030C = 0x%08x\n", NV_READ(0x40030C));
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* 0x40032C, no idea of it's exact function. Could simply be a
|
||||
* record of the currently active PGRAPH context. It's currently
|
||||
* unknown as to what bit 24 does. The nv ddx has it set, so we will
|
||||
* set it here too.
|
||||
*/
|
||||
NV_WRITE(0x40032C, instance | 0x01000000);
|
||||
/* 0x32E0 records the instance address of the active FIFO's PGRAPH
|
||||
* context. If at any time this doesn't match 0x40032C, you will
|
||||
* recieve PGRAPH_INTR_CONTEXT_SWITCH
|
||||
*/
|
||||
NV_WRITE(NV40_PFIFO_GRCTX_INSTANCE, instance);
|
||||
NV_WRITE(NV_PGRAPH_FIFO, 1);
|
||||
}
|
||||
#endif
|
||||
int
|
||||
nv30_graph_init(drm_device_t *dev)
|
||||
int nv30_graph_init(drm_device_t *dev)
|
||||
{
|
||||
drm_nouveau_private_t *dev_priv =
|
||||
(drm_nouveau_private_t *)dev->dev_private;
|
||||
|
|
Loading…
Reference in New Issue