diff options
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/nv10_graph.c | 99 |
1 files changed, 69 insertions, 30 deletions
diff --git a/shared-core/nv10_graph.c b/shared-core/nv10_graph.c index db2757d7..4cc44e21 100644 --- a/shared-core/nv10_graph.c +++ b/shared-core/nv10_graph.c @@ -527,6 +527,37 @@ NV10_PGRAPH_DEBUG_4, 0x00400a04, }; +static int nv10_graph_ctx_regs_find_offset(drm_device_t *dev, int reg) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + int i, j; + for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) { + if (nv10_graph_ctx_regs[i] == reg) + return i; + } + if (dev_priv->chipset>=0x17) { + for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) { + if (nv17_graph_ctx_regs[j] == reg) + return i; + } + } + return -1; +} + +static void restore_ctx_regs(drm_device_t *dev, int channel) +{ + drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *fifo = &dev_priv->fifos[channel]; + int i, j; + for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) + NV_WRITE(nv10_graph_ctx_regs[i], fifo->pgraph_ctx[i]); + if (dev_priv->chipset>=0x17) { + for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) + NV_WRITE(nv17_graph_ctx_regs[j], fifo->pgraph_ctx[i]); + } + nouveau_wait_for_idle(dev); +} + void nouveau_nv10_context_switch(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; @@ -559,15 +590,8 @@ void nouveau_nv10_context_switch(drm_device_t *dev) nouveau_wait_for_idle(dev); // restore PGRAPH context - //XXX not working yet #if 1 - for (i = 0; i < sizeof(nv10_graph_ctx_regs)/sizeof(nv10_graph_ctx_regs[0]); i++) - NV_WRITE(nv10_graph_ctx_regs[i], dev_priv->fifos[channel].pgraph_ctx[i]); - if (dev_priv->chipset>=0x17) { - for (j = 0; j < sizeof(nv17_graph_ctx_regs)/sizeof(nv17_graph_ctx_regs[0]); i++,j++) - NV_WRITE(nv17_graph_ctx_regs[j], dev_priv->fifos[channel].pgraph_ctx[i]); - } - nouveau_wait_for_idle(dev); + restore_ctx_regs(dev, channel); #endif NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100); @@ -582,20 +606,52 @@ void nouveau_nv10_context_switch(drm_device_t *dev) NV_WRITE(NV04_PGRAPH_FIFO,0x1); } +#define NV_WRITE_CTX(reg, val) do { \ + int offset = nv10_graph_ctx_regs_find_offset(dev, reg); \ + if (offset > 0) \ + fifo->pgraph_ctx[offset] = val; \ + } while (0) int nv10_graph_context_create(drm_device_t *dev, int channel) { drm_nouveau_private_t *dev_priv = dev->dev_private; + struct nouveau_fifo *fifo = &dev_priv->fifos[channel]; + uint32_t tmp, vramsz; + DRM_DEBUG("nv10_graph_context_create %d\n", channel); - memset(dev_priv->fifos[channel].pgraph_ctx, 0, sizeof(dev_priv->fifos[channel].pgraph_ctx)); + memset(fifo->pgraph_ctx, 0, sizeof(fifo->pgraph_ctx)); + + /* per channel init from ddx */ + tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; + /*XXX the original ddx code, does this in 2 steps : + * tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; + * NV_WRITE(NV10_PGRAPH_SURFACE, tmp); + * tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; + * NV_WRITE(NV10_PGRAPH_SURFACE, tmp); + */ + tmp |= 0x00020100; + NV_WRITE_CTX(NV10_PGRAPH_SURFACE, tmp); + + vramsz = drm_get_resource_len(dev, 0) - 1; + NV_WRITE_CTX(NV04_PGRAPH_BOFFSET0, 0); + NV_WRITE_CTX(NV04_PGRAPH_BOFFSET1, 0); + NV_WRITE_CTX(NV04_PGRAPH_BLIMIT0 , vramsz); + NV_WRITE_CTX(NV04_PGRAPH_BLIMIT1 , vramsz); + + NV_WRITE_CTX(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); + NV_WRITE_CTX(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); - //dev_priv->fifos[channel].pgraph_ctx_user = channel << 24; - dev_priv->fifos[channel].pgraph_ctx[0] = 0x0001ffff; + + NV_WRITE_CTX(NV03_PGRAPH_XY_LOGIC_MISC0, 0x0001ffff); /* is it really needed ??? */ if (dev_priv->chipset>=0x17) { - dev_priv->fifos[channel].pgraph_ctx[sizeof(nv10_graph_ctx_regs) + 0] = NV_READ(NV10_PGRAPH_DEBUG_4); - dev_priv->fifos[channel].pgraph_ctx[sizeof(nv10_graph_ctx_regs) + 1] = NV_READ(0x004006b0); + NV_WRITE_CTX(NV10_PGRAPH_DEBUG_4, NV_READ(NV10_PGRAPH_DEBUG_4)); + NV_WRITE_CTX(0x004006b0, NV_READ(0x004006b0)); } + /* for the first channel init the regs */ + if (dev_priv->fifo_alloc_count == 0) + restore_ctx_regs(dev, channel); + //XXX should be saved/restored for each fifo //we supposed here we have X fifo and only one 3D fifo. @@ -606,7 +662,6 @@ int nv10_graph_context_create(drm_device_t *dev, int channel) { int nv10_graph_init(drm_device_t *dev) { drm_nouveau_private_t *dev_priv = dev->dev_private; - uint32_t tmp, vramsz; int i; NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & @@ -637,23 +692,7 @@ int nv10_graph_init(drm_device_t *dev) { NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF); NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001); - /* the below don't belong here, per-channel context state */ - tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00; - NV_WRITE(NV10_PGRAPH_SURFACE, tmp); - tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100; - NV_WRITE(NV10_PGRAPH_SURFACE, tmp); - - vramsz = drm_get_resource_len(dev, 0) - 1; - NV_WRITE(NV04_PGRAPH_BOFFSET0, 0); - NV_WRITE(NV04_PGRAPH_BOFFSET1, 0); - NV_WRITE(NV04_PGRAPH_BLIMIT0 , vramsz); - NV_WRITE(NV04_PGRAPH_BLIMIT1 , vramsz); - - NV_WRITE(NV04_PGRAPH_PATTERN_SHAPE, 0x00000000); - NV_WRITE(NV04_PGRAPH_BETA_AND , 0xFFFFFFFF); - return 0; - } void nv10_graph_takedown(drm_device_t *dev) |