diff options
author | Jeremy Kolb <jkolb@brandeis.edu> | 2007-01-17 08:46:59 -0500 |
---|---|---|
committer | Jeremy Kolb <jkolb@brandeis.edu> | 2007-01-17 08:46:59 -0500 |
commit | 78a4f5c1bc37cbc581191f47b8b19250bfb86c1e (patch) | |
tree | b7af968001789b589af55affcf31ad0195073811 /shared-core | |
parent | fdbc34fab03eba8d257e14c6d557ffed5fa32c2d (diff) |
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.
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/nouveau_fifo.c | 2 | ||||
-rw-r--r-- | shared-core/nouveau_irq.c | 1 | ||||
-rw-r--r-- | shared-core/nouveau_state.c | 4 | ||||
-rw-r--r-- | shared-core/nv30_graph.c | 98 |
4 files changed, 11 insertions, 94 deletions
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 1e2870f1..8ea0564d 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -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); } diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index a92b8168..eca90833 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -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: diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index f324c5ff..fb35ba74 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -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) diff --git a/shared-core/nv30_graph.c b/shared-core/nv30_graph.c index dbc39490..94f6b3e8 100644 --- a/shared-core/nv30_graph.c +++ b/shared-core/nv30_graph.c @@ -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; |